pngget.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  1. /* pngget.c - retrieval of values from info struct
  2. *
  3. * Last changed in libpng 1.6.1 [March 28, 2013]
  4. * Copyright (c) 1998-2013 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. */
  13. #include "pngpriv.h"
  14. #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
  15. png_uint_32 PNGAPI
  16. png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
  17. png_uint_32 flag)
  18. {
  19. if (png_ptr != NULL && info_ptr != NULL)
  20. return(info_ptr->valid & flag);
  21. return(0);
  22. }
  23. png_size_t PNGAPI
  24. png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
  25. {
  26. if (png_ptr != NULL && info_ptr != NULL)
  27. return(info_ptr->rowbytes);
  28. return(0);
  29. }
  30. #ifdef PNG_INFO_IMAGE_SUPPORTED
  31. png_bytepp PNGAPI
  32. png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
  33. {
  34. if (png_ptr != NULL && info_ptr != NULL)
  35. return(info_ptr->row_pointers);
  36. return(0);
  37. }
  38. #endif
  39. #ifdef PNG_EASY_ACCESS_SUPPORTED
  40. /* Easy access to info, added in libpng-0.99 */
  41. png_uint_32 PNGAPI
  42. png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
  43. {
  44. if (png_ptr != NULL && info_ptr != NULL)
  45. return info_ptr->width;
  46. return (0);
  47. }
  48. png_uint_32 PNGAPI
  49. png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
  50. {
  51. if (png_ptr != NULL && info_ptr != NULL)
  52. return info_ptr->height;
  53. return (0);
  54. }
  55. png_byte PNGAPI
  56. png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
  57. {
  58. if (png_ptr != NULL && info_ptr != NULL)
  59. return info_ptr->bit_depth;
  60. return (0);
  61. }
  62. png_byte PNGAPI
  63. png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
  64. {
  65. if (png_ptr != NULL && info_ptr != NULL)
  66. return info_ptr->color_type;
  67. return (0);
  68. }
  69. png_byte PNGAPI
  70. png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
  71. {
  72. if (png_ptr != NULL && info_ptr != NULL)
  73. return info_ptr->filter_type;
  74. return (0);
  75. }
  76. png_byte PNGAPI
  77. png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
  78. {
  79. if (png_ptr != NULL && info_ptr != NULL)
  80. return info_ptr->interlace_type;
  81. return (0);
  82. }
  83. png_byte PNGAPI
  84. png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
  85. {
  86. if (png_ptr != NULL && info_ptr != NULL)
  87. return info_ptr->compression_type;
  88. return (0);
  89. }
  90. png_uint_32 PNGAPI
  91. png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
  92. info_ptr)
  93. {
  94. #ifdef PNG_pHYs_SUPPORTED
  95. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  96. {
  97. png_debug1(1, "in %s retrieval function",
  98. "png_get_x_pixels_per_meter");
  99. if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
  100. return (info_ptr->x_pixels_per_unit);
  101. }
  102. #endif
  103. return (0);
  104. }
  105. png_uint_32 PNGAPI
  106. png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
  107. info_ptr)
  108. {
  109. #ifdef PNG_pHYs_SUPPORTED
  110. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  111. {
  112. png_debug1(1, "in %s retrieval function",
  113. "png_get_y_pixels_per_meter");
  114. if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
  115. return (info_ptr->y_pixels_per_unit);
  116. }
  117. #endif
  118. return (0);
  119. }
  120. png_uint_32 PNGAPI
  121. png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
  122. {
  123. #ifdef PNG_pHYs_SUPPORTED
  124. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  125. {
  126. png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
  127. if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
  128. info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
  129. return (info_ptr->x_pixels_per_unit);
  130. }
  131. #endif
  132. return (0);
  133. }
  134. #ifdef PNG_FLOATING_POINT_SUPPORTED
  135. float PNGAPI
  136. png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
  137. info_ptr)
  138. {
  139. #ifdef PNG_READ_pHYs_SUPPORTED
  140. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  141. {
  142. png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
  143. if (info_ptr->x_pixels_per_unit != 0)
  144. return ((float)((float)info_ptr->y_pixels_per_unit
  145. /(float)info_ptr->x_pixels_per_unit));
  146. }
  147. #else
  148. PNG_UNUSED(png_ptr)
  149. PNG_UNUSED(info_ptr)
  150. #endif
  151. return ((float)0.0);
  152. }
  153. #endif
  154. #ifdef PNG_FIXED_POINT_SUPPORTED
  155. png_fixed_point PNGAPI
  156. png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
  157. png_const_inforp info_ptr)
  158. {
  159. #ifdef PNG_READ_pHYs_SUPPORTED
  160. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)
  161. && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0
  162. && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX
  163. && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
  164. {
  165. png_fixed_point res;
  166. png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
  167. /* The following casts work because a PNG 4 byte integer only has a valid
  168. * range of 0..2^31-1; otherwise the cast might overflow.
  169. */
  170. if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
  171. (png_int_32)info_ptr->x_pixels_per_unit))
  172. return res;
  173. }
  174. #else
  175. PNG_UNUSED(png_ptr)
  176. PNG_UNUSED(info_ptr)
  177. #endif
  178. return 0;
  179. }
  180. #endif
  181. png_int_32 PNGAPI
  182. png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
  183. {
  184. #ifdef PNG_oFFs_SUPPORTED
  185. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  186. {
  187. png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
  188. if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
  189. return (info_ptr->x_offset);
  190. }
  191. #endif
  192. return (0);
  193. }
  194. png_int_32 PNGAPI
  195. png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
  196. {
  197. #ifdef PNG_oFFs_SUPPORTED
  198. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  199. {
  200. png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
  201. if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
  202. return (info_ptr->y_offset);
  203. }
  204. #endif
  205. return (0);
  206. }
  207. png_int_32 PNGAPI
  208. png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
  209. {
  210. #ifdef PNG_oFFs_SUPPORTED
  211. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  212. {
  213. png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
  214. if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
  215. return (info_ptr->x_offset);
  216. }
  217. #endif
  218. return (0);
  219. }
  220. png_int_32 PNGAPI
  221. png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
  222. {
  223. #ifdef PNG_oFFs_SUPPORTED
  224. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
  225. {
  226. png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
  227. if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
  228. return (info_ptr->y_offset);
  229. }
  230. #endif
  231. return (0);
  232. }
  233. #ifdef PNG_INCH_CONVERSIONS_SUPPORTED
  234. static png_uint_32
  235. ppi_from_ppm(png_uint_32 ppm)
  236. {
  237. #if 0
  238. /* The conversion is *(2.54/100), in binary (32 digits):
  239. * .00000110100000001001110101001001
  240. */
  241. png_uint_32 t1001, t1101;
  242. ppm >>= 1; /* .1 */
  243. t1001 = ppm + (ppm >> 3); /* .1001 */
  244. t1101 = t1001 + (ppm >> 1); /* .1101 */
  245. ppm >>= 20; /* .000000000000000000001 */
  246. t1101 += t1101 >> 15; /* .1101000000000001101 */
  247. t1001 >>= 11; /* .000000000001001 */
  248. t1001 += t1001 >> 12; /* .000000000001001000000001001 */
  249. ppm += t1001; /* .000000000001001000001001001 */
  250. ppm += t1101; /* .110100000001001110101001001 */
  251. return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
  252. #else
  253. /* The argument is a PNG unsigned integer, so it is not permitted
  254. * to be bigger than 2^31.
  255. */
  256. png_fixed_point result;
  257. if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
  258. 5000))
  259. return result;
  260. /* Overflow. */
  261. return 0;
  262. #endif
  263. }
  264. png_uint_32 PNGAPI
  265. png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
  266. {
  267. return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
  268. }
  269. png_uint_32 PNGAPI
  270. png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
  271. {
  272. return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
  273. }
  274. png_uint_32 PNGAPI
  275. png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
  276. {
  277. return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
  278. }
  279. #ifdef PNG_FIXED_POINT_SUPPORTED
  280. static png_fixed_point
  281. png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
  282. {
  283. /* Convert from metres * 1,000,000 to inches * 100,000, meters to
  284. * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
  285. * Notice that this can overflow - a warning is output and 0 is
  286. * returned.
  287. */
  288. return png_muldiv_warn(png_ptr, microns, 500, 127);
  289. }
  290. png_fixed_point PNGAPI
  291. png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
  292. png_const_inforp info_ptr)
  293. {
  294. return png_fixed_inches_from_microns(png_ptr,
  295. png_get_x_offset_microns(png_ptr, info_ptr));
  296. }
  297. #endif
  298. #ifdef PNG_FIXED_POINT_SUPPORTED
  299. png_fixed_point PNGAPI
  300. png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
  301. png_const_inforp info_ptr)
  302. {
  303. return png_fixed_inches_from_microns(png_ptr,
  304. png_get_y_offset_microns(png_ptr, info_ptr));
  305. }
  306. #endif
  307. #ifdef PNG_FLOATING_POINT_SUPPORTED
  308. float PNGAPI
  309. png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
  310. {
  311. /* To avoid the overflow do the conversion directly in floating
  312. * point.
  313. */
  314. return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
  315. }
  316. #endif
  317. #ifdef PNG_FLOATING_POINT_SUPPORTED
  318. float PNGAPI
  319. png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
  320. {
  321. /* To avoid the overflow do the conversion directly in floating
  322. * point.
  323. */
  324. return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
  325. }
  326. #endif
  327. #ifdef PNG_pHYs_SUPPORTED
  328. png_uint_32 PNGAPI
  329. png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
  330. png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
  331. {
  332. png_uint_32 retval = 0;
  333. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
  334. {
  335. png_debug1(1, "in %s retrieval function", "pHYs");
  336. if (res_x != NULL)
  337. {
  338. *res_x = info_ptr->x_pixels_per_unit;
  339. retval |= PNG_INFO_pHYs;
  340. }
  341. if (res_y != NULL)
  342. {
  343. *res_y = info_ptr->y_pixels_per_unit;
  344. retval |= PNG_INFO_pHYs;
  345. }
  346. if (unit_type != NULL)
  347. {
  348. *unit_type = (int)info_ptr->phys_unit_type;
  349. retval |= PNG_INFO_pHYs;
  350. if (*unit_type == 1)
  351. {
  352. if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
  353. if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
  354. }
  355. }
  356. }
  357. return (retval);
  358. }
  359. #endif /* PNG_pHYs_SUPPORTED */
  360. #endif /* PNG_INCH_CONVERSIONS_SUPPORTED */
  361. /* png_get_channels really belongs in here, too, but it's been around longer */
  362. #endif /* PNG_EASY_ACCESS_SUPPORTED */
  363. png_byte PNGAPI
  364. png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
  365. {
  366. if (png_ptr != NULL && info_ptr != NULL)
  367. return(info_ptr->channels);
  368. return (0);
  369. }
  370. #ifdef PNG_READ_SUPPORTED
  371. png_const_bytep PNGAPI
  372. png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
  373. {
  374. if (png_ptr != NULL && info_ptr != NULL)
  375. return(info_ptr->signature);
  376. return (NULL);
  377. }
  378. #endif
  379. #ifdef PNG_bKGD_SUPPORTED
  380. png_uint_32 PNGAPI
  381. png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
  382. png_color_16p *background)
  383. {
  384. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
  385. && background != NULL)
  386. {
  387. png_debug1(1, "in %s retrieval function", "bKGD");
  388. *background = &(info_ptr->background);
  389. return (PNG_INFO_bKGD);
  390. }
  391. return (0);
  392. }
  393. #endif
  394. #ifdef PNG_cHRM_SUPPORTED
  395. /* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
  396. * same time to correct the rgb grayscale coefficient defaults obtained from the
  397. * cHRM chunk in 1.5.4
  398. */
  399. # ifdef PNG_FLOATING_POINT_SUPPORTED
  400. png_uint_32 PNGAPI
  401. png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
  402. double *white_x, double *white_y, double *red_x, double *red_y,
  403. double *green_x, double *green_y, double *blue_x, double *blue_y)
  404. {
  405. /* Quiet API change: this code used to only return the end points if a cHRM
  406. * chunk was present, but the end points can also come from iCCP or sRGB
  407. * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
  408. * the png_set_ APIs merely check that set end points are mutually
  409. * consistent.
  410. */
  411. if (png_ptr != NULL && info_ptr != NULL &&
  412. (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
  413. {
  414. png_debug1(1, "in %s retrieval function", "cHRM");
  415. if (white_x != NULL)
  416. *white_x = png_float(png_ptr,
  417. info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
  418. if (white_y != NULL)
  419. *white_y = png_float(png_ptr,
  420. info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
  421. if (red_x != NULL)
  422. *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
  423. "cHRM red X");
  424. if (red_y != NULL)
  425. *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
  426. "cHRM red Y");
  427. if (green_x != NULL)
  428. *green_x = png_float(png_ptr,
  429. info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
  430. if (green_y != NULL)
  431. *green_y = png_float(png_ptr,
  432. info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
  433. if (blue_x != NULL)
  434. *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
  435. "cHRM blue X");
  436. if (blue_y != NULL)
  437. *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
  438. "cHRM blue Y");
  439. return (PNG_INFO_cHRM);
  440. }
  441. return (0);
  442. }
  443. png_uint_32 PNGAPI
  444. png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
  445. double *red_X, double *red_Y, double *red_Z, double *green_X,
  446. double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
  447. double *blue_Z)
  448. {
  449. if (png_ptr != NULL && info_ptr != NULL &&
  450. (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
  451. {
  452. png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
  453. if (red_X != NULL)
  454. *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
  455. "cHRM red X");
  456. if (red_Y != NULL)
  457. *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
  458. "cHRM red Y");
  459. if (red_Z != NULL)
  460. *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
  461. "cHRM red Z");
  462. if (green_X != NULL)
  463. *green_X = png_float(png_ptr,
  464. info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
  465. if (green_Y != NULL)
  466. *green_Y = png_float(png_ptr,
  467. info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
  468. if (green_Z != NULL)
  469. *green_Z = png_float(png_ptr,
  470. info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
  471. if (blue_X != NULL)
  472. *blue_X = png_float(png_ptr,
  473. info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
  474. if (blue_Y != NULL)
  475. *blue_Y = png_float(png_ptr,
  476. info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
  477. if (blue_Z != NULL)
  478. *blue_Z = png_float(png_ptr,
  479. info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
  480. return (PNG_INFO_cHRM);
  481. }
  482. return (0);
  483. }
  484. # endif
  485. # ifdef PNG_FIXED_POINT_SUPPORTED
  486. png_uint_32 PNGAPI
  487. png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
  488. png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
  489. png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
  490. png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
  491. png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
  492. png_fixed_point *int_blue_Z)
  493. {
  494. if (png_ptr != NULL && info_ptr != NULL &&
  495. (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
  496. {
  497. png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
  498. if (int_red_X != NULL)
  499. *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
  500. if (int_red_Y != NULL)
  501. *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
  502. if (int_red_Z != NULL)
  503. *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
  504. if (int_green_X != NULL)
  505. *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
  506. if (int_green_Y != NULL)
  507. *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
  508. if (int_green_Z != NULL)
  509. *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
  510. if (int_blue_X != NULL)
  511. *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
  512. if (int_blue_Y != NULL)
  513. *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
  514. if (int_blue_Z != NULL)
  515. *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
  516. return (PNG_INFO_cHRM);
  517. }
  518. return (0);
  519. }
  520. png_uint_32 PNGAPI
  521. png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
  522. png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
  523. png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
  524. png_fixed_point *blue_x, png_fixed_point *blue_y)
  525. {
  526. png_debug1(1, "in %s retrieval function", "cHRM");
  527. if (png_ptr != NULL && info_ptr != NULL &&
  528. (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
  529. {
  530. if (white_x != NULL)
  531. *white_x = info_ptr->colorspace.end_points_xy.whitex;
  532. if (white_y != NULL)
  533. *white_y = info_ptr->colorspace.end_points_xy.whitey;
  534. if (red_x != NULL)
  535. *red_x = info_ptr->colorspace.end_points_xy.redx;
  536. if (red_y != NULL)
  537. *red_y = info_ptr->colorspace.end_points_xy.redy;
  538. if (green_x != NULL)
  539. *green_x = info_ptr->colorspace.end_points_xy.greenx;
  540. if (green_y != NULL)
  541. *green_y = info_ptr->colorspace.end_points_xy.greeny;
  542. if (blue_x != NULL)
  543. *blue_x = info_ptr->colorspace.end_points_xy.bluex;
  544. if (blue_y != NULL)
  545. *blue_y = info_ptr->colorspace.end_points_xy.bluey;
  546. return (PNG_INFO_cHRM);
  547. }
  548. return (0);
  549. }
  550. # endif
  551. #endif
  552. #ifdef PNG_gAMA_SUPPORTED
  553. # ifdef PNG_FIXED_POINT_SUPPORTED
  554. png_uint_32 PNGAPI
  555. png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
  556. png_fixed_point *file_gamma)
  557. {
  558. png_debug1(1, "in %s retrieval function", "gAMA");
  559. if (png_ptr != NULL && info_ptr != NULL &&
  560. (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) &&
  561. file_gamma != NULL)
  562. {
  563. *file_gamma = info_ptr->colorspace.gamma;
  564. return (PNG_INFO_gAMA);
  565. }
  566. return (0);
  567. }
  568. # endif
  569. # ifdef PNG_FLOATING_POINT_SUPPORTED
  570. png_uint_32 PNGAPI
  571. png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
  572. double *file_gamma)
  573. {
  574. png_debug1(1, "in %s retrieval function", "gAMA(float)");
  575. if (png_ptr != NULL && info_ptr != NULL &&
  576. (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) &&
  577. file_gamma != NULL)
  578. {
  579. *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
  580. "png_get_gAMA");
  581. return (PNG_INFO_gAMA);
  582. }
  583. return (0);
  584. }
  585. # endif
  586. #endif
  587. #ifdef PNG_sRGB_SUPPORTED
  588. png_uint_32 PNGAPI
  589. png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
  590. int *file_srgb_intent)
  591. {
  592. png_debug1(1, "in %s retrieval function", "sRGB");
  593. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
  594. && file_srgb_intent != NULL)
  595. {
  596. *file_srgb_intent = info_ptr->colorspace.rendering_intent;
  597. return (PNG_INFO_sRGB);
  598. }
  599. return (0);
  600. }
  601. #endif
  602. #ifdef PNG_iCCP_SUPPORTED
  603. png_uint_32 PNGAPI
  604. png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
  605. png_charpp name, int *compression_type,
  606. png_bytepp profile, png_uint_32 *proflen)
  607. {
  608. png_debug1(1, "in %s retrieval function", "iCCP");
  609. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
  610. && name != NULL && compression_type != NULL && profile != NULL &&
  611. proflen != NULL)
  612. {
  613. *name = info_ptr->iccp_name;
  614. *profile = info_ptr->iccp_profile;
  615. *proflen = png_get_uint_32(info_ptr->iccp_profile);
  616. /* This is somewhat irrelevant since the profile data returned has
  617. * actually been uncompressed.
  618. */
  619. *compression_type = PNG_COMPRESSION_TYPE_BASE;
  620. return (PNG_INFO_iCCP);
  621. }
  622. return (0);
  623. }
  624. #endif
  625. #ifdef PNG_sPLT_SUPPORTED
  626. int PNGAPI
  627. png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
  628. png_sPLT_tpp spalettes)
  629. {
  630. if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
  631. {
  632. *spalettes = info_ptr->splt_palettes;
  633. return info_ptr->splt_palettes_num;
  634. }
  635. return (0);
  636. }
  637. #endif
  638. #ifdef PNG_hIST_SUPPORTED
  639. png_uint_32 PNGAPI
  640. png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
  641. png_uint_16p *hist)
  642. {
  643. png_debug1(1, "in %s retrieval function", "hIST");
  644. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
  645. && hist != NULL)
  646. {
  647. *hist = info_ptr->hist;
  648. return (PNG_INFO_hIST);
  649. }
  650. return (0);
  651. }
  652. #endif
  653. png_uint_32 PNGAPI
  654. png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
  655. png_uint_32 *width, png_uint_32 *height, int *bit_depth,
  656. int *color_type, int *interlace_type, int *compression_type,
  657. int *filter_type)
  658. {
  659. png_debug1(1, "in %s retrieval function", "IHDR");
  660. if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
  661. height == NULL || bit_depth == NULL || color_type == NULL)
  662. return (0);
  663. *width = info_ptr->width;
  664. *height = info_ptr->height;
  665. *bit_depth = info_ptr->bit_depth;
  666. *color_type = info_ptr->color_type;
  667. if (compression_type != NULL)
  668. *compression_type = info_ptr->compression_type;
  669. if (filter_type != NULL)
  670. *filter_type = info_ptr->filter_type;
  671. if (interlace_type != NULL)
  672. *interlace_type = info_ptr->interlace_type;
  673. /* This is redundant if we can be sure that the info_ptr values were all
  674. * assigned in png_set_IHDR(). We do the check anyhow in case an
  675. * application has ignored our advice not to mess with the members
  676. * of info_ptr directly.
  677. */
  678. png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
  679. info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
  680. info_ptr->compression_type, info_ptr->filter_type);
  681. return (1);
  682. }
  683. #ifdef PNG_oFFs_SUPPORTED
  684. png_uint_32 PNGAPI
  685. png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
  686. png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
  687. {
  688. png_debug1(1, "in %s retrieval function", "oFFs");
  689. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
  690. && offset_x != NULL && offset_y != NULL && unit_type != NULL)
  691. {
  692. *offset_x = info_ptr->x_offset;
  693. *offset_y = info_ptr->y_offset;
  694. *unit_type = (int)info_ptr->offset_unit_type;
  695. return (PNG_INFO_oFFs);
  696. }
  697. return (0);
  698. }
  699. #endif
  700. #ifdef PNG_pCAL_SUPPORTED
  701. png_uint_32 PNGAPI
  702. png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
  703. png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
  704. png_charp *units, png_charpp *params)
  705. {
  706. png_debug1(1, "in %s retrieval function", "pCAL");
  707. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
  708. && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
  709. nparams != NULL && units != NULL && params != NULL)
  710. {
  711. *purpose = info_ptr->pcal_purpose;
  712. *X0 = info_ptr->pcal_X0;
  713. *X1 = info_ptr->pcal_X1;
  714. *type = (int)info_ptr->pcal_type;
  715. *nparams = (int)info_ptr->pcal_nparams;
  716. *units = info_ptr->pcal_units;
  717. *params = info_ptr->pcal_params;
  718. return (PNG_INFO_pCAL);
  719. }
  720. return (0);
  721. }
  722. #endif
  723. #ifdef PNG_sCAL_SUPPORTED
  724. # ifdef PNG_FIXED_POINT_SUPPORTED
  725. # if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
  726. defined(PNG_FLOATING_POINT_SUPPORTED)
  727. png_uint_32 PNGAPI
  728. png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
  729. int *unit, png_fixed_point *width, png_fixed_point *height)
  730. {
  731. if (png_ptr != NULL && info_ptr != NULL &&
  732. (info_ptr->valid & PNG_INFO_sCAL))
  733. {
  734. *unit = info_ptr->scal_unit;
  735. /*TODO: make this work without FP support; the API is currently eliminated
  736. * if neither floating point APIs nor internal floating point arithmetic
  737. * are enabled.
  738. */
  739. *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
  740. *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
  741. "sCAL height");
  742. return (PNG_INFO_sCAL);
  743. }
  744. return(0);
  745. }
  746. # endif /* FLOATING_ARITHMETIC */
  747. # endif /* FIXED_POINT */
  748. # ifdef PNG_FLOATING_POINT_SUPPORTED
  749. png_uint_32 PNGAPI
  750. png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
  751. int *unit, double *width, double *height)
  752. {
  753. if (png_ptr != NULL && info_ptr != NULL &&
  754. (info_ptr->valid & PNG_INFO_sCAL))
  755. {
  756. *unit = info_ptr->scal_unit;
  757. *width = atof(info_ptr->scal_s_width);
  758. *height = atof(info_ptr->scal_s_height);
  759. return (PNG_INFO_sCAL);
  760. }
  761. return(0);
  762. }
  763. # endif /* FLOATING POINT */
  764. png_uint_32 PNGAPI
  765. png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
  766. int *unit, png_charpp width, png_charpp height)
  767. {
  768. if (png_ptr != NULL && info_ptr != NULL &&
  769. (info_ptr->valid & PNG_INFO_sCAL))
  770. {
  771. *unit = info_ptr->scal_unit;
  772. *width = info_ptr->scal_s_width;
  773. *height = info_ptr->scal_s_height;
  774. return (PNG_INFO_sCAL);
  775. }
  776. return(0);
  777. }
  778. #endif /* sCAL */
  779. #ifdef PNG_pHYs_SUPPORTED
  780. png_uint_32 PNGAPI
  781. png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
  782. png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
  783. {
  784. png_uint_32 retval = 0;
  785. png_debug1(1, "in %s retrieval function", "pHYs");
  786. if (png_ptr != NULL && info_ptr != NULL &&
  787. (info_ptr->valid & PNG_INFO_pHYs))
  788. {
  789. if (res_x != NULL)
  790. {
  791. *res_x = info_ptr->x_pixels_per_unit;
  792. retval |= PNG_INFO_pHYs;
  793. }
  794. if (res_y != NULL)
  795. {
  796. *res_y = info_ptr->y_pixels_per_unit;
  797. retval |= PNG_INFO_pHYs;
  798. }
  799. if (unit_type != NULL)
  800. {
  801. *unit_type = (int)info_ptr->phys_unit_type;
  802. retval |= PNG_INFO_pHYs;
  803. }
  804. }
  805. return (retval);
  806. }
  807. #endif /* pHYs */
  808. png_uint_32 PNGAPI
  809. png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
  810. png_colorp *palette, int *num_palette)
  811. {
  812. png_debug1(1, "in %s retrieval function", "PLTE");
  813. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
  814. && palette != NULL)
  815. {
  816. *palette = info_ptr->palette;
  817. *num_palette = info_ptr->num_palette;
  818. png_debug1(3, "num_palette = %d", *num_palette);
  819. return (PNG_INFO_PLTE);
  820. }
  821. return (0);
  822. }
  823. #ifdef PNG_sBIT_SUPPORTED
  824. png_uint_32 PNGAPI
  825. png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
  826. png_color_8p *sig_bit)
  827. {
  828. png_debug1(1, "in %s retrieval function", "sBIT");
  829. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
  830. && sig_bit != NULL)
  831. {
  832. *sig_bit = &(info_ptr->sig_bit);
  833. return (PNG_INFO_sBIT);
  834. }
  835. return (0);
  836. }
  837. #endif
  838. #ifdef PNG_TEXT_SUPPORTED
  839. int PNGAPI
  840. png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
  841. png_textp *text_ptr, int *num_text)
  842. {
  843. if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
  844. {
  845. png_debug1(1, "in 0x%lx retrieval function",
  846. (unsigned long)png_ptr->chunk_name);
  847. if (text_ptr != NULL)
  848. *text_ptr = info_ptr->text;
  849. if (num_text != NULL)
  850. *num_text = info_ptr->num_text;
  851. return info_ptr->num_text;
  852. }
  853. if (num_text != NULL)
  854. *num_text = 0;
  855. return(0);
  856. }
  857. #endif
  858. #ifdef PNG_tIME_SUPPORTED
  859. png_uint_32 PNGAPI
  860. png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
  861. png_timep *mod_time)
  862. {
  863. png_debug1(1, "in %s retrieval function", "tIME");
  864. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
  865. && mod_time != NULL)
  866. {
  867. *mod_time = &(info_ptr->mod_time);
  868. return (PNG_INFO_tIME);
  869. }
  870. return (0);
  871. }
  872. #endif
  873. #ifdef PNG_tRNS_SUPPORTED
  874. png_uint_32 PNGAPI
  875. png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
  876. png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
  877. {
  878. png_uint_32 retval = 0;
  879. if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
  880. {
  881. png_debug1(1, "in %s retrieval function", "tRNS");
  882. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  883. {
  884. if (trans_alpha != NULL)
  885. {
  886. *trans_alpha = info_ptr->trans_alpha;
  887. retval |= PNG_INFO_tRNS;
  888. }
  889. if (trans_color != NULL)
  890. *trans_color = &(info_ptr->trans_color);
  891. }
  892. else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
  893. {
  894. if (trans_color != NULL)
  895. {
  896. *trans_color = &(info_ptr->trans_color);
  897. retval |= PNG_INFO_tRNS;
  898. }
  899. if (trans_alpha != NULL)
  900. *trans_alpha = NULL;
  901. }
  902. if (num_trans != NULL)
  903. {
  904. *num_trans = info_ptr->num_trans;
  905. retval |= PNG_INFO_tRNS;
  906. }
  907. }
  908. return (retval);
  909. }
  910. #endif
  911. #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
  912. int PNGAPI
  913. png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
  914. png_unknown_chunkpp unknowns)
  915. {
  916. if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
  917. {
  918. *unknowns = info_ptr->unknown_chunks;
  919. return info_ptr->unknown_chunks_num;
  920. }
  921. return (0);
  922. }
  923. #endif
  924. #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
  925. png_byte PNGAPI
  926. png_get_rgb_to_gray_status (png_const_structrp png_ptr)
  927. {
  928. return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
  929. }
  930. #endif
  931. #ifdef PNG_USER_CHUNKS_SUPPORTED
  932. png_voidp PNGAPI
  933. png_get_user_chunk_ptr(png_const_structrp png_ptr)
  934. {
  935. return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
  936. }
  937. #endif
  938. png_size_t PNGAPI
  939. png_get_compression_buffer_size(png_const_structrp png_ptr)
  940. {
  941. if (png_ptr == NULL)
  942. return 0;
  943. # ifdef PNG_WRITE_SUPPORTED
  944. if (png_ptr->mode & PNG_IS_READ_STRUCT)
  945. # endif
  946. {
  947. # ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  948. return png_ptr->IDAT_read_size;
  949. # else
  950. return PNG_IDAT_READ_SIZE;
  951. # endif
  952. }
  953. # ifdef PNG_WRITE_SUPPORTED
  954. else
  955. return png_ptr->zbuffer_size;
  956. # endif
  957. }
  958. #ifdef PNG_SET_USER_LIMITS_SUPPORTED
  959. /* These functions were added to libpng 1.2.6 and were enabled
  960. * by default in libpng-1.4.0 */
  961. png_uint_32 PNGAPI
  962. png_get_user_width_max (png_const_structrp png_ptr)
  963. {
  964. return (png_ptr ? png_ptr->user_width_max : 0);
  965. }
  966. png_uint_32 PNGAPI
  967. png_get_user_height_max (png_const_structrp png_ptr)
  968. {
  969. return (png_ptr ? png_ptr->user_height_max : 0);
  970. }
  971. /* This function was added to libpng 1.4.0 */
  972. png_uint_32 PNGAPI
  973. png_get_chunk_cache_max (png_const_structrp png_ptr)
  974. {
  975. return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
  976. }
  977. /* This function was added to libpng 1.4.1 */
  978. png_alloc_size_t PNGAPI
  979. png_get_chunk_malloc_max (png_const_structrp png_ptr)
  980. {
  981. return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
  982. }
  983. #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
  984. /* These functions were added to libpng 1.4.0 */
  985. #ifdef PNG_IO_STATE_SUPPORTED
  986. png_uint_32 PNGAPI
  987. png_get_io_state (png_const_structrp png_ptr)
  988. {
  989. return png_ptr->io_state;
  990. }
  991. png_uint_32 PNGAPI
  992. png_get_io_chunk_type (png_const_structrp png_ptr)
  993. {
  994. return png_ptr->chunk_name;
  995. }
  996. #endif /* ?PNG_IO_STATE_SUPPORTED */
  997. #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
  998. # ifdef PNG_GET_PALETTE_MAX_SUPPORTED
  999. int PNGAPI
  1000. png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
  1001. {
  1002. if (png_ptr != NULL && info_ptr != NULL)
  1003. return png_ptr->num_palette_max;
  1004. return (-1);
  1005. }
  1006. # endif
  1007. #endif
  1008. #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */