1 2 /* pngvalid.c - validate libpng by constructing then reading png files. 3 * 4 * Last changed in libpng 1.6.31 [July 27, 2017] 5 * Copyright (c) 2014-2017 John Cunningham Bowler 6 * 7 * This code is released under the libpng license. 8 * For conditions of distribution and use, see the disclaimer 9 * and license in png.h 10 * 11 * NOTES: 12 * This is a C program that is intended to be linked against libpng. It 13 * generates bitmaps internally, stores them as PNG files (using the 14 * sequential write code) then reads them back (using the sequential 15 * read code) and validates that the result has the correct data. 16 * 17 * The program can be modified and extended to test the correctness of 18 * transformations performed by libpng. 19 */ 20 21 #define _POSIX_SOURCE 1 22 #define _ISOC99_SOURCE 1 /* For floating point */ 23 #define _GNU_SOURCE 1 /* For the floating point exception extension */ 24 25 #include <signal.h> 26 #include <stdio.h> 27 28 #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) 29 # include <config.h> 30 #endif 31 32 #ifdef HAVE_FEENABLEEXCEPT /* from config.h, if included */ 33 # include <fenv.h> 34 #endif 35 36 #ifndef FE_DIVBYZERO 37 # define FE_DIVBYZERO 0 38 #endif 39 #ifndef FE_INVALID 40 # define FE_INVALID 0 41 #endif 42 #ifndef FE_OVERFLOW 43 # define FE_OVERFLOW 0 44 #endif 45 46 /* Define the following to use this test against your installed libpng, rather 47 * than the one being built here: 48 */ 49 #ifdef PNG_FREESTANDING_TESTS 50 # include <png.h> 51 #else 52 # include "../../png.h" 53 #endif 54 55 #ifdef PNG_ZLIB_HEADER 56 # include PNG_ZLIB_HEADER 57 #else 58 # include <zlib.h> /* For crc32 */ 59 #endif 60 61 /* 1.6.1 added support for the configure test harness, which uses 77 to indicate 62 * a skipped test, in earlier versions we need to succeed on a skipped test, so: 63 */ 64 #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H) 65 # define SKIP 77 66 #else 67 # define SKIP 0 68 #endif 69 70 /* pngvalid requires write support and one of the fixed or floating point APIs. 71 */ 72 #if defined(PNG_WRITE_SUPPORTED) &&\ 73 (defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED)) 74 75 #if PNG_LIBPNG_VER < 10500 76 /* This deliberately lacks the const. */ 77 typedef png_byte *png_const_bytep; 78 79 /* This is copied from 1.5.1 png.h: */ 80 #define PNG_INTERLACE_ADAM7_PASSES 7 81 #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) 82 #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) 83 #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) 84 #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) 85 #define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\ 86 -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass)) 87 #define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\ 88 -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass)) 89 #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ 90 (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass)) 91 #define PNG_COL_FROM_PASS_COL(xIn, pass) \ 92 (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass)) 93 #define PNG_PASS_MASK(pass,off) ( \ 94 ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \ 95 ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) 96 #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ 97 ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) 98 #define PNG_COL_IN_INTERLACE_PASS(x, pass) \ 99 ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) 100 101 /* These are needed too for the default build: */ 102 #define PNG_WRITE_16BIT_SUPPORTED 103 #define PNG_READ_16BIT_SUPPORTED 104 105 /* This comes from pnglibconf.h afer 1.5: */ 106 #define PNG_FP_1 100000 107 #define PNG_GAMMA_THRESHOLD_FIXED\ 108 ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1)) 109 #endif 110 111 #if PNG_LIBPNG_VER < 10600 112 /* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be 113 * compiled against earlier versions. 114 */ 115 # define png_const_structp png_structp 116 #endif 117 118 #ifndef RELEASE_BUILD 119 /* RELEASE_BUILD is true for releases and release candidates: */ 120 # define RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) 121 #endif 122 #if RELEASE_BUILD 123 # define debugonly(something) 124 #else /* !RELEASE_BUILD */ 125 # define debugonly(something) something 126 #endif /* !RELEASE_BUILD */ 127 128 #include <float.h> /* For floating point constants */ 129 #include <stdlib.h> /* For malloc */ 130 #include <string.h> /* For memcpy, memset */ 131 #include <math.h> /* For floor */ 132 133 /* Convenience macros. */ 134 #define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d)) 135 #define CHUNK_IHDR CHUNK(73,72,68,82) 136 #define CHUNK_PLTE CHUNK(80,76,84,69) 137 #define CHUNK_IDAT CHUNK(73,68,65,84) 138 #define CHUNK_IEND CHUNK(73,69,78,68) 139 #define CHUNK_cHRM CHUNK(99,72,82,77) 140 #define CHUNK_gAMA CHUNK(103,65,77,65) 141 #define CHUNK_sBIT CHUNK(115,66,73,84) 142 #define CHUNK_sRGB CHUNK(115,82,71,66) 143 144 /* Unused formal parameter errors are removed using the following macro which is 145 * expected to have no bad effects on performance. 146 */ 147 #ifndef UNUSED 148 # if defined(__GNUC__) || defined(_MSC_VER) 149 # define UNUSED(param) (void)param; 150 # else 151 # define UNUSED(param) 152 # endif 153 #endif 154 155 /***************************** EXCEPTION HANDLING *****************************/ 156 #ifdef PNG_FREESTANDING_TESTS 157 # include <cexcept.h> 158 #else 159 # include "../visupng/cexcept.h" 160 #endif 161 162 #ifdef __cplusplus 163 # define this not_the_cpp_this 164 # define new not_the_cpp_new 165 # define voidcast(type, value) static_cast<type>(value) 166 #else 167 # define voidcast(type, value) (value) 168 #endif /* __cplusplus */ 169 170 struct png_store; 171 define_exception_type(struct png_store*); 172 173 /* The following are macros to reduce typing everywhere where the well known 174 * name 'the_exception_context' must be defined. 175 */ 176 #define anon_context(ps) struct exception_context *the_exception_context = \ 177 &(ps)->exception_context 178 #define context(ps,fault) anon_context(ps); png_store *fault 179 180 /* This macro returns the number of elements in an array as an (unsigned int), 181 * it is necessary to avoid the inability of certain versions of GCC to use 182 * the value of a compile-time constant when performing range checks. It must 183 * be passed an array name. 184 */ 185 #define ARRAY_SIZE(a) ((unsigned int)((sizeof (a))/(sizeof (a)[0]))) 186 187 /* GCC BUG 66447 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66447) requires 188 * some broken GCC versions to be fixed up to avoid invalid whining about auto 189 * variables that are *not* changed within the scope of a setjmp being changed. 190 * 191 * Feel free to extend the list of broken versions. 192 */ 193 #define is_gnu(major,minor)\ 194 (defined __GNUC__) && __GNUC__ == (major) && __GNUC_MINOR__ == (minor) 195 #define is_gnu_patch(major,minor,patch)\ 196 is_gnu(major,minor) && __GNUC_PATCHLEVEL__ == 0 197 /* For the moment just do it always; all versions of GCC seem to be broken: */ 198 #ifdef __GNUC__ 199 const void * volatile make_volatile_for_gnu; 200 # define gnu_volatile(x) make_volatile_for_gnu = &x; 201 #else /* !GNUC broken versions */ 202 # define gnu_volatile(x) 203 #endif /* !GNUC broken versions */ 204 205 /******************************* UTILITIES ************************************/ 206 /* Error handling is particularly problematic in production code - error 207 * handlers often themselves have bugs which lead to programs that detect 208 * minor errors crashing. The following functions deal with one very 209 * common class of errors in error handlers - attempting to format error or 210 * warning messages into buffers that are too small. 211 */ 212 static size_t safecat(char *buffer, size_t bufsize, size_t pos, 213 const char *cat) 214 { 215 while (pos < bufsize && cat != NULL && *cat != 0) 216 buffer[pos++] = *cat++; 217 218 if (pos >= bufsize) 219 pos = bufsize-1; 220 221 buffer[pos] = 0; 222 return pos; 223 } 224 225 static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n) 226 { 227 char number[64]; 228 sprintf(number, "%d", n); 229 return safecat(buffer, bufsize, pos, number); 230 } 231 232 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 233 static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d, 234 int precision) 235 { 236 char number[64]; 237 sprintf(number, "%.*f", precision, d); 238 return safecat(buffer, bufsize, pos, number); 239 } 240 #endif 241 242 static const char invalid[] = "invalid"; 243 static const char sep[] = ": "; 244 245 static const char *colour_types[8] = 246 { 247 "grayscale", invalid, "truecolour", "indexed-colour", 248 "grayscale with alpha", invalid, "truecolour with alpha", invalid 249 }; 250 251 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 252 /* Convert a double precision value to fixed point. */ 253 static png_fixed_point 254 fix(double d) 255 { 256 d = floor(d * PNG_FP_1 + .5); 257 return (png_fixed_point)d; 258 } 259 #endif /* PNG_READ_SUPPORTED */ 260 261 /* Generate random bytes. This uses a boring repeatable algorithm and it 262 * is implemented here so that it gives the same set of numbers on every 263 * architecture. It's a linear congruential generator (Knuth or Sedgewick 264 * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and 265 * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise 266 * Generation.) 267 */ 268 static void 269 make_random_bytes(png_uint_32* seed, void* pv, size_t size) 270 { 271 png_uint_32 u0 = seed[0], u1 = seed[1]; 272 png_bytep bytes = voidcast(png_bytep, pv); 273 274 /* There are thirty three bits, the next bit in the sequence is bit-33 XOR 275 * bit-20. The top 1 bit is in u1, the bottom 32 are in u0. 276 */ 277 size_t i; 278 for (i=0; i<size; ++i) 279 { 280 /* First generate 8 new bits then shift them in at the end. */ 281 png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff; 282 u1 <<= 8; 283 u1 |= u0 >> 24; 284 u0 <<= 8; 285 u0 |= u; 286 *bytes++ = (png_byte)u; 287 } 288 289 seed[0] = u0; 290 seed[1] = u1; 291 } 292 293 static void 294 make_four_random_bytes(png_uint_32* seed, png_bytep bytes) 295 { 296 make_random_bytes(seed, bytes, 4); 297 } 298 299 #if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\ 300 defined PNG_WRITE_FILTER_SUPPORTED 301 static void 302 randomize(void *pv, size_t size) 303 { 304 static png_uint_32 random_seed[2] = {0x56789abc, 0xd}; 305 make_random_bytes(random_seed, pv, size); 306 } 307 308 #define R8(this) randomize(&(this), sizeof (this)) 309 310 #ifdef PNG_READ_SUPPORTED 311 static png_byte 312 random_byte(void) 313 { 314 unsigned char b1[1]; 315 randomize(b1, sizeof b1); 316 return b1[0]; 317 } 318 #endif /* READ */ 319 320 static png_uint_16 321 random_u16(void) 322 { 323 unsigned char b2[2]; 324 randomize(b2, sizeof b2); 325 return png_get_uint_16(b2); 326 } 327 328 #if defined PNG_READ_RGB_TO_GRAY_SUPPORTED ||\ 329 defined PNG_READ_FILLER_SUPPORTED 330 static png_uint_32 331 random_u32(void) 332 { 333 unsigned char b4[4]; 334 randomize(b4, sizeof b4); 335 return png_get_uint_32(b4); 336 } 337 #endif /* READ_FILLER || READ_RGB_TO_GRAY */ 338 339 #endif /* READ || WRITE_tRNS || WRITE_FILTER */ 340 341 #if defined PNG_READ_TRANSFORMS_SUPPORTED ||\ 342 defined PNG_WRITE_FILTER_SUPPORTED 343 static unsigned int 344 random_mod(unsigned int max) 345 { 346 return random_u16() % max; /* 0 .. max-1 */ 347 } 348 #endif /* READ_TRANSFORMS || WRITE_FILTER */ 349 350 #if (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) ||\ 351 (defined PNG_READ_FILLER_SUPPORTED) 352 static int 353 random_choice(void) 354 { 355 return random_byte() & 1; 356 } 357 #endif /* READ_RGB_TO_GRAY || READ_FILLER */ 358 359 /* A numeric ID based on PNG file characteristics. The 'do_interlace' field 360 * simply records whether pngvalid did the interlace itself or whether it 361 * was done by libpng. Width and height must be less than 256. 'palette' is an 362 * index of the palette to use for formats with a palette otherwise a boolean 363 * indicating if a tRNS chunk was generated. 364 */ 365 #define FILEID(col, depth, palette, interlace, width, height, do_interlace) \ 366 ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \ 367 (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24))) 368 369 #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U)) 370 #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU)) 371 #define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f) 372 #define INTERLACE_FROM_ID(id) ((png_byte)(((id) >> 13) & 0x3)) 373 #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1)) 374 #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff) 375 #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff) 376 377 /* Utility to construct a standard name for a standard image. */ 378 static size_t 379 standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type, 380 int bit_depth, unsigned int npalette, int interlace_type, 381 png_uint_32 w, png_uint_32 h, int do_interlace) 382 { 383 pos = safecat(buffer, bufsize, pos, colour_types[colour_type]); 384 if (colour_type == 3) /* must have a palette */ 385 { 386 pos = safecat(buffer, bufsize, pos, "["); 387 pos = safecatn(buffer, bufsize, pos, npalette); 388 pos = safecat(buffer, bufsize, pos, "]"); 389 } 390 391 else if (npalette != 0) 392 pos = safecat(buffer, bufsize, pos, "+tRNS"); 393 394 pos = safecat(buffer, bufsize, pos, " "); 395 pos = safecatn(buffer, bufsize, pos, bit_depth); 396 pos = safecat(buffer, bufsize, pos, " bit"); 397 398 if (interlace_type != PNG_INTERLACE_NONE) 399 { 400 pos = safecat(buffer, bufsize, pos, " interlaced"); 401 if (do_interlace) 402 pos = safecat(buffer, bufsize, pos, "(pngvalid)"); 403 else 404 pos = safecat(buffer, bufsize, pos, "(libpng)"); 405 } 406 407 if (w > 0 || h > 0) 408 { 409 pos = safecat(buffer, bufsize, pos, " "); 410 pos = safecatn(buffer, bufsize, pos, w); 411 pos = safecat(buffer, bufsize, pos, "x"); 412 pos = safecatn(buffer, bufsize, pos, h); 413 } 414 415 return pos; 416 } 417 418 static size_t 419 standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id) 420 { 421 return standard_name(buffer, bufsize, pos, COL_FROM_ID(id), 422 DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id), 423 WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id)); 424 } 425 426 /* Convenience API and defines to list valid formats. Note that 16 bit read and 427 * write support is required to do 16 bit read tests (we must be able to make a 428 * 16 bit image to test!) 429 */ 430 #ifdef PNG_WRITE_16BIT_SUPPORTED 431 # define WRITE_BDHI 4 432 # ifdef PNG_READ_16BIT_SUPPORTED 433 # define READ_BDHI 4 434 # define DO_16BIT 435 # endif 436 #else 437 # define WRITE_BDHI 3 438 #endif 439 #ifndef DO_16BIT 440 # define READ_BDHI 3 441 #endif 442 443 /* The following defines the number of different palettes to generate for 444 * each log bit depth of a colour type 3 standard image. 445 */ 446 #define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U) 447 448 static int 449 next_format(png_bytep colour_type, png_bytep bit_depth, 450 unsigned int* palette_number, int low_depth_gray, int tRNS) 451 { 452 if (*bit_depth == 0) 453 { 454 *colour_type = 0; 455 if (low_depth_gray) 456 *bit_depth = 1; 457 else 458 *bit_depth = 8; 459 *palette_number = 0; 460 return 1; 461 } 462 463 if (*colour_type < 4/*no alpha channel*/) 464 { 465 /* Add multiple palettes for colour type 3, one image with tRNS 466 * and one without for other non-alpha formats: 467 */ 468 unsigned int pn = ++*palette_number; 469 png_byte ct = *colour_type; 470 471 if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) || 472 (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth))) 473 return 1; 474 475 /* No: next bit depth */ 476 *palette_number = 0; 477 } 478 479 *bit_depth = (png_byte)(*bit_depth << 1); 480 481 /* Palette images are restricted to 8 bit depth */ 482 if (*bit_depth <= 8 483 #ifdef DO_16BIT 484 || (*colour_type != 3 && *bit_depth <= 16) 485 #endif 486 ) 487 return 1; 488 489 /* Move to the next color type, or return 0 at the end. */ 490 switch (*colour_type) 491 { 492 case 0: 493 *colour_type = 2; 494 *bit_depth = 8; 495 return 1; 496 497 case 2: 498 *colour_type = 3; 499 *bit_depth = 1; 500 return 1; 501 502 case 3: 503 *colour_type = 4; 504 *bit_depth = 8; 505 return 1; 506 507 case 4: 508 *colour_type = 6; 509 *bit_depth = 8; 510 return 1; 511 512 default: 513 return 0; 514 } 515 } 516 517 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 518 static unsigned int 519 sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth, 520 png_uint_32 x, unsigned int sample_index, int swap16, int littleendian) 521 { 522 png_uint_32 bit_index, result; 523 524 /* Find a sample index for the desired sample: */ 525 x *= bit_depth; 526 bit_index = x; 527 528 if ((colour_type & 1) == 0) /* !palette */ 529 { 530 if (colour_type & 2) 531 bit_index *= 3; 532 533 if (colour_type & 4) 534 bit_index += x; /* Alpha channel */ 535 536 /* Multiple channels; select one: */ 537 if (colour_type & (2+4)) 538 bit_index += sample_index * bit_depth; 539 } 540 541 /* Return the sample from the row as an integer. */ 542 row += bit_index >> 3; 543 result = *row; 544 545 if (bit_depth == 8) 546 return result; 547 548 else if (bit_depth > 8) 549 { 550 if (swap16) 551 return (*++row << 8) + result; 552 else 553 return (result << 8) + *++row; 554 } 555 556 /* Less than 8 bits per sample. By default PNG has the big end of 557 * the egg on the left of the screen, but if littleendian is set 558 * then the big end is on the right. 559 */ 560 bit_index &= 7; 561 562 if (!littleendian) 563 bit_index = 8-bit_index-bit_depth; 564 565 return (result >> bit_index) & ((1U<<bit_depth)-1); 566 } 567 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 568 569 /* Copy a single pixel, of a given size, from one buffer to another - 570 * while this is basically bit addressed there is an implicit assumption 571 * that pixels 8 or more bits in size are byte aligned and that pixels 572 * do not otherwise cross byte boundaries. (This is, so far as I know, 573 * universally true in bitmap computer graphics. [JCB 20101212]) 574 * 575 * NOTE: The to and from buffers may be the same. 576 */ 577 static void 578 pixel_copy(png_bytep toBuffer, png_uint_32 toIndex, 579 png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize, 580 int littleendian) 581 { 582 /* Assume we can multiply by 'size' without overflow because we are 583 * just working in a single buffer. 584 */ 585 toIndex *= pixelSize; 586 fromIndex *= pixelSize; 587 if (pixelSize < 8) /* Sub-byte */ 588 { 589 /* Mask to select the location of the copied pixel: */ 590 unsigned int destMask = ((1U<<pixelSize)-1) << 591 (littleendian ? toIndex&7 : 8-pixelSize-(toIndex&7)); 592 /* The following read the entire pixels and clears the extra: */ 593 unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask; 594 unsigned int sourceByte = fromBuffer[fromIndex >> 3]; 595 596 /* Don't rely on << or >> supporting '0' here, just in case: */ 597 fromIndex &= 7; 598 if (littleendian) 599 { 600 if (fromIndex > 0) sourceByte >>= fromIndex; 601 if ((toIndex & 7) > 0) sourceByte <<= toIndex & 7; 602 } 603 604 else 605 { 606 if (fromIndex > 0) sourceByte <<= fromIndex; 607 if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7; 608 } 609 610 toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask)); 611 } 612 else /* One or more bytes */ 613 memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3); 614 } 615 616 #ifdef PNG_READ_SUPPORTED 617 /* Copy a complete row of pixels, taking into account potential partial 618 * bytes at the end. 619 */ 620 static void 621 row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth, 622 int littleendian) 623 { 624 memcpy(toBuffer, fromBuffer, bitWidth >> 3); 625 626 if ((bitWidth & 7) != 0) 627 { 628 unsigned int mask; 629 630 toBuffer += bitWidth >> 3; 631 fromBuffer += bitWidth >> 3; 632 if (littleendian) 633 mask = 0xff << (bitWidth & 7); 634 else 635 mask = 0xff >> (bitWidth & 7); 636 *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask)); 637 } 638 } 639 640 /* Compare pixels - they are assumed to start at the first byte in the 641 * given buffers. 642 */ 643 static int 644 pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width) 645 { 646 #if PNG_LIBPNG_VER < 10506 647 if (memcmp(pa, pb, bit_width>>3) == 0) 648 { 649 png_uint_32 p; 650 651 if ((bit_width & 7) == 0) return 0; 652 653 /* Ok, any differences? */ 654 p = pa[bit_width >> 3]; 655 p ^= pb[bit_width >> 3]; 656 657 if (p == 0) return 0; 658 659 /* There are, but they may not be significant, remove the bits 660 * after the end (the low order bits in PNG.) 661 */ 662 bit_width &= 7; 663 p >>= 8-bit_width; 664 665 if (p == 0) return 0; 666 } 667 #else 668 /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing 669 * bits too: 670 */ 671 if (memcmp(pa, pb, (bit_width+7)>>3) == 0) 672 return 0; 673 #endif 674 675 /* Return the index of the changed byte. */ 676 { 677 png_uint_32 where = 0; 678 679 while (pa[where] == pb[where]) ++where; 680 return 1+where; 681 } 682 } 683 #endif /* PNG_READ_SUPPORTED */ 684 685 /*************************** BASIC PNG FILE WRITING ***************************/ 686 /* A png_store takes data from the sequential writer or provides data 687 * to the sequential reader. It can also store the result of a PNG 688 * write for later retrieval. 689 */ 690 #define STORE_BUFFER_SIZE 500 /* arbitrary */ 691 typedef struct png_store_buffer 692 { 693 struct png_store_buffer* prev; /* NOTE: stored in reverse order */ 694 png_byte buffer[STORE_BUFFER_SIZE]; 695 } png_store_buffer; 696 697 #define FILE_NAME_SIZE 64 698 699 typedef struct store_palette_entry /* record of a single palette entry */ 700 { 701 png_byte red; 702 png_byte green; 703 png_byte blue; 704 png_byte alpha; 705 } store_palette_entry, store_palette[256]; 706 707 typedef struct png_store_file 708 { 709 struct png_store_file* next; /* as many as you like... */ 710 char name[FILE_NAME_SIZE]; 711 unsigned int IDAT_bits; /* Number of bits in IDAT size */ 712 png_uint_32 IDAT_size; /* Total size of IDAT data */ 713 png_uint_32 id; /* must be correct (see FILEID) */ 714 png_size_t datacount; /* In this (the last) buffer */ 715 png_store_buffer data; /* Last buffer in file */ 716 int npalette; /* Number of entries in palette */ 717 store_palette_entry* palette; /* May be NULL */ 718 } png_store_file; 719 720 /* The following is a pool of memory allocated by a single libpng read or write 721 * operation. 722 */ 723 typedef struct store_pool 724 { 725 struct png_store *store; /* Back pointer */ 726 struct store_memory *list; /* List of allocated memory */ 727 png_byte mark[4]; /* Before and after data */ 728 729 /* Statistics for this run. */ 730 png_alloc_size_t max; /* Maximum single allocation */ 731 png_alloc_size_t current; /* Current allocation */ 732 png_alloc_size_t limit; /* Highest current allocation */ 733 png_alloc_size_t total; /* Total allocation */ 734 735 /* Overall statistics (retained across successive runs). */ 736 png_alloc_size_t max_max; 737 png_alloc_size_t max_limit; 738 png_alloc_size_t max_total; 739 } store_pool; 740 741 typedef struct png_store 742 { 743 /* For cexcept.h exception handling - simply store one of these; 744 * the context is a self pointer but it may point to a different 745 * png_store (in fact it never does in this program.) 746 */ 747 struct exception_context 748 exception_context; 749 750 unsigned int verbose :1; 751 unsigned int treat_warnings_as_errors :1; 752 unsigned int expect_error :1; 753 unsigned int expect_warning :1; 754 unsigned int saw_warning :1; 755 unsigned int speed :1; 756 unsigned int progressive :1; /* use progressive read */ 757 unsigned int validated :1; /* used as a temporary flag */ 758 int nerrors; 759 int nwarnings; 760 int noptions; /* number of options below: */ 761 struct { 762 unsigned char option; /* option number, 0..30 */ 763 unsigned char setting; /* setting (unset,invalid,on,off) */ 764 } options[16]; 765 char test[128]; /* Name of test */ 766 char error[256]; 767 768 /* Share fields */ 769 png_uint_32 chunklen; /* Length of chunk+overhead (chunkpos >= 8) */ 770 png_uint_32 chunktype;/* Type of chunk (valid if chunkpos >= 4) */ 771 png_uint_32 chunkpos; /* Position in chunk */ 772 png_uint_32 IDAT_size;/* Accumulated IDAT size in .new */ 773 unsigned int IDAT_bits;/* Cache of the file store value */ 774 775 /* Read fields */ 776 png_structp pread; /* Used to read a saved file */ 777 png_infop piread; 778 png_store_file* current; /* Set when reading */ 779 png_store_buffer* next; /* Set when reading */ 780 png_size_t readpos; /* Position in *next */ 781 png_byte* image; /* Buffer for reading interlaced images */ 782 png_size_t cb_image; /* Size of this buffer */ 783 png_size_t cb_row; /* Row size of the image(s) */ 784 uLong IDAT_crc; 785 png_uint_32 IDAT_len; /* Used when re-chunking IDAT chunks */ 786 png_uint_32 IDAT_pos; /* Used when re-chunking IDAT chunks */ 787 png_uint_32 image_h; /* Number of rows in a single image */ 788 store_pool read_memory_pool; 789 790 /* Write fields */ 791 png_store_file* saved; 792 png_structp pwrite; /* Used when writing a new file */ 793 png_infop piwrite; 794 png_size_t writepos; /* Position in .new */ 795 char wname[FILE_NAME_SIZE]; 796 png_store_buffer new; /* The end of the new PNG file being written. */ 797 store_pool write_memory_pool; 798 store_palette_entry* palette; 799 int npalette; 800 } png_store; 801 802 /* Initialization and cleanup */ 803 static void 804 store_pool_mark(png_bytep mark) 805 { 806 static png_uint_32 store_seed[2] = { 0x12345678, 1}; 807 808 make_four_random_bytes(store_seed, mark); 809 } 810 811 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 812 /* Use this for random 32 bit values; this function makes sure the result is 813 * non-zero. 814 */ 815 static png_uint_32 816 random_32(void) 817 { 818 819 for (;;) 820 { 821 png_byte mark[4]; 822 png_uint_32 result; 823 824 store_pool_mark(mark); 825 result = png_get_uint_32(mark); 826 827 if (result != 0) 828 return result; 829 } 830 } 831 #endif /* PNG_READ_SUPPORTED */ 832 833 static void 834 store_pool_init(png_store *ps, store_pool *pool) 835 { 836 memset(pool, 0, sizeof *pool); 837 838 pool->store = ps; 839 pool->list = NULL; 840 pool->max = pool->current = pool->limit = pool->total = 0; 841 pool->max_max = pool->max_limit = pool->max_total = 0; 842 store_pool_mark(pool->mark); 843 } 844 845 static void 846 store_init(png_store* ps) 847 { 848 memset(ps, 0, sizeof *ps); 849 init_exception_context(&ps->exception_context); 850 store_pool_init(ps, &ps->read_memory_pool); 851 store_pool_init(ps, &ps->write_memory_pool); 852 ps->verbose = 0; 853 ps->treat_warnings_as_errors = 0; 854 ps->expect_error = 0; 855 ps->expect_warning = 0; 856 ps->saw_warning = 0; 857 ps->speed = 0; 858 ps->progressive = 0; 859 ps->validated = 0; 860 ps->nerrors = ps->nwarnings = 0; 861 ps->pread = NULL; 862 ps->piread = NULL; 863 ps->saved = ps->current = NULL; 864 ps->next = NULL; 865 ps->readpos = 0; 866 ps->image = NULL; 867 ps->cb_image = 0; 868 ps->cb_row = 0; 869 ps->image_h = 0; 870 ps->pwrite = NULL; 871 ps->piwrite = NULL; 872 ps->writepos = 0; 873 ps->chunkpos = 8; 874 ps->chunktype = 0; 875 ps->chunklen = 16; 876 ps->IDAT_size = 0; 877 ps->IDAT_bits = 0; 878 ps->new.prev = NULL; 879 ps->palette = NULL; 880 ps->npalette = 0; 881 ps->noptions = 0; 882 } 883 884 static void 885 store_freebuffer(png_store_buffer* psb) 886 { 887 if (psb->prev) 888 { 889 store_freebuffer(psb->prev); 890 free(psb->prev); 891 psb->prev = NULL; 892 } 893 } 894 895 static void 896 store_freenew(png_store *ps) 897 { 898 store_freebuffer(&ps->new); 899 ps->writepos = 0; 900 ps->chunkpos = 8; 901 ps->chunktype = 0; 902 ps->chunklen = 16; 903 ps->IDAT_size = 0; 904 ps->IDAT_bits = 0; 905 if (ps->palette != NULL) 906 { 907 free(ps->palette); 908 ps->palette = NULL; 909 ps->npalette = 0; 910 } 911 } 912 913 static void 914 store_storenew(png_store *ps) 915 { 916 png_store_buffer *pb; 917 918 pb = voidcast(png_store_buffer*, malloc(sizeof *pb)); 919 920 if (pb == NULL) 921 png_error(ps->pwrite, "store new: OOM"); 922 923 *pb = ps->new; 924 ps->new.prev = pb; 925 ps->writepos = 0; 926 } 927 928 static void 929 store_freefile(png_store_file **ppf) 930 { 931 if (*ppf != NULL) 932 { 933 store_freefile(&(*ppf)->next); 934 935 store_freebuffer(&(*ppf)->data); 936 (*ppf)->datacount = 0; 937 if ((*ppf)->palette != NULL) 938 { 939 free((*ppf)->palette); 940 (*ppf)->palette = NULL; 941 (*ppf)->npalette = 0; 942 } 943 free(*ppf); 944 *ppf = NULL; 945 } 946 } 947 948 static unsigned int 949 bits_of(png_uint_32 num) 950 { 951 /* Return the number of bits in 'num' */ 952 unsigned int b = 0; 953 954 if (num & 0xffff0000U) b += 16U, num >>= 16; 955 if (num & 0xff00U) b += 8U, num >>= 8; 956 if (num & 0xf0U) b += 4U, num >>= 4; 957 if (num & 0xcU) b += 2U, num >>= 2; 958 if (num & 0x2U) ++b, num >>= 1; 959 if (num) ++b; 960 961 return b; /* 0..32 */ 962 } 963 964 /* Main interface to file storeage, after writing a new PNG file (see the API 965 * below) call store_storefile to store the result with the given name and id. 966 */ 967 static void 968 store_storefile(png_store *ps, png_uint_32 id) 969 { 970 png_store_file *pf; 971 972 if (ps->chunkpos != 0U || ps->chunktype != 0U || ps->chunklen != 0U || 973 ps->IDAT_size == 0) 974 png_error(ps->pwrite, "storefile: incomplete write"); 975 976 pf = voidcast(png_store_file*, malloc(sizeof *pf)); 977 if (pf == NULL) 978 png_error(ps->pwrite, "storefile: OOM"); 979 safecat(pf->name, sizeof pf->name, 0, ps->wname); 980 pf->id = id; 981 pf->data = ps->new; 982 pf->datacount = ps->writepos; 983 pf->IDAT_size = ps->IDAT_size; 984 pf->IDAT_bits = bits_of(ps->IDAT_size); 985 /* Because the IDAT always has zlib header stuff this must be true: */ 986 if (pf->IDAT_bits == 0U) 987 png_error(ps->pwrite, "storefile: 0 sized IDAT"); 988 ps->new.prev = NULL; 989 ps->writepos = 0; 990 ps->chunkpos = 8; 991 ps->chunktype = 0; 992 ps->chunklen = 16; 993 ps->IDAT_size = 0; 994 pf->palette = ps->palette; 995 pf->npalette = ps->npalette; 996 ps->palette = 0; 997 ps->npalette = 0; 998 999 /* And save it. */ 1000 pf->next = ps->saved; 1001 ps->saved = pf; 1002 } 1003 1004 /* Generate an error message (in the given buffer) */ 1005 static size_t 1006 store_message(png_store *ps, png_const_structp pp, char *buffer, size_t bufsize, 1007 size_t pos, const char *msg) 1008 { 1009 if (pp != NULL && pp == ps->pread) 1010 { 1011 /* Reading a file */ 1012 pos = safecat(buffer, bufsize, pos, "read: "); 1013 1014 if (ps->current != NULL) 1015 { 1016 pos = safecat(buffer, bufsize, pos, ps->current->name); 1017 pos = safecat(buffer, bufsize, pos, sep); 1018 } 1019 } 1020 1021 else if (pp != NULL && pp == ps->pwrite) 1022 { 1023 /* Writing a file */ 1024 pos = safecat(buffer, bufsize, pos, "write: "); 1025 pos = safecat(buffer, bufsize, pos, ps->wname); 1026 pos = safecat(buffer, bufsize, pos, sep); 1027 } 1028 1029 else 1030 { 1031 /* Neither reading nor writing (or a memory error in struct delete) */ 1032 pos = safecat(buffer, bufsize, pos, "pngvalid: "); 1033 } 1034 1035 if (ps->test[0] != 0) 1036 { 1037 pos = safecat(buffer, bufsize, pos, ps->test); 1038 pos = safecat(buffer, bufsize, pos, sep); 1039 } 1040 pos = safecat(buffer, bufsize, pos, msg); 1041 return pos; 1042 } 1043 1044 /* Verbose output to the error stream: */ 1045 static void 1046 store_verbose(png_store *ps, png_const_structp pp, png_const_charp prefix, 1047 png_const_charp message) 1048 { 1049 char buffer[512]; 1050 1051 if (prefix) 1052 fputs(prefix, stderr); 1053 1054 (void)store_message(ps, pp, buffer, sizeof buffer, 0, message); 1055 fputs(buffer, stderr); 1056 fputc('\n', stderr); 1057 } 1058 1059 /* Log an error or warning - the relevant count is always incremented. */ 1060 static void 1061 store_log(png_store* ps, png_const_structp pp, png_const_charp message, 1062 int is_error) 1063 { 1064 /* The warning is copied to the error buffer if there are no errors and it is 1065 * the first warning. The error is copied to the error buffer if it is the 1066 * first error (overwriting any prior warnings). 1067 */ 1068 if (is_error ? (ps->nerrors)++ == 0 : 1069 (ps->nwarnings)++ == 0 && ps->nerrors == 0) 1070 store_message(ps, pp, ps->error, sizeof ps->error, 0, message); 1071 1072 if (ps->verbose) 1073 store_verbose(ps, pp, is_error ? "error: " : "warning: ", message); 1074 } 1075 1076 #ifdef PNG_READ_SUPPORTED 1077 /* Internal error function, called with a png_store but no libpng stuff. */ 1078 static void 1079 internal_error(png_store *ps, png_const_charp message) 1080 { 1081 store_log(ps, NULL, message, 1 /* error */); 1082 1083 /* And finally throw an exception. */ 1084 { 1085 struct exception_context *the_exception_context = &ps->exception_context; 1086 Throw ps; 1087 } 1088 } 1089 #endif /* PNG_READ_SUPPORTED */ 1090 1091 /* Functions to use as PNG callbacks. */ 1092 static void PNGCBAPI 1093 store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */ 1094 { 1095 png_const_structp pp = ppIn; 1096 png_store *ps = voidcast(png_store*, png_get_error_ptr(pp)); 1097 1098 if (!ps->expect_error) 1099 store_log(ps, pp, message, 1 /* error */); 1100 1101 /* And finally throw an exception. */ 1102 { 1103 struct exception_context *the_exception_context = &ps->exception_context; 1104 Throw ps; 1105 } 1106 } 1107 1108 static void PNGCBAPI 1109 store_warning(png_structp ppIn, png_const_charp message) 1110 { 1111 png_const_structp pp = ppIn; 1112 png_store *ps = voidcast(png_store*, png_get_error_ptr(pp)); 1113 1114 if (!ps->expect_warning) 1115 store_log(ps, pp, message, 0 /* warning */); 1116 else 1117 ps->saw_warning = 1; 1118 } 1119 1120 /* These somewhat odd functions are used when reading an image to ensure that 1121 * the buffer is big enough, the png_structp is for errors. 1122 */ 1123 /* Return a single row from the correct image. */ 1124 static png_bytep 1125 store_image_row(const png_store* ps, png_const_structp pp, int nImage, 1126 png_uint_32 y) 1127 { 1128 png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2; 1129 1130 if (ps->image == NULL) 1131 png_error(pp, "no allocated image"); 1132 1133 if (coffset + ps->cb_row + 3 > ps->cb_image) 1134 png_error(pp, "image too small"); 1135 1136 return ps->image + coffset; 1137 } 1138 1139 static void 1140 store_image_free(png_store *ps, png_const_structp pp) 1141 { 1142 if (ps->image != NULL) 1143 { 1144 png_bytep image = ps->image; 1145 1146 if (image[-1] != 0xed || image[ps->cb_image] != 0xfe) 1147 { 1148 if (pp != NULL) 1149 png_error(pp, "png_store image overwrite (1)"); 1150 else 1151 store_log(ps, NULL, "png_store image overwrite (2)", 1); 1152 } 1153 1154 ps->image = NULL; 1155 ps->cb_image = 0; 1156 --image; 1157 free(image); 1158 } 1159 } 1160 1161 static void 1162 store_ensure_image(png_store *ps, png_const_structp pp, int nImages, 1163 png_size_t cbRow, png_uint_32 cRows) 1164 { 1165 png_size_t cb = nImages * cRows * (cbRow + 5); 1166 1167 if (ps->cb_image < cb) 1168 { 1169 png_bytep image; 1170 1171 store_image_free(ps, pp); 1172 1173 /* The buffer is deliberately mis-aligned. */ 1174 image = voidcast(png_bytep, malloc(cb+2)); 1175 if (image == NULL) 1176 { 1177 /* Called from the startup - ignore the error for the moment. */ 1178 if (pp == NULL) 1179 return; 1180 1181 png_error(pp, "OOM allocating image buffer"); 1182 } 1183 1184 /* These magic tags are used to detect overwrites above. */ 1185 ++image; 1186 image[-1] = 0xed; 1187 image[cb] = 0xfe; 1188 1189 ps->image = image; 1190 ps->cb_image = cb; 1191 } 1192 1193 /* We have an adequate sized image; lay out the rows. There are 2 bytes at 1194 * the start and three at the end of each (this ensures that the row 1195 * alignment starts out odd - 2+1 and changes for larger images on each row.) 1196 */ 1197 ps->cb_row = cbRow; 1198 ps->image_h = cRows; 1199 1200 /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178). 1201 * This deliberately doesn't match the bits in the size test image which are 1202 * outside the image; these are set to 0xff (all 1). To make the row 1203 * comparison work in the 'size' test case the size rows are pre-initialized 1204 * to the same value prior to calling 'standard_row'. 1205 */ 1206 memset(ps->image, 178, cb); 1207 1208 /* Then put in the marks. */ 1209 while (--nImages >= 0) 1210 { 1211 png_uint_32 y; 1212 1213 for (y=0; y<cRows; ++y) 1214 { 1215 png_bytep row = store_image_row(ps, pp, nImages, y); 1216 1217 /* The markers: */ 1218 row[-2] = 190; 1219 row[-1] = 239; 1220 row[cbRow] = 222; 1221 row[cbRow+1] = 173; 1222 row[cbRow+2] = 17; 1223 } 1224 } 1225 } 1226 1227 #ifdef PNG_READ_SUPPORTED 1228 static void 1229 store_image_check(const png_store* ps, png_const_structp pp, int iImage) 1230 { 1231 png_const_bytep image = ps->image; 1232 1233 if (image[-1] != 0xed || image[ps->cb_image] != 0xfe) 1234 png_error(pp, "image overwrite"); 1235 else 1236 { 1237 png_size_t cbRow = ps->cb_row; 1238 png_uint_32 rows = ps->image_h; 1239 1240 image += iImage * (cbRow+5) * ps->image_h; 1241 1242 image += 2; /* skip image first row markers */ 1243 1244 for (; rows > 0; --rows) 1245 { 1246 if (image[-2] != 190 || image[-1] != 239) 1247 png_error(pp, "row start overwritten"); 1248 1249 if (image[cbRow] != 222 || image[cbRow+1] != 173 || 1250 image[cbRow+2] != 17) 1251 png_error(pp, "row end overwritten"); 1252 1253 image += cbRow+5; 1254 } 1255 } 1256 } 1257 #endif /* PNG_READ_SUPPORTED */ 1258 1259 static int 1260 valid_chunktype(png_uint_32 chunktype) 1261 { 1262 /* Each byte in the chunk type must be in one of the ranges 65..90, 97..122 1263 * (both inclusive), so: 1264 */ 1265 unsigned int i; 1266 1267 for (i=0; i<4; ++i) 1268 { 1269 unsigned int c = chunktype & 0xffU; 1270 1271 if (!((c >= 65U && c <= 90U) || (c >= 97U && c <= 122U))) 1272 return 0; 1273 1274 chunktype >>= 8; 1275 } 1276 1277 return 1; /* It's valid */ 1278 } 1279 1280 static void PNGCBAPI 1281 store_write(png_structp ppIn, png_bytep pb, png_size_t st) 1282 { 1283 png_const_structp pp = ppIn; 1284 png_store *ps = voidcast(png_store*, png_get_io_ptr(pp)); 1285 size_t writepos = ps->writepos; 1286 png_uint_32 chunkpos = ps->chunkpos; 1287 png_uint_32 chunktype = ps->chunktype; 1288 png_uint_32 chunklen = ps->chunklen; 1289 1290 if (ps->pwrite != pp) 1291 png_error(pp, "store state damaged"); 1292 1293 /* Technically this is legal, but in practice libpng never writes more than 1294 * the maximum chunk size at once so if it happens something weird has 1295 * changed inside libpng (probably). 1296 */ 1297 if (st > 0x7fffffffU) 1298 png_error(pp, "unexpected write size"); 1299 1300 /* Now process the bytes to be written. Do this in units of the space in the 1301 * output (write) buffer or, at the start 4 bytes for the chunk type and 1302 * length limited in any case by the amount of data. 1303 */ 1304 while (st > 0) 1305 { 1306 if (writepos >= STORE_BUFFER_SIZE) 1307 store_storenew(ps), writepos = 0; 1308 1309 if (chunkpos < 4) 1310 { 1311 png_byte b = *pb++; 1312 --st; 1313 chunklen = (chunklen << 8) + b; 1314 ps->new.buffer[writepos++] = b; 1315 ++chunkpos; 1316 } 1317 1318 else if (chunkpos < 8) 1319 { 1320 png_byte b = *pb++; 1321 --st; 1322 chunktype = (chunktype << 8) + b; 1323 ps->new.buffer[writepos++] = b; 1324 1325 if (++chunkpos == 8) 1326 { 1327 chunklen &= 0xffffffffU; 1328 if (chunklen > 0x7fffffffU) 1329 png_error(pp, "chunk length too great"); 1330 1331 chunktype &= 0xffffffffU; 1332 if (chunktype == CHUNK_IDAT) 1333 { 1334 if (chunklen > ~ps->IDAT_size) 1335 png_error(pp, "pngvalid internal image too large"); 1336 1337 ps->IDAT_size += chunklen; 1338 } 1339 1340 else if (!valid_chunktype(chunktype)) 1341 png_error(pp, "invalid chunk type"); 1342 1343 chunklen += 12; /* for header and CRC */ 1344 } 1345 } 1346 1347 else /* chunkpos >= 8 */ 1348 { 1349 png_size_t cb = st; 1350 1351 if (cb > STORE_BUFFER_SIZE - writepos) 1352 cb = STORE_BUFFER_SIZE - writepos; 1353 1354 if (cb > chunklen - chunkpos/* bytes left in chunk*/) 1355 cb = (png_size_t)/*SAFE*/(chunklen - chunkpos); 1356 1357 memcpy(ps->new.buffer + writepos, pb, cb); 1358 chunkpos += (png_uint_32)/*SAFE*/cb; 1359 pb += cb; 1360 writepos += cb; 1361 st -= cb; 1362 1363 if (chunkpos >= chunklen) /* must be equal */ 1364 chunkpos = chunktype = chunklen = 0; 1365 } 1366 } /* while (st > 0) */ 1367 1368 ps->writepos = writepos; 1369 ps->chunkpos = chunkpos; 1370 ps->chunktype = chunktype; 1371 ps->chunklen = chunklen; 1372 } 1373 1374 static void PNGCBAPI 1375 store_flush(png_structp ppIn) 1376 { 1377 UNUSED(ppIn) /*DOES NOTHING*/ 1378 } 1379 1380 #ifdef PNG_READ_SUPPORTED 1381 static size_t 1382 store_read_buffer_size(png_store *ps) 1383 { 1384 /* Return the bytes available for read in the current buffer. */ 1385 if (ps->next != &ps->current->data) 1386 return STORE_BUFFER_SIZE; 1387 1388 return ps->current->datacount; 1389 } 1390 1391 /* Return total bytes available for read. */ 1392 static size_t 1393 store_read_buffer_avail(png_store *ps) 1394 { 1395 if (ps->current != NULL && ps->next != NULL) 1396 { 1397 png_store_buffer *next = &ps->current->data; 1398 size_t cbAvail = ps->current->datacount; 1399 1400 while (next != ps->next && next != NULL) 1401 { 1402 next = next->prev; 1403 cbAvail += STORE_BUFFER_SIZE; 1404 } 1405 1406 if (next != ps->next) 1407 png_error(ps->pread, "buffer read error"); 1408 1409 if (cbAvail > ps->readpos) 1410 return cbAvail - ps->readpos; 1411 } 1412 1413 return 0; 1414 } 1415 1416 static int 1417 store_read_buffer_next(png_store *ps) 1418 { 1419 png_store_buffer *pbOld = ps->next; 1420 png_store_buffer *pbNew = &ps->current->data; 1421 if (pbOld != pbNew) 1422 { 1423 while (pbNew != NULL && pbNew->prev != pbOld) 1424 pbNew = pbNew->prev; 1425 1426 if (pbNew != NULL) 1427 { 1428 ps->next = pbNew; 1429 ps->readpos = 0; 1430 return 1; 1431 } 1432 1433 png_error(ps->pread, "buffer lost"); 1434 } 1435 1436 return 0; /* EOF or error */ 1437 } 1438 1439 /* Need separate implementation and callback to allow use of the same code 1440 * during progressive read, where the io_ptr is set internally by libpng. 1441 */ 1442 static void 1443 store_read_imp(png_store *ps, png_bytep pb, png_size_t st) 1444 { 1445 if (ps->current == NULL || ps->next == NULL) 1446 png_error(ps->pread, "store state damaged"); 1447 1448 while (st > 0) 1449 { 1450 size_t cbAvail = store_read_buffer_size(ps) - ps->readpos; 1451 1452 if (cbAvail > 0) 1453 { 1454 if (cbAvail > st) cbAvail = st; 1455 memcpy(pb, ps->next->buffer + ps->readpos, cbAvail); 1456 st -= cbAvail; 1457 pb += cbAvail; 1458 ps->readpos += cbAvail; 1459 } 1460 1461 else if (!store_read_buffer_next(ps)) 1462 png_error(ps->pread, "read beyond end of file"); 1463 } 1464 } 1465 1466 static png_size_t 1467 store_read_chunk(png_store *ps, png_bytep pb, const png_size_t max, 1468 const png_size_t min) 1469 { 1470 png_uint_32 chunklen = ps->chunklen; 1471 png_uint_32 chunktype = ps->chunktype; 1472 png_uint_32 chunkpos = ps->chunkpos; 1473 png_size_t st = max; 1474 1475 if (st > 0) do 1476 { 1477 if (chunkpos >= chunklen) /* end of last chunk */ 1478 { 1479 png_byte buffer[8]; 1480 1481 /* Read the header of the next chunk: */ 1482 store_read_imp(ps, buffer, 8U); 1483 chunklen = png_get_uint_32(buffer) + 12U; 1484 chunktype = png_get_uint_32(buffer+4U); 1485 chunkpos = 0U; /* Position read so far */ 1486 } 1487 1488 if (chunktype == CHUNK_IDAT) 1489 { 1490 png_uint_32 IDAT_pos = ps->IDAT_pos; 1491 png_uint_32 IDAT_len = ps->IDAT_len; 1492 png_uint_32 IDAT_size = ps->IDAT_size; 1493 1494 /* The IDAT headers are constructed here; skip the input header. */ 1495 if (chunkpos < 8U) 1496 chunkpos = 8U; 1497 1498 if (IDAT_pos == IDAT_len) 1499 { 1500 png_byte random = random_byte(); 1501 1502 /* Make a new IDAT chunk, if IDAT_len is 0 this is the first IDAT, 1503 * if IDAT_size is 0 this is the end. At present this is set up 1504 * using a random number so that there is a 25% chance before 1505 * the start of the first IDAT chunk being 0 length. 1506 */ 1507 if (IDAT_len == 0U) /* First IDAT */ 1508 { 1509 switch (random & 3U) 1510 { 1511 case 0U: IDAT_len = 12U; break; /* 0 bytes */ 1512 case 1U: IDAT_len = 13U; break; /* 1 byte */ 1513 default: IDAT_len = random_u32(); 1514 IDAT_len %= IDAT_size; 1515 IDAT_len += 13U; /* 1..IDAT_size bytes */ 1516 break; 1517 } 1518 } 1519 1520 else if (IDAT_size == 0U) /* all IDAT data read */ 1521 { 1522 /* The last (IDAT) chunk should be positioned at the CRC now: */ 1523 if (chunkpos != chunklen-4U) 1524 png_error(ps->pread, "internal: IDAT size mismatch"); 1525 1526 /* The only option here is to add a zero length IDAT, this 1527 * happens 25% of the time. Because of the check above 1528 * chunklen-4U-chunkpos must be zero, we just need to skip the 1529 * CRC now. 1530 */ 1531 if ((random & 3U) == 0U) 1532 IDAT_len = 12U; /* Output another 0 length IDAT */ 1533 1534 else 1535 { 1536 /* End of IDATs, skip the CRC to make the code above load the 1537 * next chunk header next time round. 1538 */ 1539 png_byte buffer[4]; 1540 1541 store_read_imp(ps, buffer, 4U); 1542 chunkpos += 4U; 1543 ps->IDAT_pos = IDAT_pos; 1544 ps->IDAT_len = IDAT_len; 1545 ps->IDAT_size = 0U; 1546 continue; /* Read the next chunk */ 1547 } 1548 } 1549 1550 else 1551 { 1552 /* Middle of IDATs, use 'random' to determine the number of bits 1553 * to use in the IDAT length. 1554 */ 1555 IDAT_len = random_u32(); 1556 IDAT_len &= (1U << (1U + random % ps->IDAT_bits)) - 1U; 1557 if (IDAT_len > IDAT_size) 1558 IDAT_len = IDAT_size; 1559 IDAT_len += 12U; /* zero bytes may occur */ 1560 } 1561 1562 IDAT_pos = 0U; 1563 ps->IDAT_crc = 0x35af061e; /* Ie: crc32(0UL, "IDAT", 4) */ 1564 } /* IDAT_pos == IDAT_len */ 1565 1566 if (IDAT_pos < 8U) /* Return the header */ do 1567 { 1568 png_uint_32 b; 1569 unsigned int shift; 1570 1571 if (IDAT_pos < 4U) 1572 b = IDAT_len - 12U; 1573 1574 else 1575 b = CHUNK_IDAT; 1576 1577 shift = 3U & IDAT_pos; 1578 ++IDAT_pos; 1579 1580 if (shift < 3U) 1581 b >>= 8U*(3U-shift); 1582 1583 *pb++ = 0xffU & b; 1584 } 1585 while (--st > 0 && IDAT_pos < 8); 1586 1587 else if (IDAT_pos < IDAT_len - 4U) /* I.e not the CRC */ 1588 { 1589 if (chunkpos < chunklen-4U) 1590 { 1591 uInt avail = (uInt)-1; 1592 1593 if (avail > (IDAT_len-4U) - IDAT_pos) 1594 avail = (uInt)/*SAFE*/((IDAT_len-4U) - IDAT_pos); 1595 1596 if (avail > st) 1597 avail = (uInt)/*SAFE*/st; 1598 1599 if (avail > (chunklen-4U) - chunkpos) 1600 avail = (uInt)/*SAFE*/((chunklen-4U) - chunkpos); 1601 1602 store_read_imp(ps, pb, avail); 1603 ps->IDAT_crc = crc32(ps->IDAT_crc, pb, avail); 1604 pb += (png_size_t)/*SAFE*/avail; 1605 st -= (png_size_t)/*SAFE*/avail; 1606 chunkpos += (png_uint_32)/*SAFE*/avail; 1607 IDAT_size -= (png_uint_32)/*SAFE*/avail; 1608 IDAT_pos += (png_uint_32)/*SAFE*/avail; 1609 } 1610 1611 else /* skip the input CRC */ 1612 { 1613 png_byte buffer[4]; 1614 1615 store_read_imp(ps, buffer, 4U); 1616 chunkpos += 4U; 1617 } 1618 } 1619 1620 else /* IDAT crc */ do 1621 { 1622 uLong b = ps->IDAT_crc; 1623 unsigned int shift = (IDAT_len - IDAT_pos); /* 4..1 */ 1624 ++IDAT_pos; 1625 1626 if (shift > 1U) 1627 b >>= 8U*(shift-1U); 1628 1629 *pb++ = 0xffU & b; 1630 } 1631 while (--st > 0 && IDAT_pos < IDAT_len); 1632 1633 ps->IDAT_pos = IDAT_pos; 1634 ps->IDAT_len = IDAT_len; 1635 ps->IDAT_size = IDAT_size; 1636 } 1637 1638 else /* !IDAT */ 1639 { 1640 /* If there is still some pending IDAT data after the IDAT chunks have 1641 * been processed there is a problem: 1642 */ 1643 if (ps->IDAT_len > 0 && ps->IDAT_size > 0) 1644 png_error(ps->pread, "internal: missing IDAT data"); 1645 1646 if (chunktype == CHUNK_IEND && ps->IDAT_len == 0U) 1647 png_error(ps->pread, "internal: missing IDAT"); 1648 1649 if (chunkpos < 8U) /* Return the header */ do 1650 { 1651 png_uint_32 b; 1652 unsigned int shift; 1653 1654 if (chunkpos < 4U) 1655 b = chunklen - 12U; 1656 1657 else 1658 b = chunktype; 1659 1660 shift = 3U & chunkpos; 1661 ++chunkpos; 1662 1663 if (shift < 3U) 1664 b >>= 8U*(3U-shift); 1665 1666 *pb++ = 0xffU & b; 1667 } 1668 while (--st > 0 && chunkpos < 8); 1669 1670 else /* Return chunk bytes, including the CRC */ 1671 { 1672 png_size_t avail = st; 1673 1674 if (avail > chunklen - chunkpos) 1675 avail = (png_size_t)/*SAFE*/(chunklen - chunkpos); 1676 1677 store_read_imp(ps, pb, avail); 1678 pb += avail; 1679 st -= avail; 1680 chunkpos += (png_uint_32)/*SAFE*/avail; 1681 1682 /* Check for end of chunk and end-of-file; don't try to read a new 1683 * chunk header at this point unless instructed to do so by 'min'. 1684 */ 1685 if (chunkpos >= chunklen && max-st >= min && 1686 store_read_buffer_avail(ps) == 0) 1687 break; 1688 } 1689 } /* !IDAT */ 1690 } 1691 while (st > 0); 1692 1693 ps->chunklen = chunklen; 1694 ps->chunktype = chunktype; 1695 ps->chunkpos = chunkpos; 1696 1697 return st; /* space left */ 1698 } 1699 1700 static void PNGCBAPI 1701 store_read(png_structp ppIn, png_bytep pb, png_size_t st) 1702 { 1703 png_const_structp pp = ppIn; 1704 png_store *ps = voidcast(png_store*, png_get_io_ptr(pp)); 1705 1706 if (ps == NULL || ps->pread != pp) 1707 png_error(pp, "bad store read call"); 1708 1709 store_read_chunk(ps, pb, st, st); 1710 } 1711 1712 static void 1713 store_progressive_read(png_store *ps, png_structp pp, png_infop pi) 1714 { 1715 if (ps->pread != pp || ps->current == NULL || ps->next == NULL) 1716 png_error(pp, "store state damaged (progressive)"); 1717 1718 /* This is another Horowitz and Hill random noise generator. In this case 1719 * the aim is to stress the progressive reader with truly horrible variable 1720 * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers 1721 * is generated. We could probably just count from 1 to 32767 and get as 1722 * good a result. 1723 */ 1724 while (store_read_buffer_avail(ps) > 0) 1725 { 1726 static png_uint_32 noise = 2; 1727 png_size_t cb; 1728 png_byte buffer[512]; 1729 1730 /* Generate 15 more bits of stuff: */ 1731 noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff); 1732 cb = noise & 0x1ff; 1733 cb -= store_read_chunk(ps, buffer, cb, 1); 1734 png_process_data(pp, pi, buffer, cb); 1735 } 1736 } 1737 #endif /* PNG_READ_SUPPORTED */ 1738 1739 /* The caller must fill this in: */ 1740 static store_palette_entry * 1741 store_write_palette(png_store *ps, int npalette) 1742 { 1743 if (ps->pwrite == NULL) 1744 store_log(ps, NULL, "attempt to write palette without write stream", 1); 1745 1746 if (ps->palette != NULL) 1747 png_error(ps->pwrite, "multiple store_write_palette calls"); 1748 1749 /* This function can only return NULL if called with '0'! */ 1750 if (npalette > 0) 1751 { 1752 ps->palette = voidcast(store_palette_entry*, malloc(npalette * 1753 sizeof *ps->palette)); 1754 1755 if (ps->palette == NULL) 1756 png_error(ps->pwrite, "store new palette: OOM"); 1757 1758 ps->npalette = npalette; 1759 } 1760 1761 return ps->palette; 1762 } 1763 1764 #ifdef PNG_READ_SUPPORTED 1765 static store_palette_entry * 1766 store_current_palette(png_store *ps, int *npalette) 1767 { 1768 /* This is an internal error (the call has been made outside a read 1769 * operation.) 1770 */ 1771 if (ps->current == NULL) 1772 { 1773 store_log(ps, ps->pread, "no current stream for palette", 1); 1774 return NULL; 1775 } 1776 1777 /* The result may be null if there is no palette. */ 1778 *npalette = ps->current->npalette; 1779 return ps->current->palette; 1780 } 1781 #endif /* PNG_READ_SUPPORTED */ 1782 1783 /***************************** MEMORY MANAGEMENT*** ***************************/ 1784 #ifdef PNG_USER_MEM_SUPPORTED 1785 /* A store_memory is simply the header for an allocated block of memory. The 1786 * pointer returned to libpng is just after the end of the header block, the 1787 * allocated memory is followed by a second copy of the 'mark'. 1788 */ 1789 typedef struct store_memory 1790 { 1791 store_pool *pool; /* Originating pool */ 1792 struct store_memory *next; /* Singly linked list */ 1793 png_alloc_size_t size; /* Size of memory allocated */ 1794 png_byte mark[4]; /* ID marker */ 1795 } store_memory; 1796 1797 /* Handle a fatal error in memory allocation. This calls png_error if the 1798 * libpng struct is non-NULL, else it outputs a message and returns. This means 1799 * that a memory problem while libpng is running will abort (png_error) the 1800 * handling of particular file while one in cleanup (after the destroy of the 1801 * struct has returned) will simply keep going and free (or attempt to free) 1802 * all the memory. 1803 */ 1804 static void 1805 store_pool_error(png_store *ps, png_const_structp pp, const char *msg) 1806 { 1807 if (pp != NULL) 1808 png_error(pp, msg); 1809 1810 /* Else we have to do it ourselves. png_error eventually calls store_log, 1811 * above. store_log accepts a NULL png_structp - it just changes what gets 1812 * output by store_message. 1813 */ 1814 store_log(ps, pp, msg, 1 /* error */); 1815 } 1816 1817 static void 1818 store_memory_free(png_const_structp pp, store_pool *pool, store_memory *memory) 1819 { 1820 /* Note that pp may be NULL (see store_pool_delete below), the caller has 1821 * found 'memory' in pool->list *and* unlinked this entry, so this is a valid 1822 * pointer (for sure), but the contents may have been trashed. 1823 */ 1824 if (memory->pool != pool) 1825 store_pool_error(pool->store, pp, "memory corrupted (pool)"); 1826 1827 else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0) 1828 store_pool_error(pool->store, pp, "memory corrupted (start)"); 1829 1830 /* It should be safe to read the size field now. */ 1831 else 1832 { 1833 png_alloc_size_t cb = memory->size; 1834 1835 if (cb > pool->max) 1836 store_pool_error(pool->store, pp, "memory corrupted (size)"); 1837 1838 else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark) 1839 != 0) 1840 store_pool_error(pool->store, pp, "memory corrupted (end)"); 1841 1842 /* Finally give the library a chance to find problems too: */ 1843 else 1844 { 1845 pool->current -= cb; 1846 free(memory); 1847 } 1848 } 1849 } 1850 1851 static void 1852 store_pool_delete(png_store *ps, store_pool *pool) 1853 { 1854 if (pool->list != NULL) 1855 { 1856 fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test, 1857 pool == &ps->read_memory_pool ? "read" : "write", 1858 pool == &ps->read_memory_pool ? (ps->current != NULL ? 1859 ps->current->name : "unknown file") : ps->wname); 1860 ++ps->nerrors; 1861 1862 do 1863 { 1864 store_memory *next = pool->list; 1865 pool->list = next->next; 1866 next->next = NULL; 1867 1868 fprintf(stderr, "\t%lu bytes @ %p\n", 1869 (unsigned long)next->size, (const void*)(next+1)); 1870 /* The NULL means this will always return, even if the memory is 1871 * corrupted. 1872 */ 1873 store_memory_free(NULL, pool, next); 1874 } 1875 while (pool->list != NULL); 1876 } 1877 1878 /* And reset the other fields too for the next time. */ 1879 if (pool->max > pool->max_max) pool->max_max = pool->max; 1880 pool->max = 0; 1881 if (pool->current != 0) /* unexpected internal error */ 1882 fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n", 1883 ps->test, pool == &ps->read_memory_pool ? "read" : "write", 1884 pool == &ps->read_memory_pool ? (ps->current != NULL ? 1885 ps->current->name : "unknown file") : ps->wname); 1886 pool->current = 0; 1887 1888 if (pool->limit > pool->max_limit) 1889 pool->max_limit = pool->limit; 1890 1891 pool->limit = 0; 1892 1893 if (pool->total > pool->max_total) 1894 pool->max_total = pool->total; 1895 1896 pool->total = 0; 1897 1898 /* Get a new mark too. */ 1899 store_pool_mark(pool->mark); 1900 } 1901 1902 /* The memory callbacks: */ 1903 static png_voidp PNGCBAPI 1904 store_malloc(png_structp ppIn, png_alloc_size_t cb) 1905 { 1906 png_const_structp pp = ppIn; 1907 store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp)); 1908 store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) + 1909 (sizeof pool->mark))); 1910 1911 if (new != NULL) 1912 { 1913 if (cb > pool->max) 1914 pool->max = cb; 1915 1916 pool->current += cb; 1917 1918 if (pool->current > pool->limit) 1919 pool->limit = pool->current; 1920 1921 pool->total += cb; 1922 1923 new->size = cb; 1924 memcpy(new->mark, pool->mark, sizeof new->mark); 1925 memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark); 1926 new->pool = pool; 1927 new->next = pool->list; 1928 pool->list = new; 1929 ++new; 1930 } 1931 1932 else 1933 { 1934 /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed 1935 * other than to retrieve the allocation pointer! libpng calls the 1936 * store_malloc callback in two basic cases: 1937 * 1938 * 1) From png_malloc; png_malloc will do a png_error itself if NULL is 1939 * returned. 1940 * 2) From png_struct or png_info structure creation; png_malloc is 1941 * to return so cleanup can be performed. 1942 * 1943 * To handle this store_malloc can log a message, but can't do anything 1944 * else. 1945 */ 1946 store_log(pool->store, pp, "out of memory", 1 /* is_error */); 1947 } 1948 1949 return new; 1950 } 1951 1952 static void PNGCBAPI 1953 store_free(png_structp ppIn, png_voidp memory) 1954 { 1955 png_const_structp pp = ppIn; 1956 store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp)); 1957 store_memory *this = voidcast(store_memory*, memory), **test; 1958 1959 /* Because libpng calls store_free with a dummy png_struct when deleting 1960 * png_struct or png_info via png_destroy_struct_2 it is necessary to check 1961 * the passed in png_structp to ensure it is valid, and not pass it to 1962 * png_error if it is not. 1963 */ 1964 if (pp != pool->store->pread && pp != pool->store->pwrite) 1965 pp = NULL; 1966 1967 /* First check that this 'memory' really is valid memory - it must be in the 1968 * pool list. If it is, use the shared memory_free function to free it. 1969 */ 1970 --this; 1971 for (test = &pool->list; *test != this; test = &(*test)->next) 1972 { 1973 if (*test == NULL) 1974 { 1975 store_pool_error(pool->store, pp, "bad pointer to free"); 1976 return; 1977 } 1978 } 1979 1980 /* Unlink this entry, *test == this. */ 1981 *test = this->next; 1982 this->next = NULL; 1983 store_memory_free(pp, pool, this); 1984 } 1985 #endif /* PNG_USER_MEM_SUPPORTED */ 1986 1987 /* Setup functions. */ 1988 /* Cleanup when aborting a write or after storing the new file. */ 1989 static void 1990 store_write_reset(png_store *ps) 1991 { 1992 if (ps->pwrite != NULL) 1993 { 1994 anon_context(ps); 1995 1996 Try 1997 png_destroy_write_struct(&ps->pwrite, &ps->piwrite); 1998 1999 Catch_anonymous 2000 { 2001 /* memory corruption: continue. */ 2002 } 2003 2004 ps->pwrite = NULL; 2005 ps->piwrite = NULL; 2006 } 2007 2008 /* And make sure that all the memory has been freed - this will output 2009 * spurious errors in the case of memory corruption above, but this is safe. 2010 */ 2011 # ifdef PNG_USER_MEM_SUPPORTED 2012 store_pool_delete(ps, &ps->write_memory_pool); 2013 # endif 2014 2015 store_freenew(ps); 2016 } 2017 2018 /* The following is the main write function, it returns a png_struct and, 2019 * optionally, a png_info suitable for writiing a new PNG file. Use 2020 * store_storefile above to record this file after it has been written. The 2021 * returned libpng structures as destroyed by store_write_reset above. 2022 */ 2023 static png_structp 2024 set_store_for_write(png_store *ps, png_infopp ppi, const char *name) 2025 { 2026 anon_context(ps); 2027 2028 Try 2029 { 2030 if (ps->pwrite != NULL) 2031 png_error(ps->pwrite, "write store already in use"); 2032 2033 store_write_reset(ps); 2034 safecat(ps->wname, sizeof ps->wname, 0, name); 2035 2036 /* Don't do the slow memory checks if doing a speed test, also if user 2037 * memory is not supported we can't do it anyway. 2038 */ 2039 # ifdef PNG_USER_MEM_SUPPORTED 2040 if (!ps->speed) 2041 ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, 2042 ps, store_error, store_warning, &ps->write_memory_pool, 2043 store_malloc, store_free); 2044 2045 else 2046 # endif 2047 ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING, 2048 ps, store_error, store_warning); 2049 2050 png_set_write_fn(ps->pwrite, ps, store_write, store_flush); 2051 2052 # ifdef PNG_SET_OPTION_SUPPORTED 2053 { 2054 int opt; 2055 for (opt=0; opt<ps->noptions; ++opt) 2056 if (png_set_option(ps->pwrite, ps->options[opt].option, 2057 ps->options[opt].setting) == PNG_OPTION_INVALID) 2058 png_error(ps->pwrite, "png option invalid"); 2059 } 2060 # endif 2061 2062 if (ppi != NULL) 2063 *ppi = ps->piwrite = png_create_info_struct(ps->pwrite); 2064 } 2065 2066 Catch_anonymous 2067 return NULL; 2068 2069 return ps->pwrite; 2070 } 2071 2072 /* Cleanup when finished reading (either due to error or in the success case). 2073 * This routine exists even when there is no read support to make the code 2074 * tidier (avoid a mass of ifdefs) and so easier to maintain. 2075 */ 2076 static void 2077 store_read_reset(png_store *ps) 2078 { 2079 # ifdef PNG_READ_SUPPORTED 2080 if (ps->pread != NULL) 2081 { 2082 anon_context(ps); 2083 2084 Try 2085 png_destroy_read_struct(&ps->pread, &ps->piread, NULL); 2086 2087 Catch_anonymous 2088 { 2089 /* error already output: continue */ 2090 } 2091 2092 ps->pread = NULL; 2093 ps->piread = NULL; 2094 } 2095 # endif 2096 2097 # ifdef PNG_USER_MEM_SUPPORTED 2098 /* Always do this to be safe. */ 2099 store_pool_delete(ps, &ps->read_memory_pool); 2100 # endif 2101 2102 ps->current = NULL; 2103 ps->next = NULL; 2104 ps->readpos = 0; 2105 ps->validated = 0; 2106 2107 ps->chunkpos = 8; 2108 ps->chunktype = 0; 2109 ps->chunklen = 16; 2110 ps->IDAT_size = 0; 2111 } 2112 2113 #ifdef PNG_READ_SUPPORTED 2114 static void 2115 store_read_set(png_store *ps, png_uint_32 id) 2116 { 2117 png_store_file *pf = ps->saved; 2118 2119 while (pf != NULL) 2120 { 2121 if (pf->id == id) 2122 { 2123 ps->current = pf; 2124 ps->next = NULL; 2125 ps->IDAT_size = pf->IDAT_size; 2126 ps->IDAT_bits = pf->IDAT_bits; /* just a cache */ 2127 ps->IDAT_len = 0; 2128 ps->IDAT_pos = 0; 2129 ps->IDAT_crc = 0UL; 2130 store_read_buffer_next(ps); 2131 return; 2132 } 2133 2134 pf = pf->next; 2135 } 2136 2137 { 2138 size_t pos; 2139 char msg[FILE_NAME_SIZE+64]; 2140 2141 pos = standard_name_from_id(msg, sizeof msg, 0, id); 2142 pos = safecat(msg, sizeof msg, pos, ": file not found"); 2143 png_error(ps->pread, msg); 2144 } 2145 } 2146 2147 /* The main interface for reading a saved file - pass the id number of the file 2148 * to retrieve. Ids must be unique or the earlier file will be hidden. The API 2149 * returns a png_struct and, optionally, a png_info. Both of these will be 2150 * destroyed by store_read_reset above. 2151 */ 2152 static png_structp 2153 set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id, 2154 const char *name) 2155 { 2156 /* Set the name for png_error */ 2157 safecat(ps->test, sizeof ps->test, 0, name); 2158 2159 if (ps->pread != NULL) 2160 png_error(ps->pread, "read store already in use"); 2161 2162 store_read_reset(ps); 2163 2164 /* Both the create APIs can return NULL if used in their default mode 2165 * (because there is no other way of handling an error because the jmp_buf 2166 * by default is stored in png_struct and that has not been allocated!) 2167 * However, given that store_error works correctly in these circumstances 2168 * we don't ever expect NULL in this program. 2169 */ 2170 # ifdef PNG_USER_MEM_SUPPORTED 2171 if (!ps->speed) 2172 ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps, 2173 store_error, store_warning, &ps->read_memory_pool, store_malloc, 2174 store_free); 2175 2176 else 2177 # endif 2178 ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, store_error, 2179 store_warning); 2180 2181 if (ps->pread == NULL) 2182 { 2183 struct exception_context *the_exception_context = &ps->exception_context; 2184 2185 store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)", 2186 1 /*error*/); 2187 2188 Throw ps; 2189 } 2190 2191 # ifdef PNG_SET_OPTION_SUPPORTED 2192 { 2193 int opt; 2194 for (opt=0; opt<ps->noptions; ++opt) 2195 if (png_set_option(ps->pread, ps->options[opt].option, 2196 ps->options[opt].setting) == PNG_OPTION_INVALID) 2197 png_error(ps->pread, "png option invalid"); 2198 } 2199 # endif 2200 2201 store_read_set(ps, id); 2202 2203 if (ppi != NULL) 2204 *ppi = ps->piread = png_create_info_struct(ps->pread); 2205 2206 return ps->pread; 2207 } 2208 #endif /* PNG_READ_SUPPORTED */ 2209 2210 /* The overall cleanup of a store simply calls the above then removes all the 2211 * saved files. This does not delete the store itself. 2212 */ 2213 static void 2214 store_delete(png_store *ps) 2215 { 2216 store_write_reset(ps); 2217 store_read_reset(ps); 2218 store_freefile(&ps->saved); 2219 store_image_free(ps, NULL); 2220 } 2221 2222 /*********************** PNG FILE MODIFICATION ON READ ************************/ 2223 /* Files may be modified on read. The following structure contains a complete 2224 * png_store together with extra members to handle modification and a special 2225 * read callback for libpng. To use this the 'modifications' field must be set 2226 * to a list of png_modification structures that actually perform the 2227 * modification, otherwise a png_modifier is functionally equivalent to a 2228 * png_store. There is a special read function, set_modifier_for_read, which 2229 * replaces set_store_for_read. 2230 */ 2231 typedef enum modifier_state 2232 { 2233 modifier_start, /* Initial value */ 2234 modifier_signature, /* Have a signature */ 2235 modifier_IHDR /* Have an IHDR */ 2236 } modifier_state; 2237 2238 typedef struct CIE_color 2239 { 2240 /* A single CIE tristimulus value, representing the unique response of a 2241 * standard observer to a variety of light spectra. The observer recognizes 2242 * all spectra that produce this response as the same color, therefore this 2243 * is effectively a description of a color. 2244 */ 2245 double X, Y, Z; 2246 } CIE_color; 2247 2248 typedef struct color_encoding 2249 { 2250 /* A description of an (R,G,B) encoding of color (as defined above); this 2251 * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and 2252 * (0,0,1) plus an encoding value that is used to encode the linear 2253 * components R, G and B to give the actual values R^gamma, G^gamma and 2254 * B^gamma that are stored. 2255 */ 2256 double gamma; /* Encoding (file) gamma of space */ 2257 CIE_color red, green, blue; /* End points */ 2258 } color_encoding; 2259 2260 #ifdef PNG_READ_SUPPORTED 2261 #if defined PNG_READ_TRANSFORMS_SUPPORTED && defined PNG_READ_cHRM_SUPPORTED 2262 static double 2263 chromaticity_x(CIE_color c) 2264 { 2265 return c.X / (c.X + c.Y + c.Z); 2266 } 2267 2268 static double 2269 chromaticity_y(CIE_color c) 2270 { 2271 return c.Y / (c.X + c.Y + c.Z); 2272 } 2273 2274 static CIE_color 2275 white_point(const color_encoding *encoding) 2276 { 2277 CIE_color white; 2278 2279 white.X = encoding->red.X + encoding->green.X + encoding->blue.X; 2280 white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y; 2281 white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z; 2282 2283 return white; 2284 } 2285 #endif /* READ_TRANSFORMS && READ_cHRM */ 2286 2287 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2288 static void 2289 normalize_color_encoding(color_encoding *encoding) 2290 { 2291 const double whiteY = encoding->red.Y + encoding->green.Y + 2292 encoding->blue.Y; 2293 2294 if (whiteY != 1) 2295 { 2296 encoding->red.X /= whiteY; 2297 encoding->red.Y /= whiteY; 2298 encoding->red.Z /= whiteY; 2299 encoding->green.X /= whiteY; 2300 encoding->green.Y /= whiteY; 2301 encoding->green.Z /= whiteY; 2302 encoding->blue.X /= whiteY; 2303 encoding->blue.Y /= whiteY; 2304 encoding->blue.Z /= whiteY; 2305 } 2306 } 2307 #endif 2308 2309 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 2310 static size_t 2311 safecat_color_encoding(char *buffer, size_t bufsize, size_t pos, 2312 const color_encoding *e, double encoding_gamma) 2313 { 2314 if (e != 0) 2315 { 2316 if (encoding_gamma != 0) 2317 pos = safecat(buffer, bufsize, pos, "("); 2318 pos = safecat(buffer, bufsize, pos, "R("); 2319 pos = safecatd(buffer, bufsize, pos, e->red.X, 4); 2320 pos = safecat(buffer, bufsize, pos, ","); 2321 pos = safecatd(buffer, bufsize, pos, e->red.Y, 4); 2322 pos = safecat(buffer, bufsize, pos, ","); 2323 pos = safecatd(buffer, bufsize, pos, e->red.Z, 4); 2324 pos = safecat(buffer, bufsize, pos, "),G("); 2325 pos = safecatd(buffer, bufsize, pos, e->green.X, 4); 2326 pos = safecat(buffer, bufsize, pos, ","); 2327 pos = safecatd(buffer, bufsize, pos, e->green.Y, 4); 2328 pos = safecat(buffer, bufsize, pos, ","); 2329 pos = safecatd(buffer, bufsize, pos, e->green.Z, 4); 2330 pos = safecat(buffer, bufsize, pos, "),B("); 2331 pos = safecatd(buffer, bufsize, pos, e->blue.X, 4); 2332 pos = safecat(buffer, bufsize, pos, ","); 2333 pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4); 2334 pos = safecat(buffer, bufsize, pos, ","); 2335 pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4); 2336 pos = safecat(buffer, bufsize, pos, ")"); 2337 if (encoding_gamma != 0) 2338 pos = safecat(buffer, bufsize, pos, ")"); 2339 } 2340 2341 if (encoding_gamma != 0) 2342 { 2343 pos = safecat(buffer, bufsize, pos, "^"); 2344 pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5); 2345 } 2346 2347 return pos; 2348 } 2349 #endif /* READ_TRANSFORMS */ 2350 #endif /* PNG_READ_SUPPORTED */ 2351 2352 typedef struct png_modifier 2353 { 2354 png_store this; /* I am a png_store */ 2355 struct png_modification *modifications; /* Changes to make */ 2356 2357 modifier_state state; /* My state */ 2358 2359 /* Information from IHDR: */ 2360 png_byte bit_depth; /* From IHDR */ 2361 png_byte colour_type; /* From IHDR */ 2362 2363 /* While handling PLTE, IDAT and IEND these chunks may be pended to allow 2364 * other chunks to be inserted. 2365 */ 2366 png_uint_32 pending_len; 2367 png_uint_32 pending_chunk; 2368 2369 /* Test values */ 2370 double *gammas; 2371 unsigned int ngammas; 2372 unsigned int ngamma_tests; /* Number of gamma tests to run*/ 2373 double current_gamma; /* 0 if not set */ 2374 const color_encoding *encodings; 2375 unsigned int nencodings; 2376 const color_encoding *current_encoding; /* If an encoding has been set */ 2377 unsigned int encoding_counter; /* For iteration */ 2378 int encoding_ignored; /* Something overwrote it */ 2379 2380 /* Control variables used to iterate through possible encodings, the 2381 * following must be set to 0 and tested by the function that uses the 2382 * png_modifier because the modifier only sets it to 1 (true.) 2383 */ 2384 unsigned int repeat :1; /* Repeat this transform test. */ 2385 unsigned int test_uses_encoding :1; 2386 2387 /* Lowest sbit to test (pre-1.7 libpng fails for sbit < 8) */ 2388 png_byte sbitlow; 2389 2390 /* Error control - these are the limits on errors accepted by the gamma tests 2391 * below. 2392 */ 2393 double maxout8; /* Maximum output value error */ 2394 double maxabs8; /* Absolute sample error 0..1 */ 2395 double maxcalc8; /* Absolute sample error 0..1 */ 2396 double maxpc8; /* Percentage sample error 0..100% */ 2397 double maxout16; /* Maximum output value error */ 2398 double maxabs16; /* Absolute sample error 0..1 */ 2399 double maxcalc16;/* Absolute sample error 0..1 */ 2400 double maxcalcG; /* Absolute sample error 0..1 */ 2401 double maxpc16; /* Percentage sample error 0..100% */ 2402 2403 /* This is set by transforms that need to allow a higher limit, it is an 2404 * internal check on pngvalid to ensure that the calculated error limits are 2405 * not ridiculous; without this it is too easy to make a mistake in pngvalid 2406 * that allows any value through. 2407 * 2408 * NOTE: this is not checked in release builds. 2409 */ 2410 double limit; /* limit on error values, normally 4E-3 */ 2411 2412 /* Log limits - values above this are logged, but not necessarily 2413 * warned. 2414 */ 2415 double log8; /* Absolute error in 8 bits to log */ 2416 double log16; /* Absolute error in 16 bits to log */ 2417 2418 /* Logged 8 and 16 bit errors ('output' values): */ 2419 double error_gray_2; 2420 double error_gray_4; 2421 double error_gray_8; 2422 double error_gray_16; 2423 double error_color_8; 2424 double error_color_16; 2425 double error_indexed; 2426 2427 /* Flags: */ 2428 /* Whether to call png_read_update_info, not png_read_start_image, and how 2429 * many times to call it. 2430 */ 2431 int use_update_info; 2432 2433 /* Whether or not to interlace. */ 2434 int interlace_type :9; /* int, but must store '1' */ 2435 2436 /* Run the standard tests? */ 2437 unsigned int test_standard :1; 2438 2439 /* Run the odd-sized image and interlace read/write tests? */ 2440 unsigned int test_size :1; 2441 2442 /* Run tests on reading with a combination of transforms, */ 2443 unsigned int test_transform :1; 2444 unsigned int test_tRNS :1; /* Includes tRNS images */ 2445 2446 /* When to use the use_input_precision option, this controls the gamma 2447 * validation code checks. If set any value that is within the transformed 2448 * range input-.5 to input+.5 will be accepted, otherwise the value must be 2449 * within the normal limits. It should not be necessary to set this; the 2450 * result should always be exact within the permitted error limits. 2451 */ 2452 unsigned int use_input_precision :1; 2453 unsigned int use_input_precision_sbit :1; 2454 unsigned int use_input_precision_16to8 :1; 2455 2456 /* If set assume that the calculation bit depth is set by the input 2457 * precision, not the output precision. 2458 */ 2459 unsigned int calculations_use_input_precision :1; 2460 2461 /* If set assume that the calculations are done in 16 bits even if the sample 2462 * depth is 8 bits. 2463 */ 2464 unsigned int assume_16_bit_calculations :1; 2465 2466 /* Which gamma tests to run: */ 2467 unsigned int test_gamma_threshold :1; 2468 unsigned int test_gamma_transform :1; /* main tests */ 2469 unsigned int test_gamma_sbit :1; 2470 unsigned int test_gamma_scale16 :1; 2471 unsigned int test_gamma_background :1; 2472 unsigned int test_gamma_alpha_mode :1; 2473 unsigned int test_gamma_expand16 :1; 2474 unsigned int test_exhaustive :1; 2475 2476 /* Whether or not to run the low-bit-depth grayscale tests. This fails on 2477 * gamma images in some cases because of gross inaccuracies in the grayscale 2478 * gamma handling for low bit depth. 2479 */ 2480 unsigned int test_lbg :1; 2481 unsigned int test_lbg_gamma_threshold :1; 2482 unsigned int test_lbg_gamma_transform :1; 2483 unsigned int test_lbg_gamma_sbit :1; 2484 unsigned int test_lbg_gamma_composition :1; 2485 2486 unsigned int log :1; /* Log max error */ 2487 2488 /* Buffer information, the buffer size limits the size of the chunks that can 2489 * be modified - they must fit (including header and CRC) into the buffer! 2490 */ 2491 size_t flush; /* Count of bytes to flush */ 2492 size_t buffer_count; /* Bytes in buffer */ 2493 size_t buffer_position; /* Position in buffer */ 2494 png_byte buffer[1024]; 2495 } png_modifier; 2496 2497 /* This returns true if the test should be stopped now because it has already 2498 * failed and it is running silently. 2499 */ 2500 static int fail(png_modifier *pm) 2501 { 2502 return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 || 2503 (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0)); 2504 } 2505 2506 static void 2507 modifier_init(png_modifier *pm) 2508 { 2509 memset(pm, 0, sizeof *pm); 2510 store_init(&pm->this); 2511 pm->modifications = NULL; 2512 pm->state = modifier_start; 2513 pm->sbitlow = 1U; 2514 pm->ngammas = 0; 2515 pm->ngamma_tests = 0; 2516 pm->gammas = 0; 2517 pm->current_gamma = 0; 2518 pm->encodings = 0; 2519 pm->nencodings = 0; 2520 pm->current_encoding = 0; 2521 pm->encoding_counter = 0; 2522 pm->encoding_ignored = 0; 2523 pm->repeat = 0; 2524 pm->test_uses_encoding = 0; 2525 pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0; 2526 pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0; 2527 pm->maxcalcG = 0; 2528 pm->limit = 4E-3; 2529 pm->log8 = pm->log16 = 0; /* Means 'off' */ 2530 pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0; 2531 pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0; 2532 pm->error_indexed = 0; 2533 pm->use_update_info = 0; 2534 pm->interlace_type = PNG_INTERLACE_NONE; 2535 pm->test_standard = 0; 2536 pm->test_size = 0; 2537 pm->test_transform = 0; 2538 # ifdef PNG_WRITE_tRNS_SUPPORTED 2539 pm->test_tRNS = 1; 2540 # else 2541 pm->test_tRNS = 0; 2542 # endif 2543 pm->use_input_precision = 0; 2544 pm->use_input_precision_sbit = 0; 2545 pm->use_input_precision_16to8 = 0; 2546 pm->calculations_use_input_precision = 0; 2547 pm->assume_16_bit_calculations = 0; 2548 pm->test_gamma_threshold = 0; 2549 pm->test_gamma_transform = 0; 2550 pm->test_gamma_sbit = 0; 2551 pm->test_gamma_scale16 = 0; 2552 pm->test_gamma_background = 0; 2553 pm->test_gamma_alpha_mode = 0; 2554 pm->test_gamma_expand16 = 0; 2555 pm->test_lbg = 1; 2556 pm->test_lbg_gamma_threshold = 1; 2557 pm->test_lbg_gamma_transform = 1; 2558 pm->test_lbg_gamma_sbit = 1; 2559 pm->test_lbg_gamma_composition = 1; 2560 pm->test_exhaustive = 0; 2561 pm->log = 0; 2562 2563 /* Rely on the memset for all the other fields - there are no pointers */ 2564 } 2565 2566 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 2567 2568 /* This controls use of checks that explicitly know how libpng digitizes the 2569 * samples in calculations; setting this circumvents simple error limit checking 2570 * in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5 2571 * algorithm. 2572 */ 2573 #define DIGITIZE PNG_LIBPNG_VER < 10700 2574 2575 /* If pm->calculations_use_input_precision is set then operations will happen 2576 * with the precision of the input, not the precision of the output depth. 2577 * 2578 * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16 2579 * bit precision. This only affects those of the following limits that pertain 2580 * to a calculation - not a digitization operation - unless the following API is 2581 * called directly. 2582 */ 2583 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2584 #if DIGITIZE 2585 static double digitize(double value, int depth, int do_round) 2586 { 2587 /* 'value' is in the range 0 to 1, the result is the same value rounded to a 2588 * multiple of the digitization factor - 8 or 16 bits depending on both the 2589 * sample depth and the 'assume' setting. Digitization is normally by 2590 * rounding and 'do_round' should be 1, if it is 0 the digitized value will 2591 * be truncated. 2592 */ 2593 const unsigned int digitization_factor = (1U << depth) -1; 2594 2595 /* Limiting the range is done as a convenience to the caller - it's easier to 2596 * do it once here than every time at the call site. 2597 */ 2598 if (value <= 0) 2599 value = 0; 2600 2601 else if (value >= 1) 2602 value = 1; 2603 2604 value *= digitization_factor; 2605 if (do_round) value += .5; 2606 return floor(value)/digitization_factor; 2607 } 2608 #endif 2609 #endif /* RGB_TO_GRAY */ 2610 2611 #ifdef PNG_READ_GAMMA_SUPPORTED 2612 static double abserr(const png_modifier *pm, int in_depth, int out_depth) 2613 { 2614 /* Absolute error permitted in linear values - affected by the bit depth of 2615 * the calculations. 2616 */ 2617 if (pm->assume_16_bit_calculations || 2618 (pm->calculations_use_input_precision ? in_depth : out_depth) == 16) 2619 return pm->maxabs16; 2620 else 2621 return pm->maxabs8; 2622 } 2623 2624 static double calcerr(const png_modifier *pm, int in_depth, int out_depth) 2625 { 2626 /* Error in the linear composition arithmetic - only relevant when 2627 * composition actually happens (0 < alpha < 1). 2628 */ 2629 if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) 2630 return pm->maxcalc16; 2631 else if (pm->assume_16_bit_calculations) 2632 return pm->maxcalcG; 2633 else 2634 return pm->maxcalc8; 2635 } 2636 2637 static double pcerr(const png_modifier *pm, int in_depth, int out_depth) 2638 { 2639 /* Percentage error permitted in the linear values. Note that the specified 2640 * value is a percentage but this routine returns a simple number. 2641 */ 2642 if (pm->assume_16_bit_calculations || 2643 (pm->calculations_use_input_precision ? in_depth : out_depth) == 16) 2644 return pm->maxpc16 * .01; 2645 else 2646 return pm->maxpc8 * .01; 2647 } 2648 2649 /* Output error - the error in the encoded value. This is determined by the 2650 * digitization of the output so can be +/-0.5 in the actual output value. In 2651 * the expand_16 case with the current code in libpng the expand happens after 2652 * all the calculations are done in 8 bit arithmetic, so even though the output 2653 * depth is 16 the output error is determined by the 8 bit calculation. 2654 * 2655 * This limit is not determined by the bit depth of internal calculations. 2656 * 2657 * The specified parameter does *not* include the base .5 digitization error but 2658 * it is added here. 2659 */ 2660 static double outerr(const png_modifier *pm, int in_depth, int out_depth) 2661 { 2662 /* There is a serious error in the 2 and 4 bit grayscale transform because 2663 * the gamma table value (8 bits) is simply shifted, not rounded, so the 2664 * error in 4 bit grayscale gamma is up to the value below. This is a hack 2665 * to allow pngvalid to succeed: 2666 * 2667 * TODO: fix this in libpng 2668 */ 2669 if (out_depth == 2) 2670 return .73182-.5; 2671 2672 if (out_depth == 4) 2673 return .90644-.5; 2674 2675 if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) 2676 return pm->maxout16; 2677 2678 /* This is the case where the value was calculated at 8-bit precision then 2679 * scaled to 16 bits. 2680 */ 2681 else if (out_depth == 16) 2682 return pm->maxout8 * 257; 2683 2684 else 2685 return pm->maxout8; 2686 } 2687 2688 /* This does the same thing as the above however it returns the value to log, 2689 * rather than raising a warning. This is useful for debugging to track down 2690 * exactly what set of parameters cause high error values. 2691 */ 2692 static double outlog(const png_modifier *pm, int in_depth, int out_depth) 2693 { 2694 /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535) 2695 * and so must be adjusted for low bit depth grayscale: 2696 */ 2697 if (out_depth <= 8) 2698 { 2699 if (pm->log8 == 0) /* switched off */ 2700 return 256; 2701 2702 if (out_depth < 8) 2703 return pm->log8 / 255 * ((1<<out_depth)-1); 2704 2705 return pm->log8; 2706 } 2707 2708 if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) 2709 { 2710 if (pm->log16 == 0) 2711 return 65536; 2712 2713 return pm->log16; 2714 } 2715 2716 /* This is the case where the value was calculated at 8-bit precision then 2717 * scaled to 16 bits. 2718 */ 2719 if (pm->log8 == 0) 2720 return 65536; 2721 2722 return pm->log8 * 257; 2723 } 2724 2725 /* This complements the above by providing the appropriate quantization for the 2726 * final value. Normally this would just be quantization to an integral value, 2727 * but in the 8 bit calculation case it's actually quantization to a multiple of 2728 * 257! 2729 */ 2730 static int output_quantization_factor(const png_modifier *pm, int in_depth, 2731 int out_depth) 2732 { 2733 if (out_depth == 16 && in_depth != 16 && 2734 pm->calculations_use_input_precision) 2735 return 257; 2736 else 2737 return 1; 2738 } 2739 #endif /* PNG_READ_GAMMA_SUPPORTED */ 2740 2741 /* One modification structure must be provided for each chunk to be modified (in 2742 * fact more than one can be provided if multiple separate changes are desired 2743 * for a single chunk.) Modifications include adding a new chunk when a 2744 * suitable chunk does not exist. 2745 * 2746 * The caller of modify_fn will reset the CRC of the chunk and record 'modified' 2747 * or 'added' as appropriate if the modify_fn returns 1 (true). If the 2748 * modify_fn is NULL the chunk is simply removed. 2749 */ 2750 typedef struct png_modification 2751 { 2752 struct png_modification *next; 2753 png_uint_32 chunk; 2754 2755 /* If the following is NULL all matching chunks will be removed: */ 2756 int (*modify_fn)(struct png_modifier *pm, 2757 struct png_modification *me, int add); 2758 2759 /* If the following is set to PLTE, IDAT or IEND and the chunk has not been 2760 * found and modified (and there is a modify_fn) the modify_fn will be called 2761 * to add the chunk before the relevant chunk. 2762 */ 2763 png_uint_32 add; 2764 unsigned int modified :1; /* Chunk was modified */ 2765 unsigned int added :1; /* Chunk was added */ 2766 unsigned int removed :1; /* Chunk was removed */ 2767 } png_modification; 2768 2769 static void 2770 modification_reset(png_modification *pmm) 2771 { 2772 if (pmm != NULL) 2773 { 2774 pmm->modified = 0; 2775 pmm->added = 0; 2776 pmm->removed = 0; 2777 modification_reset(pmm->next); 2778 } 2779 } 2780 2781 static void 2782 modification_init(png_modification *pmm) 2783 { 2784 memset(pmm, 0, sizeof *pmm); 2785 pmm->next = NULL; 2786 pmm->chunk = 0; 2787 pmm->modify_fn = NULL; 2788 pmm->add = 0; 2789 modification_reset(pmm); 2790 } 2791 2792 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 2793 static void 2794 modifier_current_encoding(const png_modifier *pm, color_encoding *ce) 2795 { 2796 if (pm->current_encoding != 0) 2797 *ce = *pm->current_encoding; 2798 2799 else 2800 memset(ce, 0, sizeof *ce); 2801 2802 ce->gamma = pm->current_gamma; 2803 } 2804 #endif 2805 2806 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 2807 static size_t 2808 safecat_current_encoding(char *buffer, size_t bufsize, size_t pos, 2809 const png_modifier *pm) 2810 { 2811 pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding, 2812 pm->current_gamma); 2813 2814 if (pm->encoding_ignored) 2815 pos = safecat(buffer, bufsize, pos, "[overridden]"); 2816 2817 return pos; 2818 } 2819 #endif 2820 2821 /* Iterate through the usefully testable color encodings. An encoding is one 2822 * of: 2823 * 2824 * 1) Nothing (no color space, no gamma). 2825 * 2) Just a gamma value from the gamma array (including 1.0) 2826 * 3) A color space from the encodings array with the corresponding gamma. 2827 * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations) 2828 * 2829 * The iterator selects these in turn, the randomizer selects one at random, 2830 * which is used depends on the setting of the 'test_exhaustive' flag. Notice 2831 * that this function changes the colour space encoding so it must only be 2832 * called on completion of the previous test. This is what 'modifier_reset' 2833 * does, below. 2834 * 2835 * After the function has been called the 'repeat' flag will still be set; the 2836 * caller of modifier_reset must reset it at the start of each run of the test! 2837 */ 2838 static unsigned int 2839 modifier_total_encodings(const png_modifier *pm) 2840 { 2841 return 1 + /* (1) nothing */ 2842 pm->ngammas + /* (2) gamma values to test */ 2843 pm->nencodings + /* (3) total number of encodings */ 2844 /* The following test only works after the first time through the 2845 * png_modifier code because 'bit_depth' is set when the IHDR is read. 2846 * modifier_reset, below, preserves the setting until after it has called 2847 * the iterate function (also below.) 2848 * 2849 * For this reason do not rely on this function outside a call to 2850 * modifier_reset. 2851 */ 2852 ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ? 2853 pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */ 2854 } 2855 2856 static void 2857 modifier_encoding_iterate(png_modifier *pm) 2858 { 2859 if (!pm->repeat && /* Else something needs the current encoding again. */ 2860 pm->test_uses_encoding) /* Some transform is encoding dependent */ 2861 { 2862 if (pm->test_exhaustive) 2863 { 2864 if (++pm->encoding_counter >= modifier_total_encodings(pm)) 2865 pm->encoding_counter = 0; /* This will stop the repeat */ 2866 } 2867 2868 else 2869 { 2870 /* Not exhaustive - choose an encoding at random; generate a number in 2871 * the range 1..(max-1), so the result is always non-zero: 2872 */ 2873 if (pm->encoding_counter == 0) 2874 pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1; 2875 else 2876 pm->encoding_counter = 0; 2877 } 2878 2879 if (pm->encoding_counter > 0) 2880 pm->repeat = 1; 2881 } 2882 2883 else if (!pm->repeat) 2884 pm->encoding_counter = 0; 2885 } 2886 2887 static void 2888 modifier_reset(png_modifier *pm) 2889 { 2890 store_read_reset(&pm->this); 2891 pm->limit = 4E-3; 2892 pm->pending_len = pm->pending_chunk = 0; 2893 pm->flush = pm->buffer_count = pm->buffer_position = 0; 2894 pm->modifications = NULL; 2895 pm->state = modifier_start; 2896 modifier_encoding_iterate(pm); 2897 /* The following must be set in the next run. In particular 2898 * test_uses_encodings must be set in the _ini function of each transform 2899 * that looks at the encodings. (Not the 'add' function!) 2900 */ 2901 pm->test_uses_encoding = 0; 2902 pm->current_gamma = 0; 2903 pm->current_encoding = 0; 2904 pm->encoding_ignored = 0; 2905 /* These only become value after IHDR is read: */ 2906 pm->bit_depth = pm->colour_type = 0; 2907 } 2908 2909 /* The following must be called before anything else to get the encoding set up 2910 * on the modifier. In particular it must be called before the transform init 2911 * functions are called. 2912 */ 2913 static void 2914 modifier_set_encoding(png_modifier *pm) 2915 { 2916 /* Set the encoding to the one specified by the current encoding counter, 2917 * first clear out all the settings - this corresponds to an encoding_counter 2918 * of 0. 2919 */ 2920 pm->current_gamma = 0; 2921 pm->current_encoding = 0; 2922 pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */ 2923 2924 /* Now, if required, set the gamma and encoding fields. */ 2925 if (pm->encoding_counter > 0) 2926 { 2927 /* The gammas[] array is an array of screen gammas, not encoding gammas, 2928 * so we need the inverse: 2929 */ 2930 if (pm->encoding_counter <= pm->ngammas) 2931 pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1]; 2932 2933 else 2934 { 2935 unsigned int i = pm->encoding_counter - pm->ngammas; 2936 2937 if (i >= pm->nencodings) 2938 { 2939 i %= pm->nencodings; 2940 pm->current_gamma = 1; /* Linear, only in the 16 bit case */ 2941 } 2942 2943 else 2944 pm->current_gamma = pm->encodings[i].gamma; 2945 2946 pm->current_encoding = pm->encodings + i; 2947 } 2948 } 2949 } 2950 2951 /* Enquiry functions to find out what is set. Notice that there is an implicit 2952 * assumption below that the first encoding in the list is the one for sRGB. 2953 */ 2954 static int 2955 modifier_color_encoding_is_sRGB(const png_modifier *pm) 2956 { 2957 return pm->current_encoding != 0 && pm->current_encoding == pm->encodings && 2958 pm->current_encoding->gamma == pm->current_gamma; 2959 } 2960 2961 static int 2962 modifier_color_encoding_is_set(const png_modifier *pm) 2963 { 2964 return pm->current_gamma != 0; 2965 } 2966 2967 /* The guts of modification are performed during a read. */ 2968 static void 2969 modifier_crc(png_bytep buffer) 2970 { 2971 /* Recalculate the chunk CRC - a complete chunk must be in 2972 * the buffer, at the start. 2973 */ 2974 uInt datalen = png_get_uint_32(buffer); 2975 uLong crc = crc32(0, buffer+4, datalen+4); 2976 /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value. 2977 */ 2978 png_save_uint_32(buffer+datalen+8, (png_uint_32)crc); 2979 } 2980 2981 static void 2982 modifier_setbuffer(png_modifier *pm) 2983 { 2984 modifier_crc(pm->buffer); 2985 pm->buffer_count = png_get_uint_32(pm->buffer)+12; 2986 pm->buffer_position = 0; 2987 } 2988 2989 /* Separate the callback into the actual implementation (which is passed the 2990 * png_modifier explicitly) and the callback, which gets the modifier from the 2991 * png_struct. 2992 */ 2993 static void 2994 modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st) 2995 { 2996 while (st > 0) 2997 { 2998 size_t cb; 2999 png_uint_32 len, chunk; 3000 png_modification *mod; 3001 3002 if (pm->buffer_position >= pm->buffer_count) switch (pm->state) 3003 { 3004 static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; 3005 case modifier_start: 3006 store_read_chunk(&pm->this, pm->buffer, 8, 8); /* signature. */ 3007 pm->buffer_count = 8; 3008 pm->buffer_position = 0; 3009 3010 if (memcmp(pm->buffer, sign, 8) != 0) 3011 png_error(pm->this.pread, "invalid PNG file signature"); 3012 pm->state = modifier_signature; 3013 break; 3014 3015 case modifier_signature: 3016 store_read_chunk(&pm->this, pm->buffer, 13+12, 13+12); /* IHDR */ 3017 pm->buffer_count = 13+12; 3018 pm->buffer_position = 0; 3019 3020 if (png_get_uint_32(pm->buffer) != 13 || 3021 png_get_uint_32(pm->buffer+4) != CHUNK_IHDR) 3022 png_error(pm->this.pread, "invalid IHDR"); 3023 3024 /* Check the list of modifiers for modifications to the IHDR. */ 3025 mod = pm->modifications; 3026 while (mod != NULL) 3027 { 3028 if (mod->chunk == CHUNK_IHDR && mod->modify_fn && 3029 (*mod->modify_fn)(pm, mod, 0)) 3030 { 3031 mod->modified = 1; 3032 modifier_setbuffer(pm); 3033 } 3034 3035 /* Ignore removal or add if IHDR! */ 3036 mod = mod->next; 3037 } 3038 3039 /* Cache information from the IHDR (the modified one.) */ 3040 pm->bit_depth = pm->buffer[8+8]; 3041 pm->colour_type = pm->buffer[8+8+1]; 3042 3043 pm->state = modifier_IHDR; 3044 pm->flush = 0; 3045 break; 3046 3047 case modifier_IHDR: 3048 default: 3049 /* Read a new chunk and process it until we see PLTE, IDAT or 3050 * IEND. 'flush' indicates that there is still some data to 3051 * output from the preceding chunk. 3052 */ 3053 if ((cb = pm->flush) > 0) 3054 { 3055 if (cb > st) cb = st; 3056 pm->flush -= cb; 3057 store_read_chunk(&pm->this, pb, cb, cb); 3058 pb += cb; 3059 st -= cb; 3060 if (st == 0) return; 3061 } 3062 3063 /* No more bytes to flush, read a header, or handle a pending 3064 * chunk. 3065 */ 3066 if (pm->pending_chunk != 0) 3067 { 3068 png_save_uint_32(pm->buffer, pm->pending_len); 3069 png_save_uint_32(pm->buffer+4, pm->pending_chunk); 3070 pm->pending_len = 0; 3071 pm->pending_chunk = 0; 3072 } 3073 else 3074 store_read_chunk(&pm->this, pm->buffer, 8, 8); 3075 3076 pm->buffer_count = 8; 3077 pm->buffer_position = 0; 3078 3079 /* Check for something to modify or a terminator chunk. */ 3080 len = png_get_uint_32(pm->buffer); 3081 chunk = png_get_uint_32(pm->buffer+4); 3082 3083 /* Terminators first, they may have to be delayed for added 3084 * chunks 3085 */ 3086 if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT || 3087 chunk == CHUNK_IEND) 3088 { 3089 mod = pm->modifications; 3090 3091 while (mod != NULL) 3092 { 3093 if ((mod->add == chunk || 3094 (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) && 3095 mod->modify_fn != NULL && !mod->modified && !mod->added) 3096 { 3097 /* Regardless of what the modify function does do not run 3098 * this again. 3099 */ 3100 mod->added = 1; 3101 3102 if ((*mod->modify_fn)(pm, mod, 1 /*add*/)) 3103 { 3104 /* Reset the CRC on a new chunk */ 3105 if (pm->buffer_count > 0) 3106 modifier_setbuffer(pm); 3107 3108 else 3109 { 3110 pm->buffer_position = 0; 3111 mod->removed = 1; 3112 } 3113 3114 /* The buffer has been filled with something (we assume) 3115 * so output this. Pend the current chunk. 3116 */ 3117 pm->pending_len = len; 3118 pm->pending_chunk = chunk; 3119 break; /* out of while */ 3120 } 3121 } 3122 3123 mod = mod->next; 3124 } 3125 3126 /* Don't do any further processing if the buffer was modified - 3127 * otherwise the code will end up modifying a chunk that was 3128 * just added. 3129 */ 3130 if (mod != NULL) 3131 break; /* out of switch */ 3132 } 3133 3134 /* If we get to here then this chunk may need to be modified. To 3135 * do this it must be less than 1024 bytes in total size, otherwise 3136 * it just gets flushed. 3137 */ 3138 if (len+12 <= sizeof pm->buffer) 3139 { 3140 png_size_t s = len+12-pm->buffer_count; 3141 store_read_chunk(&pm->this, pm->buffer+pm->buffer_count, s, s); 3142 pm->buffer_count = len+12; 3143 3144 /* Check for a modification, else leave it be. */ 3145 mod = pm->modifications; 3146 while (mod != NULL) 3147 { 3148 if (mod->chunk == chunk) 3149 { 3150 if (mod->modify_fn == NULL) 3151 { 3152 /* Remove this chunk */ 3153 pm->buffer_count = pm->buffer_position = 0; 3154 mod->removed = 1; 3155 break; /* Terminate the while loop */ 3156 } 3157 3158 else if ((*mod->modify_fn)(pm, mod, 0)) 3159 { 3160 mod->modified = 1; 3161 /* The chunk may have been removed: */ 3162 if (pm->buffer_count == 0) 3163 { 3164 pm->buffer_position = 0; 3165 break; 3166 } 3167 modifier_setbuffer(pm); 3168 } 3169 } 3170 3171 mod = mod->next; 3172 } 3173 } 3174 3175 else 3176 pm->flush = len+12 - pm->buffer_count; /* data + crc */ 3177 3178 /* Take the data from the buffer (if there is any). */ 3179 break; 3180 } 3181 3182 /* Here to read from the modifier buffer (not directly from 3183 * the store, as in the flush case above.) 3184 */ 3185 cb = pm->buffer_count - pm->buffer_position; 3186 3187 if (cb > st) 3188 cb = st; 3189 3190 memcpy(pb, pm->buffer + pm->buffer_position, cb); 3191 st -= cb; 3192 pb += cb; 3193 pm->buffer_position += cb; 3194 } 3195 } 3196 3197 /* The callback: */ 3198 static void PNGCBAPI 3199 modifier_read(png_structp ppIn, png_bytep pb, png_size_t st) 3200 { 3201 png_const_structp pp = ppIn; 3202 png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp)); 3203 3204 if (pm == NULL || pm->this.pread != pp) 3205 png_error(pp, "bad modifier_read call"); 3206 3207 modifier_read_imp(pm, pb, st); 3208 } 3209 3210 /* Like store_progressive_read but the data is getting changed as we go so we 3211 * need a local buffer. 3212 */ 3213 static void 3214 modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi) 3215 { 3216 if (pm->this.pread != pp || pm->this.current == NULL || 3217 pm->this.next == NULL) 3218 png_error(pp, "store state damaged (progressive)"); 3219 3220 /* This is another Horowitz and Hill random noise generator. In this case 3221 * the aim is to stress the progressive reader with truly horrible variable 3222 * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers 3223 * is generated. We could probably just count from 1 to 32767 and get as 3224 * good a result. 3225 */ 3226 for (;;) 3227 { 3228 static png_uint_32 noise = 1; 3229 png_size_t cb, cbAvail; 3230 png_byte buffer[512]; 3231 3232 /* Generate 15 more bits of stuff: */ 3233 noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff); 3234 cb = noise & 0x1ff; 3235 3236 /* Check that this number of bytes are available (in the current buffer.) 3237 * (This doesn't quite work - the modifier might delete a chunk; unlikely 3238 * but possible, it doesn't happen at present because the modifier only 3239 * adds chunks to standard images.) 3240 */ 3241 cbAvail = store_read_buffer_avail(&pm->this); 3242 if (pm->buffer_count > pm->buffer_position) 3243 cbAvail += pm->buffer_count - pm->buffer_position; 3244 3245 if (cb > cbAvail) 3246 { 3247 /* Check for EOF: */ 3248 if (cbAvail == 0) 3249 break; 3250 3251 cb = cbAvail; 3252 } 3253 3254 modifier_read_imp(pm, buffer, cb); 3255 png_process_data(pp, pi, buffer, cb); 3256 } 3257 3258 /* Check the invariants at the end (if this fails it's a problem in this 3259 * file!) 3260 */ 3261 if (pm->buffer_count > pm->buffer_position || 3262 pm->this.next != &pm->this.current->data || 3263 pm->this.readpos < pm->this.current->datacount) 3264 png_error(pp, "progressive read implementation error"); 3265 } 3266 3267 /* Set up a modifier. */ 3268 static png_structp 3269 set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id, 3270 const char *name) 3271 { 3272 /* Do this first so that the modifier fields are cleared even if an error 3273 * happens allocating the png_struct. No allocation is done here so no 3274 * cleanup is required. 3275 */ 3276 pm->state = modifier_start; 3277 pm->bit_depth = 0; 3278 pm->colour_type = 255; 3279 3280 pm->pending_len = 0; 3281 pm->pending_chunk = 0; 3282 pm->flush = 0; 3283 pm->buffer_count = 0; 3284 pm->buffer_position = 0; 3285 3286 return set_store_for_read(&pm->this, ppi, id, name); 3287 } 3288 3289 3290 /******************************** MODIFICATIONS *******************************/ 3291 /* Standard modifications to add chunks. These do not require the _SUPPORTED 3292 * macros because the chunks can be there regardless of whether this specific 3293 * libpng supports them. 3294 */ 3295 typedef struct gama_modification 3296 { 3297 png_modification this; 3298 png_fixed_point gamma; 3299 } gama_modification; 3300 3301 static int 3302 gama_modify(png_modifier *pm, png_modification *me, int add) 3303 { 3304 UNUSED(add) 3305 /* This simply dumps the given gamma value into the buffer. */ 3306 png_save_uint_32(pm->buffer, 4); 3307 png_save_uint_32(pm->buffer+4, CHUNK_gAMA); 3308 png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma); 3309 return 1; 3310 } 3311 3312 static void 3313 gama_modification_init(gama_modification *me, png_modifier *pm, double gammad) 3314 { 3315 double g; 3316 3317 modification_init(&me->this); 3318 me->this.chunk = CHUNK_gAMA; 3319 me->this.modify_fn = gama_modify; 3320 me->this.add = CHUNK_PLTE; 3321 g = fix(gammad); 3322 me->gamma = (png_fixed_point)g; 3323 me->this.next = pm->modifications; 3324 pm->modifications = &me->this; 3325 } 3326 3327 typedef struct chrm_modification 3328 { 3329 png_modification this; 3330 const color_encoding *encoding; 3331 png_fixed_point wx, wy, rx, ry, gx, gy, bx, by; 3332 } chrm_modification; 3333 3334 static int 3335 chrm_modify(png_modifier *pm, png_modification *me, int add) 3336 { 3337 UNUSED(add) 3338 /* As with gAMA this just adds the required cHRM chunk to the buffer. */ 3339 png_save_uint_32(pm->buffer , 32); 3340 png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM); 3341 png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx); 3342 png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy); 3343 png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx); 3344 png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry); 3345 png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx); 3346 png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy); 3347 png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx); 3348 png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by); 3349 return 1; 3350 } 3351 3352 static void 3353 chrm_modification_init(chrm_modification *me, png_modifier *pm, 3354 const color_encoding *encoding) 3355 { 3356 CIE_color white = white_point(encoding); 3357 3358 /* Original end points: */ 3359 me->encoding = encoding; 3360 3361 /* Chromaticities (in fixed point): */ 3362 me->wx = fix(chromaticity_x(white)); 3363 me->wy = fix(chromaticity_y(white)); 3364 3365 me->rx = fix(chromaticity_x(encoding->red)); 3366 me->ry = fix(chromaticity_y(encoding->red)); 3367 me->gx = fix(chromaticity_x(encoding->green)); 3368 me->gy = fix(chromaticity_y(encoding->green)); 3369 me->bx = fix(chromaticity_x(encoding->blue)); 3370 me->by = fix(chromaticity_y(encoding->blue)); 3371 3372 modification_init(&me->this); 3373 me->this.chunk = CHUNK_cHRM; 3374 me->this.modify_fn = chrm_modify; 3375 me->this.add = CHUNK_PLTE; 3376 me->this.next = pm->modifications; 3377 pm->modifications = &me->this; 3378 } 3379 3380 typedef struct srgb_modification 3381 { 3382 png_modification this; 3383 png_byte intent; 3384 } srgb_modification; 3385 3386 static int 3387 srgb_modify(png_modifier *pm, png_modification *me, int add) 3388 { 3389 UNUSED(add) 3390 /* As above, ignore add and just make a new chunk */ 3391 png_save_uint_32(pm->buffer, 1); 3392 png_save_uint_32(pm->buffer+4, CHUNK_sRGB); 3393 pm->buffer[8] = ((srgb_modification*)me)->intent; 3394 return 1; 3395 } 3396 3397 static void 3398 srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent) 3399 { 3400 modification_init(&me->this); 3401 me->this.chunk = CHUNK_sBIT; 3402 3403 if (intent <= 3) /* if valid, else *delete* sRGB chunks */ 3404 { 3405 me->this.modify_fn = srgb_modify; 3406 me->this.add = CHUNK_PLTE; 3407 me->intent = intent; 3408 } 3409 3410 else 3411 { 3412 me->this.modify_fn = 0; 3413 me->this.add = 0; 3414 me->intent = 0; 3415 } 3416 3417 me->this.next = pm->modifications; 3418 pm->modifications = &me->this; 3419 } 3420 3421 #ifdef PNG_READ_GAMMA_SUPPORTED 3422 typedef struct sbit_modification 3423 { 3424 png_modification this; 3425 png_byte sbit; 3426 } sbit_modification; 3427 3428 static int 3429 sbit_modify(png_modifier *pm, png_modification *me, int add) 3430 { 3431 png_byte sbit = ((sbit_modification*)me)->sbit; 3432 if (pm->bit_depth > sbit) 3433 { 3434 int cb = 0; 3435 switch (pm->colour_type) 3436 { 3437 case 0: 3438 cb = 1; 3439 break; 3440 3441 case 2: 3442 case 3: 3443 cb = 3; 3444 break; 3445 3446 case 4: 3447 cb = 2; 3448 break; 3449 3450 case 6: 3451 cb = 4; 3452 break; 3453 3454 default: 3455 png_error(pm->this.pread, 3456 "unexpected colour type in sBIT modification"); 3457 } 3458 3459 png_save_uint_32(pm->buffer, cb); 3460 png_save_uint_32(pm->buffer+4, CHUNK_sBIT); 3461 3462 while (cb > 0) 3463 (pm->buffer+8)[--cb] = sbit; 3464 3465 return 1; 3466 } 3467 else if (!add) 3468 { 3469 /* Remove the sBIT chunk */ 3470 pm->buffer_count = pm->buffer_position = 0; 3471 return 1; 3472 } 3473 else 3474 return 0; /* do nothing */ 3475 } 3476 3477 static void 3478 sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit) 3479 { 3480 modification_init(&me->this); 3481 me->this.chunk = CHUNK_sBIT; 3482 me->this.modify_fn = sbit_modify; 3483 me->this.add = CHUNK_PLTE; 3484 me->sbit = sbit; 3485 me->this.next = pm->modifications; 3486 pm->modifications = &me->this; 3487 } 3488 #endif /* PNG_READ_GAMMA_SUPPORTED */ 3489 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 3490 3491 /***************************** STANDARD PNG FILES *****************************/ 3492 /* Standard files - write and save standard files. */ 3493 /* There are two basic forms of standard images. Those which attempt to have 3494 * all the possible pixel values (not possible for 16bpp images, but a range of 3495 * values are produced) and those which have a range of image sizes. The former 3496 * are used for testing transforms, in particular gamma correction and bit 3497 * reduction and increase. The latter are reserved for testing the behavior of 3498 * libpng with respect to 'odd' image sizes - particularly small images where 3499 * rows become 1 byte and interlace passes disappear. 3500 * 3501 * The first, most useful, set are the 'transform' images, the second set of 3502 * small images are the 'size' images. 3503 * 3504 * The transform files are constructed with rows which fit into a 1024 byte row 3505 * buffer. This makes allocation easier below. Further regardless of the file 3506 * format every row has 128 pixels (giving 1024 bytes for 64bpp formats). 3507 * 3508 * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed 3509 * and with an ID derived from the colour type, bit depth and interlace type 3510 * as above (FILEID). The width (128) and height (variable) are not stored in 3511 * the FILEID - instead the fields are set to 0, indicating a transform file. 3512 * 3513 * The size files ar constructed with rows a maximum of 128 bytes wide, allowing 3514 * a maximum width of 16 pixels (for the 64bpp case.) They also have a maximum 3515 * height of 16 rows. The width and height are stored in the FILEID and, being 3516 * non-zero, indicate a size file. 3517 * 3518 * Because the PNG filter code is typically the largest CPU consumer within 3519 * libpng itself there is a tendency to attempt to optimize it. This results in 3520 * special case code which needs to be validated. To cause this to happen the 3521 * 'size' images are made to use each possible filter, in so far as this is 3522 * possible for smaller images. 3523 * 3524 * For palette image (colour type 3) multiple transform images are stored with 3525 * the same bit depth to allow testing of more colour combinations - 3526 * particularly important for testing the gamma code because libpng uses a 3527 * different code path for palette images. For size images a single palette is 3528 * used. 3529 */ 3530 3531 /* Make a 'standard' palette. Because there are only 256 entries in a palette 3532 * (maximum) this actually makes a random palette in the hope that enough tests 3533 * will catch enough errors. (Note that the same palette isn't produced every 3534 * time for the same test - it depends on what previous tests have been run - 3535 * but a given set of arguments to pngvalid will always produce the same palette 3536 * at the same test! This is why pseudo-random number generators are useful for 3537 * testing.) 3538 * 3539 * The store must be open for write when this is called, otherwise an internal 3540 * error will occur. This routine contains its own magic number seed, so the 3541 * palettes generated don't change if there are intervening errors (changing the 3542 * calls to the store_mark seed.) 3543 */ 3544 static store_palette_entry * 3545 make_standard_palette(png_store* ps, int npalette, int do_tRNS) 3546 { 3547 static png_uint_32 palette_seed[2] = { 0x87654321, 9 }; 3548 3549 int i = 0; 3550 png_byte values[256][4]; 3551 3552 /* Always put in black and white plus the six primary and secondary colors. 3553 */ 3554 for (; i<8; ++i) 3555 { 3556 values[i][1] = (png_byte)((i&1) ? 255U : 0U); 3557 values[i][2] = (png_byte)((i&2) ? 255U : 0U); 3558 values[i][3] = (png_byte)((i&4) ? 255U : 0U); 3559 } 3560 3561 /* Then add 62 grays (one quarter of the remaining 256 slots). */ 3562 { 3563 int j = 0; 3564 png_byte random_bytes[4]; 3565 png_byte need[256]; 3566 3567 need[0] = 0; /*got black*/ 3568 memset(need+1, 1, (sizeof need)-2); /*need these*/ 3569 need[255] = 0; /*but not white*/ 3570 3571 while (i<70) 3572 { 3573 png_byte b; 3574 3575 if (j==0) 3576 { 3577 make_four_random_bytes(palette_seed, random_bytes); 3578 j = 4; 3579 } 3580 3581 b = random_bytes[--j]; 3582 if (need[b]) 3583 { 3584 values[i][1] = b; 3585 values[i][2] = b; 3586 values[i++][3] = b; 3587 } 3588 } 3589 } 3590 3591 /* Finally add 192 colors at random - don't worry about matches to things we 3592 * already have, chance is less than 1/65536. Don't worry about grays, 3593 * chance is the same, so we get a duplicate or extra gray less than 1 time 3594 * in 170. 3595 */ 3596 for (; i<256; ++i) 3597 make_four_random_bytes(palette_seed, values[i]); 3598 3599 /* Fill in the alpha values in the first byte. Just use all possible values 3600 * (0..255) in an apparently random order: 3601 */ 3602 { 3603 store_palette_entry *palette; 3604 png_byte selector[4]; 3605 3606 make_four_random_bytes(palette_seed, selector); 3607 3608 if (do_tRNS) 3609 for (i=0; i<256; ++i) 3610 values[i][0] = (png_byte)(i ^ selector[0]); 3611 3612 else 3613 for (i=0; i<256; ++i) 3614 values[i][0] = 255; /* no transparency/tRNS chunk */ 3615 3616 /* 'values' contains 256 ARGB values, but we only need 'npalette'. 3617 * 'npalette' will always be a power of 2: 2, 4, 16 or 256. In the low 3618 * bit depth cases select colors at random, else it is difficult to have 3619 * a set of low bit depth palette test with any chance of a reasonable 3620 * range of colors. Do this by randomly permuting values into the low 3621 * 'npalette' entries using an XOR mask generated here. This also 3622 * permutes the npalette == 256 case in a potentially useful way (there is 3623 * no relationship between palette index and the color value therein!) 3624 */ 3625 palette = store_write_palette(ps, npalette); 3626 3627 for (i=0; i<npalette; ++i) 3628 { 3629 palette[i].alpha = values[i ^ selector[1]][0]; 3630 palette[i].red = values[i ^ selector[1]][1]; 3631 palette[i].green = values[i ^ selector[1]][2]; 3632 palette[i].blue = values[i ^ selector[1]][3]; 3633 } 3634 3635 return palette; 3636 } 3637 } 3638 3639 /* Initialize a standard palette on a write stream. The 'do_tRNS' argument 3640 * indicates whether or not to also set the tRNS chunk. 3641 */ 3642 /* TODO: the png_structp here can probably be 'const' in the future */ 3643 static void 3644 init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette, 3645 int do_tRNS) 3646 { 3647 store_palette_entry *ppal = make_standard_palette(ps, npalette, do_tRNS); 3648 3649 { 3650 int i; 3651 png_color palette[256]; 3652 3653 /* Set all entries to detect overread errors. */ 3654 for (i=0; i<npalette; ++i) 3655 { 3656 palette[i].red = ppal[i].red; 3657 palette[i].green = ppal[i].green; 3658 palette[i].blue = ppal[i].blue; 3659 } 3660 3661 /* Just in case fill in the rest with detectable values: */ 3662 for (; i<256; ++i) 3663 palette[i].red = palette[i].green = palette[i].blue = 42; 3664 3665 png_set_PLTE(pp, pi, palette, npalette); 3666 } 3667 3668 if (do_tRNS) 3669 { 3670 int i, j; 3671 png_byte tRNS[256]; 3672 3673 /* Set all the entries, but skip trailing opaque entries */ 3674 for (i=j=0; i<npalette; ++i) 3675 if ((tRNS[i] = ppal[i].alpha) < 255) 3676 j = i+1; 3677 3678 /* Fill in the remainder with a detectable value: */ 3679 for (; i<256; ++i) 3680 tRNS[i] = 24; 3681 3682 #ifdef PNG_WRITE_tRNS_SUPPORTED 3683 if (j > 0) 3684 png_set_tRNS(pp, pi, tRNS, j, 0/*color*/); 3685 #endif 3686 } 3687 } 3688 3689 #ifdef PNG_WRITE_tRNS_SUPPORTED 3690 static void 3691 set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type, 3692 const int bit_depth) 3693 { 3694 /* To make this useful the tRNS color needs to match at least one pixel. 3695 * Random values are fine for gray, including the 16-bit case where we know 3696 * that the test image contains all the gray values. For RGB we need more 3697 * method as only 65536 different RGB values are generated. 3698 */ 3699 png_color_16 tRNS; 3700 const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1); 3701 3702 R8(tRNS); /* makes unset fields random */ 3703 3704 if (colour_type & 2/*RGB*/) 3705 { 3706 if (bit_depth == 8) 3707 { 3708 tRNS.red = random_u16(); 3709 tRNS.green = random_u16(); 3710 tRNS.blue = tRNS.red ^ tRNS.green; 3711 tRNS.red &= mask; 3712 tRNS.green &= mask; 3713 tRNS.blue &= mask; 3714 } 3715 3716 else /* bit_depth == 16 */ 3717 { 3718 tRNS.red = random_u16(); 3719 tRNS.green = (png_uint_16)(tRNS.red * 257); 3720 tRNS.blue = (png_uint_16)(tRNS.green * 17); 3721 } 3722 } 3723 3724 else 3725 { 3726 tRNS.gray = random_u16(); 3727 tRNS.gray &= mask; 3728 } 3729 3730 png_set_tRNS(pp, pi, NULL, 0, &tRNS); 3731 } 3732 #endif 3733 3734 /* The number of passes is related to the interlace type. There was no libpng 3735 * API to determine this prior to 1.5, so we need an inquiry function: 3736 */ 3737 static int 3738 npasses_from_interlace_type(png_const_structp pp, int interlace_type) 3739 { 3740 switch (interlace_type) 3741 { 3742 default: 3743 png_error(pp, "invalid interlace type"); 3744 3745 case PNG_INTERLACE_NONE: 3746 return 1; 3747 3748 case PNG_INTERLACE_ADAM7: 3749 return PNG_INTERLACE_ADAM7_PASSES; 3750 } 3751 } 3752 3753 static unsigned int 3754 bit_size(png_const_structp pp, png_byte colour_type, png_byte bit_depth) 3755 { 3756 switch (colour_type) 3757 { 3758 default: png_error(pp, "invalid color type"); 3759 3760 case 0: return bit_depth; 3761 3762 case 2: return 3*bit_depth; 3763 3764 case 3: return bit_depth; 3765 3766 case 4: return 2*bit_depth; 3767 3768 case 6: return 4*bit_depth; 3769 } 3770 } 3771 3772 #define TRANSFORM_WIDTH 128U 3773 #define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U) 3774 #define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */ 3775 #define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */ 3776 #define SIZE_HEIGHTMAX 16 /* Maximum range of size images */ 3777 3778 static size_t 3779 transform_rowsize(png_const_structp pp, png_byte colour_type, 3780 png_byte bit_depth) 3781 { 3782 return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8; 3783 } 3784 3785 /* transform_width(pp, colour_type, bit_depth) current returns the same number 3786 * every time, so just use a macro: 3787 */ 3788 #define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH 3789 3790 static png_uint_32 3791 transform_height(png_const_structp pp, png_byte colour_type, png_byte bit_depth) 3792 { 3793 switch (bit_size(pp, colour_type, bit_depth)) 3794 { 3795 case 1: 3796 case 2: 3797 case 4: 3798 return 1; /* Total of 128 pixels */ 3799 3800 case 8: 3801 return 2; /* Total of 256 pixels/bytes */ 3802 3803 case 16: 3804 return 512; /* Total of 65536 pixels */ 3805 3806 case 24: 3807 case 32: 3808 return 512; /* 65536 pixels */ 3809 3810 case 48: 3811 case 64: 3812 return 2048;/* 4 x 65536 pixels. */ 3813 # define TRANSFORM_HEIGHTMAX 2048 3814 3815 default: 3816 return 0; /* Error, will be caught later */ 3817 } 3818 } 3819 3820 #ifdef PNG_READ_SUPPORTED 3821 /* The following can only be defined here, now we have the definitions 3822 * of the transform image sizes. 3823 */ 3824 static png_uint_32 3825 standard_width(png_const_structp pp, png_uint_32 id) 3826 { 3827 png_uint_32 width = WIDTH_FROM_ID(id); 3828 UNUSED(pp) 3829 3830 if (width == 0) 3831 width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); 3832 3833 return width; 3834 } 3835 3836 static png_uint_32 3837 standard_height(png_const_structp pp, png_uint_32 id) 3838 { 3839 png_uint_32 height = HEIGHT_FROM_ID(id); 3840 3841 if (height == 0) 3842 height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); 3843 3844 return height; 3845 } 3846 3847 static png_uint_32 3848 standard_rowsize(png_const_structp pp, png_uint_32 id) 3849 { 3850 png_uint_32 width = standard_width(pp, id); 3851 3852 /* This won't overflow: */ 3853 width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); 3854 return (width + 7) / 8; 3855 } 3856 #endif /* PNG_READ_SUPPORTED */ 3857 3858 static void 3859 transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX], 3860 png_byte colour_type, png_byte bit_depth, png_uint_32 y) 3861 { 3862 png_uint_32 v = y << 7; 3863 png_uint_32 i = 0; 3864 3865 switch (bit_size(pp, colour_type, bit_depth)) 3866 { 3867 case 1: 3868 while (i<128/8) buffer[i] = (png_byte)(v & 0xff), v += 17, ++i; 3869 return; 3870 3871 case 2: 3872 while (i<128/4) buffer[i] = (png_byte)(v & 0xff), v += 33, ++i; 3873 return; 3874 3875 case 4: 3876 while (i<128/2) buffer[i] = (png_byte)(v & 0xff), v += 65, ++i; 3877 return; 3878 3879 case 8: 3880 /* 256 bytes total, 128 bytes in each row set as follows: */ 3881 while (i<128) buffer[i] = (png_byte)(v & 0xff), ++v, ++i; 3882 return; 3883 3884 case 16: 3885 /* Generate all 65536 pixel values in order, which includes the 8 bit 3886 * GA case as well as the 16 bit G case. 3887 */ 3888 while (i<128) 3889 { 3890 buffer[2*i] = (png_byte)((v>>8) & 0xff); 3891 buffer[2*i+1] = (png_byte)(v & 0xff); 3892 ++v; 3893 ++i; 3894 } 3895 3896 return; 3897 3898 case 24: 3899 /* 65535 pixels, but rotate the values. */ 3900 while (i<128) 3901 { 3902 /* Three bytes per pixel, r, g, b, make b by r^g */ 3903 buffer[3*i+0] = (png_byte)((v >> 8) & 0xff); 3904 buffer[3*i+1] = (png_byte)(v & 0xff); 3905 buffer[3*i+2] = (png_byte)(((v >> 8) ^ v) & 0xff); 3906 ++v; 3907 ++i; 3908 } 3909 3910 return; 3911 3912 case 32: 3913 /* 65535 pixels, r, g, b, a; just replicate */ 3914 while (i<128) 3915 { 3916 buffer[4*i+0] = (png_byte)((v >> 8) & 0xff); 3917 buffer[4*i+1] = (png_byte)(v & 0xff); 3918 buffer[4*i+2] = (png_byte)((v >> 8) & 0xff); 3919 buffer[4*i+3] = (png_byte)(v & 0xff); 3920 ++v; 3921 ++i; 3922 } 3923 3924 return; 3925 3926 case 48: 3927 /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at 3928 * each pixel, g increase by 257 (0x101) and 'b' by 0x1111: 3929 */ 3930 while (i<128) 3931 { 3932 png_uint_32 t = v++; 3933 buffer[6*i+0] = (png_byte)((t >> 8) & 0xff); 3934 buffer[6*i+1] = (png_byte)(t & 0xff); 3935 t *= 257; 3936 buffer[6*i+2] = (png_byte)((t >> 8) & 0xff); 3937 buffer[6*i+3] = (png_byte)(t & 0xff); 3938 t *= 17; 3939 buffer[6*i+4] = (png_byte)((t >> 8) & 0xff); 3940 buffer[6*i+5] = (png_byte)(t & 0xff); 3941 ++i; 3942 } 3943 3944 return; 3945 3946 case 64: 3947 /* As above in the 32 bit case. */ 3948 while (i<128) 3949 { 3950 png_uint_32 t = v++; 3951 buffer[8*i+0] = (png_byte)((t >> 8) & 0xff); 3952 buffer[8*i+1] = (png_byte)(t & 0xff); 3953 buffer[8*i+4] = (png_byte)((t >> 8) & 0xff); 3954 buffer[8*i+5] = (png_byte)(t & 0xff); 3955 t *= 257; 3956 buffer[8*i+2] = (png_byte)((t >> 8) & 0xff); 3957 buffer[8*i+3] = (png_byte)(t & 0xff); 3958 buffer[8*i+6] = (png_byte)((t >> 8) & 0xff); 3959 buffer[8*i+7] = (png_byte)(t & 0xff); 3960 ++i; 3961 } 3962 return; 3963 3964 default: 3965 break; 3966 } 3967 3968 png_error(pp, "internal error"); 3969 } 3970 3971 /* This is just to do the right cast - could be changed to a function to check 3972 * 'bd' but there isn't much point. 3973 */ 3974 #define DEPTH(bd) ((png_byte)(1U << (bd))) 3975 3976 /* This is just a helper for compiling on minimal systems with no write 3977 * interlacing support. If there is no write interlacing we can't generate test 3978 * cases with interlace: 3979 */ 3980 #ifdef PNG_WRITE_INTERLACING_SUPPORTED 3981 # define INTERLACE_LAST PNG_INTERLACE_LAST 3982 # define check_interlace_type(type) ((void)(type)) 3983 # define set_write_interlace_handling(pp,type) png_set_interlace_handling(pp) 3984 # define do_own_interlace 0 3985 #elif PNG_LIBPNG_VER < 10700 3986 # define set_write_interlace_handling(pp,type) (1) 3987 static void 3988 check_interlace_type(int const interlace_type) 3989 { 3990 /* Prior to 1.7.0 libpng does not support the write of an interlaced image 3991 * unless PNG_WRITE_INTERLACING_SUPPORTED, even with do_interlace so the 3992 * code here does the pixel interlace itself, so: 3993 */ 3994 if (interlace_type != PNG_INTERLACE_NONE) 3995 { 3996 /* This is an internal error - --interlace tests should be skipped, not 3997 * attempted. 3998 */ 3999 fprintf(stderr, "pngvalid: no interlace support\n"); 4000 exit(99); 4001 } 4002 } 4003 # define INTERLACE_LAST (PNG_INTERLACE_NONE+1) 4004 # define do_own_interlace 0 4005 #else /* libpng 1.7+ */ 4006 # define set_write_interlace_handling(pp,type)\ 4007 npasses_from_interlace_type(pp,type) 4008 # define check_interlace_type(type) ((void)(type)) 4009 # define INTERLACE_LAST PNG_INTERLACE_LAST 4010 # define do_own_interlace 1 4011 #endif /* WRITE_INTERLACING tests */ 4012 4013 #if PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED 4014 # define CAN_WRITE_INTERLACE 1 4015 #else 4016 # define CAN_WRITE_INTERLACE 0 4017 #endif 4018 4019 /* Do the same thing for read interlacing; this controls whether read tests do 4020 * their own de-interlace or use libpng. 4021 */ 4022 #ifdef PNG_READ_INTERLACING_SUPPORTED 4023 # define do_read_interlace 0 4024 #else /* no libpng read interlace support */ 4025 # define do_read_interlace 1 4026 #endif 4027 /* The following two routines use the PNG interlace support macros from 4028 * png.h to interlace or deinterlace rows. 4029 */ 4030 static void 4031 interlace_row(png_bytep buffer, png_const_bytep imageRow, 4032 unsigned int pixel_size, png_uint_32 w, int pass, int littleendian) 4033 { 4034 png_uint_32 xin, xout, xstep; 4035 4036 /* Note that this can, trivially, be optimized to a memcpy on pass 7, the 4037 * code is presented this way to make it easier to understand. In practice 4038 * consult the code in the libpng source to see other ways of doing this. 4039 * 4040 * It is OK for buffer and imageRow to be identical, because 'xin' moves 4041 * faster than 'xout' and we copy up. 4042 */ 4043 xin = PNG_PASS_START_COL(pass); 4044 xstep = 1U<<PNG_PASS_COL_SHIFT(pass); 4045 4046 for (xout=0; xin<w; xin+=xstep) 4047 { 4048 pixel_copy(buffer, xout, imageRow, xin, pixel_size, littleendian); 4049 ++xout; 4050 } 4051 } 4052 4053 #ifdef PNG_READ_SUPPORTED 4054 static void 4055 deinterlace_row(png_bytep buffer, png_const_bytep row, 4056 unsigned int pixel_size, png_uint_32 w, int pass, int littleendian) 4057 { 4058 /* The inverse of the above, 'row' is part of row 'y' of the output image, 4059 * in 'buffer'. The image is 'w' wide and this is pass 'pass', distribute 4060 * the pixels of row into buffer and return the number written (to allow 4061 * this to be checked). 4062 */ 4063 png_uint_32 xin, xout, xstep; 4064 4065 xout = PNG_PASS_START_COL(pass); 4066 xstep = 1U<<PNG_PASS_COL_SHIFT(pass); 4067 4068 for (xin=0; xout<w; xout+=xstep) 4069 { 4070 pixel_copy(buffer, xout, row, xin, pixel_size, littleendian); 4071 ++xin; 4072 } 4073 } 4074 #endif /* PNG_READ_SUPPORTED */ 4075 4076 /* Make a standardized image given an image colour type, bit depth and 4077 * interlace type. The standard images have a very restricted range of 4078 * rows and heights and are used for testing transforms rather than image 4079 * layout details. See make_size_images below for a way to make images 4080 * that test odd sizes along with the libpng interlace handling. 4081 */ 4082 #ifdef PNG_WRITE_FILTER_SUPPORTED 4083 static void 4084 choose_random_filter(png_structp pp, int start) 4085 { 4086 /* Choose filters randomly except that on the very first row ensure that 4087 * there is at least one previous row filter. 4088 */ 4089 int filters = PNG_ALL_FILTERS & random_mod(256U); 4090 4091 /* There may be no filters; skip the setting. */ 4092 if (filters != 0) 4093 { 4094 if (start && filters < PNG_FILTER_UP) 4095 filters |= PNG_FILTER_UP; 4096 4097 png_set_filter(pp, 0/*method*/, filters); 4098 } 4099 } 4100 #else /* !WRITE_FILTER */ 4101 # define choose_random_filter(pp, start) ((void)0) 4102 #endif /* !WRITE_FILTER */ 4103 4104 static void 4105 make_transform_image(png_store* const ps, png_byte const colour_type, 4106 png_byte const bit_depth, unsigned int palette_number, 4107 int interlace_type, png_const_charp name) 4108 { 4109 context(ps, fault); 4110 4111 check_interlace_type(interlace_type); 4112 4113 Try 4114 { 4115 png_infop pi; 4116 png_structp pp = set_store_for_write(ps, &pi, name); 4117 png_uint_32 h, w; 4118 4119 /* In the event of a problem return control to the Catch statement below 4120 * to do the clean up - it is not possible to 'return' directly from a Try 4121 * block. 4122 */ 4123 if (pp == NULL) 4124 Throw ps; 4125 4126 w = transform_width(pp, colour_type, bit_depth); 4127 h = transform_height(pp, colour_type, bit_depth); 4128 4129 png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type, 4130 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 4131 4132 #ifdef PNG_TEXT_SUPPORTED 4133 # if defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED) 4134 # define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_zTXt 4135 # else 4136 # define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_NONE 4137 # endif 4138 { 4139 static char key[] = "image name"; /* must be writeable */ 4140 size_t pos; 4141 png_text text; 4142 char copy[FILE_NAME_SIZE]; 4143 4144 /* Use a compressed text string to test the correct interaction of text 4145 * compression and IDAT compression. 4146 */ 4147 text.compression = TEXT_COMPRESSION; 4148 text.key = key; 4149 /* Yuck: the text must be writable! */ 4150 pos = safecat(copy, sizeof copy, 0, ps->wname); 4151 text.text = copy; 4152 text.text_length = pos; 4153 text.itxt_length = 0; 4154 text.lang = 0; 4155 text.lang_key = 0; 4156 4157 png_set_text(pp, pi, &text, 1); 4158 } 4159 #endif 4160 4161 if (colour_type == 3) /* palette */ 4162 init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/); 4163 4164 # ifdef PNG_WRITE_tRNS_SUPPORTED 4165 else if (palette_number) 4166 set_random_tRNS(pp, pi, colour_type, bit_depth); 4167 # endif 4168 4169 png_write_info(pp, pi); 4170 4171 if (png_get_rowbytes(pp, pi) != 4172 transform_rowsize(pp, colour_type, bit_depth)) 4173 png_error(pp, "transform row size incorrect"); 4174 4175 else 4176 { 4177 /* Somewhat confusingly this must be called *after* png_write_info 4178 * because if it is called before, the information in *pp has not been 4179 * updated to reflect the interlaced image. 4180 */ 4181 int npasses = set_write_interlace_handling(pp, interlace_type); 4182 int pass; 4183 4184 if (npasses != npasses_from_interlace_type(pp, interlace_type)) 4185 png_error(pp, "write: png_set_interlace_handling failed"); 4186 4187 for (pass=0; pass<npasses; ++pass) 4188 { 4189 png_uint_32 y; 4190 4191 /* do_own_interlace is a pre-defined boolean (a #define) which is 4192 * set if we have to work out the interlaced rows here. 4193 */ 4194 for (y=0; y<h; ++y) 4195 { 4196 png_byte buffer[TRANSFORM_ROWMAX]; 4197 4198 transform_row(pp, buffer, colour_type, bit_depth, y); 4199 4200 # if do_own_interlace 4201 /* If do_own_interlace *and* the image is interlaced we need a 4202 * reduced interlace row; this may be reduced to empty. 4203 */ 4204 if (interlace_type == PNG_INTERLACE_ADAM7) 4205 { 4206 /* The row must not be written if it doesn't exist, notice 4207 * that there are two conditions here, either the row isn't 4208 * ever in the pass or the row would be but isn't wide 4209 * enough to contribute any pixels. In fact the wPass test 4210 * can be used to skip the whole y loop in this case. 4211 */ 4212 if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && 4213 PNG_PASS_COLS(w, pass) > 0) 4214 interlace_row(buffer, buffer, 4215 bit_size(pp, colour_type, bit_depth), w, pass, 4216 0/*data always bigendian*/); 4217 else 4218 continue; 4219 } 4220 # endif /* do_own_interlace */ 4221 4222 choose_random_filter(pp, pass == 0 && y == 0); 4223 png_write_row(pp, buffer); 4224 } 4225 } 4226 } 4227 4228 #ifdef PNG_TEXT_SUPPORTED 4229 { 4230 static char key[] = "end marker"; 4231 static char comment[] = "end"; 4232 png_text text; 4233 4234 /* Use a compressed text string to test the correct interaction of text 4235 * compression and IDAT compression. 4236 */ 4237 text.compression = TEXT_COMPRESSION; 4238 text.key = key; 4239 text.text = comment; 4240 text.text_length = (sizeof comment)-1; 4241 text.itxt_length = 0; 4242 text.lang = 0; 4243 text.lang_key = 0; 4244 4245 png_set_text(pp, pi, &text, 1); 4246 } 4247 #endif 4248 4249 png_write_end(pp, pi); 4250 4251 /* And store this under the appropriate id, then clean up. */ 4252 store_storefile(ps, FILEID(colour_type, bit_depth, palette_number, 4253 interlace_type, 0, 0, 0)); 4254 4255 store_write_reset(ps); 4256 } 4257 4258 Catch(fault) 4259 { 4260 /* Use the png_store returned by the exception. This may help the compiler 4261 * because 'ps' is not used in this branch of the setjmp. Note that fault 4262 * and ps will always be the same value. 4263 */ 4264 store_write_reset(fault); 4265 } 4266 } 4267 4268 static void 4269 make_transform_images(png_modifier *pm) 4270 { 4271 png_byte colour_type = 0; 4272 png_byte bit_depth = 0; 4273 unsigned int palette_number = 0; 4274 4275 /* This is in case of errors. */ 4276 safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images"); 4277 4278 /* Use next_format to enumerate all the combinations we test, including 4279 * generating multiple low bit depth palette images. Non-A images (palette 4280 * and direct) are created with and without tRNS chunks. 4281 */ 4282 while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1)) 4283 { 4284 int interlace_type; 4285 4286 for (interlace_type = PNG_INTERLACE_NONE; 4287 interlace_type < INTERLACE_LAST; ++interlace_type) 4288 { 4289 char name[FILE_NAME_SIZE]; 4290 4291 standard_name(name, sizeof name, 0, colour_type, bit_depth, 4292 palette_number, interlace_type, 0, 0, do_own_interlace); 4293 make_transform_image(&pm->this, colour_type, bit_depth, palette_number, 4294 interlace_type, name); 4295 } 4296 } 4297 } 4298 4299 /* Build a single row for the 'size' test images; this fills in only the 4300 * first bit_width bits of the sample row. 4301 */ 4302 static void 4303 size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y) 4304 { 4305 /* height is in the range 1 to 16, so: */ 4306 y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4); 4307 /* the following ensures bits are set in small images: */ 4308 y ^= 0xA5; 4309 4310 while (bit_width >= 8) 4311 *buffer++ = (png_byte)y++, bit_width -= 8; 4312 4313 /* There may be up to 7 remaining bits, these go in the most significant 4314 * bits of the byte. 4315 */ 4316 if (bit_width > 0) 4317 { 4318 png_uint_32 mask = (1U<<(8-bit_width))-1; 4319 *buffer = (png_byte)((*buffer & mask) | (y & ~mask)); 4320 } 4321 } 4322 4323 static void 4324 make_size_image(png_store* const ps, png_byte const colour_type, 4325 png_byte const bit_depth, int const interlace_type, 4326 png_uint_32 const w, png_uint_32 const h, 4327 int const do_interlace) 4328 { 4329 context(ps, fault); 4330 4331 check_interlace_type(interlace_type); 4332 4333 Try 4334 { 4335 png_infop pi; 4336 png_structp pp; 4337 unsigned int pixel_size; 4338 4339 /* Make a name and get an appropriate id for the store: */ 4340 char name[FILE_NAME_SIZE]; 4341 const png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/, 4342 interlace_type, w, h, do_interlace); 4343 4344 standard_name_from_id(name, sizeof name, 0, id); 4345 pp = set_store_for_write(ps, &pi, name); 4346 4347 /* In the event of a problem return control to the Catch statement below 4348 * to do the clean up - it is not possible to 'return' directly from a Try 4349 * block. 4350 */ 4351 if (pp == NULL) 4352 Throw ps; 4353 4354 png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type, 4355 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 4356 4357 #ifdef PNG_TEXT_SUPPORTED 4358 { 4359 static char key[] = "image name"; /* must be writeable */ 4360 size_t pos; 4361 png_text text; 4362 char copy[FILE_NAME_SIZE]; 4363 4364 /* Use a compressed text string to test the correct interaction of text 4365 * compression and IDAT compression. 4366 */ 4367 text.compression = TEXT_COMPRESSION; 4368 text.key = key; 4369 /* Yuck: the text must be writable! */ 4370 pos = safecat(copy, sizeof copy, 0, ps->wname); 4371 text.text = copy; 4372 text.text_length = pos; 4373 text.itxt_length = 0; 4374 text.lang = 0; 4375 text.lang_key = 0; 4376 4377 png_set_text(pp, pi, &text, 1); 4378 } 4379 #endif 4380 4381 if (colour_type == 3) /* palette */ 4382 init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/); 4383 4384 png_write_info(pp, pi); 4385 4386 /* Calculate the bit size, divide by 8 to get the byte size - this won't 4387 * overflow because we know the w values are all small enough even for 4388 * a system where 'unsigned int' is only 16 bits. 4389 */ 4390 pixel_size = bit_size(pp, colour_type, bit_depth); 4391 if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8) 4392 png_error(pp, "size row size incorrect"); 4393 4394 else 4395 { 4396 int npasses = npasses_from_interlace_type(pp, interlace_type); 4397 png_uint_32 y; 4398 int pass; 4399 png_byte image[16][SIZE_ROWMAX]; 4400 4401 /* To help consistent error detection make the parts of this buffer 4402 * that aren't set below all '1': 4403 */ 4404 memset(image, 0xff, sizeof image); 4405 4406 if (!do_interlace && 4407 npasses != set_write_interlace_handling(pp, interlace_type)) 4408 png_error(pp, "write: png_set_interlace_handling failed"); 4409 4410 /* Prepare the whole image first to avoid making it 7 times: */ 4411 for (y=0; y<h; ++y) 4412 size_row(image[y], w * pixel_size, y); 4413 4414 for (pass=0; pass<npasses; ++pass) 4415 { 4416 /* The following two are for checking the macros: */ 4417 const png_uint_32 wPass = PNG_PASS_COLS(w, pass); 4418 4419 /* If do_interlace is set we don't call png_write_row for every 4420 * row because some of them are empty. In fact, for a 1x1 image, 4421 * most of them are empty! 4422 */ 4423 for (y=0; y<h; ++y) 4424 { 4425 png_const_bytep row = image[y]; 4426 png_byte tempRow[SIZE_ROWMAX]; 4427 4428 /* If do_interlace *and* the image is interlaced we 4429 * need a reduced interlace row; this may be reduced 4430 * to empty. 4431 */ 4432 if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7) 4433 { 4434 /* The row must not be written if it doesn't exist, notice 4435 * that there are two conditions here, either the row isn't 4436 * ever in the pass or the row would be but isn't wide 4437 * enough to contribute any pixels. In fact the wPass test 4438 * can be used to skip the whole y loop in this case. 4439 */ 4440 if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0) 4441 { 4442 /* Set to all 1's for error detection (libpng tends to 4443 * set unset things to 0). 4444 */ 4445 memset(tempRow, 0xff, sizeof tempRow); 4446 interlace_row(tempRow, row, pixel_size, w, pass, 4447 0/*data always bigendian*/); 4448 row = tempRow; 4449 } 4450 else 4451 continue; 4452 } 4453 4454 # ifdef PNG_WRITE_FILTER_SUPPORTED 4455 /* Only get to here if the row has some pixels in it, set the 4456 * filters to 'all' for the very first row and thereafter to a 4457 * single filter. It isn't well documented, but png_set_filter 4458 * does accept a filter number (per the spec) as well as a bit 4459 * mask. 4460 * 4461 * The code now uses filters at random, except that on the first 4462 * row of an image it ensures that a previous row filter is in 4463 * the set so that libpng allocates the row buffer. 4464 */ 4465 { 4466 int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST); 4467 4468 if (pass == 0 && y == 0 && 4469 (filters < PNG_FILTER_UP || w == 1U)) 4470 filters |= PNG_FILTER_UP; 4471 4472 png_set_filter(pp, 0/*method*/, filters); 4473 } 4474 # endif 4475 4476 png_write_row(pp, row); 4477 } 4478 } 4479 } 4480 4481 #ifdef PNG_TEXT_SUPPORTED 4482 { 4483 static char key[] = "end marker"; 4484 static char comment[] = "end"; 4485 png_text text; 4486 4487 /* Use a compressed text string to test the correct interaction of text 4488 * compression and IDAT compression. 4489 */ 4490 text.compression = TEXT_COMPRESSION; 4491 text.key = key; 4492 text.text = comment; 4493 text.text_length = (sizeof comment)-1; 4494 text.itxt_length = 0; 4495 text.lang = 0; 4496 text.lang_key = 0; 4497 4498 png_set_text(pp, pi, &text, 1); 4499 } 4500 #endif 4501 4502 png_write_end(pp, pi); 4503 4504 /* And store this under the appropriate id, then clean up. */ 4505 store_storefile(ps, id); 4506 4507 store_write_reset(ps); 4508 } 4509 4510 Catch(fault) 4511 { 4512 /* Use the png_store returned by the exception. This may help the compiler 4513 * because 'ps' is not used in this branch of the setjmp. Note that fault 4514 * and ps will always be the same value. 4515 */ 4516 store_write_reset(fault); 4517 } 4518 } 4519 4520 static void 4521 make_size(png_store* const ps, png_byte const colour_type, int bdlo, 4522 int const bdhi) 4523 { 4524 for (; bdlo <= bdhi; ++bdlo) 4525 { 4526 png_uint_32 width; 4527 4528 for (width = 1; width <= 16; ++width) 4529 { 4530 png_uint_32 height; 4531 4532 for (height = 1; height <= 16; ++height) 4533 { 4534 /* The four combinations of DIY interlace and interlace or not - 4535 * no interlace + DIY should be identical to no interlace with 4536 * libpng doing it. 4537 */ 4538 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE, 4539 width, height, 0); 4540 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE, 4541 width, height, 1); 4542 # ifdef PNG_WRITE_INTERLACING_SUPPORTED 4543 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7, 4544 width, height, 0); 4545 # endif 4546 # if CAN_WRITE_INTERLACE 4547 /* 1.7.0 removes the hack that prevented app write of an interlaced 4548 * image if WRITE_INTERLACE was not supported 4549 */ 4550 make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7, 4551 width, height, 1); 4552 # endif 4553 } 4554 } 4555 } 4556 } 4557 4558 static void 4559 make_size_images(png_store *ps) 4560 { 4561 /* This is in case of errors. */ 4562 safecat(ps->test, sizeof ps->test, 0, "make size images"); 4563 4564 /* Arguments are colour_type, low bit depth, high bit depth 4565 */ 4566 make_size(ps, 0, 0, WRITE_BDHI); 4567 make_size(ps, 2, 3, WRITE_BDHI); 4568 make_size(ps, 3, 0, 3 /*palette: max 8 bits*/); 4569 make_size(ps, 4, 3, WRITE_BDHI); 4570 make_size(ps, 6, 3, WRITE_BDHI); 4571 } 4572 4573 #ifdef PNG_READ_SUPPORTED 4574 /* Return a row based on image id and 'y' for checking: */ 4575 static void 4576 standard_row(png_const_structp pp, png_byte std[STANDARD_ROWMAX], 4577 png_uint_32 id, png_uint_32 y) 4578 { 4579 if (WIDTH_FROM_ID(id) == 0) 4580 transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y); 4581 else 4582 size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id), 4583 DEPTH_FROM_ID(id)), y); 4584 } 4585 #endif /* PNG_READ_SUPPORTED */ 4586 4587 /* Tests - individual test cases */ 4588 /* Like 'make_standard' but errors are deliberately introduced into the calls 4589 * to ensure that they get detected - it should not be possible to write an 4590 * invalid image with libpng! 4591 */ 4592 /* TODO: the 'set' functions can probably all be made to take a 4593 * png_const_structp rather than a modifiable one. 4594 */ 4595 #ifdef PNG_WARNINGS_SUPPORTED 4596 static void 4597 sBIT0_error_fn(png_structp pp, png_infop pi) 4598 { 4599 /* 0 is invalid... */ 4600 png_color_8 bad; 4601 bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0; 4602 png_set_sBIT(pp, pi, &bad); 4603 } 4604 4605 static void 4606 sBIT_error_fn(png_structp pp, png_infop pi) 4607 { 4608 png_byte bit_depth; 4609 png_color_8 bad; 4610 4611 if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE) 4612 bit_depth = 8; 4613 4614 else 4615 bit_depth = png_get_bit_depth(pp, pi); 4616 4617 /* Now we know the bit depth we can easily generate an invalid sBIT entry */ 4618 bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 4619 (png_byte)(bit_depth+1); 4620 png_set_sBIT(pp, pi, &bad); 4621 } 4622 4623 static const struct 4624 { 4625 void (*fn)(png_structp, png_infop); 4626 const char *msg; 4627 unsigned int warning :1; /* the error is a warning... */ 4628 } error_test[] = 4629 { 4630 /* no warnings makes these errors undetectable prior to 1.7.0 */ 4631 { sBIT0_error_fn, "sBIT(0): failed to detect error", 4632 PNG_LIBPNG_VER < 10700 }, 4633 4634 { sBIT_error_fn, "sBIT(too big): failed to detect error", 4635 PNG_LIBPNG_VER < 10700 }, 4636 }; 4637 4638 static void 4639 make_error(png_store* const ps, png_byte const colour_type, 4640 png_byte bit_depth, int interlace_type, int test, png_const_charp name) 4641 { 4642 context(ps, fault); 4643 4644 check_interlace_type(interlace_type); 4645 4646 Try 4647 { 4648 png_infop pi; 4649 const png_structp pp = set_store_for_write(ps, &pi, name); 4650 png_uint_32 w, h; 4651 gnu_volatile(pp) 4652 4653 if (pp == NULL) 4654 Throw ps; 4655 4656 w = transform_width(pp, colour_type, bit_depth); 4657 gnu_volatile(w) 4658 h = transform_height(pp, colour_type, bit_depth); 4659 gnu_volatile(h) 4660 png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type, 4661 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 4662 4663 if (colour_type == 3) /* palette */ 4664 init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/); 4665 4666 /* Time for a few errors; these are in various optional chunks, the 4667 * standard tests test the standard chunks pretty well. 4668 */ 4669 # define exception__prev exception_prev_1 4670 # define exception__env exception_env_1 4671 Try 4672 { 4673 gnu_volatile(exception__prev) 4674 4675 /* Expect this to throw: */ 4676 ps->expect_error = !error_test[test].warning; 4677 ps->expect_warning = error_test[test].warning; 4678 ps->saw_warning = 0; 4679 error_test[test].fn(pp, pi); 4680 4681 /* Normally the error is only detected here: */ 4682 png_write_info(pp, pi); 4683 4684 /* And handle the case where it was only a warning: */ 4685 if (ps->expect_warning && ps->saw_warning) 4686 Throw ps; 4687 4688 /* If we get here there is a problem, we have success - no error or 4689 * no warning - when we shouldn't have success. Log an error. 4690 */ 4691 store_log(ps, pp, error_test[test].msg, 1 /*error*/); 4692 } 4693 4694 Catch (fault) 4695 { /* expected exit */ 4696 } 4697 #undef exception__prev 4698 #undef exception__env 4699 4700 /* And clear these flags */ 4701 ps->expect_warning = 0; 4702 4703 if (ps->expect_error) 4704 ps->expect_error = 0; 4705 4706 else 4707 { 4708 /* Now write the whole image, just to make sure that the detected, or 4709 * undetected, errro has not created problems inside libpng. This 4710 * doesn't work if there was a png_error in png_write_info because that 4711 * can abort before PLTE was written. 4712 */ 4713 if (png_get_rowbytes(pp, pi) != 4714 transform_rowsize(pp, colour_type, bit_depth)) 4715 png_error(pp, "row size incorrect"); 4716 4717 else 4718 { 4719 int npasses = set_write_interlace_handling(pp, interlace_type); 4720 int pass; 4721 4722 if (npasses != npasses_from_interlace_type(pp, interlace_type)) 4723 png_error(pp, "write: png_set_interlace_handling failed"); 4724 4725 for (pass=0; pass<npasses; ++pass) 4726 { 4727 png_uint_32 y; 4728 4729 for (y=0; y<h; ++y) 4730 { 4731 png_byte buffer[TRANSFORM_ROWMAX]; 4732 4733 transform_row(pp, buffer, colour_type, bit_depth, y); 4734 4735 # if do_own_interlace 4736 /* If do_own_interlace *and* the image is interlaced we 4737 * need a reduced interlace row; this may be reduced to 4738 * empty. 4739 */ 4740 if (interlace_type == PNG_INTERLACE_ADAM7) 4741 { 4742 /* The row must not be written if it doesn't exist, 4743 * notice that there are two conditions here, either the 4744 * row isn't ever in the pass or the row would be but 4745 * isn't wide enough to contribute any pixels. In fact 4746 * the wPass test can be used to skip the whole y loop 4747 * in this case. 4748 */ 4749 if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && 4750 PNG_PASS_COLS(w, pass) > 0) 4751 interlace_row(buffer, buffer, 4752 bit_size(pp, colour_type, bit_depth), w, pass, 4753 0/*data always bigendian*/); 4754 else 4755 continue; 4756 } 4757 # endif /* do_own_interlace */ 4758 4759 png_write_row(pp, buffer); 4760 } 4761 } 4762 } /* image writing */ 4763 4764 png_write_end(pp, pi); 4765 } 4766 4767 /* The following deletes the file that was just written. */ 4768 store_write_reset(ps); 4769 } 4770 4771 Catch(fault) 4772 { 4773 store_write_reset(fault); 4774 } 4775 } 4776 4777 static int 4778 make_errors(png_modifier* const pm, png_byte const colour_type, 4779 int bdlo, int const bdhi) 4780 { 4781 for (; bdlo <= bdhi; ++bdlo) 4782 { 4783 int interlace_type; 4784 4785 for (interlace_type = PNG_INTERLACE_NONE; 4786 interlace_type < INTERLACE_LAST; ++interlace_type) 4787 { 4788 unsigned int test; 4789 char name[FILE_NAME_SIZE]; 4790 4791 standard_name(name, sizeof name, 0, colour_type, 1<<bdlo, 0, 4792 interlace_type, 0, 0, do_own_interlace); 4793 4794 for (test=0; test<ARRAY_SIZE(error_test); ++test) 4795 { 4796 make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type, 4797 test, name); 4798 4799 if (fail(pm)) 4800 return 0; 4801 } 4802 } 4803 } 4804 4805 return 1; /* keep going */ 4806 } 4807 #endif /* PNG_WARNINGS_SUPPORTED */ 4808 4809 static void 4810 perform_error_test(png_modifier *pm) 4811 { 4812 #ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */ 4813 /* Need to do this here because we just write in this test. */ 4814 safecat(pm->this.test, sizeof pm->this.test, 0, "error test"); 4815 4816 if (!make_errors(pm, 0, 0, WRITE_BDHI)) 4817 return; 4818 4819 if (!make_errors(pm, 2, 3, WRITE_BDHI)) 4820 return; 4821 4822 if (!make_errors(pm, 3, 0, 3)) 4823 return; 4824 4825 if (!make_errors(pm, 4, 3, WRITE_BDHI)) 4826 return; 4827 4828 if (!make_errors(pm, 6, 3, WRITE_BDHI)) 4829 return; 4830 #else 4831 UNUSED(pm) 4832 #endif 4833 } 4834 4835 /* This is just to validate the internal PNG formatting code - if this fails 4836 * then the warning messages the library outputs will probably be garbage. 4837 */ 4838 static void 4839 perform_formatting_test(png_store *ps) 4840 { 4841 #ifdef PNG_TIME_RFC1123_SUPPORTED 4842 /* The handle into the formatting code is the RFC1123 support; this test does 4843 * nothing if that is compiled out. 4844 */ 4845 context(ps, fault); 4846 4847 Try 4848 { 4849 png_const_charp correct = "29 Aug 2079 13:53:60 +0000"; 4850 png_const_charp result; 4851 # if PNG_LIBPNG_VER >= 10600 4852 char timestring[29]; 4853 # endif 4854 png_structp pp; 4855 png_time pt; 4856 4857 pp = set_store_for_write(ps, NULL, "libpng formatting test"); 4858 4859 if (pp == NULL) 4860 Throw ps; 4861 4862 4863 /* Arbitrary settings: */ 4864 pt.year = 2079; 4865 pt.month = 8; 4866 pt.day = 29; 4867 pt.hour = 13; 4868 pt.minute = 53; 4869 pt.second = 60; /* a leap second */ 4870 4871 # if PNG_LIBPNG_VER < 10600 4872 result = png_convert_to_rfc1123(pp, &pt); 4873 # else 4874 if (png_convert_to_rfc1123_buffer(timestring, &pt)) 4875 result = timestring; 4876 4877 else 4878 result = NULL; 4879 # endif 4880 4881 if (result == NULL) 4882 png_error(pp, "png_convert_to_rfc1123 failed"); 4883 4884 if (strcmp(result, correct) != 0) 4885 { 4886 size_t pos = 0; 4887 char msg[128]; 4888 4889 pos = safecat(msg, sizeof msg, pos, "png_convert_to_rfc1123("); 4890 pos = safecat(msg, sizeof msg, pos, correct); 4891 pos = safecat(msg, sizeof msg, pos, ") returned: '"); 4892 pos = safecat(msg, sizeof msg, pos, result); 4893 pos = safecat(msg, sizeof msg, pos, "'"); 4894 4895 png_error(pp, msg); 4896 } 4897 4898 store_write_reset(ps); 4899 } 4900 4901 Catch(fault) 4902 { 4903 store_write_reset(fault); 4904 } 4905 #else 4906 UNUSED(ps) 4907 #endif 4908 } 4909 4910 #ifdef PNG_READ_SUPPORTED 4911 /* Because we want to use the same code in both the progressive reader and the 4912 * sequential reader it is necessary to deal with the fact that the progressive 4913 * reader callbacks only have one parameter (png_get_progressive_ptr()), so this 4914 * must contain all the test parameters and all the local variables directly 4915 * accessible to the sequential reader implementation. 4916 * 4917 * The technique adopted is to reinvent part of what Dijkstra termed a 4918 * 'display'; an array of pointers to the stack frames of enclosing functions so 4919 * that a nested function definition can access the local (C auto) variables of 4920 * the functions that contain its definition. In fact C provides the first 4921 * pointer (the local variables - the stack frame pointer) and the last (the 4922 * global variables - the BCPL global vector typically implemented as global 4923 * addresses), this code requires one more pointer to make the display - the 4924 * local variables (and function call parameters) of the function that actually 4925 * invokes either the progressive or sequential reader. 4926 * 4927 * Perhaps confusingly this technique is confounded with classes - the 4928 * 'standard_display' defined here is sub-classed as the 'gamma_display' below. 4929 * A gamma_display is a standard_display, taking advantage of the ANSI-C 4930 * requirement that the pointer to the first member of a structure must be the 4931 * same as the pointer to the structure. This allows us to reuse standard_ 4932 * functions in the gamma test code; something that could not be done with 4933 * nested functions! 4934 */ 4935 typedef struct standard_display 4936 { 4937 png_store* ps; /* Test parameters (passed to the function) */ 4938 png_byte colour_type; 4939 png_byte bit_depth; 4940 png_byte red_sBIT; /* Input data sBIT values. */ 4941 png_byte green_sBIT; 4942 png_byte blue_sBIT; 4943 png_byte alpha_sBIT; 4944 png_byte interlace_type; 4945 png_byte filler; /* Output has a filler */ 4946 png_uint_32 id; /* Calculated file ID */ 4947 png_uint_32 w; /* Width of image */ 4948 png_uint_32 h; /* Height of image */ 4949 int npasses; /* Number of interlaced passes */ 4950 png_uint_32 pixel_size; /* Width of one pixel in bits */ 4951 png_uint_32 bit_width; /* Width of output row in bits */ 4952 size_t cbRow; /* Bytes in a row of the output image */ 4953 int do_interlace; /* Do interlacing internally */ 4954 int littleendian; /* App (row) data is little endian */ 4955 int is_transparent; /* Transparency information was present. */ 4956 int has_tRNS; /* color type GRAY or RGB with a tRNS chunk. */ 4957 int speed; /* Doing a speed test */ 4958 int use_update_info;/* Call update_info, not start_image */ 4959 struct 4960 { 4961 png_uint_16 red; 4962 png_uint_16 green; 4963 png_uint_16 blue; 4964 } transparent; /* The transparent color, if set. */ 4965 int npalette; /* Number of entries in the palette. */ 4966 store_palette 4967 palette; 4968 } standard_display; 4969 4970 static void 4971 standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id, 4972 int do_interlace, int use_update_info) 4973 { 4974 memset(dp, 0, sizeof *dp); 4975 4976 dp->ps = ps; 4977 dp->colour_type = COL_FROM_ID(id); 4978 dp->bit_depth = DEPTH_FROM_ID(id); 4979 if (dp->bit_depth < 1 || dp->bit_depth > 16) 4980 internal_error(ps, "internal: bad bit depth"); 4981 if (dp->colour_type == 3) 4982 dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8; 4983 else 4984 dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 4985 dp->bit_depth; 4986 dp->interlace_type = INTERLACE_FROM_ID(id); 4987 check_interlace_type(dp->interlace_type); 4988 dp->id = id; 4989 /* All the rest are filled in after the read_info: */ 4990 dp->w = 0; 4991 dp->h = 0; 4992 dp->npasses = 0; 4993 dp->pixel_size = 0; 4994 dp->bit_width = 0; 4995 dp->cbRow = 0; 4996 dp->do_interlace = do_interlace; 4997 dp->littleendian = 0; 4998 dp->is_transparent = 0; 4999 dp->speed = ps->speed; 5000 dp->use_update_info = use_update_info; 5001 dp->npalette = 0; 5002 /* Preset the transparent color to black: */ 5003 memset(&dp->transparent, 0, sizeof dp->transparent); 5004 /* Preset the palette to full intensity/opaque througout: */ 5005 memset(dp->palette, 0xff, sizeof dp->palette); 5006 } 5007 5008 /* Initialize the palette fields - this must be done later because the palette 5009 * comes from the particular png_store_file that is selected. 5010 */ 5011 static void 5012 standard_palette_init(standard_display *dp) 5013 { 5014 store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette); 5015 5016 /* The remaining entries remain white/opaque. */ 5017 if (dp->npalette > 0) 5018 { 5019 int i = dp->npalette; 5020 memcpy(dp->palette, palette, i * sizeof *palette); 5021 5022 /* Check for a non-opaque palette entry: */ 5023 while (--i >= 0) 5024 if (palette[i].alpha < 255) 5025 break; 5026 5027 # ifdef __GNUC__ 5028 /* GCC can't handle the more obviously optimizable version. */ 5029 if (i >= 0) 5030 dp->is_transparent = 1; 5031 else 5032 dp->is_transparent = 0; 5033 # else 5034 dp->is_transparent = (i >= 0); 5035 # endif 5036 } 5037 } 5038 5039 /* Utility to read the palette from the PNG file and convert it into 5040 * store_palette format. This returns 1 if there is any transparency in the 5041 * palette (it does not check for a transparent colour in the non-palette case.) 5042 */ 5043 static int 5044 read_palette(store_palette palette, int *npalette, png_const_structp pp, 5045 png_infop pi) 5046 { 5047 png_colorp pal; 5048 png_bytep trans_alpha; 5049 int num; 5050 5051 pal = 0; 5052 *npalette = -1; 5053 5054 if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE) 5055 { 5056 int i = *npalette; 5057 5058 if (i <= 0 || i > 256) 5059 png_error(pp, "validate: invalid PLTE count"); 5060 5061 while (--i >= 0) 5062 { 5063 palette[i].red = pal[i].red; 5064 palette[i].green = pal[i].green; 5065 palette[i].blue = pal[i].blue; 5066 } 5067 5068 /* Mark the remainder of the entries with a flag value (other than 5069 * white/opaque which is the flag value stored above.) 5070 */ 5071 memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette); 5072 } 5073 5074 else /* !png_get_PLTE */ 5075 { 5076 if (*npalette != (-1)) 5077 png_error(pp, "validate: invalid PLTE result"); 5078 /* But there is no palette, so record this: */ 5079 *npalette = 0; 5080 memset(palette, 113, sizeof (store_palette)); 5081 } 5082 5083 trans_alpha = 0; 5084 num = 2; /* force error below */ 5085 if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 && 5086 (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) && 5087 /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so 5088 * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans, 5089 * so in the above call we get a success, we get a pointer (who knows what 5090 * to) and we get num_trans == 0: 5091 */ 5092 !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */ 5093 { 5094 int i; 5095 5096 /* Any of these are crash-worthy - given the implementation of 5097 * png_get_tRNS up to 1.5 an app won't crash if it just checks the 5098 * result above and fails to check that the variables it passed have 5099 * actually been filled in! Note that if the app were to pass the 5100 * last, png_color_16p, variable too it couldn't rely on this. 5101 */ 5102 if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette) 5103 png_error(pp, "validate: unexpected png_get_tRNS (palette) result"); 5104 5105 for (i=0; i<num; ++i) 5106 palette[i].alpha = trans_alpha[i]; 5107 5108 for (num=*npalette; i<num; ++i) 5109 palette[i].alpha = 255; 5110 5111 for (; i<256; ++i) 5112 palette[i].alpha = 33; /* flag value */ 5113 5114 return 1; /* transparency */ 5115 } 5116 5117 else 5118 { 5119 /* No palette transparency - just set the alpha channel to opaque. */ 5120 int i; 5121 5122 for (i=0, num=*npalette; i<num; ++i) 5123 palette[i].alpha = 255; 5124 5125 for (; i<256; ++i) 5126 palette[i].alpha = 55; /* flag value */ 5127 5128 return 0; /* no transparency */ 5129 } 5130 } 5131 5132 /* Utility to validate the palette if it should not have changed (the 5133 * non-transform case). 5134 */ 5135 static void 5136 standard_palette_validate(standard_display *dp, png_const_structp pp, 5137 png_infop pi) 5138 { 5139 int npalette; 5140 store_palette palette; 5141 5142 if (read_palette(palette, &npalette, pp, pi) != dp->is_transparent) 5143 png_error(pp, "validate: palette transparency changed"); 5144 5145 if (npalette != dp->npalette) 5146 { 5147 size_t pos = 0; 5148 char msg[64]; 5149 5150 pos = safecat(msg, sizeof msg, pos, "validate: palette size changed: "); 5151 pos = safecatn(msg, sizeof msg, pos, dp->npalette); 5152 pos = safecat(msg, sizeof msg, pos, " -> "); 5153 pos = safecatn(msg, sizeof msg, pos, npalette); 5154 png_error(pp, msg); 5155 } 5156 5157 { 5158 int i = npalette; /* npalette is aliased */ 5159 5160 while (--i >= 0) 5161 if (palette[i].red != dp->palette[i].red || 5162 palette[i].green != dp->palette[i].green || 5163 palette[i].blue != dp->palette[i].blue || 5164 palette[i].alpha != dp->palette[i].alpha) 5165 png_error(pp, "validate: PLTE or tRNS chunk changed"); 5166 } 5167 } 5168 5169 /* By passing a 'standard_display' the progressive callbacks can be used 5170 * directly by the sequential code, the functions suffixed "_imp" are the 5171 * implementations, the functions without the suffix are the callbacks. 5172 * 5173 * The code for the info callback is split into two because this callback calls 5174 * png_read_update_info or png_start_read_image and what gets called depends on 5175 * whether the info needs updating (we want to test both calls in pngvalid.) 5176 */ 5177 static void 5178 standard_info_part1(standard_display *dp, png_structp pp, png_infop pi) 5179 { 5180 if (png_get_bit_depth(pp, pi) != dp->bit_depth) 5181 png_error(pp, "validate: bit depth changed"); 5182 5183 if (png_get_color_type(pp, pi) != dp->colour_type) 5184 png_error(pp, "validate: color type changed"); 5185 5186 if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE) 5187 png_error(pp, "validate: filter type changed"); 5188 5189 if (png_get_interlace_type(pp, pi) != dp->interlace_type) 5190 png_error(pp, "validate: interlacing changed"); 5191 5192 if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE) 5193 png_error(pp, "validate: compression type changed"); 5194 5195 dp->w = png_get_image_width(pp, pi); 5196 5197 if (dp->w != standard_width(pp, dp->id)) 5198 png_error(pp, "validate: image width changed"); 5199 5200 dp->h = png_get_image_height(pp, pi); 5201 5202 if (dp->h != standard_height(pp, dp->id)) 5203 png_error(pp, "validate: image height changed"); 5204 5205 /* Record (but don't check at present) the input sBIT according to the colour 5206 * type information. 5207 */ 5208 { 5209 png_color_8p sBIT = 0; 5210 5211 if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT) 5212 { 5213 int sBIT_invalid = 0; 5214 5215 if (sBIT == 0) 5216 png_error(pp, "validate: unexpected png_get_sBIT result"); 5217 5218 if (dp->colour_type & PNG_COLOR_MASK_COLOR) 5219 { 5220 if (sBIT->red == 0 || sBIT->red > dp->bit_depth) 5221 sBIT_invalid = 1; 5222 else 5223 dp->red_sBIT = sBIT->red; 5224 5225 if (sBIT->green == 0 || sBIT->green > dp->bit_depth) 5226 sBIT_invalid = 1; 5227 else 5228 dp->green_sBIT = sBIT->green; 5229 5230 if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth) 5231 sBIT_invalid = 1; 5232 else 5233 dp->blue_sBIT = sBIT->blue; 5234 } 5235 5236 else /* !COLOR */ 5237 { 5238 if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth) 5239 sBIT_invalid = 1; 5240 else 5241 dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray; 5242 } 5243 5244 /* All 8 bits in tRNS for a palette image are significant - see the 5245 * spec. 5246 */ 5247 if (dp->colour_type & PNG_COLOR_MASK_ALPHA) 5248 { 5249 if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth) 5250 sBIT_invalid = 1; 5251 else 5252 dp->alpha_sBIT = sBIT->alpha; 5253 } 5254 5255 if (sBIT_invalid) 5256 png_error(pp, "validate: sBIT value out of range"); 5257 } 5258 } 5259 5260 /* Important: this is validating the value *before* any transforms have been 5261 * put in place. It doesn't matter for the standard tests, where there are 5262 * no transforms, but it does for other tests where rowbytes may change after 5263 * png_read_update_info. 5264 */ 5265 if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id)) 5266 png_error(pp, "validate: row size changed"); 5267 5268 /* Validate the colour type 3 palette (this can be present on other color 5269 * types.) 5270 */ 5271 standard_palette_validate(dp, pp, pi); 5272 5273 /* In any case always check for a tranparent color (notice that the 5274 * colour type 3 case must not give a successful return on the get_tRNS call 5275 * with these arguments!) 5276 */ 5277 { 5278 png_color_16p trans_color = 0; 5279 5280 if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS) 5281 { 5282 if (trans_color == 0) 5283 png_error(pp, "validate: unexpected png_get_tRNS (color) result"); 5284 5285 switch (dp->colour_type) 5286 { 5287 case 0: 5288 dp->transparent.red = dp->transparent.green = dp->transparent.blue = 5289 trans_color->gray; 5290 dp->has_tRNS = 1; 5291 break; 5292 5293 case 2: 5294 dp->transparent.red = trans_color->red; 5295 dp->transparent.green = trans_color->green; 5296 dp->transparent.blue = trans_color->blue; 5297 dp->has_tRNS = 1; 5298 break; 5299 5300 case 3: 5301 /* Not expected because it should result in the array case 5302 * above. 5303 */ 5304 png_error(pp, "validate: unexpected png_get_tRNS result"); 5305 break; 5306 5307 default: 5308 png_error(pp, "validate: invalid tRNS chunk with alpha image"); 5309 } 5310 } 5311 } 5312 5313 /* Read the number of passes - expected to match the value used when 5314 * creating the image (interlaced or not). This has the side effect of 5315 * turning on interlace handling (if do_interlace is not set.) 5316 */ 5317 dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type); 5318 if (!dp->do_interlace) 5319 { 5320 # ifdef PNG_READ_INTERLACING_SUPPORTED 5321 if (dp->npasses != png_set_interlace_handling(pp)) 5322 png_error(pp, "validate: file changed interlace type"); 5323 # else /* !READ_INTERLACING */ 5324 /* This should never happen: the relevant tests (!do_interlace) should 5325 * not be run. 5326 */ 5327 if (dp->npasses > 1) 5328 png_error(pp, "validate: no libpng interlace support"); 5329 # endif /* !READ_INTERLACING */ 5330 } 5331 5332 /* Caller calls png_read_update_info or png_start_read_image now, then calls 5333 * part2. 5334 */ 5335 } 5336 5337 /* This must be called *after* the png_read_update_info call to get the correct 5338 * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed 5339 * image. 5340 */ 5341 static void 5342 standard_info_part2(standard_display *dp, png_const_structp pp, 5343 png_const_infop pi, int nImages) 5344 { 5345 /* Record cbRow now that it can be found. */ 5346 { 5347 png_byte ct = png_get_color_type(pp, pi); 5348 png_byte bd = png_get_bit_depth(pp, pi); 5349 5350 if (bd >= 8 && (ct == PNG_COLOR_TYPE_RGB || ct == PNG_COLOR_TYPE_GRAY) && 5351 dp->filler) 5352 ct |= 4; /* handle filler as faked alpha channel */ 5353 5354 dp->pixel_size = bit_size(pp, ct, bd); 5355 } 5356 dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size; 5357 dp->cbRow = png_get_rowbytes(pp, pi); 5358 5359 /* Validate the rowbytes here again. */ 5360 if (dp->cbRow != (dp->bit_width+7)/8) 5361 png_error(pp, "bad png_get_rowbytes calculation"); 5362 5363 /* Then ensure there is enough space for the output image(s). */ 5364 store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h); 5365 } 5366 5367 static void 5368 standard_info_imp(standard_display *dp, png_structp pp, png_infop pi, 5369 int nImages) 5370 { 5371 /* Note that the validation routine has the side effect of turning on 5372 * interlace handling in the subsequent code. 5373 */ 5374 standard_info_part1(dp, pp, pi); 5375 5376 /* And the info callback has to call this (or png_read_update_info - see 5377 * below in the png_modifier code for that variant. 5378 */ 5379 if (dp->use_update_info) 5380 { 5381 /* For debugging the effect of multiple calls: */ 5382 int i = dp->use_update_info; 5383 while (i-- > 0) 5384 png_read_update_info(pp, pi); 5385 } 5386 5387 else 5388 png_start_read_image(pp); 5389 5390 /* Validate the height, width and rowbytes plus ensure that sufficient buffer 5391 * exists for decoding the image. 5392 */ 5393 standard_info_part2(dp, pp, pi, nImages); 5394 } 5395 5396 static void PNGCBAPI 5397 standard_info(png_structp pp, png_infop pi) 5398 { 5399 standard_display *dp = voidcast(standard_display*, 5400 png_get_progressive_ptr(pp)); 5401 5402 /* Call with nImages==1 because the progressive reader can only produce one 5403 * image. 5404 */ 5405 standard_info_imp(dp, pp, pi, 1 /*only one image*/); 5406 } 5407 5408 static void PNGCBAPI 5409 progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass) 5410 { 5411 png_const_structp pp = ppIn; 5412 const standard_display *dp = voidcast(standard_display*, 5413 png_get_progressive_ptr(pp)); 5414 5415 /* When handling interlacing some rows will be absent in each pass, the 5416 * callback still gets called, but with a NULL pointer. This is checked 5417 * in the 'else' clause below. We need our own 'cbRow', but we can't call 5418 * png_get_rowbytes because we got no info structure. 5419 */ 5420 if (new_row != NULL) 5421 { 5422 png_bytep row; 5423 5424 /* In the case where the reader doesn't do the interlace it gives 5425 * us the y in the sub-image: 5426 */ 5427 if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7) 5428 { 5429 #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED 5430 /* Use this opportunity to validate the png 'current' APIs: */ 5431 if (y != png_get_current_row_number(pp)) 5432 png_error(pp, "png_get_current_row_number is broken"); 5433 5434 if (pass != png_get_current_pass_number(pp)) 5435 png_error(pp, "png_get_current_pass_number is broken"); 5436 #endif /* USER_TRANSFORM_INFO */ 5437 5438 y = PNG_ROW_FROM_PASS_ROW(y, pass); 5439 } 5440 5441 /* Validate this just in case. */ 5442 if (y >= dp->h) 5443 png_error(pp, "invalid y to progressive row callback"); 5444 5445 row = store_image_row(dp->ps, pp, 0, y); 5446 5447 /* Combine the new row into the old: */ 5448 #ifdef PNG_READ_INTERLACING_SUPPORTED 5449 if (dp->do_interlace) 5450 #endif /* READ_INTERLACING */ 5451 { 5452 if (dp->interlace_type == PNG_INTERLACE_ADAM7) 5453 deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass, 5454 dp->littleendian); 5455 else 5456 row_copy(row, new_row, dp->pixel_size * dp->w, dp->littleendian); 5457 } 5458 #ifdef PNG_READ_INTERLACING_SUPPORTED 5459 else 5460 png_progressive_combine_row(pp, row, new_row); 5461 #endif /* PNG_READ_INTERLACING_SUPPORTED */ 5462 } 5463 5464 else if (dp->interlace_type == PNG_INTERLACE_ADAM7 && 5465 PNG_ROW_IN_INTERLACE_PASS(y, pass) && 5466 PNG_PASS_COLS(dp->w, pass) > 0) 5467 png_error(pp, "missing row in progressive de-interlacing"); 5468 } 5469 5470 static void 5471 sequential_row(standard_display *dp, png_structp pp, png_infop pi, 5472 const int iImage, const int iDisplay) 5473 { 5474 const int npasses = dp->npasses; 5475 const int do_interlace = dp->do_interlace && 5476 dp->interlace_type == PNG_INTERLACE_ADAM7; 5477 const png_uint_32 height = standard_height(pp, dp->id); 5478 const png_uint_32 width = standard_width(pp, dp->id); 5479 const png_store* ps = dp->ps; 5480 int pass; 5481 5482 for (pass=0; pass<npasses; ++pass) 5483 { 5484 png_uint_32 y; 5485 png_uint_32 wPass = PNG_PASS_COLS(width, pass); 5486 5487 for (y=0; y<height; ++y) 5488 { 5489 if (do_interlace) 5490 { 5491 /* wPass may be zero or this row may not be in this pass. 5492 * png_read_row must not be called in either case. 5493 */ 5494 if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass)) 5495 { 5496 /* Read the row into a pair of temporary buffers, then do the 5497 * merge here into the output rows. 5498 */ 5499 png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX]; 5500 5501 /* The following aids (to some extent) error detection - we can 5502 * see where png_read_row wrote. Use opposite values in row and 5503 * display to make this easier. Don't use 0xff (which is used in 5504 * the image write code to fill unused bits) or 0 (which is a 5505 * likely value to overwrite unused bits with). 5506 */ 5507 memset(row, 0xc5, sizeof row); 5508 memset(display, 0x5c, sizeof display); 5509 5510 png_read_row(pp, row, display); 5511 5512 if (iImage >= 0) 5513 deinterlace_row(store_image_row(ps, pp, iImage, y), row, 5514 dp->pixel_size, dp->w, pass, dp->littleendian); 5515 5516 if (iDisplay >= 0) 5517 deinterlace_row(store_image_row(ps, pp, iDisplay, y), display, 5518 dp->pixel_size, dp->w, pass, dp->littleendian); 5519 } 5520 } 5521 else 5522 png_read_row(pp, 5523 iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL, 5524 iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL); 5525 } 5526 } 5527 5528 /* And finish the read operation (only really necessary if the caller wants 5529 * to find additional data in png_info from chunks after the last IDAT.) 5530 */ 5531 png_read_end(pp, pi); 5532 } 5533 5534 #ifdef PNG_TEXT_SUPPORTED 5535 static void 5536 standard_check_text(png_const_structp pp, png_const_textp tp, 5537 png_const_charp keyword, png_const_charp text) 5538 { 5539 char msg[1024]; 5540 size_t pos = safecat(msg, sizeof msg, 0, "text: "); 5541 size_t ok; 5542 5543 pos = safecat(msg, sizeof msg, pos, keyword); 5544 pos = safecat(msg, sizeof msg, pos, ": "); 5545 ok = pos; 5546 5547 if (tp->compression != TEXT_COMPRESSION) 5548 { 5549 char buf[64]; 5550 5551 sprintf(buf, "compression [%d->%d], ", TEXT_COMPRESSION, 5552 tp->compression); 5553 pos = safecat(msg, sizeof msg, pos, buf); 5554 } 5555 5556 if (tp->key == NULL || strcmp(tp->key, keyword) != 0) 5557 { 5558 pos = safecat(msg, sizeof msg, pos, "keyword \""); 5559 if (tp->key != NULL) 5560 { 5561 pos = safecat(msg, sizeof msg, pos, tp->key); 5562 pos = safecat(msg, sizeof msg, pos, "\", "); 5563 } 5564 5565 else 5566 pos = safecat(msg, sizeof msg, pos, "null, "); 5567 } 5568 5569 if (tp->text == NULL) 5570 pos = safecat(msg, sizeof msg, pos, "text lost, "); 5571 5572 else 5573 { 5574 if (tp->text_length != strlen(text)) 5575 { 5576 char buf[64]; 5577 sprintf(buf, "text length changed[%lu->%lu], ", 5578 (unsigned long)strlen(text), (unsigned long)tp->text_length); 5579 pos = safecat(msg, sizeof msg, pos, buf); 5580 } 5581 5582 if (strcmp(tp->text, text) != 0) 5583 { 5584 pos = safecat(msg, sizeof msg, pos, "text becomes \""); 5585 pos = safecat(msg, sizeof msg, pos, tp->text); 5586 pos = safecat(msg, sizeof msg, pos, "\" (was \""); 5587 pos = safecat(msg, sizeof msg, pos, text); 5588 pos = safecat(msg, sizeof msg, pos, "\"), "); 5589 } 5590 } 5591 5592 if (tp->itxt_length != 0) 5593 pos = safecat(msg, sizeof msg, pos, "iTXt length set, "); 5594 5595 if (tp->lang != NULL) 5596 { 5597 pos = safecat(msg, sizeof msg, pos, "iTXt language \""); 5598 pos = safecat(msg, sizeof msg, pos, tp->lang); 5599 pos = safecat(msg, sizeof msg, pos, "\", "); 5600 } 5601 5602 if (tp->lang_key != NULL) 5603 { 5604 pos = safecat(msg, sizeof msg, pos, "iTXt keyword \""); 5605 pos = safecat(msg, sizeof msg, pos, tp->lang_key); 5606 pos = safecat(msg, sizeof msg, pos, "\", "); 5607 } 5608 5609 if (pos > ok) 5610 { 5611 msg[pos-2] = '\0'; /* Remove the ", " at the end */ 5612 png_error(pp, msg); 5613 } 5614 } 5615 5616 static void 5617 standard_text_validate(standard_display *dp, png_const_structp pp, 5618 png_infop pi, int check_end) 5619 { 5620 png_textp tp = NULL; 5621 png_uint_32 num_text = png_get_text(pp, pi, &tp, NULL); 5622 5623 if (num_text == 2 && tp != NULL) 5624 { 5625 standard_check_text(pp, tp, "image name", dp->ps->current->name); 5626 5627 /* This exists because prior to 1.5.18 the progressive reader left the 5628 * png_struct z_stream unreset at the end of the image, so subsequent 5629 * attempts to use it simply returns Z_STREAM_END. 5630 */ 5631 if (check_end) 5632 standard_check_text(pp, tp+1, "end marker", "end"); 5633 } 5634 5635 else 5636 { 5637 char msg[64]; 5638 5639 sprintf(msg, "expected two text items, got %lu", 5640 (unsigned long)num_text); 5641 png_error(pp, msg); 5642 } 5643 } 5644 #else 5645 # define standard_text_validate(dp,pp,pi,check_end) ((void)0) 5646 #endif 5647 5648 static void 5649 standard_row_validate(standard_display *dp, png_const_structp pp, 5650 int iImage, int iDisplay, png_uint_32 y) 5651 { 5652 int where; 5653 png_byte std[STANDARD_ROWMAX]; 5654 5655 /* The row must be pre-initialized to the magic number here for the size 5656 * tests to pass: 5657 */ 5658 memset(std, 178, sizeof std); 5659 standard_row(pp, std, dp->id, y); 5660 5661 /* At the end both the 'row' and 'display' arrays should end up identical. 5662 * In earlier passes 'row' will be partially filled in, with only the pixels 5663 * that have been read so far, but 'display' will have those pixels 5664 * replicated to fill the unread pixels while reading an interlaced image. 5665 */ 5666 if (iImage >= 0 && 5667 (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y), 5668 dp->bit_width)) != 0) 5669 { 5670 char msg[64]; 5671 sprintf(msg, "PNG image row[%lu][%d] changed from %.2x to %.2x", 5672 (unsigned long)y, where-1, std[where-1], 5673 store_image_row(dp->ps, pp, iImage, y)[where-1]); 5674 png_error(pp, msg); 5675 } 5676 5677 if (iDisplay >= 0 && 5678 (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y), 5679 dp->bit_width)) != 0) 5680 { 5681 char msg[64]; 5682 sprintf(msg, "display row[%lu][%d] changed from %.2x to %.2x", 5683 (unsigned long)y, where-1, std[where-1], 5684 store_image_row(dp->ps, pp, iDisplay, y)[where-1]); 5685 png_error(pp, msg); 5686 } 5687 } 5688 5689 static void 5690 standard_image_validate(standard_display *dp, png_const_structp pp, int iImage, 5691 int iDisplay) 5692 { 5693 png_uint_32 y; 5694 5695 if (iImage >= 0) 5696 store_image_check(dp->ps, pp, iImage); 5697 5698 if (iDisplay >= 0) 5699 store_image_check(dp->ps, pp, iDisplay); 5700 5701 for (y=0; y<dp->h; ++y) 5702 standard_row_validate(dp, pp, iImage, iDisplay, y); 5703 5704 /* This avoids false positives if the validation code is never called! */ 5705 dp->ps->validated = 1; 5706 } 5707 5708 static void PNGCBAPI 5709 standard_end(png_structp ppIn, png_infop pi) 5710 { 5711 png_const_structp pp = ppIn; 5712 standard_display *dp = voidcast(standard_display*, 5713 png_get_progressive_ptr(pp)); 5714 5715 UNUSED(pi) 5716 5717 /* Validate the image - progressive reading only produces one variant for 5718 * interlaced images. 5719 */ 5720 standard_text_validate(dp, pp, pi, 5721 PNG_LIBPNG_VER >= 10518/*check_end: see comments above*/); 5722 standard_image_validate(dp, pp, 0, -1); 5723 } 5724 5725 /* A single test run checking the standard image to ensure it is not damaged. */ 5726 static void 5727 standard_test(png_store* const psIn, png_uint_32 const id, 5728 int do_interlace, int use_update_info) 5729 { 5730 standard_display d; 5731 context(psIn, fault); 5732 5733 /* Set up the display (stack frame) variables from the arguments to the 5734 * function and initialize the locals that are filled in later. 5735 */ 5736 standard_display_init(&d, psIn, id, do_interlace, use_update_info); 5737 5738 /* Everything is protected by a Try/Catch. The functions called also 5739 * typically have local Try/Catch blocks. 5740 */ 5741 Try 5742 { 5743 png_structp pp; 5744 png_infop pi; 5745 5746 /* Get a png_struct for reading the image. This will throw an error if it 5747 * fails, so we don't need to check the result. 5748 */ 5749 pp = set_store_for_read(d.ps, &pi, d.id, 5750 d.do_interlace ? (d.ps->progressive ? 5751 "pngvalid progressive deinterlacer" : 5752 "pngvalid sequential deinterlacer") : (d.ps->progressive ? 5753 "progressive reader" : "sequential reader")); 5754 5755 /* Initialize the palette correctly from the png_store_file. */ 5756 standard_palette_init(&d); 5757 5758 /* Introduce the correct read function. */ 5759 if (d.ps->progressive) 5760 { 5761 png_set_progressive_read_fn(pp, &d, standard_info, progressive_row, 5762 standard_end); 5763 5764 /* Now feed data into the reader until we reach the end: */ 5765 store_progressive_read(d.ps, pp, pi); 5766 } 5767 else 5768 { 5769 /* Note that this takes the store, not the display. */ 5770 png_set_read_fn(pp, d.ps, store_read); 5771 5772 /* Check the header values: */ 5773 png_read_info(pp, pi); 5774 5775 /* The code tests both versions of the images that the sequential 5776 * reader can produce. 5777 */ 5778 standard_info_imp(&d, pp, pi, 2 /*images*/); 5779 5780 /* Need the total bytes in the image below; we can't get to this point 5781 * unless the PNG file values have been checked against the expected 5782 * values. 5783 */ 5784 { 5785 sequential_row(&d, pp, pi, 0, 1); 5786 5787 /* After the last pass loop over the rows again to check that the 5788 * image is correct. 5789 */ 5790 if (!d.speed) 5791 { 5792 standard_text_validate(&d, pp, pi, 1/*check_end*/); 5793 standard_image_validate(&d, pp, 0, 1); 5794 } 5795 else 5796 d.ps->validated = 1; 5797 } 5798 } 5799 5800 /* Check for validation. */ 5801 if (!d.ps->validated) 5802 png_error(pp, "image read failed silently"); 5803 5804 /* Successful completion. */ 5805 } 5806 5807 Catch(fault) 5808 d.ps = fault; /* make sure this hasn't been clobbered. */ 5809 5810 /* In either case clean up the store. */ 5811 store_read_reset(d.ps); 5812 } 5813 5814 static int 5815 test_standard(png_modifier* const pm, png_byte const colour_type, 5816 int bdlo, int const bdhi) 5817 { 5818 for (; bdlo <= bdhi; ++bdlo) 5819 { 5820 int interlace_type; 5821 5822 for (interlace_type = PNG_INTERLACE_NONE; 5823 interlace_type < INTERLACE_LAST; ++interlace_type) 5824 { 5825 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5826 interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info); 5827 5828 if (fail(pm)) 5829 return 0; 5830 } 5831 } 5832 5833 return 1; /* keep going */ 5834 } 5835 5836 static void 5837 perform_standard_test(png_modifier *pm) 5838 { 5839 /* Test each colour type over the valid range of bit depths (expressed as 5840 * log2(bit_depth) in turn, stop as soon as any error is detected. 5841 */ 5842 if (!test_standard(pm, 0, 0, READ_BDHI)) 5843 return; 5844 5845 if (!test_standard(pm, 2, 3, READ_BDHI)) 5846 return; 5847 5848 if (!test_standard(pm, 3, 0, 3)) 5849 return; 5850 5851 if (!test_standard(pm, 4, 3, READ_BDHI)) 5852 return; 5853 5854 if (!test_standard(pm, 6, 3, READ_BDHI)) 5855 return; 5856 } 5857 5858 5859 /********************************** SIZE TESTS ********************************/ 5860 static int 5861 test_size(png_modifier* const pm, png_byte const colour_type, 5862 int bdlo, int const bdhi) 5863 { 5864 /* Run the tests on each combination. 5865 * 5866 * NOTE: on my 32 bit x86 each of the following blocks takes 5867 * a total of 3.5 seconds if done across every combo of bit depth 5868 * width and height. This is a waste of time in practice, hence the 5869 * hinc and winc stuff: 5870 */ 5871 static const png_byte hinc[] = {1, 3, 11, 1, 5}; 5872 static const png_byte winc[] = {1, 9, 5, 7, 1}; 5873 const int save_bdlo = bdlo; 5874 5875 for (; bdlo <= bdhi; ++bdlo) 5876 { 5877 png_uint_32 h, w; 5878 5879 for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo]) 5880 { 5881 /* First test all the 'size' images against the sequential 5882 * reader using libpng to deinterlace (where required.) This 5883 * validates the write side of libpng. There are four possibilities 5884 * to validate. 5885 */ 5886 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5887 PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/, 5888 pm->use_update_info); 5889 5890 if (fail(pm)) 5891 return 0; 5892 5893 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5894 PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/, 5895 pm->use_update_info); 5896 5897 if (fail(pm)) 5898 return 0; 5899 5900 /* Now validate the interlaced read side - do_interlace true, 5901 * in the progressive case this does actually make a difference 5902 * to the code used in the non-interlaced case too. 5903 */ 5904 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5905 PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/, 5906 pm->use_update_info); 5907 5908 if (fail(pm)) 5909 return 0; 5910 5911 # if CAN_WRITE_INTERLACE 5912 /* Validate the pngvalid code itself: */ 5913 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5914 PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/, 5915 pm->use_update_info); 5916 5917 if (fail(pm)) 5918 return 0; 5919 # endif 5920 } 5921 } 5922 5923 /* Now do the tests of libpng interlace handling, after we have made sure 5924 * that the pngvalid version works: 5925 */ 5926 for (bdlo = save_bdlo; bdlo <= bdhi; ++bdlo) 5927 { 5928 png_uint_32 h, w; 5929 5930 for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo]) 5931 { 5932 # ifdef PNG_READ_INTERLACING_SUPPORTED 5933 /* Test with pngvalid generated interlaced images first; we have 5934 * already verify these are ok (unless pngvalid has self-consistent 5935 * read/write errors, which is unlikely), so this detects errors in the 5936 * read side first: 5937 */ 5938 # if CAN_WRITE_INTERLACE 5939 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5940 PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/, 5941 pm->use_update_info); 5942 5943 if (fail(pm)) 5944 return 0; 5945 # endif 5946 # endif /* READ_INTERLACING */ 5947 5948 # ifdef PNG_WRITE_INTERLACING_SUPPORTED 5949 /* Test the libpng write side against the pngvalid read side: */ 5950 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5951 PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/, 5952 pm->use_update_info); 5953 5954 if (fail(pm)) 5955 return 0; 5956 # endif 5957 5958 # ifdef PNG_READ_INTERLACING_SUPPORTED 5959 # ifdef PNG_WRITE_INTERLACING_SUPPORTED 5960 /* Test both together: */ 5961 standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, 5962 PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/, 5963 pm->use_update_info); 5964 5965 if (fail(pm)) 5966 return 0; 5967 # endif 5968 # endif /* READ_INTERLACING */ 5969 } 5970 } 5971 5972 return 1; /* keep going */ 5973 } 5974 5975 static void 5976 perform_size_test(png_modifier *pm) 5977 { 5978 /* Test each colour type over the valid range of bit depths (expressed as 5979 * log2(bit_depth) in turn, stop as soon as any error is detected. 5980 */ 5981 if (!test_size(pm, 0, 0, READ_BDHI)) 5982 return; 5983 5984 if (!test_size(pm, 2, 3, READ_BDHI)) 5985 return; 5986 5987 /* For the moment don't do the palette test - it's a waste of time when 5988 * compared to the grayscale test. 5989 */ 5990 #if 0 5991 if (!test_size(pm, 3, 0, 3)) 5992 return; 5993 #endif 5994 5995 if (!test_size(pm, 4, 3, READ_BDHI)) 5996 return; 5997 5998 if (!test_size(pm, 6, 3, READ_BDHI)) 5999 return; 6000 } 6001 6002 6003 /******************************* TRANSFORM TESTS ******************************/ 6004 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 6005 /* A set of tests to validate libpng image transforms. The possibilities here 6006 * are legion because the transforms can be combined in a combinatorial 6007 * fashion. To deal with this some measure of restraint is required, otherwise 6008 * the tests would take forever. 6009 */ 6010 typedef struct image_pixel 6011 { 6012 /* A local (pngvalid) representation of a PNG pixel, in all its 6013 * various forms. 6014 */ 6015 unsigned int red, green, blue, alpha; /* For non-palette images. */ 6016 unsigned int palette_index; /* For a palette image. */ 6017 png_byte colour_type; /* As in the spec. */ 6018 png_byte bit_depth; /* Defines bit size in row */ 6019 png_byte sample_depth; /* Scale of samples */ 6020 unsigned int have_tRNS :1; /* tRNS chunk may need processing */ 6021 unsigned int swap_rgb :1; /* RGB swapped to BGR */ 6022 unsigned int alpha_first :1; /* Alpha at start, not end */ 6023 unsigned int alpha_inverted :1; /* Alpha channel inverted */ 6024 unsigned int mono_inverted :1; /* Gray channel inverted */ 6025 unsigned int swap16 :1; /* Byte swap 16-bit components */ 6026 unsigned int littleendian :1; /* High bits on right */ 6027 unsigned int sig_bits :1; /* Pixel shifted (sig bits only) */ 6028 6029 /* For checking the code calculates double precision floating point values 6030 * along with an error value, accumulated from the transforms. Because an 6031 * sBIT setting allows larger error bounds (indeed, by the spec, apparently 6032 * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each 6033 * channel is stored. This sBIT value is folded in to the stored error value 6034 * at the end of the application of the transforms to the pixel. 6035 * 6036 * If sig_bits is set above the red, green, blue and alpha values have been 6037 * scaled so they only contain the significant bits of the component values. 6038 */ 6039 double redf, greenf, bluef, alphaf; 6040 double rede, greene, bluee, alphae; 6041 png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT; 6042 } image_pixel; 6043 6044 /* Shared utility function, see below. */ 6045 static void 6046 image_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax, 6047 unsigned int bMax, unsigned int aMax) 6048 { 6049 this->redf = this->red / (double)rMax; 6050 this->greenf = this->green / (double)gMax; 6051 this->bluef = this->blue / (double)bMax; 6052 this->alphaf = this->alpha / (double)aMax; 6053 6054 if (this->red < rMax) 6055 this->rede = this->redf * DBL_EPSILON; 6056 else 6057 this->rede = 0; 6058 if (this->green < gMax) 6059 this->greene = this->greenf * DBL_EPSILON; 6060 else 6061 this->greene = 0; 6062 if (this->blue < bMax) 6063 this->bluee = this->bluef * DBL_EPSILON; 6064 else 6065 this->bluee = 0; 6066 if (this->alpha < aMax) 6067 this->alphae = this->alphaf * DBL_EPSILON; 6068 else 6069 this->alphae = 0; 6070 } 6071 6072 /* Initialize the structure for the next pixel - call this before doing any 6073 * transforms and call it for each pixel since all the fields may need to be 6074 * reset. 6075 */ 6076 static void 6077 image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type, 6078 png_byte bit_depth, png_uint_32 x, store_palette palette, 6079 const image_pixel *format /*from pngvalid transform of input*/) 6080 { 6081 const png_byte sample_depth = (png_byte)(colour_type == 6082 PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth); 6083 const unsigned int max = (1U<<sample_depth)-1; 6084 const int swap16 = (format != 0 && format->swap16); 6085 const int littleendian = (format != 0 && format->littleendian); 6086 const int sig_bits = (format != 0 && format->sig_bits); 6087 6088 /* Initially just set everything to the same number and the alpha to opaque. 6089 * Note that this currently assumes a simple palette where entry x has colour 6090 * rgb(x,x,x)! 6091 */ 6092 this->palette_index = this->red = this->green = this->blue = 6093 sample(row, colour_type, bit_depth, x, 0, swap16, littleendian); 6094 this->alpha = max; 6095 this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT = 6096 sample_depth; 6097 6098 /* Then override as appropriate: */ 6099 if (colour_type == 3) /* palette */ 6100 { 6101 /* This permits the caller to default to the sample value. */ 6102 if (palette != 0) 6103 { 6104 const unsigned int i = this->palette_index; 6105 6106 this->red = palette[i].red; 6107 this->green = palette[i].green; 6108 this->blue = palette[i].blue; 6109 this->alpha = palette[i].alpha; 6110 } 6111 } 6112 6113 else /* not palette */ 6114 { 6115 unsigned int i = 0; 6116 6117 if ((colour_type & 4) != 0 && format != 0 && format->alpha_first) 6118 { 6119 this->alpha = this->red; 6120 /* This handles the gray case for 'AG' pixels */ 6121 this->palette_index = this->red = this->green = this->blue = 6122 sample(row, colour_type, bit_depth, x, 1, swap16, littleendian); 6123 i = 1; 6124 } 6125 6126 if (colour_type & 2) 6127 { 6128 /* Green is second for both BGR and RGB: */ 6129 this->green = sample(row, colour_type, bit_depth, x, ++i, swap16, 6130 littleendian); 6131 6132 if (format != 0 && format->swap_rgb) /* BGR */ 6133 this->red = sample(row, colour_type, bit_depth, x, ++i, swap16, 6134 littleendian); 6135 else 6136 this->blue = sample(row, colour_type, bit_depth, x, ++i, swap16, 6137 littleendian); 6138 } 6139 6140 else /* grayscale */ if (format != 0 && format->mono_inverted) 6141 this->red = this->green = this->blue = this->red ^ max; 6142 6143 if ((colour_type & 4) != 0) /* alpha */ 6144 { 6145 if (format == 0 || !format->alpha_first) 6146 this->alpha = sample(row, colour_type, bit_depth, x, ++i, swap16, 6147 littleendian); 6148 6149 if (format != 0 && format->alpha_inverted) 6150 this->alpha ^= max; 6151 } 6152 } 6153 6154 /* Calculate the scaled values, these are simply the values divided by 6155 * 'max' and the error is initialized to the double precision epsilon value 6156 * from the header file. 6157 */ 6158 image_pixel_setf(this, 6159 sig_bits ? (1U << format->red_sBIT)-1 : max, 6160 sig_bits ? (1U << format->green_sBIT)-1 : max, 6161 sig_bits ? (1U << format->blue_sBIT)-1 : max, 6162 sig_bits ? (1U << format->alpha_sBIT)-1 : max); 6163 6164 /* Store the input information for use in the transforms - these will 6165 * modify the information. 6166 */ 6167 this->colour_type = colour_type; 6168 this->bit_depth = bit_depth; 6169 this->sample_depth = sample_depth; 6170 this->have_tRNS = 0; 6171 this->swap_rgb = 0; 6172 this->alpha_first = 0; 6173 this->alpha_inverted = 0; 6174 this->mono_inverted = 0; 6175 this->swap16 = 0; 6176 this->littleendian = 0; 6177 this->sig_bits = 0; 6178 } 6179 6180 #if defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_GRAY_TO_RGB_SUPPORTED\ 6181 || defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_EXPAND_16_SUPPORTED\ 6182 || defined PNG_READ_BACKGROUND_SUPPORTED 6183 /* Convert a palette image to an rgb image. This necessarily converts the tRNS 6184 * chunk at the same time, because the tRNS will be in palette form. The way 6185 * palette validation works means that the original palette is never updated, 6186 * instead the image_pixel value from the row contains the RGB of the 6187 * corresponding palette entry and *this* is updated. Consequently this routine 6188 * only needs to change the colour type information. 6189 */ 6190 static void 6191 image_pixel_convert_PLTE(image_pixel *this) 6192 { 6193 if (this->colour_type == PNG_COLOR_TYPE_PALETTE) 6194 { 6195 if (this->have_tRNS) 6196 { 6197 this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; 6198 this->have_tRNS = 0; 6199 } 6200 else 6201 this->colour_type = PNG_COLOR_TYPE_RGB; 6202 6203 /* The bit depth of the row changes at this point too (notice that this is 6204 * the row format, not the sample depth, which is separate.) 6205 */ 6206 this->bit_depth = 8; 6207 } 6208 } 6209 6210 /* Add an alpha channel; this will import the tRNS information because tRNS is 6211 * not valid in an alpha image. The bit depth will invariably be set to at 6212 * least 8 prior to 1.7.0. Palette images will be converted to alpha (using 6213 * the above API). With png_set_background the alpha channel is never expanded 6214 * but this routine is used by pngvalid to simplify code; 'for_background' 6215 * records this. 6216 */ 6217 static void 6218 image_pixel_add_alpha(image_pixel *this, const standard_display *display, 6219 int for_background) 6220 { 6221 if (this->colour_type == PNG_COLOR_TYPE_PALETTE) 6222 image_pixel_convert_PLTE(this); 6223 6224 if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0) 6225 { 6226 if (this->colour_type == PNG_COLOR_TYPE_GRAY) 6227 { 6228 # if PNG_LIBPNG_VER < 10700 6229 if (!for_background && this->bit_depth < 8) 6230 this->bit_depth = this->sample_depth = 8; 6231 # endif 6232 6233 if (this->have_tRNS) 6234 { 6235 /* After 1.7 the expansion of bit depth only happens if there is a 6236 * tRNS chunk to expand at this point. 6237 */ 6238 # if PNG_LIBPNG_VER >= 10700 6239 if (!for_background && this->bit_depth < 8) 6240 this->bit_depth = this->sample_depth = 8; 6241 # endif 6242 6243 this->have_tRNS = 0; 6244 6245 /* Check the input, original, channel value here against the 6246 * original tRNS gray chunk valie. 6247 */ 6248 if (this->red == display->transparent.red) 6249 this->alphaf = 0; 6250 else 6251 this->alphaf = 1; 6252 } 6253 else 6254 this->alphaf = 1; 6255 6256 this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; 6257 } 6258 6259 else if (this->colour_type == PNG_COLOR_TYPE_RGB) 6260 { 6261 if (this->have_tRNS) 6262 { 6263 this->have_tRNS = 0; 6264 6265 /* Again, check the exact input values, not the current transformed 6266 * value! 6267 */ 6268 if (this->red == display->transparent.red && 6269 this->green == display->transparent.green && 6270 this->blue == display->transparent.blue) 6271 this->alphaf = 0; 6272 else 6273 this->alphaf = 1; 6274 } 6275 else 6276 this->alphaf = 1; 6277 6278 this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; 6279 } 6280 6281 /* The error in the alpha is zero and the sBIT value comes from the 6282 * original sBIT data (actually it will always be the original bit depth). 6283 */ 6284 this->alphae = 0; 6285 this->alpha_sBIT = display->alpha_sBIT; 6286 } 6287 } 6288 #endif /* transforms that need image_pixel_add_alpha */ 6289 6290 struct transform_display; 6291 typedef struct image_transform 6292 { 6293 /* The name of this transform: a string. */ 6294 const char *name; 6295 6296 /* Each transform can be disabled from the command line: */ 6297 int enable; 6298 6299 /* The global list of transforms; read only. */ 6300 struct image_transform *const list; 6301 6302 /* The global count of the number of times this transform has been set on an 6303 * image. 6304 */ 6305 unsigned int global_use; 6306 6307 /* The local count of the number of times this transform has been set. */ 6308 unsigned int local_use; 6309 6310 /* The next transform in the list, each transform must call its own next 6311 * transform after it has processed the pixel successfully. 6312 */ 6313 const struct image_transform *next; 6314 6315 /* A single transform for the image, expressed as a series of function 6316 * callbacks and some space for values. 6317 * 6318 * First a callback to add any required modifications to the png_modifier; 6319 * this gets called just before the modifier is set up for read. 6320 */ 6321 void (*ini)(const struct image_transform *this, 6322 struct transform_display *that); 6323 6324 /* And a callback to set the transform on the current png_read_struct: 6325 */ 6326 void (*set)(const struct image_transform *this, 6327 struct transform_display *that, png_structp pp, png_infop pi); 6328 6329 /* Then a transform that takes an input pixel in one PNG format or another 6330 * and modifies it by a pngvalid implementation of the transform (thus 6331 * duplicating the libpng intent without, we hope, duplicating the bugs 6332 * in the libpng implementation!) The png_structp is solely to allow error 6333 * reporting via png_error and png_warning. 6334 */ 6335 void (*mod)(const struct image_transform *this, image_pixel *that, 6336 png_const_structp pp, const struct transform_display *display); 6337 6338 /* Add this transform to the list and return true if the transform is 6339 * meaningful for this colour type and bit depth - if false then the 6340 * transform should have no effect on the image so there's not a lot of 6341 * point running it. 6342 */ 6343 int (*add)(struct image_transform *this, 6344 const struct image_transform **that, png_byte colour_type, 6345 png_byte bit_depth); 6346 } image_transform; 6347 6348 typedef struct transform_display 6349 { 6350 standard_display this; 6351 6352 /* Parameters */ 6353 png_modifier* pm; 6354 const image_transform* transform_list; 6355 unsigned int max_gamma_8; 6356 6357 /* Local variables */ 6358 png_byte output_colour_type; 6359 png_byte output_bit_depth; 6360 png_byte unpacked; 6361 6362 /* Modifications (not necessarily used.) */ 6363 gama_modification gama_mod; 6364 chrm_modification chrm_mod; 6365 srgb_modification srgb_mod; 6366 } transform_display; 6367 6368 /* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */ 6369 static void 6370 transform_set_encoding(transform_display *this) 6371 { 6372 /* Set up the png_modifier '_current' fields then use these to determine how 6373 * to add appropriate chunks. 6374 */ 6375 png_modifier *pm = this->pm; 6376 6377 modifier_set_encoding(pm); 6378 6379 if (modifier_color_encoding_is_set(pm)) 6380 { 6381 if (modifier_color_encoding_is_sRGB(pm)) 6382 srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE); 6383 6384 else 6385 { 6386 /* Set gAMA and cHRM separately. */ 6387 gama_modification_init(&this->gama_mod, pm, pm->current_gamma); 6388 6389 if (pm->current_encoding != 0) 6390 chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding); 6391 } 6392 } 6393 } 6394 6395 /* Three functions to end the list: */ 6396 static void 6397 image_transform_ini_end(const image_transform *this, 6398 transform_display *that) 6399 { 6400 UNUSED(this) 6401 UNUSED(that) 6402 } 6403 6404 static void 6405 image_transform_set_end(const image_transform *this, 6406 transform_display *that, png_structp pp, png_infop pi) 6407 { 6408 UNUSED(this) 6409 UNUSED(that) 6410 UNUSED(pp) 6411 UNUSED(pi) 6412 } 6413 6414 /* At the end of the list recalculate the output image pixel value from the 6415 * double precision values set up by the preceding 'mod' calls: 6416 */ 6417 static unsigned int 6418 sample_scale(double sample_value, unsigned int scale) 6419 { 6420 sample_value = floor(sample_value * scale + .5); 6421 6422 /* Return NaN as 0: */ 6423 if (!(sample_value > 0)) 6424 sample_value = 0; 6425 else if (sample_value > scale) 6426 sample_value = scale; 6427 6428 return (unsigned int)sample_value; 6429 } 6430 6431 static void 6432 image_transform_mod_end(const image_transform *this, image_pixel *that, 6433 png_const_structp pp, const transform_display *display) 6434 { 6435 const unsigned int scale = (1U<<that->sample_depth)-1; 6436 const int sig_bits = that->sig_bits; 6437 6438 UNUSED(this) 6439 UNUSED(pp) 6440 UNUSED(display) 6441 6442 /* At the end recalculate the digitized red green and blue values according 6443 * to the current sample_depth of the pixel. 6444 * 6445 * The sample value is simply scaled to the maximum, checking for over 6446 * and underflow (which can both happen for some image transforms, 6447 * including simple size scaling, though libpng doesn't do that at present. 6448 */ 6449 that->red = sample_scale(that->redf, scale); 6450 6451 /* This is a bit bogus; really the above calculation should use the red_sBIT 6452 * value, not sample_depth, but because libpng does png_set_shift by just 6453 * shifting the bits we get errors if we don't do it the same way. 6454 */ 6455 if (sig_bits && that->red_sBIT < that->sample_depth) 6456 that->red >>= that->sample_depth - that->red_sBIT; 6457 6458 /* The error value is increased, at the end, according to the lowest sBIT 6459 * value seen. Common sense tells us that the intermediate integer 6460 * representations are no more accurate than +/- 0.5 in the integral values, 6461 * the sBIT allows the implementation to be worse than this. In addition the 6462 * PNG specification actually permits any error within the range (-1..+1), 6463 * but that is ignored here. Instead the final digitized value is compared, 6464 * below to the digitized value of the error limits - this has the net effect 6465 * of allowing (almost) +/-1 in the output value. It's difficult to see how 6466 * any algorithm that digitizes intermediate results can be more accurate. 6467 */ 6468 that->rede += 1./(2*((1U<<that->red_sBIT)-1)); 6469 6470 if (that->colour_type & PNG_COLOR_MASK_COLOR) 6471 { 6472 that->green = sample_scale(that->greenf, scale); 6473 if (sig_bits && that->green_sBIT < that->sample_depth) 6474 that->green >>= that->sample_depth - that->green_sBIT; 6475 6476 that->blue = sample_scale(that->bluef, scale); 6477 if (sig_bits && that->blue_sBIT < that->sample_depth) 6478 that->blue >>= that->sample_depth - that->blue_sBIT; 6479 6480 that->greene += 1./(2*((1U<<that->green_sBIT)-1)); 6481 that->bluee += 1./(2*((1U<<that->blue_sBIT)-1)); 6482 } 6483 else 6484 { 6485 that->blue = that->green = that->red; 6486 that->bluef = that->greenf = that->redf; 6487 that->bluee = that->greene = that->rede; 6488 } 6489 6490 if ((that->colour_type & PNG_COLOR_MASK_ALPHA) || 6491 that->colour_type == PNG_COLOR_TYPE_PALETTE) 6492 { 6493 that->alpha = sample_scale(that->alphaf, scale); 6494 that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1)); 6495 } 6496 else 6497 { 6498 that->alpha = scale; /* opaque */ 6499 that->alphaf = 1; /* Override this. */ 6500 that->alphae = 0; /* It's exact ;-) */ 6501 } 6502 6503 if (sig_bits && that->alpha_sBIT < that->sample_depth) 6504 that->alpha >>= that->sample_depth - that->alpha_sBIT; 6505 } 6506 6507 /* Static 'end' structure: */ 6508 static image_transform image_transform_end = 6509 { 6510 "(end)", /* name */ 6511 1, /* enable */ 6512 0, /* list */ 6513 0, /* global_use */ 6514 0, /* local_use */ 6515 0, /* next */ 6516 image_transform_ini_end, 6517 image_transform_set_end, 6518 image_transform_mod_end, 6519 0 /* never called, I want it to crash if it is! */ 6520 }; 6521 6522 /* Reader callbacks and implementations, where they differ from the standard 6523 * ones. 6524 */ 6525 static void 6526 transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id, 6527 const image_transform *transform_list) 6528 { 6529 memset(dp, 0, sizeof *dp); 6530 6531 /* Standard fields */ 6532 standard_display_init(&dp->this, &pm->this, id, do_read_interlace, 6533 pm->use_update_info); 6534 6535 /* Parameter fields */ 6536 dp->pm = pm; 6537 dp->transform_list = transform_list; 6538 dp->max_gamma_8 = 16; 6539 6540 /* Local variable fields */ 6541 dp->output_colour_type = 255; /* invalid */ 6542 dp->output_bit_depth = 255; /* invalid */ 6543 dp->unpacked = 0; /* not unpacked */ 6544 } 6545 6546 static void 6547 transform_info_imp(transform_display *dp, png_structp pp, png_infop pi) 6548 { 6549 /* Reuse the standard stuff as appropriate. */ 6550 standard_info_part1(&dp->this, pp, pi); 6551 6552 /* Now set the list of transforms. */ 6553 dp->transform_list->set(dp->transform_list, dp, pp, pi); 6554 6555 /* Update the info structure for these transforms: */ 6556 { 6557 int i = dp->this.use_update_info; 6558 /* Always do one call, even if use_update_info is 0. */ 6559 do 6560 png_read_update_info(pp, pi); 6561 while (--i > 0); 6562 } 6563 6564 /* And get the output information into the standard_display */ 6565 standard_info_part2(&dp->this, pp, pi, 1/*images*/); 6566 6567 /* Plus the extra stuff we need for the transform tests: */ 6568 dp->output_colour_type = png_get_color_type(pp, pi); 6569 dp->output_bit_depth = png_get_bit_depth(pp, pi); 6570 6571 /* If png_set_filler is in action then fake the output color type to include 6572 * an alpha channel where appropriate. 6573 */ 6574 if (dp->output_bit_depth >= 8 && 6575 (dp->output_colour_type == PNG_COLOR_TYPE_RGB || 6576 dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler) 6577 dp->output_colour_type |= 4; 6578 6579 /* Validate the combination of colour type and bit depth that we are getting 6580 * out of libpng; the semantics of something not in the PNG spec are, at 6581 * best, unclear. 6582 */ 6583 switch (dp->output_colour_type) 6584 { 6585 case PNG_COLOR_TYPE_PALETTE: 6586 if (dp->output_bit_depth > 8) goto error; 6587 /* FALLTHROUGH */ 6588 case PNG_COLOR_TYPE_GRAY: 6589 if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 || 6590 dp->output_bit_depth == 4) 6591 break; 6592 /* FALLTHROUGH */ 6593 default: 6594 if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16) 6595 break; 6596 /* FALLTHROUGH */ 6597 error: 6598 { 6599 char message[128]; 6600 size_t pos; 6601 6602 pos = safecat(message, sizeof message, 0, 6603 "invalid final bit depth: colour type("); 6604 pos = safecatn(message, sizeof message, pos, dp->output_colour_type); 6605 pos = safecat(message, sizeof message, pos, ") with bit depth: "); 6606 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); 6607 6608 png_error(pp, message); 6609 } 6610 } 6611 6612 /* Use a test pixel to check that the output agrees with what we expect - 6613 * this avoids running the whole test if the output is unexpected. This also 6614 * checks for internal errors. 6615 */ 6616 { 6617 image_pixel test_pixel; 6618 6619 memset(&test_pixel, 0, sizeof test_pixel); 6620 test_pixel.colour_type = dp->this.colour_type; /* input */ 6621 test_pixel.bit_depth = dp->this.bit_depth; 6622 if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE) 6623 test_pixel.sample_depth = 8; 6624 else 6625 test_pixel.sample_depth = test_pixel.bit_depth; 6626 /* Don't need sBIT here, but it must be set to non-zero to avoid 6627 * arithmetic overflows. 6628 */ 6629 test_pixel.have_tRNS = dp->this.is_transparent != 0; 6630 test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT = 6631 test_pixel.alpha_sBIT = test_pixel.sample_depth; 6632 6633 dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp); 6634 6635 if (test_pixel.colour_type != dp->output_colour_type) 6636 { 6637 char message[128]; 6638 size_t pos = safecat(message, sizeof message, 0, "colour type "); 6639 6640 pos = safecatn(message, sizeof message, pos, dp->output_colour_type); 6641 pos = safecat(message, sizeof message, pos, " expected "); 6642 pos = safecatn(message, sizeof message, pos, test_pixel.colour_type); 6643 6644 png_error(pp, message); 6645 } 6646 6647 if (test_pixel.bit_depth != dp->output_bit_depth) 6648 { 6649 char message[128]; 6650 size_t pos = safecat(message, sizeof message, 0, "bit depth "); 6651 6652 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); 6653 pos = safecat(message, sizeof message, pos, " expected "); 6654 pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); 6655 6656 png_error(pp, message); 6657 } 6658 6659 /* If both bit depth and colour type are correct check the sample depth. 6660 */ 6661 if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE && 6662 test_pixel.sample_depth != 8) /* oops - internal error! */ 6663 png_error(pp, "pngvalid: internal: palette sample depth not 8"); 6664 else if (dp->unpacked && test_pixel.bit_depth != 8) 6665 png_error(pp, "pngvalid: internal: bad unpacked pixel depth"); 6666 else if (!dp->unpacked && test_pixel.colour_type != PNG_COLOR_TYPE_PALETTE 6667 && test_pixel.bit_depth != test_pixel.sample_depth) 6668 { 6669 char message[128]; 6670 size_t pos = safecat(message, sizeof message, 0, 6671 "internal: sample depth "); 6672 6673 /* Because unless something has set 'unpacked' or the image is palette 6674 * mapped we expect the transform to keep sample depth and bit depth 6675 * the same. 6676 */ 6677 pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth); 6678 pos = safecat(message, sizeof message, pos, " expected "); 6679 pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); 6680 6681 png_error(pp, message); 6682 } 6683 else if (test_pixel.bit_depth != dp->output_bit_depth) 6684 { 6685 /* This could be a libpng error too; libpng has not produced what we 6686 * expect for the output bit depth. 6687 */ 6688 char message[128]; 6689 size_t pos = safecat(message, sizeof message, 0, 6690 "internal: bit depth "); 6691 6692 pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); 6693 pos = safecat(message, sizeof message, pos, " expected "); 6694 pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); 6695 6696 png_error(pp, message); 6697 } 6698 } 6699 } 6700 6701 static void PNGCBAPI 6702 transform_info(png_structp pp, png_infop pi) 6703 { 6704 transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)), 6705 pp, pi); 6706 } 6707 6708 static void 6709 transform_range_check(png_const_structp pp, unsigned int r, unsigned int g, 6710 unsigned int b, unsigned int a, unsigned int in_digitized, double in, 6711 unsigned int out, png_byte sample_depth, double err, double limit, 6712 const char *name, double digitization_error) 6713 { 6714 /* Compare the scaled, digitzed, values of our local calculation (in+-err) 6715 * with the digitized values libpng produced; 'sample_depth' is the actual 6716 * digitization depth of the libpng output colors (the bit depth except for 6717 * palette images where it is always 8.) The check on 'err' is to detect 6718 * internal errors in pngvalid itself. 6719 */ 6720 unsigned int max = (1U<<sample_depth)-1; 6721 double in_min = ceil((in-err)*max - digitization_error); 6722 double in_max = floor((in+err)*max + digitization_error); 6723 if (debugonly(err > limit ||) !(out >= in_min && out <= in_max)) 6724 { 6725 char message[256]; 6726 size_t pos; 6727 6728 pos = safecat(message, sizeof message, 0, name); 6729 pos = safecat(message, sizeof message, pos, " output value error: rgba("); 6730 pos = safecatn(message, sizeof message, pos, r); 6731 pos = safecat(message, sizeof message, pos, ","); 6732 pos = safecatn(message, sizeof message, pos, g); 6733 pos = safecat(message, sizeof message, pos, ","); 6734 pos = safecatn(message, sizeof message, pos, b); 6735 pos = safecat(message, sizeof message, pos, ","); 6736 pos = safecatn(message, sizeof message, pos, a); 6737 pos = safecat(message, sizeof message, pos, "): "); 6738 pos = safecatn(message, sizeof message, pos, out); 6739 pos = safecat(message, sizeof message, pos, " expected: "); 6740 pos = safecatn(message, sizeof message, pos, in_digitized); 6741 pos = safecat(message, sizeof message, pos, " ("); 6742 pos = safecatd(message, sizeof message, pos, (in-err)*max, 3); 6743 pos = safecat(message, sizeof message, pos, ".."); 6744 pos = safecatd(message, sizeof message, pos, (in+err)*max, 3); 6745 pos = safecat(message, sizeof message, pos, ")"); 6746 6747 png_error(pp, message); 6748 } 6749 6750 UNUSED(limit) 6751 } 6752 6753 static void 6754 transform_image_validate(transform_display *dp, png_const_structp pp, 6755 png_infop pi) 6756 { 6757 /* Constants for the loop below: */ 6758 const png_store* const ps = dp->this.ps; 6759 const png_byte in_ct = dp->this.colour_type; 6760 const png_byte in_bd = dp->this.bit_depth; 6761 const png_uint_32 w = dp->this.w; 6762 const png_uint_32 h = dp->this.h; 6763 const png_byte out_ct = dp->output_colour_type; 6764 const png_byte out_bd = dp->output_bit_depth; 6765 const png_byte sample_depth = (png_byte)(out_ct == 6766 PNG_COLOR_TYPE_PALETTE ? 8 : out_bd); 6767 const png_byte red_sBIT = dp->this.red_sBIT; 6768 const png_byte green_sBIT = dp->this.green_sBIT; 6769 const png_byte blue_sBIT = dp->this.blue_sBIT; 6770 const png_byte alpha_sBIT = dp->this.alpha_sBIT; 6771 const int have_tRNS = dp->this.is_transparent; 6772 double digitization_error; 6773 6774 store_palette out_palette; 6775 png_uint_32 y; 6776 6777 UNUSED(pi) 6778 6779 /* Check for row overwrite errors */ 6780 store_image_check(dp->this.ps, pp, 0); 6781 6782 /* Read the palette corresponding to the output if the output colour type 6783 * indicates a palette, othewise set out_palette to garbage. 6784 */ 6785 if (out_ct == PNG_COLOR_TYPE_PALETTE) 6786 { 6787 /* Validate that the palette count itself has not changed - this is not 6788 * expected. 6789 */ 6790 int npalette = (-1); 6791 6792 (void)read_palette(out_palette, &npalette, pp, pi); 6793 if (npalette != dp->this.npalette) 6794 png_error(pp, "unexpected change in palette size"); 6795 6796 digitization_error = .5; 6797 } 6798 else 6799 { 6800 png_byte in_sample_depth; 6801 6802 memset(out_palette, 0x5e, sizeof out_palette); 6803 6804 /* use-input-precision means assume that if the input has 8 bit (or less) 6805 * samples and the output has 16 bit samples the calculations will be done 6806 * with 8 bit precision, not 16. 6807 */ 6808 if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16) 6809 in_sample_depth = 8; 6810 else 6811 in_sample_depth = in_bd; 6812 6813 if (sample_depth != 16 || in_sample_depth > 8 || 6814 !dp->pm->calculations_use_input_precision) 6815 digitization_error = .5; 6816 6817 /* Else calculations are at 8 bit precision, and the output actually 6818 * consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits: 6819 */ 6820 else 6821 digitization_error = .5 * 257; 6822 } 6823 6824 for (y=0; y<h; ++y) 6825 { 6826 png_const_bytep const pRow = store_image_row(ps, pp, 0, y); 6827 png_uint_32 x; 6828 6829 /* The original, standard, row pre-transforms. */ 6830 png_byte std[STANDARD_ROWMAX]; 6831 6832 transform_row(pp, std, in_ct, in_bd, y); 6833 6834 /* Go through each original pixel transforming it and comparing with what 6835 * libpng did to the same pixel. 6836 */ 6837 for (x=0; x<w; ++x) 6838 { 6839 image_pixel in_pixel, out_pixel; 6840 unsigned int r, g, b, a; 6841 6842 /* Find out what we think the pixel should be: */ 6843 image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette, 6844 NULL); 6845 6846 in_pixel.red_sBIT = red_sBIT; 6847 in_pixel.green_sBIT = green_sBIT; 6848 in_pixel.blue_sBIT = blue_sBIT; 6849 in_pixel.alpha_sBIT = alpha_sBIT; 6850 in_pixel.have_tRNS = have_tRNS != 0; 6851 6852 /* For error detection, below. */ 6853 r = in_pixel.red; 6854 g = in_pixel.green; 6855 b = in_pixel.blue; 6856 a = in_pixel.alpha; 6857 6858 /* This applies the transforms to the input data, including output 6859 * format operations which must be used when reading the output 6860 * pixel that libpng produces. 6861 */ 6862 dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp); 6863 6864 /* Read the output pixel and compare it to what we got, we don't 6865 * use the error field here, so no need to update sBIT. in_pixel 6866 * says whether we expect libpng to change the output format. 6867 */ 6868 image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette, 6869 &in_pixel); 6870 6871 /* We don't expect changes to the index here even if the bit depth is 6872 * changed. 6873 */ 6874 if (in_ct == PNG_COLOR_TYPE_PALETTE && 6875 out_ct == PNG_COLOR_TYPE_PALETTE) 6876 { 6877 if (in_pixel.palette_index != out_pixel.palette_index) 6878 png_error(pp, "unexpected transformed palette index"); 6879 } 6880 6881 /* Check the colours for palette images too - in fact the palette could 6882 * be separately verified itself in most cases. 6883 */ 6884 if (in_pixel.red != out_pixel.red) 6885 transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf, 6886 out_pixel.red, sample_depth, in_pixel.rede, 6887 dp->pm->limit + 1./(2*((1U<<in_pixel.red_sBIT)-1)), "red/gray", 6888 digitization_error); 6889 6890 if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 && 6891 in_pixel.green != out_pixel.green) 6892 transform_range_check(pp, r, g, b, a, in_pixel.green, 6893 in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene, 6894 dp->pm->limit + 1./(2*((1U<<in_pixel.green_sBIT)-1)), "green", 6895 digitization_error); 6896 6897 if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 && 6898 in_pixel.blue != out_pixel.blue) 6899 transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef, 6900 out_pixel.blue, sample_depth, in_pixel.bluee, 6901 dp->pm->limit + 1./(2*((1U<<in_pixel.blue_sBIT)-1)), "blue", 6902 digitization_error); 6903 6904 if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 && 6905 in_pixel.alpha != out_pixel.alpha) 6906 transform_range_check(pp, r, g, b, a, in_pixel.alpha, 6907 in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae, 6908 dp->pm->limit + 1./(2*((1U<<in_pixel.alpha_sBIT)-1)), "alpha", 6909 digitization_error); 6910 } /* pixel (x) loop */ 6911 } /* row (y) loop */ 6912 6913 /* Record that something was actually checked to avoid a false positive. */ 6914 dp->this.ps->validated = 1; 6915 } 6916 6917 static void PNGCBAPI 6918 transform_end(png_structp ppIn, png_infop pi) 6919 { 6920 png_const_structp pp = ppIn; 6921 transform_display *dp = voidcast(transform_display*, 6922 png_get_progressive_ptr(pp)); 6923 6924 if (!dp->this.speed) 6925 transform_image_validate(dp, pp, pi); 6926 else 6927 dp->this.ps->validated = 1; 6928 } 6929 6930 /* A single test run. */ 6931 static void 6932 transform_test(png_modifier *pmIn, const png_uint_32 idIn, 6933 const image_transform* transform_listIn, const char * const name) 6934 { 6935 transform_display d; 6936 context(&pmIn->this, fault); 6937 6938 transform_display_init(&d, pmIn, idIn, transform_listIn); 6939 6940 Try 6941 { 6942 size_t pos = 0; 6943 png_structp pp; 6944 png_infop pi; 6945 char full_name[256]; 6946 6947 /* Make sure the encoding fields are correct and enter the required 6948 * modifications. 6949 */ 6950 transform_set_encoding(&d); 6951 6952 /* Add any modifications required by the transform list. */ 6953 d.transform_list->ini(d.transform_list, &d); 6954 6955 /* Add the color space information, if any, to the name. */ 6956 pos = safecat(full_name, sizeof full_name, pos, name); 6957 pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm); 6958 6959 /* Get a png_struct for reading the image. */ 6960 pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name); 6961 standard_palette_init(&d.this); 6962 6963 # if 0 6964 /* Logging (debugging only) */ 6965 { 6966 char buffer[256]; 6967 6968 (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0, 6969 "running test"); 6970 6971 fprintf(stderr, "%s\n", buffer); 6972 } 6973 # endif 6974 6975 /* Introduce the correct read function. */ 6976 if (d.pm->this.progressive) 6977 { 6978 /* Share the row function with the standard implementation. */ 6979 png_set_progressive_read_fn(pp, &d, transform_info, progressive_row, 6980 transform_end); 6981 6982 /* Now feed data into the reader until we reach the end: */ 6983 modifier_progressive_read(d.pm, pp, pi); 6984 } 6985 else 6986 { 6987 /* modifier_read expects a png_modifier* */ 6988 png_set_read_fn(pp, d.pm, modifier_read); 6989 6990 /* Check the header values: */ 6991 png_read_info(pp, pi); 6992 6993 /* Process the 'info' requirements. Only one image is generated */ 6994 transform_info_imp(&d, pp, pi); 6995 6996 sequential_row(&d.this, pp, pi, -1, 0); 6997 6998 if (!d.this.speed) 6999 transform_image_validate(&d, pp, pi); 7000 else 7001 d.this.ps->validated = 1; 7002 } 7003 7004 modifier_reset(d.pm); 7005 } 7006 7007 Catch(fault) 7008 { 7009 modifier_reset(voidcast(png_modifier*,(void*)fault)); 7010 } 7011 } 7012 7013 /* The transforms: */ 7014 #define ITSTRUCT(name) image_transform_##name 7015 #define ITDATA(name) image_transform_data_##name 7016 #define image_transform_ini image_transform_default_ini 7017 #define IT(name)\ 7018 static image_transform ITSTRUCT(name) =\ 7019 {\ 7020 #name,\ 7021 1, /*enable*/\ 7022 &PT, /*list*/\ 7023 0, /*global_use*/\ 7024 0, /*local_use*/\ 7025 0, /*next*/\ 7026 image_transform_ini,\ 7027 image_transform_png_set_##name##_set,\ 7028 image_transform_png_set_##name##_mod,\ 7029 image_transform_png_set_##name##_add\ 7030 } 7031 #define PT ITSTRUCT(end) /* stores the previous transform */ 7032 7033 /* To save code: */ 7034 extern void image_transform_default_ini(const image_transform *this, 7035 transform_display *that); /* silence GCC warnings */ 7036 7037 void /* private, but almost always needed */ 7038 image_transform_default_ini(const image_transform *this, 7039 transform_display *that) 7040 { 7041 this->next->ini(this->next, that); 7042 } 7043 7044 #ifdef PNG_READ_BACKGROUND_SUPPORTED 7045 static int 7046 image_transform_default_add(image_transform *this, 7047 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7048 { 7049 UNUSED(colour_type) 7050 UNUSED(bit_depth) 7051 7052 this->next = *that; 7053 *that = this; 7054 7055 return 1; 7056 } 7057 #endif 7058 7059 #ifdef PNG_READ_EXPAND_SUPPORTED 7060 /* png_set_palette_to_rgb */ 7061 static void 7062 image_transform_png_set_palette_to_rgb_set(const image_transform *this, 7063 transform_display *that, png_structp pp, png_infop pi) 7064 { 7065 png_set_palette_to_rgb(pp); 7066 this->next->set(this->next, that, pp, pi); 7067 } 7068 7069 static void 7070 image_transform_png_set_palette_to_rgb_mod(const image_transform *this, 7071 image_pixel *that, png_const_structp pp, 7072 const transform_display *display) 7073 { 7074 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 7075 image_pixel_convert_PLTE(that); 7076 7077 this->next->mod(this->next, that, pp, display); 7078 } 7079 7080 static int 7081 image_transform_png_set_palette_to_rgb_add(image_transform *this, 7082 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7083 { 7084 UNUSED(bit_depth) 7085 7086 this->next = *that; 7087 *that = this; 7088 7089 return colour_type == PNG_COLOR_TYPE_PALETTE; 7090 } 7091 7092 IT(palette_to_rgb); 7093 #undef PT 7094 #define PT ITSTRUCT(palette_to_rgb) 7095 #endif /* PNG_READ_EXPAND_SUPPORTED */ 7096 7097 #ifdef PNG_READ_EXPAND_SUPPORTED 7098 /* png_set_tRNS_to_alpha */ 7099 static void 7100 image_transform_png_set_tRNS_to_alpha_set(const image_transform *this, 7101 transform_display *that, png_structp pp, png_infop pi) 7102 { 7103 png_set_tRNS_to_alpha(pp); 7104 7105 /* If there was a tRNS chunk that would get expanded and add an alpha 7106 * channel is_transparent must be updated: 7107 */ 7108 if (that->this.has_tRNS) 7109 that->this.is_transparent = 1; 7110 7111 this->next->set(this->next, that, pp, pi); 7112 } 7113 7114 static void 7115 image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this, 7116 image_pixel *that, png_const_structp pp, 7117 const transform_display *display) 7118 { 7119 #if PNG_LIBPNG_VER < 10700 7120 /* LIBPNG BUG: this always forces palette images to RGB. */ 7121 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 7122 image_pixel_convert_PLTE(that); 7123 #endif 7124 7125 /* This effectively does an 'expand' only if there is some transparency to 7126 * convert to an alpha channel. 7127 */ 7128 if (that->have_tRNS) 7129 # if PNG_LIBPNG_VER >= 10700 7130 if (that->colour_type != PNG_COLOR_TYPE_PALETTE && 7131 (that->colour_type & PNG_COLOR_MASK_ALPHA) == 0) 7132 # endif 7133 image_pixel_add_alpha(that, &display->this, 0/*!for background*/); 7134 7135 #if PNG_LIBPNG_VER < 10700 7136 /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */ 7137 else 7138 { 7139 if (that->bit_depth < 8) 7140 that->bit_depth =8; 7141 if (that->sample_depth < 8) 7142 that->sample_depth = 8; 7143 } 7144 #endif 7145 7146 this->next->mod(this->next, that, pp, display); 7147 } 7148 7149 static int 7150 image_transform_png_set_tRNS_to_alpha_add(image_transform *this, 7151 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7152 { 7153 UNUSED(bit_depth) 7154 7155 this->next = *that; 7156 *that = this; 7157 7158 /* We don't know yet whether there will be a tRNS chunk, but we know that 7159 * this transformation should do nothing if there already is an alpha 7160 * channel. In addition, after the bug fix in 1.7.0, there is no longer 7161 * any action on a palette image. 7162 */ 7163 return 7164 # if PNG_LIBPNG_VER >= 10700 7165 colour_type != PNG_COLOR_TYPE_PALETTE && 7166 # endif 7167 (colour_type & PNG_COLOR_MASK_ALPHA) == 0; 7168 } 7169 7170 IT(tRNS_to_alpha); 7171 #undef PT 7172 #define PT ITSTRUCT(tRNS_to_alpha) 7173 #endif /* PNG_READ_EXPAND_SUPPORTED */ 7174 7175 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 7176 /* png_set_gray_to_rgb */ 7177 static void 7178 image_transform_png_set_gray_to_rgb_set(const image_transform *this, 7179 transform_display *that, png_structp pp, png_infop pi) 7180 { 7181 png_set_gray_to_rgb(pp); 7182 /* NOTE: this doesn't result in tRNS expansion. */ 7183 this->next->set(this->next, that, pp, pi); 7184 } 7185 7186 static void 7187 image_transform_png_set_gray_to_rgb_mod(const image_transform *this, 7188 image_pixel *that, png_const_structp pp, 7189 const transform_display *display) 7190 { 7191 /* NOTE: we can actually pend the tRNS processing at this point because we 7192 * can correctly recognize the original pixel value even though we have 7193 * mapped the one gray channel to the three RGB ones, but in fact libpng 7194 * doesn't do this, so we don't either. 7195 */ 7196 if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS) 7197 image_pixel_add_alpha(that, &display->this, 0/*!for background*/); 7198 7199 /* Simply expand the bit depth and alter the colour type as required. */ 7200 if (that->colour_type == PNG_COLOR_TYPE_GRAY) 7201 { 7202 /* RGB images have a bit depth at least equal to '8' */ 7203 if (that->bit_depth < 8) 7204 that->sample_depth = that->bit_depth = 8; 7205 7206 /* And just changing the colour type works here because the green and blue 7207 * channels are being maintained in lock-step with the red/gray: 7208 */ 7209 that->colour_type = PNG_COLOR_TYPE_RGB; 7210 } 7211 7212 else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) 7213 that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; 7214 7215 this->next->mod(this->next, that, pp, display); 7216 } 7217 7218 static int 7219 image_transform_png_set_gray_to_rgb_add(image_transform *this, 7220 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7221 { 7222 UNUSED(bit_depth) 7223 7224 this->next = *that; 7225 *that = this; 7226 7227 return (colour_type & PNG_COLOR_MASK_COLOR) == 0; 7228 } 7229 7230 IT(gray_to_rgb); 7231 #undef PT 7232 #define PT ITSTRUCT(gray_to_rgb) 7233 #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ 7234 7235 #ifdef PNG_READ_EXPAND_SUPPORTED 7236 /* png_set_expand */ 7237 static void 7238 image_transform_png_set_expand_set(const image_transform *this, 7239 transform_display *that, png_structp pp, png_infop pi) 7240 { 7241 png_set_expand(pp); 7242 7243 if (that->this.has_tRNS) 7244 that->this.is_transparent = 1; 7245 7246 this->next->set(this->next, that, pp, pi); 7247 } 7248 7249 static void 7250 image_transform_png_set_expand_mod(const image_transform *this, 7251 image_pixel *that, png_const_structp pp, 7252 const transform_display *display) 7253 { 7254 /* The general expand case depends on what the colour type is: */ 7255 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 7256 image_pixel_convert_PLTE(that); 7257 else if (that->bit_depth < 8) /* grayscale */ 7258 that->sample_depth = that->bit_depth = 8; 7259 7260 if (that->have_tRNS) 7261 image_pixel_add_alpha(that, &display->this, 0/*!for background*/); 7262 7263 this->next->mod(this->next, that, pp, display); 7264 } 7265 7266 static int 7267 image_transform_png_set_expand_add(image_transform *this, 7268 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7269 { 7270 UNUSED(bit_depth) 7271 7272 this->next = *that; 7273 *that = this; 7274 7275 /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit 7276 * depth is at least 8 already. 7277 */ 7278 return (colour_type & PNG_COLOR_MASK_ALPHA) == 0; 7279 } 7280 7281 IT(expand); 7282 #undef PT 7283 #define PT ITSTRUCT(expand) 7284 #endif /* PNG_READ_EXPAND_SUPPORTED */ 7285 7286 #ifdef PNG_READ_EXPAND_SUPPORTED 7287 /* png_set_expand_gray_1_2_4_to_8 7288 * Pre 1.7.0 LIBPNG BUG: this just does an 'expand' 7289 */ 7290 static void 7291 image_transform_png_set_expand_gray_1_2_4_to_8_set( 7292 const image_transform *this, transform_display *that, png_structp pp, 7293 png_infop pi) 7294 { 7295 png_set_expand_gray_1_2_4_to_8(pp); 7296 /* NOTE: don't expect this to expand tRNS */ 7297 this->next->set(this->next, that, pp, pi); 7298 } 7299 7300 static void 7301 image_transform_png_set_expand_gray_1_2_4_to_8_mod( 7302 const image_transform *this, image_pixel *that, png_const_structp pp, 7303 const transform_display *display) 7304 { 7305 #if PNG_LIBPNG_VER < 10700 7306 image_transform_png_set_expand_mod(this, that, pp, display); 7307 #else 7308 /* Only expand grayscale of bit depth less than 8: */ 7309 if (that->colour_type == PNG_COLOR_TYPE_GRAY && 7310 that->bit_depth < 8) 7311 that->sample_depth = that->bit_depth = 8; 7312 7313 this->next->mod(this->next, that, pp, display); 7314 #endif /* 1.7 or later */ 7315 } 7316 7317 static int 7318 image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this, 7319 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7320 { 7321 #if PNG_LIBPNG_VER < 10700 7322 return image_transform_png_set_expand_add(this, that, colour_type, 7323 bit_depth); 7324 #else 7325 UNUSED(bit_depth) 7326 7327 this->next = *that; 7328 *that = this; 7329 7330 /* This should do nothing unless the color type is gray and the bit depth is 7331 * less than 8: 7332 */ 7333 return colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8; 7334 #endif /* 1.7 or later */ 7335 } 7336 7337 IT(expand_gray_1_2_4_to_8); 7338 #undef PT 7339 #define PT ITSTRUCT(expand_gray_1_2_4_to_8) 7340 #endif /* PNG_READ_EXPAND_SUPPORTED */ 7341 7342 #ifdef PNG_READ_EXPAND_16_SUPPORTED 7343 /* png_set_expand_16 */ 7344 static void 7345 image_transform_png_set_expand_16_set(const image_transform *this, 7346 transform_display *that, png_structp pp, png_infop pi) 7347 { 7348 png_set_expand_16(pp); 7349 7350 /* NOTE: prior to 1.7 libpng does SET_EXPAND as well, so tRNS is expanded. */ 7351 # if PNG_LIBPNG_VER < 10700 7352 if (that->this.has_tRNS) 7353 that->this.is_transparent = 1; 7354 # endif 7355 7356 this->next->set(this->next, that, pp, pi); 7357 } 7358 7359 static void 7360 image_transform_png_set_expand_16_mod(const image_transform *this, 7361 image_pixel *that, png_const_structp pp, 7362 const transform_display *display) 7363 { 7364 /* Expect expand_16 to expand everything to 16 bits as a result of also 7365 * causing 'expand' to happen. 7366 */ 7367 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 7368 image_pixel_convert_PLTE(that); 7369 7370 if (that->have_tRNS) 7371 image_pixel_add_alpha(that, &display->this, 0/*!for background*/); 7372 7373 if (that->bit_depth < 16) 7374 that->sample_depth = that->bit_depth = 16; 7375 7376 this->next->mod(this->next, that, pp, display); 7377 } 7378 7379 static int 7380 image_transform_png_set_expand_16_add(image_transform *this, 7381 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7382 { 7383 UNUSED(colour_type) 7384 7385 this->next = *that; 7386 *that = this; 7387 7388 /* expand_16 does something unless the bit depth is already 16. */ 7389 return bit_depth < 16; 7390 } 7391 7392 IT(expand_16); 7393 #undef PT 7394 #define PT ITSTRUCT(expand_16) 7395 #endif /* PNG_READ_EXPAND_16_SUPPORTED */ 7396 7397 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* API added in 1.5.4 */ 7398 /* png_set_scale_16 */ 7399 static void 7400 image_transform_png_set_scale_16_set(const image_transform *this, 7401 transform_display *that, png_structp pp, png_infop pi) 7402 { 7403 png_set_scale_16(pp); 7404 # if PNG_LIBPNG_VER < 10700 7405 /* libpng will limit the gamma table size: */ 7406 that->max_gamma_8 = PNG_MAX_GAMMA_8; 7407 # endif 7408 this->next->set(this->next, that, pp, pi); 7409 } 7410 7411 static void 7412 image_transform_png_set_scale_16_mod(const image_transform *this, 7413 image_pixel *that, png_const_structp pp, 7414 const transform_display *display) 7415 { 7416 if (that->bit_depth == 16) 7417 { 7418 that->sample_depth = that->bit_depth = 8; 7419 if (that->red_sBIT > 8) that->red_sBIT = 8; 7420 if (that->green_sBIT > 8) that->green_sBIT = 8; 7421 if (that->blue_sBIT > 8) that->blue_sBIT = 8; 7422 if (that->alpha_sBIT > 8) that->alpha_sBIT = 8; 7423 } 7424 7425 this->next->mod(this->next, that, pp, display); 7426 } 7427 7428 static int 7429 image_transform_png_set_scale_16_add(image_transform *this, 7430 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7431 { 7432 UNUSED(colour_type) 7433 7434 this->next = *that; 7435 *that = this; 7436 7437 return bit_depth > 8; 7438 } 7439 7440 IT(scale_16); 7441 #undef PT 7442 #define PT ITSTRUCT(scale_16) 7443 #endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */ 7444 7445 #ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */ 7446 /* png_set_strip_16 */ 7447 static void 7448 image_transform_png_set_strip_16_set(const image_transform *this, 7449 transform_display *that, png_structp pp, png_infop pi) 7450 { 7451 png_set_strip_16(pp); 7452 # if PNG_LIBPNG_VER < 10700 7453 /* libpng will limit the gamma table size: */ 7454 that->max_gamma_8 = PNG_MAX_GAMMA_8; 7455 # endif 7456 this->next->set(this->next, that, pp, pi); 7457 } 7458 7459 static void 7460 image_transform_png_set_strip_16_mod(const image_transform *this, 7461 image_pixel *that, png_const_structp pp, 7462 const transform_display *display) 7463 { 7464 if (that->bit_depth == 16) 7465 { 7466 that->sample_depth = that->bit_depth = 8; 7467 if (that->red_sBIT > 8) that->red_sBIT = 8; 7468 if (that->green_sBIT > 8) that->green_sBIT = 8; 7469 if (that->blue_sBIT > 8) that->blue_sBIT = 8; 7470 if (that->alpha_sBIT > 8) that->alpha_sBIT = 8; 7471 7472 /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this 7473 * configuration option is set. From 1.5.4 the flag is never set and the 7474 * 'scale' API (above) must be used. 7475 */ 7476 # ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED 7477 # if PNG_LIBPNG_VER >= 10504 7478 # error PNG_READ_ACCURATE_SCALE should not be set 7479 # endif 7480 7481 /* The strip 16 algorithm drops the low 8 bits rather than calculating 7482 * 1/257, so we need to adjust the permitted errors appropriately: 7483 * Notice that this is only relevant prior to the addition of the 7484 * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!) 7485 */ 7486 { 7487 const double d = (255-128.5)/65535; 7488 that->rede += d; 7489 that->greene += d; 7490 that->bluee += d; 7491 that->alphae += d; 7492 } 7493 # endif 7494 } 7495 7496 this->next->mod(this->next, that, pp, display); 7497 } 7498 7499 static int 7500 image_transform_png_set_strip_16_add(image_transform *this, 7501 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7502 { 7503 UNUSED(colour_type) 7504 7505 this->next = *that; 7506 *that = this; 7507 7508 return bit_depth > 8; 7509 } 7510 7511 IT(strip_16); 7512 #undef PT 7513 #define PT ITSTRUCT(strip_16) 7514 #endif /* PNG_READ_16_TO_8_SUPPORTED */ 7515 7516 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 7517 /* png_set_strip_alpha */ 7518 static void 7519 image_transform_png_set_strip_alpha_set(const image_transform *this, 7520 transform_display *that, png_structp pp, png_infop pi) 7521 { 7522 png_set_strip_alpha(pp); 7523 this->next->set(this->next, that, pp, pi); 7524 } 7525 7526 static void 7527 image_transform_png_set_strip_alpha_mod(const image_transform *this, 7528 image_pixel *that, png_const_structp pp, 7529 const transform_display *display) 7530 { 7531 if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) 7532 that->colour_type = PNG_COLOR_TYPE_GRAY; 7533 else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) 7534 that->colour_type = PNG_COLOR_TYPE_RGB; 7535 7536 that->have_tRNS = 0; 7537 that->alphaf = 1; 7538 7539 this->next->mod(this->next, that, pp, display); 7540 } 7541 7542 static int 7543 image_transform_png_set_strip_alpha_add(image_transform *this, 7544 const image_transform **that, png_byte colour_type, png_byte bit_depth) 7545 { 7546 UNUSED(bit_depth) 7547 7548 this->next = *that; 7549 *that = this; 7550 7551 return (colour_type & PNG_COLOR_MASK_ALPHA) != 0; 7552 } 7553 7554 IT(strip_alpha); 7555 #undef PT 7556 #define PT ITSTRUCT(strip_alpha) 7557 #endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */ 7558 7559 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 7560 /* png_set_rgb_to_gray(png_structp, int err_action, double red, double green) 7561 * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red, 7562 * png_fixed_point green) 7563 * png_get_rgb_to_gray_status 7564 * 7565 * The 'default' test here uses values known to be used inside libpng prior to 7566 * 1.7.0: 7567 * 7568 * red: 6968 7569 * green: 23434 7570 * blue: 2366 7571 * 7572 * These values are being retained for compatibility, along with the somewhat 7573 * broken truncation calculation in the fast-and-inaccurate code path. Older 7574 * versions of libpng will fail the accuracy tests below because they use the 7575 * truncation algorithm everywhere. 7576 */ 7577 #define data ITDATA(rgb_to_gray) 7578 static struct 7579 { 7580 double gamma; /* File gamma to use in processing */ 7581 7582 /* The following are the parameters for png_set_rgb_to_gray: */ 7583 # ifdef PNG_FLOATING_POINT_SUPPORTED 7584 double red_to_set; 7585 double green_to_set; 7586 # else 7587 png_fixed_point red_to_set; 7588 png_fixed_point green_to_set; 7589 # endif 7590 7591 /* The actual coefficients: */ 7592 double red_coefficient; 7593 double green_coefficient; 7594 double blue_coefficient; 7595 7596 /* Set if the coeefficients have been overridden. */ 7597 int coefficients_overridden; 7598 } data; 7599 7600 #undef image_transform_ini 7601 #define image_transform_ini image_transform_png_set_rgb_to_gray_ini 7602 static void 7603 image_transform_png_set_rgb_to_gray_ini(const image_transform *this, 7604 transform_display *that) 7605 { 7606 png_modifier *pm = that->pm; 7607 const color_encoding *e = pm->current_encoding; 7608 7609 UNUSED(this) 7610 7611 /* Since we check the encoding this flag must be set: */ 7612 pm->test_uses_encoding = 1; 7613 7614 /* If 'e' is not NULL chromaticity information is present and either a cHRM 7615 * or an sRGB chunk will be inserted. 7616 */ 7617 if (e != 0) 7618 { 7619 /* Coefficients come from the encoding, but may need to be normalized to a 7620 * white point Y of 1.0 7621 */ 7622 const double whiteY = e->red.Y + e->green.Y + e->blue.Y; 7623 7624 data.red_coefficient = e->red.Y; 7625 data.green_coefficient = e->green.Y; 7626 data.blue_coefficient = e->blue.Y; 7627 7628 if (whiteY != 1) 7629 { 7630 data.red_coefficient /= whiteY; 7631 data.green_coefficient /= whiteY; 7632 data.blue_coefficient /= whiteY; 7633 } 7634 } 7635 7636 else 7637 { 7638 /* The default (built in) coeffcients, as above: */ 7639 # if PNG_LIBPNG_VER < 10700 7640 data.red_coefficient = 6968 / 32768.; 7641 data.green_coefficient = 23434 / 32768.; 7642 data.blue_coefficient = 2366 / 32768.; 7643 # else 7644 data.red_coefficient = .2126; 7645 data.green_coefficient = .7152; 7646 data.blue_coefficient = .0722; 7647 # endif 7648 } 7649 7650 data.gamma = pm->current_gamma; 7651 7652 /* If not set then the calculations assume linear encoding (implicitly): */ 7653 if (data.gamma == 0) 7654 data.gamma = 1; 7655 7656 /* The arguments to png_set_rgb_to_gray can override the coefficients implied 7657 * by the color space encoding. If doing exhaustive checks do the override 7658 * in each case, otherwise do it randomly. 7659 */ 7660 if (pm->test_exhaustive) 7661 { 7662 /* First time in coefficients_overridden is 0, the following sets it to 1, 7663 * so repeat if it is set. If a test fails this may mean we subsequently 7664 * skip a non-override test, ignore that. 7665 */ 7666 data.coefficients_overridden = !data.coefficients_overridden; 7667 pm->repeat = data.coefficients_overridden != 0; 7668 } 7669 7670 else 7671 data.coefficients_overridden = random_choice(); 7672 7673 if (data.coefficients_overridden) 7674 { 7675 /* These values override the color encoding defaults, simply use random 7676 * numbers. 7677 */ 7678 png_uint_32 ru; 7679 double total; 7680 7681 ru = random_u32(); 7682 data.green_coefficient = total = (ru & 0xffff) / 65535.; 7683 ru >>= 16; 7684 data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.; 7685 total += data.red_coefficient; 7686 data.blue_coefficient = 1 - total; 7687 7688 # ifdef PNG_FLOATING_POINT_SUPPORTED 7689 data.red_to_set = data.red_coefficient; 7690 data.green_to_set = data.green_coefficient; 7691 # else 7692 data.red_to_set = fix(data.red_coefficient); 7693 data.green_to_set = fix(data.green_coefficient); 7694 # endif 7695 7696 /* The following just changes the error messages: */ 7697 pm->encoding_ignored = 1; 7698 } 7699 7700 else 7701 { 7702 data.red_to_set = -1; 7703 data.green_to_set = -1; 7704 } 7705 7706 /* Adjust the error limit in the png_modifier because of the larger errors 7707 * produced in the digitization during the gamma handling. 7708 */ 7709 if (data.gamma != 1) /* Use gamma tables */ 7710 { 7711 if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations) 7712 { 7713 /* The computations have the form: 7714 * 7715 * r * rc + g * gc + b * bc 7716 * 7717 * Each component of which is +/-1/65535 from the gamma_to_1 table 7718 * lookup, resulting in a base error of +/-6. The gamma_from_1 7719 * conversion adds another +/-2 in the 16-bit case and 7720 * +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case. 7721 */ 7722 # if PNG_LIBPNG_VER < 10700 7723 if (that->this.bit_depth < 16) 7724 that->max_gamma_8 = PNG_MAX_GAMMA_8; 7725 # endif 7726 that->pm->limit += pow( 7727 (that->this.bit_depth == 16 || that->max_gamma_8 > 14 ? 7728 8. : 7729 6. + (1<<(15-that->max_gamma_8)) 7730 )/65535, data.gamma); 7731 } 7732 7733 else 7734 { 7735 /* Rounding to 8 bits in the linear space causes massive errors which 7736 * will trigger the error check in transform_range_check. Fix that 7737 * here by taking the gamma encoding into account. 7738 * 7739 * When DIGITIZE is set because a pre-1.7 version of libpng is being 7740 * tested allow a bigger slack. 7741 * 7742 * NOTE: this number only affects the internal limit check in pngvalid, 7743 * it has no effect on the limits applied to the libpng values. 7744 */ 7745 #if DIGITIZE 7746 that->pm->limit += pow( 2.0/255, data.gamma); 7747 #else 7748 that->pm->limit += pow( 1.0/255, data.gamma); 7749 #endif 7750 } 7751 } 7752 7753 else 7754 { 7755 /* With no gamma correction a large error comes from the truncation of the 7756 * calculation in the 8 bit case, allow for that here. 7757 */ 7758 if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations) 7759 that->pm->limit += 4E-3; 7760 } 7761 } 7762 7763 static void 7764 image_transform_png_set_rgb_to_gray_set(const image_transform *this, 7765 transform_display *that, png_structp pp, png_infop pi) 7766 { 7767 const int error_action = 1; /* no error, no defines in png.h */ 7768 7769 # ifdef PNG_FLOATING_POINT_SUPPORTED 7770 png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set); 7771 # else 7772 png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set, 7773 data.green_to_set); 7774 # endif 7775 7776 # ifdef PNG_READ_cHRM_SUPPORTED 7777 if (that->pm->current_encoding != 0) 7778 { 7779 /* We have an encoding so a cHRM chunk may have been set; if so then 7780 * check that the libpng APIs give the correct (X,Y,Z) values within 7781 * some margin of error for the round trip through the chromaticity 7782 * form. 7783 */ 7784 # ifdef PNG_FLOATING_POINT_SUPPORTED 7785 # define API_function png_get_cHRM_XYZ 7786 # define API_form "FP" 7787 # define API_type double 7788 # define API_cvt(x) (x) 7789 # else 7790 # define API_function png_get_cHRM_XYZ_fixed 7791 # define API_form "fixed" 7792 # define API_type png_fixed_point 7793 # define API_cvt(x) ((double)(x)/PNG_FP_1) 7794 # endif 7795 7796 API_type rX, gX, bX; 7797 API_type rY, gY, bY; 7798 API_type rZ, gZ, bZ; 7799 7800 if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ) 7801 & PNG_INFO_cHRM) != 0) 7802 { 7803 double maxe; 7804 const char *el; 7805 color_encoding e, o; 7806 7807 /* Expect libpng to return a normalized result, but the original 7808 * color space encoding may not be normalized. 7809 */ 7810 modifier_current_encoding(that->pm, &o); 7811 normalize_color_encoding(&o); 7812 7813 /* Sanity check the pngvalid code - the coefficients should match 7814 * the normalized Y values of the encoding unless they were 7815 * overridden. 7816 */ 7817 if (data.red_to_set == -1 && data.green_to_set == -1 && 7818 (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON || 7819 fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON || 7820 fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON)) 7821 png_error(pp, "internal pngvalid cHRM coefficient error"); 7822 7823 /* Generate a colour space encoding. */ 7824 e.gamma = o.gamma; /* not used */ 7825 e.red.X = API_cvt(rX); 7826 e.red.Y = API_cvt(rY); 7827 e.red.Z = API_cvt(rZ); 7828 e.green.X = API_cvt(gX); 7829 e.green.Y = API_cvt(gY); 7830 e.green.Z = API_cvt(gZ); 7831 e.blue.X = API_cvt(bX); 7832 e.blue.Y = API_cvt(bY); 7833 e.blue.Z = API_cvt(bZ); 7834 7835 /* This should match the original one from the png_modifier, within 7836 * the range permitted by the libpng fixed point representation. 7837 */ 7838 maxe = 0; 7839 el = "-"; /* Set to element name with error */ 7840 7841 # define CHECK(col,x)\ 7842 {\ 7843 double err = fabs(o.col.x - e.col.x);\ 7844 if (err > maxe)\ 7845 {\ 7846 maxe = err;\ 7847 el = #col "(" #x ")";\ 7848 }\ 7849 } 7850 7851 CHECK(red,X) 7852 CHECK(red,Y) 7853 CHECK(red,Z) 7854 CHECK(green,X) 7855 CHECK(green,Y) 7856 CHECK(green,Z) 7857 CHECK(blue,X) 7858 CHECK(blue,Y) 7859 CHECK(blue,Z) 7860 7861 /* Here in both fixed and floating cases to check the values read 7862 * from the cHRm chunk. PNG uses fixed point in the cHRM chunk, so 7863 * we can't expect better than +/-.5E-5 on the result, allow 1E-5. 7864 */ 7865 if (maxe >= 1E-5) 7866 { 7867 size_t pos = 0; 7868 char buffer[256]; 7869 7870 pos = safecat(buffer, sizeof buffer, pos, API_form); 7871 pos = safecat(buffer, sizeof buffer, pos, " cHRM "); 7872 pos = safecat(buffer, sizeof buffer, pos, el); 7873 pos = safecat(buffer, sizeof buffer, pos, " error: "); 7874 pos = safecatd(buffer, sizeof buffer, pos, maxe, 7); 7875 pos = safecat(buffer, sizeof buffer, pos, " "); 7876 /* Print the color space without the gamma value: */ 7877 pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0); 7878 pos = safecat(buffer, sizeof buffer, pos, " -> "); 7879 pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0); 7880 7881 png_error(pp, buffer); 7882 } 7883 } 7884 } 7885 # endif /* READ_cHRM */ 7886 7887 this->next->set(this->next, that, pp, pi); 7888 } 7889 7890 static void 7891 image_transform_png_set_rgb_to_gray_mod(const image_transform *this, 7892 image_pixel *that, png_const_structp pp, 7893 const transform_display *display) 7894 { 7895 if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0) 7896 { 7897 double gray, err; 7898 7899 # if PNG_LIBPNG_VER < 10700 7900 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) 7901 image_pixel_convert_PLTE(that); 7902 # endif 7903 7904 /* Image now has RGB channels... */ 7905 # if DIGITIZE 7906 { 7907 png_modifier *pm = display->pm; 7908 const unsigned int sample_depth = that->sample_depth; 7909 const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 : 7910 sample_depth); 7911 const unsigned int gamma_depth = 7912 (sample_depth == 16 ? 7913 display->max_gamma_8 : 7914 (pm->assume_16_bit_calculations ? 7915 display->max_gamma_8 : 7916 sample_depth)); 7917 int isgray; 7918 double r, g, b; 7919 double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi; 7920 7921 /* Do this using interval arithmetic, otherwise it is too difficult to 7922 * handle the errors correctly. 7923 * 7924 * To handle the gamma correction work out the upper and lower bounds 7925 * of the digitized value. Assume rounding here - normally the values 7926 * will be identical after this operation if there is only one 7927 * transform, feel free to delete the png_error checks on this below in 7928 * the future (this is just me trying to ensure it works!) 7929 * 7930 * Interval arithmetic is exact, but to implement it it must be 7931 * possible to control the floating point implementation rounding mode. 7932 * This cannot be done in ANSI-C, so instead I reduce the 'lo' values 7933 * by DBL_EPSILON and increase the 'hi' values by the same. 7934 */ 7935 # define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON)) 7936 # define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON)) 7937 7938 r = rlo = rhi = that->redf; 7939 rlo -= that->rede; 7940 rlo = DD(rlo, calc_depth, 1/*round*/); 7941 rhi += that->rede; 7942 rhi = DU(rhi, calc_depth, 1/*round*/); 7943 7944 g = glo = ghi = that->greenf; 7945 glo -= that->greene; 7946 glo = DD(glo, calc_depth, 1/*round*/); 7947 ghi += that->greene; 7948 ghi = DU(ghi, calc_depth, 1/*round*/); 7949 7950 b = blo = bhi = that->bluef; 7951 blo -= that->bluee; 7952 blo = DD(blo, calc_depth, 1/*round*/); 7953 bhi += that->bluee; 7954 bhi = DU(bhi, calc_depth, 1/*round*/); 7955 7956 isgray = r==g && g==b; 7957 7958 if (data.gamma != 1) 7959 { 7960 const double power = 1/data.gamma; 7961 const double abse = .5/(sample_depth == 16 ? 65535 : 255); 7962 7963 /* If a gamma calculation is done it is done using lookup tables of 7964 * precision gamma_depth, so the already digitized value above may 7965 * need to be further digitized here. 7966 */ 7967 if (gamma_depth != calc_depth) 7968 { 7969 rlo = DD(rlo, gamma_depth, 0/*truncate*/); 7970 rhi = DU(rhi, gamma_depth, 0/*truncate*/); 7971 glo = DD(glo, gamma_depth, 0/*truncate*/); 7972 ghi = DU(ghi, gamma_depth, 0/*truncate*/); 7973 blo = DD(blo, gamma_depth, 0/*truncate*/); 7974 bhi = DU(bhi, gamma_depth, 0/*truncate*/); 7975 } 7976 7977 /* 'abse' is the error in the gamma table calculation itself. */ 7978 r = pow(r, power); 7979 rlo = DD(pow(rlo, power)-abse, calc_depth, 1); 7980 rhi = DU(pow(rhi, power)+abse, calc_depth, 1); 7981 7982 g = pow(g, power); 7983 glo = DD(pow(glo, power)-abse, calc_depth, 1); 7984 ghi = DU(pow(ghi, power)+abse, calc_depth, 1); 7985 7986 b = pow(b, power); 7987 blo = DD(pow(blo, power)-abse, calc_depth, 1); 7988 bhi = DU(pow(bhi, power)+abse, calc_depth, 1); 7989 } 7990 7991 /* Now calculate the actual gray values. Although the error in the 7992 * coefficients depends on whether they were specified on the command 7993 * line (in which case truncation to 15 bits happened) or not (rounding 7994 * was used) the maxium error in an individual coefficient is always 7995 * 2/32768, because even in the rounding case the requirement that 7996 * coefficients add up to 32768 can cause a larger rounding error. 7997 * 7998 * The only time when rounding doesn't occur in 1.5.5 and later is when 7999 * the non-gamma code path is used for less than 16 bit data. 8000 */ 8001 gray = r * data.red_coefficient + g * data.green_coefficient + 8002 b * data.blue_coefficient; 8003 8004 { 8005 const int do_round = data.gamma != 1 || calc_depth == 16; 8006 const double ce = 2. / 32768; 8007 8008 graylo = DD(rlo * (data.red_coefficient-ce) + 8009 glo * (data.green_coefficient-ce) + 8010 blo * (data.blue_coefficient-ce), calc_depth, do_round); 8011 if (graylo > gray) /* always accept the right answer */ 8012 graylo = gray; 8013 8014 grayhi = DU(rhi * (data.red_coefficient+ce) + 8015 ghi * (data.green_coefficient+ce) + 8016 bhi * (data.blue_coefficient+ce), calc_depth, do_round); 8017 if (grayhi < gray) 8018 grayhi = gray; 8019 } 8020 8021 /* And invert the gamma. */ 8022 if (data.gamma != 1) 8023 { 8024 const double power = data.gamma; 8025 8026 /* And this happens yet again, shifting the values once more. */ 8027 if (gamma_depth != sample_depth) 8028 { 8029 rlo = DD(rlo, gamma_depth, 0/*truncate*/); 8030 rhi = DU(rhi, gamma_depth, 0/*truncate*/); 8031 glo = DD(glo, gamma_depth, 0/*truncate*/); 8032 ghi = DU(ghi, gamma_depth, 0/*truncate*/); 8033 blo = DD(blo, gamma_depth, 0/*truncate*/); 8034 bhi = DU(bhi, gamma_depth, 0/*truncate*/); 8035 } 8036 8037 gray = pow(gray, power); 8038 graylo = DD(pow(graylo, power), sample_depth, 1); 8039 grayhi = DU(pow(grayhi, power), sample_depth, 1); 8040 } 8041 8042 # undef DD 8043 # undef DU 8044 8045 /* Now the error can be calculated. 8046 * 8047 * If r==g==b because there is no overall gamma correction libpng 8048 * currently preserves the original value. 8049 */ 8050 if (isgray) 8051 err = (that->rede + that->greene + that->bluee)/3; 8052 8053 else 8054 { 8055 err = fabs(grayhi-gray); 8056 8057 if (fabs(gray - graylo) > err) 8058 err = fabs(graylo-gray); 8059 8060 #if !RELEASE_BUILD 8061 /* Check that this worked: */ 8062 if (err > pm->limit) 8063 { 8064 size_t pos = 0; 8065 char buffer[128]; 8066 8067 pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); 8068 pos = safecatd(buffer, sizeof buffer, pos, err, 6); 8069 pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); 8070 pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); 8071 png_warning(pp, buffer); 8072 pm->limit = err; 8073 } 8074 #endif /* !RELEASE_BUILD */ 8075 } 8076 } 8077 # else /* !DIGITIZE */ 8078 { 8079 double r = that->redf; 8080 double re = that->rede; 8081 double g = that->greenf; 8082 double ge = that->greene; 8083 double b = that->bluef; 8084 double be = that->bluee; 8085 8086 # if PNG_LIBPNG_VER < 10700 8087 /* The true gray case involves no math in earlier versions (not 8088 * true, there was some if gamma correction was happening too.) 8089 */ 8090 if (r == g && r == b) 8091 { 8092 gray = r; 8093 err = re; 8094 if (err < ge) err = ge; 8095 if (err < be) err = be; 8096 } 8097 8098 else 8099 # endif /* before 1.7 */ 8100 if (data.gamma == 1) 8101 { 8102 /* There is no need to do the conversions to and from linear space, 8103 * so the calculation should be a lot more accurate. There is a 8104 * built in error in the coefficients because they only have 15 bits 8105 * and are adjusted to make sure they add up to 32768. This 8106 * involves a integer calculation with truncation of the form: 8107 * 8108 * ((int)(coefficient * 100000) * 32768)/100000 8109 * 8110 * This is done to the red and green coefficients (the ones 8111 * provided to the API) then blue is calculated from them so the 8112 * result adds up to 32768. In the worst case this can result in 8113 * a -1 error in red and green and a +2 error in blue. Consequently 8114 * the worst case in the calculation below is 2/32768 error. 8115 * 8116 * TODO: consider fixing this in libpng by rounding the calculation 8117 * limiting the error to 1/32768. 8118 * 8119 * Handling this by adding 2/32768 here avoids needing to increase 8120 * the global error limits to take this into account.) 8121 */ 8122 gray = r * data.red_coefficient + g * data.green_coefficient + 8123 b * data.blue_coefficient; 8124 err = re * data.red_coefficient + ge * data.green_coefficient + 8125 be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON; 8126 } 8127 8128 else 8129 { 8130 /* The calculation happens in linear space, and this produces much 8131 * wider errors in the encoded space. These are handled here by 8132 * factoring the errors in to the calculation. There are two table 8133 * lookups in the calculation and each introduces a quantization 8134 * error defined by the table size. 8135 */ 8136 png_modifier *pm = display->pm; 8137 double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255); 8138 double out_qe = (that->sample_depth > 8 ? .5/65535 : 8139 (pm->assume_16_bit_calculations ? .5/(1<<display->max_gamma_8) : 8140 .5/255)); 8141 double rhi, ghi, bhi, grayhi; 8142 double g1 = 1/data.gamma; 8143 8144 rhi = r + re + in_qe; if (rhi > 1) rhi = 1; 8145 r -= re + in_qe; if (r < 0) r = 0; 8146 ghi = g + ge + in_qe; if (ghi > 1) ghi = 1; 8147 g -= ge + in_qe; if (g < 0) g = 0; 8148 bhi = b + be + in_qe; if (bhi > 1) bhi = 1; 8149 b -= be + in_qe; if (b < 0) b = 0; 8150 8151 r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON); 8152 g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON); 8153 b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON); 8154 8155 /* Work out the lower and upper bounds for the gray value in the 8156 * encoded space, then work out an average and error. Remove the 8157 * previously added input quantization error at this point. 8158 */ 8159 gray = r * data.red_coefficient + g * data.green_coefficient + 8160 b * data.blue_coefficient - 2./32768 - out_qe; 8161 if (gray <= 0) 8162 gray = 0; 8163 else 8164 { 8165 gray *= (1 - 6 * DBL_EPSILON); 8166 gray = pow(gray, data.gamma) * (1-DBL_EPSILON); 8167 } 8168 8169 grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient + 8170 bhi * data.blue_coefficient + 2./32768 + out_qe; 8171 grayhi *= (1 + 6 * DBL_EPSILON); 8172 if (grayhi >= 1) 8173 grayhi = 1; 8174 else 8175 grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON); 8176 8177 err = (grayhi - gray) / 2; 8178 gray = (grayhi + gray) / 2; 8179 8180 if (err <= in_qe) 8181 err = gray * DBL_EPSILON; 8182 8183 else 8184 err -= in_qe; 8185 8186 #if !RELEASE_BUILD 8187 /* Validate that the error is within limits (this has caused 8188 * problems before, it's much easier to detect them here.) 8189 */ 8190 if (err > pm->limit) 8191 { 8192 size_t pos = 0; 8193 char buffer[128]; 8194 8195 pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); 8196 pos = safecatd(buffer, sizeof buffer, pos, err, 6); 8197 pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); 8198 pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); 8199 png_warning(pp, buffer); 8200 pm->limit = err; 8201 } 8202 #endif /* !RELEASE_BUILD */ 8203 } 8204 } 8205 # endif /* !DIGITIZE */ 8206 8207 that->bluef = that->greenf = that->redf = gray; 8208 that->bluee = that->greene = that->rede = err; 8209 8210 /* The sBIT is the minium of the three colour channel sBITs. */ 8211 if (that->red_sBIT > that->green_sBIT) 8212 that->red_sBIT = that->green_sBIT; 8213 if (that->red_sBIT > that->blue_sBIT) 8214 that->red_sBIT = that->blue_sBIT; 8215 that->blue_sBIT = that->green_sBIT = that->red_sBIT; 8216 8217 /* And remove the colour bit in the type: */ 8218 if (that->colour_type == PNG_COLOR_TYPE_RGB) 8219 that->colour_type = PNG_COLOR_TYPE_GRAY; 8220 else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) 8221 that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; 8222 } 8223 8224 this->next->mod(this->next, that, pp, display); 8225 } 8226 8227 static int 8228 image_transform_png_set_rgb_to_gray_add(image_transform *this, 8229 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8230 { 8231 UNUSED(bit_depth) 8232 8233 this->next = *that; 8234 *that = this; 8235 8236 return (colour_type & PNG_COLOR_MASK_COLOR) != 0; 8237 } 8238 8239 #undef data 8240 IT(rgb_to_gray); 8241 #undef PT 8242 #define PT ITSTRUCT(rgb_to_gray) 8243 #undef image_transform_ini 8244 #define image_transform_ini image_transform_default_ini 8245 #endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */ 8246 8247 #ifdef PNG_READ_BACKGROUND_SUPPORTED 8248 /* png_set_background(png_structp, png_const_color_16p background_color, 8249 * int background_gamma_code, int need_expand, double background_gamma) 8250 * png_set_background_fixed(png_structp, png_const_color_16p background_color, 8251 * int background_gamma_code, int need_expand, 8252 * png_fixed_point background_gamma) 8253 * 8254 * This ignores the gamma (at present.) 8255 */ 8256 #define data ITDATA(background) 8257 static image_pixel data; 8258 8259 static void 8260 image_transform_png_set_background_set(const image_transform *this, 8261 transform_display *that, png_structp pp, png_infop pi) 8262 { 8263 png_byte colour_type, bit_depth; 8264 png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */ 8265 int expand; 8266 png_color_16 back; 8267 8268 /* We need a background colour, because we don't know exactly what transforms 8269 * have been set we have to supply the colour in the original file format and 8270 * so we need to know what that is! The background colour is stored in the 8271 * transform_display. 8272 */ 8273 R8(random_bytes); 8274 8275 /* Read the random value, for colour type 3 the background colour is actually 8276 * expressed as a 24bit rgb, not an index. 8277 */ 8278 colour_type = that->this.colour_type; 8279 if (colour_type == 3) 8280 { 8281 colour_type = PNG_COLOR_TYPE_RGB; 8282 bit_depth = 8; 8283 expand = 0; /* passing in an RGB not a pixel index */ 8284 } 8285 8286 else 8287 { 8288 if (that->this.has_tRNS) 8289 that->this.is_transparent = 1; 8290 8291 bit_depth = that->this.bit_depth; 8292 expand = 1; 8293 } 8294 8295 image_pixel_init(&data, random_bytes, colour_type, 8296 bit_depth, 0/*x*/, 0/*unused: palette*/, NULL/*format*/); 8297 8298 /* Extract the background colour from this image_pixel, but make sure the 8299 * unused fields of 'back' are garbage. 8300 */ 8301 R8(back); 8302 8303 if (colour_type & PNG_COLOR_MASK_COLOR) 8304 { 8305 back.red = (png_uint_16)data.red; 8306 back.green = (png_uint_16)data.green; 8307 back.blue = (png_uint_16)data.blue; 8308 } 8309 8310 else 8311 back.gray = (png_uint_16)data.red; 8312 8313 #ifdef PNG_FLOATING_POINT_SUPPORTED 8314 png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0); 8315 #else 8316 png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0); 8317 #endif 8318 8319 this->next->set(this->next, that, pp, pi); 8320 } 8321 8322 static void 8323 image_transform_png_set_background_mod(const image_transform *this, 8324 image_pixel *that, png_const_structp pp, 8325 const transform_display *display) 8326 { 8327 /* Check for tRNS first: */ 8328 if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE) 8329 image_pixel_add_alpha(that, &display->this, 1/*for background*/); 8330 8331 /* This is only necessary if the alpha value is less than 1. */ 8332 if (that->alphaf < 1) 8333 { 8334 /* Now we do the background calculation without any gamma correction. */ 8335 if (that->alphaf <= 0) 8336 { 8337 that->redf = data.redf; 8338 that->greenf = data.greenf; 8339 that->bluef = data.bluef; 8340 8341 that->rede = data.rede; 8342 that->greene = data.greene; 8343 that->bluee = data.bluee; 8344 8345 that->red_sBIT= data.red_sBIT; 8346 that->green_sBIT= data.green_sBIT; 8347 that->blue_sBIT= data.blue_sBIT; 8348 } 8349 8350 else /* 0 < alpha < 1 */ 8351 { 8352 double alf = 1 - that->alphaf; 8353 8354 that->redf = that->redf * that->alphaf + data.redf * alf; 8355 that->rede = that->rede * that->alphaf + data.rede * alf + 8356 DBL_EPSILON; 8357 that->greenf = that->greenf * that->alphaf + data.greenf * alf; 8358 that->greene = that->greene * that->alphaf + data.greene * alf + 8359 DBL_EPSILON; 8360 that->bluef = that->bluef * that->alphaf + data.bluef * alf; 8361 that->bluee = that->bluee * that->alphaf + data.bluee * alf + 8362 DBL_EPSILON; 8363 } 8364 8365 /* Remove the alpha type and set the alpha (not in that order.) */ 8366 that->alphaf = 1; 8367 that->alphae = 0; 8368 } 8369 8370 if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) 8371 that->colour_type = PNG_COLOR_TYPE_RGB; 8372 else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) 8373 that->colour_type = PNG_COLOR_TYPE_GRAY; 8374 /* PNG_COLOR_TYPE_PALETTE is not changed */ 8375 8376 this->next->mod(this->next, that, pp, display); 8377 } 8378 8379 #define image_transform_png_set_background_add image_transform_default_add 8380 8381 #undef data 8382 IT(background); 8383 #undef PT 8384 #define PT ITSTRUCT(background) 8385 #endif /* PNG_READ_BACKGROUND_SUPPORTED */ 8386 8387 /* png_set_quantize(png_structp, png_colorp palette, int num_palette, 8388 * int maximum_colors, png_const_uint_16p histogram, int full_quantize) 8389 * 8390 * Very difficult to validate this! 8391 */ 8392 /*NOTE: TBD NYI */ 8393 8394 /* The data layout transforms are handled by swapping our own channel data, 8395 * necessarily these need to happen at the end of the transform list because the 8396 * semantic of the channels changes after these are executed. Some of these, 8397 * like set_shift and set_packing, can't be done at present because they change 8398 * the layout of the data at the sub-sample level so sample() won't get the 8399 * right answer. 8400 */ 8401 /* png_set_invert_alpha */ 8402 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 8403 /* Invert the alpha channel 8404 * 8405 * png_set_invert_alpha(png_structrp png_ptr) 8406 */ 8407 static void 8408 image_transform_png_set_invert_alpha_set(const image_transform *this, 8409 transform_display *that, png_structp pp, png_infop pi) 8410 { 8411 png_set_invert_alpha(pp); 8412 this->next->set(this->next, that, pp, pi); 8413 } 8414 8415 static void 8416 image_transform_png_set_invert_alpha_mod(const image_transform *this, 8417 image_pixel *that, png_const_structp pp, 8418 const transform_display *display) 8419 { 8420 if (that->colour_type & 4) 8421 that->alpha_inverted = 1; 8422 8423 this->next->mod(this->next, that, pp, display); 8424 } 8425 8426 static int 8427 image_transform_png_set_invert_alpha_add(image_transform *this, 8428 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8429 { 8430 UNUSED(bit_depth) 8431 8432 this->next = *that; 8433 *that = this; 8434 8435 /* Only has an effect on pixels with alpha: */ 8436 return (colour_type & 4) != 0; 8437 } 8438 8439 IT(invert_alpha); 8440 #undef PT 8441 #define PT ITSTRUCT(invert_alpha) 8442 8443 #endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ 8444 8445 /* png_set_bgr */ 8446 #ifdef PNG_READ_BGR_SUPPORTED 8447 /* Swap R,G,B channels to order B,G,R. 8448 * 8449 * png_set_bgr(png_structrp png_ptr) 8450 * 8451 * This only has an effect on RGB and RGBA pixels. 8452 */ 8453 static void 8454 image_transform_png_set_bgr_set(const image_transform *this, 8455 transform_display *that, png_structp pp, png_infop pi) 8456 { 8457 png_set_bgr(pp); 8458 this->next->set(this->next, that, pp, pi); 8459 } 8460 8461 static void 8462 image_transform_png_set_bgr_mod(const image_transform *this, 8463 image_pixel *that, png_const_structp pp, 8464 const transform_display *display) 8465 { 8466 if (that->colour_type == PNG_COLOR_TYPE_RGB || 8467 that->colour_type == PNG_COLOR_TYPE_RGBA) 8468 that->swap_rgb = 1; 8469 8470 this->next->mod(this->next, that, pp, display); 8471 } 8472 8473 static int 8474 image_transform_png_set_bgr_add(image_transform *this, 8475 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8476 { 8477 UNUSED(bit_depth) 8478 8479 this->next = *that; 8480 *that = this; 8481 8482 return colour_type == PNG_COLOR_TYPE_RGB || 8483 colour_type == PNG_COLOR_TYPE_RGBA; 8484 } 8485 8486 IT(bgr); 8487 #undef PT 8488 #define PT ITSTRUCT(bgr) 8489 8490 #endif /* PNG_READ_BGR_SUPPORTED */ 8491 8492 /* png_set_swap_alpha */ 8493 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 8494 /* Put the alpha channel first. 8495 * 8496 * png_set_swap_alpha(png_structrp png_ptr) 8497 * 8498 * This only has an effect on GA and RGBA pixels. 8499 */ 8500 static void 8501 image_transform_png_set_swap_alpha_set(const image_transform *this, 8502 transform_display *that, png_structp pp, png_infop pi) 8503 { 8504 png_set_swap_alpha(pp); 8505 this->next->set(this->next, that, pp, pi); 8506 } 8507 8508 static void 8509 image_transform_png_set_swap_alpha_mod(const image_transform *this, 8510 image_pixel *that, png_const_structp pp, 8511 const transform_display *display) 8512 { 8513 if (that->colour_type == PNG_COLOR_TYPE_GA || 8514 that->colour_type == PNG_COLOR_TYPE_RGBA) 8515 that->alpha_first = 1; 8516 8517 this->next->mod(this->next, that, pp, display); 8518 } 8519 8520 static int 8521 image_transform_png_set_swap_alpha_add(image_transform *this, 8522 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8523 { 8524 UNUSED(bit_depth) 8525 8526 this->next = *that; 8527 *that = this; 8528 8529 return colour_type == PNG_COLOR_TYPE_GA || 8530 colour_type == PNG_COLOR_TYPE_RGBA; 8531 } 8532 8533 IT(swap_alpha); 8534 #undef PT 8535 #define PT ITSTRUCT(swap_alpha) 8536 8537 #endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */ 8538 8539 /* png_set_swap */ 8540 #ifdef PNG_READ_SWAP_SUPPORTED 8541 /* Byte swap 16-bit components. 8542 * 8543 * png_set_swap(png_structrp png_ptr) 8544 */ 8545 static void 8546 image_transform_png_set_swap_set(const image_transform *this, 8547 transform_display *that, png_structp pp, png_infop pi) 8548 { 8549 png_set_swap(pp); 8550 this->next->set(this->next, that, pp, pi); 8551 } 8552 8553 static void 8554 image_transform_png_set_swap_mod(const image_transform *this, 8555 image_pixel *that, png_const_structp pp, 8556 const transform_display *display) 8557 { 8558 if (that->bit_depth == 16) 8559 that->swap16 = 1; 8560 8561 this->next->mod(this->next, that, pp, display); 8562 } 8563 8564 static int 8565 image_transform_png_set_swap_add(image_transform *this, 8566 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8567 { 8568 UNUSED(colour_type) 8569 8570 this->next = *that; 8571 *that = this; 8572 8573 return bit_depth == 16; 8574 } 8575 8576 IT(swap); 8577 #undef PT 8578 #define PT ITSTRUCT(swap) 8579 8580 #endif /* PNG_READ_SWAP_SUPPORTED */ 8581 8582 #ifdef PNG_READ_FILLER_SUPPORTED 8583 /* Add a filler byte to 8-bit Gray or 24-bit RGB images. 8584 * 8585 * png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); 8586 * 8587 * Flags: 8588 * 8589 * PNG_FILLER_BEFORE 8590 * PNG_FILLER_AFTER 8591 */ 8592 #define data ITDATA(filler) 8593 static struct 8594 { 8595 png_uint_32 filler; 8596 int flags; 8597 } data; 8598 8599 static void 8600 image_transform_png_set_filler_set(const image_transform *this, 8601 transform_display *that, png_structp pp, png_infop pi) 8602 { 8603 /* Need a random choice for 'before' and 'after' as well as for the 8604 * filler. The 'filler' value has all 32 bits set, but only bit_depth 8605 * will be used. At this point we don't know bit_depth. 8606 */ 8607 data.filler = random_u32(); 8608 data.flags = random_choice(); 8609 8610 png_set_filler(pp, data.filler, data.flags); 8611 8612 /* The standard display handling stuff also needs to know that 8613 * there is a filler, so set that here. 8614 */ 8615 that->this.filler = 1; 8616 8617 this->next->set(this->next, that, pp, pi); 8618 } 8619 8620 static void 8621 image_transform_png_set_filler_mod(const image_transform *this, 8622 image_pixel *that, png_const_structp pp, 8623 const transform_display *display) 8624 { 8625 if (that->bit_depth >= 8 && 8626 (that->colour_type == PNG_COLOR_TYPE_RGB || 8627 that->colour_type == PNG_COLOR_TYPE_GRAY)) 8628 { 8629 const unsigned int max = (1U << that->bit_depth)-1; 8630 that->alpha = data.filler & max; 8631 that->alphaf = ((double)that->alpha) / max; 8632 that->alphae = 0; 8633 8634 /* The filler has been stored in the alpha channel, we must record 8635 * that this has been done for the checking later on, the color 8636 * type is faked to have an alpha channel, but libpng won't report 8637 * this; the app has to know the extra channel is there and this 8638 * was recording in standard_display::filler above. 8639 */ 8640 that->colour_type |= 4; /* alpha added */ 8641 that->alpha_first = data.flags == PNG_FILLER_BEFORE; 8642 } 8643 8644 this->next->mod(this->next, that, pp, display); 8645 } 8646 8647 static int 8648 image_transform_png_set_filler_add(image_transform *this, 8649 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8650 { 8651 this->next = *that; 8652 *that = this; 8653 8654 return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB || 8655 colour_type == PNG_COLOR_TYPE_GRAY); 8656 } 8657 8658 #undef data 8659 IT(filler); 8660 #undef PT 8661 #define PT ITSTRUCT(filler) 8662 8663 /* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */ 8664 /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ 8665 #define data ITDATA(add_alpha) 8666 static struct 8667 { 8668 png_uint_32 filler; 8669 int flags; 8670 } data; 8671 8672 static void 8673 image_transform_png_set_add_alpha_set(const image_transform *this, 8674 transform_display *that, png_structp pp, png_infop pi) 8675 { 8676 /* Need a random choice for 'before' and 'after' as well as for the 8677 * filler. The 'filler' value has all 32 bits set, but only bit_depth 8678 * will be used. At this point we don't know bit_depth. 8679 */ 8680 data.filler = random_u32(); 8681 data.flags = random_choice(); 8682 8683 png_set_add_alpha(pp, data.filler, data.flags); 8684 this->next->set(this->next, that, pp, pi); 8685 } 8686 8687 static void 8688 image_transform_png_set_add_alpha_mod(const image_transform *this, 8689 image_pixel *that, png_const_structp pp, 8690 const transform_display *display) 8691 { 8692 if (that->bit_depth >= 8 && 8693 (that->colour_type == PNG_COLOR_TYPE_RGB || 8694 that->colour_type == PNG_COLOR_TYPE_GRAY)) 8695 { 8696 const unsigned int max = (1U << that->bit_depth)-1; 8697 that->alpha = data.filler & max; 8698 that->alphaf = ((double)that->alpha) / max; 8699 that->alphae = 0; 8700 8701 that->colour_type |= 4; /* alpha added */ 8702 that->alpha_first = data.flags == PNG_FILLER_BEFORE; 8703 } 8704 8705 this->next->mod(this->next, that, pp, display); 8706 } 8707 8708 static int 8709 image_transform_png_set_add_alpha_add(image_transform *this, 8710 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8711 { 8712 this->next = *that; 8713 *that = this; 8714 8715 return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB || 8716 colour_type == PNG_COLOR_TYPE_GRAY); 8717 } 8718 8719 #undef data 8720 IT(add_alpha); 8721 #undef PT 8722 #define PT ITSTRUCT(add_alpha) 8723 8724 #endif /* PNG_READ_FILLER_SUPPORTED */ 8725 8726 /* png_set_packing */ 8727 #ifdef PNG_READ_PACK_SUPPORTED 8728 /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. 8729 * 8730 * png_set_packing(png_structrp png_ptr) 8731 * 8732 * This should only affect grayscale and palette images with less than 8 bits 8733 * per pixel. 8734 */ 8735 static void 8736 image_transform_png_set_packing_set(const image_transform *this, 8737 transform_display *that, png_structp pp, png_infop pi) 8738 { 8739 png_set_packing(pp); 8740 that->unpacked = 1; 8741 this->next->set(this->next, that, pp, pi); 8742 } 8743 8744 static void 8745 image_transform_png_set_packing_mod(const image_transform *this, 8746 image_pixel *that, png_const_structp pp, 8747 const transform_display *display) 8748 { 8749 /* The general expand case depends on what the colour type is, 8750 * low bit-depth pixel values are unpacked into bytes without 8751 * scaling, so sample_depth is not changed. 8752 */ 8753 if (that->bit_depth < 8) /* grayscale or palette */ 8754 that->bit_depth = 8; 8755 8756 this->next->mod(this->next, that, pp, display); 8757 } 8758 8759 static int 8760 image_transform_png_set_packing_add(image_transform *this, 8761 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8762 { 8763 UNUSED(colour_type) 8764 8765 this->next = *that; 8766 *that = this; 8767 8768 /* Nothing should happen unless the bit depth is less than 8: */ 8769 return bit_depth < 8; 8770 } 8771 8772 IT(packing); 8773 #undef PT 8774 #define PT ITSTRUCT(packing) 8775 8776 #endif /* PNG_READ_PACK_SUPPORTED */ 8777 8778 /* png_set_packswap */ 8779 #ifdef PNG_READ_PACKSWAP_SUPPORTED 8780 /* Swap pixels packed into bytes; reverses the order on screen so that 8781 * the high order bits correspond to the rightmost pixels. 8782 * 8783 * png_set_packswap(png_structrp png_ptr) 8784 */ 8785 static void 8786 image_transform_png_set_packswap_set(const image_transform *this, 8787 transform_display *that, png_structp pp, png_infop pi) 8788 { 8789 png_set_packswap(pp); 8790 that->this.littleendian = 1; 8791 this->next->set(this->next, that, pp, pi); 8792 } 8793 8794 static void 8795 image_transform_png_set_packswap_mod(const image_transform *this, 8796 image_pixel *that, png_const_structp pp, 8797 const transform_display *display) 8798 { 8799 if (that->bit_depth < 8) 8800 that->littleendian = 1; 8801 8802 this->next->mod(this->next, that, pp, display); 8803 } 8804 8805 static int 8806 image_transform_png_set_packswap_add(image_transform *this, 8807 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8808 { 8809 UNUSED(colour_type) 8810 8811 this->next = *that; 8812 *that = this; 8813 8814 return bit_depth < 8; 8815 } 8816 8817 IT(packswap); 8818 #undef PT 8819 #define PT ITSTRUCT(packswap) 8820 8821 #endif /* PNG_READ_PACKSWAP_SUPPORTED */ 8822 8823 8824 /* png_set_invert_mono */ 8825 #ifdef PNG_READ_INVERT_MONO_SUPPORTED 8826 /* Invert the gray channel 8827 * 8828 * png_set_invert_mono(png_structrp png_ptr) 8829 */ 8830 static void 8831 image_transform_png_set_invert_mono_set(const image_transform *this, 8832 transform_display *that, png_structp pp, png_infop pi) 8833 { 8834 png_set_invert_mono(pp); 8835 this->next->set(this->next, that, pp, pi); 8836 } 8837 8838 static void 8839 image_transform_png_set_invert_mono_mod(const image_transform *this, 8840 image_pixel *that, png_const_structp pp, 8841 const transform_display *display) 8842 { 8843 if (that->colour_type & 4) 8844 that->mono_inverted = 1; 8845 8846 this->next->mod(this->next, that, pp, display); 8847 } 8848 8849 static int 8850 image_transform_png_set_invert_mono_add(image_transform *this, 8851 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8852 { 8853 UNUSED(bit_depth) 8854 8855 this->next = *that; 8856 *that = this; 8857 8858 /* Only has an effect on pixels with no colour: */ 8859 return (colour_type & 2) == 0; 8860 } 8861 8862 IT(invert_mono); 8863 #undef PT 8864 #define PT ITSTRUCT(invert_mono) 8865 8866 #endif /* PNG_READ_INVERT_MONO_SUPPORTED */ 8867 8868 #ifdef PNG_READ_SHIFT_SUPPORTED 8869 /* png_set_shift(png_structp, png_const_color_8p true_bits) 8870 * 8871 * The output pixels will be shifted by the given true_bits 8872 * values. 8873 */ 8874 #define data ITDATA(shift) 8875 static png_color_8 data; 8876 8877 static void 8878 image_transform_png_set_shift_set(const image_transform *this, 8879 transform_display *that, png_structp pp, png_infop pi) 8880 { 8881 /* Get a random set of shifts. The shifts need to do something 8882 * to test the transform, so they are limited to the bit depth 8883 * of the input image. Notice that in the following the 'gray' 8884 * field is randomized independently. This acts as a check that 8885 * libpng does use the correct field. 8886 */ 8887 const unsigned int depth = that->this.bit_depth; 8888 8889 data.red = (png_byte)/*SAFE*/(random_mod(depth)+1); 8890 data.green = (png_byte)/*SAFE*/(random_mod(depth)+1); 8891 data.blue = (png_byte)/*SAFE*/(random_mod(depth)+1); 8892 data.gray = (png_byte)/*SAFE*/(random_mod(depth)+1); 8893 data.alpha = (png_byte)/*SAFE*/(random_mod(depth)+1); 8894 8895 png_set_shift(pp, &data); 8896 this->next->set(this->next, that, pp, pi); 8897 } 8898 8899 static void 8900 image_transform_png_set_shift_mod(const image_transform *this, 8901 image_pixel *that, png_const_structp pp, 8902 const transform_display *display) 8903 { 8904 /* Copy the correct values into the sBIT fields, libpng does not do 8905 * anything to palette data: 8906 */ 8907 if (that->colour_type != PNG_COLOR_TYPE_PALETTE) 8908 { 8909 that->sig_bits = 1; 8910 8911 /* The sBIT fields are reset to the values previously sent to 8912 * png_set_shift according to the colour type. 8913 * does. 8914 */ 8915 if (that->colour_type & 2) /* RGB channels */ 8916 { 8917 that->red_sBIT = data.red; 8918 that->green_sBIT = data.green; 8919 that->blue_sBIT = data.blue; 8920 } 8921 8922 else /* One grey channel */ 8923 that->red_sBIT = that->green_sBIT = that->blue_sBIT = data.gray; 8924 8925 that->alpha_sBIT = data.alpha; 8926 } 8927 8928 this->next->mod(this->next, that, pp, display); 8929 } 8930 8931 static int 8932 image_transform_png_set_shift_add(image_transform *this, 8933 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8934 { 8935 UNUSED(bit_depth) 8936 8937 this->next = *that; 8938 *that = this; 8939 8940 return colour_type != PNG_COLOR_TYPE_PALETTE; 8941 } 8942 8943 IT(shift); 8944 #undef PT 8945 #define PT ITSTRUCT(shift) 8946 8947 #endif /* PNG_READ_SHIFT_SUPPORTED */ 8948 8949 #ifdef THIS_IS_THE_PROFORMA 8950 static void 8951 image_transform_png_set_@_set(const image_transform *this, 8952 transform_display *that, png_structp pp, png_infop pi) 8953 { 8954 png_set_@(pp); 8955 this->next->set(this->next, that, pp, pi); 8956 } 8957 8958 static void 8959 image_transform_png_set_@_mod(const image_transform *this, 8960 image_pixel *that, png_const_structp pp, 8961 const transform_display *display) 8962 { 8963 this->next->mod(this->next, that, pp, display); 8964 } 8965 8966 static int 8967 image_transform_png_set_@_add(image_transform *this, 8968 const image_transform **that, png_byte colour_type, png_byte bit_depth) 8969 { 8970 this->next = *that; 8971 *that = this; 8972 8973 return 1; 8974 } 8975 8976 IT(@); 8977 #endif 8978 8979 8980 /* This may just be 'end' if all the transforms are disabled! */ 8981 static image_transform *const image_transform_first = &PT; 8982 8983 static void 8984 transform_enable(const char *name) 8985 { 8986 /* Everything starts out enabled, so if we see an 'enable' disabled 8987 * everything else the first time round. 8988 */ 8989 static int all_disabled = 0; 8990 int found_it = 0; 8991 image_transform *list = image_transform_first; 8992 8993 while (list != &image_transform_end) 8994 { 8995 if (strcmp(list->name, name) == 0) 8996 { 8997 list->enable = 1; 8998 found_it = 1; 8999 } 9000 else if (!all_disabled) 9001 list->enable = 0; 9002 9003 list = list->list; 9004 } 9005 9006 all_disabled = 1; 9007 9008 if (!found_it) 9009 { 9010 fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n", 9011 name); 9012 exit(99); 9013 } 9014 } 9015 9016 static void 9017 transform_disable(const char *name) 9018 { 9019 image_transform *list = image_transform_first; 9020 9021 while (list != &image_transform_end) 9022 { 9023 if (strcmp(list->name, name) == 0) 9024 { 9025 list->enable = 0; 9026 return; 9027 } 9028 9029 list = list->list; 9030 } 9031 9032 fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n", 9033 name); 9034 exit(99); 9035 } 9036 9037 static void 9038 image_transform_reset_count(void) 9039 { 9040 image_transform *next = image_transform_first; 9041 int count = 0; 9042 9043 while (next != &image_transform_end) 9044 { 9045 next->local_use = 0; 9046 next->next = 0; 9047 next = next->list; 9048 ++count; 9049 } 9050 9051 /* This can only happen if we every have more than 32 transforms (excluding 9052 * the end) in the list. 9053 */ 9054 if (count > 32) abort(); 9055 } 9056 9057 static int 9058 image_transform_test_counter(png_uint_32 counter, unsigned int max) 9059 { 9060 /* Test the list to see if there is any point contining, given a current 9061 * counter and a 'max' value. 9062 */ 9063 image_transform *next = image_transform_first; 9064 9065 while (next != &image_transform_end) 9066 { 9067 /* For max 0 or 1 continue until the counter overflows: */ 9068 counter >>= 1; 9069 9070 /* Continue if any entry hasn't reacked the max. */ 9071 if (max > 1 && next->local_use < max) 9072 return 1; 9073 next = next->list; 9074 } 9075 9076 return max <= 1 && counter == 0; 9077 } 9078 9079 static png_uint_32 9080 image_transform_add(const image_transform **this, unsigned int max, 9081 png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos, 9082 png_byte colour_type, png_byte bit_depth) 9083 { 9084 for (;;) /* until we manage to add something */ 9085 { 9086 png_uint_32 mask; 9087 image_transform *list; 9088 9089 /* Find the next counter value, if the counter is zero this is the start 9090 * of the list. This routine always returns the current counter (not the 9091 * next) so it returns 0 at the end and expects 0 at the beginning. 9092 */ 9093 if (counter == 0) /* first time */ 9094 { 9095 image_transform_reset_count(); 9096 if (max <= 1) 9097 counter = 1; 9098 else 9099 counter = random_32(); 9100 } 9101 else /* advance the counter */ 9102 { 9103 switch (max) 9104 { 9105 case 0: ++counter; break; 9106 case 1: counter <<= 1; break; 9107 default: counter = random_32(); break; 9108 } 9109 } 9110 9111 /* Now add all these items, if possible */ 9112 *this = &image_transform_end; 9113 list = image_transform_first; 9114 mask = 1; 9115 9116 /* Go through the whole list adding anything that the counter selects: */ 9117 while (list != &image_transform_end) 9118 { 9119 if ((counter & mask) != 0 && list->enable && 9120 (max == 0 || list->local_use < max)) 9121 { 9122 /* Candidate to add: */ 9123 if (list->add(list, this, colour_type, bit_depth) || max == 0) 9124 { 9125 /* Added, so add to the name too. */ 9126 *pos = safecat(name, sizeof_name, *pos, " +"); 9127 *pos = safecat(name, sizeof_name, *pos, list->name); 9128 } 9129 9130 else 9131 { 9132 /* Not useful and max>0, so remove it from *this: */ 9133 *this = list->next; 9134 list->next = 0; 9135 9136 /* And, since we know it isn't useful, stop it being added again 9137 * in this run: 9138 */ 9139 list->local_use = max; 9140 } 9141 } 9142 9143 mask <<= 1; 9144 list = list->list; 9145 } 9146 9147 /* Now if anything was added we have something to do. */ 9148 if (*this != &image_transform_end) 9149 return counter; 9150 9151 /* Nothing added, but was there anything in there to add? */ 9152 if (!image_transform_test_counter(counter, max)) 9153 return 0; 9154 } 9155 } 9156 9157 static void 9158 perform_transform_test(png_modifier *pm) 9159 { 9160 png_byte colour_type = 0; 9161 png_byte bit_depth = 0; 9162 unsigned int palette_number = 0; 9163 9164 while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg, 9165 pm->test_tRNS)) 9166 { 9167 png_uint_32 counter = 0; 9168 size_t base_pos; 9169 char name[64]; 9170 9171 base_pos = safecat(name, sizeof name, 0, "transform:"); 9172 9173 for (;;) 9174 { 9175 size_t pos = base_pos; 9176 const image_transform *list = 0; 9177 9178 /* 'max' is currently hardwired to '1'; this should be settable on the 9179 * command line. 9180 */ 9181 counter = image_transform_add(&list, 1/*max*/, counter, 9182 name, sizeof name, &pos, colour_type, bit_depth); 9183 9184 if (counter == 0) 9185 break; 9186 9187 /* The command line can change this to checking interlaced images. */ 9188 do 9189 { 9190 pm->repeat = 0; 9191 transform_test(pm, FILEID(colour_type, bit_depth, palette_number, 9192 pm->interlace_type, 0, 0, 0), list, name); 9193 9194 if (fail(pm)) 9195 return; 9196 } 9197 while (pm->repeat); 9198 } 9199 } 9200 } 9201 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 9202 9203 /********************************* GAMMA TESTS ********************************/ 9204 #ifdef PNG_READ_GAMMA_SUPPORTED 9205 /* Reader callbacks and implementations, where they differ from the standard 9206 * ones. 9207 */ 9208 typedef struct gamma_display 9209 { 9210 standard_display this; 9211 9212 /* Parameters */ 9213 png_modifier* pm; 9214 double file_gamma; 9215 double screen_gamma; 9216 double background_gamma; 9217 png_byte sbit; 9218 int threshold_test; 9219 int use_input_precision; 9220 int scale16; 9221 int expand16; 9222 int do_background; 9223 png_color_16 background_color; 9224 9225 /* Local variables */ 9226 double maxerrout; 9227 double maxerrpc; 9228 double maxerrabs; 9229 } gamma_display; 9230 9231 #define ALPHA_MODE_OFFSET 4 9232 9233 static void 9234 gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id, 9235 double file_gamma, double screen_gamma, png_byte sbit, int threshold_test, 9236 int use_input_precision, int scale16, int expand16, 9237 int do_background, const png_color_16 *pointer_to_the_background_color, 9238 double background_gamma) 9239 { 9240 /* Standard fields */ 9241 standard_display_init(&dp->this, &pm->this, id, do_read_interlace, 9242 pm->use_update_info); 9243 9244 /* Parameter fields */ 9245 dp->pm = pm; 9246 dp->file_gamma = file_gamma; 9247 dp->screen_gamma = screen_gamma; 9248 dp->background_gamma = background_gamma; 9249 dp->sbit = sbit; 9250 dp->threshold_test = threshold_test; 9251 dp->use_input_precision = use_input_precision; 9252 dp->scale16 = scale16; 9253 dp->expand16 = expand16; 9254 dp->do_background = do_background; 9255 if (do_background && pointer_to_the_background_color != 0) 9256 dp->background_color = *pointer_to_the_background_color; 9257 else 9258 memset(&dp->background_color, 0, sizeof dp->background_color); 9259 9260 /* Local variable fields */ 9261 dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0; 9262 } 9263 9264 static void 9265 gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi) 9266 { 9267 /* Reuse the standard stuff as appropriate. */ 9268 standard_info_part1(&dp->this, pp, pi); 9269 9270 /* If requested strip 16 to 8 bits - this is handled automagically below 9271 * because the output bit depth is read from the library. Note that there 9272 * are interactions with sBIT but, internally, libpng makes sbit at most 9273 * PNG_MAX_GAMMA_8 prior to 1.7 when doing the following. 9274 */ 9275 if (dp->scale16) 9276 # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 9277 png_set_scale_16(pp); 9278 # else 9279 /* The following works both in 1.5.4 and earlier versions: */ 9280 # ifdef PNG_READ_16_TO_8_SUPPORTED 9281 png_set_strip_16(pp); 9282 # else 9283 png_error(pp, "scale16 (16 to 8 bit conversion) not supported"); 9284 # endif 9285 # endif 9286 9287 if (dp->expand16) 9288 # ifdef PNG_READ_EXPAND_16_SUPPORTED 9289 png_set_expand_16(pp); 9290 # else 9291 png_error(pp, "expand16 (8 to 16 bit conversion) not supported"); 9292 # endif 9293 9294 if (dp->do_background >= ALPHA_MODE_OFFSET) 9295 { 9296 # ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9297 { 9298 /* This tests the alpha mode handling, if supported. */ 9299 int mode = dp->do_background - ALPHA_MODE_OFFSET; 9300 9301 /* The gamma value is the output gamma, and is in the standard, 9302 * non-inverted, represenation. It provides a default for the PNG file 9303 * gamma, but since the file has a gAMA chunk this does not matter. 9304 */ 9305 const double sg = dp->screen_gamma; 9306 # ifndef PNG_FLOATING_POINT_SUPPORTED 9307 const png_fixed_point g = fix(sg); 9308 # endif 9309 9310 # ifdef PNG_FLOATING_POINT_SUPPORTED 9311 png_set_alpha_mode(pp, mode, sg); 9312 # else 9313 png_set_alpha_mode_fixed(pp, mode, g); 9314 # endif 9315 9316 /* However, for the standard Porter-Duff algorithm the output defaults 9317 * to be linear, so if the test requires non-linear output it must be 9318 * corrected here. 9319 */ 9320 if (mode == PNG_ALPHA_STANDARD && sg != 1) 9321 { 9322 # ifdef PNG_FLOATING_POINT_SUPPORTED 9323 png_set_gamma(pp, sg, dp->file_gamma); 9324 # else 9325 png_fixed_point f = fix(dp->file_gamma); 9326 png_set_gamma_fixed(pp, g, f); 9327 # endif 9328 } 9329 } 9330 # else 9331 png_error(pp, "alpha mode handling not supported"); 9332 # endif 9333 } 9334 9335 else 9336 { 9337 /* Set up gamma processing. */ 9338 # ifdef PNG_FLOATING_POINT_SUPPORTED 9339 png_set_gamma(pp, dp->screen_gamma, dp->file_gamma); 9340 # else 9341 { 9342 png_fixed_point s = fix(dp->screen_gamma); 9343 png_fixed_point f = fix(dp->file_gamma); 9344 png_set_gamma_fixed(pp, s, f); 9345 } 9346 # endif 9347 9348 if (dp->do_background) 9349 { 9350 # ifdef PNG_READ_BACKGROUND_SUPPORTED 9351 /* NOTE: this assumes the caller provided the correct background gamma! 9352 */ 9353 const double bg = dp->background_gamma; 9354 # ifndef PNG_FLOATING_POINT_SUPPORTED 9355 const png_fixed_point g = fix(bg); 9356 # endif 9357 9358 # ifdef PNG_FLOATING_POINT_SUPPORTED 9359 png_set_background(pp, &dp->background_color, dp->do_background, 9360 0/*need_expand*/, bg); 9361 # else 9362 png_set_background_fixed(pp, &dp->background_color, 9363 dp->do_background, 0/*need_expand*/, g); 9364 # endif 9365 # else 9366 png_error(pp, "png_set_background not supported"); 9367 # endif 9368 } 9369 } 9370 9371 { 9372 int i = dp->this.use_update_info; 9373 /* Always do one call, even if use_update_info is 0. */ 9374 do 9375 png_read_update_info(pp, pi); 9376 while (--i > 0); 9377 } 9378 9379 /* Now we may get a different cbRow: */ 9380 standard_info_part2(&dp->this, pp, pi, 1 /*images*/); 9381 } 9382 9383 static void PNGCBAPI 9384 gamma_info(png_structp pp, png_infop pi) 9385 { 9386 gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp, 9387 pi); 9388 } 9389 9390 /* Validate a single component value - the routine gets the input and output 9391 * sample values as unscaled PNG component values along with a cache of all the 9392 * information required to validate the values. 9393 */ 9394 typedef struct validate_info 9395 { 9396 png_const_structp pp; 9397 gamma_display *dp; 9398 png_byte sbit; 9399 int use_input_precision; 9400 int do_background; 9401 int scale16; 9402 unsigned int sbit_max; 9403 unsigned int isbit_shift; 9404 unsigned int outmax; 9405 9406 double gamma_correction; /* Overall correction required. */ 9407 double file_inverse; /* Inverse of file gamma. */ 9408 double screen_gamma; 9409 double screen_inverse; /* Inverse of screen gamma. */ 9410 9411 double background_red; /* Linear background value, red or gray. */ 9412 double background_green; 9413 double background_blue; 9414 9415 double maxabs; 9416 double maxpc; 9417 double maxcalc; 9418 double maxout; 9419 double maxout_total; /* Total including quantization error */ 9420 double outlog; 9421 int outquant; 9422 } 9423 validate_info; 9424 9425 static void 9426 init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp, 9427 int in_depth, int out_depth) 9428 { 9429 const unsigned int outmax = (1U<<out_depth)-1; 9430 9431 vi->pp = pp; 9432 vi->dp = dp; 9433 9434 if (dp->sbit > 0 && dp->sbit < in_depth) 9435 { 9436 vi->sbit = dp->sbit; 9437 vi->isbit_shift = in_depth - dp->sbit; 9438 } 9439 9440 else 9441 { 9442 vi->sbit = (png_byte)in_depth; 9443 vi->isbit_shift = 0; 9444 } 9445 9446 vi->sbit_max = (1U << vi->sbit)-1; 9447 9448 /* This mimics the libpng threshold test, '0' is used to prevent gamma 9449 * correction in the validation test. 9450 */ 9451 vi->screen_gamma = dp->screen_gamma; 9452 if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD) 9453 vi->screen_gamma = vi->screen_inverse = 0; 9454 else 9455 vi->screen_inverse = 1/vi->screen_gamma; 9456 9457 vi->use_input_precision = dp->use_input_precision; 9458 vi->outmax = outmax; 9459 vi->maxabs = abserr(dp->pm, in_depth, out_depth); 9460 vi->maxpc = pcerr(dp->pm, in_depth, out_depth); 9461 vi->maxcalc = calcerr(dp->pm, in_depth, out_depth); 9462 vi->maxout = outerr(dp->pm, in_depth, out_depth); 9463 vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth); 9464 vi->maxout_total = vi->maxout + vi->outquant * .5; 9465 vi->outlog = outlog(dp->pm, in_depth, out_depth); 9466 9467 if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 || 9468 (dp->this.colour_type == 3 && dp->this.is_transparent) || 9469 ((dp->this.colour_type == 0 || dp->this.colour_type == 2) && 9470 dp->this.has_tRNS)) 9471 { 9472 vi->do_background = dp->do_background; 9473 9474 if (vi->do_background != 0) 9475 { 9476 const double bg_inverse = 1/dp->background_gamma; 9477 double r, g, b; 9478 9479 /* Caller must at least put the gray value into the red channel */ 9480 r = dp->background_color.red; r /= outmax; 9481 g = dp->background_color.green; g /= outmax; 9482 b = dp->background_color.blue; b /= outmax; 9483 9484 # if 0 9485 /* libpng doesn't do this optimization, if we do pngvalid will fail. 9486 */ 9487 if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD) 9488 # endif 9489 { 9490 r = pow(r, bg_inverse); 9491 g = pow(g, bg_inverse); 9492 b = pow(b, bg_inverse); 9493 } 9494 9495 vi->background_red = r; 9496 vi->background_green = g; 9497 vi->background_blue = b; 9498 } 9499 } 9500 else /* Do not expect any background processing */ 9501 vi->do_background = 0; 9502 9503 if (vi->do_background == 0) 9504 vi->background_red = vi->background_green = vi->background_blue = 0; 9505 9506 vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma); 9507 if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD) 9508 vi->gamma_correction = 0; 9509 9510 vi->file_inverse = 1/dp->file_gamma; 9511 if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD) 9512 vi->file_inverse = 0; 9513 9514 vi->scale16 = dp->scale16; 9515 } 9516 9517 /* This function handles composition of a single non-alpha component. The 9518 * argument is the input sample value, in the range 0..1, and the alpha value. 9519 * The result is the composed, linear, input sample. If alpha is less than zero 9520 * this is the alpha component and the function should not be called! 9521 */ 9522 static double 9523 gamma_component_compose(int do_background, double input_sample, double alpha, 9524 double background, int *compose) 9525 { 9526 switch (do_background) 9527 { 9528 #ifdef PNG_READ_BACKGROUND_SUPPORTED 9529 case PNG_BACKGROUND_GAMMA_SCREEN: 9530 case PNG_BACKGROUND_GAMMA_FILE: 9531 case PNG_BACKGROUND_GAMMA_UNIQUE: 9532 /* Standard PNG background processing. */ 9533 if (alpha < 1) 9534 { 9535 if (alpha > 0) 9536 { 9537 input_sample = input_sample * alpha + background * (1-alpha); 9538 if (compose != NULL) 9539 *compose = 1; 9540 } 9541 9542 else 9543 input_sample = background; 9544 } 9545 break; 9546 #endif 9547 9548 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9549 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: 9550 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: 9551 /* The components are premultiplied in either case and the output is 9552 * gamma encoded (to get standard Porter-Duff we expect the output 9553 * gamma to be set to 1.0!) 9554 */ 9555 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: 9556 /* The optimization is that the partial-alpha entries are linear 9557 * while the opaque pixels are gamma encoded, but this only affects the 9558 * output encoding. 9559 */ 9560 if (alpha < 1) 9561 { 9562 if (alpha > 0) 9563 { 9564 input_sample *= alpha; 9565 if (compose != NULL) 9566 *compose = 1; 9567 } 9568 9569 else 9570 input_sample = 0; 9571 } 9572 break; 9573 #endif 9574 9575 default: 9576 /* Standard cases where no compositing is done (so the component 9577 * value is already correct.) 9578 */ 9579 UNUSED(alpha) 9580 UNUSED(background) 9581 UNUSED(compose) 9582 break; 9583 } 9584 9585 return input_sample; 9586 } 9587 9588 /* This API returns the encoded *input* component, in the range 0..1 */ 9589 static double 9590 gamma_component_validate(const char *name, const validate_info *vi, 9591 const unsigned int id, const unsigned int od, 9592 const double alpha /* <0 for the alpha channel itself */, 9593 const double background /* component background value */) 9594 { 9595 const unsigned int isbit = id >> vi->isbit_shift; 9596 const unsigned int sbit_max = vi->sbit_max; 9597 const unsigned int outmax = vi->outmax; 9598 const int do_background = vi->do_background; 9599 9600 double i; 9601 9602 /* First check on the 'perfect' result obtained from the digitized input 9603 * value, id, and compare this against the actual digitized result, 'od'. 9604 * 'i' is the input result in the range 0..1: 9605 */ 9606 i = isbit; i /= sbit_max; 9607 9608 /* Check for the fast route: if we don't do any background composition or if 9609 * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then 9610 * just use the gamma_correction field to correct to the final output gamma. 9611 */ 9612 if (alpha == 1 /* opaque pixel component */ || !do_background 9613 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9614 || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG 9615 #endif 9616 || (alpha < 0 /* alpha channel */ 9617 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9618 && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN 9619 #endif 9620 )) 9621 { 9622 /* Then get the gamma corrected version of 'i' and compare to 'od', any 9623 * error less than .5 is insignificant - just quantization of the output 9624 * value to the nearest digital value (nevertheless the error is still 9625 * recorded - it's interesting ;-) 9626 */ 9627 double encoded_sample = i; 9628 double encoded_error; 9629 9630 /* alpha less than 0 indicates the alpha channel, which is always linear 9631 */ 9632 if (alpha >= 0 && vi->gamma_correction > 0) 9633 encoded_sample = pow(encoded_sample, vi->gamma_correction); 9634 encoded_sample *= outmax; 9635 9636 encoded_error = fabs(od-encoded_sample); 9637 9638 if (encoded_error > vi->dp->maxerrout) 9639 vi->dp->maxerrout = encoded_error; 9640 9641 if (encoded_error < vi->maxout_total && encoded_error < vi->outlog) 9642 return i; 9643 } 9644 9645 /* The slow route - attempt to do linear calculations. */ 9646 /* There may be an error, or background processing is required, so calculate 9647 * the actual sample values - unencoded light intensity values. Note that in 9648 * practice these are not completely unencoded because they include a 9649 * 'viewing correction' to decrease or (normally) increase the perceptual 9650 * contrast of the image. There's nothing we can do about this - we don't 9651 * know what it is - so assume the unencoded value is perceptually linear. 9652 */ 9653 { 9654 double input_sample = i; /* In range 0..1 */ 9655 double output, error, encoded_sample, encoded_error; 9656 double es_lo, es_hi; 9657 int compose = 0; /* Set to one if composition done */ 9658 int output_is_encoded; /* Set if encoded to screen gamma */ 9659 int log_max_error = 1; /* Check maximum error values */ 9660 png_const_charp pass = 0; /* Reason test passes (or 0 for fail) */ 9661 9662 /* Convert to linear light (with the above caveat.) The alpha channel is 9663 * already linear. 9664 */ 9665 if (alpha >= 0) 9666 { 9667 int tcompose; 9668 9669 if (vi->file_inverse > 0) 9670 input_sample = pow(input_sample, vi->file_inverse); 9671 9672 /* Handle the compose processing: */ 9673 tcompose = 0; 9674 input_sample = gamma_component_compose(do_background, input_sample, 9675 alpha, background, &tcompose); 9676 9677 if (tcompose) 9678 compose = 1; 9679 } 9680 9681 /* And similarly for the output value, but we need to check the background 9682 * handling to linearize it correctly. 9683 */ 9684 output = od; 9685 output /= outmax; 9686 9687 output_is_encoded = vi->screen_gamma > 0; 9688 9689 if (alpha < 0) /* The alpha channel */ 9690 { 9691 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9692 if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN) 9693 #endif 9694 { 9695 /* In all other cases the output alpha channel is linear already, 9696 * don't log errors here, they are much larger in linear data. 9697 */ 9698 output_is_encoded = 0; 9699 log_max_error = 0; 9700 } 9701 } 9702 9703 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9704 else /* A component */ 9705 { 9706 if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED && 9707 alpha < 1) /* the optimized case - linear output */ 9708 { 9709 if (alpha > 0) log_max_error = 0; 9710 output_is_encoded = 0; 9711 } 9712 } 9713 #endif 9714 9715 if (output_is_encoded) 9716 output = pow(output, vi->screen_gamma); 9717 9718 /* Calculate (or recalculate) the encoded_sample value and repeat the 9719 * check above (unnecessary if we took the fast route, but harmless.) 9720 */ 9721 encoded_sample = input_sample; 9722 if (output_is_encoded) 9723 encoded_sample = pow(encoded_sample, vi->screen_inverse); 9724 encoded_sample *= outmax; 9725 9726 encoded_error = fabs(od-encoded_sample); 9727 9728 /* Don't log errors in the alpha channel, or the 'optimized' case, 9729 * neither are significant to the overall perception. 9730 */ 9731 if (log_max_error && encoded_error > vi->dp->maxerrout) 9732 vi->dp->maxerrout = encoded_error; 9733 9734 if (encoded_error < vi->maxout_total) 9735 { 9736 if (encoded_error < vi->outlog) 9737 return i; 9738 9739 /* Test passed but error is bigger than the log limit, record why the 9740 * test passed: 9741 */ 9742 pass = "less than maxout:\n"; 9743 } 9744 9745 /* i: the original input value in the range 0..1 9746 * 9747 * pngvalid calculations: 9748 * input_sample: linear result; i linearized and composed, range 0..1 9749 * encoded_sample: encoded result; input_sample scaled to ouput bit depth 9750 * 9751 * libpng calculations: 9752 * output: linear result; od scaled to 0..1 and linearized 9753 * od: encoded result from libpng 9754 */ 9755 9756 /* Now we have the numbers for real errors, both absolute values as as a 9757 * percentage of the correct value (output): 9758 */ 9759 error = fabs(input_sample-output); 9760 9761 if (log_max_error && error > vi->dp->maxerrabs) 9762 vi->dp->maxerrabs = error; 9763 9764 /* The following is an attempt to ignore the tendency of quantization to 9765 * dominate the percentage errors for lower result values: 9766 */ 9767 if (log_max_error && input_sample > .5) 9768 { 9769 double percentage_error = error/input_sample; 9770 if (percentage_error > vi->dp->maxerrpc) 9771 vi->dp->maxerrpc = percentage_error; 9772 } 9773 9774 /* Now calculate the digitization limits for 'encoded_sample' using the 9775 * 'max' values. Note that maxout is in the encoded space but maxpc and 9776 * maxabs are in linear light space. 9777 * 9778 * First find the maximum error in linear light space, range 0..1: 9779 */ 9780 { 9781 double tmp = input_sample * vi->maxpc; 9782 if (tmp < vi->maxabs) tmp = vi->maxabs; 9783 /* If 'compose' is true the composition was done in linear space using 9784 * integer arithmetic. This introduces an extra error of +/- 0.5 (at 9785 * least) in the integer space used. 'maxcalc' records this, taking 9786 * into account the possibility that even for 16 bit output 8 bit space 9787 * may have been used. 9788 */ 9789 if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc; 9790 9791 /* The 'maxout' value refers to the encoded result, to compare with 9792 * this encode input_sample adjusted by the maximum error (tmp) above. 9793 */ 9794 es_lo = encoded_sample - vi->maxout; 9795 9796 if (es_lo > 0 && input_sample-tmp > 0) 9797 { 9798 double low_value = input_sample-tmp; 9799 if (output_is_encoded) 9800 low_value = pow(low_value, vi->screen_inverse); 9801 low_value *= outmax; 9802 if (low_value < es_lo) es_lo = low_value; 9803 9804 /* Quantize this appropriately: */ 9805 es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant; 9806 } 9807 9808 else 9809 es_lo = 0; 9810 9811 es_hi = encoded_sample + vi->maxout; 9812 9813 if (es_hi < outmax && input_sample+tmp < 1) 9814 { 9815 double high_value = input_sample+tmp; 9816 if (output_is_encoded) 9817 high_value = pow(high_value, vi->screen_inverse); 9818 high_value *= outmax; 9819 if (high_value > es_hi) es_hi = high_value; 9820 9821 es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant; 9822 } 9823 9824 else 9825 es_hi = outmax; 9826 } 9827 9828 /* The primary test is that the final encoded value returned by the 9829 * library should be between the two limits (inclusive) that were 9830 * calculated above. 9831 */ 9832 if (od >= es_lo && od <= es_hi) 9833 { 9834 /* The value passes, but we may need to log the information anyway. */ 9835 if (encoded_error < vi->outlog) 9836 return i; 9837 9838 if (pass == 0) 9839 pass = "within digitization limits:\n"; 9840 } 9841 9842 { 9843 /* There has been an error in processing, or we need to log this 9844 * value. 9845 */ 9846 double is_lo, is_hi; 9847 9848 /* pass is set at this point if either of the tests above would have 9849 * passed. Don't do these additional tests here - just log the 9850 * original [es_lo..es_hi] values. 9851 */ 9852 if (pass == 0 && vi->use_input_precision && vi->dp->sbit) 9853 { 9854 /* Ok, something is wrong - this actually happens in current libpng 9855 * 16-to-8 processing. Assume that the input value (id, adjusted 9856 * for sbit) can be anywhere between value-.5 and value+.5 - quite a 9857 * large range if sbit is low. 9858 * 9859 * NOTE: at present because the libpng gamma table stuff has been 9860 * changed to use a rounding algorithm to correct errors in 8-bit 9861 * calculations the precise sbit calculation (a shift) has been 9862 * lost. This can result in up to a +/-1 error in the presence of 9863 * an sbit less than the bit depth. 9864 */ 9865 # if PNG_LIBPNG_VER < 10700 9866 # define SBIT_ERROR .5 9867 # else 9868 # define SBIT_ERROR 1. 9869 # endif 9870 double tmp = (isbit - SBIT_ERROR)/sbit_max; 9871 9872 if (tmp <= 0) 9873 tmp = 0; 9874 9875 else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) 9876 tmp = pow(tmp, vi->file_inverse); 9877 9878 tmp = gamma_component_compose(do_background, tmp, alpha, background, 9879 NULL); 9880 9881 if (output_is_encoded && tmp > 0 && tmp < 1) 9882 tmp = pow(tmp, vi->screen_inverse); 9883 9884 is_lo = ceil(outmax * tmp - vi->maxout_total); 9885 9886 if (is_lo < 0) 9887 is_lo = 0; 9888 9889 tmp = (isbit + SBIT_ERROR)/sbit_max; 9890 9891 if (tmp >= 1) 9892 tmp = 1; 9893 9894 else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) 9895 tmp = pow(tmp, vi->file_inverse); 9896 9897 tmp = gamma_component_compose(do_background, tmp, alpha, background, 9898 NULL); 9899 9900 if (output_is_encoded && tmp > 0 && tmp < 1) 9901 tmp = pow(tmp, vi->screen_inverse); 9902 9903 is_hi = floor(outmax * tmp + vi->maxout_total); 9904 9905 if (is_hi > outmax) 9906 is_hi = outmax; 9907 9908 if (!(od < is_lo || od > is_hi)) 9909 { 9910 if (encoded_error < vi->outlog) 9911 return i; 9912 9913 pass = "within input precision limits:\n"; 9914 } 9915 9916 /* One last chance. If this is an alpha channel and the 16to8 9917 * option has been used and 'inaccurate' scaling is used then the 9918 * bit reduction is obtained by simply using the top 8 bits of the 9919 * value. 9920 * 9921 * This is only done for older libpng versions when the 'inaccurate' 9922 * (chop) method of scaling was used. 9923 */ 9924 # ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED 9925 # if PNG_LIBPNG_VER < 10504 9926 /* This may be required for other components in the future, 9927 * but at present the presence of gamma correction effectively 9928 * prevents the errors in the component scaling (I don't quite 9929 * understand why, but since it's better this way I care not 9930 * to ask, JB 20110419.) 9931 */ 9932 if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 && 9933 vi->sbit + vi->isbit_shift == 16) 9934 { 9935 tmp = ((id >> 8) - .5)/255; 9936 9937 if (tmp > 0) 9938 { 9939 is_lo = ceil(outmax * tmp - vi->maxout_total); 9940 if (is_lo < 0) is_lo = 0; 9941 } 9942 9943 else 9944 is_lo = 0; 9945 9946 tmp = ((id >> 8) + .5)/255; 9947 9948 if (tmp < 1) 9949 { 9950 is_hi = floor(outmax * tmp + vi->maxout_total); 9951 if (is_hi > outmax) is_hi = outmax; 9952 } 9953 9954 else 9955 is_hi = outmax; 9956 9957 if (!(od < is_lo || od > is_hi)) 9958 { 9959 if (encoded_error < vi->outlog) 9960 return i; 9961 9962 pass = "within 8 bit limits:\n"; 9963 } 9964 } 9965 # endif 9966 # endif 9967 } 9968 else /* !use_input_precision */ 9969 is_lo = es_lo, is_hi = es_hi; 9970 9971 /* Attempt to output a meaningful error/warning message: the message 9972 * output depends on the background/composite operation being performed 9973 * because this changes what parameters were actually used above. 9974 */ 9975 { 9976 size_t pos = 0; 9977 /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal 9978 * places. Just use outmax to work out which. 9979 */ 9980 int precision = (outmax >= 1000 ? 6 : 3); 9981 int use_input=1, use_background=0, do_compose=0; 9982 char msg[256]; 9983 9984 if (pass != 0) 9985 pos = safecat(msg, sizeof msg, pos, "\n\t"); 9986 9987 /* Set up the various flags, the output_is_encoded flag above 9988 * is also used below. do_compose is just a double check. 9989 */ 9990 switch (do_background) 9991 { 9992 # ifdef PNG_READ_BACKGROUND_SUPPORTED 9993 case PNG_BACKGROUND_GAMMA_SCREEN: 9994 case PNG_BACKGROUND_GAMMA_FILE: 9995 case PNG_BACKGROUND_GAMMA_UNIQUE: 9996 use_background = (alpha >= 0 && alpha < 1); 9997 # endif 9998 # ifdef PNG_READ_ALPHA_MODE_SUPPORTED 9999 /* FALLTHROUGH */ 10000 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: 10001 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: 10002 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: 10003 # endif /* ALPHA_MODE_SUPPORTED */ 10004 do_compose = (alpha > 0 && alpha < 1); 10005 use_input = (alpha != 0); 10006 break; 10007 10008 default: 10009 break; 10010 } 10011 10012 /* Check the 'compose' flag */ 10013 if (compose != do_compose) 10014 png_error(vi->pp, "internal error (compose)"); 10015 10016 /* 'name' is the component name */ 10017 pos = safecat(msg, sizeof msg, pos, name); 10018 pos = safecat(msg, sizeof msg, pos, "("); 10019 pos = safecatn(msg, sizeof msg, pos, id); 10020 if (use_input || pass != 0/*logging*/) 10021 { 10022 if (isbit != id) 10023 { 10024 /* sBIT has reduced the precision of the input: */ 10025 pos = safecat(msg, sizeof msg, pos, ", sbit("); 10026 pos = safecatn(msg, sizeof msg, pos, vi->sbit); 10027 pos = safecat(msg, sizeof msg, pos, "): "); 10028 pos = safecatn(msg, sizeof msg, pos, isbit); 10029 } 10030 pos = safecat(msg, sizeof msg, pos, "/"); 10031 /* The output is either "id/max" or "id sbit(sbit): isbit/max" */ 10032 pos = safecatn(msg, sizeof msg, pos, vi->sbit_max); 10033 } 10034 pos = safecat(msg, sizeof msg, pos, ")"); 10035 10036 /* A component may have been multiplied (in linear space) by the 10037 * alpha value, 'compose' says whether this is relevant. 10038 */ 10039 if (compose || pass != 0) 10040 { 10041 /* If any form of composition is being done report our 10042 * calculated linear value here (the code above doesn't record 10043 * the input value before composition is performed, so what 10044 * gets reported is the value after composition.) 10045 */ 10046 if (use_input || pass != 0) 10047 { 10048 if (vi->file_inverse > 0) 10049 { 10050 pos = safecat(msg, sizeof msg, pos, "^"); 10051 pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2); 10052 } 10053 10054 else 10055 pos = safecat(msg, sizeof msg, pos, "[linear]"); 10056 10057 pos = safecat(msg, sizeof msg, pos, "*(alpha)"); 10058 pos = safecatd(msg, sizeof msg, pos, alpha, precision); 10059 } 10060 10061 /* Now record the *linear* background value if it was used 10062 * (this function is not passed the original, non-linear, 10063 * value but it is contained in the test name.) 10064 */ 10065 if (use_background) 10066 { 10067 pos = safecat(msg, sizeof msg, pos, use_input ? "+" : " "); 10068 pos = safecat(msg, sizeof msg, pos, "(background)"); 10069 pos = safecatd(msg, sizeof msg, pos, background, precision); 10070 pos = safecat(msg, sizeof msg, pos, "*"); 10071 pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision); 10072 } 10073 } 10074 10075 /* Report the calculated value (input_sample) and the linearized 10076 * libpng value (output) unless this is just a component gamma 10077 * correction. 10078 */ 10079 if (compose || alpha < 0 || pass != 0) 10080 { 10081 pos = safecat(msg, sizeof msg, pos, 10082 pass != 0 ? " =\n\t" : " = "); 10083 pos = safecatd(msg, sizeof msg, pos, input_sample, precision); 10084 pos = safecat(msg, sizeof msg, pos, " (libpng: "); 10085 pos = safecatd(msg, sizeof msg, pos, output, precision); 10086 pos = safecat(msg, sizeof msg, pos, ")"); 10087 10088 /* Finally report the output gamma encoding, if any. */ 10089 if (output_is_encoded) 10090 { 10091 pos = safecat(msg, sizeof msg, pos, " ^"); 10092 pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2); 10093 pos = safecat(msg, sizeof msg, pos, "(to screen) ="); 10094 } 10095 10096 else 10097 pos = safecat(msg, sizeof msg, pos, " [screen is linear] ="); 10098 } 10099 10100 if ((!compose && alpha >= 0) || pass != 0) 10101 { 10102 if (pass != 0) /* logging */ 10103 pos = safecat(msg, sizeof msg, pos, "\n\t[overall:"); 10104 10105 /* This is the non-composition case, the internal linear 10106 * values are irrelevant (though the log below will reveal 10107 * them.) Output a much shorter warning/error message and report 10108 * the overall gamma correction. 10109 */ 10110 if (vi->gamma_correction > 0) 10111 { 10112 pos = safecat(msg, sizeof msg, pos, " ^"); 10113 pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2); 10114 pos = safecat(msg, sizeof msg, pos, "(gamma correction) ="); 10115 } 10116 10117 else 10118 pos = safecat(msg, sizeof msg, pos, 10119 " [no gamma correction] ="); 10120 10121 if (pass != 0) 10122 pos = safecat(msg, sizeof msg, pos, "]"); 10123 } 10124 10125 /* This is our calculated encoded_sample which should (but does 10126 * not) match od: 10127 */ 10128 pos = safecat(msg, sizeof msg, pos, pass != 0 ? "\n\t" : " "); 10129 pos = safecatd(msg, sizeof msg, pos, is_lo, 1); 10130 pos = safecat(msg, sizeof msg, pos, " < "); 10131 pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1); 10132 pos = safecat(msg, sizeof msg, pos, " (libpng: "); 10133 pos = safecatn(msg, sizeof msg, pos, od); 10134 pos = safecat(msg, sizeof msg, pos, ")"); 10135 pos = safecat(msg, sizeof msg, pos, "/"); 10136 pos = safecatn(msg, sizeof msg, pos, outmax); 10137 pos = safecat(msg, sizeof msg, pos, " < "); 10138 pos = safecatd(msg, sizeof msg, pos, is_hi, 1); 10139 10140 if (pass == 0) /* The error condition */ 10141 { 10142 # ifdef PNG_WARNINGS_SUPPORTED 10143 png_warning(vi->pp, msg); 10144 # else 10145 store_warning(vi->pp, msg); 10146 # endif 10147 } 10148 10149 else /* logging this value */ 10150 store_verbose(&vi->dp->pm->this, vi->pp, pass, msg); 10151 } 10152 } 10153 } 10154 10155 return i; 10156 } 10157 10158 static void 10159 gamma_image_validate(gamma_display *dp, png_const_structp pp, 10160 png_infop pi) 10161 { 10162 /* Get some constants derived from the input and output file formats: */ 10163 const png_store* const ps = dp->this.ps; 10164 const png_byte in_ct = dp->this.colour_type; 10165 const png_byte in_bd = dp->this.bit_depth; 10166 const png_uint_32 w = dp->this.w; 10167 const png_uint_32 h = dp->this.h; 10168 const size_t cbRow = dp->this.cbRow; 10169 const png_byte out_ct = png_get_color_type(pp, pi); 10170 const png_byte out_bd = png_get_bit_depth(pp, pi); 10171 10172 /* There are three sources of error, firstly the quantization in the 10173 * file encoding, determined by sbit and/or the file depth, secondly 10174 * the output (screen) gamma and thirdly the output file encoding. 10175 * 10176 * Since this API receives the screen and file gamma in double 10177 * precision it is possible to calculate an exact answer given an input 10178 * pixel value. Therefore we assume that the *input* value is exact - 10179 * sample/maxsample - calculate the corresponding gamma corrected 10180 * output to the limits of double precision arithmetic and compare with 10181 * what libpng returns. 10182 * 10183 * Since the library must quantize the output to 8 or 16 bits there is 10184 * a fundamental limit on the accuracy of the output of +/-.5 - this 10185 * quantization limit is included in addition to the other limits 10186 * specified by the paramaters to the API. (Effectively, add .5 10187 * everywhere.) 10188 * 10189 * The behavior of the 'sbit' paramter is defined by section 12.5 10190 * (sample depth scaling) of the PNG spec. That section forces the 10191 * decoder to assume that the PNG values have been scaled if sBIT is 10192 * present: 10193 * 10194 * png-sample = floor( input-sample * (max-out/max-in) + .5); 10195 * 10196 * This means that only a subset of the possible PNG values should 10197 * appear in the input. However, the spec allows the encoder to use a 10198 * variety of approximations to the above and doesn't require any 10199 * restriction of the values produced. 10200 * 10201 * Nevertheless the spec requires that the upper 'sBIT' bits of the 10202 * value stored in a PNG file be the original sample bits. 10203 * Consequently the code below simply scales the top sbit bits by 10204 * (1<<sbit)-1 to obtain an original sample value. 10205 * 10206 * Because there is limited precision in the input it is arguable that 10207 * an acceptable result is any valid result from input-.5 to input+.5. 10208 * The basic tests below do not do this, however if 'use_input_precision' 10209 * is set a subsequent test is performed above. 10210 */ 10211 const unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U; 10212 int processing; 10213 png_uint_32 y; 10214 const store_palette_entry *in_palette = dp->this.palette; 10215 const int in_is_transparent = dp->this.is_transparent; 10216 int process_tRNS; 10217 int out_npalette = -1; 10218 int out_is_transparent = 0; /* Just refers to the palette case */ 10219 store_palette out_palette; 10220 validate_info vi; 10221 10222 /* Check for row overwrite errors */ 10223 store_image_check(dp->this.ps, pp, 0); 10224 10225 /* Supply the input and output sample depths here - 8 for an indexed image, 10226 * otherwise the bit depth. 10227 */ 10228 init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd); 10229 10230 processing = (vi.gamma_correction > 0 && !dp->threshold_test) 10231 || in_bd != out_bd || in_ct != out_ct || vi.do_background; 10232 process_tRNS = dp->this.has_tRNS && vi.do_background; 10233 10234 /* TODO: FIX THIS: MAJOR BUG! If the transformations all happen inside 10235 * the palette there is no way of finding out, because libpng fails to 10236 * update the palette on png_read_update_info. Indeed, libpng doesn't 10237 * even do the required work until much later, when it doesn't have any 10238 * info pointer. Oops. For the moment 'processing' is turned off if 10239 * out_ct is palette. 10240 */ 10241 if (in_ct == 3 && out_ct == 3) 10242 processing = 0; 10243 10244 if (processing && out_ct == 3) 10245 out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi); 10246 10247 for (y=0; y<h; ++y) 10248 { 10249 png_const_bytep pRow = store_image_row(ps, pp, 0, y); 10250 png_byte std[STANDARD_ROWMAX]; 10251 10252 transform_row(pp, std, in_ct, in_bd, y); 10253 10254 if (processing) 10255 { 10256 unsigned int x; 10257 10258 for (x=0; x<w; ++x) 10259 { 10260 double alpha = 1; /* serves as a flag value */ 10261 10262 /* Record the palette index for index images. */ 10263 const unsigned int in_index = 10264 in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256; 10265 const unsigned int out_index = 10266 out_ct == 3 ? sample(std, 3, out_bd, x, 0, 0, 0) : 256; 10267 10268 /* Handle input alpha - png_set_background will cause the output 10269 * alpha to disappear so there is nothing to check. 10270 */ 10271 if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || 10272 (in_ct == 3 && in_is_transparent)) 10273 { 10274 const unsigned int input_alpha = in_ct == 3 ? 10275 dp->this.palette[in_index].alpha : 10276 sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0); 10277 10278 unsigned int output_alpha = 65536 /* as a flag value */; 10279 10280 if (out_ct == 3) 10281 { 10282 if (out_is_transparent) 10283 output_alpha = out_palette[out_index].alpha; 10284 } 10285 10286 else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0) 10287 output_alpha = sample(pRow, out_ct, out_bd, x, 10288 samples_per_pixel, 0, 0); 10289 10290 if (output_alpha != 65536) 10291 alpha = gamma_component_validate("alpha", &vi, input_alpha, 10292 output_alpha, -1/*alpha*/, 0/*background*/); 10293 10294 else /* no alpha in output */ 10295 { 10296 /* This is a copy of the calculation of 'i' above in order to 10297 * have the alpha value to use in the background calculation. 10298 */ 10299 alpha = input_alpha >> vi.isbit_shift; 10300 alpha /= vi.sbit_max; 10301 } 10302 } 10303 10304 else if (process_tRNS) 10305 { 10306 /* alpha needs to be set appropriately for this pixel, it is 10307 * currently 1 and needs to be 0 for an input pixel which matches 10308 * the values in tRNS. 10309 */ 10310 switch (in_ct) 10311 { 10312 case 0: /* gray */ 10313 if (sample(std, in_ct, in_bd, x, 0, 0, 0) == 10314 dp->this.transparent.red) 10315 alpha = 0; 10316 break; 10317 10318 case 2: /* RGB */ 10319 if (sample(std, in_ct, in_bd, x, 0, 0, 0) == 10320 dp->this.transparent.red && 10321 sample(std, in_ct, in_bd, x, 1, 0, 0) == 10322 dp->this.transparent.green && 10323 sample(std, in_ct, in_bd, x, 2, 0, 0) == 10324 dp->this.transparent.blue) 10325 alpha = 0; 10326 break; 10327 10328 default: 10329 break; 10330 } 10331 } 10332 10333 /* Handle grayscale or RGB components. */ 10334 if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */ 10335 (void)gamma_component_validate("gray", &vi, 10336 sample(std, in_ct, in_bd, x, 0, 0, 0), 10337 sample(pRow, out_ct, out_bd, x, 0, 0, 0), 10338 alpha/*component*/, vi.background_red); 10339 else /* RGB or palette */ 10340 { 10341 (void)gamma_component_validate("red", &vi, 10342 in_ct == 3 ? in_palette[in_index].red : 10343 sample(std, in_ct, in_bd, x, 0, 0, 0), 10344 out_ct == 3 ? out_palette[out_index].red : 10345 sample(pRow, out_ct, out_bd, x, 0, 0, 0), 10346 alpha/*component*/, vi.background_red); 10347 10348 (void)gamma_component_validate("green", &vi, 10349 in_ct == 3 ? in_palette[in_index].green : 10350 sample(std, in_ct, in_bd, x, 1, 0, 0), 10351 out_ct == 3 ? out_palette[out_index].green : 10352 sample(pRow, out_ct, out_bd, x, 1, 0, 0), 10353 alpha/*component*/, vi.background_green); 10354 10355 (void)gamma_component_validate("blue", &vi, 10356 in_ct == 3 ? in_palette[in_index].blue : 10357 sample(std, in_ct, in_bd, x, 2, 0, 0), 10358 out_ct == 3 ? out_palette[out_index].blue : 10359 sample(pRow, out_ct, out_bd, x, 2, 0, 0), 10360 alpha/*component*/, vi.background_blue); 10361 } 10362 } 10363 } 10364 10365 else if (memcmp(std, pRow, cbRow) != 0) 10366 { 10367 char msg[64]; 10368 10369 /* No transform is expected on the threshold tests. */ 10370 sprintf(msg, "gamma: below threshold row %lu changed", 10371 (unsigned long)y); 10372 10373 png_error(pp, msg); 10374 } 10375 } /* row (y) loop */ 10376 10377 dp->this.ps->validated = 1; 10378 } 10379 10380 static void PNGCBAPI 10381 gamma_end(png_structp ppIn, png_infop pi) 10382 { 10383 png_const_structp pp = ppIn; 10384 gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp)); 10385 10386 if (!dp->this.speed) 10387 gamma_image_validate(dp, pp, pi); 10388 else 10389 dp->this.ps->validated = 1; 10390 } 10391 10392 /* A single test run checking a gamma transformation. 10393 * 10394 * maxabs: maximum absolute error as a fraction 10395 * maxout: maximum output error in the output units 10396 * maxpc: maximum percentage error (as a percentage) 10397 */ 10398 static void 10399 gamma_test(png_modifier *pmIn, const png_byte colour_typeIn, 10400 const png_byte bit_depthIn, const int palette_numberIn, 10401 const int interlace_typeIn, 10402 const double file_gammaIn, const double screen_gammaIn, 10403 const png_byte sbitIn, const int threshold_testIn, 10404 const char *name, 10405 const int use_input_precisionIn, const int scale16In, 10406 const int expand16In, const int do_backgroundIn, 10407 const png_color_16 *bkgd_colorIn, double bkgd_gammaIn) 10408 { 10409 gamma_display d; 10410 context(&pmIn->this, fault); 10411 10412 gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn, 10413 palette_numberIn, interlace_typeIn, 0, 0, 0), 10414 file_gammaIn, screen_gammaIn, sbitIn, 10415 threshold_testIn, use_input_precisionIn, scale16In, 10416 expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn); 10417 10418 Try 10419 { 10420 png_structp pp; 10421 png_infop pi; 10422 gama_modification gama_mod; 10423 srgb_modification srgb_mod; 10424 sbit_modification sbit_mod; 10425 10426 /* For the moment don't use the png_modifier support here. */ 10427 d.pm->encoding_counter = 0; 10428 modifier_set_encoding(d.pm); /* Just resets everything */ 10429 d.pm->current_gamma = d.file_gamma; 10430 10431 /* Make an appropriate modifier to set the PNG file gamma to the 10432 * given gamma value and the sBIT chunk to the given precision. 10433 */ 10434 d.pm->modifications = NULL; 10435 gama_modification_init(&gama_mod, d.pm, d.file_gamma); 10436 srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/); 10437 if (d.sbit > 0) 10438 sbit_modification_init(&sbit_mod, d.pm, d.sbit); 10439 10440 modification_reset(d.pm->modifications); 10441 10442 /* Get a png_struct for reading the image. */ 10443 pp = set_modifier_for_read(d.pm, &pi, d.this.id, name); 10444 standard_palette_init(&d.this); 10445 10446 /* Introduce the correct read function. */ 10447 if (d.pm->this.progressive) 10448 { 10449 /* Share the row function with the standard implementation. */ 10450 png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row, 10451 gamma_end); 10452 10453 /* Now feed data into the reader until we reach the end: */ 10454 modifier_progressive_read(d.pm, pp, pi); 10455 } 10456 else 10457 { 10458 /* modifier_read expects a png_modifier* */ 10459 png_set_read_fn(pp, d.pm, modifier_read); 10460 10461 /* Check the header values: */ 10462 png_read_info(pp, pi); 10463 10464 /* Process the 'info' requirements. Only one image is generated */ 10465 gamma_info_imp(&d, pp, pi); 10466 10467 sequential_row(&d.this, pp, pi, -1, 0); 10468 10469 if (!d.this.speed) 10470 gamma_image_validate(&d, pp, pi); 10471 else 10472 d.this.ps->validated = 1; 10473 } 10474 10475 modifier_reset(d.pm); 10476 10477 if (d.pm->log && !d.threshold_test && !d.this.speed) 10478 fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n", 10479 d.this.bit_depth, colour_types[d.this.colour_type], name, 10480 d.maxerrout, d.maxerrabs, 100*d.maxerrpc); 10481 10482 /* Log the summary values too. */ 10483 if (d.this.colour_type == 0 || d.this.colour_type == 4) 10484 { 10485 switch (d.this.bit_depth) 10486 { 10487 case 1: 10488 break; 10489 10490 case 2: 10491 if (d.maxerrout > d.pm->error_gray_2) 10492 d.pm->error_gray_2 = d.maxerrout; 10493 10494 break; 10495 10496 case 4: 10497 if (d.maxerrout > d.pm->error_gray_4) 10498 d.pm->error_gray_4 = d.maxerrout; 10499 10500 break; 10501 10502 case 8: 10503 if (d.maxerrout > d.pm->error_gray_8) 10504 d.pm->error_gray_8 = d.maxerrout; 10505 10506 break; 10507 10508 case 16: 10509 if (d.maxerrout > d.pm->error_gray_16) 10510 d.pm->error_gray_16 = d.maxerrout; 10511 10512 break; 10513 10514 default: 10515 png_error(pp, "bad bit depth (internal: 1)"); 10516 } 10517 } 10518 10519 else if (d.this.colour_type == 2 || d.this.colour_type == 6) 10520 { 10521 switch (d.this.bit_depth) 10522 { 10523 case 8: 10524 10525 if (d.maxerrout > d.pm->error_color_8) 10526 d.pm->error_color_8 = d.maxerrout; 10527 10528 break; 10529 10530 case 16: 10531 10532 if (d.maxerrout > d.pm->error_color_16) 10533 d.pm->error_color_16 = d.maxerrout; 10534 10535 break; 10536 10537 default: 10538 png_error(pp, "bad bit depth (internal: 2)"); 10539 } 10540 } 10541 10542 else if (d.this.colour_type == 3) 10543 { 10544 if (d.maxerrout > d.pm->error_indexed) 10545 d.pm->error_indexed = d.maxerrout; 10546 } 10547 } 10548 10549 Catch(fault) 10550 modifier_reset(voidcast(png_modifier*,(void*)fault)); 10551 } 10552 10553 static void gamma_threshold_test(png_modifier *pm, png_byte colour_type, 10554 png_byte bit_depth, int interlace_type, double file_gamma, 10555 double screen_gamma) 10556 { 10557 size_t pos = 0; 10558 char name[64]; 10559 pos = safecat(name, sizeof name, pos, "threshold "); 10560 pos = safecatd(name, sizeof name, pos, file_gamma, 3); 10561 pos = safecat(name, sizeof name, pos, "/"); 10562 pos = safecatd(name, sizeof name, pos, screen_gamma, 3); 10563 10564 (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type, 10565 file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name, 10566 0 /*no input precision*/, 10567 0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/, 10568 0 /*no background gamma*/); 10569 } 10570 10571 static void 10572 perform_gamma_threshold_tests(png_modifier *pm) 10573 { 10574 png_byte colour_type = 0; 10575 png_byte bit_depth = 0; 10576 unsigned int palette_number = 0; 10577 10578 /* Don't test more than one instance of each palette - it's pointless, in 10579 * fact this test is somewhat excessive since libpng doesn't make this 10580 * decision based on colour type or bit depth! 10581 * 10582 * CHANGED: now test two palettes and, as a side effect, images with and 10583 * without tRNS. 10584 */ 10585 while (next_format(&colour_type, &bit_depth, &palette_number, 10586 pm->test_lbg_gamma_threshold, pm->test_tRNS)) 10587 if (palette_number < 2) 10588 { 10589 double test_gamma = 1.0; 10590 while (test_gamma >= .4) 10591 { 10592 /* There's little point testing the interlacing vs non-interlacing, 10593 * but this can be set from the command line. 10594 */ 10595 gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type, 10596 test_gamma, 1/test_gamma); 10597 test_gamma *= .95; 10598 } 10599 10600 /* And a special test for sRGB */ 10601 gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type, 10602 .45455, 2.2); 10603 10604 if (fail(pm)) 10605 return; 10606 } 10607 } 10608 10609 static void gamma_transform_test(png_modifier *pm, 10610 const png_byte colour_type, const png_byte bit_depth, 10611 const int palette_number, 10612 const int interlace_type, const double file_gamma, 10613 const double screen_gamma, const png_byte sbit, 10614 const int use_input_precision, const int scale16) 10615 { 10616 size_t pos = 0; 10617 char name[64]; 10618 10619 if (sbit != bit_depth && sbit != 0) 10620 { 10621 pos = safecat(name, sizeof name, pos, "sbit("); 10622 pos = safecatn(name, sizeof name, pos, sbit); 10623 pos = safecat(name, sizeof name, pos, ") "); 10624 } 10625 10626 else 10627 pos = safecat(name, sizeof name, pos, "gamma "); 10628 10629 if (scale16) 10630 pos = safecat(name, sizeof name, pos, "16to8 "); 10631 10632 pos = safecatd(name, sizeof name, pos, file_gamma, 3); 10633 pos = safecat(name, sizeof name, pos, "->"); 10634 pos = safecatd(name, sizeof name, pos, screen_gamma, 3); 10635 10636 gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type, 10637 file_gamma, screen_gamma, sbit, 0, name, use_input_precision, 10638 scale16, pm->test_gamma_expand16, 0 , 0, 0); 10639 } 10640 10641 static void perform_gamma_transform_tests(png_modifier *pm) 10642 { 10643 png_byte colour_type = 0; 10644 png_byte bit_depth = 0; 10645 unsigned int palette_number = 0; 10646 10647 while (next_format(&colour_type, &bit_depth, &palette_number, 10648 pm->test_lbg_gamma_transform, pm->test_tRNS)) 10649 { 10650 unsigned int i, j; 10651 10652 for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j) 10653 if (i != j) 10654 { 10655 gamma_transform_test(pm, colour_type, bit_depth, palette_number, 10656 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/, 10657 pm->use_input_precision, 0 /*do not scale16*/); 10658 10659 if (fail(pm)) 10660 return; 10661 } 10662 } 10663 } 10664 10665 static void perform_gamma_sbit_tests(png_modifier *pm) 10666 { 10667 png_byte sbit; 10668 10669 /* The only interesting cases are colour and grayscale, alpha is ignored here 10670 * for overall speed. Only bit depths where sbit is less than the bit depth 10671 * are tested. 10672 */ 10673 for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit) 10674 { 10675 png_byte colour_type = 0, bit_depth = 0; 10676 unsigned int npalette = 0; 10677 10678 while (next_format(&colour_type, &bit_depth, &npalette, 10679 pm->test_lbg_gamma_sbit, pm->test_tRNS)) 10680 if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 && 10681 ((colour_type == 3 && sbit < 8) || 10682 (colour_type != 3 && sbit < bit_depth))) 10683 { 10684 unsigned int i; 10685 10686 for (i=0; i<pm->ngamma_tests; ++i) 10687 { 10688 unsigned int j; 10689 10690 for (j=0; j<pm->ngamma_tests; ++j) if (i != j) 10691 { 10692 gamma_transform_test(pm, colour_type, bit_depth, npalette, 10693 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 10694 sbit, pm->use_input_precision_sbit, 0 /*scale16*/); 10695 10696 if (fail(pm)) 10697 return; 10698 } 10699 } 10700 } 10701 } 10702 } 10703 10704 /* Note that this requires a 16 bit source image but produces 8 bit output, so 10705 * we only need the 16bit write support, but the 16 bit images are only 10706 * generated if DO_16BIT is defined. 10707 */ 10708 #ifdef DO_16BIT 10709 static void perform_gamma_scale16_tests(png_modifier *pm) 10710 { 10711 # ifndef PNG_MAX_GAMMA_8 10712 # define PNG_MAX_GAMMA_8 11 10713 # endif 10714 # if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER < 10700 10715 # define SBIT_16_TO_8 PNG_MAX_GAMMA_8 10716 # else 10717 # define SBIT_16_TO_8 16 10718 # endif 10719 /* Include the alpha cases here. Note that sbit matches the internal value 10720 * used by the library - otherwise we will get spurious errors from the 10721 * internal sbit style approximation. 10722 * 10723 * The threshold test is here because otherwise the 16 to 8 conversion will 10724 * proceed *without* gamma correction, and the tests above will fail (but not 10725 * by much) - this could be fixed, it only appears with the -g option. 10726 */ 10727 unsigned int i, j; 10728 for (i=0; i<pm->ngamma_tests; ++i) 10729 { 10730 for (j=0; j<pm->ngamma_tests; ++j) 10731 { 10732 if (i != j && 10733 fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD) 10734 { 10735 gamma_transform_test(pm, 0, 16, 0, pm->interlace_type, 10736 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, 10737 pm->use_input_precision_16to8, 1 /*scale16*/); 10738 10739 if (fail(pm)) 10740 return; 10741 10742 gamma_transform_test(pm, 2, 16, 0, pm->interlace_type, 10743 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, 10744 pm->use_input_precision_16to8, 1 /*scale16*/); 10745 10746 if (fail(pm)) 10747 return; 10748 10749 gamma_transform_test(pm, 4, 16, 0, pm->interlace_type, 10750 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, 10751 pm->use_input_precision_16to8, 1 /*scale16*/); 10752 10753 if (fail(pm)) 10754 return; 10755 10756 gamma_transform_test(pm, 6, 16, 0, pm->interlace_type, 10757 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, 10758 pm->use_input_precision_16to8, 1 /*scale16*/); 10759 10760 if (fail(pm)) 10761 return; 10762 } 10763 } 10764 } 10765 } 10766 #endif /* 16 to 8 bit conversion */ 10767 10768 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ 10769 defined(PNG_READ_ALPHA_MODE_SUPPORTED) 10770 static void gamma_composition_test(png_modifier *pm, 10771 const png_byte colour_type, const png_byte bit_depth, 10772 const int palette_number, 10773 const int interlace_type, const double file_gamma, 10774 const double screen_gamma, 10775 const int use_input_precision, const int do_background, 10776 const int expand_16) 10777 { 10778 size_t pos = 0; 10779 png_const_charp base; 10780 double bg; 10781 char name[128]; 10782 png_color_16 background; 10783 10784 /* Make up a name and get an appropriate background gamma value. */ 10785 switch (do_background) 10786 { 10787 default: 10788 base = ""; 10789 bg = 4; /* should not be used */ 10790 break; 10791 case PNG_BACKGROUND_GAMMA_SCREEN: 10792 base = " bckg(Screen):"; 10793 bg = 1/screen_gamma; 10794 break; 10795 case PNG_BACKGROUND_GAMMA_FILE: 10796 base = " bckg(File):"; 10797 bg = file_gamma; 10798 break; 10799 case PNG_BACKGROUND_GAMMA_UNIQUE: 10800 base = " bckg(Unique):"; 10801 /* This tests the handling of a unique value, the math is such that the 10802 * value tends to be <1, but is neither screen nor file (even if they 10803 * match!) 10804 */ 10805 bg = (file_gamma + screen_gamma) / 3; 10806 break; 10807 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 10808 case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG: 10809 base = " alpha(PNG)"; 10810 bg = 4; /* should not be used */ 10811 break; 10812 case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: 10813 base = " alpha(Porter-Duff)"; 10814 bg = 4; /* should not be used */ 10815 break; 10816 case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: 10817 base = " alpha(Optimized)"; 10818 bg = 4; /* should not be used */ 10819 break; 10820 case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: 10821 base = " alpha(Broken)"; 10822 bg = 4; /* should not be used */ 10823 break; 10824 #endif 10825 } 10826 10827 /* Use random background values - the background is always presented in the 10828 * output space (8 or 16 bit components). 10829 */ 10830 if (expand_16 || bit_depth == 16) 10831 { 10832 png_uint_32 r = random_32(); 10833 10834 background.red = (png_uint_16)r; 10835 background.green = (png_uint_16)(r >> 16); 10836 r = random_32(); 10837 background.blue = (png_uint_16)r; 10838 background.gray = (png_uint_16)(r >> 16); 10839 10840 /* In earlier libpng versions, those where DIGITIZE is set, any background 10841 * gamma correction in the expand16 case was done using 8-bit gamma 10842 * correction tables, resulting in larger errors. To cope with those 10843 * cases use a 16-bit background value which will handle this gamma 10844 * correction. 10845 */ 10846 # if DIGITIZE 10847 if (expand_16 && (do_background == PNG_BACKGROUND_GAMMA_UNIQUE || 10848 do_background == PNG_BACKGROUND_GAMMA_FILE) && 10849 fabs(bg*screen_gamma-1) > PNG_GAMMA_THRESHOLD) 10850 { 10851 /* The background values will be looked up in an 8-bit table to do 10852 * the gamma correction, so only select values which are an exact 10853 * match for the 8-bit table entries: 10854 */ 10855 background.red = (png_uint_16)((background.red >> 8) * 257); 10856 background.green = (png_uint_16)((background.green >> 8) * 257); 10857 background.blue = (png_uint_16)((background.blue >> 8) * 257); 10858 background.gray = (png_uint_16)((background.gray >> 8) * 257); 10859 } 10860 # endif 10861 } 10862 10863 else /* 8 bit colors */ 10864 { 10865 png_uint_32 r = random_32(); 10866 10867 background.red = (png_byte)r; 10868 background.green = (png_byte)(r >> 8); 10869 background.blue = (png_byte)(r >> 16); 10870 background.gray = (png_byte)(r >> 24); 10871 } 10872 10873 background.index = 193; /* rgb(193,193,193) to detect errors */ 10874 10875 if (!(colour_type & PNG_COLOR_MASK_COLOR)) 10876 { 10877 /* Because, currently, png_set_background is always called with 10878 * 'need_expand' false in this case and because the gamma test itself 10879 * doesn't cause an expand to 8-bit for lower bit depths the colour must 10880 * be reduced to the correct range. 10881 */ 10882 if (bit_depth < 8) 10883 background.gray &= (png_uint_16)((1U << bit_depth)-1); 10884 10885 /* Grayscale input, we do not convert to RGB (TBD), so we must set the 10886 * background to gray - else libpng seems to fail. 10887 */ 10888 background.red = background.green = background.blue = background.gray; 10889 } 10890 10891 pos = safecat(name, sizeof name, pos, "gamma "); 10892 pos = safecatd(name, sizeof name, pos, file_gamma, 3); 10893 pos = safecat(name, sizeof name, pos, "->"); 10894 pos = safecatd(name, sizeof name, pos, screen_gamma, 3); 10895 10896 pos = safecat(name, sizeof name, pos, base); 10897 if (do_background < ALPHA_MODE_OFFSET) 10898 { 10899 /* Include the background color and gamma in the name: */ 10900 pos = safecat(name, sizeof name, pos, "("); 10901 /* This assumes no expand gray->rgb - the current code won't handle that! 10902 */ 10903 if (colour_type & PNG_COLOR_MASK_COLOR) 10904 { 10905 pos = safecatn(name, sizeof name, pos, background.red); 10906 pos = safecat(name, sizeof name, pos, ","); 10907 pos = safecatn(name, sizeof name, pos, background.green); 10908 pos = safecat(name, sizeof name, pos, ","); 10909 pos = safecatn(name, sizeof name, pos, background.blue); 10910 } 10911 else 10912 pos = safecatn(name, sizeof name, pos, background.gray); 10913 pos = safecat(name, sizeof name, pos, ")^"); 10914 pos = safecatd(name, sizeof name, pos, bg, 3); 10915 } 10916 10917 gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type, 10918 file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision, 10919 0/*strip 16*/, expand_16, do_background, &background, bg); 10920 } 10921 10922 10923 static void 10924 perform_gamma_composition_tests(png_modifier *pm, int do_background, 10925 int expand_16) 10926 { 10927 png_byte colour_type = 0; 10928 png_byte bit_depth = 0; 10929 unsigned int palette_number = 0; 10930 10931 /* Skip the non-alpha cases - there is no setting of a transparency colour at 10932 * present. 10933 * 10934 * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do, 10935 * however the palette case fails miserably so is commented out below. 10936 */ 10937 while (next_format(&colour_type, &bit_depth, &palette_number, 10938 pm->test_lbg_gamma_composition, pm->test_tRNS)) 10939 if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0 10940 #if 0 /* TODO: FIXME */ 10941 /*TODO: FIXME: this should work */ 10942 || colour_type == 3 10943 #endif 10944 || (colour_type != 3 && palette_number != 0)) 10945 { 10946 unsigned int i, j; 10947 10948 /* Don't skip the i==j case here - it's relevant. */ 10949 for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j) 10950 { 10951 gamma_composition_test(pm, colour_type, bit_depth, palette_number, 10952 pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 10953 pm->use_input_precision, do_background, expand_16); 10954 10955 if (fail(pm)) 10956 return; 10957 } 10958 } 10959 } 10960 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */ 10961 10962 static void 10963 init_gamma_errors(png_modifier *pm) 10964 { 10965 /* Use -1 to catch tests that were not actually run */ 10966 pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.; 10967 pm->error_color_8 = -1.; 10968 pm->error_indexed = -1.; 10969 pm->error_gray_16 = pm->error_color_16 = -1.; 10970 } 10971 10972 static void 10973 print_one(const char *leader, double err) 10974 { 10975 if (err != -1.) 10976 printf(" %s %.5f\n", leader, err); 10977 } 10978 10979 static void 10980 summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth, 10981 int indexed) 10982 { 10983 fflush(stderr); 10984 10985 if (who) 10986 printf("\nGamma correction with %s:\n", who); 10987 10988 else 10989 printf("\nBasic gamma correction:\n"); 10990 10991 if (low_bit_depth) 10992 { 10993 print_one(" 2 bit gray: ", pm->error_gray_2); 10994 print_one(" 4 bit gray: ", pm->error_gray_4); 10995 print_one(" 8 bit gray: ", pm->error_gray_8); 10996 print_one(" 8 bit color:", pm->error_color_8); 10997 if (indexed) 10998 print_one(" indexed: ", pm->error_indexed); 10999 } 11000 11001 print_one("16 bit gray: ", pm->error_gray_16); 11002 print_one("16 bit color:", pm->error_color_16); 11003 11004 fflush(stdout); 11005 } 11006 11007 static void 11008 perform_gamma_test(png_modifier *pm, int summary) 11009 { 11010 /*TODO: remove this*/ 11011 /* Save certain values for the temporary overrides below. */ 11012 unsigned int calculations_use_input_precision = 11013 pm->calculations_use_input_precision; 11014 # ifdef PNG_READ_BACKGROUND_SUPPORTED 11015 double maxout8 = pm->maxout8; 11016 # endif 11017 11018 /* First some arbitrary no-transform tests: */ 11019 if (!pm->this.speed && pm->test_gamma_threshold) 11020 { 11021 perform_gamma_threshold_tests(pm); 11022 11023 if (fail(pm)) 11024 return; 11025 } 11026 11027 /* Now some real transforms. */ 11028 if (pm->test_gamma_transform) 11029 { 11030 if (summary) 11031 { 11032 fflush(stderr); 11033 printf("Gamma correction error summary\n\n"); 11034 printf("The printed value is the maximum error in the pixel values\n"); 11035 printf("calculated by the libpng gamma correction code. The error\n"); 11036 printf("is calculated as the difference between the output pixel\n"); 11037 printf("value (always an integer) and the ideal value from the\n"); 11038 printf("libpng specification (typically not an integer).\n\n"); 11039 11040 printf("Expect this value to be less than .5 for 8 bit formats,\n"); 11041 printf("less than 1 for formats with fewer than 8 bits and a small\n"); 11042 printf("number (typically less than 5) for the 16 bit formats.\n"); 11043 printf("For performance reasons the value for 16 bit formats\n"); 11044 printf("increases when the image file includes an sBIT chunk.\n"); 11045 fflush(stdout); 11046 } 11047 11048 init_gamma_errors(pm); 11049 /*TODO: remove this. Necessary because the current libpng 11050 * implementation works in 8 bits: 11051 */ 11052 if (pm->test_gamma_expand16) 11053 pm->calculations_use_input_precision = 1; 11054 perform_gamma_transform_tests(pm); 11055 if (!calculations_use_input_precision) 11056 pm->calculations_use_input_precision = 0; 11057 11058 if (summary) 11059 summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/); 11060 11061 if (fail(pm)) 11062 return; 11063 } 11064 11065 /* The sbit tests produce much larger errors: */ 11066 if (pm->test_gamma_sbit) 11067 { 11068 init_gamma_errors(pm); 11069 perform_gamma_sbit_tests(pm); 11070 11071 if (summary) 11072 summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U, 1/*indexed*/); 11073 11074 if (fail(pm)) 11075 return; 11076 } 11077 11078 #ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */ 11079 if (pm->test_gamma_scale16) 11080 { 11081 /* The 16 to 8 bit strip operations: */ 11082 init_gamma_errors(pm); 11083 perform_gamma_scale16_tests(pm); 11084 11085 if (summary) 11086 { 11087 fflush(stderr); 11088 printf("\nGamma correction with 16 to 8 bit reduction:\n"); 11089 printf(" 16 bit gray: %.5f\n", pm->error_gray_16); 11090 printf(" 16 bit color: %.5f\n", pm->error_color_16); 11091 fflush(stdout); 11092 } 11093 11094 if (fail(pm)) 11095 return; 11096 } 11097 #endif 11098 11099 #ifdef PNG_READ_BACKGROUND_SUPPORTED 11100 if (pm->test_gamma_background) 11101 { 11102 init_gamma_errors(pm); 11103 11104 /*TODO: remove this. Necessary because the current libpng 11105 * implementation works in 8 bits: 11106 */ 11107 if (pm->test_gamma_expand16) 11108 { 11109 pm->calculations_use_input_precision = 1; 11110 pm->maxout8 = .499; /* because the 16 bit background is smashed */ 11111 } 11112 perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE, 11113 pm->test_gamma_expand16); 11114 if (!calculations_use_input_precision) 11115 pm->calculations_use_input_precision = 0; 11116 pm->maxout8 = maxout8; 11117 11118 if (summary) 11119 summarize_gamma_errors(pm, "background", 1, 0/*indexed*/); 11120 11121 if (fail(pm)) 11122 return; 11123 } 11124 #endif 11125 11126 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED 11127 if (pm->test_gamma_alpha_mode) 11128 { 11129 int do_background; 11130 11131 init_gamma_errors(pm); 11132 11133 /*TODO: remove this. Necessary because the current libpng 11134 * implementation works in 8 bits: 11135 */ 11136 if (pm->test_gamma_expand16) 11137 pm->calculations_use_input_precision = 1; 11138 for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD; 11139 do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm); 11140 ++do_background) 11141 perform_gamma_composition_tests(pm, do_background, 11142 pm->test_gamma_expand16); 11143 if (!calculations_use_input_precision) 11144 pm->calculations_use_input_precision = 0; 11145 11146 if (summary) 11147 summarize_gamma_errors(pm, "alpha mode", 1, 0/*indexed*/); 11148 11149 if (fail(pm)) 11150 return; 11151 } 11152 #endif 11153 } 11154 #endif /* PNG_READ_GAMMA_SUPPORTED */ 11155 #endif /* PNG_READ_SUPPORTED */ 11156 11157 /* INTERLACE MACRO VALIDATION */ 11158 /* This is copied verbatim from the specification, it is simply the pass 11159 * number in which each pixel in each 8x8 tile appears. The array must 11160 * be indexed adam7[y][x] and notice that the pass numbers are based at 11161 * 1, not 0 - the base libpng uses. 11162 */ 11163 static const 11164 png_byte adam7[8][8] = 11165 { 11166 { 1,6,4,6,2,6,4,6 }, 11167 { 7,7,7,7,7,7,7,7 }, 11168 { 5,6,5,6,5,6,5,6 }, 11169 { 7,7,7,7,7,7,7,7 }, 11170 { 3,6,4,6,3,6,4,6 }, 11171 { 7,7,7,7,7,7,7,7 }, 11172 { 5,6,5,6,5,6,5,6 }, 11173 { 7,7,7,7,7,7,7,7 } 11174 }; 11175 11176 /* This routine validates all the interlace support macros in png.h for 11177 * a variety of valid PNG widths and heights. It uses a number of similarly 11178 * named internal routines that feed off the above array. 11179 */ 11180 static png_uint_32 11181 png_pass_start_row(int pass) 11182 { 11183 int x, y; 11184 ++pass; 11185 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) 11186 return y; 11187 return 0xf; 11188 } 11189 11190 static png_uint_32 11191 png_pass_start_col(int pass) 11192 { 11193 int x, y; 11194 ++pass; 11195 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) 11196 return x; 11197 return 0xf; 11198 } 11199 11200 static int 11201 png_pass_row_shift(int pass) 11202 { 11203 int x, y, base=(-1), inc=8; 11204 ++pass; 11205 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) 11206 { 11207 if (base == (-1)) 11208 base = y; 11209 else if (base == y) 11210 {} 11211 else if (inc == y-base) 11212 base=y; 11213 else if (inc == 8) 11214 inc = y-base, base=y; 11215 else if (inc != y-base) 11216 return 0xff; /* error - more than one 'inc' value! */ 11217 } 11218 11219 if (base == (-1)) return 0xfe; /* error - no row in pass! */ 11220 11221 /* The shift is always 1, 2 or 3 - no pass has all the rows! */ 11222 switch (inc) 11223 { 11224 case 2: return 1; 11225 case 4: return 2; 11226 case 8: return 3; 11227 default: break; 11228 } 11229 11230 /* error - unrecognized 'inc' */ 11231 return (inc << 8) + 0xfd; 11232 } 11233 11234 static int 11235 png_pass_col_shift(int pass) 11236 { 11237 int x, y, base=(-1), inc=8; 11238 ++pass; 11239 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) 11240 { 11241 if (base == (-1)) 11242 base = x; 11243 else if (base == x) 11244 {} 11245 else if (inc == x-base) 11246 base=x; 11247 else if (inc == 8) 11248 inc = x-base, base=x; 11249 else if (inc != x-base) 11250 return 0xff; /* error - more than one 'inc' value! */ 11251 } 11252 11253 if (base == (-1)) return 0xfe; /* error - no row in pass! */ 11254 11255 /* The shift is always 1, 2 or 3 - no pass has all the rows! */ 11256 switch (inc) 11257 { 11258 case 1: return 0; /* pass 7 has all the columns */ 11259 case 2: return 1; 11260 case 4: return 2; 11261 case 8: return 3; 11262 default: break; 11263 } 11264 11265 /* error - unrecognized 'inc' */ 11266 return (inc << 8) + 0xfd; 11267 } 11268 11269 static png_uint_32 11270 png_row_from_pass_row(png_uint_32 yIn, int pass) 11271 { 11272 /* By examination of the array: */ 11273 switch (pass) 11274 { 11275 case 0: return yIn * 8; 11276 case 1: return yIn * 8; 11277 case 2: return yIn * 8 + 4; 11278 case 3: return yIn * 4; 11279 case 4: return yIn * 4 + 2; 11280 case 5: return yIn * 2; 11281 case 6: return yIn * 2 + 1; 11282 default: break; 11283 } 11284 11285 return 0xff; /* bad pass number */ 11286 } 11287 11288 static png_uint_32 11289 png_col_from_pass_col(png_uint_32 xIn, int pass) 11290 { 11291 /* By examination of the array: */ 11292 switch (pass) 11293 { 11294 case 0: return xIn * 8; 11295 case 1: return xIn * 8 + 4; 11296 case 2: return xIn * 4; 11297 case 3: return xIn * 4 + 2; 11298 case 4: return xIn * 2; 11299 case 5: return xIn * 2 + 1; 11300 case 6: return xIn; 11301 default: break; 11302 } 11303 11304 return 0xff; /* bad pass number */ 11305 } 11306 11307 static int 11308 png_row_in_interlace_pass(png_uint_32 y, int pass) 11309 { 11310 /* Is row 'y' in pass 'pass'? */ 11311 int x; 11312 y &= 7; 11313 ++pass; 11314 for (x=0; x<8; ++x) if (adam7[y][x] == pass) 11315 return 1; 11316 11317 return 0; 11318 } 11319 11320 static int 11321 png_col_in_interlace_pass(png_uint_32 x, int pass) 11322 { 11323 /* Is column 'x' in pass 'pass'? */ 11324 int y; 11325 x &= 7; 11326 ++pass; 11327 for (y=0; y<8; ++y) if (adam7[y][x] == pass) 11328 return 1; 11329 11330 return 0; 11331 } 11332 11333 static png_uint_32 11334 png_pass_rows(png_uint_32 height, int pass) 11335 { 11336 png_uint_32 tiles = height>>3; 11337 png_uint_32 rows = 0; 11338 unsigned int x, y; 11339 11340 height &= 7; 11341 ++pass; 11342 for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) 11343 { 11344 rows += tiles; 11345 if (y < height) ++rows; 11346 break; /* i.e. break the 'x', column, loop. */ 11347 } 11348 11349 return rows; 11350 } 11351 11352 static png_uint_32 11353 png_pass_cols(png_uint_32 width, int pass) 11354 { 11355 png_uint_32 tiles = width>>3; 11356 png_uint_32 cols = 0; 11357 unsigned int x, y; 11358 11359 width &= 7; 11360 ++pass; 11361 for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) 11362 { 11363 cols += tiles; 11364 if (x < width) ++cols; 11365 break; /* i.e. break the 'y', row, loop. */ 11366 } 11367 11368 return cols; 11369 } 11370 11371 static void 11372 perform_interlace_macro_validation(void) 11373 { 11374 /* The macros to validate, first those that depend only on pass: 11375 * 11376 * PNG_PASS_START_ROW(pass) 11377 * PNG_PASS_START_COL(pass) 11378 * PNG_PASS_ROW_SHIFT(pass) 11379 * PNG_PASS_COL_SHIFT(pass) 11380 */ 11381 int pass; 11382 11383 for (pass=0; pass<7; ++pass) 11384 { 11385 png_uint_32 m, f, v; 11386 11387 m = PNG_PASS_START_ROW(pass); 11388 f = png_pass_start_row(pass); 11389 if (m != f) 11390 { 11391 fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f); 11392 exit(99); 11393 } 11394 11395 m = PNG_PASS_START_COL(pass); 11396 f = png_pass_start_col(pass); 11397 if (m != f) 11398 { 11399 fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f); 11400 exit(99); 11401 } 11402 11403 m = PNG_PASS_ROW_SHIFT(pass); 11404 f = png_pass_row_shift(pass); 11405 if (m != f) 11406 { 11407 fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f); 11408 exit(99); 11409 } 11410 11411 m = PNG_PASS_COL_SHIFT(pass); 11412 f = png_pass_col_shift(pass); 11413 if (m != f) 11414 { 11415 fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f); 11416 exit(99); 11417 } 11418 11419 /* Macros that depend on the image or sub-image height too: 11420 * 11421 * PNG_PASS_ROWS(height, pass) 11422 * PNG_PASS_COLS(width, pass) 11423 * PNG_ROW_FROM_PASS_ROW(yIn, pass) 11424 * PNG_COL_FROM_PASS_COL(xIn, pass) 11425 * PNG_ROW_IN_INTERLACE_PASS(y, pass) 11426 * PNG_COL_IN_INTERLACE_PASS(x, pass) 11427 */ 11428 for (v=0;;) 11429 { 11430 /* The first two tests overflow if the pass row or column is outside 11431 * the possible range for a 32-bit result. In fact the values should 11432 * never be outside the range for a 31-bit result, but checking for 32 11433 * bits here ensures that if an app uses a bogus pass row or column 11434 * (just so long as it fits in a 32 bit integer) it won't get a 11435 * possibly dangerous overflow. 11436 */ 11437 /* First the base 0 stuff: */ 11438 if (v < png_pass_rows(0xFFFFFFFFU, pass)) 11439 { 11440 m = PNG_ROW_FROM_PASS_ROW(v, pass); 11441 f = png_row_from_pass_row(v, pass); 11442 if (m != f) 11443 { 11444 fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n", 11445 v, pass, m, f); 11446 exit(99); 11447 } 11448 } 11449 11450 if (v < png_pass_cols(0xFFFFFFFFU, pass)) 11451 { 11452 m = PNG_COL_FROM_PASS_COL(v, pass); 11453 f = png_col_from_pass_col(v, pass); 11454 if (m != f) 11455 { 11456 fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n", 11457 v, pass, m, f); 11458 exit(99); 11459 } 11460 } 11461 11462 m = PNG_ROW_IN_INTERLACE_PASS(v, pass); 11463 f = png_row_in_interlace_pass(v, pass); 11464 if (m != f) 11465 { 11466 fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n", 11467 v, pass, m, f); 11468 exit(99); 11469 } 11470 11471 m = PNG_COL_IN_INTERLACE_PASS(v, pass); 11472 f = png_col_in_interlace_pass(v, pass); 11473 if (m != f) 11474 { 11475 fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n", 11476 v, pass, m, f); 11477 exit(99); 11478 } 11479 11480 /* Then the base 1 stuff: */ 11481 ++v; 11482 m = PNG_PASS_ROWS(v, pass); 11483 f = png_pass_rows(v, pass); 11484 if (m != f) 11485 { 11486 fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n", 11487 v, pass, m, f); 11488 exit(99); 11489 } 11490 11491 m = PNG_PASS_COLS(v, pass); 11492 f = png_pass_cols(v, pass); 11493 if (m != f) 11494 { 11495 fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n", 11496 v, pass, m, f); 11497 exit(99); 11498 } 11499 11500 /* Move to the next v - the stepping algorithm starts skipping 11501 * values above 1024. 11502 */ 11503 if (v > 1024) 11504 { 11505 if (v == PNG_UINT_31_MAX) 11506 break; 11507 11508 v = (v << 1) ^ v; 11509 if (v >= PNG_UINT_31_MAX) 11510 v = PNG_UINT_31_MAX-1; 11511 } 11512 } 11513 } 11514 } 11515 11516 /* Test color encodings. These values are back-calculated from the published 11517 * chromaticities. The values are accurate to about 14 decimal places; 15 are 11518 * given. These values are much more accurate than the ones given in the spec, 11519 * which typically don't exceed 4 decimal places. This allows testing of the 11520 * libpng code to its theoretical accuracy of 4 decimal places. (If pngvalid 11521 * used the published errors the 'slack' permitted would have to be +/-.5E-4 or 11522 * more.) 11523 * 11524 * The png_modifier code assumes that encodings[0] is sRGB and treats it 11525 * specially: do not change the first entry in this list! 11526 */ 11527 static const color_encoding test_encodings[] = 11528 { 11529 /* sRGB: must be first in this list! */ 11530 /*gamma:*/ { 1/2.2, 11531 /*red: */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 }, 11532 /*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 }, 11533 /*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} }, 11534 /* Kodak ProPhoto (wide gamut) */ 11535 /*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/, 11536 /*red: */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 }, 11537 /*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 }, 11538 /*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} }, 11539 /* Adobe RGB (1998) */ 11540 /*gamma:*/ { 1/(2+51./256), 11541 /*red: */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 }, 11542 /*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 }, 11543 /*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} }, 11544 /* Adobe Wide Gamut RGB */ 11545 /*gamma:*/ { 1/(2+51./256), 11546 /*red: */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 }, 11547 /*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 }, 11548 /*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} }, 11549 /* Fake encoding which selects just the green channel */ 11550 /*gamma:*/ { 1.45/2.2, /* the 'Mac' gamma */ 11551 /*red: */ { 0.716500716779386, 0.000000000000000, 0.000000000000000 }, 11552 /*green:*/ { 0.101020574397477, 1.000000000000000, 0.051211818965388 }, 11553 /*blue: */ { 0.146774385252705, 0.000000000000000, 0.773892783545073} }, 11554 }; 11555 11556 /* signal handler 11557 * 11558 * This attempts to trap signals and escape without crashing. It needs a 11559 * context pointer so that it can throw an exception (call longjmp) to recover 11560 * from the condition; this is handled by making the png_modifier used by 'main' 11561 * into a global variable. 11562 */ 11563 static png_modifier pm; 11564 11565 static void signal_handler(int signum) 11566 { 11567 11568 size_t pos = 0; 11569 char msg[64]; 11570 11571 pos = safecat(msg, sizeof msg, pos, "caught signal: "); 11572 11573 switch (signum) 11574 { 11575 case SIGABRT: 11576 pos = safecat(msg, sizeof msg, pos, "abort"); 11577 break; 11578 11579 case SIGFPE: 11580 pos = safecat(msg, sizeof msg, pos, "floating point exception"); 11581 break; 11582 11583 case SIGILL: 11584 pos = safecat(msg, sizeof msg, pos, "illegal instruction"); 11585 break; 11586 11587 case SIGINT: 11588 pos = safecat(msg, sizeof msg, pos, "interrupt"); 11589 break; 11590 11591 case SIGSEGV: 11592 pos = safecat(msg, sizeof msg, pos, "invalid memory access"); 11593 break; 11594 11595 case SIGTERM: 11596 pos = safecat(msg, sizeof msg, pos, "termination request"); 11597 break; 11598 11599 default: 11600 pos = safecat(msg, sizeof msg, pos, "unknown "); 11601 pos = safecatn(msg, sizeof msg, pos, signum); 11602 break; 11603 } 11604 11605 store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/); 11606 11607 /* And finally throw an exception so we can keep going, unless this is 11608 * SIGTERM in which case stop now. 11609 */ 11610 if (signum != SIGTERM) 11611 { 11612 struct exception_context *the_exception_context = 11613 &pm.this.exception_context; 11614 11615 Throw &pm.this; 11616 } 11617 11618 else 11619 exit(1); 11620 } 11621 11622 /* main program */ 11623 int main(int argc, char **argv) 11624 { 11625 int summary = 1; /* Print the error summary at the end */ 11626 int memstats = 0; /* Print memory statistics at the end */ 11627 11628 /* Create the given output file on success: */ 11629 const char *touch = NULL; 11630 11631 /* This is an array of standard gamma values (believe it or not I've seen 11632 * every one of these mentioned somewhere.) 11633 * 11634 * In the following list the most useful values are first! 11635 */ 11636 static double 11637 gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9}; 11638 11639 /* This records the command and arguments: */ 11640 size_t cp = 0; 11641 char command[1024]; 11642 11643 anon_context(&pm.this); 11644 11645 gnu_volatile(summary) 11646 gnu_volatile(memstats) 11647 gnu_volatile(touch) 11648 11649 /* Add appropriate signal handlers, just the ANSI specified ones: */ 11650 signal(SIGABRT, signal_handler); 11651 signal(SIGFPE, signal_handler); 11652 signal(SIGILL, signal_handler); 11653 signal(SIGINT, signal_handler); 11654 signal(SIGSEGV, signal_handler); 11655 signal(SIGTERM, signal_handler); 11656 11657 #ifdef HAVE_FEENABLEEXCEPT 11658 /* Only required to enable FP exceptions on platforms where they start off 11659 * disabled; this is not necessary but if it is not done pngvalid will likely 11660 * end up ignoring FP conditions that other platforms fault. 11661 */ 11662 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); 11663 #endif 11664 11665 modifier_init(&pm); 11666 11667 /* Preallocate the image buffer, because we know how big it needs to be, 11668 * note that, for testing purposes, it is deliberately mis-aligned by tag 11669 * bytes either side. All rows have an additional five bytes of padding for 11670 * overwrite checking. 11671 */ 11672 store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX); 11673 11674 /* Don't give argv[0], it's normally some horrible libtool string: */ 11675 cp = safecat(command, sizeof command, cp, "pngvalid"); 11676 11677 /* Default to error on warning: */ 11678 pm.this.treat_warnings_as_errors = 1; 11679 11680 /* Default assume_16_bit_calculations appropriately; this tells the checking 11681 * code that 16-bit arithmetic is used for 8-bit samples when it would make a 11682 * difference. 11683 */ 11684 pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700; 11685 11686 /* Currently 16 bit expansion happens at the end of the pipeline, so the 11687 * calculations are done in the input bit depth not the output. 11688 * 11689 * TODO: fix this 11690 */ 11691 pm.calculations_use_input_precision = 1U; 11692 11693 /* Store the test gammas */ 11694 pm.gammas = gammas; 11695 pm.ngammas = ARRAY_SIZE(gammas); 11696 pm.ngamma_tests = 0; /* default to off */ 11697 11698 /* Low bit depth gray images don't do well in the gamma tests, until 11699 * this is fixed turn them off for some gamma cases: 11700 */ 11701 # ifdef PNG_WRITE_tRNS_SUPPORTED 11702 pm.test_tRNS = 1; 11703 # endif 11704 pm.test_lbg = PNG_LIBPNG_VER >= 10600; 11705 pm.test_lbg_gamma_threshold = 1; 11706 pm.test_lbg_gamma_transform = PNG_LIBPNG_VER >= 10600; 11707 pm.test_lbg_gamma_sbit = 1; 11708 pm.test_lbg_gamma_composition = PNG_LIBPNG_VER >= 10700; 11709 11710 /* And the test encodings */ 11711 pm.encodings = test_encodings; 11712 pm.nencodings = ARRAY_SIZE(test_encodings); 11713 11714 # if PNG_LIBPNG_VER < 10700 11715 pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */ 11716 # else 11717 pm.sbitlow = 1U; 11718 # endif 11719 11720 /* The following allows results to pass if they correspond to anything in the 11721 * transformed range [input-.5,input+.5]; this is is required because of the 11722 * way libpng treates the 16_TO_8 flag when building the gamma tables in 11723 * releases up to 1.6.0. 11724 * 11725 * TODO: review this 11726 */ 11727 pm.use_input_precision_16to8 = 1U; 11728 pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */ 11729 11730 /* Some default values (set the behavior for 'make check' here). 11731 * These values simply control the maximum error permitted in the gamma 11732 * transformations. The practial limits for human perception are described 11733 * below (the setting for maxpc16), however for 8 bit encodings it isn't 11734 * possible to meet the accepted capabilities of human vision - i.e. 8 bit 11735 * images can never be good enough, regardless of encoding. 11736 */ 11737 pm.maxout8 = .1; /* Arithmetic error in *encoded* value */ 11738 pm.maxabs8 = .00005; /* 1/20000 */ 11739 pm.maxcalc8 = 1./255; /* +/-1 in 8 bits for compose errors */ 11740 pm.maxpc8 = .499; /* I.e., .499% fractional error */ 11741 pm.maxout16 = .499; /* Error in *encoded* value */ 11742 pm.maxabs16 = .00005;/* 1/20000 */ 11743 pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */ 11744 # if PNG_LIBPNG_VER < 10700 11745 pm.maxcalcG = 1./((1<<PNG_MAX_GAMMA_8)-1); 11746 # else 11747 pm.maxcalcG = 1./((1<<16)-1); 11748 # endif 11749 11750 /* NOTE: this is a reasonable perceptual limit. We assume that humans can 11751 * perceive light level differences of 1% over a 100:1 range, so we need to 11752 * maintain 1 in 10000 accuracy (in linear light space), which is what the 11753 * following guarantees. It also allows significantly higher errors at 11754 * higher 16 bit values, which is important for performance. The actual 11755 * maximum 16 bit error is about +/-1.9 in the fixed point implementation but 11756 * this is only allowed for values >38149 by the following: 11757 */ 11758 pm.maxpc16 = .005; /* I.e., 1/200% - 1/20000 */ 11759 11760 /* Now parse the command line options. */ 11761 while (--argc >= 1) 11762 { 11763 int catmore = 0; /* Set if the argument has an argument. */ 11764 11765 /* Record each argument for posterity: */ 11766 cp = safecat(command, sizeof command, cp, " "); 11767 cp = safecat(command, sizeof command, cp, *++argv); 11768 11769 if (strcmp(*argv, "-v") == 0) 11770 pm.this.verbose = 1; 11771 11772 else if (strcmp(*argv, "-l") == 0) 11773 pm.log = 1; 11774 11775 else if (strcmp(*argv, "-q") == 0) 11776 summary = pm.this.verbose = pm.log = 0; 11777 11778 else if (strcmp(*argv, "-w") == 0 || 11779 strcmp(*argv, "--strict") == 0) 11780 pm.this.treat_warnings_as_errors = 1; /* NOTE: this is the default! */ 11781 11782 else if (strcmp(*argv, "--nostrict") == 0) 11783 pm.this.treat_warnings_as_errors = 0; 11784 11785 else if (strcmp(*argv, "--speed") == 0) 11786 pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0, 11787 summary = 0; 11788 11789 else if (strcmp(*argv, "--memory") == 0) 11790 memstats = 1; 11791 11792 else if (strcmp(*argv, "--size") == 0) 11793 pm.test_size = 1; 11794 11795 else if (strcmp(*argv, "--nosize") == 0) 11796 pm.test_size = 0; 11797 11798 else if (strcmp(*argv, "--standard") == 0) 11799 pm.test_standard = 1; 11800 11801 else if (strcmp(*argv, "--nostandard") == 0) 11802 pm.test_standard = 0; 11803 11804 else if (strcmp(*argv, "--transform") == 0) 11805 pm.test_transform = 1; 11806 11807 else if (strcmp(*argv, "--notransform") == 0) 11808 pm.test_transform = 0; 11809 11810 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 11811 else if (strncmp(*argv, "--transform-disable=", 11812 sizeof "--transform-disable") == 0) 11813 { 11814 pm.test_transform = 1; 11815 transform_disable(*argv + sizeof "--transform-disable"); 11816 } 11817 11818 else if (strncmp(*argv, "--transform-enable=", 11819 sizeof "--transform-enable") == 0) 11820 { 11821 pm.test_transform = 1; 11822 transform_enable(*argv + sizeof "--transform-enable"); 11823 } 11824 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 11825 11826 else if (strcmp(*argv, "--gamma") == 0) 11827 { 11828 /* Just do two gamma tests here (2.2 and linear) for speed: */ 11829 pm.ngamma_tests = 2U; 11830 pm.test_gamma_threshold = 1; 11831 pm.test_gamma_transform = 1; 11832 pm.test_gamma_sbit = 1; 11833 pm.test_gamma_scale16 = 1; 11834 pm.test_gamma_background = 1; /* composition */ 11835 pm.test_gamma_alpha_mode = 1; 11836 } 11837 11838 else if (strcmp(*argv, "--nogamma") == 0) 11839 pm.ngamma_tests = 0; 11840 11841 else if (strcmp(*argv, "--gamma-threshold") == 0) 11842 pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1; 11843 11844 else if (strcmp(*argv, "--nogamma-threshold") == 0) 11845 pm.test_gamma_threshold = 0; 11846 11847 else if (strcmp(*argv, "--gamma-transform") == 0) 11848 pm.ngamma_tests = 2U, pm.test_gamma_transform = 1; 11849 11850 else if (strcmp(*argv, "--nogamma-transform") == 0) 11851 pm.test_gamma_transform = 0; 11852 11853 else if (strcmp(*argv, "--gamma-sbit") == 0) 11854 pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1; 11855 11856 else if (strcmp(*argv, "--nogamma-sbit") == 0) 11857 pm.test_gamma_sbit = 0; 11858 11859 else if (strcmp(*argv, "--gamma-16-to-8") == 0) 11860 pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1; 11861 11862 else if (strcmp(*argv, "--nogamma-16-to-8") == 0) 11863 pm.test_gamma_scale16 = 0; 11864 11865 else if (strcmp(*argv, "--gamma-background") == 0) 11866 pm.ngamma_tests = 2U, pm.test_gamma_background = 1; 11867 11868 else if (strcmp(*argv, "--nogamma-background") == 0) 11869 pm.test_gamma_background = 0; 11870 11871 else if (strcmp(*argv, "--gamma-alpha-mode") == 0) 11872 pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1; 11873 11874 else if (strcmp(*argv, "--nogamma-alpha-mode") == 0) 11875 pm.test_gamma_alpha_mode = 0; 11876 11877 else if (strcmp(*argv, "--expand16") == 0) 11878 pm.test_gamma_expand16 = 1; 11879 11880 else if (strcmp(*argv, "--noexpand16") == 0) 11881 pm.test_gamma_expand16 = 0; 11882 11883 else if (strcmp(*argv, "--low-depth-gray") == 0) 11884 pm.test_lbg = pm.test_lbg_gamma_threshold = 11885 pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit = 11886 pm.test_lbg_gamma_composition = 1; 11887 11888 else if (strcmp(*argv, "--nolow-depth-gray") == 0) 11889 pm.test_lbg = pm.test_lbg_gamma_threshold = 11890 pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit = 11891 pm.test_lbg_gamma_composition = 0; 11892 11893 # ifdef PNG_WRITE_tRNS_SUPPORTED 11894 else if (strcmp(*argv, "--tRNS") == 0) 11895 pm.test_tRNS = 1; 11896 # endif 11897 11898 else if (strcmp(*argv, "--notRNS") == 0) 11899 pm.test_tRNS = 0; 11900 11901 else if (strcmp(*argv, "--more-gammas") == 0) 11902 pm.ngamma_tests = 3U; 11903 11904 else if (strcmp(*argv, "--all-gammas") == 0) 11905 pm.ngamma_tests = pm.ngammas; 11906 11907 else if (strcmp(*argv, "--progressive-read") == 0) 11908 pm.this.progressive = 1; 11909 11910 else if (strcmp(*argv, "--use-update-info") == 0) 11911 ++pm.use_update_info; /* Can call multiple times */ 11912 11913 else if (strcmp(*argv, "--interlace") == 0) 11914 { 11915 # if CAN_WRITE_INTERLACE 11916 pm.interlace_type = PNG_INTERLACE_ADAM7; 11917 # else /* !CAN_WRITE_INTERLACE */ 11918 fprintf(stderr, "pngvalid: no write interlace support\n"); 11919 return SKIP; 11920 # endif /* !CAN_WRITE_INTERLACE */ 11921 } 11922 11923 else if (strcmp(*argv, "--use-input-precision") == 0) 11924 pm.use_input_precision = 1U; 11925 11926 else if (strcmp(*argv, "--use-calculation-precision") == 0) 11927 pm.use_input_precision = 0; 11928 11929 else if (strcmp(*argv, "--calculations-use-input-precision") == 0) 11930 pm.calculations_use_input_precision = 1U; 11931 11932 else if (strcmp(*argv, "--assume-16-bit-calculations") == 0) 11933 pm.assume_16_bit_calculations = 1U; 11934 11935 else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0) 11936 pm.calculations_use_input_precision = 11937 pm.assume_16_bit_calculations = 0; 11938 11939 else if (strcmp(*argv, "--exhaustive") == 0) 11940 pm.test_exhaustive = 1; 11941 11942 else if (argc > 1 && strcmp(*argv, "--sbitlow") == 0) 11943 --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1; 11944 11945 else if (argc > 1 && strcmp(*argv, "--touch") == 0) 11946 --argc, touch = *++argv, catmore = 1; 11947 11948 else if (argc > 1 && strncmp(*argv, "--max", 5) == 0) 11949 { 11950 --argc; 11951 11952 if (strcmp(5+*argv, "abs8") == 0) 11953 pm.maxabs8 = atof(*++argv); 11954 11955 else if (strcmp(5+*argv, "abs16") == 0) 11956 pm.maxabs16 = atof(*++argv); 11957 11958 else if (strcmp(5+*argv, "calc8") == 0) 11959 pm.maxcalc8 = atof(*++argv); 11960 11961 else if (strcmp(5+*argv, "calc16") == 0) 11962 pm.maxcalc16 = atof(*++argv); 11963 11964 else if (strcmp(5+*argv, "out8") == 0) 11965 pm.maxout8 = atof(*++argv); 11966 11967 else if (strcmp(5+*argv, "out16") == 0) 11968 pm.maxout16 = atof(*++argv); 11969 11970 else if (strcmp(5+*argv, "pc8") == 0) 11971 pm.maxpc8 = atof(*++argv); 11972 11973 else if (strcmp(5+*argv, "pc16") == 0) 11974 pm.maxpc16 = atof(*++argv); 11975 11976 else 11977 { 11978 fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv); 11979 exit(99); 11980 } 11981 11982 catmore = 1; 11983 } 11984 11985 else if (strcmp(*argv, "--log8") == 0) 11986 --argc, pm.log8 = atof(*++argv), catmore = 1; 11987 11988 else if (strcmp(*argv, "--log16") == 0) 11989 --argc, pm.log16 = atof(*++argv), catmore = 1; 11990 11991 #ifdef PNG_SET_OPTION_SUPPORTED 11992 else if (strncmp(*argv, "--option=", 9) == 0) 11993 { 11994 /* Syntax of the argument is <option>:{on|off} */ 11995 const char *arg = 9+*argv; 11996 unsigned char option=0, setting=0; 11997 11998 #ifdef PNG_ARM_NEON 11999 if (strncmp(arg, "arm-neon:", 9) == 0) 12000 option = PNG_ARM_NEON, arg += 9; 12001 12002 else 12003 #endif 12004 #ifdef PNG_EXTENSIONS 12005 if (strncmp(arg, "extensions:", 11) == 0) 12006 option = PNG_EXTENSIONS, arg += 11; 12007 12008 else 12009 #endif 12010 #ifdef PNG_MAXIMUM_INFLATE_WINDOW 12011 if (strncmp(arg, "max-inflate-window:", 19) == 0) 12012 option = PNG_MAXIMUM_INFLATE_WINDOW, arg += 19; 12013 12014 else 12015 #endif 12016 { 12017 fprintf(stderr, "pngvalid: %s: %s: unknown option\n", *argv, arg); 12018 exit(99); 12019 } 12020 12021 if (strcmp(arg, "off") == 0) 12022 setting = PNG_OPTION_OFF; 12023 12024 else if (strcmp(arg, "on") == 0) 12025 setting = PNG_OPTION_ON; 12026 12027 else 12028 { 12029 fprintf(stderr, 12030 "pngvalid: %s: %s: unknown setting (use 'on' or 'off')\n", 12031 *argv, arg); 12032 exit(99); 12033 } 12034 12035 pm.this.options[pm.this.noptions].option = option; 12036 pm.this.options[pm.this.noptions++].setting = setting; 12037 } 12038 #endif /* PNG_SET_OPTION_SUPPORTED */ 12039 12040 else 12041 { 12042 fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv); 12043 exit(99); 12044 } 12045 12046 if (catmore) /* consumed an extra *argv */ 12047 { 12048 cp = safecat(command, sizeof command, cp, " "); 12049 cp = safecat(command, sizeof command, cp, *argv); 12050 } 12051 } 12052 12053 /* If pngvalid is run with no arguments default to a reasonable set of the 12054 * tests. 12055 */ 12056 if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 && 12057 pm.ngamma_tests == 0) 12058 { 12059 /* Make this do all the tests done in the test shell scripts with the same 12060 * parameters, where possible. The limitation is that all the progressive 12061 * read and interlace stuff has to be done in separate runs, so only the 12062 * basic 'standard' and 'size' tests are done. 12063 */ 12064 pm.test_standard = 1; 12065 pm.test_size = 1; 12066 pm.test_transform = 1; 12067 pm.ngamma_tests = 2U; 12068 } 12069 12070 if (pm.ngamma_tests > 0 && 12071 pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 && 12072 pm.test_gamma_sbit == 0 && pm.test_gamma_scale16 == 0 && 12073 pm.test_gamma_background == 0 && pm.test_gamma_alpha_mode == 0) 12074 { 12075 pm.test_gamma_threshold = 1; 12076 pm.test_gamma_transform = 1; 12077 pm.test_gamma_sbit = 1; 12078 pm.test_gamma_scale16 = 1; 12079 pm.test_gamma_background = 1; 12080 pm.test_gamma_alpha_mode = 1; 12081 } 12082 12083 else if (pm.ngamma_tests == 0) 12084 { 12085 /* Nothing to test so turn everything off: */ 12086 pm.test_gamma_threshold = 0; 12087 pm.test_gamma_transform = 0; 12088 pm.test_gamma_sbit = 0; 12089 pm.test_gamma_scale16 = 0; 12090 pm.test_gamma_background = 0; 12091 pm.test_gamma_alpha_mode = 0; 12092 } 12093 12094 Try 12095 { 12096 /* Make useful base images */ 12097 make_transform_images(&pm); 12098 12099 /* Perform the standard and gamma tests. */ 12100 if (pm.test_standard) 12101 { 12102 perform_interlace_macro_validation(); 12103 perform_formatting_test(&pm.this); 12104 # ifdef PNG_READ_SUPPORTED 12105 perform_standard_test(&pm); 12106 # endif 12107 perform_error_test(&pm); 12108 } 12109 12110 /* Various oddly sized images: */ 12111 if (pm.test_size) 12112 { 12113 make_size_images(&pm.this); 12114 # ifdef PNG_READ_SUPPORTED 12115 perform_size_test(&pm); 12116 # endif 12117 } 12118 12119 #ifdef PNG_READ_TRANSFORMS_SUPPORTED 12120 /* Combinatorial transforms: */ 12121 if (pm.test_transform) 12122 perform_transform_test(&pm); 12123 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ 12124 12125 #ifdef PNG_READ_GAMMA_SUPPORTED 12126 if (pm.ngamma_tests > 0) 12127 perform_gamma_test(&pm, summary); 12128 #endif 12129 } 12130 12131 Catch_anonymous 12132 { 12133 fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n"); 12134 if (!pm.this.verbose) 12135 { 12136 if (pm.this.error[0] != 0) 12137 fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error); 12138 12139 fprintf(stderr, "pngvalid: run with -v to see what happened\n"); 12140 } 12141 exit(1); 12142 } 12143 12144 if (summary) 12145 { 12146 printf("%s: %s (%s point arithmetic)\n", 12147 (pm.this.nerrors || (pm.this.treat_warnings_as_errors && 12148 pm.this.nwarnings)) ? "FAIL" : "PASS", 12149 command, 12150 #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500 12151 "floating" 12152 #else 12153 "fixed" 12154 #endif 12155 ); 12156 } 12157 12158 if (memstats) 12159 { 12160 printf("Allocated memory statistics (in bytes):\n" 12161 "\tread %lu maximum single, %lu peak, %lu total\n" 12162 "\twrite %lu maximum single, %lu peak, %lu total\n", 12163 (unsigned long)pm.this.read_memory_pool.max_max, 12164 (unsigned long)pm.this.read_memory_pool.max_limit, 12165 (unsigned long)pm.this.read_memory_pool.max_total, 12166 (unsigned long)pm.this.write_memory_pool.max_max, 12167 (unsigned long)pm.this.write_memory_pool.max_limit, 12168 (unsigned long)pm.this.write_memory_pool.max_total); 12169 } 12170 12171 /* Do this here to provoke memory corruption errors in memory not directly 12172 * allocated by libpng - not a complete test, but better than nothing. 12173 */ 12174 store_delete(&pm.this); 12175 12176 /* Error exit if there are any errors, and maybe if there are any 12177 * warnings. 12178 */ 12179 if (pm.this.nerrors || (pm.this.treat_warnings_as_errors && 12180 pm.this.nwarnings)) 12181 { 12182 if (!pm.this.verbose) 12183 fprintf(stderr, "pngvalid: %s\n", pm.this.error); 12184 12185 fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors, 12186 pm.this.nwarnings); 12187 12188 exit(1); 12189 } 12190 12191 /* Success case. */ 12192 if (touch != NULL) 12193 { 12194 FILE *fsuccess = fopen(touch, "wt"); 12195 12196 if (fsuccess != NULL) 12197 { 12198 int error = 0; 12199 fprintf(fsuccess, "PNG validation succeeded\n"); 12200 fflush(fsuccess); 12201 error = ferror(fsuccess); 12202 12203 if (fclose(fsuccess) || error) 12204 { 12205 fprintf(stderr, "%s: write failed\n", touch); 12206 exit(1); 12207 } 12208 } 12209 12210 else 12211 { 12212 fprintf(stderr, "%s: open failed\n", touch); 12213 exit(1); 12214 } 12215 } 12216 12217 /* This is required because some very minimal configurations do not use it: 12218 */ 12219 UNUSED(fail) 12220 return 0; 12221 } 12222 #else /* write or low level APIs not supported */ 12223 int main(void) 12224 { 12225 fprintf(stderr, 12226 "pngvalid: no low level write support in libpng, all tests skipped\n"); 12227 /* So the test is skipped: */ 12228 return SKIP; 12229 } 12230 #endif 12231