2 /* pngmem.c - stub functions for memory allocation
4 * Last changed in libpng 1.2.37 [June 4, 2009]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2009 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.
19 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
21 /* Borland DOS special memory handler */
22 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
23 /* If you change this, be sure to change the one in png.h also */
25 /* Allocate memory for a png_struct. The malloc and memset can be replaced
26 by a single call to calloc() if this is thought to improve performance. */
27 png_voidp
/* PRIVATE */
28 png_create_struct(int type
)
30 #ifdef PNG_USER_MEM_SUPPORTED
31 return (png_create_struct_2(type
, png_malloc_ptr_NULL
, png_voidp_NULL
));
34 /* Alternate version of png_create_struct, for use with user-defined malloc. */
35 png_voidp
/* PRIVATE */
36 png_create_struct_2(int type
, png_malloc_ptr malloc_fn
, png_voidp mem_ptr
)
38 #endif /* PNG_USER_MEM_SUPPORTED */
42 if (type
== PNG_STRUCT_INFO
)
43 size
= png_sizeof(png_info
);
44 else if (type
== PNG_STRUCT_PNG
)
45 size
= png_sizeof(png_struct
);
47 return (png_get_copyright(NULL
));
49 #ifdef PNG_USER_MEM_SUPPORTED
50 if (malloc_fn
!= NULL
)
52 png_struct dummy_struct
;
53 png_structp png_ptr
= &dummy_struct
;
54 png_ptr
->mem_ptr
=mem_ptr
;
55 struct_ptr
= (*(malloc_fn
))(png_ptr
, (png_uint_32
)size
);
58 #endif /* PNG_USER_MEM_SUPPORTED */
59 struct_ptr
= (png_voidp
)farmalloc(size
);
60 if (struct_ptr
!= NULL
)
61 png_memset(struct_ptr
, 0, size
);
65 /* Free memory allocated by a png_create_struct() call */
67 png_destroy_struct(png_voidp struct_ptr
)
69 #ifdef PNG_USER_MEM_SUPPORTED
70 png_destroy_struct_2(struct_ptr
, png_free_ptr_NULL
, png_voidp_NULL
);
73 /* Free memory allocated by a png_create_struct() call */
75 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
,
79 if (struct_ptr
!= NULL
)
81 #ifdef PNG_USER_MEM_SUPPORTED
84 png_struct dummy_struct
;
85 png_structp png_ptr
= &dummy_struct
;
86 png_ptr
->mem_ptr
=mem_ptr
;
87 (*(free_fn
))(png_ptr
, struct_ptr
);
90 #endif /* PNG_USER_MEM_SUPPORTED */
95 /* Allocate memory. For reasonable files, size should never exceed
96 * 64K. However, zlib may allocate more then 64K if you don't tell
97 * it not to. See zconf.h and png.h for more information. zlib does
98 * need to allocate exactly 64K, so whatever you call here must
99 * have the ability to do that.
101 * Borland seems to have a problem in DOS mode for exactly 64K.
102 * It gives you a segment with an offset of 8 (perhaps to store its
103 * memory stuff). zlib doesn't like this at all, so we have to
104 * detect and deal with it. This code should not be needed in
105 * Windows or OS/2 modes, and only in 16 bit mode. This code has
106 * been updated by Alexander Lehmann for version 0.89 to waste less
109 * Note that we can't use png_size_t for the "size" declaration,
110 * since on some systems a png_size_t is a 16-bit quantity, and as a
111 * result, we would be truncating potentially larger memory requests
112 * (which should cause a fatal error) and introducing major problems.
116 png_malloc(png_structp png_ptr
, png_uint_32 size
)
120 if (png_ptr
== NULL
|| size
== 0)
123 #ifdef PNG_USER_MEM_SUPPORTED
124 if (png_ptr
->malloc_fn
!= NULL
)
125 ret
= ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, (png_size_t
)size
));
127 ret
= (png_malloc_default(png_ptr
, size
));
128 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
129 png_error(png_ptr
, "Out of memory!");
134 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
137 #endif /* PNG_USER_MEM_SUPPORTED */
139 if (png_ptr
== NULL
|| size
== 0)
142 #ifdef PNG_MAX_MALLOC_64K
143 if (size
> (png_uint_32
)65536L)
145 png_warning(png_ptr
, "Cannot Allocate > 64K");
151 if (size
!= (size_t)size
)
153 else if (size
== (png_uint_32
)65536L)
155 if (png_ptr
->offset_table
== NULL
)
157 /* Try to see if we need to do any of this fancy stuff */
158 ret
= farmalloc(size
);
159 if (ret
== NULL
|| ((png_size_t
)ret
& 0xffff))
162 png_uint_32 total_size
;
165 png_byte huge
* hptr
;
173 if (png_ptr
->zlib_window_bits
> 14)
174 num_blocks
= (int)(1 << (png_ptr
->zlib_window_bits
- 14));
177 if (png_ptr
->zlib_mem_level
>= 7)
178 num_blocks
+= (int)(1 << (png_ptr
->zlib_mem_level
- 7));
182 total_size
= ((png_uint_32
)65536L) * (png_uint_32
)num_blocks
+16;
184 table
= farmalloc(total_size
);
188 #ifndef PNG_USER_MEM_SUPPORTED
189 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
190 png_error(png_ptr
, "Out Of Memory."); /* Note "O" and "M" */
192 png_warning(png_ptr
, "Out Of Memory.");
197 if ((png_size_t
)table
& 0xfff0)
199 #ifndef PNG_USER_MEM_SUPPORTED
200 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
202 "Farmalloc didn't return normalized pointer");
205 "Farmalloc didn't return normalized pointer");
210 png_ptr
->offset_table
= table
;
211 png_ptr
->offset_table_ptr
= farmalloc(num_blocks
*
212 png_sizeof(png_bytep
));
214 if (png_ptr
->offset_table_ptr
== NULL
)
216 #ifndef PNG_USER_MEM_SUPPORTED
217 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
218 png_error(png_ptr
, "Out Of memory."); /* Note "O" and "M" */
220 png_warning(png_ptr
, "Out Of memory.");
225 hptr
= (png_byte huge
*)table
;
226 if ((png_size_t
)hptr
& 0xf)
228 hptr
= (png_byte huge
*)((long)(hptr
) & 0xfffffff0L
);
229 hptr
= hptr
+ 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
231 for (i
= 0; i
< num_blocks
; i
++)
233 png_ptr
->offset_table_ptr
[i
] = (png_bytep
)hptr
;
234 hptr
= hptr
+ (png_uint_32
)65536L; /* "+=" fails on TC++3.0 */
237 png_ptr
->offset_table_number
= num_blocks
;
238 png_ptr
->offset_table_count
= 0;
239 png_ptr
->offset_table_count_free
= 0;
243 if (png_ptr
->offset_table_count
>= png_ptr
->offset_table_number
)
245 #ifndef PNG_USER_MEM_SUPPORTED
246 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
247 png_error(png_ptr
, "Out of Memory."); /* Note "o" and "M" */
249 png_warning(png_ptr
, "Out of Memory.");
254 ret
= png_ptr
->offset_table_ptr
[png_ptr
->offset_table_count
++];
257 ret
= farmalloc(size
);
259 #ifndef PNG_USER_MEM_SUPPORTED
262 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
263 png_error(png_ptr
, "Out of memory."); /* Note "o" and "m" */
265 png_warning(png_ptr
, "Out of memory."); /* Note "o" and "m" */
272 /* Free a pointer allocated by png_malloc(). In the default
273 * configuration, png_ptr is not used, but is passed in case it
274 * is needed. If ptr is NULL, return without taking any action.
277 png_free(png_structp png_ptr
, png_voidp ptr
)
279 if (png_ptr
== NULL
|| ptr
== NULL
)
282 #ifdef PNG_USER_MEM_SUPPORTED
283 if (png_ptr
->free_fn
!= NULL
)
285 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
289 png_free_default(png_ptr
, ptr
);
293 png_free_default(png_structp png_ptr
, png_voidp ptr
)
295 #endif /* PNG_USER_MEM_SUPPORTED */
297 if (png_ptr
== NULL
|| ptr
== NULL
)
300 if (png_ptr
->offset_table
!= NULL
)
304 for (i
= 0; i
< png_ptr
->offset_table_count
; i
++)
306 if (ptr
== png_ptr
->offset_table_ptr
[i
])
309 png_ptr
->offset_table_count_free
++;
313 if (png_ptr
->offset_table_count_free
== png_ptr
->offset_table_count
)
315 farfree(png_ptr
->offset_table
);
316 farfree(png_ptr
->offset_table_ptr
);
317 png_ptr
->offset_table
= NULL
;
318 png_ptr
->offset_table_ptr
= NULL
;
328 #else /* Not the Borland DOS special memory handler */
330 /* Allocate memory for a png_struct or a png_info. The malloc and
331 memset can be replaced by a single call to calloc() if this is thought
332 to improve performance noticably. */
333 png_voidp
/* PRIVATE */
334 png_create_struct(int type
)
336 #ifdef PNG_USER_MEM_SUPPORTED
337 return (png_create_struct_2(type
, png_malloc_ptr_NULL
, png_voidp_NULL
));
340 /* Allocate memory for a png_struct or a png_info. The malloc and
341 memset can be replaced by a single call to calloc() if this is thought
342 to improve performance noticably. */
343 png_voidp
/* PRIVATE */
344 png_create_struct_2(int type
, png_malloc_ptr malloc_fn
, png_voidp mem_ptr
)
346 #endif /* PNG_USER_MEM_SUPPORTED */
348 png_voidp struct_ptr
;
350 if (type
== PNG_STRUCT_INFO
)
351 size
= png_sizeof(png_info
);
352 else if (type
== PNG_STRUCT_PNG
)
353 size
= png_sizeof(png_struct
);
357 #ifdef PNG_USER_MEM_SUPPORTED
358 if (malloc_fn
!= NULL
)
360 png_struct dummy_struct
;
361 png_structp png_ptr
= &dummy_struct
;
362 png_ptr
->mem_ptr
=mem_ptr
;
363 struct_ptr
= (*(malloc_fn
))(png_ptr
, size
);
364 if (struct_ptr
!= NULL
)
365 png_memset(struct_ptr
, 0, size
);
368 #endif /* PNG_USER_MEM_SUPPORTED */
370 #if defined(__TURBOC__) && !defined(__FLAT__)
371 struct_ptr
= (png_voidp
)farmalloc(size
);
373 # if defined(_MSC_VER) && defined(MAXSEG_64K)
374 struct_ptr
= (png_voidp
)halloc(size
, 1);
376 struct_ptr
= (png_voidp
)malloc(size
);
379 if (struct_ptr
!= NULL
)
380 png_memset(struct_ptr
, 0, size
);
386 /* Free memory allocated by a png_create_struct() call */
388 png_destroy_struct(png_voidp struct_ptr
)
390 #ifdef PNG_USER_MEM_SUPPORTED
391 png_destroy_struct_2(struct_ptr
, png_free_ptr_NULL
, png_voidp_NULL
);
394 /* Free memory allocated by a png_create_struct() call */
396 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
,
399 #endif /* PNG_USER_MEM_SUPPORTED */
400 if (struct_ptr
!= NULL
)
402 #ifdef PNG_USER_MEM_SUPPORTED
405 png_struct dummy_struct
;
406 png_structp png_ptr
= &dummy_struct
;
407 png_ptr
->mem_ptr
=mem_ptr
;
408 (*(free_fn
))(png_ptr
, struct_ptr
);
411 #endif /* PNG_USER_MEM_SUPPORTED */
412 #if defined(__TURBOC__) && !defined(__FLAT__)
415 # if defined(_MSC_VER) && defined(MAXSEG_64K)
424 /* Allocate memory. For reasonable files, size should never exceed
425 * 64K. However, zlib may allocate more then 64K if you don't tell
426 * it not to. See zconf.h and png.h for more information. zlib does
427 * need to allocate exactly 64K, so whatever you call here must
428 * have the ability to do that.
433 png_malloc(png_structp png_ptr
, png_uint_32 size
)
437 #ifdef PNG_USER_MEM_SUPPORTED
438 if (png_ptr
== NULL
|| size
== 0)
441 if (png_ptr
->malloc_fn
!= NULL
)
442 ret
= ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, (png_size_t
)size
));
444 ret
= (png_malloc_default(png_ptr
, size
));
445 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
446 png_error(png_ptr
, "Out of Memory!");
451 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
454 #endif /* PNG_USER_MEM_SUPPORTED */
456 if (png_ptr
== NULL
|| size
== 0)
459 #ifdef PNG_MAX_MALLOC_64K
460 if (size
> (png_uint_32
)65536L)
462 #ifndef PNG_USER_MEM_SUPPORTED
463 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
464 png_error(png_ptr
, "Cannot Allocate > 64K");
471 /* Check for overflow */
472 #if defined(__TURBOC__) && !defined(__FLAT__)
473 if (size
!= (unsigned long)size
)
476 ret
= farmalloc(size
);
478 # if defined(_MSC_VER) && defined(MAXSEG_64K)
479 if (size
!= (unsigned long)size
)
482 ret
= halloc(size
, 1);
484 if (size
!= (size_t)size
)
487 ret
= malloc((size_t)size
);
491 #ifndef PNG_USER_MEM_SUPPORTED
492 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
493 png_error(png_ptr
, "Out of Memory");
499 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
500 * without taking any action.
503 png_free(png_structp png_ptr
, png_voidp ptr
)
505 if (png_ptr
== NULL
|| ptr
== NULL
)
508 #ifdef PNG_USER_MEM_SUPPORTED
509 if (png_ptr
->free_fn
!= NULL
)
511 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
515 png_free_default(png_ptr
, ptr
);
518 png_free_default(png_structp png_ptr
, png_voidp ptr
)
520 if (png_ptr
== NULL
|| ptr
== NULL
)
523 #endif /* PNG_USER_MEM_SUPPORTED */
525 #if defined(__TURBOC__) && !defined(__FLAT__)
528 # if defined(_MSC_VER) && defined(MAXSEG_64K)
536 #endif /* Not Borland DOS special memory handler */
538 #if defined(PNG_1_0_X)
539 # define png_malloc_warn png_malloc
541 /* This function was added at libpng version 1.2.3. The png_malloc_warn()
542 * function will set up png_malloc() to issue a png_warning and return NULL
543 * instead of issuing a png_error, if it fails to allocate the requested
547 png_malloc_warn(png_structp png_ptr
, png_uint_32 size
)
550 png_uint_32 save_flags
;
554 save_flags
= png_ptr
->flags
;
555 png_ptr
->flags
|=PNG_FLAG_MALLOC_NULL_MEM_OK
;
556 ptr
= (png_voidp
)png_malloc((png_structp
)png_ptr
, size
);
557 png_ptr
->flags
=save_flags
;
563 png_memcpy_check (png_structp png_ptr
, png_voidp s1
, png_voidp s2
,
568 size
= (png_size_t
)length
;
569 if ((png_uint_32
)size
!= length
)
570 png_error(png_ptr
, "Overflow in png_memcpy_check.");
572 return(png_memcpy (s1
, s2
, size
));
576 png_memset_check (png_structp png_ptr
, png_voidp s1
, int value
,
581 size
= (png_size_t
)length
;
582 if ((png_uint_32
)size
!= length
)
583 png_error(png_ptr
, "Overflow in png_memset_check.");
585 return (png_memset (s1
, value
, size
));
589 #ifdef PNG_USER_MEM_SUPPORTED
590 /* This function is called when the application wants to use another method
591 * of allocating and freeing memory.
594 png_set_mem_fn(png_structp png_ptr
, png_voidp mem_ptr
, png_malloc_ptr
595 malloc_fn
, png_free_ptr free_fn
)
599 png_ptr
->mem_ptr
= mem_ptr
;
600 png_ptr
->malloc_fn
= malloc_fn
;
601 png_ptr
->free_fn
= free_fn
;
605 /* This function returns a pointer to the mem_ptr associated with the user
606 * functions. The application should free any memory associated with this
607 * pointer before png_write_destroy and png_read_destroy are called.
610 png_get_mem_ptr(png_structp png_ptr
)
614 return ((png_voidp
)png_ptr
->mem_ptr
);
616 #endif /* PNG_USER_MEM_SUPPORTED */
617 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */