2 /* pngmem.c - stub functions for memory allocation
4 * libpng 1.0.3 - January 14, 1999
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
8 * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
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. */
27 png_create_struct(int type
)
29 #ifdef PNG_USER_MEM_SUPPORTED
30 return (png_create_struct_2(type
, NULL
));
33 /* Alternate version of png_create_struct, for use with user-defined malloc. */
35 png_create_struct_2(int type
, png_malloc_ptr malloc_fn
)
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
51 if ((struct_ptr
= (*(malloc_fn
))(NULL
, size
)) != NULL
)
52 png_memset(struct_ptr
, 0, size
);
55 #endif /* PNG_USER_MEM_SUPPORTED */
56 if ((struct_ptr
= (png_voidp
)farmalloc(size
)) != NULL
)
58 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
);
72 /* Free memory allocated by a png_create_struct() call */
74 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
)
77 if (struct_ptr
!= NULL
)
79 #ifdef PNG_USER_MEM_SUPPORTED
82 png_struct dummy_struct
;
83 png_structp png_ptr
= &dummy_struct
;
84 (*(free_fn
))(png_ptr
, struct_ptr
);
88 #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.
114 png_malloc(png_structp png_ptr
, png_uint_32 size
)
116 #ifndef PNG_USER_MEM_SUPPORTED
119 if (png_ptr
== NULL
|| size
== 0)
120 return ((png_voidp
)NULL
);
122 #ifdef PNG_USER_MEM_SUPPORTED
123 if(png_ptr
->malloc_fn
!= NULL
)
124 return ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, size
));
126 return png_malloc_default(png_ptr
, size
);
130 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
133 #endif /* PNG_USER_MEM_SUPPORTED */
135 #ifdef PNG_MAX_MALLOC_64K
136 if (size
> (png_uint_32
)65536L)
137 png_error(png_ptr
, "Cannot Allocate > 64K");
140 if (size
== (png_uint_32
)65536L)
142 if (png_ptr
->offset_table
== NULL
)
144 /* try to see if we need to do any of this fancy stuff */
145 ret
= farmalloc(size
);
146 if (ret
== NULL
|| ((png_size_t
)ret
& 0xffff))
149 png_uint_32 total_size
;
152 png_byte huge
* hptr
;
160 num_blocks
= (int)(1 << (png_ptr
->zlib_window_bits
- 14));
163 if (png_ptr
->zlib_mem_level
>= 7)
164 num_blocks
+= (int)(1 << (png_ptr
->zlib_mem_level
- 7));
168 total_size
= ((png_uint_32
)65536L) * (png_uint_32
)num_blocks
+16;
170 table
= farmalloc(total_size
);
174 png_error(png_ptr
, "Out Of Memory."); /* Note "O" and "M" */
177 if ((png_size_t
)table
& 0xfff0)
179 png_error(png_ptr
, "Farmalloc didn't return normalized pointer");
182 png_ptr
->offset_table
= table
;
183 png_ptr
->offset_table_ptr
= farmalloc(num_blocks
*
186 if (png_ptr
->offset_table_ptr
== NULL
)
188 png_error(png_ptr
, "Out Of memory.");
191 hptr
= (png_byte huge
*)table
;
192 if ((png_size_t
)hptr
& 0xf)
194 hptr
= (png_byte huge
*)((long)(hptr
) & 0xfffffff0L
);
197 for (i
= 0; i
< num_blocks
; i
++)
199 png_ptr
->offset_table_ptr
[i
] = (png_bytep
)hptr
;
200 hptr
+= (png_uint_32
)65536L;
203 png_ptr
->offset_table_number
= num_blocks
;
204 png_ptr
->offset_table_count
= 0;
205 png_ptr
->offset_table_count_free
= 0;
209 if (png_ptr
->offset_table_count
>= png_ptr
->offset_table_number
)
210 png_error(png_ptr
, "Out of Memory.");
212 ret
= png_ptr
->offset_table_ptr
[png_ptr
->offset_table_count
++];
215 ret
= farmalloc(size
);
219 png_error(png_ptr
, "Out of memory."); /* Note "o" and "m" */
225 /* free a pointer allocated by png_malloc(). In the default
226 configuration, png_ptr is not used, but is passed in case it
227 is needed. If ptr is NULL, return without taking any action. */
229 png_free(png_structp png_ptr
, png_voidp ptr
)
231 if (png_ptr
== NULL
|| ptr
== NULL
)
234 #ifdef PNG_USER_MEM_SUPPORTED
235 if (png_ptr
->free_fn
!= NULL
)
237 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
241 else png_free_default(png_ptr
, ptr
);
245 png_free_default(png_structp png_ptr
, png_voidp ptr
)
247 #endif /* PNG_USER_MEM_SUPPORTED */
249 if (png_ptr
->offset_table
!= NULL
)
253 for (i
= 0; i
< png_ptr
->offset_table_count
; i
++)
255 if (ptr
== png_ptr
->offset_table_ptr
[i
])
258 png_ptr
->offset_table_count_free
++;
262 if (png_ptr
->offset_table_count_free
== png_ptr
->offset_table_count
)
264 farfree(png_ptr
->offset_table
);
265 farfree(png_ptr
->offset_table_ptr
);
266 png_ptr
->offset_table
= NULL
;
267 png_ptr
->offset_table_ptr
= NULL
;
278 #else /* Not the Borland DOS special memory handler */
280 /* Allocate memory for a png_struct or a png_info. The malloc and
281 memset can be replaced by a single call to calloc() if this is thought
282 to improve performance noticably.*/
284 png_create_struct(int type
)
286 #ifdef PNG_USER_MEM_SUPPORTED
287 return (png_create_struct_2(type
, NULL
));
290 /* Allocate memory for a png_struct or a png_info. The malloc and
291 memset can be replaced by a single call to calloc() if this is thought
292 to improve performance noticably.*/
294 png_create_struct_2(int type
, png_malloc_ptr malloc_fn
)
296 #endif /* PNG_USER_MEM_SUPPORTED */
298 png_voidp struct_ptr
;
300 if (type
== PNG_STRUCT_INFO
)
301 size
= sizeof(png_info
);
302 else if (type
== PNG_STRUCT_PNG
)
303 size
= sizeof(png_struct
);
305 return ((png_voidp
)NULL
);
307 #ifdef PNG_USER_MEM_SUPPORTED
308 if(malloc_fn
!= NULL
)
310 if ((struct_ptr
= (*(malloc_fn
))(NULL
, size
)) != NULL
)
311 png_memset(struct_ptr
, 0, size
);
314 #endif /* PNG_USER_MEM_SUPPORTED */
316 #if defined(__TURBOC__) && !defined(__FLAT__)
317 if ((struct_ptr
= (png_voidp
)farmalloc(size
)) != NULL
)
319 # if defined(_MSC_VER) && defined(MAXSEG_64K)
320 if ((struct_ptr
= (png_voidp
)halloc(size
,1)) != NULL
)
322 if ((struct_ptr
= (png_voidp
)malloc(size
)) != NULL
)
326 png_memset(struct_ptr
, 0, size
);
333 /* Free memory allocated by a png_create_struct() call */
335 png_destroy_struct(png_voidp struct_ptr
)
337 #ifdef PNG_USER_MEM_SUPPORTED
338 png_destroy_struct_2(struct_ptr
, (png_free_ptr
)NULL
);
341 /* Free memory allocated by a png_create_struct() call */
343 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
)
345 #endif /* PNG_USER_MEM_SUPPORTED */
346 if (struct_ptr
!= NULL
)
348 #ifdef PNG_USER_MEM_SUPPORTED
351 png_struct dummy_struct
;
352 png_structp png_ptr
= &dummy_struct
;
353 (*(free_fn
))(png_ptr
, struct_ptr
);
357 #endif /* PNG_USER_MEM_SUPPORTED */
358 #if defined(__TURBOC__) && !defined(__FLAT__)
362 # if defined(_MSC_VER) && defined(MAXSEG_64K)
374 /* Allocate memory. For reasonable files, size should never exceed
375 64K. However, zlib may allocate more then 64K if you don't tell
376 it not to. See zconf.h and png.h for more information. zlib does
377 need to allocate exactly 64K, so whatever you call here must
378 have the ability to do that. */
381 png_malloc(png_structp png_ptr
, png_uint_32 size
)
383 #ifndef PNG_USER_MEM_SUPPORTED
386 if (png_ptr
== NULL
|| size
== 0)
387 return ((png_voidp
)NULL
);
389 #ifdef PNG_USER_MEM_SUPPORTED
390 if(png_ptr
->malloc_fn
!= NULL
)
391 return ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, size
));
393 return (png_malloc_default(png_ptr
, size
));
396 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
399 #endif /* PNG_USER_MEM_SUPPORTED */
401 #ifdef PNG_MAX_MALLOC_64K
402 if (size
> (png_uint_32
)65536L)
403 png_error(png_ptr
, "Cannot Allocate > 64K");
406 #if defined(__TURBOC__) && !defined(__FLAT__)
407 ret
= farmalloc(size
);
409 # if defined(_MSC_VER) && defined(MAXSEG_64K)
410 ret
= halloc(size
, 1);
412 ret
= malloc((size_t)size
);
418 png_error(png_ptr
, "Out of Memory");
424 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
425 without taking any action. */
427 png_free(png_structp png_ptr
, png_voidp ptr
)
429 if (png_ptr
== NULL
|| ptr
== NULL
)
432 #ifdef PNG_USER_MEM_SUPPORTED
433 if (png_ptr
->free_fn
!= NULL
)
435 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
439 else png_free_default(png_ptr
, ptr
);
442 png_free_default(png_structp png_ptr
, png_voidp ptr
)
444 #endif /* PNG_USER_MEM_SUPPORTED */
446 #if defined(__TURBOC__) && !defined(__FLAT__)
450 # if defined(_MSC_VER) && defined(MAXSEG_64K)
460 #endif /* Not Borland DOS special memory handler */
463 png_memcpy_check (png_structp png_ptr
, png_voidp s1
, png_voidp s2
,
468 size
= (png_size_t
)length
;
469 if ((png_uint_32
)size
!= length
)
470 png_error(png_ptr
,"Overflow in png_memcpy_check.");
472 return(png_memcpy (s1
, s2
, size
));
476 png_memset_check (png_structp png_ptr
, png_voidp s1
, int value
,
481 size
= (png_size_t
)length
;
482 if ((png_uint_32
)size
!= length
)
483 png_error(png_ptr
,"Overflow in png_memset_check.");
485 return (png_memset (s1
, value
, size
));
489 #ifdef PNG_USER_MEM_SUPPORTED
490 /* This function is called when the application wants to use another method
491 * of allocating and freeing memory.
494 png_set_mem_fn(png_structp png_ptr
, png_voidp mem_ptr
, png_malloc_ptr
495 malloc_fn
, png_free_ptr free_fn
)
497 png_ptr
->mem_ptr
= mem_ptr
;
498 png_ptr
->malloc_fn
= malloc_fn
;
499 png_ptr
->free_fn
= free_fn
;
502 /* This function returns a pointer to the mem_ptr associated with the user
503 * functions. The application should free any memory associated with this
504 * pointer before png_write_destroy and png_read_destroy are called.
507 png_get_mem_ptr(png_structp png_ptr
)
509 return ((png_voidp
)png_ptr
->mem_ptr
);
511 #endif /* PNG_USER_MEM_SUPPORTED */