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