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.32 [August 24, 2017]
  33  * Copyright (c) 1998-2002,2004,2006-2017 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 
  47 png_uint_32 PNGAPI
  48 png_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 
  57 png_size_t PNGAPI
  58 png_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
  67 png_bytepp PNGAPI
  68 png_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 */
  79 png_uint_32 PNGAPI
  80 png_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 
  88 png_uint_32 PNGAPI
  89 png_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 
  97 png_byte PNGAPI
  98 png_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 
 106 png_byte PNGAPI
 107 png_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 
 115 png_byte PNGAPI
 116 png_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 
 124 png_byte PNGAPI
 125 png_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 
 133 png_byte PNGAPI
 134 png_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 
 142 png_uint_32 PNGAPI
 143 png_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 
 164 png_uint_32 PNGAPI
 165 png_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 
 186 png_uint_32 PNGAPI
 187 png_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
 208 float PNGAPI
 209 png_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
 232 png_fixed_point PNGAPI
 233 png_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 
 263 png_int_32 PNGAPI
 264 png_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 
 283 png_int_32 PNGAPI
 284 png_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 
 303 png_int_32 PNGAPI
 304 png_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 
 323 png_int_32 PNGAPI
 324 png_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
 344 static png_uint_32
 345 ppi_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 
 376 png_uint_32 PNGAPI
 377 png_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 
 382 png_uint_32 PNGAPI
 383 png_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 
 388 png_uint_32 PNGAPI
 389 png_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
 395 static png_fixed_point
 396 png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
 397 {
 398    /* Convert from metres * 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 
 406 png_fixed_point PNGAPI
 407 png_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
 416 png_fixed_point PNGAPI
 417 png_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
 426 float PNGAPI
 427 png_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
 437 float PNGAPI
 438 png_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
 448 png_uint_32 PNGAPI
 449 png_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 
 494 png_byte PNGAPI
 495 png_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
 504 png_const_bytep PNGAPI
 505 png_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
 515 png_uint_32 PNGAPI
 516 png_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
 539 png_uint_32 PNGAPI
 540 png_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 
 585 png_uint_32 PNGAPI
 586 png_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
 631 png_uint_32 PNGAPI
 632 png_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 
 668 png_uint_32 PNGAPI
 669 png_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
 705 png_uint_32 PNGAPI
 706 png_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
 724 png_uint_32 PNGAPI
 725 png_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
 745 png_uint_32 PNGAPI
 746 png_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
 763 png_uint_32 PNGAPI
 764 png_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 && compression_type != NULL && profile != NULL &&
 773            proflen != NULL)
 774    {
 775       *name = info_ptr->iccp_name;
 776       *profile = info_ptr->iccp_profile;
 777       *proflen = png_get_uint_32(info_ptr->iccp_profile);
 778       /* This is somewhat irrelevant since the profile data returned has
 779        * actually been uncompressed.
 780        */
 781       *compression_type = PNG_COMPRESSION_TYPE_BASE;
 782       return (PNG_INFO_iCCP);
 783    }
 784 
 785    return (0);
 786 }
 787 #endif
 788 
 789 #ifdef PNG_sPLT_SUPPORTED
 790 int PNGAPI
 791 png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
 792     png_sPLT_tpp spalettes)
 793 {
 794    if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
 795    {
 796       *spalettes = info_ptr->splt_palettes;
 797       return info_ptr->splt_palettes_num;
 798    }
 799 
 800    return (0);
 801 }
 802 #endif
 803 
 804 #ifdef PNG_eXIf_SUPPORTED
 805 png_uint_32 PNGAPI
 806 png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
 807     png_bytep *exif)
 808 {
 809   png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
 810   PNG_UNUSED(info_ptr)
 811   PNG_UNUSED(exif)
 812   return 0;
 813 }
 814 
 815 png_uint_32 PNGAPI
 816 png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
 817     png_uint_32 *num_exif, png_bytep *exif)
 818 {
 819    png_debug1(1, "in %s retrieval function", "eXIf");
 820 
 821    if (png_ptr != NULL && info_ptr != NULL &&
 822        (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
 823    {
 824       *num_exif = info_ptr->num_exif;
 825       *exif = info_ptr->exif;
 826       return (PNG_INFO_eXIf);
 827    }
 828 
 829    return (0);
 830 }
 831 #endif
 832 
 833 #ifdef PNG_hIST_SUPPORTED
 834 png_uint_32 PNGAPI
 835 png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
 836     png_uint_16p *hist)
 837 {
 838    png_debug1(1, "in %s retrieval function", "hIST");
 839 
 840    if (png_ptr != NULL && info_ptr != NULL &&
 841        (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
 842    {
 843       *hist = info_ptr->hist;
 844       return (PNG_INFO_hIST);
 845    }
 846 
 847    return (0);
 848 }
 849 #endif
 850 
 851 png_uint_32 PNGAPI
 852 png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
 853     png_uint_32 *width, png_uint_32 *height, int *bit_depth,
 854     int *color_type, int *interlace_type, int *compression_type,
 855     int *filter_type)
 856 {
 857    png_debug1(1, "in %s retrieval function", "IHDR");
 858 
 859    if (png_ptr == NULL || info_ptr == NULL)
 860       return (0);
 861 
 862    if (width != NULL)
 863        *width = info_ptr->width;
 864 
 865    if (height != NULL)
 866        *height = info_ptr->height;
 867 
 868    if (bit_depth != NULL)
 869        *bit_depth = info_ptr->bit_depth;
 870 
 871    if (color_type != NULL)
 872        *color_type = info_ptr->color_type;
 873 
 874    if (compression_type != NULL)
 875       *compression_type = info_ptr->compression_type;
 876 
 877    if (filter_type != NULL)
 878       *filter_type = info_ptr->filter_type;
 879 
 880    if (interlace_type != NULL)
 881       *interlace_type = info_ptr->interlace_type;
 882 
 883    /* This is redundant if we can be sure that the info_ptr values were all
 884     * assigned in png_set_IHDR().  We do the check anyhow in case an
 885     * application has ignored our advice not to mess with the members
 886     * of info_ptr directly.
 887     */
 888    png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
 889        info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
 890        info_ptr->compression_type, info_ptr->filter_type);
 891 
 892    return (1);
 893 }
 894 
 895 #ifdef PNG_oFFs_SUPPORTED
 896 png_uint_32 PNGAPI
 897 png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
 898     png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
 899 {
 900    png_debug1(1, "in %s retrieval function", "oFFs");
 901 
 902    if (png_ptr != NULL && info_ptr != NULL &&
 903        (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
 904        offset_x != NULL && offset_y != NULL && unit_type != NULL)
 905    {
 906       *offset_x = info_ptr->x_offset;
 907       *offset_y = info_ptr->y_offset;
 908       *unit_type = (int)info_ptr->offset_unit_type;
 909       return (PNG_INFO_oFFs);
 910    }
 911 
 912    return (0);
 913 }
 914 #endif
 915 
 916 #ifdef PNG_pCAL_SUPPORTED
 917 png_uint_32 PNGAPI
 918 png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
 919     png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
 920     png_charp *units, png_charpp *params)
 921 {
 922    png_debug1(1, "in %s retrieval function", "pCAL");
 923 
 924    if (png_ptr != NULL && info_ptr != NULL &&
 925        (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
 926        purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
 927        nparams != NULL && units != NULL && params != NULL)
 928    {
 929       *purpose = info_ptr->pcal_purpose;
 930       *X0 = info_ptr->pcal_X0;
 931       *X1 = info_ptr->pcal_X1;
 932       *type = (int)info_ptr->pcal_type;
 933       *nparams = (int)info_ptr->pcal_nparams;
 934       *units = info_ptr->pcal_units;
 935       *params = info_ptr->pcal_params;
 936       return (PNG_INFO_pCAL);
 937    }
 938 
 939    return (0);
 940 }
 941 #endif
 942 
 943 #ifdef PNG_sCAL_SUPPORTED
 944 #  ifdef PNG_FIXED_POINT_SUPPORTED
 945 #    if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
 946          defined(PNG_FLOATING_POINT_SUPPORTED)
 947 png_uint_32 PNGAPI
 948 png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
 949     int *unit, png_fixed_point *width, png_fixed_point *height)
 950 {
 951    if (png_ptr != NULL && info_ptr != NULL &&
 952        (info_ptr->valid & PNG_INFO_sCAL) != 0)
 953    {
 954       *unit = info_ptr->scal_unit;
 955       /*TODO: make this work without FP support; the API is currently eliminated
 956        * if neither floating point APIs nor internal floating point arithmetic
 957        * are enabled.
 958        */
 959       *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
 960       *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
 961           "sCAL height");
 962       return (PNG_INFO_sCAL);
 963    }
 964 
 965    return(0);
 966 }
 967 #    endif /* FLOATING_ARITHMETIC */
 968 #  endif /* FIXED_POINT */
 969 #  ifdef PNG_FLOATING_POINT_SUPPORTED
 970 png_uint_32 PNGAPI
 971 png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
 972     int *unit, double *width, double *height)
 973 {
 974    if (png_ptr != NULL && info_ptr != NULL &&
 975        (info_ptr->valid & PNG_INFO_sCAL) != 0)
 976    {
 977       *unit = info_ptr->scal_unit;
 978       *width = atof(info_ptr->scal_s_width);
 979       *height = atof(info_ptr->scal_s_height);
 980       return (PNG_INFO_sCAL);
 981    }
 982 
 983    return(0);
 984 }
 985 #  endif /* FLOATING POINT */
 986 png_uint_32 PNGAPI
 987 png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
 988     int *unit, png_charpp width, png_charpp height)
 989 {
 990    if (png_ptr != NULL && info_ptr != NULL &&
 991        (info_ptr->valid & PNG_INFO_sCAL) != 0)
 992    {
 993       *unit = info_ptr->scal_unit;
 994       *width = info_ptr->scal_s_width;
 995       *height = info_ptr->scal_s_height;
 996       return (PNG_INFO_sCAL);
 997    }
 998 
 999    return(0);
1000 }
1001 #endif /* sCAL */
1002 
1003 #ifdef PNG_pHYs_SUPPORTED
1004 png_uint_32 PNGAPI
1005 png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
1006     png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
1007 {
1008    png_uint_32 retval = 0;
1009 
1010    png_debug1(1, "in %s retrieval function", "pHYs");
1011 
1012    if (png_ptr != NULL && info_ptr != NULL &&
1013        (info_ptr->valid & PNG_INFO_pHYs) != 0)
1014    {
1015       if (res_x != NULL)
1016       {
1017          *res_x = info_ptr->x_pixels_per_unit;
1018          retval |= PNG_INFO_pHYs;
1019       }
1020 
1021       if (res_y != NULL)
1022       {
1023          *res_y = info_ptr->y_pixels_per_unit;
1024          retval |= PNG_INFO_pHYs;
1025       }
1026 
1027       if (unit_type != NULL)
1028       {
1029          *unit_type = (int)info_ptr->phys_unit_type;
1030          retval |= PNG_INFO_pHYs;
1031       }
1032    }
1033 
1034    return (retval);
1035 }
1036 #endif /* pHYs */
1037 
1038 png_uint_32 PNGAPI
1039 png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
1040     png_colorp *palette, int *num_palette)
1041 {
1042    png_debug1(1, "in %s retrieval function", "PLTE");
1043 
1044    if (png_ptr != NULL && info_ptr != NULL &&
1045        (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
1046    {
1047       *palette = info_ptr->palette;
1048       *num_palette = info_ptr->num_palette;
1049       png_debug1(3, "num_palette = %d", *num_palette);
1050       return (PNG_INFO_PLTE);
1051    }
1052 
1053    return (0);
1054 }
1055 
1056 #ifdef PNG_sBIT_SUPPORTED
1057 png_uint_32 PNGAPI
1058 png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
1059     png_color_8p *sig_bit)
1060 {
1061    png_debug1(1, "in %s retrieval function", "sBIT");
1062 
1063    if (png_ptr != NULL && info_ptr != NULL &&
1064        (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
1065    {
1066       *sig_bit = &(info_ptr->sig_bit);
1067       return (PNG_INFO_sBIT);
1068    }
1069 
1070    return (0);
1071 }
1072 #endif
1073 
1074 #ifdef PNG_TEXT_SUPPORTED
1075 int PNGAPI
1076 png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
1077     png_textp *text_ptr, int *num_text)
1078 {
1079    if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
1080    {
1081       png_debug1(1, "in 0x%lx retrieval function",
1082          (unsigned long)png_ptr->chunk_name);
1083 
1084       if (text_ptr != NULL)
1085          *text_ptr = info_ptr->text;
1086 
1087       if (num_text != NULL)
1088          *num_text = info_ptr->num_text;
1089 
1090       return info_ptr->num_text;
1091    }
1092 
1093    if (num_text != NULL)
1094       *num_text = 0;
1095 
1096    return(0);
1097 }
1098 #endif
1099 
1100 #ifdef PNG_tIME_SUPPORTED
1101 png_uint_32 PNGAPI
1102 png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
1103     png_timep *mod_time)
1104 {
1105    png_debug1(1, "in %s retrieval function", "tIME");
1106 
1107    if (png_ptr != NULL && info_ptr != NULL &&
1108        (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
1109    {
1110       *mod_time = &(info_ptr->mod_time);
1111       return (PNG_INFO_tIME);
1112    }
1113 
1114    return (0);
1115 }
1116 #endif
1117 
1118 #ifdef PNG_tRNS_SUPPORTED
1119 png_uint_32 PNGAPI
1120 png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
1121     png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
1122 {
1123    png_uint_32 retval = 0;
1124    if (png_ptr != NULL && info_ptr != NULL &&
1125        (info_ptr->valid & PNG_INFO_tRNS) != 0)
1126    {
1127       png_debug1(1, "in %s retrieval function", "tRNS");
1128 
1129       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1130       {
1131          if (trans_alpha != NULL)
1132          {
1133             *trans_alpha = info_ptr->trans_alpha;
1134             retval |= PNG_INFO_tRNS;
1135          }
1136 
1137          if (trans_color != NULL)
1138             *trans_color = &(info_ptr->trans_color);
1139       }
1140 
1141       else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
1142       {
1143          if (trans_color != NULL)
1144          {
1145             *trans_color = &(info_ptr->trans_color);
1146             retval |= PNG_INFO_tRNS;
1147          }
1148 
1149          if (trans_alpha != NULL)
1150             *trans_alpha = NULL;
1151       }
1152 
1153       if (num_trans != NULL)
1154       {
1155          *num_trans = info_ptr->num_trans;
1156          retval |= PNG_INFO_tRNS;
1157       }
1158    }
1159 
1160    return (retval);
1161 }
1162 #endif
1163 
1164 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1165 int PNGAPI
1166 png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
1167     png_unknown_chunkpp unknowns)
1168 {
1169    if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
1170    {
1171       *unknowns = info_ptr->unknown_chunks;
1172       return info_ptr->unknown_chunks_num;
1173    }
1174 
1175    return (0);
1176 }
1177 #endif
1178 
1179 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1180 png_byte PNGAPI
1181 png_get_rgb_to_gray_status (png_const_structrp png_ptr)
1182 {
1183    return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
1184 }
1185 #endif
1186 
1187 #ifdef PNG_USER_CHUNKS_SUPPORTED
1188 png_voidp PNGAPI
1189 png_get_user_chunk_ptr(png_const_structrp png_ptr)
1190 {
1191    return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
1192 }
1193 #endif
1194 
1195 png_size_t PNGAPI
1196 png_get_compression_buffer_size(png_const_structrp png_ptr)
1197 {
1198    if (png_ptr == NULL)
1199       return 0;
1200 
1201 #ifdef PNG_WRITE_SUPPORTED
1202    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1203 #endif
1204    {
1205 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1206       return png_ptr->IDAT_read_size;
1207 #else
1208       return PNG_IDAT_READ_SIZE;
1209 #endif
1210    }
1211 
1212 #ifdef PNG_WRITE_SUPPORTED
1213    else
1214       return png_ptr->zbuffer_size;
1215 #endif
1216 }
1217 
1218 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
1219 /* These functions were added to libpng 1.2.6 and were enabled
1220  * by default in libpng-1.4.0 */
1221 png_uint_32 PNGAPI
1222 png_get_user_width_max (png_const_structrp png_ptr)
1223 {
1224    return (png_ptr ? png_ptr->user_width_max : 0);
1225 }
1226 
1227 png_uint_32 PNGAPI
1228 png_get_user_height_max (png_const_structrp png_ptr)
1229 {
1230    return (png_ptr ? png_ptr->user_height_max : 0);
1231 }
1232 
1233 /* This function was added to libpng 1.4.0 */
1234 png_uint_32 PNGAPI
1235 png_get_chunk_cache_max (png_const_structrp png_ptr)
1236 {
1237    return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
1238 }
1239 
1240 /* This function was added to libpng 1.4.1 */
1241 png_alloc_size_t PNGAPI
1242 png_get_chunk_malloc_max (png_const_structrp png_ptr)
1243 {
1244    return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
1245 }
1246 #endif /* SET_USER_LIMITS */
1247 
1248 /* These functions were added to libpng 1.4.0 */
1249 #ifdef PNG_IO_STATE_SUPPORTED
1250 png_uint_32 PNGAPI
1251 png_get_io_state (png_const_structrp png_ptr)
1252 {
1253    return png_ptr->io_state;
1254 }
1255 
1256 png_uint_32 PNGAPI
1257 png_get_io_chunk_type (png_const_structrp png_ptr)
1258 {
1259    return png_ptr->chunk_name;
1260 }
1261 #endif /* IO_STATE */
1262 
1263 #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1264 #  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
1265 int PNGAPI
1266 png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
1267 {
1268    if (png_ptr != NULL && info_ptr != NULL)
1269       return png_ptr->num_palette_max;
1270 
1271    return (-1);
1272 }
1273 #  endif
1274 #endif
1275 
1276 #endif /* READ || WRITE */