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.26 [October 20, 2016]
  33  * Copyright (c) 1998-2002,2004,2006-2016 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_hIST_SUPPORTED
 805 png_uint_32 PNGAPI
 806 png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
 807     png_uint_16p *hist)
 808 {
 809    png_debug1(1, "in %s retrieval function", "hIST");
 810 
 811    if (png_ptr != NULL && info_ptr != NULL &&
 812        (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
 813    {
 814       *hist = info_ptr->hist;
 815       return (PNG_INFO_hIST);
 816    }
 817 
 818    return (0);
 819 }
 820 #endif
 821 
 822 png_uint_32 PNGAPI
 823 png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
 824     png_uint_32 *width, png_uint_32 *height, int *bit_depth,
 825     int *color_type, int *interlace_type, int *compression_type,
 826     int *filter_type)
 827 {
 828    png_debug1(1, "in %s retrieval function", "IHDR");
 829 
 830    if (png_ptr == NULL || info_ptr == NULL)
 831       return (0);
 832 
 833    if (width != NULL)
 834        *width = info_ptr->width;
 835 
 836    if (height != NULL)
 837        *height = info_ptr->height;
 838 
 839    if (bit_depth != NULL)
 840        *bit_depth = info_ptr->bit_depth;
 841 
 842    if (color_type != NULL)
 843        *color_type = info_ptr->color_type;
 844 
 845    if (compression_type != NULL)
 846       *compression_type = info_ptr->compression_type;
 847 
 848    if (filter_type != NULL)
 849       *filter_type = info_ptr->filter_type;
 850 
 851    if (interlace_type != NULL)
 852       *interlace_type = info_ptr->interlace_type;
 853 
 854    /* This is redundant if we can be sure that the info_ptr values were all
 855     * assigned in png_set_IHDR().  We do the check anyhow in case an
 856     * application has ignored our advice not to mess with the members
 857     * of info_ptr directly.
 858     */
 859    png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
 860        info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
 861        info_ptr->compression_type, info_ptr->filter_type);
 862 
 863    return (1);
 864 }
 865 
 866 #ifdef PNG_oFFs_SUPPORTED
 867 png_uint_32 PNGAPI
 868 png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
 869     png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
 870 {
 871    png_debug1(1, "in %s retrieval function", "oFFs");
 872 
 873    if (png_ptr != NULL && info_ptr != NULL &&
 874        (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
 875        offset_x != NULL && offset_y != NULL && unit_type != NULL)
 876    {
 877       *offset_x = info_ptr->x_offset;
 878       *offset_y = info_ptr->y_offset;
 879       *unit_type = (int)info_ptr->offset_unit_type;
 880       return (PNG_INFO_oFFs);
 881    }
 882 
 883    return (0);
 884 }
 885 #endif
 886 
 887 #ifdef PNG_pCAL_SUPPORTED
 888 png_uint_32 PNGAPI
 889 png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
 890     png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
 891     png_charp *units, png_charpp *params)
 892 {
 893    png_debug1(1, "in %s retrieval function", "pCAL");
 894 
 895    if (png_ptr != NULL && info_ptr != NULL &&
 896        (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
 897        purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
 898        nparams != NULL && units != NULL && params != NULL)
 899    {
 900       *purpose = info_ptr->pcal_purpose;
 901       *X0 = info_ptr->pcal_X0;
 902       *X1 = info_ptr->pcal_X1;
 903       *type = (int)info_ptr->pcal_type;
 904       *nparams = (int)info_ptr->pcal_nparams;
 905       *units = info_ptr->pcal_units;
 906       *params = info_ptr->pcal_params;
 907       return (PNG_INFO_pCAL);
 908    }
 909 
 910    return (0);
 911 }
 912 #endif
 913 
 914 #ifdef PNG_sCAL_SUPPORTED
 915 #  ifdef PNG_FIXED_POINT_SUPPORTED
 916 #    if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
 917          defined(PNG_FLOATING_POINT_SUPPORTED)
 918 png_uint_32 PNGAPI
 919 png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
 920     int *unit, png_fixed_point *width, png_fixed_point *height)
 921 {
 922    if (png_ptr != NULL && info_ptr != NULL &&
 923        (info_ptr->valid & PNG_INFO_sCAL) != 0)
 924    {
 925       *unit = info_ptr->scal_unit;
 926       /*TODO: make this work without FP support; the API is currently eliminated
 927        * if neither floating point APIs nor internal floating point arithmetic
 928        * are enabled.
 929        */
 930       *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
 931       *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
 932           "sCAL height");
 933       return (PNG_INFO_sCAL);
 934    }
 935 
 936    return(0);
 937 }
 938 #    endif /* FLOATING_ARITHMETIC */
 939 #  endif /* FIXED_POINT */
 940 #  ifdef PNG_FLOATING_POINT_SUPPORTED
 941 png_uint_32 PNGAPI
 942 png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
 943     int *unit, double *width, double *height)
 944 {
 945    if (png_ptr != NULL && info_ptr != NULL &&
 946        (info_ptr->valid & PNG_INFO_sCAL) != 0)
 947    {
 948       *unit = info_ptr->scal_unit;
 949       *width = atof(info_ptr->scal_s_width);
 950       *height = atof(info_ptr->scal_s_height);
 951       return (PNG_INFO_sCAL);
 952    }
 953 
 954    return(0);
 955 }
 956 #  endif /* FLOATING POINT */
 957 png_uint_32 PNGAPI
 958 png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
 959     int *unit, png_charpp width, png_charpp height)
 960 {
 961    if (png_ptr != NULL && info_ptr != NULL &&
 962        (info_ptr->valid & PNG_INFO_sCAL) != 0)
 963    {
 964       *unit = info_ptr->scal_unit;
 965       *width = info_ptr->scal_s_width;
 966       *height = info_ptr->scal_s_height;
 967       return (PNG_INFO_sCAL);
 968    }
 969 
 970    return(0);
 971 }
 972 #endif /* sCAL */
 973 
 974 #ifdef PNG_pHYs_SUPPORTED
 975 png_uint_32 PNGAPI
 976 png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
 977     png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
 978 {
 979    png_uint_32 retval = 0;
 980 
 981    png_debug1(1, "in %s retrieval function", "pHYs");
 982 
 983    if (png_ptr != NULL && info_ptr != NULL &&
 984        (info_ptr->valid & PNG_INFO_pHYs) != 0)
 985    {
 986       if (res_x != NULL)
 987       {
 988          *res_x = info_ptr->x_pixels_per_unit;
 989          retval |= PNG_INFO_pHYs;
 990       }
 991 
 992       if (res_y != NULL)
 993       {
 994          *res_y = info_ptr->y_pixels_per_unit;
 995          retval |= PNG_INFO_pHYs;
 996       }
 997 
 998       if (unit_type != NULL)
 999       {
1000          *unit_type = (int)info_ptr->phys_unit_type;
1001          retval |= PNG_INFO_pHYs;
1002       }
1003    }
1004 
1005    return (retval);
1006 }
1007 #endif /* pHYs */
1008 
1009 png_uint_32 PNGAPI
1010 png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
1011     png_colorp *palette, int *num_palette)
1012 {
1013    png_debug1(1, "in %s retrieval function", "PLTE");
1014 
1015    if (png_ptr != NULL && info_ptr != NULL &&
1016        (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
1017    {
1018       *palette = info_ptr->palette;
1019       *num_palette = info_ptr->num_palette;
1020       png_debug1(3, "num_palette = %d", *num_palette);
1021       return (PNG_INFO_PLTE);
1022    }
1023 
1024    return (0);
1025 }
1026 
1027 #ifdef PNG_sBIT_SUPPORTED
1028 png_uint_32 PNGAPI
1029 png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
1030     png_color_8p *sig_bit)
1031 {
1032    png_debug1(1, "in %s retrieval function", "sBIT");
1033 
1034    if (png_ptr != NULL && info_ptr != NULL &&
1035        (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
1036    {
1037       *sig_bit = &(info_ptr->sig_bit);
1038       return (PNG_INFO_sBIT);
1039    }
1040 
1041    return (0);
1042 }
1043 #endif
1044 
1045 #ifdef PNG_TEXT_SUPPORTED
1046 int PNGAPI
1047 png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
1048     png_textp *text_ptr, int *num_text)
1049 {
1050    if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
1051    {
1052       png_debug1(1, "in 0x%lx retrieval function",
1053          (unsigned long)png_ptr->chunk_name);
1054 
1055       if (text_ptr != NULL)
1056          *text_ptr = info_ptr->text;
1057 
1058       if (num_text != NULL)
1059          *num_text = info_ptr->num_text;
1060 
1061       return info_ptr->num_text;
1062    }
1063 
1064    if (num_text != NULL)
1065       *num_text = 0;
1066 
1067    return(0);
1068 }
1069 #endif
1070 
1071 #ifdef PNG_tIME_SUPPORTED
1072 png_uint_32 PNGAPI
1073 png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
1074     png_timep *mod_time)
1075 {
1076    png_debug1(1, "in %s retrieval function", "tIME");
1077 
1078    if (png_ptr != NULL && info_ptr != NULL &&
1079        (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
1080    {
1081       *mod_time = &(info_ptr->mod_time);
1082       return (PNG_INFO_tIME);
1083    }
1084 
1085    return (0);
1086 }
1087 #endif
1088 
1089 #ifdef PNG_tRNS_SUPPORTED
1090 png_uint_32 PNGAPI
1091 png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
1092     png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
1093 {
1094    png_uint_32 retval = 0;
1095    if (png_ptr != NULL && info_ptr != NULL &&
1096        (info_ptr->valid & PNG_INFO_tRNS) != 0)
1097    {
1098       png_debug1(1, "in %s retrieval function", "tRNS");
1099 
1100       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1101       {
1102          if (trans_alpha != NULL)
1103          {
1104             *trans_alpha = info_ptr->trans_alpha;
1105             retval |= PNG_INFO_tRNS;
1106          }
1107 
1108          if (trans_color != NULL)
1109             *trans_color = &(info_ptr->trans_color);
1110       }
1111 
1112       else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
1113       {
1114          if (trans_color != NULL)
1115          {
1116             *trans_color = &(info_ptr->trans_color);
1117             retval |= PNG_INFO_tRNS;
1118          }
1119 
1120          if (trans_alpha != NULL)
1121             *trans_alpha = NULL;
1122       }
1123 
1124       if (num_trans != NULL)
1125       {
1126          *num_trans = info_ptr->num_trans;
1127          retval |= PNG_INFO_tRNS;
1128       }
1129    }
1130 
1131    return (retval);
1132 }
1133 #endif
1134 
1135 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1136 int PNGAPI
1137 png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
1138     png_unknown_chunkpp unknowns)
1139 {
1140    if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
1141    {
1142       *unknowns = info_ptr->unknown_chunks;
1143       return info_ptr->unknown_chunks_num;
1144    }
1145 
1146    return (0);
1147 }
1148 #endif
1149 
1150 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1151 png_byte PNGAPI
1152 png_get_rgb_to_gray_status (png_const_structrp png_ptr)
1153 {
1154    return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
1155 }
1156 #endif
1157 
1158 #ifdef PNG_USER_CHUNKS_SUPPORTED
1159 png_voidp PNGAPI
1160 png_get_user_chunk_ptr(png_const_structrp png_ptr)
1161 {
1162    return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
1163 }
1164 #endif
1165 
1166 png_size_t PNGAPI
1167 png_get_compression_buffer_size(png_const_structrp png_ptr)
1168 {
1169    if (png_ptr == NULL)
1170       return 0;
1171 
1172 #ifdef PNG_WRITE_SUPPORTED
1173    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1174 #endif
1175    {
1176 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1177       return png_ptr->IDAT_read_size;
1178 #else
1179       return PNG_IDAT_READ_SIZE;
1180 #endif
1181    }
1182 
1183 #ifdef PNG_WRITE_SUPPORTED
1184    else
1185       return png_ptr->zbuffer_size;
1186 #endif
1187 }
1188 
1189 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
1190 /* These functions were added to libpng 1.2.6 and were enabled
1191  * by default in libpng-1.4.0 */
1192 png_uint_32 PNGAPI
1193 png_get_user_width_max (png_const_structrp png_ptr)
1194 {
1195    return (png_ptr ? png_ptr->user_width_max : 0);
1196 }
1197 
1198 png_uint_32 PNGAPI
1199 png_get_user_height_max (png_const_structrp png_ptr)
1200 {
1201    return (png_ptr ? png_ptr->user_height_max : 0);
1202 }
1203 
1204 /* This function was added to libpng 1.4.0 */
1205 png_uint_32 PNGAPI
1206 png_get_chunk_cache_max (png_const_structrp png_ptr)
1207 {
1208    return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
1209 }
1210 
1211 /* This function was added to libpng 1.4.1 */
1212 png_alloc_size_t PNGAPI
1213 png_get_chunk_malloc_max (png_const_structrp png_ptr)
1214 {
1215    return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
1216 }
1217 #endif /* SET_USER_LIMITS */
1218 
1219 /* These functions were added to libpng 1.4.0 */
1220 #ifdef PNG_IO_STATE_SUPPORTED
1221 png_uint_32 PNGAPI
1222 png_get_io_state (png_const_structrp png_ptr)
1223 {
1224    return png_ptr->io_state;
1225 }
1226 
1227 png_uint_32 PNGAPI
1228 png_get_io_chunk_type (png_const_structrp png_ptr)
1229 {
1230    return png_ptr->chunk_name;
1231 }
1232 #endif /* IO_STATE */
1233 
1234 #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1235 #  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
1236 int PNGAPI
1237 png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
1238 {
1239    if (png_ptr != NULL && info_ptr != NULL)
1240       return png_ptr->num_palette_max;
1241 
1242    return (-1);
1243 }
1244 #  endif
1245 #endif
1246 
1247 #endif /* READ || WRITE */