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