Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
96 giacomo 1
 
2
/* pngrutil.c - utilities to read a PNG file
3
 *
4
 * libpng 1.2.5 - October 3, 2002
5
 * For conditions of distribution and use, see copyright notice in png.h
6
 * Copyright (c) 1998-2002 Glenn Randers-Pehrson
7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9
 *
10
 * This file contains routines that are only called from within
11
 * libpng itself during the course of reading an image.
12
 */
13
 
14
#define PNG_INTERNAL
15
#include "png.h"
16
 
17
#if defined(_WIN32_WCE)
18
/* strtod() function is not supported on WindowsCE */
19
#  ifdef PNG_FLOATING_POINT_SUPPORTED
20
__inline double strtod(const char *nptr, char **endptr)
21
{
22
   double result = 0;
23
   int len;
24
   wchar_t *str, *end;
25
 
26
   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
27
   str = (wchar_t *)malloc(len * sizeof(wchar_t));
28
   if ( NULL != str )
29
   {
30
      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
31
      result = wcstod(str, &end);
32
      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
33
      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
34
      free(str);
35
   }
36
   return result;
37
}
38
#  endif
39
#endif
40
 
41
#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
42
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
43
png_uint_32 /* PRIVATE */
44
png_get_uint_32(png_bytep buf)
45
{
46
   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
47
      ((png_uint_32)(*(buf + 1)) << 16) +
48
      ((png_uint_32)(*(buf + 2)) << 8) +
49
      (png_uint_32)(*(buf + 3));
50
 
51
   return (i);
52
}
53
 
54
#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
55
/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
56
 * data is stored in the PNG file in two's complement format, and it is
57
 * assumed that the machine format for signed integers is the same. */
58
png_int_32 /* PRIVATE */
59
png_get_int_32(png_bytep buf)
60
{
61
   png_int_32 i = ((png_int_32)(*buf) << 24) +
62
      ((png_int_32)(*(buf + 1)) << 16) +
63
      ((png_int_32)(*(buf + 2)) << 8) +
64
      (png_int_32)(*(buf + 3));
65
 
66
   return (i);
67
}
68
#endif /* PNG_READ_pCAL_SUPPORTED */
69
 
70
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
71
png_uint_16 /* PRIVATE */
72
png_get_uint_16(png_bytep buf)
73
{
74
   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
75
      (png_uint_16)(*(buf + 1)));
76
 
77
   return (i);
78
}
79
#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
80
 
81
/* Read data, and (optionally) run it through the CRC. */
82
void /* PRIVATE */
83
png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
84
{
85
   png_read_data(png_ptr, buf, length);
86
   png_calculate_crc(png_ptr, buf, length);
87
}
88
 
89
/* Optionally skip data and then check the CRC.  Depending on whether we
90
   are reading a ancillary or critical chunk, and how the program has set
91
   things up, we may calculate the CRC on the data and print a message.
92
   Returns '1' if there was a CRC error, '0' otherwise. */
93
int /* PRIVATE */
94
png_crc_finish(png_structp png_ptr, png_uint_32 skip)
95
{
96
   png_size_t i;
97
   png_size_t istop = png_ptr->zbuf_size;
98
 
99
   for (i = (png_size_t)skip; i > istop; i -= istop)
100
   {
101
      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
102
   }
103
   if (i)
104
   {
105
      png_crc_read(png_ptr, png_ptr->zbuf, i);
106
   }
107
 
108
   if (png_crc_error(png_ptr))
109
   {
110
      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
111
           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
112
          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
113
          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
114
      {
115
         png_chunk_warning(png_ptr, "CRC error");
116
      }
117
      else
118
      {
119
         png_chunk_error(png_ptr, "CRC error");
120
      }
121
      return (1);
122
   }
123
 
124
   return (0);
125
}
126
 
127
/* Compare the CRC stored in the PNG file with that calculated by libpng from
128
   the data it has read thus far. */
129
int /* PRIVATE */
130
png_crc_error(png_structp png_ptr)
131
{
132
   png_byte crc_bytes[4];
133
   png_uint_32 crc;
134
   int need_crc = 1;
135
 
136
   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
137
   {
138
      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
139
          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
140
         need_crc = 0;
141
   }
142
   else                                                    /* critical */
143
   {
144
      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
145
         need_crc = 0;
146
   }
147
 
148
   png_read_data(png_ptr, crc_bytes, 4);
149
 
150
   if (need_crc)
151
   {
152
      crc = png_get_uint_32(crc_bytes);
153
      return ((int)(crc != png_ptr->crc));
154
   }
155
   else
156
      return (0);
157
}
158
 
159
#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
160
    defined(PNG_READ_iCCP_SUPPORTED)
161
/*
162
 * Decompress trailing data in a chunk.  The assumption is that chunkdata
163
 * points at an allocated area holding the contents of a chunk with a
164
 * trailing compressed part.  What we get back is an allocated area
165
 * holding the original prefix part and an uncompressed version of the
166
 * trailing part (the malloc area passed in is freed).
167
 */
168
png_charp /* PRIVATE */
169
png_decompress_chunk(png_structp png_ptr, int comp_type,
170
                              png_charp chunkdata, png_size_t chunklength,
171
                              png_size_t prefix_size, png_size_t *newlength)
172
{
173
   static char msg[] = "Error decoding compressed text";
174
   png_charp text = NULL;
175
   png_size_t text_size;
176
 
177
   if (comp_type == PNG_COMPRESSION_TYPE_BASE)
178
   {
179
      int ret = Z_OK;
180
      png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
181
      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
182
      png_ptr->zstream.next_out = png_ptr->zbuf;
183
      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
184
 
185
      text_size = 0;
186
      text = NULL;
187
 
188
      while (png_ptr->zstream.avail_in)
189
      {
190
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
191
         if (ret != Z_OK && ret != Z_STREAM_END)
192
         {
193
            if (png_ptr->zstream.msg != NULL)
194
               png_warning(png_ptr, png_ptr->zstream.msg);
195
            else
196
               png_warning(png_ptr, msg);
197
            inflateReset(&png_ptr->zstream);
198
            png_ptr->zstream.avail_in = 0;
199
 
200
            if (text ==  NULL)
201
            {
202
               text_size = prefix_size + sizeof(msg) + 1;
203
               text = (png_charp)png_malloc_warn(png_ptr, text_size);
204
               if (text ==  NULL)
205
                 {
206
                    png_free(png_ptr,chunkdata);
207
                    png_error(png_ptr,"Not enough memory to decompress chunk");
208
                 }
209
               png_memcpy(text, chunkdata, prefix_size);
210
            }
211
 
212
            text[text_size - 1] = 0x00;
213
 
214
            /* Copy what we can of the error message into the text chunk */
215
            text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
216
            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
217
            png_memcpy(text + prefix_size, msg, text_size + 1);
218
            break;
219
         }
220
         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
221
         {
222
            if (text == NULL)
223
            {
224
               text_size = prefix_size +
225
                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;
226
               text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
227
               if (text ==  NULL)
228
                 {
229
                    png_free(png_ptr,chunkdata);
230
                    png_error(png_ptr,"Not enough memory to decompress chunk.");
231
                 }
232
               png_memcpy(text + prefix_size, png_ptr->zbuf,
233
                    text_size - prefix_size);
234
               png_memcpy(text, chunkdata, prefix_size);
235
               *(text + text_size) = 0x00;
236
            }
237
            else
238
            {
239
               png_charp tmp;
240
 
241
               tmp = text;
242
               text = (png_charp)png_malloc_warn(png_ptr,
243
                  (png_uint_32)(text_size +
244
                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
245
               if (text == NULL)
246
               {
247
                  png_free(png_ptr, tmp);
248
                  png_free(png_ptr, chunkdata);
249
                  png_error(png_ptr,"Not enough memory to decompress chunk..");
250
               }
251
               png_memcpy(text, tmp, text_size);
252
               png_free(png_ptr, tmp);
253
               png_memcpy(text + text_size, png_ptr->zbuf,
254
                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
255
               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
256
               *(text + text_size) = 0x00;
257
            }
258
            if (ret == Z_STREAM_END)
259
               break;
260
            else
261
            {
262
               png_ptr->zstream.next_out = png_ptr->zbuf;
263
               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
264
            }
265
         }
266
      }
267
      if (ret != Z_STREAM_END)
268
      {
269
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
270
         char umsg[50];
271
 
272
         if (ret == Z_BUF_ERROR)
273
            sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
274
                png_ptr->chunk_name);
275
         else if (ret == Z_DATA_ERROR)
276
            sprintf(umsg,"Data error in compressed datastream in %s chunk",
277
                png_ptr->chunk_name);
278
         else
279
            sprintf(umsg,"Incomplete compressed datastream in %s chunk",
280
                png_ptr->chunk_name);
281
         png_warning(png_ptr, umsg);
282
#else
283
         png_warning(png_ptr,
284
            "Incomplete compressed datastream in chunk other than IDAT");
285
#endif
286
         text_size=prefix_size;
287
         if (text ==  NULL)
288
         {
289
            text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
290
            if (text == NULL)
291
              {
292
                png_free(png_ptr, chunkdata);
293
                png_error(png_ptr,"Not enough memory for text.");
294
              }
295
            png_memcpy(text, chunkdata, prefix_size);
296
         }
297
         *(text + text_size) = 0x00;
298
      }
299
 
300
      inflateReset(&png_ptr->zstream);
301
      png_ptr->zstream.avail_in = 0;
302
 
303
      png_free(png_ptr, chunkdata);
304
      chunkdata = text;
305
      *newlength=text_size;
306
   }
307
   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
308
   {
309
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
310
      char umsg[50];
311
 
312
      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
313
      png_warning(png_ptr, umsg);
314
#else
315
      png_warning(png_ptr, "Unknown zTXt compression type");
316
#endif
317
 
318
      *(chunkdata + prefix_size) = 0x00;
319
      *newlength=prefix_size;
320
   }
321
 
322
   return chunkdata;
323
}
324
#endif
325
 
326
/* read and check the IDHR chunk */
327
void /* PRIVATE */
328
png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
329
{
330
   png_byte buf[13];
331
   png_uint_32 width, height;
332
   int bit_depth, color_type, compression_type, filter_type;
333
   int interlace_type;
334
 
335
   png_debug(1, "in png_handle_IHDR\n");
336
 
337
   if (png_ptr->mode & PNG_HAVE_IHDR)
338
      png_error(png_ptr, "Out of place IHDR");
339
 
340
   /* check the length */
341
   if (length != 13)
342
      png_error(png_ptr, "Invalid IHDR chunk");
343
 
344
   png_ptr->mode |= PNG_HAVE_IHDR;
345
 
346
   png_crc_read(png_ptr, buf, 13);
347
   png_crc_finish(png_ptr, 0);
348
 
349
   width = png_get_uint_32(buf);
350
   height = png_get_uint_32(buf + 4);
351
   bit_depth = buf[8];
352
   color_type = buf[9];
353
   compression_type = buf[10];
354
   filter_type = buf[11];
355
   interlace_type = buf[12];
356
 
357
 
358
   /* set internal variables */
359
   png_ptr->width = width;
360
   png_ptr->height = height;
361
   png_ptr->bit_depth = (png_byte)bit_depth;
362
   png_ptr->interlaced = (png_byte)interlace_type;
363
   png_ptr->color_type = (png_byte)color_type;
364
#if defined(PNG_MNG_FEATURES_SUPPORTED)
365
   png_ptr->filter_type = (png_byte)filter_type;
366
#endif
367
 
368
   /* find number of channels */
369
   switch (png_ptr->color_type)
370
   {
371
      case PNG_COLOR_TYPE_GRAY:
372
      case PNG_COLOR_TYPE_PALETTE:
373
         png_ptr->channels = 1;
374
         break;
375
      case PNG_COLOR_TYPE_RGB:
376
         png_ptr->channels = 3;
377
         break;
378
      case PNG_COLOR_TYPE_GRAY_ALPHA:
379
         png_ptr->channels = 2;
380
         break;
381
      case PNG_COLOR_TYPE_RGB_ALPHA:
382
         png_ptr->channels = 4;
383
         break;
384
   }
385
 
386
   /* set up other useful info */
387
   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
388
   png_ptr->channels);
389
   png_ptr->rowbytes = ((png_ptr->width *
390
      (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
391
   png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
392
   png_debug1(3,"channels = %d\n", png_ptr->channels);
393
   png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
394
   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
395
      color_type, interlace_type, compression_type, filter_type);
396
}
397
 
398
/* read and check the palette */
399
void /* PRIVATE */
400
png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
401
{
402
   png_color palette[PNG_MAX_PALETTE_LENGTH];
403
   int num, i;
404
#ifndef PNG_NO_POINTER_INDEXING
405
   png_colorp pal_ptr;
406
#endif
407
 
408
   png_debug(1, "in png_handle_PLTE\n");
409
 
410
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
411
      png_error(png_ptr, "Missing IHDR before PLTE");
412
   else if (png_ptr->mode & PNG_HAVE_IDAT)
413
   {
414
      png_warning(png_ptr, "Invalid PLTE after IDAT");
415
      png_crc_finish(png_ptr, length);
416
      return;
417
   }
418
   else if (png_ptr->mode & PNG_HAVE_PLTE)
419
      png_error(png_ptr, "Duplicate PLTE chunk");
420
 
421
   png_ptr->mode |= PNG_HAVE_PLTE;
422
 
423
   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
424
   {
425
      png_warning(png_ptr,
426
        "Ignoring PLTE chunk in grayscale PNG");
427
      png_crc_finish(png_ptr, length);
428
      return;
429
   }
430
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
431
   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
432
   {
433
      png_crc_finish(png_ptr, length);
434
      return;
435
   }
436
#endif
437
 
438
   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
439
   {
440
      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
441
      {
442
         png_warning(png_ptr, "Invalid palette chunk");
443
         png_crc_finish(png_ptr, length);
444
         return;
445
      }
446
      else
447
      {
448
         png_error(png_ptr, "Invalid palette chunk");
449
      }
450
   }
451
 
452
   num = (int)length / 3;
453
 
454
#ifndef PNG_NO_POINTER_INDEXING
455
   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
456
   {
457
      png_byte buf[3];
458
 
459
      png_crc_read(png_ptr, buf, 3);
460
      pal_ptr->red = buf[0];
461
      pal_ptr->green = buf[1];
462
      pal_ptr->blue = buf[2];
463
   }
464
#else
465
   for (i = 0; i < num; i++)
466
   {
467
      png_byte buf[3];
468
 
469
      png_crc_read(png_ptr, buf, 3);
470
      /* don't depend upon png_color being any order */
471
      palette[i].red = buf[0];
472
      palette[i].green = buf[1];
473
      palette[i].blue = buf[2];
474
   }
475
#endif
476
 
477
   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
478
      whatever the normal CRC configuration tells us.  However, if we
479
      have an RGB image, the PLTE can be considered ancillary, so
480
      we will act as though it is. */
481
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
482
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
483
#endif
484
   {
485
      png_crc_finish(png_ptr, 0);
486
   }
487
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
488
   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
489
   {
490
      /* If we don't want to use the data from an ancillary chunk,
491
         we have two options: an error abort, or a warning and we
492
         ignore the data in this chunk (which should be OK, since
493
         it's considered ancillary for a RGB or RGBA image). */
494
      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
495
      {
496
         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
497
         {
498
            png_chunk_error(png_ptr, "CRC error");
499
         }
500
         else
501
         {
502
            png_chunk_warning(png_ptr, "CRC error");
503
            return;
504
         }
505
      }
506
      /* Otherwise, we (optionally) emit a warning and use the chunk. */
507
      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
508
      {
509
         png_chunk_warning(png_ptr, "CRC error");
510
      }
511
   }
512
#endif
513
 
514
   png_set_PLTE(png_ptr, info_ptr, palette, num);
515
 
516
#if defined(PNG_READ_tRNS_SUPPORTED)
517
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
518
   {
519
      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
520
      {
521
         if (png_ptr->num_trans > (png_uint_16)num)
522
         {
523
            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
524
            png_ptr->num_trans = (png_uint_16)num;
525
         }
526
         if (info_ptr->num_trans > (png_uint_16)num)
527
         {
528
            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
529
            info_ptr->num_trans = (png_uint_16)num;
530
         }
531
      }
532
   }
533
#endif
534
 
535
}
536
 
537
void /* PRIVATE */
538
png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
539
{
540
   png_debug(1, "in png_handle_IEND\n");
541
 
542
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
543
   {
544
      png_error(png_ptr, "No image in file");
545
 
546
      info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
547
   }
548
 
549
   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
550
 
551
   if (length != 0)
552
   {
553
      png_warning(png_ptr, "Incorrect IEND chunk length");
554
   }
555
   png_crc_finish(png_ptr, length);
556
}
557
 
558
#if defined(PNG_READ_gAMA_SUPPORTED)
559
void /* PRIVATE */
560
png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
561
{
562
   png_fixed_point igamma;
563
#ifdef PNG_FLOATING_POINT_SUPPORTED
564
   float file_gamma;
565
#endif
566
   png_byte buf[4];
567
 
568
   png_debug(1, "in png_handle_gAMA\n");
569
 
570
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
571
      png_error(png_ptr, "Missing IHDR before gAMA");
572
   else if (png_ptr->mode & PNG_HAVE_IDAT)
573
   {
574
      png_warning(png_ptr, "Invalid gAMA after IDAT");
575
      png_crc_finish(png_ptr, length);
576
      return;
577
   }
578
   else if (png_ptr->mode & PNG_HAVE_PLTE)
579
      /* Should be an error, but we can cope with it */
580
      png_warning(png_ptr, "Out of place gAMA chunk");
581
 
582
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
583
#if defined(PNG_READ_sRGB_SUPPORTED)
584
      && !(info_ptr->valid & PNG_INFO_sRGB)
585
#endif
586
      )
587
   {
588
      png_warning(png_ptr, "Duplicate gAMA chunk");
589
      png_crc_finish(png_ptr, length);
590
      return;
591
   }
592
 
593
   if (length != 4)
594
   {
595
      png_warning(png_ptr, "Incorrect gAMA chunk length");
596
      png_crc_finish(png_ptr, length);
597
      return;
598
   }
599
 
600
   png_crc_read(png_ptr, buf, 4);
601
   if (png_crc_finish(png_ptr, 0))
602
      return;
603
 
604
   igamma = (png_fixed_point)png_get_uint_32(buf);
605
   /* check for zero gamma */
606
   if (igamma == 0)
607
      {
608
         png_warning(png_ptr,
609
           "Ignoring gAMA chunk with gamma=0");
610
         return;
611
      }
612
 
613
#if defined(PNG_READ_sRGB_SUPPORTED)
614
   if (info_ptr->valid & PNG_INFO_sRGB)
615
      if(igamma < 45000L || igamma > 46000L)
616
      {
617
         png_warning(png_ptr,
618
           "Ignoring incorrect gAMA value when sRGB is also present");
619
#ifndef PNG_NO_CONSOLE_IO
620
         cprintf("gamma = (%d/100000)\n", (int)igamma);
621
#endif
622
         return;
623
      }
624
#endif /* PNG_READ_sRGB_SUPPORTED */
625
 
626
#ifdef PNG_FLOATING_POINT_SUPPORTED
627
   file_gamma = (float)igamma / (float)100000.0;
628
#  ifdef PNG_READ_GAMMA_SUPPORTED
629
     png_ptr->gamma = file_gamma;
630
#  endif
631
     png_set_gAMA(png_ptr, info_ptr, file_gamma);
632
#endif
633
#ifdef PNG_FIXED_POINT_SUPPORTED
634
   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
635
#endif
636
}
637
#endif
638
 
639
#if defined(PNG_READ_sBIT_SUPPORTED)
640
void /* PRIVATE */
641
png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
642
{
643
   png_size_t truelen;
644
   png_byte buf[4];
645
 
646
   png_debug(1, "in png_handle_sBIT\n");
647
 
648
   buf[0] = buf[1] = buf[2] = buf[3] = 0;
649
 
650
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
651
      png_error(png_ptr, "Missing IHDR before sBIT");
652
   else if (png_ptr->mode & PNG_HAVE_IDAT)
653
   {
654
      png_warning(png_ptr, "Invalid sBIT after IDAT");
655
      png_crc_finish(png_ptr, length);
656
      return;
657
   }
658
   else if (png_ptr->mode & PNG_HAVE_PLTE)
659
   {
660
      /* Should be an error, but we can cope with it */
661
      png_warning(png_ptr, "Out of place sBIT chunk");
662
   }
663
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
664
   {
665
      png_warning(png_ptr, "Duplicate sBIT chunk");
666
      png_crc_finish(png_ptr, length);
667
      return;
668
   }
669
 
670
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
671
      truelen = 3;
672
   else
673
      truelen = (png_size_t)png_ptr->channels;
674
 
675
   if (length != truelen)
676
   {
677
      png_warning(png_ptr, "Incorrect sBIT chunk length");
678
      png_crc_finish(png_ptr, length);
679
      return;
680
   }
681
 
682
   png_crc_read(png_ptr, buf, truelen);
683
   if (png_crc_finish(png_ptr, 0))
684
      return;
685
 
686
   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
687
   {
688
      png_ptr->sig_bit.red = buf[0];
689
      png_ptr->sig_bit.green = buf[1];
690
      png_ptr->sig_bit.blue = buf[2];
691
      png_ptr->sig_bit.alpha = buf[3];
692
   }
693
   else
694
   {
695
      png_ptr->sig_bit.gray = buf[0];
696
      png_ptr->sig_bit.red = buf[0];
697
      png_ptr->sig_bit.green = buf[0];
698
      png_ptr->sig_bit.blue = buf[0];
699
      png_ptr->sig_bit.alpha = buf[1];
700
   }
701
   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
702
}
703
#endif
704
 
705
#if defined(PNG_READ_cHRM_SUPPORTED)
706
void /* PRIVATE */
707
png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
708
{
709
   png_byte buf[4];
710
#ifdef PNG_FLOATING_POINT_SUPPORTED
711
   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
712
#endif
713
   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
714
      int_y_green, int_x_blue, int_y_blue;
715
 
716
   png_uint_32 uint_x, uint_y;
717
 
718
   png_debug(1, "in png_handle_cHRM\n");
719
 
720
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
721
      png_error(png_ptr, "Missing IHDR before cHRM");
722
   else if (png_ptr->mode & PNG_HAVE_IDAT)
723
   {
724
      png_warning(png_ptr, "Invalid cHRM after IDAT");
725
      png_crc_finish(png_ptr, length);
726
      return;
727
   }
728
   else if (png_ptr->mode & PNG_HAVE_PLTE)
729
      /* Should be an error, but we can cope with it */
730
      png_warning(png_ptr, "Missing PLTE before cHRM");
731
 
732
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
733
#if defined(PNG_READ_sRGB_SUPPORTED)
734
      && !(info_ptr->valid & PNG_INFO_sRGB)
735
#endif
736
      )
737
   {
738
      png_warning(png_ptr, "Duplicate cHRM chunk");
739
      png_crc_finish(png_ptr, length);
740
      return;
741
   }
742
 
743
   if (length != 32)
744
   {
745
      png_warning(png_ptr, "Incorrect cHRM chunk length");
746
      png_crc_finish(png_ptr, length);
747
      return;
748
   }
749
 
750
   png_crc_read(png_ptr, buf, 4);
751
   uint_x = png_get_uint_32(buf);
752
 
753
   png_crc_read(png_ptr, buf, 4);
754
   uint_y = png_get_uint_32(buf);
755
 
756
   if (uint_x > 80000L || uint_y > 80000L ||
757
      uint_x + uint_y > 100000L)
758
   {
759
      png_warning(png_ptr, "Invalid cHRM white point");
760
      png_crc_finish(png_ptr, 24);
761
      return;
762
   }
763
   int_x_white = (png_fixed_point)uint_x;
764
   int_y_white = (png_fixed_point)uint_y;
765
 
766
   png_crc_read(png_ptr, buf, 4);
767
   uint_x = png_get_uint_32(buf);
768
 
769
   png_crc_read(png_ptr, buf, 4);
770
   uint_y = png_get_uint_32(buf);
771
 
772
   if (uint_x > 80000L || uint_y > 80000L ||
773
      uint_x + uint_y > 100000L)
774
   {
775
      png_warning(png_ptr, "Invalid cHRM red point");
776
      png_crc_finish(png_ptr, 16);
777
      return;
778
   }
779
   int_x_red = (png_fixed_point)uint_x;
780
   int_y_red = (png_fixed_point)uint_y;
781
 
782
   png_crc_read(png_ptr, buf, 4);
783
   uint_x = png_get_uint_32(buf);
784
 
785
   png_crc_read(png_ptr, buf, 4);
786
   uint_y = png_get_uint_32(buf);
787
 
788
   if (uint_x > 80000L || uint_y > 80000L ||
789
      uint_x + uint_y > 100000L)
790
   {
791
      png_warning(png_ptr, "Invalid cHRM green point");
792
      png_crc_finish(png_ptr, 8);
793
      return;
794
   }
795
   int_x_green = (png_fixed_point)uint_x;
796
   int_y_green = (png_fixed_point)uint_y;
797
 
798
   png_crc_read(png_ptr, buf, 4);
799
   uint_x = png_get_uint_32(buf);
800
 
801
   png_crc_read(png_ptr, buf, 4);
802
   uint_y = png_get_uint_32(buf);
803
 
804
   if (uint_x > 80000L || uint_y > 80000L ||
805
      uint_x + uint_y > 100000L)
806
   {
807
      png_warning(png_ptr, "Invalid cHRM blue point");
808
      png_crc_finish(png_ptr, 0);
809
      return;
810
   }
811
   int_x_blue = (png_fixed_point)uint_x;
812
   int_y_blue = (png_fixed_point)uint_y;
813
 
814
#ifdef PNG_FLOATING_POINT_SUPPORTED
815
   white_x = (float)int_x_white / (float)100000.0;
816
   white_y = (float)int_y_white / (float)100000.0;
817
   red_x   = (float)int_x_red   / (float)100000.0;
818
   red_y   = (float)int_y_red   / (float)100000.0;
819
   green_x = (float)int_x_green / (float)100000.0;
820
   green_y = (float)int_y_green / (float)100000.0;
821
   blue_x  = (float)int_x_blue  / (float)100000.0;
822
   blue_y  = (float)int_y_blue  / (float)100000.0;
823
#endif
824
 
825
#if defined(PNG_READ_sRGB_SUPPORTED)
826
   if (info_ptr->valid & PNG_INFO_sRGB)
827
      {
828
      if (abs(int_x_white - 31270L) > 1000 ||
829
          abs(int_y_white - 32900L) > 1000 ||
830
          abs(int_x_red   - 64000L) > 1000 ||
831
          abs(int_y_red   - 33000L) > 1000 ||
832
          abs(int_x_green - 30000L) > 1000 ||
833
          abs(int_y_green - 60000L) > 1000 ||
834
          abs(int_x_blue  - 15000L) > 1000 ||
835
          abs(int_y_blue  -  6000L) > 1000)
836
         {
837
 
838
            png_warning(png_ptr,
839
              "Ignoring incorrect cHRM value when sRGB is also present");
840
#ifndef PNG_NO_CONSOLE_IO
841
#ifdef PNG_FLOATING_POINT_SUPPORTED
842
            cprintf("wx=%f, wy=%f, rx=%f, ry=%f\n",
843
               white_x, white_y, red_x, red_y);
844
            cprintf("gx=%f, gy=%f, bx=%f, by=%f\n",
845
               green_x, green_y, blue_x, blue_y);
846
#else
847
            cprintf("wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
848
               int_x_white, int_y_white, int_x_red, int_y_red);
849
            cprintf("gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
850
               int_x_green, int_y_green, int_x_blue, int_y_blue);
851
#endif
852
#endif /* PNG_NO_CONSOLE_IO */
853
         }
854
         png_crc_finish(png_ptr, 0);
855
         return;
856
      }
857
#endif /* PNG_READ_sRGB_SUPPORTED */
858
 
859
#ifdef PNG_FLOATING_POINT_SUPPORTED
860
   png_set_cHRM(png_ptr, info_ptr,
861
      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
862
#endif
863
#ifdef PNG_FIXED_POINT_SUPPORTED
864
   png_set_cHRM_fixed(png_ptr, info_ptr,
865
      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
866
      int_y_green, int_x_blue, int_y_blue);
867
#endif
868
   if (png_crc_finish(png_ptr, 0))
869
      return;
870
}
871
#endif
872
 
873
#if defined(PNG_READ_sRGB_SUPPORTED)
874
void /* PRIVATE */
875
png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
876
{
877
   int intent;
878
   png_byte buf[1];
879
 
880
   png_debug(1, "in png_handle_sRGB\n");
881
 
882
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
883
      png_error(png_ptr, "Missing IHDR before sRGB");
884
   else if (png_ptr->mode & PNG_HAVE_IDAT)
885
   {
886
      png_warning(png_ptr, "Invalid sRGB after IDAT");
887
      png_crc_finish(png_ptr, length);
888
      return;
889
   }
890
   else if (png_ptr->mode & PNG_HAVE_PLTE)
891
      /* Should be an error, but we can cope with it */
892
      png_warning(png_ptr, "Out of place sRGB chunk");
893
 
894
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
895
   {
896
      png_warning(png_ptr, "Duplicate sRGB chunk");
897
      png_crc_finish(png_ptr, length);
898
      return;
899
   }
900
 
901
   if (length != 1)
902
   {
903
      png_warning(png_ptr, "Incorrect sRGB chunk length");
904
      png_crc_finish(png_ptr, length);
905
      return;
906
   }
907
 
908
   png_crc_read(png_ptr, buf, 1);
909
   if (png_crc_finish(png_ptr, 0))
910
      return;
911
 
912
   intent = buf[0];
913
   /* check for bad intent */
914
   if (intent >= PNG_sRGB_INTENT_LAST)
915
   {
916
      png_warning(png_ptr, "Unknown sRGB intent");
917
      return;
918
   }
919
 
920
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
921
   if ((info_ptr->valid & PNG_INFO_gAMA))
922
   {
923
   int igamma;
924
#ifdef PNG_FIXED_POINT_SUPPORTED
925
      igamma=(int)info_ptr->int_gamma;
926
#else
927
#  ifdef PNG_FLOATING_POINT_SUPPORTED
928
      igamma=(int)(info_ptr->gamma * 100000.);
929
#  endif
930
#endif
931
      if(igamma < 45000L || igamma > 46000L)
932
      {
933
         png_warning(png_ptr,
934
           "Ignoring incorrect gAMA value when sRGB is also present");
935
#ifndef PNG_NO_CONSOLE_IO
936
#  ifdef PNG_FIXED_POINT_SUPPORTED
937
         cprintf("incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
938
#  else
939
#    ifdef PNG_FLOATING_POINT_SUPPORTED
940
         cprintf("incorrect gamma=%f\n",png_ptr->gamma);
941
#    endif
942
#  endif
943
#endif
944
      }
945
   }
946
#endif /* PNG_READ_gAMA_SUPPORTED */
947
 
948
#ifdef PNG_READ_cHRM_SUPPORTED
949
#ifdef PNG_FIXED_POINT_SUPPORTED
950
   if (info_ptr->valid & PNG_INFO_cHRM)
951
      if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
952
          abs(info_ptr->int_y_white - 32900L) > 1000 ||
953
          abs(info_ptr->int_x_red   - 64000L) > 1000 ||
954
          abs(info_ptr->int_y_red   - 33000L) > 1000 ||
955
          abs(info_ptr->int_x_green - 30000L) > 1000 ||
956
          abs(info_ptr->int_y_green - 60000L) > 1000 ||
957
          abs(info_ptr->int_x_blue  - 15000L) > 1000 ||
958
          abs(info_ptr->int_y_blue  -  6000L) > 1000)
959
         {
960
            png_warning(png_ptr,
961
              "Ignoring incorrect cHRM value when sRGB is also present");
962
         }
963
#endif /* PNG_FIXED_POINT_SUPPORTED */
964
#endif /* PNG_READ_cHRM_SUPPORTED */
965
 
966
   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
967
}
968
#endif /* PNG_READ_sRGB_SUPPORTED */
969
 
970
#if defined(PNG_READ_iCCP_SUPPORTED)
971
void /* PRIVATE */
972
png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
973
/* Note: this does not properly handle chunks that are > 64K under DOS */
974
{
975
   png_charp chunkdata;
976
   png_byte compression_type;
977
   png_bytep pC;
978
   png_charp profile;
979
   png_uint_32 skip = 0;
980
   png_uint_32 profile_size = 0;
981
   png_uint_32 profile_length = 0;
982
   png_size_t slength, prefix_length, data_length;
983
 
984
   png_debug(1, "in png_handle_iCCP\n");
985
 
986
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
987
      png_error(png_ptr, "Missing IHDR before iCCP");
988
   else if (png_ptr->mode & PNG_HAVE_IDAT)
989
   {
990
      png_warning(png_ptr, "Invalid iCCP after IDAT");
991
      png_crc_finish(png_ptr, length);
992
      return;
993
   }
994
   else if (png_ptr->mode & PNG_HAVE_PLTE)
995
      /* Should be an error, but we can cope with it */
996
      png_warning(png_ptr, "Out of place iCCP chunk");
997
 
998
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
999
   {
1000
      png_warning(png_ptr, "Duplicate iCCP chunk");
1001
      png_crc_finish(png_ptr, length);
1002
      return;
1003
   }
1004
 
1005
#ifdef PNG_MAX_MALLOC_64K
1006
   if (length > (png_uint_32)65535L)
1007
   {
1008
      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1009
      skip = length - (png_uint_32)65535L;
1010
      length = (png_uint_32)65535L;
1011
   }
1012
#endif
1013
 
1014
   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1015
   slength = (png_size_t)length;
1016
   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1017
 
1018
   if (png_crc_finish(png_ptr, skip))
1019
   {
1020
      png_free(png_ptr, chunkdata);
1021
      return;
1022
   }
1023
 
1024
   chunkdata[slength] = 0x00;
1025
 
1026
   for (profile = chunkdata; *profile; profile++)
1027
      /* empty loop to find end of name */ ;
1028
 
1029
   ++profile;
1030
 
1031
   /* there should be at least one zero (the compression type byte)
1032
      following the separator, and we should be on it  */
1033
   if ( profile >= chunkdata + slength)
1034
   {
1035
      png_free(png_ptr, chunkdata);
1036
      png_warning(png_ptr, "Malformed iCCP chunk");
1037
      return;
1038
   }
1039
 
1040
   /* compression_type should always be zero */
1041
   compression_type = *profile++;
1042
   if (compression_type)
1043
   {
1044
      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1045
      compression_type=0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1046
                                 wrote nonzero) */
1047
   }
1048
 
1049
   prefix_length = profile - chunkdata;
1050
   chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
1051
                                    slength, prefix_length, &data_length);
1052
 
1053
   profile_length = data_length - prefix_length;
1054
 
1055
   if ( prefix_length > data_length || profile_length < 4)
1056
   {
1057
      png_free(png_ptr, chunkdata);
1058
      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1059
      return;
1060
   }
1061
 
1062
   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1063
   pC = (png_bytep)(chunkdata+prefix_length);
1064
   profile_size = ((*(pC  ))<<24) |
1065
                  ((*(pC+1))<<16) |
1066
                  ((*(pC+2))<< 8) |
1067
                  ((*(pC+3))    );
1068
 
1069
   if(profile_size < profile_length)
1070
      profile_length = profile_size;
1071
 
1072
   if(profile_size > profile_length)
1073
   {
1074
      png_free(png_ptr, chunkdata);
1075
      png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
1076
      return;
1077
   }
1078
 
1079
   png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
1080
                chunkdata + prefix_length, profile_length);
1081
   png_free(png_ptr, chunkdata);
1082
}
1083
#endif /* PNG_READ_iCCP_SUPPORTED */
1084
 
1085
#if defined(PNG_READ_sPLT_SUPPORTED)
1086
void /* PRIVATE */
1087
png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1088
/* Note: this does not properly handle chunks that are > 64K under DOS */
1089
{
1090
   png_bytep chunkdata;
1091
   png_bytep entry_start;
1092
   png_sPLT_t new_palette;
1093
#ifdef PNG_NO_POINTER_INDEXING
1094
   png_sPLT_entryp pp;
1095
#endif
1096
   int data_length, entry_size, i;
1097
   png_uint_32 skip = 0;
1098
   png_size_t slength;
1099
 
1100
   png_debug(1, "in png_handle_sPLT\n");
1101
 
1102
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1103
      png_error(png_ptr, "Missing IHDR before sPLT");
1104
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1105
   {
1106
      png_warning(png_ptr, "Invalid sPLT after IDAT");
1107
      png_crc_finish(png_ptr, length);
1108
      return;
1109
   }
1110
 
1111
#ifdef PNG_MAX_MALLOC_64K
1112
   if (length > (png_uint_32)65535L)
1113
   {
1114
      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1115
      skip = length - (png_uint_32)65535L;
1116
      length = (png_uint_32)65535L;
1117
   }
1118
#endif
1119
 
1120
   chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
1121
   slength = (png_size_t)length;
1122
   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1123
 
1124
   if (png_crc_finish(png_ptr, skip))
1125
   {
1126
      png_free(png_ptr, chunkdata);
1127
      return;
1128
   }
1129
 
1130
   chunkdata[slength] = 0x00;
1131
 
1132
   for (entry_start = chunkdata; *entry_start; entry_start++)
1133
      /* empty loop to find end of name */ ;
1134
   ++entry_start;
1135
 
1136
   /* a sample depth should follow the separator, and we should be on it  */
1137
   if (entry_start > chunkdata + slength)
1138
   {
1139
      png_free(png_ptr, chunkdata);
1140
      png_warning(png_ptr, "malformed sPLT chunk");
1141
      return;
1142
   }
1143
 
1144
   new_palette.depth = *entry_start++;
1145
   entry_size = (new_palette.depth == 8 ? 6 : 10);
1146
   data_length = (slength - (entry_start - chunkdata));
1147
 
1148
   /* integrity-check the data length */
1149
   if (data_length % entry_size)
1150
   {
1151
      png_free(png_ptr, chunkdata);
1152
      png_warning(png_ptr, "sPLT chunk has bad length");
1153
      return;
1154
   }
1155
 
1156
   new_palette.nentries = data_length / entry_size;
1157
   new_palette.entries = (png_sPLT_entryp)png_malloc(
1158
       png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
1159
 
1160
#ifndef PNG_NO_POINTER_INDEXING
1161
   for (i = 0; i < new_palette.nentries; i++)
1162
   {
1163
      png_sPLT_entryp pp = new_palette.entries + i;
1164
 
1165
      if (new_palette.depth == 8)
1166
      {
1167
          pp->red = *entry_start++;
1168
          pp->green = *entry_start++;
1169
          pp->blue = *entry_start++;
1170
          pp->alpha = *entry_start++;
1171
      }
1172
      else
1173
      {
1174
          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1175
          pp->green = png_get_uint_16(entry_start); entry_start += 2;
1176
          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1177
          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1178
      }
1179
      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1180
   }
1181
#else
1182
   pp = new_palette.entries;
1183
   for (i = 0; i < new_palette.nentries; i++)
1184
   {
1185
 
1186
      if (new_palette.depth == 8)
1187
      {
1188
          pp[i].red   = *entry_start++;
1189
          pp[i].green = *entry_start++;
1190
          pp[i].blue  = *entry_start++;
1191
          pp[i].alpha = *entry_start++;
1192
      }
1193
      else
1194
      {
1195
          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1196
          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1197
          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1198
          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1199
      }
1200
      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1201
   }
1202
#endif
1203
 
1204
   /* discard all chunk data except the name and stash that */
1205
   new_palette.name = (png_charp)chunkdata;
1206
 
1207
   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1208
 
1209
   png_free(png_ptr, chunkdata);
1210
   png_free(png_ptr, new_palette.entries);
1211
}
1212
#endif /* PNG_READ_sPLT_SUPPORTED */
1213
 
1214
#if defined(PNG_READ_tRNS_SUPPORTED)
1215
void /* PRIVATE */
1216
png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1217
{
1218
   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1219
 
1220
   png_debug(1, "in png_handle_tRNS\n");
1221
 
1222
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1223
      png_error(png_ptr, "Missing IHDR before tRNS");
1224
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1225
   {
1226
      png_warning(png_ptr, "Invalid tRNS after IDAT");
1227
      png_crc_finish(png_ptr, length);
1228
      return;
1229
   }
1230
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1231
   {
1232
      png_warning(png_ptr, "Duplicate tRNS chunk");
1233
      png_crc_finish(png_ptr, length);
1234
      return;
1235
   }
1236
 
1237
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1238
   {
1239
      if (!(png_ptr->mode & PNG_HAVE_PLTE))
1240
      {
1241
         /* Should be an error, but we can cope with it */
1242
         png_warning(png_ptr, "Missing PLTE before tRNS");
1243
      }
1244
      else if (length > (png_uint_32)png_ptr->num_palette)
1245
      {
1246
         png_warning(png_ptr, "Incorrect tRNS chunk length");
1247
         png_crc_finish(png_ptr, length);
1248
         return;
1249
      }
1250
      if (length == 0)
1251
      {
1252
         png_warning(png_ptr, "Zero length tRNS chunk");
1253
         png_crc_finish(png_ptr, length);
1254
         return;
1255
      }
1256
 
1257
      png_crc_read(png_ptr, readbuf, (png_size_t)length);
1258
      png_ptr->num_trans = (png_uint_16)length;
1259
   }
1260
   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1261
   {
1262
      png_byte buf[6];
1263
 
1264
      if (length != 6)
1265
      {
1266
         png_warning(png_ptr, "Incorrect tRNS chunk length");
1267
         png_crc_finish(png_ptr, length);
1268
         return;
1269
      }
1270
 
1271
      png_crc_read(png_ptr, buf, (png_size_t)length);
1272
      png_ptr->num_trans = 1;
1273
      png_ptr->trans_values.red = png_get_uint_16(buf);
1274
      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1275
      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1276
   }
1277
   else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1278
   {
1279
      png_byte buf[6];
1280
 
1281
      if (length != 2)
1282
      {
1283
         png_warning(png_ptr, "Incorrect tRNS chunk length");
1284
         png_crc_finish(png_ptr, length);
1285
         return;
1286
      }
1287
 
1288
      png_crc_read(png_ptr, buf, 2);
1289
      png_ptr->num_trans = 1;
1290
      png_ptr->trans_values.gray = png_get_uint_16(buf);
1291
   }
1292
   else
1293
   {
1294
      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1295
      png_crc_finish(png_ptr, length);
1296
      return;
1297
   }
1298
 
1299
   if (png_crc_finish(png_ptr, 0))
1300
      return;
1301
 
1302
   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1303
      &(png_ptr->trans_values));
1304
}
1305
#endif
1306
 
1307
#if defined(PNG_READ_bKGD_SUPPORTED)
1308
void /* PRIVATE */
1309
png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1310
{
1311
   png_size_t truelen;
1312
   png_byte buf[6];
1313
 
1314
   png_debug(1, "in png_handle_bKGD\n");
1315
 
1316
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1317
      png_error(png_ptr, "Missing IHDR before bKGD");
1318
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1319
   {
1320
      png_warning(png_ptr, "Invalid bKGD after IDAT");
1321
      png_crc_finish(png_ptr, length);
1322
      return;
1323
   }
1324
   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1325
            !(png_ptr->mode & PNG_HAVE_PLTE))
1326
   {
1327
      png_warning(png_ptr, "Missing PLTE before bKGD");
1328
      png_crc_finish(png_ptr, length);
1329
      return;
1330
   }
1331
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1332
   {
1333
      png_warning(png_ptr, "Duplicate bKGD chunk");
1334
      png_crc_finish(png_ptr, length);
1335
      return;
1336
   }
1337
 
1338
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1339
      truelen = 1;
1340
   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1341
      truelen = 6;
1342
   else
1343
      truelen = 2;
1344
 
1345
   if (length != truelen)
1346
   {
1347
      png_warning(png_ptr, "Incorrect bKGD chunk length");
1348
      png_crc_finish(png_ptr, length);
1349
      return;
1350
   }
1351
 
1352
   png_crc_read(png_ptr, buf, truelen);
1353
   if (png_crc_finish(png_ptr, 0))
1354
      return;
1355
 
1356
   /* We convert the index value into RGB components so that we can allow
1357
    * arbitrary RGB values for background when we have transparency, and
1358
    * so it is easy to determine the RGB values of the background color
1359
    * from the info_ptr struct. */
1360
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1361
   {
1362
      png_ptr->background.index = buf[0];
1363
      if(info_ptr->num_palette)
1364
      {
1365
          if(buf[0] > info_ptr->num_palette)
1366
          {
1367
             png_warning(png_ptr, "Incorrect bKGD chunk index value");
1368
             return;
1369
          }
1370
          png_ptr->background.red =
1371
             (png_uint_16)png_ptr->palette[buf[0]].red;
1372
          png_ptr->background.green =
1373
             (png_uint_16)png_ptr->palette[buf[0]].green;
1374
          png_ptr->background.blue =
1375
             (png_uint_16)png_ptr->palette[buf[0]].blue;
1376
      }
1377
   }
1378
   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1379
   {
1380
      png_ptr->background.red =
1381
      png_ptr->background.green =
1382
      png_ptr->background.blue =
1383
      png_ptr->background.gray = png_get_uint_16(buf);
1384
   }
1385
   else
1386
   {
1387
      png_ptr->background.red = png_get_uint_16(buf);
1388
      png_ptr->background.green = png_get_uint_16(buf + 2);
1389
      png_ptr->background.blue = png_get_uint_16(buf + 4);
1390
   }
1391
 
1392
   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1393
}
1394
#endif
1395
 
1396
#if defined(PNG_READ_hIST_SUPPORTED)
1397
void /* PRIVATE */
1398
png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1399
{
1400
   int num, i;
1401
   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1402
 
1403
   png_debug(1, "in png_handle_hIST\n");
1404
 
1405
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1406
      png_error(png_ptr, "Missing IHDR before hIST");
1407
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1408
   {
1409
      png_warning(png_ptr, "Invalid hIST after IDAT");
1410
      png_crc_finish(png_ptr, length);
1411
      return;
1412
   }
1413
   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1414
   {
1415
      png_warning(png_ptr, "Missing PLTE before hIST");
1416
      png_crc_finish(png_ptr, length);
1417
      return;
1418
   }
1419
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1420
   {
1421
      png_warning(png_ptr, "Duplicate hIST chunk");
1422
      png_crc_finish(png_ptr, length);
1423
      return;
1424
   }
1425
 
1426
   num = (int)length / 2 ;
1427
   if (num != png_ptr->num_palette)
1428
   {
1429
      png_warning(png_ptr, "Incorrect hIST chunk length");
1430
      png_crc_finish(png_ptr, length);
1431
      return;
1432
   }
1433
 
1434
   for (i = 0; i < num; i++)
1435
   {
1436
      png_byte buf[2];
1437
 
1438
      png_crc_read(png_ptr, buf, 2);
1439
      readbuf[i] = png_get_uint_16(buf);
1440
   }
1441
 
1442
   if (png_crc_finish(png_ptr, 0))
1443
      return;
1444
 
1445
   png_set_hIST(png_ptr, info_ptr, readbuf);
1446
}
1447
#endif
1448
 
1449
#if defined(PNG_READ_pHYs_SUPPORTED)
1450
void /* PRIVATE */
1451
png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1452
{
1453
   png_byte buf[9];
1454
   png_uint_32 res_x, res_y;
1455
   int unit_type;
1456
 
1457
   png_debug(1, "in png_handle_pHYs\n");
1458
 
1459
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1460
      png_error(png_ptr, "Missing IHDR before pHYs");
1461
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1462
   {
1463
      png_warning(png_ptr, "Invalid pHYs after IDAT");
1464
      png_crc_finish(png_ptr, length);
1465
      return;
1466
   }
1467
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1468
   {
1469
      png_warning(png_ptr, "Duplicate pHYs chunk");
1470
      png_crc_finish(png_ptr, length);
1471
      return;
1472
   }
1473
 
1474
   if (length != 9)
1475
   {
1476
      png_warning(png_ptr, "Incorrect pHYs chunk length");
1477
      png_crc_finish(png_ptr, length);
1478
      return;
1479
   }
1480
 
1481
   png_crc_read(png_ptr, buf, 9);
1482
   if (png_crc_finish(png_ptr, 0))
1483
      return;
1484
 
1485
   res_x = png_get_uint_32(buf);
1486
   res_y = png_get_uint_32(buf + 4);
1487
   unit_type = buf[8];
1488
   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1489
}
1490
#endif
1491
 
1492
#if defined(PNG_READ_oFFs_SUPPORTED)
1493
void /* PRIVATE */
1494
png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1495
{
1496
   png_byte buf[9];
1497
   png_int_32 offset_x, offset_y;
1498
   int unit_type;
1499
 
1500
   png_debug(1, "in png_handle_oFFs\n");
1501
 
1502
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1503
      png_error(png_ptr, "Missing IHDR before oFFs");
1504
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1505
   {
1506
      png_warning(png_ptr, "Invalid oFFs after IDAT");
1507
      png_crc_finish(png_ptr, length);
1508
      return;
1509
   }
1510
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1511
   {
1512
      png_warning(png_ptr, "Duplicate oFFs chunk");
1513
      png_crc_finish(png_ptr, length);
1514
      return;
1515
   }
1516
 
1517
   if (length != 9)
1518
   {
1519
      png_warning(png_ptr, "Incorrect oFFs chunk length");
1520
      png_crc_finish(png_ptr, length);
1521
      return;
1522
   }
1523
 
1524
   png_crc_read(png_ptr, buf, 9);
1525
   if (png_crc_finish(png_ptr, 0))
1526
      return;
1527
 
1528
   offset_x = png_get_int_32(buf);
1529
   offset_y = png_get_int_32(buf + 4);
1530
   unit_type = buf[8];
1531
   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1532
}
1533
#endif
1534
 
1535
#if defined(PNG_READ_pCAL_SUPPORTED)
1536
/* read the pCAL chunk (described in the PNG Extensions document) */
1537
void /* PRIVATE */
1538
png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1539
{
1540
   png_charp purpose;
1541
   png_int_32 X0, X1;
1542
   png_byte type, nparams;
1543
   png_charp buf, units, endptr;
1544
   png_charpp params;
1545
   png_size_t slength;
1546
   int i;
1547
 
1548
   png_debug(1, "in png_handle_pCAL\n");
1549
 
1550
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1551
      png_error(png_ptr, "Missing IHDR before pCAL");
1552
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1553
   {
1554
      png_warning(png_ptr, "Invalid pCAL after IDAT");
1555
      png_crc_finish(png_ptr, length);
1556
      return;
1557
   }
1558
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1559
   {
1560
      png_warning(png_ptr, "Duplicate pCAL chunk");
1561
      png_crc_finish(png_ptr, length);
1562
      return;
1563
   }
1564
 
1565
   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1566
      length + 1);
1567
   purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
1568
   if (purpose == NULL)
1569
     {
1570
       png_warning(png_ptr, "No memory for pCAL purpose.");
1571
       return;
1572
     }
1573
   slength = (png_size_t)length;
1574
   png_crc_read(png_ptr, (png_bytep)purpose, slength);
1575
 
1576
   if (png_crc_finish(png_ptr, 0))
1577
   {
1578
      png_free(png_ptr, purpose);
1579
      return;
1580
   }
1581
 
1582
   purpose[slength] = 0x00; /* null terminate the last string */
1583
 
1584
   png_debug(3, "Finding end of pCAL purpose string\n");
1585
   for (buf = purpose; *buf; buf++)
1586
      /* empty loop */ ;
1587
 
1588
   endptr = purpose + slength;
1589
 
1590
   /* We need to have at least 12 bytes after the purpose string
1591
      in order to get the parameter information. */
1592
   if (endptr <= buf + 12)
1593
   {
1594
      png_warning(png_ptr, "Invalid pCAL data");
1595
      png_free(png_ptr, purpose);
1596
      return;
1597
   }
1598
 
1599
   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1600
   X0 = png_get_int_32((png_bytep)buf+1);
1601
   X1 = png_get_int_32((png_bytep)buf+5);
1602
   type = buf[9];
1603
   nparams = buf[10];
1604
   units = buf + 11;
1605
 
1606
   png_debug(3, "Checking pCAL equation type and number of parameters\n");
1607
   /* Check that we have the right number of parameters for known
1608
      equation types. */
1609
   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1610
       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1611
       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1612
       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1613
   {
1614
      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1615
      png_free(png_ptr, purpose);
1616
      return;
1617
   }
1618
   else if (type >= PNG_EQUATION_LAST)
1619
   {
1620
      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1621
   }
1622
 
1623
   for (buf = units; *buf; buf++)
1624
      /* Empty loop to move past the units string. */ ;
1625
 
1626
   png_debug(3, "Allocating pCAL parameters array\n");
1627
   params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
1628
      *sizeof(png_charp))) ;
1629
   if (params == NULL)
1630
     {
1631
       png_free(png_ptr, purpose);
1632
       png_warning(png_ptr, "No memory for pCAL params.");
1633
       return;
1634
     }
1635
 
1636
   /* Get pointers to the start of each parameter string. */
1637
   for (i = 0; i < (int)nparams; i++)
1638
   {
1639
      buf++; /* Skip the null string terminator from previous parameter. */
1640
 
1641
      png_debug1(3, "Reading pCAL parameter %d\n", i);
1642
      for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
1643
         /* Empty loop to move past each parameter string */ ;
1644
 
1645
      /* Make sure we haven't run out of data yet */
1646
      if (buf > endptr)
1647
      {
1648
         png_warning(png_ptr, "Invalid pCAL data");
1649
         png_free(png_ptr, purpose);
1650
         png_free(png_ptr, params);
1651
         return;
1652
      }
1653
   }
1654
 
1655
   png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1656
      units, params);
1657
 
1658
   png_free(png_ptr, purpose);
1659
   png_free(png_ptr, params);
1660
}
1661
#endif
1662
 
1663
#if defined(PNG_READ_sCAL_SUPPORTED)
1664
/* read the sCAL chunk */
1665
void /* PRIVATE */
1666
png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1667
{
1668
   png_charp buffer, ep;
1669
#ifdef PNG_FLOATING_POINT_SUPPORTED
1670
   double width, height;
1671
   png_charp vp;
1672
#else
1673
#ifdef PNG_FIXED_POINT_SUPPORTED
1674
   png_charp swidth, sheight;
1675
#endif
1676
#endif
1677
   png_size_t slength;
1678
 
1679
   png_debug(1, "in png_handle_sCAL\n");
1680
 
1681
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1682
      png_error(png_ptr, "Missing IHDR before sCAL");
1683
   else if (png_ptr->mode & PNG_HAVE_IDAT)
1684
   {
1685
      png_warning(png_ptr, "Invalid sCAL after IDAT");
1686
      png_crc_finish(png_ptr, length);
1687
      return;
1688
   }
1689
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1690
   {
1691
      png_warning(png_ptr, "Duplicate sCAL chunk");
1692
      png_crc_finish(png_ptr, length);
1693
      return;
1694
   }
1695
 
1696
   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1697
      length + 1);
1698
   buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
1699
   if (buffer == NULL)
1700
     {
1701
       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1702
       return;
1703
     }
1704
   slength = (png_size_t)length;
1705
   png_crc_read(png_ptr, (png_bytep)buffer, slength);
1706
 
1707
   if (png_crc_finish(png_ptr, 0))
1708
   {
1709
      png_free(png_ptr, buffer);
1710
      return;
1711
   }
1712
 
1713
   buffer[slength] = 0x00; /* null terminate the last string */
1714
 
1715
   ep = buffer + 1;        /* skip unit byte */
1716
 
1717
#ifdef PNG_FLOATING_POINT_SUPPORTED
1718
   width = strtod(ep, &vp);
1719
   if (*vp)
1720
   {
1721
       png_warning(png_ptr, "malformed width string in sCAL chunk");
1722
       return;
1723
   }
1724
#else
1725
#ifdef PNG_FIXED_POINT_SUPPORTED
1726
   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1727
   if (swidth == NULL)
1728
     {
1729
       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1730
       return;
1731
     }
1732
   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1733
#endif
1734
#endif
1735
 
1736
   for (ep = buffer; *ep; ep++)
1737
      /* empty loop */ ;
1738
   ep++;
1739
 
1740
#ifdef PNG_FLOATING_POINT_SUPPORTED
1741
   height = strtod(ep, &vp);
1742
   if (*vp)
1743
   {
1744
       png_warning(png_ptr, "malformed height string in sCAL chunk");
1745
       return;
1746
   }
1747
#else
1748
#ifdef PNG_FIXED_POINT_SUPPORTED
1749
   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1750
   if (swidth == NULL)
1751
     {
1752
       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1753
       return;
1754
     }
1755
   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1756
#endif
1757
#endif
1758
 
1759
   if (buffer + slength < ep
1760
#ifdef PNG_FLOATING_POINT_SUPPORTED
1761
      || width <= 0. || height <= 0.
1762
#endif
1763
      )
1764
   {
1765
      png_warning(png_ptr, "Invalid sCAL data");
1766
      png_free(png_ptr, buffer);
1767
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1768
      png_free(png_ptr, swidth);
1769
      png_free(png_ptr, sheight);
1770
#endif
1771
      return;
1772
   }
1773
 
1774
 
1775
#ifdef PNG_FLOATING_POINT_SUPPORTED
1776
   png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
1777
#else
1778
#ifdef PNG_FIXED_POINT_SUPPORTED
1779
   png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
1780
#endif
1781
#endif
1782
 
1783
   png_free(png_ptr, buffer);
1784
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1785
   png_free(png_ptr, swidth);
1786
   png_free(png_ptr, sheight);
1787
#endif
1788
}
1789
#endif
1790
 
1791
#if defined(PNG_READ_tIME_SUPPORTED)
1792
void /* PRIVATE */
1793
png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1794
{
1795
   png_byte buf[7];
1796
   png_time mod_time;
1797
 
1798
   png_debug(1, "in png_handle_tIME\n");
1799
 
1800
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1801
      png_error(png_ptr, "Out of place tIME chunk");
1802
   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1803
   {
1804
      png_warning(png_ptr, "Duplicate tIME chunk");
1805
      png_crc_finish(png_ptr, length);
1806
      return;
1807
   }
1808
 
1809
   if (png_ptr->mode & PNG_HAVE_IDAT)
1810
      png_ptr->mode |= PNG_AFTER_IDAT;
1811
 
1812
   if (length != 7)
1813
   {
1814
      png_warning(png_ptr, "Incorrect tIME chunk length");
1815
      png_crc_finish(png_ptr, length);
1816
      return;
1817
   }
1818
 
1819
   png_crc_read(png_ptr, buf, 7);
1820
   if (png_crc_finish(png_ptr, 0))
1821
      return;
1822
 
1823
   mod_time.second = buf[6];
1824
   mod_time.minute = buf[5];
1825
   mod_time.hour = buf[4];
1826
   mod_time.day = buf[3];
1827
   mod_time.month = buf[2];
1828
   mod_time.year = png_get_uint_16(buf);
1829
 
1830
   png_set_tIME(png_ptr, info_ptr, &mod_time);
1831
}
1832
#endif
1833
 
1834
#if defined(PNG_READ_tEXt_SUPPORTED)
1835
/* Note: this does not properly handle chunks that are > 64K under DOS */
1836
void /* PRIVATE */
1837
png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1838
{
1839
   png_textp text_ptr;
1840
   png_charp key;
1841
   png_charp text;
1842
   png_uint_32 skip = 0;
1843
   png_size_t slength;
1844
   int ret;
1845
 
1846
   png_debug(1, "in png_handle_tEXt\n");
1847
 
1848
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1849
      png_error(png_ptr, "Missing IHDR before tEXt");
1850
 
1851
   if (png_ptr->mode & PNG_HAVE_IDAT)
1852
      png_ptr->mode |= PNG_AFTER_IDAT;
1853
 
1854
#ifdef PNG_MAX_MALLOC_64K
1855
   if (length > (png_uint_32)65535L)
1856
   {
1857
      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1858
      skip = length - (png_uint_32)65535L;
1859
      length = (png_uint_32)65535L;
1860
   }
1861
#endif
1862
 
1863
   key = (png_charp)png_malloc_warn(png_ptr, length + 1);
1864
   if (key == NULL)
1865
   {
1866
     png_warning(png_ptr, "No memory to process text chunk.");
1867
     return;
1868
   }
1869
   slength = (png_size_t)length;
1870
   png_crc_read(png_ptr, (png_bytep)key, slength);
1871
 
1872
   if (png_crc_finish(png_ptr, skip))
1873
   {
1874
      png_free(png_ptr, key);
1875
      return;
1876
   }
1877
 
1878
   key[slength] = 0x00;
1879
 
1880
   for (text = key; *text; text++)
1881
      /* empty loop to find end of key */ ;
1882
 
1883
   if (text != key + slength)
1884
      text++;
1885
 
1886
   text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1887
   if (text_ptr == NULL)
1888
   {
1889
     png_warning(png_ptr, "Not enough memory to process text chunk.");
1890
     png_free(png_ptr, key);
1891
     return;
1892
   }
1893
   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1894
   text_ptr->key = key;
1895
#ifdef PNG_iTXt_SUPPORTED
1896
   text_ptr->lang = NULL;
1897
   text_ptr->lang_key = NULL;
1898
   text_ptr->itxt_length = 0;
1899
#endif
1900
   text_ptr->text = text;
1901
   text_ptr->text_length = png_strlen(text);
1902
 
1903
   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1904
 
1905
   png_free(png_ptr, key);
1906
   png_free(png_ptr, text_ptr);
1907
   if (ret)
1908
     png_warning(png_ptr, "Insufficient memory to process text chunk.");
1909
}
1910
#endif
1911
 
1912
#if defined(PNG_READ_zTXt_SUPPORTED)
1913
/* note: this does not correctly handle chunks that are > 64K under DOS */
1914
void /* PRIVATE */
1915
png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1916
{
1917
   png_textp text_ptr;
1918
   png_charp chunkdata;
1919
   png_charp text;
1920
   int comp_type;
1921
   int ret;
1922
   png_size_t slength, prefix_len, data_len;
1923
 
1924
   png_debug(1, "in png_handle_zTXt\n");
1925
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1926
      png_error(png_ptr, "Missing IHDR before zTXt");
1927
 
1928
   if (png_ptr->mode & PNG_HAVE_IDAT)
1929
      png_ptr->mode |= PNG_AFTER_IDAT;
1930
 
1931
#ifdef PNG_MAX_MALLOC_64K
1932
   /* We will no doubt have problems with chunks even half this size, but
1933
      there is no hard and fast rule to tell us where to stop. */
1934
   if (length > (png_uint_32)65535L)
1935
   {
1936
     png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1937
     png_crc_finish(png_ptr, length);
1938
     return;
1939
   }
1940
#endif
1941
 
1942
   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1943
   if (chunkdata == NULL)
1944
   {
1945
     png_warning(png_ptr,"Out of memory processing zTXt chunk.");
1946
     return;
1947
   }
1948
   slength = (png_size_t)length;
1949
   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1950
   if (png_crc_finish(png_ptr, 0))
1951
   {
1952
      png_free(png_ptr, chunkdata);
1953
      return;
1954
   }
1955
 
1956
   chunkdata[slength] = 0x00;
1957
 
1958
   for (text = chunkdata; *text; text++)
1959
      /* empty loop */ ;
1960
 
1961
   /* zTXt must have some text after the chunkdataword */
1962
   if (text == chunkdata + slength)
1963
   {
1964
      comp_type = PNG_TEXT_COMPRESSION_NONE;
1965
      png_warning(png_ptr, "Zero length zTXt chunk");
1966
   }
1967
   else
1968
   {
1969
       comp_type = *(++text);
1970
       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
1971
       {
1972
          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
1973
          comp_type = PNG_TEXT_COMPRESSION_zTXt;
1974
       }
1975
       text++;        /* skip the compression_method byte */
1976
   }
1977
   prefix_len = text - chunkdata;
1978
 
1979
   chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
1980
                                    (png_size_t)length, prefix_len, &data_len);
1981
 
1982
   text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1983
   if (text_ptr == NULL)
1984
   {
1985
     png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
1986
     png_free(png_ptr, chunkdata);
1987
     return;
1988
   }
1989
   text_ptr->compression = comp_type;
1990
   text_ptr->key = chunkdata;
1991
#ifdef PNG_iTXt_SUPPORTED
1992
   text_ptr->lang = NULL;
1993
   text_ptr->lang_key = NULL;
1994
   text_ptr->itxt_length = 0;
1995
#endif
1996
   text_ptr->text = chunkdata + prefix_len;
1997
   text_ptr->text_length = data_len;
1998
 
1999
   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2000
 
2001
   png_free(png_ptr, text_ptr);
2002
   png_free(png_ptr, chunkdata);
2003
   if (ret)
2004
     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2005
}
2006
#endif
2007
 
2008
#if defined(PNG_READ_iTXt_SUPPORTED)
2009
/* note: this does not correctly handle chunks that are > 64K under DOS */
2010
void /* PRIVATE */
2011
png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2012
{
2013
   png_textp text_ptr;
2014
   png_charp chunkdata;
2015
   png_charp key, lang, text, lang_key;
2016
   int comp_flag;
2017
   int comp_type = 0;
2018
   int ret;
2019
   png_size_t slength, prefix_len, data_len;
2020
 
2021
   png_debug(1, "in png_handle_iTXt\n");
2022
 
2023
   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2024
      png_error(png_ptr, "Missing IHDR before iTXt");
2025
 
2026
   if (png_ptr->mode & PNG_HAVE_IDAT)
2027
      png_ptr->mode |= PNG_AFTER_IDAT;
2028
 
2029
#ifdef PNG_MAX_MALLOC_64K
2030
   /* We will no doubt have problems with chunks even half this size, but
2031
      there is no hard and fast rule to tell us where to stop. */
2032
   if (length > (png_uint_32)65535L)
2033
   {
2034
     png_warning(png_ptr,"iTXt chunk too large to fit in memory");
2035
     png_crc_finish(png_ptr, length);
2036
     return;
2037
   }
2038
#endif
2039
 
2040
   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2041
   if (chunkdata == NULL)
2042
   {
2043
     png_warning(png_ptr, "No memory to process iTXt chunk.");
2044
     return;
2045
   }
2046
   slength = (png_size_t)length;
2047
   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
2048
   if (png_crc_finish(png_ptr, 0))
2049
   {
2050
      png_free(png_ptr, chunkdata);
2051
      return;
2052
   }
2053
 
2054
   chunkdata[slength] = 0x00;
2055
 
2056
   for (lang = chunkdata; *lang; lang++)
2057
      /* empty loop */ ;
2058
   lang++;        /* skip NUL separator */
2059
 
2060
   /* iTXt must have a language tag (possibly empty), two compression bytes,
2061
      translated keyword (possibly empty), and possibly some text after the
2062
      keyword */
2063
 
2064
   if (lang >= chunkdata + slength)
2065
   {
2066
      comp_flag = PNG_TEXT_COMPRESSION_NONE;
2067
      png_warning(png_ptr, "Zero length iTXt chunk");
2068
   }
2069
   else
2070
   {
2071
       comp_flag = *lang++;
2072
       comp_type = *lang++;
2073
   }
2074
 
2075
   for (lang_key = lang; *lang_key; lang_key++)
2076
      /* empty loop */ ;
2077
   lang_key++;        /* skip NUL separator */
2078
 
2079
   for (text = lang_key; *text; text++)
2080
      /* empty loop */ ;
2081
   text++;        /* skip NUL separator */
2082
 
2083
   prefix_len = text - chunkdata;
2084
 
2085
   key=chunkdata;
2086
   if (comp_flag)
2087
       chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
2088
          (size_t)length, prefix_len, &data_len);
2089
   else
2090
       data_len=png_strlen(chunkdata + prefix_len);
2091
   text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
2092
   if (text_ptr == NULL)
2093
   {
2094
     png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
2095
     png_free(png_ptr, chunkdata);
2096
     return;
2097
   }
2098
   text_ptr->compression = (int)comp_flag + 1;
2099
   text_ptr->lang_key = chunkdata+(lang_key-key);
2100
   text_ptr->lang = chunkdata+(lang-key);
2101
   text_ptr->itxt_length = data_len;
2102
   text_ptr->text_length = 0;
2103
   text_ptr->key = chunkdata;
2104
   text_ptr->text = chunkdata + prefix_len;
2105
 
2106
   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2107
 
2108
   png_free(png_ptr, text_ptr);
2109
   png_free(png_ptr, chunkdata);
2110
   if (ret)
2111
     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2112
}
2113
#endif
2114
 
2115
/* This function is called when we haven't found a handler for a
2116
   chunk.  If there isn't a problem with the chunk itself (ie bad
2117
   chunk name, CRC, or a critical chunk), the chunk is silently ignored
2118
   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2119
   case it will be saved away to be written out later. */
2120
void /* PRIVATE */
2121
png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2122
{
2123
   png_uint_32 skip = 0;
2124
 
2125
   png_debug(1, "in png_handle_unknown\n");
2126
 
2127
   if (png_ptr->mode & PNG_HAVE_IDAT)
2128
   {
2129
#ifdef PNG_USE_LOCAL_ARRAYS
2130
      PNG_IDAT;
2131
#endif
2132
      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
2133
         png_ptr->mode |= PNG_AFTER_IDAT;
2134
   }
2135
 
2136
   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
2137
 
2138
   if (!(png_ptr->chunk_name[0] & 0x20))
2139
   {
2140
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2141
      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2142
           HANDLE_CHUNK_ALWAYS
2143
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2144
           && png_ptr->read_user_chunk_fn == NULL
2145
#endif
2146
        )
2147
#endif
2148
          png_chunk_error(png_ptr, "unknown critical chunk");
2149
   }
2150
 
2151
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2152
   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2153
   {
2154
       png_unknown_chunk chunk;
2155
 
2156
#ifdef PNG_MAX_MALLOC_64K
2157
       if (length > (png_uint_32)65535L)
2158
       {
2159
           png_warning(png_ptr, "unknown chunk too large to fit in memory");
2160
           skip = length - (png_uint_32)65535L;
2161
           length = (png_uint_32)65535L;
2162
       }
2163
#endif
2164
       png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
2165
       chunk.data = (png_bytep)png_malloc(png_ptr, length);
2166
       chunk.size = (png_size_t)length;
2167
       png_crc_read(png_ptr, (png_bytep)chunk.data, length);
2168
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2169
       if(png_ptr->read_user_chunk_fn != NULL)
2170
       {
2171
          /* callback to user unknown chunk handler */
2172
          if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
2173
          {
2174
             if (!(png_ptr->chunk_name[0] & 0x20))
2175
                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2176
                     HANDLE_CHUNK_ALWAYS)
2177
                 {
2178
                   png_free(png_ptr, chunk.data);
2179
                   png_chunk_error(png_ptr, "unknown critical chunk");
2180
                 }
2181
             png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2182
          }
2183
       }
2184
       else
2185
#endif
2186
          png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2187
       png_free(png_ptr, chunk.data);
2188
   }
2189
   else
2190
#endif
2191
      skip = length;
2192
 
2193
   png_crc_finish(png_ptr, skip);
2194
 
2195
#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2196
   info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
2197
#endif
2198
}
2199
 
2200
/* This function is called to verify that a chunk name is valid.
2201
   This function can't have the "critical chunk check" incorporated
2202
   into it, since in the future we will need to be able to call user
2203
   functions to handle unknown critical chunks after we check that
2204
   the chunk name itself is valid. */
2205
 
2206
#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
2207
 
2208
void /* PRIVATE */
2209
png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2210
{
2211
   png_debug(1, "in png_check_chunk_name\n");
2212
   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2213
       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2214
   {
2215
      png_chunk_error(png_ptr, "invalid chunk type");
2216
   }
2217
}
2218
 
2219
/* Combines the row recently read in with the existing pixels in the
2220
   row.  This routine takes care of alpha and transparency if requested.
2221
   This routine also handles the two methods of progressive display
2222
   of interlaced images, depending on the mask value.
2223
   The mask value describes which pixels are to be combined with
2224
   the row.  The pattern always repeats every 8 pixels, so just 8
2225
   bits are needed.  A one indicates the pixel is to be combined,
2226
   a zero indicates the pixel is to be skipped.  This is in addition
2227
   to any alpha or transparency value associated with the pixel.  If
2228
   you want all pixels to be combined, pass 0xff (255) in mask.  */
2229
#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
2230
void /* PRIVATE */
2231
png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2232
{
2233
   png_debug(1,"in png_combine_row\n");
2234
   if (mask == 0xff)
2235
   {
2236
      png_memcpy(row, png_ptr->row_buf + 1,
2237
         (png_size_t)((png_ptr->width *
2238
         png_ptr->row_info.pixel_depth + 7) >> 3));
2239
   }
2240
   else
2241
   {
2242
      switch (png_ptr->row_info.pixel_depth)
2243
      {
2244
         case 1:
2245
         {
2246
            png_bytep sp = png_ptr->row_buf + 1;
2247
            png_bytep dp = row;
2248
            int s_inc, s_start, s_end;
2249
            int m = 0x80;
2250
            int shift;
2251
            png_uint_32 i;
2252
            png_uint_32 row_width = png_ptr->width;
2253
 
2254
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2255
            if (png_ptr->transformations & PNG_PACKSWAP)
2256
            {
2257
                s_start = 0;
2258
                s_end = 7;
2259
                s_inc = 1;
2260
            }
2261
            else
2262
#endif
2263
            {
2264
                s_start = 7;
2265
                s_end = 0;
2266
                s_inc = -1;
2267
            }
2268
 
2269
            shift = s_start;
2270
 
2271
            for (i = 0; i < row_width; i++)
2272
            {
2273
               if (m & mask)
2274
               {
2275
                  int value;
2276
 
2277
                  value = (*sp >> shift) & 0x01;
2278
                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2279
                  *dp |= (png_byte)(value << shift);
2280
               }
2281
 
2282
               if (shift == s_end)
2283
               {
2284
                  shift = s_start;
2285
                  sp++;
2286
                  dp++;
2287
               }
2288
               else
2289
                  shift += s_inc;
2290
 
2291
               if (m == 1)
2292
                  m = 0x80;
2293
               else
2294
                  m >>= 1;
2295
            }
2296
            break;
2297
         }
2298
         case 2:
2299
         {
2300
            png_bytep sp = png_ptr->row_buf + 1;
2301
            png_bytep dp = row;
2302
            int s_start, s_end, s_inc;
2303
            int m = 0x80;
2304
            int shift;
2305
            png_uint_32 i;
2306
            png_uint_32 row_width = png_ptr->width;
2307
            int value;
2308
 
2309
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2310
            if (png_ptr->transformations & PNG_PACKSWAP)
2311
            {
2312
               s_start = 0;
2313
               s_end = 6;
2314
               s_inc = 2;
2315
            }
2316
            else
2317
#endif
2318
            {
2319
               s_start = 6;
2320
               s_end = 0;
2321
               s_inc = -2;
2322
            }
2323
 
2324
            shift = s_start;
2325
 
2326
            for (i = 0; i < row_width; i++)
2327
            {
2328
               if (m & mask)
2329
               {
2330
                  value = (*sp >> shift) & 0x03;
2331
                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2332
                  *dp |= (png_byte)(value << shift);
2333
               }
2334
 
2335
               if (shift == s_end)
2336
               {
2337
                  shift = s_start;
2338
                  sp++;
2339
                  dp++;
2340
               }
2341
               else
2342
                  shift += s_inc;
2343
               if (m == 1)
2344
                  m = 0x80;
2345
               else
2346
                  m >>= 1;
2347
            }
2348
            break;
2349
         }
2350
         case 4:
2351
         {
2352
            png_bytep sp = png_ptr->row_buf + 1;
2353
            png_bytep dp = row;
2354
            int s_start, s_end, s_inc;
2355
            int m = 0x80;
2356
            int shift;
2357
            png_uint_32 i;
2358
            png_uint_32 row_width = png_ptr->width;
2359
            int value;
2360
 
2361
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2362
            if (png_ptr->transformations & PNG_PACKSWAP)
2363
            {
2364
               s_start = 0;
2365
               s_end = 4;
2366
               s_inc = 4;
2367
            }
2368
            else
2369
#endif
2370
            {
2371
               s_start = 4;
2372
               s_end = 0;
2373
               s_inc = -4;
2374
            }
2375
            shift = s_start;
2376
 
2377
            for (i = 0; i < row_width; i++)
2378
            {
2379
               if (m & mask)
2380
               {
2381
                  value = (*sp >> shift) & 0xf;
2382
                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2383
                  *dp |= (png_byte)(value << shift);
2384
               }
2385
 
2386
               if (shift == s_end)
2387
               {
2388
                  shift = s_start;
2389
                  sp++;
2390
                  dp++;
2391
               }
2392
               else
2393
                  shift += s_inc;
2394
               if (m == 1)
2395
                  m = 0x80;
2396
               else
2397
                  m >>= 1;
2398
            }
2399
            break;
2400
         }
2401
         default:
2402
         {
2403
            png_bytep sp = png_ptr->row_buf + 1;
2404
            png_bytep dp = row;
2405
            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2406
            png_uint_32 i;
2407
            png_uint_32 row_width = png_ptr->width;
2408
            png_byte m = 0x80;
2409
 
2410
 
2411
            for (i = 0; i < row_width; i++)
2412
            {
2413
               if (m & mask)
2414
               {
2415
                  png_memcpy(dp, sp, pixel_bytes);
2416
               }
2417
 
2418
               sp += pixel_bytes;
2419
               dp += pixel_bytes;
2420
 
2421
               if (m == 1)
2422
                  m = 0x80;
2423
               else
2424
                  m >>= 1;
2425
            }
2426
            break;
2427
         }
2428
      }
2429
   }
2430
}
2431
#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
2432
 
2433
#ifdef PNG_READ_INTERLACING_SUPPORTED
2434
#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE   /* else in pngvcrd.c, pnggccrd.c */
2435
/* OLD pre-1.0.9 interface:
2436
void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2437
   png_uint_32 transformations)
2438
 */
2439
void /* PRIVATE */
2440
png_do_read_interlace(png_structp png_ptr)
2441
{
2442
   png_row_infop row_info = &(png_ptr->row_info);
2443
   png_bytep row = png_ptr->row_buf + 1;
2444
   int pass = png_ptr->pass;
2445
   png_uint_32 transformations = png_ptr->transformations;
2446
#ifdef PNG_USE_LOCAL_ARRAYS
2447
   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2448
   /* offset to next interlace block */
2449
   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2450
#endif
2451
 
2452
   png_debug(1,"in png_do_read_interlace (stock C version)\n");
2453
   if (row != NULL && row_info != NULL)
2454
   {
2455
      png_uint_32 final_width;
2456
 
2457
      final_width = row_info->width * png_pass_inc[pass];
2458
 
2459
      switch (row_info->pixel_depth)
2460
      {
2461
         case 1:
2462
         {
2463
            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2464
            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2465
            int sshift, dshift;
2466
            int s_start, s_end, s_inc;
2467
            int jstop = png_pass_inc[pass];
2468
            png_byte v;
2469
            png_uint_32 i;
2470
            int j;
2471
 
2472
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2473
            if (transformations & PNG_PACKSWAP)
2474
            {
2475
                sshift = (int)((row_info->width + 7) & 0x07);
2476
                dshift = (int)((final_width + 7) & 0x07);
2477
                s_start = 7;
2478
                s_end = 0;
2479
                s_inc = -1;
2480
            }
2481
            else
2482
#endif
2483
            {
2484
                sshift = 7 - (int)((row_info->width + 7) & 0x07);
2485
                dshift = 7 - (int)((final_width + 7) & 0x07);
2486
                s_start = 0;
2487
                s_end = 7;
2488
                s_inc = 1;
2489
            }
2490
 
2491
            for (i = 0; i < row_info->width; i++)
2492
            {
2493
               v = (png_byte)((*sp >> sshift) & 0x01);
2494
               for (j = 0; j < jstop; j++)
2495
               {
2496
                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2497
                  *dp |= (png_byte)(v << dshift);
2498
                  if (dshift == s_end)
2499
                  {
2500
                     dshift = s_start;
2501
                     dp--;
2502
                  }
2503
                  else
2504
                     dshift += s_inc;
2505
               }
2506
               if (sshift == s_end)
2507
               {
2508
                  sshift = s_start;
2509
                  sp--;
2510
               }
2511
               else
2512
                  sshift += s_inc;
2513
            }
2514
            break;
2515
         }
2516
         case 2:
2517
         {
2518
            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2519
            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2520
            int sshift, dshift;
2521
            int s_start, s_end, s_inc;
2522
            int jstop = png_pass_inc[pass];
2523
            png_uint_32 i;
2524
 
2525
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2526
            if (transformations & PNG_PACKSWAP)
2527
            {
2528
               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2529
               dshift = (int)(((final_width + 3) & 0x03) << 1);
2530
               s_start = 6;
2531
               s_end = 0;
2532
               s_inc = -2;
2533
            }
2534
            else
2535
#endif
2536
            {
2537
               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2538
               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2539
               s_start = 0;
2540
               s_end = 6;
2541
               s_inc = 2;
2542
            }
2543
 
2544
            for (i = 0; i < row_info->width; i++)
2545
            {
2546
               png_byte v;
2547
               int j;
2548
 
2549
               v = (png_byte)((*sp >> sshift) & 0x03);
2550
               for (j = 0; j < jstop; j++)
2551
               {
2552
                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2553
                  *dp |= (png_byte)(v << dshift);
2554
                  if (dshift == s_end)
2555
                  {
2556
                     dshift = s_start;
2557
                     dp--;
2558
                  }
2559
                  else
2560
                     dshift += s_inc;
2561
               }
2562
               if (sshift == s_end)
2563
               {
2564
                  sshift = s_start;
2565
                  sp--;
2566
               }
2567
               else
2568
                  sshift += s_inc;
2569
            }
2570
            break;
2571
         }
2572
         case 4:
2573
         {
2574
            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2575
            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2576
            int sshift, dshift;
2577
            int s_start, s_end, s_inc;
2578
            png_uint_32 i;
2579
            int jstop = png_pass_inc[pass];
2580
 
2581
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2582
            if (transformations & PNG_PACKSWAP)
2583
            {
2584
               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2585
               dshift = (int)(((final_width + 1) & 0x01) << 2);
2586
               s_start = 4;
2587
               s_end = 0;
2588
               s_inc = -4;
2589
            }
2590
            else
2591
#endif
2592
            {
2593
               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2594
               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2595
               s_start = 0;
2596
               s_end = 4;
2597
               s_inc = 4;
2598
            }
2599
 
2600
            for (i = 0; i < row_info->width; i++)
2601
            {
2602
               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2603
               int j;
2604
 
2605
               for (j = 0; j < jstop; j++)
2606
               {
2607
                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2608
                  *dp |= (png_byte)(v << dshift);
2609
                  if (dshift == s_end)
2610
                  {
2611
                     dshift = s_start;
2612
                     dp--;
2613
                  }
2614
                  else
2615
                     dshift += s_inc;
2616
               }
2617
               if (sshift == s_end)
2618
               {
2619
                  sshift = s_start;
2620
                  sp--;
2621
               }
2622
               else
2623
                  sshift += s_inc;
2624
            }
2625
            break;
2626
         }
2627
         default:
2628
         {
2629
            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2630
            png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2631
            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2632
 
2633
            int jstop = png_pass_inc[pass];
2634
            png_uint_32 i;
2635
 
2636
            for (i = 0; i < row_info->width; i++)
2637
            {
2638
               png_byte v[8];
2639
               int j;
2640
 
2641
               png_memcpy(v, sp, pixel_bytes);
2642
               for (j = 0; j < jstop; j++)
2643
               {
2644
                  png_memcpy(dp, v, pixel_bytes);
2645
                  dp -= pixel_bytes;
2646
               }
2647
               sp -= pixel_bytes;
2648
            }
2649
            break;
2650
         }
2651
      }
2652
      row_info->width = final_width;
2653
      row_info->rowbytes = ((final_width *
2654
         (png_uint_32)row_info->pixel_depth + 7) >> 3);
2655
   }
2656
#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2657
   transformations = transformations; /* silence compiler warning */
2658
#endif
2659
}
2660
#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
2661
#endif /* PNG_READ_INTERLACING_SUPPORTED */
2662
 
2663
#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
2664
void /* PRIVATE */
2665
png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2666
   png_bytep prev_row, int filter)
2667
{
2668
   png_debug(1, "in png_read_filter_row\n");
2669
   png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
2670
   switch (filter)
2671
   {
2672
      case PNG_FILTER_VALUE_NONE:
2673
         break;
2674
      case PNG_FILTER_VALUE_SUB:
2675
      {
2676
         png_uint_32 i;
2677
         png_uint_32 istop = row_info->rowbytes;
2678
         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2679
         png_bytep rp = row + bpp;
2680
         png_bytep lp = row;
2681
 
2682
         for (i = bpp; i < istop; i++)
2683
         {
2684
            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2685
            rp++;
2686
         }
2687
         break;
2688
      }
2689
      case PNG_FILTER_VALUE_UP:
2690
      {
2691
         png_uint_32 i;
2692
         png_uint_32 istop = row_info->rowbytes;
2693
         png_bytep rp = row;
2694
         png_bytep pp = prev_row;
2695
 
2696
         for (i = 0; i < istop; i++)
2697
         {
2698
            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2699
            rp++;
2700
         }
2701
         break;
2702
      }
2703
      case PNG_FILTER_VALUE_AVG:
2704
      {
2705
         png_uint_32 i;
2706
         png_bytep rp = row;
2707
         png_bytep pp = prev_row;
2708
         png_bytep lp = row;
2709
         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2710
         png_uint_32 istop = row_info->rowbytes - bpp;
2711
 
2712
         for (i = 0; i < bpp; i++)
2713
         {
2714
            *rp = (png_byte)(((int)(*rp) +
2715
               ((int)(*pp++) / 2 )) & 0xff);
2716
            rp++;
2717
         }
2718
 
2719
         for (i = 0; i < istop; i++)
2720
         {
2721
            *rp = (png_byte)(((int)(*rp) +
2722
               (int)(*pp++ + *lp++) / 2 ) & 0xff);
2723
            rp++;
2724
         }
2725
         break;
2726
      }
2727
      case PNG_FILTER_VALUE_PAETH:
2728
      {
2729
         png_uint_32 i;
2730
         png_bytep rp = row;
2731
         png_bytep pp = prev_row;
2732
         png_bytep lp = row;
2733
         png_bytep cp = prev_row;
2734
         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2735
         png_uint_32 istop=row_info->rowbytes - bpp;
2736
 
2737
         for (i = 0; i < bpp; i++)
2738
         {
2739
            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2740
            rp++;
2741
         }
2742
 
2743
         for (i = 0; i < istop; i++)   /* use leftover rp,pp */
2744
         {
2745
            int a, b, c, pa, pb, pc, p;
2746
 
2747
            a = *lp++;
2748
            b = *pp++;
2749
            c = *cp++;
2750
 
2751
            p = b - c;
2752
            pc = a - c;
2753
 
2754
#ifdef PNG_USE_ABS
2755
            pa = abs(p);
2756
            pb = abs(pc);
2757
            pc = abs(p + pc);
2758
#else
2759
            pa = p < 0 ? -p : p;
2760
            pb = pc < 0 ? -pc : pc;
2761
            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2762
#endif
2763
 
2764
            /*
2765
               if (pa <= pb && pa <= pc)
2766
                  p = a;
2767
               else if (pb <= pc)
2768
                  p = b;
2769
               else
2770
                  p = c;
2771
             */
2772
 
2773
            p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2774
 
2775
            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2776
            rp++;
2777
         }
2778
         break;
2779
      }
2780
      default:
2781
         png_warning(png_ptr, "Ignoring bad adaptive filter type");
2782
         *row=0;
2783
         break;
2784
   }
2785
}
2786
#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
2787
 
2788
void /* PRIVATE */
2789
png_read_finish_row(png_structp png_ptr)
2790
{
2791
#ifdef PNG_USE_LOCAL_ARRAYS
2792
   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2793
 
2794
   /* start of interlace block */
2795
   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2796
 
2797
   /* offset to next interlace block */
2798
   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2799
 
2800
   /* start of interlace block in the y direction */
2801
   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2802
 
2803
   /* offset to next interlace block in the y direction */
2804
   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2805
#endif
2806
 
2807
   png_debug(1, "in png_read_finish_row\n");
2808
   png_ptr->row_number++;
2809
   if (png_ptr->row_number < png_ptr->num_rows)
2810
      return;
2811
 
2812
   if (png_ptr->interlaced)
2813
   {
2814
      png_ptr->row_number = 0;
2815
      png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2816
      do
2817
      {
2818
         png_ptr->pass++;
2819
         if (png_ptr->pass >= 7)
2820
            break;
2821
         png_ptr->iwidth = (png_ptr->width +
2822
            png_pass_inc[png_ptr->pass] - 1 -
2823
            png_pass_start[png_ptr->pass]) /
2824
            png_pass_inc[png_ptr->pass];
2825
            png_ptr->irowbytes = ((png_ptr->iwidth *
2826
               (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2827
 
2828
         if (!(png_ptr->transformations & PNG_INTERLACE))
2829
         {
2830
            png_ptr->num_rows = (png_ptr->height +
2831
               png_pass_yinc[png_ptr->pass] - 1 -
2832
               png_pass_ystart[png_ptr->pass]) /
2833
               png_pass_yinc[png_ptr->pass];
2834
            if (!(png_ptr->num_rows))
2835
               continue;
2836
         }
2837
         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
2838
            break;
2839
      } while (png_ptr->iwidth == 0);
2840
 
2841
      if (png_ptr->pass < 7)
2842
         return;
2843
   }
2844
 
2845
   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2846
   {
2847
#ifdef PNG_USE_LOCAL_ARRAYS
2848
      PNG_IDAT;
2849
#endif
2850
      char extra;
2851
      int ret;
2852
 
2853
      png_ptr->zstream.next_out = (Byte *)&extra;
2854
      png_ptr->zstream.avail_out = (uInt)1;
2855
      for(;;)
2856
      {
2857
         if (!(png_ptr->zstream.avail_in))
2858
         {
2859
            while (!png_ptr->idat_size)
2860
            {
2861
               png_byte chunk_length[4];
2862
 
2863
               png_crc_finish(png_ptr, 0);
2864
 
2865
               png_read_data(png_ptr, chunk_length, 4);
2866
               png_ptr->idat_size = png_get_uint_32(chunk_length);
2867
 
2868
               png_reset_crc(png_ptr);
2869
               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2870
               if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
2871
                  png_error(png_ptr, "Not enough image data");
2872
 
2873
            }
2874
            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2875
            png_ptr->zstream.next_in = png_ptr->zbuf;
2876
            if (png_ptr->zbuf_size > png_ptr->idat_size)
2877
               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2878
            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2879
            png_ptr->idat_size -= png_ptr->zstream.avail_in;
2880
         }
2881
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2882
         if (ret == Z_STREAM_END)
2883
         {
2884
            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2885
               png_ptr->idat_size)
2886
               png_warning(png_ptr, "Extra compressed data");
2887
            png_ptr->mode |= PNG_AFTER_IDAT;
2888
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2889
            break;
2890
         }
2891
         if (ret != Z_OK)
2892
            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2893
                      "Decompression Error");
2894
 
2895
         if (!(png_ptr->zstream.avail_out))
2896
         {
2897
            png_warning(png_ptr, "Extra compressed data.");
2898
            png_ptr->mode |= PNG_AFTER_IDAT;
2899
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2900
            break;
2901
         }
2902
 
2903
      }
2904
      png_ptr->zstream.avail_out = 0;
2905
   }
2906
 
2907
   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2908
      png_warning(png_ptr, "Extra compression data");
2909
 
2910
   inflateReset(&png_ptr->zstream);
2911
 
2912
   png_ptr->mode |= PNG_AFTER_IDAT;
2913
}
2914
 
2915
void /* PRIVATE */
2916
png_read_start_row(png_structp png_ptr)
2917
{
2918
#ifdef PNG_USE_LOCAL_ARRAYS
2919
   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2920
 
2921
   /* start of interlace block */
2922
   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2923
 
2924
   /* offset to next interlace block */
2925
   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2926
 
2927
   /* start of interlace block in the y direction */
2928
   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2929
 
2930
   /* offset to next interlace block in the y direction */
2931
   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2932
#endif
2933
 
2934
   int max_pixel_depth;
2935
   png_uint_32 row_bytes;
2936
 
2937
   png_debug(1, "in png_read_start_row\n");
2938
   png_ptr->zstream.avail_in = 0;
2939
   png_init_read_transformations(png_ptr);
2940
   if (png_ptr->interlaced)
2941
   {
2942
      if (!(png_ptr->transformations & PNG_INTERLACE))
2943
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2944
            png_pass_ystart[0]) / png_pass_yinc[0];
2945
      else
2946
         png_ptr->num_rows = png_ptr->height;
2947
 
2948
      png_ptr->iwidth = (png_ptr->width +
2949
         png_pass_inc[png_ptr->pass] - 1 -
2950
         png_pass_start[png_ptr->pass]) /
2951
         png_pass_inc[png_ptr->pass];
2952
 
2953
         row_bytes = ((png_ptr->iwidth *
2954
            (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2955
         png_ptr->irowbytes = (png_size_t)row_bytes;
2956
         if((png_uint_32)png_ptr->irowbytes != row_bytes)
2957
            png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
2958
   }
2959
   else
2960
   {
2961
      png_ptr->num_rows = png_ptr->height;
2962
      png_ptr->iwidth = png_ptr->width;
2963
      png_ptr->irowbytes = png_ptr->rowbytes + 1;
2964
   }
2965
   max_pixel_depth = png_ptr->pixel_depth;
2966
 
2967
#if defined(PNG_READ_PACK_SUPPORTED)
2968
   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2969
      max_pixel_depth = 8;
2970
#endif
2971
 
2972
#if defined(PNG_READ_EXPAND_SUPPORTED)
2973
   if (png_ptr->transformations & PNG_EXPAND)
2974
   {
2975
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2976
      {
2977
         if (png_ptr->num_trans)
2978
            max_pixel_depth = 32;
2979
         else
2980
            max_pixel_depth = 24;
2981
      }
2982
      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2983
      {
2984
         if (max_pixel_depth < 8)
2985
            max_pixel_depth = 8;
2986
         if (png_ptr->num_trans)
2987
            max_pixel_depth *= 2;
2988
      }
2989
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2990
      {
2991
         if (png_ptr->num_trans)
2992
         {
2993
            max_pixel_depth *= 4;
2994
            max_pixel_depth /= 3;
2995
         }
2996
      }
2997
   }
2998
#endif
2999
 
3000
#if defined(PNG_READ_FILLER_SUPPORTED)
3001
   if (png_ptr->transformations & (PNG_FILLER))
3002
   {
3003
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3004
         max_pixel_depth = 32;
3005
      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3006
      {
3007
         if (max_pixel_depth <= 8)
3008
            max_pixel_depth = 16;
3009
         else
3010
            max_pixel_depth = 32;
3011
      }
3012
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3013
      {
3014
         if (max_pixel_depth <= 32)
3015
            max_pixel_depth = 32;
3016
         else
3017
            max_pixel_depth = 64;
3018
      }
3019
   }
3020
#endif
3021
 
3022
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3023
   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3024
   {
3025
      if (
3026
#if defined(PNG_READ_EXPAND_SUPPORTED)
3027
        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3028
#endif
3029
#if defined(PNG_READ_FILLER_SUPPORTED)
3030
        (png_ptr->transformations & (PNG_FILLER)) ||
3031
#endif
3032
        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3033
      {
3034
         if (max_pixel_depth <= 16)
3035
            max_pixel_depth = 32;
3036
         else
3037
            max_pixel_depth = 64;
3038
      }
3039
      else
3040
      {
3041
         if (max_pixel_depth <= 8)
3042
           {
3043
             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3044
               max_pixel_depth = 32;
3045
             else
3046
               max_pixel_depth = 24;
3047
           }
3048
         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3049
            max_pixel_depth = 64;
3050
         else
3051
            max_pixel_depth = 48;
3052
      }
3053
   }
3054
#endif
3055
 
3056
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3057
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3058
   if(png_ptr->transformations & PNG_USER_TRANSFORM)
3059
     {
3060
       int user_pixel_depth=png_ptr->user_transform_depth*
3061
         png_ptr->user_transform_channels;
3062
       if(user_pixel_depth > max_pixel_depth)
3063
         max_pixel_depth=user_pixel_depth;
3064
     }
3065
#endif
3066
 
3067
   /* align the width on the next larger 8 pixels.  Mainly used
3068
      for interlacing */
3069
   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3070
   /* calculate the maximum bytes needed, adding a byte and a pixel
3071
      for safety's sake */
3072
   row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
3073
      1 + ((max_pixel_depth + 7) >> 3);
3074
#ifdef PNG_MAX_MALLOC_64K
3075
   if (row_bytes > (png_uint_32)65536L)
3076
      png_error(png_ptr, "This image requires a row greater than 64KB");
3077
#endif
3078
   png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
3079
   png_ptr->row_buf = png_ptr->big_row_buf+32;
3080
#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
3081
   png_ptr->row_buf_size = row_bytes;
3082
#endif
3083
 
3084
#ifdef PNG_MAX_MALLOC_64K
3085
   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3086
      png_error(png_ptr, "This image requires a row greater than 64KB");
3087
#endif
3088
   png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3089
      png_ptr->rowbytes + 1));
3090
 
3091
   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3092
 
3093
   png_debug1(3, "width = %lu,\n", png_ptr->width);
3094
   png_debug1(3, "height = %lu,\n", png_ptr->height);
3095
   png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
3096
   png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
3097
   png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
3098
   png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
3099
 
3100
   png_ptr->flags |= PNG_FLAG_ROW_INIT;
3101
}