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

1225 lines
33 KiB

  1. /* pngset.c - storage of image information into info struct
  2. *
  3. * Last changed in libpng 1.5.1 [February 3, 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. #include "pngpriv.h"
  18. #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  19. #ifdef PNG_bKGD_SUPPORTED
  20. void PNGAPI
  21. png_set_bKGD(png_structp png_ptr, png_infop info_ptr,
  22. png_const_color_16p background)
  23. {
  24. png_debug1(1, "in %s storage function", "bKGD");
  25. if (png_ptr == NULL || info_ptr == NULL)
  26. return;
  27. png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16));
  28. info_ptr->valid |= PNG_INFO_bKGD;
  29. }
  30. #endif
  31. #ifdef PNG_cHRM_SUPPORTED
  32. void PNGFAPI
  33. png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
  34. png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
  35. png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
  36. png_fixed_point blue_x, png_fixed_point blue_y)
  37. {
  38. png_debug1(1, "in %s storage function", "cHRM fixed");
  39. if (png_ptr == NULL || info_ptr == NULL)
  40. return;
  41. # ifdef PNG_CHECK_cHRM_SUPPORTED
  42. if (png_check_cHRM_fixed(png_ptr,
  43. white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y))
  44. # endif
  45. {
  46. info_ptr->x_white = white_x;
  47. info_ptr->y_white = white_y;
  48. info_ptr->x_red = red_x;
  49. info_ptr->y_red = red_y;
  50. info_ptr->x_green = green_x;
  51. info_ptr->y_green = green_y;
  52. info_ptr->x_blue = blue_x;
  53. info_ptr->y_blue = blue_y;
  54. info_ptr->valid |= PNG_INFO_cHRM;
  55. }
  56. }
  57. # ifdef PNG_FLOATING_POINT_SUPPORTED
  58. void PNGAPI
  59. png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
  60. double white_x, double white_y, double red_x, double red_y,
  61. double green_x, double green_y, double blue_x, double blue_y)
  62. {
  63. png_set_cHRM_fixed(png_ptr, info_ptr,
  64. png_fixed(png_ptr, white_x, "cHRM White X"),
  65. png_fixed(png_ptr, white_y, "cHRM White Y"),
  66. png_fixed(png_ptr, red_x, "cHRM Red X"),
  67. png_fixed(png_ptr, red_y, "cHRM Red Y"),
  68. png_fixed(png_ptr, green_x, "cHRM Green X"),
  69. png_fixed(png_ptr, green_y, "cHRM Green Y"),
  70. png_fixed(png_ptr, blue_x, "cHRM Blue X"),
  71. png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
  72. }
  73. # endif /* PNG_FLOATING_POINT_SUPPORTED */
  74. #endif /* PNG_cHRM_SUPPORTED */
  75. #ifdef PNG_gAMA_SUPPORTED
  76. void PNGFAPI
  77. png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
  78. file_gamma)
  79. {
  80. png_debug1(1, "in %s storage function", "gAMA");
  81. if (png_ptr == NULL || info_ptr == NULL)
  82. return;
  83. /* Previously these values were limited, however they must be
  84. * wrong, therefore storing them (and setting PNG_INFO_gAMA)
  85. * must be wrong too.
  86. */
  87. if (file_gamma > (png_fixed_point)PNG_UINT_31_MAX)
  88. png_warning(png_ptr, "Gamma too large, ignored");
  89. else if (file_gamma <= 0)
  90. png_warning(png_ptr, "Negative or zero gamma ignored");
  91. else
  92. {
  93. info_ptr->gamma = file_gamma;
  94. info_ptr->valid |= PNG_INFO_gAMA;
  95. }
  96. }
  97. # ifdef PNG_FLOATING_POINT_SUPPORTED
  98. void PNGAPI
  99. png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
  100. {
  101. png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
  102. "png_set_gAMA"));
  103. }
  104. # endif
  105. #endif
  106. #ifdef PNG_hIST_SUPPORTED
  107. void PNGAPI
  108. png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist)
  109. {
  110. int i;
  111. png_debug1(1, "in %s storage function", "hIST");
  112. if (png_ptr == NULL || info_ptr == NULL)
  113. return;
  114. if (info_ptr->num_palette == 0 || info_ptr->num_palette
  115. > PNG_MAX_PALETTE_LENGTH)
  116. {
  117. png_warning(png_ptr,
  118. "Invalid palette size, hIST allocation skipped");
  119. return;
  120. }
  121. png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
  122. /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
  123. * version 1.2.1
  124. */
  125. png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
  126. PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16));
  127. if (png_ptr->hist == NULL)
  128. {
  129. png_warning(png_ptr, "Insufficient memory for hIST chunk data");
  130. return;
  131. }
  132. for (i = 0; i < info_ptr->num_palette; i++)
  133. png_ptr->hist[i] = hist[i];
  134. info_ptr->hist = png_ptr->hist;
  135. info_ptr->valid |= PNG_INFO_hIST;
  136. info_ptr->free_me |= PNG_FREE_HIST;
  137. }
  138. #endif
  139. void PNGAPI
  140. png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
  141. png_uint_32 width, png_uint_32 height, int bit_depth,
  142. int color_type, int interlace_type, int compression_type,
  143. int filter_type)
  144. {
  145. png_debug1(1, "in %s storage function", "IHDR");
  146. if (png_ptr == NULL || info_ptr == NULL)
  147. return;
  148. info_ptr->width = width;
  149. info_ptr->height = height;
  150. info_ptr->bit_depth = (png_byte)bit_depth;
  151. info_ptr->color_type = (png_byte)color_type;
  152. info_ptr->compression_type = (png_byte)compression_type;
  153. info_ptr->filter_type = (png_byte)filter_type;
  154. info_ptr->interlace_type = (png_byte)interlace_type;
  155. png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
  156. info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
  157. info_ptr->compression_type, info_ptr->filter_type);
  158. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  159. info_ptr->channels = 1;
  160. else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  161. info_ptr->channels = 3;
  162. else
  163. info_ptr->channels = 1;
  164. if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  165. info_ptr->channels++;
  166. info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
  167. /* Check for potential overflow */
  168. if (width >
  169. (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */
  170. - 48 /* bigrowbuf hack */
  171. - 1 /* filter byte */
  172. - 7*8 /* rounding of width to multiple of 8 pixels */
  173. - 8) /* extra max_pixel_depth pad */
  174. info_ptr->rowbytes = 0;
  175. else
  176. info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
  177. }
  178. #ifdef PNG_oFFs_SUPPORTED
  179. void PNGAPI
  180. png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
  181. png_int_32 offset_x, png_int_32 offset_y, int unit_type)
  182. {
  183. png_debug1(1, "in %s storage function", "oFFs");
  184. if (png_ptr == NULL || info_ptr == NULL)
  185. return;
  186. info_ptr->x_offset = offset_x;
  187. info_ptr->y_offset = offset_y;
  188. info_ptr->offset_unit_type = (png_byte)unit_type;
  189. info_ptr->valid |= PNG_INFO_oFFs;
  190. }
  191. #endif
  192. #ifdef PNG_pCAL_SUPPORTED
  193. void PNGAPI
  194. png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
  195. png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
  196. int nparams, png_const_charp units, png_charpp params)
  197. {
  198. png_size_t length;
  199. int i;
  200. png_debug1(1, "in %s storage function", "pCAL");
  201. if (png_ptr == NULL || info_ptr == NULL)
  202. return;
  203. length = png_strlen(purpose) + 1;
  204. png_debug1(3, "allocating purpose for info (%lu bytes)",
  205. (unsigned long)length);
  206. /* TODO: validate format of calibration name and unit name */
  207. /* Check that the type matches the specification. */
  208. if (type < 0 || type > 3)
  209. png_error(png_ptr, "Invalid pCAL equation type");
  210. /* Validate params[nparams] */
  211. for (i=0; i<nparams; ++i)
  212. if (!png_check_fp_string(params[i], png_strlen(params[i])))
  213. png_error(png_ptr, "Invalid format for pCAL parameter");
  214. info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
  215. if (info_ptr->pcal_purpose == NULL)
  216. {
  217. png_warning(png_ptr, "Insufficient memory for pCAL purpose");
  218. return;
  219. }
  220. png_memcpy(info_ptr->pcal_purpose, purpose, length);
  221. png_debug(3, "storing X0, X1, type, and nparams in info");
  222. info_ptr->pcal_X0 = X0;
  223. info_ptr->pcal_X1 = X1;
  224. info_ptr->pcal_type = (png_byte)type;
  225. info_ptr->pcal_nparams = (png_byte)nparams;
  226. length = png_strlen(units) + 1;
  227. png_debug1(3, "allocating units for info (%lu bytes)",
  228. (unsigned long)length);
  229. info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
  230. if (info_ptr->pcal_units == NULL)
  231. {
  232. png_warning(png_ptr, "Insufficient memory for pCAL units");
  233. return;
  234. }
  235. png_memcpy(info_ptr->pcal_units, units, length);
  236. info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
  237. (png_size_t)((nparams + 1) * png_sizeof(png_charp)));
  238. if (info_ptr->pcal_params == NULL)
  239. {
  240. png_warning(png_ptr, "Insufficient memory for pCAL params");
  241. return;
  242. }
  243. png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp));
  244. for (i = 0; i < nparams; i++)
  245. {
  246. length = png_strlen(params[i]) + 1;
  247. png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
  248. (unsigned long)length);
  249. info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
  250. if (info_ptr->pcal_params[i] == NULL)
  251. {
  252. png_warning(png_ptr, "Insufficient memory for pCAL parameter");
  253. return;
  254. }
  255. png_memcpy(info_ptr->pcal_params[i], params[i], length);
  256. }
  257. info_ptr->valid |= PNG_INFO_pCAL;
  258. info_ptr->free_me |= PNG_FREE_PCAL;
  259. }
  260. #endif
  261. #ifdef PNG_sCAL_SUPPORTED
  262. void PNGAPI
  263. png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
  264. int unit, png_const_charp swidth, png_const_charp sheight)
  265. {
  266. png_size_t lengthw = 0, lengthh = 0;
  267. png_debug1(1, "in %s storage function", "sCAL");
  268. if (png_ptr == NULL || info_ptr == NULL)
  269. return;
  270. /* Double check the unit (should never get here with an invalid
  271. * unit unless this is an API call.)
  272. */
  273. if (unit != 1 && unit != 2)
  274. png_error(png_ptr, "Invalid sCAL unit");
  275. if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 ||
  276. swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw))
  277. png_error(png_ptr, "Invalid sCAL width");
  278. if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 ||
  279. sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh))
  280. png_error(png_ptr, "Invalid sCAL height");
  281. info_ptr->scal_unit = (png_byte)unit;
  282. ++lengthw;
  283. png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
  284. info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw);
  285. if (info_ptr->scal_s_width == NULL)
  286. {
  287. png_warning(png_ptr, "Memory allocation failed while processing sCAL");
  288. return;
  289. }
  290. png_memcpy(info_ptr->scal_s_width, swidth, lengthw);
  291. ++lengthh;
  292. png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
  293. info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh);
  294. if (info_ptr->scal_s_height == NULL)
  295. {
  296. png_free (png_ptr, info_ptr->scal_s_width);
  297. info_ptr->scal_s_width = NULL;
  298. png_warning(png_ptr, "Memory allocation failed while processing sCAL");
  299. return;
  300. }
  301. png_memcpy(info_ptr->scal_s_height, sheight, lengthh);
  302. info_ptr->valid |= PNG_INFO_sCAL;
  303. info_ptr->free_me |= PNG_FREE_SCAL;
  304. }
  305. # ifdef PNG_FLOATING_POINT_SUPPORTED
  306. void PNGAPI
  307. png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width,
  308. double height)
  309. {
  310. png_debug1(1, "in %s storage function", "sCAL");
  311. /* Check the arguments. */
  312. if (width <= 0)
  313. png_warning(png_ptr, "Invalid sCAL width ignored");
  314. else if (height <= 0)
  315. png_warning(png_ptr, "Invalid sCAL height ignored");
  316. else
  317. {
  318. /* Convert 'width' and 'height' to ASCII. */
  319. char swidth[PNG_sCAL_MAX_DIGITS+1];
  320. char sheight[PNG_sCAL_MAX_DIGITS+1];
  321. png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width,
  322. PNG_sCAL_PRECISION);
  323. png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height,
  324. PNG_sCAL_PRECISION);
  325. png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
  326. }
  327. }
  328. # endif
  329. # ifdef PNG_FIXED_POINT_SUPPORTED
  330. void PNGAPI
  331. png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit,
  332. png_fixed_point width, png_fixed_point height)
  333. {
  334. png_debug1(1, "in %s storage function", "sCAL");
  335. /* Check the arguments. */
  336. if (width <= 0)
  337. png_warning(png_ptr, "Invalid sCAL width ignored");
  338. else if (height <= 0)
  339. png_warning(png_ptr, "Invalid sCAL height ignored");
  340. else
  341. {
  342. /* Convert 'width' and 'height' to ASCII. */
  343. char swidth[PNG_sCAL_MAX_DIGITS+1];
  344. char sheight[PNG_sCAL_MAX_DIGITS+1];
  345. png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width);
  346. png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height);
  347. png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
  348. }
  349. }
  350. # endif
  351. #endif
  352. #ifdef PNG_pHYs_SUPPORTED
  353. void PNGAPI
  354. png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
  355. png_uint_32 res_x, png_uint_32 res_y, int unit_type)
  356. {
  357. png_debug1(1, "in %s storage function", "pHYs");
  358. if (png_ptr == NULL || info_ptr == NULL)
  359. return;
  360. info_ptr->x_pixels_per_unit = res_x;
  361. info_ptr->y_pixels_per_unit = res_y;
  362. info_ptr->phys_unit_type = (png_byte)unit_type;
  363. info_ptr->valid |= PNG_INFO_pHYs;
  364. }
  365. #endif
  366. void PNGAPI
  367. png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
  368. png_const_colorp palette, int num_palette)
  369. {
  370. png_debug1(1, "in %s storage function", "PLTE");
  371. if (png_ptr == NULL || info_ptr == NULL)
  372. return;
  373. if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
  374. {
  375. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  376. png_error(png_ptr, "Invalid palette length");
  377. else
  378. {
  379. png_warning(png_ptr, "Invalid palette length");
  380. return;
  381. }
  382. }
  383. /* It may not actually be necessary to set png_ptr->palette here;
  384. * we do it for backward compatibility with the way the png_handle_tRNS
  385. * function used to do the allocation.
  386. */
  387. png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
  388. /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
  389. * of num_palette entries, in case of an invalid PNG file that has
  390. * too-large sample values.
  391. */
  392. png_ptr->palette = (png_colorp)png_calloc(png_ptr,
  393. PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
  394. png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color));
  395. info_ptr->palette = png_ptr->palette;
  396. info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
  397. info_ptr->free_me |= PNG_FREE_PLTE;
  398. info_ptr->valid |= PNG_INFO_PLTE;
  399. }
  400. #ifdef PNG_sBIT_SUPPORTED
  401. void PNGAPI
  402. png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
  403. png_const_color_8p sig_bit)
  404. {
  405. png_debug1(1, "in %s storage function", "sBIT");
  406. if (png_ptr == NULL || info_ptr == NULL)
  407. return;
  408. png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8));
  409. info_ptr->valid |= PNG_INFO_sBIT;
  410. }
  411. #endif
  412. #ifdef PNG_sRGB_SUPPORTED
  413. void PNGAPI
  414. png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int srgb_intent)
  415. {
  416. png_debug1(1, "in %s storage function", "sRGB");
  417. if (png_ptr == NULL || info_ptr == NULL)
  418. return;
  419. info_ptr->srgb_intent = (png_byte)srgb_intent;
  420. info_ptr->valid |= PNG_INFO_sRGB;
  421. }
  422. void PNGAPI
  423. png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
  424. int srgb_intent)
  425. {
  426. png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
  427. if (png_ptr == NULL || info_ptr == NULL)
  428. return;
  429. png_set_sRGB(png_ptr, info_ptr, srgb_intent);
  430. # ifdef PNG_gAMA_SUPPORTED
  431. png_set_gAMA_fixed(png_ptr, info_ptr, 45455L);
  432. # endif
  433. # ifdef PNG_cHRM_SUPPORTED
  434. png_set_cHRM_fixed(png_ptr, info_ptr,
  435. /* color x y */
  436. /* white */ 31270L, 32900L,
  437. /* red */ 64000L, 33000L,
  438. /* green */ 30000L, 60000L,
  439. /* blue */ 15000L, 6000L
  440. );
  441. # endif /* cHRM */
  442. }
  443. #endif /* sRGB */
  444. #ifdef PNG_iCCP_SUPPORTED
  445. void PNGAPI
  446. png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
  447. png_const_charp name, int compression_type,
  448. png_const_bytep profile, png_uint_32 proflen)
  449. {
  450. png_charp new_iccp_name;
  451. png_bytep new_iccp_profile;
  452. png_uint_32 length;
  453. png_debug1(1, "in %s storage function", "iCCP");
  454. if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
  455. return;
  456. length = png_strlen(name)+1;
  457. new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length);
  458. if (new_iccp_name == NULL)
  459. {
  460. png_warning(png_ptr, "Insufficient memory to process iCCP chunk");
  461. return;
  462. }
  463. png_memcpy(new_iccp_name, name, length);
  464. new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen);
  465. if (new_iccp_profile == NULL)
  466. {
  467. png_free (png_ptr, new_iccp_name);
  468. png_warning(png_ptr,
  469. "Insufficient memory to process iCCP profile");
  470. return;
  471. }
  472. png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
  473. png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
  474. info_ptr->iccp_proflen = proflen;
  475. info_ptr->iccp_name = new_iccp_name;
  476. info_ptr->iccp_profile = new_iccp_profile;
  477. /* Compression is always zero but is here so the API and info structure
  478. * does not have to change if we introduce multiple compression types
  479. */
  480. info_ptr->iccp_compression = (png_byte)compression_type;
  481. info_ptr->free_me |= PNG_FREE_ICCP;
  482. info_ptr->valid |= PNG_INFO_iCCP;
  483. }
  484. #endif
  485. #ifdef PNG_TEXT_SUPPORTED
  486. void PNGAPI
  487. png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr,
  488. int num_text)
  489. {
  490. int ret;
  491. ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
  492. if (ret)
  493. png_error(png_ptr, "Insufficient memory to store text");
  494. }
  495. int /* PRIVATE */
  496. png_set_text_2(png_structp png_ptr, png_infop info_ptr,
  497. png_const_textp text_ptr, int num_text)
  498. {
  499. int i;
  500. png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
  501. png_ptr->chunk_name[0] == '\0') ?
  502. "text" : (png_const_charp)png_ptr->chunk_name));
  503. if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
  504. return(0);
  505. /* Make sure we have enough space in the "text" array in info_struct
  506. * to hold all of the incoming text_ptr objects.
  507. */
  508. if (info_ptr->num_text + num_text > info_ptr->max_text)
  509. {
  510. if (info_ptr->text != NULL)
  511. {
  512. png_textp old_text;
  513. int old_max;
  514. old_max = info_ptr->max_text;
  515. info_ptr->max_text = info_ptr->num_text + num_text + 8;
  516. old_text = info_ptr->text;
  517. info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
  518. (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
  519. if (info_ptr->text == NULL)
  520. {
  521. png_free(png_ptr, old_text);
  522. return(1);
  523. }
  524. png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
  525. png_sizeof(png_text)));
  526. png_free(png_ptr, old_text);
  527. }
  528. else
  529. {
  530. info_ptr->max_text = num_text + 8;
  531. info_ptr->num_text = 0;
  532. info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
  533. (png_size_t)(info_ptr->max_text * png_sizeof(png_text)));
  534. if (info_ptr->text == NULL)
  535. return(1);
  536. info_ptr->free_me |= PNG_FREE_TEXT;
  537. }
  538. png_debug1(3, "allocated %d entries for info_ptr->text",
  539. info_ptr->max_text);
  540. }
  541. for (i = 0; i < num_text; i++)
  542. {
  543. png_size_t text_length, key_len;
  544. png_size_t lang_len, lang_key_len;
  545. png_textp textp = &(info_ptr->text[info_ptr->num_text]);
  546. if (text_ptr[i].key == NULL)
  547. continue;
  548. if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
  549. text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
  550. {
  551. png_warning(png_ptr, "text compression mode is out of range");
  552. continue;
  553. }
  554. key_len = png_strlen(text_ptr[i].key);
  555. if (text_ptr[i].compression <= 0)
  556. {
  557. lang_len = 0;
  558. lang_key_len = 0;
  559. }
  560. else
  561. # ifdef PNG_iTXt_SUPPORTED
  562. {
  563. /* Set iTXt data */
  564. if (text_ptr[i].lang != NULL)
  565. lang_len = png_strlen(text_ptr[i].lang);
  566. else
  567. lang_len = 0;
  568. if (text_ptr[i].lang_key != NULL)
  569. lang_key_len = png_strlen(text_ptr[i].lang_key);
  570. else
  571. lang_key_len = 0;
  572. }
  573. # else /* PNG_iTXt_SUPPORTED */
  574. {
  575. png_warning(png_ptr, "iTXt chunk not supported");
  576. continue;
  577. }
  578. # endif
  579. if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
  580. {
  581. text_length = 0;
  582. # ifdef PNG_iTXt_SUPPORTED
  583. if (text_ptr[i].compression > 0)
  584. textp->compression = PNG_ITXT_COMPRESSION_NONE;
  585. else
  586. # endif
  587. textp->compression = PNG_TEXT_COMPRESSION_NONE;
  588. }
  589. else
  590. {
  591. text_length = png_strlen(text_ptr[i].text);
  592. textp->compression = text_ptr[i].compression;
  593. }
  594. textp->key = (png_charp)png_malloc_warn(png_ptr,
  595. (png_size_t)
  596. (key_len + text_length + lang_len + lang_key_len + 4));
  597. if (textp->key == NULL)
  598. return(1);
  599. png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
  600. (unsigned long)(png_uint_32)
  601. (key_len + lang_len + lang_key_len + text_length + 4),
  602. textp->key);
  603. png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len));
  604. *(textp->key + key_len) = '\0';
  605. if (text_ptr[i].compression > 0)
  606. {
  607. textp->lang = textp->key + key_len + 1;
  608. png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
  609. *(textp->lang + lang_len) = '\0';
  610. textp->lang_key = textp->lang + lang_len + 1;
  611. png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
  612. *(textp->lang_key + lang_key_len) = '\0';
  613. textp->text = textp->lang_key + lang_key_len + 1;
  614. }
  615. else
  616. {
  617. textp->lang=NULL;
  618. textp->lang_key=NULL;
  619. textp->text = textp->key + key_len + 1;
  620. }
  621. if (text_length)
  622. png_memcpy(textp->text, text_ptr[i].text,
  623. (png_size_t)(text_length));
  624. *(textp->text + text_length) = '\0';
  625. # ifdef PNG_iTXt_SUPPORTED
  626. if (textp->compression > 0)
  627. {
  628. textp->text_length = 0;
  629. textp->itxt_length = text_length;
  630. }
  631. else
  632. # endif
  633. {
  634. textp->text_length = text_length;
  635. textp->itxt_length = 0;
  636. }
  637. info_ptr->num_text++;
  638. png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
  639. }
  640. return(0);
  641. }
  642. #endif
  643. #ifdef PNG_tIME_SUPPORTED
  644. void PNGAPI
  645. png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)
  646. {
  647. png_debug1(1, "in %s storage function", "tIME");
  648. if (png_ptr == NULL || info_ptr == NULL ||
  649. (png_ptr->mode & PNG_WROTE_tIME))
  650. return;
  651. png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time));
  652. info_ptr->valid |= PNG_INFO_tIME;
  653. }
  654. #endif
  655. #ifdef PNG_tRNS_SUPPORTED
  656. void PNGAPI
  657. png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
  658. png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
  659. {
  660. png_debug1(1, "in %s storage function", "tRNS");
  661. if (png_ptr == NULL || info_ptr == NULL)
  662. return;
  663. if (trans_alpha != NULL)
  664. {
  665. /* It may not actually be necessary to set png_ptr->trans_alpha here;
  666. * we do it for backward compatibility with the way the png_handle_tRNS
  667. * function used to do the allocation.
  668. */
  669. png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
  670. /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
  671. png_ptr->trans_alpha = info_ptr->trans_alpha =
  672. (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH);
  673. if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
  674. png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
  675. }
  676. if (trans_color != NULL)
  677. {
  678. int sample_max = (1 << info_ptr->bit_depth);
  679. if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
  680. (int)trans_color->gray > sample_max) ||
  681. (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
  682. ((int)trans_color->red > sample_max ||
  683. (int)trans_color->green > sample_max ||
  684. (int)trans_color->blue > sample_max)))
  685. png_warning(png_ptr,
  686. "tRNS chunk has out-of-range samples for bit_depth");
  687. png_memcpy(&(info_ptr->trans_color), trans_color,
  688. png_sizeof(png_color_16));
  689. if (num_trans == 0)
  690. num_trans = 1;
  691. }
  692. info_ptr->num_trans = (png_uint_16)num_trans;
  693. if (num_trans != 0)
  694. {
  695. info_ptr->valid |= PNG_INFO_tRNS;
  696. info_ptr->free_me |= PNG_FREE_TRNS;
  697. }
  698. }
  699. #endif
  700. #ifdef PNG_sPLT_SUPPORTED
  701. void PNGAPI
  702. png_set_sPLT(png_structp png_ptr,
  703. png_infop info_ptr, png_const_sPLT_tp entries, int nentries)
  704. /*
  705. * entries - array of png_sPLT_t structures
  706. * to be added to the list of palettes
  707. * in the info structure.
  708. *
  709. * nentries - number of palette structures to be
  710. * added.
  711. */
  712. {
  713. png_sPLT_tp np;
  714. int i;
  715. if (png_ptr == NULL || info_ptr == NULL)
  716. return;
  717. np = (png_sPLT_tp)png_malloc_warn(png_ptr,
  718. (info_ptr->splt_palettes_num + nentries) *
  719. (png_size_t)png_sizeof(png_sPLT_t));
  720. if (np == NULL)
  721. {
  722. png_warning(png_ptr, "No memory for sPLT palettes");
  723. return;
  724. }
  725. png_memcpy(np, info_ptr->splt_palettes,
  726. info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t));
  727. png_free(png_ptr, info_ptr->splt_palettes);
  728. info_ptr->splt_palettes=NULL;
  729. for (i = 0; i < nentries; i++)
  730. {
  731. png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
  732. png_const_sPLT_tp from = entries + i;
  733. png_uint_32 length;
  734. length = png_strlen(from->name) + 1;
  735. to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length);
  736. if (to->name == NULL)
  737. {
  738. png_warning(png_ptr,
  739. "Out of memory while processing sPLT chunk");
  740. continue;
  741. }
  742. png_memcpy(to->name, from->name, length);
  743. to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
  744. (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry)));
  745. if (to->entries == NULL)
  746. {
  747. png_warning(png_ptr,
  748. "Out of memory while processing sPLT chunk");
  749. png_free(png_ptr, to->name);
  750. to->name = NULL;
  751. continue;
  752. }
  753. png_memcpy(to->entries, from->entries,
  754. from->nentries * png_sizeof(png_sPLT_entry));
  755. to->nentries = from->nentries;
  756. to->depth = from->depth;
  757. }
  758. info_ptr->splt_palettes = np;
  759. info_ptr->splt_palettes_num += nentries;
  760. info_ptr->valid |= PNG_INFO_sPLT;
  761. info_ptr->free_me |= PNG_FREE_SPLT;
  762. }
  763. #endif /* PNG_sPLT_SUPPORTED */
  764. #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  765. void PNGAPI
  766. png_set_unknown_chunks(png_structp png_ptr,
  767. png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
  768. {
  769. png_unknown_chunkp np;
  770. int i;
  771. if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
  772. return;
  773. np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
  774. (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) *
  775. png_sizeof(png_unknown_chunk));
  776. if (np == NULL)
  777. {
  778. png_warning(png_ptr,
  779. "Out of memory while processing unknown chunk");
  780. return;
  781. }
  782. png_memcpy(np, info_ptr->unknown_chunks,
  783. (png_size_t)info_ptr->unknown_chunks_num *
  784. png_sizeof(png_unknown_chunk));
  785. png_free(png_ptr, info_ptr->unknown_chunks);
  786. info_ptr->unknown_chunks = NULL;
  787. for (i = 0; i < num_unknowns; i++)
  788. {
  789. png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
  790. png_const_unknown_chunkp from = unknowns + i;
  791. png_memcpy(to->name, from->name, png_sizeof(from->name));
  792. to->name[png_sizeof(to->name)-1] = '\0';
  793. to->size = from->size;
  794. /* Note our location in the read or write sequence */
  795. to->location = (png_byte)(png_ptr->mode & 0xff);
  796. if (from->size == 0)
  797. to->data=NULL;
  798. else
  799. {
  800. to->data = (png_bytep)png_malloc_warn(png_ptr,
  801. (png_size_t)from->size);
  802. if (to->data == NULL)
  803. {
  804. png_warning(png_ptr,
  805. "Out of memory while processing unknown chunk");
  806. to->size = 0;
  807. }
  808. else
  809. png_memcpy(to->data, from->data, from->size);
  810. }
  811. }
  812. info_ptr->unknown_chunks = np;
  813. info_ptr->unknown_chunks_num += num_unknowns;
  814. info_ptr->free_me |= PNG_FREE_UNKN;
  815. }
  816. void PNGAPI
  817. png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
  818. int chunk, int location)
  819. {
  820. if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
  821. info_ptr->unknown_chunks_num)
  822. info_ptr->unknown_chunks[chunk].location = (png_byte)location;
  823. }
  824. #endif
  825. #ifdef PNG_MNG_FEATURES_SUPPORTED
  826. png_uint_32 PNGAPI
  827. png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
  828. {
  829. png_debug(1, "in png_permit_mng_features");
  830. if (png_ptr == NULL)
  831. return (png_uint_32)0;
  832. png_ptr->mng_features_permitted =
  833. (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
  834. return (png_uint_32)png_ptr->mng_features_permitted;
  835. }
  836. #endif
  837. #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  838. void PNGAPI
  839. png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep
  840. chunk_list, int num_chunks)
  841. {
  842. png_bytep new_list, p;
  843. int i, old_num_chunks;
  844. if (png_ptr == NULL)
  845. return;
  846. if (num_chunks == 0)
  847. {
  848. if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE)
  849. png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
  850. else
  851. png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
  852. if (keep == PNG_HANDLE_CHUNK_ALWAYS)
  853. png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
  854. else
  855. png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
  856. return;
  857. }
  858. if (chunk_list == NULL)
  859. return;
  860. old_num_chunks = png_ptr->num_chunk_list;
  861. new_list=(png_bytep)png_malloc(png_ptr,
  862. (png_size_t)(5*(num_chunks + old_num_chunks)));
  863. if (png_ptr->chunk_list != NULL)
  864. {
  865. png_memcpy(new_list, png_ptr->chunk_list,
  866. (png_size_t)(5*old_num_chunks));
  867. png_free(png_ptr, png_ptr->chunk_list);
  868. png_ptr->chunk_list=NULL;
  869. }
  870. png_memcpy(new_list + 5*old_num_chunks, chunk_list,
  871. (png_size_t)(5*num_chunks));
  872. for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5)
  873. *p=(png_byte)keep;
  874. png_ptr->num_chunk_list = old_num_chunks + num_chunks;
  875. png_ptr->chunk_list = new_list;
  876. png_ptr->free_me |= PNG_FREE_LIST;
  877. }
  878. #endif
  879. #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
  880. void PNGAPI
  881. png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
  882. png_user_chunk_ptr read_user_chunk_fn)
  883. {
  884. png_debug(1, "in png_set_read_user_chunk_fn");
  885. if (png_ptr == NULL)
  886. return;
  887. png_ptr->read_user_chunk_fn = read_user_chunk_fn;
  888. png_ptr->user_chunk_ptr = user_chunk_ptr;
  889. }
  890. #endif
  891. #ifdef PNG_INFO_IMAGE_SUPPORTED
  892. void PNGAPI
  893. png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
  894. {
  895. png_debug1(1, "in %s storage function", "rows");
  896. if (png_ptr == NULL || info_ptr == NULL)
  897. return;
  898. if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
  899. png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
  900. info_ptr->row_pointers = row_pointers;
  901. if (row_pointers)
  902. info_ptr->valid |= PNG_INFO_IDAT;
  903. }
  904. #endif
  905. void PNGAPI
  906. png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
  907. {
  908. if (png_ptr == NULL)
  909. return;
  910. png_free(png_ptr, png_ptr->zbuf);
  911. if (size > ZLIB_IO_MAX)
  912. {
  913. png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
  914. png_ptr->zbuf_size = ZLIB_IO_MAX;
  915. size = ZLIB_IO_MAX; /* must fit */
  916. }
  917. else
  918. png_ptr->zbuf_size = (uInt)size;
  919. png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
  920. /* The following ensures a relatively safe failure if this gets called while
  921. * the buffer is actually in use.
  922. */
  923. png_ptr->zstream.next_out = png_ptr->zbuf;
  924. png_ptr->zstream.avail_out = 0;
  925. png_ptr->zstream.avail_in = 0;
  926. }
  927. void PNGAPI
  928. png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask)
  929. {
  930. if (png_ptr && info_ptr)
  931. info_ptr->valid &= ~mask;
  932. }
  933. #ifdef PNG_SET_USER_LIMITS_SUPPORTED
  934. /* This function was added to libpng 1.2.6 */
  935. void PNGAPI
  936. png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
  937. png_uint_32 user_height_max)
  938. {
  939. /* Images with dimensions larger than these limits will be
  940. * rejected by png_set_IHDR(). To accept any PNG datastream
  941. * regardless of dimensions, set both limits to 0x7ffffffL.
  942. */
  943. if (png_ptr == NULL)
  944. return;
  945. png_ptr->user_width_max = user_width_max;
  946. png_ptr->user_height_max = user_height_max;
  947. }
  948. /* This function was added to libpng 1.4.0 */
  949. void PNGAPI
  950. png_set_chunk_cache_max (png_structp png_ptr,
  951. png_uint_32 user_chunk_cache_max)
  952. {
  953. if (png_ptr)
  954. png_ptr->user_chunk_cache_max = user_chunk_cache_max;
  955. }
  956. /* This function was added to libpng 1.4.1 */
  957. void PNGAPI
  958. png_set_chunk_malloc_max (png_structp png_ptr,
  959. png_alloc_size_t user_chunk_malloc_max)
  960. {
  961. if (png_ptr)
  962. png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
  963. }
  964. #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
  965. #ifdef PNG_BENIGN_ERRORS_SUPPORTED
  966. void PNGAPI
  967. png_set_benign_errors(png_structp png_ptr, int allowed)
  968. {
  969. png_debug(1, "in png_set_benign_errors");
  970. if (allowed)
  971. png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
  972. else
  973. png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
  974. }
  975. #endif /* PNG_BENIGN_ERRORS_SUPPORTED */
  976. #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */