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