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 47png_uint_32 PNGAPI 48png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, 49 png_uint_32 flag) 50{ 51 if (png_ptr != NULL && info_ptr != NULL) 52 return(info_ptr->valid & flag); 53 54 return(0); 55} 56 57png_size_t PNGAPI 58png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) 59{ 60 if (png_ptr != NULL && info_ptr != NULL) 61 return(info_ptr->rowbytes); 62 63 return(0); 64} 65 66#ifdef PNG_INFO_IMAGE_SUPPORTED 67png_bytepp PNGAPI 68png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) 69{ 70 if (png_ptr != NULL && info_ptr != NULL) 71 return(info_ptr->row_pointers); 72 73 return(0); 74} 75#endif 76 77#ifdef PNG_EASY_ACCESS_SUPPORTED 78/* Easy access to info, added in libpng-0.99 */ 79png_uint_32 PNGAPI 80png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) 81{ 82 if (png_ptr != NULL && info_ptr != NULL) 83 return info_ptr->width; 84 85 return (0); 86} 87 88png_uint_32 PNGAPI 89png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) 90{ 91 if (png_ptr != NULL && info_ptr != NULL) 92 return info_ptr->height; 93 94 return (0); 95} 96 97png_byte PNGAPI 98png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) 99{ 100 if (png_ptr != NULL && info_ptr != NULL) 101 return info_ptr->bit_depth; 102 103 return (0); 104} 105 106png_byte PNGAPI 107png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) 108{ 109 if (png_ptr != NULL && info_ptr != NULL) 110 return info_ptr->color_type; 111 112 return (0); 113} 114 115png_byte PNGAPI 116png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) 117{ 118 if (png_ptr != NULL && info_ptr != NULL) 119 return info_ptr->filter_type; 120 121 return (0); 122} 123 124png_byte PNGAPI 125png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) 126{ 127 if (png_ptr != NULL && info_ptr != NULL) 128 return info_ptr->interlace_type; 129 130 return (0); 131} 132 133png_byte PNGAPI 134png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) 135{ 136 if (png_ptr != NULL && info_ptr != NULL) 137 return info_ptr->compression_type; 138 139 return (0); 140} 141 142png_uint_32 PNGAPI 143png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp 144 info_ptr) 145{ 146#ifdef PNG_pHYs_SUPPORTED 147 if (png_ptr != NULL && info_ptr != NULL && 148 (info_ptr->valid & PNG_INFO_pHYs) != 0) 149 { 150 png_debug1(1, "in %s retrieval function", 151 "png_get_x_pixels_per_meter"); 152 153 if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) 154 return (info_ptr->x_pixels_per_unit); 155 } 156#else 157 PNG_UNUSED(png_ptr) 158 PNG_UNUSED(info_ptr) 159#endif 160 161 return (0); 162} 163 164png_uint_32 PNGAPI 165png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp 166 info_ptr) 167{ 168#ifdef PNG_pHYs_SUPPORTED 169 if (png_ptr != NULL && info_ptr != NULL && 170 (info_ptr->valid & PNG_INFO_pHYs) != 0) 171 { 172 png_debug1(1, "in %s retrieval function", 173 "png_get_y_pixels_per_meter"); 174 175 if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) 176 return (info_ptr->y_pixels_per_unit); 177 } 178#else 179 PNG_UNUSED(png_ptr) 180 PNG_UNUSED(info_ptr) 181#endif 182 183 return (0); 184} 185 186png_uint_32 PNGAPI 187png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) 188{ 189#ifdef PNG_pHYs_SUPPORTED 190 if (png_ptr != NULL && info_ptr != NULL && 191 (info_ptr->valid & PNG_INFO_pHYs) != 0) 192 { 193 png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); 194 195 if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && 196 info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) 197 return (info_ptr->x_pixels_per_unit); 198 } 199#else 200 PNG_UNUSED(png_ptr) 201 PNG_UNUSED(info_ptr) 202#endif 203 204 return (0); 205} 206 207#ifdef PNG_FLOATING_POINT_SUPPORTED 208float PNGAPI 209png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp 210 info_ptr) 211{ 212#ifdef PNG_READ_pHYs_SUPPORTED 213 if (png_ptr != NULL && info_ptr != NULL && 214 (info_ptr->valid & PNG_INFO_pHYs) != 0) 215 { 216 png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); 217 218 if (info_ptr->x_pixels_per_unit != 0) 219 return ((float)((float)info_ptr->y_pixels_per_unit 220 /(float)info_ptr->x_pixels_per_unit)); 221 } 222#else 223 PNG_UNUSED(png_ptr) 224 PNG_UNUSED(info_ptr) 225#endif 226 227 return ((float)0.0); 228} 229#endif 230 231#ifdef PNG_FIXED_POINT_SUPPORTED 232png_fixed_point PNGAPI 233png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, 234 png_const_inforp info_ptr) 235{ 236#ifdef PNG_READ_pHYs_SUPPORTED 237 if (png_ptr != NULL && info_ptr != NULL && 238 (info_ptr->valid & PNG_INFO_pHYs) != 0 && 239 info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && 240 info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && 241 info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) 242 { 243 png_fixed_point res; 244 245 png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); 246 247 /* The following casts work because a PNG 4 byte integer only has a valid 248 * range of 0..2^31-1; otherwise the cast might overflow. 249 */ 250 if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, 251 (png_int_32)info_ptr->x_pixels_per_unit) != 0) 252 return res; 253 } 254#else 255 PNG_UNUSED(png_ptr) 256 PNG_UNUSED(info_ptr) 257#endif 258 259 return 0; 260} 261#endif 262 263png_int_32 PNGAPI 264png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) 265{ 266#ifdef PNG_oFFs_SUPPORTED 267 if (png_ptr != NULL && info_ptr != NULL && 268 (info_ptr->valid & PNG_INFO_oFFs) != 0) 269 { 270 png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); 271 272 if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) 273 return (info_ptr->x_offset); 274 } 275#else 276 PNG_UNUSED(png_ptr) 277 PNG_UNUSED(info_ptr) 278#endif 279 280 return (0); 281} 282 283png_int_32 PNGAPI 284png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) 285{ 286#ifdef PNG_oFFs_SUPPORTED 287 if (png_ptr != NULL && info_ptr != NULL && 288 (info_ptr->valid & PNG_INFO_oFFs) != 0) 289 { 290 png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); 291 292 if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) 293 return (info_ptr->y_offset); 294 } 295#else 296 PNG_UNUSED(png_ptr) 297 PNG_UNUSED(info_ptr) 298#endif 299 300 return (0); 301} 302 303png_int_32 PNGAPI 304png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) 305{ 306#ifdef PNG_oFFs_SUPPORTED 307 if (png_ptr != NULL && info_ptr != NULL && 308 (info_ptr->valid & PNG_INFO_oFFs) != 0) 309 { 310 png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); 311 312 if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) 313 return (info_ptr->x_offset); 314 } 315#else 316 PNG_UNUSED(png_ptr) 317 PNG_UNUSED(info_ptr) 318#endif 319 320 return (0); 321} 322 323png_int_32 PNGAPI 324png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) 325{ 326#ifdef PNG_oFFs_SUPPORTED 327 if (png_ptr != NULL && info_ptr != NULL && 328 (info_ptr->valid & PNG_INFO_oFFs) != 0) 329 { 330 png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); 331 332 if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) 333 return (info_ptr->y_offset); 334 } 335#else 336 PNG_UNUSED(png_ptr) 337 PNG_UNUSED(info_ptr) 338#endif 339 340 return (0); 341} 342 343#ifdef PNG_INCH_CONVERSIONS_SUPPORTED 344static png_uint_32 345ppi_from_ppm(png_uint_32 ppm) 346{ 347#if 0 348 /* The conversion is *(2.54/100), in binary (32 digits): 349 * .00000110100000001001110101001001 350 */ 351 png_uint_32 t1001, t1101; 352 ppm >>= 1; /* .1 */ 353 t1001 = ppm + (ppm >> 3); /* .1001 */ 354 t1101 = t1001 + (ppm >> 1); /* .1101 */ 355 ppm >>= 20; /* .000000000000000000001 */ 356 t1101 += t1101 >> 15; /* .1101000000000001101 */ 357 t1001 >>= 11; /* .000000000001001 */ 358 t1001 += t1001 >> 12; /* .000000000001001000000001001 */ 359 ppm += t1001; /* .000000000001001000001001001 */ 360 ppm += t1101; /* .110100000001001110101001001 */ 361 return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ 362#else 363 /* The argument is a PNG unsigned integer, so it is not permitted 364 * to be bigger than 2^31. 365 */ 366 png_fixed_point result; 367 if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, 368 5000) != 0) 369 return (png_uint_32)result; 370 371 /* Overflow. */ 372 return 0; 373#endif 374} 375 376png_uint_32 PNGAPI 377png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) 378{ 379 return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); 380} 381 382png_uint_32 PNGAPI 383png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) 384{ 385 return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); 386} 387 388png_uint_32 PNGAPI 389png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) 390{ 391 return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); 392} 393 394#ifdef PNG_FIXED_POINT_SUPPORTED 395static png_fixed_point 396png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) 397{ 398 /* Convert from 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 406png_fixed_point PNGAPI 407png_get_x_offset_inches_fixed(png_const_structrp png_ptr, 408 png_const_inforp info_ptr) 409{ 410 return png_fixed_inches_from_microns(png_ptr, 411 png_get_x_offset_microns(png_ptr, info_ptr)); 412} 413#endif 414 415#ifdef PNG_FIXED_POINT_SUPPORTED 416png_fixed_point PNGAPI 417png_get_y_offset_inches_fixed(png_const_structrp png_ptr, 418 png_const_inforp info_ptr) 419{ 420 return png_fixed_inches_from_microns(png_ptr, 421 png_get_y_offset_microns(png_ptr, info_ptr)); 422} 423#endif 424 425#ifdef PNG_FLOATING_POINT_SUPPORTED 426float PNGAPI 427png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) 428{ 429 /* To avoid the overflow do the conversion directly in floating 430 * point. 431 */ 432 return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); 433} 434#endif 435 436#ifdef PNG_FLOATING_POINT_SUPPORTED 437float PNGAPI 438png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) 439{ 440 /* To avoid the overflow do the conversion directly in floating 441 * point. 442 */ 443 return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); 444} 445#endif 446 447#ifdef PNG_pHYs_SUPPORTED 448png_uint_32 PNGAPI 449png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, 450 png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) 451{ 452 png_uint_32 retval = 0; 453 454 if (png_ptr != NULL && info_ptr != NULL && 455 (info_ptr->valid & PNG_INFO_pHYs) != 0) 456 { 457 png_debug1(1, "in %s retrieval function", "pHYs"); 458 459 if (res_x != NULL) 460 { 461 *res_x = info_ptr->x_pixels_per_unit; 462 retval |= PNG_INFO_pHYs; 463 } 464 465 if (res_y != NULL) 466 { 467 *res_y = info_ptr->y_pixels_per_unit; 468 retval |= PNG_INFO_pHYs; 469 } 470 471 if (unit_type != NULL) 472 { 473 *unit_type = (int)info_ptr->phys_unit_type; 474 retval |= PNG_INFO_pHYs; 475 476 if (*unit_type == 1) 477 { 478 if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); 479 if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); 480 } 481 } 482 } 483 484 return (retval); 485} 486#endif /* pHYs */ 487#endif /* INCH_CONVERSIONS */ 488 489/* png_get_channels really belongs in here, too, but it's been around longer */ 490 491#endif /* EASY_ACCESS */ 492 493 494png_byte PNGAPI 495png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) 496{ 497 if (png_ptr != NULL && info_ptr != NULL) 498 return(info_ptr->channels); 499 500 return (0); 501} 502 503#ifdef PNG_READ_SUPPORTED 504png_const_bytep PNGAPI 505png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) 506{ 507 if (png_ptr != NULL && info_ptr != NULL) 508 return(info_ptr->signature); 509 510 return (NULL); 511} 512#endif 513 514#ifdef PNG_bKGD_SUPPORTED 515png_uint_32 PNGAPI 516png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, 517 png_color_16p *background) 518{ 519 if (png_ptr != NULL && info_ptr != NULL && 520 (info_ptr->valid & PNG_INFO_bKGD) != 0 && 521 background != NULL) 522 { 523 png_debug1(1, "in %s retrieval function", "bKGD"); 524 525 *background = &(info_ptr->background); 526 return (PNG_INFO_bKGD); 527 } 528 529 return (0); 530} 531#endif 532 533#ifdef PNG_cHRM_SUPPORTED 534/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the 535 * same time to correct the rgb grayscale coefficient defaults obtained from the 536 * cHRM chunk in 1.5.4 537 */ 538# ifdef PNG_FLOATING_POINT_SUPPORTED 539png_uint_32 PNGAPI 540png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, 541 double *white_x, double *white_y, double *red_x, double *red_y, 542 double *green_x, double *green_y, double *blue_x, double *blue_y) 543{ 544 /* Quiet API change: this code used to only return the end points if a cHRM 545 * chunk was present, but the end points can also come from iCCP or sRGB 546 * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and 547 * the png_set_ APIs merely check that set end points are mutually 548 * consistent. 549 */ 550 if (png_ptr != NULL && info_ptr != NULL && 551 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 552 { 553 png_debug1(1, "in %s retrieval function", "cHRM"); 554 555 if (white_x != NULL) 556 *white_x = png_float(png_ptr, 557 info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); 558 if (white_y != NULL) 559 *white_y = png_float(png_ptr, 560 info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); 561 if (red_x != NULL) 562 *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, 563 "cHRM red X"); 564 if (red_y != NULL) 565 *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, 566 "cHRM red Y"); 567 if (green_x != NULL) 568 *green_x = png_float(png_ptr, 569 info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); 570 if (green_y != NULL) 571 *green_y = png_float(png_ptr, 572 info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); 573 if (blue_x != NULL) 574 *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, 575 "cHRM blue X"); 576 if (blue_y != NULL) 577 *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, 578 "cHRM blue Y"); 579 return (PNG_INFO_cHRM); 580 } 581 582 return (0); 583} 584 585png_uint_32 PNGAPI 586png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, 587 double *red_X, double *red_Y, double *red_Z, double *green_X, 588 double *green_Y, double *green_Z, double *blue_X, double *blue_Y, 589 double *blue_Z) 590{ 591 if (png_ptr != NULL && info_ptr != NULL && 592 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 593 { 594 png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); 595 596 if (red_X != NULL) 597 *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, 598 "cHRM red X"); 599 if (red_Y != NULL) 600 *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, 601 "cHRM red Y"); 602 if (red_Z != NULL) 603 *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, 604 "cHRM red Z"); 605 if (green_X != NULL) 606 *green_X = png_float(png_ptr, 607 info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); 608 if (green_Y != NULL) 609 *green_Y = png_float(png_ptr, 610 info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); 611 if (green_Z != NULL) 612 *green_Z = png_float(png_ptr, 613 info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); 614 if (blue_X != NULL) 615 *blue_X = png_float(png_ptr, 616 info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); 617 if (blue_Y != NULL) 618 *blue_Y = png_float(png_ptr, 619 info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); 620 if (blue_Z != NULL) 621 *blue_Z = png_float(png_ptr, 622 info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); 623 return (PNG_INFO_cHRM); 624 } 625 626 return (0); 627} 628# endif 629 630# ifdef PNG_FIXED_POINT_SUPPORTED 631png_uint_32 PNGAPI 632png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, 633 png_fixed_point *int_red_X, png_fixed_point *int_red_Y, 634 png_fixed_point *int_red_Z, png_fixed_point *int_green_X, 635 png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, 636 png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, 637 png_fixed_point *int_blue_Z) 638{ 639 if (png_ptr != NULL && info_ptr != NULL && 640 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 641 { 642 png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); 643 644 if (int_red_X != NULL) 645 *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; 646 if (int_red_Y != NULL) 647 *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; 648 if (int_red_Z != NULL) 649 *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; 650 if (int_green_X != NULL) 651 *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; 652 if (int_green_Y != NULL) 653 *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; 654 if (int_green_Z != NULL) 655 *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; 656 if (int_blue_X != NULL) 657 *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; 658 if (int_blue_Y != NULL) 659 *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; 660 if (int_blue_Z != NULL) 661 *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; 662 return (PNG_INFO_cHRM); 663 } 664 665 return (0); 666} 667 668png_uint_32 PNGAPI 669png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, 670 png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, 671 png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, 672 png_fixed_point *blue_x, png_fixed_point *blue_y) 673{ 674 png_debug1(1, "in %s retrieval function", "cHRM"); 675 676 if (png_ptr != NULL && info_ptr != NULL && 677 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 678 { 679 if (white_x != NULL) 680 *white_x = info_ptr->colorspace.end_points_xy.whitex; 681 if (white_y != NULL) 682 *white_y = info_ptr->colorspace.end_points_xy.whitey; 683 if (red_x != NULL) 684 *red_x = info_ptr->colorspace.end_points_xy.redx; 685 if (red_y != NULL) 686 *red_y = info_ptr->colorspace.end_points_xy.redy; 687 if (green_x != NULL) 688 *green_x = info_ptr->colorspace.end_points_xy.greenx; 689 if (green_y != NULL) 690 *green_y = info_ptr->colorspace.end_points_xy.greeny; 691 if (blue_x != NULL) 692 *blue_x = info_ptr->colorspace.end_points_xy.bluex; 693 if (blue_y != NULL) 694 *blue_y = info_ptr->colorspace.end_points_xy.bluey; 695 return (PNG_INFO_cHRM); 696 } 697 698 return (0); 699} 700# endif 701#endif 702 703#ifdef PNG_gAMA_SUPPORTED 704# ifdef PNG_FIXED_POINT_SUPPORTED 705png_uint_32 PNGAPI 706png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, 707 png_fixed_point *file_gamma) 708{ 709 png_debug1(1, "in %s retrieval function", "gAMA"); 710 711 if (png_ptr != NULL && info_ptr != NULL && 712 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && 713 file_gamma != NULL) 714 { 715 *file_gamma = info_ptr->colorspace.gamma; 716 return (PNG_INFO_gAMA); 717 } 718 719 return (0); 720} 721# endif 722 723# ifdef PNG_FLOATING_POINT_SUPPORTED 724png_uint_32 PNGAPI 725png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, 726 double *file_gamma) 727{ 728 png_debug1(1, "in %s retrieval function", "gAMA(float)"); 729 730 if (png_ptr != NULL && info_ptr != NULL && 731 (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && 732 file_gamma != NULL) 733 { 734 *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, 735 "png_get_gAMA"); 736 return (PNG_INFO_gAMA); 737 } 738 739 return (0); 740} 741# endif 742#endif 743 744#ifdef PNG_sRGB_SUPPORTED 745png_uint_32 PNGAPI 746png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, 747 int *file_srgb_intent) 748{ 749 png_debug1(1, "in %s retrieval function", "sRGB"); 750 751 if (png_ptr != NULL && info_ptr != NULL && 752 (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) 753 { 754 *file_srgb_intent = info_ptr->colorspace.rendering_intent; 755 return (PNG_INFO_sRGB); 756 } 757 758 return (0); 759} 760#endif 761 762#ifdef PNG_iCCP_SUPPORTED 763png_uint_32 PNGAPI 764png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, 765 png_charpp name, int *compression_type, 766 png_bytepp profile, png_uint_32 *proflen) 767{ 768 png_debug1(1, "in %s retrieval function", "iCCP"); 769 770 if (png_ptr != NULL && info_ptr != NULL && 771 (info_ptr->valid & PNG_INFO_iCCP) != 0 && 772 name != NULL && 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 790int PNGAPI 791png_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 805png_uint_32 PNGAPI 806png_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 822png_uint_32 PNGAPI 823png_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 867png_uint_32 PNGAPI 868png_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 888png_uint_32 PNGAPI 889png_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) 918png_uint_32 PNGAPI 919png_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 941png_uint_32 PNGAPI 942png_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 */ 957png_uint_32 PNGAPI 958png_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 975png_uint_32 PNGAPI 976png_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 1009png_uint_32 PNGAPI 1010png_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 1028png_uint_32 PNGAPI 1029png_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 1046int PNGAPI 1047png_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 1072png_uint_32 PNGAPI 1073png_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 1090png_uint_32 PNGAPI 1091png_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 1136int PNGAPI 1137png_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 1151png_byte PNGAPI 1152png_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 1159png_voidp PNGAPI 1160png_get_user_chunk_ptr(png_const_structrp png_ptr) 1161{ 1162 return (png_ptr ? png_ptr->user_chunk_ptr : NULL); 1163} 1164#endif 1165 1166png_size_t PNGAPI 1167png_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 */ 1192png_uint_32 PNGAPI 1193png_get_user_width_max (png_const_structrp png_ptr) 1194{ 1195 return (png_ptr ? png_ptr->user_width_max : 0); 1196} 1197 1198png_uint_32 PNGAPI 1199png_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 */ 1205png_uint_32 PNGAPI 1206png_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 */ 1212png_alloc_size_t PNGAPI 1213png_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 1221png_uint_32 PNGAPI 1222png_get_io_state (png_const_structrp png_ptr) 1223{ 1224 return png_ptr->io_state; 1225} 1226 1227png_uint_32 PNGAPI 1228png_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 1236int PNGAPI 1237png_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 */ 1248