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