]> git.saurik.com Git - wxWidgets.git/blame - src/png/pngmem.c
Applied patch [ 649157 ] wxDisplay for Unix
[wxWidgets.git] / src / png / pngmem.c
CommitLineData
75b6e0a0
GD
1
2/* pngmem.c - stub functions for memory allocation
3 *
2b5f62a0 4 * libpng 1.2.5rc3 - September 18, 2002
75b6e0a0 5 * For conditions of distribution and use, see copyright notice in png.h
4946a942
GD
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.)
75b6e0a0
GD
9 *
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.
15 */
16
17#define PNG_INTERNAL
18#include "png.h"
19
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 */
23
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. */
4946a942 26png_voidp /* PRIVATE */
75b6e0a0
GD
27png_create_struct(int type)
28{
29#ifdef PNG_USER_MEM_SUPPORTED
4946a942 30 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
75b6e0a0
GD
31}
32
33/* Alternate version of png_create_struct, for use with user-defined malloc. */
4946a942
GD
34png_voidp /* PRIVATE */
35png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
75b6e0a0
GD
36{
37#endif /* PNG_USER_MEM_SUPPORTED */
38 png_size_t size;
39 png_voidp struct_ptr;
40
41 if (type == PNG_STRUCT_INFO)
42 size = sizeof(png_info);
43 else if (type == PNG_STRUCT_PNG)
44 size = sizeof(png_struct);
45 else
4946a942 46 return (png_get_copyright());
75b6e0a0
GD
47
48#ifdef PNG_USER_MEM_SUPPORTED
49 if(malloc_fn != NULL)
50 {
4946a942
GD
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);
75b6e0a0 55 }
4946a942 56 else
75b6e0a0 57#endif /* PNG_USER_MEM_SUPPORTED */
4946a942
GD
58 struct_ptr = (png_voidp)farmalloc(size));
59 if (struct_ptr != NULL)
75b6e0a0 60 png_memset(struct_ptr, 0, size);
75b6e0a0
GD
61 return (struct_ptr);
62}
63
75b6e0a0 64/* Free memory allocated by a png_create_struct() call */
4946a942 65void /* PRIVATE */
75b6e0a0
GD
66png_destroy_struct(png_voidp struct_ptr)
67{
68#ifdef PNG_USER_MEM_SUPPORTED
4946a942 69 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
75b6e0a0
GD
70}
71
72/* Free memory allocated by a png_create_struct() call */
4946a942
GD
73void /* PRIVATE */
74png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
75 png_voidp mem_ptr)
75b6e0a0
GD
76{
77#endif
78 if (struct_ptr != NULL)
79 {
80#ifdef PNG_USER_MEM_SUPPORTED
81 if(free_fn != NULL)
82 {
83 png_struct dummy_struct;
84 png_structp png_ptr = &dummy_struct;
4946a942 85 png_ptr->mem_ptr=mem_ptr;
75b6e0a0 86 (*(free_fn))(png_ptr, struct_ptr);
75b6e0a0
GD
87 return;
88 }
89#endif /* PNG_USER_MEM_SUPPORTED */
90 farfree (struct_ptr);
75b6e0a0
GD
91 }
92}
93
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.
99 *
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
106 * memory.
107 *
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.
112 */
4946a942
GD
113
114png_voidp PNGAPI
75b6e0a0
GD
115png_malloc(png_structp png_ptr, png_uint_32 size)
116{
75b6e0a0 117 png_voidp ret;
4946a942 118
75b6e0a0 119 if (png_ptr == NULL || size == 0)
4946a942 120 return (NULL);
75b6e0a0
GD
121
122#ifdef PNG_USER_MEM_SUPPORTED
123 if(png_ptr->malloc_fn != NULL)
4946a942
GD
124 {
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!");
128 return (ret);
129 }
75b6e0a0
GD
130 else
131 return png_malloc_default(png_ptr, size);
132}
133
4946a942 134png_voidp PNGAPI
75b6e0a0
GD
135png_malloc_default(png_structp png_ptr, png_uint_32 size)
136{
137 png_voidp ret;
138#endif /* PNG_USER_MEM_SUPPORTED */
139
140#ifdef PNG_MAX_MALLOC_64K
141 if (size > (png_uint_32)65536L)
142 png_error(png_ptr, "Cannot Allocate > 64K");
143#endif
144
145 if (size == (png_uint_32)65536L)
146 {
147 if (png_ptr->offset_table == NULL)
148 {
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))
152 {
153 int num_blocks;
154 png_uint_32 total_size;
155 png_bytep table;
156 int i;
157 png_byte huge * hptr;
158
159 if (ret != NULL)
160 {
161 farfree(ret);
162 ret = NULL;
163 }
164
4946a942
GD
165 if(png_ptr->zlib_window_bits > 14)
166 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
167 else
75b6e0a0
GD
168 num_blocks = 1;
169 if (png_ptr->zlib_mem_level >= 7)
170 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
171 else
172 num_blocks++;
173
174 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
175
176 table = farmalloc(total_size);
177
178 if (table == NULL)
179 {
4946a942
GD
180 if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
181 png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
182 else
183 png_warning(png_ptr, "Out Of Memory.");
184 return (NULL);
75b6e0a0
GD
185 }
186
187 if ((png_size_t)table & 0xfff0)
188 {
4946a942
GD
189 if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
190 png_error(png_ptr,
191 "Farmalloc didn't return normalized pointer");
192 else
193 png_warning(png_ptr,
194 "Farmalloc didn't return normalized pointer");
195 return (NULL);
75b6e0a0
GD
196 }
197
198 png_ptr->offset_table = table;
199 png_ptr->offset_table_ptr = farmalloc(num_blocks *
200 sizeof (png_bytep));
201
202 if (png_ptr->offset_table_ptr == NULL)
203 {
4946a942
GD
204 if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
205 png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
206 else
207 png_warning(png_ptr, "Out Of memory.");
208 return (NULL);
75b6e0a0
GD
209 }
210
211 hptr = (png_byte huge *)table;
212 if ((png_size_t)hptr & 0xf)
213 {
214 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
4946a942 215 hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
75b6e0a0
GD
216 }
217 for (i = 0; i < num_blocks; i++)
218 {
219 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
4946a942 220 hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
75b6e0a0
GD
221 }
222
223 png_ptr->offset_table_number = num_blocks;
224 png_ptr->offset_table_count = 0;
225 png_ptr->offset_table_count_free = 0;
226 }
227 }
228
229 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
4946a942
GD
230 {
231 if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
232 png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
233 else
234 png_warning(png_ptr, "Out of Memory.");
235 return (NULL);
236 }
75b6e0a0
GD
237
238 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
239 }
240 else
241 ret = farmalloc(size);
242
243 if (ret == NULL)
244 {
4946a942
GD
245 if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
246 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
247 else
248 png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
75b6e0a0
GD
249 }
250
251 return (ret);
252}
253
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. */
4946a942 257void PNGAPI
75b6e0a0
GD
258png_free(png_structp png_ptr, png_voidp ptr)
259{
260 if (png_ptr == NULL || ptr == NULL)
261 return;
262
263#ifdef PNG_USER_MEM_SUPPORTED
264 if (png_ptr->free_fn != NULL)
265 {
266 (*(png_ptr->free_fn))(png_ptr, ptr);
75b6e0a0
GD
267 return;
268 }
269 else png_free_default(png_ptr, ptr);
270}
271
4946a942 272void PNGAPI
75b6e0a0
GD
273png_free_default(png_structp png_ptr, png_voidp ptr)
274{
275#endif /* PNG_USER_MEM_SUPPORTED */
276
277 if (png_ptr->offset_table != NULL)
278 {
279 int i;
280
281 for (i = 0; i < png_ptr->offset_table_count; i++)
282 {
283 if (ptr == png_ptr->offset_table_ptr[i])
284 {
285 ptr = NULL;
286 png_ptr->offset_table_count_free++;
287 break;
288 }
289 }
290 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
291 {
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;
296 }
297 }
298
299 if (ptr != NULL)
300 {
301 farfree(ptr);
75b6e0a0
GD
302 }
303}
304
305#else /* Not the Borland DOS special memory handler */
306
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
4946a942
GD
309 to improve performance noticably. */
310png_voidp /* PRIVATE */
75b6e0a0
GD
311png_create_struct(int type)
312{
313#ifdef PNG_USER_MEM_SUPPORTED
4946a942 314 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
75b6e0a0
GD
315}
316
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
4946a942
GD
319 to improve performance noticably. */
320png_voidp /* PRIVATE */
321png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
75b6e0a0
GD
322{
323#endif /* PNG_USER_MEM_SUPPORTED */
324 png_size_t size;
325 png_voidp struct_ptr;
326
327 if (type == PNG_STRUCT_INFO)
328 size = sizeof(png_info);
329 else if (type == PNG_STRUCT_PNG)
330 size = sizeof(png_struct);
331 else
4946a942 332 return (NULL);
75b6e0a0
GD
333
334#ifdef PNG_USER_MEM_SUPPORTED
335 if(malloc_fn != NULL)
336 {
4946a942
GD
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)
75b6e0a0
GD
342 png_memset(struct_ptr, 0, size);
343 return (struct_ptr);
344 }
345#endif /* PNG_USER_MEM_SUPPORTED */
346
347#if defined(__TURBOC__) && !defined(__FLAT__)
348 if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
349#else
350# if defined(_MSC_VER) && defined(MAXSEG_64K)
351 if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
352# else
353 if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
354# endif
355#endif
356 {
357 png_memset(struct_ptr, 0, size);
358 }
359
360 return (struct_ptr);
361}
362
363
364/* Free memory allocated by a png_create_struct() call */
4946a942 365void /* PRIVATE */
75b6e0a0
GD
366png_destroy_struct(png_voidp struct_ptr)
367{
368#ifdef PNG_USER_MEM_SUPPORTED
4946a942 369 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
75b6e0a0
GD
370}
371
372/* Free memory allocated by a png_create_struct() call */
4946a942
GD
373void /* PRIVATE */
374png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
375 png_voidp mem_ptr)
75b6e0a0
GD
376{
377#endif /* PNG_USER_MEM_SUPPORTED */
378 if (struct_ptr != NULL)
379 {
380#ifdef PNG_USER_MEM_SUPPORTED
381 if(free_fn != NULL)
382 {
383 png_struct dummy_struct;
384 png_structp png_ptr = &dummy_struct;
4946a942 385 png_ptr->mem_ptr=mem_ptr;
75b6e0a0 386 (*(free_fn))(png_ptr, struct_ptr);
75b6e0a0
GD
387 return;
388 }
389#endif /* PNG_USER_MEM_SUPPORTED */
390#if defined(__TURBOC__) && !defined(__FLAT__)
391 farfree(struct_ptr);
75b6e0a0
GD
392#else
393# if defined(_MSC_VER) && defined(MAXSEG_64K)
394 hfree(struct_ptr);
75b6e0a0
GD
395# else
396 free(struct_ptr);
75b6e0a0
GD
397# endif
398#endif
399 }
400}
401
75b6e0a0
GD
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. */
407
4946a942 408png_voidp PNGAPI
75b6e0a0
GD
409png_malloc(png_structp png_ptr, png_uint_32 size)
410{
75b6e0a0 411 png_voidp ret;
4946a942 412
75b6e0a0 413 if (png_ptr == NULL || size == 0)
4946a942 414 return (NULL);
75b6e0a0
GD
415
416#ifdef PNG_USER_MEM_SUPPORTED
417 if(png_ptr->malloc_fn != NULL)
4946a942
GD
418 {
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!");
422 return (ret);
423 }
75b6e0a0
GD
424 else
425 return (png_malloc_default(png_ptr, size));
426}
4946a942
GD
427
428png_voidp PNGAPI
75b6e0a0
GD
429png_malloc_default(png_structp png_ptr, png_uint_32 size)
430{
431 png_voidp ret;
432#endif /* PNG_USER_MEM_SUPPORTED */
433
434#ifdef PNG_MAX_MALLOC_64K
435 if (size > (png_uint_32)65536L)
4946a942
GD
436 {
437 if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
438 png_error(png_ptr, "Cannot Allocate > 64K");
439 else
440 return NULL;
441 }
75b6e0a0
GD
442#endif
443
444#if defined(__TURBOC__) && !defined(__FLAT__)
445 ret = farmalloc(size);
446#else
447# if defined(_MSC_VER) && defined(MAXSEG_64K)
448 ret = halloc(size, 1);
449# else
450 ret = malloc((size_t)size);
451# endif
452#endif
453
4946a942 454 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
75b6e0a0 455 png_error(png_ptr, "Out of Memory");
75b6e0a0
GD
456
457 return (ret);
458}
459
460/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
461 without taking any action. */
4946a942 462void PNGAPI
75b6e0a0
GD
463png_free(png_structp png_ptr, png_voidp ptr)
464{
465 if (png_ptr == NULL || ptr == NULL)
466 return;
467
468#ifdef PNG_USER_MEM_SUPPORTED
469 if (png_ptr->free_fn != NULL)
470 {
471 (*(png_ptr->free_fn))(png_ptr, ptr);
75b6e0a0
GD
472 return;
473 }
474 else png_free_default(png_ptr, ptr);
475}
4946a942 476void PNGAPI
75b6e0a0
GD
477png_free_default(png_structp png_ptr, png_voidp ptr)
478{
4946a942
GD
479 if (png_ptr == NULL || ptr == NULL)
480 return;
481
75b6e0a0
GD
482#endif /* PNG_USER_MEM_SUPPORTED */
483
484#if defined(__TURBOC__) && !defined(__FLAT__)
485 farfree(ptr);
75b6e0a0
GD
486#else
487# if defined(_MSC_VER) && defined(MAXSEG_64K)
488 hfree(ptr);
75b6e0a0
GD
489# else
490 free(ptr);
75b6e0a0
GD
491# endif
492#endif
493}
494
495#endif /* Not Borland DOS special memory handler */
496
4946a942
GD
497#if defined(PNG_1_0_X)
498# define png_malloc_warn png_malloc
499#else
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.
503 */
504png_voidp PNGAPI
505png_malloc_warn(png_structp png_ptr, png_uint_32 size)
506{
507 png_voidp ptr;
508 png_uint_32 save_flags=png_ptr->flags;
509
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;
513 return(ptr);
514}
515#endif
516
517png_voidp PNGAPI
75b6e0a0
GD
518png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
519 png_uint_32 length)
520{
521 png_size_t size;
522
523 size = (png_size_t)length;
524 if ((png_uint_32)size != length)
525 png_error(png_ptr,"Overflow in png_memcpy_check.");
526
527 return(png_memcpy (s1, s2, size));
528}
529
4946a942 530png_voidp PNGAPI
75b6e0a0
GD
531png_memset_check (png_structp png_ptr, png_voidp s1, int value,
532 png_uint_32 length)
533{
534 png_size_t size;
535
536 size = (png_size_t)length;
537 if ((png_uint_32)size != length)
538 png_error(png_ptr,"Overflow in png_memset_check.");
539
540 return (png_memset (s1, value, size));
541
542}
543
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.
547 */
4946a942 548void PNGAPI
75b6e0a0
GD
549png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
550 malloc_fn, png_free_ptr free_fn)
551{
552 png_ptr->mem_ptr = mem_ptr;
553 png_ptr->malloc_fn = malloc_fn;
554 png_ptr->free_fn = free_fn;
555}
556
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.
560 */
4946a942 561png_voidp PNGAPI
75b6e0a0
GD
562png_get_mem_ptr(png_structp png_ptr)
563{
564 return ((png_voidp)png_ptr->mem_ptr);
565}
566#endif /* PNG_USER_MEM_SUPPORTED */