2 /* pngmem.c - stub functions for memory allocation
4 * libpng 1.2.0 - September 1, 2001
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2001 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10 * This file provides a location for all memory allocation. Users who
11 * need special memory handling are expected to supply replacement
12 * functions for png_malloc() and png_free(), and to use
13 * png_create_read_struct_2() and png_create_write_struct_2() to
14 * identify the replacement functions.
20 /* Borland DOS special memory handler */
21 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
22 /* if you change this, be sure to change the one in png.h also */
24 /* Allocate memory for a png_struct. The malloc and memset can be replaced
25 by a single call to calloc() if this is thought to improve performance. */
26 png_voidp /* PRIVATE */
27 png_create_struct(int type)
29 #ifdef PNG_USER_MEM_SUPPORTED
30 return (png_create_struct_2(type, NULL, NULL));
33 /* Alternate version of png_create_struct, for use with user-defined malloc. */
34 png_voidp /* PRIVATE */
35 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
37 #endif /* PNG_USER_MEM_SUPPORTED */
41 if (type == PNG_STRUCT_INFO)
42 size = sizeof(png_info);
43 else if (type == PNG_STRUCT_PNG)
44 size = sizeof(png_struct);
46 return ((png_voidp)NULL);
48 #ifdef PNG_USER_MEM_SUPPORTED
53 png_struct dummy_struct;
54 png_structp png_ptr = &dummy_struct;
55 png_ptr->mem_ptr=mem_ptr;
56 struct_ptr = (*(malloc_fn))(png_ptr, size);
59 struct_ptr = (*(malloc_fn))(NULL, size);
60 if (struct_ptr != NULL)
61 png_memset(struct_ptr, 0, size);
64 #endif /* PNG_USER_MEM_SUPPORTED */
65 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
67 png_memset(struct_ptr, 0, size);
73 /* Free memory allocated by a png_create_struct() call */
75 png_destroy_struct(png_voidp struct_ptr)
77 #ifdef PNG_USER_MEM_SUPPORTED
78 png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL, (png_voidp)NULL);
81 /* Free memory allocated by a png_create_struct() call */
83 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
87 if (struct_ptr != NULL)
89 #ifdef PNG_USER_MEM_SUPPORTED
92 png_struct dummy_struct;
93 png_structp png_ptr = &dummy_struct;
94 png_ptr->mem_ptr=mem_ptr;
95 (*(free_fn))(png_ptr, struct_ptr);
98 #endif /* PNG_USER_MEM_SUPPORTED */
103 /* Allocate memory. For reasonable files, size should never exceed
104 * 64K. However, zlib may allocate more then 64K if you don't tell
105 * it not to. See zconf.h and png.h for more information. zlib does
106 * need to allocate exactly 64K, so whatever you call here must
107 * have the ability to do that.
109 * Borland seems to have a problem in DOS mode for exactly 64K.
110 * It gives you a segment with an offset of 8 (perhaps to store its
111 * memory stuff). zlib doesn't like this at all, so we have to
112 * detect and deal with it. This code should not be needed in
113 * Windows or OS/2 modes, and only in 16 bit mode. This code has
114 * been updated by Alexander Lehmann for version 0.89 to waste less
117 * Note that we can't use png_size_t for the "size" declaration,
118 * since on some systems a png_size_t is a 16-bit quantity, and as a
119 * result, we would be truncating potentially larger memory requests
120 * (which should cause a fatal error) and introducing major problems.
123 png_malloc(png_structp png_ptr, png_uint_32 size)
125 #ifndef PNG_USER_MEM_SUPPORTED
128 if (png_ptr == NULL || size == 0)
129 return ((png_voidp)NULL);
131 #ifdef PNG_USER_MEM_SUPPORTED
132 if(png_ptr->malloc_fn != NULL)
134 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
136 png_error(png_ptr, "Out of memory!");
140 return png_malloc_default(png_ptr, size);
144 png_malloc_default(png_structp png_ptr, png_uint_32 size)
147 #endif /* PNG_USER_MEM_SUPPORTED */
149 #ifdef PNG_MAX_MALLOC_64K
150 if (size > (png_uint_32)65536L)
151 png_error(png_ptr, "Cannot Allocate > 64K");
154 if (size == (png_uint_32)65536L)
156 if (png_ptr->offset_table == NULL)
158 /* try to see if we need to do any of this fancy stuff */
159 ret = farmalloc(size);
160 if (ret == NULL || ((png_size_t)ret & 0xffff))
163 png_uint_32 total_size;
166 png_byte huge * hptr;
174 if(png_ptr->zlib_window_bits > 14)
175 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
178 if (png_ptr->zlib_mem_level >= 7)
179 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
183 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
185 table = farmalloc(total_size);
189 png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
192 if ((png_size_t)table & 0xfff0)
194 png_error(png_ptr, "Farmalloc didn't return normalized pointer");
197 png_ptr->offset_table = table;
198 png_ptr->offset_table_ptr = farmalloc(num_blocks *
201 if (png_ptr->offset_table_ptr == NULL)
203 png_error(png_ptr, "Out Of memory.");
206 hptr = (png_byte huge *)table;
207 if ((png_size_t)hptr & 0xf)
209 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
210 hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
212 for (i = 0; i < num_blocks; i++)
214 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
215 hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
218 png_ptr->offset_table_number = num_blocks;
219 png_ptr->offset_table_count = 0;
220 png_ptr->offset_table_count_free = 0;
224 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
225 png_error(png_ptr, "Out of Memory.");
227 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
230 ret = farmalloc(size);
234 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
240 /* free a pointer allocated by png_malloc(). In the default
241 configuration, png_ptr is not used, but is passed in case it
242 is needed. If ptr is NULL, return without taking any action. */
244 png_free(png_structp png_ptr, png_voidp ptr)
246 if (png_ptr == NULL || ptr == NULL)
249 #ifdef PNG_USER_MEM_SUPPORTED
250 if (png_ptr->free_fn != NULL)
252 (*(png_ptr->free_fn))(png_ptr, ptr);
255 else png_free_default(png_ptr, ptr);
259 png_free_default(png_structp png_ptr, png_voidp ptr)
261 #endif /* PNG_USER_MEM_SUPPORTED */
263 if (png_ptr->offset_table != NULL)
267 for (i = 0; i < png_ptr->offset_table_count; i++)
269 if (ptr == png_ptr->offset_table_ptr[i])
272 png_ptr->offset_table_count_free++;
276 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
278 farfree(png_ptr->offset_table);
279 farfree(png_ptr->offset_table_ptr);
280 png_ptr->offset_table = NULL;
281 png_ptr->offset_table_ptr = NULL;
291 #else /* Not the Borland DOS special memory handler */
293 /* Allocate memory for a png_struct or a png_info. The malloc and
294 memset can be replaced by a single call to calloc() if this is thought
295 to improve performance noticably.*/
296 png_voidp /* PRIVATE */
297 png_create_struct(int type)
299 #ifdef PNG_USER_MEM_SUPPORTED
300 return (png_create_struct_2(type, NULL, NULL));
303 /* Allocate memory for a png_struct or a png_info. The malloc and
304 memset can be replaced by a single call to calloc() if this is thought
305 to improve performance noticably.*/
306 png_voidp /* PRIVATE */
307 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
309 #endif /* PNG_USER_MEM_SUPPORTED */
311 png_voidp struct_ptr;
313 if (type == PNG_STRUCT_INFO)
314 size = sizeof(png_info);
315 else if (type == PNG_STRUCT_PNG)
316 size = sizeof(png_struct);
318 return ((png_voidp)NULL);
320 #ifdef PNG_USER_MEM_SUPPORTED
321 if(malloc_fn != NULL)
325 png_struct dummy_struct;
326 png_structp png_ptr = &dummy_struct;
327 png_ptr->mem_ptr=mem_ptr;
328 struct_ptr = (*(malloc_fn))(png_ptr, size);
331 struct_ptr = (*(malloc_fn))(NULL, size);
332 if (struct_ptr != NULL)
333 png_memset(struct_ptr, 0, size);
336 #endif /* PNG_USER_MEM_SUPPORTED */
338 #if defined(__TURBOC__) && !defined(__FLAT__)
339 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
341 # if defined(_MSC_VER) && defined(MAXSEG_64K)
342 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
344 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
348 png_memset(struct_ptr, 0, size);
355 /* Free memory allocated by a png_create_struct() call */
357 png_destroy_struct(png_voidp struct_ptr)
359 #ifdef PNG_USER_MEM_SUPPORTED
360 png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL, (png_voidp)NULL);
363 /* Free memory allocated by a png_create_struct() call */
365 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
368 #endif /* PNG_USER_MEM_SUPPORTED */
369 if (struct_ptr != NULL)
371 #ifdef PNG_USER_MEM_SUPPORTED
374 png_struct dummy_struct;
375 png_structp png_ptr = &dummy_struct;
376 png_ptr->mem_ptr=mem_ptr;
377 (*(free_fn))(png_ptr, struct_ptr);
380 #endif /* PNG_USER_MEM_SUPPORTED */
381 #if defined(__TURBOC__) && !defined(__FLAT__)
384 # if defined(_MSC_VER) && defined(MAXSEG_64K)
394 /* Allocate memory. For reasonable files, size should never exceed
395 64K. However, zlib may allocate more then 64K if you don't tell
396 it not to. See zconf.h and png.h for more information. zlib does
397 need to allocate exactly 64K, so whatever you call here must
398 have the ability to do that. */
401 png_malloc(png_structp png_ptr, png_uint_32 size)
404 if (png_ptr == NULL || size == 0)
405 return ((png_voidp)NULL);
407 #ifdef PNG_USER_MEM_SUPPORTED
408 if(png_ptr->malloc_fn != NULL)
410 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
412 png_error(png_ptr, "Out of Memory!");
416 return (png_malloc_default(png_ptr, size));
418 png_voidp /* PRIVATE */
419 png_malloc_default(png_structp png_ptr, png_uint_32 size)
422 #endif /* PNG_USER_MEM_SUPPORTED */
424 #ifdef PNG_MAX_MALLOC_64K
425 if (size > (png_uint_32)65536L)
426 png_error(png_ptr, "Cannot Allocate > 64K");
429 #if defined(__TURBOC__) && !defined(__FLAT__)
430 ret = farmalloc(size);
432 # if defined(_MSC_VER) && defined(MAXSEG_64K)
433 ret = halloc(size, 1);
435 ret = malloc((size_t)size);
440 png_error(png_ptr, "Out of Memory");
445 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
446 without taking any action. */
448 png_free(png_structp png_ptr, png_voidp ptr)
450 if (png_ptr == NULL || ptr == NULL)
453 #ifdef PNG_USER_MEM_SUPPORTED
454 if (png_ptr->free_fn != NULL)
456 (*(png_ptr->free_fn))(png_ptr, ptr);
459 else png_free_default(png_ptr, ptr);
462 png_free_default(png_structp png_ptr, png_voidp ptr)
464 if (png_ptr == NULL || ptr == NULL)
467 #endif /* PNG_USER_MEM_SUPPORTED */
469 #if defined(__TURBOC__) && !defined(__FLAT__)
472 # if defined(_MSC_VER) && defined(MAXSEG_64K)
480 #endif /* Not Borland DOS special memory handler */
482 png_voidp /* PRIVATE */
483 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
488 size = (png_size_t)length;
489 if ((png_uint_32)size != length)
490 png_error(png_ptr,"Overflow in png_memcpy_check.");
492 return(png_memcpy (s1, s2, size));
495 png_voidp /* PRIVATE */
496 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
501 size = (png_size_t)length;
502 if ((png_uint_32)size != length)
503 png_error(png_ptr,"Overflow in png_memset_check.");
505 return (png_memset (s1, value, size));
509 #ifdef PNG_USER_MEM_SUPPORTED
510 /* This function is called when the application wants to use another method
511 * of allocating and freeing memory.
514 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
515 malloc_fn, png_free_ptr free_fn)
517 png_ptr->mem_ptr = mem_ptr;
518 png_ptr->malloc_fn = malloc_fn;
519 png_ptr->free_fn = free_fn;
522 /* This function returns a pointer to the mem_ptr associated with the user
523 * functions. The application should free any memory associated with this
524 * pointer before png_write_destroy and png_read_destroy are called.
527 png_get_mem_ptr(png_structp png_ptr)
529 return ((png_voidp)png_ptr->mem_ptr);
531 #endif /* PNG_USER_MEM_SUPPORTED */