apps/png/libpng/pngmem.c

Go to the documentation of this file.
00001 
00002 /* pngmem.c - stub functions for memory allocation
00003  *
00004  * libpng version 1.2.8 - December 3, 2004
00005  * For conditions of distribution and use, see copyright notice in png.h
00006  * Copyright (c) 1998-2004 Glenn Randers-Pehrson
00007  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00008  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00009  *
00010  * This file provides a location for all memory allocation.  Users who
00011  * need special memory handling are expected to supply replacement
00012  * functions for png_malloc() and png_free(), and to use
00013  * png_create_read_struct_2() and png_create_write_struct_2() to
00014  * identify the replacement functions.
00015  */
00016 
00017 #define PNG_INTERNAL
00018 #include "png.h"
00019 
00020 /* Borland DOS special memory handler */
00021 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
00022 /* if you change this, be sure to change the one in png.h also */
00023 
00024 /* Allocate memory for a png_struct.  The malloc and memset can be replaced
00025    by a single call to calloc() if this is thought to improve performance. */
00026 png_voidp /* PRIVATE */
00027 png_create_struct(int type)
00028 {
00029 #ifdef PNG_USER_MEM_SUPPORTED
00030    return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
00031 }
00032 
00033 /* Alternate version of png_create_struct, for use with user-defined malloc. */
00034 png_voidp /* PRIVATE */
00035 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
00036 {
00037 #endif /* PNG_USER_MEM_SUPPORTED */
00038    png_size_t size;
00039    png_voidp struct_ptr;
00040 
00041    if (type == PNG_STRUCT_INFO)
00042      size = png_sizeof(png_info);
00043    else if (type == PNG_STRUCT_PNG)
00044      size = png_sizeof(png_struct);
00045    else
00046      return (png_get_copyright(NULL));
00047 
00048 #ifdef PNG_USER_MEM_SUPPORTED
00049    if(malloc_fn != NULL)
00050    {
00051       png_struct dummy_struct;
00052       png_structp png_ptr = &dummy_struct;
00053       png_ptr->mem_ptr=mem_ptr;
00054       struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
00055    }
00056    else
00057 #endif /* PNG_USER_MEM_SUPPORTED */
00058       struct_ptr = (png_voidp)farmalloc(size);
00059    if (struct_ptr != NULL)
00060       png_memset(struct_ptr, 0, size);
00061    return (struct_ptr);
00062 }
00063 
00064 /* Free memory allocated by a png_create_struct() call */
00065 void /* PRIVATE */
00066 png_destroy_struct(png_voidp struct_ptr)
00067 {
00068 #ifdef PNG_USER_MEM_SUPPORTED
00069    png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
00070 }
00071 
00072 /* Free memory allocated by a png_create_struct() call */
00073 void /* PRIVATE */
00074 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
00075     png_voidp mem_ptr)
00076 {
00077 #endif
00078    if (struct_ptr != NULL)
00079    {
00080 #ifdef PNG_USER_MEM_SUPPORTED
00081       if(free_fn != NULL)
00082       {
00083          png_struct dummy_struct;
00084          png_structp png_ptr = &dummy_struct;
00085          png_ptr->mem_ptr=mem_ptr;
00086          (*(free_fn))(png_ptr, struct_ptr);
00087          return;
00088       }
00089 #endif /* PNG_USER_MEM_SUPPORTED */
00090       farfree (struct_ptr);
00091    }
00092 }
00093 
00094 /* Allocate memory.  For reasonable files, size should never exceed
00095  * 64K.  However, zlib may allocate more then 64K if you don't tell
00096  * it not to.  See zconf.h and png.h for more information. zlib does
00097  * need to allocate exactly 64K, so whatever you call here must
00098  * have the ability to do that.
00099  *
00100  * Borland seems to have a problem in DOS mode for exactly 64K.
00101  * It gives you a segment with an offset of 8 (perhaps to store its
00102  * memory stuff).  zlib doesn't like this at all, so we have to
00103  * detect and deal with it.  This code should not be needed in
00104  * Windows or OS/2 modes, and only in 16 bit mode.  This code has
00105  * been updated by Alexander Lehmann for version 0.89 to waste less
00106  * memory.
00107  *
00108  * Note that we can't use png_size_t for the "size" declaration,
00109  * since on some systems a png_size_t is a 16-bit quantity, and as a
00110  * result, we would be truncating potentially larger memory requests
00111  * (which should cause a fatal error) and introducing major problems.
00112  */
00113 
00114 png_voidp PNGAPI
00115 png_malloc(png_structp png_ptr, png_uint_32 size)
00116 {
00117    png_voidp ret;
00118 
00119    if (png_ptr == NULL || size == 0)
00120       return (NULL);
00121 
00122 #ifdef PNG_USER_MEM_SUPPORTED
00123    if(png_ptr->malloc_fn != NULL)
00124        ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
00125    else
00126        ret = (png_malloc_default(png_ptr, size));
00127    if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00128        png_error(png_ptr, "Out of memory!");
00129    return (ret);
00130 }
00131 
00132 png_voidp PNGAPI
00133 png_malloc_default(png_structp png_ptr, png_uint_32 size)
00134 {
00135    png_voidp ret;
00136 #endif /* PNG_USER_MEM_SUPPORTED */
00137 
00138 #ifdef PNG_MAX_MALLOC_64K
00139    if (size > (png_uint_32)65536L)
00140    {
00141       png_warning(png_ptr, "Cannot Allocate > 64K");
00142       ret = NULL;
00143    }
00144    else
00145 #endif
00146 
00147    if (size != (size_t)size)
00148      ret = NULL;
00149    else if (size == (png_uint_32)65536L)
00150    {
00151       if (png_ptr->offset_table == NULL)
00152       {
00153          /* try to see if we need to do any of this fancy stuff */
00154          ret = farmalloc(size);
00155          if (ret == NULL || ((png_size_t)ret & 0xffff))
00156          {
00157             int num_blocks;
00158             png_uint_32 total_size;
00159             png_bytep table;
00160             int i;
00161             png_byte huge * hptr;
00162 
00163             if (ret != NULL)
00164             {
00165                farfree(ret);
00166                ret = NULL;
00167             }
00168 
00169             if(png_ptr->zlib_window_bits > 14)
00170                num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
00171             else
00172                num_blocks = 1;
00173             if (png_ptr->zlib_mem_level >= 7)
00174                num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
00175             else
00176                num_blocks++;
00177 
00178             total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
00179 
00180             table = farmalloc(total_size);
00181 
00182             if (table == NULL)
00183             {
00184 #ifndef PNG_USER_MEM_SUPPORTED
00185                if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00186                   png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
00187                else
00188                   png_warning(png_ptr, "Out Of Memory.");
00189 #endif
00190                return (NULL);
00191             }
00192 
00193             if ((png_size_t)table & 0xfff0)
00194             {
00195 #ifndef PNG_USER_MEM_SUPPORTED
00196                if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00197                   png_error(png_ptr,
00198                     "Farmalloc didn't return normalized pointer");
00199                else
00200                   png_warning(png_ptr,
00201                     "Farmalloc didn't return normalized pointer");
00202 #endif
00203                return (NULL);
00204             }
00205 
00206             png_ptr->offset_table = table;
00207             png_ptr->offset_table_ptr = farmalloc(num_blocks *
00208                png_sizeof (png_bytep));
00209 
00210             if (png_ptr->offset_table_ptr == NULL)
00211             {
00212 #ifndef PNG_USER_MEM_SUPPORTED
00213                if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00214                   png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
00215                else
00216                   png_warning(png_ptr, "Out Of memory.");
00217 #endif
00218                return (NULL);
00219             }
00220 
00221             hptr = (png_byte huge *)table;
00222             if ((png_size_t)hptr & 0xf)
00223             {
00224                hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
00225                hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
00226             }
00227             for (i = 0; i < num_blocks; i++)
00228             {
00229                png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
00230                hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
00231             }
00232 
00233             png_ptr->offset_table_number = num_blocks;
00234             png_ptr->offset_table_count = 0;
00235             png_ptr->offset_table_count_free = 0;
00236          }
00237       }
00238 
00239       if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
00240       {
00241 #ifndef PNG_USER_MEM_SUPPORTED
00242          if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00243             png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
00244          else
00245             png_warning(png_ptr, "Out of Memory.");
00246 #endif
00247          return (NULL);
00248       }
00249 
00250       ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
00251    }
00252    else
00253       ret = farmalloc(size);
00254 
00255 #ifndef PNG_USER_MEM_SUPPORTED
00256    if (ret == NULL)
00257    {
00258       if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00259          png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
00260       else
00261          png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
00262    }
00263 #endif
00264 
00265    return (ret);
00266 }
00267 
00268 /* free a pointer allocated by png_malloc().  In the default
00269    configuration, png_ptr is not used, but is passed in case it
00270    is needed.  If ptr is NULL, return without taking any action. */
00271 void PNGAPI
00272 png_free(png_structp png_ptr, png_voidp ptr)
00273 {
00274    if (png_ptr == NULL || ptr == NULL)
00275       return;
00276 
00277 #ifdef PNG_USER_MEM_SUPPORTED
00278    if (png_ptr->free_fn != NULL)
00279    {
00280       (*(png_ptr->free_fn))(png_ptr, ptr);
00281       return;
00282    }
00283    else png_free_default(png_ptr, ptr);
00284 }
00285 
00286 void PNGAPI
00287 png_free_default(png_structp png_ptr, png_voidp ptr)
00288 {
00289 #endif /* PNG_USER_MEM_SUPPORTED */
00290 
00291    if (png_ptr->offset_table != NULL)
00292    {
00293       int i;
00294 
00295       for (i = 0; i < png_ptr->offset_table_count; i++)
00296       {
00297          if (ptr == png_ptr->offset_table_ptr[i])
00298          {
00299             ptr = NULL;
00300             png_ptr->offset_table_count_free++;
00301             break;
00302          }
00303       }
00304       if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
00305       {
00306          farfree(png_ptr->offset_table);
00307          farfree(png_ptr->offset_table_ptr);
00308          png_ptr->offset_table = NULL;
00309          png_ptr->offset_table_ptr = NULL;
00310       }
00311    }
00312 
00313    if (ptr != NULL)
00314    {
00315       farfree(ptr);
00316    }
00317 }
00318 
00319 #else /* Not the Borland DOS special memory handler */
00320 
00321 /* Allocate memory for a png_struct or a png_info.  The malloc and
00322    memset can be replaced by a single call to calloc() if this is thought
00323    to improve performance noticably. */
00324 png_voidp /* PRIVATE */
00325 png_create_struct(int type)
00326 {
00327 #ifdef PNG_USER_MEM_SUPPORTED
00328    return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
00329 }
00330 
00331 /* Allocate memory for a png_struct or a png_info.  The malloc and
00332    memset can be replaced by a single call to calloc() if this is thought
00333    to improve performance noticably. */
00334 png_voidp /* PRIVATE */
00335 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
00336 {
00337 #endif /* PNG_USER_MEM_SUPPORTED */
00338    png_size_t size;
00339    png_voidp struct_ptr;
00340 
00341    if (type == PNG_STRUCT_INFO)
00342       size = png_sizeof(png_info);
00343    else if (type == PNG_STRUCT_PNG)
00344       size = png_sizeof(png_struct);
00345    else
00346       return (NULL);
00347 
00348 #ifdef PNG_USER_MEM_SUPPORTED
00349    if(malloc_fn != NULL)
00350    {
00351       png_struct dummy_struct;
00352       png_structp png_ptr = &dummy_struct;
00353       png_ptr->mem_ptr=mem_ptr;
00354       struct_ptr = (*(malloc_fn))(png_ptr, size);
00355       if (struct_ptr != NULL)
00356          png_memset(struct_ptr, 0, size);
00357       return (struct_ptr);
00358    }
00359 #endif /* PNG_USER_MEM_SUPPORTED */
00360 
00361 #if defined(__TURBOC__) && !defined(__FLAT__)
00362    struct_ptr = (png_voidp)farmalloc(size);
00363 #else
00364 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00365    struct_ptr = (png_voidp)halloc(size,1);
00366 # else
00367    struct_ptr = (png_voidp)malloc(size);
00368 # endif
00369 #endif
00370    if (struct_ptr != NULL)
00371       png_memset(struct_ptr, 0, size);
00372 
00373    return (struct_ptr);
00374 }
00375 
00376 
00377 /* Free memory allocated by a png_create_struct() call */
00378 void /* PRIVATE */
00379 png_destroy_struct(png_voidp struct_ptr)
00380 {
00381 #ifdef PNG_USER_MEM_SUPPORTED
00382    png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
00383 }
00384 
00385 /* Free memory allocated by a png_create_struct() call */
00386 void /* PRIVATE */
00387 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
00388     png_voidp mem_ptr)
00389 {
00390 #endif /* PNG_USER_MEM_SUPPORTED */
00391    if (struct_ptr != NULL)
00392    {
00393 #ifdef PNG_USER_MEM_SUPPORTED
00394       if(free_fn != NULL)
00395       {
00396          png_struct dummy_struct;
00397          png_structp png_ptr = &dummy_struct;
00398          png_ptr->mem_ptr=mem_ptr;
00399          (*(free_fn))(png_ptr, struct_ptr);
00400          return;
00401       }
00402 #endif /* PNG_USER_MEM_SUPPORTED */
00403 #if defined(__TURBOC__) && !defined(__FLAT__)
00404       farfree(struct_ptr);
00405 #else
00406 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00407       hfree(struct_ptr);
00408 # else
00409       free(struct_ptr);
00410 # endif
00411 #endif
00412    }
00413 }
00414 
00415 /* Allocate memory.  For reasonable files, size should never exceed
00416    64K.  However, zlib may allocate more then 64K if you don't tell
00417    it not to.  See zconf.h and png.h for more information.  zlib does
00418    need to allocate exactly 64K, so whatever you call here must
00419    have the ability to do that. */
00420 
00421 png_voidp PNGAPI
00422 png_malloc(png_structp png_ptr, png_uint_32 size)
00423 {
00424    png_voidp ret;
00425 
00426 #ifdef PNG_USER_MEM_SUPPORTED
00427    if (png_ptr == NULL || size == 0)
00428       return (NULL);
00429 
00430    if(png_ptr->malloc_fn != NULL)
00431        ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
00432    else
00433        ret = (png_malloc_default(png_ptr, size));
00434    if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00435        png_error(png_ptr, "Out of Memory!");
00436    return (ret);
00437 }
00438 
00439 png_voidp PNGAPI
00440 png_malloc_default(png_structp png_ptr, png_uint_32 size)
00441 {
00442    png_voidp ret;
00443 #endif /* PNG_USER_MEM_SUPPORTED */
00444 
00445    if (png_ptr == NULL || size == 0)
00446       return (NULL);
00447 
00448 #ifdef PNG_MAX_MALLOC_64K
00449    if (size > (png_uint_32)65536L)
00450    {
00451 #ifndef PNG_USER_MEM_SUPPORTED
00452       if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00453          png_error(png_ptr, "Cannot Allocate > 64K");
00454       else
00455 #endif
00456          return NULL;
00457    }
00458 #endif
00459 
00460  /* Check for overflow */
00461 #if defined(__TURBOC__) && !defined(__FLAT__)
00462  if (size != (unsigned long)size)
00463    ret = NULL;
00464  else
00465    ret = farmalloc(size);
00466 #else
00467 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00468  if (size != (unsigned long)size)
00469    ret = NULL;
00470  else
00471    ret = halloc(size, 1);
00472 # else
00473  if (size != (size_t)size)
00474    ret = NULL;
00475  else
00476    ret = malloc((size_t)size);
00477 # endif
00478 #endif
00479 
00480 #ifndef PNG_USER_MEM_SUPPORTED
00481    if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
00482       png_error(png_ptr, "Out of Memory");
00483 #endif
00484 
00485    return (ret);
00486 }
00487 
00488 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
00489    without taking any action. */
00490 void PNGAPI
00491 png_free(png_structp png_ptr, png_voidp ptr)
00492 {
00493    if (png_ptr == NULL || ptr == NULL)
00494       return;
00495 
00496 #ifdef PNG_USER_MEM_SUPPORTED
00497    if (png_ptr->free_fn != NULL)
00498    {
00499       (*(png_ptr->free_fn))(png_ptr, ptr);
00500       return;
00501    }
00502    else png_free_default(png_ptr, ptr);
00503 }
00504 void PNGAPI
00505 png_free_default(png_structp png_ptr, png_voidp ptr)
00506 {
00507    if (png_ptr == NULL || ptr == NULL)
00508       return;
00509 
00510 #endif /* PNG_USER_MEM_SUPPORTED */
00511 
00512 #if defined(__TURBOC__) && !defined(__FLAT__)
00513    farfree(ptr);
00514 #else
00515 # if defined(_MSC_VER) && defined(MAXSEG_64K)
00516    hfree(ptr);
00517 # else
00518    free(ptr);
00519 # endif
00520 #endif
00521 }
00522 
00523 #endif /* Not Borland DOS special memory handler */
00524 
00525 #if defined(PNG_1_0_X)
00526 #  define png_malloc_warn png_malloc
00527 #else
00528 /* This function was added at libpng version 1.2.3.  The png_malloc_warn()
00529  * function will set up png_malloc() to issue a png_warning and return NULL
00530  * instead of issuing a png_error, if it fails to allocate the requested
00531  * memory.
00532  */
00533 png_voidp PNGAPI
00534 png_malloc_warn(png_structp png_ptr, png_uint_32 size)
00535 {
00536    png_voidp ptr;
00537    png_uint_32 save_flags=png_ptr->flags;
00538 
00539    png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
00540    ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
00541    png_ptr->flags=save_flags;
00542    return(ptr);
00543 }
00544 #endif
00545 
00546 png_voidp PNGAPI
00547 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
00548    png_uint_32 length)
00549 {
00550    png_size_t size;
00551 
00552    size = (png_size_t)length;
00553    if ((png_uint_32)size != length)
00554       png_error(png_ptr,"Overflow in png_memcpy_check.");
00555 
00556    return(png_memcpy (s1, s2, size));
00557 }
00558 
00559 png_voidp PNGAPI
00560 png_memset_check (png_structp png_ptr, png_voidp s1, int value,
00561    png_uint_32 length)
00562 {
00563    png_size_t size;
00564 
00565    size = (png_size_t)length;
00566    if ((png_uint_32)size != length)
00567       png_error(png_ptr,"Overflow in png_memset_check.");
00568 
00569    return (png_memset (s1, value, size));
00570 
00571 }
00572 
00573 #ifdef PNG_USER_MEM_SUPPORTED
00574 /* This function is called when the application wants to use another method
00575  * of allocating and freeing memory.
00576  */
00577 void PNGAPI
00578 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
00579   malloc_fn, png_free_ptr free_fn)
00580 {
00581    png_ptr->mem_ptr = mem_ptr;
00582    png_ptr->malloc_fn = malloc_fn;
00583    png_ptr->free_fn = free_fn;
00584 }
00585 
00586 /* This function returns a pointer to the mem_ptr associated with the user
00587  * functions.  The application should free any memory associated with this
00588  * pointer before png_write_destroy and png_read_destroy are called.
00589  */
00590 png_voidp PNGAPI
00591 png_get_mem_ptr(png_structp png_ptr)
00592 {
00593    return ((png_voidp)png_ptr->mem_ptr);
00594 }
00595 #endif /* PNG_USER_MEM_SUPPORTED */

Generated on Fri Nov 28 00:06:22 2008 for elphel by  doxygen 1.5.1