1*593dc095SDavid du Colombier
27dd7cddfSDavid du Colombier /* pngmem.c - stub functions for memory allocation
37dd7cddfSDavid du Colombier *
4*593dc095SDavid du Colombier * libpng version 1.2.8 - December 3, 2004
57dd7cddfSDavid du Colombier * For conditions of distribution and use, see copyright notice in png.h
6*593dc095SDavid du Colombier * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7*593dc095SDavid du Colombier * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8*593dc095SDavid du Colombier * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
97dd7cddfSDavid du Colombier *
10*593dc095SDavid du Colombier * This file provides a location for all memory allocation. Users who
11*593dc095SDavid du Colombier * need special memory handling are expected to supply replacement
12*593dc095SDavid du Colombier * functions for png_malloc() and png_free(), and to use
13*593dc095SDavid du Colombier * png_create_read_struct_2() and png_create_write_struct_2() to
14*593dc095SDavid du Colombier * identify the replacement functions.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier #define PNG_INTERNAL
187dd7cddfSDavid du Colombier #include "png.h"
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier /* Borland DOS special memory handler */
217dd7cddfSDavid du Colombier #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
227dd7cddfSDavid du Colombier /* if you change this, be sure to change the one in png.h also */
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier /* Allocate memory for a png_struct. The malloc and memset can be replaced
257dd7cddfSDavid du Colombier by a single call to calloc() if this is thought to improve performance. */
26*593dc095SDavid du Colombier png_voidp /* PRIVATE */
png_create_struct(int type)277dd7cddfSDavid du Colombier png_create_struct(int type)
287dd7cddfSDavid du Colombier {
29*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
30*593dc095SDavid du Colombier return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
31*593dc095SDavid du Colombier }
32*593dc095SDavid du Colombier
33*593dc095SDavid du Colombier /* Alternate version of png_create_struct, for use with user-defined malloc. */
34*593dc095SDavid du Colombier png_voidp /* PRIVATE */
png_create_struct_2(int type,png_malloc_ptr malloc_fn,png_voidp mem_ptr)35*593dc095SDavid du Colombier png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
36*593dc095SDavid du Colombier {
37*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
387dd7cddfSDavid du Colombier png_size_t size;
397dd7cddfSDavid du Colombier png_voidp struct_ptr;
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier if (type == PNG_STRUCT_INFO)
42*593dc095SDavid du Colombier size = png_sizeof(png_info);
437dd7cddfSDavid du Colombier else if (type == PNG_STRUCT_PNG)
44*593dc095SDavid du Colombier size = png_sizeof(png_struct);
457dd7cddfSDavid du Colombier else
46*593dc095SDavid du Colombier return (png_get_copyright(NULL));
477dd7cddfSDavid du Colombier
48*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
49*593dc095SDavid du Colombier if(malloc_fn != NULL)
507dd7cddfSDavid du Colombier {
51*593dc095SDavid du Colombier png_struct dummy_struct;
52*593dc095SDavid du Colombier png_structp png_ptr = &dummy_struct;
53*593dc095SDavid du Colombier png_ptr->mem_ptr=mem_ptr;
54*593dc095SDavid du Colombier struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
55*593dc095SDavid du Colombier }
56*593dc095SDavid du Colombier else
57*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
58*593dc095SDavid du Colombier struct_ptr = (png_voidp)farmalloc(size);
59*593dc095SDavid du Colombier if (struct_ptr != NULL)
607dd7cddfSDavid du Colombier png_memset(struct_ptr, 0, size);
61*593dc095SDavid du Colombier return (struct_ptr);
627dd7cddfSDavid du Colombier }
637dd7cddfSDavid du Colombier
647dd7cddfSDavid du Colombier /* Free memory allocated by a png_create_struct() call */
65*593dc095SDavid du Colombier void /* PRIVATE */
png_destroy_struct(png_voidp struct_ptr)667dd7cddfSDavid du Colombier png_destroy_struct(png_voidp struct_ptr)
677dd7cddfSDavid du Colombier {
68*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
69*593dc095SDavid du Colombier png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
70*593dc095SDavid du Colombier }
71*593dc095SDavid du Colombier
72*593dc095SDavid du Colombier /* Free memory allocated by a png_create_struct() call */
73*593dc095SDavid du Colombier void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr,png_free_ptr free_fn,png_voidp mem_ptr)74*593dc095SDavid du Colombier png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
75*593dc095SDavid du Colombier png_voidp mem_ptr)
76*593dc095SDavid du Colombier {
77*593dc095SDavid du Colombier #endif
787dd7cddfSDavid du Colombier if (struct_ptr != NULL)
797dd7cddfSDavid du Colombier {
80*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
81*593dc095SDavid du Colombier if(free_fn != NULL)
82*593dc095SDavid du Colombier {
83*593dc095SDavid du Colombier png_struct dummy_struct;
84*593dc095SDavid du Colombier png_structp png_ptr = &dummy_struct;
85*593dc095SDavid du Colombier png_ptr->mem_ptr=mem_ptr;
86*593dc095SDavid du Colombier (*(free_fn))(png_ptr, struct_ptr);
87*593dc095SDavid du Colombier return;
88*593dc095SDavid du Colombier }
89*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
907dd7cddfSDavid du Colombier farfree (struct_ptr);
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier }
937dd7cddfSDavid du Colombier
947dd7cddfSDavid du Colombier /* Allocate memory. For reasonable files, size should never exceed
957dd7cddfSDavid du Colombier * 64K. However, zlib may allocate more then 64K if you don't tell
967dd7cddfSDavid du Colombier * it not to. See zconf.h and png.h for more information. zlib does
977dd7cddfSDavid du Colombier * need to allocate exactly 64K, so whatever you call here must
987dd7cddfSDavid du Colombier * have the ability to do that.
997dd7cddfSDavid du Colombier *
1007dd7cddfSDavid du Colombier * Borland seems to have a problem in DOS mode for exactly 64K.
101*593dc095SDavid du Colombier * It gives you a segment with an offset of 8 (perhaps to store its
1027dd7cddfSDavid du Colombier * memory stuff). zlib doesn't like this at all, so we have to
1037dd7cddfSDavid du Colombier * detect and deal with it. This code should not be needed in
1047dd7cddfSDavid du Colombier * Windows or OS/2 modes, and only in 16 bit mode. This code has
1057dd7cddfSDavid du Colombier * been updated by Alexander Lehmann for version 0.89 to waste less
1067dd7cddfSDavid du Colombier * memory.
1077dd7cddfSDavid du Colombier *
1087dd7cddfSDavid du Colombier * Note that we can't use png_size_t for the "size" declaration,
1097dd7cddfSDavid du Colombier * since on some systems a png_size_t is a 16-bit quantity, and as a
1107dd7cddfSDavid du Colombier * result, we would be truncating potentially larger memory requests
1117dd7cddfSDavid du Colombier * (which should cause a fatal error) and introducing major problems.
1127dd7cddfSDavid du Colombier */
113*593dc095SDavid du Colombier
114*593dc095SDavid du Colombier png_voidp PNGAPI
png_malloc(png_structp png_ptr,png_uint_32 size)115*593dc095SDavid du Colombier png_malloc(png_structp png_ptr, png_uint_32 size)
1167dd7cddfSDavid du Colombier {
1177dd7cddfSDavid du Colombier png_voidp ret;
118*593dc095SDavid du Colombier
1197dd7cddfSDavid du Colombier if (png_ptr == NULL || size == 0)
120*593dc095SDavid du Colombier return (NULL);
121*593dc095SDavid du Colombier
122*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
123*593dc095SDavid du Colombier if(png_ptr->malloc_fn != NULL)
124*593dc095SDavid du Colombier ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
125*593dc095SDavid du Colombier else
126*593dc095SDavid du Colombier ret = (png_malloc_default(png_ptr, size));
127*593dc095SDavid du Colombier if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
128*593dc095SDavid du Colombier png_error(png_ptr, "Out of memory!");
129*593dc095SDavid du Colombier return (ret);
130*593dc095SDavid du Colombier }
131*593dc095SDavid du Colombier
132*593dc095SDavid du Colombier png_voidp PNGAPI
png_malloc_default(png_structp png_ptr,png_uint_32 size)133*593dc095SDavid du Colombier png_malloc_default(png_structp png_ptr, png_uint_32 size)
134*593dc095SDavid du Colombier {
135*593dc095SDavid du Colombier png_voidp ret;
136*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
1377dd7cddfSDavid du Colombier
1387dd7cddfSDavid du Colombier #ifdef PNG_MAX_MALLOC_64K
1397dd7cddfSDavid du Colombier if (size > (png_uint_32)65536L)
140*593dc095SDavid du Colombier {
141*593dc095SDavid du Colombier png_warning(png_ptr, "Cannot Allocate > 64K");
142*593dc095SDavid du Colombier ret = NULL;
143*593dc095SDavid du Colombier }
144*593dc095SDavid du Colombier else
1457dd7cddfSDavid du Colombier #endif
1467dd7cddfSDavid du Colombier
147*593dc095SDavid du Colombier if (size != (size_t)size)
148*593dc095SDavid du Colombier ret = NULL;
149*593dc095SDavid du Colombier else if (size == (png_uint_32)65536L)
1507dd7cddfSDavid du Colombier {
1517dd7cddfSDavid du Colombier if (png_ptr->offset_table == NULL)
1527dd7cddfSDavid du Colombier {
1537dd7cddfSDavid du Colombier /* try to see if we need to do any of this fancy stuff */
1547dd7cddfSDavid du Colombier ret = farmalloc(size);
1557dd7cddfSDavid du Colombier if (ret == NULL || ((png_size_t)ret & 0xffff))
1567dd7cddfSDavid du Colombier {
1577dd7cddfSDavid du Colombier int num_blocks;
1587dd7cddfSDavid du Colombier png_uint_32 total_size;
1597dd7cddfSDavid du Colombier png_bytep table;
1607dd7cddfSDavid du Colombier int i;
1617dd7cddfSDavid du Colombier png_byte huge * hptr;
1627dd7cddfSDavid du Colombier
1637dd7cddfSDavid du Colombier if (ret != NULL)
1647dd7cddfSDavid du Colombier {
1657dd7cddfSDavid du Colombier farfree(ret);
1667dd7cddfSDavid du Colombier ret = NULL;
1677dd7cddfSDavid du Colombier }
1687dd7cddfSDavid du Colombier
169*593dc095SDavid du Colombier if(png_ptr->zlib_window_bits > 14)
1707dd7cddfSDavid du Colombier num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
171*593dc095SDavid du Colombier else
1727dd7cddfSDavid du Colombier num_blocks = 1;
1737dd7cddfSDavid du Colombier if (png_ptr->zlib_mem_level >= 7)
1747dd7cddfSDavid du Colombier num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
1757dd7cddfSDavid du Colombier else
1767dd7cddfSDavid du Colombier num_blocks++;
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
1797dd7cddfSDavid du Colombier
1807dd7cddfSDavid du Colombier table = farmalloc(total_size);
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier if (table == NULL)
1837dd7cddfSDavid du Colombier {
184*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
185*593dc095SDavid du Colombier if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
1867dd7cddfSDavid du Colombier png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
187*593dc095SDavid du Colombier else
188*593dc095SDavid du Colombier png_warning(png_ptr, "Out Of Memory.");
189*593dc095SDavid du Colombier #endif
190*593dc095SDavid du Colombier return (NULL);
1917dd7cddfSDavid du Colombier }
1927dd7cddfSDavid du Colombier
1937dd7cddfSDavid du Colombier if ((png_size_t)table & 0xfff0)
1947dd7cddfSDavid du Colombier {
195*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
196*593dc095SDavid du Colombier if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
197*593dc095SDavid du Colombier png_error(png_ptr,
198*593dc095SDavid du Colombier "Farmalloc didn't return normalized pointer");
199*593dc095SDavid du Colombier else
200*593dc095SDavid du Colombier png_warning(png_ptr,
201*593dc095SDavid du Colombier "Farmalloc didn't return normalized pointer");
202*593dc095SDavid du Colombier #endif
203*593dc095SDavid du Colombier return (NULL);
2047dd7cddfSDavid du Colombier }
2057dd7cddfSDavid du Colombier
2067dd7cddfSDavid du Colombier png_ptr->offset_table = table;
2077dd7cddfSDavid du Colombier png_ptr->offset_table_ptr = farmalloc(num_blocks *
208*593dc095SDavid du Colombier png_sizeof (png_bytep));
2097dd7cddfSDavid du Colombier
2107dd7cddfSDavid du Colombier if (png_ptr->offset_table_ptr == NULL)
2117dd7cddfSDavid du Colombier {
212*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
213*593dc095SDavid du Colombier if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
214*593dc095SDavid du Colombier png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
215*593dc095SDavid du Colombier else
216*593dc095SDavid du Colombier png_warning(png_ptr, "Out Of memory.");
217*593dc095SDavid du Colombier #endif
218*593dc095SDavid du Colombier return (NULL);
2197dd7cddfSDavid du Colombier }
2207dd7cddfSDavid du Colombier
2217dd7cddfSDavid du Colombier hptr = (png_byte huge *)table;
2227dd7cddfSDavid du Colombier if ((png_size_t)hptr & 0xf)
2237dd7cddfSDavid du Colombier {
2247dd7cddfSDavid du Colombier hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
225*593dc095SDavid du Colombier hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier for (i = 0; i < num_blocks; i++)
2287dd7cddfSDavid du Colombier {
2297dd7cddfSDavid du Colombier png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
230*593dc095SDavid du Colombier hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier png_ptr->offset_table_number = num_blocks;
2347dd7cddfSDavid du Colombier png_ptr->offset_table_count = 0;
2357dd7cddfSDavid du Colombier png_ptr->offset_table_count_free = 0;
2367dd7cddfSDavid du Colombier }
2377dd7cddfSDavid du Colombier }
2387dd7cddfSDavid du Colombier
2397dd7cddfSDavid du Colombier if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
240*593dc095SDavid du Colombier {
241*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
242*593dc095SDavid du Colombier if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
243*593dc095SDavid du Colombier png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
244*593dc095SDavid du Colombier else
245*593dc095SDavid du Colombier png_warning(png_ptr, "Out of Memory.");
246*593dc095SDavid du Colombier #endif
247*593dc095SDavid du Colombier return (NULL);
248*593dc095SDavid du Colombier }
2497dd7cddfSDavid du Colombier
2507dd7cddfSDavid du Colombier ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
2517dd7cddfSDavid du Colombier }
2527dd7cddfSDavid du Colombier else
2537dd7cddfSDavid du Colombier ret = farmalloc(size);
2547dd7cddfSDavid du Colombier
255*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
2567dd7cddfSDavid du Colombier if (ret == NULL)
2577dd7cddfSDavid du Colombier {
258*593dc095SDavid du Colombier if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
2597dd7cddfSDavid du Colombier png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
260*593dc095SDavid du Colombier else
261*593dc095SDavid du Colombier png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
262*593dc095SDavid du Colombier }
263*593dc095SDavid du Colombier #endif
264*593dc095SDavid du Colombier
265*593dc095SDavid du Colombier return (ret);
2667dd7cddfSDavid du Colombier }
2677dd7cddfSDavid du Colombier
268*593dc095SDavid du Colombier /* free a pointer allocated by png_malloc(). In the default
2697dd7cddfSDavid du Colombier configuration, png_ptr is not used, but is passed in case it
2707dd7cddfSDavid du Colombier is needed. If ptr is NULL, return without taking any action. */
271*593dc095SDavid du Colombier void PNGAPI
png_free(png_structp png_ptr,png_voidp ptr)272*593dc095SDavid du Colombier png_free(png_structp png_ptr, png_voidp ptr)
2737dd7cddfSDavid du Colombier {
2747dd7cddfSDavid du Colombier if (png_ptr == NULL || ptr == NULL)
2757dd7cddfSDavid du Colombier return;
2767dd7cddfSDavid du Colombier
277*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
278*593dc095SDavid du Colombier if (png_ptr->free_fn != NULL)
279*593dc095SDavid du Colombier {
280*593dc095SDavid du Colombier (*(png_ptr->free_fn))(png_ptr, ptr);
281*593dc095SDavid du Colombier return;
282*593dc095SDavid du Colombier }
283*593dc095SDavid du Colombier else png_free_default(png_ptr, ptr);
284*593dc095SDavid du Colombier }
285*593dc095SDavid du Colombier
286*593dc095SDavid du Colombier void PNGAPI
png_free_default(png_structp png_ptr,png_voidp ptr)287*593dc095SDavid du Colombier png_free_default(png_structp png_ptr, png_voidp ptr)
288*593dc095SDavid du Colombier {
289*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
290*593dc095SDavid du Colombier
2917dd7cddfSDavid du Colombier if (png_ptr->offset_table != NULL)
2927dd7cddfSDavid du Colombier {
2937dd7cddfSDavid du Colombier int i;
2947dd7cddfSDavid du Colombier
2957dd7cddfSDavid du Colombier for (i = 0; i < png_ptr->offset_table_count; i++)
2967dd7cddfSDavid du Colombier {
2977dd7cddfSDavid du Colombier if (ptr == png_ptr->offset_table_ptr[i])
2987dd7cddfSDavid du Colombier {
2997dd7cddfSDavid du Colombier ptr = NULL;
3007dd7cddfSDavid du Colombier png_ptr->offset_table_count_free++;
3017dd7cddfSDavid du Colombier break;
3027dd7cddfSDavid du Colombier }
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
3057dd7cddfSDavid du Colombier {
3067dd7cddfSDavid du Colombier farfree(png_ptr->offset_table);
3077dd7cddfSDavid du Colombier farfree(png_ptr->offset_table_ptr);
3087dd7cddfSDavid du Colombier png_ptr->offset_table = NULL;
3097dd7cddfSDavid du Colombier png_ptr->offset_table_ptr = NULL;
3107dd7cddfSDavid du Colombier }
3117dd7cddfSDavid du Colombier }
3127dd7cddfSDavid du Colombier
3137dd7cddfSDavid du Colombier if (ptr != NULL)
3147dd7cddfSDavid du Colombier {
3157dd7cddfSDavid du Colombier farfree(ptr);
3167dd7cddfSDavid du Colombier }
3177dd7cddfSDavid du Colombier }
3187dd7cddfSDavid du Colombier
3197dd7cddfSDavid du Colombier #else /* Not the Borland DOS special memory handler */
3207dd7cddfSDavid du Colombier
3217dd7cddfSDavid du Colombier /* Allocate memory for a png_struct or a png_info. The malloc and
3227dd7cddfSDavid du Colombier memset can be replaced by a single call to calloc() if this is thought
3237dd7cddfSDavid du Colombier to improve performance noticably. */
324*593dc095SDavid du Colombier png_voidp /* PRIVATE */
png_create_struct(int type)3257dd7cddfSDavid du Colombier png_create_struct(int type)
3267dd7cddfSDavid du Colombier {
327*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
328*593dc095SDavid du Colombier return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
329*593dc095SDavid du Colombier }
330*593dc095SDavid du Colombier
331*593dc095SDavid du Colombier /* Allocate memory for a png_struct or a png_info. The malloc and
332*593dc095SDavid du Colombier memset can be replaced by a single call to calloc() if this is thought
333*593dc095SDavid du Colombier to improve performance noticably. */
334*593dc095SDavid du Colombier png_voidp /* PRIVATE */
png_create_struct_2(int type,png_malloc_ptr malloc_fn,png_voidp mem_ptr)335*593dc095SDavid du Colombier png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
336*593dc095SDavid du Colombier {
337*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
3387dd7cddfSDavid du Colombier png_size_t size;
3397dd7cddfSDavid du Colombier png_voidp struct_ptr;
3407dd7cddfSDavid du Colombier
3417dd7cddfSDavid du Colombier if (type == PNG_STRUCT_INFO)
342*593dc095SDavid du Colombier size = png_sizeof(png_info);
3437dd7cddfSDavid du Colombier else if (type == PNG_STRUCT_PNG)
344*593dc095SDavid du Colombier size = png_sizeof(png_struct);
3457dd7cddfSDavid du Colombier else
346*593dc095SDavid du Colombier return (NULL);
347*593dc095SDavid du Colombier
348*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
349*593dc095SDavid du Colombier if(malloc_fn != NULL)
350*593dc095SDavid du Colombier {
351*593dc095SDavid du Colombier png_struct dummy_struct;
352*593dc095SDavid du Colombier png_structp png_ptr = &dummy_struct;
353*593dc095SDavid du Colombier png_ptr->mem_ptr=mem_ptr;
354*593dc095SDavid du Colombier struct_ptr = (*(malloc_fn))(png_ptr, size);
355*593dc095SDavid du Colombier if (struct_ptr != NULL)
356*593dc095SDavid du Colombier png_memset(struct_ptr, 0, size);
357*593dc095SDavid du Colombier return (struct_ptr);
358*593dc095SDavid du Colombier }
359*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
3607dd7cddfSDavid du Colombier
3617dd7cddfSDavid du Colombier #if defined(__TURBOC__) && !defined(__FLAT__)
362*593dc095SDavid du Colombier struct_ptr = (png_voidp)farmalloc(size);
3637dd7cddfSDavid du Colombier #else
3647dd7cddfSDavid du Colombier # if defined(_MSC_VER) && defined(MAXSEG_64K)
365*593dc095SDavid du Colombier struct_ptr = (png_voidp)halloc(size,1);
3667dd7cddfSDavid du Colombier # else
367*593dc095SDavid du Colombier struct_ptr = (png_voidp)malloc(size);
3687dd7cddfSDavid du Colombier # endif
3697dd7cddfSDavid du Colombier #endif
370*593dc095SDavid du Colombier if (struct_ptr != NULL)
3717dd7cddfSDavid du Colombier png_memset(struct_ptr, 0, size);
3727dd7cddfSDavid du Colombier
373*593dc095SDavid du Colombier return (struct_ptr);
3747dd7cddfSDavid du Colombier }
3757dd7cddfSDavid du Colombier
3767dd7cddfSDavid du Colombier
3777dd7cddfSDavid du Colombier /* Free memory allocated by a png_create_struct() call */
378*593dc095SDavid du Colombier void /* PRIVATE */
png_destroy_struct(png_voidp struct_ptr)3797dd7cddfSDavid du Colombier png_destroy_struct(png_voidp struct_ptr)
3807dd7cddfSDavid du Colombier {
381*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
382*593dc095SDavid du Colombier png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
383*593dc095SDavid du Colombier }
384*593dc095SDavid du Colombier
385*593dc095SDavid du Colombier /* Free memory allocated by a png_create_struct() call */
386*593dc095SDavid du Colombier void /* PRIVATE */
png_destroy_struct_2(png_voidp struct_ptr,png_free_ptr free_fn,png_voidp mem_ptr)387*593dc095SDavid du Colombier png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
388*593dc095SDavid du Colombier png_voidp mem_ptr)
389*593dc095SDavid du Colombier {
390*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
3917dd7cddfSDavid du Colombier if (struct_ptr != NULL)
3927dd7cddfSDavid du Colombier {
393*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
394*593dc095SDavid du Colombier if(free_fn != NULL)
395*593dc095SDavid du Colombier {
396*593dc095SDavid du Colombier png_struct dummy_struct;
397*593dc095SDavid du Colombier png_structp png_ptr = &dummy_struct;
398*593dc095SDavid du Colombier png_ptr->mem_ptr=mem_ptr;
399*593dc095SDavid du Colombier (*(free_fn))(png_ptr, struct_ptr);
400*593dc095SDavid du Colombier return;
401*593dc095SDavid du Colombier }
402*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
4037dd7cddfSDavid du Colombier #if defined(__TURBOC__) && !defined(__FLAT__)
4047dd7cddfSDavid du Colombier farfree(struct_ptr);
4057dd7cddfSDavid du Colombier #else
4067dd7cddfSDavid du Colombier # if defined(_MSC_VER) && defined(MAXSEG_64K)
4077dd7cddfSDavid du Colombier hfree(struct_ptr);
4087dd7cddfSDavid du Colombier # else
4097dd7cddfSDavid du Colombier free(struct_ptr);
4107dd7cddfSDavid du Colombier # endif
4117dd7cddfSDavid du Colombier #endif
4127dd7cddfSDavid du Colombier }
4137dd7cddfSDavid du Colombier }
4147dd7cddfSDavid du Colombier
4157dd7cddfSDavid du Colombier /* Allocate memory. For reasonable files, size should never exceed
4167dd7cddfSDavid du Colombier 64K. However, zlib may allocate more then 64K if you don't tell
4177dd7cddfSDavid du Colombier it not to. See zconf.h and png.h for more information. zlib does
4187dd7cddfSDavid du Colombier need to allocate exactly 64K, so whatever you call here must
4197dd7cddfSDavid du Colombier have the ability to do that. */
4207dd7cddfSDavid du Colombier
421*593dc095SDavid du Colombier png_voidp PNGAPI
png_malloc(png_structp png_ptr,png_uint_32 size)422*593dc095SDavid du Colombier png_malloc(png_structp png_ptr, png_uint_32 size)
4237dd7cddfSDavid du Colombier {
4247dd7cddfSDavid du Colombier png_voidp ret;
4257dd7cddfSDavid du Colombier
426*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
427*593dc095SDavid du Colombier if (png_ptr == NULL || size == 0)
428*593dc095SDavid du Colombier return (NULL);
429*593dc095SDavid du Colombier
430*593dc095SDavid du Colombier if(png_ptr->malloc_fn != NULL)
431*593dc095SDavid du Colombier ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
432*593dc095SDavid du Colombier else
433*593dc095SDavid du Colombier ret = (png_malloc_default(png_ptr, size));
434*593dc095SDavid du Colombier if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
435*593dc095SDavid du Colombier png_error(png_ptr, "Out of Memory!");
436*593dc095SDavid du Colombier return (ret);
437*593dc095SDavid du Colombier }
438*593dc095SDavid du Colombier
439*593dc095SDavid du Colombier png_voidp PNGAPI
png_malloc_default(png_structp png_ptr,png_uint_32 size)440*593dc095SDavid du Colombier png_malloc_default(png_structp png_ptr, png_uint_32 size)
441*593dc095SDavid du Colombier {
442*593dc095SDavid du Colombier png_voidp ret;
443*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
444*593dc095SDavid du Colombier
445*593dc095SDavid du Colombier if (png_ptr == NULL || size == 0)
446*593dc095SDavid du Colombier return (NULL);
4477dd7cddfSDavid du Colombier
4487dd7cddfSDavid du Colombier #ifdef PNG_MAX_MALLOC_64K
4497dd7cddfSDavid du Colombier if (size > (png_uint_32)65536L)
450*593dc095SDavid du Colombier {
451*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
452*593dc095SDavid du Colombier if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
4537dd7cddfSDavid du Colombier png_error(png_ptr, "Cannot Allocate > 64K");
454*593dc095SDavid du Colombier else
455*593dc095SDavid du Colombier #endif
456*593dc095SDavid du Colombier return NULL;
457*593dc095SDavid du Colombier }
4587dd7cddfSDavid du Colombier #endif
4597dd7cddfSDavid du Colombier
460*593dc095SDavid du Colombier /* Check for overflow */
4617dd7cddfSDavid du Colombier #if defined(__TURBOC__) && !defined(__FLAT__)
462*593dc095SDavid du Colombier if (size != (unsigned long)size)
463*593dc095SDavid du Colombier ret = NULL;
464*593dc095SDavid du Colombier else
4657dd7cddfSDavid du Colombier ret = farmalloc(size);
4667dd7cddfSDavid du Colombier #else
4677dd7cddfSDavid du Colombier # if defined(_MSC_VER) && defined(MAXSEG_64K)
468*593dc095SDavid du Colombier if (size != (unsigned long)size)
469*593dc095SDavid du Colombier ret = NULL;
470*593dc095SDavid du Colombier else
4717dd7cddfSDavid du Colombier ret = halloc(size, 1);
4727dd7cddfSDavid du Colombier # else
473*593dc095SDavid du Colombier if (size != (size_t)size)
474*593dc095SDavid du Colombier ret = NULL;
475*593dc095SDavid du Colombier else
476*593dc095SDavid du Colombier ret = malloc((size_t)size);
4777dd7cddfSDavid du Colombier # endif
4787dd7cddfSDavid du Colombier #endif
4797dd7cddfSDavid du Colombier
480*593dc095SDavid du Colombier #ifndef PNG_USER_MEM_SUPPORTED
481*593dc095SDavid du Colombier if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
4827dd7cddfSDavid du Colombier png_error(png_ptr, "Out of Memory");
483*593dc095SDavid du Colombier #endif
484*593dc095SDavid du Colombier
485*593dc095SDavid du Colombier return (ret);
4867dd7cddfSDavid du Colombier }
4877dd7cddfSDavid du Colombier
488*593dc095SDavid du Colombier /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
489*593dc095SDavid du Colombier without taking any action. */
490*593dc095SDavid du Colombier void PNGAPI
png_free(png_structp png_ptr,png_voidp ptr)491*593dc095SDavid du Colombier png_free(png_structp png_ptr, png_voidp ptr)
4927dd7cddfSDavid du Colombier {
4937dd7cddfSDavid du Colombier if (png_ptr == NULL || ptr == NULL)
4947dd7cddfSDavid du Colombier return;
4957dd7cddfSDavid du Colombier
496*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
497*593dc095SDavid du Colombier if (png_ptr->free_fn != NULL)
498*593dc095SDavid du Colombier {
499*593dc095SDavid du Colombier (*(png_ptr->free_fn))(png_ptr, ptr);
500*593dc095SDavid du Colombier return;
501*593dc095SDavid du Colombier }
502*593dc095SDavid du Colombier else png_free_default(png_ptr, ptr);
503*593dc095SDavid du Colombier }
504*593dc095SDavid du Colombier void PNGAPI
png_free_default(png_structp png_ptr,png_voidp ptr)505*593dc095SDavid du Colombier png_free_default(png_structp png_ptr, png_voidp ptr)
506*593dc095SDavid du Colombier {
507*593dc095SDavid du Colombier if (png_ptr == NULL || ptr == NULL)
508*593dc095SDavid du Colombier return;
509*593dc095SDavid du Colombier
510*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
511*593dc095SDavid du Colombier
5127dd7cddfSDavid du Colombier #if defined(__TURBOC__) && !defined(__FLAT__)
5137dd7cddfSDavid du Colombier farfree(ptr);
5147dd7cddfSDavid du Colombier #else
5157dd7cddfSDavid du Colombier # if defined(_MSC_VER) && defined(MAXSEG_64K)
5167dd7cddfSDavid du Colombier hfree(ptr);
5177dd7cddfSDavid du Colombier # else
5187dd7cddfSDavid du Colombier free(ptr);
5197dd7cddfSDavid du Colombier # endif
5207dd7cddfSDavid du Colombier #endif
5217dd7cddfSDavid du Colombier }
5227dd7cddfSDavid du Colombier
5237dd7cddfSDavid du Colombier #endif /* Not Borland DOS special memory handler */
5247dd7cddfSDavid du Colombier
525*593dc095SDavid du Colombier #if defined(PNG_1_0_X)
526*593dc095SDavid du Colombier # define png_malloc_warn png_malloc
527*593dc095SDavid du Colombier #else
528*593dc095SDavid du Colombier /* This function was added at libpng version 1.2.3. The png_malloc_warn()
529*593dc095SDavid du Colombier * function will set up png_malloc() to issue a png_warning and return NULL
530*593dc095SDavid du Colombier * instead of issuing a png_error, if it fails to allocate the requested
531*593dc095SDavid du Colombier * memory.
532*593dc095SDavid du Colombier */
533*593dc095SDavid du Colombier png_voidp PNGAPI
png_malloc_warn(png_structp png_ptr,png_uint_32 size)534*593dc095SDavid du Colombier png_malloc_warn(png_structp png_ptr, png_uint_32 size)
535*593dc095SDavid du Colombier {
536*593dc095SDavid du Colombier png_voidp ptr;
537*593dc095SDavid du Colombier png_uint_32 save_flags=png_ptr->flags;
538*593dc095SDavid du Colombier
539*593dc095SDavid du Colombier png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
540*593dc095SDavid du Colombier ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
541*593dc095SDavid du Colombier png_ptr->flags=save_flags;
542*593dc095SDavid du Colombier return(ptr);
543*593dc095SDavid du Colombier }
544*593dc095SDavid du Colombier #endif
545*593dc095SDavid du Colombier
546*593dc095SDavid du Colombier png_voidp PNGAPI
png_memcpy_check(png_structp png_ptr,png_voidp s1,png_voidp s2,png_uint_32 length)547*593dc095SDavid du Colombier png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
548*593dc095SDavid du Colombier png_uint_32 length)
549*593dc095SDavid du Colombier {
550*593dc095SDavid du Colombier png_size_t size;
551*593dc095SDavid du Colombier
552*593dc095SDavid du Colombier size = (png_size_t)length;
553*593dc095SDavid du Colombier if ((png_uint_32)size != length)
554*593dc095SDavid du Colombier png_error(png_ptr,"Overflow in png_memcpy_check.");
555*593dc095SDavid du Colombier
556*593dc095SDavid du Colombier return(png_memcpy (s1, s2, size));
557*593dc095SDavid du Colombier }
558*593dc095SDavid du Colombier
559*593dc095SDavid du Colombier png_voidp PNGAPI
png_memset_check(png_structp png_ptr,png_voidp s1,int value,png_uint_32 length)560*593dc095SDavid du Colombier png_memset_check (png_structp png_ptr, png_voidp s1, int value,
561*593dc095SDavid du Colombier png_uint_32 length)
562*593dc095SDavid du Colombier {
563*593dc095SDavid du Colombier png_size_t size;
564*593dc095SDavid du Colombier
565*593dc095SDavid du Colombier size = (png_size_t)length;
566*593dc095SDavid du Colombier if ((png_uint_32)size != length)
567*593dc095SDavid du Colombier png_error(png_ptr,"Overflow in png_memset_check.");
568*593dc095SDavid du Colombier
569*593dc095SDavid du Colombier return (png_memset (s1, value, size));
570*593dc095SDavid du Colombier
571*593dc095SDavid du Colombier }
572*593dc095SDavid du Colombier
573*593dc095SDavid du Colombier #ifdef PNG_USER_MEM_SUPPORTED
574*593dc095SDavid du Colombier /* This function is called when the application wants to use another method
575*593dc095SDavid du Colombier * of allocating and freeing memory.
576*593dc095SDavid du Colombier */
577*593dc095SDavid du Colombier void PNGAPI
png_set_mem_fn(png_structp png_ptr,png_voidp mem_ptr,png_malloc_ptr malloc_fn,png_free_ptr free_fn)578*593dc095SDavid du Colombier png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
579*593dc095SDavid du Colombier malloc_fn, png_free_ptr free_fn)
580*593dc095SDavid du Colombier {
581*593dc095SDavid du Colombier png_ptr->mem_ptr = mem_ptr;
582*593dc095SDavid du Colombier png_ptr->malloc_fn = malloc_fn;
583*593dc095SDavid du Colombier png_ptr->free_fn = free_fn;
584*593dc095SDavid du Colombier }
585*593dc095SDavid du Colombier
586*593dc095SDavid du Colombier /* This function returns a pointer to the mem_ptr associated with the user
587*593dc095SDavid du Colombier * functions. The application should free any memory associated with this
588*593dc095SDavid du Colombier * pointer before png_write_destroy and png_read_destroy are called.
589*593dc095SDavid du Colombier */
590*593dc095SDavid du Colombier png_voidp PNGAPI
png_get_mem_ptr(png_structp png_ptr)591*593dc095SDavid du Colombier png_get_mem_ptr(png_structp png_ptr)
592*593dc095SDavid du Colombier {
593*593dc095SDavid du Colombier return ((png_voidp)png_ptr->mem_ptr);
594*593dc095SDavid du Colombier }
595*593dc095SDavid du Colombier #endif /* PNG_USER_MEM_SUPPORTED */
596