source: svn/newcon3bcm2_21bu/dst/dlib/src/PNG/pngrutil.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 68.8 KB
Line 
1/*
2 * $Id: //suprahd/releases/suprahd_163/suprahd_ztvapp640_163/drivers/graphics/PNG/lpng102/pngrutil.c#1 $
3 * $Revision: #1 $
4 * $DateTime: 2006/02/24 17:51:46 $
5 * $Change: 42566 $
6 * $Author: pryush.sharma $
7 */
8
9
10/* pngrutil.c - utilities to read a PNG file
11 *
12 * libpng 1.0.2 - June 14, 1998
13 * For conditions of distribution and use, see copyright notice in png.h
14 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
15 * Copyright (c) 1996, 1997 Andreas Dilger
16 * Copyright (c) 1998, Glenn Randers-Pehrson
17 *
18 * This file contains routines that are only called from within
19 * libpng itself during the course of reading an image.
20 */
21
22#define PNG_INTERNAL
23#include "png.h"
24//BKTEMP #include "user_dbg.h"
25
26#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
27/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
28png_uint_32
29png_get_uint_32(png_bytep buf)
30{
31   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
32      ((png_uint_32)(*(buf + 1)) << 16) +
33      ((png_uint_32)(*(buf + 2)) << 8) +
34      (png_uint_32)(*(buf + 3));
35
36   return (i);
37}
38
39#if defined(PNG_READ_pCAL_SUPPORTED)
40/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
41 * data is stored in the PNG file in two's complement format, and it is
42 * assumed that the machine format for signed integers is the same. */
43png_int_32
44png_get_int_32(png_bytep buf)
45{
46   png_int_32 i = ((png_int_32)(*buf) << 24) +
47      ((png_int_32)(*(buf + 1)) << 16) +
48      ((png_int_32)(*(buf + 2)) << 8) +
49      (png_int_32)(*(buf + 3));
50
51   return (i);
52}
53#endif /* PNG_READ_pCAL_SUPPORTED */
54
55/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
56png_uint_16
57png_get_uint_16(png_bytep buf)
58{
59   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
60      (png_uint_16)(*(buf + 1)));
61
62   return (i);
63}
64#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
65
66/* Read data, and (optionally) run it through the CRC. */
67void
68png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
69{
70   png_read_data(png_ptr, buf, length);
71   png_calculate_crc(png_ptr, buf, length);
72}
73
74/* Optionally skip data and then check the CRC.  Depending on whether we
75   are reading a ancillary or critical chunk, and how the program has set
76   things up, we may calculate the CRC on the data and print a message.
77   Returns '1' if there was a CRC error, '0' otherwise. */
78int
79png_crc_finish(png_structp png_ptr, png_uint_32 skip)
80{
81   png_size_t i;
82   png_size_t istop = png_ptr->zbuf_size;
83
84   for (i = (png_size_t)skip; i > istop; i -= istop)
85   {
86      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
87   }
88   if (i)
89   {
90      png_crc_read(png_ptr, png_ptr->zbuf, i);
91   }
92
93   if (png_crc_error(png_ptr))
94   {
95      if ((png_ptr->chunk_name[0] & 0x20 &&                /* Ancillary */
96           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
97          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
98           png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
99      {
100         png_chunk_warning(png_ptr, "CRC error");
101      }
102      else
103      {
104         png_chunk_error(png_ptr, "CRC error");
105      }
106      return (1);
107   }
108
109   return (0);
110}
111
112/* Compare the CRC stored in the PNG file with that calculated by libpng from
113   the data it has read thus far. */
114int
115png_crc_error(png_structp png_ptr)
116{
117   png_byte crc_bytes[4];
118   png_uint_32 crc;
119   int need_crc = 1;
120
121   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
122   {
123      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
124          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
125         need_crc = 0;
126   }
127   else                                                    /* critical */
128   {
129      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
130         need_crc = 0;
131   }
132
133   png_read_data(png_ptr, crc_bytes, 4);
134
135   if (need_crc)
136   {
137      crc = png_get_uint_32(crc_bytes);
138      return ((int)(crc != png_ptr->crc));
139   }
140   else
141      return (0);
142}
143
144
145/* read and check the IDHR chunk */
146void
147png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
148{
149   png_byte buf[13];
150   png_uint_32 width, height;
151   int bit_depth, color_type, compression_type, filter_type;
152   int interlace_type;
153
154   png_debug(1, "in png_handle_IHDR\n");
155
156   if (png_ptr->mode != PNG_BEFORE_IHDR)
157      png_error(png_ptr, "Out of place IHDR");
158
159   /* check the length */
160   if (length != 13)
161      png_error(png_ptr, "Invalid IHDR chunk");
162
163   png_ptr->mode |= PNG_HAVE_IHDR;
164
165   png_crc_read(png_ptr, buf, 13);
166   png_crc_finish(png_ptr, 0);
167
168   width = png_get_uint_32(buf);
169   height = png_get_uint_32(buf + 4);
170   bit_depth = buf[8];
171   color_type = buf[9];
172   compression_type = buf[10];
173   filter_type = buf[11];
174   interlace_type = buf[12];
175
176   /* check for width and height valid values */
177   if (width == 0 || width > (png_uint_32)2147483647L || height == 0 ||
178        height > (png_uint_32)2147483647L)
179      png_error(png_ptr, "Invalid image size in IHDR");
180
181   /* check other values */
182   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
183      bit_depth != 8 && bit_depth != 16)
184      png_error(png_ptr, "Invalid bit depth in IHDR");
185
186   if (color_type < 0 || color_type == 1 ||
187      color_type == 5 || color_type > 6)
188      png_error(png_ptr, "Invalid color type in IHDR");
189
190   if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth) > 8 ||
191       ((color_type == PNG_COLOR_TYPE_RGB ||
192         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
193         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
194      png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
195
196   if (interlace_type >= PNG_INTERLACE_LAST)
197      png_error(png_ptr, "Unknown interlace method in IHDR");
198
199   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
200      png_error(png_ptr, "Unknown compression method in IHDR");
201
202   if (filter_type != PNG_FILTER_TYPE_BASE)
203      png_error(png_ptr, "Unknown filter method in IHDR");
204
205   /* set internal variables */
206   png_ptr->width = width;
207   png_ptr->height = height;
208   png_ptr->bit_depth = (png_byte)bit_depth;
209   png_ptr->interlaced = (png_byte)interlace_type;
210   png_ptr->color_type = (png_byte)color_type;
211
212   /* find number of channels */
213   switch (png_ptr->color_type)
214   {
215      case PNG_COLOR_TYPE_GRAY:
216      case PNG_COLOR_TYPE_PALETTE:
217         png_ptr->channels = 1;
218         break;
219      case PNG_COLOR_TYPE_RGB:
220         png_ptr->channels = 3;
221         break;
222      case PNG_COLOR_TYPE_GRAY_ALPHA:
223         png_ptr->channels = 2;
224         break;
225      case PNG_COLOR_TYPE_RGB_ALPHA:
226         png_ptr->channels = 4;
227         break;
228   }
229
230   /* set up other useful info */
231   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
232   png_ptr->channels);
233   png_ptr->rowbytes = ((png_ptr->width *
234      (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
235   png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
236   png_debug1(3,"channels = %d\n", png_ptr->channels);
237   png_debug1(3,"rowbytes = %d\n", png_ptr->rowbytes);
238   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
239      color_type, interlace_type, compression_type, filter_type);
240}
241
242/* read and check the palette */
243void
244png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
245{
246   png_colorp palette;
247   int num, i;
248
249   png_debug(1, "in png_handle_PLTE\n");
250
251   if (!(png_ptr->mode & PNG_HAVE_IHDR))
252      png_error(png_ptr, "Missing IHDR before PLTE");
253   else if (png_ptr->mode & PNG_HAVE_IDAT)
254   {
255      png_warning(png_ptr, "Invalid PLTE after IDAT");
256      png_crc_finish(png_ptr, length);
257      return;
258   }
259   else if (png_ptr->mode & PNG_HAVE_PLTE)
260      png_error(png_ptr, "Duplicate PLTE chunk");
261
262   png_ptr->mode |= PNG_HAVE_PLTE;
263
264#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
265   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
266   {
267      png_crc_finish(png_ptr, length);
268      return;
269   }
270#endif
271
272   if (length % 3)
273   {
274      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
275      {
276         png_warning(png_ptr, "Invalid palette chunk");
277         png_crc_finish(png_ptr, length);
278         return;
279      }
280      else
281      {
282         png_error(png_ptr, "Invalid palette chunk");
283      }
284   }
285
286   num = (int)length / 3;
287   palette = (png_colorp)png_zalloc(png_ptr, (uInt)num, sizeof (png_color));
288   png_ptr->flags |= PNG_FLAG_FREE_PALETTE;
289   for (i = 0; i < num; i++)
290   {
291      png_byte buf[3];
292
293      png_crc_read(png_ptr, buf, 3);
294      /* don't depend upon png_color being any order */
295      palette[i].red = buf[0];
296      palette[i].green = buf[1];
297      palette[i].blue = buf[2];
298   }
299
300   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
301      whatever the normal CRC configuration tells us.  However, if we
302      have an RGB image, the PLTE can be considered ancillary, so
303      we will act as though it is. */
304#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
305   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
306#endif
307   {
308      png_crc_finish(png_ptr, 0);
309   }
310#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
311   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
312   {
313      /* If we don't want to use the data from an ancillary chunk,
314         we have two options: an error abort, or a warning and we
315         ignore the data in this chunk (which should be OK, since
316         it's considered ancillary for a RGB or RGBA image). */
317      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
318      {
319         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
320         {
321            png_chunk_error(png_ptr, "CRC error");
322         }
323         else
324         {
325            png_chunk_warning(png_ptr, "CRC error");
326            png_ptr->flags &= ~PNG_FLAG_FREE_PALETTE;
327            png_zfree(png_ptr, palette);
328            return;
329         }
330      }
331      /* Otherwise, we (optionally) emit a warning and use the chunk. */
332      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
333      {
334         png_chunk_warning(png_ptr, "CRC error");
335      }
336   }
337#endif
338   png_ptr->palette = palette;
339   png_ptr->num_palette = (png_uint_16)num;
340   png_set_PLTE(png_ptr, info_ptr, palette, num);
341
342#if defined (PNG_READ_tRNS_SUPPORTED)
343   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
344   {
345      if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
346      {
347         if (png_ptr->num_trans > png_ptr->num_palette)
348         {
349            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
350            png_ptr->num_trans = png_ptr->num_palette;
351         }
352      }
353   }
354#endif
355
356}
357
358void
359png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
360{
361   png_debug(1, "in png_handle_IEND\n");
362
363   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
364   {
365      png_error(png_ptr, "No image in file");
366
367      /* to quiet compiler warnings about unused info_ptr */
368      if (info_ptr == NULL)
369         return;
370   }
371
372   png_ptr->mode |= PNG_AFTER_IDAT | PNG_HAVE_IEND;
373
374   if (length != 0)
375   {
376      png_warning(png_ptr, "Incorrect IEND chunk length");
377   }
378   png_crc_finish(png_ptr, length);
379}
380
381#if defined(PNG_READ_gAMA_SUPPORTED)
382void
383png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
384{
385   png_uint_32 igamma;
386   float file_gamma;
387   png_byte buf[4];
388
389   png_debug(1, "in png_handle_gAMA\n");
390
391   if (!(png_ptr->mode & PNG_HAVE_IHDR))
392      png_error(png_ptr, "Missing IHDR before gAMA");
393   else if (png_ptr->mode & PNG_HAVE_IDAT)
394   {
395      png_warning(png_ptr, "Invalid gAMA after IDAT");
396      png_crc_finish(png_ptr, length);
397      return;
398   }
399   else if (png_ptr->mode & PNG_HAVE_PLTE)
400      /* Should be an error, but we can cope with it */
401      png_warning(png_ptr, "Out of place gAMA chunk");
402
403   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_gAMA
404#if defined(PNG_READ_sRGB_SUPPORTED)
405      && !(info_ptr->valid & PNG_INFO_sRGB)
406#endif
407      )
408   {
409      png_warning(png_ptr, "Duplicate gAMA chunk");
410      png_crc_finish(png_ptr, length);
411      return;
412   }
413
414   if (length != 4)
415   {
416      png_warning(png_ptr, "Incorrect gAMA chunk length");
417      png_crc_finish(png_ptr, length);
418      return;
419   }
420
421   png_crc_read(png_ptr, buf, 4);
422   if (png_crc_finish(png_ptr, 0))
423      return;
424
425   igamma = png_get_uint_32(buf);
426   /* check for zero gamma */
427   if (igamma == 0)
428      return;
429
430#if defined(PNG_READ_sRGB_SUPPORTED)
431   if (info_ptr->valid & PNG_INFO_sRGB)
432      if(igamma != (png_uint_32)45000L)
433      {
434#if 0//BKTODO:
435         png_warning(png_ptr,
436           "Ignoring incorrect gAMA value when sRGB is also present");
437#ifndef PNG_NO_STDIO
438         OS_DbgPrintf("igamma = %lu\n", igamma);
439#endif
440#endif
441         return;
442      }
443#endif /* PNG_READ_sRGB_SUPPORTED */
444
445   file_gamma = (float)igamma / (float)100000.0;
446#ifdef PNG_READ_GAMMA_SUPPORTED
447   png_ptr->gamma = file_gamma;
448#endif
449   png_set_gAMA(png_ptr, info_ptr, file_gamma);
450}
451#endif
452
453#if defined(PNG_READ_sBIT_SUPPORTED)
454void
455png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
456{
457   png_size_t truelen;
458   png_byte buf[4];
459
460   png_debug(1, "in png_handle_sBIT\n");
461
462   buf[0] = buf[1] = buf[2] = buf[3] = 0;
463
464   if (!(png_ptr->mode & PNG_HAVE_IHDR))
465      png_error(png_ptr, "Missing IHDR before sBIT");
466   else if (png_ptr->mode & PNG_HAVE_IDAT)
467   {
468      png_warning(png_ptr, "Invalid sBIT after IDAT");
469      png_crc_finish(png_ptr, length);
470      return;
471   }
472   else if (png_ptr->mode & PNG_HAVE_PLTE)
473   {
474      /* Should be an error, but we can cope with it */
475      png_warning(png_ptr, "Out of place sBIT chunk");
476   }
477   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT)
478   {
479      png_warning(png_ptr, "Duplicate sBIT chunk");
480      png_crc_finish(png_ptr, length);
481      return;
482   }
483
484   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
485      truelen = 3;
486   else
487      truelen = (png_size_t)png_ptr->channels;
488
489   if (length != truelen)
490   {
491      png_warning(png_ptr, "Incorrect sBIT chunk length");
492      png_crc_finish(png_ptr, length);
493      return;
494   }
495
496   png_crc_read(png_ptr, buf, truelen);
497   if (png_crc_finish(png_ptr, 0))
498      return;
499
500   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
501   {
502      png_ptr->sig_bit.red = buf[0];
503      png_ptr->sig_bit.green = buf[1];
504      png_ptr->sig_bit.blue = buf[2];
505      png_ptr->sig_bit.alpha = buf[3];
506   }
507   else
508   {
509      png_ptr->sig_bit.gray = buf[0];
510      png_ptr->sig_bit.alpha = buf[1];
511   }
512   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
513}
514#endif
515
516//BKTEMP
517static float  fabs(float x)
518{
519    float  s;
520
521    if (x < 0)
522        s = -x;
523    else
524        s = x;
525
526    return s;
527}
528
529
530#if defined(PNG_READ_cHRM_SUPPORTED)
531void
532png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
533{
534   png_byte buf[4];
535   png_uint_32 val;
536   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
537
538   png_debug(1, "in png_handle_cHRM\n");
539
540   if (!(png_ptr->mode & PNG_HAVE_IHDR))
541      png_error(png_ptr, "Missing IHDR before sBIT");
542   else if (png_ptr->mode & PNG_HAVE_IDAT)
543   {
544      png_warning(png_ptr, "Invalid cHRM after IDAT");
545      png_crc_finish(png_ptr, length);
546      return;
547   }
548   else if (png_ptr->mode & PNG_HAVE_PLTE)
549      /* Should be an error, but we can cope with it */
550      png_warning(png_ptr, "Missing PLTE before cHRM");
551
552   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_cHRM
553#if defined(PNG_READ_sRGB_SUPPORTED)
554      && !(info_ptr->valid & PNG_INFO_sRGB)
555#endif
556      )
557   {
558      png_warning(png_ptr, "Duplicate cHRM chunk");
559      png_crc_finish(png_ptr, length);
560      return;
561   }
562
563   if (length != 32)
564   {
565      png_warning(png_ptr, "Incorrect cHRM chunk length");
566      png_crc_finish(png_ptr, length);
567      return;
568   }
569
570   png_crc_read(png_ptr, buf, 4);
571   val = png_get_uint_32(buf);
572   white_x = (float)val / (float)100000.0;
573
574   png_crc_read(png_ptr, buf, 4);
575   val = png_get_uint_32(buf);
576   white_y = (float)val / (float)100000.0;
577
578   if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
579       white_x + white_y > 1.0)
580   {
581      png_warning(png_ptr, "Invalid cHRM white point");
582      png_crc_finish(png_ptr, 24);
583      return;
584   }
585
586   png_crc_read(png_ptr, buf, 4);
587   val = png_get_uint_32(buf);
588   red_x = (float)val / (float)100000.0;
589
590   png_crc_read(png_ptr, buf, 4);
591   val = png_get_uint_32(buf);
592   red_y = (float)val / (float)100000.0;
593
594   if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
595       red_x + red_y > 1.0)
596   {
597      png_warning(png_ptr, "Invalid cHRM red point");
598      png_crc_finish(png_ptr, 16);
599      return;
600   }
601
602   png_crc_read(png_ptr, buf, 4);
603   val = png_get_uint_32(buf);
604   green_x = (float)val / (float)100000.0;
605
606   png_crc_read(png_ptr, buf, 4);
607   val = png_get_uint_32(buf);
608   green_y = (float)val / (float)100000.0;
609
610   if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
611       green_x + green_y > 1.0)
612   {
613      png_warning(png_ptr, "Invalid cHRM green point");
614      png_crc_finish(png_ptr, 8);
615      return;
616   }
617
618   png_crc_read(png_ptr, buf, 4);
619   val = png_get_uint_32(buf);
620   blue_x = (float)val / (float)100000.0;
621
622   png_crc_read(png_ptr, buf, 4);
623   val = png_get_uint_32(buf);
624   blue_y = (float)val / (float)100000.0;
625
626   if (blue_x < (float)0 || blue_x > (float)0.8 || blue_y < (float)0 ||
627       blue_y > (float)0.8 || blue_x + blue_y > (float)1.0)
628   {
629      png_warning(png_ptr, "Invalid cHRM blue point");
630      png_crc_finish(png_ptr, 0);
631      return;
632   }
633
634   if (png_crc_finish(png_ptr, 0))
635      return;
636
637#if defined(PNG_READ_sRGB_SUPPORTED)
638   if (info_ptr->valid & PNG_INFO_sRGB)
639      {
640      if (fabs(white_x - (float).3127) > (float).001 ||
641          fabs(white_y - (float).3290) > (float).001 ||
642          fabs(  red_x - (float).6400) > (float).001 ||
643          fabs(  red_y - (float).3300) > (float).001 ||
644          fabs(green_x - (float).3000) > (float).001 ||
645          fabs(green_y - (float).6000) > (float).001 ||
646          fabs( blue_x - (float).1500) > (float).001 ||
647          fabs( blue_y - (float).0600) > (float).001)
648         {
649
650            png_warning(png_ptr,
651              "Ignoring incorrect cHRM value when sRGB is also present");
652#ifndef PNG_NO_STDIO
653            OS_DbgPrintf("wx=%f, wy=%f, rx=%f, ry=%f\n",
654               white_x, white_y, red_x, red_y);
655            OS_DbgPrintf("gx=%f, gy=%f, bx=%f, by=%f\n",
656               green_x, green_y, blue_x, blue_y);
657#endif
658         }
659         return;
660      }
661#endif /* PNG_READ_sRGB_SUPPORTED */
662
663   png_set_cHRM(png_ptr, info_ptr,
664      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
665}
666#endif
667
668#if defined(PNG_READ_sRGB_SUPPORTED)
669void
670png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
671{
672   int intent;
673   png_byte buf[1];
674
675   png_debug(1, "in png_handle_sRGB\n");
676
677   if (!(png_ptr->mode & PNG_HAVE_IHDR))
678      png_error(png_ptr, "Missing IHDR before sRGB");
679   else if (png_ptr->mode & PNG_HAVE_IDAT)
680   {
681      png_warning(png_ptr, "Invalid sRGB after IDAT");
682      png_crc_finish(png_ptr, length);
683      return;
684   }
685   else if (png_ptr->mode & PNG_HAVE_PLTE)
686      /* Should be an error, but we can cope with it */
687      png_warning(png_ptr, "Out of place sRGB chunk");
688
689   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sRGB)
690   {
691      png_warning(png_ptr, "Duplicate sRGB chunk");
692      png_crc_finish(png_ptr, length);
693      return;
694   }
695
696   if (length != 1)
697   {
698      png_warning(png_ptr, "Incorrect sRGB chunk length");
699      png_crc_finish(png_ptr, length);
700      return;
701   }
702
703   png_crc_read(png_ptr, buf, 1);
704   if (png_crc_finish(png_ptr, 0))
705      return;
706
707   intent = buf[0];
708   /* check for bad intent */
709   if (intent >= PNG_sRGB_INTENT_LAST)
710   {
711      png_warning(png_ptr, "Unknown sRGB intent");
712      return;
713   }
714
715#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
716   if ((info_ptr->valid & PNG_INFO_gAMA))
717      if((png_uint_32)(png_ptr->gamma*(float)100000.+.5) != (png_uint_32)45000L)
718      {
719         png_warning(png_ptr,
720           "Ignoring incorrect gAMA value when sRGB is also present");
721#ifndef PNG_NO_STDIO
722           OS_DbgPrintf("gamma=%f\n",png_ptr->gamma);
723#endif
724      }
725#endif /* PNG_READ_gAMA_SUPPORTED */
726
727#ifdef PNG_READ_cHRM_SUPPORTED
728   if (info_ptr->valid & PNG_INFO_cHRM)
729      if (fabs(info_ptr->x_white - (float).3127) > (float).001 ||
730          fabs(info_ptr->y_white - (float).3290) > (float).001 ||
731          fabs(  info_ptr->x_red - (float).6400) > (float).001 ||
732          fabs(  info_ptr->y_red - (float).3300) > (float).001 ||
733          fabs(info_ptr->x_green - (float).3000) > (float).001 ||
734          fabs(info_ptr->y_green - (float).6000) > (float).001 ||
735          fabs( info_ptr->x_blue - (float).1500) > (float).001 ||
736          fabs( info_ptr->y_blue - (float).0600) > (float).001)
737         {
738            png_warning(png_ptr,
739              "Ignoring incorrect cHRM value when sRGB is also present");
740         }
741#endif /* PNG_READ_cHRM_SUPPORTED */
742
743   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
744}
745#endif /* PNG_READ_sRGB_SUPPORTED */
746
747#if defined(PNG_READ_tRNS_SUPPORTED)
748void
749png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
750{
751   png_debug(1, "in png_handle_tRNS\n");
752
753   if (!(png_ptr->mode & PNG_HAVE_IHDR))
754      png_error(png_ptr, "Missing IHDR before tRNS");
755   else if (png_ptr->mode & PNG_HAVE_IDAT)
756   {
757      png_warning(png_ptr, "Invalid tRNS after IDAT");
758      png_crc_finish(png_ptr, length);
759      return;
760   }
761   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
762   {
763      png_warning(png_ptr, "Duplicate tRNS chunk");
764      png_crc_finish(png_ptr, length);
765      return;
766   }
767
768   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
769   {
770      if (!(png_ptr->mode & PNG_HAVE_PLTE))
771      {
772         /* Should be an error, but we can cope with it */
773         png_warning(png_ptr, "Missing PLTE before tRNS");
774      }
775      else if (length > png_ptr->num_palette)
776      {
777         png_warning(png_ptr, "Incorrect tRNS chunk length");
778         png_crc_finish(png_ptr, length);
779         return;
780      }
781      if (length == 0)
782      {
783         png_warning(png_ptr, "Zero length tRNS chunk");
784         png_crc_finish(png_ptr, length);
785         return;
786      }
787
788      png_ptr->trans = (png_bytep)png_malloc(png_ptr, length);
789      png_ptr->flags |= PNG_FLAG_FREE_TRANS;
790      png_crc_read(png_ptr, png_ptr->trans, (png_size_t)length);
791      png_ptr->num_trans = (png_uint_16)length;
792   }
793   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
794   {
795      png_byte buf[6];
796
797      if (length != 6)
798      {
799         png_warning(png_ptr, "Incorrect tRNS chunk length");
800         png_crc_finish(png_ptr, length);
801         return;
802      }
803
804      png_crc_read(png_ptr, buf, (png_size_t)length);
805      png_ptr->num_trans = 1;
806      png_ptr->trans_values.red = png_get_uint_16(buf);
807      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
808      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
809   }
810   else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
811   {
812      png_byte buf[6];
813
814      if (length != 2)
815      {
816         png_warning(png_ptr, "Incorrect tRNS chunk length");
817         png_crc_finish(png_ptr, length);
818         return;
819      }
820
821      png_crc_read(png_ptr, buf, 2);
822      png_ptr->num_trans = 1;
823      png_ptr->trans_values.gray = png_get_uint_16(buf);
824   }
825   else
826   {
827      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
828      png_crc_finish(png_ptr, length);
829      return;
830   }
831
832   if (png_crc_finish(png_ptr, 0))
833      return;
834
835   png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
836      &(png_ptr->trans_values));
837}
838#endif
839
840#if defined(PNG_READ_bKGD_SUPPORTED)
841void
842png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
843{
844   png_size_t truelen;
845   png_byte buf[6];
846
847   png_debug(1, "in png_handle_bKGD\n");
848
849   if (!(png_ptr->mode & PNG_HAVE_IHDR))
850      png_error(png_ptr, "Missing IHDR before bKGD");
851   else if (png_ptr->mode & PNG_HAVE_IDAT)
852   {
853      png_warning(png_ptr, "Invalid bKGD after IDAT");
854      png_crc_finish(png_ptr, length);
855      return;
856   }
857   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
858            !(png_ptr->mode & PNG_HAVE_PLTE))
859   {
860      png_warning(png_ptr, "Missing PLTE before bKGD");
861      png_crc_finish(png_ptr, length);
862      return;
863   }
864   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD)
865   {
866      png_warning(png_ptr, "Duplicate bKGD chunk");
867      png_crc_finish(png_ptr, length);
868      return;
869   }
870
871   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
872      truelen = 1;
873   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
874      truelen = 6;
875   else
876      truelen = 2;
877
878   if (length != truelen)
879   {
880      png_warning(png_ptr, "Incorrect bKGD chunk length");
881      png_crc_finish(png_ptr, length);
882      return;
883   }
884
885   png_crc_read(png_ptr, buf, truelen);
886   if (png_crc_finish(png_ptr, 0))
887      return;
888
889   /* We convert the index value into RGB components so that we can allow
890    * arbitrary RGB values for background when we have transparency, and
891    * so it is easy to determine the RGB values of the background color
892    * from the info_ptr struct. */
893   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
894   {
895      png_ptr->background.index = buf[0];
896      png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
897      png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
898      png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
899   }
900   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
901   {
902      png_ptr->background.red =
903      png_ptr->background.green =
904      png_ptr->background.blue =
905      png_ptr->background.gray = png_get_uint_16(buf);
906   }
907   else
908   {
909      png_ptr->background.red = png_get_uint_16(buf);
910      png_ptr->background.green = png_get_uint_16(buf + 2);
911      png_ptr->background.blue = png_get_uint_16(buf + 4);
912   }
913
914   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
915}
916#endif
917
918#if defined(PNG_READ_hIST_SUPPORTED)
919void
920png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
921{
922   int num, i;
923
924   png_debug(1, "in png_handle_hIST\n");
925
926   if (!(png_ptr->mode & PNG_HAVE_IHDR))
927      png_error(png_ptr, "Missing IHDR before hIST");
928   else if (png_ptr->mode & PNG_HAVE_IDAT)
929   {
930      png_warning(png_ptr, "Invalid hIST after IDAT");
931      png_crc_finish(png_ptr, length);
932      return;
933   }
934   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
935   {
936      png_warning(png_ptr, "Missing PLTE before hIST");
937      png_crc_finish(png_ptr, length);
938      return;
939   }
940   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST)
941   {
942      png_warning(png_ptr, "Duplicate hIST chunk");
943      png_crc_finish(png_ptr, length);
944      return;
945   }
946
947   if (length != (png_uint_32)(2 * png_ptr->num_palette))
948   {
949      png_warning(png_ptr, "Incorrect hIST chunk length");
950      png_crc_finish(png_ptr, length);
951      return;
952   }
953
954   num = (int)length / 2;
955   png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
956      (png_uint_32)(num * sizeof (png_uint_16)));
957   png_ptr->flags |= PNG_FLAG_FREE_HIST;
958   for (i = 0; i < num; i++)
959   {
960      png_byte buf[2];
961
962      png_crc_read(png_ptr, buf, 2);
963      png_ptr->hist[i] = png_get_uint_16(buf);
964   }
965
966   if (png_crc_finish(png_ptr, 0))
967      return;
968
969   png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
970}
971#endif
972
973#if defined(PNG_READ_pHYs_SUPPORTED)
974void
975png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
976{
977   png_byte buf[9];
978   png_uint_32 res_x, res_y;
979   int unit_type;
980
981   png_debug(1, "in png_handle_pHYs\n");
982
983   if (!(png_ptr->mode & PNG_HAVE_IHDR))
984      png_error(png_ptr, "Missing IHDR before pHYS");
985   else if (png_ptr->mode & PNG_HAVE_IDAT)
986   {
987      png_warning(png_ptr, "Invalid pHYS after IDAT");
988      png_crc_finish(png_ptr, length);
989      return;
990   }
991   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
992   {
993      png_warning(png_ptr, "Duplicate pHYS chunk");
994      png_crc_finish(png_ptr, length);
995      return;
996   }
997
998   if (length != 9)
999   {
1000      png_warning(png_ptr, "Incorrect pHYs chunk length");
1001      png_crc_finish(png_ptr, length);
1002      return;
1003   }
1004
1005   png_crc_read(png_ptr, buf, 9);
1006   if (png_crc_finish(png_ptr, 0))
1007      return;
1008
1009   res_x = png_get_uint_32(buf);
1010   res_y = png_get_uint_32(buf + 4);
1011   unit_type = buf[8];
1012   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1013}
1014#endif
1015
1016#if defined(PNG_READ_oFFs_SUPPORTED)
1017void
1018png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1019{
1020   png_byte buf[9];
1021   png_uint_32 offset_x, offset_y;
1022   int unit_type;
1023
1024   png_debug(1, "in png_handle_oFFs\n");
1025
1026   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1027      png_error(png_ptr, "Missing IHDR before oFFs");
1028   else if (png_ptr->mode & PNG_HAVE_IDAT)
1029   {
1030      png_warning(png_ptr, "Invalid oFFs after IDAT");
1031      png_crc_finish(png_ptr, length);
1032      return;
1033   }
1034   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs)
1035   {
1036      png_warning(png_ptr, "Duplicate oFFs chunk");
1037      png_crc_finish(png_ptr, length);
1038      return;
1039   }
1040
1041   if (length != 9)
1042   {
1043      png_warning(png_ptr, "Incorrect oFFs chunk length");
1044      png_crc_finish(png_ptr, length);
1045      return;
1046   }
1047
1048   png_crc_read(png_ptr, buf, 9);
1049   if (png_crc_finish(png_ptr, 0))
1050      return;
1051
1052   offset_x = png_get_uint_32(buf);
1053   offset_y = png_get_uint_32(buf + 4);
1054   unit_type = buf[8];
1055   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1056}
1057#endif
1058
1059#if defined(PNG_READ_pCAL_SUPPORTED)
1060/* read the pCAL chunk (png-scivis-19970203) */
1061void
1062png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1063{
1064   png_charp purpose;
1065   png_int_32 X0, X1;
1066   png_byte type, nparams;
1067   png_charp buf, units, endptr;
1068   png_charpp params;
1069   png_size_t slength;
1070   int i;
1071
1072   png_debug(1, "in png_handle_pCAL\n");
1073
1074   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1075      png_error(png_ptr, "Missing IHDR before pCAL");
1076   else if (png_ptr->mode & PNG_HAVE_IDAT)
1077   {
1078      png_warning(png_ptr, "Invalid pCAL after IDAT");
1079      png_crc_finish(png_ptr, length);
1080      return;
1081   }
1082   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL)
1083   {
1084      png_warning(png_ptr, "Duplicate pCAL chunk");
1085      png_crc_finish(png_ptr, length);
1086      return;
1087   }
1088
1089   png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
1090      length + 1);
1091   purpose = (png_charp)png_malloc(png_ptr, length + 1);
1092   slength = (png_size_t)length;
1093   png_crc_read(png_ptr, (png_bytep)purpose, slength);
1094
1095   if (png_crc_finish(png_ptr, 0))
1096   {
1097      png_free(png_ptr, purpose);
1098      return;
1099   }
1100
1101   purpose[slength] = 0x00; /* null terminate the last string */
1102
1103   png_debug(3, "Finding end of pCAL purpose string\n");
1104   for (buf = purpose; *buf; buf++)
1105      /* empty loop */ ;
1106
1107   endptr = purpose + slength;
1108
1109   /* We need to have at least 12 bytes after the purpose string
1110      in order to get the parameter information. */
1111   if (endptr <= buf + 12)
1112   {
1113      png_warning(png_ptr, "Invalid pCAL data");
1114      png_free(png_ptr, purpose);
1115      return;
1116   }
1117
1118   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1119   X0 = png_get_int_32((png_bytep)buf+1);
1120   X1 = png_get_int_32((png_bytep)buf+5);
1121   type = buf[9];
1122   nparams = buf[10];
1123   units = buf + 11;
1124
1125   png_debug(3, "Checking pCAL equation type and number of parameters\n");
1126   /* Check that we have the right number of parameters for known
1127      equation types. */
1128   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1129       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1130       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1131       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1132   {
1133      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1134      png_free(png_ptr, purpose);
1135      return;
1136   }
1137   else if (type >= PNG_EQUATION_LAST)
1138   {
1139      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1140   }
1141
1142   for (buf = units; *buf; buf++)
1143      /* Empty loop to move past the units string. */ ;
1144
1145   png_debug(3, "Allocating pCAL parameters array\n");
1146   params = (png_charpp)png_malloc(png_ptr, (png_uint_32)(nparams
1147      *sizeof(png_charp))) ;
1148
1149   /* Get pointers to the start of each parameter string. */
1150   for (i = 0; i < (int)nparams; i++)
1151   {
1152      buf++; /* Skip the null string terminator from previous parameter. */
1153
1154      png_debug1(3, "Reading pCAL parameter %d\n", i);
1155      for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
1156         /* Empty loop to move past each parameter string */ ;
1157
1158      /* Make sure we haven't run out of data yet */
1159      if (buf > endptr)
1160      {
1161         png_warning(png_ptr, "Invalid pCAL data");
1162         png_free(png_ptr, purpose);
1163         png_free(png_ptr, params);
1164         return;
1165      }
1166   }
1167
1168   png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1169      units, params);
1170
1171   png_free(png_ptr, purpose);
1172   png_free(png_ptr, params);
1173}
1174#endif
1175
1176#if defined(PNG_READ_tIME_SUPPORTED)
1177void
1178png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1179{
1180   png_byte buf[7];
1181   png_time mod_time;
1182
1183   png_debug(1, "in png_handle_tIME\n");
1184
1185   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1186      png_error(png_ptr, "Out of place tIME chunk");
1187   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME)
1188   {
1189      png_warning(png_ptr, "Duplicate tIME chunk");
1190      png_crc_finish(png_ptr, length);
1191      return;
1192   }
1193
1194   if (png_ptr->mode & PNG_HAVE_IDAT)
1195      png_ptr->mode |= PNG_AFTER_IDAT;
1196
1197   if (length != 7)
1198   {
1199      png_warning(png_ptr, "Incorrect tIME chunk length");
1200      png_crc_finish(png_ptr, length);
1201      return;
1202   }
1203
1204   png_crc_read(png_ptr, buf, 7);
1205   if (png_crc_finish(png_ptr, 0))
1206      return;
1207
1208   mod_time.second = buf[6];
1209   mod_time.minute = buf[5];
1210   mod_time.hour = buf[4];
1211   mod_time.day = buf[3];
1212   mod_time.month = buf[2];
1213   mod_time.year = png_get_uint_16(buf);
1214
1215   png_set_tIME(png_ptr, info_ptr, &mod_time);
1216}
1217#endif
1218
1219#if defined(PNG_READ_tEXt_SUPPORTED)
1220/* Note: this does not properly handle chunks that are > 64K under DOS */
1221void
1222png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1223{
1224   png_textp text_ptr;
1225   png_charp key;
1226   png_charp text;
1227   png_uint_32 skip = 0;
1228   png_size_t slength;
1229
1230   png_debug(1, "in png_handle_tEXt\n");
1231
1232   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1233      png_error(png_ptr, "Missing IHDR before tEXt");
1234
1235   if (png_ptr->mode & PNG_HAVE_IDAT)
1236      png_ptr->mode |= PNG_AFTER_IDAT;
1237
1238#ifdef PNG_MAX_MALLOC_64K
1239   if (length > (png_uint_32)65535L)
1240   {
1241      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1242      skip = length - (png_uint_32)65535L;
1243      length = (png_uint_32)65535L;
1244   }
1245#endif
1246
1247   key = (png_charp)png_malloc(png_ptr, length + 1);
1248   slength = (png_size_t)length;
1249   png_crc_read(png_ptr, (png_bytep)key, slength);
1250
1251   if (png_crc_finish(png_ptr, skip))
1252   {
1253      png_free(png_ptr, key);
1254      return;
1255   }
1256
1257   key[slength] = 0x00;
1258
1259   for (text = key; *text; text++)
1260      /* empty loop to find end of key */ ;
1261
1262   if (text != key + slength)
1263      text++;
1264
1265   text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
1266   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1267   text_ptr->key = key;
1268   text_ptr->text = text;
1269
1270   png_set_text(png_ptr, info_ptr, text_ptr, 1);
1271
1272   png_free(png_ptr, text_ptr);
1273}
1274#endif
1275
1276#if defined(PNG_READ_zTXt_SUPPORTED)
1277/* note: this does not correctly handle chunks that are > 64K under DOS */
1278void
1279png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1280{
1281   static char msg[] = "Error decoding zTXt chunk";
1282   png_textp text_ptr;
1283   png_charp key;
1284   png_charp text;
1285   int comp_type = PNG_TEXT_COMPRESSION_NONE;
1286   png_size_t slength;
1287
1288   png_debug(1, "in png_handle_zTXt\n");
1289
1290   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1291      png_error(png_ptr, "Missing IHDR before zTXt");
1292
1293   if (png_ptr->mode & PNG_HAVE_IDAT)
1294      png_ptr->mode |= PNG_AFTER_IDAT;
1295
1296#ifdef PNG_MAX_MALLOC_64K
1297   /* We will no doubt have problems with chunks even half this size, but
1298      there is no hard and fast rule to tell us where to stop. */
1299   if (length > (png_uint_32)65535L)
1300   {
1301     png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1302     png_crc_finish(png_ptr, length);
1303     return;
1304   }
1305#endif
1306
1307   key = (png_charp)png_malloc(png_ptr, length + 1);
1308   slength = (png_size_t)length;
1309   png_crc_read(png_ptr, (png_bytep)key, slength);
1310   if (png_crc_finish(png_ptr, 0))
1311   {
1312      png_free(png_ptr, key);
1313      return;
1314   }
1315
1316   key[slength] = 0x00;
1317
1318   for (text = key; *text; text++)
1319      /* empty loop */ ;
1320
1321   /* zTXt must have some text after the keyword */
1322   if (text == key + slength)
1323   {
1324      png_warning(png_ptr, "Zero length zTXt chunk");
1325   }
1326   else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
1327   {
1328      png_size_t text_size, key_size;
1329      text++;
1330
1331      png_ptr->zstream.next_in = (png_bytep)text;
1332      png_ptr->zstream.avail_in = (uInt)(length - (text - key));
1333      png_ptr->zstream.next_out = png_ptr->zbuf;
1334      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1335
1336      key_size = (png_size_t)(text - key);
1337      text_size = 0;
1338      text = NULL;
1339
1340      while (png_ptr->zstream.avail_in)
1341      {
1342         int ret;
1343
1344         ret = png_inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
1345         if (ret != Z_OK && ret != Z_STREAM_END)
1346         {
1347            if (png_ptr->zstream.msg != NULL)
1348               png_warning(png_ptr, png_ptr->zstream.msg);
1349            else
1350               png_warning(png_ptr, msg);
1351            png_inflateReset(&png_ptr->zstream);
1352            png_ptr->zstream.avail_in = 0;
1353
1354            if (text ==  NULL)
1355            {
1356               text_size = key_size + sizeof(msg) + 1;
1357               text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size);
1358               png_memcpy(text, key, key_size);
1359            }
1360
1361            text[text_size - 1] = 0x00;
1362
1363            /* Copy what we can of the error message into the text chunk */
1364            text_size = (png_size_t)(slength - (text - key) - 1);
1365            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
1366            png_memcpy(text + key_size, msg, text_size + 1);
1367            break;
1368         }
1369         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
1370         {
1371            if (text == NULL)
1372            {
1373               text = (png_charp)png_malloc(png_ptr,
1374                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
1375                     + key_size + 1));
1376               png_memcpy(text + key_size, png_ptr->zbuf,
1377                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1378               png_memcpy(text, key, key_size);
1379               text_size = key_size + png_ptr->zbuf_size -
1380                  png_ptr->zstream.avail_out;
1381               *(text + text_size) = 0x00;
1382            }
1383            else
1384            {
1385               png_charp tmp;
1386
1387               tmp = text;
1388               text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
1389                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
1390               png_memcpy(text, tmp, text_size);
1391               png_free(png_ptr, tmp);
1392               png_memcpy(text + text_size, png_ptr->zbuf,
1393                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
1394               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1395               *(text + text_size) = 0x00;
1396            }
1397            if (ret != Z_STREAM_END)
1398            {
1399               png_ptr->zstream.next_out = png_ptr->zbuf;
1400               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1401            }
1402            else
1403            {
1404               break;
1405            }
1406         }
1407      }
1408
1409      png_inflateReset(&png_ptr->zstream);
1410      png_ptr->zstream.avail_in = 0;
1411
1412      png_free(png_ptr, key);
1413      key = text;
1414      text += key_size;
1415   }
1416   else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
1417   {
1418      png_size_t text_size;
1419#if !defined(PNG_NO_STDIO)
1420      char umsg[50];
1421
1422      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
1423      png_warning(png_ptr, umsg);
1424#else
1425      png_warning(png_ptr, "Unknown zTXt compression type");
1426#endif
1427
1428      /* Copy what we can of the error message into the text chunk */
1429      text_size = (png_size_t)(slength - (text - key) - 1);
1430      text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
1431      png_memcpy(text, msg, text_size + 1);
1432   }
1433
1434   text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
1435   text_ptr->compression = comp_type;
1436   text_ptr->key = key;
1437   text_ptr->text = text;
1438
1439   png_set_text(png_ptr, info_ptr, text_ptr, 1);
1440
1441   png_free(png_ptr, text_ptr);
1442}
1443#endif
1444
1445/* This function is called when we haven't found a handler for a
1446   chunk.  If there isn't a problem with the chunk itself (ie bad
1447   chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
1448void
1449png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1450{
1451   png_debug(1, "in png_handle_unknown\n");
1452
1453   /* In the future we can have code here that calls user-supplied
1454    * callback functions for unknown chunks before they are ignored or
1455    * cause an error.
1456    */
1457   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
1458
1459   if (!(png_ptr->chunk_name[0] & 0x20))
1460   {
1461      png_chunk_error(png_ptr, "unknown critical chunk");
1462
1463      /* to quiet compiler warnings about unused info_ptr */
1464      if (info_ptr == NULL)
1465         return;
1466   }
1467
1468   if (png_ptr->mode & PNG_HAVE_IDAT)
1469      png_ptr->mode |= PNG_AFTER_IDAT;
1470
1471   png_crc_finish(png_ptr, length);
1472
1473}
1474
1475/* This function is called to verify that a chunk name is valid.
1476   This function can't have the "critical chunk check" incorporated
1477   into it, since in the future we will need to be able to call user
1478   functions to handle unknown critical chunks after we check that
1479   the chunk name itself is valid. */
1480
1481#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
1482
1483void
1484png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
1485{
1486   png_debug(1, "in png_check_chunk_name\n");
1487   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
1488       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
1489   {
1490      png_chunk_error(png_ptr, "invalid chunk type");
1491   }
1492}
1493
1494/* Combines the row recently read in with the existing pixels in the
1495   row.  This routine takes care of alpha and transparency if requested.
1496   This routine also handles the two methods of progressive display
1497   of interlaced images, depending on the mask value.
1498   The mask value describes which pixels are to be combined with
1499   the row.  The pattern always repeats every 8 pixels, so just 8
1500   bits are needed.  A one indicates the pixel is to be combined,
1501   a zero indicates the pixel is to be skipped.  This is in addition
1502   to any alpha or transparency value associated with the pixel.  If
1503   you want all pixels to be combined, pass 0xff (255) in mask.  */
1504void
1505png_combine_row(png_structp png_ptr, png_bytep row,
1506   int mask)
1507{
1508   png_debug(1,"in png_combine_row\n");
1509   if (mask == 0xff)
1510   {
1511      png_memcpy(row, png_ptr->row_buf + 1,
1512         (png_size_t)((png_ptr->width *
1513         png_ptr->row_info.pixel_depth + 7) >> 3));
1514   }
1515   else
1516   {
1517      switch (png_ptr->row_info.pixel_depth)
1518      {
1519         case 1:
1520         {
1521            png_bytep sp = png_ptr->row_buf + 1;
1522            png_bytep dp = row;
1523            int s_inc, s_start, s_end;
1524            int m = 0x80;
1525            int shift;
1526            png_uint_32 i;
1527            png_uint_32 row_width = png_ptr->width;
1528
1529#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1530            if (png_ptr->transformations & PNG_PACKSWAP)
1531            {
1532                s_start = 0;
1533                s_end = 7;
1534                s_inc = 1;
1535            }
1536            else
1537#endif
1538            {
1539                s_start = 7;
1540                s_end = 0;
1541                s_inc = -1;
1542            }
1543
1544            shift = s_start;
1545
1546            for (i = 0; i < row_width; i++)
1547            {
1548               if (m & mask)
1549               {
1550                  int value;
1551
1552                  value = (*sp >> shift) & 0x1;
1553                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
1554                  *dp |= (png_byte)(value << shift);
1555               }
1556
1557               if (shift == s_end)
1558               {
1559                  shift = s_start;
1560                  sp++;
1561                  dp++;
1562               }
1563               else
1564                  shift += s_inc;
1565
1566               if (m == 1)
1567                  m = 0x80;
1568               else
1569                  m >>= 1;
1570            }
1571            break;
1572         }
1573         case 2:
1574         {
1575            png_bytep sp = png_ptr->row_buf + 1;
1576            png_bytep dp = row;
1577            int s_start, s_end, s_inc;
1578            int m = 0x80;
1579            int shift;
1580            png_uint_32 i;
1581            png_uint_32 row_width = png_ptr->width;
1582            int value;
1583
1584#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1585            if (png_ptr->transformations & PNG_PACKSWAP)
1586            {
1587               s_start = 0;
1588               s_end = 6;
1589               s_inc = 2;
1590            }
1591            else
1592#endif
1593            {
1594               s_start = 6;
1595               s_end = 0;
1596               s_inc = -2;
1597            }
1598
1599            shift = s_start;
1600
1601            for (i = 0; i < row_width; i++)
1602            {
1603               if (m & mask)
1604               {
1605                  value = (*sp >> shift) & 0x3;
1606                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
1607                  *dp |= (png_byte)(value << shift);
1608               }
1609
1610               if (shift == s_end)
1611               {
1612                  shift = s_start;
1613                  sp++;
1614                  dp++;
1615               }
1616               else
1617                  shift += s_inc;
1618               if (m == 1)
1619                  m = 0x80;
1620               else
1621                  m >>= 1;
1622            }
1623            break;
1624         }
1625         case 4:
1626         {
1627            png_bytep sp = png_ptr->row_buf + 1;
1628            png_bytep dp = row;
1629            int s_start, s_end, s_inc;
1630            int m = 0x80;
1631            int shift;
1632            png_uint_32 i;
1633            png_uint_32 row_width = png_ptr->width;
1634            int value;
1635
1636#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1637            if (png_ptr->transformations & PNG_PACKSWAP)
1638            {
1639               s_start = 0;
1640               s_end = 4;
1641               s_inc = 4;
1642            }
1643            else
1644#endif
1645            {
1646               s_start = 4;
1647               s_end = 0;
1648               s_inc = -4;
1649            }
1650            shift = s_start;
1651
1652            for (i = 0; i < row_width; i++)
1653            {
1654               if (m & mask)
1655               {
1656                  value = (*sp >> shift) & 0xf;
1657                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
1658                  *dp |= (png_byte)(value << shift);
1659               }
1660
1661               if (shift == s_end)
1662               {
1663                  shift = s_start;
1664                  sp++;
1665                  dp++;
1666               }
1667               else
1668                  shift += s_inc;
1669               if (m == 1)
1670                  m = 0x80;
1671               else
1672                  m >>= 1;
1673            }
1674            break;
1675         }
1676         default:
1677         {
1678            png_bytep sp = png_ptr->row_buf + 1;
1679            png_bytep dp = row;
1680            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
1681            png_uint_32 i;
1682            png_uint_32 row_width = png_ptr->width;
1683            png_byte m = 0x80;
1684
1685
1686            for (i = 0; i < row_width; i++)
1687            {
1688               if (m & mask)
1689               {
1690                  png_memcpy(dp, sp, pixel_bytes);
1691               }
1692
1693               sp += pixel_bytes;
1694               dp += pixel_bytes;
1695
1696               if (m == 1)
1697                  m = 0x80;
1698               else
1699                  m >>= 1;
1700            }
1701            break;
1702         }
1703      }
1704   }
1705}
1706
1707#if defined(PNG_READ_INTERLACING_SUPPORTED)
1708void
1709png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
1710   png_uint_32 transformations)
1711{
1712   png_debug(1,"in png_do_read_interlace\n");
1713   if (row != NULL && row_info != NULL)
1714   {
1715      png_uint_32 final_width;
1716
1717      final_width = row_info->width * png_pass_inc[pass];
1718
1719      switch (row_info->pixel_depth)
1720      {
1721         case 1:
1722         {
1723            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
1724            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
1725            int sshift, dshift;
1726            int s_start, s_end, s_inc;
1727            int jstop = png_pass_inc[pass];
1728            png_byte v;
1729            png_uint_32 i;
1730            int j;
1731
1732#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1733            if (transformations & PNG_PACKSWAP)
1734            {
1735                sshift = (int)((row_info->width + 7) & 7);
1736                dshift = (int)((final_width + 7) & 7);
1737                s_start = 7;
1738                s_end = 0;
1739                s_inc = -1;
1740            }
1741            else
1742#endif
1743            {
1744                sshift = 7 - (int)((row_info->width + 7) & 7);
1745                dshift = 7 - (int)((final_width + 7) & 7);
1746                s_start = 0;
1747                s_end = 7;
1748                s_inc = 1;
1749            }
1750
1751            for (i = 0; i < row_info->width; i++)
1752            {
1753               v = (png_byte)((*sp >> sshift) & 0x1);
1754               for (j = 0; j < jstop; j++)
1755               {
1756                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
1757                  *dp |= (png_byte)(v << dshift);
1758                  if (dshift == s_end)
1759                  {
1760                     dshift = s_start;
1761                     dp--;
1762                  }
1763                  else
1764                     dshift += s_inc;
1765               }
1766               if (sshift == s_end)
1767               {
1768                  sshift = s_start;
1769                  sp--;
1770               }
1771               else
1772                  sshift += s_inc;
1773            }
1774            break;
1775         }
1776         case 2:
1777         {
1778            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
1779            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
1780            int sshift, dshift;
1781            int s_start, s_end, s_inc;
1782            int jstop = png_pass_inc[pass];
1783            png_uint_32 i;
1784
1785#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1786            if (transformations & PNG_PACKSWAP)
1787            {
1788               sshift = (int)(((row_info->width + 3) & 3) << 1);
1789               dshift = (int)(((final_width + 3) & 3) << 1);
1790               s_start = 6;
1791               s_end = 0;
1792               s_inc = -2;
1793            }
1794            else
1795#endif
1796            {
1797               sshift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
1798               dshift = (int)((3 - ((final_width + 3) & 3)) << 1);
1799               s_start = 0;
1800               s_end = 6;
1801               s_inc = 2;
1802            }
1803
1804            for (i = 0; i < row_info->width; i++)
1805            {
1806               png_byte v;
1807               int j;
1808
1809               v = (png_byte)((*sp >> sshift) & 0x3);
1810               for (j = 0; j < jstop; j++)
1811               {
1812                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
1813                  *dp |= (png_byte)(v << dshift);
1814                  if (dshift == s_end)
1815                  {
1816                     dshift = s_start;
1817                     dp--;
1818                  }
1819                  else
1820                     dshift += s_inc;
1821               }
1822               if (sshift == s_end)
1823               {
1824                  sshift = s_start;
1825                  sp--;
1826               }
1827               else
1828                  sshift += s_inc;
1829            }
1830            break;
1831         }
1832         case 4:
1833         {
1834            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
1835            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
1836            int sshift, dshift;
1837            int s_start, s_end, s_inc;
1838            png_uint_32 i;
1839            int jstop = png_pass_inc[pass];
1840
1841#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1842            if (transformations & PNG_PACKSWAP)
1843            {
1844               sshift = (int)(((row_info->width + 1) & 1) << 2);
1845               dshift = (int)(((final_width + 1) & 1) << 2);
1846               s_start = 4;
1847               s_end = 0;
1848               s_inc = -4;
1849            }
1850            else
1851#endif
1852            {
1853               sshift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
1854               dshift = (int)((1 - ((final_width + 1) & 1)) << 2);
1855               s_start = 0;
1856               s_end = 4;
1857               s_inc = 4;
1858            }
1859
1860            for (i = 0; i < row_info->width; i++)
1861            {
1862               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
1863               int j;
1864
1865               for (j = 0; j < jstop; j++)
1866               {
1867                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
1868                  *dp |= (png_byte)(v << dshift);
1869                  if (dshift == s_end)
1870                  {
1871                     dshift = s_start;
1872                     dp--;
1873                  }
1874                  else
1875                     dshift += s_inc;
1876               }
1877               if (sshift == s_end)
1878               {
1879                  sshift = s_start;
1880                  sp--;
1881               }
1882               else
1883                  sshift += s_inc;
1884            }
1885            break;
1886         }
1887         default:
1888         {
1889            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
1890            png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
1891            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
1892            int jstop = png_pass_inc[pass];
1893            png_uint_32 i;
1894
1895            for (i = 0; i < row_info->width; i++)
1896            {
1897               png_byte v[8];
1898               int j;
1899
1900               png_memcpy(v, sp, pixel_bytes);
1901               for (j = 0; j < jstop; j++)
1902               {
1903                  png_memcpy(dp, v, pixel_bytes);
1904                  dp -= pixel_bytes;
1905               }
1906               sp -= pixel_bytes;
1907            }
1908            break;
1909         }
1910      }
1911      row_info->width = final_width;
1912      row_info->rowbytes = ((final_width *
1913         (png_uint_32)row_info->pixel_depth + 7) >> 3);
1914   }
1915}
1916#endif
1917
1918#ifndef PNG_READ_SLOW_FILTERING
1919void
1920png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
1921   png_bytep prev_row, int filter)
1922{
1923   png_debug(1, "in png_read_filter_row\n");
1924   png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
1925
1926
1927   switch (filter)
1928   {
1929      case PNG_FILTER_VALUE_NONE:
1930         break;
1931      case PNG_FILTER_VALUE_SUB:
1932      {
1933         png_uint_32 i;
1934         png_uint_32 istop = row_info->rowbytes;
1935         png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
1936         png_bytep rp = row + bpp;
1937         png_bytep lp = row;
1938
1939         for (i = bpp; i < istop; i++)
1940         {
1941            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
1942            rp++;
1943         }
1944         break;
1945      }
1946      case PNG_FILTER_VALUE_UP:
1947      {
1948         png_uint_32 i;
1949         png_uint_32 istop = row_info->rowbytes;
1950         png_bytep rp = row;
1951         png_bytep pp = prev_row;
1952
1953         for (i = 0; i < istop; i++)
1954         {
1955            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
1956            rp++;
1957         }
1958         break;
1959      }
1960      case PNG_FILTER_VALUE_AVG:
1961      {
1962         png_uint_32 i;
1963         png_bytep rp = row;
1964         png_bytep pp = prev_row;
1965         png_bytep lp = row;
1966         png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
1967         png_uint_32 istop = row_info->rowbytes - bpp;
1968
1969         for (i = 0; i < bpp; i++)
1970         {
1971            *rp = (png_byte)(((int)(*rp) +
1972               ((int)(*pp++) / 2)) & 0xff);
1973            rp++;
1974         }
1975       
1976         for (i = 0; i < istop; i++)
1977         {
1978            *rp = (png_byte)(((int)(*rp) +
1979               (int)(*pp++ + *lp++) / 2) & 0xff);
1980            rp++;
1981         }
1982         break;
1983      }
1984      case PNG_FILTER_VALUE_PAETH:
1985      {
1986         png_uint_32 i;
1987         png_bytep rp = row;
1988         png_bytep pp = prev_row;
1989         png_bytep lp = row;
1990         png_bytep cp = prev_row;
1991         png_uint_32 bpp = (row_info->pixel_depth + 7) / 8;
1992         png_uint_32 istop=row_info->rowbytes - bpp;
1993
1994         for (i = 0; i < bpp; i++)
1995         {
1996            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
1997            rp++;
1998         }
1999
2000         for (i = 0; i < istop; i++)   /* use leftover rp,pp */
2001         {
2002            int a, b, c, pa, pb, pc, p;
2003
2004            a = *lp++;
2005            b = *pp++;
2006            c = *cp++;
2007
2008            p = b - c;
2009            pc = a - c;
2010
2011#ifdef PNG_USE_ABS
2012            pa = abs(p);
2013            pb = abs(pc);
2014            pc = abs(p + pc);
2015#else
2016            pa = p < 0 ? -p : p;
2017            pb = pc < 0 ? -pc : pc;
2018            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2019#endif
2020
2021            /*
2022               if (pa <= pb && pa <= pc)
2023                  p = a;
2024               else if (pb <= pc)
2025                  p = b;
2026               else
2027                  p = c;
2028             */
2029
2030            p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2031
2032            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2033            rp++;
2034         }
2035         break;
2036      }
2037      default:
2038         png_error(png_ptr, "Bad adaptive filter type");
2039         break;
2040   }
2041}
2042#else /* PNG_READ_SLOW_FILTERING */
2043void
2044png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2045   png_bytep prev_row, int filter)
2046{
2047   png_debug(1, "in png_read_filter_row\n");
2048   png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
2049
2050
2051   switch (filter)
2052   {
2053      case PNG_FILTER_VALUE_NONE:
2054         break;
2055      case PNG_FILTER_VALUE_SUB:
2056      {
2057         png_uint_32 i;
2058         int bpp = (row_info->pixel_depth + 7) / 8;
2059         png_bytep rp;
2060         png_bytep lp;
2061
2062         for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
2063            i < row_info->rowbytes; i++, rp++, lp++)
2064         {
2065            *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
2066         }
2067         break;
2068      }
2069      case PNG_FILTER_VALUE_UP:
2070      {
2071         png_uint_32 i;
2072         png_bytep rp;
2073         png_bytep pp;
2074
2075         for (i = 0, rp = row, pp = prev_row;
2076            i < row_info->rowbytes; i++, rp++, pp++)
2077         {
2078            *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
2079         }
2080         break;
2081      }
2082      case PNG_FILTER_VALUE_AVG:
2083      {
2084         png_uint_32 i;
2085         int bpp = (row_info->pixel_depth + 7) / 8;
2086         png_bytep rp;
2087         png_bytep pp;
2088         png_bytep lp;
2089
2090         for (i = 0, rp = row, pp = prev_row;
2091            i < (png_uint_32)bpp; i++, rp++, pp++)
2092         {
2093            *rp = (png_byte)(((int)(*rp) +
2094               ((int)(*pp) / 2)) & 0xff);
2095         }
2096         for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
2097         {
2098            *rp = (png_byte)(((int)(*rp) +
2099               (int)(*pp + *lp) / 2) & 0xff);
2100         }
2101         break;
2102      }
2103      case PNG_FILTER_VALUE_PAETH:
2104      {
2105         int bpp = (row_info->pixel_depth + 7) / 8;
2106         png_uint_32 i;
2107         png_bytep rp;
2108         png_bytep pp;
2109         png_bytep lp;
2110         png_bytep cp;
2111
2112         for (i = 0, rp = row, pp = prev_row,
2113            lp = row - bpp, cp = prev_row - bpp;
2114            i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
2115         {
2116            int a, b, c, pa, pb, pc, p;
2117
2118            b = *pp;
2119            if (i >= (png_uint_32)bpp)
2120            {
2121               c = *cp;
2122               a = *lp;
2123            }
2124            else
2125            {
2126               a = c = 0;
2127            }
2128            p = a + b - c;
2129            pa = abs(p - a);
2130            pb = abs(p - b);
2131            pc = abs(p - c);
2132
2133            if (pa <= pb && pa <= pc)
2134               p = a;
2135            else if (pb <= pc)
2136               p = b;
2137            else
2138               p = c;
2139
2140            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2141         }
2142         break;
2143      }
2144      default:
2145         png_error(png_ptr, "Bad adaptive filter type");
2146         break;
2147   }
2148}
2149#endif /* PNG_READ_SLOW_FILTERING */
2150
2151void
2152png_read_finish_row(png_structp png_ptr)
2153{
2154   png_debug(1, "in png_read_finish_row\n");
2155   png_ptr->row_number++;
2156   if (png_ptr->row_number < png_ptr->num_rows)
2157      return;
2158
2159   if (png_ptr->interlaced)
2160   {
2161      png_ptr->row_number = 0;
2162      png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2163      do
2164      {
2165         png_ptr->pass++;
2166         if (png_ptr->pass >= 7)
2167            break;
2168         png_ptr->iwidth = (png_ptr->width +
2169            png_pass_inc[png_ptr->pass] - 1 -
2170            png_pass_start[png_ptr->pass]) /
2171            png_pass_inc[png_ptr->pass];
2172            png_ptr->irowbytes = ((png_ptr->iwidth *
2173               (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2174
2175         if (!(png_ptr->transformations & PNG_INTERLACE))
2176         {
2177            png_ptr->num_rows = (png_ptr->height +
2178               png_pass_yinc[png_ptr->pass] - 1 -
2179               png_pass_ystart[png_ptr->pass]) /
2180               png_pass_yinc[png_ptr->pass];
2181            if (!(png_ptr->num_rows))
2182               continue;
2183         }
2184         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
2185            break;
2186      } while (png_ptr->iwidth == 0);
2187
2188      if (png_ptr->pass < 7)
2189         return;
2190   }
2191
2192   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2193   {
2194      char extra;
2195      int ret;
2196
2197      png_ptr->zstream.next_out = (Byte *)&extra;
2198      png_ptr->zstream.avail_out = (uInt)1;
2199      for(;;)
2200      {
2201         if (!(png_ptr->zstream.avail_in))
2202         {
2203            while (!png_ptr->idat_size)
2204            {
2205               png_byte chunk_length[4];
2206
2207               png_crc_finish(png_ptr, 0);
2208
2209               png_read_data(png_ptr, chunk_length, 4);
2210               png_ptr->idat_size = png_get_uint_32(chunk_length);
2211
2212               png_reset_crc(png_ptr);
2213               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2214               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
2215                  png_error(png_ptr, "Not enough image data");
2216
2217            }
2218            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2219            png_ptr->zstream.next_in = png_ptr->zbuf;
2220            if (png_ptr->zbuf_size > png_ptr->idat_size)
2221               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2222            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2223            png_ptr->idat_size -= png_ptr->zstream.avail_in;
2224         }
2225         ret = png_inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2226         if (ret == Z_STREAM_END)
2227         {
2228            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2229               png_ptr->idat_size)
2230               png_error(png_ptr, "Extra compressed data");
2231            png_ptr->mode |= PNG_AFTER_IDAT;
2232            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2233            break;
2234         }
2235         if (ret != Z_OK)
2236            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2237                      "Decompression Error");
2238
2239         if (!(png_ptr->zstream.avail_out))
2240            png_error(png_ptr, "Extra compressed data");
2241
2242      }
2243      png_ptr->zstream.avail_out = 0;
2244   }
2245
2246   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2247      png_error(png_ptr, "Extra compression data");
2248
2249   png_inflateReset(&png_ptr->zstream);
2250
2251   png_ptr->mode |= PNG_AFTER_IDAT;
2252}
2253
2254void
2255png_read_start_row(png_structp png_ptr)
2256{
2257   int max_pixel_depth;
2258   png_uint_32 row_bytes;
2259
2260   png_debug(1, "in png_read_start_row\n");
2261   png_ptr->zstream.avail_in = 0;
2262   png_init_read_transformations(png_ptr);
2263   if (png_ptr->interlaced)
2264   {
2265      if (!(png_ptr->transformations & PNG_INTERLACE))
2266         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2267            png_pass_ystart[0]) / png_pass_yinc[0];
2268      else
2269         png_ptr->num_rows = png_ptr->height;
2270
2271      png_ptr->iwidth = (png_ptr->width +
2272         png_pass_inc[png_ptr->pass] - 1 -
2273         png_pass_start[png_ptr->pass]) /
2274         png_pass_inc[png_ptr->pass];
2275
2276         row_bytes = ((png_ptr->iwidth *
2277            (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2278         png_ptr->irowbytes = (png_size_t)row_bytes;
2279         if((png_uint_32)png_ptr->irowbytes != row_bytes)
2280            png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
2281   }
2282   else
2283   {
2284      png_ptr->num_rows = png_ptr->height;
2285      png_ptr->iwidth = png_ptr->width;
2286      png_ptr->irowbytes = png_ptr->rowbytes + 1;
2287   }
2288   max_pixel_depth = png_ptr->pixel_depth;
2289
2290#if defined(PNG_READ_PACK_SUPPORTED)
2291   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2292      max_pixel_depth = 8;
2293#endif
2294
2295#if defined(PNG_READ_EXPAND_SUPPORTED)
2296   if (png_ptr->transformations & PNG_EXPAND)
2297   {
2298      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2299      {
2300         if (png_ptr->num_trans)
2301            max_pixel_depth = 32;
2302         else
2303            max_pixel_depth = 24;
2304      }
2305      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2306      {
2307         if (max_pixel_depth < 8)
2308            max_pixel_depth = 8;
2309         if (png_ptr->num_trans)
2310            max_pixel_depth *= 2;
2311      }
2312      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2313      {
2314         if (png_ptr->num_trans)
2315         {
2316            max_pixel_depth *= 4;
2317            max_pixel_depth /= 3;
2318         }
2319      }
2320   }
2321#endif
2322
2323#if defined(PNG_READ_FILLER_SUPPORTED)
2324   if (png_ptr->transformations & (PNG_FILLER))
2325   {
2326      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2327         max_pixel_depth = 32;
2328      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2329      {
2330         if (max_pixel_depth <= 8)
2331            max_pixel_depth = 16;
2332         else
2333            max_pixel_depth = 32;
2334      }
2335      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2336      {
2337         if (max_pixel_depth <= 32)
2338            max_pixel_depth = 32;
2339         else
2340            max_pixel_depth = 64;
2341      }
2342   }
2343#endif
2344
2345#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2346   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
2347   {
2348      if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
2349         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2350      {
2351         if (max_pixel_depth <= 16)
2352            max_pixel_depth = 32;
2353         else if (max_pixel_depth <= 32)
2354            max_pixel_depth = 64;
2355      }
2356      else
2357      {
2358         if (max_pixel_depth <= 8)
2359            max_pixel_depth = 24;
2360         else if (max_pixel_depth <= 16)
2361            max_pixel_depth = 48;
2362      }
2363   }
2364#endif
2365
2366   /* align the width on the next larger 8 pixels.  Mainly used
2367      for interlacing */
2368   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
2369   /* calculate the maximum bytes needed, adding a byte and a pixel
2370      for safety's sake */
2371   row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
2372      1 + ((max_pixel_depth + 7) >> 3);
2373#ifdef PNG_MAX_MALLOC_64K
2374   if (row_bytes > (png_uint_32)65536L)
2375      png_error(png_ptr, "This image requires a row greater than 64KB");
2376#endif
2377   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, row_bytes);
2378
2379#ifdef PNG_MAX_MALLOC_64K
2380   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
2381      png_error(png_ptr, "This image requires a row greater than 64KB");
2382#endif
2383   png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
2384      png_ptr->rowbytes + 1));
2385
2386   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2387
2388   png_debug1(3, "width = %d,\n", png_ptr->width);
2389   png_debug1(3, "height = %d,\n", png_ptr->height);
2390   png_debug1(3, "iwidth = %d,\n", png_ptr->iwidth);
2391   png_debug1(3, "num_rows = %d\n", png_ptr->num_rows);
2392   png_debug1(3, "rowbytes = %d,\n", png_ptr->rowbytes);
2393   png_debug1(3, "irowbytes = %d,\n", png_ptr->irowbytes);
2394
2395   png_ptr->flags |= PNG_FLAG_ROW_INIT;
2396}
Note: See TracBrowser for help on using the repository browser.