Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6709 lines
198 KiB

  1. /* pngvalid.c - validate libpng by constructing then reading png files.
  2. *
  3. * Last changed in libpng 1.5.2 [March 31, 2011]
  4. * Copyright (c) 2011 Glenn Randers-Pehrson
  5. * Written by 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. #include "png.h"
  21. #if PNG_LIBPNG_VER < 10500
  22. /* This delibarately lacks the PNG_CONST. */
  23. typedef png_byte *png_const_bytep;
  24. /* This is copied from 1.5.1 png.h: */
  25. #define PNG_INTERLACE_ADAM7_PASSES 7
  26. #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
  27. #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
  28. #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
  29. #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
  30. #define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
  31. -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
  32. #define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
  33. -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
  34. #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
  35. (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
  36. #define PNG_COL_FROM_PASS_COL(xIn, pass) \
  37. (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
  38. #define PNG_PASS_MASK(pass,off) ( \
  39. ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
  40. ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
  41. #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
  42. ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
  43. #define PNG_COL_IN_INTERLACE_PASS(x, pass) \
  44. ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
  45. /* These are needed too for the defualt build: */
  46. #define PNG_WRITE_16BIT_SUPPORTED
  47. #define PNG_READ_16BIT_SUPPORTED
  48. #endif
  49. #include "zlib.h" /* For crc32 */
  50. #include <float.h> /* For floating point constants */
  51. #include <stdlib.h> /* For malloc */
  52. #include <string.h> /* For memcpy, memset */
  53. #include <math.h> /* For floor */
  54. /* Unused formal parameter errors are removed using the following macro which is
  55. * expected to have no bad effects on performance.
  56. */
  57. #ifndef UNUSED
  58. # if defined(__GNUC__) || defined(_MSC_VER)
  59. # define UNUSED(param) (void)param;
  60. # else
  61. # define UNUSED(param)
  62. # endif
  63. #endif
  64. /***************************** EXCEPTION HANDLING *****************************/
  65. #include "contrib/visupng/cexcept.h"
  66. struct png_store;
  67. define_exception_type(struct png_store*);
  68. /* The following are macros to reduce typing everywhere where the well known
  69. * name 'the_exception_context' must be defined.
  70. */
  71. #define anon_context(ps) struct exception_context *the_exception_context = \
  72. &(ps)->exception_context
  73. #define context(ps,fault) anon_context(ps); png_store *fault
  74. /******************************* UTILITIES ************************************/
  75. /* Error handling is particularly problematic in production code - error
  76. * handlers often themselves have bugs which lead to programs that detect
  77. * minor errors crashing. The following functions deal with one very
  78. * common class of errors in error handlers - attempting to format error or
  79. * warning messages into buffers that are too small.
  80. */
  81. static size_t safecat(char *buffer, size_t bufsize, size_t pos,
  82. PNG_CONST char *cat)
  83. {
  84. while (pos < bufsize && cat != NULL && *cat != 0)
  85. buffer[pos++] = *cat++;
  86. if (pos >= bufsize)
  87. pos = bufsize-1;
  88. buffer[pos] = 0;
  89. return pos;
  90. }
  91. static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)
  92. {
  93. char number[64];
  94. sprintf(number, "%d", n);
  95. return safecat(buffer, bufsize, pos, number);
  96. }
  97. static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,
  98. int precision)
  99. {
  100. char number[64];
  101. sprintf(number, "%.*f", precision, d);
  102. return safecat(buffer, bufsize, pos, number);
  103. }
  104. static PNG_CONST char invalid[] = "invalid";
  105. static PNG_CONST char sep[] = ": ";
  106. /* NOTE: this is indexed by ln2(bit_depth)! */
  107. static PNG_CONST char *bit_depths[8] =
  108. {
  109. "1", "2", "4", "8", "16", invalid, invalid, invalid
  110. };
  111. static PNG_CONST char *colour_types[8] =
  112. {
  113. "greyscale", invalid, "truecolour", "indexed-colour",
  114. "greyscale with alpha", invalid, "truecolour with alpha", invalid
  115. };
  116. /* To get log-bit-depth from bit depth, returns 0 to 7 (7 on error). */
  117. static unsigned int
  118. log2depth(png_byte bit_depth)
  119. {
  120. switch (bit_depth)
  121. {
  122. case 1:
  123. return 0;
  124. case 2:
  125. return 1;
  126. case 4:
  127. return 2;
  128. case 8:
  129. return 3;
  130. case 16:
  131. return 4;
  132. default:
  133. return 7;
  134. }
  135. }
  136. /* A numeric ID based on PNG file characteristics. The 'do_interlace' field
  137. * simply records whether pngvalid did the interlace itself or whether it
  138. * was done by libpng. Width and height must be less than 256.
  139. */
  140. #define FILEID(col, depth, interlace, width, height, do_interlace) \
  141. ((png_uint_32)((col) + ((depth)<<3) + ((interlace)<<8) + \
  142. (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))
  143. #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
  144. #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
  145. #define INTERLACE_FROM_ID(id) ((int)(((id) >> 8) & 0x3))
  146. #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
  147. #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
  148. #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
  149. /* Utility to construct a standard name for a standard image. */
  150. static size_t
  151. standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
  152. int log_bit_depth, int interlace_type, png_uint_32 w, png_uint_32 h,
  153. int do_interlace)
  154. {
  155. pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
  156. pos = safecat(buffer, bufsize, pos, " ");
  157. pos = safecat(buffer, bufsize, pos, bit_depths[log_bit_depth]);
  158. pos = safecat(buffer, bufsize, pos, " bit ");
  159. if (interlace_type != PNG_INTERLACE_NONE)
  160. pos = safecat(buffer, bufsize, pos, "interlaced");
  161. if (do_interlace)
  162. pos = safecat(buffer, bufsize, pos, "(pngvalid)");
  163. else
  164. pos = safecat(buffer, bufsize, pos, "(libpng)");
  165. if (w > 0 || h > 0)
  166. {
  167. pos = safecat(buffer, bufsize, pos, " ");
  168. pos = safecatn(buffer, bufsize, pos, w);
  169. pos = safecat(buffer, bufsize, pos, "x");
  170. pos = safecatn(buffer, bufsize, pos, h);
  171. }
  172. return pos;
  173. }
  174. static size_t
  175. standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
  176. {
  177. return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),
  178. log2depth(DEPTH_FROM_ID(id)), INTERLACE_FROM_ID(id),
  179. WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));
  180. }
  181. /* Convenience API and defines to list valid formats. Note that 16 bit read and
  182. * write support is required to do 16 bit read tests (we must be able to make a
  183. * 16 bit image to test!)
  184. */
  185. #ifdef PNG_WRITE_16BIT_SUPPORTED
  186. # define WRITE_BDHI 4
  187. # ifdef PNG_READ_16BIT_SUPPORTED
  188. # define READ_BDHI 4
  189. # define DO_16BIT
  190. # endif
  191. #else
  192. # define WRITE_BDHI 3
  193. #endif
  194. #ifndef DO_16BIT
  195. # define READ_BDHI 3
  196. #endif
  197. static int
  198. next_format(png_bytep colour_type, png_bytep bit_depth)
  199. {
  200. if (*bit_depth == 0)
  201. {
  202. *colour_type = 0, *bit_depth = 1;
  203. return 1;
  204. }
  205. *bit_depth = (png_byte)(*bit_depth << 1);
  206. /* Palette images are restricted to 8 bit depth */
  207. if (*bit_depth <= 8
  208. # ifdef DO_16BIT
  209. || (*colour_type != 3 && *bit_depth <= 16)
  210. # endif
  211. )
  212. return 1;
  213. /* Move to the next color type, or return 0 at the end. */
  214. switch (*colour_type)
  215. {
  216. case 0:
  217. *colour_type = 2;
  218. *bit_depth = 8;
  219. return 1;
  220. case 2:
  221. *colour_type = 3;
  222. *bit_depth = 1;
  223. return 1;
  224. case 3:
  225. *colour_type = 4;
  226. *bit_depth = 8;
  227. return 1;
  228. case 4:
  229. *colour_type = 6;
  230. *bit_depth = 8;
  231. return 1;
  232. default:
  233. return 0;
  234. }
  235. }
  236. static unsigned int
  237. sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
  238. png_uint_32 x, unsigned int sample_index)
  239. {
  240. png_uint_32 bit_index, result;
  241. /* Find a sample index for the desired sample: */
  242. x *= bit_depth;
  243. bit_index = x;
  244. if ((colour_type & 1) == 0) /* !palette */
  245. {
  246. if (colour_type & 2)
  247. bit_index *= 3;
  248. if (colour_type & 4)
  249. bit_index += x; /* Alpha channel */
  250. if (colour_type & (2+4))
  251. bit_index += sample_index * bit_depth; /* Multiple channels: select one */
  252. }
  253. /* Return the sample from the row as an integer. */
  254. row += bit_index >> 3;
  255. result = *row;
  256. if (bit_depth == 8)
  257. return result;
  258. else if (bit_depth > 8)
  259. return (result << 8) + *++row;
  260. /* Less than 8 bits per sample. */
  261. bit_index &= 7;
  262. return (result >> (8-bit_index-bit_depth)) & ((1U<<bit_depth)-1);
  263. }
  264. /* Copy a single pixel, of a given size, from one buffer to another -
  265. * while this is basically bit addressed there is an implicit assumption
  266. * that pixels 8 or more bits in size are byte aligned and that pixels
  267. * do not otherwise cross byte boundaries. (This is, so far as I know,
  268. * universally true in bitmap computer graphics. [JCB 20101212])
  269. *
  270. * NOTE: The to and from buffers may be the same.
  271. */
  272. static void
  273. pixel_copy(png_bytep toBuffer, png_uint_32 toIndex,
  274. png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize)
  275. {
  276. /* Assume we can multiply by 'size' without overflow because we are
  277. * just working in a single buffer.
  278. */
  279. toIndex *= pixelSize;
  280. fromIndex *= pixelSize;
  281. if (pixelSize < 8) /* Sub-byte */
  282. {
  283. /* Mask to select the location of the copied pixel: */
  284. unsigned int destMask = ((1U<<pixelSize)-1) << (8-pixelSize-(toIndex&7));
  285. /* The following read the entire pixels and clears the extra: */
  286. unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;
  287. unsigned int sourceByte = fromBuffer[fromIndex >> 3];
  288. /* Don't rely on << or >> supporting '0' here, just in case: */
  289. fromIndex &= 7;
  290. if (fromIndex > 0) sourceByte <<= fromIndex;
  291. if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;
  292. toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));
  293. }
  294. else /* One or more bytes */
  295. memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);
  296. }
  297. /* Compare pixels - they are assumed to start at the first byte in the
  298. * given buffers.
  299. */
  300. static int
  301. pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
  302. {
  303. if (memcmp(pa, pb, bit_width>>3) == 0)
  304. {
  305. png_uint_32 p;
  306. if ((bit_width & 7) == 0) return 0;
  307. /* Ok, any differences? */
  308. p = pa[bit_width >> 3];
  309. p ^= pb[bit_width >> 3];
  310. if (p == 0) return 0;
  311. /* There are, but they may not be significant, remove the bits
  312. * after the end (the low order bits in PNG.)
  313. */
  314. bit_width &= 7;
  315. p >>= 8-bit_width;
  316. if (p == 0) return 0;
  317. }
  318. return 1; /* Different */
  319. }
  320. /*************************** BASIC PNG FILE WRITING ***************************/
  321. /* A png_store takes data from the sequential writer or provides data
  322. * to the sequential reader. It can also store the result of a PNG
  323. * write for later retrieval.
  324. */
  325. #define STORE_BUFFER_SIZE 500 /* arbitrary */
  326. typedef struct png_store_buffer
  327. {
  328. struct png_store_buffer* prev; /* NOTE: stored in reverse order */
  329. png_byte buffer[STORE_BUFFER_SIZE];
  330. } png_store_buffer;
  331. #define FILE_NAME_SIZE 64
  332. typedef struct png_store_file
  333. {
  334. struct png_store_file* next; /* as many as you like... */
  335. char name[FILE_NAME_SIZE];
  336. png_uint_32 id; /* must be correct (see FILEID) */
  337. png_size_t datacount; /* In this (the last) buffer */
  338. png_store_buffer data; /* Last buffer in file */
  339. } png_store_file;
  340. /* The following is a pool of memory allocated by a single libpng read or write
  341. * operation.
  342. */
  343. typedef struct store_pool
  344. {
  345. struct png_store *store; /* Back pointer */
  346. struct store_memory *list; /* List of allocated memory */
  347. png_byte mark[4]; /* Before and after data */
  348. /* Statistics for this run. */
  349. png_alloc_size_t max; /* Maximum single allocation */
  350. png_alloc_size_t current; /* Current allocation */
  351. png_alloc_size_t limit; /* Highest current allocation */
  352. png_alloc_size_t total; /* Total allocation */
  353. /* Overall statistics (retained across successive runs). */
  354. png_alloc_size_t max_max;
  355. png_alloc_size_t max_limit;
  356. png_alloc_size_t max_total;
  357. } store_pool;
  358. typedef struct png_store
  359. {
  360. /* For cexcept.h exception handling - simply store one of these;
  361. * the context is a self pointer but it may point to a different
  362. * png_store (in fact it never does in this program.)
  363. */
  364. struct exception_context
  365. exception_context;
  366. unsigned int verbose :1;
  367. unsigned int treat_warnings_as_errors :1;
  368. unsigned int expect_error :1;
  369. unsigned int expect_warning :1;
  370. unsigned int saw_warning :1;
  371. unsigned int speed :1;
  372. unsigned int progressive :1; /* use progressive read */
  373. unsigned int validated :1; /* used as a temporary flag */
  374. int nerrors;
  375. int nwarnings;
  376. char test[128]; /* Name of test */
  377. char error[256];
  378. /* Read fields */
  379. png_structp pread; /* Used to read a saved file */
  380. png_infop piread;
  381. png_store_file* current; /* Set when reading */
  382. png_store_buffer* next; /* Set when reading */
  383. png_size_t readpos; /* Position in *next */
  384. png_byte* image; /* Buffer for reading interlaced images */
  385. size_t cb_image; /* Size of this buffer */
  386. store_pool read_memory_pool;
  387. /* Write fields */
  388. png_store_file* saved;
  389. png_structp pwrite; /* Used when writing a new file */
  390. png_infop piwrite;
  391. png_size_t writepos; /* Position in .new */
  392. char wname[FILE_NAME_SIZE];
  393. png_store_buffer new; /* The end of the new PNG file being written. */
  394. store_pool write_memory_pool;
  395. } png_store;
  396. /* Initialization and cleanup */
  397. static void
  398. store_pool_mark(png_byte *mark)
  399. {
  400. /* Generate a new mark. This uses a boring repeatable algorithm and it is
  401. * implemented here so that it gives the same set of numbers on every
  402. * architecture. It's a linear congruential generator (Knuth or Sedgewick
  403. * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
  404. * Hill, "The Art of Electronics".
  405. */
  406. static png_uint_32 u0 = 0x12345678, u1 = 1;
  407. /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
  408. * bit-20. The top 1 bit is in u1, the bottom 32 are in u0.
  409. */
  410. int i;
  411. for (i=0; i<4; ++i)
  412. {
  413. /* First generate 8 new bits then shift them in at the end. */
  414. png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
  415. u1 <<= 8;
  416. u1 |= u0 >> 24;
  417. u0 <<= 8;
  418. u0 |= u;
  419. *mark++ = (png_byte)u;
  420. }
  421. }
  422. /* Use this for random 32 bit values, this function makes sure the result is
  423. * non-zero.
  424. */
  425. static png_uint_32
  426. random_32(void)
  427. {
  428. for(;;)
  429. {
  430. png_byte mark[4];
  431. png_uint_32 result;
  432. store_pool_mark(mark);
  433. result = png_get_uint_32(mark);
  434. if (result != 0)
  435. return result;
  436. }
  437. }
  438. static void
  439. store_pool_init(png_store *ps, store_pool *pool)
  440. {
  441. memset(pool, 0, sizeof *pool);
  442. pool->store = ps;
  443. pool->list = NULL;
  444. pool->max = pool->current = pool->limit = pool->total = 0;
  445. pool->max_max = pool->max_limit = pool->max_total = 0;
  446. store_pool_mark(pool->mark);
  447. }
  448. static void
  449. store_init(png_store* ps)
  450. {
  451. memset(ps, 0, sizeof *ps);
  452. init_exception_context(&ps->exception_context);
  453. store_pool_init(ps, &ps->read_memory_pool);
  454. store_pool_init(ps, &ps->write_memory_pool);
  455. ps->verbose = 0;
  456. ps->treat_warnings_as_errors = 0;
  457. ps->expect_error = 0;
  458. ps->expect_warning = 0;
  459. ps->saw_warning = 0;
  460. ps->speed = 0;
  461. ps->progressive = 0;
  462. ps->validated = 0;
  463. ps->nerrors = ps->nwarnings = 0;
  464. ps->pread = NULL;
  465. ps->piread = NULL;
  466. ps->saved = ps->current = NULL;
  467. ps->next = NULL;
  468. ps->readpos = 0;
  469. ps->image = NULL;
  470. ps->cb_image = 0;
  471. ps->pwrite = NULL;
  472. ps->piwrite = NULL;
  473. ps->writepos = 0;
  474. ps->new.prev = NULL;
  475. }
  476. /* This somewhat odd function is used when reading an image to ensure that the
  477. * buffer is big enough - this is why a png_structp is available.
  478. */
  479. static void
  480. store_ensure_image(png_store *ps, png_structp pp, size_t cb)
  481. {
  482. if (ps->cb_image < cb)
  483. {
  484. if (ps->image != NULL)
  485. {
  486. free(ps->image-1);
  487. ps->cb_image = 0;
  488. }
  489. /* The buffer is deliberately mis-aligned. */
  490. ps->image = malloc(cb+1);
  491. if (ps->image == NULL)
  492. png_error(pp, "OOM allocating image buffer");
  493. ++(ps->image);
  494. ps->cb_image = cb;
  495. }
  496. /* And, for error checking, the whole buffer is set to '1' - this
  497. * matches what happens with the 'size' test images on write and also
  498. * matches the unused bits in the test rows.
  499. */
  500. memset(ps->image, 0xff, cb);
  501. }
  502. static void
  503. store_freebuffer(png_store_buffer* psb)
  504. {
  505. if (psb->prev)
  506. {
  507. store_freebuffer(psb->prev);
  508. free(psb->prev);
  509. psb->prev = NULL;
  510. }
  511. }
  512. static void
  513. store_freenew(png_store *ps)
  514. {
  515. store_freebuffer(&ps->new);
  516. ps->writepos = 0;
  517. }
  518. static void
  519. store_storenew(png_store *ps)
  520. {
  521. png_store_buffer *pb;
  522. if (ps->writepos != STORE_BUFFER_SIZE)
  523. png_error(ps->pwrite, "invalid store call");
  524. pb = malloc(sizeof *pb);
  525. if (pb == NULL)
  526. png_error(ps->pwrite, "store new: OOM");
  527. *pb = ps->new;
  528. ps->new.prev = pb;
  529. ps->writepos = 0;
  530. }
  531. static void
  532. store_freefile(png_store_file **ppf)
  533. {
  534. if (*ppf != NULL)
  535. {
  536. store_freefile(&(*ppf)->next);
  537. store_freebuffer(&(*ppf)->data);
  538. (*ppf)->datacount = 0;
  539. free(*ppf);
  540. *ppf = NULL;
  541. }
  542. }
  543. /* Main interface to file storeage, after writing a new PNG file (see the API
  544. * below) call store_storefile to store the result with the given name and id.
  545. */
  546. static void
  547. store_storefile(png_store *ps, png_uint_32 id)
  548. {
  549. png_store_file *pf = malloc(sizeof *pf);
  550. if (pf == NULL)
  551. png_error(ps->pwrite, "storefile: OOM");
  552. safecat(pf->name, sizeof pf->name, 0, ps->wname);
  553. pf->id = id;
  554. pf->data = ps->new;
  555. pf->datacount = ps->writepos;
  556. ps->new.prev = NULL;
  557. ps->writepos = 0;
  558. /* And save it. */
  559. pf->next = ps->saved;
  560. ps->saved = pf;
  561. }
  562. /* Generate an error message (in the given buffer) */
  563. static size_t
  564. store_message(png_store *ps, png_structp pp, char *buffer, size_t bufsize,
  565. size_t pos, PNG_CONST char *msg)
  566. {
  567. if (pp != NULL && pp == ps->pread)
  568. {
  569. /* Reading a file */
  570. pos = safecat(buffer, bufsize, pos, "read: ");
  571. if (ps->current != NULL)
  572. {
  573. pos = safecat(buffer, bufsize, pos, ps->current->name);
  574. pos = safecat(buffer, bufsize, pos, sep);
  575. }
  576. }
  577. else if (pp != NULL && pp == ps->pwrite)
  578. {
  579. /* Writing a file */
  580. pos = safecat(buffer, bufsize, pos, "write: ");
  581. pos = safecat(buffer, bufsize, pos, ps->wname);
  582. pos = safecat(buffer, bufsize, pos, sep);
  583. }
  584. else
  585. {
  586. /* Neither reading nor writing (or a memory error in struct delete) */
  587. pos = safecat(buffer, bufsize, pos, "pngvalid: ");
  588. }
  589. if (ps->test[0] != 0)
  590. {
  591. pos = safecat(buffer, bufsize, pos, ps->test);
  592. pos = safecat(buffer, bufsize, pos, sep);
  593. }
  594. pos = safecat(buffer, bufsize, pos, msg);
  595. return pos;
  596. }
  597. /* Log an error or warning - the relevant count is always incremented. */
  598. static void
  599. store_log(png_store* ps, png_structp pp, png_const_charp message, int is_error)
  600. {
  601. /* The warning is copied to the error buffer if there are no errors and it is
  602. * the first warning. The error is copied to the error buffer if it is the
  603. * first error (overwriting any prior warnings).
  604. */
  605. if (is_error ? (ps->nerrors)++ == 0 :
  606. (ps->nwarnings)++ == 0 && ps->nerrors == 0)
  607. store_message(ps, pp, ps->error, sizeof ps->error, 0, message);
  608. if (ps->verbose)
  609. {
  610. char buffer[256];
  611. size_t pos;
  612. if (is_error)
  613. pos = safecat(buffer, sizeof buffer, 0, "error: ");
  614. else
  615. pos = safecat(buffer, sizeof buffer, 0, "warning: ");
  616. store_message(ps, pp, buffer, sizeof buffer, pos, message);
  617. fputs(buffer, stderr);
  618. fputc('\n', stderr);
  619. }
  620. }
  621. /* Functions to use as PNG callbacks. */
  622. static void
  623. store_error(png_structp pp, png_const_charp message) /* PNG_NORETURN */
  624. {
  625. png_store *ps = png_get_error_ptr(pp);
  626. if (!ps->expect_error)
  627. store_log(ps, pp, message, 1 /* error */);
  628. /* And finally throw an exception. */
  629. {
  630. struct exception_context *the_exception_context = &ps->exception_context;
  631. Throw ps;
  632. }
  633. }
  634. static void
  635. store_warning(png_structp pp, png_const_charp message)
  636. {
  637. png_store *ps = png_get_error_ptr(pp);
  638. if (!ps->expect_warning)
  639. store_log(ps, pp, message, 0 /* warning */);
  640. else
  641. ps->saw_warning = 1;
  642. }
  643. static void
  644. store_write(png_structp pp, png_bytep pb, png_size_t st)
  645. {
  646. png_store *ps = png_get_io_ptr(pp);
  647. if (ps->pwrite != pp)
  648. png_error(pp, "store state damaged");
  649. while (st > 0)
  650. {
  651. size_t cb;
  652. if (ps->writepos >= STORE_BUFFER_SIZE)
  653. store_storenew(ps);
  654. cb = st;
  655. if (cb > STORE_BUFFER_SIZE - ps->writepos)
  656. cb = STORE_BUFFER_SIZE - ps->writepos;
  657. memcpy(ps->new.buffer + ps->writepos, pb, cb);
  658. pb += cb;
  659. st -= cb;
  660. ps->writepos += cb;
  661. }
  662. }
  663. static void
  664. store_flush(png_structp pp)
  665. {
  666. UNUSED(pp) /*DOES NOTHING*/
  667. }
  668. static size_t
  669. store_read_buffer_size(png_store *ps)
  670. {
  671. /* Return the bytes available for read in the current buffer. */
  672. if (ps->next != &ps->current->data)
  673. return STORE_BUFFER_SIZE;
  674. return ps->current->datacount;
  675. }
  676. /* Return total bytes available for read. */
  677. static size_t
  678. store_read_buffer_avail(png_store *ps)
  679. {
  680. if (ps->current != NULL && ps->next != NULL)
  681. {
  682. png_store_buffer *next = &ps->current->data;
  683. size_t cbAvail = ps->current->datacount;
  684. while (next != ps->next && next != NULL)
  685. {
  686. next = next->prev;
  687. cbAvail += STORE_BUFFER_SIZE;
  688. }
  689. if (next != ps->next)
  690. png_error(ps->pread, "buffer read error");
  691. if (cbAvail > ps->readpos)
  692. return cbAvail - ps->readpos;
  693. }
  694. return 0;
  695. }
  696. static int
  697. store_read_buffer_next(png_store *ps)
  698. {
  699. png_store_buffer *pbOld = ps->next;
  700. png_store_buffer *pbNew = &ps->current->data;
  701. if (pbOld != pbNew)
  702. {
  703. while (pbNew != NULL && pbNew->prev != pbOld)
  704. pbNew = pbNew->prev;
  705. if (pbNew != NULL)
  706. {
  707. ps->next = pbNew;
  708. ps->readpos = 0;
  709. return 1;
  710. }
  711. png_error(ps->pread, "buffer lost");
  712. }
  713. return 0; /* EOF or error */
  714. }
  715. /* Need separate implementation and callback to allow use of the same code
  716. * during progressive read, where the io_ptr is set internally by libpng.
  717. */
  718. static void
  719. store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
  720. {
  721. if (ps->current == NULL || ps->next == NULL)
  722. png_error(ps->pread, "store state damaged");
  723. while (st > 0)
  724. {
  725. size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;
  726. if (cbAvail > 0)
  727. {
  728. if (cbAvail > st) cbAvail = st;
  729. memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);
  730. st -= cbAvail;
  731. pb += cbAvail;
  732. ps->readpos += cbAvail;
  733. }
  734. else if (!store_read_buffer_next(ps))
  735. png_error(ps->pread, "read beyond end of file");
  736. }
  737. }
  738. static void
  739. store_read(png_structp pp, png_bytep pb, png_size_t st)
  740. {
  741. png_store *ps = png_get_io_ptr(pp);
  742. if (ps == NULL || ps->pread != pp)
  743. png_error(pp, "bad store read call");
  744. store_read_imp(ps, pb, st);
  745. }
  746. static void
  747. store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
  748. {
  749. /* Notice that a call to store_read will cause this function to fail because
  750. * readpos will be set.
  751. */
  752. if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
  753. png_error(pp, "store state damaged (progressive)");
  754. do
  755. {
  756. if (ps->readpos != 0)
  757. png_error(pp, "store_read called during progressive read");
  758. png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));
  759. }
  760. while (store_read_buffer_next(ps));
  761. }
  762. /***************************** MEMORY MANAGEMENT*** ***************************/
  763. /* A store_memory is simply the header for an allocated block of memory. The
  764. * pointer returned to libpng is just after the end of the header block, the
  765. * allocated memory is followed by a second copy of the 'mark'.
  766. */
  767. typedef struct store_memory
  768. {
  769. store_pool *pool; /* Originating pool */
  770. struct store_memory *next; /* Singly linked list */
  771. png_alloc_size_t size; /* Size of memory allocated */
  772. png_byte mark[4]; /* ID marker */
  773. } store_memory;
  774. /* Handle a fatal error in memory allocation. This calls png_error if the
  775. * libpng struct is non-NULL, else it outputs a message and returns. This means
  776. * that a memory problem while libpng is running will abort (png_error) the
  777. * handling of particular file while one in cleanup (after the destroy of the
  778. * struct has returned) will simply keep going and free (or attempt to free)
  779. * all the memory.
  780. */
  781. static void
  782. store_pool_error(png_store *ps, png_structp pp, PNG_CONST char *msg)
  783. {
  784. if (pp != NULL)
  785. png_error(pp, msg);
  786. /* Else we have to do it ourselves. png_error eventually calls store_log,
  787. * above. store_log accepts a NULL png_structp - it just changes what gets
  788. * output by store_message.
  789. */
  790. store_log(ps, pp, msg, 1 /* error */);
  791. }
  792. static void
  793. store_memory_free(png_structp pp, store_pool *pool, store_memory *memory)
  794. {
  795. /* Note that pp may be NULL (see store_pool_delete below), the caller has
  796. * found 'memory' in pool->list *and* unlinked this entry, so this is a valid
  797. * pointer (for sure), but the contents may have been trashed.
  798. */
  799. if (memory->pool != pool)
  800. store_pool_error(pool->store, pp, "memory corrupted (pool)");
  801. else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)
  802. store_pool_error(pool->store, pp, "memory corrupted (start)");
  803. /* It should be safe to read the size field now. */
  804. else
  805. {
  806. png_alloc_size_t cb = memory->size;
  807. if (cb > pool->max)
  808. store_pool_error(pool->store, pp, "memory corrupted (size)");
  809. else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)
  810. != 0)
  811. store_pool_error(pool->store, pp, "memory corrupted (end)");
  812. /* Finally give the library a chance to find problems too: */
  813. else
  814. {
  815. pool->current -= cb;
  816. free(memory);
  817. }
  818. }
  819. }
  820. static void
  821. store_pool_delete(png_store *ps, store_pool *pool)
  822. {
  823. if (pool->list != NULL)
  824. {
  825. fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test,
  826. pool == &ps->read_memory_pool ? "read" : "write",
  827. pool == &ps->read_memory_pool ? (ps->current != NULL ?
  828. ps->current->name : "unknown file") : ps->wname);
  829. ++ps->nerrors;
  830. do
  831. {
  832. store_memory *next = pool->list;
  833. pool->list = next->next;
  834. next->next = NULL;
  835. fprintf(stderr, "\t%lu bytes @ %p\n",
  836. (unsigned long)next->size, (PNG_CONST void*)(next+1));
  837. /* The NULL means this will always return, even if the memory is
  838. * corrupted.
  839. */
  840. store_memory_free(NULL, pool, next);
  841. }
  842. while (pool->list != NULL);
  843. }
  844. /* And reset the other fields too for the next time. */
  845. if (pool->max > pool->max_max) pool->max_max = pool->max;
  846. pool->max = 0;
  847. if (pool->current != 0) /* unexpected internal error */
  848. fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n",
  849. ps->test, pool == &ps->read_memory_pool ? "read" : "write",
  850. pool == &ps->read_memory_pool ? (ps->current != NULL ?
  851. ps->current->name : "unknown file") : ps->wname);
  852. pool->current = 0;
  853. if (pool->limit > pool->max_limit)
  854. pool->max_limit = pool->limit;
  855. pool->limit = 0;
  856. if (pool->total > pool->max_total)
  857. pool->max_total = pool->total;
  858. pool->total = 0;
  859. /* Get a new mark too. */
  860. store_pool_mark(pool->mark);
  861. }
  862. /* The memory callbacks: */
  863. static png_voidp
  864. store_malloc(png_structp pp, png_alloc_size_t cb)
  865. {
  866. store_pool *pool = png_get_mem_ptr(pp);
  867. store_memory *new = malloc(cb + (sizeof *new) + (sizeof pool->mark));
  868. if (new != NULL)
  869. {
  870. if (cb > pool->max)
  871. pool->max = cb;
  872. pool->current += cb;
  873. if (pool->current > pool->limit)
  874. pool->limit = pool->current;
  875. pool->total += cb;
  876. new->size = cb;
  877. memcpy(new->mark, pool->mark, sizeof new->mark);
  878. memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);
  879. new->pool = pool;
  880. new->next = pool->list;
  881. pool->list = new;
  882. ++new;
  883. }
  884. else
  885. store_pool_error(pool->store, pp, "out of memory");
  886. return new;
  887. }
  888. static void
  889. store_free(png_structp pp, png_voidp memory)
  890. {
  891. store_pool *pool = png_get_mem_ptr(pp);
  892. store_memory *this = memory, **test;
  893. /* First check that this 'memory' really is valid memory - it must be in the
  894. * pool list. If it is, use the shared memory_free function to free it.
  895. */
  896. --this;
  897. for (test = &pool->list; *test != this; test = &(*test)->next)
  898. {
  899. if (*test == NULL)
  900. {
  901. store_pool_error(pool->store, pp, "bad pointer to free");
  902. return;
  903. }
  904. }
  905. /* Unlink this entry, *test == this. */
  906. *test = this->next;
  907. this->next = NULL;
  908. store_memory_free(pp, pool, this);
  909. }
  910. /* Setup functions. */
  911. /* Cleanup when aborting a write or after storing the new file. */
  912. static void
  913. store_write_reset(png_store *ps)
  914. {
  915. if (ps->pwrite != NULL)
  916. {
  917. anon_context(ps);
  918. Try
  919. png_destroy_write_struct(&ps->pwrite, &ps->piwrite);
  920. Catch_anonymous
  921. {
  922. /* memory corruption: continue. */
  923. }
  924. ps->pwrite = NULL;
  925. ps->piwrite = NULL;
  926. }
  927. /* And make sure that all the memory has been freed - this will output
  928. * spurious errors in the case of memory corruption above, but this is safe.
  929. */
  930. store_pool_delete(ps, &ps->write_memory_pool);
  931. store_freenew(ps);
  932. }
  933. /* The following is the main write function, it returns a png_struct and,
  934. * optionally, a png_info suitable for writiing a new PNG file. Use
  935. * store_storefile above to record this file after it has been written. The
  936. * returned libpng structures as destroyed by store_write_reset above.
  937. */
  938. static png_structp
  939. set_store_for_write(png_store *ps, png_infopp ppi,
  940. PNG_CONST char * volatile name)
  941. {
  942. anon_context(ps);
  943. Try
  944. {
  945. if (ps->pwrite != NULL)
  946. png_error(ps->pwrite, "write store already in use");
  947. store_write_reset(ps);
  948. safecat(ps->wname, sizeof ps->wname, 0, name);
  949. /* Don't do the slow memory checks if doing a speed test. */
  950. if (ps->speed)
  951. ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,
  952. ps, store_error, store_warning);
  953. else
  954. ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
  955. ps, store_error, store_warning, &ps->write_memory_pool,
  956. store_malloc, store_free);
  957. png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
  958. if (ppi != NULL)
  959. *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);
  960. }
  961. Catch_anonymous
  962. return NULL;
  963. return ps->pwrite;
  964. }
  965. /* Cleanup when finished reading (either due to error or in the success case).
  966. */
  967. static void
  968. store_read_reset(png_store *ps)
  969. {
  970. if (ps->pread != NULL)
  971. {
  972. anon_context(ps);
  973. Try
  974. png_destroy_read_struct(&ps->pread, &ps->piread, NULL);
  975. Catch_anonymous
  976. {
  977. /* error already output: continue */
  978. }
  979. ps->pread = NULL;
  980. ps->piread = NULL;
  981. }
  982. /* Always do this to be safe. */
  983. store_pool_delete(ps, &ps->read_memory_pool);
  984. ps->current = NULL;
  985. ps->next = NULL;
  986. ps->readpos = 0;
  987. ps->validated = 0;
  988. }
  989. static void
  990. store_read_set(png_store *ps, png_uint_32 id)
  991. {
  992. png_store_file *pf = ps->saved;
  993. while (pf != NULL)
  994. {
  995. if (pf->id == id)
  996. {
  997. ps->current = pf;
  998. ps->next = NULL;
  999. store_read_buffer_next(ps);
  1000. return;
  1001. }
  1002. pf = pf->next;
  1003. }
  1004. {
  1005. size_t pos;
  1006. char msg[FILE_NAME_SIZE+64];
  1007. pos = standard_name_from_id(msg, sizeof msg, 0, id);
  1008. pos = safecat(msg, sizeof msg, pos, ": file not found");
  1009. png_error(ps->pread, msg);
  1010. }
  1011. }
  1012. /* The main interface for reading a saved file - pass the id number of the file
  1013. * to retrieve. Ids must be unique or the earlier file will be hidden. The API
  1014. * returns a png_struct and, optionally, a png_info. Both of these will be
  1015. * destroyed by store_read_reset above.
  1016. */
  1017. static png_structp
  1018. set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,
  1019. PNG_CONST char *name)
  1020. {
  1021. /* Set the name for png_error */
  1022. safecat(ps->test, sizeof ps->test, 0, name);
  1023. if (ps->pread != NULL)
  1024. png_error(ps->pread, "read store already in use");
  1025. store_read_reset(ps);
  1026. /* Both the create APIs can return NULL if used in their default mode
  1027. * (because there is no other way of handling an error because the jmp_buf
  1028. * by default is stored in png_struct and that has not been allocated!)
  1029. * However, given that store_error works correctly in these circumstances
  1030. * we don't ever expect NULL in this program.
  1031. */
  1032. if (ps->speed)
  1033. ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps,
  1034. store_error, store_warning);
  1035. else
  1036. ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,
  1037. store_error, store_warning, &ps->read_memory_pool, store_malloc,
  1038. store_free);
  1039. if (ps->pread == NULL)
  1040. {
  1041. struct exception_context *the_exception_context = &ps->exception_context;
  1042. store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)",
  1043. 1 /*error*/);
  1044. Throw ps;
  1045. }
  1046. store_read_set(ps, id);
  1047. if (ppi != NULL)
  1048. *ppi = ps->piread = png_create_info_struct(ps->pread);
  1049. return ps->pread;
  1050. }
  1051. /* The overall cleanup of a store simply calls the above then removes all the
  1052. * saved files. This does not delete the store itself.
  1053. */
  1054. static void
  1055. store_delete(png_store *ps)
  1056. {
  1057. store_write_reset(ps);
  1058. store_read_reset(ps);
  1059. store_freefile(&ps->saved);
  1060. if (ps->image != NULL)
  1061. {
  1062. free(ps->image-1);
  1063. ps->image = NULL;
  1064. ps->cb_image = 0;
  1065. }
  1066. }
  1067. /*********************** PNG FILE MODIFICATION ON READ ************************/
  1068. /* Files may be modified on read. The following structure contains a complete
  1069. * png_store together with extra members to handle modification and a special
  1070. * read callback for libpng. To use this the 'modifications' field must be set
  1071. * to a list of png_modification structures that actually perform the
  1072. * modification, otherwise a png_modifier is functionally equivalent to a
  1073. * png_store. There is a special read function, set_modifier_for_read, which
  1074. * replaces set_store_for_read.
  1075. */
  1076. typedef struct png_modifier
  1077. {
  1078. png_store this; /* I am a png_store */
  1079. struct png_modification *modifications; /* Changes to make */
  1080. enum modifier_state
  1081. {
  1082. modifier_start, /* Initial value */
  1083. modifier_signature, /* Have a signature */
  1084. modifier_IHDR /* Have an IHDR */
  1085. } state; /* My state */
  1086. /* Information from IHDR: */
  1087. png_byte bit_depth; /* From IHDR */
  1088. png_byte colour_type; /* From IHDR */
  1089. /* While handling PLTE, IDAT and IEND these chunks may be pended to allow
  1090. * other chunks to be inserted.
  1091. */
  1092. png_uint_32 pending_len;
  1093. png_uint_32 pending_chunk;
  1094. /* Test values */
  1095. double *gammas;
  1096. unsigned int ngammas;
  1097. /* Lowest sbit to test (libpng fails for sbit < 8) */
  1098. png_byte sbitlow;
  1099. /* Error control - these are the limits on errors accepted by the gamma tests
  1100. * below.
  1101. */
  1102. double maxout8; /* Maximum output value error */
  1103. double maxabs8; /* Absolute sample error 0..1 */
  1104. double maxpc8; /* Percentage sample error 0..100% */
  1105. double maxout16; /* Maximum output value error */
  1106. double maxabs16; /* Absolute sample error 0..1 */
  1107. double maxpc16; /* Percentage sample error 0..100% */
  1108. /* Logged 8 and 16 bit errors ('output' values): */
  1109. double error_gray_2;
  1110. double error_gray_4;
  1111. double error_gray_8;
  1112. double error_gray_16;
  1113. double error_color_8;
  1114. double error_color_16;
  1115. /* Flags: */
  1116. /* Whether or not to interlace. */
  1117. int interlace_type :9; /* int, but must store '1' */
  1118. /* Run the standard tests? */
  1119. unsigned int test_standard :1;
  1120. /* Run the odd-sized image and interlace read/write tests? */
  1121. unsigned int test_size :1;
  1122. /* Run tests on reading with a combiniation of transforms, */
  1123. unsigned int test_transform :1;
  1124. /* When to use the use_input_precision option: */
  1125. unsigned int use_input_precision :1;
  1126. unsigned int use_input_precision_sbit :1;
  1127. unsigned int use_input_precision_16to8 :1;
  1128. /* Which gamma tests to run: */
  1129. unsigned int test_gamma_threshold :1;
  1130. unsigned int test_gamma_transform :1; /* main tests */
  1131. unsigned int test_gamma_sbit :1;
  1132. unsigned int test_gamma_strip16 :1;
  1133. unsigned int log :1; /* Log max error */
  1134. /* Buffer information, the buffer size limits the size of the chunks that can
  1135. * be modified - they must fit (including header and CRC) into the buffer!
  1136. */
  1137. size_t flush; /* Count of bytes to flush */
  1138. size_t buffer_count; /* Bytes in buffer */
  1139. size_t buffer_position; /* Position in buffer */
  1140. png_byte buffer[1024];
  1141. } png_modifier;
  1142. static double abserr(png_modifier *pm, png_byte bit_depth)
  1143. {
  1144. return bit_depth == 16 ? pm->maxabs16 : pm->maxabs8;
  1145. }
  1146. static double pcerr(png_modifier *pm, png_byte bit_depth)
  1147. {
  1148. return (bit_depth == 16 ? pm->maxpc16 : pm->maxpc8) * .01;
  1149. }
  1150. static double outerr(png_modifier *pm, png_byte bit_depth)
  1151. {
  1152. /* There is a serious error in the 2 and 4 bit grayscale transform because
  1153. * the gamma table value (8 bits) is simply shifted, not rounded, so the
  1154. * error in 4 bit greyscale gamma is up to the value below. This is a hack
  1155. * to allow pngvalid to succeed:
  1156. */
  1157. if (bit_depth == 2)
  1158. return .73182-.5;
  1159. if (bit_depth == 4)
  1160. return .90644-.5;
  1161. if (bit_depth == 16)
  1162. return pm->maxout16;
  1163. return pm->maxout8;
  1164. }
  1165. /* This returns true if the test should be stopped now because it has already
  1166. * failed and it is running silently.
  1167. */
  1168. static int fail(png_modifier *pm)
  1169. {
  1170. return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 ||
  1171. (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0));
  1172. }
  1173. static void
  1174. modifier_init(png_modifier *pm)
  1175. {
  1176. memset(pm, 0, sizeof *pm);
  1177. store_init(&pm->this);
  1178. pm->modifications = NULL;
  1179. pm->state = modifier_start;
  1180. pm->sbitlow = 1U;
  1181. pm->maxout8 = pm->maxpc8 = pm->maxabs8 = 0;
  1182. pm->maxout16 = pm->maxpc16 = pm->maxabs16 = 0;
  1183. pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
  1184. pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
  1185. pm->interlace_type = PNG_INTERLACE_NONE;
  1186. pm->test_standard = 0;
  1187. pm->test_size = 0;
  1188. pm->test_transform = 0;
  1189. pm->use_input_precision = 0;
  1190. pm->use_input_precision_sbit = 0;
  1191. pm->use_input_precision_16to8 = 0;
  1192. pm->test_gamma_threshold = 0;
  1193. pm->test_gamma_transform = 0;
  1194. pm->test_gamma_sbit = 0;
  1195. pm->test_gamma_strip16 = 0;
  1196. pm->log = 0;
  1197. /* Rely on the memset for all the other fields - there are no pointers */
  1198. }
  1199. /* One modification structure must be provided for each chunk to be modified (in
  1200. * fact more than one can be provided if multiple separate changes are desired
  1201. * for a single chunk.) Modifications include adding a new chunk when a
  1202. * suitable chunk does not exist.
  1203. *
  1204. * The caller of modify_fn will reset the CRC of the chunk and record 'modified'
  1205. * or 'added' as appropriate if the modify_fn returns 1 (true). If the
  1206. * modify_fn is NULL the chunk is simply removed.
  1207. */
  1208. typedef struct png_modification
  1209. {
  1210. struct png_modification *next;
  1211. png_uint_32 chunk;
  1212. /* If the following is NULL all matching chunks will be removed: */
  1213. int (*modify_fn)(struct png_modifier *pm,
  1214. struct png_modification *me, int add);
  1215. /* If the following is set to PLTE, IDAT or IEND and the chunk has not been
  1216. * found and modified (and there is a modify_fn) the modify_fn will be called
  1217. * to add the chunk before the relevant chunk.
  1218. */
  1219. png_uint_32 add;
  1220. unsigned int modified :1; /* Chunk was modified */
  1221. unsigned int added :1; /* Chunk was added */
  1222. unsigned int removed :1; /* Chunk was removed */
  1223. } png_modification;
  1224. static void modification_reset(png_modification *pmm)
  1225. {
  1226. if (pmm != NULL)
  1227. {
  1228. pmm->modified = 0;
  1229. pmm->added = 0;
  1230. pmm->removed = 0;
  1231. modification_reset(pmm->next);
  1232. }
  1233. }
  1234. static void
  1235. modification_init(png_modification *pmm)
  1236. {
  1237. memset(pmm, 0, sizeof *pmm);
  1238. pmm->next = NULL;
  1239. pmm->chunk = 0;
  1240. pmm->modify_fn = NULL;
  1241. pmm->add = 0;
  1242. modification_reset(pmm);
  1243. }
  1244. static void
  1245. modifier_reset(png_modifier *pm)
  1246. {
  1247. store_read_reset(&pm->this);
  1248. pm->modifications = NULL;
  1249. pm->state = modifier_start;
  1250. pm->bit_depth = pm->colour_type = 0;
  1251. pm->pending_len = pm->pending_chunk = 0;
  1252. pm->flush = pm->buffer_count = pm->buffer_position = 0;
  1253. }
  1254. /* Convenience macros. */
  1255. #define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
  1256. #define CHUNK_IHDR CHUNK(73,72,68,82)
  1257. #define CHUNK_PLTE CHUNK(80,76,84,69)
  1258. #define CHUNK_IDAT CHUNK(73,68,65,84)
  1259. #define CHUNK_IEND CHUNK(73,69,78,68)
  1260. #define CHUNK_cHRM CHUNK(99,72,82,77)
  1261. #define CHUNK_gAMA CHUNK(103,65,77,65)
  1262. #define CHUNK_sBIT CHUNK(115,66,73,84)
  1263. #define CHUNK_sRGB CHUNK(115,82,71,66)
  1264. /* The guts of modification are performed during a read. */
  1265. static void
  1266. modifier_crc(png_bytep buffer)
  1267. {
  1268. /* Recalculate the chunk CRC - a complete chunk must be in
  1269. * the buffer, at the start.
  1270. */
  1271. uInt datalen = png_get_uint_32(buffer);
  1272. png_save_uint_32(buffer+datalen+8, crc32(0L, buffer+4, datalen+4));
  1273. }
  1274. static void
  1275. modifier_setbuffer(png_modifier *pm)
  1276. {
  1277. modifier_crc(pm->buffer);
  1278. pm->buffer_count = png_get_uint_32(pm->buffer)+12;
  1279. pm->buffer_position = 0;
  1280. }
  1281. /* Separate the callback into the actual implementation (which is passed the
  1282. * png_modifier explicitly) and the callback, which gets the modifier from the
  1283. * png_struct.
  1284. */
  1285. static void
  1286. modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
  1287. {
  1288. while (st > 0)
  1289. {
  1290. size_t cb;
  1291. png_uint_32 len, chunk;
  1292. png_modification *mod;
  1293. if (pm->buffer_position >= pm->buffer_count) switch (pm->state)
  1294. {
  1295. static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
  1296. case modifier_start:
  1297. store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */
  1298. pm->buffer_count = 8;
  1299. pm->buffer_position = 0;
  1300. if (memcmp(pm->buffer, sign, 8) != 0)
  1301. png_error(pm->this.pread, "invalid PNG file signature");
  1302. pm->state = modifier_signature;
  1303. break;
  1304. case modifier_signature:
  1305. store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */
  1306. pm->buffer_count = 13+12;
  1307. pm->buffer_position = 0;
  1308. if (png_get_uint_32(pm->buffer) != 13 ||
  1309. png_get_uint_32(pm->buffer+4) != CHUNK_IHDR)
  1310. png_error(pm->this.pread, "invalid IHDR");
  1311. /* Check the list of modifiers for modifications to the IHDR. */
  1312. mod = pm->modifications;
  1313. while (mod != NULL)
  1314. {
  1315. if (mod->chunk == CHUNK_IHDR && mod->modify_fn &&
  1316. (*mod->modify_fn)(pm, mod, 0))
  1317. {
  1318. mod->modified = 1;
  1319. modifier_setbuffer(pm);
  1320. }
  1321. /* Ignore removal or add if IHDR! */
  1322. mod = mod->next;
  1323. }
  1324. /* Cache information from the IHDR (the modified one.) */
  1325. pm->bit_depth = pm->buffer[8+8];
  1326. pm->colour_type = pm->buffer[8+8+1];
  1327. pm->state = modifier_IHDR;
  1328. pm->flush = 0;
  1329. break;
  1330. case modifier_IHDR:
  1331. default:
  1332. /* Read a new chunk and process it until we see PLTE, IDAT or
  1333. * IEND. 'flush' indicates that there is still some data to
  1334. * output from the preceding chunk.
  1335. */
  1336. if ((cb = pm->flush) > 0)
  1337. {
  1338. if (cb > st) cb = st;
  1339. pm->flush -= cb;
  1340. store_read_imp(&pm->this, pb, cb);
  1341. pb += cb;
  1342. st -= cb;
  1343. if (st <= 0) return;
  1344. }
  1345. /* No more bytes to flush, read a header, or handle a pending
  1346. * chunk.
  1347. */
  1348. if (pm->pending_chunk != 0)
  1349. {
  1350. png_save_uint_32(pm->buffer, pm->pending_len);
  1351. png_save_uint_32(pm->buffer+4, pm->pending_chunk);
  1352. pm->pending_len = 0;
  1353. pm->pending_chunk = 0;
  1354. }
  1355. else
  1356. store_read_imp(&pm->this, pm->buffer, 8);
  1357. pm->buffer_count = 8;
  1358. pm->buffer_position = 0;
  1359. /* Check for something to modify or a terminator chunk. */
  1360. len = png_get_uint_32(pm->buffer);
  1361. chunk = png_get_uint_32(pm->buffer+4);
  1362. /* Terminators first, they may have to be delayed for added
  1363. * chunks
  1364. */
  1365. if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT ||
  1366. chunk == CHUNK_IEND)
  1367. {
  1368. mod = pm->modifications;
  1369. while (mod != NULL)
  1370. {
  1371. if ((mod->add == chunk ||
  1372. (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) &&
  1373. mod->modify_fn != NULL && !mod->modified && !mod->added)
  1374. {
  1375. /* Regardless of what the modify function does do not run
  1376. * this again.
  1377. */
  1378. mod->added = 1;
  1379. if ((*mod->modify_fn)(pm, mod, 1 /*add*/))
  1380. {
  1381. /* Reset the CRC on a new chunk */
  1382. if (pm->buffer_count > 0)
  1383. modifier_setbuffer(pm);
  1384. else
  1385. {
  1386. pm->buffer_position = 0;
  1387. mod->removed = 1;
  1388. }
  1389. /* The buffer has been filled with something (we assume)
  1390. * so output this. Pend the current chunk.
  1391. */
  1392. pm->pending_len = len;
  1393. pm->pending_chunk = chunk;
  1394. break; /* out of while */
  1395. }
  1396. }
  1397. mod = mod->next;
  1398. }
  1399. /* Don't do any further processing if the buffer was modified -
  1400. * otherwise the code will end up modifying a chunk that was
  1401. * just added.
  1402. */
  1403. if (mod != NULL)
  1404. break; /* out of switch */
  1405. }
  1406. /* If we get to here then this chunk may need to be modified. To
  1407. * do this it must be less than 1024 bytes in total size, otherwise
  1408. * it just gets flushed.
  1409. */
  1410. if (len+12 <= sizeof pm->buffer)
  1411. {
  1412. store_read_imp(&pm->this, pm->buffer+pm->buffer_count,
  1413. len+12-pm->buffer_count);
  1414. pm->buffer_count = len+12;
  1415. /* Check for a modification, else leave it be. */
  1416. mod = pm->modifications;
  1417. while (mod != NULL)
  1418. {
  1419. if (mod->chunk == chunk)
  1420. {
  1421. if (mod->modify_fn == NULL)
  1422. {
  1423. /* Remove this chunk */
  1424. pm->buffer_count = pm->buffer_position = 0;
  1425. mod->removed = 1;
  1426. break; /* Terminate the while loop */
  1427. }
  1428. else if ((*mod->modify_fn)(pm, mod, 0))
  1429. {
  1430. mod->modified = 1;
  1431. /* The chunk may have been removed: */
  1432. if (pm->buffer_count == 0)
  1433. {
  1434. pm->buffer_position = 0;
  1435. break;
  1436. }
  1437. modifier_setbuffer(pm);
  1438. }
  1439. }
  1440. mod = mod->next;
  1441. }
  1442. }
  1443. else
  1444. pm->flush = len+12 - pm->buffer_count; /* data + crc */
  1445. /* Take the data from the buffer (if there is any). */
  1446. break;
  1447. }
  1448. /* Here to read from the modifier buffer (not directly from
  1449. * the store, as in the flush case above.)
  1450. */
  1451. cb = pm->buffer_count - pm->buffer_position;
  1452. if (cb > st)
  1453. cb = st;
  1454. memcpy(pb, pm->buffer + pm->buffer_position, cb);
  1455. st -= cb;
  1456. pb += cb;
  1457. pm->buffer_position += cb;
  1458. }
  1459. }
  1460. /* The callback: */
  1461. static void
  1462. modifier_read(png_structp pp, png_bytep pb, png_size_t st)
  1463. {
  1464. png_modifier *pm = png_get_io_ptr(pp);
  1465. if (pm == NULL || pm->this.pread != pp)
  1466. png_error(pp, "bad modifier_read call");
  1467. modifier_read_imp(pm, pb, st);
  1468. }
  1469. /* Like store_progressive_read but the data is getting changed as we go so we
  1470. * need a local buffer.
  1471. */
  1472. static void
  1473. modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)
  1474. {
  1475. if (pm->this.pread != pp || pm->this.current == NULL ||
  1476. pm->this.next == NULL)
  1477. png_error(pp, "store state damaged (progressive)");
  1478. /* This is another Horowitz and Hill random noise generator. In this case
  1479. * the aim is to stress the progressive reader with truely horrible variable
  1480. * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
  1481. * is generated. We could probably just count from 1 to 32767 and get as
  1482. * good a result.
  1483. */
  1484. for (;;)
  1485. {
  1486. static png_uint_32 noise = 1;
  1487. png_size_t cb, cbAvail;
  1488. png_byte buffer[512];
  1489. /* Generate 15 more bits of stuff: */
  1490. noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
  1491. cb = noise & 0x1ff;
  1492. /* Check that this number of bytes are available (in the current buffer.)
  1493. * (This doesn't quite work - the modifier might delete a chunk; unlikely
  1494. * but possible, it doesn't happen at present because the modifier only
  1495. * adds chunks to standard images.)
  1496. */
  1497. cbAvail = store_read_buffer_avail(&pm->this);
  1498. if (pm->buffer_count > pm->buffer_position)
  1499. cbAvail += pm->buffer_count - pm->buffer_position;
  1500. if (cb > cbAvail)
  1501. {
  1502. /* Check for EOF: */
  1503. if (cbAvail == 0)
  1504. break;
  1505. cb = cbAvail;
  1506. }
  1507. modifier_read_imp(pm, buffer, cb);
  1508. png_process_data(pp, pi, buffer, cb);
  1509. }
  1510. /* Check the invariants at the end (if this fails it's a problem in this
  1511. * file!)
  1512. */
  1513. if (pm->buffer_count > pm->buffer_position ||
  1514. pm->this.next != &pm->this.current->data ||
  1515. pm->this.readpos < pm->this.current->datacount)
  1516. png_error(pp, "progressive read implementation error");
  1517. }
  1518. /* Set up a modifier. */
  1519. static png_structp
  1520. set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id,
  1521. PNG_CONST char *name)
  1522. {
  1523. /* Do this first so that the modifier fields are cleared even if an error
  1524. * happens allocating the png_struct. No allocation is done here so no
  1525. * cleanup is required.
  1526. */
  1527. pm->state = modifier_start;
  1528. pm->bit_depth = 0;
  1529. pm->colour_type = 255;
  1530. pm->pending_len = 0;
  1531. pm->pending_chunk = 0;
  1532. pm->flush = 0;
  1533. pm->buffer_count = 0;
  1534. pm->buffer_position = 0;
  1535. return set_store_for_read(&pm->this, ppi, id, name);
  1536. }
  1537. /***************************** STANDARD PNG FILES *****************************/
  1538. /* Standard files - write and save standard files. */
  1539. /* There are two basic forms of standard images. Those which attempt to have
  1540. * all the possible pixel values (not possible for 16bpp images, but a range of
  1541. * values are produced) and those which have a range of image sizes. The former
  1542. * are used for testing transforms, in particular gamma correction and bit
  1543. * reduction and increase. The latter are reserved for testing the behavior of
  1544. * libpng with respect to 'odd' image sizes - particularly small images where
  1545. * rows become 1 byte and interlace passes disappear.
  1546. *
  1547. * The first, most useful, set are the 'transform' images, the second set of
  1548. * small images are the 'size' images.
  1549. *
  1550. * The transform files are constructed with rows which fit into a 1024 byte row
  1551. * buffer. This makes allocation easier below. Further regardless of the file
  1552. * format every row has 128 pixels (giving 1024 bytes for 64bpp formats).
  1553. *
  1554. * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed
  1555. * and with an ID derived from the colour type, bit depth and interlace type
  1556. * as above (FILEID). The width (128) and height (variable) are not stored in
  1557. * the FILEID - instead the fields are set to 0, indicating a transform file.
  1558. *
  1559. * The size files ar constructed with rows a maximum of 128 bytes wide, allowing
  1560. * a maximum width of 16 pixels (for the 64bpp case.) They also have a maximum
  1561. * height of 16 rows. The width and height are stored in the FILEID and, being
  1562. * non-zero, indicate a size file.
  1563. */
  1564. /* The number of passes is related to the interlace type. There wass no libpng
  1565. * API to determine this prior to 1.5, so we need an inquiry function:
  1566. */
  1567. static int
  1568. npasses_from_interlace_type(png_structp pp, int interlace_type)
  1569. {
  1570. switch (interlace_type)
  1571. {
  1572. default:
  1573. png_error(pp, "invalid interlace type");
  1574. case PNG_INTERLACE_NONE:
  1575. return 1;
  1576. case PNG_INTERLACE_ADAM7:
  1577. return PNG_INTERLACE_ADAM7_PASSES;
  1578. }
  1579. }
  1580. static unsigned int
  1581. bit_size(png_structp pp, png_byte colour_type, png_byte bit_depth)
  1582. {
  1583. switch (colour_type)
  1584. {
  1585. case 0: return bit_depth;
  1586. case 2: return 3*bit_depth;
  1587. case 3: return bit_depth;
  1588. case 4: return 2*bit_depth;
  1589. case 6: return 4*bit_depth;
  1590. default: png_error(pp, "invalid color type");
  1591. }
  1592. }
  1593. #define TRANSFORM_WIDTH 128U
  1594. #define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U)
  1595. #define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */
  1596. #define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */
  1597. /* So the maximum image sizes are as follows. A 'transform' image may require
  1598. * more than 65535 bytes. The size images are a maximum of 2046 bytes.
  1599. */
  1600. #define TRANSFORM_IMAGEMAX (TRANSFORM_ROWMAX * (png_uint_32)2048)
  1601. #define SIZE_IMAGEMAX (SIZE_ROWMAX * 16U)
  1602. static size_t
  1603. transform_rowsize(png_structp pp, png_byte colour_type, png_byte bit_depth)
  1604. {
  1605. return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8;
  1606. }
  1607. /* transform_width(pp, colour_type, bit_depth) current returns the same number
  1608. * every time, so just use a macro:
  1609. */
  1610. #define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH
  1611. static png_uint_32
  1612. transform_height(png_structp pp, png_byte colour_type, png_byte bit_depth)
  1613. {
  1614. switch (bit_size(pp, colour_type, bit_depth))
  1615. {
  1616. case 1:
  1617. case 2:
  1618. case 4:
  1619. return 1; /* Total of 128 pixels */
  1620. case 8:
  1621. return 2; /* Total of 256 pixels/bytes */
  1622. case 16:
  1623. return 512; /* Total of 65536 pixels */
  1624. case 24:
  1625. case 32:
  1626. return 512; /* 65536 pixels */
  1627. case 48:
  1628. case 64:
  1629. return 2048;/* 4 x 65536 pixels. */
  1630. default:
  1631. return 0; /* Error, will be caught later */
  1632. }
  1633. }
  1634. /* The following can only be defined here, now we have the definitions
  1635. * of the transform image sizes.
  1636. */
  1637. static png_uint_32
  1638. standard_width(png_structp pp, png_uint_32 id)
  1639. {
  1640. png_uint_32 width = WIDTH_FROM_ID(id);
  1641. UNUSED(pp)
  1642. if (width == 0)
  1643. width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
  1644. return width;
  1645. }
  1646. static png_uint_32
  1647. standard_height(png_structp pp, png_uint_32 id)
  1648. {
  1649. png_uint_32 height = HEIGHT_FROM_ID(id);
  1650. if (height == 0)
  1651. height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
  1652. return height;
  1653. }
  1654. static png_uint_32
  1655. standard_rowsize(png_structp pp, png_uint_32 id)
  1656. {
  1657. png_uint_32 width = standard_width(pp, id);
  1658. /* This won't overflow: */
  1659. width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
  1660. return (width + 7) / 8;
  1661. }
  1662. static void
  1663. transform_row(png_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
  1664. png_byte colour_type, png_byte bit_depth, png_uint_32 y)
  1665. {
  1666. png_uint_32 v = y << 7;
  1667. png_uint_32 i = 0;
  1668. switch (bit_size(pp, colour_type, bit_depth))
  1669. {
  1670. case 1:
  1671. while (i<128/8) buffer[i] = v & 0xff, v += 17, ++i;
  1672. return;
  1673. case 2:
  1674. while (i<128/4) buffer[i] = v & 0xff, v += 33, ++i;
  1675. return;
  1676. case 4:
  1677. while (i<128/2) buffer[i] = v & 0xff, v += 65, ++i;
  1678. return;
  1679. case 8:
  1680. /* 256 bytes total, 128 bytes in each row set as follows: */
  1681. while (i<128) buffer[i] = v & 0xff, ++v, ++i;
  1682. return;
  1683. case 16:
  1684. /* Generate all 65536 pixel values in order, which includes the 8 bit
  1685. * GA case as well as the 16 bit G case.
  1686. */
  1687. while (i<128)
  1688. buffer[2*i] = (v>>8) & 0xff, buffer[2*i+1] = v & 0xff, ++v, ++i;
  1689. return;
  1690. case 24:
  1691. /* 65535 pixels, but rotate the values. */
  1692. while (i<128)
  1693. {
  1694. /* Three bytes per pixel, r, g, b, make b by r^g */
  1695. buffer[3*i+0] = (v >> 8) & 0xff;
  1696. buffer[3*i+1] = v & 0xff;
  1697. buffer[3*i+2] = ((v >> 8) ^ v) & 0xff;
  1698. ++v;
  1699. ++i;
  1700. }
  1701. return;
  1702. case 32:
  1703. /* 65535 pixels, r, g, b, a; just replicate */
  1704. while (i<128)
  1705. {
  1706. buffer[4*i+0] = (v >> 8) & 0xff;
  1707. buffer[4*i+1] = v & 0xff;
  1708. buffer[4*i+2] = (v >> 8) & 0xff;
  1709. buffer[4*i+3] = v & 0xff;
  1710. ++v;
  1711. ++i;
  1712. }
  1713. return;
  1714. case 48:
  1715. /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at
  1716. * each pixel, g increase by 257 (0x101) and 'b' by 0x1111:
  1717. */
  1718. while (i<128)
  1719. {
  1720. png_uint_32 t = v++;
  1721. buffer[6*i+0] = (t >> 8) & 0xff;
  1722. buffer[6*i+1] = t & 0xff;
  1723. t *= 257;
  1724. buffer[6*i+2] = (t >> 8) & 0xff;
  1725. buffer[6*i+3] = t & 0xff;
  1726. t *= 17;
  1727. buffer[6*i+4] = (t >> 8) & 0xff;
  1728. buffer[6*i+5] = t & 0xff;
  1729. ++i;
  1730. }
  1731. return;
  1732. case 64:
  1733. /* As above in the 32 bit case. */
  1734. while (i<128)
  1735. {
  1736. png_uint_32 t = v++;
  1737. buffer[8*i+0] = (t >> 8) & 0xff;
  1738. buffer[8*i+1] = t & 0xff;
  1739. buffer[8*i+4] = (t >> 8) & 0xff;
  1740. buffer[8*i+5] = t & 0xff;
  1741. t *= 257;
  1742. buffer[8*i+2] = (t >> 8) & 0xff;
  1743. buffer[8*i+3] = t & 0xff;
  1744. buffer[8*i+6] = (t >> 8) & 0xff;
  1745. buffer[8*i+7] = t & 0xff;
  1746. ++i;
  1747. }
  1748. return;
  1749. default:
  1750. break;
  1751. }
  1752. png_error(pp, "internal error");
  1753. }
  1754. /* This is just to do the right cast - could be changed to a function to check
  1755. * 'bd' but there isn't much point.
  1756. */
  1757. #define DEPTH(bd) ((png_byte)(1U << (bd)))
  1758. /* Make a standardized image given a an image colour type, bit depth and
  1759. * interlace type. The standard images have a very restricted range of
  1760. * rows and heights and are used for testing transforms rather than image
  1761. * layout details. See make_size_images below for a way to make images
  1762. * that test odd sizes along with the libpng interlace handling.
  1763. */
  1764. static void
  1765. make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
  1766. png_byte PNG_CONST bit_depth, int interlace_type, png_const_charp name)
  1767. {
  1768. context(ps, fault);
  1769. Try
  1770. {
  1771. png_infop pi;
  1772. png_structp pp = set_store_for_write(ps, &pi, name);
  1773. png_uint_32 h;
  1774. /* In the event of a problem return control to the Catch statement below
  1775. * to do the clean up - it is not possible to 'return' directly from a Try
  1776. * block.
  1777. */
  1778. if (pp == NULL)
  1779. Throw ps;
  1780. h = transform_height(pp, colour_type, bit_depth);
  1781. png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth), h,
  1782. bit_depth, colour_type, interlace_type,
  1783. PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  1784. if (colour_type == 3) /* palette */
  1785. {
  1786. unsigned int i = 0;
  1787. png_color pal[256];
  1788. do
  1789. pal[i].red = pal[i].green = pal[i].blue = (png_byte)i;
  1790. while(++i < 256U);
  1791. png_set_PLTE(pp, pi, pal, 256);
  1792. }
  1793. png_write_info(pp, pi);
  1794. if (png_get_rowbytes(pp, pi) !=
  1795. transform_rowsize(pp, colour_type, bit_depth))
  1796. png_error(pp, "row size incorrect");
  1797. else
  1798. {
  1799. /* Somewhat confusingly this must be called *after* png_write_info
  1800. * because if it is called before, the information in *pp has not been
  1801. * updated to reflect the interlaced image.
  1802. */
  1803. int npasses = png_set_interlace_handling(pp);
  1804. int pass;
  1805. if (npasses != npasses_from_interlace_type(pp, interlace_type))
  1806. png_error(pp, "write: png_set_interlace_handling failed");
  1807. for (pass=0; pass<npasses; ++pass)
  1808. {
  1809. png_uint_32 y;
  1810. for (y=0; y<h; ++y)
  1811. {
  1812. png_byte buffer[TRANSFORM_ROWMAX];
  1813. transform_row(pp, buffer, colour_type, bit_depth, y);
  1814. png_write_row(pp, buffer);
  1815. }
  1816. }
  1817. }
  1818. png_write_end(pp, pi);
  1819. /* And store this under the appropriate id, then clean up. */
  1820. store_storefile(ps, FILEID(colour_type, bit_depth, interlace_type,
  1821. 0, 0, 0));
  1822. store_write_reset(ps);
  1823. }
  1824. Catch(fault)
  1825. {
  1826. /* Use the png_store returned by the exception. This may help the compiler
  1827. * because 'ps' is not used in this branch of the setjmp. Note that fault
  1828. * and ps will always be the same value.
  1829. */
  1830. store_write_reset(fault);
  1831. }
  1832. }
  1833. static void
  1834. make_standard(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
  1835. int PNG_CONST bdhi)
  1836. {
  1837. for (; bdlo <= bdhi; ++bdlo)
  1838. {
  1839. int interlace_type;
  1840. for (interlace_type = PNG_INTERLACE_NONE;
  1841. interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
  1842. {
  1843. char name[FILE_NAME_SIZE];
  1844. standard_name(name, sizeof name, 0, colour_type, bdlo, interlace_type,
  1845. 0, 0, 0);
  1846. make_transform_image(ps, colour_type, DEPTH(bdlo), interlace_type,
  1847. name);
  1848. }
  1849. }
  1850. }
  1851. static void
  1852. make_transform_images(png_store *ps)
  1853. {
  1854. /* This is in case of errors. */
  1855. safecat(ps->test, sizeof ps->test, 0, "make standard images");
  1856. /* Arguments are colour_type, low bit depth, high bit depth
  1857. */
  1858. make_standard(ps, 0, 0, WRITE_BDHI);
  1859. make_standard(ps, 2, 3, WRITE_BDHI);
  1860. make_standard(ps, 3, 0, 3 /*palette: max 8 bits*/);
  1861. make_standard(ps, 4, 3, WRITE_BDHI);
  1862. make_standard(ps, 6, 3, WRITE_BDHI);
  1863. }
  1864. /* The following two routines use the PNG interlace support macros from
  1865. * png.h to interlace or deinterlace rows.
  1866. */
  1867. static void
  1868. interlace_row(png_bytep buffer, png_const_bytep imageRow,
  1869. unsigned int pixel_size, png_uint_32 w, int pass)
  1870. {
  1871. png_uint_32 xin, xout, xstep;
  1872. /* Note that this can, trivially, be optimized to a memcpy on pass 7, the
  1873. * code is presented this way to make it easier to understand. In practice
  1874. * consult the code in the libpng source to see other ways of doing this.
  1875. */
  1876. xin = PNG_PASS_START_COL(pass);
  1877. xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
  1878. for (xout=0; xin<w; xin+=xstep)
  1879. {
  1880. pixel_copy(buffer, xout, imageRow, xin, pixel_size);
  1881. ++xout;
  1882. }
  1883. }
  1884. static void
  1885. deinterlace_row(png_bytep buffer, png_const_bytep row,
  1886. unsigned int pixel_size, png_uint_32 w, int pass)
  1887. {
  1888. /* The inverse of the above, 'row' is part of row 'y' of the output image,
  1889. * in 'buffer'. The image is 'w' wide and this is pass 'pass', distribute
  1890. * the pixels of row into buffer and return the number written (to allow
  1891. * this to be checked).
  1892. */
  1893. png_uint_32 xin, xout, xstep;
  1894. xout = PNG_PASS_START_COL(pass);
  1895. xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
  1896. for (xin=0; xout<w; xout+=xstep)
  1897. {
  1898. pixel_copy(buffer, xout, row, xin, pixel_size);
  1899. ++xin;
  1900. }
  1901. }
  1902. /* Build a single row for the 'size' test images, this fills in only the
  1903. * first bit_width bits of the sample row.
  1904. */
  1905. static void
  1906. size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y)
  1907. {
  1908. /* height is in the range 1 to 16, so: */
  1909. y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4);
  1910. /* the following ensures bits are set in small images: */
  1911. y ^= 0xA5;
  1912. while (bit_width >= 8)
  1913. *buffer++ = (png_byte)y++, bit_width -= 8;
  1914. /* There may be up to 7 remaining bits, these go in the most significant
  1915. * bits of the byte.
  1916. */
  1917. if (bit_width > 0)
  1918. {
  1919. png_uint_32 mask = (1U<<(8-bit_width))-1;
  1920. *buffer = (png_byte)((*buffer & mask) | (y & ~mask));
  1921. }
  1922. }
  1923. static void
  1924. make_size_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
  1925. png_byte PNG_CONST bit_depth, int PNG_CONST interlace_type,
  1926. png_uint_32 PNG_CONST w, png_uint_32 PNG_CONST h,
  1927. int PNG_CONST do_interlace)
  1928. {
  1929. context(ps, fault);
  1930. Try
  1931. {
  1932. png_infop pi;
  1933. png_structp pp;
  1934. unsigned int pixel_size;
  1935. /* Make a name and get an appropriate id for the store: */
  1936. char name[FILE_NAME_SIZE];
  1937. PNG_CONST png_uint_32 id = FILEID(colour_type, bit_depth, interlace_type,
  1938. w, h, do_interlace);
  1939. standard_name_from_id(name, sizeof name, 0, id);
  1940. pp = set_store_for_write(ps, &pi, name);
  1941. /* In the event of a problem return control to the Catch statement below
  1942. * to do the clean up - it is not possible to 'return' directly from a Try
  1943. * block.
  1944. */
  1945. if (pp == NULL)
  1946. Throw ps;
  1947. png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
  1948. PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  1949. /* Same palette as make_transform_image - I don' think there is any
  1950. * benefit from using a different one (JB 20101211)
  1951. */
  1952. if (colour_type == 3) /* palette */
  1953. {
  1954. unsigned int i = 0;
  1955. png_color pal[256];
  1956. do
  1957. pal[i].red = pal[i].green = pal[i].blue = (png_byte)i;
  1958. while(++i < 256U);
  1959. png_set_PLTE(pp, pi, pal, 256);
  1960. }
  1961. png_write_info(pp, pi);
  1962. /* Calculate the bit size, divide by 8 to get the byte size - this won't
  1963. * overflow because we know the w values are all small enough even for
  1964. * a system where 'unsigned int' is only 16 bits.
  1965. */
  1966. pixel_size = bit_size(pp, colour_type, bit_depth);
  1967. if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8)
  1968. png_error(pp, "row size incorrect");
  1969. else
  1970. {
  1971. int npasses = npasses_from_interlace_type(pp, interlace_type);
  1972. png_uint_32 y;
  1973. int pass;
  1974. png_byte image[16][SIZE_ROWMAX];
  1975. /* To help consistent error detection make the parts of this buffer
  1976. * that aren't set below all '1':
  1977. */
  1978. memset(image, 0xff, sizeof image);
  1979. if (!do_interlace && npasses != png_set_interlace_handling(pp))
  1980. png_error(pp, "write: png_set_interlace_handling failed");
  1981. /* Prepare the whole image first to avoid making it 7 times: */
  1982. for (y=0; y<h; ++y)
  1983. size_row(image[y], w * pixel_size, y);
  1984. for (pass=0; pass<npasses; ++pass)
  1985. {
  1986. /* The following two are for checking the macros: */
  1987. PNG_CONST png_uint_32 wPass = PNG_PASS_COLS(w, pass);
  1988. /* If do_interlace is set we don't call png_write_row for every
  1989. * row because some of them are empty. In fact, for a 1x1 image,
  1990. * most of them are empty!
  1991. */
  1992. for (y=0; y<h; ++y)
  1993. {
  1994. png_const_bytep row = image[y];
  1995. png_byte tempRow[SIZE_ROWMAX];
  1996. /* If do_interlace *and* the image is interlaced we
  1997. * need a reduced interlace row, this may be reduced
  1998. * to empty.
  1999. */
  2000. if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7)
  2001. {
  2002. /* The row must not be written if it doesn't exist, notice
  2003. * that there are two conditions here, either the row isn't
  2004. * ever in the pass or the row would be but isn't wide
  2005. * enough to contribute any pixels. In fact the wPass test
  2006. * can be used to skip the whole y loop in this case.
  2007. */
  2008. if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0)
  2009. {
  2010. /* Set to all 1's for error detection (libpng tends to
  2011. * set unset things to 0).
  2012. */
  2013. memset(tempRow, 0xff, sizeof tempRow);
  2014. interlace_row(tempRow, row, pixel_size, w, pass);
  2015. row = tempRow;
  2016. }
  2017. else
  2018. continue;
  2019. }
  2020. /* Only get to here if the row has some pixels in it. */
  2021. png_write_row(pp, row);
  2022. }
  2023. }
  2024. }
  2025. png_write_end(pp, pi);
  2026. /* And store this under the appropriate id, then clean up. */
  2027. store_storefile(ps, id);
  2028. store_write_reset(ps);
  2029. }
  2030. Catch(fault)
  2031. {
  2032. /* Use the png_store returned by the exception. This may help the compiler
  2033. * because 'ps' is not used in this branch of the setjmp. Note that fault
  2034. * and ps will always be the same value.
  2035. */
  2036. store_write_reset(fault);
  2037. }
  2038. }
  2039. static void
  2040. make_size(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type, int bdlo,
  2041. int PNG_CONST bdhi)
  2042. {
  2043. for (; bdlo <= bdhi; ++bdlo)
  2044. {
  2045. png_uint_32 width;
  2046. for (width = 1; width <= 16; ++width)
  2047. {
  2048. png_uint_32 height;
  2049. for (height = 1; height <= 16; ++height)
  2050. {
  2051. /* The four combinations of DIY interlace and interlace or not -
  2052. * no interlace + DIY should be identical to no interlace with
  2053. * libpng doing it.
  2054. */
  2055. make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
  2056. width, height, 0);
  2057. make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
  2058. width, height, 1);
  2059. make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
  2060. width, height, 0);
  2061. make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
  2062. width, height, 1);
  2063. }
  2064. }
  2065. }
  2066. }
  2067. static void
  2068. make_size_images(png_store *ps)
  2069. {
  2070. /* This is in case of errors. */
  2071. safecat(ps->test, sizeof ps->test, 0, "make size images");
  2072. /* Arguments are colour_type, low bit depth, high bit depth
  2073. */
  2074. make_size(ps, 0, 0, WRITE_BDHI);
  2075. make_size(ps, 2, 3, WRITE_BDHI);
  2076. make_size(ps, 3, 0, 3 /*palette: max 8 bits*/);
  2077. make_size(ps, 4, 3, WRITE_BDHI);
  2078. make_size(ps, 6, 3, WRITE_BDHI);
  2079. }
  2080. /* Return a row based on image id and 'y' for checking: */
  2081. static void
  2082. standard_row(png_structp pp, png_byte std[STANDARD_ROWMAX], png_uint_32 id,
  2083. png_uint_32 y)
  2084. {
  2085. if (WIDTH_FROM_ID(id) == 0)
  2086. transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y);
  2087. else
  2088. size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id),
  2089. DEPTH_FROM_ID(id)), y);
  2090. }
  2091. /* Tests - individual test cases */
  2092. /* Like 'make_standard' but errors are deliberately introduced into the calls
  2093. * to ensure that they get detected - it should not be possible to write an
  2094. * invalid image with libpng!
  2095. */
  2096. static void
  2097. sBIT0_error_fn(png_structp pp, png_infop pi)
  2098. {
  2099. /* 0 is invalid... */
  2100. png_color_8 bad;
  2101. bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0;
  2102. png_set_sBIT(pp, pi, &bad);
  2103. }
  2104. static void
  2105. sBIT_error_fn(png_structp pp, png_infop pi)
  2106. {
  2107. png_byte bit_depth;
  2108. png_color_8 bad;
  2109. if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE)
  2110. bit_depth = 8;
  2111. else
  2112. bit_depth = png_get_bit_depth(pp, pi);
  2113. /* Now we know the bit depth we can easily generate an invalid sBIT entry */
  2114. bad.red = bad.green = bad.blue = bad.gray = bad.alpha =
  2115. (png_byte)(bit_depth+1);
  2116. png_set_sBIT(pp, pi, &bad);
  2117. }
  2118. static PNG_CONST struct
  2119. {
  2120. void (*fn)(png_structp, png_infop);
  2121. PNG_CONST char *msg;
  2122. unsigned int warning :1; /* the error is a warning... */
  2123. } error_test[] =
  2124. {
  2125. { sBIT0_error_fn, "sBIT(0): failed to detect error", 1 },
  2126. { sBIT_error_fn, "sBIT(too big): failed to detect error", 1 },
  2127. };
  2128. static void
  2129. make_error(png_store* volatile ps, png_byte PNG_CONST colour_type,
  2130. png_byte bit_depth, int interlace_type, int test, png_const_charp name)
  2131. {
  2132. context(ps, fault);
  2133. Try
  2134. {
  2135. png_structp pp;
  2136. png_infop pi;
  2137. pp = set_store_for_write(ps, &pi, name);
  2138. if (pp == NULL)
  2139. Throw ps;
  2140. png_set_IHDR(pp, pi, transform_width(pp, colour_type, bit_depth),
  2141. transform_height(pp, colour_type, bit_depth), bit_depth, colour_type,
  2142. interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  2143. if (colour_type == 3) /* palette */
  2144. {
  2145. unsigned int i = 0;
  2146. png_color pal[256];
  2147. do
  2148. pal[i].red = pal[i].green = pal[i].blue = (png_byte)i;
  2149. while(++i < 256U);
  2150. png_set_PLTE(pp, pi, pal, 256);
  2151. }
  2152. /* Time for a few errors, these are in various optional chunks, the
  2153. * standard tests test the standard chunks pretty well.
  2154. */
  2155. # define exception__prev exception_prev_1
  2156. # define exception__env exception_env_1
  2157. Try
  2158. {
  2159. /* Expect this to throw: */
  2160. ps->expect_error = !error_test[test].warning;
  2161. ps->expect_warning = error_test[test].warning;
  2162. ps->saw_warning = 0;
  2163. error_test[test].fn(pp, pi);
  2164. /* Normally the error is only detected here: */
  2165. png_write_info(pp, pi);
  2166. /* And handle the case where it was only a warning: */
  2167. if (ps->expect_warning && ps->saw_warning)
  2168. Throw ps;
  2169. /* If we get here there is a problem, we have success - no error or
  2170. * no warning - when we shouldn't have success. Log an error.
  2171. */
  2172. store_log(ps, pp, error_test[test].msg, 1 /*error*/);
  2173. }
  2174. Catch (fault)
  2175. ps = fault; /* expected exit, make sure ps is not clobbered */
  2176. #undef exception__prev
  2177. #undef exception__env
  2178. /* And clear these flags */
  2179. ps->expect_error = 0;
  2180. ps->expect_warning = 0;
  2181. /* Now write the whole image, just to make sure that the detected, or
  2182. * undetected, errro has not created problems inside libpng.
  2183. */
  2184. if (png_get_rowbytes(pp, pi) !=
  2185. transform_rowsize(pp, colour_type, bit_depth))
  2186. png_error(pp, "row size incorrect");
  2187. else
  2188. {
  2189. png_uint_32 h = transform_height(pp, colour_type, bit_depth);
  2190. int npasses = png_set_interlace_handling(pp);
  2191. int pass;
  2192. if (npasses != npasses_from_interlace_type(pp, interlace_type))
  2193. png_error(pp, "write: png_set_interlace_handling failed");
  2194. for (pass=0; pass<npasses; ++pass)
  2195. {
  2196. png_uint_32 y;
  2197. for (y=0; y<h; ++y)
  2198. {
  2199. png_byte buffer[TRANSFORM_ROWMAX];
  2200. transform_row(pp, buffer, colour_type, bit_depth, y);
  2201. png_write_row(pp, buffer);
  2202. }
  2203. }
  2204. }
  2205. png_write_end(pp, pi);
  2206. /* The following deletes the file that was just written. */
  2207. store_write_reset(ps);
  2208. }
  2209. Catch(fault)
  2210. {
  2211. store_write_reset(fault);
  2212. }
  2213. }
  2214. static int
  2215. make_errors(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
  2216. int bdlo, int PNG_CONST bdhi)
  2217. {
  2218. for (; bdlo <= bdhi; ++bdlo)
  2219. {
  2220. int interlace_type;
  2221. for (interlace_type = PNG_INTERLACE_NONE;
  2222. interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
  2223. {
  2224. unsigned int test;
  2225. char name[FILE_NAME_SIZE];
  2226. standard_name(name, sizeof name, 0, colour_type, bdlo, interlace_type,
  2227. 0, 0, 0);
  2228. for (test=0; test<(sizeof error_test)/(sizeof error_test[0]); ++test)
  2229. {
  2230. make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type,
  2231. test, name);
  2232. if (fail(pm))
  2233. return 0;
  2234. }
  2235. }
  2236. }
  2237. return 1; /* keep going */
  2238. }
  2239. static void
  2240. perform_error_test(png_modifier *pm)
  2241. {
  2242. /* Need to do this here because we just write in this test. */
  2243. safecat(pm->this.test, sizeof pm->this.test, 0, "error test");
  2244. if (!make_errors(pm, 0, 0, WRITE_BDHI))
  2245. return;
  2246. if (!make_errors(pm, 2, 3, WRITE_BDHI))
  2247. return;
  2248. if (!make_errors(pm, 3, 0, 3))
  2249. return;
  2250. if (!make_errors(pm, 4, 3, WRITE_BDHI))
  2251. return;
  2252. if (!make_errors(pm, 6, 3, WRITE_BDHI))
  2253. return;
  2254. }
  2255. /* Because we want to use the same code in both the progressive reader and the
  2256. * sequential reader it is necessary to deal with the fact that the progressive
  2257. * reader callbacks only have one parameter (png_get_progressive_ptr()), so this
  2258. * must contain all the test parameters and all the local variables directly
  2259. * accessible to the sequential reader implementation.
  2260. *
  2261. * The technique adopted is to reinvent part of what Dijkstra termed a
  2262. * 'display'; an array of pointers to the stack frames of enclosing functions so
  2263. * that a nested function definition can access the local (C auto) variables of
  2264. * the functions that contain its definition. In fact C provides the first
  2265. * pointer (the local variables - the stack frame pointer) and the last (the
  2266. * global variables - the BCPL global vector typically implemented as global
  2267. * addresses), this code requires one more pointer to make the display - the
  2268. * local variables (and function call parameters) of the function that actually
  2269. * invokes either the progressive or sequential reader.
  2270. *
  2271. * Perhaps confusingly this technique is confounded with classes - the
  2272. * 'standard_display' defined here is sub-classed as the 'gamma_display' below.
  2273. * A gamma_display is a standard_display, taking advantage of the ANSI-C
  2274. * requirement that the pointer to the first member of a structure must be the
  2275. * same as the pointer to the structure. This allows us to reuse standard_
  2276. * functions in the gamma test code; something that could not be done with
  2277. * nested funtions!
  2278. */
  2279. typedef struct standard_palette_entry /* pngvalid format palette! */
  2280. {
  2281. png_byte red;
  2282. png_byte green;
  2283. png_byte blue;
  2284. png_byte alpha;
  2285. } standard_palette[256];
  2286. typedef struct standard_display
  2287. {
  2288. png_store* ps; /* Test parameters (passed to the function) */
  2289. png_byte colour_type;
  2290. png_byte bit_depth;
  2291. png_byte red_sBIT; /* Input data sBIT values. */
  2292. png_byte green_sBIT;
  2293. png_byte blue_sBIT;
  2294. png_byte alpha_sBIT;
  2295. int interlace_type;
  2296. png_uint_32 id; /* Calculated file ID */
  2297. png_uint_32 w; /* Width of image */
  2298. png_uint_32 h; /* Height of image */
  2299. int npasses; /* Number of interlaced passes */
  2300. png_uint_32 pixel_size; /* Width of one pixel in bits */
  2301. png_uint_32 bit_width; /* Width of output row in bits */
  2302. size_t cbRow; /* Bytes in a row of the output image */
  2303. int do_interlace; /* Do interlacing internally */
  2304. int is_transparent; /* Transparecy information was present. */
  2305. struct
  2306. {
  2307. png_uint_16 red;
  2308. png_uint_16 green;
  2309. png_uint_16 blue;
  2310. } transparent; /* The transparent color, if set. */
  2311. standard_palette
  2312. palette;
  2313. } standard_display;
  2314. static void
  2315. standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
  2316. int do_interlace)
  2317. {
  2318. dp->ps = ps;
  2319. dp->colour_type = COL_FROM_ID(id);
  2320. dp->bit_depth = DEPTH_FROM_ID(id);
  2321. dp->alpha_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =
  2322. dp->bit_depth;
  2323. dp->interlace_type = INTERLACE_FROM_ID(id);
  2324. dp->id = id;
  2325. /* All the rest are filled in after the read_info: */
  2326. dp->w = 0;
  2327. dp->h = 0;
  2328. dp->npasses = 0;
  2329. dp->pixel_size = 0;
  2330. dp->bit_width = 0;
  2331. dp->cbRow = 0;
  2332. dp->do_interlace = do_interlace;
  2333. dp->is_transparent = 0;
  2334. /* Preset the transparent color to black: */
  2335. memset(&dp->transparent, 0, sizeof dp->transparent);
  2336. /* Preset the palette to full intensity/opaque througout: */
  2337. memset(dp->palette, 0xff, sizeof dp->palette);
  2338. }
  2339. /* Call this only if the colour type is 3 - PNG_COLOR_TYPE_PALETTE - otherwise
  2340. * it will png_error out. The API returns true if tRNS information was
  2341. * present.
  2342. */
  2343. static int
  2344. standard_palette_init(standard_palette palette, png_structp pp, png_infop pi)
  2345. {
  2346. png_colorp pal;
  2347. png_bytep trans_alpha;
  2348. int num;
  2349. pal = 0;
  2350. num = -1;
  2351. if (png_get_PLTE(pp, pi, &pal, &num) & PNG_INFO_PLTE)
  2352. {
  2353. int i;
  2354. for (i=0; i<num; ++i)
  2355. {
  2356. palette[i].red = pal[i].red;
  2357. palette[i].green = pal[i].green;
  2358. palette[i].blue = pal[i].blue;
  2359. }
  2360. /* Mark the remainder of the entries with a flag value: */
  2361. for (; i<256; ++i)
  2362. palette[i].red = palette[i].green = palette[i].blue = 126;
  2363. }
  2364. else /* !png_get_PLTE */
  2365. png_error(pp, "validate: missing PLTE with color type 3");
  2366. trans_alpha = 0;
  2367. num = -1;
  2368. if (png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS)
  2369. {
  2370. int i;
  2371. /* Any of these are crash-worthy - given the implementation of
  2372. * png_get_tRNS up to 1.5 an app won't crash if it just checks the
  2373. * result above and fails to check that the variables it passed have
  2374. * actually been filled in! Note that if the app were to pass the
  2375. * last, png_color_16p, variable too it couldn't rely on this.
  2376. */
  2377. if (trans_alpha == 0 || num <= 0 || num > 256)
  2378. png_error(pp, "validate: unexpected png_get_tRNS (palette) result");
  2379. for (i=0; i<num; ++i)
  2380. palette[i].alpha = trans_alpha[i];
  2381. for (; i<256; ++i)
  2382. palette[i].alpha = 255;
  2383. return 1; /* transparency */
  2384. }
  2385. else
  2386. {
  2387. /* No transparency - just set the alpha channel to opaque. */
  2388. int i;
  2389. for (i=0; i<256; ++i)
  2390. palette[i].alpha = 255;
  2391. return 0; /* no transparency */
  2392. }
  2393. }
  2394. /* By passing a 'standard_display' the progressive callbacks can be used
  2395. * directly by the sequential code, the functions suffixed "_imp" are the
  2396. * implementations, the functions without the suffix are the callbacks.
  2397. *
  2398. * The code for the info callback is split into two because this callback calls
  2399. * png_read_update_info or png_start_read_image and what gets called depends on
  2400. * whether the info needs updating (we want to test both calls in pngvalid.)
  2401. */
  2402. static void
  2403. standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
  2404. {
  2405. if (png_get_bit_depth(pp, pi) != dp->bit_depth)
  2406. png_error(pp, "validate: bit depth changed");
  2407. if (png_get_color_type(pp, pi) != dp->colour_type)
  2408. png_error(pp, "validate: color type changed");
  2409. if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE)
  2410. png_error(pp, "validate: filter type changed");
  2411. if (png_get_interlace_type(pp, pi) != dp->interlace_type)
  2412. png_error(pp, "validate: interlacing changed");
  2413. if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE)
  2414. png_error(pp, "validate: compression type changed");
  2415. dp->w = png_get_image_width(pp, pi);
  2416. if (dp->w != standard_width(pp, dp->id))
  2417. png_error(pp, "validate: image width changed");
  2418. dp->h = png_get_image_height(pp, pi);
  2419. if (dp->h != standard_height(pp, dp->id))
  2420. png_error(pp, "validate: image height changed");
  2421. /* Record (but don't check at present) the input sBIT according to the colour
  2422. * type information.
  2423. */
  2424. {
  2425. png_color_8p sBIT = 0;
  2426. if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT)
  2427. {
  2428. int sBIT_invalid = 0;
  2429. if (sBIT == 0)
  2430. png_error(pp, "validate: unexpected png_get_sBIT result");
  2431. if (dp->colour_type & PNG_COLOR_MASK_COLOR)
  2432. {
  2433. if (sBIT->red == 0 || sBIT->red > dp->bit_depth)
  2434. sBIT_invalid = 1;
  2435. else
  2436. dp->red_sBIT = sBIT->red;
  2437. if (sBIT->green == 0 || sBIT->green > dp->bit_depth)
  2438. sBIT_invalid = 1;
  2439. else
  2440. dp->green_sBIT = sBIT->green;
  2441. if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth)
  2442. sBIT_invalid = 1;
  2443. else
  2444. dp->blue_sBIT = sBIT->blue;
  2445. }
  2446. else /* !COLOR */
  2447. {
  2448. if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth)
  2449. sBIT_invalid = 1;
  2450. else
  2451. dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray;
  2452. }
  2453. /* All 8 bits in tRNS for a palette image are significant - see the
  2454. * spec.
  2455. */
  2456. if (dp->colour_type & PNG_COLOR_MASK_ALPHA)
  2457. {
  2458. if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth)
  2459. sBIT_invalid = 1;
  2460. else
  2461. dp->alpha_sBIT = sBIT->alpha;
  2462. }
  2463. if (sBIT_invalid)
  2464. png_error(pp, "validate: sBIT value out of range");
  2465. }
  2466. }
  2467. /* Important: this is validating the value *before* any transforms have been
  2468. * put in place. It doesn't matter for the standard tests, where there are
  2469. * no transforms, but it does for other tests where rowbytes may change after
  2470. * png_read_update_info.
  2471. */
  2472. if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id))
  2473. png_error(pp, "validate: row size changed");
  2474. /* The palette is never read for non-palette images, even though it is valid
  2475. * - this could be changed.
  2476. */
  2477. if (dp->colour_type == 3) /* palette */
  2478. {
  2479. int i;
  2480. dp->is_transparent = standard_palette_init(dp->palette, pp, pi);
  2481. /* And validate the result. */
  2482. for (i=0; i<256; ++i)
  2483. if (dp->palette[i].red != i || dp->palette[i].green != i ||
  2484. dp->palette[i].blue != i)
  2485. png_error(pp, "validate: color type 3 PLTE chunk changed");
  2486. }
  2487. /* In any case always check for a tranparent color: */
  2488. {
  2489. png_color_16p trans_color = 0;
  2490. if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS)
  2491. {
  2492. if (trans_color == 0)
  2493. png_error(pp, "validate: unexpected png_get_tRNS (color) result");
  2494. switch (dp->colour_type)
  2495. {
  2496. case 0:
  2497. dp->transparent.red = dp->transparent.green = dp->transparent.blue =
  2498. trans_color->gray;
  2499. dp->is_transparent = 1;
  2500. break;
  2501. case 2:
  2502. dp->transparent.red = trans_color->red;
  2503. dp->transparent.green = trans_color->green;
  2504. dp->transparent.blue = trans_color->blue;
  2505. dp->is_transparent = 1;
  2506. break;
  2507. case 3:
  2508. /* Not expected because it should result in the array case
  2509. * above.
  2510. */
  2511. png_error(pp, "validate: unexpected png_get_tRNS result");
  2512. break;
  2513. default:
  2514. png_error(pp, "validate: invalid tRNS chunk with alpha image");
  2515. }
  2516. }
  2517. }
  2518. /* Read the number of passes - expected to match the value used when
  2519. * creating the image (interlaced or not). This has the side effect of
  2520. * turning on interlace handling (if do_interlace is not set.)
  2521. */
  2522. dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type);
  2523. if (!dp->do_interlace && dp->npasses != png_set_interlace_handling(pp))
  2524. png_error(pp, "validate: file changed interlace type");
  2525. /* Caller calls png_read_update_info or png_start_read_image now, then calls
  2526. * part2.
  2527. */
  2528. }
  2529. /* This must be called *after* the png_read_update_info call to get the correct
  2530. * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed
  2531. * image.
  2532. */
  2533. static void
  2534. standard_info_part2(standard_display *dp, png_structp pp, png_infop pi,
  2535. int nImages)
  2536. {
  2537. /* Record cbRow now that it can be found. */
  2538. dp->pixel_size = bit_size(pp, png_get_color_type(pp, pi),
  2539. png_get_bit_depth(pp, pi));
  2540. dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;
  2541. dp->cbRow = png_get_rowbytes(pp, pi);
  2542. /* Validate the rowbytes here again. */
  2543. if (dp->cbRow != (dp->bit_width+7)/8)
  2544. png_error(pp, "bad png_get_rowbytes calculation");
  2545. /* Then ensure there is enough space for the output image(s). */
  2546. store_ensure_image(dp->ps, pp, nImages * dp->cbRow * dp->h);
  2547. }
  2548. static void
  2549. standard_info_imp(standard_display *dp, png_structp pp, png_infop pi,
  2550. int nImages)
  2551. {
  2552. /* Note that the validation routine has the side effect of turning on
  2553. * interlace handling in the subsequent code.
  2554. */
  2555. standard_info_part1(dp, pp, pi);
  2556. /* And the info callback has to call this (or png_read_update_info - see
  2557. * below in the png_modifier code for that variant.
  2558. */
  2559. png_start_read_image(pp);
  2560. /* Validate the height, width and rowbytes plus ensure that sufficient buffer
  2561. * exists for decoding the image.
  2562. */
  2563. standard_info_part2(dp, pp, pi, nImages);
  2564. }
  2565. static void
  2566. standard_info(png_structp pp, png_infop pi)
  2567. {
  2568. standard_display *dp = png_get_progressive_ptr(pp);
  2569. /* Call with nImages==1 because the progressive reader can only produce one
  2570. * image.
  2571. */
  2572. standard_info_imp(dp, pp, pi, 1 /*only one image*/);
  2573. }
  2574. static void
  2575. progressive_row(png_structp pp, png_bytep new_row, png_uint_32 y, int pass)
  2576. {
  2577. PNG_CONST standard_display *dp = png_get_progressive_ptr(pp);
  2578. /* When handling interlacing some rows will be absent in each pass, the
  2579. * callback still gets called, but with a NULL pointer. This is checked
  2580. * in the 'else' clause below. We need our own 'cbRow', but we can't call
  2581. * png_get_rowbytes because we got no info structure.
  2582. */
  2583. if (new_row != NULL)
  2584. {
  2585. png_bytep row;
  2586. /* In the case where the reader doesn't do the interlace it gives
  2587. * us the y in the sub-image:
  2588. */
  2589. if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7)
  2590. {
  2591. /* Use this opportunity to validate the png 'current' APIs: */
  2592. if (y != png_get_current_row_number(pp))
  2593. png_error(pp, "png_get_current_row_number is broken");
  2594. if (pass != png_get_current_pass_number(pp))
  2595. png_error(pp, "png_get_current_pass_number is broken");
  2596. y = PNG_ROW_FROM_PASS_ROW(y, pass);
  2597. }
  2598. /* Validate this just in case. */
  2599. if (y >= dp->h)
  2600. png_error(pp, "invalid y to progressive row callback");
  2601. row = dp->ps->image + y * dp->cbRow;
  2602. /* Combine the new row into the old: */
  2603. if (dp->do_interlace)
  2604. {
  2605. if (dp->interlace_type == PNG_INTERLACE_ADAM7)
  2606. deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass);
  2607. else
  2608. memcpy(row, new_row, dp->cbRow);
  2609. }
  2610. else
  2611. png_progressive_combine_row(pp, row, new_row);
  2612. } else if (dp->interlace_type == PNG_INTERLACE_ADAM7 &&
  2613. PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
  2614. PNG_PASS_COLS(dp->w, pass) > 0)
  2615. png_error(pp, "missing row in progressive de-interlacing");
  2616. }
  2617. static void
  2618. sequential_row(standard_display *dp, png_structp pp, png_infop pi,
  2619. PNG_CONST png_bytep pImage, PNG_CONST png_bytep pDisplay)
  2620. {
  2621. PNG_CONST int npasses = dp->npasses;
  2622. PNG_CONST int do_interlace = dp->do_interlace &&
  2623. dp->interlace_type == PNG_INTERLACE_ADAM7;
  2624. PNG_CONST png_uint_32 height = standard_height(pp, dp->id);
  2625. PNG_CONST png_uint_32 width = standard_width(pp, dp->id);
  2626. PNG_CONST size_t cbRow = dp->cbRow;
  2627. int pass;
  2628. for (pass=0; pass<npasses; ++pass)
  2629. {
  2630. png_uint_32 y;
  2631. png_uint_32 wPass = PNG_PASS_COLS(width, pass);
  2632. png_bytep pRow1 = pImage;
  2633. png_bytep pRow2 = pDisplay;
  2634. for (y=0; y<height; ++y)
  2635. {
  2636. if (do_interlace)
  2637. {
  2638. /* wPass may be zero or this row may not be in this pass.
  2639. * png_read_row must not be called in either case.
  2640. */
  2641. if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass))
  2642. {
  2643. /* Read the row into a pair of temporary buffers, then do the
  2644. * merge here into the output rows.
  2645. */
  2646. png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX];
  2647. /* The following aids (to some extent) error detection - we can
  2648. * see where png_read_row wrote. Use opposite values in row and
  2649. * display to make this easier.
  2650. */
  2651. memset(row, 0xff, sizeof row);
  2652. memset(display, 0, sizeof display);
  2653. png_read_row(pp, row, display);
  2654. if (pRow1 != NULL)
  2655. deinterlace_row(pRow1, row, dp->pixel_size, dp->w, pass);
  2656. if (pRow2 != NULL)
  2657. deinterlace_row(pRow2, display, dp->pixel_size, dp->w, pass);
  2658. }
  2659. }
  2660. else
  2661. png_read_row(pp, pRow1, pRow2);
  2662. if (pRow1 != NULL)
  2663. pRow1 += cbRow;
  2664. if (pRow2 != NULL)
  2665. pRow2 += cbRow;
  2666. }
  2667. }
  2668. /* And finish the read operation (only really necessary if the caller wants
  2669. * to find additional data in png_info from chunks after the last IDAT.)
  2670. */
  2671. png_read_end(pp, pi);
  2672. }
  2673. static void
  2674. standard_row_validate(standard_display *dp, png_structp pp, png_const_bytep row,
  2675. png_const_bytep display, png_uint_32 y)
  2676. {
  2677. png_byte std[STANDARD_ROWMAX];
  2678. memset(std, 0xff, sizeof std);
  2679. standard_row(pp, std, dp->id, y);
  2680. /* At the end both the 'row' and 'display' arrays should end up identical.
  2681. * In earlier passes 'row' will be partially filled in, with only the pixels
  2682. * that have been read so far, but 'display' will have those pixels
  2683. * replicated to fill the unread pixels while reading an interlaced image.
  2684. * The side effect inside the libpng sequential reader is that the 'row'
  2685. * array retains the correct values for unwritten pixels within the row
  2686. * bytes, while the 'display' array gets bits off the end of the image (in
  2687. * the last byte) trashed. Unfortunately in the progressive reader the
  2688. * row bytes are always trashed, so we always do a pixel_cmp here even though
  2689. * a memcmp of all cbRow bytes will succeed for the sequential reader.
  2690. */
  2691. if (row != NULL && pixel_cmp(std, row, dp->bit_width) != 0)
  2692. {
  2693. char msg[64];
  2694. sprintf(msg, "PNG image row %d changed", y);
  2695. png_error(pp, msg);
  2696. }
  2697. /* In this case use pixel_cmp because we need to compare a partial
  2698. * byte at the end of the row if the row is not an exact multiple
  2699. * of 8 bits wide.
  2700. */
  2701. if (display != NULL && pixel_cmp(std, display, dp->bit_width) != 0)
  2702. {
  2703. char msg[64];
  2704. sprintf(msg, "display row %d changed", y);
  2705. png_error(pp, msg);
  2706. }
  2707. }
  2708. static void
  2709. standard_image_validate(standard_display *dp, png_structp pp,
  2710. png_const_bytep pImage, png_const_bytep pDisplay)
  2711. {
  2712. png_uint_32 y;
  2713. for (y=0; y<dp->h; ++y)
  2714. {
  2715. standard_row_validate(dp, pp, pImage, pDisplay, y);
  2716. if (pImage != NULL)
  2717. pImage += dp->cbRow;
  2718. if (pDisplay != NULL)
  2719. pDisplay += dp->cbRow;
  2720. }
  2721. /* This avoids false positives if the validation code is never called! */
  2722. dp->ps->validated = 1;
  2723. }
  2724. static void
  2725. standard_end(png_structp pp, png_infop pi)
  2726. {
  2727. standard_display *dp = png_get_progressive_ptr(pp);
  2728. UNUSED(pi)
  2729. /* Validate the image - progressive reading only produces one variant for
  2730. * interlaced images.
  2731. */
  2732. standard_image_validate(dp, pp, dp->ps->image, NULL);
  2733. }
  2734. /* A single test run checking the standard image to ensure it is not damaged. */
  2735. static void
  2736. standard_test(png_store* PNG_CONST psIn, png_uint_32 PNG_CONST id,
  2737. int do_interlace)
  2738. {
  2739. standard_display d;
  2740. context(psIn, fault);
  2741. /* Set up the display (stack frame) variables from the arguments to the
  2742. * function and initialize the locals that are filled in later.
  2743. */
  2744. standard_display_init(&d, psIn, id, do_interlace);
  2745. /* Everything is protected by a Try/Catch. The functions called also
  2746. * typically have local Try/Catch blocks.
  2747. */
  2748. Try
  2749. {
  2750. png_structp pp;
  2751. png_infop pi;
  2752. /* Get a png_struct for reading the image. This will throw an error if it
  2753. * fails, so we don't need to check the result.
  2754. */
  2755. pp = set_store_for_read(d.ps, &pi, d.id,
  2756. d.do_interlace ? (d.ps->progressive ?
  2757. "pngvalid progressive deinterlacer" :
  2758. "pngvalid sequential deinterlacer") : (d.ps->progressive ?
  2759. "progressive reader" : "sequential reader"));
  2760. /* Introduce the correct read function. */
  2761. if (d.ps->progressive)
  2762. {
  2763. png_set_progressive_read_fn(pp, &d, standard_info, progressive_row,
  2764. standard_end);
  2765. /* Now feed data into the reader until we reach the end: */
  2766. store_progressive_read(d.ps, pp, pi);
  2767. }
  2768. else
  2769. {
  2770. /* Note that this takes the store, not the display. */
  2771. png_set_read_fn(pp, d.ps, store_read);
  2772. /* Check the header values: */
  2773. png_read_info(pp, pi);
  2774. /* The code tests both versions of the images that the sequential
  2775. * reader can produce.
  2776. */
  2777. standard_info_imp(&d, pp, pi, 2 /*images*/);
  2778. /* Need the total bytes in the image below; we can't get to this point
  2779. * unless the PNG file values have been checked against the expected
  2780. * values.
  2781. */
  2782. {
  2783. PNG_CONST png_bytep pImage = d.ps->image;
  2784. PNG_CONST png_bytep pDisplay = pImage + d.cbRow * d.h;
  2785. sequential_row(&d, pp, pi, pImage, pDisplay);
  2786. /* After the last pass loop over the rows again to check that the
  2787. * image is correct.
  2788. */
  2789. standard_image_validate(&d, pp, pImage, pDisplay);
  2790. }
  2791. }
  2792. /* Check for validation. */
  2793. if (!d.ps->validated)
  2794. png_error(pp, "image read failed silently");
  2795. /* Successful completion. */
  2796. }
  2797. Catch(fault)
  2798. d.ps = fault; /* make sure this hasn't been clobbered. */
  2799. /* In either case clean up the store. */
  2800. store_read_reset(d.ps);
  2801. }
  2802. static int
  2803. test_standard(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
  2804. int bdlo, int PNG_CONST bdhi)
  2805. {
  2806. for (; bdlo <= bdhi; ++bdlo)
  2807. {
  2808. int interlace_type;
  2809. for (interlace_type = PNG_INTERLACE_NONE;
  2810. interlace_type < PNG_INTERLACE_LAST; ++interlace_type)
  2811. {
  2812. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2813. interlace_type, 0, 0, 0), 0/*do_interlace*/);
  2814. if (fail(pm))
  2815. return 0;
  2816. }
  2817. }
  2818. return 1; /* keep going */
  2819. }
  2820. static void
  2821. perform_standard_test(png_modifier *pm)
  2822. {
  2823. /* Test each colour type over the valid range of bit depths (expressed as
  2824. * log2(bit_depth) in turn, stop as soon as any error is detected.
  2825. */
  2826. if (!test_standard(pm, 0, 0, READ_BDHI))
  2827. return;
  2828. if (!test_standard(pm, 2, 3, READ_BDHI))
  2829. return;
  2830. if (!test_standard(pm, 3, 0, 3))
  2831. return;
  2832. if (!test_standard(pm, 4, 3, READ_BDHI))
  2833. return;
  2834. if (!test_standard(pm, 6, 3, READ_BDHI))
  2835. return;
  2836. }
  2837. /********************************** SIZE TESTS ********************************/
  2838. static int
  2839. test_size(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
  2840. int bdlo, int PNG_CONST bdhi)
  2841. {
  2842. /* Run the tests on each combination.
  2843. *
  2844. * NOTE: on my 32 bit x86 each of the following blocks takes
  2845. * a total of 3.5 seconds if done across every combo of bit depth
  2846. * width and height. This is a waste of time in practice, hence the
  2847. * hinc and winc stuff:
  2848. */
  2849. static PNG_CONST png_byte hinc[] = {1, 3, 11, 1, 5};
  2850. static PNG_CONST png_byte winc[] = {1, 9, 5, 7, 1};
  2851. for (; bdlo <= bdhi; ++bdlo)
  2852. {
  2853. png_uint_32 h, w;
  2854. for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
  2855. {
  2856. /* First test all the 'size' images against the sequential
  2857. * reader using libpng to deinterlace (where required.) This
  2858. * validates the write side of libpng. There are four possibilities
  2859. * to validate.
  2860. */
  2861. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2862. PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/);
  2863. if (fail(pm))
  2864. return 0;
  2865. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2866. PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/);
  2867. if (fail(pm))
  2868. return 0;
  2869. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2870. PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/);
  2871. if (fail(pm))
  2872. return 0;
  2873. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2874. PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/);
  2875. if (fail(pm))
  2876. return 0;
  2877. /* Now validate the interlaced read side - do_interlace true,
  2878. * in the progressive case this does actually make a difference
  2879. * to the code used in the non-interlaced case too.
  2880. */
  2881. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2882. PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/);
  2883. if (fail(pm))
  2884. return 0;
  2885. standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo),
  2886. PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/);
  2887. if (fail(pm))
  2888. return 0;
  2889. }
  2890. }
  2891. return 1; /* keep going */
  2892. }
  2893. static void
  2894. perform_size_test(png_modifier *pm)
  2895. {
  2896. /* Test each colour type over the valid range of bit depths (expressed as
  2897. * log2(bit_depth) in turn, stop as soon as any error is detected.
  2898. */
  2899. if (!test_size(pm, 0, 0, READ_BDHI))
  2900. return;
  2901. if (!test_size(pm, 2, 3, READ_BDHI))
  2902. return;
  2903. /* For the moment don't do the palette test - it's a waste of time when
  2904. * compared to the greyscale test.
  2905. */
  2906. #if 0
  2907. if (!test_size(pm, 3, 0, 3))
  2908. return;
  2909. #endif
  2910. if (!test_size(pm, 4, 3, READ_BDHI))
  2911. return;
  2912. if (!test_size(pm, 6, 3, READ_BDHI))
  2913. return;
  2914. }
  2915. /******************************* TRANSFORM TESTS ******************************/
  2916. /* A set of tests to validate libpng image transforms. The possibilities here
  2917. * are legion because the transforms can be combined in a combinatorial
  2918. * fashion. To deal with this some measure of restraint is required, otherwise
  2919. * the tests would take forever.
  2920. */
  2921. typedef struct image_pixel
  2922. {
  2923. /* A local (pngvalid) representation of a PNG pixel, in all its
  2924. * various forms.
  2925. */
  2926. unsigned int red, green, blue, alpha; /* For non-palette images. */
  2927. unsigned int palette_index; /* For a palette image. */
  2928. png_byte colour_type; /* As in the spec. */
  2929. png_byte bit_depth; /* Defines bit size in row */
  2930. png_byte sample_depth; /* Scale of samples */
  2931. int have_tRNS; /* tRNS chunk may need processing */
  2932. /* For checking the code calculates double precision floating point values
  2933. * along with an error value, accumulated from the transforms. Because an
  2934. * sBIT setting allows larger error bounds (indeed, by the spec, apparently
  2935. * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each
  2936. * channel is stored. This sBIT value is folded in to the stored error value
  2937. * at the end of the application of the transforms to the pixel.
  2938. */
  2939. double redf, greenf, bluef, alphaf;
  2940. double rede, greene, bluee, alphae;
  2941. png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT;
  2942. } image_pixel;
  2943. /* Shared utility function, see below. */
  2944. static void
  2945. image_pixel_setf(image_pixel *this, unsigned int max)
  2946. {
  2947. this->redf = this->red / (double)max;
  2948. this->greenf = this->green / (double)max;
  2949. this->bluef = this->blue / (double)max;
  2950. this->alphaf = this->alpha / (double)max;
  2951. if (this->red < max)
  2952. this->rede = this->redf * DBL_EPSILON;
  2953. else
  2954. this->rede = 0;
  2955. if (this->green < max)
  2956. this->greene = this->greenf * DBL_EPSILON;
  2957. else
  2958. this->greene = 0;
  2959. if (this->blue < max)
  2960. this->bluee = this->bluef * DBL_EPSILON;
  2961. else
  2962. this->bluee = 0;
  2963. if (this->alpha < max)
  2964. this->alphae = this->alphaf * DBL_EPSILON;
  2965. else
  2966. this->alphae = 0;
  2967. }
  2968. /* Initialize the structure for the next pixel - call this before doing any
  2969. * transforms and call it for each pixel since all the fields may need to be
  2970. * reset.
  2971. */
  2972. static void
  2973. image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
  2974. png_byte bit_depth, png_uint_32 x, standard_palette palette)
  2975. {
  2976. PNG_CONST png_byte sample_depth = (png_byte)(colour_type ==
  2977. PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
  2978. PNG_CONST unsigned int max = (1U<<sample_depth)-1;
  2979. /* Initially just set everything to the same number and the alpha to opaque.
  2980. * Note that this currently assumes a simple palette where entry x has colour
  2981. * rgb(x,x,x)!
  2982. */
  2983. this->palette_index = this->red = this->green = this->blue =
  2984. sample(row, colour_type, bit_depth, x, 0);
  2985. this->alpha = max;
  2986. this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =
  2987. sample_depth;
  2988. /* Then override as appropriate: */
  2989. if (colour_type == 3) /* palette */
  2990. {
  2991. /* This permits the caller to default to the sample value. */
  2992. if (palette != 0)
  2993. {
  2994. PNG_CONST unsigned int i = this->palette_index;
  2995. this->red = palette[i].red;
  2996. this->green = palette[i].green;
  2997. this->blue = palette[i].blue;
  2998. this->alpha = palette[i].alpha;
  2999. }
  3000. }
  3001. else /* not palette */
  3002. {
  3003. unsigned int i = 0;
  3004. if (colour_type & 2)
  3005. {
  3006. this->green = sample(row, colour_type, bit_depth, x, 1);
  3007. this->blue = sample(row, colour_type, bit_depth, x, 2);
  3008. i = 2;
  3009. }
  3010. if (colour_type & 4)
  3011. this->alpha = sample(row, colour_type, bit_depth, x, ++i);
  3012. }
  3013. /* Calculate the scaled values, these are simply the values divided by
  3014. * 'max' and the error is initialized to the double precision epsilon value
  3015. * from the header file.
  3016. */
  3017. image_pixel_setf(this, max);
  3018. /* Store the input information for use in the transforms - these will
  3019. * modify the information.
  3020. */
  3021. this->colour_type = colour_type;
  3022. this->bit_depth = bit_depth;
  3023. this->sample_depth = sample_depth;
  3024. this->have_tRNS = 0;
  3025. }
  3026. /* Convert a palette image to an rgb image. This necessarily converts the tRNS
  3027. * chunk at the same time, because the tRNS will be in palette form.
  3028. */
  3029. static void
  3030. image_pixel_convert_PLTE(image_pixel *this, const standard_display *display)
  3031. {
  3032. if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
  3033. {
  3034. PNG_CONST unsigned int i = this->palette_index;
  3035. this->bit_depth = this->sample_depth;
  3036. this->red = display->palette[i].red;
  3037. this->green = display->palette[i].green;
  3038. this->blue = display->palette[i].blue;
  3039. this->red_sBIT = display->red_sBIT;
  3040. this->green_sBIT = display->green_sBIT;
  3041. this->blue_sBIT = display->blue_sBIT;
  3042. if (this->have_tRNS)
  3043. {
  3044. this->alpha = display->palette[i].alpha;
  3045. this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
  3046. this->have_tRNS = 0;
  3047. }
  3048. else
  3049. {
  3050. this->alpha = 255;
  3051. this->colour_type = PNG_COLOR_TYPE_RGB;
  3052. }
  3053. this->alpha_sBIT = 8;
  3054. /* And regenerate the scaled values and all the errors, which are now set
  3055. * back to the initial values.
  3056. */
  3057. image_pixel_setf(this, 255);
  3058. }
  3059. }
  3060. /* Add an alpha channel, this will glom in the tRNS information because tRNS is
  3061. * not valid in an alpha image. The bit depth will invariably be set to at
  3062. * least 8. Palette images will be converted to alpha (using the above API).
  3063. */
  3064. static void
  3065. image_pixel_add_alpha(image_pixel *this, const standard_display *display)
  3066. {
  3067. if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
  3068. image_pixel_convert_PLTE(this, display);
  3069. if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
  3070. {
  3071. if (this->colour_type == PNG_COLOR_TYPE_GRAY)
  3072. {
  3073. if (this->bit_depth < 8)
  3074. this->bit_depth = 8;
  3075. if (this->have_tRNS)
  3076. {
  3077. this->have_tRNS = 0;
  3078. /* Check the input, original, channel value here against the
  3079. * original tRNS gray chunk valie.
  3080. */
  3081. if (this->red == display->transparent.red)
  3082. this->alphaf = 0;
  3083. else
  3084. this->alphaf = 1;
  3085. }
  3086. else
  3087. this->alphaf = 1;
  3088. this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  3089. }
  3090. else if (this->colour_type == PNG_COLOR_TYPE_RGB)
  3091. {
  3092. if (this->have_tRNS)
  3093. {
  3094. this->have_tRNS = 0;
  3095. /* Again, check the exact input values, not the current transformed
  3096. * value!
  3097. */
  3098. if (this->red == display->transparent.red &&
  3099. this->green == display->transparent.green &&
  3100. this->blue == display->transparent.blue)
  3101. this->alphaf = 0;
  3102. else
  3103. this->alphaf = 1;
  3104. this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
  3105. }
  3106. }
  3107. /* The error in the alpha is zero and the sBIT value comes from the
  3108. * original sBIT data (actually it will always be the original bit depth).
  3109. */
  3110. this->alphae = 0;
  3111. this->alpha_sBIT = display->alpha_sBIT;
  3112. }
  3113. }
  3114. struct transform_display;
  3115. typedef struct image_transform
  3116. {
  3117. /* The name of this transform: a string. */
  3118. PNG_CONST char *name;
  3119. /* Each transform can be disabled from the command line: */
  3120. int enable;
  3121. /* The global list of transforms; read only. */
  3122. struct image_transform *PNG_CONST list;
  3123. /* The global count of the number of times this transform has been set on an
  3124. * image.
  3125. */
  3126. unsigned int global_use;
  3127. /* The local count of the number of times this transform has been set. */
  3128. unsigned int local_use;
  3129. /* The next transform in the list, each transform must call its own next
  3130. * transform after it has processed the pixel successfully.
  3131. */
  3132. PNG_CONST struct image_transform *next;
  3133. /* A single transform for the image, expressed as a series of function
  3134. * callbacks and some space for values.
  3135. *
  3136. * First a callback to set the transform on the current png_read_struct:
  3137. */
  3138. void (*set)(PNG_CONST struct image_transform *this,
  3139. struct transform_display *that, png_structp pp, png_infop pi);
  3140. /* Then a transform that takes an input pixel in one PNG format or another
  3141. * and modifies it by a pngvalid implementation of the transform (thus
  3142. * duplicating the libpng intent without, we hope, duplicating the bugs
  3143. * in the libpng implementation!) The png_structp is solely to allow error
  3144. * reporting via png_error and png_warning.
  3145. */
  3146. void (*mod)(PNG_CONST struct image_transform *this, image_pixel *that,
  3147. png_structp pp, PNG_CONST struct transform_display *display);
  3148. /* Add this transform to the list and return true if the transform is
  3149. * meaningful for this colour type and bit depth - if false then the
  3150. * transform should have no effect on the image so there's not a lot of
  3151. * point running it.
  3152. */
  3153. int (*add)(struct image_transform *this,
  3154. PNG_CONST struct image_transform **that, png_byte colour_type,
  3155. png_byte bit_depth);
  3156. } image_transform;
  3157. typedef struct transform_display
  3158. {
  3159. standard_display this;
  3160. /* Parameters */
  3161. png_modifier* pm;
  3162. PNG_CONST image_transform* transform_list;
  3163. /* Local variables */
  3164. png_byte output_colour_type;
  3165. png_byte output_bit_depth;
  3166. } transform_display;
  3167. /* Two functions to end the list: */
  3168. static void
  3169. image_transform_set_end(PNG_CONST image_transform *this,
  3170. transform_display *that, png_structp pp, png_infop pi)
  3171. {
  3172. UNUSED(this)
  3173. UNUSED(that)
  3174. UNUSED(pp)
  3175. UNUSED(pi)
  3176. }
  3177. /* At the end of the list recalculate the output image pixel value from the
  3178. * double precision values set up by the preceding 'mod' calls:
  3179. */
  3180. static unsigned int
  3181. sample_scale(double sample_value, unsigned int scale)
  3182. {
  3183. sample_value = floor(sample_value * scale + .5);
  3184. /* Return NaN as 0: */
  3185. if (!(sample_value > 0))
  3186. sample_value = 0;
  3187. else if (sample_value > scale)
  3188. sample_value = scale;
  3189. return (unsigned int)sample_value;
  3190. }
  3191. static void
  3192. image_transform_mod_end(PNG_CONST image_transform *this, image_pixel *that,
  3193. png_structp pp, PNG_CONST transform_display *display)
  3194. {
  3195. PNG_CONST unsigned int scale = (1U<<that->sample_depth)-1;
  3196. UNUSED(this)
  3197. UNUSED(pp)
  3198. UNUSED(display)
  3199. /* At the end recalculate the digitized red green and blue values according
  3200. * to the current sample_depth of the pixel.
  3201. *
  3202. * The sample value is simply scaled to the maximum, checking for over
  3203. * and underflow (which can both happen for some image transforms,
  3204. * including simple size scaling, though libpng doesn't do that at present.
  3205. */
  3206. that->red = sample_scale(that->redf, scale);
  3207. /* The error value is increased, at the end, according to the lowest sBIT
  3208. * value seen. Common sense tells us that the intermediate integer
  3209. * representations are no more accurate than +/- 0.5 in the integral values,
  3210. * the sBIT allows the implementation to be worse than this. In addition the
  3211. * PNG specification actually permits any error within the range (-1..+1),
  3212. * but that is ignored here. Instead the final digitized value is compared,
  3213. * below to the digitized value of the error limits - this has the net effect
  3214. * of allowing (almost) +/-1 in the output value. It's difficult to see how
  3215. * any algorithm that digitizes intermediate results can be more accurate.
  3216. */
  3217. that->rede += 1./(2*((1U<<that->red_sBIT)-1));
  3218. if (that->colour_type & PNG_COLOR_MASK_COLOR)
  3219. {
  3220. that->green = sample_scale(that->greenf, scale);
  3221. that->blue = sample_scale(that->bluef, scale);
  3222. that->greene += 1./(2*((1U<<that->green_sBIT)-1));
  3223. that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
  3224. }
  3225. else
  3226. {
  3227. that->blue = that->green = that->red;
  3228. that->bluef = that->greenf = that->redf;
  3229. that->bluee = that->greene = that->rede;
  3230. }
  3231. if ((that->colour_type & PNG_COLOR_MASK_ALPHA) ||
  3232. that->colour_type == PNG_COLOR_TYPE_PALETTE)
  3233. {
  3234. that->alpha = sample_scale(that->alphaf, scale);
  3235. that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1));
  3236. }
  3237. else
  3238. {
  3239. that->alpha = scale; /* opaque */
  3240. that->alpha = 1; /* Override this. */
  3241. that->alphae = 0; /* It's exact ;-) */
  3242. }
  3243. }
  3244. /* Static 'end' structure: */
  3245. static image_transform image_transform_end =
  3246. {
  3247. "(end)", /* name */
  3248. 1, /* enable */
  3249. 0, /* list */
  3250. 0, /* global_use */
  3251. 0, /* local_use */
  3252. 0, /* next */
  3253. image_transform_set_end,
  3254. image_transform_mod_end,
  3255. 0 /* never called, I want it to crash if it is! */
  3256. };
  3257. /* Reader callbacks and implementations, where they differ from the standard
  3258. * ones.
  3259. */
  3260. static void
  3261. transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id,
  3262. PNG_CONST image_transform *transform_list)
  3263. {
  3264. /* Standard fields */
  3265. standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/);
  3266. /* Parameter fields */
  3267. dp->pm = pm;
  3268. dp->transform_list = transform_list;
  3269. /* Local variable fields */
  3270. dp->output_colour_type = 255; /* invalid */
  3271. dp->output_bit_depth = 255; /* invalid */
  3272. }
  3273. static void
  3274. transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
  3275. {
  3276. /* Reuse the standard stuff as appropriate. */
  3277. standard_info_part1(&dp->this, pp, pi);
  3278. /* Now set the list of transforms. */
  3279. dp->transform_list->set(dp->transform_list, dp, pp, pi);
  3280. /* Update the info structure for these transforms: */
  3281. png_read_update_info(pp, pi);
  3282. /* And get the output information into the standard_display */
  3283. standard_info_part2(&dp->this, pp, pi, 1/*images*/);
  3284. /* Plus the extra stuff we need for the transform tests: */
  3285. dp->output_colour_type = png_get_color_type(pp, pi);
  3286. dp->output_bit_depth = png_get_bit_depth(pp, pi);
  3287. /* Validate the combination of colour type and bit depth that we are getting
  3288. * out of libpng; the semantics of something not in the PNG spec are, at
  3289. * best, unclear.
  3290. */
  3291. switch (dp->output_colour_type)
  3292. {
  3293. case PNG_COLOR_TYPE_PALETTE:
  3294. if (dp->output_bit_depth > 8) goto error;
  3295. /*FALL THROUGH*/
  3296. case PNG_COLOR_TYPE_GRAY:
  3297. if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||
  3298. dp->output_bit_depth == 4)
  3299. break;
  3300. /*FALL THROUGH*/
  3301. default:
  3302. if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)
  3303. break;
  3304. /*FALL THROUGH*/
  3305. error:
  3306. {
  3307. char message[128];
  3308. size_t pos;
  3309. pos = safecat(message, sizeof message, 0,
  3310. "invalid final bit depth: colour type(");
  3311. pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
  3312. pos = safecat(message, sizeof message, pos, ") with bit depth: ");
  3313. pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
  3314. png_error(pp, message);
  3315. }
  3316. }
  3317. /* Use a test pixel to check that the output agrees with what we expect -
  3318. * this avoids running the whole test if the output is unexpected.
  3319. */
  3320. {
  3321. image_pixel test_pixel;
  3322. memset(&test_pixel, 0, sizeof test_pixel);
  3323. test_pixel.colour_type = dp->this.colour_type; /* input */
  3324. test_pixel.bit_depth = dp->this.bit_depth;
  3325. if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
  3326. test_pixel.sample_depth = 8;
  3327. else
  3328. test_pixel.sample_depth = test_pixel.bit_depth;
  3329. /* Don't need sBIT here */
  3330. test_pixel.have_tRNS = dp->this.is_transparent;
  3331. dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp);
  3332. if (test_pixel.colour_type != dp->output_colour_type)
  3333. {
  3334. char message[128];
  3335. size_t pos = safecat(message, sizeof message, 0, "colour type ");
  3336. pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
  3337. pos = safecat(message, sizeof message, pos, " expected ");
  3338. pos = safecatn(message, sizeof message, pos, test_pixel.colour_type);
  3339. png_error(pp, message);
  3340. }
  3341. if (test_pixel.bit_depth != dp->output_bit_depth)
  3342. {
  3343. char message[128];
  3344. size_t pos = safecat(message, sizeof message, 0, "bit depth ");
  3345. pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
  3346. pos = safecat(message, sizeof message, pos, " expected ");
  3347. pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
  3348. png_error(pp, message);
  3349. }
  3350. /* If both bit depth and colour type are correct check the sample depth.
  3351. * I believe these are both internal errors.
  3352. */
  3353. if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
  3354. {
  3355. if (test_pixel.sample_depth != 8) /* oops - internal error! */
  3356. png_error(pp, "pngvalid: internal: palette sample depth not 8");
  3357. }
  3358. else if (test_pixel.sample_depth != dp->output_bit_depth)
  3359. {
  3360. char message[128];
  3361. size_t pos = safecat(message, sizeof message, 0,
  3362. "internal: sample depth ");
  3363. pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
  3364. pos = safecat(message, sizeof message, pos, " expected ");
  3365. pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
  3366. png_error(pp, message);
  3367. }
  3368. }
  3369. }
  3370. static void
  3371. transform_info(png_structp pp, png_infop pi)
  3372. {
  3373. transform_info_imp(png_get_progressive_ptr(pp), pp, pi);
  3374. }
  3375. static void
  3376. transform_range_check(png_structp pp, unsigned int r, unsigned int g,
  3377. unsigned int b, unsigned int a, unsigned int in_digitized, double in,
  3378. unsigned int out, png_byte sample_depth, double err, PNG_CONST char *name)
  3379. {
  3380. /* Compare the scaled, digitzed, values of our local calculation (in+-err)
  3381. * with the digitized values libpng produced; 'sample_depth' is the actual
  3382. * digitization depth of the libpng output colors (the bit depth except for
  3383. * palette images where it is always 8.)
  3384. */
  3385. unsigned int max = (1U<<sample_depth)-1;
  3386. double in_min = ceil((in-err)*max - .5);
  3387. double in_max = floor((in+err)*max + .5);
  3388. if (!(out >= in_min && out <= in_max))
  3389. {
  3390. char message[256];
  3391. size_t pos;
  3392. pos = safecat(message, sizeof message, 0, name);
  3393. pos = safecat(message, sizeof message, pos, " output value error: rgba(");
  3394. pos = safecatn(message, sizeof message, pos, r);
  3395. pos = safecat(message, sizeof message, pos, ",");
  3396. pos = safecatn(message, sizeof message, pos, g);
  3397. pos = safecat(message, sizeof message, pos, ",");
  3398. pos = safecatn(message, sizeof message, pos, b);
  3399. pos = safecat(message, sizeof message, pos, ",");
  3400. pos = safecatn(message, sizeof message, pos, a);
  3401. pos = safecat(message, sizeof message, pos, "): ");
  3402. pos = safecatn(message, sizeof message, pos, out);
  3403. pos = safecat(message, sizeof message, pos, " expected: ");
  3404. pos = safecatn(message, sizeof message, pos, in_digitized);
  3405. pos = safecat(message, sizeof message, pos, " (");
  3406. pos = safecatd(message, sizeof message, pos, (in-err)*max, 3);
  3407. pos = safecat(message, sizeof message, pos, "..");
  3408. pos = safecatd(message, sizeof message, pos, (in+err)*max, 3);
  3409. pos = safecat(message, sizeof message, pos, ")");
  3410. png_error(pp, message);
  3411. }
  3412. }
  3413. static void
  3414. transform_image_validate(transform_display *dp, png_structp pp, png_infop pi,
  3415. png_const_bytep pRow)
  3416. {
  3417. /* Constants for the loop below: */
  3418. PNG_CONST png_byte in_ct = dp->this.colour_type;
  3419. PNG_CONST png_byte in_bd = dp->this.bit_depth;
  3420. PNG_CONST png_uint_32 w = dp->this.w;
  3421. PNG_CONST png_uint_32 h = dp->this.h;
  3422. PNG_CONST size_t cbRow = dp->this.cbRow;
  3423. PNG_CONST png_byte out_ct = dp->output_colour_type;
  3424. PNG_CONST png_byte out_bd = dp->output_bit_depth;
  3425. PNG_CONST png_byte sample_depth = (png_byte)(out_ct ==
  3426. PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
  3427. PNG_CONST png_byte red_sBIT = dp->this.red_sBIT;
  3428. PNG_CONST png_byte green_sBIT = dp->this.green_sBIT;
  3429. PNG_CONST png_byte blue_sBIT = dp->this.blue_sBIT;
  3430. PNG_CONST png_byte alpha_sBIT = dp->this.alpha_sBIT;
  3431. PNG_CONST int have_tRNS = dp->this.is_transparent;
  3432. standard_palette out_palette;
  3433. png_uint_32 y;
  3434. UNUSED(pi)
  3435. /* Read the palette corresponding to the output if the output colour type
  3436. * indicates a palette, othewise set out_palette to garbage.
  3437. */
  3438. if (out_ct == PNG_COLOR_TYPE_PALETTE)
  3439. (void)standard_palette_init(out_palette, pp, pi);
  3440. else
  3441. memset(out_palette, 0x5e, sizeof out_palette);
  3442. for (y=0; y<h; ++y, pRow += cbRow)
  3443. {
  3444. png_uint_32 x;
  3445. /* The original, standard, row pre-transforms. */
  3446. png_byte std[STANDARD_ROWMAX];
  3447. transform_row(pp, std, in_ct, in_bd, y);
  3448. /* Go through each original pixel transforming it and comparing with what
  3449. * libpng did to the same pixel.
  3450. */
  3451. for (x=0; x<w; ++x)
  3452. {
  3453. image_pixel in_pixel, out_pixel;
  3454. unsigned int r, g, b, a;
  3455. /* Find out what we think the pixel should be: */
  3456. image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette);
  3457. in_pixel.red_sBIT = red_sBIT;
  3458. in_pixel.green_sBIT = green_sBIT;
  3459. in_pixel.blue_sBIT = blue_sBIT;
  3460. in_pixel.alpha_sBIT = alpha_sBIT;
  3461. in_pixel.have_tRNS = have_tRNS;
  3462. /* For error detection, below. */
  3463. r = in_pixel.red;
  3464. g = in_pixel.green;
  3465. b = in_pixel.blue;
  3466. a = in_pixel.alpha;
  3467. dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);
  3468. /* Read the output pixel and compare it to what we got, we don't
  3469. * use the error field here, so no need to update sBIT.
  3470. */
  3471. image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette);
  3472. /* We don't expect changes to the index here even if the bit depth is
  3473. * changed.
  3474. */
  3475. if (in_ct == PNG_COLOR_TYPE_PALETTE &&
  3476. out_ct == PNG_COLOR_TYPE_PALETTE)
  3477. {
  3478. if (in_pixel.palette_index != out_pixel.palette_index)
  3479. png_error(pp, "unexpected transformed palette index");
  3480. }
  3481. /* Check the colours for palette images too - in fact the palette could
  3482. * be separately verified itself in most cases.
  3483. */
  3484. if (in_pixel.red != out_pixel.red)
  3485. transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf,
  3486. out_pixel.red, sample_depth, in_pixel.rede, "red/gray");
  3487. if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
  3488. in_pixel.green != out_pixel.green)
  3489. transform_range_check(pp, r, g, b, a, in_pixel.green,
  3490. in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene,
  3491. "green");
  3492. if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
  3493. in_pixel.blue != out_pixel.blue)
  3494. transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef,
  3495. out_pixel.blue, sample_depth, in_pixel.bluee, "blue");
  3496. if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 &&
  3497. in_pixel.alpha != out_pixel.alpha)
  3498. transform_range_check(pp, r, g, b, a, in_pixel.alpha,
  3499. in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae,
  3500. "alpha");
  3501. } /* pixel (x) loop */
  3502. } /* row (y) loop */
  3503. /* Record that something was actually checked to avoid a false positive. */
  3504. dp->this.ps->validated = 1;
  3505. }
  3506. static void
  3507. transform_end(png_structp pp, png_infop pi)
  3508. {
  3509. transform_display *dp = png_get_progressive_ptr(pp);
  3510. transform_image_validate(dp, pp, pi, dp->this.ps->image);
  3511. }
  3512. /* A single test run. */
  3513. static void
  3514. transform_test(png_modifier *pmIn, PNG_CONST png_uint_32 idIn,
  3515. PNG_CONST image_transform* transform_listIn, PNG_CONST char *name)
  3516. {
  3517. transform_display d;
  3518. context(&pmIn->this, fault);
  3519. transform_display_init(&d, pmIn, idIn, transform_listIn);
  3520. Try
  3521. {
  3522. png_structp pp;
  3523. png_infop pi;
  3524. /* Get a png_struct for writing the image. */
  3525. pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
  3526. # if 0
  3527. /* Logging (debugging only) */
  3528. {
  3529. char buffer[256];
  3530. (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0,
  3531. "running test");
  3532. fprintf(stderr, "%s\n", buffer);
  3533. }
  3534. # endif
  3535. /* Introduce the correct read function. */
  3536. if (d.pm->this.progressive)
  3537. {
  3538. /* Share the row function with the standard implementation. */
  3539. png_set_progressive_read_fn(pp, &d, transform_info, progressive_row,
  3540. transform_end);
  3541. /* Now feed data into the reader until we reach the end: */
  3542. modifier_progressive_read(d.pm, pp, pi);
  3543. }
  3544. else
  3545. {
  3546. /* modifier_read expects a png_modifier* */
  3547. png_set_read_fn(pp, d.pm, modifier_read);
  3548. /* Check the header values: */
  3549. png_read_info(pp, pi);
  3550. /* Process the 'info' requirements. Only one image is generated */
  3551. transform_info_imp(&d, pp, pi);
  3552. sequential_row(&d.this, pp, pi, NULL, d.this.ps->image);
  3553. transform_image_validate(&d, pp, pi, d.this.ps->image);
  3554. }
  3555. modifier_reset(d.pm);
  3556. }
  3557. Catch(fault)
  3558. modifier_reset((png_modifier*)fault);
  3559. }
  3560. /* The transforms: */
  3561. #define ITSTRUCT(name) image_transform_##name
  3562. #define IT(name,prev)\
  3563. static image_transform ITSTRUCT(name) =\
  3564. {\
  3565. #name,\
  3566. 1, /*enable*/\
  3567. &ITSTRUCT(prev), /*list*/\
  3568. 0, /*global_use*/\
  3569. 0, /*local_use*/\
  3570. 0, /*next*/\
  3571. image_transform_png_set_##name##_set,\
  3572. image_transform_png_set_##name##_mod,\
  3573. image_transform_png_set_##name##_add\
  3574. }
  3575. /* To save code: */
  3576. static int
  3577. image_transform_default_add(image_transform *this,
  3578. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3579. {
  3580. UNUSED(colour_type)
  3581. UNUSED(bit_depth)
  3582. this->next = *that;
  3583. *that = this;
  3584. return 1;
  3585. }
  3586. /* png_set_palette_to_rgb */
  3587. static void
  3588. image_transform_png_set_palette_to_rgb_set(PNG_CONST image_transform *this,
  3589. transform_display *that, png_structp pp, png_infop pi)
  3590. {
  3591. png_set_palette_to_rgb(pp);
  3592. this->next->set(this->next, that, pp, pi);
  3593. }
  3594. static void
  3595. image_transform_png_set_palette_to_rgb_mod(PNG_CONST image_transform *this,
  3596. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3597. {
  3598. if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
  3599. image_pixel_convert_PLTE(that, &display->this);
  3600. this->next->mod(this->next, that, pp, display);
  3601. }
  3602. static int
  3603. image_transform_png_set_palette_to_rgb_add(image_transform *this,
  3604. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3605. {
  3606. UNUSED(bit_depth)
  3607. this->next = *that;
  3608. *that = this;
  3609. return colour_type == PNG_COLOR_TYPE_PALETTE;
  3610. }
  3611. IT(palette_to_rgb, end);
  3612. /* png_set_tRNS_to_alpha */
  3613. static void
  3614. image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this,
  3615. transform_display *that, png_structp pp, png_infop pi)
  3616. {
  3617. png_set_tRNS_to_alpha(pp);
  3618. this->next->set(this->next, that, pp, pi);
  3619. }
  3620. static void
  3621. image_transform_png_set_tRNS_to_alpha_mod(PNG_CONST image_transform *this,
  3622. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3623. {
  3624. /* LIBPNG BUG: this always forces palette images to RGB. */
  3625. if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
  3626. image_pixel_convert_PLTE(that, &display->this);
  3627. /* This effectively does an 'expand' only if there is some transparency to
  3628. * covert to an alpha channel.
  3629. */
  3630. if (that->have_tRNS)
  3631. image_pixel_add_alpha(that, &display->this);
  3632. /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */
  3633. else
  3634. {
  3635. if (that->bit_depth < 8)
  3636. that->bit_depth =8;
  3637. if (that->sample_depth < 8)
  3638. that->sample_depth = 8;
  3639. }
  3640. this->next->mod(this->next, that, pp, display);
  3641. }
  3642. static int
  3643. image_transform_png_set_tRNS_to_alpha_add(image_transform *this,
  3644. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3645. {
  3646. UNUSED(bit_depth)
  3647. this->next = *that;
  3648. *that = this;
  3649. /* We don't know yet whether there will be a tRNS chunk, but we know that
  3650. * this transformation should do nothing if there already is an alpha
  3651. * channel.
  3652. */
  3653. return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
  3654. }
  3655. IT(tRNS_to_alpha,palette_to_rgb);
  3656. /* png_set_gray_to_rgb */
  3657. static void
  3658. image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this,
  3659. transform_display *that, png_structp pp, png_infop pi)
  3660. {
  3661. png_set_gray_to_rgb(pp);
  3662. this->next->set(this->next, that, pp, pi);
  3663. }
  3664. static void
  3665. image_transform_png_set_gray_to_rgb_mod(PNG_CONST image_transform *this,
  3666. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3667. {
  3668. /* NOTE: we can actually pend the tRNS processing at this point because we
  3669. * can correctly recognize the original pixel value even though we have
  3670. * mapped the one gray channel to the three RGB ones, but in fact libpng
  3671. * doesn't do this, so we don't either.
  3672. */
  3673. if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS)
  3674. image_pixel_add_alpha(that, &display->this);
  3675. /* Simply expand the bit depth and alter the colour type as required. */
  3676. if (that->colour_type == PNG_COLOR_TYPE_GRAY)
  3677. {
  3678. /* RGB images have a bit depth at least equal to '8' */
  3679. if (that->bit_depth < 8)
  3680. that->sample_depth = that->bit_depth = 8;
  3681. /* And just changing the colour type works here because the green and blue
  3682. * channels are being maintained in lock-step with the red/gray:
  3683. */
  3684. that->colour_type = PNG_COLOR_TYPE_RGB;
  3685. }
  3686. else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  3687. that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
  3688. this->next->mod(this->next, that, pp, display);
  3689. }
  3690. static int
  3691. image_transform_png_set_gray_to_rgb_add(image_transform *this,
  3692. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3693. {
  3694. UNUSED(bit_depth)
  3695. this->next = *that;
  3696. *that = this;
  3697. return (colour_type & PNG_COLOR_MASK_COLOR) == 0;
  3698. }
  3699. IT(gray_to_rgb,tRNS_to_alpha);
  3700. /* png_set_expand */
  3701. static void
  3702. image_transform_png_set_expand_set(PNG_CONST image_transform *this,
  3703. transform_display *that, png_structp pp, png_infop pi)
  3704. {
  3705. png_set_expand(pp);
  3706. this->next->set(this->next, that, pp, pi);
  3707. }
  3708. static void
  3709. image_transform_png_set_expand_mod(PNG_CONST image_transform *this,
  3710. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3711. {
  3712. /* The general expand case depends on what the colour type is: */
  3713. if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
  3714. image_pixel_convert_PLTE(that, &display->this);
  3715. else if (that->bit_depth < 8) /* grayscale */
  3716. that->sample_depth = that->bit_depth = 8;
  3717. if (that->have_tRNS)
  3718. image_pixel_add_alpha(that, &display->this);
  3719. this->next->mod(this->next, that, pp, display);
  3720. }
  3721. static int
  3722. image_transform_png_set_expand_add(image_transform *this,
  3723. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3724. {
  3725. UNUSED(bit_depth)
  3726. this->next = *that;
  3727. *that = this;
  3728. /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit
  3729. * depth is at least 8 already.
  3730. */
  3731. return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
  3732. }
  3733. IT(expand,gray_to_rgb);
  3734. /* png_set_expand_gray_1_2_4_to_8
  3735. * LIBPNG BUG: this just does an 'expand'
  3736. */
  3737. static void
  3738. image_transform_png_set_expand_gray_1_2_4_to_8_set(
  3739. PNG_CONST image_transform *this, transform_display *that, png_structp pp,
  3740. png_infop pi)
  3741. {
  3742. png_set_expand_gray_1_2_4_to_8(pp);
  3743. this->next->set(this->next, that, pp, pi);
  3744. }
  3745. static void
  3746. image_transform_png_set_expand_gray_1_2_4_to_8_mod(
  3747. PNG_CONST image_transform *this, image_pixel *that, png_structp pp,
  3748. PNG_CONST transform_display *display)
  3749. {
  3750. image_transform_png_set_expand_mod(this, that, pp, display);
  3751. }
  3752. static int
  3753. image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,
  3754. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3755. {
  3756. return image_transform_png_set_expand_add(this, that, colour_type,
  3757. bit_depth);
  3758. }
  3759. IT(expand_gray_1_2_4_to_8, expand);
  3760. /* png_set_expand_16 */
  3761. static void
  3762. image_transform_png_set_expand_16_set(PNG_CONST image_transform *this,
  3763. transform_display *that, png_structp pp, png_infop pi)
  3764. {
  3765. png_set_expand_16(pp);
  3766. this->next->set(this->next, that, pp, pi);
  3767. }
  3768. static void
  3769. image_transform_png_set_expand_16_mod(PNG_CONST image_transform *this,
  3770. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3771. {
  3772. /* Expect expand_16 to expand everything to 16 bits as a result of also
  3773. * causing 'expand' to happen.
  3774. */
  3775. if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
  3776. image_pixel_convert_PLTE(that, &display->this);
  3777. if (that->have_tRNS)
  3778. image_pixel_add_alpha(that, &display->this);
  3779. if (that->bit_depth < 16)
  3780. that->sample_depth = that->bit_depth = 16;
  3781. this->next->mod(this->next, that, pp, display);
  3782. }
  3783. static int
  3784. image_transform_png_set_expand_16_add(image_transform *this,
  3785. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3786. {
  3787. UNUSED(colour_type)
  3788. this->next = *that;
  3789. *that = this;
  3790. /* expand_16 does something unless the bit depth is already 16. */
  3791. return bit_depth < 16;
  3792. }
  3793. IT(expand_16, expand_gray_1_2_4_to_8);
  3794. /* png_set_strip_16 */
  3795. static void
  3796. image_transform_png_set_strip_16_set(PNG_CONST image_transform *this,
  3797. transform_display *that, png_structp pp, png_infop pi)
  3798. {
  3799. png_set_strip_16(pp);
  3800. this->next->set(this->next, that, pp, pi);
  3801. }
  3802. static void
  3803. image_transform_png_set_strip_16_mod(PNG_CONST image_transform *this,
  3804. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3805. {
  3806. if (that->bit_depth == 16)
  3807. {
  3808. that->sample_depth = that->bit_depth = 8;
  3809. if (that->red_sBIT > 8) that->red_sBIT = 8;
  3810. if (that->green_sBIT > 8) that->green_sBIT = 8;
  3811. if (that->blue_sBIT > 8) that->blue_sBIT = 8;
  3812. if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
  3813. # ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
  3814. /* The strip 16 algoirithm drops the low 8 bits rather than calculating
  3815. * 1/257, so we need to adjust the permitted errors appropriately:
  3816. */
  3817. {
  3818. PNG_CONST double d = (255-128.5)/65535;
  3819. that->rede += d;
  3820. that->greene += d;
  3821. that->bluee += d;
  3822. that->alphae += d;
  3823. }
  3824. # endif
  3825. }
  3826. this->next->mod(this->next, that, pp, display);
  3827. }
  3828. static int
  3829. image_transform_png_set_strip_16_add(image_transform *this,
  3830. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3831. {
  3832. UNUSED(colour_type)
  3833. this->next = *that;
  3834. *that = this;
  3835. return bit_depth > 8;
  3836. }
  3837. IT(strip_16, expand_16);
  3838. /* png_set_strip_alpha */
  3839. static void
  3840. image_transform_png_set_strip_alpha_set(PNG_CONST image_transform *this,
  3841. transform_display *that, png_structp pp, png_infop pi)
  3842. {
  3843. png_set_strip_alpha(pp);
  3844. this->next->set(this->next, that, pp, pi);
  3845. }
  3846. static void
  3847. image_transform_png_set_strip_alpha_mod(PNG_CONST image_transform *this,
  3848. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3849. {
  3850. if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  3851. that->colour_type = PNG_COLOR_TYPE_GRAY;
  3852. else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3853. that->colour_type = PNG_COLOR_TYPE_RGB;
  3854. that->have_tRNS = 0;
  3855. that->alphaf = 1;
  3856. that->alphae = 0;
  3857. this->next->mod(this->next, that, pp, display);
  3858. }
  3859. static int
  3860. image_transform_png_set_strip_alpha_add(image_transform *this,
  3861. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3862. {
  3863. UNUSED(bit_depth)
  3864. this->next = *that;
  3865. *that = this;
  3866. return (colour_type & PNG_COLOR_MASK_ALPHA) != 0;
  3867. }
  3868. IT(strip_alpha,strip_16);
  3869. /* png_set_rgb_to_gray(png_structp, int err_action, double red, double green)
  3870. * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red,
  3871. * png_fixed_point green)
  3872. * png_get_rgb_to_gray_status
  3873. *
  3874. * At present the APIs are simply tested using the 16.16 fixed point conversion
  3875. * values known to be used inside libpng:
  3876. *
  3877. * red: 6968
  3878. * green: 23434
  3879. * blue: 2366
  3880. *
  3881. * NOTE: this currently ignores the gamma because no gamma is being set, the
  3882. * tests on gamma need to happen in the gamma test set.
  3883. */
  3884. static void
  3885. image_transform_png_set_rgb_to_gray_set(PNG_CONST image_transform *this,
  3886. transform_display *that, png_structp pp, png_infop pi)
  3887. {
  3888. PNG_CONST int error_action = 1; /* no error, no defines in png.h */
  3889. # ifdef PNG_FLOATING_POINT_SUPPORTED
  3890. png_set_rgb_to_gray(pp, error_action, -1, -1);
  3891. # else
  3892. png_set_rgb_to_gray_fixed(pp, error_action, -1, -1);
  3893. # endif
  3894. this->next->set(this->next, that, pp, pi);
  3895. }
  3896. static void
  3897. image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
  3898. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3899. {
  3900. if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0)
  3901. {
  3902. if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
  3903. image_pixel_convert_PLTE(that, &display->this);
  3904. /* Image now has RGB channels... */
  3905. that->bluef = that->greenf = that->redf = (that->redf * 6968 +
  3906. that->greenf * 23434 + that->bluef * 2366) / 32768;
  3907. that->bluee = that->greene = that->rede = (that->rede * 6968 +
  3908. that->greene * 23434 + that->bluee * 2366) / 32768 *
  3909. (1 + DBL_EPSILON * 6);
  3910. /* The sBIT is the minium of the three colour channel sBITs. */
  3911. if (that->red_sBIT > that->green_sBIT)
  3912. that->red_sBIT = that->green_sBIT;
  3913. if (that->red_sBIT > that->blue_sBIT)
  3914. that->red_sBIT = that->blue_sBIT;
  3915. that->blue_sBIT = that->green_sBIT = that->red_sBIT;
  3916. /* And zap the colour bit in the type: */
  3917. if (that->colour_type == PNG_COLOR_TYPE_RGB)
  3918. that->colour_type = PNG_COLOR_TYPE_GRAY;
  3919. else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3920. that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  3921. }
  3922. this->next->mod(this->next, that, pp, display);
  3923. }
  3924. static int
  3925. image_transform_png_set_rgb_to_gray_add(image_transform *this,
  3926. PNG_CONST image_transform **that, png_byte colour_type, png_byte bit_depth)
  3927. {
  3928. UNUSED(bit_depth)
  3929. this->next = *that;
  3930. *that = this;
  3931. return (colour_type & PNG_COLOR_MASK_COLOR) != 0;
  3932. }
  3933. IT(rgb_to_gray,strip_alpha);
  3934. /* png_set_background(png_structp, png_const_color_16p background_color,
  3935. * int background_gamma_code, int need_expand, double background_gamma)
  3936. * png_set_background_fixed(png_structp, png_const_color_16p background_color,
  3937. * int background_gamma_code, int need_expand,
  3938. * png_fixed_point background_gamma)
  3939. *
  3940. * As with rgb_to_gray this ignores the gamma.
  3941. */
  3942. static void
  3943. image_transform_png_set_background_set(PNG_CONST image_transform *this,
  3944. transform_display *that, png_structp pp, png_infop pi)
  3945. {
  3946. png_color_16 back;
  3947. /* Since we don't know the output bit depth at this point we must use the
  3948. * input values and ask libpng to expand the chunk as required.
  3949. */
  3950. back.index = 255; /* Should not be used */
  3951. back.gray = back.blue = back.green = back.red =
  3952. (png_uint_16)((1U << that->this.bit_depth) >> 1);
  3953. # ifdef PNG_FLOATING_POINT_SUPPORTED
  3954. png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1, 0);
  3955. # else
  3956. png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, 1, 0);
  3957. # endif
  3958. this->next->set(this->next, that, pp, pi);
  3959. }
  3960. static void
  3961. image_transform_png_set_background_mod(PNG_CONST image_transform *this,
  3962. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  3963. {
  3964. /* Check for tRNS first: */
  3965. if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE)
  3966. image_pixel_add_alpha(that, &display->this);
  3967. /* This is only necessary if the alpha value is less than 1. */
  3968. if (that->alphaf < 1)
  3969. {
  3970. /* Repeat the calculation above and scale the result: */
  3971. unsigned int tmp = (1U << display->this.bit_depth);
  3972. double component = (tmp >> 1)/(double)(tmp-1);
  3973. /* Now we do the background calculation without any gamma correction. */
  3974. if (that->alphaf <= 0)
  3975. {
  3976. that->bluef = that->greenf = that->redf = component;
  3977. that->bluee = that->greene = that->rede = component * DBL_EPSILON;
  3978. that->blue_sBIT = that->green_sBIT = that->red_sBIT = that->bit_depth;
  3979. }
  3980. else
  3981. {
  3982. component *= 1-that->alphaf;
  3983. that->redf = that->redf * that->alphaf + component;
  3984. that->rede = that->rede * that->alphaf + that->redf * 3 * DBL_EPSILON;
  3985. that->greenf = that->greenf * that->alphaf + component;
  3986. that->greene = that->greene * that->alphaf + that->greenf * 3 *
  3987. DBL_EPSILON;
  3988. that->bluef = that->bluef * that->alphaf + component;
  3989. that->bluee = that->bluee * that->alphaf + that->bluef * 3 *
  3990. DBL_EPSILON;
  3991. }
  3992. /* Remove the alpha type and set the alpha. */
  3993. that->alphaf = 1;
  3994. that->alphae = 0;
  3995. if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3996. that->colour_type = PNG_COLOR_TYPE_RGB;
  3997. else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  3998. that->colour_type = PNG_COLOR_TYPE_GRAY;
  3999. }
  4000. this->next->mod(this->next, that, pp, display);
  4001. }
  4002. #define image_transform_png_set_background_add image_transform_default_add
  4003. IT(background,rgb_to_gray);
  4004. static image_transform *PNG_CONST image_transform_first = &ITSTRUCT(background);
  4005. static void
  4006. transform_enable(PNG_CONST char *name)
  4007. {
  4008. /* Everything starts out enabled, so if we see an 'enable' disabled
  4009. * everything else the first time round.
  4010. */
  4011. static int all_disabled = 0;
  4012. int found_it = 0;
  4013. image_transform *list = image_transform_first;
  4014. while (list != &image_transform_end)
  4015. {
  4016. if (strcmp(list->name, name) == 0)
  4017. {
  4018. list->enable = 1;
  4019. found_it = 1;
  4020. }
  4021. else if (!all_disabled)
  4022. list->enable = 0;
  4023. list = list->list;
  4024. }
  4025. all_disabled = 1;
  4026. if (!found_it)
  4027. {
  4028. fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n",
  4029. name);
  4030. exit(1);
  4031. }
  4032. }
  4033. static void
  4034. transform_disable(PNG_CONST char *name)
  4035. {
  4036. image_transform *list = image_transform_first;
  4037. while (list != &image_transform_end)
  4038. {
  4039. if (strcmp(list->name, name) == 0)
  4040. {
  4041. list->enable = 0;
  4042. return;
  4043. }
  4044. list = list->list;
  4045. }
  4046. fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n",
  4047. name);
  4048. exit(1);
  4049. }
  4050. static void
  4051. image_transform_reset_count(void)
  4052. {
  4053. image_transform *next = image_transform_first;
  4054. int count = 0;
  4055. while (next != &image_transform_end)
  4056. {
  4057. next->local_use = 0;
  4058. next->next = 0;
  4059. next = next->list;
  4060. ++count;
  4061. }
  4062. /* This can only happen if we every have more than 32 transforms (excluding
  4063. * the end) in the list.
  4064. */
  4065. if (count > 32) abort();
  4066. }
  4067. static int
  4068. image_transform_test_counter(png_uint_32 counter, unsigned int max)
  4069. {
  4070. /* Test the list to see if there is any point contining, given a current
  4071. * counter and a 'max' value.
  4072. */
  4073. image_transform *next = image_transform_first;
  4074. while (next != &image_transform_end)
  4075. {
  4076. /* For max 0 or 1 continue until the counter overflows: */
  4077. counter >>= 1;
  4078. /* Continue if any entry hasn't reacked the max. */
  4079. if (max > 1 && next->local_use < max)
  4080. return 1;
  4081. next = next->list;
  4082. }
  4083. return max <= 1 && counter == 0;
  4084. }
  4085. static png_uint_32
  4086. image_transform_add(PNG_CONST image_transform **this, unsigned int max,
  4087. png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos,
  4088. png_byte colour_type, png_byte bit_depth)
  4089. {
  4090. for (;;) /* until we manage to add something */
  4091. {
  4092. png_uint_32 mask;
  4093. image_transform *list;
  4094. /* Find the next counter value, if the counter is zero this is the start
  4095. * of the list. This routine always returns the current counter (not the
  4096. * next) so it returns 0 at the end and expects 0 at the beginning.
  4097. */
  4098. if (counter == 0) /* first time */
  4099. {
  4100. image_transform_reset_count();
  4101. if (max <= 1)
  4102. counter = 1;
  4103. else
  4104. counter = random_32();
  4105. }
  4106. else /* advance the counter */
  4107. {
  4108. switch (max)
  4109. {
  4110. case 0: ++counter; break;
  4111. case 1: counter <<= 1; break;
  4112. default: counter = random_32(); break;
  4113. }
  4114. }
  4115. /* Now add all these items, if possible */
  4116. *this = &image_transform_end;
  4117. list = image_transform_first;
  4118. mask = 1;
  4119. /* Go through the whole list adding anything that the counter selects: */
  4120. while (list != &image_transform_end)
  4121. {
  4122. if ((counter & mask) != 0 && list->enable &&
  4123. (max == 0 || list->local_use < max))
  4124. {
  4125. /* Candidate to add: */
  4126. if (list->add(list, this, colour_type, bit_depth) || max == 0)
  4127. {
  4128. /* Added, so add to the name too. */
  4129. *pos = safecat(name, sizeof_name, *pos, " +");
  4130. *pos = safecat(name, sizeof_name, *pos, list->name);
  4131. }
  4132. else
  4133. {
  4134. /* Not useful and max>0, so remvoe it from *this: */
  4135. *this = list->next;
  4136. list->next = 0;
  4137. /* And, since we know it isn't useful, stop it being added again
  4138. * in this run:
  4139. */
  4140. list->local_use = max;
  4141. }
  4142. }
  4143. mask <<= 1;
  4144. list = list->list;
  4145. }
  4146. /* Now if anything was added we have something to do. */
  4147. if (*this != &image_transform_end)
  4148. return counter;
  4149. /* Nothing added, but was there anything in there to add? */
  4150. if (!image_transform_test_counter(counter, max))
  4151. return 0;
  4152. }
  4153. }
  4154. #ifdef THIS_IS_THE_PROFORMA
  4155. static void
  4156. image_transform_png_set_@_set(PNG_CONST image_transform *this,
  4157. transform_display *that, png_structp pp, png_infop pi)
  4158. {
  4159. png_set_@(pp);
  4160. this->next->set(this->next, that, pp, pi);
  4161. }
  4162. static void
  4163. image_transform_png_set_@_mod(PNG_CONST image_transform *this,
  4164. image_pixel *that, png_structp pp, PNG_CONST transform_display *display)
  4165. {
  4166. this->next->mod(this->next, that, pp, display);
  4167. }
  4168. static int
  4169. image_transform_png_set_@_add(image_transform *this,
  4170. PNG_CONST image_transform **that, char *name, size_t sizeof_name,
  4171. size_t *pos, png_byte colour_type, png_byte bit_depth)
  4172. {
  4173. this->next = *that;
  4174. *that = this;
  4175. *pos = safecat(name, sizeof_name, *pos, " +@");
  4176. return 1;
  4177. }
  4178. IT(@);
  4179. #endif
  4180. /* png_set_quantize(png_structp, png_colorp palette, int num_palette,
  4181. * int maximum_colors, png_const_uint_16p histogram, int full_quantize)
  4182. *
  4183. * Very difficult to validate this!
  4184. */
  4185. /*NOTE: TBD NYI */
  4186. /* The data layout transforms are handled by swapping our own channel data,
  4187. * necessarily these need to happen at the end of the transform list because the
  4188. * semantic of the channels changes after these are executed. Some of these,
  4189. * like set_shift and set_packing, can't be done at present because they change
  4190. * the layout of the data at the sub-sample level so sample() won't get the
  4191. * right answer.
  4192. */
  4193. /* png_set_invert_alpha */
  4194. /*NOTE: TBD NYI */
  4195. /* png_set_bgr */
  4196. /*NOTE: TBD NYI */
  4197. /* png_set_swap_alpha */
  4198. /*NOTE: TBD NYI */
  4199. /* png_set_swap */
  4200. /*NOTE: TBD NYI */
  4201. /* png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); */
  4202. /*NOTE: TBD NYI */
  4203. /* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
  4204. /*NOTE: TBD NYI */
  4205. /* png_set_packing */
  4206. /*NOTE: TBD NYI */
  4207. /* png_set_packswap */
  4208. /*NOTE: TBD NYI */
  4209. /* png_set_invert_mono */
  4210. /*NOTE: TBD NYI */
  4211. /* png_set_shift(png_structp, png_const_color_8p true_bits) */
  4212. /*NOTE: TBD NYI */
  4213. static int
  4214. test_transform(png_modifier* PNG_CONST pm, png_byte PNG_CONST colour_type,
  4215. int bdlo, int PNG_CONST bdhi, png_uint_32 max)
  4216. {
  4217. for (; bdlo <= bdhi; ++bdlo)
  4218. {
  4219. PNG_CONST png_byte bit_depth = DEPTH(bdlo);
  4220. png_uint_32 counter = 0;
  4221. size_t base_pos;
  4222. char name[64];
  4223. base_pos = safecat(name, sizeof name, 0, "transform:");
  4224. for (;;)
  4225. {
  4226. size_t pos = base_pos;
  4227. PNG_CONST image_transform *list = 0;
  4228. counter = image_transform_add(&list, max, counter, name, sizeof name,
  4229. &pos, colour_type, bit_depth);
  4230. if (counter == 0)
  4231. break;
  4232. /* The command line can change this to checking interlaced images. */
  4233. transform_test(pm, FILEID(colour_type, bit_depth, pm->interlace_type,
  4234. 0, 0, 0), list, name);
  4235. if (fail(pm))
  4236. return 0;
  4237. }
  4238. }
  4239. return 1; /* keep going */
  4240. }
  4241. static void
  4242. perform_transform_test(png_modifier *pm)
  4243. {
  4244. /* Test each colour type over the valid range of bit depths (expressed as
  4245. * log2(bit_depth) in turn, stop as soon as any error is detected.
  4246. */
  4247. if (!test_transform(pm, 0, 0, READ_BDHI, 1))
  4248. return;
  4249. if (!test_transform(pm, 2, 3, READ_BDHI, 1))
  4250. return;
  4251. if (!test_transform(pm, 3, 0, 3, 1))
  4252. return;
  4253. if (!test_transform(pm, 4, 3, READ_BDHI, 1))
  4254. return;
  4255. if (!test_transform(pm, 6, 3, READ_BDHI, 1))
  4256. return;
  4257. }
  4258. /********************************* GAMMA TESTS ********************************/
  4259. /* Gamma test images. */
  4260. typedef struct gamma_modification
  4261. {
  4262. png_modification this;
  4263. png_fixed_point gamma;
  4264. } gamma_modification;
  4265. static int
  4266. gamma_modify(png_modifier *pm, png_modification *me, int add)
  4267. {
  4268. UNUSED(add)
  4269. /* This simply dumps the given gamma value into the buffer. */
  4270. png_save_uint_32(pm->buffer, 4);
  4271. png_save_uint_32(pm->buffer+4, CHUNK_gAMA);
  4272. png_save_uint_32(pm->buffer+8, ((gamma_modification*)me)->gamma);
  4273. return 1;
  4274. }
  4275. static void
  4276. gamma_modification_init(gamma_modification *me, png_modifier *pm, double gammad)
  4277. {
  4278. double g;
  4279. modification_init(&me->this);
  4280. me->this.chunk = CHUNK_gAMA;
  4281. me->this.modify_fn = gamma_modify;
  4282. me->this.add = CHUNK_PLTE;
  4283. g = floor(gammad * 100000 + .5);
  4284. me->gamma = (png_fixed_point)g;
  4285. me->this.next = pm->modifications;
  4286. pm->modifications = &me->this;
  4287. }
  4288. typedef struct srgb_modification
  4289. {
  4290. png_modification this;
  4291. png_byte intent;
  4292. } srgb_modification;
  4293. static int
  4294. srgb_modify(png_modifier *pm, png_modification *me, int add)
  4295. {
  4296. UNUSED(add)
  4297. /* As above, ignore add and just make a new chunk */
  4298. png_save_uint_32(pm->buffer, 1);
  4299. png_save_uint_32(pm->buffer+4, CHUNK_sRGB);
  4300. pm->buffer[8] = ((srgb_modification*)me)->intent;
  4301. return 1;
  4302. }
  4303. static void
  4304. srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent)
  4305. {
  4306. modification_init(&me->this);
  4307. me->this.chunk = CHUNK_sBIT;
  4308. if (intent <= 3) /* if valid, else *delete* sRGB chunks */
  4309. {
  4310. me->this.modify_fn = srgb_modify;
  4311. me->this.add = CHUNK_PLTE;
  4312. me->intent = intent;
  4313. }
  4314. else
  4315. {
  4316. me->this.modify_fn = 0;
  4317. me->this.add = 0;
  4318. me->intent = 0;
  4319. }
  4320. me->this.next = pm->modifications;
  4321. pm->modifications = &me->this;
  4322. }
  4323. typedef struct sbit_modification
  4324. {
  4325. png_modification this;
  4326. png_byte sbit;
  4327. } sbit_modification;
  4328. static int
  4329. sbit_modify(png_modifier *pm, png_modification *me, int add)
  4330. {
  4331. png_byte sbit = ((sbit_modification*)me)->sbit;
  4332. if (pm->bit_depth > sbit)
  4333. {
  4334. int cb = 0;
  4335. switch (pm->colour_type)
  4336. {
  4337. case 0:
  4338. cb = 1;
  4339. break;
  4340. case 2:
  4341. case 3:
  4342. cb = 3;
  4343. break;
  4344. case 4:
  4345. cb = 2;
  4346. break;
  4347. case 6:
  4348. cb = 4;
  4349. break;
  4350. default:
  4351. png_error(pm->this.pread,
  4352. "unexpected colour type in sBIT modification");
  4353. }
  4354. png_save_uint_32(pm->buffer, cb);
  4355. png_save_uint_32(pm->buffer+4, CHUNK_sBIT);
  4356. while (cb > 0)
  4357. (pm->buffer+8)[--cb] = sbit;
  4358. return 1;
  4359. }
  4360. else if (!add)
  4361. {
  4362. /* Remove the sBIT chunk */
  4363. pm->buffer_count = pm->buffer_position = 0;
  4364. return 1;
  4365. }
  4366. else
  4367. return 0; /* do nothing */
  4368. }
  4369. static void
  4370. sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit)
  4371. {
  4372. modification_init(&me->this);
  4373. me->this.chunk = CHUNK_sBIT;
  4374. me->this.modify_fn = sbit_modify;
  4375. me->this.add = CHUNK_PLTE;
  4376. me->sbit = sbit;
  4377. me->this.next = pm->modifications;
  4378. pm->modifications = &me->this;
  4379. }
  4380. /* Reader callbacks and implementations, where they differ from the standard
  4381. * ones.
  4382. */
  4383. typedef struct gamma_display
  4384. {
  4385. standard_display this;
  4386. /* Parameters */
  4387. png_modifier* pm;
  4388. double file_gamma;
  4389. double screen_gamma;
  4390. png_byte sbit;
  4391. int threshold_test;
  4392. PNG_CONST char* name;
  4393. int speed;
  4394. int use_input_precision;
  4395. int strip16;
  4396. /* Local variables */
  4397. double maxerrout;
  4398. double maxerrpc;
  4399. double maxerrabs;
  4400. } gamma_display;
  4401. static void
  4402. gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id,
  4403. double file_gamma, double screen_gamma, png_byte sbit, int threshold_test,
  4404. int speed, int use_input_precision, int strip16)
  4405. {
  4406. /* Standard fields */
  4407. standard_display_init(&dp->this, &pm->this, id, 0/*do_interlace*/);
  4408. /* Parameter fields */
  4409. dp->pm = pm;
  4410. dp->file_gamma = file_gamma;
  4411. dp->screen_gamma = screen_gamma;
  4412. dp->sbit = sbit;
  4413. dp->threshold_test = threshold_test;
  4414. dp->speed = speed;
  4415. dp->use_input_precision = use_input_precision;
  4416. dp->strip16 = strip16;
  4417. /* Local variable fields */
  4418. dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0;
  4419. }
  4420. static void
  4421. gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
  4422. {
  4423. /* Reuse the standard stuff as appropriate. */
  4424. standard_info_part1(&dp->this, pp, pi);
  4425. /* If requested strip 16 to 8 bits - this is handled automagically below
  4426. * because the output bit depth is read from the library. Note that there
  4427. * are interactions with sBIT but, internally, libpng makes sbit at most
  4428. * PNG_MAX_GAMMA_8 when doing the following.
  4429. */
  4430. if (dp->strip16)
  4431. # ifdef PNG_READ_16_TO_8_SUPPORTED
  4432. png_set_strip_16(pp);
  4433. # else
  4434. png_error(pp, "strip16 (16 to 8 bit conversion) not supported");
  4435. # endif
  4436. png_read_update_info(pp, pi);
  4437. /* Now we may get a different cbRow: */
  4438. standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
  4439. }
  4440. static void
  4441. gamma_info(png_structp pp, png_infop pi)
  4442. {
  4443. gamma_info_imp(png_get_progressive_ptr(pp), pp, pi);
  4444. }
  4445. static void
  4446. gamma_image_validate(gamma_display *dp, png_structp pp, png_infop pi,
  4447. png_const_bytep pRow)
  4448. {
  4449. /* Get some constants derived from the input and output file formats: */
  4450. PNG_CONST png_byte sbit = dp->sbit;
  4451. PNG_CONST double file_gamma = dp->file_gamma;
  4452. PNG_CONST double screen_gamma = dp->screen_gamma;
  4453. PNG_CONST int use_input_precision = dp->use_input_precision;
  4454. PNG_CONST int speed = dp->speed;
  4455. PNG_CONST png_byte in_ct = dp->this.colour_type;
  4456. PNG_CONST png_byte in_bd = dp->this.bit_depth;
  4457. PNG_CONST png_uint_32 w = dp->this.w;
  4458. PNG_CONST png_uint_32 h = dp->this.h;
  4459. PNG_CONST size_t cbRow = dp->this.cbRow;
  4460. PNG_CONST png_byte out_ct = png_get_color_type(pp, pi);
  4461. PNG_CONST png_byte out_bd = png_get_bit_depth(pp, pi);
  4462. PNG_CONST unsigned int outmax = (1U<<out_bd)-1;
  4463. PNG_CONST double maxabs = abserr(dp->pm, out_bd);
  4464. PNG_CONST double maxout = outerr(dp->pm, out_bd);
  4465. PNG_CONST double maxpc = pcerr(dp->pm, out_bd);
  4466. /* There are three sources of error, firstly the quantization in the
  4467. * file encoding, determined by sbit and/or the file depth, secondly
  4468. * the output (screen) gamma and thirdly the output file encoding.
  4469. *
  4470. * Since this API receives the screen and file gamma in double
  4471. * precision it is possible to calculate an exact answer given an input
  4472. * pixel value. Therefore we assume that the *input* value is exact -
  4473. * sample/maxsample - calculate the corresponding gamma corrected
  4474. * output to the limits of double precision arithmetic and compare with
  4475. * what libpng returns.
  4476. *
  4477. * Since the library must quantize the output to 8 or 16 bits there is
  4478. * a fundamental limit on the accuracy of the output of +/-.5 - this
  4479. * quantization limit is included in addition to the other limits
  4480. * specified by the paramaters to the API. (Effectively, add .5
  4481. * everywhere.)
  4482. *
  4483. * The behavior of the 'sbit' paramter is defined by section 12.5
  4484. * (sample depth scaling) of the PNG spec. That section forces the
  4485. * decoder to assume that the PNG values have been scaled if sBIT is
  4486. * present:
  4487. *
  4488. * png-sample = floor( input-sample * (max-out/max-in) + .5);
  4489. *
  4490. * This means that only a subset of the possible PNG values should
  4491. * appear in the input. However, the spec allows the encoder to use a
  4492. * variety of approximations to the above and doesn't require any
  4493. * restriction of the values produced.
  4494. *
  4495. * Nevertheless the spec requires that the upper 'sBIT' bits of the
  4496. * value stored in a PNG file be the original sample bits.
  4497. * Consequently the code below simply scales the top sbit bits by
  4498. * (1<<sbit)-1 to obtain an original sample value.
  4499. *
  4500. * Because there is limited precision in the input it is arguable that
  4501. * an acceptable result is any valid result from input-.5 to input+.5.
  4502. * The basic tests below do not do this, however if
  4503. * 'use_input_precision' is set a subsequent test is performed below.
  4504. */
  4505. PNG_CONST int processing = (fabs(screen_gamma*file_gamma-1) >=
  4506. PNG_GAMMA_THRESHOLD && !dp->threshold_test && !speed && in_ct != 3) ||
  4507. in_bd != out_bd;
  4508. PNG_CONST unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
  4509. PNG_CONST double gamma_correction = 1/(file_gamma*screen_gamma);/* Overall */
  4510. double maxerrout = 0, maxerrabs = 0, maxerrpc = 0;
  4511. png_uint_32 y;
  4512. for (y=0; y<h; ++y, pRow += cbRow)
  4513. {
  4514. unsigned int s, x;
  4515. png_byte std[STANDARD_ROWMAX];
  4516. transform_row(pp, std, in_ct, in_bd, y);
  4517. if (processing)
  4518. {
  4519. for (x=0; x<w; ++x) for (s=0; s<samples_per_pixel; ++s)
  4520. {
  4521. /* Input sample values: */
  4522. PNG_CONST unsigned int
  4523. id = sample(std, in_ct, in_bd, x, s);
  4524. PNG_CONST unsigned int
  4525. od = sample(pRow, out_ct, out_bd, x, s);
  4526. PNG_CONST unsigned int
  4527. isbit = id >> (in_bd-sbit);
  4528. double i, input_sample, encoded_sample, output;
  4529. double encoded_error, error;
  4530. double es_lo, es_hi;
  4531. /* First check on the 'perfect' result obtained from the
  4532. * digitized input value, id, and compare this against the
  4533. * actual digitized result, 'od'. 'i' is the input result
  4534. * in the range 0..1:
  4535. *
  4536. * NOTE: sBIT should be taken into account here but isn't,
  4537. * as described above.
  4538. */
  4539. i = isbit; i /= (1U<<sbit)-1;
  4540. /* Then get the gamma corrected version of 'i' and compare
  4541. * to 'od', any error less than .5 is insignificant - just
  4542. * quantization of the output value to the nearest digital
  4543. * value (nevertheless the error is still recorded - it's
  4544. * interesting ;-)
  4545. */
  4546. encoded_sample = pow(i, gamma_correction) * outmax;
  4547. encoded_error = fabs(od-encoded_sample);
  4548. if (encoded_error > maxerrout)
  4549. maxerrout = encoded_error;
  4550. if (encoded_error < .5+maxout)
  4551. continue;
  4552. /* There may be an error, so calculate the actual sample
  4553. * values - unencoded light intensity values. Note that
  4554. * in practice these are not unencoded because they
  4555. * include a 'viewing correction' to decrease or
  4556. * (normally) increase the perceptual contrast of the
  4557. * image. There's nothing we can do about this - we don't
  4558. * know what it is - so assume the unencoded value is
  4559. * perceptually linear.
  4560. */
  4561. input_sample = pow(i, 1/file_gamma); /* In range 0..1 */
  4562. output = od;
  4563. output /= outmax;
  4564. output = pow(output, screen_gamma);
  4565. /* Now we have the numbers for real errors, both absolute
  4566. * values as as a percentage of the correct value (output):
  4567. */
  4568. error = fabs(input_sample-output);
  4569. if (error > maxerrabs)
  4570. maxerrabs = error;
  4571. /* The following is an attempt to ignore the tendency of
  4572. * quantization to dominate the percentage errors for low
  4573. * output sample values:
  4574. */
  4575. if (input_sample*maxpc > .5+maxabs)
  4576. {
  4577. double percentage_error = error/input_sample;
  4578. if (percentage_error > maxerrpc) maxerrpc = percentage_error;
  4579. }
  4580. /* Now calculate the digitization limits for
  4581. * 'encoded_sample' using the 'max' values. Note that
  4582. * maxout is in the encoded space but maxpc and maxabs are
  4583. * in linear light space.
  4584. *
  4585. * First find the maximum error in linear light space,
  4586. * range 0..1:
  4587. */
  4588. {
  4589. double tmp = input_sample * maxpc;
  4590. if (tmp < maxabs) tmp = maxabs;
  4591. /* Low bound - the minimum of the three: */
  4592. es_lo = encoded_sample - maxout;
  4593. if (es_lo > 0 && input_sample-tmp > 0)
  4594. {
  4595. double low_value = outmax * pow(input_sample-tmp,
  4596. 1/screen_gamma);
  4597. if (low_value < es_lo) es_lo = low_value;
  4598. }
  4599. else
  4600. es_lo = 0;
  4601. es_hi = encoded_sample + maxout;
  4602. if (es_hi < outmax && input_sample+tmp < 1)
  4603. {
  4604. double high_value = outmax * pow(input_sample+tmp,
  4605. 1/screen_gamma);
  4606. if (high_value > es_hi) es_hi = high_value;
  4607. }
  4608. else
  4609. es_hi = outmax;
  4610. }
  4611. /* The primary test is that the final encoded value
  4612. * returned by the library should be between the two limits
  4613. * (inclusive) that were calculated above. At this point
  4614. * quantization of the output must be taken into account.
  4615. */
  4616. if (od+.5 < es_lo || od-.5 > es_hi)
  4617. {
  4618. /* There has been an error in processing. */
  4619. double is_lo, is_hi;
  4620. if (use_input_precision)
  4621. {
  4622. /* Ok, something is wrong - this actually happens in
  4623. * current libpng sbit processing. Assume that the
  4624. * input value (id, adjusted for sbit) can be
  4625. * anywhere between value-.5 and value+.5 - quite a
  4626. * large range if sbit is low.
  4627. */
  4628. double tmp = (isbit - .5)/((1U<<sbit)-1);
  4629. if (tmp > 0)
  4630. {
  4631. is_lo = outmax * pow(tmp, gamma_correction) - maxout;
  4632. if (is_lo < 0) is_lo = 0;
  4633. }
  4634. else
  4635. is_lo = 0;
  4636. tmp = (isbit + .5)/((1U<<sbit)-1);
  4637. if (tmp < 1)
  4638. {
  4639. is_hi = outmax * pow(tmp, gamma_correction) + maxout;
  4640. if (is_hi > outmax) is_hi = outmax;
  4641. }
  4642. else
  4643. is_hi = outmax;
  4644. if (!(od+.5 < is_lo || od-.5 > is_hi))
  4645. continue;
  4646. }
  4647. else
  4648. is_lo = es_lo, is_hi = es_hi;
  4649. {
  4650. char msg[256];
  4651. sprintf(msg,
  4652. "error: %.3f; %u{%u;%u} -> %u not %.2f (%.1f-%.1f)",
  4653. od-encoded_sample, id, sbit, isbit, od,
  4654. encoded_sample, is_lo, is_hi);
  4655. png_warning(pp, msg);
  4656. }
  4657. }
  4658. }
  4659. }
  4660. else if (!speed && memcmp(std, pRow, cbRow) != 0)
  4661. {
  4662. char msg[64];
  4663. /* No transform is expected on the threshold tests. */
  4664. sprintf(msg, "gamma: below threshold row %d changed", y);
  4665. png_error(pp, msg);
  4666. }
  4667. } /* row (y) loop */
  4668. dp->maxerrout = maxerrout;
  4669. dp->maxerrabs = maxerrabs;
  4670. dp->maxerrpc = maxerrpc;
  4671. dp->this.ps->validated = 1;
  4672. }
  4673. static void
  4674. gamma_end(png_structp pp, png_infop pi)
  4675. {
  4676. gamma_display *dp = png_get_progressive_ptr(pp);
  4677. gamma_image_validate(dp, pp, pi, dp->this.ps->image);
  4678. }
  4679. /* A single test run checking a gamma transformation.
  4680. *
  4681. * maxabs: maximum absolute error as a fraction
  4682. * maxout: maximum output error in the output units
  4683. * maxpc: maximum percentage error (as a percentage)
  4684. */
  4685. static void
  4686. gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn,
  4687. PNG_CONST png_byte bit_depthIn, PNG_CONST int interlace_typeIn,
  4688. PNG_CONST double file_gammaIn, PNG_CONST double screen_gammaIn,
  4689. PNG_CONST png_byte sbitIn, PNG_CONST int threshold_testIn,
  4690. PNG_CONST char *name, PNG_CONST int speedIn,
  4691. PNG_CONST int use_input_precisionIn, PNG_CONST int strip16In)
  4692. {
  4693. gamma_display d;
  4694. context(&pmIn->this, fault);
  4695. gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn,
  4696. interlace_typeIn, 0, 0, 0), file_gammaIn, screen_gammaIn, sbitIn,
  4697. threshold_testIn, speedIn, use_input_precisionIn, strip16In);
  4698. Try
  4699. {
  4700. png_structp pp;
  4701. png_infop pi;
  4702. gamma_modification gamma_mod;
  4703. srgb_modification srgb_mod;
  4704. sbit_modification sbit_mod;
  4705. /* Make an appropriate modifier to set the PNG file gamma to the
  4706. * given gamma value and the sBIT chunk to the given precision.
  4707. */
  4708. d.pm->modifications = NULL;
  4709. gamma_modification_init(&gamma_mod, d.pm, d.file_gamma);
  4710. srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/);
  4711. sbit_modification_init(&sbit_mod, d.pm, d.sbit);
  4712. modification_reset(d.pm->modifications);
  4713. /* Get a png_struct for writing the image. */
  4714. pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
  4715. /* Set up gamma processing. */
  4716. #ifdef PNG_FLOATING_POINT_SUPPORTED
  4717. png_set_gamma(pp, d.screen_gamma, d.file_gamma);
  4718. #else
  4719. {
  4720. png_fixed_point s = floor(d.screen_gamma*100000+.5);
  4721. png_fixed_point f = floor(d.file_gamma*100000+.5);
  4722. png_set_gamma_fixed(pp, s, f);
  4723. }
  4724. #endif
  4725. /* Introduce the correct read function. */
  4726. if (d.pm->this.progressive)
  4727. {
  4728. /* Share the row function with the standard implementation. */
  4729. png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row,
  4730. gamma_end);
  4731. /* Now feed data into the reader until we reach the end: */
  4732. modifier_progressive_read(d.pm, pp, pi);
  4733. }
  4734. else
  4735. {
  4736. /* modifier_read expects a png_modifier* */
  4737. png_set_read_fn(pp, d.pm, modifier_read);
  4738. /* Check the header values: */
  4739. png_read_info(pp, pi);
  4740. /* Process the 'info' requirements. Only one image is generated */
  4741. gamma_info_imp(&d, pp, pi);
  4742. sequential_row(&d.this, pp, pi, NULL, d.this.ps->image);
  4743. gamma_image_validate(&d, pp, pi, d.this.ps->image);
  4744. }
  4745. modifier_reset(d.pm);
  4746. if (d.pm->log && !d.threshold_test && !d.speed)
  4747. fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n",
  4748. d.this.bit_depth, colour_types[d.this.colour_type], d.name,
  4749. d.maxerrout, d.maxerrabs, 100*d.maxerrpc);
  4750. /* Log the summary values too. */
  4751. if (d.this.colour_type == 0 || d.this.colour_type == 4)
  4752. {
  4753. switch (d.this.bit_depth)
  4754. {
  4755. case 1:
  4756. break;
  4757. case 2:
  4758. if (d.maxerrout > d.pm->error_gray_2)
  4759. d.pm->error_gray_2 = d.maxerrout;
  4760. break;
  4761. case 4:
  4762. if (d.maxerrout > d.pm->error_gray_4)
  4763. d.pm->error_gray_4 = d.maxerrout;
  4764. break;
  4765. case 8:
  4766. if (d.maxerrout > d.pm->error_gray_8)
  4767. d.pm->error_gray_8 = d.maxerrout;
  4768. break;
  4769. case 16:
  4770. if (d.maxerrout > d.pm->error_gray_16)
  4771. d.pm->error_gray_16 = d.maxerrout;
  4772. break;
  4773. default:
  4774. png_error(pp, "bad bit depth (internal: 1)");
  4775. }
  4776. }
  4777. else if (d.this.colour_type == 2 || d.this.colour_type == 6)
  4778. {
  4779. switch (d.this.bit_depth)
  4780. {
  4781. case 8:
  4782. if (d.maxerrout > d.pm->error_color_8)
  4783. d.pm->error_color_8 = d.maxerrout;
  4784. break;
  4785. case 16:
  4786. if (d.maxerrout > d.pm->error_color_16)
  4787. d.pm->error_color_16 = d.maxerrout;
  4788. break;
  4789. default:
  4790. png_error(pp, "bad bit depth (internal: 2)");
  4791. }
  4792. }
  4793. }
  4794. Catch(fault)
  4795. modifier_reset((png_modifier*)fault);
  4796. }
  4797. static void gamma_threshold_test(png_modifier *pm, png_byte colour_type,
  4798. png_byte bit_depth, int interlace_type, double file_gamma,
  4799. double screen_gamma)
  4800. {
  4801. size_t pos = 0;
  4802. char name[64];
  4803. pos = safecat(name, sizeof name, pos, "threshold ");
  4804. pos = safecatd(name, sizeof name, pos, file_gamma, 3);
  4805. pos = safecat(name, sizeof name, pos, "/");
  4806. pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
  4807. (void)gamma_test(pm, colour_type, bit_depth, interlace_type, file_gamma,
  4808. screen_gamma, bit_depth, 1, name, 0 /*speed*/, 0 /*no input precision*/,
  4809. 0 /*no strip16*/);
  4810. }
  4811. static void
  4812. perform_gamma_threshold_tests(png_modifier *pm)
  4813. {
  4814. png_byte colour_type = 0;
  4815. png_byte bit_depth = 0;
  4816. while (next_format(&colour_type, &bit_depth))
  4817. {
  4818. double test_gamma = 1.0;
  4819. while (test_gamma >= .4)
  4820. {
  4821. /* There's little point testing the interlacing vs non-interlacing,
  4822. * but this can be set from the command line.
  4823. */
  4824. gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
  4825. test_gamma, 1/test_gamma);
  4826. test_gamma *= .95;
  4827. }
  4828. /* And a special test for sRGB */
  4829. gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
  4830. .45455, 2.2);
  4831. if (fail(pm))
  4832. return;
  4833. }
  4834. }
  4835. static void gamma_transform_test(png_modifier *pm,
  4836. PNG_CONST png_byte colour_type, PNG_CONST png_byte bit_depth,
  4837. PNG_CONST int interlace_type, PNG_CONST double file_gamma,
  4838. PNG_CONST double screen_gamma, PNG_CONST png_byte sbit, PNG_CONST int speed,
  4839. PNG_CONST int use_input_precision, PNG_CONST int strip16)
  4840. {
  4841. size_t pos = 0;
  4842. char name[64];
  4843. if (sbit != bit_depth)
  4844. {
  4845. pos = safecat(name, sizeof name, pos, "sbit(");
  4846. pos = safecatn(name, sizeof name, pos, sbit);
  4847. pos = safecat(name, sizeof name, pos, ") ");
  4848. }
  4849. else
  4850. pos = safecat(name, sizeof name, pos, "gamma ");
  4851. if (strip16)
  4852. pos = safecat(name, sizeof name, pos, "16to8 ");
  4853. pos = safecatd(name, sizeof name, pos, file_gamma, 3);
  4854. pos = safecat(name, sizeof name, pos, "->");
  4855. pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
  4856. gamma_test(pm, colour_type, bit_depth, interlace_type, file_gamma,
  4857. screen_gamma, sbit, 0, name, speed, use_input_precision, strip16);
  4858. }
  4859. static void perform_gamma_transform_tests(png_modifier *pm, int speed)
  4860. {
  4861. png_byte colour_type = 0;
  4862. png_byte bit_depth = 0;
  4863. /* Ignore palette images - the gamma correction happens on the palette entry,
  4864. * haven't got the tests for this yet.
  4865. */
  4866. while (next_format(&colour_type, &bit_depth)) if (colour_type != 3)
  4867. {
  4868. unsigned int i, j;
  4869. for (i=0; i<pm->ngammas; ++i) for (j=0; j<pm->ngammas; ++j) if (i != j)
  4870. {
  4871. gamma_transform_test(pm, colour_type, bit_depth, pm->interlace_type,
  4872. 1/pm->gammas[i], pm->gammas[j], bit_depth, speed,
  4873. pm->use_input_precision, 0 /*do not strip16*/);
  4874. if (fail(pm))
  4875. return;
  4876. }
  4877. }
  4878. }
  4879. static void perform_gamma_sbit_tests(png_modifier *pm, int speed)
  4880. {
  4881. png_byte sbit;
  4882. /* The only interesting cases are colour and grayscale, alpha is ignored here
  4883. * for overall speed. Only bit depths 8 and 16 are tested.
  4884. */
  4885. for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit)
  4886. {
  4887. unsigned int i, j;
  4888. for (i=0; i<pm->ngammas; ++i)
  4889. {
  4890. for (j=0; j<pm->ngammas; ++j)
  4891. {
  4892. if (i != j)
  4893. {
  4894. if (sbit < 8)
  4895. {
  4896. gamma_transform_test(pm, 0, 8, pm->interlace_type,
  4897. 1/pm->gammas[i], pm->gammas[j], sbit, speed,
  4898. pm->use_input_precision_sbit, 0 /*strip16*/);
  4899. if (fail(pm))
  4900. return;
  4901. gamma_transform_test(pm, 2, 8, pm->interlace_type,
  4902. 1/pm->gammas[i], pm->gammas[j], sbit, speed,
  4903. pm->use_input_precision_sbit, 0 /*strip16*/);
  4904. if (fail(pm))
  4905. return;
  4906. }
  4907. #ifdef DO_16BIT
  4908. gamma_transform_test(pm, 0, 16, pm->interlace_type,
  4909. 1/pm->gammas[i], pm->gammas[j], sbit, speed,
  4910. pm->use_input_precision_sbit, 0 /*strip16*/);
  4911. if (fail(pm))
  4912. return;
  4913. gamma_transform_test(pm, 2, 16, pm->interlace_type,
  4914. 1/pm->gammas[i], pm->gammas[j], sbit, speed,
  4915. pm->use_input_precision_sbit, 0 /*strip16*/);
  4916. if (fail(pm))
  4917. return;
  4918. #endif
  4919. }
  4920. }
  4921. }
  4922. }
  4923. }
  4924. /* Note that this requires a 16 bit source image but produces 8 bit output, so
  4925. * we only need the 16bit write support.
  4926. */
  4927. #ifdef PNG_READ_16_TO_8_SUPPORTED
  4928. static void perform_gamma_strip16_tests(png_modifier *pm, int speed)
  4929. {
  4930. # ifndef PNG_MAX_GAMMA_8
  4931. # define PNG_MAX_GAMMA_8 11
  4932. # endif
  4933. /* Include the alpha cases here. Note that sbit matches the internal value
  4934. * used by the library - otherwise we will get spurious errors from the
  4935. * internal sbit style approximation.
  4936. *
  4937. * The threshold test is here because otherwise the 16 to 8 conversion will
  4938. * proceed *without* gamma correction, and the tests above will fail (but not
  4939. * by much) - this could be fixed, it only appears with the -g option.
  4940. */
  4941. unsigned int i, j;
  4942. for (i=0; i<pm->ngammas; ++i)
  4943. {
  4944. for (j=0; j<pm->ngammas; ++j)
  4945. {
  4946. if (i != j &&
  4947. fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)
  4948. {
  4949. gamma_transform_test(pm, 0, 16, pm->interlace_type, 1/pm->gammas[i],
  4950. pm->gammas[j], PNG_MAX_GAMMA_8, speed,
  4951. pm->use_input_precision_16to8, 1 /*strip16*/);
  4952. if (fail(pm))
  4953. return;
  4954. gamma_transform_test(pm, 2, 16, pm->interlace_type, 1/pm->gammas[i],
  4955. pm->gammas[j], PNG_MAX_GAMMA_8, speed,
  4956. pm->use_input_precision_16to8, 1 /*strip16*/);
  4957. if (fail(pm))
  4958. return;
  4959. gamma_transform_test(pm, 4, 16, pm->interlace_type, 1/pm->gammas[i],
  4960. pm->gammas[j], PNG_MAX_GAMMA_8, speed,
  4961. pm->use_input_precision_16to8, 1 /*strip16*/);
  4962. if (fail(pm))
  4963. return;
  4964. gamma_transform_test(pm, 6, 16, pm->interlace_type, 1/pm->gammas[i],
  4965. pm->gammas[j], PNG_MAX_GAMMA_8, speed,
  4966. pm->use_input_precision_16to8, 1 /*strip16*/);
  4967. if (fail(pm))
  4968. return;
  4969. }
  4970. }
  4971. }
  4972. }
  4973. #endif /* 16 to 8 bit conversion */
  4974. static void
  4975. perform_gamma_test(png_modifier *pm, int speed, int summary)
  4976. {
  4977. /* First some arbitrary no-transform tests: */
  4978. if (!speed && pm->test_gamma_threshold)
  4979. {
  4980. perform_gamma_threshold_tests(pm);
  4981. if (fail(pm))
  4982. return;
  4983. }
  4984. /* Now some real transforms. */
  4985. if (pm->test_gamma_transform)
  4986. {
  4987. perform_gamma_transform_tests(pm, speed);
  4988. if (summary)
  4989. {
  4990. printf("Gamma correction error summary\n\n");
  4991. printf("The printed value is the maximum error in the pixel values\n");
  4992. printf("calculated by the libpng gamma correction code. The error\n");
  4993. printf("is calculated as the difference between the output pixel\n");
  4994. printf("value (always an integer) and the ideal value from the\n");
  4995. printf("libpng specification (typically not an integer).\n\n");
  4996. printf("Expect this value to be less than .5 for 8 bit formats,\n");
  4997. printf("less than 1 for formats with fewer than 8 bits and a small\n");
  4998. printf("number (typically less than 5) for the 16 bit formats.\n");
  4999. printf("For performance reasons the value for 16 bit formats\n");
  5000. printf("increases when the image file includes an sBIT chunk.\n\n");
  5001. printf(" 2 bit gray: %.5f\n", pm->error_gray_2);
  5002. printf(" 4 bit gray: %.5f\n", pm->error_gray_4);
  5003. printf(" 8 bit gray: %.5f\n", pm->error_gray_8);
  5004. printf(" 8 bit color: %.5f\n", pm->error_color_8);
  5005. #ifdef DO_16BIT
  5006. printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
  5007. printf(" 16 bit color: %.5f\n", pm->error_color_16);
  5008. #endif
  5009. }
  5010. }
  5011. /* The sbit tests produce much larger errors: */
  5012. if (pm->test_gamma_sbit)
  5013. {
  5014. pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 =
  5015. pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
  5016. perform_gamma_sbit_tests(pm, speed);
  5017. if (summary)
  5018. {
  5019. printf("Gamma correction with sBIT:\n");
  5020. if (pm->sbitlow < 8U)
  5021. {
  5022. printf(" 2 bit gray: %.5f\n", pm->error_gray_2);
  5023. printf(" 4 bit gray: %.5f\n", pm->error_gray_4);
  5024. printf(" 8 bit gray: %.5f\n", pm->error_gray_8);
  5025. printf(" 8 bit color: %.5f\n", pm->error_color_8);
  5026. }
  5027. #ifdef DO_16BIT
  5028. printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
  5029. printf(" 16 bit color: %.5f\n", pm->error_color_16);
  5030. #endif
  5031. }
  5032. }
  5033. #ifdef PNG_READ_16_TO_8_SUPPORTED
  5034. if (pm->test_gamma_strip16)
  5035. {
  5036. /* The 16 to 8 bit strip operations: */
  5037. pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 =
  5038. pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
  5039. perform_gamma_strip16_tests(pm, speed);
  5040. if (summary)
  5041. {
  5042. printf("Gamma correction with 16 to 8 bit reduction:\n");
  5043. printf(" 16 bit gray: %.5f\n", pm->error_gray_16);
  5044. printf(" 16 bit color: %.5f\n", pm->error_color_16);
  5045. }
  5046. }
  5047. #endif
  5048. }
  5049. /* INTERLACE MACRO VALIDATION */
  5050. /* This is copied verbatim from the specification, it is simply the pass
  5051. * number in which each pixel in each 8x8 tile appears. The array must
  5052. * be indexed adam7[y][x] and notice that the pass numbers are based at
  5053. * 1, not 0 - the base libpng uses.
  5054. */
  5055. static PNG_CONST
  5056. png_byte adam7[8][8] =
  5057. {
  5058. { 1,6,4,6,2,6,4,6 },
  5059. { 7,7,7,7,7,7,7,7 },
  5060. { 5,6,5,6,5,6,5,6 },
  5061. { 7,7,7,7,7,7,7,7 },
  5062. { 3,6,4,6,3,6,4,6 },
  5063. { 7,7,7,7,7,7,7,7 },
  5064. { 5,6,5,6,5,6,5,6 },
  5065. { 7,7,7,7,7,7,7,7 }
  5066. };
  5067. /* This routine validates all the interlace support macros in png.h for
  5068. * a variety of valid PNG widths and heights. It uses a number of similarly
  5069. * named internal routines that feed off the above array.
  5070. */
  5071. static png_uint_32
  5072. png_pass_start_row(int pass)
  5073. {
  5074. int x, y;
  5075. ++pass;
  5076. for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
  5077. return y;
  5078. return 0xf;
  5079. }
  5080. static png_uint_32
  5081. png_pass_start_col(int pass)
  5082. {
  5083. int x, y;
  5084. ++pass;
  5085. for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
  5086. return x;
  5087. return 0xf;
  5088. }
  5089. static int
  5090. png_pass_row_shift(int pass)
  5091. {
  5092. int x, y, base=(-1), inc=8;
  5093. ++pass;
  5094. for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
  5095. {
  5096. if (base == (-1))
  5097. base = y;
  5098. else if (base == y)
  5099. {}
  5100. else if (inc == y-base)
  5101. base=y;
  5102. else if (inc == 8)
  5103. inc = y-base, base=y;
  5104. else if (inc != y-base)
  5105. return 0xff; /* error - more than one 'inc' value! */
  5106. }
  5107. if (base == (-1)) return 0xfe; /* error - no row in pass! */
  5108. /* The shift is always 1, 2 or 3 - no pass has all the rows! */
  5109. switch (inc)
  5110. {
  5111. case 2: return 1;
  5112. case 4: return 2;
  5113. case 8: return 3;
  5114. default: break;
  5115. }
  5116. /* error - unrecognized 'inc' */
  5117. return (inc << 8) + 0xfd;
  5118. }
  5119. static int
  5120. png_pass_col_shift(int pass)
  5121. {
  5122. int x, y, base=(-1), inc=8;
  5123. ++pass;
  5124. for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
  5125. {
  5126. if (base == (-1))
  5127. base = x;
  5128. else if (base == x)
  5129. {}
  5130. else if (inc == x-base)
  5131. base=x;
  5132. else if (inc == 8)
  5133. inc = x-base, base=x;
  5134. else if (inc != x-base)
  5135. return 0xff; /* error - more than one 'inc' value! */
  5136. }
  5137. if (base == (-1)) return 0xfe; /* error - no row in pass! */
  5138. /* The shift is always 1, 2 or 3 - no pass has all the rows! */
  5139. switch (inc)
  5140. {
  5141. case 1: return 0; /* pass 7 has all the columns */
  5142. case 2: return 1;
  5143. case 4: return 2;
  5144. case 8: return 3;
  5145. default: break;
  5146. }
  5147. /* error - unrecognized 'inc' */
  5148. return (inc << 8) + 0xfd;
  5149. }
  5150. static png_uint_32
  5151. png_row_from_pass_row(png_uint_32 yIn, int pass)
  5152. {
  5153. /* By examination of the array: */
  5154. switch (pass)
  5155. {
  5156. case 0: return yIn * 8;
  5157. case 1: return yIn * 8;
  5158. case 2: return yIn * 8 + 4;
  5159. case 3: return yIn * 4;
  5160. case 4: return yIn * 4 + 2;
  5161. case 5: return yIn * 2;
  5162. case 6: return yIn * 2 + 1;
  5163. default: break;
  5164. }
  5165. return 0xff; /* bad pass number */
  5166. }
  5167. static png_uint_32
  5168. png_col_from_pass_col(png_uint_32 xIn, int pass)
  5169. {
  5170. /* By examination of the array: */
  5171. switch (pass)
  5172. {
  5173. case 0: return xIn * 8;
  5174. case 1: return xIn * 8 + 4;
  5175. case 2: return xIn * 4;
  5176. case 3: return xIn * 4 + 2;
  5177. case 4: return xIn * 2;
  5178. case 5: return xIn * 2 + 1;
  5179. case 6: return xIn;
  5180. default: break;
  5181. }
  5182. return 0xff; /* bad pass number */
  5183. }
  5184. static int
  5185. png_row_in_interlace_pass(png_uint_32 y, int pass)
  5186. {
  5187. /* Is row 'y' in pass 'pass'? */
  5188. int x;
  5189. y &= 7;
  5190. ++pass;
  5191. for (x=0; x<8; ++x) if (adam7[y][x] == pass)
  5192. return 1;
  5193. return 0;
  5194. }
  5195. static int
  5196. png_col_in_interlace_pass(png_uint_32 x, int pass)
  5197. {
  5198. /* Is column 'x' in pass 'pass'? */
  5199. int y;
  5200. x &= 7;
  5201. ++pass;
  5202. for (y=0; y<8; ++y) if (adam7[y][x] == pass)
  5203. return 1;
  5204. return 0;
  5205. }
  5206. static png_uint_32
  5207. png_pass_rows(png_uint_32 height, int pass)
  5208. {
  5209. png_uint_32 tiles = height>>3;
  5210. png_uint_32 rows = 0;
  5211. unsigned int x, y;
  5212. height &= 7;
  5213. ++pass;
  5214. for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
  5215. {
  5216. rows += tiles;
  5217. if (y < height) ++rows;
  5218. break; /* i.e. break the 'x', column, loop. */
  5219. }
  5220. return rows;
  5221. }
  5222. static png_uint_32
  5223. png_pass_cols(png_uint_32 width, int pass)
  5224. {
  5225. png_uint_32 tiles = width>>3;
  5226. png_uint_32 cols = 0;
  5227. unsigned int x, y;
  5228. width &= 7;
  5229. ++pass;
  5230. for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
  5231. {
  5232. cols += tiles;
  5233. if (x < width) ++cols;
  5234. break; /* i.e. break the 'y', row, loop. */
  5235. }
  5236. return cols;
  5237. }
  5238. static void
  5239. perform_interlace_macro_validation(void)
  5240. {
  5241. /* The macros to validate, first those that depend only on pass:
  5242. *
  5243. * PNG_PASS_START_ROW(pass)
  5244. * PNG_PASS_START_COL(pass)
  5245. * PNG_PASS_ROW_SHIFT(pass)
  5246. * PNG_PASS_COL_SHIFT(pass)
  5247. */
  5248. int pass;
  5249. for (pass=0; pass<7; ++pass)
  5250. {
  5251. png_uint_32 m, f, v;
  5252. m = PNG_PASS_START_ROW(pass);
  5253. f = png_pass_start_row(pass);
  5254. if (m != f)
  5255. {
  5256. fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f);
  5257. exit(1);
  5258. }
  5259. m = PNG_PASS_START_COL(pass);
  5260. f = png_pass_start_col(pass);
  5261. if (m != f)
  5262. {
  5263. fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f);
  5264. exit(1);
  5265. }
  5266. m = PNG_PASS_ROW_SHIFT(pass);
  5267. f = png_pass_row_shift(pass);
  5268. if (m != f)
  5269. {
  5270. fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f);
  5271. exit(1);
  5272. }
  5273. m = PNG_PASS_COL_SHIFT(pass);
  5274. f = png_pass_col_shift(pass);
  5275. if (m != f)
  5276. {
  5277. fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f);
  5278. exit(1);
  5279. }
  5280. /* Macros that depend on the image or sub-image height too:
  5281. *
  5282. * PNG_PASS_ROWS(height, pass)
  5283. * PNG_PASS_COLS(width, pass)
  5284. * PNG_ROW_FROM_PASS_ROW(yIn, pass)
  5285. * PNG_COL_FROM_PASS_COL(xIn, pass)
  5286. * PNG_ROW_IN_INTERLACE_PASS(y, pass)
  5287. * PNG_COL_IN_INTERLACE_PASS(x, pass)
  5288. */
  5289. for (v=0;;)
  5290. {
  5291. /* First the base 0 stuff: */
  5292. m = PNG_ROW_FROM_PASS_ROW(v, pass);
  5293. f = png_row_from_pass_row(v, pass);
  5294. if (m != f)
  5295. {
  5296. fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
  5297. v, pass, m, f);
  5298. exit(1);
  5299. }
  5300. m = PNG_COL_FROM_PASS_COL(v, pass);
  5301. f = png_col_from_pass_col(v, pass);
  5302. if (m != f)
  5303. {
  5304. fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
  5305. v, pass, m, f);
  5306. exit(1);
  5307. }
  5308. m = PNG_ROW_IN_INTERLACE_PASS(v, pass);
  5309. f = png_row_in_interlace_pass(v, pass);
  5310. if (m != f)
  5311. {
  5312. fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
  5313. v, pass, m, f);
  5314. exit(1);
  5315. }
  5316. m = PNG_COL_IN_INTERLACE_PASS(v, pass);
  5317. f = png_col_in_interlace_pass(v, pass);
  5318. if (m != f)
  5319. {
  5320. fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
  5321. v, pass, m, f);
  5322. exit(1);
  5323. }
  5324. /* Then the base 1 stuff: */
  5325. ++v;
  5326. m = PNG_PASS_ROWS(v, pass);
  5327. f = png_pass_rows(v, pass);
  5328. if (m != f)
  5329. {
  5330. fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n",
  5331. v, pass, m, f);
  5332. exit(1);
  5333. }
  5334. m = PNG_PASS_COLS(v, pass);
  5335. f = png_pass_cols(v, pass);
  5336. if (m != f)
  5337. {
  5338. fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n",
  5339. v, pass, m, f);
  5340. exit(1);
  5341. }
  5342. /* Move to the next v - the stepping algorithm starts skipping
  5343. * values above 1024.
  5344. */
  5345. if (v > 1024)
  5346. {
  5347. if (v == PNG_UINT_31_MAX)
  5348. break;
  5349. v = (v << 1) ^ v;
  5350. if (v >= PNG_UINT_31_MAX)
  5351. v = PNG_UINT_31_MAX-1;
  5352. }
  5353. }
  5354. }
  5355. }
  5356. /* main program */
  5357. int main(int argc, PNG_CONST char **argv)
  5358. {
  5359. volatile int summary = 1; /* Print the error summary at the end */
  5360. /* Create the given output file on success: */
  5361. PNG_CONST char *volatile touch = NULL;
  5362. /* This is an array of standard gamma values (believe it or not I've seen
  5363. * every one of these mentioned somewhere.)
  5364. *
  5365. * In the following list the most useful values are first!
  5366. */
  5367. static double
  5368. gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9};
  5369. png_modifier pm;
  5370. context(&pm.this, fault);
  5371. modifier_init(&pm);
  5372. /* Preallocate the image buffer, because we know how big it needs to be,
  5373. * note that, for testing purposes, it is deliberately mis-aligned.
  5374. */
  5375. pm.this.image = malloc(2*TRANSFORM_IMAGEMAX+1);
  5376. if (pm.this.image != NULL)
  5377. {
  5378. /* Ignore OOM at this point - the 'ensure' routine above will allocate
  5379. * the array appropriately.
  5380. */
  5381. ++(pm.this.image);
  5382. pm.this.cb_image = 2*TRANSFORM_IMAGEMAX;
  5383. }
  5384. /* Default to error on warning: */
  5385. pm.this.treat_warnings_as_errors = 1;
  5386. /* Store the test gammas */
  5387. pm.gammas = gammas;
  5388. pm.ngammas = 0; /* default to off */
  5389. pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
  5390. pm.use_input_precision_16to8 = 1U; /* Because of the way libpng does it */
  5391. /* Some default values (set the behavior for 'make check' here).
  5392. * These values simply control the maximum error permitted in the gamma
  5393. * transformations. The practial limits for human perception are described
  5394. * below (the setting for maxpc16), however for 8 bit encodings it isn't
  5395. * possible to meet the accepted capabilities of human vision - i.e. 8 bit
  5396. * images can never be good enough, regardless of encoding.
  5397. */
  5398. pm.maxout8 = .1; /* Arithmetic error in *encoded* value */
  5399. pm.maxabs8 = .00005; /* 1/20000 */
  5400. pm.maxpc8 = .499; /* I.e., .499% fractional error */
  5401. pm.maxout16 = .499; /* Error in *encoded* value */
  5402. pm.maxabs16 = .00005;/* 1/20000 */
  5403. /* NOTE: this is a reasonable perceptual limit. We assume that humans can
  5404. * perceive light level differences of 1% over a 100:1 range, so we need to
  5405. * maintain 1 in 10000 accuracy (in linear light space), which is what the
  5406. * following guarantees. It also allows significantly higher errors at
  5407. * higher 16 bit values, which is important for performance. The actual
  5408. * maximum 16 bit error is about +/-1.9 in the fixed point implementation but
  5409. * this is only allowed for values >38149 by the following:
  5410. */
  5411. pm.maxpc16 = .005; /* I.e., 1/200% - 1/20000 */
  5412. /* Now parse the command line options. */
  5413. while (--argc >= 1)
  5414. {
  5415. if (strcmp(*++argv, "-v") == 0)
  5416. pm.this.verbose = 1;
  5417. else if (strcmp(*argv, "-l") == 0)
  5418. pm.log = 1;
  5419. else if (strcmp(*argv, "-q") == 0)
  5420. summary = pm.this.verbose = pm.log = 0;
  5421. else if (strcmp(*argv, "-w") == 0)
  5422. pm.this.treat_warnings_as_errors = 0;
  5423. else if (strcmp(*argv, "--speed") == 0)
  5424. pm.this.speed = 1, pm.ngammas = (sizeof gammas)/(sizeof gammas[0]),
  5425. pm.test_standard = 0;
  5426. else if (strcmp(*argv, "--size") == 0)
  5427. pm.test_size = 1;
  5428. else if (strcmp(*argv, "--nosize") == 0)
  5429. pm.test_size = 0;
  5430. else if (strcmp(*argv, "--standard") == 0)
  5431. pm.test_standard = 1;
  5432. else if (strcmp(*argv, "--nostandard") == 0)
  5433. pm.test_standard = 0;
  5434. else if (strcmp(*argv, "--transform") == 0)
  5435. pm.test_transform = 1;
  5436. else if (strcmp(*argv, "--notransform") == 0)
  5437. pm.test_transform = 0;
  5438. else if (strncmp(*argv, "--transform-disable=",
  5439. sizeof "--transform-disable") == 0)
  5440. {
  5441. pm.test_transform = 1;
  5442. transform_disable(*argv + sizeof "--transform-disable");
  5443. }
  5444. else if (strncmp(*argv, "--transform-enable=",
  5445. sizeof "--transform-enable") == 0)
  5446. {
  5447. pm.test_transform = 1;
  5448. transform_enable(*argv + sizeof "--transform-enable");
  5449. }
  5450. else if (strcmp(*argv, "--gamma") == 0)
  5451. {
  5452. /* Just do two gamma tests here (2.2 and linear) for speed: */
  5453. pm.ngammas = 2U;
  5454. pm.test_gamma_threshold = 1;
  5455. pm.test_gamma_transform = 1;
  5456. pm.test_gamma_sbit = 1;
  5457. pm.test_gamma_strip16 = 1;
  5458. }
  5459. else if (strcmp(*argv, "--nogamma") == 0)
  5460. pm.ngammas = 0;
  5461. else if (strcmp(*argv, "--gamma-threshold") == 0)
  5462. pm.ngammas = 2U, pm.test_gamma_threshold = 1;
  5463. else if (strcmp(*argv, "--nogamma-threshold") == 0)
  5464. pm.test_gamma_threshold = 0;
  5465. else if (strcmp(*argv, "--gamma-transform") == 0)
  5466. pm.ngammas = 2U, pm.test_gamma_transform = 1;
  5467. else if (strcmp(*argv, "--nogamma-transform") == 0)
  5468. pm.test_gamma_transform = 0;
  5469. else if (strcmp(*argv, "--gamma-sbit") == 0)
  5470. pm.ngammas = 2U, pm.test_gamma_sbit = 1;
  5471. else if (strcmp(*argv, "--nogamma-sbit") == 0)
  5472. pm.test_gamma_sbit = 0;
  5473. else if (strcmp(*argv, "--gamma-16-to-8") == 0)
  5474. pm.ngammas = 2U, pm.test_gamma_strip16 = 1;
  5475. else if (strcmp(*argv, "--nogamma-16-to-8") == 0)
  5476. pm.test_gamma_strip16 = 0;
  5477. else if (strcmp(*argv, "--all-gammas") == 0)
  5478. pm.ngammas = (sizeof gammas)/(sizeof gammas[0]);
  5479. else if (strcmp(*argv, "--progressive-read") == 0)
  5480. pm.this.progressive = 1;
  5481. else if (strcmp(*argv, "--interlace") == 0)
  5482. pm.interlace_type = PNG_INTERLACE_ADAM7;
  5483. else if (argc >= 1 && strcmp(*argv, "--sbitlow") == 0)
  5484. --argc, pm.sbitlow = (png_byte)atoi(*++argv);
  5485. else if (argc >= 1 && strcmp(*argv, "--touch") == 0)
  5486. --argc, touch = *++argv;
  5487. else if (argc >= 1 && strncmp(*argv, "--max", 4) == 0)
  5488. {
  5489. --argc;
  5490. if (strcmp(4+*argv, "abs8") == 0)
  5491. pm.maxabs8 = atof(*++argv);
  5492. else if (strcmp(4+*argv, "abs16") == 0)
  5493. pm.maxabs16 = atof(*++argv);
  5494. else if (strcmp(4+*argv, "out8") == 0)
  5495. pm.maxout8 = atof(*++argv);
  5496. else if (strcmp(4+*argv, "out16") == 0)
  5497. pm.maxout16 = atof(*++argv);
  5498. else if (strcmp(4+*argv, "pc8") == 0)
  5499. pm.maxpc8 = atof(*++argv);
  5500. else if (strcmp(4+*argv, "pc16") == 0)
  5501. pm.maxpc16 = atof(*++argv);
  5502. else
  5503. {
  5504. fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv);
  5505. exit(1);
  5506. }
  5507. }
  5508. else
  5509. {
  5510. fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv);
  5511. exit(1);
  5512. }
  5513. }
  5514. /* If pngvalid is run with no arguments default to a reasonable set of the
  5515. * tests.
  5516. */
  5517. if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 &&
  5518. pm.ngammas == 0)
  5519. {
  5520. pm.test_standard = 1;
  5521. pm.test_size = 1;
  5522. pm.test_transform = 1;
  5523. pm.ngammas = 3U;
  5524. }
  5525. if (pm.ngammas > 0 &&
  5526. pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 &&
  5527. pm.test_gamma_sbit == 0 && pm.test_gamma_strip16 == 0)
  5528. {
  5529. pm.test_gamma_threshold = 1;
  5530. pm.test_gamma_transform = 1;
  5531. pm.test_gamma_sbit = 1;
  5532. pm.test_gamma_strip16 = 1;
  5533. }
  5534. else if (pm.ngammas == 0)
  5535. {
  5536. /* Nothing to test so turn everything off: */
  5537. pm.test_gamma_threshold = 0;
  5538. pm.test_gamma_transform = 0;
  5539. pm.test_gamma_sbit = 0;
  5540. pm.test_gamma_strip16 = 0;
  5541. }
  5542. Try
  5543. {
  5544. /* Make useful base images */
  5545. make_transform_images(&pm.this);
  5546. /* Perform the standard and gamma tests. */
  5547. if (pm.test_standard)
  5548. {
  5549. perform_interlace_macro_validation();
  5550. perform_standard_test(&pm);
  5551. perform_error_test(&pm);
  5552. }
  5553. /* Various oddly sized images: */
  5554. if (pm.test_size)
  5555. {
  5556. make_size_images(&pm.this);
  5557. perform_size_test(&pm);
  5558. }
  5559. /* Combinatorial transforms: */
  5560. if (pm.test_transform)
  5561. perform_transform_test(&pm);
  5562. if (pm.ngammas > 0)
  5563. perform_gamma_test(&pm, pm.this.speed != 0,
  5564. summary && !pm.this.speed);
  5565. }
  5566. Catch(fault)
  5567. {
  5568. fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n");
  5569. if (!pm.this.verbose)
  5570. {
  5571. if (pm.this.error[0] != 0)
  5572. fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error);
  5573. fprintf(stderr, "pngvalid: run with -v to see what happened\n");
  5574. }
  5575. exit(1);
  5576. }
  5577. if (summary && !pm.this.speed)
  5578. {
  5579. printf("Results using %s point arithmetic %s\n",
  5580. #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
  5581. "floating",
  5582. #else
  5583. "fixed",
  5584. #endif
  5585. (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
  5586. pm.this.nwarnings)) ? "(errors)" : (pm.this.nwarnings ?
  5587. "(warnings)" : "(no errors or warnings)")
  5588. );
  5589. printf("Allocated memory statistics (in bytes):\n"
  5590. "\tread %lu maximum single, %lu peak, %lu total\n"
  5591. "\twrite %lu maximum single, %lu peak, %lu total\n",
  5592. (unsigned long)pm.this.read_memory_pool.max_max,
  5593. (unsigned long)pm.this.read_memory_pool.max_limit,
  5594. (unsigned long)pm.this.read_memory_pool.max_total,
  5595. (unsigned long)pm.this.write_memory_pool.max_max,
  5596. (unsigned long)pm.this.write_memory_pool.max_limit,
  5597. (unsigned long)pm.this.write_memory_pool.max_total);
  5598. }
  5599. /* Do this here to provoke memory corruption errors in memory not directly
  5600. * allocated by libpng - not a complete test, but better than nothing.
  5601. */
  5602. store_delete(&pm.this);
  5603. /* Error exit if there are any errors, and maybe if there are any
  5604. * warnings.
  5605. */
  5606. if (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
  5607. pm.this.nwarnings))
  5608. {
  5609. if (!pm.this.verbose)
  5610. fprintf(stderr, "pngvalid: %s\n", pm.this.error);
  5611. fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors,
  5612. pm.this.nwarnings);
  5613. exit(1);
  5614. }
  5615. /* Success case. */
  5616. if (touch != NULL)
  5617. {
  5618. FILE *fsuccess = fopen(touch, "wt");
  5619. if (fsuccess != NULL)
  5620. {
  5621. int error = 0;
  5622. fprintf(fsuccess, "PNG validation succeeded\n");
  5623. fflush(fsuccess);
  5624. error = ferror(fsuccess);
  5625. if (fclose(fsuccess) || error)
  5626. {
  5627. fprintf(stderr, "%s: write failed\n", touch);
  5628. exit(1);
  5629. }
  5630. }
  5631. }
  5632. return 0;
  5633. }