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