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 */