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