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