Remove ancient trunk folder from svn repository
[synfig.git] / gtkmm-osx / libpng-1.2.5 / pngmem.c
1
2 /* pngmem.c - stub functions for memory allocation
3  *
4  * libpng 1.2.5 - October 3, 2002
5  * For conditions of distribution and use, see copyright notice in png.h
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.)
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. */
26 png_voidp /* PRIVATE */
27 png_create_struct(int type)
28 {
29 #ifdef PNG_USER_MEM_SUPPORTED
30    return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
31 }
32
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)
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
46      return (png_get_copyright());
47
48 #ifdef PNG_USER_MEM_SUPPORTED
49    if(malloc_fn != NULL)
50    {
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);
55    }
56    else
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);
61    return (struct_ptr);
62 }
63
64 /* Free memory allocated by a png_create_struct() call */
65 void /* PRIVATE */
66 png_destroy_struct(png_voidp struct_ptr)
67 {
68 #ifdef PNG_USER_MEM_SUPPORTED
69    png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
70 }
71
72 /* Free memory allocated by a png_create_struct() call */
73 void /* PRIVATE */
74 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
75     png_voidp mem_ptr)
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;
85          png_ptr->mem_ptr=mem_ptr;
86          (*(free_fn))(png_ptr, struct_ptr);
87          return;
88       }
89 #endif /* PNG_USER_MEM_SUPPORTED */
90       farfree (struct_ptr);
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  */
113
114 png_voidp PNGAPI
115 png_malloc(png_structp png_ptr, png_uint_32 size)
116 {
117    png_voidp ret;
118
119    if (png_ptr == NULL || size == 0)
120       return (NULL);
121
122 #ifdef PNG_USER_MEM_SUPPORTED
123    if(png_ptr->malloc_fn != NULL)
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    }
130    else
131        return png_malloc_default(png_ptr, size);
132 }
133
134 png_voidp PNGAPI
135 png_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
165             if(png_ptr->zlib_window_bits > 14)
166                num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
167             else
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             {
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);
185             }
186
187             if ((png_size_t)table & 0xfff0)
188             {
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);
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             {
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);
209             }
210
211             hptr = (png_byte huge *)table;
212             if ((png_size_t)hptr & 0xf)
213             {
214                hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
215                hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
216             }
217             for (i = 0; i < num_blocks; i++)
218             {
219                png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
220                hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
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)
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       }
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    {
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" */
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. */
257 void PNGAPI
258 png_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);
267       return;
268    }
269    else png_free_default(png_ptr, ptr);
270 }
271
272 void PNGAPI
273 png_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);
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
309    to improve performance noticably. */
310 png_voidp /* PRIVATE */
311 png_create_struct(int type)
312 {
313 #ifdef PNG_USER_MEM_SUPPORTED
314    return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
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
319    to improve performance noticably. */
320 png_voidp /* PRIVATE */
321 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
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
332       return (NULL);
333
334 #ifdef PNG_USER_MEM_SUPPORTED
335    if(malloc_fn != NULL)
336    {
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)
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 */
365 void /* PRIVATE */
366 png_destroy_struct(png_voidp struct_ptr)
367 {
368 #ifdef PNG_USER_MEM_SUPPORTED
369    png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
370 }
371
372 /* Free memory allocated by a png_create_struct() call */
373 void /* PRIVATE */
374 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
375     png_voidp mem_ptr)
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;
385          png_ptr->mem_ptr=mem_ptr;
386          (*(free_fn))(png_ptr, struct_ptr);
387          return;
388       }
389 #endif /* PNG_USER_MEM_SUPPORTED */
390 #if defined(__TURBOC__) && !defined(__FLAT__)
391       farfree(struct_ptr);
392 #else
393 # if defined(_MSC_VER) && defined(MAXSEG_64K)
394       hfree(struct_ptr);
395 # else
396       free(struct_ptr);
397 # endif
398 #endif
399    }
400 }
401
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
408 png_voidp PNGAPI
409 png_malloc(png_structp png_ptr, png_uint_32 size)
410 {
411    png_voidp ret;
412
413    if (png_ptr == NULL || size == 0)
414       return (NULL);
415
416 #ifdef PNG_USER_MEM_SUPPORTED
417    if(png_ptr->malloc_fn != NULL)
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    }
424    else
425        return (png_malloc_default(png_ptr, size));
426 }
427
428 png_voidp PNGAPI
429 png_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)
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    }
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
454    if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
455       png_error(png_ptr, "Out of Memory");
456
457    return (ret);
458 }
459
460 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
461    without taking any action. */
462 void PNGAPI
463 png_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);
472       return;
473    }
474    else png_free_default(png_ptr, ptr);
475 }
476 void PNGAPI
477 png_free_default(png_structp png_ptr, png_voidp ptr)
478 {
479    if (png_ptr == NULL || ptr == NULL)
480       return;
481
482 #endif /* PNG_USER_MEM_SUPPORTED */
483
484 #if defined(__TURBOC__) && !defined(__FLAT__)
485    farfree(ptr);
486 #else
487 # if defined(_MSC_VER) && defined(MAXSEG_64K)
488    hfree(ptr);
489 # else
490    free(ptr);
491 # endif
492 #endif
493 }
494
495 #endif /* Not Borland DOS special memory handler */
496
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  */
504 png_voidp PNGAPI
505 png_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
517 png_voidp PNGAPI
518 png_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
530 png_voidp PNGAPI
531 png_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  */
548 void PNGAPI
549 png_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  */
561 png_voidp PNGAPI
562 png_get_mem_ptr(png_structp png_ptr)
563 {
564    return ((png_voidp)png_ptr->mem_ptr);
565 }
566 #endif /* PNG_USER_MEM_SUPPORTED */