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