2 /* pngmem.c - stub functions for memory allocation
\r
4 * Last changed in libpng 1.2.30 [August 15, 2008]
\r
5 * For conditions of distribution and use, see copyright notice in png.h
\r
6 * Copyright (c) 1998-2008 Glenn Randers-Pehrson
\r
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
\r
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
\r
10 * This file provides a location for all memory allocation. Users who
\r
11 * need special memory handling are expected to supply replacement
\r
12 * functions for png_malloc() and png_free(), and to use
\r
13 * png_create_read_struct_2() and png_create_write_struct_2() to
\r
14 * identify the replacement functions.
\r
17 #define PNG_INTERNAL
\r
19 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
\r
21 /* Borland DOS special memory handler */
\r
22 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
\r
23 /* if you change this, be sure to change the one in png.h also */
\r
25 /* Allocate memory for a png_struct. The malloc and memset can be replaced
\r
26 by a single call to calloc() if this is thought to improve performance. */
\r
27 png_voidp /* PRIVATE */
\r
28 png_create_struct(int type)
\r
30 #ifdef PNG_USER_MEM_SUPPORTED
\r
31 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
\r
34 /* Alternate version of png_create_struct, for use with user-defined malloc. */
\r
35 png_voidp /* PRIVATE */
\r
36 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
\r
38 #endif /* PNG_USER_MEM_SUPPORTED */
\r
40 png_voidp struct_ptr;
\r
42 if (type == PNG_STRUCT_INFO)
\r
43 size = png_sizeof(png_info);
\r
44 else if (type == PNG_STRUCT_PNG)
\r
45 size = png_sizeof(png_struct);
\r
47 return (png_get_copyright(NULL));
\r
49 #ifdef PNG_USER_MEM_SUPPORTED
\r
50 if (malloc_fn != NULL)
\r
52 png_struct dummy_struct;
\r
53 png_structp png_ptr = &dummy_struct;
\r
54 png_ptr->mem_ptr=mem_ptr;
\r
55 struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
\r
58 #endif /* PNG_USER_MEM_SUPPORTED */
\r
59 struct_ptr = (png_voidp)farmalloc(size);
\r
60 if (struct_ptr != NULL)
\r
61 png_memset(struct_ptr, 0, size);
\r
62 return (struct_ptr);
\r
65 /* Free memory allocated by a png_create_struct() call */
\r
67 png_destroy_struct(png_voidp struct_ptr)
\r
69 #ifdef PNG_USER_MEM_SUPPORTED
\r
70 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
\r
73 /* Free memory allocated by a png_create_struct() call */
\r
75 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
\r
79 if (struct_ptr != NULL)
\r
81 #ifdef PNG_USER_MEM_SUPPORTED
\r
82 if (free_fn != NULL)
\r
84 png_struct dummy_struct;
\r
85 png_structp png_ptr = &dummy_struct;
\r
86 png_ptr->mem_ptr=mem_ptr;
\r
87 (*(free_fn))(png_ptr, struct_ptr);
\r
90 #endif /* PNG_USER_MEM_SUPPORTED */
\r
91 farfree (struct_ptr);
\r
95 /* Allocate memory. For reasonable files, size should never exceed
\r
96 * 64K. However, zlib may allocate more then 64K if you don't tell
\r
97 * it not to. See zconf.h and png.h for more information. zlib does
\r
98 * need to allocate exactly 64K, so whatever you call here must
\r
99 * have the ability to do that.
\r
101 * Borland seems to have a problem in DOS mode for exactly 64K.
\r
102 * It gives you a segment with an offset of 8 (perhaps to store its
\r
103 * memory stuff). zlib doesn't like this at all, so we have to
\r
104 * detect and deal with it. This code should not be needed in
\r
105 * Windows or OS/2 modes, and only in 16 bit mode. This code has
\r
106 * been updated by Alexander Lehmann for version 0.89 to waste less
\r
109 * Note that we can't use png_size_t for the "size" declaration,
\r
110 * since on some systems a png_size_t is a 16-bit quantity, and as a
\r
111 * result, we would be truncating potentially larger memory requests
\r
112 * (which should cause a fatal error) and introducing major problems.
\r
116 png_malloc(png_structp png_ptr, png_uint_32 size)
\r
120 if (png_ptr == NULL || size == 0)
\r
123 #ifdef PNG_USER_MEM_SUPPORTED
\r
124 if (png_ptr->malloc_fn != NULL)
\r
125 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
\r
127 ret = (png_malloc_default(png_ptr, size));
\r
128 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
129 png_error(png_ptr, "Out of memory!");
\r
134 png_malloc_default(png_structp png_ptr, png_uint_32 size)
\r
137 #endif /* PNG_USER_MEM_SUPPORTED */
\r
139 if (png_ptr == NULL || size == 0)
\r
142 #ifdef PNG_MAX_MALLOC_64K
\r
143 if (size > (png_uint_32)65536L)
\r
145 png_warning(png_ptr, "Cannot Allocate > 64K");
\r
151 if (size != (size_t)size)
\r
153 else if (size == (png_uint_32)65536L)
\r
155 if (png_ptr->offset_table == NULL)
\r
157 /* try to see if we need to do any of this fancy stuff */
\r
158 ret = farmalloc(size);
\r
159 if (ret == NULL || ((png_size_t)ret & 0xffff))
\r
162 png_uint_32 total_size;
\r
165 png_byte huge * hptr;
\r
173 if (png_ptr->zlib_window_bits > 14)
\r
174 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
\r
177 if (png_ptr->zlib_mem_level >= 7)
\r
178 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
\r
182 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
\r
184 table = farmalloc(total_size);
\r
188 #ifndef PNG_USER_MEM_SUPPORTED
\r
189 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
190 png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
\r
192 png_warning(png_ptr, "Out Of Memory.");
\r
197 if ((png_size_t)table & 0xfff0)
\r
199 #ifndef PNG_USER_MEM_SUPPORTED
\r
200 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
202 "Farmalloc didn't return normalized pointer");
\r
204 png_warning(png_ptr,
\r
205 "Farmalloc didn't return normalized pointer");
\r
210 png_ptr->offset_table = table;
\r
211 png_ptr->offset_table_ptr = farmalloc(num_blocks *
\r
212 png_sizeof(png_bytep));
\r
214 if (png_ptr->offset_table_ptr == NULL)
\r
216 #ifndef PNG_USER_MEM_SUPPORTED
\r
217 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
218 png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
\r
220 png_warning(png_ptr, "Out Of memory.");
\r
225 hptr = (png_byte huge *)table;
\r
226 if ((png_size_t)hptr & 0xf)
\r
228 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
\r
229 hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
\r
231 for (i = 0; i < num_blocks; i++)
\r
233 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
\r
234 hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
\r
237 png_ptr->offset_table_number = num_blocks;
\r
238 png_ptr->offset_table_count = 0;
\r
239 png_ptr->offset_table_count_free = 0;
\r
243 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
\r
245 #ifndef PNG_USER_MEM_SUPPORTED
\r
246 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
247 png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
\r
249 png_warning(png_ptr, "Out of Memory.");
\r
254 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
\r
257 ret = farmalloc(size);
\r
259 #ifndef PNG_USER_MEM_SUPPORTED
\r
262 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
263 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
\r
265 png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
\r
272 /* free a pointer allocated by png_malloc(). In the default
\r
273 configuration, png_ptr is not used, but is passed in case it
\r
274 is needed. If ptr is NULL, return without taking any action. */
\r
277 png_free(png_structp png_ptr, png_voidp ptr)
\r
279 if (png_ptr == NULL || ptr == NULL)
\r
282 #ifdef PNG_USER_MEM_SUPPORTED
\r
283 if (png_ptr->free_fn != NULL)
\r
285 (*(png_ptr->free_fn))(png_ptr, ptr);
\r
288 else png_free_default(png_ptr, ptr);
\r
292 png_free_default(png_structp png_ptr, png_voidp ptr)
\r
294 #endif /* PNG_USER_MEM_SUPPORTED */
\r
296 if (png_ptr == NULL || ptr == NULL) return;
\r
298 if (png_ptr->offset_table != NULL)
\r
302 for (i = 0; i < png_ptr->offset_table_count; i++)
\r
304 if (ptr == png_ptr->offset_table_ptr[i])
\r
307 png_ptr->offset_table_count_free++;
\r
311 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
\r
313 farfree(png_ptr->offset_table);
\r
314 farfree(png_ptr->offset_table_ptr);
\r
315 png_ptr->offset_table = NULL;
\r
316 png_ptr->offset_table_ptr = NULL;
\r
326 #else /* Not the Borland DOS special memory handler */
\r
328 /* Allocate memory for a png_struct or a png_info. The malloc and
\r
329 memset can be replaced by a single call to calloc() if this is thought
\r
330 to improve performance noticably. */
\r
331 png_voidp /* PRIVATE */
\r
332 png_create_struct(int type)
\r
334 #ifdef PNG_USER_MEM_SUPPORTED
\r
335 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
\r
338 /* Allocate memory for a png_struct or a png_info. The malloc and
\r
339 memset can be replaced by a single call to calloc() if this is thought
\r
340 to improve performance noticably. */
\r
341 png_voidp /* PRIVATE */
\r
342 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
\r
344 #endif /* PNG_USER_MEM_SUPPORTED */
\r
346 png_voidp struct_ptr;
\r
348 if (type == PNG_STRUCT_INFO)
\r
349 size = png_sizeof(png_info);
\r
350 else if (type == PNG_STRUCT_PNG)
\r
351 size = png_sizeof(png_struct);
\r
355 #ifdef PNG_USER_MEM_SUPPORTED
\r
356 if (malloc_fn != NULL)
\r
358 png_struct dummy_struct;
\r
359 png_structp png_ptr = &dummy_struct;
\r
360 png_ptr->mem_ptr=mem_ptr;
\r
361 struct_ptr = (*(malloc_fn))(png_ptr, size);
\r
362 if (struct_ptr != NULL)
\r
363 png_memset(struct_ptr, 0, size);
\r
364 return (struct_ptr);
\r
366 #endif /* PNG_USER_MEM_SUPPORTED */
\r
368 #if defined(__TURBOC__) && !defined(__FLAT__)
\r
369 struct_ptr = (png_voidp)farmalloc(size);
\r
371 # if defined(_MSC_VER) && defined(MAXSEG_64K)
\r
372 struct_ptr = (png_voidp)halloc(size, 1);
\r
374 struct_ptr = (png_voidp)malloc(size);
\r
377 if (struct_ptr != NULL)
\r
378 png_memset(struct_ptr, 0, size);
\r
380 return (struct_ptr);
\r
384 /* Free memory allocated by a png_create_struct() call */
\r
386 png_destroy_struct(png_voidp struct_ptr)
\r
388 #ifdef PNG_USER_MEM_SUPPORTED
\r
389 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
\r
392 /* Free memory allocated by a png_create_struct() call */
\r
394 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
\r
397 #endif /* PNG_USER_MEM_SUPPORTED */
\r
398 if (struct_ptr != NULL)
\r
400 #ifdef PNG_USER_MEM_SUPPORTED
\r
401 if (free_fn != NULL)
\r
403 png_struct dummy_struct;
\r
404 png_structp png_ptr = &dummy_struct;
\r
405 png_ptr->mem_ptr=mem_ptr;
\r
406 (*(free_fn))(png_ptr, struct_ptr);
\r
409 #endif /* PNG_USER_MEM_SUPPORTED */
\r
410 #if defined(__TURBOC__) && !defined(__FLAT__)
\r
411 farfree(struct_ptr);
\r
413 # if defined(_MSC_VER) && defined(MAXSEG_64K)
\r
422 /* Allocate memory. For reasonable files, size should never exceed
\r
423 64K. However, zlib may allocate more then 64K if you don't tell
\r
424 it not to. See zconf.h and png.h for more information. zlib does
\r
425 need to allocate exactly 64K, so whatever you call here must
\r
426 have the ability to do that. */
\r
429 png_malloc(png_structp png_ptr, png_uint_32 size)
\r
433 #ifdef PNG_USER_MEM_SUPPORTED
\r
434 if (png_ptr == NULL || size == 0)
\r
437 if (png_ptr->malloc_fn != NULL)
\r
438 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
\r
440 ret = (png_malloc_default(png_ptr, size));
\r
441 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
442 png_error(png_ptr, "Out of Memory!");
\r
447 png_malloc_default(png_structp png_ptr, png_uint_32 size)
\r
450 #endif /* PNG_USER_MEM_SUPPORTED */
\r
452 if (png_ptr == NULL || size == 0)
\r
455 #ifdef PNG_MAX_MALLOC_64K
\r
456 if (size > (png_uint_32)65536L)
\r
458 #ifndef PNG_USER_MEM_SUPPORTED
\r
459 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
460 png_error(png_ptr, "Cannot Allocate > 64K");
\r
467 /* Check for overflow */
\r
468 #if defined(__TURBOC__) && !defined(__FLAT__)
\r
469 if (size != (unsigned long)size)
\r
472 ret = farmalloc(size);
\r
474 # if defined(_MSC_VER) && defined(MAXSEG_64K)
\r
475 if (size != (unsigned long)size)
\r
478 ret = halloc(size, 1);
\r
480 if (size != (size_t)size)
\r
483 ret = malloc((size_t)size);
\r
487 #ifndef PNG_USER_MEM_SUPPORTED
\r
488 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
\r
489 png_error(png_ptr, "Out of Memory");
\r
495 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
\r
496 without taking any action. */
\r
498 png_free(png_structp png_ptr, png_voidp ptr)
\r
500 if (png_ptr == NULL || ptr == NULL)
\r
503 #ifdef PNG_USER_MEM_SUPPORTED
\r
504 if (png_ptr->free_fn != NULL)
\r
506 (*(png_ptr->free_fn))(png_ptr, ptr);
\r
509 else png_free_default(png_ptr, ptr);
\r
512 png_free_default(png_structp png_ptr, png_voidp ptr)
\r
514 if (png_ptr == NULL || ptr == NULL)
\r
517 #endif /* PNG_USER_MEM_SUPPORTED */
\r
519 #if defined(__TURBOC__) && !defined(__FLAT__)
\r
522 # if defined(_MSC_VER) && defined(MAXSEG_64K)
\r
530 #endif /* Not Borland DOS special memory handler */
\r
532 #if defined(PNG_1_0_X)
\r
533 # define png_malloc_warn png_malloc
\r
535 /* This function was added at libpng version 1.2.3. The png_malloc_warn()
\r
536 * function will set up png_malloc() to issue a png_warning and return NULL
\r
537 * instead of issuing a png_error, if it fails to allocate the requested
\r
541 png_malloc_warn(png_structp png_ptr, png_uint_32 size)
\r
544 png_uint_32 save_flags;
\r
545 if (png_ptr == NULL) return (NULL);
\r
547 save_flags = png_ptr->flags;
\r
548 png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
\r
549 ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
\r
550 png_ptr->flags=save_flags;
\r
556 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
\r
557 png_uint_32 length)
\r
561 size = (png_size_t)length;
\r
562 if ((png_uint_32)size != length)
\r
563 png_error(png_ptr, "Overflow in png_memcpy_check.");
\r
565 return(png_memcpy (s1, s2, size));
\r
569 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
\r
570 png_uint_32 length)
\r
574 size = (png_size_t)length;
\r
575 if ((png_uint_32)size != length)
\r
576 png_error(png_ptr, "Overflow in png_memset_check.");
\r
578 return (png_memset (s1, value, size));
\r
582 #ifdef PNG_USER_MEM_SUPPORTED
\r
583 /* This function is called when the application wants to use another method
\r
584 * of allocating and freeing memory.
\r
587 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
\r
588 malloc_fn, png_free_ptr free_fn)
\r
590 if (png_ptr != NULL)
\r
592 png_ptr->mem_ptr = mem_ptr;
\r
593 png_ptr->malloc_fn = malloc_fn;
\r
594 png_ptr->free_fn = free_fn;
\r
598 /* This function returns a pointer to the mem_ptr associated with the user
\r
599 * functions. The application should free any memory associated with this
\r
600 * pointer before png_write_destroy and png_read_destroy are called.
\r
603 png_get_mem_ptr(png_structp png_ptr)
\r
605 if (png_ptr == NULL) return (NULL);
\r
606 return ((png_voidp)png_ptr->mem_ptr);
\r
608 #endif /* PNG_USER_MEM_SUPPORTED */
\r
609 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
\r