Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: third_party/lpng_v163/pngread.c

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

Powered by Google App Engine
This is Rietveld 408576698