pngget.c 31 KB

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