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

2 3
/* png.c - location for general purpose libpng functions
 *
4
 * Last changed in libpng 1.4.0 [December 15, 2008]
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2008 Glenn Randers-Pehrson
7 8
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9
 */
G
Guy Schalnat 已提交
10 11 12

#define PNG_NO_EXTERN
#include "png.h"
13
#include "pngpriv.h"
G
Guy Schalnat 已提交
14

15
/* Generate a compiler error if there is an old png.h in the search path. */
16
typedef version_1_4_0beta47 Your_png_h_is_not_version_1_4_0beta47;
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
PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
G
Guy Schalnat 已提交
24

25 26
#ifdef PNG_READ_SUPPORTED

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 33 34 35 36 37 38 39 40
/* 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;
41 42
PNG_iCCP;
PNG_iTXt;
43 44
PNG_oFFs;
PNG_pCAL;
45
PNG_sCAL;
46 47
PNG_pHYs;
PNG_sBIT;
48
PNG_sPLT;
49 50 51 52 53
PNG_sRGB;
PNG_tEXt;
PNG_tIME;
PNG_tRNS;
PNG_zTXt;
G
Guy Schalnat 已提交
54

55
#ifdef PNG_READ_SUPPORTED
G
Guy Schalnat 已提交
56 57 58
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */

/* start of interlace block */
59
PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
G
Guy Schalnat 已提交
60 61

/* offset to next interlace block */
62
PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
G
Guy Schalnat 已提交
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};
G
Guy Schalnat 已提交
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};
G
Guy Schalnat 已提交
69

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

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

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

82
#endif /* PNG_READ_SUPPORTED */
83
#endif /* PNG_USE_GLOBAL_ARRAYS */
84

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
#ifdef PNG_READ_SUPPORTED
92
void PNGAPI
A
Andreas Dilger 已提交
93 94
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
{
95
   if (png_ptr == NULL) return;
96
   png_debug(1, "in png_set_sig_bytes");
A
Andreas Dilger 已提交
97
   if (num_bytes > 8)
98
      png_error(png_ptr, "Too many bytes for PNG signature");
A
Andreas Dilger 已提交
99

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

/* 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).
 */
111
int PNGAPI
A
Andreas Dilger 已提交
112
png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
G
Guy Schalnat 已提交
113
{
114
   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
A
Andreas Dilger 已提交
115 116 117
   if (num_to_check > 8)
      num_to_check = 8;
   else if (num_to_check < 1)
118
      return (-1);
A
Andreas Dilger 已提交
119

A
Andreas Dilger 已提交
120
   if (start > 7)
121
      return (-1);
G
Guy Schalnat 已提交
122

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

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

129
#endif /* PNG_READ_SUPPORTED */
G
Guy Schalnat 已提交
130

131
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
132
/* Function to allocate memory for zlib and clear it to 0. */
133
voidpf /* private */
G
Guy Schalnat 已提交
134
png_zalloc(voidpf png_ptr, uInt items, uInt size)
G
Guy Schalnat 已提交
135
{
136 137 138
   png_voidp ptr;
   png_structp p=(png_structp)png_ptr;
   png_uint_32 save_flags=p->flags;
139
   png_alloc_size_t num_bytes;
140

141
   if (png_ptr == NULL) return (NULL);
142 143
   if (items > PNG_UINT_32_MAX/size)
   {
144 145
     png_warning (p, "Potential overflow in png_zalloc()");
     return (NULL);
146
   }
147
   num_bytes = (png_alloc_size_t)items * size;
G
Guy Schalnat 已提交
148

149 150 151
   p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
   ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
   p->flags=save_flags;
G
Guy Schalnat 已提交
152

153 154 155 156
   return ((voidpf)ptr);
}

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

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

A
Andreas Dilger 已提交
172
/* Calculate the CRC over a section of data.  We can only pass as
173 174 175 176
 * 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.
 */
177
void /* PRIVATE */
A
Andreas Dilger 已提交
178
png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
G
Guy Schalnat 已提交
179
{
A
Andreas Dilger 已提交
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
   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)
195
      png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
G
Guy Schalnat 已提交
196
}
G
Guy Schalnat 已提交
197

A
Andreas Dilger 已提交
198
/* Allocate the memory for an info_struct for the application.  We don't
199
 * really need the png_ptr, but it could potentially be useful in the
200
 * future.  This should be used in favour of malloc(png_sizeof(png_info))
201 202 203
 * 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.
 */
204
png_infop PNGAPI
G
Guy Schalnat 已提交
205 206 207 208
png_create_info_struct(png_structp png_ptr)
{
   png_infop info_ptr;

209
   png_debug(1, "in png_create_info_struct");
210
   if (png_ptr == NULL) return (NULL);
211
#ifdef PNG_USER_MEM_SUPPORTED
212 213
   info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
      png_ptr->malloc_fn, png_ptr->mem_ptr);
214
#else
215
   info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
216
#endif
217
   if (info_ptr != NULL)
218
      png_info_init_3(&info_ptr, png_sizeof(png_info));
G
Guy Schalnat 已提交
219

220
   return (info_ptr);
G
Guy Schalnat 已提交
221 222
}

A
Andreas Dilger 已提交
223
/* This function frees the memory associated with a single info struct.
224 225 226 227
 * 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.
 */
228
void PNGAPI
A
Andreas Dilger 已提交
229 230 231
png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
{
   png_infop info_ptr = NULL;
232
   if (png_ptr == NULL) return;
A
Andreas Dilger 已提交
233

234
   png_debug(1, "in png_destroy_info_struct");
A
Andreas Dilger 已提交
235
   if (info_ptr_ptr != NULL)
A
Andreas Dilger 已提交
236 237
      info_ptr = *info_ptr_ptr;

A
Andreas Dilger 已提交
238
   if (info_ptr != NULL)
A
Andreas Dilger 已提交
239 240 241
   {
      png_info_destroy(png_ptr, info_ptr);

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

/* Initialize the info structure.  This is now an internal function (0.89)
253 254 255
 * and applications using it are urged to use png_create_info_struct()
 * instead.
 */
256

257 258 259 260 261
void PNGAPI
png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
{
   png_infop info_ptr = *ptr_ptr;

262
   if (info_ptr == NULL) return;
263

264
   png_debug(1, "in png_info_init_3");
265

266
   if (png_sizeof(png_info) > png_info_struct_size)
267 268 269 270 271 272
     {
       png_destroy_struct(info_ptr);
       info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
       *ptr_ptr = info_ptr;
     }

G
Guy Schalnat 已提交
273
   /* set everything to 0 */
274
   png_memset(info_ptr, 0, png_sizeof(png_info));
A
Andreas Dilger 已提交
275 276
}

277
#ifdef PNG_FREE_ME_SUPPORTED
278
void PNGAPI
279 280 281
png_data_freer(png_structp png_ptr, png_infop info_ptr,
   int freer, png_uint_32 mask)
{
282
   png_debug(1, "in png_data_freer");
283 284
   if (png_ptr == NULL || info_ptr == NULL)
      return;
285
   if (freer == PNG_DESTROY_WILL_FREE_DATA)
286
      info_ptr->free_me |= mask;
287
   else if (freer == PNG_USER_WILL_FREE_DATA)
288 289 290
      info_ptr->free_me &= ~mask;
   else
      png_warning(png_ptr,
291
         "Unknown freer parameter in png_data_freer");
292
}
293
#endif
294

295
void PNGAPI
296 297
png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
   int num)
298
{
299
   png_debug(1, "in png_free_data");
300 301
   if (png_ptr == NULL || info_ptr == NULL)
      return;
302 303 304

#if defined(PNG_TEXT_SUPPORTED)
/* free text item num or (if num == -1) all text items */
305
#ifdef PNG_FREE_ME_SUPPORTED
306
if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
307 308
#else
if (mask & PNG_FREE_TEXT)
309
#endif
310
{
311 312
   if (num != -1)
   {
313
     if (info_ptr->text && info_ptr->text[num].key)
314 315 316 317 318
     {
         png_free(png_ptr, info_ptr->text[num].key);
         info_ptr->text[num].key = NULL;
     }
   }
319
   else
320
   {
321 322 323 324 325 326
       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;
327 328 329 330 331 332
   }
}
#endif

#if defined(PNG_tRNS_SUPPORTED)
/* free any tRNS entry */
333
#ifdef PNG_FREE_ME_SUPPORTED
334
if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
335
#else
336
if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
337
#endif
338
{
339
    png_free(png_ptr, info_ptr->trans);
340
    info_ptr->trans = NULL;
341
    info_ptr->valid &= ~PNG_INFO_tRNS;
342 343 344
#ifndef PNG_FREE_ME_SUPPORTED
    png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
#endif
345 346 347 348 349
}
#endif

#if defined(PNG_sCAL_SUPPORTED)
/* free any sCAL entry */
350
#ifdef PNG_FREE_ME_SUPPORTED
351
if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
352 353 354
#else
if (mask & PNG_FREE_SCAL)
#endif
355
{
356
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
357 358
    png_free(png_ptr, info_ptr->scal_s_width);
    png_free(png_ptr, info_ptr->scal_s_height);
359 360
    info_ptr->scal_s_width = NULL;
    info_ptr->scal_s_height = NULL;
361
#endif
362
    info_ptr->valid &= ~PNG_INFO_sCAL;
363 364 365 366 367
}
#endif

#if defined(PNG_pCAL_SUPPORTED)
/* free any pCAL entry */
368
#ifdef PNG_FREE_ME_SUPPORTED
369
if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
370 371 372
#else
if (mask & PNG_FREE_PCAL)
#endif
373
{
374 375
    png_free(png_ptr, info_ptr->pcal_purpose);
    png_free(png_ptr, info_ptr->pcal_units);
376 377
    info_ptr->pcal_purpose = NULL;
    info_ptr->pcal_units = NULL;
378 379 380 381
    if (info_ptr->pcal_params != NULL)
    {
        int i;
        for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
382
        {
383
          png_free(png_ptr, info_ptr->pcal_params[i]);
384 385
          info_ptr->pcal_params[i]=NULL;
        }
386
        png_free(png_ptr, info_ptr->pcal_params);
387
        info_ptr->pcal_params = NULL;
388 389
    }
    info_ptr->valid &= ~PNG_INFO_pCAL;
390 391 392 393
}
#endif

#if defined(PNG_iCCP_SUPPORTED)
394
/* free any iCCP entry */
395
#ifdef PNG_FREE_ME_SUPPORTED
396
if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
397
#else
398
if (mask & PNG_FREE_ICCP)
399
#endif
400
{
401 402
    png_free(png_ptr, info_ptr->iccp_name);
    png_free(png_ptr, info_ptr->iccp_profile);
403 404
    info_ptr->iccp_name = NULL;
    info_ptr->iccp_profile = NULL;
405
    info_ptr->valid &= ~PNG_INFO_iCCP;
406 407 408 409 410
}
#endif

#if defined(PNG_sPLT_SUPPORTED)
/* free a given sPLT entry, or (if num == -1) all sPLT entries */
411
#ifdef PNG_FREE_ME_SUPPORTED
412
if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
413
#else
414
if (mask & PNG_FREE_SPLT)
415
#endif
416 417 418
{
   if (num != -1)
   {
419
      if (info_ptr->splt_palettes)
420 421 422
      {
          png_free(png_ptr, info_ptr->splt_palettes[num].name);
          png_free(png_ptr, info_ptr->splt_palettes[num].entries);
423 424
          info_ptr->splt_palettes[num].name = NULL;
          info_ptr->splt_palettes[num].entries = NULL;
425
      }
426 427 428
   }
   else
   {
429
       if (info_ptr->splt_palettes_num)
430 431 432 433
       {
         int i;
         for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
            png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
434

435
         png_free(png_ptr, info_ptr->splt_palettes);
436
         info_ptr->splt_palettes = NULL;
437 438
         info_ptr->splt_palettes_num = 0;
       }
439
       info_ptr->valid &= ~PNG_INFO_sPLT;
440 441 442 443 444
   }
}
#endif

#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
445 446 447 448 449
  if (png_ptr->unknown_chunk.data)
  {
    png_free(png_ptr, png_ptr->unknown_chunk.data);
    png_ptr->unknown_chunk.data = NULL;
  }
450

451
#ifdef PNG_FREE_ME_SUPPORTED
452
if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
453
#else
454
if (mask & PNG_FREE_UNKN)
455
#endif
456 457 458
{
   if (num != -1)
   {
459
       if (info_ptr->unknown_chunks)
460 461 462 463
       {
          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
          info_ptr->unknown_chunks[num].data = NULL;
       }
464 465 466
   }
   else
   {
467 468
       int i;

469
       if (info_ptr->unknown_chunks_num)
470 471 472
       {
         for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
            png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
473

474
         png_free(png_ptr, info_ptr->unknown_chunks);
475
         info_ptr->unknown_chunks = NULL;
476 477
         info_ptr->unknown_chunks_num = 0;
       }
478 479 480 481 482 483
   }
}
#endif

#if defined(PNG_hIST_SUPPORTED)
/* free any hIST entry */
484
#ifdef PNG_FREE_ME_SUPPORTED
485
if ((mask & PNG_FREE_HIST)  & info_ptr->free_me)
486
#else
487
if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
488
#endif
489
{
490
    png_free(png_ptr, info_ptr->hist);
491
    info_ptr->hist = NULL;
492
    info_ptr->valid &= ~PNG_INFO_hIST;
493 494 495
#ifndef PNG_FREE_ME_SUPPORTED
    png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
#endif
496 497 498 499
}
#endif

/* free any PLTE entry that was internally allocated */
500
#ifdef PNG_FREE_ME_SUPPORTED
501
if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
502
#else
503
if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
504
#endif
505
{
506
    png_zfree(png_ptr, info_ptr->palette);
507
    info_ptr->palette = NULL;
508
    info_ptr->valid &= ~PNG_INFO_PLTE;
509 510 511
#ifndef PNG_FREE_ME_SUPPORTED
    png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
#endif
512
    info_ptr->num_palette = 0;
513 514 515 516
}

#if defined(PNG_INFO_IMAGE_SUPPORTED)
/* free any image bits attached to the info structure */
517
#ifdef PNG_FREE_ME_SUPPORTED
518
if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
519 520
#else
if (mask & PNG_FREE_ROWS)
521
#endif
522
{
523
    if (info_ptr->row_pointers)
524
    {
525 526
       int row;
       for (row = 0; row < (int)info_ptr->height; row++)
527
       {
528
          png_free(png_ptr, info_ptr->row_pointers[row]);
529
       }
530
       png_free(png_ptr, info_ptr->row_pointers);
531
    }
532
    info_ptr->valid &= ~PNG_INFO_IDAT;
533
}
534
#endif
535

536
#ifdef PNG_FREE_ME_SUPPORTED
537
   if (num == -1)
538
     info_ptr->free_me &= ~mask;
539 540
   else
     info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
541
#endif
542
}
543

A
Andreas Dilger 已提交
544
/* This is an internal routine to free any memory that the info struct is
A
Andreas Dilger 已提交
545 546 547
 * pointing to before re-using it or freeing the struct itself.  Recall
 * that png_free() checks for NULL pointers for us.
 */
548
void /* PRIVATE */
A
Andreas Dilger 已提交
549 550
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
{
551
   png_debug(1, "in png_info_destroy");
552 553

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

555
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
556 557 558
   if (png_ptr->num_chunk_list)
   {
       png_free(png_ptr, png_ptr->chunk_list);
559
       png_ptr->num_chunk_list = 0;
560
   }
A
Andreas Dilger 已提交
561
#endif
562

563
   png_info_init_3(&info_ptr, png_sizeof(png_info));
G
Guy Schalnat 已提交
564
}
565
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
G
Guy Schalnat 已提交
566

G
Guy Schalnat 已提交
567
/* This function returns a pointer to the io_ptr associated with the user
568 569 570
 * functions.  The application should free any memory associated with this
 * pointer before png_write_destroy() or png_read_destroy() are called.
 */
571
png_voidp PNGAPI
G
Guy Schalnat 已提交
572 573
png_get_io_ptr(png_structp png_ptr)
{
574
   if (png_ptr == NULL) return (NULL);
575
   return (png_ptr->io_ptr);
G
Guy Schalnat 已提交
576
}
A
Andreas Dilger 已提交
577

578
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
A
Andreas Dilger 已提交
579 580
#if !defined(PNG_NO_STDIO)
/* Initialize the default input/output functions for the PNG file.  If you
581
 * use your own read or write routines, you can call either png_set_read_fn()
582 583 584
 * 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.
585
 */
586
void PNGAPI
587
png_init_io(png_structp png_ptr, png_FILE_p fp)
G
Guy Schalnat 已提交
588
{
589
   png_debug(1, "in png_init_io");
590
   if (png_ptr == NULL) return;
G
Guy Schalnat 已提交
591 592
   png_ptr->io_ptr = (png_voidp)fp;
}
A
Andreas Dilger 已提交
593
#endif
594 595 596 597 598

#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.
 */
599
png_charp PNGAPI
600 601 602
png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
{
   static PNG_CONST char short_months[12][4] =
603 604
        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
605

606
   if (png_ptr == NULL) return (NULL);
607
   if (png_ptr->time_buffer == NULL)
608 609 610 611
   {
      png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
         png_sizeof(char)));
   }
612 613

#ifdef USE_FAR_KEYWORD
614 615
   {
      char near_time_buf[29];
616
      png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000",
617 618 619 620
          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,
621
          29*png_sizeof(char));
622
   }
623
#else
624
   png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000",
625 626 627
       ptime->day % 32, short_months[(ptime->month - 1) % 12],
       ptime->year, ptime->hour % 24, ptime->minute % 60,
       ptime->second % 61);
628 629 630 631
#endif
   return ((png_charp)png_ptr->time_buffer);
}
#endif /* PNG_TIME_RFC1123_SUPPORTED */
632

633
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
634

635
png_charp PNGAPI
636 637
png_get_copyright(png_structp png_ptr)
{
638
   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
639 640 641 642
#ifdef PNG_STRING_COPYRIGHT
      return PNG_STRING_COPYRIGHT
#else
#ifdef __STDC__
643
   return ((png_charp) PNG_STRING_NEWLINE \
644
     "libpng version x 1.4.0beta47 - December 15, 2008" PNG_STRING_NEWLINE \
645 646 647 648
     "Copyright (c) 1998-2008 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
     "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
     "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
     PNG_STRING_NEWLINE);
649
#else
650
      return ((png_charp) "libpng version 1.4.0beta47 - December 15, 2008\
651 652 653 654 655
      Copyright (c) 1998-2008 Glenn Randers-Pehrson\
      Copyright (c) 1996-1997 Andreas Dilger\
      Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.");
#endif
#endif
656
}
657

658
/* The following return the library version as a short string in the
659 660 661 662 663 664
 * 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.
 * Note: now there is no difference between png_get_libpng_ver() and
 * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
 * it is guaranteed that png.c uses the correct version of png.h.
665
 */
666
png_charp PNGAPI
667 668 669
png_get_libpng_ver(png_structp png_ptr)
{
   /* Version of *.c files used when building libpng */
670 671
   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
   return ((png_charp) PNG_LIBPNG_VER_STRING);
672 673
}

674
png_charp PNGAPI
675 676 677
png_get_header_ver(png_structp png_ptr)
{
   /* Version of *.h files used when building libpng */
678 679
   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
   return ((png_charp) PNG_LIBPNG_VER_STRING);
680 681
}

682
png_charp PNGAPI
683 684 685
png_get_header_version(png_structp png_ptr)
{
   /* Returns longer string containing both version and date */
686
   png_ptr = png_ptr;  /* silence compiler warning about unused png_ptr */
687
#ifdef __STDC__
688 689 690 691
   return ((png_charp) PNG_HEADER_VERSION_STRING
#ifndef PNG_READ_SUPPORTED
   "     (NO READ SUPPORT)"
#endif
692
   PNG_STRING_NEWLINE);
693 694 695
#else
   return ((png_charp) PNG_HEADER_VERSION_STRING);
#endif
696 697
}

698
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
699
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
700
int PNGAPI
701 702 703 704 705
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;
706
   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
707
      return 0;
708 709
   p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
   for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
710
      if (!png_memcmp(chunk_name, p, 4))
711
        return ((int)*(p + 4));
712 713 714
   return 0;
}
#endif
715 716

/* This function, added to libpng-1.0.6g, is untested. */
717
int PNGAPI
718 719
png_reset_zstream(png_structp png_ptr)
{
720
   if (png_ptr == NULL) return Z_STREAM_ERROR;
721 722
   return (inflateReset(&png_ptr->zstream));
}
723
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
724

725
/* This function was added to libpng-1.0.7 */
726 727 728 729
png_uint_32 PNGAPI
png_access_version_number(void)
{
   /* Version of *.c files used when building libpng */
730
   return((png_uint_32) PNG_LIBPNG_VER);
731 732 733
}


734

735 736 737 738 739 740
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
#ifdef PNG_SIZE_T
/* Added at libpng version 1.2.6 */
   PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
png_size_t PNGAPI
png_convert_size(size_t size)
741
{
742 743 744
  if (size > (png_size_t)-1)
     PNG_ABORT();  /* We haven't got access to png_ptr, so no png_error() */
  return ((png_size_t)size);
745
}
746
#endif /* PNG_SIZE_T */
747

748
/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
749
#if defined(PNG_cHRM_SUPPORTED)
750
#if !defined(PNG_NO_CHECK_cHRM)
751

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789
/*
 Multiply two 32-bit numbers, V1 and V2, using 32-bit
 arithmetic, to produce a 64 bit result in the HI/LO words.

          A B
        x C D
       ------
      AD || BD
AC || CB || 0

 where A and B are the high and low 16-bit words of V1,
 C and D are the 16-bit words of V2, AD is the product of
 A and D, and X || Y is (X << 16) + Y.
*/

void png_64bit_product (long v1, long v2, unsigned long *hi_product,
   unsigned long *lo_product)
{
 int a, b, c, d;
 long lo, hi, x, y;

 a = (v1 >> 16) & 0xffff;
 b = v1 & 0xffff;
 c = (v2 >> 16) & 0xffff;
 d = v2 & 0xffff;

 lo = b * d;                   /* BD */
 x = a * d + c * b;            /* AD + CB */
 y = ((lo >> 16) & 0xffff) + x;

 lo = (lo & 0xffff) | ((y & 0xffff) << 16);
 hi = (y >> 16) & 0xffff;

 hi += a * c;                  /* AC */

 *hi_product = (unsigned long)hi;
 *lo_product = (unsigned long)lo;
}
790 791 792 793 794 795 796
int /* private */
png_check_cHRM_fixed(png_structp png_ptr,
   png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
   png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
   png_fixed_point blue_x, png_fixed_point blue_y)
{
   int ret = 1;
797
   unsigned long xy_hi,xy_lo,yx_hi,yx_lo;
798 799 800 801 802

   png_debug(1, "in function png_check_cHRM_fixed");
   if (png_ptr == NULL)
      return 0;

803 804 805 806
   if (white_x < 0 || white_y <= 0 ||
         red_x < 0 ||   red_y <  0 ||
       green_x < 0 || green_y <  0 ||
        blue_x < 0 ||  blue_y <  0)
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
   {
      png_warning(png_ptr,
        "Ignoring attempt to set negative chromaticity value");
      ret = 0;
   }
   if (white_x > (png_fixed_point) PNG_UINT_31_MAX ||
       white_y > (png_fixed_point) PNG_UINT_31_MAX ||
         red_x > (png_fixed_point) PNG_UINT_31_MAX ||
         red_y > (png_fixed_point) PNG_UINT_31_MAX ||
       green_x > (png_fixed_point) PNG_UINT_31_MAX ||
       green_y > (png_fixed_point) PNG_UINT_31_MAX ||
        blue_x > (png_fixed_point) PNG_UINT_31_MAX ||
        blue_y > (png_fixed_point) PNG_UINT_31_MAX )
   {
      png_warning(png_ptr,
        "Ignoring attempt to set chromaticity value exceeding 21474.83");
      ret = 0;
   }
825
   if (white_x > 100000L - white_y)
826 827 828 829
   {
      png_warning(png_ptr, "Invalid cHRM white point");
      ret = 0;
   }
830
   if (red_x > 100000L - red_y)
831 832 833 834
   {
      png_warning(png_ptr, "Invalid cHRM red point");
      ret = 0;
   }
835
   if (green_x > 100000L - green_y)
836 837 838 839
   {
      png_warning(png_ptr, "Invalid cHRM green point");
      ret = 0;
   }
840
   if (blue_x > 100000L - blue_y)
841 842 843 844
   {
      png_warning(png_ptr, "Invalid cHRM blue point");
      ret = 0;
   }
845 846 847 848 849 850 851 852 853 854 855

   png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo);
   png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo);

   if (xy_hi == yx_hi && xy_lo == yx_lo)
   {
      png_warning(png_ptr,
         "Ignoring attempt to set cHRM RGB triangle with zero area");
      ret = 0;
   }

856 857
   return ret;
}
858
#endif /* NO_PNG_CHECK_cHRM */
859
#endif /* PNG_cHRM_SUPPORTED */
860
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */