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