Home Docs Forums Bugzilla LXR Doxygen CVS Bonsai
Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

png.c

Go to the documentation of this file.
00001 
00002 /* png.c - location for general purpose libpng functions
00003  *
00004  * libpng version 1.0.12 - June 8, 2001
00005  * Copyright (c) 1998-2001 Glenn Randers-Pehrson
00006  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00007  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00008  *
00009  */
00010 
00011 #define PNG_INTERNAL
00012 #define PNG_NO_EXTERN
00013 #include "png.h"
00014 
00015 /* Generate a compiler error if there is an old png.h in the search path. */
00016 typedef version_1_0_12 Your_png_h_is_not_version_1_0_12;
00017 
00018 /* Version information for C files.  This had better match the version
00019  * string defined in png.h.  */
00020 
00021 #ifdef PNG_USE_GLOBAL_ARRAYS
00022 /* png_libpng_ver was changed to a function in version 1.0.5c */
00023 const char png_libpng_ver[18] = "1.0.12";
00024 
00025 /* png_sig was changed to a function in version 1.0.5c */
00026 /* Place to hold the signature string for a PNG file. */
00027 const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
00028 
00029 /* Invoke global declarations for constant strings for known chunk types */
00030 PNG_IHDR;
00031 PNG_IDAT;
00032 PNG_IEND;
00033 PNG_PLTE;
00034 PNG_bKGD;
00035 PNG_cHRM;
00036 PNG_gAMA;
00037 PNG_hIST;
00038 PNG_iCCP;
00039 PNG_iTXt;
00040 PNG_oFFs;
00041 PNG_pCAL;
00042 PNG_sCAL;
00043 PNG_pHYs;
00044 PNG_sBIT;
00045 PNG_sPLT;
00046 PNG_sRGB;
00047 PNG_tEXt;
00048 PNG_tIME;
00049 PNG_tRNS;
00050 PNG_zTXt;
00051 
00052 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
00053 
00054 /* start of interlace block */
00055 const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
00056 
00057 /* offset to next interlace block */
00058 const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
00059 
00060 /* start of interlace block in the y direction */
00061 const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
00062 
00063 /* offset to next interlace block in the y direction */
00064 const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
00065 
00066 /* width of interlace block (used in assembler routines only) */
00067 #ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
00068 const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
00069 #endif
00070 
00071 /* Height of interlace block.  This is not currently used - if you need
00072  * it, uncomment it here and in png.h
00073 const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
00074 */
00075 
00076 /* Mask to determine which pixels are valid in a pass */
00077 const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
00078 
00079 /* Mask to determine which pixels to overwrite while displaying */
00080 const int FARDATA png_pass_dsp_mask[]
00081    = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
00082 
00083 #endif
00084 
00085 /* Tells libpng that we have already handled the first "num_bytes" bytes
00086  * of the PNG file signature.  If the PNG data is embedded into another
00087  * stream we can set num_bytes = 8 so that libpng will not attempt to read
00088  * or write any of the magic bytes before it starts on the IHDR.
00089  */
00090 
00091 void PNGAPI
00092 png_set_sig_bytes(png_structp png_ptr, int num_bytes)
00093 {
00094    png_debug(1, "in png_set_sig_bytes\n");
00095    if (num_bytes > 8)
00096       png_error(png_ptr, "Too many bytes for PNG signature.");
00097 
00098    png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
00099 }
00100 
00101 /* Checks whether the supplied bytes match the PNG signature.  We allow
00102  * checking less than the full 8-byte signature so that those apps that
00103  * already read the first few bytes of a file to determine the file type
00104  * can simply check the remaining bytes for extra assurance.  Returns
00105  * an integer less than, equal to, or greater than zero if sig is found,
00106  * respectively, to be less than, to match, or be greater than the correct
00107  * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
00108  */
00109 int PNGAPI
00110 png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
00111 {
00112    png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
00113    if (num_to_check > 8)
00114       num_to_check = 8;
00115    else if (num_to_check < 1)
00116       return (0);
00117 
00118    if (start > 7)
00119       return (0);
00120 
00121    if (start + num_to_check > 8)
00122       num_to_check = 8 - start;
00123 
00124    return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
00125 }
00126 
00127 /* (Obsolete) function to check signature bytes.  It does not allow one
00128  * to check a partial signature.  This function might be removed in the
00129  * future - use png_sig_cmp().  Returns true (nonzero) if the file is a PNG.
00130  */
00131 int PNGAPI
00132 png_check_sig(png_bytep sig, int num)
00133 {
00134   return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
00135 }
00136 
00137 /* Function to allocate memory for zlib and clear it to 0. */
00138 voidpf /* PRIVATE */
00139 png_zalloc(voidpf png_ptr, uInt items, uInt size)
00140 {
00141    png_uint_32 num_bytes = (png_uint_32)items * size;
00142    png_voidp ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
00143 
00144 #ifndef PNG_NO_ZALLOC_ZERO
00145    if (num_bytes > (png_uint_32)0x8000L)
00146    {
00147       png_memset(ptr, 0, (png_size_t)0x8000L);
00148       png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
00149          (png_size_t)(num_bytes - (png_uint_32)0x8000L));
00150    }
00151    else
00152    {
00153       png_memset(ptr, 0, (png_size_t)num_bytes);
00154    }
00155 #endif
00156    return ((voidpf)ptr);
00157 }
00158 
00159 /* function to free memory for zlib */
00160 void /* PRIVATE */
00161 png_zfree(voidpf png_ptr, voidpf ptr)
00162 {
00163    png_free((png_structp)png_ptr, (png_voidp)ptr);
00164 }
00165 
00166 /* Reset the CRC variable to 32 bits of 1's.  Care must be taken
00167  * in case CRC is > 32 bits to leave the top bits 0.
00168  */
00169 void /* PRIVATE */
00170 png_reset_crc(png_structp png_ptr)
00171 {
00172    png_ptr->crc = crc32(0, Z_NULL, 0);
00173 }
00174 
00175 /* Calculate the CRC over a section of data.  We can only pass as
00176  * much data to this routine as the largest single buffer size.  We
00177  * also check that this data will actually be used before going to the
00178  * trouble of calculating it.
00179  */
00180 void /* PRIVATE */
00181 png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
00182 {
00183    int need_crc = 1;
00184 
00185    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
00186    {
00187       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
00188           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
00189          need_crc = 0;
00190    }
00191    else                                                    /* critical */
00192    {
00193       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
00194          need_crc = 0;
00195    }
00196 
00197    if (need_crc)
00198       png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
00199 }
00200 
00201 /* Allocate the memory for an info_struct for the application.  We don't
00202  * really need the png_ptr, but it could potentially be useful in the
00203  * future.  This should be used in favour of malloc(sizeof(png_info))
00204  * and png_info_init() so that applications that want to use a shared
00205  * libpng don't have to be recompiled if png_info changes size.
00206  */
00207 png_infop PNGAPI
00208 png_create_info_struct(png_structp png_ptr)
00209 {
00210    png_infop info_ptr;
00211 
00212    png_debug(1, "in png_create_info_struct\n");
00213    if(png_ptr == NULL) return (NULL);
00214 #ifdef PNG_USER_MEM_SUPPORTED
00215    if ((info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
00216       png_ptr->malloc_fn, png_ptr->mem_ptr)) != NULL)
00217 #else
00218    if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
00219 #endif
00220    {
00221       png_info_init_3(&info_ptr, sizeof(png_info));
00222    }
00223 
00224    return (info_ptr);
00225 }
00226 
00227 /* This function frees the memory associated with a single info struct.
00228  * Normally, one would use either png_destroy_read_struct() or
00229  * png_destroy_write_struct() to free an info struct, but this may be
00230  * useful for some applications.
00231  */
00232 void PNGAPI
00233 png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
00234 {
00235    png_infop info_ptr = NULL;
00236 
00237    png_debug(1, "in png_destroy_info_struct\n");
00238    if (info_ptr_ptr != NULL)
00239       info_ptr = *info_ptr_ptr;
00240 
00241    if (info_ptr != NULL)
00242    {
00243       png_info_destroy(png_ptr, info_ptr);
00244 
00245 #ifdef PNG_USER_MEM_SUPPORTED
00246       png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
00247           png_ptr->mem_ptr);
00248 #else
00249       png_destroy_struct((png_voidp)info_ptr);
00250 #endif
00251       *info_ptr_ptr = (png_infop)NULL;
00252    }
00253 }
00254 
00255 /* Initialize the info structure.  This is now an internal function (0.89)
00256  * and applications using it are urged to use png_create_info_struct()
00257  * instead.
00258  */
00259 #undef png_info_init
00260 void PNGAPI
00261 png_info_init(png_infop info_ptr)
00262 {
00263    /* We only come here via pre-1.0.12-compiled applications */
00264    png_info_init_3(&info_ptr, 0);
00265 }
00266 
00267 void PNGAPI
00268 png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
00269 {
00270    png_infop info_ptr = *ptr_ptr;
00271 
00272    png_debug(1, "in png_info_init_3\n");
00273 
00274    if(sizeof(png_info) > png_info_struct_size)
00275      {
00276        png_destroy_struct(info_ptr);
00277        info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
00278        *ptr_ptr = info_ptr;
00279      }
00280 
00281    /* set everything to 0 */
00282    png_memset(info_ptr, 0, sizeof (png_info));
00283 }
00284 
00285 #ifdef PNG_FREE_ME_SUPPORTED
00286 void PNGAPI
00287 png_data_freer(png_structp png_ptr, png_infop info_ptr,
00288    int freer, png_uint_32 mask)
00289 {
00290    png_debug(1, "in png_data_freer\n");
00291    if (png_ptr == NULL || info_ptr == NULL)
00292       return;
00293    if(freer == PNG_DESTROY_WILL_FREE_DATA)
00294       info_ptr->free_me |= mask;
00295    else if(freer == PNG_USER_WILL_FREE_DATA)
00296       info_ptr->free_me &= ~mask;
00297    else
00298       png_warning(png_ptr,
00299          "Unknown freer parameter in png_data_freer.");
00300 }
00301 #endif
00302 
00303 void PNGAPI
00304 png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
00305    int num)
00306 {
00307    png_debug(1, "in png_free_data\n");
00308    if (png_ptr == NULL || info_ptr == NULL)
00309       return;
00310 
00311 #if defined(PNG_TEXT_SUPPORTED)
00312 /* free text item num or (if num == -1) all text items */
00313 #ifdef PNG_FREE_ME_SUPPORTED
00314 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
00315 #else
00316 if (mask & PNG_FREE_TEXT)
00317 #endif
00318 {
00319    if (num != -1)
00320    {
00321      if (info_ptr->text && info_ptr->text[num].key)
00322      {
00323          png_free(png_ptr, info_ptr->text[num].key);
00324          info_ptr->text[num].key = NULL;
00325      }
00326    }
00327    else
00328    {
00329        int i;
00330        for (i = 0; i < info_ptr->num_text; i++)
00331            png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
00332        png_free(png_ptr, info_ptr->text);
00333        info_ptr->text = NULL;
00334        info_ptr->num_text=0;
00335    }
00336 }
00337 #endif
00338 
00339 #if defined(PNG_tRNS_SUPPORTED)
00340 /* free any tRNS entry */
00341 #ifdef PNG_FREE_ME_SUPPORTED
00342 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
00343 #else
00344 if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
00345 #endif
00346 {
00347     png_free(png_ptr, info_ptr->trans);
00348     info_ptr->valid &= ~PNG_INFO_tRNS;
00349     info_ptr->trans = NULL;
00350 }
00351 #endif
00352 
00353 #if defined(PNG_sCAL_SUPPORTED)
00354 /* free any sCAL entry */
00355 #ifdef PNG_FREE_ME_SUPPORTED
00356 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
00357 #else
00358 if (mask & PNG_FREE_SCAL)
00359 #endif
00360 {
00361 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
00362     png_free(png_ptr, info_ptr->scal_s_width);
00363     png_free(png_ptr, info_ptr->scal_s_height);
00364     info_ptr->scal_s_width = NULL;
00365     info_ptr->scal_s_height = NULL;
00366 #endif
00367     info_ptr->valid &= ~PNG_INFO_sCAL;
00368 }
00369 #endif
00370 
00371 #if defined(PNG_pCAL_SUPPORTED)
00372 /* free any pCAL entry */
00373 #ifdef PNG_FREE_ME_SUPPORTED
00374 if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
00375 #else
00376 if (mask & PNG_FREE_PCAL)
00377 #endif
00378 {
00379     png_free(png_ptr, info_ptr->pcal_purpose);
00380     png_free(png_ptr, info_ptr->pcal_units);
00381     info_ptr->pcal_purpose = NULL;
00382     info_ptr->pcal_units = NULL;
00383     if (info_ptr->pcal_params != NULL)
00384     {
00385         int i;
00386         for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
00387         {
00388           png_free(png_ptr, info_ptr->pcal_params[i]);
00389           info_ptr->pcal_params[i]=NULL;
00390         }
00391         png_free(png_ptr, info_ptr->pcal_params);
00392         info_ptr->pcal_params = NULL;
00393     }
00394     info_ptr->valid &= ~PNG_INFO_pCAL;
00395 }
00396 #endif
00397 
00398 #if defined(PNG_iCCP_SUPPORTED)
00399 /* free any iCCP entry */
00400 #ifdef PNG_FREE_ME_SUPPORTED
00401 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
00402 #else
00403 if (mask & PNG_FREE_ICCP)
00404 #endif
00405 {
00406     png_free(png_ptr, info_ptr->iccp_name);
00407     png_free(png_ptr, info_ptr->iccp_profile);
00408     info_ptr->iccp_name = NULL;
00409     info_ptr->iccp_profile = NULL;
00410     info_ptr->valid &= ~PNG_INFO_iCCP;
00411 }
00412 #endif
00413 
00414 #if defined(PNG_sPLT_SUPPORTED)
00415 /* free a given sPLT entry, or (if num == -1) all sPLT entries */
00416 #ifdef PNG_FREE_ME_SUPPORTED
00417 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
00418 #else
00419 if (mask & PNG_FREE_SPLT)
00420 #endif
00421 {
00422    if (num != -1)
00423    {
00424       if(info_ptr->splt_palettes)
00425       {
00426           png_free(png_ptr, info_ptr->splt_palettes[num].name);
00427           png_free(png_ptr, info_ptr->splt_palettes[num].entries);
00428           info_ptr->splt_palettes[num].name = NULL;
00429           info_ptr->splt_palettes[num].entries = NULL;
00430       }
00431    }
00432    else
00433    {
00434        if(info_ptr->splt_palettes_num)
00435        {
00436          int i;
00437          for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
00438             png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
00439 
00440          png_free(png_ptr, info_ptr->splt_palettes);
00441          info_ptr->splt_palettes = NULL;
00442          info_ptr->splt_palettes_num = 0;
00443        }
00444        info_ptr->valid &= ~PNG_INFO_sPLT;
00445    }
00446 }
00447 #endif
00448 
00449 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
00450 #ifdef PNG_FREE_ME_SUPPORTED
00451 if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
00452 #else
00453 if (mask & PNG_FREE_UNKN)
00454 #endif
00455 {
00456    if (num != -1)
00457    {
00458        if(info_ptr->unknown_chunks)
00459        {
00460           png_free(png_ptr, info_ptr->unknown_chunks[num].data);
00461           info_ptr->unknown_chunks[num].data = NULL;
00462        }
00463    }
00464    else
00465    {
00466        int i;
00467 
00468        if(info_ptr->unknown_chunks_num)
00469        {
00470          for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
00471             png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
00472 
00473          png_free(png_ptr, info_ptr->unknown_chunks);
00474          info_ptr->unknown_chunks = NULL;
00475          info_ptr->unknown_chunks_num = 0;
00476        }
00477    }
00478 }
00479 #endif
00480 
00481 #if defined(PNG_hIST_SUPPORTED)
00482 /* free any hIST entry */
00483 #ifdef PNG_FREE_ME_SUPPORTED
00484 if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
00485 #else
00486 if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
00487 #endif
00488 {
00489     png_free(png_ptr, info_ptr->hist);
00490     info_ptr->hist = NULL;
00491     info_ptr->valid &= ~PNG_INFO_hIST;
00492 }
00493 #endif
00494 
00495 /* free any PLTE entry that was internally allocated */
00496 #ifdef PNG_FREE_ME_SUPPORTED
00497 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
00498 #else
00499 if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
00500 #endif
00501 {
00502     png_zfree(png_ptr, info_ptr->palette);
00503     info_ptr->palette = NULL;
00504     info_ptr->valid &= ~PNG_INFO_PLTE;
00505     info_ptr->num_palette = 0;
00506 }
00507 
00508 #if defined(PNG_INFO_IMAGE_SUPPORTED)
00509 /* free any image bits attached to the info structure */
00510 #ifdef PNG_FREE_ME_SUPPORTED
00511 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
00512 #else
00513 if (mask & PNG_FREE_ROWS)
00514 #endif
00515 {
00516     if(info_ptr->row_pointers)
00517     {
00518        int row;
00519        for (row = 0; row < (int)info_ptr->height; row++)
00520        {
00521           png_free(png_ptr, info_ptr->row_pointers[row]);
00522           info_ptr->row_pointers[row]=NULL;
00523        }
00524        png_free(png_ptr, info_ptr->row_pointers);
00525        info_ptr->row_pointers=NULL;
00526     }
00527     info_ptr->valid &= ~PNG_INFO_IDAT;
00528 }
00529 #endif
00530 
00531 #ifdef PNG_FREE_ME_SUPPORTED
00532    if(num == -1)
00533      info_ptr->free_me &= ~mask;
00534    else
00535      info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
00536 #endif
00537 }
00538 
00539 /* This is an internal routine to free any memory that the info struct is
00540  * pointing to before re-using it or freeing the struct itself.  Recall
00541  * that png_free() checks for NULL pointers for us.
00542  */
00543 void /* PRIVATE */
00544 png_info_destroy(png_structp png_ptr, png_infop info_ptr)
00545 {
00546    png_debug(1, "in png_info_destroy\n");
00547 
00548    png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
00549 
00550 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
00551    if (png_ptr->num_chunk_list)
00552    {
00553        png_free(png_ptr, png_ptr->chunk_list);
00554        png_ptr->chunk_list=NULL;
00555        png_ptr->num_chunk_list=0;
00556    }
00557 #endif
00558 
00559    png_info_init_3(&info_ptr, sizeof(png_info));
00560 }
00561 
00562 /* This function returns a pointer to the io_ptr associated with the user
00563  * functions.  The application should free any memory associated with this
00564  * pointer before png_write_destroy() or png_read_destroy() are called.
00565  */
00566 png_voidp PNGAPI
00567 png_get_io_ptr(png_structp png_ptr)
00568 {
00569    return (png_ptr->io_ptr);
00570 }
00571 
00572 #if !defined(PNG_NO_STDIO)
00573 /* Initialize the default input/output functions for the PNG file.  If you
00574  * use your own read or write routines, you can call either png_set_read_fn()
00575  * or png_set_write_fn() instead of png_init_io().  If you have defined
00576  * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
00577  * necessarily available.
00578  */
00579 void PNGAPI
00580 png_init_io(png_structp png_ptr, png_FILE_p fp)
00581 {
00582    png_debug(1, "in png_init_io\n");
00583    png_ptr->io_ptr = (png_voidp)fp;
00584 }
00585 #endif
00586 
00587 #if defined(PNG_TIME_RFC1123_SUPPORTED)
00588 /* Convert the supplied time into an RFC 1123 string suitable for use in
00589  * a "Creation Time" or other text-based time string.
00590  */
00591 png_charp PNGAPI
00592 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
00593 {
00594    static PNG_CONST char short_months[12][4] =
00595         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
00596          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
00597 
00598    if (png_ptr->time_buffer == NULL)
00599    {
00600       png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
00601          sizeof(char)));
00602    }
00603 
00604 #if defined(_WIN32_WCE)
00605    {
00606       wchar_t time_buf[29];
00607       wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
00608           ptime->day % 32, short_months[(ptime->month - 1) % 12],
00609         ptime->year, ptime->hour % 24, ptime->minute % 60,
00610           ptime->second % 61);
00611       WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
00612           NULL, NULL);
00613    }
00614 #else
00615 #ifdef USE_FAR_KEYWORD
00616    {
00617       char near_time_buf[29];
00618       sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
00619           ptime->day % 32, short_months[(ptime->month - 1) % 12],
00620           ptime->year, ptime->hour % 24, ptime->minute % 60,
00621           ptime->second % 61);
00622       png_memcpy(png_ptr->time_buffer, near_time_buf,
00623           29*sizeof(char));
00624    }
00625 #else
00626    sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
00627        ptime->day % 32, short_months[(ptime->month - 1) % 12],
00628        ptime->year, ptime->hour % 24, ptime->minute % 60,
00629        ptime->second % 61);
00630 #endif
00631 #endif /* _WIN32_WCE */
00632    return ((png_charp)png_ptr->time_buffer);
00633 }
00634 #endif /* PNG_TIME_RFC1123_SUPPORTED */
00635 
00636 #if 0
00637 /* Signature string for a PNG file. */
00638 png_bytep PNGAPI
00639 png_sig_bytes(void)
00640 {
00641    return ((png_bytep)"\211\120\116\107\015\012\032\012");
00642 }
00643 #endif
00644 
00645 png_charp PNGAPI
00646 png_get_copyright(png_structp png_ptr)
00647 {
00648    if (png_ptr != NULL || png_ptr == NULL)  /* silence compiler warning */
00649    return ((png_charp) "\n libpng version 1.0.12 - June 8, 2001\n\
00650    Copyright (c) 1998-2001 Glenn Randers-Pehrson\n\
00651    Copyright (c) 1996, 1997 Andreas Dilger\n\
00652    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n");
00653    return ((png_charp) "");
00654 }
00655 
00656 /* The following return the library version as a short string in the
00657  * format 1.0.0 through 99.99.99zz.  To get the version of *.h files used
00658  * with your application, print out PNG_LIBPNG_VER_STRING, which is defined
00659  * in png.h.
00660  */
00661 
00662 png_charp PNGAPI
00663 png_get_libpng_ver(png_structp png_ptr)
00664 {
00665    /* Version of *.c files used when building libpng */
00666    if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
00667       return((png_charp) "1.0.12");
00668    return((png_charp) "1.0.12");
00669 }
00670 
00671 png_charp PNGAPI
00672 png_get_header_ver(png_structp png_ptr)
00673 {
00674    /* Version of *.h files used when building libpng */
00675    if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
00676       return((png_charp) PNG_LIBPNG_VER_STRING);
00677    return((png_charp) PNG_LIBPNG_VER_STRING);
00678 }
00679 
00680 png_charp PNGAPI
00681 png_get_header_version(png_structp png_ptr)
00682 {
00683    /* Returns longer string containing both version and date */
00684    if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
00685       return((png_charp) PNG_HEADER_VERSION_STRING);
00686    return((png_charp) PNG_HEADER_VERSION_STRING);
00687 }
00688 
00689 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
00690 int /* PRIVATE */
00691 png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
00692 {
00693    /* check chunk_name and return "keep" value if it's on the list, else 0 */
00694    int i;
00695    png_bytep p;
00696    if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
00697       return 0;
00698    p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
00699    for (i = png_ptr->num_chunk_list; i; i--, p-=5)
00700       if (!png_memcmp(chunk_name, p, 4))
00701         return ((int)*(p+4));
00702    return 0;
00703 }
00704 #endif
00705 
00706 /* This function, added to libpng-1.0.6g, is untested. */
00707 int PNGAPI
00708 png_reset_zstream(png_structp png_ptr)
00709 {
00710    return (inflateReset(&png_ptr->zstream));
00711 }
00712 
00713 /* This function was added to libpng-1.0.7 */
00714 png_uint_32 PNGAPI
00715 png_access_version_number(void)
00716 {
00717    /* Version of *.c files used when building libpng */
00718    return((png_uint_32) 10012L);
00719 }
00720 
00721 /* this function was added to libpng 1.2.0 */
00722 #if !defined(PNG_USE_PNGGCCRD) && \
00723     !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
00724 int PNGAPI
00725 png_mmx_support(void)
00726 {
00727     return -1;
00728 }
00729 #endif