source: trunk/third/libpng/pngmem.c @ 17001

Revision 17001, 13.9 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17000, which included commits to RCS files with non-trunk default branches.
Line 
1
2/* pngmem.c - stub functions for memory allocation
3 *
4 * libpng 1.2.1 - December 12, 2001
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2001 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. */
26png_voidp /* PRIVATE */
27png_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. */
34png_voidp /* PRIVATE */
35png_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 (NULL);
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 */
65void /* PRIVATE */
66png_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 */
73void /* PRIVATE */
74png_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 */
113png_voidp PNGAPI
114png_malloc(png_structp png_ptr, png_uint_32 size)
115{
116#ifndef PNG_USER_MEM_SUPPORTED
117   png_voidp ret;
118#endif
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)
127          png_error(png_ptr, "Out of memory!");
128       return (ret);
129   }
130   else
131       return png_malloc_default(png_ptr, size);
132}
133
134png_voidp PNGAPI
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
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               png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
181            }
182
183            if ((png_size_t)table & 0xfff0)
184            {
185               png_error(png_ptr, "Farmalloc didn't return normalized pointer");
186            }
187
188            png_ptr->offset_table = table;
189            png_ptr->offset_table_ptr = farmalloc(num_blocks *
190               sizeof (png_bytep));
191
192            if (png_ptr->offset_table_ptr == NULL)
193            {
194               png_error(png_ptr, "Out Of memory.");
195            }
196
197            hptr = (png_byte huge *)table;
198            if ((png_size_t)hptr & 0xf)
199            {
200               hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
201               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
202            }
203            for (i = 0; i < num_blocks; i++)
204            {
205               png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
206               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
207            }
208
209            png_ptr->offset_table_number = num_blocks;
210            png_ptr->offset_table_count = 0;
211            png_ptr->offset_table_count_free = 0;
212         }
213      }
214
215      if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
216         png_error(png_ptr, "Out of Memory.");
217
218      ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
219   }
220   else
221      ret = farmalloc(size);
222
223   if (ret == NULL)
224   {
225      png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
226   }
227
228   return (ret);
229}
230
231/* free a pointer allocated by png_malloc().  In the default
232   configuration, png_ptr is not used, but is passed in case it
233   is needed.  If ptr is NULL, return without taking any action. */
234void PNGAPI
235png_free(png_structp png_ptr, png_voidp ptr)
236{
237   if (png_ptr == NULL || ptr == NULL)
238      return;
239
240#ifdef PNG_USER_MEM_SUPPORTED
241   if (png_ptr->free_fn != NULL)
242   {
243      (*(png_ptr->free_fn))(png_ptr, ptr);
244      return;
245   }
246   else png_free_default(png_ptr, ptr);
247}
248
249void PNGAPI
250png_free_default(png_structp png_ptr, png_voidp ptr)
251{
252#endif /* PNG_USER_MEM_SUPPORTED */
253
254   if (png_ptr->offset_table != NULL)
255   {
256      int i;
257
258      for (i = 0; i < png_ptr->offset_table_count; i++)
259      {
260         if (ptr == png_ptr->offset_table_ptr[i])
261         {
262            ptr = NULL;
263            png_ptr->offset_table_count_free++;
264            break;
265         }
266      }
267      if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
268      {
269         farfree(png_ptr->offset_table);
270         farfree(png_ptr->offset_table_ptr);
271         png_ptr->offset_table = NULL;
272         png_ptr->offset_table_ptr = NULL;
273      }
274   }
275
276   if (ptr != NULL)
277   {
278      farfree(ptr);
279   }
280}
281
282#else /* Not the Borland DOS special memory handler */
283
284/* Allocate memory for a png_struct or a png_info.  The malloc and
285   memset can be replaced by a single call to calloc() if this is thought
286   to improve performance noticably.*/
287png_voidp /* PRIVATE */
288png_create_struct(int type)
289{
290#ifdef PNG_USER_MEM_SUPPORTED
291   return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
292}
293
294/* Allocate memory for a png_struct or a png_info.  The malloc and
295   memset can be replaced by a single call to calloc() if this is thought
296   to improve performance noticably.*/
297png_voidp /* PRIVATE */
298png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
299{
300#endif /* PNG_USER_MEM_SUPPORTED */
301   png_size_t size;
302   png_voidp struct_ptr;
303
304   if (type == PNG_STRUCT_INFO)
305      size = sizeof(png_info);
306   else if (type == PNG_STRUCT_PNG)
307      size = sizeof(png_struct);
308   else
309      return (NULL);
310
311#ifdef PNG_USER_MEM_SUPPORTED
312   if(malloc_fn != NULL)
313   {
314      png_struct dummy_struct;
315      png_structp png_ptr = &dummy_struct;
316      png_ptr->mem_ptr=mem_ptr;
317      struct_ptr = (*(malloc_fn))(png_ptr, size);
318      if (struct_ptr != NULL)
319         png_memset(struct_ptr, 0, size);
320      return (struct_ptr);
321   }
322#endif /* PNG_USER_MEM_SUPPORTED */
323
324#if defined(__TURBOC__) && !defined(__FLAT__)
325   if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
326#else
327# if defined(_MSC_VER) && defined(MAXSEG_64K)
328   if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
329# else
330   if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
331# endif
332#endif
333   {
334      png_memset(struct_ptr, 0, size);
335   }
336
337   return (struct_ptr);
338}
339
340
341/* Free memory allocated by a png_create_struct() call */
342void /* PRIVATE */
343png_destroy_struct(png_voidp struct_ptr)
344{
345#ifdef PNG_USER_MEM_SUPPORTED
346   png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
347}
348
349/* Free memory allocated by a png_create_struct() call */
350void /* PRIVATE */
351png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
352    png_voidp mem_ptr)
353{
354#endif /* PNG_USER_MEM_SUPPORTED */
355   if (struct_ptr != NULL)
356   {
357#ifdef PNG_USER_MEM_SUPPORTED
358      if(free_fn != NULL)
359      {
360         png_struct dummy_struct;
361         png_structp png_ptr = &dummy_struct;
362         png_ptr->mem_ptr=mem_ptr;
363         (*(free_fn))(png_ptr, struct_ptr);
364         return;
365      }
366#endif /* PNG_USER_MEM_SUPPORTED */
367#if defined(__TURBOC__) && !defined(__FLAT__)
368      farfree(struct_ptr);
369#else
370# if defined(_MSC_VER) && defined(MAXSEG_64K)
371      hfree(struct_ptr);
372# else
373      free(struct_ptr);
374# endif
375#endif
376   }
377}
378
379
380/* Allocate memory.  For reasonable files, size should never exceed
381   64K.  However, zlib may allocate more then 64K if you don't tell
382   it not to.  See zconf.h and png.h for more information.  zlib does
383   need to allocate exactly 64K, so whatever you call here must
384   have the ability to do that. */
385
386png_voidp PNGAPI
387png_malloc(png_structp png_ptr, png_uint_32 size)
388{
389   png_voidp ret;
390   if (png_ptr == NULL || size == 0)
391      return (NULL);
392
393#ifdef PNG_USER_MEM_SUPPORTED
394   if(png_ptr->malloc_fn != NULL)
395   {
396       ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
397       if (ret == NULL)
398          png_error(png_ptr, "Out of Memory!");
399       return (ret);
400   }
401   else
402       return (png_malloc_default(png_ptr, size));
403}
404png_voidp /* PRIVATE */
405png_malloc_default(png_structp png_ptr, png_uint_32 size)
406{
407   png_voidp ret;
408#endif /* PNG_USER_MEM_SUPPORTED */
409
410#ifdef PNG_MAX_MALLOC_64K
411   if (size > (png_uint_32)65536L)
412      png_error(png_ptr, "Cannot Allocate > 64K");
413#endif
414
415#if defined(__TURBOC__) && !defined(__FLAT__)
416   ret = farmalloc(size);
417#else
418# if defined(_MSC_VER) && defined(MAXSEG_64K)
419   ret = halloc(size, 1);
420# else
421   ret = malloc((size_t)size);
422# endif
423#endif
424
425   if (ret == NULL)
426      png_error(png_ptr, "Out of Memory");
427
428   return (ret);
429}
430
431/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
432   without taking any action. */
433void PNGAPI
434png_free(png_structp png_ptr, png_voidp ptr)
435{
436   if (png_ptr == NULL || ptr == NULL)
437      return;
438
439#ifdef PNG_USER_MEM_SUPPORTED
440   if (png_ptr->free_fn != NULL)
441   {
442      (*(png_ptr->free_fn))(png_ptr, ptr);
443      return;
444   }
445   else png_free_default(png_ptr, ptr);
446}
447void /* PRIVATE */
448png_free_default(png_structp png_ptr, png_voidp ptr)
449{
450   if (png_ptr == NULL || ptr == NULL)
451      return;
452
453#endif /* PNG_USER_MEM_SUPPORTED */
454
455#if defined(__TURBOC__) && !defined(__FLAT__)
456   farfree(ptr);
457#else
458# if defined(_MSC_VER) && defined(MAXSEG_64K)
459   hfree(ptr);
460# else
461   free(ptr);
462# endif
463#endif
464}
465
466#endif /* Not Borland DOS special memory handler */
467
468png_voidp /* PRIVATE */
469png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
470   png_uint_32 length)
471{
472   png_size_t size;
473
474   size = (png_size_t)length;
475   if ((png_uint_32)size != length)
476      png_error(png_ptr,"Overflow in png_memcpy_check.");
477
478   return(png_memcpy (s1, s2, size));
479}
480
481png_voidp /* PRIVATE */
482png_memset_check (png_structp png_ptr, png_voidp s1, int value,
483   png_uint_32 length)
484{
485   png_size_t size;
486
487   size = (png_size_t)length;
488   if ((png_uint_32)size != length)
489      png_error(png_ptr,"Overflow in png_memset_check.");
490
491   return (png_memset (s1, value, size));
492
493}
494
495#ifdef PNG_USER_MEM_SUPPORTED
496/* This function is called when the application wants to use another method
497 * of allocating and freeing memory.
498 */
499void PNGAPI
500png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
501  malloc_fn, png_free_ptr free_fn)
502{
503   png_ptr->mem_ptr = mem_ptr;
504   png_ptr->malloc_fn = malloc_fn;
505   png_ptr->free_fn = free_fn;
506}
507
508/* This function returns a pointer to the mem_ptr associated with the user
509 * functions.  The application should free any memory associated with this
510 * pointer before png_write_destroy and png_read_destroy are called.
511 */
512png_voidp PNGAPI
513png_get_mem_ptr(png_structp png_ptr)
514{
515   return ((png_voidp)png_ptr->mem_ptr);
516}
517#endif /* PNG_USER_MEM_SUPPORTED */
Note: See TracBrowser for help on using the repository browser.