PageRenderTime 69ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/lib_png/base/libpng-1.6.16/contrib/libtests/pngvalid.c

https://bitbucket.org/xixs/lua
C | 10595 lines | 7015 code | 1570 blank | 2010 comment | 1600 complexity | e1d608dbe15242bcd4d13bdfda584db7 MD5 | raw file
Possible License(s): Zlib, BSD-3-Clause, CC0-1.0, GPL-3.0, GPL-2.0, CPL-1.0, MPL-2.0-no-copyleft-exception, LGPL-2.0, LGPL-2.1, LGPL-3.0, 0BSD, Cube

Large files files are truncated, but you can click here to view the full file

  1. /* pngvalid.c - validate libpng by constructing then reading png files.
  2. *
  3. * Last changed in libpng 1.6.14 [October 23, 2014]
  4. * Copyright (c) 2014 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. #define _POSIX_SOURCE 1
  21. #define _ISOC99_SOURCE 1 /* For floating point */
  22. #define _GNU_SOURCE 1 /* For the floating point exception extension */
  23. #include <signal.h>
  24. #include <stdio.h>
  25. #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
  26. # include <config.h>
  27. #endif
  28. #ifdef HAVE_FEENABLEEXCEPT /* from config.h, if included */
  29. # include <fenv.h>
  30. #endif
  31. #ifndef FE_DIVBYZERO
  32. # define FE_DIVBYZERO 0
  33. #endif
  34. #ifndef FE_INVALID
  35. # define FE_INVALID 0
  36. #endif
  37. #ifndef FE_OVERFLOW
  38. # define FE_OVERFLOW 0
  39. #endif
  40. /* Define the following to use this test against your installed libpng, rather
  41. * than the one being built here:
  42. */
  43. #ifdef PNG_FREESTANDING_TESTS
  44. # include <png.h>
  45. #else
  46. # include "../../png.h"
  47. #endif
  48. #ifdef PNG_ZLIB_HEADER
  49. # include PNG_ZLIB_HEADER
  50. #else
  51. # include <zlib.h> /* For crc32 */
  52. #endif
  53. /* 1.6.1 added support for the configure test harness, which uses 77 to indicate
  54. * a skipped test, in earlier versions we need to succeed on a skipped test, so:
  55. */
  56. #if PNG_LIBPNG_VER < 10601
  57. # define SKIP 0
  58. #else
  59. # define SKIP 77
  60. #endif
  61. /* pngvalid requires write support and one of the fixed or floating point APIs.
  62. */
  63. #if defined(PNG_WRITE_SUPPORTED) &&\
  64. (defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED))
  65. #if PNG_LIBPNG_VER < 10500
  66. /* This deliberately lacks the PNG_CONST. */
  67. typedef png_byte *png_const_bytep;
  68. /* This is copied from 1.5.1 png.h: */
  69. #define PNG_INTERLACE_ADAM7_PASSES 7
  70. #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
  71. #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
  72. #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
  73. #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
  74. #define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
  75. -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
  76. #define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
  77. -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
  78. #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
  79. (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
  80. #define PNG_COL_FROM_PASS_COL(xIn, pass) \
  81. (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
  82. #define PNG_PASS_MASK(pass,off) ( \
  83. ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
  84. ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
  85. #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
  86. ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
  87. #define PNG_COL_IN_INTERLACE_PASS(x, pass) \
  88. ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
  89. /* These are needed too for the default build: */
  90. #define PNG_WRITE_16BIT_SUPPORTED
  91. #define PNG_READ_16BIT_SUPPORTED
  92. /* This comes from pnglibconf.h afer 1.5: */
  93. #define PNG_FP_1 100000
  94. #define PNG_GAMMA_THRESHOLD_FIXED\
  95. ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
  96. #endif
  97. #if PNG_LIBPNG_VER < 10600
  98. /* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be
  99. * compiled against earlier versions.
  100. */
  101. # define png_const_structp png_structp
  102. #endif
  103. #include <float.h> /* For floating point constants */
  104. #include <stdlib.h> /* For malloc */
  105. #include <string.h> /* For memcpy, memset */
  106. #include <math.h> /* For floor */
  107. /* Unused formal parameter errors are removed using the following macro which is
  108. * expected to have no bad effects on performance.
  109. */
  110. #ifndef UNUSED
  111. # if defined(__GNUC__) || defined(_MSC_VER)
  112. # define UNUSED(param) (void)param;
  113. # else
  114. # define UNUSED(param)
  115. # endif
  116. #endif
  117. /***************************** EXCEPTION HANDLING *****************************/
  118. #ifdef PNG_FREESTANDING_TESTS
  119. # include <cexcept.h>
  120. #else
  121. # include "../visupng/cexcept.h"
  122. #endif
  123. #ifdef __cplusplus
  124. # define this not_the_cpp_this
  125. # define new not_the_cpp_new
  126. # define voidcast(type, value) static_cast<type>(value)
  127. #else
  128. # define voidcast(type, value) (value)
  129. #endif /* __cplusplus */
  130. struct png_store;
  131. define_exception_type(struct png_store*);
  132. /* The following are macros to reduce typing everywhere where the well known
  133. * name 'the_exception_context' must be defined.
  134. */
  135. #define anon_context(ps) struct exception_context *the_exception_context = \
  136. &(ps)->exception_context
  137. #define context(ps,fault) anon_context(ps); png_store *fault
  138. /* This macro returns the number of elements in an array as an (unsigned int),
  139. * it is necessary to avoid the inability of certain versions of GCC to use
  140. * the value of a compile-time constant when performing range checks. It must
  141. * be passed an array name.
  142. */
  143. #define ARRAY_SIZE(a) ((unsigned int)((sizeof (a))/(sizeof (a)[0])))
  144. /******************************* UTILITIES ************************************/
  145. /* Error handling is particularly problematic in production code - error
  146. * handlers often themselves have bugs which lead to programs that detect
  147. * minor errors crashing. The following functions deal with one very
  148. * common class of errors in error handlers - attempting to format error or
  149. * warning messages into buffers that are too small.
  150. */
  151. static size_t safecat(char *buffer, size_t bufsize, size_t pos,
  152. PNG_CONST char *cat)
  153. {
  154. while (pos < bufsize && cat != NULL && *cat != 0)
  155. buffer[pos++] = *cat++;
  156. if (pos >= bufsize)
  157. pos = bufsize-1;
  158. buffer[pos] = 0;
  159. return pos;
  160. }
  161. static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)
  162. {
  163. char number[64];
  164. sprintf(number, "%d", n);
  165. return safecat(buffer, bufsize, pos, number);
  166. }
  167. #ifdef PNG_READ_TRANSFORMS_SUPPORTED
  168. static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,
  169. int precision)
  170. {
  171. char number[64];
  172. sprintf(number, "%.*f", precision, d);
  173. return safecat(buffer, bufsize, pos, number);
  174. }
  175. #endif
  176. static PNG_CONST char invalid[] = "invalid";
  177. static PNG_CONST char sep[] = ": ";
  178. static PNG_CONST char *colour_types[8] =
  179. {
  180. "grayscale", invalid, "truecolour", "indexed-colour",
  181. "grayscale with alpha", invalid, "truecolour with alpha", invalid
  182. };
  183. #ifdef PNG_READ_SUPPORTED
  184. /* Convert a double precision value to fixed point. */
  185. static png_fixed_point
  186. fix(double d)
  187. {
  188. d = floor(d * PNG_FP_1 + .5);
  189. return (png_fixed_point)d;
  190. }
  191. #endif /* PNG_READ_SUPPORTED */
  192. /* Generate random bytes. This uses a boring repeatable algorithm and it
  193. * is implemented here so that it gives the same set of numbers on every
  194. * architecture. It's a linear congruential generator (Knuth or Sedgewick
  195. * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
  196. * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise
  197. * Generation.)
  198. */
  199. static void
  200. make_random_bytes(png_uint_32* seed, void* pv, size_t size)
  201. {
  202. png_uint_32 u0 = seed[0], u1 = seed[1];
  203. png_bytep bytes = voidcast(png_bytep, pv);
  204. /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
  205. * bit-20. The top 1 bit is in u1, the bottom 32 are in u0.
  206. */
  207. size_t i;
  208. for (i=0; i<size; ++i)
  209. {
  210. /* First generate 8 new bits then shift them in at the end. */
  211. png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
  212. u1 <<= 8;
  213. u1 |= u0 >> 24;
  214. u0 <<= 8;
  215. u0 |= u;
  216. *bytes++ = (png_byte)u;
  217. }
  218. seed[0] = u0;
  219. seed[1] = u1;
  220. }
  221. static void
  222. make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
  223. {
  224. make_random_bytes(seed, bytes, 4);
  225. }
  226. #ifdef PNG_READ_SUPPORTED
  227. static void
  228. randomize(void *pv, size_t size)
  229. {
  230. static png_uint_32 random_seed[2] = {0x56789abc, 0xd};
  231. make_random_bytes(random_seed, pv, size);
  232. }
  233. #define RANDOMIZE(this) randomize(&(this), sizeof (this))
  234. static unsigned int
  235. random_mod(unsigned int max)
  236. {
  237. unsigned int x;
  238. RANDOMIZE(x);
  239. return x % max; /* 0 .. max-1 */
  240. }
  241. #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
  242. static int
  243. random_choice(void)
  244. {
  245. unsigned char x;
  246. RANDOMIZE(x);
  247. return x & 1;
  248. }
  249. #endif
  250. #endif /* PNG_READ_SUPPORTED */
  251. /* A numeric ID based on PNG file characteristics. The 'do_interlace' field
  252. * simply records whether pngvalid did the interlace itself or whether it
  253. * was done by libpng. Width and height must be less than 256. 'palette' is an
  254. * index of the palette to use for formats with a palette (0 otherwise.)
  255. */
  256. #define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
  257. ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
  258. (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))
  259. #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
  260. #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
  261. #define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f)
  262. #define INTERLACE_FROM_ID(id) ((int)(((id) >> 13) & 0x3))
  263. #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
  264. #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
  265. #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
  266. /* Utility to construct a standard name for a standard image. */
  267. static size_t
  268. standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
  269. int bit_depth, unsigned int npalette, int interlace_type,
  270. png_uint_32 w, png_uint_32 h, int do_interlace)
  271. {
  272. pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
  273. if (npalette > 0)
  274. {
  275. pos = safecat(buffer, bufsize, pos, "[");
  276. pos = safecatn(buffer, bufsize, pos, npalette);
  277. pos = safecat(buffer, bufsize, pos, "]");
  278. }
  279. pos = safecat(buffer, bufsize, pos, " ");
  280. pos = safecatn(buffer, bufsize, pos, bit_depth);
  281. pos = safecat(buffer, bufsize, pos, " bit");
  282. if (interlace_type != PNG_INTERLACE_NONE)
  283. {
  284. pos = safecat(buffer, bufsize, pos, " interlaced");
  285. if (do_interlace)
  286. pos = safecat(buffer, bufsize, pos, "(pngvalid)");
  287. else
  288. pos = safecat(buffer, bufsize, pos, "(libpng)");
  289. }
  290. if (w > 0 || h > 0)
  291. {
  292. pos = safecat(buffer, bufsize, pos, " ");
  293. pos = safecatn(buffer, bufsize, pos, w);
  294. pos = safecat(buffer, bufsize, pos, "x");
  295. pos = safecatn(buffer, bufsize, pos, h);
  296. }
  297. return pos;
  298. }
  299. static size_t
  300. standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
  301. {
  302. return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),
  303. DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id),
  304. WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));
  305. }
  306. /* Convenience API and defines to list valid formats. Note that 16 bit read and
  307. * write support is required to do 16 bit read tests (we must be able to make a
  308. * 16 bit image to test!)
  309. */
  310. #ifdef PNG_WRITE_16BIT_SUPPORTED
  311. # define WRITE_BDHI 4
  312. # ifdef PNG_READ_16BIT_SUPPORTED
  313. # define READ_BDHI 4
  314. # define DO_16BIT
  315. # endif
  316. #else
  317. # define WRITE_BDHI 3
  318. #endif
  319. #ifndef DO_16BIT
  320. # define READ_BDHI 3
  321. #endif
  322. /* The following defines the number of different palettes to generate for
  323. * each log bit depth of a colour type 3 standard image.
  324. */
  325. #define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U)
  326. static int
  327. next_format(png_bytep colour_type, png_bytep bit_depth,
  328. unsigned int* palette_number, int no_low_depth_gray)
  329. {
  330. if (*bit_depth == 0)
  331. {
  332. *colour_type = 0;
  333. if (no_low_depth_gray)
  334. *bit_depth = 8;
  335. else
  336. *bit_depth = 1;
  337. *palette_number = 0;
  338. return 1;
  339. }
  340. if (*colour_type == 3)
  341. {
  342. /* Add multiple palettes for colour type 3. */
  343. if (++*palette_number < PALETTE_COUNT(*bit_depth))
  344. return 1;
  345. *palette_number = 0;
  346. }
  347. *bit_depth = (png_byte)(*bit_depth << 1);
  348. /* Palette images are restricted to 8 bit depth */
  349. if (*bit_depth <= 8
  350. #ifdef DO_16BIT
  351. || (*colour_type != 3 && *bit_depth <= 16)
  352. #endif
  353. )
  354. return 1;
  355. /* Move to the next color type, or return 0 at the end. */
  356. switch (*colour_type)
  357. {
  358. case 0:
  359. *colour_type = 2;
  360. *bit_depth = 8;
  361. return 1;
  362. case 2:
  363. *colour_type = 3;
  364. *bit_depth = 1;
  365. return 1;
  366. case 3:
  367. *colour_type = 4;
  368. *bit_depth = 8;
  369. return 1;
  370. case 4:
  371. *colour_type = 6;
  372. *bit_depth = 8;
  373. return 1;
  374. default:
  375. return 0;
  376. }
  377. }
  378. #ifdef PNG_READ_TRANSFORMS_SUPPORTED
  379. static unsigned int
  380. sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
  381. png_uint_32 x, unsigned int sample_index)
  382. {
  383. png_uint_32 bit_index, result;
  384. /* Find a sample index for the desired sample: */
  385. x *= bit_depth;
  386. bit_index = x;
  387. if ((colour_type & 1) == 0) /* !palette */
  388. {
  389. if (colour_type & 2)
  390. bit_index *= 3;
  391. if (colour_type & 4)
  392. bit_index += x; /* Alpha channel */
  393. /* Multiple channels; select one: */
  394. if (colour_type & (2+4))
  395. bit_index += sample_index * bit_depth;
  396. }
  397. /* Return the sample from the row as an integer. */
  398. row += bit_index >> 3;
  399. result = *row;
  400. if (bit_depth == 8)
  401. return result;
  402. else if (bit_depth > 8)
  403. return (result << 8) + *++row;
  404. /* Less than 8 bits per sample. */
  405. bit_index &= 7;
  406. return (result >> (8-bit_index-bit_depth)) & ((1U<<bit_depth)-1);
  407. }
  408. #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
  409. /* Copy a single pixel, of a given size, from one buffer to another -
  410. * while this is basically bit addressed there is an implicit assumption
  411. * that pixels 8 or more bits in size are byte aligned and that pixels
  412. * do not otherwise cross byte boundaries. (This is, so far as I know,
  413. * universally true in bitmap computer graphics. [JCB 20101212])
  414. *
  415. * NOTE: The to and from buffers may be the same.
  416. */
  417. static void
  418. pixel_copy(png_bytep toBuffer, png_uint_32 toIndex,
  419. png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize)
  420. {
  421. /* Assume we can multiply by 'size' without overflow because we are
  422. * just working in a single buffer.
  423. */
  424. toIndex *= pixelSize;
  425. fromIndex *= pixelSize;
  426. if (pixelSize < 8) /* Sub-byte */
  427. {
  428. /* Mask to select the location of the copied pixel: */
  429. unsigned int destMask = ((1U<<pixelSize)-1) << (8-pixelSize-(toIndex&7));
  430. /* The following read the entire pixels and clears the extra: */
  431. unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;
  432. unsigned int sourceByte = fromBuffer[fromIndex >> 3];
  433. /* Don't rely on << or >> supporting '0' here, just in case: */
  434. fromIndex &= 7;
  435. if (fromIndex > 0) sourceByte <<= fromIndex;
  436. if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;
  437. toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));
  438. }
  439. else /* One or more bytes */
  440. memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);
  441. }
  442. #ifdef PNG_READ_SUPPORTED
  443. /* Copy a complete row of pixels, taking into account potential partial
  444. * bytes at the end.
  445. */
  446. static void
  447. row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth)
  448. {
  449. memcpy(toBuffer, fromBuffer, bitWidth >> 3);
  450. if ((bitWidth & 7) != 0)
  451. {
  452. unsigned int mask;
  453. toBuffer += bitWidth >> 3;
  454. fromBuffer += bitWidth >> 3;
  455. /* The remaining bits are in the top of the byte, the mask is the bits to
  456. * retain.
  457. */
  458. mask = 0xff >> (bitWidth & 7);
  459. *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask));
  460. }
  461. }
  462. /* Compare pixels - they are assumed to start at the first byte in the
  463. * given buffers.
  464. */
  465. static int
  466. pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
  467. {
  468. #if PNG_LIBPNG_VER < 10506
  469. if (memcmp(pa, pb, bit_width>>3) == 0)
  470. {
  471. png_uint_32 p;
  472. if ((bit_width & 7) == 0) return 0;
  473. /* Ok, any differences? */
  474. p = pa[bit_width >> 3];
  475. p ^= pb[bit_width >> 3];
  476. if (p == 0) return 0;
  477. /* There are, but they may not be significant, remove the bits
  478. * after the end (the low order bits in PNG.)
  479. */
  480. bit_width &= 7;
  481. p >>= 8-bit_width;
  482. if (p == 0) return 0;
  483. }
  484. #else
  485. /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing
  486. * bits too:
  487. */
  488. if (memcmp(pa, pb, (bit_width+7)>>3) == 0)
  489. return 0;
  490. #endif
  491. /* Return the index of the changed byte. */
  492. {
  493. png_uint_32 where = 0;
  494. while (pa[where] == pb[where]) ++where;
  495. return 1+where;
  496. }
  497. }
  498. #endif /* PNG_READ_SUPPORTED */
  499. /*************************** BASIC PNG FILE WRITING ***************************/
  500. /* A png_store takes data from the sequential writer or provides data
  501. * to the sequential reader. It can also store the result of a PNG
  502. * write for later retrieval.
  503. */
  504. #define STORE_BUFFER_SIZE 500 /* arbitrary */
  505. typedef struct png_store_buffer
  506. {
  507. struct png_store_buffer* prev; /* NOTE: stored in reverse order */
  508. png_byte buffer[STORE_BUFFER_SIZE];
  509. } png_store_buffer;
  510. #define FILE_NAME_SIZE 64
  511. typedef struct store_palette_entry /* record of a single palette entry */
  512. {
  513. png_byte red;
  514. png_byte green;
  515. png_byte blue;
  516. png_byte alpha;
  517. } store_palette_entry, store_palette[256];
  518. typedef struct png_store_file
  519. {
  520. struct png_store_file* next; /* as many as you like... */
  521. char name[FILE_NAME_SIZE];
  522. png_uint_32 id; /* must be correct (see FILEID) */
  523. png_size_t datacount; /* In this (the last) buffer */
  524. png_store_buffer data; /* Last buffer in file */
  525. int npalette; /* Number of entries in palette */
  526. store_palette_entry* palette; /* May be NULL */
  527. } png_store_file;
  528. /* The following is a pool of memory allocated by a single libpng read or write
  529. * operation.
  530. */
  531. typedef struct store_pool
  532. {
  533. struct png_store *store; /* Back pointer */
  534. struct store_memory *list; /* List of allocated memory */
  535. png_byte mark[4]; /* Before and after data */
  536. /* Statistics for this run. */
  537. png_alloc_size_t max; /* Maximum single allocation */
  538. png_alloc_size_t current; /* Current allocation */
  539. png_alloc_size_t limit; /* Highest current allocation */
  540. png_alloc_size_t total; /* Total allocation */
  541. /* Overall statistics (retained across successive runs). */
  542. png_alloc_size_t max_max;
  543. png_alloc_size_t max_limit;
  544. png_alloc_size_t max_total;
  545. } store_pool;
  546. typedef struct png_store
  547. {
  548. /* For cexcept.h exception handling - simply store one of these;
  549. * the context is a self pointer but it may point to a different
  550. * png_store (in fact it never does in this program.)
  551. */
  552. struct exception_context
  553. exception_context;
  554. unsigned int verbose :1;
  555. unsigned int treat_warnings_as_errors :1;
  556. unsigned int expect_error :1;
  557. unsigned int expect_warning :1;
  558. unsigned int saw_warning :1;
  559. unsigned int speed :1;
  560. unsigned int progressive :1; /* use progressive read */
  561. unsigned int validated :1; /* used as a temporary flag */
  562. int nerrors;
  563. int nwarnings;
  564. int noptions; /* number of options below: */
  565. struct {
  566. unsigned char option; /* option number, 0..30 */
  567. unsigned char setting; /* setting (unset,invalid,on,off) */
  568. } options[16];
  569. char test[128]; /* Name of test */
  570. char error[256];
  571. /* Read fields */
  572. png_structp pread; /* Used to read a saved file */
  573. png_infop piread;
  574. png_store_file* current; /* Set when reading */
  575. png_store_buffer* next; /* Set when reading */
  576. png_size_t readpos; /* Position in *next */
  577. png_byte* image; /* Buffer for reading interlaced images */
  578. png_size_t cb_image; /* Size of this buffer */
  579. png_size_t cb_row; /* Row size of the image(s) */
  580. png_uint_32 image_h; /* Number of rows in a single image */
  581. store_pool read_memory_pool;
  582. /* Write fields */
  583. png_store_file* saved;
  584. png_structp pwrite; /* Used when writing a new file */
  585. png_infop piwrite;
  586. png_size_t writepos; /* Position in .new */
  587. char wname[FILE_NAME_SIZE];
  588. png_store_buffer new; /* The end of the new PNG file being written. */
  589. store_pool write_memory_pool;
  590. store_palette_entry* palette;
  591. int npalette;
  592. } png_store;
  593. /* Initialization and cleanup */
  594. static void
  595. store_pool_mark(png_bytep mark)
  596. {
  597. static png_uint_32 store_seed[2] = { 0x12345678, 1};
  598. make_four_random_bytes(store_seed, mark);
  599. }
  600. #ifdef PNG_READ_SUPPORTED
  601. /* Use this for random 32 bit values; this function makes sure the result is
  602. * non-zero.
  603. */
  604. static png_uint_32
  605. random_32(void)
  606. {
  607. for (;;)
  608. {
  609. png_byte mark[4];
  610. png_uint_32 result;
  611. store_pool_mark(mark);
  612. result = png_get_uint_32(mark);
  613. if (result != 0)
  614. return result;
  615. }
  616. }
  617. #endif /* PNG_READ_SUPPORTED */
  618. static void
  619. store_pool_init(png_store *ps, store_pool *pool)
  620. {
  621. memset(pool, 0, sizeof *pool);
  622. pool->store = ps;
  623. pool->list = NULL;
  624. pool->max = pool->current = pool->limit = pool->total = 0;
  625. pool->max_max = pool->max_limit = pool->max_total = 0;
  626. store_pool_mark(pool->mark);
  627. }
  628. static void
  629. store_init(png_store* ps)
  630. {
  631. memset(ps, 0, sizeof *ps);
  632. init_exception_context(&ps->exception_context);
  633. store_pool_init(ps, &ps->read_memory_pool);
  634. store_pool_init(ps, &ps->write_memory_pool);
  635. ps->verbose = 0;
  636. ps->treat_warnings_as_errors = 0;
  637. ps->expect_error = 0;
  638. ps->expect_warning = 0;
  639. ps->saw_warning = 0;
  640. ps->speed = 0;
  641. ps->progressive = 0;
  642. ps->validated = 0;
  643. ps->nerrors = ps->nwarnings = 0;
  644. ps->pread = NULL;
  645. ps->piread = NULL;
  646. ps->saved = ps->current = NULL;
  647. ps->next = NULL;
  648. ps->readpos = 0;
  649. ps->image = NULL;
  650. ps->cb_image = 0;
  651. ps->cb_row = 0;
  652. ps->image_h = 0;
  653. ps->pwrite = NULL;
  654. ps->piwrite = NULL;
  655. ps->writepos = 0;
  656. ps->new.prev = NULL;
  657. ps->palette = NULL;
  658. ps->npalette = 0;
  659. ps->noptions = 0;
  660. }
  661. static void
  662. store_freebuffer(png_store_buffer* psb)
  663. {
  664. if (psb->prev)
  665. {
  666. store_freebuffer(psb->prev);
  667. free(psb->prev);
  668. psb->prev = NULL;
  669. }
  670. }
  671. static void
  672. store_freenew(png_store *ps)
  673. {
  674. store_freebuffer(&ps->new);
  675. ps->writepos = 0;
  676. if (ps->palette != NULL)
  677. {
  678. free(ps->palette);
  679. ps->palette = NULL;
  680. ps->npalette = 0;
  681. }
  682. }
  683. static void
  684. store_storenew(png_store *ps)
  685. {
  686. png_store_buffer *pb;
  687. if (ps->writepos != STORE_BUFFER_SIZE)
  688. png_error(ps->pwrite, "invalid store call");
  689. pb = voidcast(png_store_buffer*, malloc(sizeof *pb));
  690. if (pb == NULL)
  691. png_error(ps->pwrite, "store new: OOM");
  692. *pb = ps->new;
  693. ps->new.prev = pb;
  694. ps->writepos = 0;
  695. }
  696. static void
  697. store_freefile(png_store_file **ppf)
  698. {
  699. if (*ppf != NULL)
  700. {
  701. store_freefile(&(*ppf)->next);
  702. store_freebuffer(&(*ppf)->data);
  703. (*ppf)->datacount = 0;
  704. if ((*ppf)->palette != NULL)
  705. {
  706. free((*ppf)->palette);
  707. (*ppf)->palette = NULL;
  708. (*ppf)->npalette = 0;
  709. }
  710. free(*ppf);
  711. *ppf = NULL;
  712. }
  713. }
  714. /* Main interface to file storeage, after writing a new PNG file (see the API
  715. * below) call store_storefile to store the result with the given name and id.
  716. */
  717. static void
  718. store_storefile(png_store *ps, png_uint_32 id)
  719. {
  720. png_store_file *pf = voidcast(png_store_file*, malloc(sizeof *pf));
  721. if (pf == NULL)
  722. png_error(ps->pwrite, "storefile: OOM");
  723. safecat(pf->name, sizeof pf->name, 0, ps->wname);
  724. pf->id = id;
  725. pf->data = ps->new;
  726. pf->datacount = ps->writepos;
  727. ps->new.prev = NULL;
  728. ps->writepos = 0;
  729. pf->palette = ps->palette;
  730. pf->npalette = ps->npalette;
  731. ps->palette = 0;
  732. ps->npalette = 0;
  733. /* And save it. */
  734. pf->next = ps->saved;
  735. ps->saved = pf;
  736. }
  737. /* Generate an error message (in the given buffer) */
  738. static size_t
  739. store_message(png_store *ps, png_const_structp pp, char *buffer, size_t bufsize,
  740. size_t pos, PNG_CONST char *msg)
  741. {
  742. if (pp != NULL && pp == ps->pread)
  743. {
  744. /* Reading a file */
  745. pos = safecat(buffer, bufsize, pos, "read: ");
  746. if (ps->current != NULL)
  747. {
  748. pos = safecat(buffer, bufsize, pos, ps->current->name);
  749. pos = safecat(buffer, bufsize, pos, sep);
  750. }
  751. }
  752. else if (pp != NULL && pp == ps->pwrite)
  753. {
  754. /* Writing a file */
  755. pos = safecat(buffer, bufsize, pos, "write: ");
  756. pos = safecat(buffer, bufsize, pos, ps->wname);
  757. pos = safecat(buffer, bufsize, pos, sep);
  758. }
  759. else
  760. {
  761. /* Neither reading nor writing (or a memory error in struct delete) */
  762. pos = safecat(buffer, bufsize, pos, "pngvalid: ");
  763. }
  764. if (ps->test[0] != 0)
  765. {
  766. pos = safecat(buffer, bufsize, pos, ps->test);
  767. pos = safecat(buffer, bufsize, pos, sep);
  768. }
  769. pos = safecat(buffer, bufsize, pos, msg);
  770. return pos;
  771. }
  772. /* Verbose output to the error stream: */
  773. static void
  774. store_verbose(png_store *ps, png_const_structp pp, png_const_charp prefix,
  775. png_const_charp message)
  776. {
  777. char buffer[512];
  778. if (prefix)
  779. fputs(prefix, stderr);
  780. (void)store_message(ps, pp, buffer, sizeof buffer, 0, message);
  781. fputs(buffer, stderr);
  782. fputc('\n', stderr);
  783. }
  784. /* Log an error or warning - the relevant count is always incremented. */
  785. static void
  786. store_log(png_store* ps, png_const_structp pp, png_const_charp message,
  787. int is_error)
  788. {
  789. /* The warning is copied to the error buffer if there are no errors and it is
  790. * the first warning. The error is copied to the error buffer if it is the
  791. * first error (overwriting any prior warnings).
  792. */
  793. if (is_error ? (ps->nerrors)++ == 0 :
  794. (ps->nwarnings)++ == 0 && ps->nerrors == 0)
  795. store_message(ps, pp, ps->error, sizeof ps->error, 0, message);
  796. if (ps->verbose)
  797. store_verbose(ps, pp, is_error ? "error: " : "warning: ", message);
  798. }
  799. #ifdef PNG_READ_SUPPORTED
  800. /* Internal error function, called with a png_store but no libpng stuff. */
  801. static void
  802. internal_error(png_store *ps, png_const_charp message)
  803. {
  804. store_log(ps, NULL, message, 1 /* error */);
  805. /* And finally throw an exception. */
  806. {
  807. struct exception_context *the_exception_context = &ps->exception_context;
  808. Throw ps;
  809. }
  810. }
  811. #endif /* PNG_READ_SUPPORTED */
  812. /* Functions to use as PNG callbacks. */
  813. static void PNGCBAPI
  814. store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */
  815. {
  816. png_const_structp pp = ppIn;
  817. png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
  818. if (!ps->expect_error)
  819. store_log(ps, pp, message, 1 /* error */);
  820. /* And finally throw an exception. */
  821. {
  822. struct exception_context *the_exception_context = &ps->exception_context;
  823. Throw ps;
  824. }
  825. }
  826. static void PNGCBAPI
  827. store_warning(png_structp ppIn, png_const_charp message)
  828. {
  829. png_const_structp pp = ppIn;
  830. png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
  831. if (!ps->expect_warning)
  832. store_log(ps, pp, message, 0 /* warning */);
  833. else
  834. ps->saw_warning = 1;
  835. }
  836. /* These somewhat odd functions are used when reading an image to ensure that
  837. * the buffer is big enough, the png_structp is for errors.
  838. */
  839. /* Return a single row from the correct image. */
  840. static png_bytep
  841. store_image_row(PNG_CONST png_store* ps, png_const_structp pp, int nImage,
  842. png_uint_32 y)
  843. {
  844. png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;
  845. if (ps->image == NULL)
  846. png_error(pp, "no allocated image");
  847. if (coffset + ps->cb_row + 3 > ps->cb_image)
  848. png_error(pp, "image too small");
  849. return ps->image + coffset;
  850. }
  851. static void
  852. store_image_free(png_store *ps, png_const_structp pp)
  853. {
  854. if (ps->image != NULL)
  855. {
  856. png_bytep image = ps->image;
  857. if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
  858. {
  859. if (pp != NULL)
  860. png_error(pp, "png_store image overwrite (1)");
  861. else
  862. store_log(ps, NULL, "png_store image overwrite (2)", 1);
  863. }
  864. ps->image = NULL;
  865. ps->cb_image = 0;
  866. --image;
  867. free(image);
  868. }
  869. }
  870. static void
  871. store_ensure_image(png_store *ps, png_const_structp pp, int nImages,
  872. png_size_t cbRow, png_uint_32 cRows)
  873. {
  874. png_size_t cb = nImages * cRows * (cbRow + 5);
  875. if (ps->cb_image < cb)
  876. {
  877. png_bytep image;
  878. store_image_free(ps, pp);
  879. /* The buffer is deliberately mis-aligned. */
  880. image = voidcast(png_bytep, malloc(cb+2));
  881. if (image == NULL)
  882. {
  883. /* Called from the startup - ignore the error for the moment. */
  884. if (pp == NULL)
  885. return;
  886. png_error(pp, "OOM allocating image buffer");
  887. }
  888. /* These magic tags are used to detect overwrites above. */
  889. ++image;
  890. image[-1] = 0xed;
  891. image[cb] = 0xfe;
  892. ps->image = image;
  893. ps->cb_image = cb;
  894. }
  895. /* We have an adequate sized image; lay out the rows. There are 2 bytes at
  896. * the start and three at the end of each (this ensures that the row
  897. * alignment starts out odd - 2+1 and changes for larger images on each row.)
  898. */
  899. ps->cb_row = cbRow;
  900. ps->image_h = cRows;
  901. /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178).
  902. * This deliberately doesn't match the bits in the size test image which are
  903. * outside the image; these are set to 0xff (all 1). To make the row
  904. * comparison work in the 'size' test case the size rows are pre-initialized
  905. * to the same value prior to calling 'standard_row'.
  906. */
  907. memset(ps->image, 178, cb);
  908. /* Then put in the marks. */
  909. while (--nImages >= 0)
  910. {
  911. png_uint_32 y;
  912. for (y=0; y<cRows; ++y)
  913. {
  914. png_bytep row = store_image_row(ps, pp, nImages, y);
  915. /* The markers: */
  916. row[-2] = 190;
  917. row[-1] = 239;
  918. row[cbRow] = 222;
  919. row[cbRow+1] = 173;
  920. row[cbRow+2] = 17;
  921. }
  922. }
  923. }
  924. #ifdef PNG_READ_SUPPORTED
  925. static void
  926. store_image_check(PNG_CONST png_store* ps, png_const_structp pp, int iImage)
  927. {
  928. png_const_bytep image = ps->image;
  929. if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
  930. png_error(pp, "image overwrite");
  931. else
  932. {
  933. png_size_t cbRow = ps->cb_row;
  934. png_uint_32 rows = ps->image_h;
  935. image += iImage * (cbRow+5) * ps->image_h;
  936. image += 2; /* skip image first row markers */
  937. while (rows-- > 0)
  938. {
  939. if (image[-2] != 190 || image[-1] != 239)
  940. png_error(pp, "row start overwritten");
  941. if (image[cbRow] != 222 || image[cbRow+1] != 173 ||
  942. image[cbRow+2] != 17)
  943. png_error(pp, "row end overwritten");
  944. image += cbRow+5;
  945. }
  946. }
  947. }
  948. #endif /* PNG_READ_SUPPORTED */
  949. static void PNGCBAPI
  950. store_write(png_structp ppIn, png_bytep pb, png_size_t st)
  951. {
  952. png_const_structp pp = ppIn;
  953. png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
  954. if (ps->pwrite != pp)
  955. png_error(pp, "store state damaged");
  956. while (st > 0)
  957. {
  958. size_t cb;
  959. if (ps->writepos >= STORE_BUFFER_SIZE)
  960. store_storenew(ps);
  961. cb = st;
  962. if (cb > STORE_BUFFER_SIZE - ps->writepos)
  963. cb = STORE_BUFFER_SIZE - ps->writepos;
  964. memcpy(ps->new.buffer + ps->writepos, pb, cb);
  965. pb += cb;
  966. st -= cb;
  967. ps->writepos += cb;
  968. }
  969. }
  970. static void PNGCBAPI
  971. store_flush(png_structp ppIn)
  972. {
  973. UNUSED(ppIn) /*DOES NOTHING*/
  974. }
  975. #ifdef PNG_READ_SUPPORTED
  976. static size_t
  977. store_read_buffer_size(png_store *ps)
  978. {
  979. /* Return the bytes available for read in the current buffer. */
  980. if (ps->next != &ps->current->data)
  981. return STORE_BUFFER_SIZE;
  982. return ps->current->datacount;
  983. }
  984. #ifdef PNG_READ_TRANSFORMS_SUPPORTED
  985. /* Return total bytes available for read. */
  986. static size_t
  987. store_read_buffer_avail(png_store *ps)
  988. {
  989. if (ps->current != NULL && ps->next != NULL)
  990. {
  991. png_store_buffer *next = &ps->current->data;
  992. size_t cbAvail = ps->current->datacount;
  993. while (next != ps->next && next != NULL)
  994. {
  995. next = next->prev;
  996. cbAvail += STORE_BUFFER_SIZE;
  997. }
  998. if (next != ps->next)
  999. png_error(ps->pread, "buffer read error");
  1000. if (cbAvail > ps->readpos)
  1001. return cbAvail - ps->readpos;
  1002. }
  1003. return 0;
  1004. }
  1005. #endif
  1006. static int
  1007. store_read_buffer_next(png_store *ps)
  1008. {
  1009. png_store_buffer *pbOld = ps->next;
  1010. png_store_buffer *pbNew = &ps->current->data;
  1011. if (pbOld != pbNew)
  1012. {
  1013. while (pbNew != NULL && pbNew->prev != pbOld)
  1014. pbNew = pbNew->prev;
  1015. if (pbNew != NULL)
  1016. {
  1017. ps->next = pbNew;
  1018. ps->readpos = 0;
  1019. return 1;
  1020. }
  1021. png_error(ps->pread, "buffer lost");
  1022. }
  1023. return 0; /* EOF or error */
  1024. }
  1025. /* Need separate implementation and callback to allow use of the same code
  1026. * during progressive read, where the io_ptr is set internally by libpng.
  1027. */
  1028. static void
  1029. store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
  1030. {
  1031. if (ps->current == NULL || ps->next == NULL)
  1032. png_error(ps->pread, "store state damaged");
  1033. while (st > 0)
  1034. {
  1035. size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;
  1036. if (cbAvail > 0)
  1037. {
  1038. if (cbAvail > st) cbAvail = st;
  1039. memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);
  1040. st -= cbAvail;
  1041. pb += cbAvail;
  1042. ps->readpos += cbAvail;
  1043. }
  1044. else if (!store_read_buffer_next(ps))
  1045. png_error(ps->pread, "read beyond end of file");
  1046. }
  1047. }
  1048. static void PNGCBAPI
  1049. store_read(png_structp ppIn, png_bytep pb, png_size_t st)
  1050. {
  1051. png_const_structp pp = ppIn;
  1052. png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
  1053. if (ps == NULL || ps->pread != pp)
  1054. png_error(pp, "bad store read call");
  1055. store_read_imp(ps, pb, st);
  1056. }
  1057. static void
  1058. store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
  1059. {
  1060. /* Notice that a call to store_read will cause this function to fail because
  1061. * readpos will be set.
  1062. */
  1063. if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
  1064. png_error(pp, "store state damaged (progressive)");
  1065. do
  1066. {
  1067. if (ps->readpos != 0)
  1068. png_error(pp, "store_read called during progressive read");
  1069. png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));
  1070. }
  1071. while (store_read_buffer_next(ps));
  1072. }
  1073. #endif /* PNG_READ_SUPPORTED */
  1074. /* The caller must fill this in: */
  1075. static store_palette_entry *
  1076. store_write_palette(png_store *ps, int npalette)
  1077. {
  1078. if (ps->pwrite == NULL)
  1079. store_log(ps, NULL, "attempt to write palette without write stream", 1);
  1080. if (ps->palette != NULL)
  1081. png_error(ps->pwrite, "multiple store_write_palette calls");
  1082. /* This function can only return NULL if called with '0'! */
  1083. if (npalette > 0)
  1084. {
  1085. ps->palette = voidcast(store_palette_entry*, malloc(npalette *
  1086. sizeof *ps->palette));
  1087. if (ps->palette == NULL)
  1088. png_error(ps->pwrite, "store new palette: OOM");
  1089. ps->npalette = npalette;
  1090. }
  1091. return ps->palette;
  1092. }
  1093. #ifdef PNG_READ_SUPPORTED
  1094. static store_palette_entry *
  1095. store_current_palette(png_store *ps, int *npalette)
  1096. {
  1097. /* This is an internal error (the call has been made outside a read
  1098. * operation.)
  1099. */
  1100. if (ps->current == NULL)
  1101. store_log(ps, ps->pread, "no current stream for palette", 1);
  1102. /* The result may be null if there is no palette. */
  1103. *npalette = ps->current->npalette;
  1104. return ps->current->palette;
  1105. }
  1106. #endif /* PNG_READ_SUPPORTED */
  1107. /***************************** MEMORY MANAGEMENT*** ***************************/
  1108. #ifdef PNG_USER_MEM_SUPPORTED
  1109. /* A store_memory is simply the header for an allocated block of memory. The
  1110. * pointer returned to libpng is just after the end of the header block, the
  1111. * allocated memory is followed by a second copy of the 'mark'.
  1112. */
  1113. typedef struct store_memory
  1114. {
  1115. store_pool *pool; /* Originating pool */
  1116. struct store_memory *next; /* Singly linked list */
  1117. png_alloc_size_t size; /* Size of memory allocated */
  1118. png_byte mark[4]; /* ID marker */
  1119. } store_memory;
  1120. /* Handle a fatal error in memory allocation. This calls png_error if the
  1121. * libpng struct is non-NULL, else it outputs a message and returns. This means
  1122. * that a memory problem while libpng is running will abort (png_error) the
  1123. * handling of particular file while one in cleanup (after the destroy of the
  1124. * struct has returned) will simply keep going and free (or attempt to free)
  1125. * all the memory.
  1126. */
  1127. static void
  1128. store_pool_error(png_store *ps, png_const_structp pp, PNG_CONST char *msg)
  1129. {
  1130. if (pp != NULL)
  1131. png_error(pp, msg);
  1132. /* Else we have to do it ourselves. png_error eventually calls store_log,
  1133. * above. store_log accepts a NULL png_structp - it just changes what gets
  1134. * output by store_message.
  1135. */
  1136. store_log(ps, pp, msg, 1 /* error */);
  1137. }
  1138. static void
  1139. store_memory_free(png_const_structp pp, store_pool *pool, store_memory *memory)
  1140. {
  1141. /* Note that pp may be NULL (see store_pool_delete below), the caller has
  1142. * found 'memory' in pool->list *and* unlinked this entry, so this is a valid
  1143. * pointer (for sure), but the contents may have been trashed.
  1144. */
  1145. if (memory->pool != pool)
  1146. store_pool_error(pool->store, pp, "memory corrupted (pool)");
  1147. else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)
  1148. store_pool_error(pool->store, pp, "memory corrupted (start)");
  1149. /* It should be safe to read the size field now. */
  1150. else
  1151. {
  1152. png_alloc_size_t cb = memory->size;
  1153. if (cb > pool->max)
  1154. store_pool_error(pool->store, pp, "memory corrupted (size)");
  1155. else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)
  1156. != 0)
  1157. store_pool_error(pool->store, pp, "memory corrupted (end)");
  1158. /* Finally give the library a chance to find problems too: */
  1159. else
  1160. {
  1161. pool->current -= cb;
  1162. free(memory);
  1163. }
  1164. }
  1165. }
  1166. static void
  1167. store_pool_delete(png_store *ps, store_pool *pool)
  1168. {
  1169. if (pool->list != NULL)
  1170. {
  1171. fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test,
  1172. pool == &ps->read_memory_pool ? "read" : "write",
  1173. pool == &ps->read_memory_pool ? (ps->current != NULL ?
  1174. ps->current->name : "unknown file") : ps->wname);
  1175. ++ps->nerrors;
  1176. do
  1177. {
  1178. store_memory *next = pool->list;
  1179. pool->list = next->next;
  1180. next->next = NULL;
  1181. fprintf(stderr, "\t%lu bytes @ %p\n",
  1182. (unsigned long)next->size, (PNG_CONST void*)(next+1));
  1183. /* The NULL means this will always return, even if the memory is
  1184. * corrupted.
  1185. */
  1186. store_memory_free(NULL, pool, next);
  1187. }
  1188. while (pool->list != NULL);
  1189. }
  1190. /* And reset the other fields too for the next time. */
  1191. if (pool->max > pool->max_max) pool->max_max = pool->max;
  1192. pool->max = 0;
  1193. if (pool->current != 0) /* unexpected internal error */
  1194. fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n",
  1195. ps->test, pool == &ps->read_memory_pool ? "read" : "write",
  1196. pool == &ps->read_memory_pool ? (ps->current != NULL ?
  1197. ps->current->name : "unknown file") : ps->wname);
  1198. pool->current = 0;
  1199. if (pool->limit > pool->max_limit)
  1200. pool->max_limit = pool->limit;
  1201. pool->limit = 0;
  1202. if (pool->total > pool->max_total)
  1203. pool->max_total = pool->total;
  1204. pool->total = 0;
  1205. /* Get a new mark too. */
  1206. store_pool_mark(pool->mark);
  1207. }
  1208. /* The memory callbacks: */
  1209. static png_voidp PNGCBAPI
  1210. store_malloc(png_structp ppIn, png_alloc_size_t cb)
  1211. {
  1212. png_const_structp pp = ppIn;
  1213. store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
  1214. store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) +
  1215. (sizeof pool->mark)));
  1216. if (new != NULL)
  1217. {
  1218. if (cb > pool->max)
  1219. pool->max = cb;
  1220. pool->current += cb;
  1221. if (pool->current > pool->limit)
  1222. pool->limit = pool->current;
  1223. pool->total += cb;
  1224. new->size = cb;
  1225. memcpy(new->mark, pool->mark, sizeof new->mark);
  1226. memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);
  1227. new->pool = pool;
  1228. new->next = pool->list;
  1229. pool->list = new;
  1230. ++new;
  1231. }
  1232. else
  1233. {
  1234. /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed
  1235. * other than to retrieve the allocation pointer! libpng calls the
  1236. * store_malloc callback in two basic cases:
  1237. *
  1238. * 1) From png_malloc; png_malloc will do a png_error itself if NULL is
  1239. * returned.
  1240. * 2) From png_struct or png_info structure creation; png_malloc is
  1241. * to return so cleanup can be performed.
  1242. *
  1243. * To handle this store_malloc can log a message, but can't do anything
  1244. * else.
  1245. */
  1246. store_log(pool->store, pp, "out of memory", 1 /* is_error */);
  1247. }
  1248. return new;
  1249. }
  1250. static void PNGCBAPI
  1251. store_free(png_structp ppIn, png_voidp memory)
  1252. {
  1253. png_const_structp pp = ppIn;
  1254. store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
  1255. store_memory *this = voidcast(store_memory*, memory), **test;
  1256. /* Because libpng calls store_free with a dummy png_struct when deleting
  1257. * png_struct or png_info via png_destroy_struct_2 it is necessary to check
  1258. * the passed in png_structp to ensure it is valid, and not pass it to
  1259. * png_error if it is not.
  1260. */
  1261. if (pp != pool->store->pread && pp != pool->store->pwrite)
  1262. pp = NULL;
  1263. /* First check that this 'memory' really is valid memory - it must be in the
  1264. * pool list. If it is, use the shared memory_free function to free it.
  1265. */
  1266. --this;
  1267. for (test = &pool->list; *test != this; test = &(*test)->next)
  1268. {
  1269. if (*test == NULL)
  1270. {
  1271. store_pool_error(pool->store, pp, "bad pointer to free");
  1272. return;
  1273. }
  1274. }
  1275. /* Unlink this entry, *test == this. */
  1276. *test = this->next;
  1277. this->next = NULL;
  1278. store_memory_free(pp, pool, this);
  1279. }
  1280. #endif /* PNG_USER_MEM_SUPPORTED */
  1281. /* Setup functions. */
  1282. /* Cleanup when aborting a write or after storing the new file. */
  1283. static void
  1284. store_write_reset(png_store *ps)
  1285. {
  1286. if (ps->pwrite != NULL)
  1287. {
  1288. anon_context(ps);
  1289. Try
  1290. png_destroy_write_struct(&ps->pwrite, &ps->piwrite);
  1291. Catch_anonymous
  1292. {
  1293. /* memory corruption: continue. */
  1294. }
  1295. ps->pwrite = NULL;
  1296. ps->piwrite = NULL;
  1297. }
  1298. /* And make sure that all the memory has been freed - this will output
  1299. * spurious errors in the case of memory corruption above, but this is safe.
  1300. */
  1301. # ifdef PNG_USER_MEM_SUPPORTED
  1302. store_pool_delete(ps, &ps->write_memory_pool);
  1303. # endif
  1304. store_freenew(ps);
  1305. }
  1306. /* The following is the main write function, it returns a png_struct and,
  1307. * optionally, a png_info suitable for writiing a new PNG file. Use
  1308. * store_storefile above to record this file after it has been written. The
  1309. * returned libpng structures as destroyed by store_write_reset above.
  1310. */
  1311. static png_structp
  1312. set_store_for_write(png_store *ps, png_infopp ppi,
  1313. PNG_CONST char * volatile name)
  1314. {
  1315. anon_context(ps);
  1316. Try
  1317. {
  1318. if (ps->pwrite != NULL)
  1319. png_error(ps->pwrite, "write store already in use");
  1320. store_write_reset(ps);
  1321. safecat(ps->wname, sizeof ps->wname, 0, name);
  1322. /* Don't do the slow memory checks if doing a speed test, also if user
  1323. * memory is not supported we can't do it anyway.
  1324. */
  1325. # ifdef PNG_USER_MEM_SUPPORTED
  1326. if (!ps->speed)
  1327. ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
  1328. ps, store_error, store_warning, &ps->write_memory_pool,
  1329. store_malloc, store_free);
  1330. else
  1331. # endif
  1332. ps->pwrite = png_create_write_struct(png_get_libpng_ver(NULL),
  1333. ps, store_error, store_warning);
  1334. png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
  1335. # ifdef PNG_SET_OPTION_SUPPORTED
  1336. {
  1337. int opt;
  1338. for (opt=0; opt<ps->noptions; ++opt)
  1339. if (png_set_option(ps->pwrite, ps->options[opt].option,
  1340. ps->options[opt].setting) == PNG_OPTION_INVALID)
  1341. png_error(ps->pwrite, "png option invalid");
  1342. }
  1343. # endif
  1344. if (ppi != NULL)
  1345. *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);
  1346. }
  1347. Catch_anonymous
  1348. return NULL;
  1349. return ps->pwrite;
  1350. }
  1351. /* Cleanup when finished reading (either due to error or in the success case).
  1352. * This routine exists even when there is no read support to make the code
  1353. * tidier (avoid a mass of ifdefs) and so easier to maintain.
  1354. */
  1355. static void
  1356. store_read_reset(png_store *ps)
  1357. {
  1358. # ifdef PNG_READ_SUPPORTED
  1359. if (ps->pread != NULL)
  1360. {
  1361. anon_context(ps);
  1362. Try
  1363. png_destroy_read_struct(&ps->pread, &ps->piread, NULL);
  1364. Catch_anonymous
  1365. {
  1366. /* error already output: continue */
  1367. }
  1368. ps->pread = NULL;
  1369. ps->piread = NULL;
  1370. }
  1371. # endif
  1372. # ifdef PNG_USER_MEM_SUPPORTED
  1373. /* Always do this to be safe. */
  1374. store_pool_delete(ps, &ps->read_memory_pool);
  1375. # endif
  1376. ps->current = NULL;
  1377. ps->next = NULL;
  1378. ps->readpos = 0;
  1379. ps->validated = 0;
  1380. }
  1381. #ifdef PNG_READ_SUPPORTED
  1382. static void
  1383. store_read_set(png_store *ps, png_uint_32 id)
  1384. {
  1385. png_store_file *pf = ps->saved;
  1386. while (pf != NULL)
  1387. {
  1388. if (pf->id == id)
  1389. {
  1390. ps->current = pf;
  1391. ps->next = NULL;
  1392. store_read_buffer_next(ps);
  1393. return;
  1394. }
  1395. pf = pf->next;
  1396. }
  1397. {
  1398. size_t pos;
  1399. char msg[FILE_NAME_SIZE+64];
  1400. pos = standard_name_from_id(msg, sizeof msg, 0, id);
  1401. pos = safecat(msg, sizeof msg, pos, ": file not found");
  1402. png_error(ps->pread, msg);
  1403. }
  1404. }
  1405. /* The main interface for reading a saved file - pass the id number of the file
  1406. * to retrieve. Ids must be unique or the earlier file will be hidden. The API
  1407. * returns a png_struct and, optionally, a png_info. Both of these will be
  1408. * destroyed by store_read_reset above.
  1409. */
  1410. static png_structp
  1411. set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,
  1412. PNG_CONST char *name)
  1413. {
  1414. /* Set the name for png_error */
  1415. safecat(ps->test, sizeof ps->test, 0, name);
  1416. if (ps->pread != NULL)
  1417. png_error(ps->pread, "read store already in use");
  1418. store_read_reset(ps);
  1419. /* Both the create APIs can return NULL if used in their default mode
  1420. * (because there is no other way of handling an error because the jmp_buf
  1421. * by default is stored in png_struct and that has not been allocated!)
  1422. * However, given that store_error works correctly in these circumstances
  1423. * we don't ever expect NULL in this program.
  1424. */
  1425. # ifdef PNG_USER_MEM_SUPPORTED
  1426. if (!ps->speed)
  1427. ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,
  1428. store_error, store_warning, &ps->read_memory_pool, store_malloc,
  1429. store_free);
  1430. else
  1431. # endif
  1432. ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, store_error,
  1433. store_warning);
  1434. if (ps->pread == NULL)
  1435. {
  1436. struct exception_context *the_exception_context = &ps->exception_context;
  1437. store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)",
  1438. 1 /*error*/);
  1439. Throw ps;
  1440. }
  1441. # ifdef PNG_SET_OPTION_SUPPORTED
  1442. {
  1443. int opt;
  1444. for (opt=0; opt<ps->noptions; ++opt)
  1445. if (png_set_option(ps->pread, ps->options[opt].option,
  1446. ps->options[opt].setting) == PNG_OPTION_INVALID)
  1447. png_error(ps->pread, "png option invalid");
  1448. }
  1449. # endif
  1450. store_read_set(ps, id);
  1451. if (ppi != NULL)
  1452. *ppi = ps->piread = png_create_info_struct(ps->pread);
  1453. return ps->pread;
  1454. }
  1455. #endif /* PNG_READ_SUPPORTED */
  1456. /* The overall cleanup of a store simply calls the above then removes all the
  1457. * saved files. This does not delete the store itself.
  1458. */
  1459. static void
  1460. store_delete(png_store *ps)
  1461. {
  1462. store_write_reset(ps);
  1463. store_read_reset(ps);
  1464. store_freefile(&ps->saved);
  1465. store_image_free(ps, NULL);
  1466. }
  1467. /*********************** PNG FILE MODIFICATION ON READ ************************/
  1468. /* Files may be modified on read. The following structure contains a complete
  1469. * png_store together with extra members to handle modification and a special
  1470. * read callback for libpng. To use this the 'modifications' field must be set
  1471. * to a list of png_modification structures that actually perform the
  1472. * modification, otherwise a png_modifier is functionally equivalent to a
  1473. * png_store. There is a special read function, set_modifier_for_read, which
  1474. * replaces set_store_for_read.
  1475. */
  1476. typedef enum modifier_state
  1477. {
  1478. modifier_start, /* Initial value */
  1479. modifier_signature, /* Have a signature */
  1480. modifier_IHDR /* Have an IHDR */
  1481. } modifier_state;
  1482. typedef struct CIE_color
  1483. {
  1484. /* A single CIE tristimulus value, representing the unique response of a
  1485. * standard observer to a variety of light spectra. The observer recognizes
  1486. * all spectra that produce this response as the same color, therefore this
  1487. * is effectively a description of a color.
  1488. */

Large files files are truncated, but you can click here to view the full file