1
2/* pngread.c - read a PNG file
3 *
4 * Last changed in libpng 1.6.10 [March 6, 2014]
5 * Copyright (c) 1998-2014 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 *
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
12 *
13 * This file contains routines that an application calls directly to
14 * read a PNG file or stream.
15 */
16
17#include "pngpriv.h"
18#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
19#  include <errno.h>
20#endif
21
22#ifdef PNG_READ_SUPPORTED
23
24/* Create a PNG structure for reading, and allocate any memory needed. */
25PNG_FUNCTION(png_structp,PNGAPI
26png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
27    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
28{
29#ifndef PNG_USER_MEM_SUPPORTED
30   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
31      error_fn, warn_fn, NULL, NULL, NULL);
32#else
33   return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
34       warn_fn, NULL, NULL, NULL);
35}
36
37/* Alternate create PNG structure for reading, and allocate any memory
38 * needed.
39 */
40PNG_FUNCTION(png_structp,PNGAPI
41png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
42    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
43    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
44{
45   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
46      error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
47#endif /* PNG_USER_MEM_SUPPORTED */
48
49   if (png_ptr != NULL)
50   {
51      png_ptr->mode = PNG_IS_READ_STRUCT;
52
53      /* Added in libpng-1.6.0; this can be used to detect a read structure if
54       * required (it will be zero in a write structure.)
55       */
56#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
57         png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
58#     endif
59
60#     ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED
61         png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
62
63         /* In stable builds only warn if an application error can be completely
64          * handled.
65          */
66#        if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
67            png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
68#        endif
69#     endif
70
71      /* TODO: delay this, it can be done in png_init_io (if the app doesn't
72       * do it itself) avoiding setting the default function if it is not
73       * required.
74       */
75      png_set_read_fn(png_ptr, NULL, NULL);
76
77#ifdef PNG_INDEX_SUPPORTED
78      png_ptr->index = NULL;
79#endif
80   }
81
82   return png_ptr;
83}
84
85
86#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
87/* Read the information before the actual image data.  This has been
88 * changed in v0.90 to allow reading a file that already has the magic
89 * bytes read from the stream.  You can tell libpng how many bytes have
90 * been read from the beginning of the stream (up to the maximum of 8)
91 * via png_set_sig_bytes(), and we will only check the remaining bytes
92 * here.  The application can then have access to the signature bytes we
93 * read if it is determined that this isn't a valid PNG file.
94 */
95void PNGAPI
96png_read_info(png_structrp png_ptr, png_inforp info_ptr)
97{
98#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
99   int keep;
100#endif
101
102   png_debug(1, "in png_read_info");
103
104   if (png_ptr == NULL || info_ptr == NULL)
105      return;
106
107   /* Read and check the PNG file signature. */
108   png_read_sig(png_ptr, info_ptr);
109
110   for (;;)
111   {
112      png_uint_32 length = png_read_chunk_header(png_ptr);
113      png_uint_32 chunk_name = png_ptr->chunk_name;
114
115      /* IDAT logic needs to happen here to simplify getting the two flags
116       * right.
117       */
118      if (chunk_name == png_IDAT)
119      {
120         if (!(png_ptr->mode & PNG_HAVE_IHDR))
121            png_chunk_error(png_ptr, "Missing IHDR before IDAT");
122
123         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
124             !(png_ptr->mode & PNG_HAVE_PLTE))
125            png_chunk_error(png_ptr, "Missing PLTE before IDAT");
126
127         else if (png_ptr->mode & PNG_AFTER_IDAT)
128            png_chunk_benign_error(png_ptr, "Too many IDATs found");
129
130         png_ptr->mode |= PNG_HAVE_IDAT;
131      }
132
133      else if (png_ptr->mode & PNG_HAVE_IDAT)
134         png_ptr->mode |= PNG_AFTER_IDAT;
135
136      /* This should be a binary subdivision search or a hash for
137       * matching the chunk name rather than a linear search.
138       */
139      if (chunk_name == png_IHDR)
140         png_handle_IHDR(png_ptr, info_ptr, length);
141
142      else if (chunk_name == png_IEND)
143         png_handle_IEND(png_ptr, info_ptr, length);
144
145#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
146      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
147      {
148         png_handle_unknown(png_ptr, info_ptr, length, keep);
149
150         if (chunk_name == png_PLTE)
151            png_ptr->mode |= PNG_HAVE_PLTE;
152
153         else if (chunk_name == png_IDAT)
154         {
155            png_ptr->idat_size = 0; /* It has been consumed */
156            break;
157         }
158      }
159#endif
160      else if (chunk_name == png_PLTE)
161         png_handle_PLTE(png_ptr, info_ptr, length);
162
163      else if (chunk_name == png_IDAT)
164      {
165         png_ptr->idat_size = length;
166         break;
167      }
168
169#ifdef PNG_READ_bKGD_SUPPORTED
170      else if (chunk_name == png_bKGD)
171         png_handle_bKGD(png_ptr, info_ptr, length);
172#endif
173
174#ifdef PNG_READ_cHRM_SUPPORTED
175      else if (chunk_name == png_cHRM)
176         png_handle_cHRM(png_ptr, info_ptr, length);
177#endif
178
179#ifdef PNG_READ_gAMA_SUPPORTED
180      else if (chunk_name == png_gAMA)
181         png_handle_gAMA(png_ptr, info_ptr, length);
182#endif
183
184#ifdef PNG_READ_hIST_SUPPORTED
185      else if (chunk_name == png_hIST)
186         png_handle_hIST(png_ptr, info_ptr, length);
187#endif
188
189#ifdef PNG_READ_oFFs_SUPPORTED
190      else if (chunk_name == png_oFFs)
191         png_handle_oFFs(png_ptr, info_ptr, length);
192#endif
193
194#ifdef PNG_READ_pCAL_SUPPORTED
195      else if (chunk_name == png_pCAL)
196         png_handle_pCAL(png_ptr, info_ptr, length);
197#endif
198
199#ifdef PNG_READ_sCAL_SUPPORTED
200      else if (chunk_name == png_sCAL)
201         png_handle_sCAL(png_ptr, info_ptr, length);
202#endif
203
204#ifdef PNG_READ_pHYs_SUPPORTED
205      else if (chunk_name == png_pHYs)
206         png_handle_pHYs(png_ptr, info_ptr, length);
207#endif
208
209#ifdef PNG_READ_sBIT_SUPPORTED
210      else if (chunk_name == png_sBIT)
211         png_handle_sBIT(png_ptr, info_ptr, length);
212#endif
213
214#ifdef PNG_READ_sRGB_SUPPORTED
215      else if (chunk_name == png_sRGB)
216         png_handle_sRGB(png_ptr, info_ptr, length);
217#endif
218
219#ifdef PNG_READ_iCCP_SUPPORTED
220      else if (chunk_name == png_iCCP)
221         png_handle_iCCP(png_ptr, info_ptr, length);
222#endif
223
224#ifdef PNG_READ_sPLT_SUPPORTED
225      else if (chunk_name == png_sPLT)
226         png_handle_sPLT(png_ptr, info_ptr, length);
227#endif
228
229#ifdef PNG_READ_tEXt_SUPPORTED
230      else if (chunk_name == png_tEXt)
231         png_handle_tEXt(png_ptr, info_ptr, length);
232#endif
233
234#ifdef PNG_READ_tIME_SUPPORTED
235      else if (chunk_name == png_tIME)
236         png_handle_tIME(png_ptr, info_ptr, length);
237#endif
238
239#ifdef PNG_READ_tRNS_SUPPORTED
240      else if (chunk_name == png_tRNS)
241         png_handle_tRNS(png_ptr, info_ptr, length);
242#endif
243
244#ifdef PNG_READ_zTXt_SUPPORTED
245      else if (chunk_name == png_zTXt)
246         png_handle_zTXt(png_ptr, info_ptr, length);
247#endif
248
249#ifdef PNG_READ_iTXt_SUPPORTED
250      else if (chunk_name == png_iTXt)
251         png_handle_iTXt(png_ptr, info_ptr, length);
252#endif
253
254      else
255         png_handle_unknown(png_ptr, info_ptr, length,
256            PNG_HANDLE_CHUNK_AS_DEFAULT);
257   }
258}
259#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
260
261/* Optional call to update the users info_ptr structure */
262void PNGAPI
263png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
264{
265   png_debug(1, "in png_read_update_info");
266
267   if (png_ptr != NULL)
268   {
269#ifdef PNG_INDEX_SUPPORTED
270      if (png_ptr->index) {
271         png_read_start_row(png_ptr);
272      }
273#endif
274      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
275      {
276         png_read_start_row(png_ptr);
277
278#        ifdef PNG_READ_TRANSFORMS_SUPPORTED
279            png_read_transform_info(png_ptr, info_ptr);
280#        else
281            PNG_UNUSED(info_ptr)
282#        endif
283      }
284#ifndef PNG_INDEX_SUPPORTED
285      /* New in 1.6.0 this avoids the bug of doing the initializations twice */
286      else
287         png_app_error(png_ptr,
288            "png_read_update_info/png_start_read_image: duplicate call");
289#endif
290   }
291}
292
293#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
294/* Initialize palette, background, etc, after transformations
295 * are set, but before any reading takes place.  This allows
296 * the user to obtain a gamma-corrected palette, for example.
297 * If the user doesn't call this, we will do it ourselves.
298 */
299void PNGAPI
300png_start_read_image(png_structrp png_ptr)
301{
302   png_debug(1, "in png_start_read_image");
303
304   if (png_ptr != NULL)
305   {
306      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
307         png_read_start_row(png_ptr);
308
309      /* New in 1.6.0 this avoids the bug of doing the initializations twice */
310      else
311         png_app_error(png_ptr,
312            "png_start_read_image/png_read_update_info: duplicate call");
313   }
314}
315#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
316
317#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
318#ifdef PNG_MNG_FEATURES_SUPPORTED
319/* Undoes intrapixel differencing,
320 * NOTE: this is apparently only supported in the 'sequential' reader.
321 */
322static void
323png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
324{
325   png_debug(1, "in png_do_read_intrapixel");
326
327   if (
328       (row_info->color_type & PNG_COLOR_MASK_COLOR))
329   {
330      int bytes_per_pixel;
331      png_uint_32 row_width = row_info->width;
332
333      if (row_info->bit_depth == 8)
334      {
335         png_bytep rp;
336         png_uint_32 i;
337
338         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
339            bytes_per_pixel = 3;
340
341         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
342            bytes_per_pixel = 4;
343
344         else
345            return;
346
347         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
348         {
349            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
350            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
351         }
352      }
353      else if (row_info->bit_depth == 16)
354      {
355         png_bytep rp;
356         png_uint_32 i;
357
358         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
359            bytes_per_pixel = 6;
360
361         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
362            bytes_per_pixel = 8;
363
364         else
365            return;
366
367         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
368         {
369            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
370            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
371            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
372            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
373            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
374            *(rp    ) = (png_byte)((red >> 8) & 0xff);
375            *(rp + 1) = (png_byte)(red & 0xff);
376            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
377            *(rp + 5) = (png_byte)(blue & 0xff);
378         }
379      }
380   }
381}
382#endif /* PNG_MNG_FEATURES_SUPPORTED */
383
384void PNGAPI
385png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
386{
387   png_row_info row_info;
388
389   if (png_ptr == NULL)
390      return;
391
392   png_debug2(1, "in png_read_row (row %lu, pass %d)",
393       (unsigned long)png_ptr->row_number, png_ptr->pass);
394
395   /* png_read_start_row sets the information (in particular iwidth) for this
396    * interlace pass.
397    */
398   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
399      png_read_start_row(png_ptr);
400
401   /* 1.5.6: row_info moved out of png_struct to a local here. */
402   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
403   row_info.color_type = png_ptr->color_type;
404   row_info.bit_depth = png_ptr->bit_depth;
405   row_info.channels = png_ptr->channels;
406   row_info.pixel_depth = png_ptr->pixel_depth;
407   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
408
409   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
410   {
411   /* Check for transforms that have been set but were defined out */
412#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
413   if (png_ptr->transformations & PNG_INVERT_MONO)
414      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
415#endif
416
417#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
418   if (png_ptr->transformations & PNG_FILLER)
419      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
420#endif
421
422#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
423    !defined(PNG_READ_PACKSWAP_SUPPORTED)
424   if (png_ptr->transformations & PNG_PACKSWAP)
425      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
426#endif
427
428#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
429   if (png_ptr->transformations & PNG_PACK)
430      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
431#endif
432
433#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
434   if (png_ptr->transformations & PNG_SHIFT)
435      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
436#endif
437
438#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
439   if (png_ptr->transformations & PNG_BGR)
440      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
441#endif
442
443#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
444   if (png_ptr->transformations & PNG_SWAP_BYTES)
445      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
446#endif
447   }
448
449#ifdef PNG_READ_INTERLACING_SUPPORTED
450   /* If interlaced and we do not need a new row, combine row and return.
451    * Notice that the pixels we have from previous rows have been transformed
452    * already; we can only combine like with like (transformed or
453    * untransformed) and, because of the libpng API for interlaced images, this
454    * means we must transform before de-interlacing.
455    */
456   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
457   {
458      switch (png_ptr->pass)
459      {
460         case 0:
461            if (png_ptr->row_number & 0x07)
462            {
463               if (dsp_row != NULL)
464                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
465               png_read_finish_row(png_ptr);
466               return;
467            }
468            break;
469
470         case 1:
471            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
472            {
473               if (dsp_row != NULL)
474                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
475
476               png_read_finish_row(png_ptr);
477               return;
478            }
479            break;
480
481         case 2:
482            if ((png_ptr->row_number & 0x07) != 4)
483            {
484               if (dsp_row != NULL && (png_ptr->row_number & 4))
485                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
486
487               png_read_finish_row(png_ptr);
488               return;
489            }
490            break;
491
492         case 3:
493            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
494            {
495               if (dsp_row != NULL)
496                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
497
498               png_read_finish_row(png_ptr);
499               return;
500            }
501            break;
502
503         case 4:
504            if ((png_ptr->row_number & 3) != 2)
505            {
506               if (dsp_row != NULL && (png_ptr->row_number & 2))
507                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
508
509               png_read_finish_row(png_ptr);
510               return;
511            }
512            break;
513
514         case 5:
515            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
516            {
517               if (dsp_row != NULL)
518                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
519
520               png_read_finish_row(png_ptr);
521               return;
522            }
523            break;
524
525         default:
526         case 6:
527            if (!(png_ptr->row_number & 1))
528            {
529               png_read_finish_row(png_ptr);
530               return;
531            }
532            break;
533      }
534   }
535#endif
536
537   if (!(png_ptr->mode & PNG_HAVE_IDAT))
538      png_error(png_ptr, "Invalid attempt to read row data");
539
540   /* Fill the row with IDAT data: */
541   png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
542
543   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
544   {
545      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
546         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
547            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
548      else
549         png_error(png_ptr, "bad adaptive filter value");
550   }
551
552   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
553    * 1.5.6, while the buffer really is this big in current versions of libpng
554    * it may not be in the future, so this was changed just to copy the
555    * interlaced count:
556    */
557   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
558
559#ifdef PNG_MNG_FEATURES_SUPPORTED
560   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
561       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
562   {
563      /* Intrapixel differencing */
564      png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
565   }
566#endif
567
568#ifdef PNG_READ_TRANSFORMS_SUPPORTED
569   if (png_ptr->transformations)
570      png_do_read_transformations(png_ptr, &row_info);
571#endif
572
573   /* The transformed pixel depth should match the depth now in row_info. */
574   if (png_ptr->transformed_pixel_depth == 0)
575   {
576      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
577      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
578         png_error(png_ptr, "sequential row overflow");
579   }
580
581   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
582      png_error(png_ptr, "internal sequential row size calculation error");
583
584#ifdef PNG_READ_INTERLACING_SUPPORTED
585   /* Blow up interlaced rows to full size */
586   if (png_ptr->interlaced &&
587      (png_ptr->transformations & PNG_INTERLACE))
588   {
589      if (png_ptr->pass < 6)
590         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
591            png_ptr->transformations);
592
593      if (dsp_row != NULL)
594         png_combine_row(png_ptr, dsp_row, 1/*display*/);
595
596      if (row != NULL)
597         png_combine_row(png_ptr, row, 0/*row*/);
598   }
599
600   else
601#endif
602   {
603      if (row != NULL)
604         png_combine_row(png_ptr, row, -1/*ignored*/);
605
606      if (dsp_row != NULL)
607         png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
608   }
609   png_read_finish_row(png_ptr);
610
611   if (png_ptr->read_row_fn != NULL)
612      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
613
614}
615#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
616
617#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
618/* Read one or more rows of image data.  If the image is interlaced,
619 * and png_set_interlace_handling() has been called, the rows need to
620 * contain the contents of the rows from the previous pass.  If the
621 * image has alpha or transparency, and png_handle_alpha()[*] has been
622 * called, the rows contents must be initialized to the contents of the
623 * screen.
624 *
625 * "row" holds the actual image, and pixels are placed in it
626 * as they arrive.  If the image is displayed after each pass, it will
627 * appear to "sparkle" in.  "display_row" can be used to display a
628 * "chunky" progressive image, with finer detail added as it becomes
629 * available.  If you do not want this "chunky" display, you may pass
630 * NULL for display_row.  If you do not want the sparkle display, and
631 * you have not called png_handle_alpha(), you may pass NULL for rows.
632 * If you have called png_handle_alpha(), and the image has either an
633 * alpha channel or a transparency chunk, you must provide a buffer for
634 * rows.  In this case, you do not have to provide a display_row buffer
635 * also, but you may.  If the image is not interlaced, or if you have
636 * not called png_set_interlace_handling(), the display_row buffer will
637 * be ignored, so pass NULL to it.
638 *
639 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
640 */
641
642void PNGAPI
643png_read_rows(png_structrp png_ptr, png_bytepp row,
644    png_bytepp display_row, png_uint_32 num_rows)
645{
646   png_uint_32 i;
647   png_bytepp rp;
648   png_bytepp dp;
649
650   png_debug(1, "in png_read_rows");
651
652   if (png_ptr == NULL)
653      return;
654
655   rp = row;
656   dp = display_row;
657   if (rp != NULL && dp != NULL)
658      for (i = 0; i < num_rows; i++)
659      {
660         png_bytep rptr = *rp++;
661         png_bytep dptr = *dp++;
662
663         png_read_row(png_ptr, rptr, dptr);
664      }
665
666   else if (rp != NULL)
667      for (i = 0; i < num_rows; i++)
668      {
669         png_bytep rptr = *rp;
670         png_read_row(png_ptr, rptr, NULL);
671         rp++;
672      }
673
674   else if (dp != NULL)
675      for (i = 0; i < num_rows; i++)
676      {
677         png_bytep dptr = *dp;
678         png_read_row(png_ptr, NULL, dptr);
679         dp++;
680      }
681}
682#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
683
684#ifdef PNG_INDEX_SUPPORTED
685#define IDAT_HEADER_SIZE 8
686
687/* Set the png read position to a new position based on idat_position and
688 * offset.
689 */
690void
691png_set_read_offset(png_structp png_ptr,
692      png_uint_32 idat_position, png_uint_32 bytes_left)
693{
694   png_seek_data(png_ptr, idat_position);
695   png_ptr->idat_size = png_read_chunk_header(png_ptr);
696
697   // We need to add back IDAT_HEADER_SIZE because in zlib's perspective,
698   // IDAT_HEADER in PNG is already stripped out.
699   png_seek_data(png_ptr, idat_position + IDAT_HEADER_SIZE + png_ptr->idat_size - bytes_left);
700   png_ptr->idat_size = bytes_left;
701}
702
703/* Configure png decoder to decode the pass starting from *row.
704 * The requested row may be adjusted to align with an indexing row.
705 * The actual row for the decoder to start its decoding will be returned in
706 * *row.
707 */
708void PNGAPI
709png_configure_decoder(png_structp png_ptr, int *row, int pass)
710{
711   png_indexp index = png_ptr->index;
712   int n = *row / index->step[pass];
713   png_line_indexp line_index = index->pass_line_index[pass][n];
714
715   // Adjust row to an indexing row.
716   *row = n * index->step[pass];
717   png_ptr->row_number = *row;
718
719#ifdef PNG_READ_INTERLACING_SUPPORTED
720   if (png_ptr->interlaced)
721      png_set_interlaced_pass(png_ptr, pass);
722#endif
723
724   long row_byte_length =
725      PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
726
727   inflateEnd(&png_ptr->zstream);
728   inflateCopy(&png_ptr->zstream, line_index->z_state);
729
730   // Set the png read position to line_index.
731   png_set_read_offset(png_ptr, line_index->stream_idat_position,
732         line_index->bytes_left_in_idat);
733   memcpy(png_ptr->prev_row, line_index->prev_row, row_byte_length);
734   png_ptr->zstream.avail_in = 0;
735}
736
737/* Build the line index and store the index in png_ptr->index.
738 */
739void PNGAPI
740png_build_index(png_structp png_ptr)
741{
742   // number of rows in a 8x8 block for each interlaced pass.
743   int number_rows_in_pass[7] = {1, 1, 1, 2, 2, 4, 4};
744
745   int ret;
746   png_uint_32 i, j;
747   png_bytep rp;
748   int p, pass_number = 1;
749
750#ifdef PNG_READ_INTERLACING_SUPPORTED
751   pass_number = png_set_interlace_handling(png_ptr);
752#endif
753
754   if (png_ptr == NULL)
755      return;
756
757   png_read_start_row(png_ptr);
758
759#ifdef PNG_READ_INTERLACING_SUPPORTED
760   if (!png_ptr->interlaced)
761#endif
762   {
763      number_rows_in_pass[0] = 8;
764   }
765
766   rp = png_malloc(png_ptr, png_ptr->rowbytes);
767
768   png_indexp index = png_malloc(png_ptr, sizeof(png_index));
769   png_ptr->index = index;
770
771   index->stream_idat_position = png_ptr->total_data_read - IDAT_HEADER_SIZE;
772
773   // Set the default size of index in each pass to 0,
774   // so that we can free index correctly in png_destroy_read_struct.
775   for (p = 0; p < 7; p++)
776      index->size[p] = 0;
777
778   for (p = 0; p < pass_number; p++)
779   {
780      // We adjust the index step in each pass to make sure each pass
781      // has roughly the same size of index.
782      // This way, we won't consume to much memory in recording index.
783      index->step[p] = INDEX_SAMPLE_SIZE * (8 / number_rows_in_pass[p]);
784      const int temp_size =
785         (png_ptr->height + index->step[p] - 1) / index->step[p];
786      index->pass_line_index[p] =
787         png_malloc(png_ptr, temp_size * sizeof(png_line_indexp));
788
789      // Get the row_byte_length seen by the filter. This value may be
790      // different from the row_byte_length of a bitmap in the case of
791      // color palette mode.
792      int row_byte_length =
793         PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
794
795      // Now, we record index for each indexing row.
796      for (i = 0; i < temp_size; i++)
797      {
798         png_line_indexp line_index = png_malloc(png_ptr, sizeof(png_line_index));
799         index->pass_line_index[p][i] = line_index;
800
801         line_index->z_state = png_malloc(png_ptr, sizeof(z_stream));
802         inflateCopy(line_index->z_state, &png_ptr->zstream);
803         line_index->prev_row = png_malloc(png_ptr, row_byte_length);
804         memcpy(line_index->prev_row, png_ptr->prev_row, row_byte_length);
805         line_index->stream_idat_position = index->stream_idat_position;
806         line_index->bytes_left_in_idat = png_ptr->idat_size + png_ptr->zstream.avail_in;
807
808         // increment the size now that we have the backing data structures.
809         // This prevents a crash in the event that png_read_row fails and
810         // we need to cleanup the partially constructed png_index_struct;
811         index->size[p] += 1;
812
813         // Skip the "step" number of rows to the next indexing row.
814         for (j = 0; j < index->step[p] &&
815               i * index->step[p] + j < png_ptr->height; j++)
816         {
817            png_read_row(png_ptr, rp, NULL);
818         }
819      }
820   }
821   png_free(png_ptr, rp);
822}
823#endif
824
825#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
826/* Read the entire image.  If the image has an alpha channel or a tRNS
827 * chunk, and you have called png_handle_alpha()[*], you will need to
828 * initialize the image to the current image that PNG will be overlaying.
829 * We set the num_rows again here, in case it was incorrectly set in
830 * png_read_start_row() by a call to png_read_update_info() or
831 * png_start_read_image() if png_set_interlace_handling() wasn't called
832 * prior to either of these functions like it should have been.  You can
833 * only call this function once.  If you desire to have an image for
834 * each pass of a interlaced image, use png_read_rows() instead.
835 *
836 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
837 */
838void PNGAPI
839png_read_image(png_structrp png_ptr, png_bytepp image)
840{
841   png_uint_32 i, image_height;
842   int pass, j;
843   png_bytepp rp;
844
845   png_debug(1, "in png_read_image");
846
847   if (png_ptr == NULL)
848      return;
849
850#ifdef PNG_READ_INTERLACING_SUPPORTED
851   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
852   {
853      pass = png_set_interlace_handling(png_ptr);
854      /* And make sure transforms are initialized. */
855      png_start_read_image(png_ptr);
856   }
857   else
858   {
859      if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
860      {
861         /* Caller called png_start_read_image or png_read_update_info without
862          * first turning on the PNG_INTERLACE transform.  We can fix this here,
863          * but the caller should do it!
864          */
865         png_warning(png_ptr, "Interlace handling should be turned on when "
866            "using png_read_image");
867         /* Make sure this is set correctly */
868         png_ptr->num_rows = png_ptr->height;
869      }
870
871      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
872       * the above error case.
873       */
874      pass = png_set_interlace_handling(png_ptr);
875   }
876#else
877   if (png_ptr->interlaced)
878      png_error(png_ptr,
879          "Cannot read interlaced image -- interlace handler disabled");
880
881   pass = 1;
882#endif
883
884   image_height=png_ptr->height;
885
886   for (j = 0; j < pass; j++)
887   {
888      rp = image;
889      for (i = 0; i < image_height; i++)
890      {
891         png_read_row(png_ptr, *rp, NULL);
892         rp++;
893      }
894   }
895}
896#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
897
898#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
899/* Read the end of the PNG file.  Will not read past the end of the
900 * file, will verify the end is accurate, and will read any comments
901 * or time information at the end of the file, if info is not NULL.
902 */
903void PNGAPI
904png_read_end(png_structrp png_ptr, png_inforp info_ptr)
905{
906#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
907   int keep;
908#endif
909
910   png_debug(1, "in png_read_end");
911
912   if (png_ptr == NULL)
913      return;
914
915   /* If png_read_end is called in the middle of reading the rows there may
916    * still be pending IDAT data and an owned zstream.  Deal with this here.
917    */
918#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
919   if (!png_chunk_unknown_handling(png_ptr, png_IDAT))
920#endif
921      png_read_finish_IDAT(png_ptr);
922
923#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
924   /* Report invalid palette index; added at libng-1.5.10 */
925   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
926      png_ptr->num_palette_max > png_ptr->num_palette)
927     png_benign_error(png_ptr, "Read palette index exceeding num_palette");
928#endif
929
930   do
931   {
932      png_uint_32 length = png_read_chunk_header(png_ptr);
933      png_uint_32 chunk_name = png_ptr->chunk_name;
934
935      if (chunk_name == png_IEND)
936         png_handle_IEND(png_ptr, info_ptr, length);
937
938      else if (chunk_name == png_IHDR)
939         png_handle_IHDR(png_ptr, info_ptr, length);
940
941      else if (info_ptr == NULL)
942         png_crc_finish(png_ptr, length);
943
944#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
945      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
946      {
947         if (chunk_name == png_IDAT)
948         {
949            if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
950               png_benign_error(png_ptr, "Too many IDATs found");
951         }
952         png_handle_unknown(png_ptr, info_ptr, length, keep);
953         if (chunk_name == png_PLTE)
954            png_ptr->mode |= PNG_HAVE_PLTE;
955      }
956#endif
957
958      else if (chunk_name == png_IDAT)
959      {
960         /* Zero length IDATs are legal after the last IDAT has been
961          * read, but not after other chunks have been read.
962          */
963         if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
964            png_benign_error(png_ptr, "Too many IDATs found");
965
966         png_crc_finish(png_ptr, length);
967      }
968      else if (chunk_name == png_PLTE)
969         png_handle_PLTE(png_ptr, info_ptr, length);
970
971#ifdef PNG_READ_bKGD_SUPPORTED
972      else if (chunk_name == png_bKGD)
973         png_handle_bKGD(png_ptr, info_ptr, length);
974#endif
975
976#ifdef PNG_READ_cHRM_SUPPORTED
977      else if (chunk_name == png_cHRM)
978         png_handle_cHRM(png_ptr, info_ptr, length);
979#endif
980
981#ifdef PNG_READ_gAMA_SUPPORTED
982      else if (chunk_name == png_gAMA)
983         png_handle_gAMA(png_ptr, info_ptr, length);
984#endif
985
986#ifdef PNG_READ_hIST_SUPPORTED
987      else if (chunk_name == png_hIST)
988         png_handle_hIST(png_ptr, info_ptr, length);
989#endif
990
991#ifdef PNG_READ_oFFs_SUPPORTED
992      else if (chunk_name == png_oFFs)
993         png_handle_oFFs(png_ptr, info_ptr, length);
994#endif
995
996#ifdef PNG_READ_pCAL_SUPPORTED
997      else if (chunk_name == png_pCAL)
998         png_handle_pCAL(png_ptr, info_ptr, length);
999#endif
1000
1001#ifdef PNG_READ_sCAL_SUPPORTED
1002      else if (chunk_name == png_sCAL)
1003         png_handle_sCAL(png_ptr, info_ptr, length);
1004#endif
1005
1006#ifdef PNG_READ_pHYs_SUPPORTED
1007      else if (chunk_name == png_pHYs)
1008         png_handle_pHYs(png_ptr, info_ptr, length);
1009#endif
1010
1011#ifdef PNG_READ_sBIT_SUPPORTED
1012      else if (chunk_name == png_sBIT)
1013         png_handle_sBIT(png_ptr, info_ptr, length);
1014#endif
1015
1016#ifdef PNG_READ_sRGB_SUPPORTED
1017      else if (chunk_name == png_sRGB)
1018         png_handle_sRGB(png_ptr, info_ptr, length);
1019#endif
1020
1021#ifdef PNG_READ_iCCP_SUPPORTED
1022      else if (chunk_name == png_iCCP)
1023         png_handle_iCCP(png_ptr, info_ptr, length);
1024#endif
1025
1026#ifdef PNG_READ_sPLT_SUPPORTED
1027      else if (chunk_name == png_sPLT)
1028         png_handle_sPLT(png_ptr, info_ptr, length);
1029#endif
1030
1031#ifdef PNG_READ_tEXt_SUPPORTED
1032      else if (chunk_name == png_tEXt)
1033         png_handle_tEXt(png_ptr, info_ptr, length);
1034#endif
1035
1036#ifdef PNG_READ_tIME_SUPPORTED
1037      else if (chunk_name == png_tIME)
1038         png_handle_tIME(png_ptr, info_ptr, length);
1039#endif
1040
1041#ifdef PNG_READ_tRNS_SUPPORTED
1042      else if (chunk_name == png_tRNS)
1043         png_handle_tRNS(png_ptr, info_ptr, length);
1044#endif
1045
1046#ifdef PNG_READ_zTXt_SUPPORTED
1047      else if (chunk_name == png_zTXt)
1048         png_handle_zTXt(png_ptr, info_ptr, length);
1049#endif
1050
1051#ifdef PNG_READ_iTXt_SUPPORTED
1052      else if (chunk_name == png_iTXt)
1053         png_handle_iTXt(png_ptr, info_ptr, length);
1054#endif
1055
1056      else
1057         png_handle_unknown(png_ptr, info_ptr, length,
1058            PNG_HANDLE_CHUNK_AS_DEFAULT);
1059   } while (!(png_ptr->mode & PNG_HAVE_IEND));
1060}
1061#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1062
1063/* Free all memory used in the read struct */
1064static void
1065png_read_destroy(png_structrp png_ptr)
1066{
1067   png_debug(1, "in png_read_destroy");
1068
1069#ifdef PNG_READ_GAMMA_SUPPORTED
1070   png_destroy_gamma_table(png_ptr);
1071#endif
1072
1073   png_free(png_ptr, png_ptr->big_row_buf);
1074   png_free(png_ptr, png_ptr->big_prev_row);
1075   png_free(png_ptr, png_ptr->read_buffer);
1076
1077#ifdef PNG_READ_QUANTIZE_SUPPORTED
1078   png_free(png_ptr, png_ptr->palette_lookup);
1079   png_free(png_ptr, png_ptr->quantize_index);
1080#endif
1081
1082   if (png_ptr->free_me & PNG_FREE_PLTE)
1083      png_zfree(png_ptr, png_ptr->palette);
1084   png_ptr->free_me &= ~PNG_FREE_PLTE;
1085
1086#if defined(PNG_tRNS_SUPPORTED) || \
1087    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1088   if (png_ptr->free_me & PNG_FREE_TRNS)
1089      png_free(png_ptr, png_ptr->trans_alpha);
1090   png_ptr->free_me &= ~PNG_FREE_TRNS;
1091#endif
1092
1093   inflateEnd(&png_ptr->zstream);
1094
1095#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1096   png_free(png_ptr, png_ptr->save_buffer);
1097#endif
1098
1099#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) &&\
1100   defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1101   png_free(png_ptr, png_ptr->unknown_chunk.data);
1102#endif
1103
1104#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
1105   png_free(png_ptr, png_ptr->chunk_list);
1106#endif
1107
1108#ifdef PNG_INDEX_SUPPORTED
1109   if (png_ptr->index) {
1110      unsigned int i, p;
1111      png_indexp index = png_ptr->index;
1112      for (p = 0; p < 7; p++) {
1113         for (i = 0; i < index->size[p]; i++) {
1114            inflateEnd(index->pass_line_index[p][i]->z_state);
1115            png_free(png_ptr, index->pass_line_index[p][i]->z_state);
1116            png_free(png_ptr, index->pass_line_index[p][i]->prev_row);
1117            png_free(png_ptr, index->pass_line_index[p][i]);
1118         }
1119         if (index->size[p] != 0) {
1120            png_free(png_ptr, index->pass_line_index[p]);
1121         }
1122      }
1123      png_free(png_ptr, index);
1124   }
1125#endif
1126
1127   /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
1128    * callbacks are still set at this point.  They are required to complete the
1129    * destruction of the png_struct itself.
1130    */
1131}
1132
1133/* Free all memory used by the read */
1134void PNGAPI
1135png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
1136    png_infopp end_info_ptr_ptr)
1137{
1138   png_structrp png_ptr = NULL;
1139
1140   png_debug(1, "in png_destroy_read_struct");
1141
1142   if (png_ptr_ptr != NULL)
1143      png_ptr = *png_ptr_ptr;
1144
1145   if (png_ptr == NULL)
1146      return;
1147
1148   /* libpng 1.6.0: use the API to destroy info structs to ensure consistent
1149    * behavior.  Prior to 1.6.0 libpng did extra 'info' destruction in this API.
1150    * The extra was, apparently, unnecessary yet this hides memory leak bugs.
1151    */
1152   png_destroy_info_struct(png_ptr, end_info_ptr_ptr);
1153   png_destroy_info_struct(png_ptr, info_ptr_ptr);
1154
1155   *png_ptr_ptr = NULL;
1156   png_read_destroy(png_ptr);
1157   png_destroy_png_struct(png_ptr);
1158}
1159
1160void PNGAPI
1161png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
1162{
1163   if (png_ptr == NULL)
1164      return;
1165
1166   png_ptr->read_row_fn = read_row_fn;
1167}
1168
1169
1170#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1171#ifdef PNG_INFO_IMAGE_SUPPORTED
1172void PNGAPI
1173png_read_png(png_structrp png_ptr, png_inforp info_ptr,
1174                           int transforms,
1175                           voidp params)
1176{
1177   if (png_ptr == NULL || info_ptr == NULL)
1178      return;
1179
1180   /* png_read_info() gives us all of the information from the
1181    * PNG file before the first IDAT (image data chunk).
1182    */
1183   png_read_info(png_ptr, info_ptr);
1184   if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
1185      png_error(png_ptr, "Image is too high to process with png_read_png()");
1186
1187   /* -------------- image transformations start here ------------------- */
1188   /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
1189    * is not implemented.  This will only happen in de-configured (non-default)
1190    * libpng builds.  The results can be unexpected - png_read_png may return
1191    * short or mal-formed rows because the transform is skipped.
1192    */
1193
1194   /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
1195    */
1196   if (transforms & PNG_TRANSFORM_SCALE_16)
1197     /* Added at libpng-1.5.4. "strip_16" produces the same result that it
1198      * did in earlier versions, while "scale_16" is now more accurate.
1199      */
1200#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1201      png_set_scale_16(png_ptr);
1202#else
1203      png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
1204#endif
1205
1206   /* If both SCALE and STRIP are required pngrtran will effectively cancel the
1207    * latter by doing SCALE first.  This is ok and allows apps not to check for
1208    * which is supported to get the right answer.
1209    */
1210   if (transforms & PNG_TRANSFORM_STRIP_16)
1211#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1212      png_set_strip_16(png_ptr);
1213#else
1214      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
1215#endif
1216
1217   /* Strip alpha bytes from the input data without combining with
1218    * the background (not recommended).
1219    */
1220   if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
1221#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1222      png_set_strip_alpha(png_ptr);
1223#else
1224      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
1225#endif
1226
1227   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1228    * byte into separate bytes (useful for paletted and grayscale images).
1229    */
1230   if (transforms & PNG_TRANSFORM_PACKING)
1231#ifdef PNG_READ_PACK_SUPPORTED
1232      png_set_packing(png_ptr);
1233#else
1234      png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
1235#endif
1236
1237   /* Change the order of packed pixels to least significant bit first
1238    * (not useful if you are using png_set_packing).
1239    */
1240   if (transforms & PNG_TRANSFORM_PACKSWAP)
1241#ifdef PNG_READ_PACKSWAP_SUPPORTED
1242      png_set_packswap(png_ptr);
1243#else
1244      png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
1245#endif
1246
1247   /* Expand paletted colors into true RGB triplets
1248    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
1249    * Expand paletted or RGB images with transparency to full alpha
1250    * channels so the data will be available as RGBA quartets.
1251    */
1252   if (transforms & PNG_TRANSFORM_EXPAND)
1253#ifdef PNG_READ_EXPAND_SUPPORTED
1254      png_set_expand(png_ptr);
1255#else
1256      png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
1257#endif
1258
1259   /* We don't handle background color or gamma transformation or quantizing.
1260    */
1261
1262   /* Invert monochrome files to have 0 as white and 1 as black
1263    */
1264   if (transforms & PNG_TRANSFORM_INVERT_MONO)
1265#ifdef PNG_READ_INVERT_SUPPORTED
1266      png_set_invert_mono(png_ptr);
1267#else
1268      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
1269#endif
1270
1271   /* If you want to shift the pixel values from the range [0,255] or
1272    * [0,65535] to the original [0,7] or [0,31], or whatever range the
1273    * colors were originally in:
1274    */
1275   if (transforms & PNG_TRANSFORM_SHIFT)
1276#ifdef PNG_READ_SHIFT_SUPPORTED
1277      if (info_ptr->valid & PNG_INFO_sBIT)
1278         png_set_shift(png_ptr, &info_ptr->sig_bit);
1279#else
1280      png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
1281#endif
1282
1283   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
1284   if (transforms & PNG_TRANSFORM_BGR)
1285#ifdef PNG_READ_BGR_SUPPORTED
1286      png_set_bgr(png_ptr);
1287#else
1288      png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
1289#endif
1290
1291   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
1292   if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
1293#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1294      png_set_swap_alpha(png_ptr);
1295#else
1296      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
1297#endif
1298
1299   /* Swap bytes of 16-bit files to least significant byte first */
1300   if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1301#ifdef PNG_READ_SWAP_SUPPORTED
1302      png_set_swap(png_ptr);
1303#else
1304      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
1305#endif
1306
1307/* Added at libpng-1.2.41 */
1308   /* Invert the alpha channel from opacity to transparency */
1309   if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1310#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1311      png_set_invert_alpha(png_ptr);
1312#else
1313      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1314#endif
1315
1316/* Added at libpng-1.2.41 */
1317   /* Expand grayscale image to RGB */
1318   if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
1319#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1320      png_set_gray_to_rgb(png_ptr);
1321#else
1322      png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
1323#endif
1324
1325/* Added at libpng-1.5.4 */
1326   if (transforms & PNG_TRANSFORM_EXPAND_16)
1327#ifdef PNG_READ_EXPAND_16_SUPPORTED
1328      png_set_expand_16(png_ptr);
1329#else
1330      png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
1331#endif
1332
1333   /* We don't handle adding filler bytes */
1334
1335   /* We use png_read_image and rely on that for interlace handling, but we also
1336    * call png_read_update_info therefore must turn on interlace handling now:
1337    */
1338   (void)png_set_interlace_handling(png_ptr);
1339
1340   /* Optional call to gamma correct and add the background to the palette
1341    * and update info structure.  REQUIRED if you are expecting libpng to
1342    * update the palette for you (i.e., you selected such a transform above).
1343    */
1344   png_read_update_info(png_ptr, info_ptr);
1345
1346   /* -------------- image transformations end here ------------------- */
1347
1348   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1349   if (info_ptr->row_pointers == NULL)
1350   {
1351      png_uint_32 iptr;
1352
1353      info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
1354          info_ptr->height * (sizeof (png_bytep))));
1355
1356      for (iptr=0; iptr<info_ptr->height; iptr++)
1357         info_ptr->row_pointers[iptr] = NULL;
1358
1359      info_ptr->free_me |= PNG_FREE_ROWS;
1360
1361      for (iptr = 0; iptr < info_ptr->height; iptr++)
1362         info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
1363            png_malloc(png_ptr, info_ptr->rowbytes));
1364   }
1365
1366   png_read_image(png_ptr, info_ptr->row_pointers);
1367   info_ptr->valid |= PNG_INFO_IDAT;
1368
1369   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1370   png_read_end(png_ptr, info_ptr);
1371
1372   PNG_UNUSED(params)
1373}
1374#endif /* PNG_INFO_IMAGE_SUPPORTED */
1375#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1376
1377#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
1378/* SIMPLIFIED READ
1379 *
1380 * This code currently relies on the sequential reader, though it could easily
1381 * be made to work with the progressive one.
1382 */
1383/* Arguments to png_image_finish_read: */
1384
1385/* Encoding of PNG data (used by the color-map code) */
1386#  define P_NOTSET  0 /* File encoding not yet known */
1387#  define P_sRGB    1 /* 8-bit encoded to sRGB gamma */
1388#  define P_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
1389#  define P_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */
1390#  define P_LINEAR8 4 /* 8-bit linear: only from a file value */
1391
1392/* Color-map processing: after libpng has run on the PNG image further
1393 * processing may be needed to conver the data to color-map indicies.
1394 */
1395#define PNG_CMAP_NONE      0
1396#define PNG_CMAP_GA        1 /* Process GA data to a color-map with alpha */
1397#define PNG_CMAP_TRANS     2 /* Process GA data to a background index */
1398#define PNG_CMAP_RGB       3 /* Process RGB data */
1399#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */
1400
1401/* The following document where the background is for each processing case. */
1402#define PNG_CMAP_NONE_BACKGROUND      256
1403#define PNG_CMAP_GA_BACKGROUND        231
1404#define PNG_CMAP_TRANS_BACKGROUND     254
1405#define PNG_CMAP_RGB_BACKGROUND       256
1406#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216
1407
1408typedef struct
1409{
1410   /* Arguments: */
1411   png_imagep image;
1412   png_voidp  buffer;
1413   png_int_32 row_stride;
1414   png_voidp  colormap;
1415   png_const_colorp background;
1416   /* Local variables: */
1417   png_voidp       local_row;
1418   png_voidp       first_row;
1419   ptrdiff_t       row_bytes;           /* step between rows */
1420   int             file_encoding;       /* E_ values above */
1421   png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */
1422   int             colormap_processing; /* PNG_CMAP_ values above */
1423} png_image_read_control;
1424
1425/* Do all the *safe* initialization - 'safe' means that png_error won't be
1426 * called, so setting up the jmp_buf is not required.  This means that anything
1427 * called from here must *not* call png_malloc - it has to call png_malloc_warn
1428 * instead so that control is returned safely back to this routine.
1429 */
1430static int
1431png_image_read_init(png_imagep image)
1432{
1433   if (image->opaque == NULL)
1434   {
1435      png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,
1436          png_safe_error, png_safe_warning);
1437
1438      /* And set the rest of the structure to NULL to ensure that the various
1439       * fields are consistent.
1440       */
1441      memset(image, 0, (sizeof *image));
1442      image->version = PNG_IMAGE_VERSION;
1443
1444      if (png_ptr != NULL)
1445      {
1446         png_infop info_ptr = png_create_info_struct(png_ptr);
1447
1448         if (info_ptr != NULL)
1449         {
1450            png_controlp control = png_voidcast(png_controlp,
1451               png_malloc_warn(png_ptr, (sizeof *control)));
1452
1453            if (control != NULL)
1454            {
1455               memset(control, 0, (sizeof *control));
1456
1457               control->png_ptr = png_ptr;
1458               control->info_ptr = info_ptr;
1459               control->for_write = 0;
1460
1461               image->opaque = control;
1462               return 1;
1463            }
1464
1465            /* Error clean up */
1466            png_destroy_info_struct(png_ptr, &info_ptr);
1467         }
1468
1469         png_destroy_read_struct(&png_ptr, NULL, NULL);
1470      }
1471
1472      return png_image_error(image, "png_image_read: out of memory");
1473   }
1474
1475   return png_image_error(image, "png_image_read: opaque pointer not NULL");
1476}
1477
1478/* Utility to find the base format of a PNG file from a png_struct. */
1479static png_uint_32
1480png_image_format(png_structrp png_ptr)
1481{
1482   png_uint_32 format = 0;
1483
1484   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1485      format |= PNG_FORMAT_FLAG_COLOR;
1486
1487   if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)
1488      format |= PNG_FORMAT_FLAG_ALPHA;
1489
1490   /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
1491    * sets the png_struct fields; that's all we are interested in here.  The
1492    * precise interaction with an app call to png_set_tRNS and PNG file reading
1493    * is unclear.
1494    */
1495   else if (png_ptr->num_trans > 0)
1496      format |= PNG_FORMAT_FLAG_ALPHA;
1497
1498   if (png_ptr->bit_depth == 16)
1499      format |= PNG_FORMAT_FLAG_LINEAR;
1500
1501   if (png_ptr->color_type & PNG_COLOR_MASK_PALETTE)
1502      format |= PNG_FORMAT_FLAG_COLORMAP;
1503
1504   return format;
1505}
1506
1507/* Is the given gamma significantly different from sRGB?  The test is the same
1508 * one used in pngrtran.c when deciding whether to do gamma correction.  The
1509 * arithmetic optimizes the division by using the fact that the inverse of the
1510 * file sRGB gamma is 2.2
1511 */
1512static int
1513png_gamma_not_sRGB(png_fixed_point g)
1514{
1515   if (g < PNG_FP_1)
1516   {
1517      /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
1518      if (g == 0)
1519         return 0;
1520
1521      return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
1522   }
1523
1524   return 1;
1525}
1526
1527/* Do the main body of a 'png_image_begin_read' function; read the PNG file
1528 * header and fill in all the information.  This is executed in a safe context,
1529 * unlike the init routine above.
1530 */
1531static int
1532png_image_read_header(png_voidp argument)
1533{
1534   png_imagep image = png_voidcast(png_imagep, argument);
1535   png_structrp png_ptr = image->opaque->png_ptr;
1536   png_inforp info_ptr = image->opaque->info_ptr;
1537
1538   png_set_benign_errors(png_ptr, 1/*warn*/);
1539   png_read_info(png_ptr, info_ptr);
1540
1541   /* Do this the fast way; just read directly out of png_struct. */
1542   image->width = png_ptr->width;
1543   image->height = png_ptr->height;
1544
1545   {
1546      png_uint_32 format = png_image_format(png_ptr);
1547
1548      image->format = format;
1549
1550#ifdef PNG_COLORSPACE_SUPPORTED
1551      /* Does the colorspace match sRGB?  If there is no color endpoint
1552       * (colorant) information assume yes, otherwise require the
1553       * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set.  If the
1554       * colorspace has been determined to be invalid ignore it.
1555       */
1556      if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
1557         & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
1558            PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
1559         image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
1560#endif
1561   }
1562
1563   /* We need the maximum number of entries regardless of the format the
1564    * application sets here.
1565    */
1566   {
1567      png_uint_32 cmap_entries;
1568
1569      switch (png_ptr->color_type)
1570      {
1571         case PNG_COLOR_TYPE_GRAY:
1572            cmap_entries = 1U << png_ptr->bit_depth;
1573            break;
1574
1575         case PNG_COLOR_TYPE_PALETTE:
1576            cmap_entries = png_ptr->num_palette;
1577            break;
1578
1579         default:
1580            cmap_entries = 256;
1581            break;
1582      }
1583
1584      if (cmap_entries > 256)
1585         cmap_entries = 256;
1586
1587      image->colormap_entries = cmap_entries;
1588   }
1589
1590   return 1;
1591}
1592
1593#ifdef PNG_STDIO_SUPPORTED
1594int PNGAPI
1595png_image_begin_read_from_stdio(png_imagep image, FILE* file)
1596{
1597   if (image != NULL && image->version == PNG_IMAGE_VERSION)
1598   {
1599      if (file != NULL)
1600      {
1601         if (png_image_read_init(image))
1602         {
1603            /* This is slightly evil, but png_init_io doesn't do anything other
1604             * than this and we haven't changed the standard IO functions so
1605             * this saves a 'safe' function.
1606             */
1607            image->opaque->png_ptr->io_ptr = file;
1608            return png_safe_execute(image, png_image_read_header, image);
1609         }
1610      }
1611
1612      else
1613         return png_image_error(image,
1614            "png_image_begin_read_from_stdio: invalid argument");
1615   }
1616
1617   else if (image != NULL)
1618      return png_image_error(image,
1619         "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
1620
1621   return 0;
1622}
1623
1624int PNGAPI
1625png_image_begin_read_from_file(png_imagep image, const char *file_name)
1626{
1627   if (image != NULL && image->version == PNG_IMAGE_VERSION)
1628   {
1629      if (file_name != NULL)
1630      {
1631         FILE *fp = fopen(file_name, "rb");
1632
1633         if (fp != NULL)
1634         {
1635            if (png_image_read_init(image))
1636            {
1637               image->opaque->png_ptr->io_ptr = fp;
1638               image->opaque->owned_file = 1;
1639               return png_safe_execute(image, png_image_read_header, image);
1640            }
1641
1642            /* Clean up: just the opened file. */
1643            (void)fclose(fp);
1644         }
1645
1646         else
1647            return png_image_error(image, strerror(errno));
1648      }
1649
1650      else
1651         return png_image_error(image,
1652            "png_image_begin_read_from_file: invalid argument");
1653   }
1654
1655   else if (image != NULL)
1656      return png_image_error(image,
1657         "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
1658
1659   return 0;
1660}
1661#endif /* PNG_STDIO_SUPPORTED */
1662
1663static void PNGCBAPI
1664png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
1665{
1666   if (png_ptr != NULL)
1667   {
1668      png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
1669      if (image != NULL)
1670      {
1671         png_controlp cp = image->opaque;
1672         if (cp != NULL)
1673         {
1674            png_const_bytep memory = cp->memory;
1675            png_size_t size = cp->size;
1676
1677            if (memory != NULL && size >= need)
1678            {
1679               memcpy(out, memory, need);
1680               cp->memory = memory + need;
1681               cp->size = size - need;
1682               return;
1683            }
1684
1685            png_error(png_ptr, "read beyond end of data");
1686         }
1687      }
1688
1689      png_error(png_ptr, "invalid memory read");
1690   }
1691}
1692
1693int PNGAPI png_image_begin_read_from_memory(png_imagep image,
1694   png_const_voidp memory, png_size_t size)
1695{
1696   if (image != NULL && image->version == PNG_IMAGE_VERSION)
1697   {
1698      if (memory != NULL && size > 0)
1699      {
1700         if (png_image_read_init(image))
1701         {
1702            /* Now set the IO functions to read from the memory buffer and
1703             * store it into io_ptr.  Again do this in-place to avoid calling a
1704             * libpng function that requires error handling.
1705             */
1706            image->opaque->memory = png_voidcast(png_const_bytep, memory);
1707            image->opaque->size = size;
1708            image->opaque->png_ptr->io_ptr = image;
1709            image->opaque->png_ptr->read_data_fn = png_image_memory_read;
1710
1711            return png_safe_execute(image, png_image_read_header, image);
1712         }
1713      }
1714
1715      else
1716         return png_image_error(image,
1717            "png_image_begin_read_from_memory: invalid argument");
1718   }
1719
1720   else if (image != NULL)
1721      return png_image_error(image,
1722         "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
1723
1724   return 0;
1725}
1726
1727/* Utility function to skip chunks that are not used by the simplified image
1728 * read functions and an appropriate macro to call it.
1729 */
1730#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1731static void
1732png_image_skip_unused_chunks(png_structrp png_ptr)
1733{
1734   /* Prepare the reader to ignore all recognized chunks whose data will not
1735    * be used, i.e., all chunks recognized by libpng except for those
1736    * involved in basic image reading:
1737    *
1738    *    IHDR, PLTE, IDAT, IEND
1739    *
1740    * Or image data handling:
1741    *
1742    *    tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
1743    *
1744    * This provides a small performance improvement and eliminates any
1745    * potential vulnerability to security problems in the unused chunks.
1746    *
1747    * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
1748    * too.  This allows the simplified API to be compiled without iCCP support,
1749    * however if the support is there the chunk is still checked to detect
1750    * errors (which are unfortunately quite common.)
1751    */
1752   {
1753         static PNG_CONST png_byte chunks_to_process[] = {
1754            98,  75,  71,  68, '\0',  /* bKGD */
1755            99,  72,  82,  77, '\0',  /* cHRM */
1756           103,  65,  77,  65, '\0',  /* gAMA */
1757#        ifdef PNG_READ_iCCP_SUPPORTED
1758           105,  67,  67,  80, '\0',  /* iCCP */
1759#        endif
1760           115,  66,  73,  84, '\0',  /* sBIT */
1761           115,  82,  71,  66, '\0',  /* sRGB */
1762           };
1763
1764       /* Ignore unknown chunks and all other chunks except for the
1765        * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
1766        */
1767       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
1768         NULL, -1);
1769
1770       /* But do not ignore image data handling chunks */
1771       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
1772         chunks_to_process, (sizeof chunks_to_process)/5);
1773    }
1774}
1775
1776#  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
1777#else
1778#  define PNG_SKIP_CHUNKS(p) ((void)0)
1779#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */
1780
1781/* The following macro gives the exact rounded answer for all values in the
1782 * range 0..255 (it actually divides by 51.2, but the rounding still generates
1783 * the correct numbers 0..5
1784 */
1785#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)
1786
1787/* Utility functions to make particular color-maps */
1788static void
1789set_file_encoding(png_image_read_control *display)
1790{
1791   png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
1792   if (png_gamma_significant(g))
1793   {
1794      if (png_gamma_not_sRGB(g))
1795      {
1796         display->file_encoding = P_FILE;
1797         display->gamma_to_linear = png_reciprocal(g);
1798      }
1799
1800      else
1801         display->file_encoding = P_sRGB;
1802   }
1803
1804   else
1805      display->file_encoding = P_LINEAR8;
1806}
1807
1808static unsigned int
1809decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
1810{
1811   if (encoding == P_FILE) /* double check */
1812      encoding = display->file_encoding;
1813
1814   if (encoding == P_NOTSET) /* must be the file encoding */
1815   {
1816      set_file_encoding(display);
1817      encoding = display->file_encoding;
1818   }
1819
1820   switch (encoding)
1821   {
1822      case P_FILE:
1823         value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
1824         break;
1825
1826      case P_sRGB:
1827         value = png_sRGB_table[value];
1828         break;
1829
1830      case P_LINEAR:
1831         break;
1832
1833      case P_LINEAR8:
1834         value *= 257;
1835         break;
1836
1837      default:
1838         png_error(display->image->opaque->png_ptr,
1839            "unexpected encoding (internal error)");
1840         break;
1841   }
1842
1843   return value;
1844}
1845
1846static png_uint_32
1847png_colormap_compose(png_image_read_control *display,
1848   png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
1849   png_uint_32 background, int encoding)
1850{
1851   /* The file value is composed on the background, the background has the given
1852    * encoding and so does the result, the file is encoded with P_FILE and the
1853    * file and alpha are 8-bit values.  The (output) encoding will always be
1854    * P_LINEAR or P_sRGB.
1855    */
1856   png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
1857   png_uint_32 b = decode_gamma(display, background, encoding);
1858
1859   /* The alpha is always an 8-bit value (it comes from the palette), the value
1860    * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
1861    */
1862   f = f * alpha + b * (255-alpha);
1863
1864   if (encoding == P_LINEAR)
1865   {
1866      /* Scale to 65535; divide by 255, approximately (in fact this is extremely
1867       * accurate, it divides by 255.00000005937181414556, with no overflow.)
1868       */
1869      f *= 257; /* Now scaled by 65535 */
1870      f += f >> 16;
1871      f = (f+32768) >> 16;
1872   }
1873
1874   else /* P_sRGB */
1875      f = PNG_sRGB_FROM_LINEAR(f);
1876
1877   return f;
1878}
1879
1880/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
1881 * be 8-bit.
1882 */
1883static void
1884png_create_colormap_entry(png_image_read_control *display,
1885   png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
1886   png_uint_32 alpha, int encoding)
1887{
1888   png_imagep image = display->image;
1889   const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) ?
1890      P_LINEAR : P_sRGB;
1891   const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
1892      (red != green || green != blue);
1893
1894   if (ip > 255)
1895      png_error(image->opaque->png_ptr, "color-map index out of range");
1896
1897   /* Update the cache with whether the file gamma is significantly different
1898    * from sRGB.
1899    */
1900   if (encoding == P_FILE)
1901   {
1902      if (display->file_encoding == P_NOTSET)
1903         set_file_encoding(display);
1904
1905      /* Note that the cached value may be P_FILE too, but if it is then the
1906       * gamma_to_linear member has been set.
1907       */
1908      encoding = display->file_encoding;
1909   }
1910
1911   if (encoding == P_FILE)
1912   {
1913      png_fixed_point g = display->gamma_to_linear;
1914
1915      red = png_gamma_16bit_correct(red*257, g);
1916      green = png_gamma_16bit_correct(green*257, g);
1917      blue = png_gamma_16bit_correct(blue*257, g);
1918
1919      if (convert_to_Y || output_encoding == P_LINEAR)
1920      {
1921         alpha *= 257;
1922         encoding = P_LINEAR;
1923      }
1924
1925      else
1926      {
1927         red = PNG_sRGB_FROM_LINEAR(red * 255);
1928         green = PNG_sRGB_FROM_LINEAR(green * 255);
1929         blue = PNG_sRGB_FROM_LINEAR(blue * 255);
1930         encoding = P_sRGB;
1931      }
1932   }
1933
1934   else if (encoding == P_LINEAR8)
1935   {
1936      /* This encoding occurs quite frequently in test cases because PngSuite
1937       * includes a gAMA 1.0 chunk with most images.
1938       */
1939      red *= 257;
1940      green *= 257;
1941      blue *= 257;
1942      alpha *= 257;
1943      encoding = P_LINEAR;
1944   }
1945
1946   else if (encoding == P_sRGB && (convert_to_Y || output_encoding == P_LINEAR))
1947   {
1948      /* The values are 8-bit sRGB values, but must be converted to 16-bit
1949       * linear.
1950       */
1951      red = png_sRGB_table[red];
1952      green = png_sRGB_table[green];
1953      blue = png_sRGB_table[blue];
1954      alpha *= 257;
1955      encoding = P_LINEAR;
1956   }
1957
1958   /* This is set if the color isn't gray but the output is. */
1959   if (encoding == P_LINEAR)
1960   {
1961      if (convert_to_Y)
1962      {
1963         /* NOTE: these values are copied from png_do_rgb_to_gray */
1964         png_uint_32 y = (png_uint_32)6968 * red  + (png_uint_32)23434 * green +
1965            (png_uint_32)2366 * blue;
1966
1967         if (output_encoding == P_LINEAR)
1968            y = (y + 16384) >> 15;
1969
1970         else
1971         {
1972            /* y is scaled by 32768, we need it scaled by 255: */
1973            y = (y + 128) >> 8;
1974            y *= 255;
1975            y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
1976            encoding = P_sRGB;
1977         }
1978
1979         blue = red = green = y;
1980      }
1981
1982      else if (output_encoding == P_sRGB)
1983      {
1984         red = PNG_sRGB_FROM_LINEAR(red * 255);
1985         green = PNG_sRGB_FROM_LINEAR(green * 255);
1986         blue = PNG_sRGB_FROM_LINEAR(blue * 255);
1987         alpha = PNG_DIV257(alpha);
1988         encoding = P_sRGB;
1989      }
1990   }
1991
1992   if (encoding != output_encoding)
1993      png_error(image->opaque->png_ptr, "bad encoding (internal error)");
1994
1995   /* Store the value. */
1996   {
1997#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
1998         const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
1999            (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
2000#     else
2001#        define afirst 0
2002#     endif
2003#     ifdef PNG_FORMAT_BGR_SUPPORTED
2004         const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
2005#     else
2006#        define bgr 0
2007#     endif
2008
2009      if (output_encoding == P_LINEAR)
2010      {
2011         png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
2012
2013         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
2014
2015         /* The linear 16-bit values must be pre-multiplied by the alpha channel
2016          * value, if less than 65535 (this is, effectively, composite on black
2017          * if the alpha channel is removed.)
2018          */
2019         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
2020         {
2021            case 4:
2022               entry[afirst ? 0 : 3] = (png_uint_16)alpha;
2023               /* FALL THROUGH */
2024
2025            case 3:
2026               if (alpha < 65535)
2027               {
2028                  if (alpha > 0)
2029                  {
2030                     blue = (blue * alpha + 32767U)/65535U;
2031                     green = (green * alpha + 32767U)/65535U;
2032                     red = (red * alpha + 32767U)/65535U;
2033                  }
2034
2035                  else
2036                     red = green = blue = 0;
2037               }
2038               entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
2039               entry[afirst + 1] = (png_uint_16)green;
2040               entry[afirst + bgr] = (png_uint_16)red;
2041               break;
2042
2043            case 2:
2044               entry[1 ^ afirst] = (png_uint_16)alpha;
2045               /* FALL THROUGH */
2046
2047            case 1:
2048               if (alpha < 65535)
2049               {
2050                  if (alpha > 0)
2051                     green = (green * alpha + 32767U)/65535U;
2052
2053                  else
2054                     green = 0;
2055               }
2056               entry[afirst] = (png_uint_16)green;
2057               break;
2058
2059            default:
2060               break;
2061         }
2062      }
2063
2064      else /* output encoding is P_sRGB */
2065      {
2066         png_bytep entry = png_voidcast(png_bytep, display->colormap);
2067
2068         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
2069
2070         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
2071         {
2072            case 4:
2073               entry[afirst ? 0 : 3] = (png_byte)alpha;
2074            case 3:
2075               entry[afirst + (2 ^ bgr)] = (png_byte)blue;
2076               entry[afirst + 1] = (png_byte)green;
2077               entry[afirst + bgr] = (png_byte)red;
2078               break;
2079
2080            case 2:
2081               entry[1 ^ afirst] = (png_byte)alpha;
2082            case 1:
2083               entry[afirst] = (png_byte)green;
2084               break;
2085
2086            default:
2087               break;
2088         }
2089      }
2090
2091#     ifdef afirst
2092#        undef afirst
2093#     endif
2094#     ifdef bgr
2095#        undef bgr
2096#     endif
2097   }
2098}
2099
2100static int
2101make_gray_file_colormap(png_image_read_control *display)
2102{
2103   unsigned int i;
2104
2105   for (i=0; i<256; ++i)
2106      png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
2107
2108   return i;
2109}
2110
2111static int
2112make_gray_colormap(png_image_read_control *display)
2113{
2114   unsigned int i;
2115
2116   for (i=0; i<256; ++i)
2117      png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
2118
2119   return i;
2120}
2121#define PNG_GRAY_COLORMAP_ENTRIES 256
2122
2123static int
2124make_ga_colormap(png_image_read_control *display)
2125{
2126   unsigned int i, a;
2127
2128   /* Alpha is retained, the output will be a color-map with entries
2129    * selected by six levels of alpha.  One transparent entry, 6 gray
2130    * levels for all the intermediate alpha values, leaving 230 entries
2131    * for the opaque grays.  The color-map entries are the six values
2132    * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
2133    * relevant entry.
2134    *
2135    * if (alpha > 229) // opaque
2136    * {
2137    *    // The 231 entries are selected to make the math below work:
2138    *    base = 0;
2139    *    entry = (231 * gray + 128) >> 8;
2140    * }
2141    * else if (alpha < 26) // transparent
2142    * {
2143    *    base = 231;
2144    *    entry = 0;
2145    * }
2146    * else // partially opaque
2147    * {
2148    *    base = 226 + 6 * PNG_DIV51(alpha);
2149    *    entry = PNG_DIV51(gray);
2150    * }
2151    */
2152   i = 0;
2153   while (i < 231)
2154   {
2155      unsigned int gray = (i * 256 + 115) / 231;
2156      png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
2157   }
2158
2159   /* 255 is used here for the component values for consistency with the code
2160    * that undoes premultiplication in pngwrite.c.
2161    */
2162   png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
2163
2164   for (a=1; a<5; ++a)
2165   {
2166      unsigned int g;
2167
2168      for (g=0; g<6; ++g)
2169         png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
2170            P_sRGB);
2171   }
2172
2173   return i;
2174}
2175
2176#define PNG_GA_COLORMAP_ENTRIES 256
2177
2178static int
2179make_rgb_colormap(png_image_read_control *display)
2180{
2181   unsigned int i, r;
2182
2183   /* Build a 6x6x6 opaque RGB cube */
2184   for (i=r=0; r<6; ++r)
2185   {
2186      unsigned int g;
2187
2188      for (g=0; g<6; ++g)
2189      {
2190         unsigned int b;
2191
2192         for (b=0; b<6; ++b)
2193            png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
2194               P_sRGB);
2195      }
2196   }
2197
2198   return i;
2199}
2200
2201#define PNG_RGB_COLORMAP_ENTRIES 216
2202
2203/* Return a palette index to the above palette given three 8-bit sRGB values. */
2204#define PNG_RGB_INDEX(r,g,b) \
2205   ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
2206
2207static int
2208png_image_read_colormap(png_voidp argument)
2209{
2210   png_image_read_control *display =
2211      png_voidcast(png_image_read_control*, argument);
2212   const png_imagep image = display->image;
2213
2214   const png_structrp png_ptr = image->opaque->png_ptr;
2215   const png_uint_32 output_format = image->format;
2216   const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) ?
2217      P_LINEAR : P_sRGB;
2218
2219   unsigned int cmap_entries;
2220   unsigned int output_processing;        /* Output processing option */
2221   unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
2222
2223   /* Background information; the background color and the index of this color
2224    * in the color-map if it exists (else 256).
2225    */
2226   unsigned int background_index = 256;
2227   png_uint_32 back_r, back_g, back_b;
2228
2229   /* Flags to accumulate things that need to be done to the input. */
2230   int expand_tRNS = 0;
2231
2232   /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is
2233    * very difficult to do, the results look awful, and it is difficult to see
2234    * what possible use it is because the application can't control the
2235    * color-map.
2236    */
2237   if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
2238         png_ptr->num_trans > 0) /* alpha in input */ &&
2239      ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
2240   {
2241      if (output_encoding == P_LINEAR) /* compose on black */
2242         back_b = back_g = back_r = 0;
2243
2244      else if (display->background == NULL /* no way to remove it */)
2245         png_error(png_ptr,
2246            "a background color must be supplied to remove alpha/transparency");
2247
2248      /* Get a copy of the background color (this avoids repeating the checks
2249       * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
2250       * output format.
2251       */
2252      else
2253      {
2254         back_g = display->background->green;
2255         if (output_format & PNG_FORMAT_FLAG_COLOR)
2256         {
2257            back_r = display->background->red;
2258            back_b = display->background->blue;
2259         }
2260         else
2261            back_b = back_r = back_g;
2262      }
2263   }
2264
2265   else if (output_encoding == P_LINEAR)
2266      back_b = back_r = back_g = 65535;
2267
2268   else
2269      back_b = back_r = back_g = 255;
2270
2271   /* Default the input file gamma if required - this is necessary because
2272    * libpng assumes that if no gamma information is present the data is in the
2273    * output format, but the simplified API deduces the gamma from the input
2274    * format.
2275    */
2276   if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
2277   {
2278      /* Do this directly, not using the png_colorspace functions, to ensure
2279       * that it happens even if the colorspace is invalid (though probably if
2280       * it is the setting will be ignored)  Note that the same thing can be
2281       * achieved at the application interface with png_set_gAMA.
2282       */
2283      if (png_ptr->bit_depth == 16 &&
2284         (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
2285         png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
2286
2287      else
2288         png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
2289
2290      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
2291   }
2292
2293   /* Decide what to do based on the PNG color type of the input data.  The
2294    * utility function png_create_colormap_entry deals with most aspects of the
2295    * output transformations; this code works out how to produce bytes of
2296    * color-map entries from the original format.
2297    */
2298   switch (png_ptr->color_type)
2299   {
2300      case PNG_COLOR_TYPE_GRAY:
2301         if (png_ptr->bit_depth <= 8)
2302         {
2303            /* There at most 256 colors in the output, regardless of
2304             * transparency.
2305             */
2306            unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
2307
2308            cmap_entries = 1U << png_ptr->bit_depth;
2309            if (cmap_entries > image->colormap_entries)
2310               png_error(png_ptr, "gray[8] color-map: too few entries");
2311
2312            step = 255 / (cmap_entries - 1);
2313            output_processing = PNG_CMAP_NONE;
2314
2315            /* If there is a tRNS chunk then this either selects a transparent
2316             * value or, if the output has no alpha, the background color.
2317             */
2318            if (png_ptr->num_trans > 0)
2319            {
2320               trans = png_ptr->trans_color.gray;
2321
2322               if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
2323                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
2324            }
2325
2326            /* png_create_colormap_entry just takes an RGBA and writes the
2327             * corresponding color-map entry using the format from 'image',
2328             * including the required conversion to sRGB or linear as
2329             * appropriate.  The input values are always either sRGB (if the
2330             * gamma correction flag is 0) or 0..255 scaled file encoded values
2331             * (if the function must gamma correct them).
2332             */
2333            for (i=val=0; i<cmap_entries; ++i, val += step)
2334            {
2335               /* 'i' is a file value.  While this will result in duplicated
2336                * entries for 8-bit non-sRGB encoded files it is necessary to
2337                * have non-gamma corrected values to do tRNS handling.
2338                */
2339               if (i != trans)
2340                  png_create_colormap_entry(display, i, val, val, val, 255,
2341                     P_FILE/*8-bit with file gamma*/);
2342
2343               /* Else this entry is transparent.  The colors don't matter if
2344                * there is an alpha channel (back_alpha == 0), but it does no
2345                * harm to pass them in; the values are not set above so this
2346                * passes in white.
2347                *
2348                * NOTE: this preserves the full precision of the application
2349                * supplied background color when it is used.
2350                */
2351               else
2352                  png_create_colormap_entry(display, i, back_r, back_g, back_b,
2353                     back_alpha, output_encoding);
2354            }
2355
2356            /* We need libpng to preserve the original encoding. */
2357            data_encoding = P_FILE;
2358
2359            /* The rows from libpng, while technically gray values, are now also
2360             * color-map indicies; however, they may need to be expanded to 1
2361             * byte per pixel.  This is what png_set_packing does (i.e., it
2362             * unpacks the bit values into bytes.)
2363             */
2364            if (png_ptr->bit_depth < 8)
2365               png_set_packing(png_ptr);
2366         }
2367
2368         else /* bit depth is 16 */
2369         {
2370            /* The 16-bit input values can be converted directly to 8-bit gamma
2371             * encoded values; however, if a tRNS chunk is present 257 color-map
2372             * entries are required.  This means that the extra entry requires
2373             * special processing; add an alpha channel, sacrifice gray level
2374             * 254 and convert transparent (alpha==0) entries to that.
2375             *
2376             * Use libpng to chop the data to 8 bits.  Convert it to sRGB at the
2377             * same time to minimize quality loss.  If a tRNS chunk is present
2378             * this means libpng must handle it too; otherwise it is impossible
2379             * to do the exact match on the 16-bit value.
2380             *
2381             * If the output has no alpha channel *and* the background color is
2382             * gray then it is possible to let libpng handle the substitution by
2383             * ensuring that the corresponding gray level matches the background
2384             * color exactly.
2385             */
2386            data_encoding = P_sRGB;
2387
2388            if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2389               png_error(png_ptr, "gray[16] color-map: too few entries");
2390
2391            cmap_entries = make_gray_colormap(display);
2392
2393            if (png_ptr->num_trans > 0)
2394            {
2395               unsigned int back_alpha;
2396
2397               if (output_format & PNG_FORMAT_FLAG_ALPHA)
2398                  back_alpha = 0;
2399
2400               else
2401               {
2402                  if (back_r == back_g && back_g == back_b)
2403                  {
2404                     /* Background is gray; no special processing will be
2405                      * required.
2406                      */
2407                     png_color_16 c;
2408                     png_uint_32 gray = back_g;
2409
2410                     if (output_encoding == P_LINEAR)
2411                     {
2412                        gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2413
2414                        /* And make sure the corresponding palette entry
2415                         * matches.
2416                         */
2417                        png_create_colormap_entry(display, gray, back_g, back_g,
2418                           back_g, 65535, P_LINEAR);
2419                     }
2420
2421                     /* The background passed to libpng, however, must be the
2422                      * sRGB value.
2423                      */
2424                     c.index = 0; /*unused*/
2425                     c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2426
2427                     /* NOTE: does this work without expanding tRNS to alpha?
2428                      * It should be the color->gray case below apparently
2429                      * doesn't.
2430                      */
2431                     png_set_background_fixed(png_ptr, &c,
2432                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2433                        0/*gamma: not used*/);
2434
2435                     output_processing = PNG_CMAP_NONE;
2436                     break;
2437                  }
2438
2439                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
2440               }
2441
2442               /* output_processing means that the libpng-processed row will be
2443                * 8-bit GA and it has to be processing to single byte color-map
2444                * values.  Entry 254 is replaced by either a completely
2445                * transparent entry or by the background color at full
2446                * precision (and the background color is not a simple gray leve
2447                * in this case.)
2448                */
2449               expand_tRNS = 1;
2450               output_processing = PNG_CMAP_TRANS;
2451               background_index = 254;
2452
2453               /* And set (overwrite) color-map entry 254 to the actual
2454                * background color at full precision.
2455                */
2456               png_create_colormap_entry(display, 254, back_r, back_g, back_b,
2457                  back_alpha, output_encoding);
2458            }
2459
2460            else
2461               output_processing = PNG_CMAP_NONE;
2462         }
2463         break;
2464
2465      case PNG_COLOR_TYPE_GRAY_ALPHA:
2466         /* 8-bit or 16-bit PNG with two channels - gray and alpha.  A minimum
2467          * of 65536 combinations.  If, however, the alpha channel is to be
2468          * removed there are only 256 possibilities if the background is gray.
2469          * (Otherwise there is a subset of the 65536 possibilities defined by
2470          * the triangle between black, white and the background color.)
2471          *
2472          * Reduce 16-bit files to 8-bit and sRGB encode the result.  No need to
2473          * worry about tRNS matching - tRNS is ignored if there is an alpha
2474          * channel.
2475          */
2476         data_encoding = P_sRGB;
2477
2478         if (output_format & PNG_FORMAT_FLAG_ALPHA)
2479         {
2480            if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2481               png_error(png_ptr, "gray+alpha color-map: too few entries");
2482
2483            cmap_entries = make_ga_colormap(display);
2484
2485            background_index = PNG_CMAP_GA_BACKGROUND;
2486            output_processing = PNG_CMAP_GA;
2487         }
2488
2489         else /* alpha is removed */
2490         {
2491            /* Alpha must be removed as the PNG data is processed when the
2492             * background is a color because the G and A channels are
2493             * independent and the vector addition (non-parallel vectors) is a
2494             * 2-D problem.
2495             *
2496             * This can be reduced to the same algorithm as above by making a
2497             * colormap containing gray levels (for the opaque grays), a
2498             * background entry (for a transparent pixel) and a set of four six
2499             * level color values, one set for each intermediate alpha value.
2500             * See the comments in make_ga_colormap for how this works in the
2501             * per-pixel processing.
2502             *
2503             * If the background is gray, however, we only need a 256 entry gray
2504             * level color map.  It is sufficient to make the entry generated
2505             * for the background color be exactly the color specified.
2506             */
2507            if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
2508               (back_r == back_g && back_g == back_b))
2509            {
2510               /* Background is gray; no special processing will be required. */
2511               png_color_16 c;
2512               png_uint_32 gray = back_g;
2513
2514               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2515                  png_error(png_ptr, "gray-alpha color-map: too few entries");
2516
2517               cmap_entries = make_gray_colormap(display);
2518
2519               if (output_encoding == P_LINEAR)
2520               {
2521                  gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2522
2523                  /* And make sure the corresponding palette entry matches. */
2524                  png_create_colormap_entry(display, gray, back_g, back_g,
2525                     back_g, 65535, P_LINEAR);
2526               }
2527
2528               /* The background passed to libpng, however, must be the sRGB
2529                * value.
2530                */
2531               c.index = 0; /*unused*/
2532               c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2533
2534               png_set_background_fixed(png_ptr, &c,
2535                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2536                  0/*gamma: not used*/);
2537
2538               output_processing = PNG_CMAP_NONE;
2539            }
2540
2541            else
2542            {
2543               png_uint_32 i, a;
2544
2545               /* This is the same as png_make_ga_colormap, above, except that
2546                * the entries are all opaque.
2547                */
2548               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2549                  png_error(png_ptr, "ga-alpha color-map: too few entries");
2550
2551               i = 0;
2552               while (i < 231)
2553               {
2554                  png_uint_32 gray = (i * 256 + 115) / 231;
2555                  png_create_colormap_entry(display, i++, gray, gray, gray,
2556                     255, P_sRGB);
2557               }
2558
2559               /* NOTE: this preserves the full precision of the application
2560                * background color.
2561                */
2562               background_index = i;
2563               png_create_colormap_entry(display, i++, back_r, back_g, back_b,
2564                  output_encoding == P_LINEAR ? 65535U : 255U, output_encoding);
2565
2566               /* For non-opaque input composite on the sRGB background - this
2567                * requires inverting the encoding for each component.  The input
2568                * is still converted to the sRGB encoding because this is a
2569                * reasonable approximate to the logarithmic curve of human
2570                * visual sensitivity, at least over the narrow range which PNG
2571                * represents.  Consequently 'G' is always sRGB encoded, while
2572                * 'A' is linear.  We need the linear background colors.
2573                */
2574               if (output_encoding == P_sRGB) /* else already linear */
2575               {
2576                  /* This may produce a value not exactly matching the
2577                   * background, but that's ok because these numbers are only
2578                   * used when alpha != 0
2579                   */
2580                  back_r = png_sRGB_table[back_r];
2581                  back_g = png_sRGB_table[back_g];
2582                  back_b = png_sRGB_table[back_b];
2583               }
2584
2585               for (a=1; a<5; ++a)
2586               {
2587                  unsigned int g;
2588
2589                  /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled
2590                   * by an 8-bit alpha value (0..255).
2591                   */
2592                  png_uint_32 alpha = 51 * a;
2593                  png_uint_32 back_rx = (255-alpha) * back_r;
2594                  png_uint_32 back_gx = (255-alpha) * back_g;
2595                  png_uint_32 back_bx = (255-alpha) * back_b;
2596
2597                  for (g=0; g<6; ++g)
2598                  {
2599                     png_uint_32 gray = png_sRGB_table[g*51] * alpha;
2600
2601                     png_create_colormap_entry(display, i++,
2602                        PNG_sRGB_FROM_LINEAR(gray + back_rx),
2603                        PNG_sRGB_FROM_LINEAR(gray + back_gx),
2604                        PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
2605                  }
2606               }
2607
2608               cmap_entries = i;
2609               output_processing = PNG_CMAP_GA;
2610            }
2611         }
2612         break;
2613
2614      case PNG_COLOR_TYPE_RGB:
2615      case PNG_COLOR_TYPE_RGB_ALPHA:
2616         /* Exclude the case where the output is gray; we can always handle this
2617          * with the cases above.
2618          */
2619         if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
2620         {
2621            /* The color-map will be grayscale, so we may as well convert the
2622             * input RGB values to a simple grayscale and use the grayscale
2623             * code above.
2624             *
2625             * NOTE: calling this apparently damages the recognition of the
2626             * transparent color in background color handling; call
2627             * png_set_tRNS_to_alpha before png_set_background_fixed.
2628             */
2629            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
2630               -1);
2631            data_encoding = P_sRGB;
2632
2633            /* The output will now be one or two 8-bit gray or gray+alpha
2634             * channels.  The more complex case arises when the input has alpha.
2635             */
2636            if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2637               png_ptr->num_trans > 0) &&
2638               (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2639            {
2640               /* Both input and output have an alpha channel, so no background
2641                * processing is required; just map the GA bytes to the right
2642                * color-map entry.
2643                */
2644               expand_tRNS = 1;
2645
2646               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2647                  png_error(png_ptr, "rgb[ga] color-map: too few entries");
2648
2649               cmap_entries = make_ga_colormap(display);
2650               background_index = PNG_CMAP_GA_BACKGROUND;
2651               output_processing = PNG_CMAP_GA;
2652            }
2653
2654            else
2655            {
2656               /* Either the input or the output has no alpha channel, so there
2657                * will be no non-opaque pixels in the color-map; it will just be
2658                * grayscale.
2659                */
2660               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2661                  png_error(png_ptr, "rgb[gray] color-map: too few entries");
2662
2663               /* Ideally this code would use libpng to do the gamma correction,
2664                * but if an input alpha channel is to be removed we will hit the
2665                * libpng bug in gamma+compose+rgb-to-gray (the double gamma
2666                * correction bug).  Fix this by dropping the gamma correction in
2667                * this case and doing it in the palette; this will result in
2668                * duplicate palette entries, but that's better than the
2669                * alternative of double gamma correction.
2670                */
2671               if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2672                  png_ptr->num_trans > 0) &&
2673                  png_gamma_not_sRGB(png_ptr->colorspace.gamma))
2674               {
2675                  cmap_entries = make_gray_file_colormap(display);
2676                  data_encoding = P_FILE;
2677               }
2678
2679               else
2680                  cmap_entries = make_gray_colormap(display);
2681
2682               /* But if the input has alpha or transparency it must be removed
2683                */
2684               if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2685                  png_ptr->num_trans > 0)
2686               {
2687                  png_color_16 c;
2688                  png_uint_32 gray = back_g;
2689
2690                  /* We need to ensure that the application background exists in
2691                   * the colormap and that completely transparent pixels map to
2692                   * it.  Achieve this simply by ensuring that the entry
2693                   * selected for the background really is the background color.
2694                   */
2695                  if (data_encoding == P_FILE) /* from the fixup above */
2696                  {
2697                     /* The app supplied a gray which is in output_encoding, we
2698                      * need to convert it to a value of the input (P_FILE)
2699                      * encoding then set this palette entry to the required
2700                      * output encoding.
2701                      */
2702                     if (output_encoding == P_sRGB)
2703                        gray = png_sRGB_table[gray]; /* now P_LINEAR */
2704
2705                     gray = PNG_DIV257(png_gamma_16bit_correct(gray,
2706                        png_ptr->colorspace.gamma)); /* now P_FILE */
2707
2708                     /* And make sure the corresponding palette entry contains
2709                      * exactly the required sRGB value.
2710                      */
2711                     png_create_colormap_entry(display, gray, back_g, back_g,
2712                        back_g, 0/*unused*/, output_encoding);
2713                  }
2714
2715                  else if (output_encoding == P_LINEAR)
2716                  {
2717                     gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2718
2719                     /* And make sure the corresponding palette entry matches.
2720                      */
2721                     png_create_colormap_entry(display, gray, back_g, back_g,
2722                        back_g, 0/*unused*/, P_LINEAR);
2723                  }
2724
2725                  /* The background passed to libpng, however, must be the
2726                   * output (normally sRGB) value.
2727                   */
2728                  c.index = 0; /*unused*/
2729                  c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2730
2731                  /* NOTE: the following is apparently a bug in libpng. Without
2732                   * it the transparent color recognition in
2733                   * png_set_background_fixed seems to go wrong.
2734                   */
2735                  expand_tRNS = 1;
2736                  png_set_background_fixed(png_ptr, &c,
2737                     PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2738                     0/*gamma: not used*/);
2739               }
2740
2741               output_processing = PNG_CMAP_NONE;
2742            }
2743         }
2744
2745         else /* output is color */
2746         {
2747            /* We could use png_quantize here so long as there is no transparent
2748             * color or alpha; png_quantize ignores alpha.  Easier overall just
2749             * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
2750             * Consequently we always want libpng to produce sRGB data.
2751             */
2752            data_encoding = P_sRGB;
2753
2754            /* Is there any transparency or alpha? */
2755            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2756               png_ptr->num_trans > 0)
2757            {
2758               /* Is there alpha in the output too?  If so all four channels are
2759                * processed into a special RGB cube with alpha support.
2760                */
2761               if (output_format & PNG_FORMAT_FLAG_ALPHA)
2762               {
2763                  png_uint_32 r;
2764
2765                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
2766                     png_error(png_ptr, "rgb+alpha color-map: too few entries");
2767
2768                  cmap_entries = make_rgb_colormap(display);
2769
2770                  /* Add a transparent entry. */
2771                  png_create_colormap_entry(display, cmap_entries, 255, 255,
2772                     255, 0, P_sRGB);
2773
2774                  /* This is stored as the background index for the processing
2775                   * algorithm.
2776                   */
2777                  background_index = cmap_entries++;
2778
2779                  /* Add 27 r,g,b entries each with alpha 0.5. */
2780                  for (r=0; r<256; r = (r << 1) | 0x7f)
2781                  {
2782                     png_uint_32 g;
2783
2784                     for (g=0; g<256; g = (g << 1) | 0x7f)
2785                     {
2786                        png_uint_32 b;
2787
2788                        /* This generates components with the values 0, 127 and
2789                         * 255
2790                         */
2791                        for (b=0; b<256; b = (b << 1) | 0x7f)
2792                           png_create_colormap_entry(display, cmap_entries++,
2793                              r, g, b, 128, P_sRGB);
2794                     }
2795                  }
2796
2797                  expand_tRNS = 1;
2798                  output_processing = PNG_CMAP_RGB_ALPHA;
2799               }
2800
2801               else
2802               {
2803                  /* Alpha/transparency must be removed.  The background must
2804                   * exist in the color map (achieved by setting adding it after
2805                   * the 666 color-map).  If the standard processing code will
2806                   * pick up this entry automatically that's all that is
2807                   * required; libpng can be called to do the background
2808                   * processing.
2809                   */
2810                  unsigned int sample_size =
2811                     PNG_IMAGE_SAMPLE_SIZE(output_format);
2812                  png_uint_32 r, g, b; /* sRGB background */
2813
2814                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
2815                     png_error(png_ptr, "rgb-alpha color-map: too few entries");
2816
2817                  cmap_entries = make_rgb_colormap(display);
2818
2819                  png_create_colormap_entry(display, cmap_entries, back_r,
2820                        back_g, back_b, 0/*unused*/, output_encoding);
2821
2822                  if (output_encoding == P_LINEAR)
2823                  {
2824                     r = PNG_sRGB_FROM_LINEAR(back_r * 255);
2825                     g = PNG_sRGB_FROM_LINEAR(back_g * 255);
2826                     b = PNG_sRGB_FROM_LINEAR(back_b * 255);
2827                  }
2828
2829                  else
2830                  {
2831                     r = back_r;
2832                     g = back_g;
2833                     b = back_g;
2834                  }
2835
2836                  /* Compare the newly-created color-map entry with the one the
2837                   * PNG_CMAP_RGB algorithm will use.  If the two entries don't
2838                   * match, add the new one and set this as the background
2839                   * index.
2840                   */
2841                  if (memcmp((png_const_bytep)display->colormap +
2842                        sample_size * cmap_entries,
2843                     (png_const_bytep)display->colormap +
2844                        sample_size * PNG_RGB_INDEX(r,g,b),
2845                     sample_size) != 0)
2846                  {
2847                     /* The background color must be added. */
2848                     background_index = cmap_entries++;
2849
2850                     /* Add 27 r,g,b entries each with created by composing with
2851                      * the background at alpha 0.5.
2852                      */
2853                     for (r=0; r<256; r = (r << 1) | 0x7f)
2854                     {
2855                        for (g=0; g<256; g = (g << 1) | 0x7f)
2856                        {
2857                           /* This generates components with the values 0, 127
2858                            * and 255
2859                            */
2860                           for (b=0; b<256; b = (b << 1) | 0x7f)
2861                              png_create_colormap_entry(display, cmap_entries++,
2862                                 png_colormap_compose(display, r, P_sRGB, 128,
2863                                    back_r, output_encoding),
2864                                 png_colormap_compose(display, g, P_sRGB, 128,
2865                                    back_g, output_encoding),
2866                                 png_colormap_compose(display, b, P_sRGB, 128,
2867                                    back_b, output_encoding),
2868                                 0/*unused*/, output_encoding);
2869                        }
2870                     }
2871
2872                     expand_tRNS = 1;
2873                     output_processing = PNG_CMAP_RGB_ALPHA;
2874                  }
2875
2876                  else /* background color is in the standard color-map */
2877                  {
2878                     png_color_16 c;
2879
2880                     c.index = 0; /*unused*/
2881                     c.red = (png_uint_16)back_r;
2882                     c.gray = c.green = (png_uint_16)back_g;
2883                     c.blue = (png_uint_16)back_b;
2884
2885                     png_set_background_fixed(png_ptr, &c,
2886                        PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2887                        0/*gamma: not used*/);
2888
2889                     output_processing = PNG_CMAP_RGB;
2890                  }
2891               }
2892            }
2893
2894            else /* no alpha or transparency in the input */
2895            {
2896               /* Alpha in the output is irrelevant, simply map the opaque input
2897                * pixels to the 6x6x6 color-map.
2898                */
2899               if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
2900                  png_error(png_ptr, "rgb color-map: too few entries");
2901
2902               cmap_entries = make_rgb_colormap(display);
2903               output_processing = PNG_CMAP_RGB;
2904            }
2905         }
2906         break;
2907
2908      case PNG_COLOR_TYPE_PALETTE:
2909         /* It's already got a color-map.  It may be necessary to eliminate the
2910          * tRNS entries though.
2911          */
2912         {
2913            unsigned int num_trans = png_ptr->num_trans;
2914            png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
2915            png_const_colorp colormap = png_ptr->palette;
2916            const int do_background = trans != NULL &&
2917               (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
2918            unsigned int i;
2919
2920            /* Just in case: */
2921            if (trans == NULL)
2922               num_trans = 0;
2923
2924            output_processing = PNG_CMAP_NONE;
2925            data_encoding = P_FILE; /* Don't change from color-map indicies */
2926            cmap_entries = png_ptr->num_palette;
2927            if (cmap_entries > 256)
2928               cmap_entries = 256;
2929
2930            if (cmap_entries > image->colormap_entries)
2931               png_error(png_ptr, "palette color-map: too few entries");
2932
2933            for (i=0; i < cmap_entries; ++i)
2934            {
2935               if (do_background && i < num_trans && trans[i] < 255)
2936               {
2937                  if (trans[i] == 0)
2938                     png_create_colormap_entry(display, i, back_r, back_g,
2939                        back_b, 0, output_encoding);
2940
2941                  else
2942                  {
2943                     /* Must compose the PNG file color in the color-map entry
2944                      * on the sRGB color in 'back'.
2945                      */
2946                     png_create_colormap_entry(display, i,
2947                        png_colormap_compose(display, colormap[i].red, P_FILE,
2948                           trans[i], back_r, output_encoding),
2949                        png_colormap_compose(display, colormap[i].green, P_FILE,
2950                           trans[i], back_g, output_encoding),
2951                        png_colormap_compose(display, colormap[i].blue, P_FILE,
2952                           trans[i], back_b, output_encoding),
2953                        output_encoding == P_LINEAR ? trans[i] * 257U :
2954                           trans[i],
2955                        output_encoding);
2956                  }
2957               }
2958
2959               else
2960                  png_create_colormap_entry(display, i, colormap[i].red,
2961                     colormap[i].green, colormap[i].blue,
2962                     i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
2963            }
2964
2965            /* The PNG data may have indicies packed in fewer than 8 bits, it
2966             * must be expanded if so.
2967             */
2968            if (png_ptr->bit_depth < 8)
2969               png_set_packing(png_ptr);
2970         }
2971         break;
2972
2973      default:
2974         png_error(png_ptr, "invalid PNG color type");
2975         /*NOT REACHED*/
2976         break;
2977   }
2978
2979   /* Now deal with the output processing */
2980   if (expand_tRNS && png_ptr->num_trans > 0 &&
2981      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
2982      png_set_tRNS_to_alpha(png_ptr);
2983
2984   switch (data_encoding)
2985   {
2986      default:
2987         png_error(png_ptr, "bad data option (internal error)");
2988         break;
2989
2990      case P_sRGB:
2991         /* Change to 8-bit sRGB */
2992         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
2993         /* FALL THROUGH */
2994
2995      case P_FILE:
2996         if (png_ptr->bit_depth > 8)
2997            png_set_scale_16(png_ptr);
2998         break;
2999   }
3000
3001   if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
3002      png_error(png_ptr, "color map overflow (BAD internal error)");
3003
3004   image->colormap_entries = cmap_entries;
3005
3006   /* Double check using the recorded background index */
3007   switch (output_processing)
3008   {
3009      case PNG_CMAP_NONE:
3010         if (background_index != PNG_CMAP_NONE_BACKGROUND)
3011            goto bad_background;
3012         break;
3013
3014      case PNG_CMAP_GA:
3015         if (background_index != PNG_CMAP_GA_BACKGROUND)
3016            goto bad_background;
3017         break;
3018
3019      case PNG_CMAP_TRANS:
3020         if (background_index >= cmap_entries ||
3021            background_index != PNG_CMAP_TRANS_BACKGROUND)
3022            goto bad_background;
3023         break;
3024
3025      case PNG_CMAP_RGB:
3026         if (background_index != PNG_CMAP_RGB_BACKGROUND)
3027            goto bad_background;
3028         break;
3029
3030      case PNG_CMAP_RGB_ALPHA:
3031         if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)
3032            goto bad_background;
3033         break;
3034
3035      default:
3036         png_error(png_ptr, "bad processing option (internal error)");
3037
3038      bad_background:
3039         png_error(png_ptr, "bad background index (internal error)");
3040   }
3041
3042   display->colormap_processing = output_processing;
3043
3044   return 1/*ok*/;
3045}
3046
3047/* The final part of the color-map read called from png_image_finish_read. */
3048static int
3049png_image_read_and_map(png_voidp argument)
3050{
3051   png_image_read_control *display = png_voidcast(png_image_read_control*,
3052      argument);
3053   png_imagep image = display->image;
3054   png_structrp png_ptr = image->opaque->png_ptr;
3055   int passes;
3056
3057   /* Called when the libpng data must be transformed into the color-mapped
3058    * form.  There is a local row buffer in display->local and this routine must
3059    * do the interlace handling.
3060    */
3061   switch (png_ptr->interlaced)
3062   {
3063      case PNG_INTERLACE_NONE:
3064         passes = 1;
3065         break;
3066
3067      case PNG_INTERLACE_ADAM7:
3068         passes = PNG_INTERLACE_ADAM7_PASSES;
3069         break;
3070
3071      default:
3072         png_error(png_ptr, "unknown interlace type");
3073   }
3074
3075   {
3076      png_uint_32  height = image->height;
3077      png_uint_32  width = image->width;
3078      int          proc = display->colormap_processing;
3079      png_bytep    first_row = png_voidcast(png_bytep, display->first_row);
3080      ptrdiff_t    step_row = display->row_bytes;
3081      int pass;
3082
3083      for (pass = 0; pass < passes; ++pass)
3084      {
3085         unsigned int     startx, stepx, stepy;
3086         png_uint_32      y;
3087
3088         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3089         {
3090            /* The row may be empty for a short image: */
3091            if (PNG_PASS_COLS(width, pass) == 0)
3092               continue;
3093
3094            startx = PNG_PASS_START_COL(pass);
3095            stepx = PNG_PASS_COL_OFFSET(pass);
3096            y = PNG_PASS_START_ROW(pass);
3097            stepy = PNG_PASS_ROW_OFFSET(pass);
3098         }
3099
3100         else
3101         {
3102            y = 0;
3103            startx = 0;
3104            stepx = stepy = 1;
3105         }
3106
3107         for (; y<height; y += stepy)
3108         {
3109            png_bytep inrow = png_voidcast(png_bytep, display->local_row);
3110            png_bytep outrow = first_row + y * step_row;
3111            png_const_bytep end_row = outrow + width;
3112
3113            /* Read read the libpng data into the temporary buffer. */
3114            png_read_row(png_ptr, inrow, NULL);
3115
3116            /* Now process the row according to the processing option, note
3117             * that the caller verifies that the format of the libpng output
3118             * data is as required.
3119             */
3120            outrow += startx;
3121            switch (proc)
3122            {
3123               case PNG_CMAP_GA:
3124                  for (; outrow < end_row; outrow += stepx)
3125                  {
3126                     /* The data is always in the PNG order */
3127                     unsigned int gray = *inrow++;
3128                     unsigned int alpha = *inrow++;
3129                     unsigned int entry;
3130
3131                     /* NOTE: this code is copied as a comment in
3132                      * make_ga_colormap above.  Please update the
3133                      * comment if you change this code!
3134                      */
3135                     if (alpha > 229) /* opaque */
3136                     {
3137                        entry = (231 * gray + 128) >> 8;
3138                     }
3139                     else if (alpha < 26) /* transparent */
3140                     {
3141                        entry = 231;
3142                     }
3143                     else /* partially opaque */
3144                     {
3145                        entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
3146                     }
3147
3148                     *outrow = (png_byte)entry;
3149                  }
3150                  break;
3151
3152               case PNG_CMAP_TRANS:
3153                  for (; outrow < end_row; outrow += stepx)
3154                  {
3155                     png_byte gray = *inrow++;
3156                     png_byte alpha = *inrow++;
3157
3158                     if (alpha == 0)
3159                        *outrow = PNG_CMAP_TRANS_BACKGROUND;
3160
3161                     else if (gray != PNG_CMAP_TRANS_BACKGROUND)
3162                        *outrow = gray;
3163
3164                     else
3165                        *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);
3166                  }
3167                  break;
3168
3169               case PNG_CMAP_RGB:
3170                  for (; outrow < end_row; outrow += stepx)
3171                  {
3172                     *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);
3173                     inrow += 3;
3174                  }
3175                  break;
3176
3177               case PNG_CMAP_RGB_ALPHA:
3178                  for (; outrow < end_row; outrow += stepx)
3179                  {
3180                     unsigned int alpha = inrow[3];
3181
3182                     /* Because the alpha entries only hold alpha==0.5 values
3183                      * split the processing at alpha==0.25 (64) and 0.75
3184                      * (196).
3185                      */
3186
3187                     if (alpha >= 196)
3188                        *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
3189                           inrow[2]);
3190
3191                     else if (alpha < 64)
3192                        *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
3193
3194                     else
3195                     {
3196                        /* Likewise there are three entries for each of r, g
3197                         * and b.  We could select the entry by popcount on
3198                         * the top two bits on those architectures that
3199                         * support it, this is what the code below does,
3200                         * crudely.
3201                         */
3202                        unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;
3203
3204                        /* Here are how the values map:
3205                         *
3206                         * 0x00 .. 0x3f -> 0
3207                         * 0x40 .. 0xbf -> 1
3208                         * 0xc0 .. 0xff -> 2
3209                         *
3210                         * So, as above with the explicit alpha checks, the
3211                         * breakpoints are at 64 and 196.
3212                         */
3213                        if (inrow[0] & 0x80) back_i += 9; /* red */
3214                        if (inrow[0] & 0x40) back_i += 9;
3215                        if (inrow[0] & 0x80) back_i += 3; /* green */
3216                        if (inrow[0] & 0x40) back_i += 3;
3217                        if (inrow[0] & 0x80) back_i += 1; /* blue */
3218                        if (inrow[0] & 0x40) back_i += 1;
3219
3220                        *outrow = (png_byte)back_i;
3221                     }
3222
3223                     inrow += 4;
3224                  }
3225                  break;
3226
3227               default:
3228                  break;
3229            }
3230         }
3231      }
3232   }
3233
3234   return 1;
3235}
3236
3237static int
3238png_image_read_colormapped(png_voidp argument)
3239{
3240   png_image_read_control *display = png_voidcast(png_image_read_control*,
3241      argument);
3242   png_imagep image = display->image;
3243   png_controlp control = image->opaque;
3244   png_structrp png_ptr = control->png_ptr;
3245   png_inforp info_ptr = control->info_ptr;
3246
3247   int passes = 0; /* As a flag */
3248
3249   PNG_SKIP_CHUNKS(png_ptr);
3250
3251   /* Update the 'info' structure and make sure the result is as required; first
3252    * make sure to turn on the interlace handling if it will be required
3253    * (because it can't be turned on *after* the call to png_read_update_info!)
3254    */
3255   if (display->colormap_processing == PNG_CMAP_NONE)
3256      passes = png_set_interlace_handling(png_ptr);
3257
3258   png_read_update_info(png_ptr, info_ptr);
3259
3260   /* The expected output can be deduced from the colormap_processing option. */
3261   switch (display->colormap_processing)
3262   {
3263      case PNG_CMAP_NONE:
3264         /* Output must be one channel and one byte per pixel, the output
3265          * encoding can be anything.
3266          */
3267         if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
3268            info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&
3269            info_ptr->bit_depth == 8)
3270            break;
3271
3272         goto bad_output;
3273
3274      case PNG_CMAP_TRANS:
3275      case PNG_CMAP_GA:
3276         /* Output must be two channels and the 'G' one must be sRGB, the latter
3277          * can be checked with an exact number because it should have been set
3278          * to this number above!
3279          */
3280         if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
3281            info_ptr->bit_depth == 8 &&
3282            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3283            image->colormap_entries == 256)
3284            break;
3285
3286         goto bad_output;
3287
3288      case PNG_CMAP_RGB:
3289         /* Output must be 8-bit sRGB encoded RGB */
3290         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
3291            info_ptr->bit_depth == 8 &&
3292            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3293            image->colormap_entries == 216)
3294            break;
3295
3296         goto bad_output;
3297
3298      case PNG_CMAP_RGB_ALPHA:
3299         /* Output must be 8-bit sRGB encoded RGBA */
3300         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
3301            info_ptr->bit_depth == 8 &&
3302            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3303            image->colormap_entries == 244 /* 216 + 1 + 27 */)
3304            break;
3305
3306         /* goto bad_output; */
3307         /* FALL THROUGH */
3308
3309      default:
3310      bad_output:
3311         png_error(png_ptr, "bad color-map processing (internal error)");
3312   }
3313
3314   /* Now read the rows.  Do this here if it is possible to read directly into
3315    * the output buffer, otherwise allocate a local row buffer of the maximum
3316    * size libpng requires and call the relevant processing routine safely.
3317    */
3318   {
3319      png_voidp first_row = display->buffer;
3320      ptrdiff_t row_bytes = display->row_stride;
3321
3322      /* The following expression is designed to work correctly whether it gives
3323       * a signed or an unsigned result.
3324       */
3325      if (row_bytes < 0)
3326      {
3327         char *ptr = png_voidcast(char*, first_row);
3328         ptr += (image->height-1) * (-row_bytes);
3329         first_row = png_voidcast(png_voidp, ptr);
3330      }
3331
3332      display->first_row = first_row;
3333      display->row_bytes = row_bytes;
3334   }
3335
3336   if (passes == 0)
3337   {
3338      int result;
3339      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
3340
3341      display->local_row = row;
3342      result = png_safe_execute(image, png_image_read_and_map, display);
3343      display->local_row = NULL;
3344      png_free(png_ptr, row);
3345
3346      return result;
3347   }
3348
3349   else
3350   {
3351      png_alloc_size_t row_bytes = display->row_bytes;
3352
3353      while (--passes >= 0)
3354      {
3355         png_uint_32      y = image->height;
3356         png_bytep        row = png_voidcast(png_bytep, display->first_row);
3357
3358         while (y-- > 0)
3359         {
3360            png_read_row(png_ptr, row, NULL);
3361            row += row_bytes;
3362         }
3363      }
3364
3365      return 1;
3366   }
3367}
3368
3369/* Just the row reading part of png_image_read. */
3370static int
3371png_image_read_composite(png_voidp argument)
3372{
3373   png_image_read_control *display = png_voidcast(png_image_read_control*,
3374      argument);
3375   png_imagep image = display->image;
3376   png_structrp png_ptr = image->opaque->png_ptr;
3377   int passes;
3378
3379   switch (png_ptr->interlaced)
3380   {
3381      case PNG_INTERLACE_NONE:
3382         passes = 1;
3383         break;
3384
3385      case PNG_INTERLACE_ADAM7:
3386         passes = PNG_INTERLACE_ADAM7_PASSES;
3387         break;
3388
3389      default:
3390         png_error(png_ptr, "unknown interlace type");
3391   }
3392
3393   {
3394      png_uint_32  height = image->height;
3395      png_uint_32  width = image->width;
3396      ptrdiff_t    step_row = display->row_bytes;
3397      unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
3398      int pass;
3399
3400      for (pass = 0; pass < passes; ++pass)
3401      {
3402         unsigned int     startx, stepx, stepy;
3403         png_uint_32      y;
3404
3405         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3406         {
3407            /* The row may be empty for a short image: */
3408            if (PNG_PASS_COLS(width, pass) == 0)
3409               continue;
3410
3411            startx = PNG_PASS_START_COL(pass) * channels;
3412            stepx = PNG_PASS_COL_OFFSET(pass) * channels;
3413            y = PNG_PASS_START_ROW(pass);
3414            stepy = PNG_PASS_ROW_OFFSET(pass);
3415         }
3416
3417         else
3418         {
3419            y = 0;
3420            startx = 0;
3421            stepx = channels;
3422            stepy = 1;
3423         }
3424
3425         for (; y<height; y += stepy)
3426         {
3427            png_bytep inrow = png_voidcast(png_bytep, display->local_row);
3428            png_bytep outrow;
3429            png_const_bytep end_row;
3430
3431            /* Read the row, which is packed: */
3432            png_read_row(png_ptr, inrow, NULL);
3433
3434            outrow = png_voidcast(png_bytep, display->first_row);
3435            outrow += y * step_row;
3436            end_row = outrow + width * channels;
3437
3438            /* Now do the composition on each pixel in this row. */
3439            outrow += startx;
3440            for (; outrow < end_row; outrow += stepx)
3441            {
3442               png_byte alpha = inrow[channels];
3443
3444               if (alpha > 0) /* else no change to the output */
3445               {
3446                  unsigned int c;
3447
3448                  for (c=0; c<channels; ++c)
3449                  {
3450                     png_uint_32 component = inrow[c];
3451
3452                     if (alpha < 255) /* else just use component */
3453                     {
3454                        /* This is PNG_OPTIMIZED_ALPHA, the component value
3455                         * is a linear 8-bit value.  Combine this with the
3456                         * current outrow[c] value which is sRGB encoded.
3457                         * Arithmetic here is 16-bits to preserve the output
3458                         * values correctly.
3459                         */
3460                        component *= 257*255; /* =65535 */
3461                        component += (255-alpha)*png_sRGB_table[outrow[c]];
3462
3463                        /* So 'component' is scaled by 255*65535 and is
3464                         * therefore appropriate for the sRGB to linear
3465                         * conversion table.
3466                         */
3467                        component = PNG_sRGB_FROM_LINEAR(component);
3468                     }
3469
3470                     outrow[c] = (png_byte)component;
3471                  }
3472               }
3473
3474               inrow += channels+1; /* components and alpha channel */
3475            }
3476         }
3477      }
3478   }
3479
3480   return 1;
3481}
3482
3483/* The do_local_background case; called when all the following transforms are to
3484 * be done:
3485 *
3486 * PNG_RGB_TO_GRAY
3487 * PNG_COMPOSITE
3488 * PNG_GAMMA
3489 *
3490 * This is a work-round for the fact that both the PNG_RGB_TO_GRAY and
3491 * PNG_COMPOSITE code performs gamma correction, so we get double gamma
3492 * correction.  The fix-up is to prevent the PNG_COMPOSITE operation happening
3493 * inside libpng, so this routine sees an 8 or 16-bit gray+alpha row and handles
3494 * the removal or pre-multiplication of the alpha channel.
3495 */
3496static int
3497png_image_read_background(png_voidp argument)
3498{
3499   png_image_read_control *display = png_voidcast(png_image_read_control*,
3500      argument);
3501   png_imagep image = display->image;
3502   png_structrp png_ptr = image->opaque->png_ptr;
3503   png_inforp info_ptr = image->opaque->info_ptr;
3504   png_uint_32 height = image->height;
3505   png_uint_32 width = image->width;
3506   int pass, passes;
3507
3508   /* Double check the convoluted logic below.  We expect to get here with
3509    * libpng doing rgb to gray and gamma correction but background processing
3510    * left to the png_image_read_background function.  The rows libpng produce
3511    * might be 8 or 16-bit but should always have two channels; gray plus alpha.
3512    */
3513   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
3514      png_error(png_ptr, "lost rgb to gray");
3515
3516   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
3517      png_error(png_ptr, "unexpected compose");
3518
3519   if (png_get_channels(png_ptr, info_ptr) != 2)
3520      png_error(png_ptr, "lost/gained channels");
3521
3522   /* Expect the 8-bit case to always remove the alpha channel */
3523   if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&
3524      (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
3525      png_error(png_ptr, "unexpected 8-bit transformation");
3526
3527   switch (png_ptr->interlaced)
3528   {
3529      case PNG_INTERLACE_NONE:
3530         passes = 1;
3531         break;
3532
3533      case PNG_INTERLACE_ADAM7:
3534         passes = PNG_INTERLACE_ADAM7_PASSES;
3535         break;
3536
3537      default:
3538         png_error(png_ptr, "unknown interlace type");
3539   }
3540
3541   /* Use direct access to info_ptr here because otherwise the simplified API
3542    * would require PNG_EASY_ACCESS_SUPPORTED (just for this.)  Note this is
3543    * checking the value after libpng expansions, not the original value in the
3544    * PNG.
3545    */
3546   switch (info_ptr->bit_depth)
3547   {
3548      default:
3549         png_error(png_ptr, "unexpected bit depth");
3550         break;
3551
3552      case 8:
3553         /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
3554          * to be removed by composing on a background: either the row if
3555          * display->background is NULL or display->background->green if not.
3556          * Unlike the code above ALPHA_OPTIMIZED has *not* been done.
3557          */
3558         {
3559            png_bytep first_row = png_voidcast(png_bytep, display->first_row);
3560            ptrdiff_t step_row = display->row_bytes;
3561
3562            for (pass = 0; pass < passes; ++pass)
3563            {
3564               png_bytep        row = png_voidcast(png_bytep,
3565                                                   display->first_row);
3566               unsigned int     startx, stepx, stepy;
3567               png_uint_32      y;
3568
3569               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3570               {
3571                  /* The row may be empty for a short image: */
3572                  if (PNG_PASS_COLS(width, pass) == 0)
3573                     continue;
3574
3575                  startx = PNG_PASS_START_COL(pass);
3576                  stepx = PNG_PASS_COL_OFFSET(pass);
3577                  y = PNG_PASS_START_ROW(pass);
3578                  stepy = PNG_PASS_ROW_OFFSET(pass);
3579               }
3580
3581               else
3582               {
3583                  y = 0;
3584                  startx = 0;
3585                  stepx = stepy = 1;
3586               }
3587
3588               if (display->background == NULL)
3589               {
3590                  for (; y<height; y += stepy)
3591                  {
3592                     png_bytep inrow = png_voidcast(png_bytep,
3593                        display->local_row);
3594                     png_bytep outrow = first_row + y * step_row;
3595                     png_const_bytep end_row = outrow + width;
3596
3597                     /* Read the row, which is packed: */
3598                     png_read_row(png_ptr, inrow, NULL);
3599
3600                     /* Now do the composition on each pixel in this row. */
3601                     outrow += startx;
3602                     for (; outrow < end_row; outrow += stepx)
3603                     {
3604                        png_byte alpha = inrow[1];
3605
3606                        if (alpha > 0) /* else no change to the output */
3607                        {
3608                           png_uint_32 component = inrow[0];
3609
3610                           if (alpha < 255) /* else just use component */
3611                           {
3612                              /* Since PNG_OPTIMIZED_ALPHA was not set it is
3613                               * necessary to invert the sRGB transfer
3614                               * function and multiply the alpha out.
3615                               */
3616                              component = png_sRGB_table[component] * alpha;
3617                              component += png_sRGB_table[outrow[0]] *
3618                                 (255-alpha);
3619                              component = PNG_sRGB_FROM_LINEAR(component);
3620                           }
3621
3622                           outrow[0] = (png_byte)component;
3623                        }
3624
3625                        inrow += 2; /* gray and alpha channel */
3626                     }
3627                  }
3628               }
3629
3630               else /* constant background value */
3631               {
3632                  png_byte background8 = display->background->green;
3633                  png_uint_16 background = png_sRGB_table[background8];
3634
3635                  for (; y<height; y += stepy)
3636                  {
3637                     png_bytep inrow = png_voidcast(png_bytep,
3638                        display->local_row);
3639                     png_bytep outrow = first_row + y * step_row;
3640                     png_const_bytep end_row = outrow + width;
3641
3642                     /* Read the row, which is packed: */
3643                     png_read_row(png_ptr, inrow, NULL);
3644
3645                     /* Now do the composition on each pixel in this row. */
3646                     outrow += startx;
3647                     for (; outrow < end_row; outrow += stepx)
3648                     {
3649                        png_byte alpha = inrow[1];
3650
3651                        if (alpha > 0) /* else use background */
3652                        {
3653                           png_uint_32 component = inrow[0];
3654
3655                           if (alpha < 255) /* else just use component */
3656                           {
3657                              component = png_sRGB_table[component] * alpha;
3658                              component += background * (255-alpha);
3659                              component = PNG_sRGB_FROM_LINEAR(component);
3660                           }
3661
3662                           outrow[0] = (png_byte)component;
3663                        }
3664
3665                        else
3666                           outrow[0] = background8;
3667
3668                        inrow += 2; /* gray and alpha channel */
3669                     }
3670
3671                     row += display->row_bytes;
3672                  }
3673               }
3674            }
3675         }
3676         break;
3677
3678      case 16:
3679         /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must
3680          * still be done and, maybe, the alpha channel removed.  This code also
3681          * handles the alpha-first option.
3682          */
3683         {
3684            png_uint_16p first_row = png_voidcast(png_uint_16p,
3685               display->first_row);
3686            /* The division by two is safe because the caller passed in a
3687             * stride which was multiplied by 2 (below) to get row_bytes.
3688             */
3689            ptrdiff_t    step_row = display->row_bytes / 2;
3690            int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
3691            unsigned int outchannels = 1+preserve_alpha;
3692            int swap_alpha = 0;
3693
3694#           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
3695               if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST))
3696                  swap_alpha = 1;
3697#           endif
3698
3699            for (pass = 0; pass < passes; ++pass)
3700            {
3701               unsigned int     startx, stepx, stepy;
3702               png_uint_32      y;
3703
3704               /* The 'x' start and step are adjusted to output components here.
3705                */
3706               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3707               {
3708                  /* The row may be empty for a short image: */
3709                  if (PNG_PASS_COLS(width, pass) == 0)
3710                     continue;
3711
3712                  startx = PNG_PASS_START_COL(pass) * outchannels;
3713                  stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;
3714                  y = PNG_PASS_START_ROW(pass);
3715                  stepy = PNG_PASS_ROW_OFFSET(pass);
3716               }
3717
3718               else
3719               {
3720                  y = 0;
3721                  startx = 0;
3722                  stepx = outchannels;
3723                  stepy = 1;
3724               }
3725
3726               for (; y<height; y += stepy)
3727               {
3728                  png_const_uint_16p inrow;
3729                  png_uint_16p outrow = first_row + y*step_row;
3730                  png_uint_16p end_row = outrow + width * outchannels;
3731
3732                  /* Read the row, which is packed: */
3733                  png_read_row(png_ptr, png_voidcast(png_bytep,
3734                     display->local_row), NULL);
3735                  inrow = png_voidcast(png_const_uint_16p, display->local_row);
3736
3737                  /* Now do the pre-multiplication on each pixel in this row.
3738                   */
3739                  outrow += startx;
3740                  for (; outrow < end_row; outrow += stepx)
3741                  {
3742                     png_uint_32 component = inrow[0];
3743                     png_uint_16 alpha = inrow[1];
3744
3745                     if (alpha > 0) /* else 0 */
3746                     {
3747                        if (alpha < 65535) /* else just use component */
3748                        {
3749                           component *= alpha;
3750                           component += 32767;
3751                           component /= 65535;
3752                        }
3753                     }
3754
3755                     else
3756                        component = 0;
3757
3758                     outrow[swap_alpha] = (png_uint_16)component;
3759                     if (preserve_alpha)
3760                        outrow[1 ^ swap_alpha] = alpha;
3761
3762                     inrow += 2; /* components and alpha channel */
3763                  }
3764               }
3765            }
3766         }
3767         break;
3768   }
3769
3770   return 1;
3771}
3772
3773/* The guts of png_image_finish_read as a png_safe_execute callback. */
3774static int
3775png_image_read_direct(png_voidp argument)
3776{
3777   png_image_read_control *display = png_voidcast(png_image_read_control*,
3778      argument);
3779   png_imagep image = display->image;
3780   png_structrp png_ptr = image->opaque->png_ptr;
3781   png_inforp info_ptr = image->opaque->info_ptr;
3782
3783   png_uint_32 format = image->format;
3784   int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
3785   int do_local_compose = 0;
3786   int do_local_background = 0; /* to avoid double gamma correction bug */
3787   int passes = 0;
3788
3789   /* Add transforms to ensure the correct output format is produced then check
3790    * that the required implementation support is there.  Always expand; always
3791    * need 8 bits minimum, no palette and expanded tRNS.
3792    */
3793   png_set_expand(png_ptr);
3794
3795   /* Now check the format to see if it was modified. */
3796   {
3797      png_uint_32 base_format = png_image_format(png_ptr) &
3798         ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;
3799      png_uint_32 change = format ^ base_format;
3800      png_fixed_point output_gamma;
3801      int mode; /* alpha mode */
3802
3803      /* Do this first so that we have a record if rgb to gray is happening. */
3804      if (change & PNG_FORMAT_FLAG_COLOR)
3805      {
3806         /* gray<->color transformation required. */
3807         if (format & PNG_FORMAT_FLAG_COLOR)
3808            png_set_gray_to_rgb(png_ptr);
3809
3810         else
3811         {
3812            /* libpng can't do both rgb to gray and
3813             * background/pre-multiplication if there is also significant gamma
3814             * correction, because both operations require linear colors and
3815             * the code only supports one transform doing the gamma correction.
3816             * Handle this by doing the pre-multiplication or background
3817             * operation in this code, if necessary.
3818             *
3819             * TODO: fix this by rewriting pngrtran.c (!)
3820             *
3821             * For the moment (given that fixing this in pngrtran.c is an
3822             * enormous change) 'do_local_background' is used to indicate that
3823             * the problem exists.
3824             */
3825            if (base_format & PNG_FORMAT_FLAG_ALPHA)
3826               do_local_background = 1/*maybe*/;
3827
3828            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
3829               PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
3830         }
3831
3832         change &= ~PNG_FORMAT_FLAG_COLOR;
3833      }
3834
3835      /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
3836       */
3837      {
3838         png_fixed_point input_gamma_default;
3839
3840         if ((base_format & PNG_FORMAT_FLAG_LINEAR) &&
3841            (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
3842            input_gamma_default = PNG_GAMMA_LINEAR;
3843         else
3844            input_gamma_default = PNG_DEFAULT_sRGB;
3845
3846         /* Call png_set_alpha_mode to set the default for the input gamma; the
3847          * output gamma is set by a second call below.
3848          */
3849         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
3850      }
3851
3852      if (linear)
3853      {
3854         /* If there *is* an alpha channel in the input it must be multiplied
3855          * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
3856          */
3857         if (base_format & PNG_FORMAT_FLAG_ALPHA)
3858            mode = PNG_ALPHA_STANDARD; /* associated alpha */
3859
3860         else
3861            mode = PNG_ALPHA_PNG;
3862
3863         output_gamma = PNG_GAMMA_LINEAR;
3864      }
3865
3866      else
3867      {
3868         mode = PNG_ALPHA_PNG;
3869         output_gamma = PNG_DEFAULT_sRGB;
3870      }
3871
3872      /* If 'do_local_background' is set check for the presence of gamma
3873       * correction; this is part of the work-round for the libpng bug
3874       * described above.
3875       *
3876       * TODO: fix libpng and remove this.
3877       */
3878      if (do_local_background)
3879      {
3880         png_fixed_point gtest;
3881
3882         /* This is 'png_gamma_threshold' from pngrtran.c; the test used for
3883          * gamma correction, the screen gamma hasn't been set on png_struct
3884          * yet; it's set below.  png_struct::gamma, however, is set to the
3885          * final value.
3886          */
3887         if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
3888               PNG_FP_1) && !png_gamma_significant(gtest))
3889            do_local_background = 0;
3890
3891         else if (mode == PNG_ALPHA_STANDARD)
3892         {
3893            do_local_background = 2/*required*/;
3894            mode = PNG_ALPHA_PNG; /* prevent libpng doing it */
3895         }
3896
3897         /* else leave as 1 for the checks below */
3898      }
3899
3900      /* If the bit-depth changes then handle that here. */
3901      if (change & PNG_FORMAT_FLAG_LINEAR)
3902      {
3903         if (linear /*16-bit output*/)
3904            png_set_expand_16(png_ptr);
3905
3906         else /* 8-bit output */
3907            png_set_scale_16(png_ptr);
3908
3909         change &= ~PNG_FORMAT_FLAG_LINEAR;
3910      }
3911
3912      /* Now the background/alpha channel changes. */
3913      if (change & PNG_FORMAT_FLAG_ALPHA)
3914      {
3915         /* Removing an alpha channel requires composition for the 8-bit
3916          * formats; for the 16-bit it is already done, above, by the
3917          * pre-multiplication and the channel just needs to be stripped.
3918          */
3919         if (base_format & PNG_FORMAT_FLAG_ALPHA)
3920         {
3921            /* If RGB->gray is happening the alpha channel must be left and the
3922             * operation completed locally.
3923             *
3924             * TODO: fix libpng and remove this.
3925             */
3926            if (do_local_background)
3927               do_local_background = 2/*required*/;
3928
3929            /* 16-bit output: just remove the channel */
3930            else if (linear) /* compose on black (well, pre-multiply) */
3931               png_set_strip_alpha(png_ptr);
3932
3933            /* 8-bit output: do an appropriate compose */
3934            else if (display->background != NULL)
3935            {
3936               png_color_16 c;
3937
3938               c.index = 0; /*unused*/
3939               c.red = display->background->red;
3940               c.green = display->background->green;
3941               c.blue = display->background->blue;
3942               c.gray = display->background->green;
3943
3944               /* This is always an 8-bit sRGB value, using the 'green' channel
3945                * for gray is much better than calculating the luminance here;
3946                * we can get off-by-one errors in that calculation relative to
3947                * the app expectations and that will show up in transparent
3948                * pixels.
3949                */
3950               png_set_background_fixed(png_ptr, &c,
3951                  PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
3952                  0/*gamma: not used*/);
3953            }
3954
3955            else /* compose on row: implemented below. */
3956            {
3957               do_local_compose = 1;
3958               /* This leaves the alpha channel in the output, so it has to be
3959                * removed by the code below.  Set the encoding to the 'OPTIMIZE'
3960                * one so the code only has to hack on the pixels that require
3961                * composition.
3962                */
3963               mode = PNG_ALPHA_OPTIMIZED;
3964            }
3965         }
3966
3967         else /* output needs an alpha channel */
3968         {
3969            /* This is tricky because it happens before the swap operation has
3970             * been accomplished; however, the swap does *not* swap the added
3971             * alpha channel (weird API), so it must be added in the correct
3972             * place.
3973             */
3974            png_uint_32 filler; /* opaque filler */
3975            int where;
3976
3977            if (linear)
3978               filler = 65535;
3979
3980            else
3981               filler = 255;
3982
3983#           ifdef PNG_FORMAT_AFIRST_SUPPORTED
3984               if (format & PNG_FORMAT_FLAG_AFIRST)
3985               {
3986                  where = PNG_FILLER_BEFORE;
3987                  change &= ~PNG_FORMAT_FLAG_AFIRST;
3988               }
3989
3990               else
3991#           endif
3992               where = PNG_FILLER_AFTER;
3993
3994            png_set_add_alpha(png_ptr, filler, where);
3995         }
3996
3997         /* This stops the (irrelevant) call to swap_alpha below. */
3998         change &= ~PNG_FORMAT_FLAG_ALPHA;
3999      }
4000
4001      /* Now set the alpha mode correctly; this is always done, even if there is
4002       * no alpha channel in either the input or the output because it correctly
4003       * sets the output gamma.
4004       */
4005      png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
4006
4007#     ifdef PNG_FORMAT_BGR_SUPPORTED
4008         if (change & PNG_FORMAT_FLAG_BGR)
4009         {
4010            /* Check only the output format; PNG is never BGR; don't do this if
4011             * the output is gray, but fix up the 'format' value in that case.
4012             */
4013            if (format & PNG_FORMAT_FLAG_COLOR)
4014               png_set_bgr(png_ptr);
4015
4016            else
4017               format &= ~PNG_FORMAT_FLAG_BGR;
4018
4019            change &= ~PNG_FORMAT_FLAG_BGR;
4020         }
4021#     endif
4022
4023#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
4024         if (change & PNG_FORMAT_FLAG_AFIRST)
4025         {
4026            /* Only relevant if there is an alpha channel - it's particularly
4027             * important to handle this correctly because do_local_compose may
4028             * be set above and then libpng will keep the alpha channel for this
4029             * code to remove.
4030             */
4031            if (format & PNG_FORMAT_FLAG_ALPHA)
4032            {
4033               /* Disable this if doing a local background,
4034                * TODO: remove this when local background is no longer required.
4035                */
4036               if (do_local_background != 2)
4037                  png_set_swap_alpha(png_ptr);
4038            }
4039
4040            else
4041               format &= ~PNG_FORMAT_FLAG_AFIRST;
4042
4043            change &= ~PNG_FORMAT_FLAG_AFIRST;
4044         }
4045#     endif
4046
4047      /* If the *output* is 16-bit then we need to check for a byte-swap on this
4048       * architecture.
4049       */
4050      if (linear)
4051      {
4052         PNG_CONST png_uint_16 le = 0x0001;
4053
4054         if (*(png_const_bytep)&le)
4055            png_set_swap(png_ptr);
4056      }
4057
4058      /* If change is not now 0 some transformation is missing - error out. */
4059      if (change)
4060         png_error(png_ptr, "png_read_image: unsupported transformation");
4061   }
4062
4063   PNG_SKIP_CHUNKS(png_ptr);
4064
4065   /* Update the 'info' structure and make sure the result is as required; first
4066    * make sure to turn on the interlace handling if it will be required
4067    * (because it can't be turned on *after* the call to png_read_update_info!)
4068    *
4069    * TODO: remove the do_local_background fixup below.
4070    */
4071   if (!do_local_compose && do_local_background != 2)
4072      passes = png_set_interlace_handling(png_ptr);
4073
4074   png_read_update_info(png_ptr, info_ptr);
4075
4076   {
4077      png_uint_32 info_format = 0;
4078
4079      if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
4080         info_format |= PNG_FORMAT_FLAG_COLOR;
4081
4082      if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
4083      {
4084         /* do_local_compose removes this channel below. */
4085         if (!do_local_compose)
4086         {
4087            /* do_local_background does the same if required. */
4088            if (do_local_background != 2 ||
4089               (format & PNG_FORMAT_FLAG_ALPHA) != 0)
4090               info_format |= PNG_FORMAT_FLAG_ALPHA;
4091         }
4092      }
4093
4094      else if (do_local_compose) /* internal error */
4095         png_error(png_ptr, "png_image_read: alpha channel lost");
4096
4097      if (info_ptr->bit_depth == 16)
4098         info_format |= PNG_FORMAT_FLAG_LINEAR;
4099
4100#     ifdef PNG_FORMAT_BGR_SUPPORTED
4101         if (png_ptr->transformations & PNG_BGR)
4102            info_format |= PNG_FORMAT_FLAG_BGR;
4103#     endif
4104
4105#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
4106         if (do_local_background == 2)
4107         {
4108            if (format & PNG_FORMAT_FLAG_AFIRST)
4109               info_format |= PNG_FORMAT_FLAG_AFIRST;
4110         }
4111
4112         if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||
4113            ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
4114            (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
4115         {
4116            if (do_local_background == 2)
4117               png_error(png_ptr, "unexpected alpha swap transformation");
4118
4119            info_format |= PNG_FORMAT_FLAG_AFIRST;
4120         }
4121#     endif
4122
4123      /* This is actually an internal error. */
4124      if (info_format != format)
4125         png_error(png_ptr, "png_read_image: invalid transformations");
4126   }
4127
4128   /* Now read the rows.  If do_local_compose is set then it is necessary to use
4129    * a local row buffer.  The output will be GA, RGBA or BGRA and must be
4130    * converted to G, RGB or BGR as appropriate.  The 'local_row' member of the
4131    * display acts as a flag.
4132    */
4133   {
4134      png_voidp first_row = display->buffer;
4135      ptrdiff_t row_bytes = display->row_stride;
4136
4137      if (linear)
4138         row_bytes *= 2;
4139
4140      /* The following expression is designed to work correctly whether it gives
4141       * a signed or an unsigned result.
4142       */
4143      if (row_bytes < 0)
4144      {
4145         char *ptr = png_voidcast(char*, first_row);
4146         ptr += (image->height-1) * (-row_bytes);
4147         first_row = png_voidcast(png_voidp, ptr);
4148      }
4149
4150      display->first_row = first_row;
4151      display->row_bytes = row_bytes;
4152   }
4153
4154   if (do_local_compose)
4155   {
4156      int result;
4157      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
4158
4159      display->local_row = row;
4160      result = png_safe_execute(image, png_image_read_composite, display);
4161      display->local_row = NULL;
4162      png_free(png_ptr, row);
4163
4164      return result;
4165   }
4166
4167   else if (do_local_background == 2)
4168   {
4169      int result;
4170      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
4171
4172      display->local_row = row;
4173      result = png_safe_execute(image, png_image_read_background, display);
4174      display->local_row = NULL;
4175      png_free(png_ptr, row);
4176
4177      return result;
4178   }
4179
4180   else
4181   {
4182      png_alloc_size_t row_bytes = display->row_bytes;
4183
4184      while (--passes >= 0)
4185      {
4186         png_uint_32      y = image->height;
4187         png_bytep        row = png_voidcast(png_bytep, display->first_row);
4188
4189         while (y-- > 0)
4190         {
4191            png_read_row(png_ptr, row, NULL);
4192            row += row_bytes;
4193         }
4194      }
4195
4196      return 1;
4197   }
4198}
4199
4200int PNGAPI
4201png_image_finish_read(png_imagep image, png_const_colorp background,
4202   void *buffer, png_int_32 row_stride, void *colormap)
4203{
4204   if (image != NULL && image->version == PNG_IMAGE_VERSION)
4205   {
4206      png_uint_32 check;
4207
4208      if (row_stride == 0)
4209         row_stride = PNG_IMAGE_ROW_STRIDE(*image);
4210
4211      if (row_stride < 0)
4212         check = -row_stride;
4213
4214      else
4215         check = row_stride;
4216
4217      if (image->opaque != NULL && buffer != NULL &&
4218         check >= PNG_IMAGE_ROW_STRIDE(*image))
4219      {
4220         if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
4221            (image->colormap_entries > 0 && colormap != NULL))
4222         {
4223            int result;
4224            png_image_read_control display;
4225
4226            memset(&display, 0, (sizeof display));
4227            display.image = image;
4228            display.buffer = buffer;
4229            display.row_stride = row_stride;
4230            display.colormap = colormap;
4231            display.background = background;
4232            display.local_row = NULL;
4233
4234            /* Choose the correct 'end' routine; for the color-map case all the
4235             * setup has already been done.
4236             */
4237            if (image->format & PNG_FORMAT_FLAG_COLORMAP)
4238               result =
4239                  png_safe_execute(image, png_image_read_colormap, &display) &&
4240                  png_safe_execute(image, png_image_read_colormapped, &display);
4241
4242            else
4243               result =
4244                  png_safe_execute(image, png_image_read_direct, &display);
4245
4246            png_image_free(image);
4247            return result;
4248         }
4249
4250         else
4251            return png_image_error(image,
4252               "png_image_finish_read[color-map]: no color-map");
4253      }
4254
4255      else
4256         return png_image_error(image,
4257            "png_image_finish_read: invalid argument");
4258   }
4259
4260   else if (image != NULL)
4261      return png_image_error(image,
4262         "png_image_finish_read: damaged PNG_IMAGE_VERSION");
4263
4264   return 0;
4265}
4266
4267#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
4268#endif /* PNG_READ_SUPPORTED */
4269