PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/compiler/android/jni/ftk/pngrutil.c

http://ftk.googlecode.com/
C | 2274 lines | 1849 code | 285 blank | 140 comment | 404 complexity | 6dd551fbad69fa49ae32c4118455856f MD5 | raw file
Possible License(s): LGPL-3.0
  1. /* pngrutil.c - utilities to read a PNG file
  2. *
  3. * Last changed in libpng 1.2.44 [June 26, 2010]
  4. * Copyright (c) 1998-2010 Glenn Randers-Pehrson
  5. * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  6. * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  7. *
  8. * This code is released under the libpng license.
  9. * For conditions of distribution and use, see the disclaimer
  10. * and license in png.h
  11. *
  12. * This file contains routines that are only called from within
  13. * libpng itself during the course of reading an image.
  14. */
  15. #define PNG_INTERNAL
  16. #define PNG_NO_PEDANTIC_WARNINGS
  17. #include "png.h"
  18. #ifdef PNG_READ_SUPPORTED
  19. #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
  20. # define WIN32_WCE_OLD
  21. #endif
  22. #ifdef PNG_FLOATING_POINT_SUPPORTED
  23. # ifdef WIN32_WCE_OLD
  24. /* The strtod() function is not supported on WindowsCE */
  25. __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
  26. char **endptr)
  27. {
  28. double result = 0;
  29. int len;
  30. wchar_t *str, *end;
  31. len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
  32. str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
  33. if ( NULL != str )
  34. {
  35. MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
  36. result = wcstod(str, &end);
  37. len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
  38. *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
  39. png_free(png_ptr, str);
  40. }
  41. return result;
  42. }
  43. # else
  44. # define png_strtod(p,a,b) strtod(a,b)
  45. # endif
  46. #endif
  47. png_uint_32 PNGAPI
  48. png_get_uint_31(png_structp png_ptr, png_bytep buf)
  49. {
  50. #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
  51. png_uint_32 i = png_get_uint_32(buf);
  52. #else
  53. /* Avoid an extra function call by inlining the result. */
  54. png_uint_32 i = ((png_uint_32)(*buf) << 24) +
  55. ((png_uint_32)(*(buf + 1)) << 16) +
  56. ((png_uint_32)(*(buf + 2)) << 8) +
  57. (png_uint_32)(*(buf + 3));
  58. #endif
  59. if (i > PNG_UINT_31_MAX)
  60. png_error(png_ptr, "PNG unsigned integer out of range.");
  61. return (i);
  62. }
  63. #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
  64. /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
  65. png_uint_32 PNGAPI
  66. png_get_uint_32(png_bytep buf)
  67. {
  68. png_uint_32 i = ((png_uint_32)(*buf) << 24) +
  69. ((png_uint_32)(*(buf + 1)) << 16) +
  70. ((png_uint_32)(*(buf + 2)) << 8) +
  71. (png_uint_32)(*(buf + 3));
  72. return (i);
  73. }
  74. /* Grab a signed 32-bit integer from a buffer in big-endian format. The
  75. * data is stored in the PNG file in two's complement format, and it is
  76. * assumed that the machine format for signed integers is the same.
  77. */
  78. png_int_32 PNGAPI
  79. png_get_int_32(png_bytep buf)
  80. {
  81. png_int_32 i = ((png_int_32)(*buf) << 24) +
  82. ((png_int_32)(*(buf + 1)) << 16) +
  83. ((png_int_32)(*(buf + 2)) << 8) +
  84. (png_int_32)(*(buf + 3));
  85. return (i);
  86. }
  87. /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
  88. png_uint_16 PNGAPI
  89. png_get_uint_16(png_bytep buf)
  90. {
  91. png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
  92. (png_uint_16)(*(buf + 1)));
  93. return (i);
  94. }
  95. #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
  96. /* Read the chunk header (length + type name).
  97. * Put the type name into png_ptr->chunk_name, and return the length.
  98. */
  99. png_uint_32 /* PRIVATE */
  100. png_read_chunk_header(png_structp png_ptr)
  101. {
  102. png_byte buf[8];
  103. png_uint_32 length;
  104. /* Read the length and the chunk name */
  105. png_read_data(png_ptr, buf, 8);
  106. length = png_get_uint_31(png_ptr, buf);
  107. /* Put the chunk name into png_ptr->chunk_name */
  108. png_memcpy(png_ptr->chunk_name, buf + 4, 4);
  109. png_debug2(0, "Reading %s chunk, length = %lu",
  110. png_ptr->chunk_name, length);
  111. /* Reset the crc and run it over the chunk name */
  112. png_reset_crc(png_ptr);
  113. png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
  114. /* Check to see if chunk name is valid */
  115. png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  116. return length;
  117. }
  118. /* Read data, and (optionally) run it through the CRC. */
  119. void /* PRIVATE */
  120. png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
  121. {
  122. if (png_ptr == NULL)
  123. return;
  124. png_read_data(png_ptr, buf, length);
  125. png_calculate_crc(png_ptr, buf, length);
  126. }
  127. #ifdef PNG_INDEX_SUPPORTED
  128. /* Optionally skip data and then check the CRC. Depending on whether we
  129. * are reading a ancillary or critical chunk, and how the program has set
  130. * things up, we may calculate the CRC on the data and print a message.
  131. * Returns '1' if there was a CRC error, '0' otherwise.
  132. */
  133. int /* PRIVATE */
  134. png_opt_crc_finish(png_structp png_ptr, png_uint_32 skip, int check_crc)
  135. {
  136. png_size_t i;
  137. png_size_t istop = png_ptr->zbuf_size;
  138. for (i = (png_size_t)skip; i > istop; i -= istop)
  139. {
  140. png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  141. }
  142. if (i)
  143. {
  144. png_crc_read(png_ptr, png_ptr->zbuf, i);
  145. }
  146. if (png_crc_error(png_ptr))
  147. {
  148. if (!check_crc) {
  149. png_chunk_warning(png_ptr, "CRC error");
  150. return (1);
  151. }
  152. if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
  153. !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
  154. (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
  155. (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
  156. {
  157. png_chunk_warning(png_ptr, "CRC error");
  158. }
  159. else
  160. {
  161. png_chunk_error(png_ptr, "CRC error");
  162. }
  163. return (1);
  164. }
  165. return (0);
  166. }
  167. #endif
  168. /* Optionally skip data and then check the CRC. Depending on whether we
  169. * are reading a ancillary or critical chunk, and how the program has set
  170. * things up, we may calculate the CRC on the data and print a message.
  171. * Returns '1' if there was a CRC error, '0' otherwise.
  172. */
  173. int /* PRIVATE */
  174. png_crc_finish(png_structp png_ptr, png_uint_32 skip)
  175. {
  176. return png_opt_crc_finish(png_ptr, skip, 1);
  177. }
  178. /* Compare the CRC stored in the PNG file with that calculated by libpng from
  179. * the data it has read thus far.
  180. */
  181. int /* PRIVATE */
  182. png_crc_error(png_structp png_ptr)
  183. {
  184. png_byte crc_bytes[4];
  185. png_uint_32 crc;
  186. int need_crc = 1;
  187. if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
  188. {
  189. if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
  190. (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
  191. need_crc = 0;
  192. }
  193. else /* critical */
  194. {
  195. if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
  196. need_crc = 0;
  197. }
  198. png_read_data(png_ptr, crc_bytes, 4);
  199. if (need_crc)
  200. {
  201. crc = png_get_uint_32(crc_bytes);
  202. return ((int)(crc != png_ptr->crc));
  203. }
  204. else
  205. return (0);
  206. }
  207. #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
  208. defined(PNG_READ_iCCP_SUPPORTED)
  209. static png_size_t
  210. png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
  211. png_bytep output, png_size_t output_size)
  212. {
  213. png_size_t count = 0;
  214. png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
  215. png_ptr->zstream.avail_in = size;
  216. while (1)
  217. {
  218. int ret, avail;
  219. /* Reset the output buffer each time round - we empty it
  220. * after every inflate call.
  221. */
  222. png_ptr->zstream.next_out = png_ptr->zbuf;
  223. png_ptr->zstream.avail_out = png_ptr->zbuf_size;
  224. ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
  225. avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  226. /* First copy/count any new output - but only if we didn't
  227. * get an error code.
  228. */
  229. if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
  230. {
  231. if (output != 0 && output_size > count)
  232. {
  233. int copy = output_size - count;
  234. if (avail < copy) copy = avail;
  235. png_memcpy(output + count, png_ptr->zbuf, copy);
  236. }
  237. count += avail;
  238. }
  239. if (ret == Z_OK)
  240. continue;
  241. /* Termination conditions - always reset the zstream, it
  242. * must be left in inflateInit state.
  243. */
  244. png_ptr->zstream.avail_in = 0;
  245. inflateReset(&png_ptr->zstream);
  246. if (ret == Z_STREAM_END)
  247. return count; /* NOTE: may be zero. */
  248. /* Now handle the error codes - the API always returns 0
  249. * and the error message is dumped into the uncompressed
  250. * buffer if available.
  251. */
  252. {
  253. PNG_CONST char *msg;
  254. if (png_ptr->zstream.msg != 0)
  255. msg = png_ptr->zstream.msg;
  256. else
  257. {
  258. #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
  259. char umsg[52];
  260. switch (ret)
  261. {
  262. case Z_BUF_ERROR:
  263. msg = "Buffer error in compressed datastream in %s chunk";
  264. break;
  265. case Z_DATA_ERROR:
  266. msg = "Data error in compressed datastream in %s chunk";
  267. break;
  268. default:
  269. msg = "Incomplete compressed datastream in %s chunk";
  270. break;
  271. }
  272. png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
  273. msg = umsg;
  274. #else
  275. msg = "Damaged compressed datastream in chunk other than IDAT";
  276. #endif
  277. }
  278. png_warning(png_ptr, msg);
  279. }
  280. /* 0 means an error - notice that this code simple ignores
  281. * zero length compressed chunks as a result.
  282. */
  283. return 0;
  284. }
  285. }
  286. /*
  287. * Decompress trailing data in a chunk. The assumption is that chunkdata
  288. * points at an allocated area holding the contents of a chunk with a
  289. * trailing compressed part. What we get back is an allocated area
  290. * holding the original prefix part and an uncompressed version of the
  291. * trailing part (the malloc area passed in is freed).
  292. */
  293. void /* PRIVATE */
  294. png_decompress_chunk(png_structp png_ptr, int comp_type,
  295. png_size_t chunklength,
  296. png_size_t prefix_size, png_size_t *newlength)
  297. {
  298. /* The caller should guarantee this */
  299. if (prefix_size > chunklength)
  300. {
  301. /* The recovery is to delete the chunk. */
  302. png_warning(png_ptr, "invalid chunklength");
  303. prefix_size = 0; /* To delete everything */
  304. }
  305. else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
  306. {
  307. png_size_t expanded_size = png_inflate(png_ptr,
  308. (png_bytep)(png_ptr->chunkdata + prefix_size),
  309. chunklength - prefix_size,
  310. 0/*output*/, 0/*output size*/);
  311. /* Now check the limits on this chunk - if the limit fails the
  312. * compressed data will be removed, the prefix will remain.
  313. */
  314. #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
  315. if (png_ptr->user_chunk_malloc_max &&
  316. (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
  317. #else
  318. # ifdef PNG_USER_CHUNK_MALLOC_MAX
  319. if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
  320. prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
  321. # endif
  322. #endif
  323. png_warning(png_ptr, "Exceeded size limit while expanding chunk");
  324. /* If the size is zero either there was an error and a message
  325. * has already been output (warning) or the size really is zero
  326. * and we have nothing to do - the code will exit through the
  327. * error case below.
  328. */
  329. #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
  330. defined(PNG_USER_CHUNK_MALLOC_MAX)
  331. else
  332. #endif
  333. if (expanded_size > 0)
  334. {
  335. /* Success (maybe) - really uncompress the chunk. */
  336. png_size_t new_size = 0;
  337. png_charp text = png_malloc_warn(png_ptr,
  338. prefix_size + expanded_size + 1);
  339. if (text != NULL)
  340. {
  341. png_memcpy(text, png_ptr->chunkdata, prefix_size);
  342. new_size = png_inflate(png_ptr,
  343. (png_bytep)(png_ptr->chunkdata + prefix_size),
  344. chunklength - prefix_size,
  345. (png_bytep)(text + prefix_size), expanded_size);
  346. text[prefix_size + expanded_size] = 0; /* just in case */
  347. if (new_size == expanded_size)
  348. {
  349. png_free(png_ptr, png_ptr->chunkdata);
  350. png_ptr->chunkdata = text;
  351. *newlength = prefix_size + expanded_size;
  352. return; /* The success return! */
  353. }
  354. png_warning(png_ptr, "png_inflate logic error");
  355. png_free(png_ptr, text);
  356. }
  357. else
  358. png_warning(png_ptr, "Not enough memory to decompress chunk.");
  359. }
  360. }
  361. else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
  362. {
  363. #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
  364. char umsg[50];
  365. png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
  366. comp_type);
  367. png_warning(png_ptr, umsg);
  368. #else
  369. png_warning(png_ptr, "Unknown zTXt compression type");
  370. #endif
  371. /* The recovery is to simply drop the data. */
  372. }
  373. /* Generic error return - leave the prefix, delete the compressed
  374. * data, reallocate the chunkdata to remove the potentially large
  375. * amount of compressed data.
  376. */
  377. {
  378. png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
  379. if (text != NULL)
  380. {
  381. if (prefix_size > 0)
  382. png_memcpy(text, png_ptr->chunkdata, prefix_size);
  383. png_free(png_ptr, png_ptr->chunkdata);
  384. png_ptr->chunkdata = text;
  385. /* This is an extra zero in the 'uncompressed' part. */
  386. *(png_ptr->chunkdata + prefix_size) = 0x00;
  387. }
  388. /* Ignore a malloc error here - it is safe. */
  389. }
  390. *newlength = prefix_size;
  391. }
  392. #endif
  393. /* Read and check the IDHR chunk */
  394. void /* PRIVATE */
  395. png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  396. {
  397. png_byte buf[13];
  398. png_uint_32 width, height;
  399. int bit_depth, color_type, compression_type, filter_type;
  400. int interlace_type;
  401. png_debug(1, "in png_handle_IHDR");
  402. if (png_ptr->mode & PNG_HAVE_IHDR)
  403. png_error(png_ptr, "Out of place IHDR");
  404. /* Check the length */
  405. if (length != 13)
  406. png_error(png_ptr, "Invalid IHDR chunk");
  407. png_ptr->mode |= PNG_HAVE_IHDR;
  408. png_crc_read(png_ptr, buf, 13);
  409. png_crc_finish(png_ptr, 0);
  410. width = png_get_uint_31(png_ptr, buf);
  411. height = png_get_uint_31(png_ptr, buf + 4);
  412. bit_depth = buf[8];
  413. color_type = buf[9];
  414. compression_type = buf[10];
  415. filter_type = buf[11];
  416. interlace_type = buf[12];
  417. /* Set internal variables */
  418. png_ptr->width = width;
  419. png_ptr->height = height;
  420. png_ptr->bit_depth = (png_byte)bit_depth;
  421. png_ptr->interlaced = (png_byte)interlace_type;
  422. png_ptr->color_type = (png_byte)color_type;
  423. #ifdef PNG_MNG_FEATURES_SUPPORTED
  424. png_ptr->filter_type = (png_byte)filter_type;
  425. #endif
  426. png_ptr->compression_type = (png_byte)compression_type;
  427. /* Find number of channels */
  428. switch (png_ptr->color_type)
  429. {
  430. case PNG_COLOR_TYPE_GRAY:
  431. case PNG_COLOR_TYPE_PALETTE:
  432. png_ptr->channels = 1;
  433. break;
  434. case PNG_COLOR_TYPE_RGB:
  435. png_ptr->channels = 3;
  436. break;
  437. case PNG_COLOR_TYPE_GRAY_ALPHA:
  438. png_ptr->channels = 2;
  439. break;
  440. case PNG_COLOR_TYPE_RGB_ALPHA:
  441. png_ptr->channels = 4;
  442. break;
  443. }
  444. /* Set up other useful info */
  445. png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
  446. png_ptr->channels);
  447. png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
  448. png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
  449. png_debug1(3, "channels = %d", png_ptr->channels);
  450. png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
  451. png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
  452. color_type, interlace_type, compression_type, filter_type);
  453. }
  454. /* Read and check the palette */
  455. void /* PRIVATE */
  456. png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  457. {
  458. png_color palette[PNG_MAX_PALETTE_LENGTH];
  459. int num, i;
  460. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  461. png_colorp pal_ptr;
  462. #endif
  463. png_debug(1, "in png_handle_PLTE");
  464. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  465. png_error(png_ptr, "Missing IHDR before PLTE");
  466. else if (png_ptr->mode & PNG_HAVE_IDAT)
  467. {
  468. png_warning(png_ptr, "Invalid PLTE after IDAT");
  469. png_crc_finish(png_ptr, length);
  470. return;
  471. }
  472. else if (png_ptr->mode & PNG_HAVE_PLTE)
  473. png_error(png_ptr, "Duplicate PLTE chunk");
  474. png_ptr->mode |= PNG_HAVE_PLTE;
  475. if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
  476. {
  477. png_warning(png_ptr,
  478. "Ignoring PLTE chunk in grayscale PNG");
  479. png_crc_finish(png_ptr, length);
  480. return;
  481. }
  482. #ifndef PNG_READ_OPT_PLTE_SUPPORTED
  483. if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  484. {
  485. png_crc_finish(png_ptr, length);
  486. return;
  487. }
  488. #endif
  489. if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
  490. {
  491. if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  492. {
  493. png_warning(png_ptr, "Invalid palette chunk");
  494. png_crc_finish(png_ptr, length);
  495. return;
  496. }
  497. else
  498. {
  499. png_error(png_ptr, "Invalid palette chunk");
  500. }
  501. }
  502. num = (int)length / 3;
  503. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  504. for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
  505. {
  506. png_byte buf[3];
  507. png_crc_read(png_ptr, buf, 3);
  508. pal_ptr->red = buf[0];
  509. pal_ptr->green = buf[1];
  510. pal_ptr->blue = buf[2];
  511. }
  512. #else
  513. for (i = 0; i < num; i++)
  514. {
  515. png_byte buf[3];
  516. png_crc_read(png_ptr, buf, 3);
  517. /* Don't depend upon png_color being any order */
  518. palette[i].red = buf[0];
  519. palette[i].green = buf[1];
  520. palette[i].blue = buf[2];
  521. }
  522. #endif
  523. /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
  524. * whatever the normal CRC configuration tells us. However, if we
  525. * have an RGB image, the PLTE can be considered ancillary, so
  526. * we will act as though it is.
  527. */
  528. #ifndef PNG_READ_OPT_PLTE_SUPPORTED
  529. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  530. #endif
  531. {
  532. png_crc_finish(png_ptr, 0);
  533. }
  534. #ifndef PNG_READ_OPT_PLTE_SUPPORTED
  535. else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
  536. {
  537. /* If we don't want to use the data from an ancillary chunk,
  538. we have two options: an error abort, or a warning and we
  539. ignore the data in this chunk (which should be OK, since
  540. it's considered ancillary for a RGB or RGBA image). */
  541. if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
  542. {
  543. if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
  544. {
  545. png_chunk_error(png_ptr, "CRC error");
  546. }
  547. else
  548. {
  549. png_chunk_warning(png_ptr, "CRC error");
  550. return;
  551. }
  552. }
  553. /* Otherwise, we (optionally) emit a warning and use the chunk. */
  554. else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
  555. {
  556. png_chunk_warning(png_ptr, "CRC error");
  557. }
  558. }
  559. #endif
  560. png_set_PLTE(png_ptr, info_ptr, palette, num);
  561. #ifdef PNG_READ_tRNS_SUPPORTED
  562. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  563. {
  564. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  565. {
  566. if (png_ptr->num_trans > (png_uint_16)num)
  567. {
  568. png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
  569. png_ptr->num_trans = (png_uint_16)num;
  570. }
  571. if (info_ptr->num_trans > (png_uint_16)num)
  572. {
  573. png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
  574. info_ptr->num_trans = (png_uint_16)num;
  575. }
  576. }
  577. }
  578. #endif
  579. }
  580. void /* PRIVATE */
  581. png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  582. {
  583. png_debug(1, "in png_handle_IEND");
  584. if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
  585. {
  586. png_error(png_ptr, "No image in file");
  587. }
  588. png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
  589. if (length != 0)
  590. {
  591. png_warning(png_ptr, "Incorrect IEND chunk length");
  592. }
  593. png_crc_finish(png_ptr, length);
  594. info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
  595. }
  596. #ifdef PNG_READ_gAMA_SUPPORTED
  597. void /* PRIVATE */
  598. png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  599. {
  600. png_fixed_point igamma;
  601. #ifdef PNG_FLOATING_POINT_SUPPORTED
  602. float file_gamma;
  603. #endif
  604. png_byte buf[4];
  605. png_debug(1, "in png_handle_gAMA");
  606. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  607. png_error(png_ptr, "Missing IHDR before gAMA");
  608. else if (png_ptr->mode & PNG_HAVE_IDAT)
  609. {
  610. png_warning(png_ptr, "Invalid gAMA after IDAT");
  611. png_crc_finish(png_ptr, length);
  612. return;
  613. }
  614. else if (png_ptr->mode & PNG_HAVE_PLTE)
  615. /* Should be an error, but we can cope with it */
  616. png_warning(png_ptr, "Out of place gAMA chunk");
  617. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
  618. #ifdef PNG_READ_sRGB_SUPPORTED
  619. && !(info_ptr->valid & PNG_INFO_sRGB)
  620. #endif
  621. )
  622. {
  623. png_warning(png_ptr, "Duplicate gAMA chunk");
  624. png_crc_finish(png_ptr, length);
  625. return;
  626. }
  627. if (length != 4)
  628. {
  629. png_warning(png_ptr, "Incorrect gAMA chunk length");
  630. png_crc_finish(png_ptr, length);
  631. return;
  632. }
  633. png_crc_read(png_ptr, buf, 4);
  634. if (png_crc_finish(png_ptr, 0))
  635. return;
  636. igamma = (png_fixed_point)png_get_uint_32(buf);
  637. /* Check for zero gamma */
  638. if (igamma == 0)
  639. {
  640. png_warning(png_ptr,
  641. "Ignoring gAMA chunk with gamma=0");
  642. return;
  643. }
  644. #ifdef PNG_READ_sRGB_SUPPORTED
  645. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
  646. if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
  647. {
  648. png_warning(png_ptr,
  649. "Ignoring incorrect gAMA value when sRGB is also present");
  650. #ifdef PNG_CONSOLE_IO_SUPPORTED
  651. fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
  652. #endif
  653. return;
  654. }
  655. #endif /* PNG_READ_sRGB_SUPPORTED */
  656. #ifdef PNG_FLOATING_POINT_SUPPORTED
  657. file_gamma = (float)igamma / (float)100000.0;
  658. # ifdef PNG_READ_GAMMA_SUPPORTED
  659. png_ptr->gamma = file_gamma;
  660. # endif
  661. png_set_gAMA(png_ptr, info_ptr, file_gamma);
  662. #endif
  663. #ifdef PNG_FIXED_POINT_SUPPORTED
  664. png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
  665. #endif
  666. }
  667. #endif
  668. #ifdef PNG_READ_sBIT_SUPPORTED
  669. void /* PRIVATE */
  670. png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  671. {
  672. png_size_t truelen;
  673. png_byte buf[4];
  674. png_debug(1, "in png_handle_sBIT");
  675. buf[0] = buf[1] = buf[2] = buf[3] = 0;
  676. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  677. png_error(png_ptr, "Missing IHDR before sBIT");
  678. else if (png_ptr->mode & PNG_HAVE_IDAT)
  679. {
  680. png_warning(png_ptr, "Invalid sBIT after IDAT");
  681. png_crc_finish(png_ptr, length);
  682. return;
  683. }
  684. else if (png_ptr->mode & PNG_HAVE_PLTE)
  685. {
  686. /* Should be an error, but we can cope with it */
  687. png_warning(png_ptr, "Out of place sBIT chunk");
  688. }
  689. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
  690. {
  691. png_warning(png_ptr, "Duplicate sBIT chunk");
  692. png_crc_finish(png_ptr, length);
  693. return;
  694. }
  695. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  696. truelen = 3;
  697. else
  698. truelen = (png_size_t)png_ptr->channels;
  699. if (length != truelen || length > 4)
  700. {
  701. png_warning(png_ptr, "Incorrect sBIT chunk length");
  702. png_crc_finish(png_ptr, length);
  703. return;
  704. }
  705. png_crc_read(png_ptr, buf, truelen);
  706. if (png_crc_finish(png_ptr, 0))
  707. return;
  708. if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  709. {
  710. png_ptr->sig_bit.red = buf[0];
  711. png_ptr->sig_bit.green = buf[1];
  712. png_ptr->sig_bit.blue = buf[2];
  713. png_ptr->sig_bit.alpha = buf[3];
  714. }
  715. else
  716. {
  717. png_ptr->sig_bit.gray = buf[0];
  718. png_ptr->sig_bit.red = buf[0];
  719. png_ptr->sig_bit.green = buf[0];
  720. png_ptr->sig_bit.blue = buf[0];
  721. png_ptr->sig_bit.alpha = buf[1];
  722. }
  723. png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
  724. }
  725. #endif
  726. #ifdef PNG_READ_cHRM_SUPPORTED
  727. void /* PRIVATE */
  728. png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  729. {
  730. png_byte buf[32];
  731. #ifdef PNG_FLOATING_POINT_SUPPORTED
  732. float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
  733. #endif
  734. png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
  735. int_y_green, int_x_blue, int_y_blue;
  736. png_uint_32 uint_x, uint_y;
  737. png_debug(1, "in png_handle_cHRM");
  738. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  739. png_error(png_ptr, "Missing IHDR before cHRM");
  740. else if (png_ptr->mode & PNG_HAVE_IDAT)
  741. {
  742. png_warning(png_ptr, "Invalid cHRM after IDAT");
  743. png_crc_finish(png_ptr, length);
  744. return;
  745. }
  746. else if (png_ptr->mode & PNG_HAVE_PLTE)
  747. /* Should be an error, but we can cope with it */
  748. png_warning(png_ptr, "Missing PLTE before cHRM");
  749. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
  750. #ifdef PNG_READ_sRGB_SUPPORTED
  751. && !(info_ptr->valid & PNG_INFO_sRGB)
  752. #endif
  753. )
  754. {
  755. png_warning(png_ptr, "Duplicate cHRM chunk");
  756. png_crc_finish(png_ptr, length);
  757. return;
  758. }
  759. if (length != 32)
  760. {
  761. png_warning(png_ptr, "Incorrect cHRM chunk length");
  762. png_crc_finish(png_ptr, length);
  763. return;
  764. }
  765. png_crc_read(png_ptr, buf, 32);
  766. if (png_crc_finish(png_ptr, 0))
  767. return;
  768. uint_x = png_get_uint_32(buf);
  769. uint_y = png_get_uint_32(buf + 4);
  770. int_x_white = (png_fixed_point)uint_x;
  771. int_y_white = (png_fixed_point)uint_y;
  772. uint_x = png_get_uint_32(buf + 8);
  773. uint_y = png_get_uint_32(buf + 12);
  774. int_x_red = (png_fixed_point)uint_x;
  775. int_y_red = (png_fixed_point)uint_y;
  776. uint_x = png_get_uint_32(buf + 16);
  777. uint_y = png_get_uint_32(buf + 20);
  778. int_x_green = (png_fixed_point)uint_x;
  779. int_y_green = (png_fixed_point)uint_y;
  780. uint_x = png_get_uint_32(buf + 24);
  781. uint_y = png_get_uint_32(buf + 28);
  782. int_x_blue = (png_fixed_point)uint_x;
  783. int_y_blue = (png_fixed_point)uint_y;
  784. #ifdef PNG_FLOATING_POINT_SUPPORTED
  785. white_x = (float)int_x_white / (float)100000.0;
  786. white_y = (float)int_y_white / (float)100000.0;
  787. red_x = (float)int_x_red / (float)100000.0;
  788. red_y = (float)int_y_red / (float)100000.0;
  789. green_x = (float)int_x_green / (float)100000.0;
  790. green_y = (float)int_y_green / (float)100000.0;
  791. blue_x = (float)int_x_blue / (float)100000.0;
  792. blue_y = (float)int_y_blue / (float)100000.0;
  793. #endif
  794. #ifdef PNG_READ_sRGB_SUPPORTED
  795. if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
  796. {
  797. if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
  798. PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
  799. PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
  800. PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
  801. PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
  802. PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
  803. PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
  804. PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
  805. {
  806. png_warning(png_ptr,
  807. "Ignoring incorrect cHRM value when sRGB is also present");
  808. #ifdef PNG_CONSOLE_IO_SUPPORTED
  809. #ifdef PNG_FLOATING_POINT_SUPPORTED
  810. fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
  811. white_x, white_y, red_x, red_y);
  812. fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
  813. green_x, green_y, blue_x, blue_y);
  814. #else
  815. fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
  816. (long)int_x_white, (long)int_y_white,
  817. (long)int_x_red, (long)int_y_red);
  818. fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
  819. (long)int_x_green, (long)int_y_green,
  820. (long)int_x_blue, (long)int_y_blue);
  821. #endif
  822. #endif /* PNG_CONSOLE_IO_SUPPORTED */
  823. }
  824. return;
  825. }
  826. #endif /* PNG_READ_sRGB_SUPPORTED */
  827. #ifdef PNG_FLOATING_POINT_SUPPORTED
  828. png_set_cHRM(png_ptr, info_ptr,
  829. white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
  830. #endif
  831. #ifdef PNG_FIXED_POINT_SUPPORTED
  832. png_set_cHRM_fixed(png_ptr, info_ptr,
  833. int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
  834. int_y_green, int_x_blue, int_y_blue);
  835. #endif
  836. }
  837. #endif
  838. #ifdef PNG_READ_sRGB_SUPPORTED
  839. void /* PRIVATE */
  840. png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  841. {
  842. int intent;
  843. png_byte buf[1];
  844. png_debug(1, "in png_handle_sRGB");
  845. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  846. png_error(png_ptr, "Missing IHDR before sRGB");
  847. else if (png_ptr->mode & PNG_HAVE_IDAT)
  848. {
  849. png_warning(png_ptr, "Invalid sRGB after IDAT");
  850. png_crc_finish(png_ptr, length);
  851. return;
  852. }
  853. else if (png_ptr->mode & PNG_HAVE_PLTE)
  854. /* Should be an error, but we can cope with it */
  855. png_warning(png_ptr, "Out of place sRGB chunk");
  856. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
  857. {
  858. png_warning(png_ptr, "Duplicate sRGB chunk");
  859. png_crc_finish(png_ptr, length);
  860. return;
  861. }
  862. if (length != 1)
  863. {
  864. png_warning(png_ptr, "Incorrect sRGB chunk length");
  865. png_crc_finish(png_ptr, length);
  866. return;
  867. }
  868. png_crc_read(png_ptr, buf, 1);
  869. if (png_crc_finish(png_ptr, 0))
  870. return;
  871. intent = buf[0];
  872. /* Check for bad intent */
  873. if (intent >= PNG_sRGB_INTENT_LAST)
  874. {
  875. png_warning(png_ptr, "Unknown sRGB intent");
  876. return;
  877. }
  878. #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  879. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
  880. {
  881. png_fixed_point igamma;
  882. #ifdef PNG_FIXED_POINT_SUPPORTED
  883. igamma=info_ptr->int_gamma;
  884. #else
  885. # ifdef PNG_FLOATING_POINT_SUPPORTED
  886. igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
  887. # endif
  888. #endif
  889. if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
  890. {
  891. png_warning(png_ptr,
  892. "Ignoring incorrect gAMA value when sRGB is also present");
  893. #ifdef PNG_CONSOLE_IO_SUPPORTED
  894. # ifdef PNG_FIXED_POINT_SUPPORTED
  895. fprintf(stderr, "incorrect gamma=(%d/100000)\n",
  896. (int)png_ptr->int_gamma);
  897. # else
  898. # ifdef PNG_FLOATING_POINT_SUPPORTED
  899. fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
  900. # endif
  901. # endif
  902. #endif
  903. }
  904. }
  905. #endif /* PNG_READ_gAMA_SUPPORTED */
  906. #ifdef PNG_READ_cHRM_SUPPORTED
  907. #ifdef PNG_FIXED_POINT_SUPPORTED
  908. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
  909. if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
  910. PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
  911. PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
  912. PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
  913. PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
  914. PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
  915. PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
  916. PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
  917. {
  918. png_warning(png_ptr,
  919. "Ignoring incorrect cHRM value when sRGB is also present");
  920. }
  921. #endif /* PNG_FIXED_POINT_SUPPORTED */
  922. #endif /* PNG_READ_cHRM_SUPPORTED */
  923. png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
  924. }
  925. #endif /* PNG_READ_sRGB_SUPPORTED */
  926. #ifdef PNG_READ_iCCP_SUPPORTED
  927. void /* PRIVATE */
  928. png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  929. /* Note: this does not properly handle chunks that are > 64K under DOS */
  930. {
  931. png_byte compression_type;
  932. png_bytep pC;
  933. png_charp profile;
  934. png_uint_32 skip = 0;
  935. png_uint_32 profile_size, profile_length;
  936. png_size_t slength, prefix_length, data_length;
  937. png_debug(1, "in png_handle_iCCP");
  938. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  939. png_error(png_ptr, "Missing IHDR before iCCP");
  940. else if (png_ptr->mode & PNG_HAVE_IDAT)
  941. {
  942. png_warning(png_ptr, "Invalid iCCP after IDAT");
  943. png_crc_finish(png_ptr, length);
  944. return;
  945. }
  946. else if (png_ptr->mode & PNG_HAVE_PLTE)
  947. /* Should be an error, but we can cope with it */
  948. png_warning(png_ptr, "Out of place iCCP chunk");
  949. if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
  950. {
  951. png_warning(png_ptr, "Duplicate iCCP chunk");
  952. png_crc_finish(png_ptr, length);
  953. return;
  954. }
  955. #ifdef PNG_MAX_MALLOC_64K
  956. if (length > (png_uint_32)65535L)
  957. {
  958. png_warning(png_ptr, "iCCP chunk too large to fit in memory");
  959. skip = length - (png_uint_32)65535L;
  960. length = (png_uint_32)65535L;
  961. }
  962. #endif
  963. png_free(png_ptr, png_ptr->chunkdata);
  964. png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  965. slength = (png_size_t)length;
  966. png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  967. if (png_crc_finish(png_ptr, skip))
  968. {
  969. png_free(png_ptr, png_ptr->chunkdata);
  970. png_ptr->chunkdata = NULL;
  971. return;
  972. }
  973. png_ptr->chunkdata[slength] = 0x00;
  974. for (profile = png_ptr->chunkdata; *profile; profile++)
  975. /* Empty loop to find end of name */ ;
  976. ++profile;
  977. /* There should be at least one zero (the compression type byte)
  978. * following the separator, and we should be on it
  979. */
  980. if ( profile >= png_ptr->chunkdata + slength - 1)
  981. {
  982. png_free(png_ptr, png_ptr->chunkdata);
  983. png_ptr->chunkdata = NULL;
  984. png_warning(png_ptr, "Malformed iCCP chunk");
  985. return;
  986. }
  987. /* Compression_type should always be zero */
  988. compression_type = *profile++;
  989. if (compression_type)
  990. {
  991. png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
  992. compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
  993. wrote nonzero) */
  994. }
  995. prefix_length = profile - png_ptr->chunkdata;
  996. png_decompress_chunk(png_ptr, compression_type,
  997. slength, prefix_length, &data_length);
  998. profile_length = data_length - prefix_length;
  999. if ( prefix_length > data_length || profile_length < 4)
  1000. {
  1001. png_free(png_ptr, png_ptr->chunkdata);
  1002. png_ptr->chunkdata = NULL;
  1003. png_warning(png_ptr, "Profile size field missing from iCCP chunk");
  1004. return;
  1005. }
  1006. /* Check the profile_size recorded in the first 32 bits of the ICC profile */
  1007. pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
  1008. profile_size = ((*(pC ))<<24) |
  1009. ((*(pC + 1))<<16) |
  1010. ((*(pC + 2))<< 8) |
  1011. ((*(pC + 3)) );
  1012. if (profile_size < profile_length)
  1013. profile_length = profile_size;
  1014. if (profile_size > profile_length)
  1015. {
  1016. png_free(png_ptr, png_ptr->chunkdata);
  1017. png_ptr->chunkdata = NULL;
  1018. png_warning(png_ptr, "Ignoring truncated iCCP profile.");
  1019. return;
  1020. }
  1021. png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
  1022. compression_type, png_ptr->chunkdata + prefix_length, profile_length);
  1023. png_free(png_ptr, png_ptr->chunkdata);
  1024. png_ptr->chunkdata = NULL;
  1025. }
  1026. #endif /* PNG_READ_iCCP_SUPPORTED */
  1027. #ifdef PNG_READ_sPLT_SUPPORTED
  1028. void /* PRIVATE */
  1029. png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1030. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1031. {
  1032. png_bytep entry_start;
  1033. png_sPLT_t new_palette;
  1034. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  1035. png_sPLT_entryp pp;
  1036. #endif
  1037. int data_length, entry_size, i;
  1038. png_uint_32 skip = 0;
  1039. png_size_t slength;
  1040. png_debug(1, "in png_handle_sPLT");
  1041. #ifdef PNG_USER_LIMITS_SUPPORTED
  1042. if (png_ptr->user_chunk_cache_max != 0)
  1043. {
  1044. if (png_ptr->user_chunk_cache_max == 1)
  1045. {
  1046. png_crc_finish(png_ptr, length);
  1047. return;
  1048. }
  1049. if (--png_ptr->user_chunk_cache_max == 1)
  1050. {
  1051. png_warning(png_ptr, "No space in chunk cache for sPLT");
  1052. png_crc_finish(png_ptr, length);
  1053. return;
  1054. }
  1055. }
  1056. #endif
  1057. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1058. png_error(png_ptr, "Missing IHDR before sPLT");
  1059. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1060. {
  1061. png_warning(png_ptr, "Invalid sPLT after IDAT");
  1062. png_crc_finish(png_ptr, length);
  1063. return;
  1064. }
  1065. #ifdef PNG_MAX_MALLOC_64K
  1066. if (length > (png_uint_32)65535L)
  1067. {
  1068. png_warning(png_ptr, "sPLT chunk too large to fit in memory");
  1069. skip = length - (png_uint_32)65535L;
  1070. length = (png_uint_32)65535L;
  1071. }
  1072. #endif
  1073. png_free(png_ptr, png_ptr->chunkdata);
  1074. png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
  1075. slength = (png_size_t)length;
  1076. png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1077. if (png_crc_finish(png_ptr, skip))
  1078. {
  1079. png_free(png_ptr, png_ptr->chunkdata);
  1080. png_ptr->chunkdata = NULL;
  1081. return;
  1082. }
  1083. png_ptr->chunkdata[slength] = 0x00;
  1084. for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
  1085. entry_start++)
  1086. /* Empty loop to find end of name */ ;
  1087. ++entry_start;
  1088. /* A sample depth should follow the separator, and we should be on it */
  1089. if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
  1090. {
  1091. png_free(png_ptr, png_ptr->chunkdata);
  1092. png_ptr->chunkdata = NULL;
  1093. png_warning(png_ptr, "malformed sPLT chunk");
  1094. return;
  1095. }
  1096. new_palette.depth = *entry_start++;
  1097. entry_size = (new_palette.depth == 8 ? 6 : 10);
  1098. data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
  1099. /* Integrity-check the data length */
  1100. if (data_length % entry_size)
  1101. {
  1102. png_free(png_ptr, png_ptr->chunkdata);
  1103. png_ptr->chunkdata = NULL;
  1104. png_warning(png_ptr, "sPLT chunk has bad length");
  1105. return;
  1106. }
  1107. new_palette.nentries = (png_int_32) ( data_length / entry_size);
  1108. if ((png_uint_32) new_palette.nentries >
  1109. (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
  1110. {
  1111. png_warning(png_ptr, "sPLT chunk too long");
  1112. return;
  1113. }
  1114. new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
  1115. png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
  1116. if (new_palette.entries == NULL)
  1117. {
  1118. png_warning(png_ptr, "sPLT chunk requires too much memory");
  1119. return;
  1120. }
  1121. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  1122. for (i = 0; i < new_palette.nentries; i++)
  1123. {
  1124. pp = new_palette.entries + i;
  1125. if (new_palette.depth == 8)
  1126. {
  1127. pp->red = *entry_start++;
  1128. pp->green = *entry_start++;
  1129. pp->blue = *entry_start++;
  1130. pp->alpha = *entry_start++;
  1131. }
  1132. else
  1133. {
  1134. pp->red = png_get_uint_16(entry_start); entry_start += 2;
  1135. pp->green = png_get_uint_16(entry_start); entry_start += 2;
  1136. pp->blue = png_get_uint_16(entry_start); entry_start += 2;
  1137. pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
  1138. }
  1139. pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1140. }
  1141. #else
  1142. pp = new_palette.entries;
  1143. for (i = 0; i < new_palette.nentries; i++)
  1144. {
  1145. if (new_palette.depth == 8)
  1146. {
  1147. pp[i].red = *entry_start++;
  1148. pp[i].green = *entry_start++;
  1149. pp[i].blue = *entry_start++;
  1150. pp[i].alpha = *entry_start++;
  1151. }
  1152. else
  1153. {
  1154. pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
  1155. pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
  1156. pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
  1157. pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
  1158. }
  1159. pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
  1160. }
  1161. #endif
  1162. /* Discard all chunk data except the name and stash that */
  1163. new_palette.name = png_ptr->chunkdata;
  1164. png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
  1165. png_free(png_ptr, png_ptr->chunkdata);
  1166. png_ptr->chunkdata = NULL;
  1167. png_free(png_ptr, new_palette.entries);
  1168. }
  1169. #endif /* PNG_READ_sPLT_SUPPORTED */
  1170. #ifdef PNG_READ_tRNS_SUPPORTED
  1171. void /* PRIVATE */
  1172. png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1173. {
  1174. png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
  1175. png_debug(1, "in png_handle_tRNS");
  1176. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1177. png_error(png_ptr, "Missing IHDR before tRNS");
  1178. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1179. {
  1180. png_warning(png_ptr, "Invalid tRNS after IDAT");
  1181. png_crc_finish(png_ptr, length);
  1182. return;
  1183. }
  1184. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  1185. {
  1186. png_warning(png_ptr, "Duplicate tRNS chunk");
  1187. png_crc_finish(png_ptr, length);
  1188. return;
  1189. }
  1190. if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1191. {
  1192. png_byte buf[2];
  1193. if (length != 2)
  1194. {
  1195. png_warning(png_ptr, "Incorrect tRNS chunk length");
  1196. png_crc_finish(png_ptr, length);
  1197. return;
  1198. }
  1199. png_crc_read(png_ptr, buf, 2);
  1200. png_ptr->num_trans = 1;
  1201. png_ptr->trans_values.gray = png_get_uint_16(buf);
  1202. }
  1203. else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  1204. {
  1205. png_byte buf[6];
  1206. if (length != 6)
  1207. {
  1208. png_warning(png_ptr, "Incorrect tRNS chunk length");
  1209. png_crc_finish(png_ptr, length);
  1210. return;
  1211. }
  1212. png_crc_read(png_ptr, buf, (png_size_t)length);
  1213. png_ptr->num_trans = 1;
  1214. png_ptr->trans_values.red = png_get_uint_16(buf);
  1215. png_ptr->trans_values.green = png_get_uint_16(buf + 2);
  1216. png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
  1217. }
  1218. else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1219. {
  1220. if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1221. {
  1222. /* Should be an error, but we can cope with it. */
  1223. png_warning(png_ptr, "Missing PLTE before tRNS");
  1224. }
  1225. if (length > (png_uint_32)png_ptr->num_palette ||
  1226. length > PNG_MAX_PALETTE_LENGTH)
  1227. {
  1228. png_warning(png_ptr, "Incorrect tRNS chunk length");
  1229. png_crc_finish(png_ptr, length);
  1230. return;
  1231. }
  1232. if (length == 0)
  1233. {
  1234. png_warning(png_ptr, "Zero length tRNS chunk");
  1235. png_crc_finish(png_ptr, length);
  1236. return;
  1237. }
  1238. png_crc_read(png_ptr, readbuf, (png_size_t)length);
  1239. png_ptr->num_trans = (png_uint_16)length;
  1240. }
  1241. else
  1242. {
  1243. png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
  1244. png_crc_finish(png_ptr, length);
  1245. return;
  1246. }
  1247. if (png_crc_finish(png_ptr, 0))
  1248. {
  1249. png_ptr->num_trans = 0;
  1250. return;
  1251. }
  1252. png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
  1253. &(png_ptr->trans_values));
  1254. }
  1255. #endif
  1256. #ifdef PNG_READ_bKGD_SUPPORTED
  1257. void /* PRIVATE */
  1258. png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1259. {
  1260. png_size_t truelen;
  1261. png_byte buf[6];
  1262. png_debug(1, "in png_handle_bKGD");
  1263. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1264. png_error(png_ptr, "Missing IHDR before bKGD");
  1265. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1266. {
  1267. png_warning(png_ptr, "Invalid bKGD after IDAT");
  1268. png_crc_finish(png_ptr, length);
  1269. return;
  1270. }
  1271. else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  1272. !(png_ptr->mode & PNG_HAVE_PLTE))
  1273. {
  1274. png_warning(png_ptr, "Missing PLTE before bKGD");
  1275. png_crc_finish(png_ptr, length);
  1276. return;
  1277. }
  1278. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
  1279. {
  1280. png_warning(png_ptr, "Duplicate bKGD chunk");
  1281. png_crc_finish(png_ptr, length);
  1282. return;
  1283. }
  1284. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1285. truelen = 1;
  1286. else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1287. truelen = 6;
  1288. else
  1289. truelen = 2;
  1290. if (length != truelen)
  1291. {
  1292. png_warning(png_ptr, "Incorrect bKGD chunk length");
  1293. png_crc_finish(png_ptr, length);
  1294. return;
  1295. }
  1296. png_crc_read(png_ptr, buf, truelen);
  1297. if (png_crc_finish(png_ptr, 0))
  1298. return;
  1299. /* We convert the index value into RGB components so that we can allow
  1300. * arbitrary RGB values for background when we have transparency, and
  1301. * so it is easy to determine the RGB values of the background color
  1302. * from the info_ptr struct. */
  1303. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1304. {
  1305. png_ptr->background.index = buf[0];
  1306. if (info_ptr && info_ptr->num_palette)
  1307. {
  1308. if (buf[0] >= info_ptr->num_palette)
  1309. {
  1310. png_warning(png_ptr, "Incorrect bKGD chunk index value");
  1311. return;
  1312. }
  1313. png_ptr->background.red =
  1314. (png_uint_16)png_ptr->palette[buf[0]].red;
  1315. png_ptr->background.green =
  1316. (png_uint_16)png_ptr->palette[buf[0]].green;
  1317. png_ptr->background.blue =
  1318. (png_uint_16)png_ptr->palette[buf[0]].blue;
  1319. }
  1320. }
  1321. else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
  1322. {
  1323. png_ptr->background.red =
  1324. png_ptr->background.green =
  1325. png_ptr->background.blue =
  1326. png_ptr->background.gray = png_get_uint_16(buf);
  1327. }
  1328. else
  1329. {
  1330. png_ptr->background.red = png_get_uint_16(buf);
  1331. png_ptr->background.green = png_get_uint_16(buf + 2);
  1332. png_ptr->background.blue = png_get_uint_16(buf + 4);
  1333. }
  1334. png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
  1335. }
  1336. #endif
  1337. #ifdef PNG_READ_hIST_SUPPORTED
  1338. void /* PRIVATE */
  1339. png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1340. {
  1341. unsigned int num, i;
  1342. png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
  1343. png_debug(1, "in png_handle_hIST");
  1344. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1345. png_error(png_ptr, "Missing IHDR before hIST");
  1346. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1347. {
  1348. png_warning(png_ptr, "Invalid hIST after IDAT");
  1349. png_crc_finish(png_ptr, length);
  1350. return;
  1351. }
  1352. else if (!(png_ptr->mode & PNG_HAVE_PLTE))
  1353. {
  1354. png_warning(png_ptr, "Missing PLTE before hIST");
  1355. png_crc_finish(png_ptr, length);
  1356. return;
  1357. }
  1358. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
  1359. {
  1360. png_warning(png_ptr, "Duplicate hIST chunk");
  1361. png_crc_finish(png_ptr, length);
  1362. return;
  1363. }
  1364. num = length / 2 ;
  1365. if (num != (unsigned int) png_ptr->num_palette || num >
  1366. (unsigned int) PNG_MAX_PALETTE_LENGTH)
  1367. {
  1368. png_warning(png_ptr, "Incorrect hIST chunk length");
  1369. png_crc_finish(png_ptr, length);
  1370. return;
  1371. }
  1372. for (i = 0; i < num; i++)
  1373. {
  1374. png_byte buf[2];
  1375. png_crc_read(png_ptr, buf, 2);
  1376. readbuf[i] = png_get_uint_16(buf);
  1377. }
  1378. if (png_crc_finish(png_ptr, 0))
  1379. return;
  1380. png_set_hIST(png_ptr, info_ptr, readbuf);
  1381. }
  1382. #endif
  1383. #ifdef PNG_READ_pHYs_SUPPORTED
  1384. void /* PRIVATE */
  1385. png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1386. {
  1387. png_byte buf[9];
  1388. png_uint_32 res_x, res_y;
  1389. int unit_type;
  1390. png_debug(1, "in png_handle_pHYs");
  1391. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1392. png_error(png_ptr, "Missing IHDR before pHYs");
  1393. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1394. {
  1395. png_warning(png_ptr, "Invalid pHYs after IDAT");
  1396. png_crc_finish(png_ptr, length);
  1397. return;
  1398. }
  1399. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  1400. {
  1401. png_warning(png_ptr, "Duplicate pHYs chunk");
  1402. png_crc_finish(png_ptr, length);
  1403. return;
  1404. }
  1405. if (length != 9)
  1406. {
  1407. png_warning(png_ptr, "Incorrect pHYs chunk length");
  1408. png_crc_finish(png_ptr, length);
  1409. return;
  1410. }
  1411. png_crc_read(png_ptr, buf, 9);
  1412. if (png_crc_finish(png_ptr, 0))
  1413. return;
  1414. res_x = png_get_uint_32(buf);
  1415. res_y = png_get_uint_32(buf + 4);
  1416. unit_type = buf[8];
  1417. png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
  1418. }
  1419. #endif
  1420. #ifdef PNG_READ_oFFs_SUPPORTED
  1421. void /* PRIVATE */
  1422. png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1423. {
  1424. png_byte buf[9];
  1425. png_int_32 offset_x, offset_y;
  1426. int unit_type;
  1427. png_debug(1, "in png_handle_oFFs");
  1428. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1429. png_error(png_ptr, "Missing IHDR before oFFs");
  1430. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1431. {
  1432. png_warning(png_ptr, "Invalid oFFs after IDAT");
  1433. png_crc_finish(png_ptr, length);
  1434. return;
  1435. }
  1436. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  1437. {
  1438. png_warning(png_ptr, "Duplicate oFFs chunk");
  1439. png_crc_finish(png_ptr, length);
  1440. return;
  1441. }
  1442. if (length != 9)
  1443. {
  1444. png_warning(png_ptr, "Incorrect oFFs chunk length");
  1445. png_crc_finish(png_ptr, length);
  1446. return;
  1447. }
  1448. png_crc_read(png_ptr, buf, 9);
  1449. if (png_crc_finish(png_ptr, 0))
  1450. return;
  1451. offset_x = png_get_int_32(buf);
  1452. offset_y = png_get_int_32(buf + 4);
  1453. unit_type = buf[8];
  1454. png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
  1455. }
  1456. #endif
  1457. #ifdef PNG_READ_pCAL_SUPPORTED
  1458. /* Read the pCAL chunk (described in the PNG Extensions document) */
  1459. void /* PRIVATE */
  1460. png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1461. {
  1462. png_int_32 X0, X1;
  1463. png_byte type, nparams;
  1464. png_charp buf, units, endptr;
  1465. png_charpp params;
  1466. png_size_t slength;
  1467. int i;
  1468. png_debug(1, "in png_handle_pCAL");
  1469. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1470. png_error(png_ptr, "Missing IHDR before pCAL");
  1471. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1472. {
  1473. png_warning(png_ptr, "Invalid pCAL after IDAT");
  1474. png_crc_finish(png_ptr, length);
  1475. return;
  1476. }
  1477. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
  1478. {
  1479. png_warning(png_ptr, "Duplicate pCAL chunk");
  1480. png_crc_finish(png_ptr, length);
  1481. return;
  1482. }
  1483. png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
  1484. length + 1);
  1485. png_free(png_ptr, png_ptr->chunkdata);
  1486. png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1487. if (png_ptr->chunkdata == NULL)
  1488. {
  1489. png_warning(png_ptr, "No memory for pCAL purpose.");
  1490. return;
  1491. }
  1492. slength = (png_size_t)length;
  1493. png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1494. if (png_crc_finish(png_ptr, 0))
  1495. {
  1496. png_free(png_ptr, png_ptr->chunkdata);
  1497. png_ptr->chunkdata = NULL;
  1498. return;
  1499. }
  1500. png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
  1501. png_debug(3, "Finding end of pCAL purpose string");
  1502. for (buf = png_ptr->chunkdata; *buf; buf++)
  1503. /* Empty loop */ ;
  1504. endptr = png_ptr->chunkdata + slength;
  1505. /* We need to have at least 12 bytes after the purpose string
  1506. in order to get the parameter information. */
  1507. if (endptr <= buf + 12)
  1508. {
  1509. png_warning(png_ptr, "Invalid pCAL data");
  1510. png_free(png_ptr, png_ptr->chunkdata);
  1511. png_ptr->chunkdata = NULL;
  1512. return;
  1513. }
  1514. png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
  1515. X0 = png_get_int_32((png_bytep)buf+1);
  1516. X1 = png_get_int_32((png_bytep)buf+5);
  1517. type = buf[9];
  1518. nparams = buf[10];
  1519. units = buf + 11;
  1520. png_debug(3, "Checking pCAL equation type and number of parameters");
  1521. /* Check that we have the right number of parameters for known
  1522. equation types. */
  1523. if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
  1524. (type == PNG_EQUATION_BASE_E && nparams != 3) ||
  1525. (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
  1526. (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
  1527. {
  1528. png_warning(png_ptr, "Invalid pCAL parameters for equation type");
  1529. png_free(png_ptr, png_ptr->chunkdata);
  1530. png_ptr->chunkdata = NULL;
  1531. return;
  1532. }
  1533. else if (type >= PNG_EQUATION_LAST)
  1534. {
  1535. png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
  1536. }
  1537. for (buf = units; *buf; buf++)
  1538. /* Empty loop to move past the units string. */ ;
  1539. png_debug(3, "Allocating pCAL parameters array");
  1540. params = (png_charpp)png_malloc_warn(png_ptr,
  1541. (png_uint_32)(nparams * png_sizeof(png_charp))) ;
  1542. if (params == NULL)
  1543. {
  1544. png_free(png_ptr, png_ptr->chunkdata);
  1545. png_ptr->chunkdata = NULL;
  1546. png_warning(png_ptr, "No memory for pCAL params.");
  1547. return;
  1548. }
  1549. /* Get pointers to the start of each parameter string. */
  1550. for (i = 0; i < (int)nparams; i++)
  1551. {
  1552. buf++; /* Skip the null string terminator from previous parameter. */
  1553. png_debug1(3, "Reading pCAL parameter %d", i);
  1554. for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
  1555. /* Empty loop to move past each parameter string */ ;
  1556. /* Make sure we haven't run out of data yet */
  1557. if (buf > endptr)
  1558. {
  1559. png_warning(png_ptr, "Invalid pCAL data");
  1560. png_free(png_ptr, png_ptr->chunkdata);
  1561. png_ptr->chunkdata = NULL;
  1562. png_free(png_ptr, params);
  1563. return;
  1564. }
  1565. }
  1566. png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
  1567. units, params);
  1568. png_free(png_ptr, png_ptr->chunkdata);
  1569. png_ptr->chunkdata = NULL;
  1570. png_free(png_ptr, params);
  1571. }
  1572. #endif
  1573. #ifdef PNG_READ_sCAL_SUPPORTED
  1574. /* Read the sCAL chunk */
  1575. void /* PRIVATE */
  1576. png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1577. {
  1578. png_charp ep;
  1579. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1580. double width, height;
  1581. png_charp vp;
  1582. #else
  1583. #ifdef PNG_FIXED_POINT_SUPPORTED
  1584. png_charp swidth, sheight;
  1585. #endif
  1586. #endif
  1587. png_size_t slength;
  1588. png_debug(1, "in png_handle_sCAL");
  1589. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1590. png_error(png_ptr, "Missing IHDR before sCAL");
  1591. else if (png_ptr->mode & PNG_HAVE_IDAT)
  1592. {
  1593. png_warning(png_ptr, "Invalid sCAL after IDAT");
  1594. png_crc_finish(png_ptr, length);
  1595. return;
  1596. }
  1597. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
  1598. {
  1599. png_warning(png_ptr, "Duplicate sCAL chunk");
  1600. png_crc_finish(png_ptr, length);
  1601. return;
  1602. }
  1603. png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
  1604. length + 1);
  1605. png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1606. if (png_ptr->chunkdata == NULL)
  1607. {
  1608. png_warning(png_ptr, "Out of memory while processing sCAL chunk");
  1609. png_crc_finish(png_ptr, length);
  1610. return;
  1611. }
  1612. slength = (png_size_t)length;
  1613. png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1614. if (png_crc_finish(png_ptr, 0))
  1615. {
  1616. png_free(png_ptr, png_ptr->chunkdata);
  1617. png_ptr->chunkdata = NULL;
  1618. return;
  1619. }
  1620. png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
  1621. ep = png_ptr->chunkdata + 1; /* Skip unit byte */
  1622. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1623. width = png_strtod(png_ptr, ep, &vp);
  1624. if (*vp)
  1625. {
  1626. png_warning(png_ptr, "malformed width string in sCAL chunk");
  1627. png_free(png_ptr, png_ptr->chunkdata);
  1628. png_ptr->chunkdata = NULL;
  1629. return;
  1630. }
  1631. #else
  1632. #ifdef PNG_FIXED_POINT_SUPPORTED
  1633. swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
  1634. if (swidth == NULL)
  1635. {
  1636. png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
  1637. png_free(png_ptr, png_ptr->chunkdata);
  1638. png_ptr->chunkdata = NULL;
  1639. return;
  1640. }
  1641. png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
  1642. #endif
  1643. #endif
  1644. for (ep = png_ptr->chunkdata; *ep; ep++)
  1645. /* Empty loop */ ;
  1646. ep++;
  1647. if (png_ptr->chunkdata + slength < ep)
  1648. {
  1649. png_warning(png_ptr, "Truncated sCAL chunk");
  1650. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1651. png_free(png_ptr, swidth);
  1652. #endif
  1653. png_free(png_ptr, png_ptr->chunkdata);
  1654. png_ptr->chunkdata = NULL;
  1655. return;
  1656. }
  1657. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1658. height = png_strtod(png_ptr, ep, &vp);
  1659. if (*vp)
  1660. {
  1661. png_warning(png_ptr, "malformed height string in sCAL chunk");
  1662. png_free(png_ptr, png_ptr->chunkdata);
  1663. png_ptr->chunkdata = NULL;
  1664. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1665. png_free(png_ptr, swidth);
  1666. #endif
  1667. return;
  1668. }
  1669. #else
  1670. #ifdef PNG_FIXED_POINT_SUPPORTED
  1671. sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
  1672. if (sheight == NULL)
  1673. {
  1674. png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
  1675. png_free(png_ptr, png_ptr->chunkdata);
  1676. png_ptr->chunkdata = NULL;
  1677. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1678. png_free(png_ptr, swidth);
  1679. #endif
  1680. return;
  1681. }
  1682. png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
  1683. #endif
  1684. #endif
  1685. if (png_ptr->chunkdata + slength < ep
  1686. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1687. || width <= 0. || height <= 0.
  1688. #endif
  1689. )
  1690. {
  1691. png_warning(png_ptr, "Invalid sCAL data");
  1692. png_free(png_ptr, png_ptr->chunkdata);
  1693. png_ptr->chunkdata = NULL;
  1694. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1695. png_free(png_ptr, swidth);
  1696. png_free(png_ptr, sheight);
  1697. #endif
  1698. return;
  1699. }
  1700. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1701. png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
  1702. #else
  1703. #ifdef PNG_FIXED_POINT_SUPPORTED
  1704. png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
  1705. #endif
  1706. #endif
  1707. png_free(png_ptr, png_ptr->chunkdata);
  1708. png_ptr->chunkdata = NULL;
  1709. #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
  1710. png_free(png_ptr, swidth);
  1711. png_free(png_ptr, sheight);
  1712. #endif
  1713. }
  1714. #endif
  1715. #ifdef PNG_READ_tIME_SUPPORTED
  1716. void /* PRIVATE */
  1717. png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1718. {
  1719. png_byte buf[7];
  1720. png_time mod_time;
  1721. png_debug(1, "in png_handle_tIME");
  1722. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1723. png_error(png_ptr, "Out of place tIME chunk");
  1724. else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
  1725. {
  1726. png_warning(png_ptr, "Duplicate tIME chunk");
  1727. png_crc_finish(png_ptr, length);
  1728. return;
  1729. }
  1730. if (png_ptr->mode & PNG_HAVE_IDAT)
  1731. png_ptr->mode |= PNG_AFTER_IDAT;
  1732. if (length != 7)
  1733. {
  1734. png_warning(png_ptr, "Incorrect tIME chunk length");
  1735. png_crc_finish(png_ptr, length);
  1736. return;
  1737. }
  1738. png_crc_read(png_ptr, buf, 7);
  1739. if (png_crc_finish(png_ptr, 0))
  1740. return;
  1741. mod_time.second = buf[6];
  1742. mod_time.minute = buf[5];
  1743. mod_time.hour = buf[4];
  1744. mod_time.day = buf[3];
  1745. mod_time.month = buf[2];
  1746. mod_time.year = png_get_uint_16(buf);
  1747. png_set_tIME(png_ptr, info_ptr, &mod_time);
  1748. }
  1749. #endif
  1750. #ifdef PNG_READ_tEXt_SUPPORTED
  1751. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1752. void /* PRIVATE */
  1753. png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1754. {
  1755. png_textp text_ptr;
  1756. png_charp key;
  1757. png_charp text;
  1758. png_uint_32 skip = 0;
  1759. png_size_t slength;
  1760. int ret;
  1761. png_debug(1, "in png_handle_tEXt");
  1762. #ifdef PNG_USER_LIMITS_SUPPORTED
  1763. if (png_ptr->user_chunk_cache_max != 0)
  1764. {
  1765. if (png_ptr->user_chunk_cache_max == 1)
  1766. {
  1767. png_crc_finish(png_ptr, length);
  1768. return;
  1769. }
  1770. if (--png_ptr->user_chunk_cache_max == 1)
  1771. {
  1772. png_warning(png_ptr, "No space in chunk cache for tEXt");
  1773. png_crc_finish(png_ptr, length);
  1774. return;
  1775. }
  1776. }
  1777. #endif
  1778. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1779. png_error(png_ptr, "Missing IHDR before tEXt");
  1780. if (png_ptr->mode & PNG_HAVE_IDAT)
  1781. png_ptr->mode |= PNG_AFTER_IDAT;
  1782. #ifdef PNG_MAX_MALLOC_64K
  1783. if (length > (png_uint_32)65535L)
  1784. {
  1785. png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  1786. skip = length - (png_uint_32)65535L;
  1787. length = (png_uint_32)65535L;
  1788. }
  1789. #endif
  1790. png_free(png_ptr, png_ptr->chunkdata);
  1791. png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1792. if (png_ptr->chunkdata == NULL)
  1793. {
  1794. png_warning(png_ptr, "No memory to process text chunk.");
  1795. return;
  1796. }
  1797. slength = (png_size_t)length;
  1798. png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1799. if (png_crc_finish(png_ptr, skip))
  1800. {
  1801. png_free(png_ptr, png_ptr->chunkdata);
  1802. png_ptr->chunkdata = NULL;
  1803. return;
  1804. }
  1805. key = png_ptr->chunkdata;
  1806. key[slength] = 0x00;
  1807. for (text = key; *text; text++)
  1808. /* Empty loop to find end of key */ ;
  1809. if (text != key + slength)
  1810. text++;
  1811. text_ptr = (png_textp)png_malloc_warn(png_ptr,
  1812. (png_uint_32)png_sizeof(png_text));
  1813. if (text_ptr == NULL)
  1814. {
  1815. png_warning(png_ptr, "Not enough memory to process text chunk.");
  1816. png_free(png_ptr, png_ptr->chunkdata);
  1817. png_ptr->chunkdata = NULL;
  1818. return;
  1819. }
  1820. text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1821. text_ptr->key = key;
  1822. #ifdef PNG_iTXt_SUPPORTED
  1823. text_ptr->lang = NULL;
  1824. text_ptr->lang_key = NULL;
  1825. text_ptr->itxt_length = 0;
  1826. #endif
  1827. text_ptr->text = text;
  1828. text_ptr->text_length = png_strlen(text);
  1829. ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1830. png_free(png_ptr, png_ptr->chunkdata);
  1831. png_ptr->chunkdata = NULL;
  1832. png_free(png_ptr, text_ptr);
  1833. if (ret)
  1834. png_warning(png_ptr, "Insufficient memory to process text chunk.");
  1835. }
  1836. #endif
  1837. #ifdef PNG_READ_zTXt_SUPPORTED
  1838. /* Note: this does not correctly handle chunks that are > 64K under DOS */
  1839. void /* PRIVATE */
  1840. png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1841. {
  1842. png_textp text_ptr;
  1843. png_charp text;
  1844. int comp_type;
  1845. int ret;
  1846. png_size_t slength, prefix_len, data_len;
  1847. png_debug(1, "in png_handle_zTXt");
  1848. #ifdef PNG_USER_LIMITS_SUPPORTED
  1849. if (png_ptr->user_chunk_cache_max != 0)
  1850. {
  1851. if (png_ptr->user_chunk_cache_max == 1)
  1852. {
  1853. png_crc_finish(png_ptr, length);
  1854. return;
  1855. }
  1856. if (--png_ptr->user_chunk_cache_max == 1)
  1857. {
  1858. png_warning(png_ptr, "No space in chunk cache for zTXt");
  1859. png_crc_finish(png_ptr, length);
  1860. return;
  1861. }
  1862. }
  1863. #endif
  1864. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1865. png_error(png_ptr, "Missing IHDR before zTXt");
  1866. if (png_ptr->mode & PNG_HAVE_IDAT)
  1867. png_ptr->mode |= PNG_AFTER_IDAT;
  1868. #ifdef PNG_MAX_MALLOC_64K
  1869. /* We will no doubt have problems with chunks even half this size, but
  1870. there is no hard and fast rule to tell us where to stop. */
  1871. if (length > (png_uint_32)65535L)
  1872. {
  1873. png_warning(png_ptr, "zTXt chunk too large to fit in memory");
  1874. png_crc_finish(png_ptr, length);
  1875. return;
  1876. }
  1877. #endif
  1878. png_free(png_ptr, png_ptr->chunkdata);
  1879. png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1880. if (png_ptr->chunkdata == NULL)
  1881. {
  1882. png_warning(png_ptr, "Out of memory processing zTXt chunk.");
  1883. return;
  1884. }
  1885. slength = (png_size_t)length;
  1886. png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
  1887. if (png_crc_finish(png_ptr, 0))
  1888. {
  1889. png_free(png_ptr, png_ptr->chunkdata);
  1890. png_ptr->chunkdata = NULL;
  1891. return;
  1892. }
  1893. png_ptr->chunkdata[slength] = 0x00;
  1894. for (text = png_ptr->chunkdata; *text; text++)
  1895. /* Empty loop */ ;
  1896. /* zTXt must have some text after the chunkdataword */
  1897. if (text >= png_ptr->chunkdata + slength - 2)
  1898. {
  1899. png_warning(png_ptr, "Truncated zTXt chunk");
  1900. png_free(png_ptr, png_ptr->chunkdata);
  1901. png_ptr->chunkdata = NULL;
  1902. return;
  1903. }
  1904. else
  1905. {
  1906. comp_type = *(++text);
  1907. if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
  1908. {
  1909. png_warning(png_ptr, "Unknown compression type in zTXt chunk");
  1910. comp_type = PNG_TEXT_COMPRESSION_zTXt;
  1911. }
  1912. text++; /* Skip the compression_method byte */
  1913. }
  1914. prefix_len = text - png_ptr->chunkdata;
  1915. png_decompress_chunk(png_ptr, comp_type,
  1916. (png_size_t)length, prefix_len, &data_len);
  1917. text_ptr = (png_textp)png_malloc_warn(png_ptr,
  1918. (png_uint_32)png_sizeof(png_text));
  1919. if (text_ptr == NULL)
  1920. {
  1921. png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
  1922. png_free(png_ptr, png_ptr->chunkdata);
  1923. png_ptr->chunkdata = NULL;
  1924. return;
  1925. }
  1926. text_ptr->compression = comp_type;
  1927. text_ptr->key = png_ptr->chunkdata;
  1928. #ifdef PNG_iTXt_SUPPORTED
  1929. text_ptr->lang = NULL;
  1930. text_ptr->lang_key = NULL;
  1931. text_ptr->itxt_length = 0;
  1932. #endif
  1933. text_ptr->text = png_ptr->chunkdata + prefix_len;
  1934. text_ptr->text_length = data_len;
  1935. ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
  1936. png_free(png_ptr, text_ptr);
  1937. png_free(png_ptr, png_ptr->chunkdata);
  1938. png_ptr->chunkdata = NULL;
  1939. if (ret)
  1940. png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
  1941. }
  1942. #endif
  1943. #ifdef PNG_READ_iTXt_SUPPORTED
  1944. /* Note: this does not correctly handle chunks that are > 64K under DOS */
  1945. void /* PRIVATE */
  1946. png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1947. {
  1948. png_textp text_ptr;
  1949. png_charp key, lang, text, lang_key;
  1950. int comp_flag;
  1951. int comp_type = 0;
  1952. int ret;
  1953. png_size_t slength, prefix_len, data_len;
  1954. png_debug(1, "in png_handle_iTXt");
  1955. #ifdef PNG_USER_LIMITS_SUPPORTED
  1956. if (png_ptr->user_chunk_cache_max != 0)
  1957. {
  1958. if (png_ptr->user_chunk_cache_max == 1)
  1959. {
  1960. png_crc_finish(png_ptr, length);
  1961. return;
  1962. }
  1963. if (--png_ptr->user_chunk_cache_max == 1)
  1964. {
  1965. png_warning(png_ptr, "No space in chunk cache for iTXt");
  1966. png_crc_finish(png_ptr, length);
  1967. return;
  1968. }
  1969. }
  1970. #endif
  1971. if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1972. png_error(png_ptr, "Missing IHDR before iTXt");
  1973. if (png_ptr->mode & PNG_HAVE_IDAT)
  1974. png_ptr->mode |= PNG_AFTER_IDAT;
  1975. #ifdef PNG_MAX_MALLOC_64K
  1976. /* We will no doubt have problems with chunks even half this size, but
  1977. there is no hard and fast rule to tell us where to stop. */
  1978. if (length > (png_uint_32)65535L)
  1979. {
  1980. png_warning(png_ptr, "iTXt chunk too large to fit in memory");
  1981. png_crc_finish(png_ptr, length);
  1982. return;
  1983. }
  1984. #endif
  1985. png_free(png_ptr, png_ptr->chunkdata);
  1986. png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
  1987. if (png_ptr->chunkdata == NULL)
  1988. {
  1989. png_warning(png_ptr, "No memory to process iTXt ch