pngget.c 30 KB

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