Home | History | Annotate | Download | only in lpng_v163
      1 /* pngmem.c - stub functions for memory allocation
      2  *
      3  * Last changed in libpng 1.6.0 [February 14, 2013]
      4  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
      5  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
      6  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      7  *
      8  * This code is released under the libpng license.
      9  * For conditions of distribution and use, see the disclaimer
     10  * and license in png.h
     11  *
     12  * This file provides a location for all memory allocation.  Users who
     13  * need special memory handling are expected to supply replacement
     14  * functions for png_malloc() and png_free(), and to use
     15  * png_create_read_struct_2() and png_create_write_struct_2() to
     16  * identify the replacement functions.
     17  */
     18 
     19 #include "pngpriv.h"
     20 
     21 #if defined(_FX_MANAGED_CODE_) && defined(__cplusplus)
     22 extern "C" {
     23 #endif
     24 
     25 void*	FXMEM_DefaultAlloc(int byte_size, int);
     26 void	FXMEM_DefaultFree(void* pointer, int);
     27 
     28 #if defined(_FX_MANAGED_CODE_) && defined(__cplusplus)
     29 }
     30 #endif
     31 
     32 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
     33 /* Free a png_struct */
     34 void /* PRIVATE */
     35 png_destroy_png_struct(png_structrp png_ptr)
     36 {
     37    if (png_ptr != NULL)
     38    {
     39       /* png_free might call png_error and may certainly call
     40        * png_get_mem_ptr, so fake a temporary png_struct to support this.
     41        */
     42       png_struct dummy_struct = *png_ptr;
     43       memset(png_ptr, 0, (sizeof *png_ptr));
     44       png_free(&dummy_struct, png_ptr);
     45 
     46 #     ifdef PNG_SETJMP_SUPPORTED
     47          /* We may have a jmp_buf left to deallocate. */
     48          png_free_jmpbuf(&dummy_struct);
     49 #     endif
     50    }
     51 }
     52 
     53 /* Allocate memory.  For reasonable files, size should never exceed
     54  * 64K.  However, zlib may allocate more then 64K if you don't tell
     55  * it not to.  See zconf.h and png.h for more information.  zlib does
     56  * need to allocate exactly 64K, so whatever you call here must
     57  * have the ability to do that.
     58  */
     59 PNG_FUNCTION(png_voidp,PNGAPI
     60 png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
     61 {
     62    png_voidp ret;
     63 
     64    ret = png_malloc(png_ptr, size);
     65 
     66    if (ret != NULL)
     67       memset(ret, 0, size);
     68 
     69    return ret;
     70 }
     71 
     72 /* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
     73  * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
     74  * Checking and error handling must happen outside this routine; it returns NULL
     75  * if the allocation cannot be done (for any reason.)
     76  */
     77 PNG_FUNCTION(png_voidp /* PRIVATE */,
     78 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
     79    PNG_ALLOCATED)
     80 {
     81    /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
     82     * allocators have also been removed in 1.6.0, so any 16-bit system now has
     83     * to implement a user memory handler.  This checks to be sure it isn't
     84     * called with big numbers.
     85     */
     86 #ifdef PNG_USER_MEM_SUPPORTED
     87    PNG_UNUSED(png_ptr)
     88 #endif
     89    if (size > 0 && size <= PNG_SIZE_MAX
     90 #     ifdef PNG_MAX_MALLOC_64K
     91          && size <= 65536U
     92 #     endif
     93       )
     94    {
     95 #ifdef PNG_USER_MEM_SUPPORTED
     96       if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
     97          return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
     98 
     99       else
    100 #endif
    101          return FXMEM_DefaultAlloc((int)size, 0);
    102          //return malloc((size_t)size); /* checked for truncation above */
    103    }
    104 
    105    else
    106       return NULL;
    107 }
    108 
    109 /* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
    110  * that arises because of the checks in png_realloc_array that are repeated in
    111  * png_malloc_array.
    112  */
    113 static png_voidp
    114 png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
    115    size_t element_size)
    116 {
    117    png_alloc_size_t req = nelements; /* known to be > 0 */
    118 
    119    if (req <= PNG_SIZE_MAX/element_size)
    120       return png_malloc_base(png_ptr, req * element_size);
    121 
    122    /* The failure case when the request is too large */
    123    return NULL;
    124 }
    125 
    126 PNG_FUNCTION(png_voidp /* PRIVATE */,
    127 png_malloc_array,(png_const_structrp png_ptr, int nelements,
    128    size_t element_size),PNG_ALLOCATED)
    129 {
    130    if (nelements <= 0 || element_size == 0)
    131       png_error(png_ptr, "internal error: array alloc");
    132 
    133    return png_malloc_array_checked(png_ptr, nelements, element_size);
    134 }
    135 
    136 PNG_FUNCTION(png_voidp /* PRIVATE */,
    137 png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
    138    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
    139 {
    140    /* These are internal errors: */
    141    if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
    142       (old_array == NULL && old_elements > 0))
    143       png_error(png_ptr, "internal error: array realloc");
    144 
    145    /* Check for overflow on the elements count (so the caller does not have to
    146     * check.)
    147     */
    148    if (add_elements <= INT_MAX - old_elements)
    149    {
    150       png_voidp new_array = png_malloc_array_checked(png_ptr,
    151          old_elements+add_elements, element_size);
    152 
    153       if (new_array != NULL)
    154       {
    155          /* Because png_malloc_array worked the size calculations below cannot
    156           * overflow.
    157           */
    158          if (old_elements > 0)
    159             memcpy(new_array, old_array, element_size*(unsigned)old_elements);
    160 
    161          memset((char*)new_array + element_size*(unsigned)old_elements, 0,
    162             element_size*(unsigned)add_elements);
    163 
    164          return new_array;
    165       }
    166    }
    167 
    168    return NULL; /* error */
    169 }
    170 
    171 /* Various functions that have different error handling are derived from this.
    172  * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
    173  * function png_malloc_default is also provided.
    174  */
    175 PNG_FUNCTION(png_voidp,PNGAPI
    176 png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
    177 {
    178    png_voidp ret;
    179 
    180    if (png_ptr == NULL)
    181       return NULL;
    182 
    183    ret = png_malloc_base(png_ptr, size);
    184 
    185    if (ret == NULL)
    186        png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
    187 
    188    return ret;
    189 }
    190 
    191 #ifdef PNG_USER_MEM_SUPPORTED
    192 PNG_FUNCTION(png_voidp,PNGAPI
    193 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
    194    PNG_ALLOCATED PNG_DEPRECATED)
    195 {
    196    png_voidp ret;
    197 
    198    if (png_ptr == NULL)
    199       return NULL;
    200 
    201    /* Passing 'NULL' here bypasses the application provided memory handler. */
    202    ret = png_malloc_base(NULL/*use malloc*/, size);
    203 
    204    if (ret == NULL)
    205       png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
    206 
    207    return ret;
    208 }
    209 #endif /* PNG_USER_MEM_SUPPORTED */
    210 
    211 /* This function was added at libpng version 1.2.3.  The png_malloc_warn()
    212  * function will issue a png_warning and return NULL instead of issuing a
    213  * png_error, if it fails to allocate the requested memory.
    214  */
    215 PNG_FUNCTION(png_voidp,PNGAPI
    216 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
    217    PNG_ALLOCATED)
    218 {
    219    if (png_ptr != NULL)
    220    {
    221       png_voidp ret = png_malloc_base(png_ptr, size);
    222 
    223       if (ret != NULL)
    224          return ret;
    225 
    226       png_warning(png_ptr, "Out of memory");
    227    }
    228 
    229    return NULL;
    230 }
    231 
    232 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
    233  * without taking any action.
    234  */
    235 void PNGAPI
    236 png_free(png_const_structrp png_ptr, png_voidp ptr)
    237 {
    238    if (png_ptr == NULL || ptr == NULL)
    239       return;
    240 
    241 #ifdef PNG_USER_MEM_SUPPORTED
    242    if (png_ptr->free_fn != NULL)
    243       png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
    244 
    245    else
    246       png_free_default(png_ptr, ptr);
    247 }
    248 
    249 PNG_FUNCTION(void,PNGAPI
    250 png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
    251 {
    252    if (png_ptr == NULL || ptr == NULL)
    253       return;
    254 #endif /* PNG_USER_MEM_SUPPORTED */
    255 
    256    FXMEM_DefaultFree(ptr, 0);
    257    //free(ptr);
    258 }
    259 
    260 #ifdef PNG_USER_MEM_SUPPORTED
    261 /* This function is called when the application wants to use another method
    262  * of allocating and freeing memory.
    263  */
    264 void PNGAPI
    265 png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
    266   malloc_fn, png_free_ptr free_fn)
    267 {
    268    if (png_ptr != NULL)
    269    {
    270       png_ptr->mem_ptr = mem_ptr;
    271       png_ptr->malloc_fn = malloc_fn;
    272       png_ptr->free_fn = free_fn;
    273    }
    274 }
    275 
    276 /* This function returns a pointer to the mem_ptr associated with the user
    277  * functions.  The application should free any memory associated with this
    278  * pointer before png_write_destroy and png_read_destroy are called.
    279  */
    280 png_voidp PNGAPI
    281 png_get_mem_ptr(png_const_structrp png_ptr)
    282 {
    283    if (png_ptr == NULL)
    284       return NULL;
    285 
    286    return png_ptr->mem_ptr;
    287 }
    288 #endif /* PNG_USER_MEM_SUPPORTED */
    289 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
    290