1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25/* pngget.c - retrieval of values from info struct
26 *
27 * This file is available under and governed by the GNU General Public
28 * License version 2 only, as published by the Free Software Foundation.
29 * However, the following notice accompanied the original version of this
30 * file and, per its terms, should not be removed:
31 *
32 * Last changed in libpng 1.6.35 [July 15, 2018]
33 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
34 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
35 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
36 *
37 * This code is released under the libpng license.
38 * For conditions of distribution and use, see the disclaimer
39 * and license in png.h
40 *
41 */
42
43#include "pngpriv.h"
44
45#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
46
47png_uint_32 PNGAPI
48png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
49 png_uint_32 flag)
50{
51 if (png_ptr != NULL && info_ptr != NULL)
52 return(info_ptr->valid & flag);
53
54 return(0);
55}
56
57size_t PNGAPI
58png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
59{
60 if (png_ptr != NULL && info_ptr != NULL)
61 return(info_ptr->rowbytes);
62
63 return(0);
64}
65
66#ifdef PNG_INFO_IMAGE_SUPPORTED
67png_bytepp PNGAPI
68png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
69{
70 if (png_ptr != NULL && info_ptr != NULL)
71 return(info_ptr->row_pointers);
72
73 return(0);
74}
75#endif
76
77#ifdef PNG_EASY_ACCESS_SUPPORTED
78/* Easy access to info, added in libpng-0.99 */
79png_uint_32 PNGAPI
80png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
81{
82 if (png_ptr != NULL && info_ptr != NULL)
83 return info_ptr->width;
84
85 return (0);
86}
87
88png_uint_32 PNGAPI
89png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
90{
91 if (png_ptr != NULL && info_ptr != NULL)
92 return info_ptr->height;
93
94 return (0);
95}
96
97png_byte PNGAPI
98png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
99{
100 if (png_ptr != NULL && info_ptr != NULL)
101 return info_ptr->bit_depth;
102
103 return (0);
104}
105
106png_byte PNGAPI
107png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
108{
109 if (png_ptr != NULL && info_ptr != NULL)
110 return info_ptr->color_type;
111
112 return (0);
113}
114
115png_byte PNGAPI
116png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
117{
118 if (png_ptr != NULL && info_ptr != NULL)
119 return info_ptr->filter_type;
120
121 return (0);
122}
123
124png_byte PNGAPI
125png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
126{
127 if (png_ptr != NULL && info_ptr != NULL)
128 return info_ptr->interlace_type;
129
130 return (0);
131}
132
133png_byte PNGAPI
134png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
135{
136 if (png_ptr != NULL && info_ptr != NULL)
137 return info_ptr->compression_type;
138
139 return (0);
140}
141
142png_uint_32 PNGAPI
143png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
144 info_ptr)
145{
146#ifdef PNG_pHYs_SUPPORTED
147 if (png_ptr != NULL && info_ptr != NULL &&
148 (info_ptr->valid & PNG_INFO_pHYs) != 0)
149 {
150 png_debug1(1, "in %s retrieval function",
151 "png_get_x_pixels_per_meter");
152
153 if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
154 return (info_ptr->x_pixels_per_unit);
155 }
156#else
157 PNG_UNUSED(png_ptr)
158 PNG_UNUSED(info_ptr)
159#endif
160
161 return (0);
162}
163
164png_uint_32 PNGAPI
165png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
166 info_ptr)
167{
168#ifdef PNG_pHYs_SUPPORTED
169 if (png_ptr != NULL && info_ptr != NULL &&
170 (info_ptr->valid & PNG_INFO_pHYs) != 0)
171 {
172 png_debug1(1, "in %s retrieval function",
173 "png_get_y_pixels_per_meter");
174
175 if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
176 return (info_ptr->y_pixels_per_unit);
177 }
178#else
179 PNG_UNUSED(png_ptr)
180 PNG_UNUSED(info_ptr)
181#endif
182
183 return (0);
184}
185
186png_uint_32 PNGAPI
187png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
188{
189#ifdef PNG_pHYs_SUPPORTED
190 if (png_ptr != NULL && info_ptr != NULL &&
191 (info_ptr->valid & PNG_INFO_pHYs) != 0)
192 {
193 png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
194
195 if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
196 info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
197 return (info_ptr->x_pixels_per_unit);
198 }
199#else
200 PNG_UNUSED(png_ptr)
201 PNG_UNUSED(info_ptr)
202#endif
203
204 return (0);
205}
206
207#ifdef PNG_FLOATING_POINT_SUPPORTED
208float PNGAPI
209png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
210 info_ptr)
211{
212#ifdef PNG_READ_pHYs_SUPPORTED
213 if (png_ptr != NULL && info_ptr != NULL &&
214 (info_ptr->valid & PNG_INFO_pHYs) != 0)
215 {
216 png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
217
218 if (info_ptr->x_pixels_per_unit != 0)
219 return ((float)((float)info_ptr->y_pixels_per_unit
220 /(float)info_ptr->x_pixels_per_unit));
221 }
222#else
223 PNG_UNUSED(png_ptr)
224 PNG_UNUSED(info_ptr)
225#endif
226
227 return ((float)0.0);
228}
229#endif
230
231#ifdef PNG_FIXED_POINT_SUPPORTED
232png_fixed_point PNGAPI
233png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
234 png_const_inforp info_ptr)
235{
236#ifdef PNG_READ_pHYs_SUPPORTED
237 if (png_ptr != NULL && info_ptr != NULL &&
238 (info_ptr->valid & PNG_INFO_pHYs) != 0 &&
239 info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
240 info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&
241 info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
242 {
243 png_fixed_point res;
244
245 png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
246
247 /* The following casts work because a PNG 4 byte integer only has a valid
248 * range of 0..2^31-1; otherwise the cast might overflow.
249 */
250 if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
251 (png_int_32)info_ptr->x_pixels_per_unit) != 0)
252 return res;
253 }
254#else
255 PNG_UNUSED(png_ptr)
256 PNG_UNUSED(info_ptr)
257#endif
258
259 return 0;
260}
261#endif
262
263png_int_32 PNGAPI
264png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
265{
266#ifdef PNG_oFFs_SUPPORTED
267 if (png_ptr != NULL && info_ptr != NULL &&
268 (info_ptr->valid & PNG_INFO_oFFs) != 0)
269 {
270 png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
271
272 if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
273 return (info_ptr->x_offset);
274 }
275#else
276 PNG_UNUSED(png_ptr)
277 PNG_UNUSED(info_ptr)
278#endif
279
280 return (0);
281}
282
283png_int_32 PNGAPI
284png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
285{
286#ifdef PNG_oFFs_SUPPORTED
287 if (png_ptr != NULL && info_ptr != NULL &&
288 (info_ptr->valid & PNG_INFO_oFFs) != 0)
289 {
290 png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
291
292 if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
293 return (info_ptr->y_offset);
294 }
295#else
296 PNG_UNUSED(png_ptr)
297 PNG_UNUSED(info_ptr)
298#endif
299
300 return (0);
301}
302
303png_int_32 PNGAPI
304png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
305{
306#ifdef PNG_oFFs_SUPPORTED
307 if (png_ptr != NULL && info_ptr != NULL &&
308 (info_ptr->valid & PNG_INFO_oFFs) != 0)
309 {
310 png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
311
312 if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
313 return (info_ptr->x_offset);
314 }
315#else
316 PNG_UNUSED(png_ptr)
317 PNG_UNUSED(info_ptr)
318#endif
319
320 return (0);
321}
322
323png_int_32 PNGAPI
324png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
325{
326#ifdef PNG_oFFs_SUPPORTED
327 if (png_ptr != NULL && info_ptr != NULL &&
328 (info_ptr->valid & PNG_INFO_oFFs) != 0)
329 {
330 png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
331
332 if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
333 return (info_ptr->y_offset);
334 }
335#else
336 PNG_UNUSED(png_ptr)
337 PNG_UNUSED(info_ptr)
338#endif
339
340 return (0);
341}
342
343#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
344static png_uint_32
345ppi_from_ppm(png_uint_32 ppm)
346{
347#if 0
348 /* The conversion is *(2.54/100), in binary (32 digits):
349 * .00000110100000001001110101001001
350 */
351 png_uint_32 t1001, t1101;
352 ppm >>= 1; /* .1 */
353 t1001 = ppm + (ppm >> 3); /* .1001 */
354 t1101 = t1001 + (ppm >> 1); /* .1101 */
355 ppm >>= 20; /* .000000000000000000001 */
356 t1101 += t1101 >> 15; /* .1101000000000001101 */
357 t1001 >>= 11; /* .000000000001001 */
358 t1001 += t1001 >> 12; /* .000000000001001000000001001 */
359 ppm += t1001; /* .000000000001001000001001001 */
360 ppm += t1101; /* .110100000001001110101001001 */
361 return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
362#else
363 /* The argument is a PNG unsigned integer, so it is not permitted
364 * to be bigger than 2^31.
365 */
366 png_fixed_point result;
367 if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
368 5000) != 0)
369 return (png_uint_32)result;
370
371 /* Overflow. */
372 return 0;
373#endif
374}
375
376png_uint_32 PNGAPI
377png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
378{
379 return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
380}
381
382png_uint_32 PNGAPI
383png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
384{
385 return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
386}
387
388png_uint_32 PNGAPI
389png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
390{
391 return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
392}
393
394#ifdef PNG_FIXED_POINT_SUPPORTED
395static png_fixed_point
396png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
397{
398 /* Convert from meters * 1,000,000 to inches * 100,000, meters to
399 * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
400 * Notice that this can overflow - a warning is output and 0 is
401 * returned.
402 */
403 return png_muldiv_warn(png_ptr, microns, 500, 127);
404}
405
406png_fixed_point PNGAPI
407png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
408 png_const_inforp info_ptr)
409{
410 return png_fixed_inches_from_microns(png_ptr,
411 png_get_x_offset_microns(png_ptr, info_ptr));
412}
413#endif
414
415#ifdef PNG_FIXED_POINT_SUPPORTED
416png_fixed_point PNGAPI
417png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
418 png_const_inforp info_ptr)
419{
420 return png_fixed_inches_from_microns(png_ptr,
421 png_get_y_offset_microns(png_ptr, info_ptr));
422}
423#endif
424
425#ifdef PNG_FLOATING_POINT_SUPPORTED
426float PNGAPI
427png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
428{
429 /* To avoid the overflow do the conversion directly in floating
430 * point.
431 */
432 return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
433}
434#endif
435
436#ifdef PNG_FLOATING_POINT_SUPPORTED
437float PNGAPI
438png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
439{
440 /* To avoid the overflow do the conversion directly in floating
441 * point.
442 */
443 return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
444}
445#endif
446
447#ifdef PNG_pHYs_SUPPORTED
448png_uint_32 PNGAPI
449png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
450 png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
451{
452 png_uint_32 retval = 0;
453
454 if (png_ptr != NULL && info_ptr != NULL &&
455 (info_ptr->valid & PNG_INFO_pHYs) != 0)
456 {
457 png_debug1(1, "in %s retrieval function", "pHYs");
458
459 if (res_x != NULL)
460 {
461 *res_x = info_ptr->x_pixels_per_unit;
462 retval |= PNG_INFO_pHYs;
463 }
464
465 if (res_y != NULL)
466 {
467 *res_y = info_ptr->y_pixels_per_unit;
468 retval |= PNG_INFO_pHYs;
469 }
470
471 if (unit_type != NULL)
472 {
473 *unit_type = (int)info_ptr->phys_unit_type;
474 retval |= PNG_INFO_pHYs;
475
476 if (*unit_type == 1)
477 {
478 if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
479 if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
480 }
481 }
482 }
483
484 return (retval);
485}
486#endif /* pHYs */
487#endif /* INCH_CONVERSIONS */
488
489/* png_get_channels really belongs in here, too, but it's been around longer */
490
491#endif /* EASY_ACCESS */
492
493
494png_byte PNGAPI
495png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
496{
497 if (png_ptr != NULL && info_ptr != NULL)
498 return(info_ptr->channels);
499
500 return (0);
501}
502
503#ifdef PNG_READ_SUPPORTED
504png_const_bytep PNGAPI
505png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
506{
507 if (png_ptr != NULL && info_ptr != NULL)
508 return(info_ptr->signature);
509
510 return (NULL);
511}
512#endif
513
514#ifdef PNG_bKGD_SUPPORTED
515png_uint_32 PNGAPI
516png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
517 png_color_16p *background)
518{
519 if (png_ptr != NULL && info_ptr != NULL &&
520 (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
521 background != NULL)
522 {
523 png_debug1(1, "in %s retrieval function", "bKGD");
524
525 *background = &(info_ptr->background);
526 return (PNG_INFO_bKGD);
527 }
528
529 return (0);
530}
531#endif
532
533#ifdef PNG_cHRM_SUPPORTED
534/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
535 * same time to correct the rgb grayscale coefficient defaults obtained from the
536 * cHRM chunk in 1.5.4
537 */
538# ifdef PNG_FLOATING_POINT_SUPPORTED
539png_uint_32 PNGAPI
540png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
541 double *white_x, double *white_y, double *red_x, double *red_y,
542 double *green_x, double *green_y, double *blue_x, double *blue_y)
543{
544 /* Quiet API change: this code used to only return the end points if a cHRM
545 * chunk was present, but the end points can also come from iCCP or sRGB
546 * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
547 * the png_set_ APIs merely check that set end points are mutually
548 * consistent.
549 */
550 if (png_ptr != NULL && info_ptr != NULL &&
551 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
552 {
553 png_debug1(1, "in %s retrieval function", "cHRM");
554
555 if (white_x != NULL)
556 *white_x = png_float(png_ptr,
557 info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
558 if (white_y != NULL)
559 *white_y = png_float(png_ptr,
560 info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
561 if (red_x != NULL)
562 *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
563 "cHRM red X");
564 if (red_y != NULL)
565 *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
566 "cHRM red Y");
567 if (green_x != NULL)
568 *green_x = png_float(png_ptr,
569 info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
570 if (green_y != NULL)
571 *green_y = png_float(png_ptr,
572 info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
573 if (blue_x != NULL)
574 *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
575 "cHRM blue X");
576 if (blue_y != NULL)
577 *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
578 "cHRM blue Y");
579 return (PNG_INFO_cHRM);
580 }
581
582 return (0);
583}
584
585png_uint_32 PNGAPI
586png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
587 double *red_X, double *red_Y, double *red_Z, double *green_X,
588 double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
589 double *blue_Z)
590{
591 if (png_ptr != NULL && info_ptr != NULL &&
592 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
593 {
594 png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
595
596 if (red_X != NULL)
597 *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
598 "cHRM red X");
599 if (red_Y != NULL)
600 *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
601 "cHRM red Y");
602 if (red_Z != NULL)
603 *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
604 "cHRM red Z");
605 if (green_X != NULL)
606 *green_X = png_float(png_ptr,
607 info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
608 if (green_Y != NULL)
609 *green_Y = png_float(png_ptr,
610 info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
611 if (green_Z != NULL)
612 *green_Z = png_float(png_ptr,
613 info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
614 if (blue_X != NULL)
615 *blue_X = png_float(png_ptr,
616 info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
617 if (blue_Y != NULL)
618 *blue_Y = png_float(png_ptr,
619 info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
620 if (blue_Z != NULL)
621 *blue_Z = png_float(png_ptr,
622 info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
623 return (PNG_INFO_cHRM);
624 }
625
626 return (0);
627}
628# endif
629
630# ifdef PNG_FIXED_POINT_SUPPORTED
631png_uint_32 PNGAPI
632png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
633 png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
634 png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
635 png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
636 png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
637 png_fixed_point *int_blue_Z)
638{
639 if (png_ptr != NULL && info_ptr != NULL &&
640 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
641 {
642 png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
643
644 if (int_red_X != NULL)
645 *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
646 if (int_red_Y != NULL)
647 *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
648 if (int_red_Z != NULL)
649 *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
650 if (int_green_X != NULL)
651 *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
652 if (int_green_Y != NULL)
653 *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
654 if (int_green_Z != NULL)
655 *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
656 if (int_blue_X != NULL)
657 *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
658 if (int_blue_Y != NULL)
659 *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
660 if (int_blue_Z != NULL)
661 *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
662 return (PNG_INFO_cHRM);
663 }
664
665 return (0);
666}
667
668png_uint_32 PNGAPI
669png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
670 png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
671 png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
672 png_fixed_point *blue_x, png_fixed_point *blue_y)
673{
674 png_debug1(1, "in %s retrieval function", "cHRM");
675
676 if (png_ptr != NULL && info_ptr != NULL &&
677 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
678 {
679 if (white_x != NULL)
680 *white_x = info_ptr->colorspace.end_points_xy.whitex;
681 if (white_y != NULL)
682 *white_y = info_ptr->colorspace.end_points_xy.whitey;
683 if (red_x != NULL)
684 *red_x = info_ptr->colorspace.end_points_xy.redx;
685 if (red_y != NULL)
686 *red_y = info_ptr->colorspace.end_points_xy.redy;
687 if (green_x != NULL)
688 *green_x = info_ptr->colorspace.end_points_xy.greenx;
689 if (green_y != NULL)
690 *green_y = info_ptr->colorspace.end_points_xy.greeny;
691 if (blue_x != NULL)
692 *blue_x = info_ptr->colorspace.end_points_xy.bluex;
693 if (blue_y != NULL)
694 *blue_y = info_ptr->colorspace.end_points_xy.bluey;
695 return (PNG_INFO_cHRM);
696 }
697
698 return (0);
699}
700# endif
701#endif
702
703#ifdef PNG_gAMA_SUPPORTED
704# ifdef PNG_FIXED_POINT_SUPPORTED
705png_uint_32 PNGAPI
706png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
707 png_fixed_point *file_gamma)
708{
709 png_debug1(1, "in %s retrieval function", "gAMA");
710
711 if (png_ptr != NULL && info_ptr != NULL &&
712 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
713 file_gamma != NULL)
714 {
715 *file_gamma = info_ptr->colorspace.gamma;
716 return (PNG_INFO_gAMA);
717 }
718
719 return (0);
720}
721# endif
722
723# ifdef PNG_FLOATING_POINT_SUPPORTED
724png_uint_32 PNGAPI
725png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
726 double *file_gamma)
727{
728 png_debug1(1, "in %s retrieval function", "gAMA(float)");
729
730 if (png_ptr != NULL && info_ptr != NULL &&
731 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
732 file_gamma != NULL)
733 {
734 *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
735 "png_get_gAMA");
736 return (PNG_INFO_gAMA);
737 }
738
739 return (0);
740}
741# endif
742#endif
743
744#ifdef PNG_sRGB_SUPPORTED
745png_uint_32 PNGAPI
746png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
747 int *file_srgb_intent)
748{
749 png_debug1(1, "in %s retrieval function", "sRGB");
750
751 if (png_ptr != NULL && info_ptr != NULL &&
752 (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
753 {
754 *file_srgb_intent = info_ptr->colorspace.rendering_intent;
755 return (PNG_INFO_sRGB);
756 }
757
758 return (0);
759}
760#endif
761
762#ifdef PNG_iCCP_SUPPORTED
763png_uint_32 PNGAPI
764png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
765 png_charpp name, int *compression_type,
766 png_bytepp profile, png_uint_32 *proflen)
767{
768 png_debug1(1, "in %s retrieval function", "iCCP");
769
770 if (png_ptr != NULL && info_ptr != NULL &&
771 (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
772 name != NULL && profile != NULL && proflen != NULL)
773 {
774 *name = info_ptr->iccp_name;
775 *profile = info_ptr->iccp_profile;
776 *proflen = png_get_uint_32(info_ptr->iccp_profile);
777 /* This is somewhat irrelevant since the profile data returned has
778 * actually been uncompressed.
779 */
780 if (compression_type != NULL)
781 *compression_type = PNG_COMPRESSION_TYPE_BASE;
782 return (PNG_INFO_iCCP);
783 }
784
785 return (0);
786
787}
788#endif
789
790#ifdef PNG_sPLT_SUPPORTED
791int PNGAPI
792png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
793 png_sPLT_tpp spalettes)
794{
795 if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
796 {
797 *spalettes = info_ptr->splt_palettes;
798 return info_ptr->splt_palettes_num;
799 }
800
801 return (0);
802}
803#endif
804
805#ifdef PNG_eXIf_SUPPORTED
806png_uint_32 PNGAPI
807png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
808 png_bytep *exif)
809{
810 png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
811 PNG_UNUSED(info_ptr)
812 PNG_UNUSED(exif)
813 return 0;
814}
815
816png_uint_32 PNGAPI
817png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
818 png_uint_32 *num_exif, png_bytep *exif)
819{
820 png_debug1(1, "in %s retrieval function", "eXIf");
821
822 if (png_ptr != NULL && info_ptr != NULL &&
823 (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
824 {
825 *num_exif = info_ptr->num_exif;
826 *exif = info_ptr->exif;
827 return (PNG_INFO_eXIf);
828 }
829
830 return (0);
831}
832#endif
833
834#ifdef PNG_hIST_SUPPORTED
835png_uint_32 PNGAPI
836png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
837 png_uint_16p *hist)
838{
839 png_debug1(1, "in %s retrieval function", "hIST");
840
841 if (png_ptr != NULL && info_ptr != NULL &&
842 (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
843 {
844 *hist = info_ptr->hist;
845 return (PNG_INFO_hIST);
846 }
847
848 return (0);
849}
850#endif
851
852png_uint_32 PNGAPI
853png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
854 png_uint_32 *width, png_uint_32 *height, int *bit_depth,
855 int *color_type, int *interlace_type, int *compression_type,
856 int *filter_type)
857{
858 png_debug1(1, "in %s retrieval function", "IHDR");
859
860 if (png_ptr == NULL || info_ptr == NULL)
861 return (0);
862
863 if (width != NULL)
864 *width = info_ptr->width;
865
866 if (height != NULL)
867 *height = info_ptr->height;
868
869 if (bit_depth != NULL)
870 *bit_depth = info_ptr->bit_depth;
871
872 if (color_type != NULL)
873 *color_type = info_ptr->color_type;
874
875 if (compression_type != NULL)
876 *compression_type = info_ptr->compression_type;
877
878 if (filter_type != NULL)
879 *filter_type = info_ptr->filter_type;
880
881 if (interlace_type != NULL)
882 *interlace_type = info_ptr->interlace_type;
883
884 /* This is redundant if we can be sure that the info_ptr values were all
885 * assigned in png_set_IHDR(). We do the check anyhow in case an
886 * application has ignored our advice not to mess with the members
887 * of info_ptr directly.
888 */
889 png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
890 info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
891 info_ptr->compression_type, info_ptr->filter_type);
892
893 return (1);
894}
895
896#ifdef PNG_oFFs_SUPPORTED
897png_uint_32 PNGAPI
898png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
899 png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
900{
901 png_debug1(1, "in %s retrieval function", "oFFs");
902
903 if (png_ptr != NULL && info_ptr != NULL &&
904 (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
905 offset_x != NULL && offset_y != NULL && unit_type != NULL)
906 {
907 *offset_x = info_ptr->x_offset;
908 *offset_y = info_ptr->y_offset;
909 *unit_type = (int)info_ptr->offset_unit_type;
910 return (PNG_INFO_oFFs);
911 }
912
913 return (0);
914}
915#endif
916
917#ifdef PNG_pCAL_SUPPORTED
918png_uint_32 PNGAPI
919png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
920 png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
921 png_charp *units, png_charpp *params)
922{
923 png_debug1(1, "in %s retrieval function", "pCAL");
924
925 if (png_ptr != NULL && info_ptr != NULL &&
926 (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
927 purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
928 nparams != NULL && units != NULL && params != NULL)
929 {
930 *purpose = info_ptr->pcal_purpose;
931 *X0 = info_ptr->pcal_X0;
932 *X1 = info_ptr->pcal_X1;
933 *type = (int)info_ptr->pcal_type;
934 *nparams = (int)info_ptr->pcal_nparams;
935 *units = info_ptr->pcal_units;
936 *params = info_ptr->pcal_params;
937 return (PNG_INFO_pCAL);
938 }
939
940 return (0);
941}
942#endif
943
944#ifdef PNG_sCAL_SUPPORTED
945# ifdef PNG_FIXED_POINT_SUPPORTED
946# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
947 defined(PNG_FLOATING_POINT_SUPPORTED)
948png_uint_32 PNGAPI
949png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
950 int *unit, png_fixed_point *width, png_fixed_point *height)
951{
952 if (png_ptr != NULL && info_ptr != NULL &&
953 (info_ptr->valid & PNG_INFO_sCAL) != 0)
954 {
955 *unit = info_ptr->scal_unit;
956 /*TODO: make this work without FP support; the API is currently eliminated
957 * if neither floating point APIs nor internal floating point arithmetic
958 * are enabled.
959 */
960 *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
961 *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
962 "sCAL height");
963 return (PNG_INFO_sCAL);
964 }
965
966 return(0);
967}
968# endif /* FLOATING_ARITHMETIC */
969# endif /* FIXED_POINT */
970# ifdef PNG_FLOATING_POINT_SUPPORTED
971png_uint_32 PNGAPI
972png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
973 int *unit, double *width, double *height)
974{
975 if (png_ptr != NULL && info_ptr != NULL &&
976 (info_ptr->valid & PNG_INFO_sCAL) != 0)
977 {
978 *unit = info_ptr->scal_unit;
979 *width = atof(info_ptr->scal_s_width);
980 *height = atof(info_ptr->scal_s_height);
981 return (PNG_INFO_sCAL);
982 }
983
984 return(0);
985}
986# endif /* FLOATING POINT */
987png_uint_32 PNGAPI
988png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
989 int *unit, png_charpp width, png_charpp height)
990{
991 if (png_ptr != NULL && info_ptr != NULL &&
992 (info_ptr->valid & PNG_INFO_sCAL) != 0)
993 {
994 *unit = info_ptr->scal_unit;
995 *width = info_ptr->scal_s_width;
996 *height = info_ptr->scal_s_height;
997 return (PNG_INFO_sCAL);
998 }
999
1000 return(0);
1001}
1002#endif /* sCAL */
1003
1004#ifdef PNG_pHYs_SUPPORTED
1005png_uint_32 PNGAPI
1006png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
1007 png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
1008{
1009 png_uint_32 retval = 0;
1010
1011 png_debug1(1, "in %s retrieval function", "pHYs");
1012
1013 if (png_ptr != NULL && info_ptr != NULL &&
1014 (info_ptr->valid & PNG_INFO_pHYs) != 0)
1015 {
1016 if (res_x != NULL)
1017 {
1018 *res_x = info_ptr->x_pixels_per_unit;
1019 retval |= PNG_INFO_pHYs;
1020 }
1021
1022 if (res_y != NULL)
1023 {
1024 *res_y = info_ptr->y_pixels_per_unit;
1025 retval |= PNG_INFO_pHYs;
1026 }
1027
1028 if (unit_type != NULL)
1029 {
1030 *unit_type = (int)info_ptr->phys_unit_type;
1031 retval |= PNG_INFO_pHYs;
1032 }
1033 }
1034
1035 return (retval);
1036}
1037#endif /* pHYs */
1038
1039png_uint_32 PNGAPI
1040png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
1041 png_colorp *palette, int *num_palette)
1042{
1043 png_debug1(1, "in %s retrieval function", "PLTE");
1044
1045 if (png_ptr != NULL && info_ptr != NULL &&
1046 (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
1047 {
1048 *palette = info_ptr->palette;
1049 *num_palette = info_ptr->num_palette;
1050 png_debug1(3, "num_palette = %d", *num_palette);
1051 return (PNG_INFO_PLTE);
1052 }
1053
1054 return (0);
1055}
1056
1057#ifdef PNG_sBIT_SUPPORTED
1058png_uint_32 PNGAPI
1059png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
1060 png_color_8p *sig_bit)
1061{
1062 png_debug1(1, "in %s retrieval function", "sBIT");
1063
1064 if (png_ptr != NULL && info_ptr != NULL &&
1065 (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
1066 {
1067 *sig_bit = &(info_ptr->sig_bit);
1068 return (PNG_INFO_sBIT);
1069 }
1070
1071 return (0);
1072}
1073#endif
1074
1075#ifdef PNG_TEXT_SUPPORTED
1076int PNGAPI
1077png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
1078 png_textp *text_ptr, int *num_text)
1079{
1080 if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
1081 {
1082 png_debug1(1, "in 0x%lx retrieval function",
1083 (unsigned long)png_ptr->chunk_name);
1084
1085 if (text_ptr != NULL)
1086 *text_ptr = info_ptr->text;
1087
1088 if (num_text != NULL)
1089 *num_text = info_ptr->num_text;
1090
1091 return info_ptr->num_text;
1092 }
1093
1094 if (num_text != NULL)
1095 *num_text = 0;
1096
1097 return(0);
1098}
1099#endif
1100
1101#ifdef PNG_tIME_SUPPORTED
1102png_uint_32 PNGAPI
1103png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
1104 png_timep *mod_time)
1105{
1106 png_debug1(1, "in %s retrieval function", "tIME");
1107
1108 if (png_ptr != NULL && info_ptr != NULL &&
1109 (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
1110 {
1111 *mod_time = &(info_ptr->mod_time);
1112 return (PNG_INFO_tIME);
1113 }
1114
1115 return (0);
1116}
1117#endif
1118
1119#ifdef PNG_tRNS_SUPPORTED
1120png_uint_32 PNGAPI
1121png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
1122 png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
1123{
1124 png_uint_32 retval = 0;
1125 if (png_ptr != NULL && info_ptr != NULL &&
1126 (info_ptr->valid & PNG_INFO_tRNS) != 0)
1127 {
1128 png_debug1(1, "in %s retrieval function", "tRNS");
1129
1130 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1131 {
1132 if (trans_alpha != NULL)
1133 {
1134 *trans_alpha = info_ptr->trans_alpha;
1135 retval |= PNG_INFO_tRNS;
1136 }
1137
1138 if (trans_color != NULL)
1139 *trans_color = &(info_ptr->trans_color);
1140 }
1141
1142 else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
1143 {
1144 if (trans_color != NULL)
1145 {
1146 *trans_color = &(info_ptr->trans_color);
1147 retval |= PNG_INFO_tRNS;
1148 }
1149
1150 if (trans_alpha != NULL)
1151 *trans_alpha = NULL;
1152 }
1153
1154 if (num_trans != NULL)
1155 {
1156 *num_trans = info_ptr->num_trans;
1157 retval |= PNG_INFO_tRNS;
1158 }
1159 }
1160
1161 return (retval);
1162}
1163#endif
1164
1165#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1166int PNGAPI
1167png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
1168 png_unknown_chunkpp unknowns)
1169{
1170 if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
1171 {
1172 *unknowns = info_ptr->unknown_chunks;
1173 return info_ptr->unknown_chunks_num;
1174 }
1175
1176 return (0);
1177}
1178#endif
1179
1180#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1181png_byte PNGAPI
1182png_get_rgb_to_gray_status (png_const_structrp png_ptr)
1183{
1184 return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
1185}
1186#endif
1187
1188#ifdef PNG_USER_CHUNKS_SUPPORTED
1189png_voidp PNGAPI
1190png_get_user_chunk_ptr(png_const_structrp png_ptr)
1191{
1192 return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
1193}
1194#endif
1195
1196size_t PNGAPI
1197png_get_compression_buffer_size(png_const_structrp png_ptr)
1198{
1199 if (png_ptr == NULL)
1200 return 0;
1201
1202#ifdef PNG_WRITE_SUPPORTED
1203 if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1204#endif
1205 {
1206#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1207 return png_ptr->IDAT_read_size;
1208#else
1209 return PNG_IDAT_READ_SIZE;
1210#endif
1211 }
1212
1213#ifdef PNG_WRITE_SUPPORTED
1214 else
1215 return png_ptr->zbuffer_size;
1216#endif
1217}
1218
1219#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1220/* These functions were added to libpng 1.2.6 and were enabled
1221 * by default in libpng-1.4.0 */
1222png_uint_32 PNGAPI
1223png_get_user_width_max (png_const_structrp png_ptr)
1224{
1225 return (png_ptr ? png_ptr->user_width_max : 0);
1226}
1227
1228png_uint_32 PNGAPI
1229png_get_user_height_max (png_const_structrp png_ptr)
1230{
1231 return (png_ptr ? png_ptr->user_height_max : 0);
1232}
1233
1234/* This function was added to libpng 1.4.0 */
1235png_uint_32 PNGAPI
1236png_get_chunk_cache_max (png_const_structrp png_ptr)
1237{
1238 return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
1239}
1240
1241/* This function was added to libpng 1.4.1 */
1242png_alloc_size_t PNGAPI
1243png_get_chunk_malloc_max (png_const_structrp png_ptr)
1244{
1245 return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
1246}
1247#endif /* SET_USER_LIMITS */
1248
1249/* These functions were added to libpng 1.4.0 */
1250#ifdef PNG_IO_STATE_SUPPORTED
1251png_uint_32 PNGAPI
1252png_get_io_state (png_const_structrp png_ptr)
1253{
1254 return png_ptr->io_state;
1255}
1256
1257png_uint_32 PNGAPI
1258png_get_io_chunk_type (png_const_structrp png_ptr)
1259{
1260 return png_ptr->chunk_name;
1261}
1262#endif /* IO_STATE */
1263
1264#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1265# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
1266int PNGAPI
1267png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
1268{
1269 if (png_ptr != NULL && info_ptr != NULL)
1270 return png_ptr->num_palette_max;
1271
1272 return (-1);
1273}
1274# endif
1275#endif
1276
1277#endif /* READ || WRITE */
1278