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