/media/libpng/pngset.c

http://github.com/zpao/v8monkey · C · 1319 lines · 1090 code · 168 blank · 61 comment · 267 complexity · 2daf7da68d78f4ea45bc25f97cbc8c06 MD5 · raw file

  1. /* pngset.c - storage of image information into info struct
  2. *
  3. * Last changed in libpng 1.4.6 [January 14, 2011]
  4. * Copyright (c) 1998-2011 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. * The functions here are used during reads to store data from the file
  13. * into the info struct, and during writes to store application data
  14. * into the info struct for writing into the file. This abstracts the
  15. * info struct and allows us to change the structure in the future.
  16. */
  17. #define PNG_NO_PEDANTIC_WARNINGS
  18. #include "png.h"
  19. #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  20. #include "pngpriv.h"
  21. #ifdef PNG_bKGD_SUPPORTED
  22. void PNGAPI
  23. png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
  24. {
  25. png_debug1(1, "in %s storage function", "bKGD");
  26. if (png_ptr == NULL || info_ptr == NULL)
  27. return;
  28. png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
  29. info_ptr->valid |= PNG_INFO_bKGD;
  30. }
  31. #endif
  32. #ifdef PNG_cHRM_SUPPORTED
  33. #ifdef PNG_FLOATING_POINT_SUPPORTED
  34. void PNGAPI
  35. png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
  36. double white_x, double white_y, double red_x, double red_y,
  37. double green_x, double green_y, double blue_x, double blue_y)
  38. {
  39. png_debug1(1, "in %s storage function", "cHRM");
  40. if (png_ptr == NULL || info_ptr == NULL)
  41. return;
  42. info_ptr->x_white = (float)white_x;
  43. info_ptr->y_white = (float)white_y;
  44. info_ptr->x_red = (float)red_x;
  45. info_ptr->y_red = (float)red_y;
  46. info_ptr->x_green = (float)green_x;
  47. info_ptr->y_green = (float)green_y;
  48. info_ptr->x_blue = (float)blue_x;
  49. info_ptr->y_blue = (float)blue_y;
  50. #ifdef PNG_FIXED_POINT_SUPPORTED
  51. info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
  52. info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
  53. info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5);
  54. info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5);
  55. info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
  56. info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
  57. info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5);
  58. info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5);
  59. #endif
  60. info_ptr->valid |= PNG_INFO_cHRM;
  61. }
  62. #endif /* PNG_FLOATING_POINT_SUPPORTED */
  63. #ifdef PNG_FIXED_POINT_SUPPORTED
  64. void PNGAPI
  65. png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
  66. png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
  67. png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
  68. png_fixed_point blue_x, png_fixed_point blue_y)
  69. {
  70. png_debug1(1, "in %s storage function", "cHRM fixed");
  71. if (png_ptr == NULL || info_ptr == NULL)
  72. return;
  73. #ifdef PNG_CHECK_cHRM_SUPPORTED
  74. if (png_check_cHRM_fixed(png_ptr,
  75. white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
  76. #endif
  77. {
  78. info_ptr->int_x_white = white_x;
  79. info_ptr->int_y_white = white_y;
  80. info_ptr->int_x_red = red_x;
  81. info_ptr->int_y_red = red_y;
  82. info_ptr->int_x_green = green_x;
  83. info_ptr->int_y_green = green_y;
  84. info_ptr->int_x_blue = blue_x;
  85. info_ptr->int_y_blue = blue_y;
  86. #ifdef PNG_FLOATING_POINT_SUPPORTED
  87. info_ptr->x_white = (float)(white_x/100000.);
  88. info_ptr->y_white = (float)(white_y/100000.);
  89. info_ptr->x_red = (float)( red_x/100000.);
  90. info_ptr->y_red = (float)( red_y/100000.);
  91. info_ptr->x_green = (float)(green_x/100000.);
  92. info_ptr->y_green = (float)(green_y/100000.);
  93. info_ptr->x_blue = (float)( blue_x/100000.);
  94. info_ptr->y_blue = (float)( blue_y/100000.);
  95. #endif
  96. info_ptr->valid |= PNG_INFO_cHRM;
  97. }
  98. }
  99. #endif /* PNG_FIXED_POINT_SUPPORTED */
  100. #endif /* PNG_cHRM_SUPPORTED */
  101. #ifdef PNG_gAMA_SUPPORTED
  102. #ifdef PNG_FLOATING_POINT_SUPPORTED
  103. void PNGAPI
  104. png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
  105. {
  106. double png_gamma;
  107. png_debug1(1, "in %s storage function", "gAMA");
  108. if (png_ptr == NULL || info_ptr == NULL)
  109. return;
  110. /* Check for overflow */
  111. if (file_gamma > 21474.83)
  112. {
  113. png_warning(png_ptr, "Limiting gamma to 21474.83");
  114. png_gamma=21474.83;
  115. }
  116. else
  117. png_gamma = file_gamma;
  118. info_ptr->gamma = (float)png_gamma;
  119. #ifdef PNG_FIXED_POINT_SUPPORTED
  120. info_ptr->int_gamma = (int)(png_gamma*100000.+.5);
  121. #endif
  122. info_ptr->valid |= PNG_INFO_gAMA;
  123. if (png_gamma == 0.0)
  124. png_warning(png_ptr, "Setting gamma=0");
  125. }
  126. #endif
  127. void PNGAPI
  128. png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
  129. int_gamma)
  130. {
  131. png_fixed_point png_gamma;
  132. png_debug1(1, "in %s storage function", "gAMA");
  133. if (png_ptr == NULL || info_ptr == NULL)
  134. return;
  135. if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX)
  136. {
  137. png_warning(png_ptr, "Limiting gamma to 21474.83");
  138. png_gamma=PNG_UINT_31_MAX;
  139. }
  140. else
  141. {
  142. if (int_gamma < 0)
  143. {
  144. png_warning(png_ptr, "Setting negative gamma to zero");
  145. png_gamma = 0;
  146. }
  147. else
  148. png_gamma = int_gamma;
  149. }
  150. #ifdef PNG_FLOATING_POINT_SUPPORTED
  151. info_ptr->gamma = (float)(png_gamma/100000.);
  152. #endif
  153. #ifdef PNG_FIXED_POINT_SUPPORTED
  154. info_ptr->int_gamma = png_gamma;
  155. #endif
  156. info_ptr->valid |= PNG_INFO_gAMA;
  157. if (png_gamma == 0)
  158. png_warning(png_ptr, "Setting gamma=0");
  159. }
  160. #endif
  161. #ifdef PNG_hIST_SUPPORTED
  162. void PNGAPI
  163. png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
  164. {
  165. int i;
  166. png_debug1(1, "in %s storage function", "hIST");
  167. if (png_ptr == NULL || info_ptr == NULL)
  168. return;
  169. if (info_ptr->num_palette == 0 || info_ptr->num_palette
  170. > PNG_MAX_PALETTE_LENGTH)
  171. {
  172. png_warning(png_ptr,
  173. "Invalid palette size, hIST allocation skipped");
  174. return;
  175. }
  176. png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
  177. /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
  178. * version 1.2.1
  179. */
  180. png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
  181. PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
  182. if (png_ptr->hist == NULL)
  183. {
  184. png_warning(png_ptr, "Insufficient memory for hIST chunk data");
  185. return;
  186. }
  187. for (i = 0; i < info_ptr->num_palette; i++)
  188. png_ptr->hist[i] = hist[i];
  189. info_ptr->hist = png_ptr->hist;
  190. info_ptr->valid |= PNG_INFO_hIST;
  191. info_ptr->free_me |= PNG_FREE_HIST;
  192. }
  193. #endif
  194. void PNGAPI
  195. png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
  196. png_uint_32 width, png_uint_32 height, int bit_depth,
  197. int color_type, int interlace_type, int compression_type,
  198. int filter_type)
  199. {
  200. png_debug1(1, "in %s storage function", "IHDR");
  201. if (png_ptr == NULL || info_ptr == NULL)
  202. return;
  203. info_ptr->width = width;
  204. info_ptr->height = height;
  205. info_ptr->bit_depth = (png_byte)bit_depth;
  206. info_ptr->color_type = (png_byte)color_type;
  207. info_ptr->compression_type = (png_byte)compression_type;
  208. info_ptr->filter_type = (png_byte)filter_type;
  209. info_ptr->interlace_type = (png_byte)interlace_type;
  210. png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
  211. info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
  212. info_ptr->compression_type, info_ptr->filter_type);
  213. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  214. info_ptr->channels = 1;
  215. else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  216. info_ptr->channels = 3;
  217. else
  218. info_ptr->channels = 1;
  219. if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  220. info_ptr->channels++;
  221. info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
  222. /* Check for potential overflow */
  223. if (width > (PNG_UINT_32_MAX
  224. >> 3) /* 8-byte RGBA pixels */
  225. - 64 /* bigrowbuf hack */
  226. - 1 /* filter byte */
  227. - 7*8 /* rounding of width to multiple of 8 pixels */
  228. - 8) /* extra max_pixel_depth pad */
  229. info_ptr->rowbytes = 0;
  230. else
  231. info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
  232. #if defined(PNG_APNG_SUPPORTED)
  233. /* for non-animated png. this may be overwritten from an acTL chunk later */
  234. info_ptr->num_frames = 1;
  235. #endif
  236. }
  237. #ifdef PNG_oFFs_SUPPORTED
  238. void PNGAPI
  239. png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
  240. png_int_32 offset_x, png_int_32 offset_y, int unit_type)
  241. {
  242. png_debug1(1, "in %s storage function", "oFFs");
  243. if (png_ptr == NULL || info_ptr == NULL)
  244. return;
  245. info_ptr->x_offset = offset_x;
  246. info_ptr->y_offset = offset_y;
  247. info_ptr->offset_unit_type = (png_byte)unit_type;
  248. info_ptr->valid |= PNG_INFO_oFFs;
  249. }
  250. #endif
  251. #ifdef PNG_pCAL_SUPPORTED
  252. void PNGAPI
  253. png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
  254. png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
  255. png_charp units, png_charpp params)
  256. {
  257. png_size_t length;
  258. int i;
  259. png_debug1(1, "in %s storage function", "pCAL");
  260. if (png_ptr == NULL || info_ptr == NULL)
  261. return;
  262. length = png_strlen(purpose) + 1;
  263. png_debug1(3, "allocating purpose for info (%lu bytes)",
  264. (unsigned long)length);
  265. info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
  266. if (info_ptr->pcal_purpose == NULL)
  267. {
  268. png_warning(png_ptr, "Insufficient memory for pCAL purpose");
  269. return;
  270. }
  271. png_memcpy(info_ptr->pcal_purpose, purpose, length);
  272. png_debug(3, "storing X0, X1, type, and nparams in info");
  273. info_ptr->pcal_X0 = X0;
  274. info_ptr->pcal_X1 = X1;
  275. info_ptr->pcal_type = (png_byte)type;
  276. info_ptr->pcal_nparams = (png_byte)nparams;
  277. length = png_strlen(units) + 1;
  278. png_debug1(3, "allocating units for info (%lu bytes)",
  279. (unsigned long)length);
  280. info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
  281. if (info_ptr->pcal_units == NULL)
  282. {
  283. png_warning(png_ptr, "Insufficient memory for pCAL units");
  284. return;
  285. }
  286. png_memcpy(info_ptr->pcal_units, units, length);
  287. info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
  288. (png_size_t)((nparams + 1) * png_sizeof(png_charp)));
  289. if (info_ptr->pcal_params == NULL)
  290. {
  291. png_warning(png_ptr, "Insufficient memory for pCAL params");
  292. return;
  293. }
  294. png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
  295. for (i = 0; i < nparams; i++)
  296. {
  297. length = png_strlen(params[i]) + 1;
  298. png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
  299. (unsigned long)length);
  300. info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
  301. if (info_ptr->pcal_params[i] == NULL)
  302. {
  303. png_warning(png_ptr, "Insufficient memory for pCAL parameter");
  304. return;
  305. }
  306. png_memcpy(info_ptr->pcal_params[i], params[i], length);
  307. }
  308. info_ptr->valid |= PNG_INFO_pCAL;
  309. info_ptr->free_me |= PNG_FREE_PCAL;
  310. }
  311. #endif
  312. #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
  313. #ifdef PNG_FLOATING_POINT_SUPPORTED
  314. void PNGAPI
  315. png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
  316. int unit, double width, double height)
  317. {
  318. png_debug1(1, "in %s storage function", "sCAL");
  319. if (png_ptr == NULL || info_ptr == NULL)
  320. return;
  321. info_ptr->scal_unit = (png_byte)unit;
  322. info_ptr->scal_pixel_width = width;
  323. info_ptr->scal_pixel_height = height;
  324. info_ptr->valid |= PNG_INFO_sCAL;
  325. }
  326. #else
  327. #ifdef PNG_FIXED_POINT_SUPPORTED
  328. void PNGAPI
  329. png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
  330. int unit, png_charp swidth, png_charp sheight)
  331. {
  332. png_size_t length;
  333. png_debug1(1, "in %s storage function", "sCAL");
  334. if (png_ptr == NULL || info_ptr == NULL)
  335. return;
  336. info_ptr->scal_unit = (png_byte)unit;
  337. length = png_strlen(swidth) + 1;
  338. png_debug1(3, "allocating unit for info (%u bytes)",
  339. (unsigned int)length);
  340. info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length);
  341. if (info_ptr->scal_s_width == NULL)
  342. {
  343. png_warning(png_ptr,
  344. "Memory allocation failed while processing sCAL");
  345. return;
  346. }
  347. png_memcpy(info_ptr->scal_s_width, swidth, length);
  348. length = png_strlen(sheight) + 1;
  349. png_debug1(3, "allocating unit for info (%u bytes)",
  350. (unsigned int)length);
  351. info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length);
  352. if (info_ptr->scal_s_height == NULL)
  353. {
  354. png_free (png_ptr, info_ptr->scal_s_width);
  355. info_ptr->scal_s_width = NULL;
  356. png_warning(png_ptr,
  357. "Memory allocation failed while processing sCAL");
  358. return;
  359. }
  360. png_memcpy(info_ptr->scal_s_height, sheight, length);
  361. info_ptr->valid |= PNG_INFO_sCAL;
  362. info_ptr->free_me |= PNG_FREE_SCAL;
  363. }
  364. #endif
  365. #endif
  366. #endif
  367. #ifdef PNG_pHYs_SUPPORTED
  368. void PNGAPI
  369. png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
  370. png_uint_32 res_x, png_uint_32 res_y, int unit_type)
  371. {
  372. png_debug1(1, "in %s storage function", "pHYs");
  373. if (png_ptr == NULL || info_ptr == NULL)
  374. return;
  375. info_ptr->x_pixels_per_unit = res_x;
  376. info_ptr->y_pixels_per_unit = res_y;
  377. info_ptr->phys_unit_type = (png_byte)unit_type;
  378. info_ptr->valid |= PNG_INFO_pHYs;
  379. }
  380. #endif
  381. void PNGAPI
  382. png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
  383. png_colorp palette, int num_palette)
  384. {
  385. png_debug1(1, "in %s storage function", "PLTE");
  386. if (png_ptr == NULL || info_ptr == NULL)
  387. return;
  388. if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
  389. {
  390. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  391. png_error(png_ptr, "Invalid palette length");
  392. else
  393. {
  394. png_warning(png_ptr, "Invalid palette length");
  395. return;
  396. }
  397. }
  398. /*
  399. * It may not actually be necessary to set png_ptr->palette here;
  400. * we do it for backward compatibility with the way the png_handle_tRNS
  401. * function used to do the allocation.
  402. */
  403. png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
  404. /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
  405. * of num_palette entries, in case of an invalid PNG file that has
  406. * too-large sample values.
  407. */
  408. png_ptr->palette = (png_colorp)png_calloc(png_ptr,
  409. PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
  410. png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
  411. info_ptr->palette = png_ptr->palette;
  412. info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
  413. info_ptr->free_me |= PNG_FREE_PLTE;
  414. info_ptr->valid |= PNG_INFO_PLTE;
  415. }
  416. #ifdef PNG_sBIT_SUPPORTED
  417. void PNGAPI
  418. png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
  419. png_color_8p sig_bit)
  420. {
  421. png_debug1(1, "in %s storage function", "sBIT");
  422. if (png_ptr == NULL || info_ptr == NULL)
  423. return;
  424. png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
  425. info_ptr->valid |= PNG_INFO_sBIT;
  426. }
  427. #endif
  428. #ifdef PNG_sRGB_SUPPORTED
  429. void PNGAPI
  430. png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
  431. {
  432. png_debug1(1, "in %s storage function", "sRGB");
  433. if (png_ptr == NULL || info_ptr == NULL)
  434. return;
  435. info_ptr->srgb_intent = (png_byte)intent;
  436. info_ptr->valid |= PNG_INFO_sRGB;
  437. }
  438. void PNGAPI
  439. png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
  440. int intent)
  441. {
  442. #ifdef PNG_gAMA_SUPPORTED
  443. #ifdef PNG_FLOATING_POINT_SUPPORTED
  444. float file_gamma;
  445. #endif
  446. #ifdef PNG_FIXED_POINT_SUPPORTED
  447. png_fixed_point int_file_gamma;
  448. #endif
  449. #endif
  450. #ifdef PNG_cHRM_SUPPORTED
  451. #ifdef PNG_FLOATING_POINT_SUPPORTED
  452. float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
  453. #endif
  454. png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
  455. int_green_y, int_blue_x, int_blue_y;
  456. #endif
  457. png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
  458. if (png_ptr == NULL || info_ptr == NULL)
  459. return;
  460. png_set_sRGB(png_ptr, info_ptr, intent);
  461. #ifdef PNG_gAMA_SUPPORTED
  462. #ifdef PNG_FLOATING_POINT_SUPPORTED
  463. file_gamma = (float).45455;
  464. png_set_gAMA(png_ptr, info_ptr, file_gamma);
  465. #endif
  466. #ifdef PNG_FIXED_POINT_SUPPORTED
  467. int_file_gamma = 45455L;
  468. png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
  469. #endif
  470. #endif
  471. #ifdef PNG_cHRM_SUPPORTED
  472. int_white_x = 31270L;
  473. int_white_y = 32900L;
  474. int_red_x = 64000L;
  475. int_red_y = 33000L;
  476. int_green_x = 30000L;
  477. int_green_y = 60000L;
  478. int_blue_x = 15000L;
  479. int_blue_y = 6000L;
  480. #ifdef PNG_FLOATING_POINT_SUPPORTED
  481. white_x = (float).3127;
  482. white_y = (float).3290;
  483. red_x = (float).64;
  484. red_y = (float).33;
  485. green_x = (float).30;
  486. green_y = (float).60;
  487. blue_x = (float).15;
  488. blue_y = (float).06;
  489. #endif
  490. #ifdef PNG_FIXED_POINT_SUPPORTED
  491. png_set_cHRM_fixed(png_ptr, info_ptr,
  492. int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
  493. int_green_y, int_blue_x, int_blue_y);
  494. #endif
  495. #ifdef PNG_FLOATING_POINT_SUPPORTED
  496. png_set_cHRM(png_ptr, info_ptr,
  497. white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
  498. #endif
  499. #endif /* cHRM */
  500. }
  501. #endif /* sRGB */
  502. #ifdef PNG_iCCP_SUPPORTED
  503. void PNGAPI
  504. png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
  505. png_charp name, int compression_type,
  506. png_charp profile, png_uint_32 proflen)
  507. {
  508. png_charp new_iccp_name;
  509. png_charp new_iccp_profile;
  510. png_uint_32 length;
  511. png_debug1(1, "in %s storage function", "iCCP");
  512. if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
  513. return;
  514. length = png_strlen(name)+1;
  515. new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
  516. if (new_iccp_name == NULL)
  517. {
  518. png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
  519. return;
  520. }
  521. png_memcpy(new_iccp_name, name, length);
  522. new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen);
  523. if (new_iccp_profile == NULL)
  524. {
  525. png_free (png_ptr, new_iccp_name);
  526. png_warning(png_ptr,
  527. "Insufficient memory to process iCCP profile");
  528. return;
  529. }
  530. png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
  531. png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
  532. info_ptr->iccp_proflen = proflen;
  533. info_ptr->iccp_name = new_iccp_name;
  534. info_ptr->iccp_profile = new_iccp_profile;
  535. /* Compression is always zero but is here so the API and info structure
  536. * does not have to change if we introduce multiple compression types */
  537. info_ptr->iccp_compression = (png_byte)compression_type;
  538. info_ptr->free_me |= PNG_FREE_ICCP;
  539. info_ptr->valid |= PNG_INFO_iCCP;
  540. }
  541. #endif
  542. #ifdef PNG_TEXT_SUPPORTED
  543. void PNGAPI
  544. png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
  545. int num_text)
  546. {
  547. int ret;
  548. ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
  549. if (ret)
  550. png_error(png_ptr, "Insufficient memory to store text");
  551. }
  552. int /* PRIVATE */
  553. png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
  554. int num_text)
  555. {
  556. int i;
  557. png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
  558. png_ptr->chunk_name[0] == '\0') ?
  559. "text" : (png_const_charp)png_ptr->chunk_name));
  560. if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
  561. return(0);
  562. /* Make sure we have enough space in the "text" array in info_struct
  563. * to hold all of the incoming text_ptr objects.
  564. */
  565. if (info_ptr->num_text + num_text > info_ptr->max_text)
  566. {
  567. if (info_ptr->text != NULL)
  568. {
  569. png_textp old_text;
  570. int old_max;
  571. old_max = info_ptr->max_text;
  572. info_ptr->max_text = info_ptr->num_text + num_text + 8;
  573. old_text = info_ptr->text;
  574. info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
  575. (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
  576. if (info_ptr->text == NULL)
  577. {
  578. png_free(png_ptr, old_text);
  579. return(1);
  580. }
  581. png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
  582. png_sizeof(png_text)));
  583. png_free(png_ptr, old_text);
  584. }
  585. else
  586. {
  587. info_ptr->max_text = num_text + 8;
  588. info_ptr->num_text = 0;
  589. info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
  590. (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
  591. if (info_ptr->text == NULL)
  592. return(1);
  593. info_ptr->free_me |= PNG_FREE_TEXT;
  594. }
  595. png_debug1(3, "allocated %d entries for info_ptr->text",
  596. info_ptr->max_text);
  597. }
  598. for (i = 0; i < num_text; i++)
  599. {
  600. png_size_t text_length, key_len;
  601. png_size_t lang_len, lang_key_len;
  602. png_textp textp = &(info_ptr->text[info_ptr->num_text]);
  603. if (text_ptr[i].key == NULL)
  604. continue;
  605. if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
  606. text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
  607. {
  608. png_warning(png_ptr, "text compression mode is out of range");
  609. continue;
  610. }
  611. key_len = png_strlen(text_ptr[i].key);
  612. if (text_ptr[i].compression <= 0)
  613. {
  614. lang_len = 0;
  615. lang_key_len = 0;
  616. }
  617. else
  618. #ifdef PNG_iTXt_SUPPORTED
  619. {
  620. /* Set iTXt data */
  621. if (text_ptr[i].lang != NULL)
  622. lang_len = png_strlen(text_ptr[i].lang);
  623. else
  624. lang_len = 0;
  625. if (text_ptr[i].lang_key != NULL)
  626. lang_key_len = png_strlen(text_ptr[i].lang_key);
  627. else
  628. lang_key_len = 0;
  629. }
  630. #else /* PNG_iTXt_SUPPORTED */
  631. {
  632. png_warning(png_ptr, "iTXt chunk not supported");
  633. continue;
  634. }
  635. #endif
  636. if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
  637. {
  638. text_length = 0;
  639. #ifdef PNG_iTXt_SUPPORTED
  640. if (text_ptr[i].compression > 0)
  641. textp->compression = PNG_ITXT_COMPRESSION_NONE;
  642. else
  643. #endif
  644. textp->compression = PNG_TEXT_COMPRESSION_NONE;
  645. }
  646. else
  647. {
  648. text_length = png_strlen(text_ptr[i].text);
  649. textp->compression = text_ptr[i].compression;
  650. }
  651. textp->key = (png_charp)png_malloc_warn(png_ptr,
  652. (png_size_t)
  653. (key_len + text_length + lang_len + lang_key_len + 4));
  654. if (textp->key == NULL)
  655. return(1);
  656. png_debug2(2, "Allocated %lu bytes at %x in png_set_text",
  657. (unsigned long)(png_uint_32)
  658. (key_len + lang_len + lang_key_len + text_length + 4),
  659. (int)textp->key);
  660. png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
  661. *(textp->key + key_len) = '\0';
  662. #ifdef PNG_iTXt_SUPPORTED
  663. if (text_ptr[i].compression > 0)
  664. {
  665. textp->lang = textp->key + key_len + 1;
  666. png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
  667. *(textp->lang + lang_len) = '\0';
  668. textp->lang_key = textp->lang + lang_len + 1;
  669. png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
  670. *(textp->lang_key + lang_key_len) = '\0';
  671. textp->text = textp->lang_key + lang_key_len + 1;
  672. }
  673. else
  674. #endif
  675. {
  676. #ifdef PNG_iTXt_SUPPORTED
  677. textp->lang=NULL;
  678. textp->lang_key=NULL;
  679. #endif
  680. textp->text = textp->key + key_len + 1;
  681. }
  682. if (text_length)
  683. png_memcpy(textp->text, text_ptr[i].text,
  684. (png_size_t)(text_length));
  685. *(textp->text + text_length) = '\0';
  686. #ifdef PNG_iTXt_SUPPORTED
  687. if (textp->compression > 0)
  688. {
  689. textp->text_length = 0;
  690. textp->itxt_length = text_length;
  691. }
  692. else
  693. #endif
  694. {
  695. textp->text_length = text_length;
  696. #ifdef PNG_iTXt_SUPPORTED
  697. textp->itxt_length = 0;
  698. #endif
  699. }
  700. info_ptr->num_text++;
  701. png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
  702. }
  703. return(0);
  704. }
  705. #endif
  706. #ifdef PNG_tIME_SUPPORTED
  707. void PNGAPI
  708. png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
  709. {
  710. png_debug1(1, "in %s storage function", "tIME");
  711. if (png_ptr == NULL || info_ptr == NULL ||
  712. (png_ptr->mode & PNG_WROTE_tIME))
  713. return;
  714. png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
  715. info_ptr->valid |= PNG_INFO_tIME;
  716. }
  717. #endif
  718. #ifdef PNG_tRNS_SUPPORTED
  719. void PNGAPI
  720. png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
  721. png_bytep trans_alpha, int num_trans, png_color_16p trans_color)
  722. {
  723. png_debug1(1, "in %s storage function", "tRNS");
  724. if (png_ptr == NULL || info_ptr == NULL)
  725. return;
  726. if (trans_alpha != NULL)
  727. {
  728. /* It may not actually be necessary to set png_ptr->trans_alpha here;
  729. * we do it for backward compatibility with the way the png_handle_tRNS
  730. * function used to do the allocation.
  731. */
  732. png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
  733. /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
  734. png_ptr->trans_alpha = info_ptr->trans_alpha = (png_bytep)png_malloc(png_ptr,
  735. (png_size_t)PNG_MAX_PALETTE_LENGTH);
  736. if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
  737. png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
  738. }
  739. if (trans_color != NULL)
  740. {
  741. int sample_max = (1 << info_ptr->bit_depth);
  742. if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
  743. (int)trans_color->gray > sample_max) ||
  744. (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
  745. ((int)trans_color->red > sample_max ||
  746. (int)trans_color->green > sample_max ||
  747. (int)trans_color->blue > sample_max)))
  748. png_warning(png_ptr,
  749. "tRNS chunk has out-of-range samples for bit_depth");
  750. png_memcpy(&(info_ptr->trans_color), trans_color,
  751. png_sizeof(png_color_16));
  752. if (num_trans == 0)
  753. num_trans = 1;
  754. }
  755. info_ptr->num_trans = (png_uint_16)num_trans;
  756. if (num_trans != 0)
  757. {
  758. info_ptr->valid |= PNG_INFO_tRNS;
  759. info_ptr->free_me |= PNG_FREE_TRNS;
  760. }
  761. }
  762. #endif
  763. #ifdef PNG_sPLT_SUPPORTED
  764. void PNGAPI
  765. png_set_sPLT(png_structp png_ptr,
  766. png_infop info_ptr, png_sPLT_tp entries, int nentries)
  767. /*
  768. * entries - array of png_sPLT_t structures
  769. * to be added to the list of palettes
  770. * in the info structure.
  771. * nentries - number of palette structures to be
  772. * added.
  773. */
  774. {
  775. png_sPLT_tp np;
  776. int i;
  777. if (png_ptr == NULL || info_ptr == NULL)
  778. return;
  779. np = (png_sPLT_tp)png_malloc_warn(png_ptr,
  780. (info_ptr->splt_palettes_num + nentries) *
  781. (png_size_t)png_sizeof(png_sPLT_t));
  782. if (np == NULL)
  783. {
  784. png_warning(png_ptr, "No memory for sPLT palettes");
  785. return;
  786. }
  787. png_memcpy(np, info_ptr->splt_palettes,
  788. info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
  789. png_free(png_ptr, info_ptr->splt_palettes);
  790. info_ptr->splt_palettes=NULL;
  791. for (i = 0; i < nentries; i++)
  792. {
  793. png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
  794. png_sPLT_tp from = entries + i;
  795. png_uint_32 length;
  796. length = png_strlen(from->name) + 1;
  797. to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length);
  798. if (to->name == NULL)
  799. {
  800. png_warning(png_ptr,
  801. "Out of memory while processing sPLT chunk");
  802. continue;
  803. }
  804. png_memcpy(to->name, from->name, length);
  805. to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
  806. (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry)));
  807. if (to->entries == NULL)
  808. {
  809. png_warning(png_ptr,
  810. "Out of memory while processing sPLT chunk");
  811. png_free(png_ptr, to->name);
  812. to->name = NULL;
  813. continue;
  814. }
  815. png_memcpy(to->entries, from->entries,
  816. from->nentries * png_sizeof(png_sPLT_entry));
  817. to->nentries = from->nentries;
  818. to->depth = from->depth;
  819. }
  820. info_ptr->splt_palettes = np;
  821. info_ptr->splt_palettes_num += nentries;
  822. info_ptr->valid |= PNG_INFO_sPLT;
  823. info_ptr->free_me |= PNG_FREE_SPLT;
  824. }
  825. #endif /* PNG_sPLT_SUPPORTED */
  826. #if defined(PNG_APNG_SUPPORTED)
  827. png_uint_32 PNGAPI
  828. png_set_acTL(png_structp png_ptr, png_infop info_ptr,
  829. png_uint_32 num_frames, png_uint_32 num_plays)
  830. {
  831. png_debug1(1, "in %s storage function", "acTL");
  832. if (png_ptr == NULL || info_ptr == NULL)
  833. {
  834. png_warning(png_ptr,
  835. "Call to png_set_acTL() with NULL png_ptr "
  836. "or info_ptr ignored");
  837. return (0);
  838. }
  839. if (num_frames == 0)
  840. {
  841. png_warning(png_ptr,
  842. "Ignoring attempt to set acTL with num_frames zero");
  843. return (0);
  844. }
  845. if (num_frames > PNG_UINT_31_MAX)
  846. {
  847. png_warning(png_ptr,
  848. "Ignoring attempt to set acTL with num_frames > 2^31-1");
  849. return (0);
  850. }
  851. if (num_plays > PNG_UINT_31_MAX)
  852. {
  853. png_warning(png_ptr,
  854. "Ignoring attempt to set acTL with num_plays "
  855. "> 2^31-1");
  856. return (0);
  857. }
  858. info_ptr->num_frames = num_frames;
  859. info_ptr->num_plays = num_plays;
  860. info_ptr->valid |= PNG_INFO_acTL;
  861. return (1);
  862. }
  863. /* delay_num and delay_den can hold any 16-bit values including zero */
  864. png_uint_32 PNGAPI
  865. png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
  866. png_uint_32 width, png_uint_32 height,
  867. png_uint_32 x_offset, png_uint_32 y_offset,
  868. png_uint_16 delay_num, png_uint_16 delay_den,
  869. png_byte dispose_op, png_byte blend_op)
  870. {
  871. png_debug1(1, "in %s storage function", "fcTL");
  872. if (png_ptr == NULL || info_ptr == NULL)
  873. {
  874. png_warning(png_ptr,
  875. "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
  876. "ignored");
  877. return (0);
  878. }
  879. png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
  880. delay_num, delay_den, dispose_op, blend_op);
  881. /* For efficiency, ignore BLEND_OP_OVER when image is opaque.
  882. * See bug #441971 and #455140
  883. */
  884. if (blend_op == PNG_BLEND_OP_OVER)
  885. {
  886. if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
  887. !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
  888. {
  889. png_warning(png_ptr,
  890. "PNG_BLEND_OP_OVER is meaningless and wasteful "
  891. "for opaque images, ignored");
  892. blend_op = PNG_BLEND_OP_SOURCE;
  893. }
  894. }
  895. info_ptr->next_frame_width = width;
  896. info_ptr->next_frame_height = height;
  897. info_ptr->next_frame_x_offset = x_offset;
  898. info_ptr->next_frame_y_offset = y_offset;
  899. info_ptr->next_frame_delay_num = delay_num;
  900. info_ptr->next_frame_delay_den = delay_den;
  901. info_ptr->next_frame_dispose_op = dispose_op;
  902. info_ptr->next_frame_blend_op = blend_op;
  903. info_ptr->valid |= PNG_INFO_fcTL;
  904. return (1);
  905. }
  906. void /* PRIVATE */
  907. png_ensure_fcTL_is_valid(png_structp png_ptr,
  908. png_uint_32 width, png_uint_32 height,
  909. png_uint_32 x_offset, png_uint_32 y_offset,
  910. png_uint_16 delay_num, png_uint_16 delay_den,
  911. png_byte dispose_op, png_byte blend_op)
  912. {
  913. if (width + x_offset > png_ptr->first_frame_width ||
  914. height + y_offset > png_ptr->first_frame_height)
  915. png_error(png_ptr, "dimensions of a frame are greater than"
  916. "the ones in IHDR");
  917. if (width > PNG_UINT_31_MAX)
  918. png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
  919. if (height > PNG_UINT_31_MAX)
  920. png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
  921. if (x_offset > PNG_UINT_31_MAX)
  922. png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
  923. if (y_offset > PNG_UINT_31_MAX)
  924. png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
  925. if (dispose_op != PNG_DISPOSE_OP_NONE &&
  926. dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
  927. dispose_op != PNG_DISPOSE_OP_PREVIOUS)
  928. png_error(png_ptr, "invalid dispose_op in fcTL");
  929. if (blend_op != PNG_BLEND_OP_SOURCE &&
  930. blend_op != PNG_BLEND_OP_OVER)
  931. png_error(png_ptr, "invalid blend_op in fcTL");
  932. }
  933. png_uint_32 PNGAPI
  934. png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
  935. png_byte is_hidden)
  936. {
  937. png_debug(1, "in png_first_frame_is_hidden()");
  938. if (png_ptr == NULL)
  939. return 0;
  940. if(is_hidden)
  941. png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
  942. else
  943. png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
  944. return 1;
  945. }
  946. #endif /* PNG_APNG_SUPPORTED */
  947. #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  948. void PNGAPI
  949. png_set_unknown_chunks(png_structp png_ptr,
  950. png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
  951. {
  952. png_unknown_chunkp np;
  953. int i;
  954. if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
  955. return;
  956. np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
  957. (png_size_t)((info_ptr->unknown_chunks_num + num_unknowns) *
  958. png_sizeof(png_unknown_chunk)));
  959. if (np == NULL)
  960. {
  961. png_warning(png_ptr,
  962. "Out of memory while processing unknown chunk");
  963. return;
  964. }
  965. png_memcpy(np, info_ptr->unknown_chunks,
  966. info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk));
  967. png_free(png_ptr, info_ptr->unknown_chunks);
  968. for (i = 0; i < num_unknowns; i++)
  969. {
  970. png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
  971. png_unknown_chunkp from = unknowns + i;
  972. png_memcpy((png_charp)to->name,
  973. (png_charp)from->name,
  974. png_sizeof(from->name));
  975. to->name[png_sizeof(to->name)-1] = '\0';
  976. to->size = from->size;
  977. /* Note our location in the read or write sequence */
  978. to->location = (png_byte)(png_ptr->mode & 0xff);
  979. if (from->size == 0)
  980. to->data=NULL;
  981. else
  982. {
  983. to->data = (png_bytep)png_malloc_warn(png_ptr,
  984. (png_size_t)from->size);
  985. if (to->data == NULL)
  986. {
  987. png_warning(png_ptr,
  988. "Out of memory while processing unknown chunk");
  989. to->size = 0;
  990. }
  991. else
  992. png_memcpy(to->data, from->data, from->size);
  993. }
  994. }
  995. info_ptr->unknown_chunks = np;
  996. info_ptr->unknown_chunks_num += num_unknowns;
  997. info_ptr->free_me |= PNG_FREE_UNKN;
  998. }
  999. void PNGAPI
  1000. png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
  1001. int chunk, int location)
  1002. {
  1003. if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
  1004. (int)info_ptr->unknown_chunks_num)
  1005. info_ptr->unknown_chunks[chunk].location = (png_byte)location;
  1006. }
  1007. #endif
  1008. #ifdef PNG_MNG_FEATURES_SUPPORTED
  1009. png_uint_32 PNGAPI
  1010. png_permit_mng_features(png_structp png_ptr, png_uint_32 mng_features)
  1011. {
  1012. png_debug(1, "in png_permit_mng_features");
  1013. if (png_ptr == NULL)
  1014. return (png_uint_32)0;
  1015. png_ptr->mng_features_permitted =
  1016. (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
  1017. return (png_uint_32)png_ptr->mng_features_permitted;
  1018. }
  1019. #endif
  1020. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  1021. void PNGAPI
  1022. png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
  1023. chunk_list, int num_chunks)
  1024. {
  1025. png_bytep new_list, p;
  1026. int i, old_num_chunks;
  1027. if (png_ptr == NULL)
  1028. return;
  1029. if (num_chunks == 0)
  1030. {
  1031. if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
  1032. png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
  1033. else
  1034. png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
  1035. if (keep == PNG_HANDLE_CHUNK_ALWAYS)
  1036. png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
  1037. else
  1038. png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
  1039. return;
  1040. }
  1041. if (chunk_list == NULL)
  1042. return;
  1043. old_num_chunks = png_ptr->num_chunk_list;
  1044. new_list=(png_bytep)png_malloc(png_ptr,
  1045. (png_size_t)
  1046. (5*(num_chunks + old_num_chunks)));
  1047. if (png_ptr->chunk_list != NULL)
  1048. {
  1049. png_memcpy(new_list, png_ptr->chunk_list,
  1050. (png_size_t)(5*old_num_chunks));
  1051. png_free(png_ptr, png_ptr->chunk_list);
  1052. png_ptr->chunk_list=NULL;
  1053. }
  1054. png_memcpy(new_list + 5*old_num_chunks, chunk_list,
  1055. (png_size_t)(5*num_chunks));
  1056. for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
  1057. *p=(png_byte)keep;
  1058. png_ptr->num_chunk_list = old_num_chunks + num_chunks;
  1059. png_ptr->chunk_list = new_list;
  1060. png_ptr->free_me |= PNG_FREE_LIST;
  1061. }
  1062. #endif
  1063. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  1064. void PNGAPI
  1065. png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
  1066. png_user_chunk_ptr read_user_chunk_fn)
  1067. {
  1068. png_debug(1, "in png_set_read_user_chunk_fn");
  1069. if (png_ptr == NULL)
  1070. return;
  1071. png_ptr->read_user_chunk_fn = read_user_chunk_fn;
  1072. png_ptr->user_chunk_ptr = user_chunk_ptr;
  1073. }
  1074. #endif
  1075. #ifdef PNG_INFO_IMAGE_SUPPORTED
  1076. void PNGAPI
  1077. png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
  1078. {
  1079. png_debug1(1, "in %s storage function", "rows");
  1080. if (png_ptr == NULL || info_ptr == NULL)
  1081. return;
  1082. if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
  1083. png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
  1084. info_ptr->row_pointers = row_pointers;
  1085. if (row_pointers)
  1086. info_ptr->valid |= PNG_INFO_IDAT;
  1087. }
  1088. #endif
  1089. void PNGAPI
  1090. png_set_compression_buffer_size(png_structp png_ptr,
  1091. png_size_t size)
  1092. {
  1093. if (png_ptr == NULL)
  1094. return;
  1095. png_free(png_ptr, png_ptr->zbuf);
  1096. png_ptr->zbuf_size = size;
  1097. png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
  1098. png_ptr->zstream.next_out = png_ptr->zbuf;
  1099. png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1100. }
  1101. void PNGAPI
  1102. png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
  1103. {
  1104. if (png_ptr && info_ptr)
  1105. info_ptr->valid &= ~mask;
  1106. }
  1107. #ifdef PNG_SET_USER_LIMITS_SUPPORTED
  1108. /* This function was added to libpng 1.2.6 */
  1109. void PNGAPI
  1110. png_set_user_limits(png_structp png_ptr, png_uint_32 user_width_max,
  1111. png_uint_32 user_height_max)
  1112. {
  1113. /* Images with dimensions larger than these limits will be
  1114. * rejected by png_set_IHDR(). To accept any PNG datastream
  1115. * regardless of dimensions, set both limits to 0x7ffffffL.
  1116. */
  1117. if (png_ptr == NULL)
  1118. return;
  1119. png_ptr->user_width_max = user_width_max;
  1120. png_ptr->user_height_max = user_height_max;
  1121. }
  1122. /* This function was added to libpng 1.4.0 */
  1123. void PNGAPI
  1124. png_set_chunk_cache_max(png_structp png_ptr,
  1125. png_uint_32 user_chunk_cache_max)
  1126. {
  1127. if (png_ptr)
  1128. png_ptr->user_chunk_cache_max = user_chunk_cache_max;
  1129. }
  1130. /* This function was added to libpng 1.4.1 */
  1131. void PNGAPI
  1132. png_set_chunk_malloc_max(png_structp png_ptr,
  1133. png_alloc_size_t user_chunk_malloc_max)
  1134. {
  1135. if (png_ptr)
  1136. png_ptr->user_chunk_malloc_max =
  1137. (png_size_t)user_chunk_malloc_max;
  1138. }
  1139. #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
  1140. #ifdef PNG_BENIGN_ERRORS_SUPPORTED
  1141. void PNGAPI
  1142. png_set_benign_errors(png_structp png_ptr, int allowed)
  1143. {
  1144. png_debug(1, "in png_set_benign_errors");
  1145. if (allowed)
  1146. png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
  1147. else
  1148. png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
  1149. }
  1150. #endif /* PNG_BENIGN_ERRORS_SUPPORTED */
  1151. #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */