png.c 21.3 KB
Newer Older
G
Guy Schalnat 已提交
1

2 3
/* png.c - location for general purpose libpng functions
 *
4
 * libpng version 1.2.0beta2 - May 7, 2001
5
 * Copyright (c) 1998-2001 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8
 *
9
 */
G
Guy Schalnat 已提交
10 11 12 13 14

#define PNG_INTERNAL
#define PNG_NO_EXTERN
#include "png.h"

15
/* Generate a compiler error if there is an old png.h in the search path. */
16
typedef version_1_2_0beta2 Your_png_h_is_not_version_1_2_0beta2;
17

A
Andreas Dilger 已提交
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
const char png_libpng_ver[18] = "1.2.0beta2";
G
Guy Schalnat 已提交
24

25
/* png_sig was changed to a function in version 1.0.5c */
26
/* Place to hold the signature string for a PNG file. */
27
const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
28

29 30 31 32 33 34 35 36 37
/* Invoke global declarations for constant strings for known chunk types */
PNG_IHDR;
PNG_IDAT;
PNG_IEND;
PNG_PLTE;
PNG_bKGD;
PNG_cHRM;
PNG_gAMA;
PNG_hIST;
38 39
PNG_iCCP;
PNG_iTXt;
40 41
PNG_oFFs;
PNG_pCAL;
42
PNG_sCAL;
43 44
PNG_pHYs;
PNG_sBIT;
45
PNG_sPLT;
46 47 48 49 50
PNG_sRGB;
PNG_tEXt;
PNG_tIME;
PNG_tRNS;
PNG_zTXt;
G
Guy Schalnat 已提交
51 52 53 54

/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */

/* start of interlace block */
55
const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
G
Guy Schalnat 已提交
56 57

/* offset to next interlace block */
58
const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
G
Guy Schalnat 已提交
59 60

/* start of interlace block in the y direction */
61
const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
G
Guy Schalnat 已提交
62 63

/* offset to next interlace block in the y direction */
64
const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
G
Guy Schalnat 已提交
65

66 67
/* width of interlace block (used in assembler routines only) */
#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
68
const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
69
#endif
G
Guy Schalnat 已提交
70

71 72
/* Height of interlace block.  This is not currently used - if you need
 * it, uncomment it here and in png.h
73
const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
G
Guy Schalnat 已提交
74 75
*/

76
/* Mask to determine which pixels are valid in a pass */
77
const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
G
Guy Schalnat 已提交
78

79
/* Mask to determine which pixels to overwrite while displaying */
80 81
const int FARDATA png_pass_dsp_mask[]
   = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
G
Guy Schalnat 已提交
82

83 84
#endif

A
Andreas Dilger 已提交
85 86 87 88 89
/* Tells libpng that we have already handled the first "num_bytes" bytes
 * of the PNG file signature.  If the PNG data is embedded into another
 * stream we can set num_bytes = 8 so that libpng will not attempt to read
 * or write any of the magic bytes before it starts on the IHDR.
 */
90

91
void PNGAPI
A
Andreas Dilger 已提交
92 93
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
{
A
Andreas Dilger 已提交
94
   png_debug(1, "in png_set_sig_bytes\n");
A
Andreas Dilger 已提交
95 96 97
   if (num_bytes > 8)
      png_error(png_ptr, "Too many bytes for PNG signature.");

98
   png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
A
Andreas Dilger 已提交
99 100 101 102 103 104 105 106 107 108
}

/* Checks whether the supplied bytes match the PNG signature.  We allow
 * checking less than the full 8-byte signature so that those apps that
 * already read the first few bytes of a file to determine the file type
 * can simply check the remaining bytes for extra assurance.  Returns
 * an integer less than, equal to, or greater than zero if sig is found,
 * respectively, to be less than, to match, or be greater than the correct
 * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
 */
109
int PNGAPI
A
Andreas Dilger 已提交
110
png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
G
Guy Schalnat 已提交
111
{
112
   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
A
Andreas Dilger 已提交
113 114 115
   if (num_to_check > 8)
      num_to_check = 8;
   else if (num_to_check < 1)
116
      return (0);
A
Andreas Dilger 已提交
117

A
Andreas Dilger 已提交
118
   if (start > 7)
119
      return (0);
G
Guy Schalnat 已提交
120

A
Andreas Dilger 已提交
121 122 123
   if (start + num_to_check > 8)
      num_to_check = 8 - start;

124
   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
A
Andreas Dilger 已提交
125 126 127
}

/* (Obsolete) function to check signature bytes.  It does not allow one
128 129
 * to check a partial signature.  This function might be removed in the
 * future - use png_sig_cmp().  Returns true (nonzero) if the file is a PNG.
130
 */
131
int PNGAPI
A
Andreas Dilger 已提交
132 133
png_check_sig(png_bytep sig, int num)
{
134
  return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
G
Guy Schalnat 已提交
135 136
}

137
/* Function to allocate memory for zlib and clear it to 0. */
138
voidpf /* PRIVATE */
G
Guy Schalnat 已提交
139
png_zalloc(voidpf png_ptr, uInt items, uInt size)
G
Guy Schalnat 已提交
140
{
141 142
   png_uint_32 num_bytes = (png_uint_32)items * size;
   png_voidp ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
G
Guy Schalnat 已提交
143

144
#ifndef PNG_NO_ZALLOC_ZERO
145
   if (num_bytes > (png_uint_32)0x8000L)
G
Guy Schalnat 已提交
146
   {
147 148 149 150 151 152 153
      png_memset(ptr, 0, (png_size_t)0x8000L);
      png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
         (png_size_t)(num_bytes - (png_uint_32)0x8000L));
   }
   else
   {
      png_memset(ptr, 0, (png_size_t)num_bytes);
G
Guy Schalnat 已提交
154
   }
155
#endif
156
   return ((voidpf)ptr);
G
Guy Schalnat 已提交
157 158 159
}

/* function to free memory for zlib */
160
void /* PRIVATE */
G
Guy Schalnat 已提交
161
png_zfree(voidpf png_ptr, voidpf ptr)
G
Guy Schalnat 已提交
162
{
A
Andreas Dilger 已提交
163
   png_free((png_structp)png_ptr, (png_voidp)ptr);
G
Guy Schalnat 已提交
164 165
}

A
Andreas Dilger 已提交
166
/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
167 168
 * in case CRC is > 32 bits to leave the top bits 0.
 */
169
void /* PRIVATE */
G
Guy Schalnat 已提交
170
png_reset_crc(png_structp png_ptr)
G
Guy Schalnat 已提交
171
{
A
Andreas Dilger 已提交
172
   png_ptr->crc = crc32(0, Z_NULL, 0);
G
Guy Schalnat 已提交
173 174
}

A
Andreas Dilger 已提交
175
/* Calculate the CRC over a section of data.  We can only pass as
176 177 178 179
 * much data to this routine as the largest single buffer size.  We
 * also check that this data will actually be used before going to the
 * trouble of calculating it.
 */
180
void /* PRIVATE */
A
Andreas Dilger 已提交
181
png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
G
Guy Schalnat 已提交
182
{
A
Andreas Dilger 已提交
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
   int need_crc = 1;

   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
   {
      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
         need_crc = 0;
   }
   else                                                    /* critical */
   {
      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
         need_crc = 0;
   }

   if (need_crc)
198
      png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
G
Guy Schalnat 已提交
199
}
G
Guy Schalnat 已提交
200

A
Andreas Dilger 已提交
201
/* Allocate the memory for an info_struct for the application.  We don't
202 203 204 205 206
 * really need the png_ptr, but it could potentially be useful in the
 * future.  This should be used in favour of malloc(sizeof(png_info))
 * and png_info_init() so that applications that want to use a shared
 * libpng don't have to be recompiled if png_info changes size.
 */
207
png_infop PNGAPI
G
Guy Schalnat 已提交
208 209 210 211
png_create_info_struct(png_structp png_ptr)
{
   png_infop info_ptr;

A
Andreas Dilger 已提交
212
   png_debug(1, "in png_create_info_struct\n");
213
   if(png_ptr == NULL) return (NULL);
214 215
#ifdef PNG_USER_MEM_SUPPORTED
   if ((info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
216
      png_ptr->malloc_fn)) != NULL)
217
#else
G
Guy Schalnat 已提交
218
   if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
219
#endif
G
Guy Schalnat 已提交
220
   {
221
      png_info_init(info_ptr);
G
Guy Schalnat 已提交
222 223
   }

224
   return (info_ptr);
G
Guy Schalnat 已提交
225 226
}

A
Andreas Dilger 已提交
227
/* This function frees the memory associated with a single info struct.
228 229 230 231
 * Normally, one would use either png_destroy_read_struct() or
 * png_destroy_write_struct() to free an info struct, but this may be
 * useful for some applications.
 */
232
void PNGAPI
A
Andreas Dilger 已提交
233 234 235 236
png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
{
   png_infop info_ptr = NULL;

A
Andreas Dilger 已提交
237 238
   png_debug(1, "in png_destroy_info_struct\n");
   if (info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
239 240
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
241
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
242 243 244
   {
      png_info_destroy(png_ptr, info_ptr);

245
#ifdef PNG_USER_MEM_SUPPORTED
246
      png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn);
247
#else
A
Andreas Dilger 已提交
248
      png_destroy_struct((png_voidp)info_ptr);
249
#endif
A
Andreas Dilger 已提交
250 251 252 253 254
      *info_ptr_ptr = (png_infop)NULL;
   }
}

/* Initialize the info structure.  This is now an internal function (0.89)
255 256 257
 * and applications using it are urged to use png_create_info_struct()
 * instead.
 */
258
void /* PRIVATE */
A
Andreas Dilger 已提交
259
png_info_init(png_infop info_ptr)
G
Guy Schalnat 已提交
260
{
261
   png_debug(1, "in png_info_init\n");
G
Guy Schalnat 已提交
262
   /* set everything to 0 */
A
Andreas Dilger 已提交
263 264 265
   png_memset(info_ptr, 0, sizeof (png_info));
}

266
#ifdef PNG_FREE_ME_SUPPORTED
267
void PNGAPI
268 269 270 271 272 273 274 275 276 277 278 279 280 281
png_data_freer(png_structp png_ptr, png_infop info_ptr,
   int freer, png_uint_32 mask)
{
   png_debug(1, "in png_data_freer\n");
   if (png_ptr == NULL || info_ptr == NULL)
      return;
   if(freer == PNG_DESTROY_WILL_FREE_DATA)
      info_ptr->free_me |= mask;
   else if(freer == PNG_USER_WILL_FREE_DATA)
      info_ptr->free_me &= ~mask;
   else
      png_warning(png_ptr,
         "Unknown freer parameter in png_data_freer.");
}
282
#endif
283

284
void PNGAPI
285 286
png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
   int num)
287
{
288
   png_debug(1, "in png_free_data\n");
289 290
   if (png_ptr == NULL || info_ptr == NULL)
      return;
291 292 293

#if defined(PNG_TEXT_SUPPORTED)
/* free text item num or (if num == -1) all text items */
294
#ifdef PNG_FREE_ME_SUPPORTED
295
if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
296 297
#else
if (mask & PNG_FREE_TEXT)
298
#endif
299
{
300 301
   if (num != -1)
   {
302
     if (info_ptr->text && info_ptr->text[num].key)
303 304 305 306 307
     {
         png_free(png_ptr, info_ptr->text[num].key);
         info_ptr->text[num].key = NULL;
     }
   }
308
   else
309
   {
310 311 312 313 314 315
       int i;
       for (i = 0; i < info_ptr->num_text; i++)
           png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
       png_free(png_ptr, info_ptr->text);
       info_ptr->text = NULL;
       info_ptr->num_text=0;
316 317 318 319 320 321
   }
}
#endif

#if defined(PNG_tRNS_SUPPORTED)
/* free any tRNS entry */
322
#ifdef PNG_FREE_ME_SUPPORTED
323
if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
324
#else
325
if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
326
#endif
327
{
328 329
    png_free(png_ptr, info_ptr->trans);
    info_ptr->valid &= ~PNG_INFO_tRNS;
330
    info_ptr->trans = NULL;
331 332 333 334 335
}
#endif

#if defined(PNG_sCAL_SUPPORTED)
/* free any sCAL entry */
336
#ifdef PNG_FREE_ME_SUPPORTED
337
if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
338 339 340
#else
if (mask & PNG_FREE_SCAL)
#endif
341
{
342
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
343 344
    png_free(png_ptr, info_ptr->scal_s_width);
    png_free(png_ptr, info_ptr->scal_s_height);
345 346
    info_ptr->scal_s_width = NULL;
    info_ptr->scal_s_height = NULL;
347
#endif
348
    info_ptr->valid &= ~PNG_INFO_sCAL;
349 350 351 352 353
}
#endif

#if defined(PNG_pCAL_SUPPORTED)
/* free any pCAL entry */
354
#ifdef PNG_FREE_ME_SUPPORTED
355
if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
356 357 358
#else
if (mask & PNG_FREE_PCAL)
#endif
359
{
360 361
    png_free(png_ptr, info_ptr->pcal_purpose);
    png_free(png_ptr, info_ptr->pcal_units);
362 363
    info_ptr->pcal_purpose = NULL;
    info_ptr->pcal_units = NULL;
364 365 366 367
    if (info_ptr->pcal_params != NULL)
    {
        int i;
        for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
368
        {
369
          png_free(png_ptr, info_ptr->pcal_params[i]);
370 371
          info_ptr->pcal_params[i]=NULL;
        }
372
        png_free(png_ptr, info_ptr->pcal_params);
373
        info_ptr->pcal_params = NULL;
374 375
    }
    info_ptr->valid &= ~PNG_INFO_pCAL;
376 377 378 379
}
#endif

#if defined(PNG_iCCP_SUPPORTED)
380
/* free any iCCP entry */
381
#ifdef PNG_FREE_ME_SUPPORTED
382
if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
383
#else
384
if (mask & PNG_FREE_ICCP)
385
#endif
386
{
387 388
    png_free(png_ptr, info_ptr->iccp_name);
    png_free(png_ptr, info_ptr->iccp_profile);
389 390
    info_ptr->iccp_name = NULL;
    info_ptr->iccp_profile = NULL;
391
    info_ptr->valid &= ~PNG_INFO_iCCP;
392 393 394 395 396
}
#endif

#if defined(PNG_sPLT_SUPPORTED)
/* free a given sPLT entry, or (if num == -1) all sPLT entries */
397
#ifdef PNG_FREE_ME_SUPPORTED
398
if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
399
#else
400
if (mask & PNG_FREE_SPLT)
401
#endif
402 403 404
{
   if (num != -1)
   {
405 406 407 408
      if(info_ptr->splt_palettes)
      {
          png_free(png_ptr, info_ptr->splt_palettes[num].name);
          png_free(png_ptr, info_ptr->splt_palettes[num].entries);
409 410
          info_ptr->splt_palettes[num].name = NULL;
          info_ptr->splt_palettes[num].entries = NULL;
411
      }
412 413 414
   }
   else
   {
415 416 417 418 419
       if(info_ptr->splt_palettes_num)
       {
         int i;
         for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
            png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
420

421
         png_free(png_ptr, info_ptr->splt_palettes);
422
         info_ptr->splt_palettes = NULL;
423 424
         info_ptr->splt_palettes_num = 0;
       }
425
       info_ptr->valid &= ~PNG_INFO_sPLT;
426 427 428 429 430
   }
}
#endif

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
431
#ifdef PNG_FREE_ME_SUPPORTED
432
if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
433
#else
434
if (mask & PNG_FREE_UNKN)
435
#endif
436 437 438
{
   if (num != -1)
   {
439 440 441 442 443
       if(info_ptr->unknown_chunks)
       {
          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
          info_ptr->unknown_chunks[num].data = NULL;
       }
444 445 446
   }
   else
   {
447 448
       int i;

449 450 451 452
       if(info_ptr->unknown_chunks_num)
       {
         for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
            png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
453

454
         png_free(png_ptr, info_ptr->unknown_chunks);
455
         info_ptr->unknown_chunks = NULL;
456 457
         info_ptr->unknown_chunks_num = 0;
       }
458 459 460 461 462 463
   }
}
#endif

#if defined(PNG_hIST_SUPPORTED)
/* free any hIST entry */
464
#ifdef PNG_FREE_ME_SUPPORTED
465
if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
466
#else
467
if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
468
#endif
469
{
470
    png_free(png_ptr, info_ptr->hist);
471
    info_ptr->hist = NULL;
472
    info_ptr->valid &= ~PNG_INFO_hIST;
473 474 475 476
}
#endif

/* free any PLTE entry that was internally allocated */
477
#ifdef PNG_FREE_ME_SUPPORTED
478
if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
479
#else
480
if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
481
#endif
482
{
483
    png_zfree(png_ptr, info_ptr->palette);
484
    info_ptr->palette = NULL;
485 486
    info_ptr->valid &= ~PNG_INFO_PLTE;
    info_ptr->num_palette = 0;
487 488 489 490
}

#if defined(PNG_INFO_IMAGE_SUPPORTED)
/* free any image bits attached to the info structure */
491
#ifdef PNG_FREE_ME_SUPPORTED
492
if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
493 494
#else
if (mask & PNG_FREE_ROWS)
495
#endif
496 497 498
{
    if(info_ptr->row_pointers)
    {
499 500
       int row;
       for (row = 0; row < (int)info_ptr->height; row++)
501
       {
502
          png_free(png_ptr, info_ptr->row_pointers[row]);
503 504
          info_ptr->row_pointers[row]=NULL;
       }
505
       png_free(png_ptr, info_ptr->row_pointers);
506 507
       info_ptr->row_pointers=NULL;
    }
508
    info_ptr->valid &= ~PNG_INFO_IDAT;
509
}
510
#endif
511

512
#ifdef PNG_FREE_ME_SUPPORTED
513 514
   if(num == -1)
     info_ptr->free_me &= ~mask;
515 516
   else
     info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
517
#endif
518
}
519

A
Andreas Dilger 已提交
520
/* This is an internal routine to free any memory that the info struct is
A
Andreas Dilger 已提交
521 522 523
 * pointing to before re-using it or freeing the struct itself.  Recall
 * that png_free() checks for NULL pointers for us.
 */
524
void /* PRIVATE */
A
Andreas Dilger 已提交
525 526
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
{
A
Andreas Dilger 已提交
527
   png_debug(1, "in png_info_destroy\n");
528 529

   png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
530

531
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
532 533 534
   if (png_ptr->num_chunk_list)
   {
       png_free(png_ptr, png_ptr->chunk_list);
535
       png_ptr->chunk_list=NULL;
536 537
       png_ptr->num_chunk_list=0;
   }
A
Andreas Dilger 已提交
538
#endif
539

540
   png_info_init(info_ptr);
G
Guy Schalnat 已提交
541
}
G
Guy Schalnat 已提交
542

G
Guy Schalnat 已提交
543
/* This function returns a pointer to the io_ptr associated with the user
544 545 546
 * functions.  The application should free any memory associated with this
 * pointer before png_write_destroy() or png_read_destroy() are called.
 */
547
png_voidp PNGAPI
G
Guy Schalnat 已提交
548 549
png_get_io_ptr(png_structp png_ptr)
{
550
   return (png_ptr->io_ptr);
G
Guy Schalnat 已提交
551
}
A
Andreas Dilger 已提交
552 553 554

#if !defined(PNG_NO_STDIO)
/* Initialize the default input/output functions for the PNG file.  If you
555
 * use your own read or write routines, you can call either png_set_read_fn()
556 557 558
 * or png_set_write_fn() instead of png_init_io().  If you have defined
 * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
 * necessarily available.
559
 */
560
void PNGAPI
561
png_init_io(png_structp png_ptr, png_FILE_p fp)
G
Guy Schalnat 已提交
562
{
A
Andreas Dilger 已提交
563
   png_debug(1, "in png_init_io\n");
G
Guy Schalnat 已提交
564 565
   png_ptr->io_ptr = (png_voidp)fp;
}
A
Andreas Dilger 已提交
566
#endif
567 568 569 570 571

#if defined(PNG_TIME_RFC1123_SUPPORTED)
/* Convert the supplied time into an RFC 1123 string suitable for use in
 * a "Creation Time" or other text-based time string.
 */
572
png_charp PNGAPI
573 574 575
png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
{
   static PNG_CONST char short_months[12][4] =
576 577
        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
578 579 580 581 582 583 584

   if (png_ptr->time_buffer == NULL)
   {
      png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
         sizeof(char)));
   }

585
#if defined(_WIN32_WCE)
586 587 588 589 590 591 592 593 594
   {
      wchar_t time_buf[29];
      wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
          ptime->day % 32, short_months[(ptime->month - 1) % 12],
        ptime->year, ptime->hour % 24, ptime->minute % 60,
          ptime->second % 61);
      WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
          NULL, NULL);
   }
595
#else
596
#ifdef USE_FAR_KEYWORD
597 598 599 600 601 602 603 604 605
   {
      char near_time_buf[29];
      sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
          ptime->day % 32, short_months[(ptime->month - 1) % 12],
          ptime->year, ptime->hour % 24, ptime->minute % 60,
          ptime->second % 61);
      png_memcpy(png_ptr->time_buffer, near_time_buf,
          29*sizeof(char));
   }
606 607
#else
   sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
608 609 610
       ptime->day % 32, short_months[(ptime->month - 1) % 12],
       ptime->year, ptime->hour % 24, ptime->minute % 60,
       ptime->second % 61);
611
#endif
612
#endif /* _WIN32_WCE */
613 614 615
   return ((png_charp)png_ptr->time_buffer);
}
#endif /* PNG_TIME_RFC1123_SUPPORTED */
616

617
#if 0
618
/* Signature string for a PNG file. */
619
png_bytep PNGAPI
620
png_sig_bytes(void)
621
{
622
   return ((png_bytep)"\211\120\116\107\015\012\032\012");
623
}
624
#endif
625

626
png_charp PNGAPI
627 628
png_get_copyright(png_structp png_ptr)
{
629
   if (png_ptr != NULL || png_ptr == NULL)  /* silence compiler warning */
630
   return ((png_charp) "\n libpng version 1.2.0beta2 - May 7, 2001\n\
631
   Copyright (c) 1998-2001 Glenn Randers-Pehrson\n\
632
   Copyright (c) 1996, 1997 Andreas Dilger\n\
633
   Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n");
634
   return ((png_charp) "");
635
}
636

637 638 639 640 641 642
/* The following return the library version as a short string in the
 * format 1.0.0 through 99.99.99zz.  To get the version of *.h files used
 * with your application, print out PNG_LIBPNG_VER_STRING, which is defined
 * in png.h.
 */

643
png_charp PNGAPI
644 645 646 647
png_get_libpng_ver(png_structp png_ptr)
{
   /* Version of *.c files used when building libpng */
   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
648 649
      return((png_charp) "1.2.0beta2");
   return((png_charp) "1.2.0beta2");
650 651
}

652
png_charp PNGAPI
653 654 655 656
png_get_header_ver(png_structp png_ptr)
{
   /* Version of *.h files used when building libpng */
   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
657 658
      return((png_charp) PNG_LIBPNG_VER_STRING);
   return((png_charp) PNG_LIBPNG_VER_STRING);
659 660
}

661
png_charp PNGAPI
662 663 664 665
png_get_header_version(png_structp png_ptr)
{
   /* Returns longer string containing both version and date */
   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
666 667
      return((png_charp) PNG_HEADER_VERSION_STRING);
   return((png_charp) PNG_HEADER_VERSION_STRING);
668 669
}

670
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
671
int /* PRIVATE */
672 673 674 675 676 677 678 679 680 681 682 683 684 685
png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
{
   /* check chunk_name and return "keep" value if it's on the list, else 0 */
   int i;
   png_bytep p;
   if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
      return 0;
   p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
   for (i = png_ptr->num_chunk_list; i; i--, p-=5)
      if (!png_memcmp(chunk_name, p, 4))
        return ((int)*(p+4));
   return 0;
}
#endif
686 687

/* This function, added to libpng-1.0.6g, is untested. */
688
int PNGAPI
689 690 691 692
png_reset_zstream(png_structp png_ptr)
{
   return (inflateReset(&png_ptr->zstream));
}
693

694
/* This function was added to libpng-1.0.7 */
695 696 697 698
png_uint_32 PNGAPI
png_access_version_number(void)
{
   /* Version of *.c files used when building libpng */
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
   return((png_uint_32) 10200L);
}


#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
    /* GRR:  could add this:   && defined(PNG_MMX_CODE_SUPPORTED) */
/* this INTERNAL function was added to libpng 1.2.0 */
void /* PRIVATE */
png_init_mmx_flags (png_structp png_ptr)
{
    png_ptr->mmx_rowbytes_threshold = 0;
    png_ptr->mmx_bitdepth_threshold = 0;

#if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))

    png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;

    if (png_mmx_support()) {
        png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
                              | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
#endif
#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
                              | PNG_ASM_FLAG_MMX_READ_INTERLACE
#endif
#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
                              ;
#else
                              | PNG_ASM_FLAG_MMX_READ_FILTER_SUB
                              | PNG_ASM_FLAG_MMX_READ_FILTER_UP
                              | PNG_ASM_FLAG_MMX_READ_FILTER_AVG
                              | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;

        png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
        png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
#endif
    } else {
        png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
                               | PNG_MMX_READ_FLAGS
                               | PNG_MMX_WRITE_FLAGS );
    }

#else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */

    /* clear all MMX flags; no support is compiled in */
    png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );

#endif /* ?(PNGVCRD || PNGGCCRD) */
747
}
748

749 750
#endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */

751 752 753
/* this function was added to libpng 1.2.0 */
#if !defined(PNG_USE_PNGGCCRD) && \
    !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
754 755 756 757 758 759
int PNGAPI
png_mmx_support(void)
{
    return -1;
}
#endif