PageRenderTime 165ms CodeModel.GetById 22ms RepoModel.GetById 2ms app.codeStats 0ms

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

http://ftk.googlecode.com/
C | 2165 lines | 1649 code | 255 blank | 261 comment | 300 complexity | 93f3f82ecfb072a5cbccbf81965a5fdc MD5 | raw file
Possible License(s): LGPL-3.0
  1. /* pngwutil.c - utilities to write a PNG file
  2. *
  3. * Last changed in libpng 1.2.43 [February 25, 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. #define PNG_INTERNAL
  13. #define PNG_NO_PEDANTIC_WARNINGS
  14. #include "png.h"
  15. #ifdef PNG_WRITE_SUPPORTED
  16. /* Place a 32-bit number into a buffer in PNG byte order. We work
  17. * with unsigned numbers for convenience, although one supported
  18. * ancillary chunk uses signed (two's complement) numbers.
  19. */
  20. void PNGAPI
  21. png_save_uint_32(png_bytep buf, png_uint_32 i)
  22. {
  23. buf[0] = (png_byte)((i >> 24) & 0xff);
  24. buf[1] = (png_byte)((i >> 16) & 0xff);
  25. buf[2] = (png_byte)((i >> 8) & 0xff);
  26. buf[3] = (png_byte)(i & 0xff);
  27. }
  28. /* The png_save_int_32 function assumes integers are stored in two's
  29. * complement format. If this isn't the case, then this routine needs to
  30. * be modified to write data in two's complement format.
  31. */
  32. void PNGAPI
  33. png_save_int_32(png_bytep buf, png_int_32 i)
  34. {
  35. buf[0] = (png_byte)((i >> 24) & 0xff);
  36. buf[1] = (png_byte)((i >> 16) & 0xff);
  37. buf[2] = (png_byte)((i >> 8) & 0xff);
  38. buf[3] = (png_byte)(i & 0xff);
  39. }
  40. /* Place a 16-bit number into a buffer in PNG byte order.
  41. * The parameter is declared unsigned int, not png_uint_16,
  42. * just to avoid potential problems on pre-ANSI C compilers.
  43. */
  44. void PNGAPI
  45. png_save_uint_16(png_bytep buf, unsigned int i)
  46. {
  47. buf[0] = (png_byte)((i >> 8) & 0xff);
  48. buf[1] = (png_byte)(i & 0xff);
  49. }
  50. /* Simple function to write the signature. If we have already written
  51. * the magic bytes of the signature, or more likely, the PNG stream is
  52. * being embedded into another stream and doesn't need its own signature,
  53. * we should call png_set_sig_bytes() to tell libpng how many of the
  54. * bytes have already been written.
  55. */
  56. void /* PRIVATE */
  57. png_write_sig(png_structp png_ptr)
  58. {
  59. png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
  60. /* Write the rest of the 8 byte signature */
  61. png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
  62. (png_size_t)(8 - png_ptr->sig_bytes));
  63. if (png_ptr->sig_bytes < 3)
  64. png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
  65. }
  66. /* Write a PNG chunk all at once. The type is an array of ASCII characters
  67. * representing the chunk name. The array must be at least 4 bytes in
  68. * length, and does not need to be null terminated. To be safe, pass the
  69. * pre-defined chunk names here, and if you need a new one, define it
  70. * where the others are defined. The length is the length of the data.
  71. * All the data must be present. If that is not possible, use the
  72. * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
  73. * functions instead.
  74. */
  75. void PNGAPI
  76. png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
  77. png_bytep data, png_size_t length)
  78. {
  79. if (png_ptr == NULL)
  80. return;
  81. png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
  82. png_write_chunk_data(png_ptr, data, (png_size_t)length);
  83. png_write_chunk_end(png_ptr);
  84. }
  85. /* Write the start of a PNG chunk. The type is the chunk type.
  86. * The total_length is the sum of the lengths of all the data you will be
  87. * passing in png_write_chunk_data().
  88. */
  89. void PNGAPI
  90. png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
  91. png_uint_32 length)
  92. {
  93. png_byte buf[8];
  94. png_debug2(0, "Writing %s chunk, length = %lu", chunk_name,
  95. (unsigned long)length);
  96. if (png_ptr == NULL)
  97. return;
  98. /* Write the length and the chunk name */
  99. png_save_uint_32(buf, length);
  100. png_memcpy(buf + 4, chunk_name, 4);
  101. png_write_data(png_ptr, buf, (png_size_t)8);
  102. /* Put the chunk name into png_ptr->chunk_name */
  103. png_memcpy(png_ptr->chunk_name, chunk_name, 4);
  104. /* Reset the crc and run it over the chunk name */
  105. png_reset_crc(png_ptr);
  106. png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
  107. }
  108. /* Write the data of a PNG chunk started with png_write_chunk_start().
  109. * Note that multiple calls to this function are allowed, and that the
  110. * sum of the lengths from these calls *must* add up to the total_length
  111. * given to png_write_chunk_start().
  112. */
  113. void PNGAPI
  114. png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
  115. {
  116. /* Write the data, and run the CRC over it */
  117. if (png_ptr == NULL)
  118. return;
  119. if (data != NULL && length > 0)
  120. {
  121. png_write_data(png_ptr, data, length);
  122. /* Update the CRC after writing the data,
  123. * in case that the user I/O routine alters it.
  124. */
  125. png_calculate_crc(png_ptr, data, length);
  126. }
  127. }
  128. /* Finish a chunk started with png_write_chunk_start(). */
  129. void PNGAPI
  130. png_write_chunk_end(png_structp png_ptr)
  131. {
  132. png_byte buf[4];
  133. if (png_ptr == NULL) return;
  134. /* Write the crc in a single operation */
  135. png_save_uint_32(buf, png_ptr->crc);
  136. png_write_data(png_ptr, buf, (png_size_t)4);
  137. }
  138. #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
  139. /* This pair of functions encapsulates the operation of (a) compressing a
  140. * text string, and (b) issuing it later as a series of chunk data writes.
  141. * The compression_state structure is shared context for these functions
  142. * set up by the caller in order to make the whole mess thread-safe.
  143. */
  144. typedef struct
  145. {
  146. char *input; /* The uncompressed input data */
  147. int input_len; /* Its length */
  148. int num_output_ptr; /* Number of output pointers used */
  149. int max_output_ptr; /* Size of output_ptr */
  150. png_charpp output_ptr; /* Array of pointers to output */
  151. } compression_state;
  152. /* Compress given text into storage in the png_ptr structure */
  153. static int /* PRIVATE */
  154. png_text_compress(png_structp png_ptr,
  155. png_charp text, png_size_t text_len, int compression,
  156. compression_state *comp)
  157. {
  158. int ret;
  159. comp->num_output_ptr = 0;
  160. comp->max_output_ptr = 0;
  161. comp->output_ptr = NULL;
  162. comp->input = NULL;
  163. comp->input_len = 0;
  164. /* We may just want to pass the text right through */
  165. if (compression == PNG_TEXT_COMPRESSION_NONE)
  166. {
  167. comp->input = text;
  168. comp->input_len = text_len;
  169. return((int)text_len);
  170. }
  171. if (compression >= PNG_TEXT_COMPRESSION_LAST)
  172. {
  173. #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
  174. char msg[50];
  175. png_snprintf(msg, 50, "Unknown compression type %d", compression);
  176. png_warning(png_ptr, msg);
  177. #else
  178. png_warning(png_ptr, "Unknown compression type");
  179. #endif
  180. }
  181. /* We can't write the chunk until we find out how much data we have,
  182. * which means we need to run the compressor first and save the
  183. * output. This shouldn't be a problem, as the vast majority of
  184. * comments should be reasonable, but we will set up an array of
  185. * malloc'd pointers to be sure.
  186. *
  187. * If we knew the application was well behaved, we could simplify this
  188. * greatly by assuming we can always malloc an output buffer large
  189. * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
  190. * and malloc this directly. The only time this would be a bad idea is
  191. * if we can't malloc more than 64K and we have 64K of random input
  192. * data, or if the input string is incredibly large (although this
  193. * wouldn't cause a failure, just a slowdown due to swapping).
  194. */
  195. /* Set up the compression buffers */
  196. png_ptr->zstream.avail_in = (uInt)text_len;
  197. png_ptr->zstream.next_in = (Bytef *)text;
  198. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  199. png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
  200. /* This is the same compression loop as in png_write_row() */
  201. do
  202. {
  203. /* Compress the data */
  204. ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
  205. if (ret != Z_OK)
  206. {
  207. /* Error */
  208. if (png_ptr->zstream.msg != NULL)
  209. png_error(png_ptr, png_ptr->zstream.msg);
  210. else
  211. png_error(png_ptr, "zlib error");
  212. }
  213. /* Check to see if we need more room */
  214. if (!(png_ptr->zstream.avail_out))
  215. {
  216. /* Make sure the output array has room */
  217. if (comp->num_output_ptr >= comp->max_output_ptr)
  218. {
  219. int old_max;
  220. old_max = comp->max_output_ptr;
  221. comp->max_output_ptr = comp->num_output_ptr + 4;
  222. if (comp->output_ptr != NULL)
  223. {
  224. png_charpp old_ptr;
  225. old_ptr = comp->output_ptr;
  226. comp->output_ptr = (png_charpp)png_malloc(png_ptr,
  227. (png_uint_32)
  228. (comp->max_output_ptr * png_sizeof(png_charpp)));
  229. png_memcpy(comp->output_ptr, old_ptr, old_max
  230. * png_sizeof(png_charp));
  231. png_free(png_ptr, old_ptr);
  232. }
  233. else
  234. comp->output_ptr = (png_charpp)png_malloc(png_ptr,
  235. (png_uint_32)
  236. (comp->max_output_ptr * png_sizeof(png_charp)));
  237. }
  238. /* Save the data */
  239. comp->output_ptr[comp->num_output_ptr] =
  240. (png_charp)png_malloc(png_ptr,
  241. (png_uint_32)png_ptr->zbuf_size);
  242. png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
  243. png_ptr->zbuf_size);
  244. comp->num_output_ptr++;
  245. /* and reset the buffer */
  246. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  247. png_ptr->zstream.next_out = png_ptr->zbuf;
  248. }
  249. /* Continue until we don't have any more to compress */
  250. } while (png_ptr->zstream.avail_in);
  251. /* Finish the compression */
  252. do
  253. {
  254. /* Tell zlib we are finished */
  255. ret = deflate(&png_ptr->zstream, Z_FINISH);
  256. if (ret == Z_OK)
  257. {
  258. /* Check to see if we need more room */
  259. if (!(png_ptr->zstream.avail_out))
  260. {
  261. /* Check to make sure our output array has room */
  262. if (comp->num_output_ptr >= comp->max_output_ptr)
  263. {
  264. int old_max;
  265. old_max = comp->max_output_ptr;
  266. comp->max_output_ptr = comp->num_output_ptr + 4;
  267. if (comp->output_ptr != NULL)
  268. {
  269. png_charpp old_ptr;
  270. old_ptr = comp->output_ptr;
  271. /* This could be optimized to realloc() */
  272. comp->output_ptr = (png_charpp)png_malloc(png_ptr,
  273. (png_uint_32)(comp->max_output_ptr *
  274. png_sizeof(png_charp)));
  275. png_memcpy(comp->output_ptr, old_ptr,
  276. old_max * png_sizeof(png_charp));
  277. png_free(png_ptr, old_ptr);
  278. }
  279. else
  280. comp->output_ptr = (png_charpp)png_malloc(png_ptr,
  281. (png_uint_32)(comp->max_output_ptr *
  282. png_sizeof(png_charp)));
  283. }
  284. /* Save the data */
  285. comp->output_ptr[comp->num_output_ptr] =
  286. (png_charp)png_malloc(png_ptr,
  287. (png_uint_32)png_ptr->zbuf_size);
  288. png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
  289. png_ptr->zbuf_size);
  290. comp->num_output_ptr++;
  291. /* and reset the buffer pointers */
  292. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  293. png_ptr->zstream.next_out = png_ptr->zbuf;
  294. }
  295. }
  296. else if (ret != Z_STREAM_END)
  297. {
  298. /* We got an error */
  299. if (png_ptr->zstream.msg != NULL)
  300. png_error(png_ptr, png_ptr->zstream.msg);
  301. else
  302. png_error(png_ptr, "zlib error");
  303. }
  304. } while (ret != Z_STREAM_END);
  305. /* Text length is number of buffers plus last buffer */
  306. text_len = png_ptr->zbuf_size * comp->num_output_ptr;
  307. if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
  308. text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
  309. return((int)text_len);
  310. }
  311. /* Ship the compressed text out via chunk writes */
  312. static void /* PRIVATE */
  313. png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
  314. {
  315. int i;
  316. /* Handle the no-compression case */
  317. if (comp->input)
  318. {
  319. png_write_chunk_data(png_ptr, (png_bytep)comp->input,
  320. (png_size_t)comp->input_len);
  321. return;
  322. }
  323. /* Write saved output buffers, if any */
  324. for (i = 0; i < comp->num_output_ptr; i++)
  325. {
  326. png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i],
  327. (png_size_t)png_ptr->zbuf_size);
  328. png_free(png_ptr, comp->output_ptr[i]);
  329. comp->output_ptr[i]=NULL;
  330. }
  331. if (comp->max_output_ptr != 0)
  332. png_free(png_ptr, comp->output_ptr);
  333. comp->output_ptr=NULL;
  334. /* Write anything left in zbuf */
  335. if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
  336. png_write_chunk_data(png_ptr, png_ptr->zbuf,
  337. (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
  338. /* Reset zlib for another zTXt/iTXt or image data */
  339. deflateReset(&png_ptr->zstream);
  340. png_ptr->zstream.data_type = Z_BINARY;
  341. }
  342. #endif
  343. /* Write the IHDR chunk, and update the png_struct with the necessary
  344. * information. Note that the rest of this code depends upon this
  345. * information being correct.
  346. */
  347. void /* PRIVATE */
  348. png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
  349. int bit_depth, int color_type, int compression_type, int filter_type,
  350. int interlace_type)
  351. {
  352. #ifdef PNG_USE_LOCAL_ARRAYS
  353. PNG_IHDR;
  354. #endif
  355. int ret;
  356. png_byte buf[13]; /* Buffer to store the IHDR info */
  357. png_debug(1, "in png_write_IHDR");
  358. /* Check that we have valid input data from the application info */
  359. switch (color_type)
  360. {
  361. case PNG_COLOR_TYPE_GRAY:
  362. switch (bit_depth)
  363. {
  364. case 1:
  365. case 2:
  366. case 4:
  367. case 8:
  368. case 16: png_ptr->channels = 1; break;
  369. default: png_error(png_ptr,
  370. "Invalid bit depth for grayscale image");
  371. }
  372. break;
  373. case PNG_COLOR_TYPE_RGB:
  374. if (bit_depth != 8 && bit_depth != 16)
  375. png_error(png_ptr, "Invalid bit depth for RGB image");
  376. png_ptr->channels = 3;
  377. break;
  378. case PNG_COLOR_TYPE_PALETTE:
  379. switch (bit_depth)
  380. {
  381. case 1:
  382. case 2:
  383. case 4:
  384. case 8: png_ptr->channels = 1; break;
  385. default: png_error(png_ptr, "Invalid bit depth for paletted image");
  386. }
  387. break;
  388. case PNG_COLOR_TYPE_GRAY_ALPHA:
  389. if (bit_depth != 8 && bit_depth != 16)
  390. png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
  391. png_ptr->channels = 2;
  392. break;
  393. case PNG_COLOR_TYPE_RGB_ALPHA:
  394. if (bit_depth != 8 && bit_depth != 16)
  395. png_error(png_ptr, "Invalid bit depth for RGBA image");
  396. png_ptr->channels = 4;
  397. break;
  398. default:
  399. png_error(png_ptr, "Invalid image color type specified");
  400. }
  401. if (compression_type != PNG_COMPRESSION_TYPE_BASE)
  402. {
  403. png_warning(png_ptr, "Invalid compression type specified");
  404. compression_type = PNG_COMPRESSION_TYPE_BASE;
  405. }
  406. /* Write filter_method 64 (intrapixel differencing) only if
  407. * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
  408. * 2. Libpng did not write a PNG signature (this filter_method is only
  409. * used in PNG datastreams that are embedded in MNG datastreams) and
  410. * 3. The application called png_permit_mng_features with a mask that
  411. * included PNG_FLAG_MNG_FILTER_64 and
  412. * 4. The filter_method is 64 and
  413. * 5. The color_type is RGB or RGBA
  414. */
  415. if (
  416. #ifdef PNG_MNG_FEATURES_SUPPORTED
  417. !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
  418. ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
  419. (color_type == PNG_COLOR_TYPE_RGB ||
  420. color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
  421. (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
  422. #endif
  423. filter_type != PNG_FILTER_TYPE_BASE)
  424. {
  425. png_warning(png_ptr, "Invalid filter type specified");
  426. filter_type = PNG_FILTER_TYPE_BASE;
  427. }
  428. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  429. if (interlace_type != PNG_INTERLACE_NONE &&
  430. interlace_type != PNG_INTERLACE_ADAM7)
  431. {
  432. png_warning(png_ptr, "Invalid interlace type specified");
  433. interlace_type = PNG_INTERLACE_ADAM7;
  434. }
  435. #else
  436. interlace_type=PNG_INTERLACE_NONE;
  437. #endif
  438. /* Save the relevent information */
  439. png_ptr->bit_depth = (png_byte)bit_depth;
  440. png_ptr->color_type = (png_byte)color_type;
  441. png_ptr->interlaced = (png_byte)interlace_type;
  442. #ifdef PNG_MNG_FEATURES_SUPPORTED
  443. png_ptr->filter_type = (png_byte)filter_type;
  444. #endif
  445. png_ptr->compression_type = (png_byte)compression_type;
  446. png_ptr->width = width;
  447. png_ptr->height = height;
  448. png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
  449. png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
  450. /* Set the usr info, so any transformations can modify it */
  451. png_ptr->usr_width = png_ptr->width;
  452. png_ptr->usr_bit_depth = png_ptr->bit_depth;
  453. png_ptr->usr_channels = png_ptr->channels;
  454. /* Pack the header information into the buffer */
  455. png_save_uint_32(buf, width);
  456. png_save_uint_32(buf + 4, height);
  457. buf[8] = (png_byte)bit_depth;
  458. buf[9] = (png_byte)color_type;
  459. buf[10] = (png_byte)compression_type;
  460. buf[11] = (png_byte)filter_type;
  461. buf[12] = (png_byte)interlace_type;
  462. /* Write the chunk */
  463. png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
  464. /* Initialize zlib with PNG info */
  465. png_ptr->zstream.zalloc = png_zalloc;
  466. png_ptr->zstream.zfree = png_zfree;
  467. png_ptr->zstream.opaque = (voidpf)png_ptr;
  468. if (!(png_ptr->do_filter))
  469. {
  470. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
  471. png_ptr->bit_depth < 8)
  472. png_ptr->do_filter = PNG_FILTER_NONE;
  473. else
  474. png_ptr->do_filter = PNG_ALL_FILTERS;
  475. }
  476. if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
  477. {
  478. if (png_ptr->do_filter != PNG_FILTER_NONE)
  479. png_ptr->zlib_strategy = Z_FILTERED;
  480. else
  481. png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
  482. }
  483. if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
  484. png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
  485. if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
  486. png_ptr->zlib_mem_level = 8;
  487. if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
  488. png_ptr->zlib_window_bits = 15;
  489. if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
  490. png_ptr->zlib_method = 8;
  491. ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
  492. png_ptr->zlib_method, png_ptr->zlib_window_bits,
  493. png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
  494. if (ret != Z_OK)
  495. {
  496. if (ret == Z_VERSION_ERROR) png_error(png_ptr,
  497. "zlib failed to initialize compressor -- version error");
  498. if (ret == Z_STREAM_ERROR) png_error(png_ptr,
  499. "zlib failed to initialize compressor -- stream error");
  500. if (ret == Z_MEM_ERROR) png_error(png_ptr,
  501. "zlib failed to initialize compressor -- mem error");
  502. png_error(png_ptr, "zlib failed to initialize compressor");
  503. }
  504. png_ptr->zstream.next_out = png_ptr->zbuf;
  505. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  506. /* libpng is not interested in zstream.data_type */
  507. /* Set it to a predefined value, to avoid its evaluation inside zlib */
  508. png_ptr->zstream.data_type = Z_BINARY;
  509. png_ptr->mode = PNG_HAVE_IHDR;
  510. }
  511. /* Write the palette. We are careful not to trust png_color to be in the
  512. * correct order for PNG, so people can redefine it to any convenient
  513. * structure.
  514. */
  515. void /* PRIVATE */
  516. png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
  517. {
  518. #ifdef PNG_USE_LOCAL_ARRAYS
  519. PNG_PLTE;
  520. #endif
  521. png_uint_32 i;
  522. png_colorp pal_ptr;
  523. png_byte buf[3];
  524. png_debug(1, "in png_write_PLTE");
  525. if ((
  526. #ifdef PNG_MNG_FEATURES_SUPPORTED
  527. !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
  528. #endif
  529. num_pal == 0) || num_pal > 256)
  530. {
  531. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  532. {
  533. png_error(png_ptr, "Invalid number of colors in palette");
  534. }
  535. else
  536. {
  537. png_warning(png_ptr, "Invalid number of colors in palette");
  538. return;
  539. }
  540. }
  541. if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
  542. {
  543. png_warning(png_ptr,
  544. "Ignoring request to write a PLTE chunk in grayscale PNG");
  545. return;
  546. }
  547. png_ptr->num_palette = (png_uint_16)num_pal;
  548. png_debug1(3, "num_palette = %d", png_ptr->num_palette);
  549. png_write_chunk_start(png_ptr, (png_bytep)png_PLTE,
  550. (png_uint_32)(num_pal * 3));
  551. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  552. for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
  553. {
  554. buf[0] = pal_ptr->red;
  555. buf[1] = pal_ptr->green;
  556. buf[2] = pal_ptr->blue;
  557. png_write_chunk_data(png_ptr, buf, (png_size_t)3);
  558. }
  559. #else
  560. /* This is a little slower but some buggy compilers need to do this
  561. * instead
  562. */
  563. pal_ptr=palette;
  564. for (i = 0; i < num_pal; i++)
  565. {
  566. buf[0] = pal_ptr[i].red;
  567. buf[1] = pal_ptr[i].green;
  568. buf[2] = pal_ptr[i].blue;
  569. png_write_chunk_data(png_ptr, buf, (png_size_t)3);
  570. }
  571. #endif
  572. png_write_chunk_end(png_ptr);
  573. png_ptr->mode |= PNG_HAVE_PLTE;
  574. }
  575. /* Write an IDAT chunk */
  576. void /* PRIVATE */
  577. png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
  578. {
  579. #ifdef PNG_USE_LOCAL_ARRAYS
  580. PNG_IDAT;
  581. #endif
  582. png_debug(1, "in png_write_IDAT");
  583. /* Optimize the CMF field in the zlib stream. */
  584. /* This hack of the zlib stream is compliant to the stream specification. */
  585. if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
  586. png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
  587. {
  588. unsigned int z_cmf = data[0]; /* zlib compression method and flags */
  589. if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
  590. {
  591. /* Avoid memory underflows and multiplication overflows.
  592. *
  593. * The conditions below are practically always satisfied;
  594. * however, they still must be checked.
  595. */
  596. if (length >= 2 &&
  597. png_ptr->height < 16384 && png_ptr->width < 16384)
  598. {
  599. png_uint_32 uncompressed_idat_size = png_ptr->height *
  600. ((png_ptr->width *
  601. png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
  602. unsigned int z_cinfo = z_cmf >> 4;
  603. unsigned int half_z_window_size = 1 << (z_cinfo + 7);
  604. while (uncompressed_idat_size <= half_z_window_size &&
  605. half_z_window_size >= 256)
  606. {
  607. z_cinfo--;
  608. half_z_window_size >>= 1;
  609. }
  610. z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
  611. if (data[0] != (png_byte)z_cmf)
  612. {
  613. data[0] = (png_byte)z_cmf;
  614. data[1] &= 0xe0;
  615. data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
  616. }
  617. }
  618. }
  619. else
  620. png_error(png_ptr,
  621. "Invalid zlib compression method or flags in IDAT");
  622. }
  623. png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
  624. png_ptr->mode |= PNG_HAVE_IDAT;
  625. }
  626. /* Write an IEND chunk */
  627. void /* PRIVATE */
  628. png_write_IEND(png_structp png_ptr)
  629. {
  630. #ifdef PNG_USE_LOCAL_ARRAYS
  631. PNG_IEND;
  632. #endif
  633. png_debug(1, "in png_write_IEND");
  634. png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
  635. (png_size_t)0);
  636. png_ptr->mode |= PNG_HAVE_IEND;
  637. }
  638. #ifdef PNG_WRITE_gAMA_SUPPORTED
  639. /* Write a gAMA chunk */
  640. #ifdef PNG_FLOATING_POINT_SUPPORTED
  641. void /* PRIVATE */
  642. png_write_gAMA(png_structp png_ptr, double file_gamma)
  643. {
  644. #ifdef PNG_USE_LOCAL_ARRAYS
  645. PNG_gAMA;
  646. #endif
  647. png_uint_32 igamma;
  648. png_byte buf[4];
  649. png_debug(1, "in png_write_gAMA");
  650. /* file_gamma is saved in 1/100,000ths */
  651. igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
  652. png_save_uint_32(buf, igamma);
  653. png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
  654. }
  655. #endif
  656. #ifdef PNG_FIXED_POINT_SUPPORTED
  657. void /* PRIVATE */
  658. png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
  659. {
  660. #ifdef PNG_USE_LOCAL_ARRAYS
  661. PNG_gAMA;
  662. #endif
  663. png_byte buf[4];
  664. png_debug(1, "in png_write_gAMA");
  665. /* file_gamma is saved in 1/100,000ths */
  666. png_save_uint_32(buf, (png_uint_32)file_gamma);
  667. png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
  668. }
  669. #endif
  670. #endif
  671. #ifdef PNG_WRITE_sRGB_SUPPORTED
  672. /* Write a sRGB chunk */
  673. void /* PRIVATE */
  674. png_write_sRGB(png_structp png_ptr, int srgb_intent)
  675. {
  676. #ifdef PNG_USE_LOCAL_ARRAYS
  677. PNG_sRGB;
  678. #endif
  679. png_byte buf[1];
  680. png_debug(1, "in png_write_sRGB");
  681. if (srgb_intent >= PNG_sRGB_INTENT_LAST)
  682. png_warning(png_ptr,
  683. "Invalid sRGB rendering intent specified");
  684. buf[0]=(png_byte)srgb_intent;
  685. png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
  686. }
  687. #endif
  688. #ifdef PNG_WRITE_iCCP_SUPPORTED
  689. /* Write an iCCP chunk */
  690. void /* PRIVATE */
  691. png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
  692. png_charp profile, int profile_len)
  693. {
  694. #ifdef PNG_USE_LOCAL_ARRAYS
  695. PNG_iCCP;
  696. #endif
  697. png_size_t name_len;
  698. png_charp new_name;
  699. compression_state comp;
  700. int embedded_profile_len = 0;
  701. png_debug(1, "in png_write_iCCP");
  702. comp.num_output_ptr = 0;
  703. comp.max_output_ptr = 0;
  704. comp.output_ptr = NULL;
  705. comp.input = NULL;
  706. comp.input_len = 0;
  707. if ((name_len = png_check_keyword(png_ptr, name,
  708. &new_name)) == 0)
  709. return;
  710. if (compression_type != PNG_COMPRESSION_TYPE_BASE)
  711. png_warning(png_ptr, "Unknown compression type in iCCP chunk");
  712. if (profile == NULL)
  713. profile_len = 0;
  714. if (profile_len > 3)
  715. embedded_profile_len =
  716. ((*( (png_bytep)profile ))<<24) |
  717. ((*( (png_bytep)profile + 1))<<16) |
  718. ((*( (png_bytep)profile + 2))<< 8) |
  719. ((*( (png_bytep)profile + 3)) );
  720. if (embedded_profile_len < 0)
  721. {
  722. png_warning(png_ptr,
  723. "Embedded profile length in iCCP chunk is negative");
  724. png_free(png_ptr, new_name);
  725. return;
  726. }
  727. if (profile_len < embedded_profile_len)
  728. {
  729. png_warning(png_ptr,
  730. "Embedded profile length too large in iCCP chunk");
  731. png_free(png_ptr, new_name);
  732. return;
  733. }
  734. if (profile_len > embedded_profile_len)
  735. {
  736. png_warning(png_ptr,
  737. "Truncating profile to actual length in iCCP chunk");
  738. profile_len = embedded_profile_len;
  739. }
  740. if (profile_len)
  741. profile_len = png_text_compress(png_ptr, profile,
  742. (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
  743. /* Make sure we include the NULL after the name and the compression type */
  744. png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
  745. (png_uint_32)(name_len + profile_len + 2));
  746. new_name[name_len + 1] = 0x00;
  747. png_write_chunk_data(png_ptr, (png_bytep)new_name,
  748. (png_size_t)(name_len + 2));
  749. if (profile_len)
  750. png_write_compressed_data_out(png_ptr, &comp);
  751. png_write_chunk_end(png_ptr);
  752. png_free(png_ptr, new_name);
  753. }
  754. #endif
  755. #ifdef PNG_WRITE_sPLT_SUPPORTED
  756. /* Write a sPLT chunk */
  757. void /* PRIVATE */
  758. png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
  759. {
  760. #ifdef PNG_USE_LOCAL_ARRAYS
  761. PNG_sPLT;
  762. #endif
  763. png_size_t name_len;
  764. png_charp new_name;
  765. png_byte entrybuf[10];
  766. int entry_size = (spalette->depth == 8 ? 6 : 10);
  767. int palette_size = entry_size * spalette->nentries;
  768. png_sPLT_entryp ep;
  769. #ifndef PNG_POINTER_INDEXING_SUPPORTED
  770. int i;
  771. #endif
  772. png_debug(1, "in png_write_sPLT");
  773. if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0)
  774. return;
  775. /* Make sure we include the NULL after the name */
  776. png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
  777. (png_uint_32)(name_len + 2 + palette_size));
  778. png_write_chunk_data(png_ptr, (png_bytep)new_name,
  779. (png_size_t)(name_len + 1));
  780. png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1);
  781. /* Loop through each palette entry, writing appropriately */
  782. #ifdef PNG_POINTER_INDEXING_SUPPORTED
  783. for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
  784. {
  785. if (spalette->depth == 8)
  786. {
  787. entrybuf[0] = (png_byte)ep->red;
  788. entrybuf[1] = (png_byte)ep->green;
  789. entrybuf[2] = (png_byte)ep->blue;
  790. entrybuf[3] = (png_byte)ep->alpha;
  791. png_save_uint_16(entrybuf + 4, ep->frequency);
  792. }
  793. else
  794. {
  795. png_save_uint_16(entrybuf + 0, ep->red);
  796. png_save_uint_16(entrybuf + 2, ep->green);
  797. png_save_uint_16(entrybuf + 4, ep->blue);
  798. png_save_uint_16(entrybuf + 6, ep->alpha);
  799. png_save_uint_16(entrybuf + 8, ep->frequency);
  800. }
  801. png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
  802. }
  803. #else
  804. ep=spalette->entries;
  805. for (i=0; i>spalette->nentries; i++)
  806. {
  807. if (spalette->depth == 8)
  808. {
  809. entrybuf[0] = (png_byte)ep[i].red;
  810. entrybuf[1] = (png_byte)ep[i].green;
  811. entrybuf[2] = (png_byte)ep[i].blue;
  812. entrybuf[3] = (png_byte)ep[i].alpha;
  813. png_save_uint_16(entrybuf + 4, ep[i].frequency);
  814. }
  815. else
  816. {
  817. png_save_uint_16(entrybuf + 0, ep[i].red);
  818. png_save_uint_16(entrybuf + 2, ep[i].green);
  819. png_save_uint_16(entrybuf + 4, ep[i].blue);
  820. png_save_uint_16(entrybuf + 6, ep[i].alpha);
  821. png_save_uint_16(entrybuf + 8, ep[i].frequency);
  822. }
  823. png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
  824. }
  825. #endif
  826. png_write_chunk_end(png_ptr);
  827. png_free(png_ptr, new_name);
  828. }
  829. #endif
  830. #ifdef PNG_WRITE_sBIT_SUPPORTED
  831. /* Write the sBIT chunk */
  832. void /* PRIVATE */
  833. png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
  834. {
  835. #ifdef PNG_USE_LOCAL_ARRAYS
  836. PNG_sBIT;
  837. #endif
  838. png_byte buf[4];
  839. png_size_t size;
  840. png_debug(1, "in png_write_sBIT");
  841. /* Make sure we don't depend upon the order of PNG_COLOR_8 */
  842. if (color_type & PNG_COLOR_MASK_COLOR)
  843. {
  844. png_byte maxbits;
  845. maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
  846. png_ptr->usr_bit_depth);
  847. if (sbit->red == 0 || sbit->red > maxbits ||
  848. sbit->green == 0 || sbit->green > maxbits ||
  849. sbit->blue == 0 || sbit->blue > maxbits)
  850. {
  851. png_warning(png_ptr, "Invalid sBIT depth specified");
  852. return;
  853. }
  854. buf[0] = sbit->red;
  855. buf[1] = sbit->green;
  856. buf[2] = sbit->blue;
  857. size = 3;
  858. }
  859. else
  860. {
  861. if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
  862. {
  863. png_warning(png_ptr, "Invalid sBIT depth specified");
  864. return;
  865. }
  866. buf[0] = sbit->gray;
  867. size = 1;
  868. }
  869. if (color_type & PNG_COLOR_MASK_ALPHA)
  870. {
  871. if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
  872. {
  873. png_warning(png_ptr, "Invalid sBIT depth specified");
  874. return;
  875. }
  876. buf[size++] = sbit->alpha;
  877. }
  878. png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
  879. }
  880. #endif
  881. #ifdef PNG_WRITE_cHRM_SUPPORTED
  882. /* Write the cHRM chunk */
  883. #ifdef PNG_FLOATING_POINT_SUPPORTED
  884. void /* PRIVATE */
  885. png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
  886. double red_x, double red_y, double green_x, double green_y,
  887. double blue_x, double blue_y)
  888. {
  889. #ifdef PNG_USE_LOCAL_ARRAYS
  890. PNG_cHRM;
  891. #endif
  892. png_byte buf[32];
  893. png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y,
  894. int_green_x, int_green_y, int_blue_x, int_blue_y;
  895. png_debug(1, "in png_write_cHRM");
  896. int_white_x = (png_uint_32)(white_x * 100000.0 + 0.5);
  897. int_white_y = (png_uint_32)(white_y * 100000.0 + 0.5);
  898. int_red_x = (png_uint_32)(red_x * 100000.0 + 0.5);
  899. int_red_y = (png_uint_32)(red_y * 100000.0 + 0.5);
  900. int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5);
  901. int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5);
  902. int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5);
  903. int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5);
  904. #ifdef PNG_CHECK_cHRM_SUPPORTED
  905. if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y,
  906. int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y))
  907. #endif
  908. {
  909. /* Each value is saved in 1/100,000ths */
  910. png_save_uint_32(buf, int_white_x);
  911. png_save_uint_32(buf + 4, int_white_y);
  912. png_save_uint_32(buf + 8, int_red_x);
  913. png_save_uint_32(buf + 12, int_red_y);
  914. png_save_uint_32(buf + 16, int_green_x);
  915. png_save_uint_32(buf + 20, int_green_y);
  916. png_save_uint_32(buf + 24, int_blue_x);
  917. png_save_uint_32(buf + 28, int_blue_y);
  918. png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
  919. }
  920. }
  921. #endif
  922. #ifdef PNG_FIXED_POINT_SUPPORTED
  923. void /* PRIVATE */
  924. png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
  925. png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
  926. png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
  927. png_fixed_point blue_y)
  928. {
  929. #ifdef PNG_USE_LOCAL_ARRAYS
  930. PNG_cHRM;
  931. #endif
  932. png_byte buf[32];
  933. png_debug(1, "in png_write_cHRM");
  934. /* Each value is saved in 1/100,000ths */
  935. #ifdef PNG_CHECK_cHRM_SUPPORTED
  936. if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y,
  937. green_x, green_y, blue_x, blue_y))
  938. #endif
  939. {
  940. png_save_uint_32(buf, (png_uint_32)white_x);
  941. png_save_uint_32(buf + 4, (png_uint_32)white_y);
  942. png_save_uint_32(buf + 8, (png_uint_32)red_x);
  943. png_save_uint_32(buf + 12, (png_uint_32)red_y);
  944. png_save_uint_32(buf + 16, (png_uint_32)green_x);
  945. png_save_uint_32(buf + 20, (png_uint_32)green_y);
  946. png_save_uint_32(buf + 24, (png_uint_32)blue_x);
  947. png_save_uint_32(buf + 28, (png_uint_32)blue_y);
  948. png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
  949. }
  950. }
  951. #endif
  952. #endif
  953. #ifdef PNG_WRITE_tRNS_SUPPORTED
  954. /* Write the tRNS chunk */
  955. void /* PRIVATE */
  956. png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
  957. int num_trans, int color_type)
  958. {
  959. #ifdef PNG_USE_LOCAL_ARRAYS
  960. PNG_tRNS;
  961. #endif
  962. png_byte buf[6];
  963. png_debug(1, "in png_write_tRNS");
  964. if (color_type == PNG_COLOR_TYPE_PALETTE)
  965. {
  966. if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
  967. {
  968. png_warning(png_ptr, "Invalid number of transparent colors specified");
  969. return;
  970. }
  971. /* Write the chunk out as it is */
  972. png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans,
  973. (png_size_t)num_trans);
  974. }
  975. else if (color_type == PNG_COLOR_TYPE_GRAY)
  976. {
  977. /* One 16 bit value */
  978. if (tran->gray >= (1 << png_ptr->bit_depth))
  979. {
  980. png_warning(png_ptr,
  981. "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
  982. return;
  983. }
  984. png_save_uint_16(buf, tran->gray);
  985. png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
  986. }
  987. else if (color_type == PNG_COLOR_TYPE_RGB)
  988. {
  989. /* Three 16 bit values */
  990. png_save_uint_16(buf, tran->red);
  991. png_save_uint_16(buf + 2, tran->green);
  992. png_save_uint_16(buf + 4, tran->blue);
  993. if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
  994. {
  995. png_warning(png_ptr,
  996. "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
  997. return;
  998. }
  999. png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
  1000. }
  1001. else
  1002. {
  1003. png_warning(png_ptr, "Can't write tRNS with an alpha channel");
  1004. }
  1005. }
  1006. #endif
  1007. #ifdef PNG_WRITE_bKGD_SUPPORTED
  1008. /* Write the background chunk */
  1009. void /* PRIVATE */
  1010. png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
  1011. {
  1012. #ifdef PNG_USE_LOCAL_ARRAYS
  1013. PNG_bKGD;
  1014. #endif
  1015. png_byte buf[6];
  1016. png_debug(1, "in png_write_bKGD");
  1017. if (color_type == PNG_COLOR_TYPE_PALETTE)
  1018. {
  1019. if (
  1020. #ifdef PNG_MNG_FEATURES_SUPPORTED
  1021. (png_ptr->num_palette ||
  1022. (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
  1023. #endif
  1024. back->index >= png_ptr->num_palette)
  1025. {
  1026. png_warning(png_ptr, "Invalid background palette index");
  1027. return;
  1028. }
  1029. buf[0] = back->index;
  1030. png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
  1031. }
  1032. else if (color_type & PNG_COLOR_MASK_COLOR)
  1033. {
  1034. png_save_uint_16(buf, back->red);
  1035. png_save_uint_16(buf + 2, back->green);
  1036. png_save_uint_16(buf + 4, back->blue);
  1037. if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
  1038. {
  1039. png_warning(png_ptr,
  1040. "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
  1041. return;
  1042. }
  1043. png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
  1044. }
  1045. else
  1046. {
  1047. if (back->gray >= (1 << png_ptr->bit_depth))
  1048. {
  1049. png_warning(png_ptr,
  1050. "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
  1051. return;
  1052. }
  1053. png_save_uint_16(buf, back->gray);
  1054. png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
  1055. }
  1056. }
  1057. #endif
  1058. #ifdef PNG_WRITE_hIST_SUPPORTED
  1059. /* Write the histogram */
  1060. void /* PRIVATE */
  1061. png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
  1062. {
  1063. #ifdef PNG_USE_LOCAL_ARRAYS
  1064. PNG_hIST;
  1065. #endif
  1066. int i;
  1067. png_byte buf[3];
  1068. png_debug(1, "in png_write_hIST");
  1069. if (num_hist > (int)png_ptr->num_palette)
  1070. {
  1071. png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
  1072. png_ptr->num_palette);
  1073. png_warning(png_ptr, "Invalid number of histogram entries specified");
  1074. return;
  1075. }
  1076. png_write_chunk_start(png_ptr, (png_bytep)png_hIST,
  1077. (png_uint_32)(num_hist * 2));
  1078. for (i = 0; i < num_hist; i++)
  1079. {
  1080. png_save_uint_16(buf, hist[i]);
  1081. png_write_chunk_data(png_ptr, buf, (png_size_t)2);
  1082. }
  1083. png_write_chunk_end(png_ptr);
  1084. }
  1085. #endif
  1086. #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
  1087. defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
  1088. /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
  1089. * and if invalid, correct the keyword rather than discarding the entire
  1090. * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
  1091. * length, forbids leading or trailing whitespace, multiple internal spaces,
  1092. * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
  1093. *
  1094. * The new_key is allocated to hold the corrected keyword and must be freed
  1095. * by the calling routine. This avoids problems with trying to write to
  1096. * static keywords without having to have duplicate copies of the strings.
  1097. */
  1098. png_size_t /* PRIVATE */
  1099. png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
  1100. {
  1101. png_size_t key_len;
  1102. png_charp kp, dp;
  1103. int kflag;
  1104. int kwarn=0;
  1105. png_debug(1, "in png_check_keyword");
  1106. *new_key = NULL;
  1107. if (key == NULL || (key_len = png_strlen(key)) == 0)
  1108. {
  1109. png_warning(png_ptr, "zero length keyword");
  1110. return ((png_size_t)0);
  1111. }
  1112. png_debug1(2, "Keyword to be checked is '%s'", key);
  1113. *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
  1114. if (*new_key == NULL)
  1115. {
  1116. png_warning(png_ptr, "Out of memory while procesing keyword");
  1117. return ((png_size_t)0);
  1118. }
  1119. /* Replace non-printing characters with a blank and print a warning */
  1120. for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
  1121. {
  1122. if ((png_byte)*kp < 0x20 ||
  1123. ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
  1124. {
  1125. #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
  1126. char msg[40];
  1127. png_snprintf(msg, 40,
  1128. "invalid keyword character 0x%02X", (png_byte)*kp);
  1129. png_warning(png_ptr, msg);
  1130. #else
  1131. png_warning(png_ptr, "invalid character in keyword");
  1132. #endif
  1133. *dp = ' ';
  1134. }
  1135. else
  1136. {
  1137. *dp = *kp;
  1138. }
  1139. }
  1140. *dp = '\0';
  1141. /* Remove any trailing white space. */
  1142. kp = *new_key + key_len - 1;
  1143. if (*kp == ' ')
  1144. {
  1145. png_warning(png_ptr, "trailing spaces removed from keyword");
  1146. while (*kp == ' ')
  1147. {
  1148. *(kp--) = '\0';
  1149. key_len--;
  1150. }
  1151. }
  1152. /* Remove any leading white space. */
  1153. kp = *new_key;
  1154. if (*kp == ' ')
  1155. {
  1156. png_warning(png_ptr, "leading spaces removed from keyword");
  1157. while (*kp == ' ')
  1158. {
  1159. kp++;
  1160. key_len--;
  1161. }
  1162. }
  1163. png_debug1(2, "Checking for multiple internal spaces in '%s'", kp);
  1164. /* Remove multiple internal spaces. */
  1165. for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
  1166. {
  1167. if (*kp == ' ' && kflag == 0)
  1168. {
  1169. *(dp++) = *kp;
  1170. kflag = 1;
  1171. }
  1172. else if (*kp == ' ')
  1173. {
  1174. key_len--;
  1175. kwarn=1;
  1176. }
  1177. else
  1178. {
  1179. *(dp++) = *kp;
  1180. kflag = 0;
  1181. }
  1182. }
  1183. *dp = '\0';
  1184. if (kwarn)
  1185. png_warning(png_ptr, "extra interior spaces removed from keyword");
  1186. if (key_len == 0)
  1187. {
  1188. png_free(png_ptr, *new_key);
  1189. *new_key=NULL;
  1190. png_warning(png_ptr, "Zero length keyword");
  1191. }
  1192. if (key_len > 79)
  1193. {
  1194. png_warning(png_ptr, "keyword length must be 1 - 79 characters");
  1195. (*new_key)[79] = '\0';
  1196. key_len = 79;
  1197. }
  1198. return (key_len);
  1199. }
  1200. #endif
  1201. #ifdef PNG_WRITE_tEXt_SUPPORTED
  1202. /* Write a tEXt chunk */
  1203. void /* PRIVATE */
  1204. png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
  1205. png_size_t text_len)
  1206. {
  1207. #ifdef PNG_USE_LOCAL_ARRAYS
  1208. PNG_tEXt;
  1209. #endif
  1210. png_size_t key_len;
  1211. png_charp new_key;
  1212. png_debug(1, "in png_write_tEXt");
  1213. if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
  1214. return;
  1215. if (text == NULL || *text == '\0')
  1216. text_len = 0;
  1217. else
  1218. text_len = png_strlen(text);
  1219. /* Make sure we include the 0 after the key */
  1220. png_write_chunk_start(png_ptr, (png_bytep)png_tEXt,
  1221. (png_uint_32)(key_len + text_len + 1));
  1222. /*
  1223. * We leave it to the application to meet PNG-1.0 requirements on the
  1224. * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
  1225. * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
  1226. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
  1227. */
  1228. png_write_chunk_data(png_ptr, (png_bytep)new_key,
  1229. (png_size_t)(key_len + 1));
  1230. if (text_len)
  1231. png_write_chunk_data(png_ptr, (png_bytep)text, (png_size_t)text_len);
  1232. png_write_chunk_end(png_ptr);
  1233. png_free(png_ptr, new_key);
  1234. }
  1235. #endif
  1236. #ifdef PNG_WRITE_zTXt_SUPPORTED
  1237. /* Write a compressed text chunk */
  1238. void /* PRIVATE */
  1239. png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
  1240. png_size_t text_len, int compression)
  1241. {
  1242. #ifdef PNG_USE_LOCAL_ARRAYS
  1243. PNG_zTXt;
  1244. #endif
  1245. png_size_t key_len;
  1246. char buf[1];
  1247. png_charp new_key;
  1248. compression_state comp;
  1249. png_debug(1, "in png_write_zTXt");
  1250. comp.num_output_ptr = 0;
  1251. comp.max_output_ptr = 0;
  1252. comp.output_ptr = NULL;
  1253. comp.input = NULL;
  1254. comp.input_len = 0;
  1255. if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
  1256. {
  1257. png_free(png_ptr, new_key);
  1258. return;
  1259. }
  1260. if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
  1261. {
  1262. png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
  1263. png_free(png_ptr, new_key);
  1264. return;
  1265. }
  1266. text_len = png_strlen(text);
  1267. /* Compute the compressed data; do it now for the length */
  1268. text_len = png_text_compress(png_ptr, text, text_len, compression,
  1269. &comp);
  1270. /* Write start of chunk */
  1271. png_write_chunk_start(png_ptr, (png_bytep)png_zTXt,
  1272. (png_uint_32)(key_len+text_len + 2));
  1273. /* Write key */
  1274. png_write_chunk_data(png_ptr, (png_bytep)new_key,
  1275. (png_size_t)(key_len + 1));
  1276. png_free(png_ptr, new_key);
  1277. buf[0] = (png_byte)compression;
  1278. /* Write compression */
  1279. png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
  1280. /* Write the compressed data */
  1281. png_write_compressed_data_out(png_ptr, &comp);
  1282. /* Close the chunk */
  1283. png_write_chunk_end(png_ptr);
  1284. }
  1285. #endif
  1286. #ifdef PNG_WRITE_iTXt_SUPPORTED
  1287. /* Write an iTXt chunk */
  1288. void /* PRIVATE */
  1289. png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
  1290. png_charp lang, png_charp lang_key, png_charp text)
  1291. {
  1292. #ifdef PNG_USE_LOCAL_ARRAYS
  1293. PNG_iTXt;
  1294. #endif
  1295. png_size_t lang_len, key_len, lang_key_len, text_len;
  1296. png_charp new_lang;
  1297. png_charp new_key = NULL;
  1298. png_byte cbuf[2];
  1299. compression_state comp;
  1300. png_debug(1, "in png_write_iTXt");
  1301. comp.num_output_ptr = 0;
  1302. comp.max_output_ptr = 0;
  1303. comp.output_ptr = NULL;
  1304. comp.input = NULL;
  1305. if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0)
  1306. return;
  1307. if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
  1308. {
  1309. png_warning(png_ptr, "Empty language field in iTXt chunk");
  1310. new_lang = NULL;
  1311. lang_len = 0;
  1312. }
  1313. if (lang_key == NULL)
  1314. lang_key_len = 0;
  1315. else
  1316. lang_key_len = png_strlen(lang_key);
  1317. if (text == NULL)
  1318. text_len = 0;
  1319. else
  1320. text_len = png_strlen(text);
  1321. /* Compute the compressed data; do it now for the length */
  1322. text_len = png_text_compress(png_ptr, text, text_len, compression-2,
  1323. &comp);
  1324. /* Make sure we include the compression flag, the compression byte,
  1325. * and the NULs after the key, lang, and lang_key parts */
  1326. png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
  1327. (png_uint_32)(
  1328. 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
  1329. + key_len
  1330. + lang_len
  1331. + lang_key_len
  1332. + text_len));
  1333. /* We leave it to the application to meet PNG-1.0 requirements on the
  1334. * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
  1335. * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
  1336. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
  1337. */
  1338. png_write_chunk_data(png_ptr, (png_bytep)new_key,
  1339. (png_size_t)(key_len + 1));
  1340. /* Set the compression flag */
  1341. if (compression == PNG_ITXT_COMPRESSION_NONE || \
  1342. compression == PNG_TEXT_COMPRESSION_NONE)
  1343. cbuf[0] = 0;
  1344. else /* compression == PNG_ITXT_COMPRESSION_zTXt */
  1345. cbuf[0] = 1;
  1346. /* Set the compression method */
  1347. cbuf[1] = 0;
  1348. png_write_chunk_data(png_ptr, cbuf, (png_size_t)2);
  1349. cbuf[0] = 0;
  1350. png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf),
  1351. (png_size_t)(lang_len + 1));
  1352. png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf),
  1353. (png_size_t)(lang_key_len + 1));
  1354. png_write_compressed_data_out(png_ptr, &comp);
  1355. png_write_chunk_end(png_ptr);
  1356. png_free(png_ptr, new_key);
  1357. png_free(png_ptr, new_lang);
  1358. }
  1359. #endif
  1360. #ifdef PNG_WRITE_oFFs_SUPPORTED
  1361. /* Write the oFFs chunk */
  1362. void /* PRIVATE */
  1363. png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
  1364. int unit_type)
  1365. {
  1366. #ifdef PNG_USE_LOCAL_ARRAYS
  1367. PNG_oFFs;
  1368. #endif
  1369. png_byte buf[9];
  1370. png_debug(1, "in png_write_oFFs");
  1371. if (unit_type >= PNG_OFFSET_LAST)
  1372. png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
  1373. png_save_int_32(buf, x_offset);
  1374. png_save_int_32(buf + 4, y_offset);
  1375. buf[8] = (png_byte)unit_type;
  1376. png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
  1377. }
  1378. #endif
  1379. #ifdef PNG_WRITE_pCAL_SUPPORTED
  1380. /* Write the pCAL chunk (described in the PNG extensions document) */
  1381. void /* PRIVATE */
  1382. png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
  1383. png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
  1384. {
  1385. #ifdef PNG_USE_LOCAL_ARRAYS
  1386. PNG_pCAL;
  1387. #endif
  1388. png_size_t purpose_len, units_len, total_len;
  1389. png_uint_32p params_len;
  1390. png_byte buf[10];
  1391. png_charp new_purpose;
  1392. int i;
  1393. png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
  1394. if (type >= PNG_EQUATION_LAST)
  1395. png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
  1396. purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
  1397. png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
  1398. units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
  1399. png_debug1(3, "pCAL units length = %d", (int)units_len);
  1400. total_len = purpose_len + units_len + 10;
  1401. params_len = (png_uint_32p)png_malloc(png_ptr,
  1402. (png_uint_32)(nparams * png_sizeof(png_uint_32)));
  1403. /* Find the length of each parameter, making sure we don't count the
  1404. null terminator for the last parameter. */
  1405. for (i = 0; i < nparams; i++)
  1406. {
  1407. params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
  1408. png_debug2(3, "pCAL parameter %d length = %lu", i,
  1409. (unsigned long) params_len[i]);
  1410. total_len += (png_size_t)params_len[i];
  1411. }
  1412. png_debug1(3, "pCAL total length = %d", (int)total_len);
  1413. png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
  1414. png_write_chunk_data(png_ptr, (png_bytep)new_purpose,
  1415. (png_size_t)purpose_len);
  1416. png_save_int_32(buf, X0);
  1417. png_save_int_32(buf + 4, X1);
  1418. buf[8] = (png_byte)type;
  1419. buf[9] = (png_byte)nparams;
  1420. png_write_chunk_data(png_ptr, buf, (png_size_t)10);
  1421. png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
  1422. png_free(png_ptr, new_purpose);
  1423. for (i = 0; i < nparams; i++)
  1424. {
  1425. png_write_chunk_data(png_ptr, (png_bytep)params[i],
  1426. (png_size_t)params_len[i]);
  1427. }
  1428. png_free(png_ptr, params_len);
  1429. png_write_chunk_end(png_ptr);
  1430. }
  1431. #endif
  1432. #ifdef PNG_WRITE_sCAL_SUPPORTED
  1433. /* Write the sCAL chunk */
  1434. #if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
  1435. void /* PRIVATE */
  1436. png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
  1437. {
  1438. #ifdef PNG_USE_LOCAL_ARRAYS
  1439. PNG_sCAL;
  1440. #endif
  1441. char buf[64];
  1442. png_size_t total_len;
  1443. png_debug(1, "in png_write_sCAL");
  1444. buf[0] = (char)unit;
  1445. #ifdef _WIN32_WCE
  1446. /* sprintf() function is not supported on WindowsCE */
  1447. {
  1448. wchar_t wc_buf[32];
  1449. size_t wc_len;
  1450. swprintf(wc_buf, TEXT("%12.12e"), width);
  1451. wc_len = wcslen(wc_buf);
  1452. WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL,
  1453. NULL);
  1454. total_len = wc_len + 2;
  1455. swprintf(wc_buf, TEXT("%12.12e"), height);
  1456. wc_len = wcslen(wc_buf);
  1457. WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
  1458. NULL, NULL);
  1459. total_len += wc_len;
  1460. }
  1461. #else
  1462. png_snprintf(buf + 1, 63, "%12.12e", width);
  1463. total_len = 1 + png_strlen(buf + 1) + 1;
  1464. png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
  1465. total_len += png_strlen(buf + total_len);
  1466. #endif
  1467. png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
  1468. png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len);
  1469. }
  1470. #else
  1471. #ifdef PNG_FIXED_POINT_SUPPORTED
  1472. void /* PRIVATE */
  1473. png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
  1474. png_charp height)
  1475. {
  1476. #ifdef PNG_USE_LOCAL_ARRAYS
  1477. PNG_sCAL;
  1478. #endif
  1479. png_byte buf[64];
  1480. png_size_t wlen, hlen, total_len;
  1481. png_debug(1, "in png_write_sCAL_s");
  1482. wlen = png_strlen(width);
  1483. hlen = png_strlen(height);
  1484. total_len = wlen + hlen + 2;
  1485. if (total_len > 64)
  1486. {
  1487. png_warning(png_ptr, "Can't write sCAL (buffer too small)");
  1488. return;
  1489. }
  1490. buf[0] = (png_byte)unit;
  1491. png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
  1492. png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
  1493. png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
  1494. png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len);
  1495. }
  1496. #endif
  1497. #endif
  1498. #endif
  1499. #ifdef PNG_WRITE_pHYs_SUPPORTED
  1500. /* Write the pHYs chunk */
  1501. void /* PRIVATE */
  1502. png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
  1503. png_uint_32 y_pixels_per_unit,
  1504. int unit_type)
  1505. {
  1506. #ifdef PNG_USE_LOCAL_ARRAYS
  1507. PNG_pHYs;
  1508. #endif
  1509. png_byte buf[9];
  1510. png_debug(1, "in png_write_pHYs");
  1511. if (unit_type >= PNG_RESOLUTION_LAST)
  1512. png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
  1513. png_save_uint_32(buf, x_pixels_per_unit);
  1514. png_save_uint_32(buf + 4, y_pixels_per_unit);
  1515. buf[8] = (png_byte)unit_type;
  1516. png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
  1517. }
  1518. #endif
  1519. #ifdef PNG_WRITE_tIME_SUPPORTED
  1520. /* Write the tIME chunk. Use either png_convert_from_struct_tm()
  1521. * or png_convert_from_time_t(), or fill in the structure yourself.
  1522. */
  1523. void /* PRIVATE */
  1524. png_write_tIME(png_structp png_ptr, png_timep mod_time)
  1525. {
  1526. #ifdef PNG_USE_LOCAL_ARRAYS
  1527. PNG_tIME;
  1528. #endif
  1529. png_byte buf[7];
  1530. png_debug(1, "in png_write_tIME");
  1531. if (mod_time->month > 12 || mod_time->month < 1 ||
  1532. mod_time->day > 31 || mod_time->day < 1 ||
  1533. mod_time->hour > 23 || mod_time->second > 60)
  1534. {
  1535. png_warning(png_ptr, "Invalid time specified for tIME chunk");
  1536. return;
  1537. }
  1538. png_save_uint_16(buf, mod_time->year);
  1539. buf[2] = mod_time->month;
  1540. buf[3] = mod_time->day;
  1541. buf[4] = mod_time->hour;
  1542. buf[5] = mod_time->minute;
  1543. buf[6] = mod_time->second;
  1544. png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
  1545. }
  1546. #endif
  1547. /* Initializes the row writing capability of libpng */
  1548. void /* PRIVATE */
  1549. png_write_start_row(png_structp png_ptr)
  1550. {
  1551. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  1552. /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1553. /* Start of interlace block */
  1554. int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  1555. /* Offset to next interlace block */
  1556. int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  1557. /* Start of interlace block in the y direction */
  1558. int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  1559. /* Offset to next interlace block in the y direction */
  1560. int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  1561. #endif
  1562. png_size_t buf_size;
  1563. png_debug(1, "in png_write_start_row");
  1564. buf_size = (png_size_t)(PNG_ROWBYTES(
  1565. png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1);
  1566. /* Set up row buffer */
  1567. png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
  1568. (png_uint_32)buf_size);
  1569. png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
  1570. #ifdef PNG_WRITE_FILTER_SUPPORTED
  1571. /* Set up filtering buffer, if using this filter */
  1572. if (png_ptr->do_filter & PNG_FILTER_SUB)
  1573. {
  1574. png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
  1575. (png_uint_32)(png_ptr->rowbytes + 1));
  1576. png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
  1577. }
  1578. /* We only need to keep the previous row if we are using one of these. */
  1579. if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
  1580. {
  1581. /* Set up previous row buffer */
  1582. png_ptr->prev_row = (png_bytep)png_calloc(png_ptr,
  1583. (png_uint_32)buf_size);
  1584. if (png_ptr->do_filter & PNG_FILTER_UP)
  1585. {
  1586. png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
  1587. (png_uint_32)(png_ptr->rowbytes + 1));
  1588. png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
  1589. }
  1590. if (png_ptr->do_filter & PNG_FILTER_AVG)
  1591. {
  1592. png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
  1593. (png_uint_32)(png_ptr->rowbytes + 1));
  1594. png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
  1595. }
  1596. if (png_ptr->do_filter & PNG_FILTER_PAETH)
  1597. {
  1598. png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
  1599. (png_uint_32)(png_ptr->rowbytes + 1));
  1600. png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
  1601. }
  1602. }
  1603. #endif /* PNG_WRITE_FILTER_SUPPORTED */
  1604. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  1605. /* If interlaced, we need to set up width and height of pass */
  1606. if (png_ptr->interlaced)
  1607. {
  1608. if (!(png_ptr->transformations & PNG_INTERLACE))
  1609. {
  1610. png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  1611. png_pass_ystart[0]) / png_pass_yinc[0];
  1612. png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
  1613. png_pass_start[0]) / png_pass_inc[0];
  1614. }
  1615. else
  1616. {
  1617. png_ptr->num_rows = png_ptr->height;
  1618. png_ptr->usr_width = png_ptr->width;
  1619. }
  1620. }
  1621. else
  1622. #endif
  1623. {
  1624. png_ptr->num_rows = png_ptr->height;
  1625. png_ptr->usr_width = png_ptr->width;
  1626. }
  1627. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1628. png_ptr->zstream.next_out = png_ptr->zbuf;
  1629. }
  1630. /* Internal use only. Called when finished processing a row of data. */
  1631. void /* PRIVATE */
  1632. png_write_finish_row(png_structp png_ptr)
  1633. {
  1634. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  1635. /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1636. /* Start of interlace block */
  1637. int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  1638. /* Offset to next interlace block */
  1639. int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  1640. /* Start of interlace block in the y direction */
  1641. int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
  1642. /* Offset to next interlace block in the y direction */
  1643. int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
  1644. #endif
  1645. int ret;
  1646. png_debug(1, "in png_write_finish_row");
  1647. /* Next row */
  1648. png_ptr->row_number++;
  1649. /* See if we are done */
  1650. if (png_ptr->row_number < png_ptr->num_rows)
  1651. return;
  1652. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  1653. /* If interlaced, go to next pass */
  1654. if (png_ptr->interlaced)
  1655. {
  1656. png_ptr->row_number = 0;
  1657. if (png_ptr->transformations & PNG_INTERLACE)
  1658. {
  1659. png_ptr->pass++;
  1660. }
  1661. else
  1662. {
  1663. /* Loop until we find a non-zero width or height pass */
  1664. do
  1665. {
  1666. png_ptr->pass++;
  1667. if (png_ptr->pass >= 7)
  1668. break;
  1669. png_ptr->usr_width = (png_ptr->width +
  1670. png_pass_inc[png_ptr->pass] - 1 -
  1671. png_pass_start[png_ptr->pass]) /
  1672. png_pass_inc[png_ptr->pass];
  1673. png_ptr->num_rows = (png_ptr->height +
  1674. png_pass_yinc[png_ptr->pass] - 1 -
  1675. png_pass_ystart[png_ptr->pass]) /
  1676. png_pass_yinc[png_ptr->pass];
  1677. if (png_ptr->transformations & PNG_INTERLACE)
  1678. break;
  1679. } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
  1680. }
  1681. /* Reset the row above the image for the next pass */
  1682. if (png_ptr->pass < 7)
  1683. {
  1684. if (png_ptr->prev_row != NULL)
  1685. png_memset(png_ptr->prev_row, 0,
  1686. (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
  1687. png_ptr->usr_bit_depth, png_ptr->width)) + 1);
  1688. return;
  1689. }
  1690. }
  1691. #endif
  1692. /* If we get here, we've just written the last row, so we need
  1693. to flush the compressor */
  1694. do
  1695. {
  1696. /* Tell the compressor we are done */
  1697. ret = deflate(&png_ptr->zstream, Z_FINISH);
  1698. /* Check for an error */
  1699. if (ret == Z_OK)
  1700. {
  1701. /* Check to see if we need more room */
  1702. if (!(png_ptr->zstream.avail_out))
  1703. {
  1704. png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  1705. png_ptr->zstream.next_out = png_ptr->zbuf;
  1706. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1707. }
  1708. }
  1709. else if (ret != Z_STREAM_END)
  1710. {
  1711. if (png_ptr->zstream.msg != NULL)
  1712. png_error(png_ptr, png_ptr->zstream.msg);
  1713. else
  1714. png_error(png_ptr, "zlib error");
  1715. }
  1716. } while (ret != Z_STREAM_END);
  1717. /* Write any extra space */
  1718. if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
  1719. {
  1720. png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
  1721. png_ptr->zstream.avail_out);
  1722. }
  1723. deflateReset(&png_ptr->zstream);
  1724. png_ptr->zstream.data_type = Z_BINARY;
  1725. }
  1726. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  1727. /* Pick out the correct pixels for the interlace pass.
  1728. * The basic idea here is to go through the row with a source
  1729. * pointer and a destination pointer (sp and dp), and copy the
  1730. * correct pixels for the pass. As the row gets compacted,
  1731. * sp will always be >= dp, so we should never overwrite anything.
  1732. * See the default: case for the easiest code to understand.
  1733. */
  1734. void /* PRIVATE */
  1735. png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
  1736. {
  1737. /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1738. /* Start of interlace block */
  1739. int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
  1740. /* Offset to next interlace block */
  1741. int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
  1742. png_debug(1, "in png_do_write_interlace");
  1743. /* We don't have to do anything on the last pass (6) */
  1744. #ifdef PNG_USELESS_TESTS_SUPPORTED
  1745. if (row != NULL && row_info != NULL && pass < 6)
  1746. #else
  1747. if (pass < 6)
  1748. #endif
  1749. {
  1750. /* Each pixel depth is handled separately */
  1751. switch (row_info->pixel_depth)
  1752. {
  1753. case 1:
  1754. {
  1755. png_bytep sp;
  1756. png_bytep dp;
  1757. int shift;
  1758. int d;
  1759. int value;
  1760. png_uint_32 i;
  1761. png_uint_32 row_width = row_info->width;
  1762. dp = row;
  1763. d = 0;
  1764. shift = 7;
  1765. for (i = png_pass_start[pass]; i < row_width;
  1766. i += png_pass_inc[pass])
  1767. {
  1768. sp = row + (png_size_t)(i >> 3);
  1769. value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
  1770. d |= (value << shift);
  1771. if (shift == 0)
  1772. {
  1773. shift = 7;
  1774. *dp++ = (png_byte)d;
  1775. d = 0;
  1776. }
  1777. else
  1778. shift--;
  1779. }
  1780. if (shift != 7)
  1781. *dp = (png_byte)d;
  1782. break;
  1783. }
  1784. case 2:
  1785. {
  1786. png_bytep sp;
  1787. png_bytep dp;
  1788. int shift;
  1789. int d;
  1790. int value;
  1791. png_uint_32 i;
  1792. png_uint_32 row_width = row_info->width;
  1793. dp = row;
  1794. shift = 6;
  1795. d = 0;
  1796. for (i = png_pass_start[pass]; i < row_width;
  1797. i += png_pass_inc[pass])
  1798. {
  1799. sp = row + (png_size_t)(i >> 2);
  1800. value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
  1801. d |= (value << shift);
  1802. if (shift == 0)
  1803. {
  1804. shift = 6;
  1805. *dp++ = (png_byte)d;
  1806. d = 0;
  1807. }
  1808. else
  1809. shift -= 2;
  1810. }
  1811. if (shift != 6)
  1812. *dp = (png_byte)d;
  1813. break;
  1814. }
  1815. case 4:
  1816. {
  1817. png_bytep sp;
  1818. png_bytep dp;
  1819. int shift;
  1820. int d;
  1821. int value;
  1822. png_uint_32 i;
  1823. png_uint_32 row_width = row_info->width;
  1824. dp = row;
  1825. shift = 4;
  1826. d = 0;
  1827. for (i = png_pass_start[pass]; i < row_width;
  1828. i += png_pass_inc[pass])
  1829. {
  1830. sp = row + (png_size_t)(i >> 1);
  1831. value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
  1832. d |= (value << shift);
  1833. if (shift == 0)
  1834. {
  1835. shift = 4;
  1836. *dp++ = (png_byte)d;
  1837. d = 0;
  1838. }
  1839. else
  1840. shift -= 4;
  1841. }
  1842. if (shift != 4)
  1843. *dp = (png_byte)d;
  1844. break;
  1845. }
  1846. default:
  1847. {
  1848. png_bytep sp;
  1849. png_bytep dp;
  1850. png_uint_32 i;
  1851. png_uint_32 row_width = row_info->width;
  1852. png_size_t pixel_bytes;
  1853. /* Start at the beginning */
  1854. dp = row;
  1855. /* Find out how many bytes each pixel takes up */
  1856. pixel_bytes = (row_info->pixel_depth >> 3);
  1857. /* Loop through the row, only looking at the pixels that
  1858. matter */
  1859. for (i = png_pass_start[pass]; i < row_width;
  1860. i += png_pass_inc[pass])
  1861. {
  1862. /* Find out where the original pixel is */
  1863. sp = row + (png_size_t)i * pixel_bytes;
  1864. /* Move the pixel */
  1865. if (dp != sp)
  1866. png_memcpy(dp, sp, pixel_bytes);
  1867. /* Next pixel */
  1868. dp += pixel_bytes;
  1869. }
  1870. break;
  1871. }
  1872. }
  1873. /* Set new row width */
  1874. row_info->width = (row_info->width +
  1875. png_pass_inc[pass] - 1 -
  1876. png_pass_start[pass]) /
  1877. png_pass_inc[pass];
  1878. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
  1879. row_info->width);
  1880. }
  1881. }
  1882. #endif
  1883. /* This filters the row, chooses which filter to use, if it has not already
  1884. * been specified by the application, and then writes the row out with the
  1885. * chosen filter.
  1886. */
  1887. #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
  1888. #define PNG_HISHIFT 10
  1889. #define PNG_LOMASK ((png_uint_32)0xffffL)
  1890. #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
  1891. void /* PRIVATE */
  1892. png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
  1893. {
  1894. png_bytep best_row;
  1895. #ifdef PNG_WRITE_FILTER_SUPPORTED
  1896. png_bytep prev_row, row_buf;
  1897. png_uint_32 mins, bpp;
  1898. png_byte filter_to_do = png_ptr->do_filter;
  1899. png_uint_32 row_bytes = row_info->rowbytes;
  1900. #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
  1901. int num_p_filters = (int)png_ptr->num_prev_filters;
  1902. #endif
  1903. png_debug(1, "in png_write_find_filter");
  1904. #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
  1905. if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
  1906. {
  1907. /* These will never be selected so we need not test them. */
  1908. filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
  1909. }
  1910. #e