Back to index

tetex-bin  3.0
png.c
Go to the documentation of this file.
00001 
00002 /* png.c - location for general purpose libpng functions
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 
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_2_8 Your_png_h_is_not_version_1_2_8;
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] = PNG_LIBPNG_VER_STRING;
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 /* PNG_USE_GLOBAL_ARRAYS */
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 #ifdef PNG_1_0_X
00139 voidpf PNGAPI
00140 #else
00141 voidpf /* private */
00142 #endif
00143 png_zalloc(voidpf png_ptr, uInt items, uInt size)
00144 {
00145    png_voidp ptr;
00146    png_structp p=png_ptr;
00147    png_uint_32 save_flags=p->flags;
00148    png_uint_32 num_bytes;
00149 
00150    if (items > PNG_UINT_32_MAX/size)
00151    {
00152      png_warning (png_ptr, "Potential overflow in png_zalloc()");
00153      return (NULL);
00154    }
00155    num_bytes = (png_uint_32)items * size;
00156 
00157    p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
00158    ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
00159    p->flags=save_flags;
00160 
00161 #if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
00162    if (ptr == NULL)
00163        return ((voidpf)ptr);
00164 
00165    if (num_bytes > (png_uint_32)0x8000L)
00166    {
00167       png_memset(ptr, 0, (png_size_t)0x8000L);
00168       png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
00169          (png_size_t)(num_bytes - (png_uint_32)0x8000L));
00170    }
00171    else
00172    {
00173       png_memset(ptr, 0, (png_size_t)num_bytes);
00174    }
00175 #endif
00176    return ((voidpf)ptr);
00177 }
00178 
00179 /* function to free memory for zlib */
00180 #ifdef PNG_1_0_X
00181 void PNGAPI
00182 #else
00183 void /* private */
00184 #endif
00185 png_zfree(voidpf png_ptr, voidpf ptr)
00186 {
00187    png_free((png_structp)png_ptr, (png_voidp)ptr);
00188 }
00189 
00190 /* Reset the CRC variable to 32 bits of 1's.  Care must be taken
00191  * in case CRC is > 32 bits to leave the top bits 0.
00192  */
00193 void /* PRIVATE */
00194 png_reset_crc(png_structp png_ptr)
00195 {
00196    png_ptr->crc = crc32(0, Z_NULL, 0);
00197 }
00198 
00199 /* Calculate the CRC over a section of data.  We can only pass as
00200  * much data to this routine as the largest single buffer size.  We
00201  * also check that this data will actually be used before going to the
00202  * trouble of calculating it.
00203  */
00204 void /* PRIVATE */
00205 png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
00206 {
00207    int need_crc = 1;
00208 
00209    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
00210    {
00211       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
00212           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
00213          need_crc = 0;
00214    }
00215    else                                                    /* critical */
00216    {
00217       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
00218          need_crc = 0;
00219    }
00220 
00221    if (need_crc)
00222       png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
00223 }
00224 
00225 /* Allocate the memory for an info_struct for the application.  We don't
00226  * really need the png_ptr, but it could potentially be useful in the
00227  * future.  This should be used in favour of malloc(png_sizeof(png_info))
00228  * and png_info_init() so that applications that want to use a shared
00229  * libpng don't have to be recompiled if png_info changes size.
00230  */
00231 png_infop PNGAPI
00232 png_create_info_struct(png_structp png_ptr)
00233 {
00234    png_infop info_ptr;
00235 
00236    png_debug(1, "in png_create_info_struct\n");
00237    if(png_ptr == NULL) return (NULL);
00238 #ifdef PNG_USER_MEM_SUPPORTED
00239    info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
00240       png_ptr->malloc_fn, png_ptr->mem_ptr);
00241 #else
00242    info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
00243 #endif
00244    if (info_ptr != NULL)
00245       png_info_init_3(&info_ptr, png_sizeof(png_info));
00246 
00247    return (info_ptr);
00248 }
00249 
00250 /* This function frees the memory associated with a single info struct.
00251  * Normally, one would use either png_destroy_read_struct() or
00252  * png_destroy_write_struct() to free an info struct, but this may be
00253  * useful for some applications.
00254  */
00255 void PNGAPI
00256 png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
00257 {
00258    png_infop info_ptr = NULL;
00259 
00260    png_debug(1, "in png_destroy_info_struct\n");
00261    if (info_ptr_ptr != NULL)
00262       info_ptr = *info_ptr_ptr;
00263 
00264    if (info_ptr != NULL)
00265    {
00266       png_info_destroy(png_ptr, info_ptr);
00267 
00268 #ifdef PNG_USER_MEM_SUPPORTED
00269       png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
00270           png_ptr->mem_ptr);
00271 #else
00272       png_destroy_struct((png_voidp)info_ptr);
00273 #endif
00274       *info_ptr_ptr = NULL;
00275    }
00276 }
00277 
00278 /* Initialize the info structure.  This is now an internal function (0.89)
00279  * and applications using it are urged to use png_create_info_struct()
00280  * instead.
00281  */
00282 #if defined(PNG_1_0_X) || defined (PNG_1_2_X)
00283 #undef png_info_init
00284 void PNGAPI
00285 png_info_init(png_infop info_ptr)
00286 {
00287    /* We only come here via pre-1.0.12-compiled applications */
00288    png_info_init_3(&info_ptr, 0);
00289 }
00290 #endif
00291 
00292 void PNGAPI
00293 png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
00294 {
00295    png_infop info_ptr = *ptr_ptr;
00296 
00297    png_debug(1, "in png_info_init_3\n");
00298 
00299    if(png_sizeof(png_info) > png_info_struct_size)
00300      {
00301        png_destroy_struct(info_ptr);
00302        info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
00303        *ptr_ptr = info_ptr;
00304      }
00305 
00306    /* set everything to 0 */
00307    png_memset(info_ptr, 0, png_sizeof (png_info));
00308 }
00309 
00310 #ifdef PNG_FREE_ME_SUPPORTED
00311 void PNGAPI
00312 png_data_freer(png_structp png_ptr, png_infop info_ptr,
00313    int freer, png_uint_32 mask)
00314 {
00315    png_debug(1, "in png_data_freer\n");
00316    if (png_ptr == NULL || info_ptr == NULL)
00317       return;
00318    if(freer == PNG_DESTROY_WILL_FREE_DATA)
00319       info_ptr->free_me |= mask;
00320    else if(freer == PNG_USER_WILL_FREE_DATA)
00321       info_ptr->free_me &= ~mask;
00322    else
00323       png_warning(png_ptr,
00324          "Unknown freer parameter in png_data_freer.");
00325 }
00326 #endif
00327 
00328 void PNGAPI
00329 png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
00330    int num)
00331 {
00332    png_debug(1, "in png_free_data\n");
00333    if (png_ptr == NULL || info_ptr == NULL)
00334       return;
00335 
00336 #if defined(PNG_TEXT_SUPPORTED)
00337 /* free text item num or (if num == -1) all text items */
00338 #ifdef PNG_FREE_ME_SUPPORTED
00339 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
00340 #else
00341 if (mask & PNG_FREE_TEXT)
00342 #endif
00343 {
00344    if (num != -1)
00345    {
00346      if (info_ptr->text && info_ptr->text[num].key)
00347      {
00348          png_free(png_ptr, info_ptr->text[num].key);
00349          info_ptr->text[num].key = NULL;
00350      }
00351    }
00352    else
00353    {
00354        int i;
00355        for (i = 0; i < info_ptr->num_text; i++)
00356            png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
00357        png_free(png_ptr, info_ptr->text);
00358        info_ptr->text = NULL;
00359        info_ptr->num_text=0;
00360    }
00361 }
00362 #endif
00363 
00364 #if defined(PNG_tRNS_SUPPORTED)
00365 /* free any tRNS entry */
00366 #ifdef PNG_FREE_ME_SUPPORTED
00367 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
00368 #else
00369 if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
00370 #endif
00371 {
00372     png_free(png_ptr, info_ptr->trans);
00373     info_ptr->valid &= ~PNG_INFO_tRNS;
00374 #ifndef PNG_FREE_ME_SUPPORTED
00375     png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
00376 #endif
00377     info_ptr->trans = NULL;
00378 }
00379 #endif
00380 
00381 #if defined(PNG_sCAL_SUPPORTED)
00382 /* free any sCAL entry */
00383 #ifdef PNG_FREE_ME_SUPPORTED
00384 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
00385 #else
00386 if (mask & PNG_FREE_SCAL)
00387 #endif
00388 {
00389 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
00390     png_free(png_ptr, info_ptr->scal_s_width);
00391     png_free(png_ptr, info_ptr->scal_s_height);
00392     info_ptr->scal_s_width = NULL;
00393     info_ptr->scal_s_height = NULL;
00394 #endif
00395     info_ptr->valid &= ~PNG_INFO_sCAL;
00396 }
00397 #endif
00398 
00399 #if defined(PNG_pCAL_SUPPORTED)
00400 /* free any pCAL entry */
00401 #ifdef PNG_FREE_ME_SUPPORTED
00402 if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
00403 #else
00404 if (mask & PNG_FREE_PCAL)
00405 #endif
00406 {
00407     png_free(png_ptr, info_ptr->pcal_purpose);
00408     png_free(png_ptr, info_ptr->pcal_units);
00409     info_ptr->pcal_purpose = NULL;
00410     info_ptr->pcal_units = NULL;
00411     if (info_ptr->pcal_params != NULL)
00412     {
00413         int i;
00414         for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
00415         {
00416           png_free(png_ptr, info_ptr->pcal_params[i]);
00417           info_ptr->pcal_params[i]=NULL;
00418         }
00419         png_free(png_ptr, info_ptr->pcal_params);
00420         info_ptr->pcal_params = NULL;
00421     }
00422     info_ptr->valid &= ~PNG_INFO_pCAL;
00423 }
00424 #endif
00425 
00426 #if defined(PNG_iCCP_SUPPORTED)
00427 /* free any iCCP entry */
00428 #ifdef PNG_FREE_ME_SUPPORTED
00429 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
00430 #else
00431 if (mask & PNG_FREE_ICCP)
00432 #endif
00433 {
00434     png_free(png_ptr, info_ptr->iccp_name);
00435     png_free(png_ptr, info_ptr->iccp_profile);
00436     info_ptr->iccp_name = NULL;
00437     info_ptr->iccp_profile = NULL;
00438     info_ptr->valid &= ~PNG_INFO_iCCP;
00439 }
00440 #endif
00441 
00442 #if defined(PNG_sPLT_SUPPORTED)
00443 /* free a given sPLT entry, or (if num == -1) all sPLT entries */
00444 #ifdef PNG_FREE_ME_SUPPORTED
00445 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
00446 #else
00447 if (mask & PNG_FREE_SPLT)
00448 #endif
00449 {
00450    if (num != -1)
00451    {
00452       if(info_ptr->splt_palettes)
00453       {
00454           png_free(png_ptr, info_ptr->splt_palettes[num].name);
00455           png_free(png_ptr, info_ptr->splt_palettes[num].entries);
00456           info_ptr->splt_palettes[num].name = NULL;
00457           info_ptr->splt_palettes[num].entries = NULL;
00458       }
00459    }
00460    else
00461    {
00462        if(info_ptr->splt_palettes_num)
00463        {
00464          int i;
00465          for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
00466             png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
00467 
00468          png_free(png_ptr, info_ptr->splt_palettes);
00469          info_ptr->splt_palettes = NULL;
00470          info_ptr->splt_palettes_num = 0;
00471        }
00472        info_ptr->valid &= ~PNG_INFO_sPLT;
00473    }
00474 }
00475 #endif
00476 
00477 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
00478 #ifdef PNG_FREE_ME_SUPPORTED
00479 if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
00480 #else
00481 if (mask & PNG_FREE_UNKN)
00482 #endif
00483 {
00484    if (num != -1)
00485    {
00486        if(info_ptr->unknown_chunks)
00487        {
00488           png_free(png_ptr, info_ptr->unknown_chunks[num].data);
00489           info_ptr->unknown_chunks[num].data = NULL;
00490        }
00491    }
00492    else
00493    {
00494        int i;
00495 
00496        if(info_ptr->unknown_chunks_num)
00497        {
00498          for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
00499             png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
00500 
00501          png_free(png_ptr, info_ptr->unknown_chunks);
00502          info_ptr->unknown_chunks = NULL;
00503          info_ptr->unknown_chunks_num = 0;
00504        }
00505    }
00506 }
00507 #endif
00508 
00509 #if defined(PNG_hIST_SUPPORTED)
00510 /* free any hIST entry */
00511 #ifdef PNG_FREE_ME_SUPPORTED
00512 if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
00513 #else
00514 if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
00515 #endif
00516 {
00517     png_free(png_ptr, info_ptr->hist);
00518     info_ptr->hist = NULL;
00519     info_ptr->valid &= ~PNG_INFO_hIST;
00520 #ifndef PNG_FREE_ME_SUPPORTED
00521     png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
00522 #endif
00523 }
00524 #endif
00525 
00526 /* free any PLTE entry that was internally allocated */
00527 #ifdef PNG_FREE_ME_SUPPORTED
00528 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
00529 #else
00530 if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
00531 #endif
00532 {
00533     png_zfree(png_ptr, info_ptr->palette);
00534     info_ptr->palette = NULL;
00535     info_ptr->valid &= ~PNG_INFO_PLTE;
00536 #ifndef PNG_FREE_ME_SUPPORTED
00537     png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
00538 #endif
00539     info_ptr->num_palette = 0;
00540 }
00541 
00542 #if defined(PNG_INFO_IMAGE_SUPPORTED)
00543 /* free any image bits attached to the info structure */
00544 #ifdef PNG_FREE_ME_SUPPORTED
00545 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
00546 #else
00547 if (mask & PNG_FREE_ROWS)
00548 #endif
00549 {
00550     if(info_ptr->row_pointers)
00551     {
00552        int row;
00553        for (row = 0; row < (int)info_ptr->height; row++)
00554        {
00555           png_free(png_ptr, info_ptr->row_pointers[row]);
00556           info_ptr->row_pointers[row]=NULL;
00557        }
00558        png_free(png_ptr, info_ptr->row_pointers);
00559        info_ptr->row_pointers=NULL;
00560     }
00561     info_ptr->valid &= ~PNG_INFO_IDAT;
00562 }
00563 #endif
00564 
00565 #ifdef PNG_FREE_ME_SUPPORTED
00566    if(num == -1)
00567      info_ptr->free_me &= ~mask;
00568    else
00569      info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
00570 #endif
00571 }
00572 
00573 /* This is an internal routine to free any memory that the info struct is
00574  * pointing to before re-using it or freeing the struct itself.  Recall
00575  * that png_free() checks for NULL pointers for us.
00576  */
00577 void /* PRIVATE */
00578 png_info_destroy(png_structp png_ptr, png_infop info_ptr)
00579 {
00580    png_debug(1, "in png_info_destroy\n");
00581 
00582    png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
00583 
00584 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
00585    if (png_ptr->num_chunk_list)
00586    {
00587        png_free(png_ptr, png_ptr->chunk_list);
00588        png_ptr->chunk_list=NULL;
00589        png_ptr->num_chunk_list=0;
00590    }
00591 #endif
00592 
00593    png_info_init_3(&info_ptr, png_sizeof(png_info));
00594 }
00595 
00596 /* This function returns a pointer to the io_ptr associated with the user
00597  * functions.  The application should free any memory associated with this
00598  * pointer before png_write_destroy() or png_read_destroy() are called.
00599  */
00600 png_voidp PNGAPI
00601 png_get_io_ptr(png_structp png_ptr)
00602 {
00603    return (png_ptr->io_ptr);
00604 }
00605 
00606 #if !defined(PNG_NO_STDIO)
00607 /* Initialize the default input/output functions for the PNG file.  If you
00608  * use your own read or write routines, you can call either png_set_read_fn()
00609  * or png_set_write_fn() instead of png_init_io().  If you have defined
00610  * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
00611  * necessarily available.
00612  */
00613 void PNGAPI
00614 png_init_io(png_structp png_ptr, png_FILE_p fp)
00615 {
00616    png_debug(1, "in png_init_io\n");
00617    png_ptr->io_ptr = (png_voidp)fp;
00618 }
00619 #endif
00620 
00621 #if defined(PNG_TIME_RFC1123_SUPPORTED)
00622 /* Convert the supplied time into an RFC 1123 string suitable for use in
00623  * a "Creation Time" or other text-based time string.
00624  */
00625 png_charp PNGAPI
00626 png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
00627 {
00628    static PNG_CONST char short_months[12][4] =
00629         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
00630          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
00631 
00632    if (png_ptr->time_buffer == NULL)
00633    {
00634       png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
00635          png_sizeof(char)));
00636    }
00637 
00638 #if defined(_WIN32_WCE)
00639    {
00640       wchar_t time_buf[29];
00641       wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
00642           ptime->day % 32, short_months[(ptime->month - 1) % 12],
00643         ptime->year, ptime->hour % 24, ptime->minute % 60,
00644           ptime->second % 61);
00645       WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
00646           NULL, NULL);
00647    }
00648 #else
00649 #ifdef USE_FAR_KEYWORD
00650    {
00651       char near_time_buf[29];
00652       sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
00653           ptime->day % 32, short_months[(ptime->month - 1) % 12],
00654           ptime->year, ptime->hour % 24, ptime->minute % 60,
00655           ptime->second % 61);
00656       png_memcpy(png_ptr->time_buffer, near_time_buf,
00657           29*png_sizeof(char));
00658    }
00659 #else
00660    sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
00661        ptime->day % 32, short_months[(ptime->month - 1) % 12],
00662        ptime->year, ptime->hour % 24, ptime->minute % 60,
00663        ptime->second % 61);
00664 #endif
00665 #endif /* _WIN32_WCE */
00666    return ((png_charp)png_ptr->time_buffer);
00667 }
00668 #endif /* PNG_TIME_RFC1123_SUPPORTED */
00669 
00670 #if 0
00671 /* Signature string for a PNG file. */
00672 png_bytep PNGAPI
00673 png_sig_bytes(void)
00674 {
00675    return ((png_bytep)"\211\120\116\107\015\012\032\012");
00676 }
00677 #endif
00678 
00679 png_charp PNGAPI
00680 png_get_copyright(png_structp png_ptr)
00681 {
00682    if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
00683    return ((png_charp) "\n libpng version 1.2.8 - December 3, 2004\n\
00684    Copyright (c) 1998-2004 Glenn Randers-Pehrson\n\
00685    Copyright (c) 1996-1997 Andreas Dilger\n\
00686    Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
00687    return ((png_charp) "");
00688 }
00689 
00690 /* The following return the library version as a short string in the
00691  * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
00692  * used with your application, print out PNG_LIBPNG_VER_STRING, which
00693  * is defined in png.h.
00694  * Note: now there is no difference between png_get_libpng_ver() and
00695  * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
00696  * it is guaranteed that png.c uses the correct version of png.h.
00697  */
00698 png_charp PNGAPI
00699 png_get_libpng_ver(png_structp png_ptr)
00700 {
00701    /* Version of *.c files used when building libpng */
00702    if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
00703       return ((png_charp) PNG_LIBPNG_VER_STRING);
00704    return ((png_charp) "");
00705 }
00706 
00707 png_charp PNGAPI
00708 png_get_header_ver(png_structp png_ptr)
00709 {
00710    /* Version of *.h files used when building libpng */
00711    if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
00712       return ((png_charp) PNG_LIBPNG_VER_STRING);
00713    return ((png_charp) "");
00714 }
00715 
00716 png_charp PNGAPI
00717 png_get_header_version(png_structp png_ptr)
00718 {
00719    /* Returns longer string containing both version and date */
00720    if (&png_ptr != NULL)  /* silence compiler warning about unused png_ptr */
00721       return ((png_charp) PNG_HEADER_VERSION_STRING);
00722    return ((png_charp) "");
00723 }
00724 
00725 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
00726 int PNGAPI
00727 png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
00728 {
00729    /* check chunk_name and return "keep" value if it's on the list, else 0 */
00730    int i;
00731    png_bytep p;
00732    if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
00733       return 0;
00734    p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
00735    for (i = png_ptr->num_chunk_list; i; i--, p-=5)
00736       if (!png_memcmp(chunk_name, p, 4))
00737         return ((int)*(p+4));
00738    return 0;
00739 }
00740 #endif
00741 
00742 /* This function, added to libpng-1.0.6g, is untested. */
00743 int PNGAPI
00744 png_reset_zstream(png_structp png_ptr)
00745 {
00746    return (inflateReset(&png_ptr->zstream));
00747 }
00748 
00749 /* This function was added to libpng-1.0.7 */
00750 png_uint_32 PNGAPI
00751 png_access_version_number(void)
00752 {
00753    /* Version of *.c files used when building libpng */
00754    return((png_uint_32) PNG_LIBPNG_VER);
00755 }
00756 
00757 
00758 #if !defined(PNG_1_0_X)
00759 #if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
00760     /* GRR:  could add this:   && defined(PNG_MMX_CODE_SUPPORTED) */
00761 /* this INTERNAL function was added to libpng 1.2.0 */
00762 void /* PRIVATE */
00763 png_init_mmx_flags (png_structp png_ptr)
00764 {
00765     png_ptr->mmx_rowbytes_threshold = 0;
00766     png_ptr->mmx_bitdepth_threshold = 0;
00767 
00768 #  if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))
00769 
00770     png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
00771 
00772     if (png_mmx_support() > 0) {
00773         png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
00774 #    ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
00775                               | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
00776 #    endif
00777 #    ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
00778                               | PNG_ASM_FLAG_MMX_READ_INTERLACE
00779 #    endif
00780 #    ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
00781                               ;
00782 #    else
00783                               | PNG_ASM_FLAG_MMX_READ_FILTER_SUB
00784                               | PNG_ASM_FLAG_MMX_READ_FILTER_UP
00785                               | PNG_ASM_FLAG_MMX_READ_FILTER_AVG
00786                               | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
00787 
00788         png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
00789         png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
00790 #    endif
00791     } else {
00792         png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
00793                                | PNG_MMX_READ_FLAGS
00794                                | PNG_MMX_WRITE_FLAGS );
00795     }
00796 
00797 #  else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */
00798 
00799     /* clear all MMX flags; no support is compiled in */
00800     png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );
00801 
00802 #  endif /* ?(PNGVCRD || PNGGCCRD) */
00803 }
00804 
00805 #endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */
00806 
00807 /* this function was added to libpng 1.2.0 */
00808 #if !defined(PNG_USE_PNGGCCRD) && \
00809     !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
00810 int PNGAPI
00811 png_mmx_support(void)
00812 {
00813     return -1;
00814 }
00815 #endif
00816 #endif /* PNG_1_0_X */
00817 
00818 #ifdef PNG_SIZE_T
00819 /* Added at libpng version 1.2.6 */
00820    PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
00821 png_size_t PNGAPI
00822 png_convert_size(size_t size)
00823 {
00824   if (size > (png_size_t)-1)
00825      PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */
00826   return ((png_size_t)size);
00827 }
00828 #endif /* PNG_SIZE_T */