]> git.saurik.com Git - wxWidgets.git/blob - src/png/pngmem.c
introduce wxBG_STYLE_{ERASE,PAINT} and implement their documented semantics in wxGTK
[wxWidgets.git] / src / png / pngmem.c
1
2 /* pngmem.c - stub functions for memory allocation
3 *
4 * Last changed in libpng 1.2.30 [August 15, 2008]
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2008 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.)
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 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
20
21 /* Borland DOS special memory handler */
22 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
23 /* if you change this, be sure to change the one in png.h also */
24
25 /* Allocate memory for a png_struct. The malloc and memset can be replaced
26 by a single call to calloc() if this is thought to improve performance. */
27 png_voidp /* PRIVATE */
28 png_create_struct(int type)
29 {
30 #ifdef PNG_USER_MEM_SUPPORTED
31 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
32 }
33
34 /* Alternate version of png_create_struct, for use with user-defined malloc. */
35 png_voidp /* PRIVATE */
36 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
37 {
38 #endif /* PNG_USER_MEM_SUPPORTED */
39 png_size_t size;
40 png_voidp struct_ptr;
41
42 if (type == PNG_STRUCT_INFO)
43 size = png_sizeof(png_info);
44 else if (type == PNG_STRUCT_PNG)
45 size = png_sizeof(png_struct);
46 else
47 return (png_get_copyright(NULL));
48
49 #ifdef PNG_USER_MEM_SUPPORTED
50 if (malloc_fn != NULL)
51 {
52 png_struct dummy_struct;
53 png_structp png_ptr = &dummy_struct;
54 png_ptr->mem_ptr=mem_ptr;
55 struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
56 }
57 else
58 #endif /* PNG_USER_MEM_SUPPORTED */
59 struct_ptr = (png_voidp)farmalloc(size);
60 if (struct_ptr != NULL)
61 png_memset(struct_ptr, 0, size);
62 return (struct_ptr);
63 }
64
65 /* Free memory allocated by a png_create_struct() call */
66 void /* PRIVATE */
67 png_destroy_struct(png_voidp struct_ptr)
68 {
69 #ifdef PNG_USER_MEM_SUPPORTED
70 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
71 }
72
73 /* Free memory allocated by a png_create_struct() call */
74 void /* PRIVATE */
75 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
76 png_voidp mem_ptr)
77 {
78 #endif
79 if (struct_ptr != NULL)
80 {
81 #ifdef PNG_USER_MEM_SUPPORTED
82 if (free_fn != NULL)
83 {
84 png_struct dummy_struct;
85 png_structp png_ptr = &dummy_struct;
86 png_ptr->mem_ptr=mem_ptr;
87 (*(free_fn))(png_ptr, struct_ptr);
88 return;
89 }
90 #endif /* PNG_USER_MEM_SUPPORTED */
91 farfree (struct_ptr);
92 }
93 }
94
95 /* Allocate memory. For reasonable files, size should never exceed
96 * 64K. However, zlib may allocate more then 64K if you don't tell
97 * it not to. See zconf.h and png.h for more information. zlib does
98 * need to allocate exactly 64K, so whatever you call here must
99 * have the ability to do that.
100 *
101 * Borland seems to have a problem in DOS mode for exactly 64K.
102 * It gives you a segment with an offset of 8 (perhaps to store its
103 * memory stuff). zlib doesn't like this at all, so we have to
104 * detect and deal with it. This code should not be needed in
105 * Windows or OS/2 modes, and only in 16 bit mode. This code has
106 * been updated by Alexander Lehmann for version 0.89 to waste less
107 * memory.
108 *
109 * Note that we can't use png_size_t for the "size" declaration,
110 * since on some systems a png_size_t is a 16-bit quantity, and as a
111 * result, we would be truncating potentially larger memory requests
112 * (which should cause a fatal error) and introducing major problems.
113 */
114
115 png_voidp PNGAPI
116 png_malloc(png_structp png_ptr, png_uint_32 size)
117 {
118 png_voidp ret;
119
120 if (png_ptr == NULL || size == 0)
121 return (NULL);
122
123 #ifdef PNG_USER_MEM_SUPPORTED
124 if (png_ptr->malloc_fn != NULL)
125 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
126 else
127 ret = (png_malloc_default(png_ptr, size));
128 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
129 png_error(png_ptr, "Out of memory!");
130 return (ret);
131 }
132
133 png_voidp PNGAPI
134 png_malloc_default(png_structp png_ptr, png_uint_32 size)
135 {
136 png_voidp ret;
137 #endif /* PNG_USER_MEM_SUPPORTED */
138
139 if (png_ptr == NULL || size == 0)
140 return (NULL);
141
142 #ifdef PNG_MAX_MALLOC_64K
143 if (size > (png_uint_32)65536L)
144 {
145 png_warning(png_ptr, "Cannot Allocate > 64K");
146 ret = NULL;
147 }
148 else
149 #endif
150
151 if (size != (size_t)size)
152 ret = NULL;
153 else if (size == (png_uint_32)65536L)
154 {
155 if (png_ptr->offset_table == NULL)
156 {
157 /* try to see if we need to do any of this fancy stuff */
158 ret = farmalloc(size);
159 if (ret == NULL || ((png_size_t)ret & 0xffff))
160 {
161 int num_blocks;
162 png_uint_32 total_size;
163 png_bytep table;
164 int i;
165 png_byte huge * hptr;
166
167 if (ret != NULL)
168 {
169 farfree(ret);
170 ret = NULL;
171 }
172
173 if (png_ptr->zlib_window_bits > 14)
174 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
175 else
176 num_blocks = 1;
177 if (png_ptr->zlib_mem_level >= 7)
178 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
179 else
180 num_blocks++;
181
182 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
183
184 table = farmalloc(total_size);
185
186 if (table == NULL)
187 {
188 #ifndef PNG_USER_MEM_SUPPORTED
189 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
190 png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
191 else
192 png_warning(png_ptr, "Out Of Memory.");
193 #endif
194 return (NULL);
195 }
196
197 if ((png_size_t)table & 0xfff0)
198 {
199 #ifndef PNG_USER_MEM_SUPPORTED
200 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
201 png_error(png_ptr,
202 "Farmalloc didn't return normalized pointer");
203 else
204 png_warning(png_ptr,
205 "Farmalloc didn't return normalized pointer");
206 #endif
207 return (NULL);
208 }
209
210 png_ptr->offset_table = table;
211 png_ptr->offset_table_ptr = farmalloc(num_blocks *
212 png_sizeof(png_bytep));
213
214 if (png_ptr->offset_table_ptr == NULL)
215 {
216 #ifndef PNG_USER_MEM_SUPPORTED
217 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
218 png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
219 else
220 png_warning(png_ptr, "Out Of memory.");
221 #endif
222 return (NULL);
223 }
224
225 hptr = (png_byte huge *)table;
226 if ((png_size_t)hptr & 0xf)
227 {
228 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
229 hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
230 }
231 for (i = 0; i < num_blocks; i++)
232 {
233 png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
234 hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
235 }
236
237 png_ptr->offset_table_number = num_blocks;
238 png_ptr->offset_table_count = 0;
239 png_ptr->offset_table_count_free = 0;
240 }
241 }
242
243 if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
244 {
245 #ifndef PNG_USER_MEM_SUPPORTED
246 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
247 png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
248 else
249 png_warning(png_ptr, "Out of Memory.");
250 #endif
251 return (NULL);
252 }
253
254 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
255 }
256 else
257 ret = farmalloc(size);
258
259 #ifndef PNG_USER_MEM_SUPPORTED
260 if (ret == NULL)
261 {
262 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
263 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
264 else
265 png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
266 }
267 #endif
268
269 return (ret);
270 }
271
272 /* free a pointer allocated by png_malloc(). In the default
273 configuration, png_ptr is not used, but is passed in case it
274 is needed. If ptr is NULL, return without taking any action. */
275
276 void PNGAPI
277 png_free(png_structp png_ptr, png_voidp ptr)
278 {
279 if (png_ptr == NULL || ptr == NULL)
280 return;
281
282 #ifdef PNG_USER_MEM_SUPPORTED
283 if (png_ptr->free_fn != NULL)
284 {
285 (*(png_ptr->free_fn))(png_ptr, ptr);
286 return;
287 }
288 else png_free_default(png_ptr, ptr);
289 }
290
291 void PNGAPI
292 png_free_default(png_structp png_ptr, png_voidp ptr)
293 {
294 #endif /* PNG_USER_MEM_SUPPORTED */
295
296 if (png_ptr == NULL || ptr == NULL) return;
297
298 if (png_ptr->offset_table != NULL)
299 {
300 int i;
301
302 for (i = 0; i < png_ptr->offset_table_count; i++)
303 {
304 if (ptr == png_ptr->offset_table_ptr[i])
305 {
306 ptr = NULL;
307 png_ptr->offset_table_count_free++;
308 break;
309 }
310 }
311 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
312 {
313 farfree(png_ptr->offset_table);
314 farfree(png_ptr->offset_table_ptr);
315 png_ptr->offset_table = NULL;
316 png_ptr->offset_table_ptr = NULL;
317 }
318 }
319
320 if (ptr != NULL)
321 {
322 farfree(ptr);
323 }
324 }
325
326 #else /* Not the Borland DOS special memory handler */
327
328 /* Allocate memory for a png_struct or a png_info. The malloc and
329 memset can be replaced by a single call to calloc() if this is thought
330 to improve performance noticably. */
331 png_voidp /* PRIVATE */
332 png_create_struct(int type)
333 {
334 #ifdef PNG_USER_MEM_SUPPORTED
335 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
336 }
337
338 /* Allocate memory for a png_struct or a png_info. The malloc and
339 memset can be replaced by a single call to calloc() if this is thought
340 to improve performance noticably. */
341 png_voidp /* PRIVATE */
342 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
343 {
344 #endif /* PNG_USER_MEM_SUPPORTED */
345 png_size_t size;
346 png_voidp struct_ptr;
347
348 if (type == PNG_STRUCT_INFO)
349 size = png_sizeof(png_info);
350 else if (type == PNG_STRUCT_PNG)
351 size = png_sizeof(png_struct);
352 else
353 return (NULL);
354
355 #ifdef PNG_USER_MEM_SUPPORTED
356 if (malloc_fn != NULL)
357 {
358 png_struct dummy_struct;
359 png_structp png_ptr = &dummy_struct;
360 png_ptr->mem_ptr=mem_ptr;
361 struct_ptr = (*(malloc_fn))(png_ptr, size);
362 if (struct_ptr != NULL)
363 png_memset(struct_ptr, 0, size);
364 return (struct_ptr);
365 }
366 #endif /* PNG_USER_MEM_SUPPORTED */
367
368 #if defined(__TURBOC__) && !defined(__FLAT__)
369 struct_ptr = (png_voidp)farmalloc(size);
370 #else
371 # if defined(_MSC_VER) && defined(MAXSEG_64K)
372 struct_ptr = (png_voidp)halloc(size, 1);
373 # else
374 struct_ptr = (png_voidp)malloc(size);
375 # endif
376 #endif
377 if (struct_ptr != NULL)
378 png_memset(struct_ptr, 0, size);
379
380 return (struct_ptr);
381 }
382
383
384 /* Free memory allocated by a png_create_struct() call */
385 void /* PRIVATE */
386 png_destroy_struct(png_voidp struct_ptr)
387 {
388 #ifdef PNG_USER_MEM_SUPPORTED
389 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
390 }
391
392 /* Free memory allocated by a png_create_struct() call */
393 void /* PRIVATE */
394 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
395 png_voidp mem_ptr)
396 {
397 #endif /* PNG_USER_MEM_SUPPORTED */
398 if (struct_ptr != NULL)
399 {
400 #ifdef PNG_USER_MEM_SUPPORTED
401 if (free_fn != NULL)
402 {
403 png_struct dummy_struct;
404 png_structp png_ptr = &dummy_struct;
405 png_ptr->mem_ptr=mem_ptr;
406 (*(free_fn))(png_ptr, struct_ptr);
407 return;
408 }
409 #endif /* PNG_USER_MEM_SUPPORTED */
410 #if defined(__TURBOC__) && !defined(__FLAT__)
411 farfree(struct_ptr);
412 #else
413 # if defined(_MSC_VER) && defined(MAXSEG_64K)
414 hfree(struct_ptr);
415 # else
416 free(struct_ptr);
417 # endif
418 #endif
419 }
420 }
421
422 /* Allocate memory. For reasonable files, size should never exceed
423 64K. However, zlib may allocate more then 64K if you don't tell
424 it not to. See zconf.h and png.h for more information. zlib does
425 need to allocate exactly 64K, so whatever you call here must
426 have the ability to do that. */
427
428 png_voidp PNGAPI
429 png_malloc(png_structp png_ptr, png_uint_32 size)
430 {
431 png_voidp ret;
432
433 #ifdef PNG_USER_MEM_SUPPORTED
434 if (png_ptr == NULL || size == 0)
435 return (NULL);
436
437 if (png_ptr->malloc_fn != NULL)
438 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
439 else
440 ret = (png_malloc_default(png_ptr, size));
441 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
442 png_error(png_ptr, "Out of Memory!");
443 return (ret);
444 }
445
446 png_voidp PNGAPI
447 png_malloc_default(png_structp png_ptr, png_uint_32 size)
448 {
449 png_voidp ret;
450 #endif /* PNG_USER_MEM_SUPPORTED */
451
452 if (png_ptr == NULL || size == 0)
453 return (NULL);
454
455 #ifdef PNG_MAX_MALLOC_64K
456 if (size > (png_uint_32)65536L)
457 {
458 #ifndef PNG_USER_MEM_SUPPORTED
459 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
460 png_error(png_ptr, "Cannot Allocate > 64K");
461 else
462 #endif
463 return NULL;
464 }
465 #endif
466
467 /* Check for overflow */
468 #if defined(__TURBOC__) && !defined(__FLAT__)
469 if (size != (unsigned long)size)
470 ret = NULL;
471 else
472 ret = farmalloc(size);
473 #else
474 # if defined(_MSC_VER) && defined(MAXSEG_64K)
475 if (size != (unsigned long)size)
476 ret = NULL;
477 else
478 ret = halloc(size, 1);
479 # else
480 if (size != (size_t)size)
481 ret = NULL;
482 else
483 ret = malloc((size_t)size);
484 # endif
485 #endif
486
487 #ifndef PNG_USER_MEM_SUPPORTED
488 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
489 png_error(png_ptr, "Out of Memory");
490 #endif
491
492 return (ret);
493 }
494
495 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return
496 without taking any action. */
497 void PNGAPI
498 png_free(png_structp png_ptr, png_voidp ptr)
499 {
500 if (png_ptr == NULL || ptr == NULL)
501 return;
502
503 #ifdef PNG_USER_MEM_SUPPORTED
504 if (png_ptr->free_fn != NULL)
505 {
506 (*(png_ptr->free_fn))(png_ptr, ptr);
507 return;
508 }
509 else png_free_default(png_ptr, ptr);
510 }
511 void PNGAPI
512 png_free_default(png_structp png_ptr, png_voidp ptr)
513 {
514 if (png_ptr == NULL || ptr == NULL)
515 return;
516
517 #endif /* PNG_USER_MEM_SUPPORTED */
518
519 #if defined(__TURBOC__) && !defined(__FLAT__)
520 farfree(ptr);
521 #else
522 # if defined(_MSC_VER) && defined(MAXSEG_64K)
523 hfree(ptr);
524 # else
525 free(ptr);
526 # endif
527 #endif
528 }
529
530 #endif /* Not Borland DOS special memory handler */
531
532 #if defined(PNG_1_0_X)
533 # define png_malloc_warn png_malloc
534 #else
535 /* This function was added at libpng version 1.2.3. The png_malloc_warn()
536 * function will set up png_malloc() to issue a png_warning and return NULL
537 * instead of issuing a png_error, if it fails to allocate the requested
538 * memory.
539 */
540 png_voidp PNGAPI
541 png_malloc_warn(png_structp png_ptr, png_uint_32 size)
542 {
543 png_voidp ptr;
544 png_uint_32 save_flags;
545 if (png_ptr == NULL) return (NULL);
546
547 save_flags = png_ptr->flags;
548 png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
549 ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
550 png_ptr->flags=save_flags;
551 return(ptr);
552 }
553 #endif
554
555 png_voidp PNGAPI
556 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
557 png_uint_32 length)
558 {
559 png_size_t size;
560
561 size = (png_size_t)length;
562 if ((png_uint_32)size != length)
563 png_error(png_ptr, "Overflow in png_memcpy_check.");
564
565 return(png_memcpy (s1, s2, size));
566 }
567
568 png_voidp PNGAPI
569 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
570 png_uint_32 length)
571 {
572 png_size_t size;
573
574 size = (png_size_t)length;
575 if ((png_uint_32)size != length)
576 png_error(png_ptr, "Overflow in png_memset_check.");
577
578 return (png_memset (s1, value, size));
579
580 }
581
582 #ifdef PNG_USER_MEM_SUPPORTED
583 /* This function is called when the application wants to use another method
584 * of allocating and freeing memory.
585 */
586 void PNGAPI
587 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
588 malloc_fn, png_free_ptr free_fn)
589 {
590 if (png_ptr != NULL)
591 {
592 png_ptr->mem_ptr = mem_ptr;
593 png_ptr->malloc_fn = malloc_fn;
594 png_ptr->free_fn = free_fn;
595 }
596 }
597
598 /* This function returns a pointer to the mem_ptr associated with the user
599 * functions. The application should free any memory associated with this
600 * pointer before png_write_destroy and png_read_destroy are called.
601 */
602 png_voidp PNGAPI
603 png_get_mem_ptr(png_structp png_ptr)
604 {
605 if (png_ptr == NULL) return (NULL);
606 return ((png_voidp)png_ptr->mem_ptr);
607 }
608 #endif /* PNG_USER_MEM_SUPPORTED */
609 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */