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