Home | History | Annotate | Download | only in libpng-1.2.19
      1 
      2 /* png.c - location for general purpose libpng functions
      3  *
      4  * Last changed in libpng 1.2.19 August 18, 2007
      5  * For conditions of distribution and use, see copyright notice in png.h
      6  * Copyright (c) 1998-2007 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 
     11 #define PNG_INTERNAL
     12 #define PNG_NO_EXTERN
     13 #include "png.h"
     14 
     15 /* Generate a compiler error if there is an old png.h in the search path. */
     16 typedef version_1_2_19 Your_png_h_is_not_version_1_2_19;
     17 
     18 /* Version information for C files.  This had better match the version
     19  * string defined in png.h.  */
     20 
     21 #ifdef PNG_USE_GLOBAL_ARRAYS
     22 /* png_libpng_ver was changed to a function in version 1.0.5c */
     23 PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
     24 
     25 #ifdef PNG_READ_SUPPORTED
     26 
     27 /* png_sig was changed to a function in version 1.0.5c */
     28 /* Place to hold the signature string for a PNG file. */
     29 PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
     30 #endif /* PNG_READ_SUPPORTED */
     31 
     32 /* Invoke global declarations for constant strings for known chunk types */
     33 PNG_IHDR;
     34 PNG_IDAT;
     35 PNG_IEND;
     36 PNG_PLTE;
     37 PNG_bKGD;
     38 PNG_cHRM;
     39 PNG_gAMA;
     40 PNG_hIST;
     41 PNG_iCCP;
     42 PNG_iTXt;
     43 PNG_oFFs;
     44 PNG_pCAL;
     45 PNG_sCAL;
     46 PNG_pHYs;
     47 PNG_sBIT;
     48 PNG_sPLT;
     49 PNG_sRGB;
     50 PNG_tEXt;
     51 PNG_tIME;
     52 PNG_tRNS;
     53 PNG_zTXt;
     54 
     55 #ifdef PNG_READ_SUPPORTED
     56 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
     57 
     58 /* start of interlace block */
     59 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
     60 
     61 /* offset to next interlace block */
     62 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
     63 
     64 /* start of interlace block in the y direction */
     65 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
     66 
     67 /* offset to next interlace block in the y direction */
     68 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
     69 
     70 /* width of interlace block (used in assembler routines only) */
     71 #if defined(PNG_HAVE_MMX_COMBINE_ROW) || defined(PNG_OPTIMIZED_CODE_SUPPORTED)
     72 PNG_CONST int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
     73 #endif
     74 
     75 /* Height of interlace block.  This is not currently used - if you need
     76  * it, uncomment it here and in png.h
     77 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
     78 */
     79 
     80 /* Mask to determine which pixels are valid in a pass */
     81 PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
     82 
     83 /* Mask to determine which pixels to overwrite while displaying */
     84 PNG_CONST int FARDATA png_pass_dsp_mask[]
     85    = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
     86 
     87 #endif /* PNG_READ_SUPPORTED */
     88 #endif /* PNG_USE_GLOBAL_ARRAYS */
     89 
     90 /* Tells libpng that we have already handled the first "num_bytes" bytes
     91  * of the PNG file signature.  If the PNG data is embedded into another
     92  * stream we can set num_bytes = 8 so that libpng will not attempt to read
     93  * or write any of the magic bytes before it starts on the IHDR.
     94  */
     95 
     96 #ifdef PNG_READ_SUPPORTED
     97 void PNGAPI
     98 png_set_sig_bytes(png_structp png_ptr, int num_bytes)
     99 {
    100    if(png_ptr == NULL) return;
    101    png_debug(1, "in png_set_sig_bytes\n");
    102    if (num_bytes > 8)
    103       png_error(png_ptr, "Too many bytes for PNG signature.");
    104 
    105    png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
    106 }
    107 
    108 /* Checks whether the supplied bytes match the PNG signature.  We allow
    109  * checking less than the full 8-byte signature so that those apps that
    110  * already read the first few bytes of a file to determine the file type
    111  * can simply check the remaining bytes for extra assurance.  Returns
    112  * an integer less than, equal to, or greater than zero if sig is found,
    113  * respectively, to be less than, to match, or be greater than the correct
    114  * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
    115  */
    116 int PNGAPI
    117 png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
    118 {
    119    png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    120    if (num_to_check > 8)
    121       num_to_check = 8;
    122    else if (num_to_check < 1)
    123       return (-1);
    124 
    125    if (start > 7)
    126       return (-1);
    127 
    128    if (start + num_to_check > 8)
    129       num_to_check = 8 - start;
    130 
    131    return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
    132 }
    133 
    134 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
    135 /* (Obsolete) function to check signature bytes.  It does not allow one
    136  * to check a partial signature.  This function might be removed in the
    137  * future - use png_sig_cmp().  Returns true (nonzero) if the file is PNG.
    138  */
    139 int PNGAPI
    140 png_check_sig(png_bytep sig, int num)
    141 {
    142   return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
    143 }
    144 #endif
    145 #endif /* PNG_READ_SUPPORTED */
    146 
    147 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    148 /* Function to allocate memory for zlib and clear it to 0. */
    149 #ifdef PNG_1_0_X
    150 voidpf PNGAPI
    151 #else
    152 voidpf /* private */
    153 #endif
    154 png_zalloc(voidpf png_ptr, uInt items, uInt size)
    155 {
    156    png_voidp ptr;
    157    png_structp p=(png_structp)png_ptr;
    158    png_uint_32 save_flags=p->flags;
    159    png_uint_32 num_bytes;
    160 
    161    if(png_ptr == NULL) return (NULL);
    162    if (items > PNG_UINT_32_MAX/size)
    163    {
    164      png_warning (p, "Potential overflow in png_zalloc()");
    165      return (NULL);
    166    }
    167    num_bytes = (png_uint_32)items * size;
    168 
    169    p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
    170    ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
    171    p->flags=save_flags;
    172 
    173 #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
    174    if (ptr == NULL)
    175        return ((voidpf)ptr);
    176 
    177    if (num_bytes > (png_uint_32)0x8000L)
    178    {
    179       png_memset(ptr, 0, (png_size_t)0x8000L);
    180       png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
    181          (png_size_t)(num_bytes - (png_uint_32)0x8000L));
    182    }
    183    else
    184    {
    185       png_memset(ptr, 0, (png_size_t)num_bytes);
    186    }
    187 #endif
    188    return ((voidpf)ptr);
    189 }
    190 
    191 /* function to free memory for zlib */
    192 #ifdef PNG_1_0_X
    193 void PNGAPI
    194 #else
    195 void /* private */
    196 #endif
    197 png_zfree(voidpf png_ptr, voidpf ptr)
    198 {
    199    png_free((png_structp)png_ptr, (png_voidp)ptr);
    200 }
    201 
    202 /* Reset the CRC variable to 32 bits of 1's.  Care must be taken
    203  * in case CRC is > 32 bits to leave the top bits 0.
    204  */
    205 void /* PRIVATE */
    206 png_reset_crc(png_structp png_ptr)
    207 {
    208    png_ptr->crc = crc32(0, Z_NULL, 0);
    209 }
    210 
    211 /* Calculate the CRC over a section of data.  We can only pass as
    212  * much data to this routine as the largest single buffer size.  We
    213  * also check that this data will actually be used before going to the
    214  * trouble of calculating it.
    215  */
    216 void /* PRIVATE */
    217 png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
    218 {
    219    int need_crc = 1;
    220 
    221    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
    222    {
    223       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
    224           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
    225          need_crc = 0;
    226    }
    227    else                                                    /* critical */
    228    {
    229       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
    230          need_crc = 0;
    231    }
    232 
    233    if (need_crc)
    234       png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
    235 }
    236 
    237 /* Allocate the memory for an info_struct for the application.  We don't
    238  * really need the png_ptr, but it could potentially be useful in the
    239  * future.  This should be used in favour of malloc(png_sizeof(png_info))
    240  * and png_info_init() so that applications that want to use a shared
    241  * libpng don't have to be recompiled if png_info changes size.
    242  */
    243 png_infop PNGAPI
    244 png_create_info_struct(png_structp png_ptr)
    245 {
    246    png_infop info_ptr;
    247 
    248    png_debug(1, "in png_create_info_struct\n");
    249    if(png_ptr == NULL) return (NULL);
    250 #ifdef PNG_USER_MEM_SUPPORTED
    251    info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
    252       png_ptr->malloc_fn, png_ptr->mem_ptr);
    253 #else
    254    info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
    255 #endif
    256    if (info_ptr != NULL)
    257       png_info_init_3(&info_ptr, png_sizeof(png_info));
    258 
    259    return (info_ptr);
    260 }
    261 
    262 /* This function frees the memory associated with a single info struct.
    263  * Normally, one would use either png_destroy_read_struct() or
    264  * png_destroy_write_struct() to free an info struct, but this may be
    265  * useful for some applications.
    266  */
    267 void PNGAPI
    268 png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
    269 {
    270    png_infop info_ptr = NULL;
    271    if(png_ptr == NULL) return;
    272 
    273    png_debug(1, "in png_destroy_info_struct\n");
    274    if (info_ptr_ptr != NULL)
    275       info_ptr = *info_ptr_ptr;
    276 
    277    if (info_ptr != NULL)
    278    {
    279       png_info_destroy(png_ptr, info_ptr);
    280 
    281 #ifdef PNG_USER_MEM_SUPPORTED
    282       png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
    283           png_ptr->mem_ptr);
    284 #else
    285       png_destroy_struct((png_voidp)info_ptr);
    286 #endif
    287       *info_ptr_ptr = NULL;
    288    }
    289 }
    290 
    291 /* Initialize the info structure.  This is now an internal function (0.89)
    292  * and applications using it are urged to use png_create_info_struct()
    293  * instead.
    294  */
    295 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
    296 #undef png_info_init
    297 void PNGAPI
    298 png_info_init(png_infop info_ptr)
    299 {
    300    /* We only come here via pre-1.0.12-compiled applications */
    301    png_info_init_3(&info_ptr, 0);
    302 }
    303 #endif
    304 
    305 void PNGAPI
    306 png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
    307 {
    308    png_infop info_ptr = *ptr_ptr;
    309 
    310    if(info_ptr == NULL) return;
    311 
    312    png_debug(1, "in png_info_init_3\n");
    313 
    314    if(png_sizeof(png_info) > png_info_struct_size)
    315      {
    316        png_destroy_struct(info_ptr);
    317        info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
    318        *ptr_ptr = info_ptr;
    319      }
    320 
    321    /* set everything to 0 */
    322    png_memset(info_ptr, 0, png_sizeof (png_info));
    323 }
    324 
    325 #ifdef PNG_FREE_ME_SUPPORTED
    326 void PNGAPI
    327 png_data_freer(png_structp png_ptr, png_infop info_ptr,
    328    int freer, png_uint_32 mask)
    329 {
    330    png_debug(1, "in png_data_freer\n");
    331    if (png_ptr == NULL || info_ptr == NULL)
    332       return;
    333    if(freer == PNG_DESTROY_WILL_FREE_DATA)
    334       info_ptr->free_me |= mask;
    335    else if(freer == PNG_USER_WILL_FREE_DATA)
    336       info_ptr->free_me &= ~mask;
    337    else
    338       png_warning(png_ptr,
    339          "Unknown freer parameter in png_data_freer.");
    340 }
    341 #endif
    342 
    343 void PNGAPI
    344 png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
    345    int num)
    346 {
    347    png_debug(1, "in png_free_data\n");
    348    if (png_ptr == NULL || info_ptr == NULL)
    349       return;
    350 
    351 #if defined(PNG_TEXT_SUPPORTED)
    352 /* free text item num or (if num == -1) all text items */
    353 #ifdef PNG_FREE_ME_SUPPORTED
    354 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
    355 #else
    356 if (mask & PNG_FREE_TEXT)
    357 #endif
    358 {
    359    if (num != -1)
    360    {
    361      if (info_ptr->text && info_ptr->text[num].key)
    362      {
    363          png_free(png_ptr, info_ptr->text[num].key);
    364          info_ptr->text[num].key = NULL;
    365      }
    366    }
    367    else
    368    {
    369        int i;
    370        for (i = 0; i < info_ptr->num_text; i++)
    371            png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
    372        png_free(png_ptr, info_ptr->text);
    373        info_ptr->text = NULL;
    374        info_ptr->num_text=0;
    375    }
    376 }
    377 #endif
    378 
    379 #if defined(PNG_tRNS_SUPPORTED)
    380 /* free any tRNS entry */
    381 #ifdef PNG_FREE_ME_SUPPORTED
    382 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
    383 #else
    384 if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
    385 #endif
    386 {
    387     png_free(png_ptr, info_ptr->trans);
    388     info_ptr->valid &= ~PNG_INFO_tRNS;
    389 #ifndef PNG_FREE_ME_SUPPORTED
    390     png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
    391 #endif
    392     info_ptr->trans = NULL;
    393 }
    394 #endif
    395 
    396 #if defined(PNG_sCAL_SUPPORTED)
    397 /* free any sCAL entry */
    398 #ifdef PNG_FREE_ME_SUPPORTED
    399 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
    400 #else
    401 if (mask & PNG_FREE_SCAL)
    402 #endif
    403 {
    404 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
    405     png_free(png_ptr, info_ptr->scal_s_width);
    406     png_free(png_ptr, info_ptr->scal_s_height);
    407     info_ptr->scal_s_width = NULL;
    408     info_ptr->scal_s_height = NULL;
    409 #endif
    410     info_ptr->valid &= ~PNG_INFO_sCAL;
    411 }
    412 #endif
    413 
    414 #if defined(PNG_pCAL_SUPPORTED)
    415 /* free any pCAL entry */
    416 #ifdef PNG_FREE_ME_SUPPORTED
    417 if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
    418 #else
    419 if (mask & PNG_FREE_PCAL)
    420 #endif
    421 {
    422     png_free(png_ptr, info_ptr->pcal_purpose);
    423     png_free(png_ptr, info_ptr->pcal_units);
    424     info_ptr->pcal_purpose = NULL;
    425     info_ptr->pcal_units = NULL;
    426     if (info_ptr->pcal_params != NULL)
    427     {
    428         int i;
    429         for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
    430         {
    431           png_free(png_ptr, info_ptr->pcal_params[i]);
    432           info_ptr->pcal_params[i]=NULL;
    433         }
    434         png_free(png_ptr, info_ptr->pcal_params);
    435         info_ptr->pcal_params = NULL;
    436     }
    437     info_ptr->valid &= ~PNG_INFO_pCAL;
    438 }
    439 #endif
    440 
    441 #if defined(PNG_iCCP_SUPPORTED)
    442 /* free any iCCP entry */
    443 #ifdef PNG_FREE_ME_SUPPORTED
    444 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
    445 #else
    446 if (mask & PNG_FREE_ICCP)
    447 #endif
    448 {
    449     png_free(png_ptr, info_ptr->iccp_name);
    450     png_free(png_ptr, info_ptr->iccp_profile);
    451     info_ptr->iccp_name = NULL;
    452     info_ptr->iccp_profile = NULL;
    453     info_ptr->valid &= ~PNG_INFO_iCCP;
    454 }
    455 #endif
    456 
    457 #if defined(PNG_sPLT_SUPPORTED)
    458 /* free a given sPLT entry, or (if num == -1) all sPLT entries */
    459 #ifdef PNG_FREE_ME_SUPPORTED
    460 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
    461 #else
    462 if (mask & PNG_FREE_SPLT)
    463 #endif
    464 {
    465    if (num != -1)
    466    {
    467       if(info_ptr->splt_palettes)
    468       {
    469           png_free(png_ptr, info_ptr->splt_palettes[num].name);
    470           png_free(png_ptr, info_ptr->splt_palettes[num].entries);
    471           info_ptr->splt_palettes[num].name = NULL;
    472           info_ptr->splt_palettes[num].entries = NULL;
    473       }
    474    }
    475    else
    476    {
    477        if(info_ptr->splt_palettes_num)
    478        {
    479          int i;
    480          for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
    481             png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
    482 
    483          png_free(png_ptr, info_ptr->splt_palettes);
    484          info_ptr->splt_palettes = NULL;
    485          info_ptr->splt_palettes_num = 0;
    486        }
    487        info_ptr->valid &= ~PNG_INFO_sPLT;
    488    }
    489 }
    490 #endif
    491 
    492 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
    493   if(png_ptr->unknown_chunk.data)
    494   {
    495     png_free(png_ptr, png_ptr->unknown_chunk.data);
    496     png_ptr->unknown_chunk.data = NULL;
    497   }
    498 #ifdef PNG_FREE_ME_SUPPORTED
    499 if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
    500 #else
    501 if (mask & PNG_FREE_UNKN)
    502 #endif
    503 {
    504    if (num != -1)
    505    {
    506        if(info_ptr->unknown_chunks)
    507        {
    508           png_free(png_ptr, info_ptr->unknown_chunks[num].data);
    509           info_ptr->unknown_chunks[num].data = NULL;
    510        }
    511    }
    512    else
    513    {
    514        int i;
    515 
    516        if(info_ptr->unknown_chunks_num)
    517        {
    518          for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
    519             png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
    520 
    521          png_free(png_ptr, info_ptr->unknown_chunks);
    522          info_ptr->unknown_chunks = NULL;
    523          info_ptr->unknown_chunks_num = 0;
    524        }
    525    }
    526 }
    527 #endif
    528 
    529 #if defined(PNG_hIST_SUPPORTED)
    530 /* free any hIST entry */
    531 #ifdef PNG_FREE_ME_SUPPORTED
    532 if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
    533 #else
    534 if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
    535 #endif
    536 {
    537     png_free(png_ptr, info_ptr->hist);
    538     info_ptr->hist = NULL;
    539     info_ptr->valid &= ~PNG_INFO_hIST;
    540 #ifndef PNG_FREE_ME_SUPPORTED
    541     png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
    542 #endif
    543 }
    544 #endif
    545 
    546 /* free any PLTE entry that was internally allocated */
    547 #ifdef PNG_FREE_ME_SUPPORTED
    548 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
    549 #else
    550 if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
    551 #endif
    552 {
    553     png_zfree(png_ptr, info_ptr->palette);
    554     info_ptr->palette = NULL;
    555     info_ptr->valid &= ~PNG_INFO_PLTE;
    556 #ifndef PNG_FREE_ME_SUPPORTED
    557     png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
    558 #endif
    559     info_ptr->num_palette = 0;
    560 }
    561 
    562 #if defined(PNG_INFO_IMAGE_SUPPORTED)
    563 /* free any image bits attached to the info structure */
    564 #ifdef PNG_FREE_ME_SUPPORTED
    565 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
    566 #else
    567 if (mask & PNG_FREE_ROWS)
    568 #endif
    569 {
    570     if(info_ptr->row_pointers)
    571     {
    572        int row;
    573        for (row = 0; row < (int)info_ptr->height; row++)
    574        {
    575           png_free(png_ptr, info_ptr->row_pointers[row]);
    576           info_ptr->row_pointers[row]=NULL;
    577        }
    578        png_free(png_ptr, info_ptr->row_pointers);
    579        info_ptr->row_pointers=NULL;
    580     }
    581     info_ptr->valid &= ~PNG_INFO_IDAT;
    582 }
    583 #endif
    584 
    585 #ifdef PNG_FREE_ME_SUPPORTED
    586    if(num == -1)
    587      info_ptr->free_me &= ~mask;
    588    else
    589      info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
    590 #endif
    591 }
    592 
    593 /* This is an internal routine to free any memory that the info struct is
    594  * pointing to before re-using it or freeing the struct itself.  Recall
    595  * that png_free() checks for NULL pointers for us.
    596  */
    597 void /* PRIVATE */
    598 png_info_destroy(png_structp png_ptr, png_infop info_ptr)
    599 {
    600    png_debug(1, "in png_info_destroy\n");
    601 
    602    png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    603 
    604 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
    605    if (png_ptr->num_chunk_list)
    606    {
    607        png_free(png_ptr, png_ptr->chunk_list);
    608        png_ptr->chunk_list=NULL;
    609        png_ptr->num_chunk_list=0;
    610    }
    611 #endif
    612 
    613    png_info_init_3(&info_ptr, png_sizeof(png_info));
    614 }
    615 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
    616 
    617 /* This function returns a pointer to the io_ptr associated with the user
    618  * functions.  The application should free any memory associated with this
    619  * pointer before png_write_destroy() or png_read_destroy() are called.
    620  */
    621 png_voidp PNGAPI
    622 png_get_io_ptr(png_structp png_ptr)
    623 {
    624    if(png_ptr == NULL) return (NULL);
    625    return (png_ptr->io_ptr);
    626 }
    627 
    628 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    629 #if !defined(PNG_NO_STDIO)
    630 /* Initialize the default input/output functions for the PNG file.  If you
    631  * use your own read or write routines, you can call either png_set_read_fn()
    632  * or png_set_write_fn() instead of png_init_io().  If you have defined
    633  * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
    634  * necessarily available.
    635  */
    636 void PNGAPI
    637 png_init_io(png_structp png_ptr, png_FILE_p fp)
    638 {
    639    png_debug(1, "in png_init_io\n");
    640    if(png_ptr == NULL) return;
    641    png_ptr->io_ptr = (png_voidp)fp;
    642 }
    643 #endif
    644 
    645 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    646 /* Convert the supplied time into an RFC 1123 string suitable for use in
    647  * a "Creation Time" or other text-based time string.
    648  */
    649 png_charp PNGAPI
    650 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
    651 {
    652    static PNG_CONST char short_months[12][4] =
    653         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
    654          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    655 
    656    if(png_ptr == NULL) return (NULL);
    657    if (png_ptr->time_buffer == NULL)
    658    {
    659       png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
    660          png_sizeof(char)));
    661    }
    662 
    663 #if defined(_WIN32_WCE)
    664    {
    665       wchar_t time_buf[29];
    666       wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
    667           ptime->day % 32, short_months[(ptime->month - 1) % 12],
    668         ptime->year, ptime->hour % 24, ptime->minute % 60,
    669           ptime->second % 61);
    670       WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
    671           NULL, NULL);
    672    }
    673 #else
    674 #ifdef USE_FAR_KEYWORD
    675    {
    676       char near_time_buf[29];
    677       png_snprintf6(near_time_buf,29,"%d %s %d %02d:%02d:%02d +0000",
    678           ptime->day % 32, short_months[(ptime->month - 1) % 12],
    679           ptime->year, ptime->hour % 24, ptime->minute % 60,
    680           ptime->second % 61);
    681       png_memcpy(png_ptr->time_buffer, near_time_buf,
    682           29*png_sizeof(char));
    683    }
    684 #else
    685    png_snprintf6(png_ptr->time_buffer,29,"%d %s %d %02d:%02d:%02d +0000",
    686        ptime->day % 32, short_months[(ptime->month - 1) % 12],
    687        ptime->year, ptime->hour % 24, ptime->minute % 60,
    688        ptime->second % 61);
    689 #endif
    690 #endif /* _WIN32_WCE */
    691    return ((png_charp)png_ptr->time_buffer);
    692 }
    693 #endif /* PNG_TIME_RFC1123_SUPPORTED */
    694 
    695 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
    696 
    697 png_charp PNGAPI
    698 png_get_copyright(png_structp png_ptr)
    699 {
    700    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
    701    return ((png_charp) "\n libpng version 1.2.19 - August 18, 2007\n\
    702    Copyright (c) 1998-2007 Glenn Randers-Pehrson\n\
    703    Copyright (c) 1996-1997 Andreas Dilger\n\
    704    Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
    705 }
    706 
    707 /* The following return the library version as a short string in the
    708  * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
    709  * used with your application, print out PNG_LIBPNG_VER_STRING, which
    710  * is defined in png.h.
    711  * Note: now there is no difference between png_get_libpng_ver() and
    712  * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
    713  * it is guaranteed that png.c uses the correct version of png.h.
    714  */
    715 png_charp PNGAPI
    716 png_get_libpng_ver(png_structp png_ptr)
    717 {
    718    /* Version of *.c files used when building libpng */
    719    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
    720    return ((png_charp) PNG_LIBPNG_VER_STRING);
    721 }
    722 
    723 png_charp PNGAPI
    724 png_get_header_ver(png_structp png_ptr)
    725 {
    726    /* Version of *.h files used when building libpng */
    727    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
    728    return ((png_charp) PNG_LIBPNG_VER_STRING);
    729 }
    730 
    731 png_charp PNGAPI
    732 png_get_header_version(png_structp png_ptr)
    733 {
    734    /* Returns longer string containing both version and date */
    735    png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
    736    return ((png_charp) PNG_HEADER_VERSION_STRING
    737 #ifdef PNG_READ_SUPPORTED
    738 #  ifdef PNG_USE_PNGGCCRD
    739 #    ifdef __x86_64__
    740 #      ifdef __PIC__
    741    "     (PNGGCRD x86_64, PIC)\n"
    742 #      else
    743 #        ifdef PNG_THREAD_UNSAFE_OK
    744    "     (PNGGCRD x86_64, Thread unsafe)\n"
    745 #        else
    746    "     (PNGGCRD x86_64, Thread safe)\n"
    747 #        endif
    748 #      endif
    749 #    else
    750 #    ifdef PNG_THREAD_UNSAFE_OK
    751    "     (PNGGCRD, Thread unsafe)\n"
    752 #      else
    753    "     (PNGGCRD, Thread safe)\n"
    754 #      endif
    755 #    endif
    756 #  else
    757 #    ifdef PNG_USE_PNGVCRD
    758 #      ifdef __x86_64__
    759    "     (x86_64 PNGVCRD)\n"
    760 #      else
    761    "     (PNGVCRD)\n"
    762 #      endif
    763 #    else
    764 #      ifdef __x86_64__
    765 #        ifdef PNG_OPTIMIZED_CODE_SUPPORTED
    766    "     (x86_64 OPTIMIZED)\n"
    767 #        else
    768    "     (x86_64 NOT OPTIMIZED)\n"
    769 #        endif
    770 #      else
    771 #        ifdef PNG_OPTIMIZED_CODE_SUPPORTED
    772    "     (OPTIMIZED)\n"
    773 #        else
    774    "     (NOT OPTIMIZED)\n"
    775 #        endif
    776 #      endif
    777 #    endif
    778 #  endif
    779 #else
    780    "     (NO READ SUPPORT)\n"
    781 #endif
    782    );
    783 }
    784 
    785 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    786 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    787 int PNGAPI
    788 png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
    789 {
    790    /* check chunk_name and return "keep" value if it's on the list, else 0 */
    791    int i;
    792    png_bytep p;
    793    if(png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
    794       return 0;
    795    p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
    796    for (i = png_ptr->num_chunk_list; i; i--, p-=5)
    797       if (!png_memcmp(chunk_name, p, 4))
    798         return ((int)*(p+4));
    799    return 0;
    800 }
    801 #endif
    802 
    803 /* This function, added to libpng-1.0.6g, is untested. */
    804 int PNGAPI
    805 png_reset_zstream(png_structp png_ptr)
    806 {
    807    if (png_ptr == NULL) return Z_STREAM_ERROR;
    808    return (inflateReset(&png_ptr->zstream));
    809 }
    810 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
    811 
    812 /* This function was added to libpng-1.0.7 */
    813 png_uint_32 PNGAPI
    814 png_access_version_number(void)
    815 {
    816    /* Version of *.c files used when building libpng */
    817    return((png_uint_32) PNG_LIBPNG_VER);
    818 }
    819 
    820 
    821 #if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
    822 #if !defined(PNG_1_0_X)
    823 #if defined(PNG_MMX_CODE_SUPPORTED)
    824 /* this INTERNAL function was added to libpng 1.2.0 */
    825 void /* PRIVATE */
    826 png_init_mmx_flags (png_structp png_ptr)
    827 {
    828     if(png_ptr == NULL) return;
    829     png_ptr->mmx_rowbytes_threshold = 0;
    830     png_ptr->mmx_bitdepth_threshold = 0;
    831 
    832 #  if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))
    833 
    834     png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
    835 
    836     if (png_mmx_support() > 0) {
    837         png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
    838 #    ifdef PNG_HAVE_MMX_COMBINE_ROW
    839                               | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
    840 #    endif
    841 #    ifdef PNG_HAVE_MMX_READ_INTERLACE
    842                               | PNG_ASM_FLAG_MMX_READ_INTERLACE
    843 #    endif
    844 #    ifndef PNG_HAVE_MMX_READ_FILTER_ROW
    845                               ;
    846 #    else
    847                               | PNG_ASM_FLAG_MMX_READ_FILTER_SUB
    848                               | PNG_ASM_FLAG_MMX_READ_FILTER_UP
    849                               | PNG_ASM_FLAG_MMX_READ_FILTER_AVG
    850                               | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
    851 
    852         png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
    853         png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
    854 #    endif
    855     } else {
    856         png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
    857                                | PNG_MMX_READ_FLAGS
    858                                | PNG_MMX_WRITE_FLAGS );
    859     }
    860 
    861 #  else /* !(PNGVCRD || PNGGCCRD) */
    862 
    863     /* clear all MMX flags; no support is compiled in */
    864     png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );
    865 
    866 #  endif /* ?(PNGVCRD || PNGGCCRD) */
    867 }
    868 
    869 #endif /* !(PNG_MMX_CODE_SUPPORTED) */
    870 
    871 /* this function was added to libpng 1.2.0 */
    872 #if !defined(PNG_USE_PNGGCCRD) && \
    873     !(defined(PNG_MMX_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
    874 int PNGAPI
    875 png_mmx_support(void)
    876 {
    877     return -1;
    878 }
    879 #endif
    880 #endif /* PNG_1_0_X */
    881 #endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */
    882 
    883 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    884 #ifdef PNG_SIZE_T
    885 /* Added at libpng version 1.2.6 */
    886    PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
    887 png_size_t PNGAPI
    888 png_convert_size(size_t size)
    889 {
    890   if (size > (png_size_t)-1)
    891      PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */
    892   return ((png_size_t)size);
    893 }
    894 #endif /* PNG_SIZE_T */
    895 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
    896