pngset.c (36564B)
1 2 /* pngset.c - storage of image information into info struct 3 * 4 * Last changed in libpng 1.2.49 [March 29, 2012] 5 * Copyright (c) 1998-2012 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 * The functions here are used during reads to store data from the file 14 * into the info struct, and during writes to store application data 15 * into the info struct for writing into the file. This abstracts the 16 * info struct and allows us to change the structure in the future. 17 */ 18 19 #define PNG_INTERNAL 20 #define PNG_NO_PEDANTIC_WARNINGS 21 #include "png.h" 22 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 23 24 #ifdef PNG_bKGD_SUPPORTED 25 void PNGAPI 26 png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) 27 { 28 png_debug1(1, "in %s storage function", "bKGD"); 29 30 if (png_ptr == NULL || info_ptr == NULL) 31 return; 32 33 png_memcpy(&(info_ptr->background), background, png_sizeof(png_color_16)); 34 info_ptr->valid |= PNG_INFO_bKGD; 35 } 36 #endif 37 38 #ifdef PNG_cHRM_SUPPORTED 39 #ifdef PNG_FLOATING_POINT_SUPPORTED 40 void PNGAPI 41 png_set_cHRM(png_structp png_ptr, png_infop info_ptr, 42 double white_x, double white_y, double red_x, double red_y, 43 double green_x, double green_y, double blue_x, double blue_y) 44 { 45 png_debug1(1, "in %s storage function", "cHRM"); 46 47 if (png_ptr == NULL || info_ptr == NULL) 48 return; 49 50 info_ptr->x_white = (float)white_x; 51 info_ptr->y_white = (float)white_y; 52 info_ptr->x_red = (float)red_x; 53 info_ptr->y_red = (float)red_y; 54 info_ptr->x_green = (float)green_x; 55 info_ptr->y_green = (float)green_y; 56 info_ptr->x_blue = (float)blue_x; 57 info_ptr->y_blue = (float)blue_y; 58 #ifdef PNG_FIXED_POINT_SUPPORTED 59 info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); 60 info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); 61 info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); 62 info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); 63 info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); 64 info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); 65 info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); 66 info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); 67 #endif 68 info_ptr->valid |= PNG_INFO_cHRM; 69 } 70 #endif /* PNG_FLOATING_POINT_SUPPORTED */ 71 72 #ifdef PNG_FIXED_POINT_SUPPORTED 73 void PNGAPI 74 png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, 75 png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, 76 png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, 77 png_fixed_point blue_x, png_fixed_point blue_y) 78 { 79 png_debug1(1, "in %s storage function", "cHRM fixed"); 80 81 if (png_ptr == NULL || info_ptr == NULL) 82 return; 83 84 #ifdef PNG_CHECK_cHRM_SUPPORTED 85 if (png_check_cHRM_fixed(png_ptr, 86 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) 87 #endif 88 { 89 info_ptr->int_x_white = white_x; 90 info_ptr->int_y_white = white_y; 91 info_ptr->int_x_red = red_x; 92 info_ptr->int_y_red = red_y; 93 info_ptr->int_x_green = green_x; 94 info_ptr->int_y_green = green_y; 95 info_ptr->int_x_blue = blue_x; 96 info_ptr->int_y_blue = blue_y; 97 #ifdef PNG_FLOATING_POINT_SUPPORTED 98 info_ptr->x_white = (float)(white_x/100000.); 99 info_ptr->y_white = (float)(white_y/100000.); 100 info_ptr->x_red = (float)( red_x/100000.); 101 info_ptr->y_red = (float)( red_y/100000.); 102 info_ptr->x_green = (float)(green_x/100000.); 103 info_ptr->y_green = (float)(green_y/100000.); 104 info_ptr->x_blue = (float)( blue_x/100000.); 105 info_ptr->y_blue = (float)( blue_y/100000.); 106 #endif 107 info_ptr->valid |= PNG_INFO_cHRM; 108 } 109 } 110 #endif /* PNG_FIXED_POINT_SUPPORTED */ 111 #endif /* PNG_cHRM_SUPPORTED */ 112 113 #ifdef PNG_gAMA_SUPPORTED 114 #ifdef PNG_FLOATING_POINT_SUPPORTED 115 void PNGAPI 116 png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) 117 { 118 double png_gamma; 119 120 png_debug1(1, "in %s storage function", "gAMA"); 121 122 if (png_ptr == NULL || info_ptr == NULL) 123 return; 124 125 /* Check for overflow */ 126 if (file_gamma > 21474.83) 127 { 128 png_warning(png_ptr, "Limiting gamma to 21474.83"); 129 png_gamma=21474.83; 130 } 131 else 132 png_gamma = file_gamma; 133 info_ptr->gamma = (float)png_gamma; 134 #ifdef PNG_FIXED_POINT_SUPPORTED 135 info_ptr->int_gamma = (int)(png_gamma*100000.+.5); 136 #endif 137 info_ptr->valid |= PNG_INFO_gAMA; 138 if (png_gamma == 0.0) 139 png_warning(png_ptr, "Setting gamma=0"); 140 } 141 #endif 142 void PNGAPI 143 png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point 144 int_gamma) 145 { 146 png_fixed_point png_gamma; 147 148 png_debug1(1, "in %s storage function", "gAMA"); 149 150 if (png_ptr == NULL || info_ptr == NULL) 151 return; 152 153 if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX) 154 { 155 png_warning(png_ptr, "Limiting gamma to 21474.83"); 156 png_gamma=PNG_UINT_31_MAX; 157 } 158 else 159 { 160 if (int_gamma < 0) 161 { 162 png_warning(png_ptr, "Setting negative gamma to zero"); 163 png_gamma = 0; 164 } 165 else 166 png_gamma = int_gamma; 167 } 168 #ifdef PNG_FLOATING_POINT_SUPPORTED 169 info_ptr->gamma = (float)(png_gamma/100000.); 170 #endif 171 #ifdef PNG_FIXED_POINT_SUPPORTED 172 info_ptr->int_gamma = png_gamma; 173 #endif 174 info_ptr->valid |= PNG_INFO_gAMA; 175 if (png_gamma == 0) 176 png_warning(png_ptr, "Setting gamma=0"); 177 } 178 #endif 179 180 #ifdef PNG_hIST_SUPPORTED 181 void PNGAPI 182 png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) 183 { 184 int i; 185 186 png_debug1(1, "in %s storage function", "hIST"); 187 188 if (png_ptr == NULL || info_ptr == NULL) 189 return; 190 191 if (info_ptr->num_palette == 0 || info_ptr->num_palette 192 > PNG_MAX_PALETTE_LENGTH) 193 { 194 png_warning(png_ptr, 195 "Invalid palette size, hIST allocation skipped."); 196 return; 197 } 198 199 #ifdef PNG_FREE_ME_SUPPORTED 200 png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); 201 #endif 202 /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in 203 * version 1.2.1 204 */ 205 png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, 206 (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16))); 207 if (png_ptr->hist == NULL) 208 { 209 png_warning(png_ptr, "Insufficient memory for hIST chunk data."); 210 return; 211 } 212 213 for (i = 0; i < info_ptr->num_palette; i++) 214 png_ptr->hist[i] = hist[i]; 215 info_ptr->hist = png_ptr->hist; 216 info_ptr->valid |= PNG_INFO_hIST; 217 218 #ifdef PNG_FREE_ME_SUPPORTED 219 info_ptr->free_me |= PNG_FREE_HIST; 220 #else 221 png_ptr->flags |= PNG_FLAG_FREE_HIST; 222 #endif 223 } 224 #endif 225 226 void PNGAPI 227 png_set_IHDR(png_structp png_ptr, png_infop info_ptr, 228 png_uint_32 width, png_uint_32 height, int bit_depth, 229 int color_type, int interlace_type, int compression_type, 230 int filter_type) 231 { 232 png_debug1(1, "in %s storage function", "IHDR"); 233 234 if (png_ptr == NULL || info_ptr == NULL) 235 return; 236 237 info_ptr->width = width; 238 info_ptr->height = height; 239 info_ptr->bit_depth = (png_byte)bit_depth; 240 info_ptr->color_type = (png_byte)color_type; 241 info_ptr->compression_type = (png_byte)compression_type; 242 info_ptr->filter_type = (png_byte)filter_type; 243 info_ptr->interlace_type = (png_byte)interlace_type; 244 245 png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, 246 info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, 247 info_ptr->compression_type, info_ptr->filter_type); 248 249 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 250 info_ptr->channels = 1; 251 else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) 252 info_ptr->channels = 3; 253 else 254 info_ptr->channels = 1; 255 if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) 256 info_ptr->channels++; 257 info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); 258 259 /* Check for potential overflow */ 260 if (width > (PNG_UINT_32_MAX 261 >> 3) /* 8-byte RGBA pixels */ 262 - 64 /* bigrowbuf hack */ 263 - 1 /* filter byte */ 264 - 7*8 /* rounding of width to multiple of 8 pixels */ 265 - 8) /* extra max_pixel_depth pad */ 266 info_ptr->rowbytes = (png_size_t)0; 267 else 268 info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); 269 } 270 271 #ifdef PNG_oFFs_SUPPORTED 272 void PNGAPI 273 png_set_oFFs(png_structp png_ptr, png_infop info_ptr, 274 png_int_32 offset_x, png_int_32 offset_y, int unit_type) 275 { 276 png_debug1(1, "in %s storage function", "oFFs"); 277 278 if (png_ptr == NULL || info_ptr == NULL) 279 return; 280 281 info_ptr->x_offset = offset_x; 282 info_ptr->y_offset = offset_y; 283 info_ptr->offset_unit_type = (png_byte)unit_type; 284 info_ptr->valid |= PNG_INFO_oFFs; 285 } 286 #endif 287 288 #ifdef PNG_pCAL_SUPPORTED 289 void PNGAPI 290 png_set_pCAL(png_structp png_ptr, png_infop info_ptr, 291 png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, 292 png_charp units, png_charpp params) 293 { 294 png_uint_32 length; 295 int i; 296 297 png_debug1(1, "in %s storage function", "pCAL"); 298 299 if (png_ptr == NULL || info_ptr == NULL) 300 return; 301 302 length = png_strlen(purpose) + 1; 303 png_debug1(3, "allocating purpose for info (%lu bytes)", 304 (unsigned long)length); 305 info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); 306 if (info_ptr->pcal_purpose == NULL) 307 { 308 png_warning(png_ptr, "Insufficient memory for pCAL purpose."); 309 return; 310 } 311 png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); 312 313 png_debug(3, "storing X0, X1, type, and nparams in info"); 314 info_ptr->pcal_X0 = X0; 315 info_ptr->pcal_X1 = X1; 316 info_ptr->pcal_type = (png_byte)type; 317 info_ptr->pcal_nparams = (png_byte)nparams; 318 319 length = png_strlen(units) + 1; 320 png_debug1(3, "allocating units for info (%lu bytes)", 321 (unsigned long)length); 322 info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); 323 if (info_ptr->pcal_units == NULL) 324 { 325 png_warning(png_ptr, "Insufficient memory for pCAL units."); 326 return; 327 } 328 png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); 329 330 info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, 331 (png_uint_32)((nparams + 1) * png_sizeof(png_charp))); 332 if (info_ptr->pcal_params == NULL) 333 { 334 png_warning(png_ptr, "Insufficient memory for pCAL params."); 335 return; 336 } 337 338 png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); 339 340 for (i = 0; i < nparams; i++) 341 { 342 length = png_strlen(params[i]) + 1; 343 png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, 344 (unsigned long)length); 345 info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); 346 if (info_ptr->pcal_params[i] == NULL) 347 { 348 png_warning(png_ptr, "Insufficient memory for pCAL parameter."); 349 return; 350 } 351 png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); 352 } 353 354 info_ptr->valid |= PNG_INFO_pCAL; 355 #ifdef PNG_FREE_ME_SUPPORTED 356 info_ptr->free_me |= PNG_FREE_PCAL; 357 #endif 358 } 359 #endif 360 361 #if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) 362 #ifdef PNG_FLOATING_POINT_SUPPORTED 363 void PNGAPI 364 png_set_sCAL(png_structp png_ptr, png_infop info_ptr, 365 int unit, double width, double height) 366 { 367 png_debug1(1, "in %s storage function", "sCAL"); 368 369 if (png_ptr == NULL || info_ptr == NULL) 370 return; 371 372 info_ptr->scal_unit = (png_byte)unit; 373 info_ptr->scal_pixel_width = width; 374 info_ptr->scal_pixel_height = height; 375 376 info_ptr->valid |= PNG_INFO_sCAL; 377 } 378 #else 379 #ifdef PNG_FIXED_POINT_SUPPORTED 380 void PNGAPI 381 png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, 382 int unit, png_charp swidth, png_charp sheight) 383 { 384 png_uint_32 length; 385 386 png_debug1(1, "in %s storage function", "sCAL"); 387 388 if (png_ptr == NULL || info_ptr == NULL) 389 return; 390 391 info_ptr->scal_unit = (png_byte)unit; 392 393 length = png_strlen(swidth) + 1; 394 png_debug1(3, "allocating unit for info (%u bytes)", 395 (unsigned int)length); 396 info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); 397 if (info_ptr->scal_s_width == NULL) 398 { 399 png_warning(png_ptr, 400 "Memory allocation failed while processing sCAL."); 401 return; 402 } 403 png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length); 404 405 length = png_strlen(sheight) + 1; 406 png_debug1(3, "allocating unit for info (%u bytes)", 407 (unsigned int)length); 408 info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); 409 if (info_ptr->scal_s_height == NULL) 410 { 411 png_free (png_ptr, info_ptr->scal_s_width); 412 info_ptr->scal_s_width = NULL; 413 png_warning(png_ptr, 414 "Memory allocation failed while processing sCAL."); 415 return; 416 } 417 png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); 418 info_ptr->valid |= PNG_INFO_sCAL; 419 #ifdef PNG_FREE_ME_SUPPORTED 420 info_ptr->free_me |= PNG_FREE_SCAL; 421 #endif 422 } 423 #endif 424 #endif 425 #endif 426 427 #ifdef PNG_pHYs_SUPPORTED 428 void PNGAPI 429 png_set_pHYs(png_structp png_ptr, png_infop info_ptr, 430 png_uint_32 res_x, png_uint_32 res_y, int unit_type) 431 { 432 png_debug1(1, "in %s storage function", "pHYs"); 433 434 if (png_ptr == NULL || info_ptr == NULL) 435 return; 436 437 info_ptr->x_pixels_per_unit = res_x; 438 info_ptr->y_pixels_per_unit = res_y; 439 info_ptr->phys_unit_type = (png_byte)unit_type; 440 info_ptr->valid |= PNG_INFO_pHYs; 441 } 442 #endif 443 444 void PNGAPI 445 png_set_PLTE(png_structp png_ptr, png_infop info_ptr, 446 png_colorp palette, int num_palette) 447 { 448 449 png_debug1(1, "in %s storage function", "PLTE"); 450 451 if (png_ptr == NULL || info_ptr == NULL) 452 return; 453 454 if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) 455 { 456 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 457 png_error(png_ptr, "Invalid palette length"); 458 else 459 { 460 png_warning(png_ptr, "Invalid palette length"); 461 return; 462 } 463 } 464 465 /* It may not actually be necessary to set png_ptr->palette here; 466 * we do it for backward compatibility with the way the png_handle_tRNS 467 * function used to do the allocation. 468 */ 469 #ifdef PNG_FREE_ME_SUPPORTED 470 png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); 471 #endif 472 473 /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead 474 * of num_palette entries, in case of an invalid PNG file that has 475 * too-large sample values. 476 */ 477 png_ptr->palette = (png_colorp)png_calloc(png_ptr, 478 PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); 479 png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); 480 info_ptr->palette = png_ptr->palette; 481 info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; 482 483 #ifdef PNG_FREE_ME_SUPPORTED 484 info_ptr->free_me |= PNG_FREE_PLTE; 485 #else 486 png_ptr->flags |= PNG_FLAG_FREE_PLTE; 487 #endif 488 489 info_ptr->valid |= PNG_INFO_PLTE; 490 } 491 492 #ifdef PNG_sBIT_SUPPORTED 493 void PNGAPI 494 png_set_sBIT(png_structp png_ptr, png_infop info_ptr, 495 png_color_8p sig_bit) 496 { 497 png_debug1(1, "in %s storage function", "sBIT"); 498 499 if (png_ptr == NULL || info_ptr == NULL) 500 return; 501 502 png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); 503 info_ptr->valid |= PNG_INFO_sBIT; 504 } 505 #endif 506 507 #ifdef PNG_sRGB_SUPPORTED 508 void PNGAPI 509 png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) 510 { 511 png_debug1(1, "in %s storage function", "sRGB"); 512 513 if (png_ptr == NULL || info_ptr == NULL) 514 return; 515 516 info_ptr->srgb_intent = (png_byte)intent; 517 info_ptr->valid |= PNG_INFO_sRGB; 518 } 519 520 void PNGAPI 521 png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, 522 int intent) 523 { 524 #ifdef PNG_gAMA_SUPPORTED 525 #ifdef PNG_FLOATING_POINT_SUPPORTED 526 float file_gamma; 527 #endif 528 #ifdef PNG_FIXED_POINT_SUPPORTED 529 png_fixed_point int_file_gamma; 530 #endif 531 #endif 532 #ifdef PNG_cHRM_SUPPORTED 533 #ifdef PNG_FLOATING_POINT_SUPPORTED 534 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 535 #endif 536 png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, 537 int_green_y, int_blue_x, int_blue_y; 538 #endif 539 png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); 540 541 if (png_ptr == NULL || info_ptr == NULL) 542 return; 543 544 png_set_sRGB(png_ptr, info_ptr, intent); 545 546 #ifdef PNG_gAMA_SUPPORTED 547 #ifdef PNG_FLOATING_POINT_SUPPORTED 548 file_gamma = (float).45455; 549 png_set_gAMA(png_ptr, info_ptr, file_gamma); 550 #endif 551 #ifdef PNG_FIXED_POINT_SUPPORTED 552 int_file_gamma = 45455L; 553 png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); 554 #endif 555 #endif 556 557 #ifdef PNG_cHRM_SUPPORTED 558 int_white_x = 31270L; 559 int_white_y = 32900L; 560 int_red_x = 64000L; 561 int_red_y = 33000L; 562 int_green_x = 30000L; 563 int_green_y = 60000L; 564 int_blue_x = 15000L; 565 int_blue_y = 6000L; 566 567 #ifdef PNG_FLOATING_POINT_SUPPORTED 568 white_x = (float).3127; 569 white_y = (float).3290; 570 red_x = (float).64; 571 red_y = (float).33; 572 green_x = (float).30; 573 green_y = (float).60; 574 blue_x = (float).15; 575 blue_y = (float).06; 576 #endif 577 578 #ifdef PNG_FIXED_POINT_SUPPORTED 579 png_set_cHRM_fixed(png_ptr, info_ptr, 580 int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, 581 int_green_y, int_blue_x, int_blue_y); 582 #endif 583 #ifdef PNG_FLOATING_POINT_SUPPORTED 584 png_set_cHRM(png_ptr, info_ptr, 585 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 586 #endif 587 #endif /* cHRM */ 588 } 589 #endif /* sRGB */ 590 591 592 #ifdef PNG_iCCP_SUPPORTED 593 void PNGAPI 594 png_set_iCCP(png_structp png_ptr, png_infop info_ptr, 595 png_charp name, int compression_type, 596 png_charp profile, png_uint_32 proflen) 597 { 598 png_charp new_iccp_name; 599 png_charp new_iccp_profile; 600 png_uint_32 length; 601 602 png_debug1(1, "in %s storage function", "iCCP"); 603 604 if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) 605 return; 606 607 length = png_strlen(name)+1; 608 new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); 609 if (new_iccp_name == NULL) 610 { 611 png_warning(png_ptr, "Insufficient memory to process iCCP chunk."); 612 return; 613 } 614 png_memcpy(new_iccp_name, name, length); 615 new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); 616 if (new_iccp_profile == NULL) 617 { 618 png_free (png_ptr, new_iccp_name); 619 png_warning(png_ptr, 620 "Insufficient memory to process iCCP profile."); 621 return; 622 } 623 png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); 624 625 png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); 626 627 info_ptr->iccp_proflen = proflen; 628 info_ptr->iccp_name = new_iccp_name; 629 info_ptr->iccp_profile = new_iccp_profile; 630 /* Compression is always zero but is here so the API and info structure 631 * does not have to change if we introduce multiple compression types 632 */ 633 info_ptr->iccp_compression = (png_byte)compression_type; 634 #ifdef PNG_FREE_ME_SUPPORTED 635 info_ptr->free_me |= PNG_FREE_ICCP; 636 #endif 637 info_ptr->valid |= PNG_INFO_iCCP; 638 } 639 #endif 640 641 #ifdef PNG_TEXT_SUPPORTED 642 void PNGAPI 643 png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, 644 int num_text) 645 { 646 int ret; 647 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); 648 if (ret) 649 png_error(png_ptr, "Insufficient memory to store text"); 650 } 651 652 int /* PRIVATE */ 653 png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, 654 int num_text) 655 { 656 int i; 657 658 png_debug1(1, "in %s storage function", ((png_ptr == NULL || 659 png_ptr->chunk_name[0] == '\0') ? 660 "text" : (png_const_charp)png_ptr->chunk_name)); 661 662 if (png_ptr == NULL || info_ptr == NULL || num_text == 0) 663 return(0); 664 665 /* Make sure we have enough space in the "text" array in info_struct 666 * to hold all of the incoming text_ptr objects. 667 */ 668 if (info_ptr->num_text + num_text > info_ptr->max_text) 669 { 670 int old_max_text = info_ptr->max_text; 671 int old_num_text = info_ptr->num_text; 672 673 if (info_ptr->text != NULL) 674 { 675 png_textp old_text; 676 677 info_ptr->max_text = info_ptr->num_text + num_text + 8; 678 old_text = info_ptr->text; 679 680 info_ptr->text = (png_textp)png_malloc_warn(png_ptr, 681 (png_uint_32)(info_ptr->max_text * png_sizeof(png_text))); 682 if (info_ptr->text == NULL) 683 { 684 /* Restore to previous condition */ 685 info_ptr->max_text = old_max_text; 686 info_ptr->text = old_text; 687 return(1); 688 } 689 png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max_text * 690 png_sizeof(png_text))); 691 png_free(png_ptr, old_text); 692 } 693 else 694 { 695 info_ptr->max_text = num_text + 8; 696 info_ptr->num_text = 0; 697 info_ptr->text = (png_textp)png_malloc_warn(png_ptr, 698 (png_uint_32)(info_ptr->max_text * png_sizeof(png_text))); 699 if (info_ptr->text == NULL) 700 { 701 /* Restore to previous condition */ 702 info_ptr->num_text = old_num_text; 703 info_ptr->max_text = old_max_text; 704 return(1); 705 } 706 #ifdef PNG_FREE_ME_SUPPORTED 707 info_ptr->free_me |= PNG_FREE_TEXT; 708 #endif 709 } 710 png_debug1(3, "allocated %d entries for info_ptr->text", 711 info_ptr->max_text); 712 } 713 714 for (i = 0; i < num_text; i++) 715 { 716 png_size_t text_length, key_len; 717 png_size_t lang_len, lang_key_len; 718 png_textp textp = &(info_ptr->text[info_ptr->num_text]); 719 720 if (text_ptr[i].key == NULL) 721 continue; 722 723 key_len = png_strlen(text_ptr[i].key); 724 725 if (text_ptr[i].compression <= 0) 726 { 727 lang_len = 0; 728 lang_key_len = 0; 729 } 730 731 else 732 #ifdef PNG_iTXt_SUPPORTED 733 { 734 /* Set iTXt data */ 735 736 if (text_ptr[i].lang != NULL) 737 lang_len = png_strlen(text_ptr[i].lang); 738 else 739 lang_len = 0; 740 if (text_ptr[i].lang_key != NULL) 741 lang_key_len = png_strlen(text_ptr[i].lang_key); 742 else 743 lang_key_len = 0; 744 } 745 #else /* PNG_iTXt_SUPPORTED */ 746 { 747 png_warning(png_ptr, "iTXt chunk not supported."); 748 continue; 749 } 750 #endif 751 752 if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') 753 { 754 text_length = 0; 755 #ifdef PNG_iTXt_SUPPORTED 756 if (text_ptr[i].compression > 0) 757 textp->compression = PNG_ITXT_COMPRESSION_NONE; 758 else 759 #endif 760 textp->compression = PNG_TEXT_COMPRESSION_NONE; 761 } 762 763 else 764 { 765 text_length = png_strlen(text_ptr[i].text); 766 textp->compression = text_ptr[i].compression; 767 } 768 769 textp->key = (png_charp)png_malloc_warn(png_ptr, 770 (png_uint_32) 771 (key_len + text_length + lang_len + lang_key_len + 4)); 772 if (textp->key == NULL) 773 return(1); 774 png_debug2(2, "Allocated %lu bytes at %x in png_set_text", 775 (png_uint_32) 776 (key_len + lang_len + lang_key_len + text_length + 4), 777 (int)textp->key); 778 779 png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); 780 *(textp->key + key_len) = '\0'; 781 #ifdef PNG_iTXt_SUPPORTED 782 if (text_ptr[i].compression > 0) 783 { 784 textp->lang = textp->key + key_len + 1; 785 png_memcpy(textp->lang, text_ptr[i].lang, lang_len); 786 *(textp->lang + lang_len) = '\0'; 787 textp->lang_key = textp->lang + lang_len + 1; 788 png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); 789 *(textp->lang_key + lang_key_len) = '\0'; 790 textp->text = textp->lang_key + lang_key_len + 1; 791 } 792 else 793 #endif 794 { 795 #ifdef PNG_iTXt_SUPPORTED 796 textp->lang=NULL; 797 textp->lang_key=NULL; 798 #endif 799 textp->text = textp->key + key_len + 1; 800 } 801 if (text_length) 802 png_memcpy(textp->text, text_ptr[i].text, 803 (png_size_t)(text_length)); 804 *(textp->text + text_length) = '\0'; 805 806 #ifdef PNG_iTXt_SUPPORTED 807 if (textp->compression > 0) 808 { 809 textp->text_length = 0; 810 textp->itxt_length = text_length; 811 } 812 else 813 #endif 814 815 { 816 textp->text_length = text_length; 817 #ifdef PNG_iTXt_SUPPORTED 818 textp->itxt_length = 0; 819 #endif 820 } 821 info_ptr->num_text++; 822 png_debug1(3, "transferred text chunk %d", info_ptr->num_text); 823 } 824 return(0); 825 } 826 #endif 827 828 #ifdef PNG_tIME_SUPPORTED 829 void PNGAPI 830 png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) 831 { 832 png_debug1(1, "in %s storage function", "tIME"); 833 834 if (png_ptr == NULL || info_ptr == NULL || 835 (png_ptr->mode & PNG_WROTE_tIME)) 836 return; 837 838 png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); 839 info_ptr->valid |= PNG_INFO_tIME; 840 } 841 #endif 842 843 #ifdef PNG_tRNS_SUPPORTED 844 void PNGAPI 845 png_set_tRNS(png_structp png_ptr, png_infop info_ptr, 846 png_bytep trans, int num_trans, png_color_16p trans_values) 847 { 848 png_debug1(1, "in %s storage function", "tRNS"); 849 850 if (png_ptr == NULL || info_ptr == NULL) 851 return; 852 853 if (trans != NULL) 854 { 855 /* It may not actually be necessary to set png_ptr->trans here; 856 * we do it for backward compatibility with the way the png_handle_tRNS 857 * function used to do the allocation. 858 */ 859 860 #ifdef PNG_FREE_ME_SUPPORTED 861 png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); 862 #endif 863 864 /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ 865 png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, 866 (png_uint_32)PNG_MAX_PALETTE_LENGTH); 867 if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) 868 png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); 869 } 870 871 if (trans_values != NULL) 872 { 873 int sample_max = (1 << info_ptr->bit_depth); 874 if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && 875 (int)trans_values->gray > sample_max) || 876 (info_ptr->color_type == PNG_COLOR_TYPE_RGB && 877 ((int)trans_values->red > sample_max || 878 (int)trans_values->green > sample_max || 879 (int)trans_values->blue > sample_max))) 880 png_warning(png_ptr, 881 "tRNS chunk has out-of-range samples for bit_depth"); 882 png_memcpy(&(info_ptr->trans_values), trans_values, 883 png_sizeof(png_color_16)); 884 if (num_trans == 0) 885 num_trans = 1; 886 } 887 888 info_ptr->num_trans = (png_uint_16)num_trans; 889 if (num_trans != 0) 890 { 891 info_ptr->valid |= PNG_INFO_tRNS; 892 #ifdef PNG_FREE_ME_SUPPORTED 893 info_ptr->free_me |= PNG_FREE_TRNS; 894 #else 895 png_ptr->flags |= PNG_FLAG_FREE_TRNS; 896 #endif 897 } 898 } 899 #endif 900 901 #ifdef PNG_sPLT_SUPPORTED 902 void PNGAPI 903 png_set_sPLT(png_structp png_ptr, 904 png_infop info_ptr, png_sPLT_tp entries, int nentries) 905 /* 906 * entries - array of png_sPLT_t structures 907 * to be added to the list of palettes 908 * in the info structure. 909 * nentries - number of palette structures to be 910 * added. 911 */ 912 { 913 png_sPLT_tp np; 914 int i; 915 916 if (png_ptr == NULL || info_ptr == NULL) 917 return; 918 919 np = (png_sPLT_tp)png_malloc_warn(png_ptr, 920 (info_ptr->splt_palettes_num + nentries) * 921 (png_uint_32)png_sizeof(png_sPLT_t)); 922 if (np == NULL) 923 { 924 png_warning(png_ptr, "No memory for sPLT palettes."); 925 return; 926 } 927 928 png_memcpy(np, info_ptr->splt_palettes, 929 info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); 930 png_free(png_ptr, info_ptr->splt_palettes); 931 info_ptr->splt_palettes=NULL; 932 933 for (i = 0; i < nentries; i++) 934 { 935 png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; 936 png_sPLT_tp from = entries + i; 937 png_uint_32 length; 938 939 length = png_strlen(from->name) + 1; 940 to->name = (png_charp)png_malloc_warn(png_ptr, length); 941 if (to->name == NULL) 942 { 943 png_warning(png_ptr, 944 "Out of memory while processing sPLT chunk"); 945 continue; 946 } 947 png_memcpy(to->name, from->name, length); 948 to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, 949 (png_uint_32)(from->nentries * png_sizeof(png_sPLT_entry))); 950 if (to->entries == NULL) 951 { 952 png_warning(png_ptr, 953 "Out of memory while processing sPLT chunk"); 954 png_free(png_ptr, to->name); 955 to->name = NULL; 956 continue; 957 } 958 png_memcpy(to->entries, from->entries, 959 from->nentries * png_sizeof(png_sPLT_entry)); 960 to->nentries = from->nentries; 961 to->depth = from->depth; 962 } 963 964 info_ptr->splt_palettes = np; 965 info_ptr->splt_palettes_num += nentries; 966 info_ptr->valid |= PNG_INFO_sPLT; 967 #ifdef PNG_FREE_ME_SUPPORTED 968 info_ptr->free_me |= PNG_FREE_SPLT; 969 #endif 970 } 971 #endif /* PNG_sPLT_SUPPORTED */ 972 973 #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED 974 void PNGAPI 975 png_set_unknown_chunks(png_structp png_ptr, 976 png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) 977 { 978 png_unknown_chunkp np; 979 int i; 980 981 if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) 982 return; 983 984 np = (png_unknown_chunkp)png_malloc_warn(png_ptr, 985 (png_uint_32)((info_ptr->unknown_chunks_num + num_unknowns) * 986 png_sizeof(png_unknown_chunk))); 987 if (np == NULL) 988 { 989 png_warning(png_ptr, 990 "Out of memory while processing unknown chunk."); 991 return; 992 } 993 994 png_memcpy(np, info_ptr->unknown_chunks, 995 info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); 996 png_free(png_ptr, info_ptr->unknown_chunks); 997 info_ptr->unknown_chunks = NULL; 998 999 for (i = 0; i < num_unknowns; i++) 1000 { 1001 png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; 1002 png_unknown_chunkp from = unknowns + i; 1003 1004 png_memcpy((png_charp)to->name, (png_charp)from->name, 1005 png_sizeof(from->name)); 1006 to->name[png_sizeof(to->name)-1] = '\0'; 1007 to->size = from->size; 1008 /* Note our location in the read or write sequence */ 1009 to->location = (png_byte)(png_ptr->mode & 0xff); 1010 1011 if (from->size == 0) 1012 to->data=NULL; 1013 else 1014 { 1015 to->data = (png_bytep)png_malloc_warn(png_ptr, 1016 (png_uint_32)from->size); 1017 if (to->data == NULL) 1018 { 1019 png_warning(png_ptr, 1020 "Out of memory while processing unknown chunk."); 1021 to->size = 0; 1022 } 1023 else 1024 png_memcpy(to->data, from->data, from->size); 1025 } 1026 } 1027 1028 info_ptr->unknown_chunks = np; 1029 info_ptr->unknown_chunks_num += num_unknowns; 1030 #ifdef PNG_FREE_ME_SUPPORTED 1031 info_ptr->free_me |= PNG_FREE_UNKN; 1032 #endif 1033 } 1034 void PNGAPI 1035 png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, 1036 int chunk, int location) 1037 { 1038 if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < 1039 (int)info_ptr->unknown_chunks_num) 1040 info_ptr->unknown_chunks[chunk].location = (png_byte)location; 1041 } 1042 #endif 1043 1044 #if defined(PNG_1_0_X) || defined(PNG_1_2_X) 1045 #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ 1046 defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) 1047 void PNGAPI 1048 png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) 1049 { 1050 /* This function is deprecated in favor of png_permit_mng_features() 1051 and will be removed from libpng-1.3.0 */ 1052 1053 png_debug(1, "in png_permit_empty_plte, DEPRECATED."); 1054 1055 if (png_ptr == NULL) 1056 return; 1057 png_ptr->mng_features_permitted = (png_byte) 1058 ((png_ptr->mng_features_permitted & (~PNG_FLAG_MNG_EMPTY_PLTE)) | 1059 ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE))); 1060 } 1061 #endif 1062 #endif 1063 1064 #ifdef PNG_MNG_FEATURES_SUPPORTED 1065 png_uint_32 PNGAPI 1066 png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) 1067 { 1068 png_debug(1, "in png_permit_mng_features"); 1069 1070 if (png_ptr == NULL) 1071 return (png_uint_32)0; 1072 png_ptr->mng_features_permitted = 1073 (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); 1074 return (png_uint_32)png_ptr->mng_features_permitted; 1075 } 1076 #endif 1077 1078 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 1079 void PNGAPI 1080 png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep 1081 chunk_list, int num_chunks) 1082 { 1083 png_bytep new_list, p; 1084 int i, old_num_chunks; 1085 if (png_ptr == NULL) 1086 return; 1087 if (num_chunks == 0) 1088 { 1089 if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) 1090 png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; 1091 else 1092 png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; 1093 1094 if (keep == PNG_HANDLE_CHUNK_ALWAYS) 1095 png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; 1096 else 1097 png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; 1098 return; 1099 } 1100 if (chunk_list == NULL) 1101 return; 1102 old_num_chunks = png_ptr->num_chunk_list; 1103 new_list=(png_bytep)png_malloc(png_ptr, 1104 (png_uint_32) 1105 (5*(num_chunks + old_num_chunks))); 1106 if (png_ptr->chunk_list != NULL) 1107 { 1108 png_memcpy(new_list, png_ptr->chunk_list, 1109 (png_size_t)(5*old_num_chunks)); 1110 png_free(png_ptr, png_ptr->chunk_list); 1111 png_ptr->chunk_list=NULL; 1112 } 1113 png_memcpy(new_list + 5*old_num_chunks, chunk_list, 1114 (png_size_t)(5*num_chunks)); 1115 for (p = new_list + 5*old_num_chunks + 4, i = 0; i<num_chunks; i++, p += 5) 1116 *p=(png_byte)keep; 1117 png_ptr->num_chunk_list = old_num_chunks + num_chunks; 1118 png_ptr->chunk_list = new_list; 1119 #ifdef PNG_FREE_ME_SUPPORTED 1120 png_ptr->free_me |= PNG_FREE_LIST; 1121 #endif 1122 } 1123 #endif 1124 1125 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED 1126 void PNGAPI 1127 png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, 1128 png_user_chunk_ptr read_user_chunk_fn) 1129 { 1130 png_debug(1, "in png_set_read_user_chunk_fn"); 1131 1132 if (png_ptr == NULL) 1133 return; 1134 1135 png_ptr->read_user_chunk_fn = read_user_chunk_fn; 1136 png_ptr->user_chunk_ptr = user_chunk_ptr; 1137 } 1138 #endif 1139 1140 #ifdef PNG_INFO_IMAGE_SUPPORTED 1141 void PNGAPI 1142 png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) 1143 { 1144 png_debug1(1, "in %s storage function", "rows"); 1145 1146 if (png_ptr == NULL || info_ptr == NULL) 1147 return; 1148 1149 if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) 1150 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); 1151 info_ptr->row_pointers = row_pointers; 1152 if (row_pointers) 1153 info_ptr->valid |= PNG_INFO_IDAT; 1154 } 1155 #endif 1156 1157 void PNGAPI 1158 png_set_compression_buffer_size(png_structp png_ptr, 1159 png_uint_32 size) 1160 { 1161 if (png_ptr == NULL) 1162 return; 1163 png_free(png_ptr, png_ptr->zbuf); 1164 png_ptr->zbuf_size = (png_size_t)size; 1165 png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); 1166 png_ptr->zstream.next_out = png_ptr->zbuf; 1167 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 1168 } 1169 1170 void PNGAPI 1171 png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) 1172 { 1173 if (png_ptr && info_ptr) 1174 info_ptr->valid &= ~mask; 1175 } 1176 1177 1178 #ifndef PNG_1_0_X 1179 #ifdef PNG_ASSEMBLER_CODE_SUPPORTED 1180 /* Function was added to libpng 1.2.0 and should always exist by default */ 1181 void PNGAPI 1182 png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) 1183 { 1184 /* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */ 1185 if (png_ptr != NULL) 1186 png_ptr->asm_flags = 0; 1187 asm_flags = asm_flags; /* Quiet the compiler */ 1188 } 1189 1190 /* This function was added to libpng 1.2.0 */ 1191 void PNGAPI 1192 png_set_mmx_thresholds (png_structp png_ptr, 1193 png_byte mmx_bitdepth_threshold, 1194 png_uint_32 mmx_rowbytes_threshold) 1195 { 1196 /* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */ 1197 if (png_ptr == NULL) 1198 return; 1199 /* Quiet the compiler */ 1200 mmx_bitdepth_threshold = mmx_bitdepth_threshold; 1201 mmx_rowbytes_threshold = mmx_rowbytes_threshold; 1202 } 1203 #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ 1204 1205 #ifdef PNG_SET_USER_LIMITS_SUPPORTED 1206 /* This function was added to libpng 1.2.6 */ 1207 void PNGAPI 1208 png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, 1209 png_uint_32 user_height_max) 1210 { 1211 /* Images with dimensions larger than these limits will be 1212 * rejected by png_set_IHDR(). To accept any PNG datastream 1213 * regardless of dimensions, set both limits to 0x7ffffffL. 1214 */ 1215 if (png_ptr == NULL) 1216 return; 1217 png_ptr->user_width_max = user_width_max; 1218 png_ptr->user_height_max = user_height_max; 1219 } 1220 #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ 1221 1222 1223 #ifdef PNG_BENIGN_ERRORS_SUPPORTED 1224 void PNGAPI 1225 png_set_benign_errors(png_structp png_ptr, int allowed) 1226 { 1227 png_debug(1, "in png_set_benign_errors"); 1228 1229 if (allowed) 1230 png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; 1231 else 1232 png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; 1233 } 1234 #endif /* PNG_BENIGN_ERRORS_SUPPORTED */ 1235 #endif /* ?PNG_1_0_X */ 1236 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */