2 /* pngmem.c - stub functions for memory allocation
4 * libpng version 1.2.7 - September 12, 2004
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2004 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
= png_sizeof(png_info
);
43 else if (type
== PNG_STRUCT_PNG
)
44 size
= png_sizeof(png_struct
);
46 return (png_get_copyright(NULL
));
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
)
124 ret
= ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, (png_size_t
)size
));
126 ret
= (png_malloc_default(png_ptr
, size
));
127 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
128 png_error(png_ptr
, "Out of memory!");
133 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
136 #endif /* PNG_USER_MEM_SUPPORTED */
138 #ifdef PNG_MAX_MALLOC_64K
139 if (size
> (png_uint_32
)65536L)
141 png_warning(png_ptr
, "Cannot Allocate > 64K");
147 if (size
!= (size_t)size
)
149 else if (size
== (png_uint_32
)65536L)
151 if (png_ptr
->offset_table
== NULL
)
153 /* try to see if we need to do any of this fancy stuff */
154 ret
= farmalloc(size
);
155 if (ret
== NULL
|| ((png_size_t
)ret
& 0xffff))
158 png_uint_32 total_size
;
161 png_byte huge
* hptr
;
169 if(png_ptr
->zlib_window_bits
> 14)
170 num_blocks
= (int)(1 << (png_ptr
->zlib_window_bits
- 14));
173 if (png_ptr
->zlib_mem_level
>= 7)
174 num_blocks
+= (int)(1 << (png_ptr
->zlib_mem_level
- 7));
178 total_size
= ((png_uint_32
)65536L) * (png_uint_32
)num_blocks
+16;
180 table
= farmalloc(total_size
);
184 #ifndef PNG_USER_MEM_SUPPORTED
185 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
186 png_error(png_ptr
, "Out Of Memory."); /* Note "O" and "M" */
188 png_warning(png_ptr
, "Out Of Memory.");
193 if ((png_size_t
)table
& 0xfff0)
195 #ifndef PNG_USER_MEM_SUPPORTED
196 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
198 "Farmalloc didn't return normalized pointer");
201 "Farmalloc didn't return normalized pointer");
206 png_ptr
->offset_table
= table
;
207 png_ptr
->offset_table_ptr
= farmalloc(num_blocks
*
208 png_sizeof (png_bytep
));
210 if (png_ptr
->offset_table_ptr
== NULL
)
212 #ifndef PNG_USER_MEM_SUPPORTED
213 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
214 png_error(png_ptr
, "Out Of memory."); /* Note "O" and "M" */
216 png_warning(png_ptr
, "Out Of memory.");
221 hptr
= (png_byte huge
*)table
;
222 if ((png_size_t
)hptr
& 0xf)
224 hptr
= (png_byte huge
*)((long)(hptr
) & 0xfffffff0L
);
225 hptr
= hptr
+ 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
227 for (i
= 0; i
< num_blocks
; i
++)
229 png_ptr
->offset_table_ptr
[i
] = (png_bytep
)hptr
;
230 hptr
= hptr
+ (png_uint_32
)65536L; /* "+=" fails on TC++3.0 */
233 png_ptr
->offset_table_number
= num_blocks
;
234 png_ptr
->offset_table_count
= 0;
235 png_ptr
->offset_table_count_free
= 0;
239 if (png_ptr
->offset_table_count
>= png_ptr
->offset_table_number
)
241 #ifndef PNG_USER_MEM_SUPPORTED
242 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
243 png_error(png_ptr
, "Out of Memory."); /* Note "o" and "M" */
245 png_warning(png_ptr
, "Out of Memory.");
250 ret
= png_ptr
->offset_table_ptr
[png_ptr
->offset_table_count
++];
253 ret
= farmalloc(size
);
255 #ifndef PNG_USER_MEM_SUPPORTED
258 if ((png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
259 png_error(png_ptr
, "Out of memory."); /* Note "o" and "m" */
261 png_warning(png_ptr
, "Out of memory."); /* Note "o" and "m" */
268 /* free a pointer allocated by png_malloc(). In the default
269 configuration, png_ptr is not used, but is passed in case it
270 is needed. If ptr is NULL, return without taking any action. */
272 png_free(png_structp png_ptr
, png_voidp ptr
)
274 if (png_ptr
== NULL
|| ptr
== NULL
)
277 #ifdef PNG_USER_MEM_SUPPORTED
278 if (png_ptr
->free_fn
!= NULL
)
280 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
283 else png_free_default(png_ptr
, ptr
);
287 png_free_default(png_structp png_ptr
, png_voidp ptr
)
289 #endif /* PNG_USER_MEM_SUPPORTED */
291 if (png_ptr
->offset_table
!= NULL
)
295 for (i
= 0; i
< png_ptr
->offset_table_count
; i
++)
297 if (ptr
== png_ptr
->offset_table_ptr
[i
])
300 png_ptr
->offset_table_count_free
++;
304 if (png_ptr
->offset_table_count_free
== png_ptr
->offset_table_count
)
306 farfree(png_ptr
->offset_table
);
307 farfree(png_ptr
->offset_table_ptr
);
308 png_ptr
->offset_table
= NULL
;
309 png_ptr
->offset_table_ptr
= NULL
;
319 #else /* Not the Borland DOS special memory handler */
321 /* Allocate memory for a png_struct or a png_info. The malloc and
322 memset can be replaced by a single call to calloc() if this is thought
323 to improve performance noticably. */
324 png_voidp
/* PRIVATE */
325 png_create_struct(int type
)
327 #ifdef PNG_USER_MEM_SUPPORTED
328 return (png_create_struct_2(type
, png_malloc_ptr_NULL
, png_voidp_NULL
));
331 /* Allocate memory for a png_struct or a png_info. The malloc and
332 memset can be replaced by a single call to calloc() if this is thought
333 to improve performance noticably. */
334 png_voidp
/* PRIVATE */
335 png_create_struct_2(int type
, png_malloc_ptr malloc_fn
, png_voidp mem_ptr
)
337 #endif /* PNG_USER_MEM_SUPPORTED */
339 png_voidp struct_ptr
;
341 if (type
== PNG_STRUCT_INFO
)
342 size
= png_sizeof(png_info
);
343 else if (type
== PNG_STRUCT_PNG
)
344 size
= png_sizeof(png_struct
);
348 #ifdef PNG_USER_MEM_SUPPORTED
349 if(malloc_fn
!= NULL
)
351 png_struct dummy_struct
;
352 png_structp png_ptr
= &dummy_struct
;
353 png_ptr
->mem_ptr
=mem_ptr
;
354 struct_ptr
= (*(malloc_fn
))(png_ptr
, size
);
355 if (struct_ptr
!= NULL
)
356 png_memset(struct_ptr
, 0, size
);
359 #endif /* PNG_USER_MEM_SUPPORTED */
361 #if defined(__TURBOC__) && !defined(__FLAT__)
362 struct_ptr
= (png_voidp
)farmalloc(size
);
364 # if defined(_MSC_VER) && defined(MAXSEG_64K)
365 struct_ptr
= (png_voidp
)halloc(size
,1);
367 struct_ptr
= (png_voidp
)malloc(size
);
370 if (struct_ptr
!= NULL
)
371 png_memset(struct_ptr
, 0, size
);
377 /* Free memory allocated by a png_create_struct() call */
379 png_destroy_struct(png_voidp struct_ptr
)
381 #ifdef PNG_USER_MEM_SUPPORTED
382 png_destroy_struct_2(struct_ptr
, png_free_ptr_NULL
, png_voidp_NULL
);
385 /* Free memory allocated by a png_create_struct() call */
387 png_destroy_struct_2(png_voidp struct_ptr
, png_free_ptr free_fn
,
390 #endif /* PNG_USER_MEM_SUPPORTED */
391 if (struct_ptr
!= NULL
)
393 #ifdef PNG_USER_MEM_SUPPORTED
396 png_struct dummy_struct
;
397 png_structp png_ptr
= &dummy_struct
;
398 png_ptr
->mem_ptr
=mem_ptr
;
399 (*(free_fn
))(png_ptr
, struct_ptr
);
402 #endif /* PNG_USER_MEM_SUPPORTED */
403 #if defined(__TURBOC__) && !defined(__FLAT__)
406 # if defined(_MSC_VER) && defined(MAXSEG_64K)
415 /* Allocate memory. For reasonable files, size should never exceed
416 64K. However, zlib may allocate more then 64K if you don't tell
417 it not to. See zconf.h and png.h for more information. zlib does
418 need to allocate exactly 64K, so whatever you call here must
419 have the ability to do that. */
422 png_malloc(png_structp png_ptr
, png_uint_32 size
)
426 #ifdef PNG_USER_MEM_SUPPORTED
427 if (png_ptr
== NULL
|| size
== 0)
430 if(png_ptr
->malloc_fn
!= NULL
)
431 ret
= ((png_voidp
)(*(png_ptr
->malloc_fn
))(png_ptr
, (png_size_t
)size
));
433 ret
= (png_malloc_default(png_ptr
, size
));
434 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
435 png_error(png_ptr
, "Out of Memory!");
440 png_malloc_default(png_structp png_ptr
, png_uint_32 size
)
443 #endif /* PNG_USER_MEM_SUPPORTED */
445 if (png_ptr
== NULL
|| size
== 0)
448 #ifdef PNG_MAX_MALLOC_64K
449 if (size
> (png_uint_32
)65536L)
451 #ifndef PNG_USER_MEM_SUPPORTED
452 if(png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
453 png_error(png_ptr
, "Cannot Allocate > 64K");
460 /* Check for overflow */
461 #if defined(__TURBOC__) && !defined(__FLAT__)
462 if (size
!= (unsigned long)size
)
465 ret
= farmalloc(size
);
467 # if defined(_MSC_VER) && defined(MAXSEG_64K)
468 if (size
!= (unsigned long)size
)
471 ret
= halloc(size
, 1);
473 if (size
!= (size_t)size
)
476 ret
= malloc((size_t)size
);
480 #ifndef PNG_USER_MEM_SUPPORTED
481 if (ret
== NULL
&& (png_ptr
->flags
&PNG_FLAG_MALLOC_NULL_MEM_OK
) == 0)
482 png_error(png_ptr
, "Out of Memory");
488 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
489 without taking any action. */
491 png_free(png_structp png_ptr
, png_voidp ptr
)
493 if (png_ptr
== NULL
|| ptr
== NULL
)
496 #ifdef PNG_USER_MEM_SUPPORTED
497 if (png_ptr
->free_fn
!= NULL
)
499 (*(png_ptr
->free_fn
))(png_ptr
, ptr
);
502 else png_free_default(png_ptr
, ptr
);
505 png_free_default(png_structp png_ptr
, png_voidp ptr
)
507 if (png_ptr
== NULL
|| ptr
== NULL
)
510 #endif /* PNG_USER_MEM_SUPPORTED */
512 #if defined(__TURBOC__) && !defined(__FLAT__)
515 # if defined(_MSC_VER) && defined(MAXSEG_64K)
523 #endif /* Not Borland DOS special memory handler */
525 #if defined(PNG_1_0_X)
526 # define png_malloc_warn png_malloc
528 /* This function was added at libpng version 1.2.3. The png_malloc_warn()
529 * function will set up png_malloc() to issue a png_warning and return NULL
530 * instead of issuing a png_error, if it fails to allocate the requested
534 png_malloc_warn(png_structp png_ptr
, png_uint_32 size
)
537 png_uint_32 save_flags
=png_ptr
->flags
;
539 png_ptr
->flags
|=PNG_FLAG_MALLOC_NULL_MEM_OK
;
540 ptr
= (png_voidp
)png_malloc((png_structp
)png_ptr
, size
);
541 png_ptr
->flags
=save_flags
;
547 png_memcpy_check (png_structp png_ptr
, png_voidp s1
, png_voidp s2
,
552 size
= (png_size_t
)length
;
553 if ((png_uint_32
)size
!= length
)
554 png_error(png_ptr
,"Overflow in png_memcpy_check.");
556 return(png_memcpy (s1
, s2
, size
));
560 png_memset_check (png_structp png_ptr
, png_voidp s1
, int value
,
565 size
= (png_size_t
)length
;
566 if ((png_uint_32
)size
!= length
)
567 png_error(png_ptr
,"Overflow in png_memset_check.");
569 return (png_memset (s1
, value
, size
));
573 #ifdef PNG_USER_MEM_SUPPORTED
574 /* This function is called when the application wants to use another method
575 * of allocating and freeing memory.
578 png_set_mem_fn(png_structp png_ptr
, png_voidp mem_ptr
, png_malloc_ptr
579 malloc_fn
, png_free_ptr free_fn
)
581 png_ptr
->mem_ptr
= mem_ptr
;
582 png_ptr
->malloc_fn
= malloc_fn
;
583 png_ptr
->free_fn
= free_fn
;
586 /* This function returns a pointer to the mem_ptr associated with the user
587 * functions. The application should free any memory associated with this
588 * pointer before png_write_destroy and png_read_destroy are called.
591 png_get_mem_ptr(png_structp png_ptr
)
593 return ((png_voidp
)png_ptr
->mem_ptr
);
595 #endif /* PNG_USER_MEM_SUPPORTED */