VirtualBox

source: vbox/trunk/src/libs/libpng-1.6.45/pngread.c@ 107861

Last change on this file since 107861 was 107813, checked in by vboxsync, 5 weeks ago

libpng-1.6.45: Applied and adjusted our libpng changes to 1.6.45. bugref:8515

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette