~ubuntu-branches/debian/squeeze/stella/squeeze

« back to all changes in this revision

Viewing changes to src/macosx/libpng/pngrutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna, Franczen Attila, Luca Falavigna
  • Date: 2008-11-08 12:04:12 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20081108120412-w6xq87vzgokstfey
Tags: 2.6.1-0ubuntu1
[ Franczen Attila ]
* New upstream release (LP: #183571).
* Updated policy to 3.8.0.

[ Luca Falavigna ]
* debian/patches/gcc-4.3: fix FTBFS with gcc-4.3 compiler.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
         fprintf(stderr, "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
 
            fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
843
 
               white_x, white_y, red_x, red_y);
844
 
            fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
845
 
               green_x, green_y, blue_x, blue_y);
846
 
#else
847
 
            fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
848
 
               int_x_white, int_y_white, int_x_red, int_y_red);
849
 
            fprintf(stderr,"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
 
         fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
938
 
#  else
939
 
#    ifdef PNG_FLOATING_POINT_SUPPORTED
940
 
         fprintf(stderr,"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
 
}