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