2 /* pngmem.c - stub functions for memory allocation
4 * libpng 1.2.4 - July 8, 2002
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2002 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
, png_malloc_ptr_NULL
, png_voidp_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_get_copyright());
48 #ifdef PNG_USER_MEM_SUPPORTED
51 png_struct dummy_struct
;
52 png_structp png_ptr
= &dummy_struct
;
53 png_ptr
->mem_ptr
=mem_ptr
;
54 struct_ptr
= (*(malloc_fn
))(png_ptr
, (png_uint_32
)size
);
57 #endif /* PNG_USER_MEM_SUPPORTED */
58 struct_ptr
= (png_voidp
)farmalloc(size
));
59 if (struct_ptr
!= NULL
)
60 png_memset(struct_ptr
, 0, size
);
64 /* Free memory allocated by a png_create_struct() call */
66 png_destroy_struct(png_voidp struct_ptr
)
68 #ifdef PNG_USER_MEM_SUPPORTED
69 png_destroy_struct_2(struct_ptr
, png_free_ptr_NULL
, png_voidp_NULL
);
72 /* Free memory allocated by a png_create_struct() call */
74 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
,
78 if (struct_ptr
!= NULL
)
80 #ifdef PNG_USER_MEM_SUPPORTED
83 png_struct dummy_struct
;
84 png_structp png_ptr
= &dummy_struct
;
85 png_ptr
->mem_ptr
=mem_ptr
;
86 (*(free_fn
))(png_ptr
, struct_ptr
);
89 #endif /* PNG_USER_MEM_SUPPORTED */
94 /* Allocate memory. For reasonable files, size should never exceed
95 * 64K. However, zlib may allocate more then 64K if you don't tell
96 * it not to. See zconf.h and png.h for more information. zlib does
97 * need to allocate exactly 64K, so whatever you call here must
98 * have the ability to do that.
100 * Borland seems to have a problem in DOS mode for exactly 64K.
101 * It gives you a segment with an offset of 8 (perhaps to store its
102 * memory stuff). zlib doesn't like this at all, so we have to
103 * detect and deal with it. This code should not be needed in
104 * Windows or OS/2 modes, and only in 16 bit mode. This code has
105 * been updated by Alexander Lehmann for version 0.89 to waste less
108 * Note that we can't use png_size_t for the "size" declaration,
109 * since on some systems a png_size_t is a 16-bit quantity, and as a
110 * result, we would be truncating potentially larger memory requests
111 * (which should cause a fatal error) and introducing major problems.
115 png_malloc(png_structp png_ptr
, png_uint_32 size
)
119 if (png_ptr
== NULL
|| size
== 0)
122 #ifdef PNG_USER_MEM_SUPPORTED
123 if(png_ptr
->malloc_fn
!= NULL
)
125 ret
= ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, (png_size_t
)size
));
126 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
127 png_error(png_ptr
, "Out of memory!");
131 return png_malloc_default(png_ptr
, size
);
135 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
138 #endif /* PNG_USER_MEM_SUPPORTED */
140 #ifdef PNG_MAX_MALLOC_64K
141 if (size
> (png_uint_32
)65536L)
142 png_error(png_ptr
, "Cannot Allocate > 64K");
145 if (size
== (png_uint_32
)65536L)
147 if (png_ptr
->offset_table
== NULL
)
149 /* try to see if we need to do any of this fancy stuff */
150 ret
= farmalloc(size
);
151 if (ret
== NULL
|| ((png_size_t
)ret
& 0xffff))
154 png_uint_32 total_size
;
157 png_byte huge
* hptr
;
165 if(png_ptr
->zlib_window_bits
> 14)
166 num_blocks
= (int)(1 << (png_ptr
->zlib_window_bits
- 14));
169 if (png_ptr
->zlib_mem_level
>= 7)
170 num_blocks
+= (int)(1 << (png_ptr
->zlib_mem_level
- 7));
174 total_size
= ((png_uint_32
)65536L) * (png_uint_32
)num_blocks
+16;
176 table
= farmalloc(total_size
);
180 if (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
181 png_error(png_ptr
, "Out Of Memory."); /* Note "O" and "M" */
183 png_warning(png_ptr
, "Out Of Memory.");
187 if ((png_size_t
)table
& 0xfff0)
189 if (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
191 "Farmalloc didn't return normalized pointer");
194 "Farmalloc didn't return normalized pointer");
198 png_ptr
->offset_table
= table
;
199 png_ptr
->offset_table_ptr
= farmalloc(num_blocks
*
202 if (png_ptr
->offset_table_ptr
== NULL
)
204 if (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
205 png_error(png_ptr
, "Out Of memory."); /* Note "O" and "M" */
207 png_warning(png_ptr
, "Out Of memory.");
211 hptr
= (png_byte huge
*)table
;
212 if ((png_size_t
)hptr
& 0xf)
214 hptr
= (png_byte huge
*)((long)(hptr
) & 0xfffffff0L
);
215 hptr
= hptr
+ 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
217 for (i
= 0; i
< num_blocks
; i
++)
219 png_ptr
->offset_table_ptr
[i
] = (png_bytep
)hptr
;
220 hptr
= hptr
+ (png_uint_32
)65536L; /* "+=" fails on TC++3.0 */
223 png_ptr
->offset_table_number
= num_blocks
;
224 png_ptr
->offset_table_count
= 0;
225 png_ptr
->offset_table_count_free
= 0;
229 if (png_ptr
->offset_table_count
>= png_ptr
->offset_table_number
)
231 if (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
232 png_error(png_ptr
, "Out of Memory."); /* Note "o" and "M" */
234 png_warning(png_ptr
, "Out of Memory.");
238 ret
= png_ptr
->offset_table_ptr
[png_ptr
->offset_table_count
++];
241 ret
= farmalloc(size
);
245 if (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
246 png_error(png_ptr
, "Out of memory."); /* Note "o" and "m" */
248 png_warning(png_ptr
, "Out of memory."); /* Note "o" and "m" */
254 /* free a pointer allocated by png_malloc(). In the default
255 configuration, png_ptr is not used, but is passed in case it
256 is needed. If ptr is NULL, return without taking any action. */
258 png_free(png_structp png_ptr
, png_voidp ptr
)
260 if (png_ptr
== NULL
|| ptr
== NULL
)
263 #ifdef PNG_USER_MEM_SUPPORTED
264 if (png_ptr
->free_fn
!= NULL
)
266 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
269 else png_free_default(png_ptr
, ptr
);
273 png_free_default(png_structp png_ptr
, png_voidp ptr
)
275 #endif /* PNG_USER_MEM_SUPPORTED */
277 if (png_ptr
->offset_table
!= NULL
)
281 for (i
= 0; i
< png_ptr
->offset_table_count
; i
++)
283 if (ptr
== png_ptr
->offset_table_ptr
[i
])
286 png_ptr
->offset_table_count_free
++;
290 if (png_ptr
->offset_table_count_free
== png_ptr
->offset_table_count
)
292 farfree(png_ptr
->offset_table
);
293 farfree(png_ptr
->offset_table_ptr
);
294 png_ptr
->offset_table
= NULL
;
295 png_ptr
->offset_table_ptr
= NULL
;
305 #else /* Not the Borland DOS special memory handler */
307 /* Allocate memory for a png_struct or a png_info. The malloc and
308 memset can be replaced by a single call to calloc() if this is thought
309 to improve performance noticably. */
310 png_voidp
/* PRIVATE */
311 png_create_struct(int type
)
313 #ifdef PNG_USER_MEM_SUPPORTED
314 return (png_create_struct_2(type
, png_malloc_ptr_NULL
, png_voidp_NULL
));
317 /* Allocate memory for a png_struct or a png_info. The malloc and
318 memset can be replaced by a single call to calloc() if this is thought
319 to improve performance noticably. */
320 png_voidp
/* PRIVATE */
321 png_create_struct_2(int type
, png_malloc_ptr malloc_fn
, png_voidp mem_ptr
)
323 #endif /* PNG_USER_MEM_SUPPORTED */
325 png_voidp struct_ptr
;
327 if (type
== PNG_STRUCT_INFO
)
328 size
= sizeof(png_info
);
329 else if (type
== PNG_STRUCT_PNG
)
330 size
= sizeof(png_struct
);
334 #ifdef PNG_USER_MEM_SUPPORTED
335 if(malloc_fn
!= NULL
)
337 png_struct dummy_struct
;
338 png_structp png_ptr
= &dummy_struct
;
339 png_ptr
->mem_ptr
=mem_ptr
;
340 struct_ptr
= (*(malloc_fn
))(png_ptr
, size
);
341 if (struct_ptr
!= NULL
)
342 png_memset(struct_ptr
, 0, size
);
345 #endif /* PNG_USER_MEM_SUPPORTED */
347 #if defined(__TURBOC__) && !defined(__FLAT__)
348 if ((struct_ptr
= (png_voidp
)farmalloc(size
)) != NULL
)
350 # if defined(_MSC_VER) && defined(MAXSEG_64K)
351 if ((struct_ptr
= (png_voidp
)halloc(size
,1)) != NULL
)
353 if ((struct_ptr
= (png_voidp
)malloc(size
)) != NULL
)
357 png_memset(struct_ptr
, 0, size
);
364 /* Free memory allocated by a png_create_struct() call */
366 png_destroy_struct(png_voidp struct_ptr
)
368 #ifdef PNG_USER_MEM_SUPPORTED
369 png_destroy_struct_2(struct_ptr
, png_free_ptr_NULL
, png_voidp_NULL
);
372 /* Free memory allocated by a png_create_struct() call */
374 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
,
377 #endif /* PNG_USER_MEM_SUPPORTED */
378 if (struct_ptr
!= NULL
)
380 #ifdef PNG_USER_MEM_SUPPORTED
383 png_struct dummy_struct
;
384 png_structp png_ptr
= &dummy_struct
;
385 png_ptr
->mem_ptr
=mem_ptr
;
386 (*(free_fn
))(png_ptr
, struct_ptr
);
389 #endif /* PNG_USER_MEM_SUPPORTED */
390 #if defined(__TURBOC__) && !defined(__FLAT__)
393 # if defined(_MSC_VER) && defined(MAXSEG_64K)
402 /* Allocate memory. For reasonable files, size should never exceed
403 64K. However, zlib may allocate more then 64K if you don't tell
404 it not to. See zconf.h and png.h for more information. zlib does
405 need to allocate exactly 64K, so whatever you call here must
406 have the ability to do that. */
409 png_malloc(png_structp png_ptr
, png_uint_32 size
)
413 if (png_ptr
== NULL
|| size
== 0)
416 #ifdef PNG_USER_MEM_SUPPORTED
417 if(png_ptr
->malloc_fn
!= NULL
)
419 ret
= ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, (png_size_t
)size
));
420 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
421 png_error(png_ptr
, "Out of Memory!");
425 return (png_malloc_default(png_ptr
, size
));
429 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
432 #endif /* PNG_USER_MEM_SUPPORTED */
434 #ifdef PNG_MAX_MALLOC_64K
435 if (size
> (png_uint_32
)65536L)
437 if(png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
438 png_error(png_ptr
, "Cannot Allocate > 64K");
444 #if defined(__TURBOC__) && !defined(__FLAT__)
445 ret
= farmalloc(size
);
447 # if defined(_MSC_VER) && defined(MAXSEG_64K)
448 ret
= halloc(size
, 1);
450 ret
= malloc((size_t)size
);
454 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
455 png_error(png_ptr
, "Out of Memory");
460 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
461 without taking any action. */
463 png_free(png_structp png_ptr
, png_voidp ptr
)
465 if (png_ptr
== NULL
|| ptr
== NULL
)
468 #ifdef PNG_USER_MEM_SUPPORTED
469 if (png_ptr
->free_fn
!= NULL
)
471 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
474 else png_free_default(png_ptr
, ptr
);
477 png_free_default(png_structp png_ptr
, png_voidp ptr
)
479 if (png_ptr
== NULL
|| ptr
== NULL
)
482 #endif /* PNG_USER_MEM_SUPPORTED */
484 #if defined(__TURBOC__) && !defined(__FLAT__)
487 # if defined(_MSC_VER) && defined(MAXSEG_64K)
495 #endif /* Not Borland DOS special memory handler */
497 #if defined(PNG_1_0_X)
498 # define png_malloc_warn png_malloc
500 /* This function was added at libpng version 1.2.3. The png_malloc_warn()
501 * function will issue a png_warning and return NULL instead of issuing a
502 * png_error, if it fails to allocate the requested memory.
505 png_malloc_warn(png_structp png_ptr
, png_uint_32 size
)
508 png_uint_32 save_flags
=png_ptr
->flags
;
510 png_ptr
->flags
|=PNG_FLAG_MALLOC_NULL_MEM_OK
;
511 ptr
= (png_voidp
)png_malloc((png_structp
)png_ptr
, size
);
512 png_ptr
->flags
=save_flags
;
518 png_memcpy_check (png_structp png_ptr
, png_voidp s1
, png_voidp s2
,
523 size
= (png_size_t
)length
;
524 if ((png_uint_32
)size
!= length
)
525 png_error(png_ptr
,"Overflow in png_memcpy_check.");
527 return(png_memcpy (s1
, s2
, size
));
531 png_memset_check (png_structp png_ptr
, png_voidp s1
, int value
,
536 size
= (png_size_t
)length
;
537 if ((png_uint_32
)size
!= length
)
538 png_error(png_ptr
,"Overflow in png_memset_check.");
540 return (png_memset (s1
, value
, size
));
544 #ifdef PNG_USER_MEM_SUPPORTED
545 /* This function is called when the application wants to use another method
546 * of allocating and freeing memory.
549 png_set_mem_fn(png_structp png_ptr
, png_voidp mem_ptr
, png_malloc_ptr
550 malloc_fn
, png_free_ptr free_fn
)
552 png_ptr
->mem_ptr
= mem_ptr
;
553 png_ptr
->malloc_fn
= malloc_fn
;
554 png_ptr
->free_fn
= free_fn
;
557 /* This function returns a pointer to the mem_ptr associated with the user
558 * functions. The application should free any memory associated with this
559 * pointer before png_write_destroy and png_read_destroy are called.
562 png_get_mem_ptr(png_structp png_ptr
)
564 return ((png_voidp
)png_ptr
->mem_ptr
);
566 #endif /* PNG_USER_MEM_SUPPORTED */