1 2/* pngwutil.c - utilities to write a PNG file 3 * 4 * Last changed in libpng 1.5.10 [March 8, 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 14#include "pngpriv.h" 15 16#ifdef PNG_WRITE_SUPPORTED 17 18#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED 19/* Place a 32-bit number into a buffer in PNG byte order. We work 20 * with unsigned numbers for convenience, although one supported 21 * ancillary chunk uses signed (two's complement) numbers. 22 */ 23void PNGAPI 24png_save_uint_32(png_bytep buf, png_uint_32 i) 25{ 26 buf[0] = (png_byte)((i >> 24) & 0xff); 27 buf[1] = (png_byte)((i >> 16) & 0xff); 28 buf[2] = (png_byte)((i >> 8) & 0xff); 29 buf[3] = (png_byte)(i & 0xff); 30} 31 32#ifdef PNG_SAVE_INT_32_SUPPORTED 33/* The png_save_int_32 function assumes integers are stored in two's 34 * complement format. If this isn't the case, then this routine needs to 35 * be modified to write data in two's complement format. Note that, 36 * the following works correctly even if png_int_32 has more than 32 bits 37 * (compare the more complex code required on read for sign extention.) 38 */ 39void PNGAPI 40png_save_int_32(png_bytep buf, png_int_32 i) 41{ 42 buf[0] = (png_byte)((i >> 24) & 0xff); 43 buf[1] = (png_byte)((i >> 16) & 0xff); 44 buf[2] = (png_byte)((i >> 8) & 0xff); 45 buf[3] = (png_byte)(i & 0xff); 46} 47#endif 48 49/* Place a 16-bit number into a buffer in PNG byte order. 50 * The parameter is declared unsigned int, not png_uint_16, 51 * just to avoid potential problems on pre-ANSI C compilers. 52 */ 53void PNGAPI 54png_save_uint_16(png_bytep buf, unsigned int i) 55{ 56 buf[0] = (png_byte)((i >> 8) & 0xff); 57 buf[1] = (png_byte)(i & 0xff); 58} 59#endif 60 61/* Simple function to write the signature. If we have already written 62 * the magic bytes of the signature, or more likely, the PNG stream is 63 * being embedded into another stream and doesn't need its own signature, 64 * we should call png_set_sig_bytes() to tell libpng how many of the 65 * bytes have already been written. 66 */ 67void PNGAPI 68png_write_sig(png_structp png_ptr) 69{ 70 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 71 72#ifdef PNG_IO_STATE_SUPPORTED 73 /* Inform the I/O callback that the signature is being written */ 74 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; 75#endif 76 77 /* Write the rest of the 8 byte signature */ 78 png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], 79 (png_size_t)(8 - png_ptr->sig_bytes)); 80 81 if (png_ptr->sig_bytes < 3) 82 png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; 83} 84 85/* Write the start of a PNG chunk. The type is the chunk type. 86 * The total_length is the sum of the lengths of all the data you will be 87 * passing in png_write_chunk_data(). 88 */ 89static void 90png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name, 91 png_uint_32 length) 92{ 93 png_byte buf[8]; 94 95#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) 96 PNG_CSTRING_FROM_CHUNK(buf, chunk_name); 97 png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); 98#endif 99 100 if (png_ptr == NULL) 101 return; 102 103#ifdef PNG_IO_STATE_SUPPORTED 104 /* Inform the I/O callback that the chunk header is being written. 105 * PNG_IO_CHUNK_HDR requires a single I/O call. 106 */ 107 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; 108#endif 109 110 /* Write the length and the chunk name */ 111 png_save_uint_32(buf, length); 112 png_save_uint_32(buf + 4, chunk_name); 113 png_write_data(png_ptr, buf, 8); 114 115 /* Put the chunk name into png_ptr->chunk_name */ 116 png_ptr->chunk_name = chunk_name; 117 118 /* Reset the crc and run it over the chunk name */ 119 png_reset_crc(png_ptr); 120 121 png_calculate_crc(png_ptr, buf + 4, 4); 122 123#ifdef PNG_IO_STATE_SUPPORTED 124 /* Inform the I/O callback that chunk data will (possibly) be written. 125 * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. 126 */ 127 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; 128#endif 129} 130 131void PNGAPI 132png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string, 133 png_uint_32 length) 134{ 135 png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); 136} 137 138/* Write the data of a PNG chunk started with png_write_chunk_header(). 139 * Note that multiple calls to this function are allowed, and that the 140 * sum of the lengths from these calls *must* add up to the total_length 141 * given to png_write_chunk_header(). 142 */ 143void PNGAPI 144png_write_chunk_data(png_structp png_ptr, png_const_bytep data, 145 png_size_t length) 146{ 147 /* Write the data, and run the CRC over it */ 148 if (png_ptr == NULL) 149 return; 150 151 if (data != NULL && length > 0) 152 { 153 png_write_data(png_ptr, data, length); 154 155 /* Update the CRC after writing the data, 156 * in case that the user I/O routine alters it. 157 */ 158 png_calculate_crc(png_ptr, data, length); 159 } 160} 161 162/* Finish a chunk started with png_write_chunk_header(). */ 163void PNGAPI 164png_write_chunk_end(png_structp png_ptr) 165{ 166 png_byte buf[4]; 167 168 if (png_ptr == NULL) return; 169 170#ifdef PNG_IO_STATE_SUPPORTED 171 /* Inform the I/O callback that the chunk CRC is being written. 172 * PNG_IO_CHUNK_CRC requires a single I/O function call. 173 */ 174 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; 175#endif 176 177 /* Write the crc in a single operation */ 178 png_save_uint_32(buf, png_ptr->crc); 179 180 png_write_data(png_ptr, buf, (png_size_t)4); 181} 182 183/* Write a PNG chunk all at once. The type is an array of ASCII characters 184 * representing the chunk name. The array must be at least 4 bytes in 185 * length, and does not need to be null terminated. To be safe, pass the 186 * pre-defined chunk names here, and if you need a new one, define it 187 * where the others are defined. The length is the length of the data. 188 * All the data must be present. If that is not possible, use the 189 * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() 190 * functions instead. 191 */ 192static void 193png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name, 194 png_const_bytep data, png_size_t length) 195{ 196 if (png_ptr == NULL) 197 return; 198 199 /* On 64 bit architectures 'length' may not fit in a png_uint_32. */ 200 if (length > PNG_UINT_32_MAX) 201 png_error(png_ptr, "length exceeds PNG maxima"); 202 203 png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); 204 png_write_chunk_data(png_ptr, data, length); 205 png_write_chunk_end(png_ptr); 206} 207 208/* This is the API that calls the internal function above. */ 209void PNGAPI 210png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string, 211 png_const_bytep data, png_size_t length) 212{ 213 png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, 214 length); 215} 216 217/* Initialize the compressor for the appropriate type of compression. */ 218static void 219png_zlib_claim(png_structp png_ptr, png_uint_32 state) 220{ 221 if (!(png_ptr->zlib_state & PNG_ZLIB_IN_USE)) 222 { 223 /* If already initialized for 'state' do not re-init. */ 224 if (png_ptr->zlib_state != state) 225 { 226 int ret = Z_OK; 227 png_const_charp who = "-"; 228 229 /* If actually initialized for another state do a deflateEnd. */ 230 if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) 231 { 232 ret = deflateEnd(&png_ptr->zstream); 233 who = "end"; 234 png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; 235 } 236 237 /* zlib itself detects an incomplete state on deflateEnd */ 238 if (ret == Z_OK) switch (state) 239 { 240# ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED 241 case PNG_ZLIB_FOR_TEXT: 242 ret = deflateInit2(&png_ptr->zstream, 243 png_ptr->zlib_text_level, png_ptr->zlib_text_method, 244 png_ptr->zlib_text_window_bits, 245 png_ptr->zlib_text_mem_level, png_ptr->zlib_text_strategy); 246 who = "text"; 247 break; 248# endif 249 250 case PNG_ZLIB_FOR_IDAT: 251 ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, 252 png_ptr->zlib_method, png_ptr->zlib_window_bits, 253 png_ptr->zlib_mem_level, png_ptr->zlib_strategy); 254 who = "IDAT"; 255 break; 256 257 default: 258 png_error(png_ptr, "invalid zlib state"); 259 } 260 261 if (ret == Z_OK) 262 png_ptr->zlib_state = state; 263 264 else /* an error in deflateEnd or deflateInit2 */ 265 { 266 size_t pos = 0; 267 char msg[64]; 268 269 pos = png_safecat(msg, sizeof msg, pos, 270 "zlib failed to initialize compressor ("); 271 pos = png_safecat(msg, sizeof msg, pos, who); 272 273 switch (ret) 274 { 275 case Z_VERSION_ERROR: 276 pos = png_safecat(msg, sizeof msg, pos, ") version error"); 277 break; 278 279 case Z_STREAM_ERROR: 280 pos = png_safecat(msg, sizeof msg, pos, ") stream error"); 281 break; 282 283 case Z_MEM_ERROR: 284 pos = png_safecat(msg, sizeof msg, pos, ") memory error"); 285 break; 286 287 default: 288 pos = png_safecat(msg, sizeof msg, pos, ") unknown error"); 289 break; 290 } 291 292 png_error(png_ptr, msg); 293 } 294 } 295 296 /* Here on success, claim the zstream: */ 297 png_ptr->zlib_state |= PNG_ZLIB_IN_USE; 298 } 299 300 else 301 png_error(png_ptr, "zstream already in use (internal error)"); 302} 303 304/* The opposite: release the stream. It is also reset, this API will warn on 305 * error but will not fail. 306 */ 307static void 308png_zlib_release(png_structp png_ptr) 309{ 310 if (png_ptr->zlib_state & PNG_ZLIB_IN_USE) 311 { 312 int ret = deflateReset(&png_ptr->zstream); 313 314 png_ptr->zlib_state &= ~PNG_ZLIB_IN_USE; 315 316 if (ret != Z_OK) 317 { 318 png_const_charp err; 319 PNG_WARNING_PARAMETERS(p) 320 321 switch (ret) 322 { 323 case Z_VERSION_ERROR: 324 err = "version"; 325 break; 326 327 case Z_STREAM_ERROR: 328 err = "stream"; 329 break; 330 331 case Z_MEM_ERROR: 332 err = "memory"; 333 break; 334 335 default: 336 err = "unknown"; 337 break; 338 } 339 340 png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, ret); 341 png_warning_parameter(p, 2, err); 342 343 if (png_ptr->zstream.msg) 344 err = png_ptr->zstream.msg; 345 else 346 err = "[no zlib message]"; 347 348 png_warning_parameter(p, 3, err); 349 350 png_formatted_warning(png_ptr, p, 351 "zlib failed to reset compressor: @1(@2): @3"); 352 } 353 } 354 355 else 356 png_warning(png_ptr, "zstream not in use (internal error)"); 357} 358 359#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED 360/* This pair of functions encapsulates the operation of (a) compressing a 361 * text string, and (b) issuing it later as a series of chunk data writes. 362 * The compression_state structure is shared context for these functions 363 * set up by the caller in order to make the whole mess thread-safe. 364 */ 365 366typedef struct 367{ 368 png_const_bytep input; /* The uncompressed input data */ 369 png_size_t input_len; /* Its length */ 370 int num_output_ptr; /* Number of output pointers used */ 371 int max_output_ptr; /* Size of output_ptr */ 372 png_bytep *output_ptr; /* Array of pointers to output */ 373} compression_state; 374 375/* Compress given text into storage in the png_ptr structure */ 376static int /* PRIVATE */ 377png_text_compress(png_structp png_ptr, 378 png_const_charp text, png_size_t text_len, int compression, 379 compression_state *comp) 380{ 381 int ret; 382 383 comp->num_output_ptr = 0; 384 comp->max_output_ptr = 0; 385 comp->output_ptr = NULL; 386 comp->input = NULL; 387 comp->input_len = text_len; 388 389 /* We may just want to pass the text right through */ 390 if (compression == PNG_TEXT_COMPRESSION_NONE) 391 { 392 comp->input = (png_const_bytep)text; 393 return((int)text_len); 394 } 395 396 if (compression >= PNG_TEXT_COMPRESSION_LAST) 397 { 398 PNG_WARNING_PARAMETERS(p) 399 400 png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, 401 compression); 402 png_formatted_warning(png_ptr, p, "Unknown compression type @1"); 403 } 404 405 /* We can't write the chunk until we find out how much data we have, 406 * which means we need to run the compressor first and save the 407 * output. This shouldn't be a problem, as the vast majority of 408 * comments should be reasonable, but we will set up an array of 409 * malloc'd pointers to be sure. 410 * 411 * If we knew the application was well behaved, we could simplify this 412 * greatly by assuming we can always malloc an output buffer large 413 * enough to hold the compressed text ((1001 * text_len / 1000) + 12) 414 * and malloc this directly. The only time this would be a bad idea is 415 * if we can't malloc more than 64K and we have 64K of random input 416 * data, or if the input string is incredibly large (although this 417 * wouldn't cause a failure, just a slowdown due to swapping). 418 */ 419 png_zlib_claim(png_ptr, PNG_ZLIB_FOR_TEXT); 420 421 /* Set up the compression buffers */ 422 /* TODO: the following cast hides a potential overflow problem. */ 423 png_ptr->zstream.avail_in = (uInt)text_len; 424 425 /* NOTE: assume zlib doesn't overwrite the input */ 426 png_ptr->zstream.next_in = (Bytef *)text; 427 png_ptr->zstream.avail_out = png_ptr->zbuf_size; 428 png_ptr->zstream.next_out = png_ptr->zbuf; 429 430 /* This is the same compression loop as in png_write_row() */ 431 do 432 { 433 /* Compress the data */ 434 ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); 435 436 if (ret != Z_OK) 437 { 438 /* Error */ 439 if (png_ptr->zstream.msg != NULL) 440 png_error(png_ptr, png_ptr->zstream.msg); 441 442 else 443 png_error(png_ptr, "zlib error"); 444 } 445 446 /* Check to see if we need more room */ 447 if (!(png_ptr->zstream.avail_out)) 448 { 449 /* Make sure the output array has room */ 450 if (comp->num_output_ptr >= comp->max_output_ptr) 451 { 452 int old_max; 453 454 old_max = comp->max_output_ptr; 455 comp->max_output_ptr = comp->num_output_ptr + 4; 456 if (comp->output_ptr != NULL) 457 { 458 png_bytepp old_ptr; 459 460 old_ptr = comp->output_ptr; 461 462 comp->output_ptr = (png_bytepp)png_malloc(png_ptr, 463 (png_alloc_size_t) 464 (comp->max_output_ptr * png_sizeof(png_charpp))); 465 466 png_memcpy(comp->output_ptr, old_ptr, old_max 467 * png_sizeof(png_charp)); 468 469 png_free(png_ptr, old_ptr); 470 } 471 else 472 comp->output_ptr = (png_bytepp)png_malloc(png_ptr, 473 (png_alloc_size_t) 474 (comp->max_output_ptr * png_sizeof(png_charp))); 475 } 476 477 /* Save the data */ 478 comp->output_ptr[comp->num_output_ptr] = 479 (png_bytep)png_malloc(png_ptr, 480 (png_alloc_size_t)png_ptr->zbuf_size); 481 482 png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, 483 png_ptr->zbuf_size); 484 485 comp->num_output_ptr++; 486 487 /* and reset the buffer */ 488 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 489 png_ptr->zstream.next_out = png_ptr->zbuf; 490 } 491 /* Continue until we don't have any more to compress */ 492 } while (png_ptr->zstream.avail_in); 493 494 /* Finish the compression */ 495 do 496 { 497 /* Tell zlib we are finished */ 498 ret = deflate(&png_ptr->zstream, Z_FINISH); 499 500 if (ret == Z_OK) 501 { 502 /* Check to see if we need more room */ 503 if (!(png_ptr->zstream.avail_out)) 504 { 505 /* Check to make sure our output array has room */ 506 if (comp->num_output_ptr >= comp->max_output_ptr) 507 { 508 int old_max; 509 510 old_max = comp->max_output_ptr; 511 comp->max_output_ptr = comp->num_output_ptr + 4; 512 if (comp->output_ptr != NULL) 513 { 514 png_bytepp old_ptr; 515 516 old_ptr = comp->output_ptr; 517 518 /* This could be optimized to realloc() */ 519 comp->output_ptr = (png_bytepp)png_malloc(png_ptr, 520 (png_alloc_size_t)(comp->max_output_ptr * 521 png_sizeof(png_charp))); 522 523 png_memcpy(comp->output_ptr, old_ptr, 524 old_max * png_sizeof(png_charp)); 525 526 png_free(png_ptr, old_ptr); 527 } 528 529 else 530 comp->output_ptr = (png_bytepp)png_malloc(png_ptr, 531 (png_alloc_size_t)(comp->max_output_ptr * 532 png_sizeof(png_charp))); 533 } 534 535 /* Save the data */ 536 comp->output_ptr[comp->num_output_ptr] = 537 (png_bytep)png_malloc(png_ptr, 538 (png_alloc_size_t)png_ptr->zbuf_size); 539 540 png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, 541 png_ptr->zbuf_size); 542 543 comp->num_output_ptr++; 544 545 /* and reset the buffer pointers */ 546 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 547 png_ptr->zstream.next_out = png_ptr->zbuf; 548 } 549 } 550 else if (ret != Z_STREAM_END) 551 { 552 /* We got an error */ 553 if (png_ptr->zstream.msg != NULL) 554 png_error(png_ptr, png_ptr->zstream.msg); 555 556 else 557 png_error(png_ptr, "zlib error"); 558 } 559 } while (ret != Z_STREAM_END); 560 561 /* Text length is number of buffers plus last buffer */ 562 text_len = png_ptr->zbuf_size * comp->num_output_ptr; 563 564 if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) 565 text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; 566 567 return((int)text_len); 568} 569 570/* Ship the compressed text out via chunk writes */ 571static void /* PRIVATE */ 572png_write_compressed_data_out(png_structp png_ptr, compression_state *comp, 573 png_size_t data_len) 574{ 575 int i; 576 577 /* Handle the no-compression case */ 578 if (comp->input) 579 { 580 png_write_chunk_data(png_ptr, comp->input, data_len); 581 582 return; 583 } 584 585#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED 586 /* The zbuf_size test is because the code below doesn't work if zbuf_size is 587 * '1'; simply skip it to avoid memory overwrite. 588 */ 589 if (data_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1) 590 { 591 unsigned int z_cmf; /* zlib compression method and flags */ 592 593 /* Optimize the CMF field in the zlib stream. This hack of the zlib 594 * stream is compliant to the stream specification. 595 */ 596 597 if (comp->num_output_ptr) 598 z_cmf = comp->output_ptr[0][0]; 599 else 600 z_cmf = png_ptr->zbuf[0]; 601 602 if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) 603 { 604 unsigned int z_cinfo; 605 unsigned int half_z_window_size; 606 png_size_t uncompressed_text_size = comp->input_len; 607 608 z_cinfo = z_cmf >> 4; 609 half_z_window_size = 1 << (z_cinfo + 7); 610 611 while (uncompressed_text_size <= half_z_window_size && 612 half_z_window_size >= 256) 613 { 614 z_cinfo--; 615 half_z_window_size >>= 1; 616 } 617 618 z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); 619 620 if (comp->num_output_ptr) 621 { 622 623 if (comp->output_ptr[0][0] != z_cmf) 624 { 625 int tmp; 626 627 comp->output_ptr[0][0] = (png_byte)z_cmf; 628 tmp = comp->output_ptr[0][1] & 0xe0; 629 tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; 630 comp->output_ptr[0][1] = (png_byte)tmp; 631 } 632 } 633 else 634 { 635 int tmp; 636 637 png_ptr->zbuf[0] = (png_byte)z_cmf; 638 tmp = png_ptr->zbuf[1] & 0xe0; 639 tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; 640 png_ptr->zbuf[1] = (png_byte)tmp; 641 } 642 } 643 644 else 645 png_error(png_ptr, 646 "Invalid zlib compression method or flags in non-IDAT chunk"); 647 } 648#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ 649 650 /* Write saved output buffers, if any */ 651 for (i = 0; i < comp->num_output_ptr; i++) 652 { 653 png_write_chunk_data(png_ptr, comp->output_ptr[i], 654 (png_size_t)png_ptr->zbuf_size); 655 656 png_free(png_ptr, comp->output_ptr[i]); 657 } 658 659 if (comp->max_output_ptr != 0) 660 png_free(png_ptr, comp->output_ptr); 661 662 /* Write anything left in zbuf */ 663 if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) 664 png_write_chunk_data(png_ptr, png_ptr->zbuf, 665 (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); 666 667 /* Reset zlib for another zTXt/iTXt or image data */ 668 png_zlib_release(png_ptr); 669} 670#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ 671 672/* Write the IHDR chunk, and update the png_struct with the necessary 673 * information. Note that the rest of this code depends upon this 674 * information being correct. 675 */ 676void /* PRIVATE */ 677png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, 678 int bit_depth, int color_type, int compression_type, int filter_type, 679 int interlace_type) 680{ 681 png_byte buf[13]; /* Buffer to store the IHDR info */ 682 683 png_debug(1, "in png_write_IHDR"); 684 685 /* Check that we have valid input data from the application info */ 686 switch (color_type) 687 { 688 case PNG_COLOR_TYPE_GRAY: 689 switch (bit_depth) 690 { 691 case 1: 692 case 2: 693 case 4: 694 case 8: 695#ifdef PNG_WRITE_16BIT_SUPPORTED 696 case 16: 697#endif 698 png_ptr->channels = 1; break; 699 700 default: 701 png_error(png_ptr, 702 "Invalid bit depth for grayscale image"); 703 } 704 break; 705 706 case PNG_COLOR_TYPE_RGB: 707#ifdef PNG_WRITE_16BIT_SUPPORTED 708 if (bit_depth != 8 && bit_depth != 16) 709#else 710 if (bit_depth != 8) 711#endif 712 png_error(png_ptr, "Invalid bit depth for RGB image"); 713 714 png_ptr->channels = 3; 715 break; 716 717 case PNG_COLOR_TYPE_PALETTE: 718 switch (bit_depth) 719 { 720 case 1: 721 case 2: 722 case 4: 723 case 8: 724 png_ptr->channels = 1; 725 break; 726 727 default: 728 png_error(png_ptr, "Invalid bit depth for paletted image"); 729 } 730 break; 731 732 case PNG_COLOR_TYPE_GRAY_ALPHA: 733 if (bit_depth != 8 && bit_depth != 16) 734 png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); 735 736 png_ptr->channels = 2; 737 break; 738 739 case PNG_COLOR_TYPE_RGB_ALPHA: 740#ifdef PNG_WRITE_16BIT_SUPPORTED 741 if (bit_depth != 8 && bit_depth != 16) 742#else 743 if (bit_depth != 8) 744#endif 745 png_error(png_ptr, "Invalid bit depth for RGBA image"); 746 747 png_ptr->channels = 4; 748 break; 749 750 default: 751 png_error(png_ptr, "Invalid image color type specified"); 752 } 753 754 if (compression_type != PNG_COMPRESSION_TYPE_BASE) 755 { 756 png_warning(png_ptr, "Invalid compression type specified"); 757 compression_type = PNG_COMPRESSION_TYPE_BASE; 758 } 759 760 /* Write filter_method 64 (intrapixel differencing) only if 761 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 762 * 2. Libpng did not write a PNG signature (this filter_method is only 763 * used in PNG datastreams that are embedded in MNG datastreams) and 764 * 3. The application called png_permit_mng_features with a mask that 765 * included PNG_FLAG_MNG_FILTER_64 and 766 * 4. The filter_method is 64 and 767 * 5. The color_type is RGB or RGBA 768 */ 769 if ( 770#ifdef PNG_MNG_FEATURES_SUPPORTED 771 !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 772 ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && 773 (color_type == PNG_COLOR_TYPE_RGB || 774 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && 775 (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && 776#endif 777 filter_type != PNG_FILTER_TYPE_BASE) 778 { 779 png_warning(png_ptr, "Invalid filter type specified"); 780 filter_type = PNG_FILTER_TYPE_BASE; 781 } 782 783#ifdef PNG_WRITE_INTERLACING_SUPPORTED 784 if (interlace_type != PNG_INTERLACE_NONE && 785 interlace_type != PNG_INTERLACE_ADAM7) 786 { 787 png_warning(png_ptr, "Invalid interlace type specified"); 788 interlace_type = PNG_INTERLACE_ADAM7; 789 } 790#else 791 interlace_type=PNG_INTERLACE_NONE; 792#endif 793 794 /* Save the relevent information */ 795 png_ptr->bit_depth = (png_byte)bit_depth; 796 png_ptr->color_type = (png_byte)color_type; 797 png_ptr->interlaced = (png_byte)interlace_type; 798#ifdef PNG_MNG_FEATURES_SUPPORTED 799 png_ptr->filter_type = (png_byte)filter_type; 800#endif 801 png_ptr->compression_type = (png_byte)compression_type; 802 png_ptr->width = width; 803 png_ptr->height = height; 804 805 png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); 806 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); 807 /* Set the usr info, so any transformations can modify it */ 808 png_ptr->usr_width = png_ptr->width; 809 png_ptr->usr_bit_depth = png_ptr->bit_depth; 810 png_ptr->usr_channels = png_ptr->channels; 811 812 /* Pack the header information into the buffer */ 813 png_save_uint_32(buf, width); 814 png_save_uint_32(buf + 4, height); 815 buf[8] = (png_byte)bit_depth; 816 buf[9] = (png_byte)color_type; 817 buf[10] = (png_byte)compression_type; 818 buf[11] = (png_byte)filter_type; 819 buf[12] = (png_byte)interlace_type; 820 821 /* Write the chunk */ 822 png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); 823 824 /* Initialize zlib with PNG info */ 825 png_ptr->zstream.zalloc = png_zalloc; 826 png_ptr->zstream.zfree = png_zfree; 827 png_ptr->zstream.opaque = (voidpf)png_ptr; 828 829 if (!(png_ptr->do_filter)) 830 { 831 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || 832 png_ptr->bit_depth < 8) 833 png_ptr->do_filter = PNG_FILTER_NONE; 834 835 else 836 png_ptr->do_filter = PNG_ALL_FILTERS; 837 } 838 839 if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) 840 { 841 if (png_ptr->do_filter != PNG_FILTER_NONE) 842 png_ptr->zlib_strategy = Z_FILTERED; 843 844 else 845 png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; 846 } 847 848 if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) 849 png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; 850 851 if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) 852 png_ptr->zlib_mem_level = 8; 853 854 if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) 855 png_ptr->zlib_window_bits = 15; 856 857 if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) 858 png_ptr->zlib_method = 8; 859 860#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED 861#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED 862 if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_STRATEGY)) 863 png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; 864 865 if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_LEVEL)) 866 png_ptr->zlib_text_level = png_ptr->zlib_level; 867 868 if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL)) 869 png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; 870 871 if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS)) 872 png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; 873 874 if (!(png_ptr->flags & PNG_FLAG_ZTXT_CUSTOM_METHOD)) 875 png_ptr->zlib_text_method = png_ptr->zlib_method; 876#else 877 png_ptr->zlib_text_strategy = Z_DEFAULT_STRATEGY; 878 png_ptr->zlib_text_level = png_ptr->zlib_level; 879 png_ptr->zlib_text_mem_level = png_ptr->zlib_mem_level; 880 png_ptr->zlib_text_window_bits = png_ptr->zlib_window_bits; 881 png_ptr->zlib_text_method = png_ptr->zlib_method; 882#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ 883#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ 884 885 /* Record that the compressor has not yet been initialized. */ 886 png_ptr->zlib_state = PNG_ZLIB_UNINITIALIZED; 887 888 png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ 889} 890 891/* Write the palette. We are careful not to trust png_color to be in the 892 * correct order for PNG, so people can redefine it to any convenient 893 * structure. 894 */ 895void /* PRIVATE */ 896png_write_PLTE(png_structp png_ptr, png_const_colorp palette, 897 png_uint_32 num_pal) 898{ 899 png_uint_32 i; 900 png_const_colorp pal_ptr; 901 png_byte buf[3]; 902 903 png_debug(1, "in png_write_PLTE"); 904 905 if (( 906#ifdef PNG_MNG_FEATURES_SUPPORTED 907 !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && 908#endif 909 num_pal == 0) || num_pal > 256) 910 { 911 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 912 { 913 png_error(png_ptr, "Invalid number of colors in palette"); 914 } 915 916 else 917 { 918 png_warning(png_ptr, "Invalid number of colors in palette"); 919 return; 920 } 921 } 922 923 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 924 { 925 png_warning(png_ptr, 926 "Ignoring request to write a PLTE chunk in grayscale PNG"); 927 928 return; 929 } 930 931 png_ptr->num_palette = (png_uint_16)num_pal; 932 png_debug1(3, "num_palette = %d", png_ptr->num_palette); 933 934 png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); 935#ifdef PNG_POINTER_INDEXING_SUPPORTED 936 937 for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) 938 { 939 buf[0] = pal_ptr->red; 940 buf[1] = pal_ptr->green; 941 buf[2] = pal_ptr->blue; 942 png_write_chunk_data(png_ptr, buf, (png_size_t)3); 943 } 944 945#else 946 /* This is a little slower but some buggy compilers need to do this 947 * instead 948 */ 949 pal_ptr=palette; 950 951 for (i = 0; i < num_pal; i++) 952 { 953 buf[0] = pal_ptr[i].red; 954 buf[1] = pal_ptr[i].green; 955 buf[2] = pal_ptr[i].blue; 956 png_write_chunk_data(png_ptr, buf, (png_size_t)3); 957 } 958 959#endif 960 png_write_chunk_end(png_ptr); 961 png_ptr->mode |= PNG_HAVE_PLTE; 962} 963 964/* Write an IDAT chunk */ 965void /* PRIVATE */ 966png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) 967{ 968 png_debug(1, "in png_write_IDAT"); 969 970#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED 971 if (!(png_ptr->mode & PNG_HAVE_IDAT) && 972 png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) 973 { 974 /* Optimize the CMF field in the zlib stream. This hack of the zlib 975 * stream is compliant to the stream specification. 976 */ 977 unsigned int z_cmf = data[0]; /* zlib compression method and flags */ 978 979 if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) 980 { 981 /* Avoid memory underflows and multiplication overflows. 982 * 983 * The conditions below are practically always satisfied; 984 * however, they still must be checked. 985 */ 986 if (length >= 2 && 987 png_ptr->height < 16384 && png_ptr->width < 16384) 988 { 989 /* Compute the maximum possible length of the datastream */ 990 991 /* Number of pixels, plus for each row a filter byte 992 * and possibly a padding byte, so increase the maximum 993 * size to account for these. 994 */ 995 unsigned int z_cinfo; 996 unsigned int half_z_window_size; 997 png_uint_32 uncompressed_idat_size = png_ptr->height * 998 ((png_ptr->width * 999 png_ptr->channels * png_ptr->bit_depth + 15) >> 3); 1000 1001 /* If it's interlaced, each block of 8 rows is sent as up to 1002 * 14 rows, i.e., 6 additional rows, each with a filter byte 1003 * and possibly a padding byte 1004 */ 1005 if (png_ptr->interlaced) 1006 uncompressed_idat_size += ((png_ptr->height + 7)/8) * 1007 (png_ptr->bit_depth < 8 ? 12 : 6); 1008 1009 z_cinfo = z_cmf >> 4; 1010 half_z_window_size = 1 << (z_cinfo + 7); 1011 1012 while (uncompressed_idat_size <= half_z_window_size && 1013 half_z_window_size >= 256) 1014 { 1015 z_cinfo--; 1016 half_z_window_size >>= 1; 1017 } 1018 1019 z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); 1020 1021 if (data[0] != z_cmf) 1022 { 1023 int tmp; 1024 data[0] = (png_byte)z_cmf; 1025 tmp = data[1] & 0xe0; 1026 tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; 1027 data[1] = (png_byte)tmp; 1028 } 1029 } 1030 } 1031 1032 else 1033 png_error(png_ptr, 1034 "Invalid zlib compression method or flags in IDAT"); 1035 } 1036#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ 1037 1038 png_write_complete_chunk(png_ptr, png_IDAT, data, length); 1039 png_ptr->mode |= PNG_HAVE_IDAT; 1040 1041 /* Prior to 1.5.4 this code was replicated in every caller (except at the 1042 * end, where it isn't technically necessary). Since this function has 1043 * flushed the data we can safely reset the zlib output buffer here. 1044 */ 1045 png_ptr->zstream.next_out = png_ptr->zbuf; 1046 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 1047} 1048 1049/* Write an IEND chunk */ 1050void /* PRIVATE */ 1051png_write_IEND(png_structp png_ptr) 1052{ 1053 png_debug(1, "in png_write_IEND"); 1054 1055 png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); 1056 png_ptr->mode |= PNG_HAVE_IEND; 1057} 1058 1059#ifdef PNG_WRITE_gAMA_SUPPORTED 1060/* Write a gAMA chunk */ 1061void /* PRIVATE */ 1062png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) 1063{ 1064 png_byte buf[4]; 1065 1066 png_debug(1, "in png_write_gAMA"); 1067 1068 /* file_gamma is saved in 1/100,000ths */ 1069 png_save_uint_32(buf, (png_uint_32)file_gamma); 1070 png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); 1071} 1072#endif 1073 1074#ifdef PNG_WRITE_sRGB_SUPPORTED 1075/* Write a sRGB chunk */ 1076void /* PRIVATE */ 1077png_write_sRGB(png_structp png_ptr, int srgb_intent) 1078{ 1079 png_byte buf[1]; 1080 1081 png_debug(1, "in png_write_sRGB"); 1082 1083 if (srgb_intent >= PNG_sRGB_INTENT_LAST) 1084 png_warning(png_ptr, 1085 "Invalid sRGB rendering intent specified"); 1086 1087 buf[0]=(png_byte)srgb_intent; 1088 png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); 1089} 1090#endif 1091 1092#ifdef PNG_WRITE_iCCP_SUPPORTED 1093/* Write an iCCP chunk */ 1094void /* PRIVATE */ 1095png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, 1096 png_const_charp profile, int profile_len) 1097{ 1098 png_size_t name_len; 1099 png_charp new_name; 1100 compression_state comp; 1101 int embedded_profile_len = 0; 1102 1103 png_debug(1, "in png_write_iCCP"); 1104 1105 comp.num_output_ptr = 0; 1106 comp.max_output_ptr = 0; 1107 comp.output_ptr = NULL; 1108 comp.input = NULL; 1109 comp.input_len = 0; 1110 1111 if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) 1112 return; 1113 1114 if (compression_type != PNG_COMPRESSION_TYPE_BASE) 1115 png_warning(png_ptr, "Unknown compression type in iCCP chunk"); 1116 1117 if (profile == NULL) 1118 profile_len = 0; 1119 1120 if (profile_len > 3) 1121 embedded_profile_len = 1122 ((*( (png_const_bytep)profile ))<<24) | 1123 ((*( (png_const_bytep)profile + 1))<<16) | 1124 ((*( (png_const_bytep)profile + 2))<< 8) | 1125 ((*( (png_const_bytep)profile + 3)) ); 1126 1127 if (embedded_profile_len < 0) 1128 { 1129 png_warning(png_ptr, 1130 "Embedded profile length in iCCP chunk is negative"); 1131 1132 png_free(png_ptr, new_name); 1133 return; 1134 } 1135 1136 if (profile_len < embedded_profile_len) 1137 { 1138 png_warning(png_ptr, 1139 "Embedded profile length too large in iCCP chunk"); 1140 1141 png_free(png_ptr, new_name); 1142 return; 1143 } 1144 1145 if (profile_len > embedded_profile_len) 1146 { 1147 png_warning(png_ptr, 1148 "Truncating profile to actual length in iCCP chunk"); 1149 1150 profile_len = embedded_profile_len; 1151 } 1152 1153 if (profile_len) 1154 profile_len = png_text_compress(png_ptr, profile, 1155 (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); 1156 1157 /* Make sure we include the NULL after the name and the compression type */ 1158 png_write_chunk_header(png_ptr, png_iCCP, 1159 (png_uint_32)(name_len + profile_len + 2)); 1160 1161 new_name[name_len + 1] = 0x00; 1162 1163 png_write_chunk_data(png_ptr, (png_bytep)new_name, 1164 (png_size_t)(name_len + 2)); 1165 1166 if (profile_len) 1167 { 1168 png_write_compressed_data_out(png_ptr, &comp, profile_len); 1169 } 1170 1171 png_write_chunk_end(png_ptr); 1172 png_free(png_ptr, new_name); 1173} 1174#endif 1175 1176#ifdef PNG_WRITE_sPLT_SUPPORTED 1177/* Write a sPLT chunk */ 1178void /* PRIVATE */ 1179png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) 1180{ 1181 png_size_t name_len; 1182 png_charp new_name; 1183 png_byte entrybuf[10]; 1184 png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); 1185 png_size_t palette_size = entry_size * spalette->nentries; 1186 png_sPLT_entryp ep; 1187#ifndef PNG_POINTER_INDEXING_SUPPORTED 1188 int i; 1189#endif 1190 1191 png_debug(1, "in png_write_sPLT"); 1192 1193 if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) 1194 return; 1195 1196 /* Make sure we include the NULL after the name */ 1197 png_write_chunk_header(png_ptr, png_sPLT, 1198 (png_uint_32)(name_len + 2 + palette_size)); 1199 1200 png_write_chunk_data(png_ptr, (png_bytep)new_name, 1201 (png_size_t)(name_len + 1)); 1202 1203 png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); 1204 1205 /* Loop through each palette entry, writing appropriately */ 1206#ifdef PNG_POINTER_INDEXING_SUPPORTED 1207 for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++) 1208 { 1209 if (spalette->depth == 8) 1210 { 1211 entrybuf[0] = (png_byte)ep->red; 1212 entrybuf[1] = (png_byte)ep->green; 1213 entrybuf[2] = (png_byte)ep->blue; 1214 entrybuf[3] = (png_byte)ep->alpha; 1215 png_save_uint_16(entrybuf + 4, ep->frequency); 1216 } 1217 1218 else 1219 { 1220 png_save_uint_16(entrybuf + 0, ep->red); 1221 png_save_uint_16(entrybuf + 2, ep->green); 1222 png_save_uint_16(entrybuf + 4, ep->blue); 1223 png_save_uint_16(entrybuf + 6, ep->alpha); 1224 png_save_uint_16(entrybuf + 8, ep->frequency); 1225 } 1226 1227 png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); 1228 } 1229#else 1230 ep=spalette->entries; 1231 for (i = 0; i>spalette->nentries; i++) 1232 { 1233 if (spalette->depth == 8) 1234 { 1235 entrybuf[0] = (png_byte)ep[i].red; 1236 entrybuf[1] = (png_byte)ep[i].green; 1237 entrybuf[2] = (png_byte)ep[i].blue; 1238 entrybuf[3] = (png_byte)ep[i].alpha; 1239 png_save_uint_16(entrybuf + 4, ep[i].frequency); 1240 } 1241 1242 else 1243 { 1244 png_save_uint_16(entrybuf + 0, ep[i].red); 1245 png_save_uint_16(entrybuf + 2, ep[i].green); 1246 png_save_uint_16(entrybuf + 4, ep[i].blue); 1247 png_save_uint_16(entrybuf + 6, ep[i].alpha); 1248 png_save_uint_16(entrybuf + 8, ep[i].frequency); 1249 } 1250 1251 png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); 1252 } 1253#endif 1254 1255 png_write_chunk_end(png_ptr); 1256 png_free(png_ptr, new_name); 1257} 1258#endif 1259 1260#ifdef PNG_WRITE_sBIT_SUPPORTED 1261/* Write the sBIT chunk */ 1262void /* PRIVATE */ 1263png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) 1264{ 1265 png_byte buf[4]; 1266 png_size_t size; 1267 1268 png_debug(1, "in png_write_sBIT"); 1269 1270 /* Make sure we don't depend upon the order of PNG_COLOR_8 */ 1271 if (color_type & PNG_COLOR_MASK_COLOR) 1272 { 1273 png_byte maxbits; 1274 1275 maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : 1276 png_ptr->usr_bit_depth); 1277 1278 if (sbit->red == 0 || sbit->red > maxbits || 1279 sbit->green == 0 || sbit->green > maxbits || 1280 sbit->blue == 0 || sbit->blue > maxbits) 1281 { 1282 png_warning(png_ptr, "Invalid sBIT depth specified"); 1283 return; 1284 } 1285 1286 buf[0] = sbit->red; 1287 buf[1] = sbit->green; 1288 buf[2] = sbit->blue; 1289 size = 3; 1290 } 1291 1292 else 1293 { 1294 if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) 1295 { 1296 png_warning(png_ptr, "Invalid sBIT depth specified"); 1297 return; 1298 } 1299 1300 buf[0] = sbit->gray; 1301 size = 1; 1302 } 1303 1304 if (color_type & PNG_COLOR_MASK_ALPHA) 1305 { 1306 if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) 1307 { 1308 png_warning(png_ptr, "Invalid sBIT depth specified"); 1309 return; 1310 } 1311 1312 buf[size++] = sbit->alpha; 1313 } 1314 1315 png_write_complete_chunk(png_ptr, png_sBIT, buf, size); 1316} 1317#endif 1318 1319#ifdef PNG_WRITE_cHRM_SUPPORTED 1320/* Write the cHRM chunk */ 1321void /* PRIVATE */ 1322png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, 1323 png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, 1324 png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, 1325 png_fixed_point blue_y) 1326{ 1327 png_byte buf[32]; 1328 1329 png_debug(1, "in png_write_cHRM"); 1330 1331 /* Each value is saved in 1/100,000ths */ 1332#ifdef PNG_CHECK_cHRM_SUPPORTED 1333 if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, 1334 green_x, green_y, blue_x, blue_y)) 1335#endif 1336 { 1337 png_save_uint_32(buf, (png_uint_32)white_x); 1338 png_save_uint_32(buf + 4, (png_uint_32)white_y); 1339 1340 png_save_uint_32(buf + 8, (png_uint_32)red_x); 1341 png_save_uint_32(buf + 12, (png_uint_32)red_y); 1342 1343 png_save_uint_32(buf + 16, (png_uint_32)green_x); 1344 png_save_uint_32(buf + 20, (png_uint_32)green_y); 1345 1346 png_save_uint_32(buf + 24, (png_uint_32)blue_x); 1347 png_save_uint_32(buf + 28, (png_uint_32)blue_y); 1348 1349 png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); 1350 } 1351} 1352#endif 1353 1354#ifdef PNG_WRITE_tRNS_SUPPORTED 1355/* Write the tRNS chunk */ 1356void /* PRIVATE */ 1357png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, 1358 png_const_color_16p tran, int num_trans, int color_type) 1359{ 1360 png_byte buf[6]; 1361 1362 png_debug(1, "in png_write_tRNS"); 1363 1364 if (color_type == PNG_COLOR_TYPE_PALETTE) 1365 { 1366 if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) 1367 { 1368 png_warning(png_ptr, "Invalid number of transparent colors specified"); 1369 return; 1370 } 1371 1372 /* Write the chunk out as it is */ 1373 png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); 1374 } 1375 1376 else if (color_type == PNG_COLOR_TYPE_GRAY) 1377 { 1378 /* One 16 bit value */ 1379 if (tran->gray >= (1 << png_ptr->bit_depth)) 1380 { 1381 png_warning(png_ptr, 1382 "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); 1383 1384 return; 1385 } 1386 1387 png_save_uint_16(buf, tran->gray); 1388 png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); 1389 } 1390 1391 else if (color_type == PNG_COLOR_TYPE_RGB) 1392 { 1393 /* Three 16 bit values */ 1394 png_save_uint_16(buf, tran->red); 1395 png_save_uint_16(buf + 2, tran->green); 1396 png_save_uint_16(buf + 4, tran->blue); 1397#ifdef PNG_WRITE_16BIT_SUPPORTED 1398 if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) 1399#else 1400 if (buf[0] | buf[2] | buf[4]) 1401#endif 1402 { 1403 png_warning(png_ptr, 1404 "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); 1405 return; 1406 } 1407 1408 png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); 1409 } 1410 1411 else 1412 { 1413 png_warning(png_ptr, "Can't write tRNS with an alpha channel"); 1414 } 1415} 1416#endif 1417 1418#ifdef PNG_WRITE_bKGD_SUPPORTED 1419/* Write the background chunk */ 1420void /* PRIVATE */ 1421png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) 1422{ 1423 png_byte buf[6]; 1424 1425 png_debug(1, "in png_write_bKGD"); 1426 1427 if (color_type == PNG_COLOR_TYPE_PALETTE) 1428 { 1429 if ( 1430#ifdef PNG_MNG_FEATURES_SUPPORTED 1431 (png_ptr->num_palette || 1432 (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && 1433#endif 1434 back->index >= png_ptr->num_palette) 1435 { 1436 png_warning(png_ptr, "Invalid background palette index"); 1437 return; 1438 } 1439 1440 buf[0] = back->index; 1441 png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); 1442 } 1443 1444 else if (color_type & PNG_COLOR_MASK_COLOR) 1445 { 1446 png_save_uint_16(buf, back->red); 1447 png_save_uint_16(buf + 2, back->green); 1448 png_save_uint_16(buf + 4, back->blue); 1449#ifdef PNG_WRITE_16BIT_SUPPORTED 1450 if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) 1451#else 1452 if (buf[0] | buf[2] | buf[4]) 1453#endif 1454 { 1455 png_warning(png_ptr, 1456 "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); 1457 1458 return; 1459 } 1460 1461 png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); 1462 } 1463 1464 else 1465 { 1466 if (back->gray >= (1 << png_ptr->bit_depth)) 1467 { 1468 png_warning(png_ptr, 1469 "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); 1470 1471 return; 1472 } 1473 1474 png_save_uint_16(buf, back->gray); 1475 png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); 1476 } 1477} 1478#endif 1479 1480#ifdef PNG_WRITE_hIST_SUPPORTED 1481/* Write the histogram */ 1482void /* PRIVATE */ 1483png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) 1484{ 1485 int i; 1486 png_byte buf[3]; 1487 1488 png_debug(1, "in png_write_hIST"); 1489 1490 if (num_hist > (int)png_ptr->num_palette) 1491 { 1492 png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, 1493 png_ptr->num_palette); 1494 1495 png_warning(png_ptr, "Invalid number of histogram entries specified"); 1496 return; 1497 } 1498 1499 png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); 1500 1501 for (i = 0; i < num_hist; i++) 1502 { 1503 png_save_uint_16(buf, hist[i]); 1504 png_write_chunk_data(png_ptr, buf, (png_size_t)2); 1505 } 1506 1507 png_write_chunk_end(png_ptr); 1508} 1509#endif 1510 1511#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ 1512 defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) 1513/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, 1514 * and if invalid, correct the keyword rather than discarding the entire 1515 * chunk. The PNG 1.0 specification requires keywords 1-79 characters in 1516 * length, forbids leading or trailing whitespace, multiple internal spaces, 1517 * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. 1518 * 1519 * The new_key is allocated to hold the corrected keyword and must be freed 1520 * by the calling routine. This avoids problems with trying to write to 1521 * static keywords without having to have duplicate copies of the strings. 1522 */ 1523png_size_t /* PRIVATE */ 1524png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) 1525{ 1526 png_size_t key_len; 1527 png_const_charp ikp; 1528 png_charp kp, dp; 1529 int kflag; 1530 int kwarn=0; 1531 1532 png_debug(1, "in png_check_keyword"); 1533 1534 *new_key = NULL; 1535 1536 if (key == NULL || (key_len = png_strlen(key)) == 0) 1537 { 1538 png_warning(png_ptr, "zero length keyword"); 1539 return ((png_size_t)0); 1540 } 1541 1542 png_debug1(2, "Keyword to be checked is '%s'", key); 1543 1544 *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); 1545 1546 if (*new_key == NULL) 1547 { 1548 png_warning(png_ptr, "Out of memory while procesing keyword"); 1549 return ((png_size_t)0); 1550 } 1551 1552 /* Replace non-printing characters with a blank and print a warning */ 1553 for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) 1554 { 1555 if ((png_byte)*ikp < 0x20 || 1556 ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) 1557 { 1558 PNG_WARNING_PARAMETERS(p) 1559 1560 png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_02x, 1561 (png_byte)*ikp); 1562 png_formatted_warning(png_ptr, p, "invalid keyword character 0x@1"); 1563 *dp = ' '; 1564 } 1565 1566 else 1567 { 1568 *dp = *ikp; 1569 } 1570 } 1571 *dp = '\0'; 1572 1573 /* Remove any trailing white space. */ 1574 kp = *new_key + key_len - 1; 1575 if (*kp == ' ') 1576 { 1577 png_warning(png_ptr, "trailing spaces removed from keyword"); 1578 1579 while (*kp == ' ') 1580 { 1581 *(kp--) = '\0'; 1582 key_len--; 1583 } 1584 } 1585 1586 /* Remove any leading white space. */ 1587 kp = *new_key; 1588 if (*kp == ' ') 1589 { 1590 png_warning(png_ptr, "leading spaces removed from keyword"); 1591 1592 while (*kp == ' ') 1593 { 1594 kp++; 1595 key_len--; 1596 } 1597 } 1598 1599 png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); 1600 1601 /* Remove multiple internal spaces. */ 1602 for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) 1603 { 1604 if (*kp == ' ' && kflag == 0) 1605 { 1606 *(dp++) = *kp; 1607 kflag = 1; 1608 } 1609 1610 else if (*kp == ' ') 1611 { 1612 key_len--; 1613 kwarn = 1; 1614 } 1615 1616 else 1617 { 1618 *(dp++) = *kp; 1619 kflag = 0; 1620 } 1621 } 1622 *dp = '\0'; 1623 if (kwarn) 1624 png_warning(png_ptr, "extra interior spaces removed from keyword"); 1625 1626 if (key_len == 0) 1627 { 1628 png_free(png_ptr, *new_key); 1629 png_warning(png_ptr, "Zero length keyword"); 1630 } 1631 1632 if (key_len > 79) 1633 { 1634 png_warning(png_ptr, "keyword length must be 1 - 79 characters"); 1635 (*new_key)[79] = '\0'; 1636 key_len = 79; 1637 } 1638 1639 return (key_len); 1640} 1641#endif 1642 1643#ifdef PNG_WRITE_tEXt_SUPPORTED 1644/* Write a tEXt chunk */ 1645void /* PRIVATE */ 1646png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, 1647 png_size_t text_len) 1648{ 1649 png_size_t key_len; 1650 png_charp new_key; 1651 1652 png_debug(1, "in png_write_tEXt"); 1653 1654 if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) 1655 return; 1656 1657 if (text == NULL || *text == '\0') 1658 text_len = 0; 1659 1660 else 1661 text_len = png_strlen(text); 1662 1663 /* Make sure we include the 0 after the key */ 1664 png_write_chunk_header(png_ptr, png_tEXt, 1665 (png_uint_32)(key_len + text_len + 1)); 1666 /* 1667 * We leave it to the application to meet PNG-1.0 requirements on the 1668 * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of 1669 * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. 1670 * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. 1671 */ 1672 png_write_chunk_data(png_ptr, (png_bytep)new_key, 1673 (png_size_t)(key_len + 1)); 1674 1675 if (text_len) 1676 png_write_chunk_data(png_ptr, (png_const_bytep)text, 1677 (png_size_t)text_len); 1678 1679 png_write_chunk_end(png_ptr); 1680 png_free(png_ptr, new_key); 1681} 1682#endif 1683 1684#ifdef PNG_WRITE_zTXt_SUPPORTED 1685/* Write a compressed text chunk */ 1686void /* PRIVATE */ 1687png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, 1688 png_size_t text_len, int compression) 1689{ 1690 png_size_t key_len; 1691 png_byte buf; 1692 png_charp new_key; 1693 compression_state comp; 1694 1695 png_debug(1, "in png_write_zTXt"); 1696 1697 comp.num_output_ptr = 0; 1698 comp.max_output_ptr = 0; 1699 comp.output_ptr = NULL; 1700 comp.input = NULL; 1701 comp.input_len = 0; 1702 1703 if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) 1704 { 1705 png_free(png_ptr, new_key); 1706 return; 1707 } 1708 1709 if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) 1710 { 1711 png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); 1712 png_free(png_ptr, new_key); 1713 return; 1714 } 1715 1716 text_len = png_strlen(text); 1717 1718 /* Compute the compressed data; do it now for the length */ 1719 text_len = png_text_compress(png_ptr, text, text_len, compression, 1720 &comp); 1721 1722 /* Write start of chunk */ 1723 png_write_chunk_header(png_ptr, png_zTXt, 1724 (png_uint_32)(key_len+text_len + 2)); 1725 1726 /* Write key */ 1727 png_write_chunk_data(png_ptr, (png_bytep)new_key, 1728 (png_size_t)(key_len + 1)); 1729 1730 png_free(png_ptr, new_key); 1731 1732 buf = (png_byte)compression; 1733 1734 /* Write compression */ 1735 png_write_chunk_data(png_ptr, &buf, (png_size_t)1); 1736 1737 /* Write the compressed data */ 1738 png_write_compressed_data_out(png_ptr, &comp, text_len); 1739 1740 /* Close the chunk */ 1741 png_write_chunk_end(png_ptr); 1742} 1743#endif 1744 1745#ifdef PNG_WRITE_iTXt_SUPPORTED 1746/* Write an iTXt chunk */ 1747void /* PRIVATE */ 1748png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, 1749 png_const_charp lang, png_const_charp lang_key, png_const_charp text) 1750{ 1751 png_size_t lang_len, key_len, lang_key_len, text_len; 1752 png_charp new_lang; 1753 png_charp new_key = NULL; 1754 png_byte cbuf[2]; 1755 compression_state comp; 1756 1757 png_debug(1, "in png_write_iTXt"); 1758 1759 comp.num_output_ptr = 0; 1760 comp.max_output_ptr = 0; 1761 comp.output_ptr = NULL; 1762 comp.input = NULL; 1763 1764 if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) 1765 return; 1766 1767 if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) 1768 { 1769 png_warning(png_ptr, "Empty language field in iTXt chunk"); 1770 new_lang = NULL; 1771 lang_len = 0; 1772 } 1773 1774 if (lang_key == NULL) 1775 lang_key_len = 0; 1776 1777 else 1778 lang_key_len = png_strlen(lang_key); 1779 1780 if (text == NULL) 1781 text_len = 0; 1782 1783 else 1784 text_len = png_strlen(text); 1785 1786 /* Compute the compressed data; do it now for the length */ 1787 text_len = png_text_compress(png_ptr, text, text_len, compression - 2, 1788 &comp); 1789 1790 1791 /* Make sure we include the compression flag, the compression byte, 1792 * and the NULs after the key, lang, and lang_key parts 1793 */ 1794 1795 png_write_chunk_header(png_ptr, png_iTXt, (png_uint_32)( 1796 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ 1797 + key_len 1798 + lang_len 1799 + lang_key_len 1800 + text_len)); 1801 1802 /* We leave it to the application to meet PNG-1.0 requirements on the 1803 * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of 1804 * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. 1805 * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. 1806 */ 1807 png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); 1808 1809 /* Set the compression flag */ 1810 if (compression == PNG_ITXT_COMPRESSION_NONE || 1811 compression == PNG_TEXT_COMPRESSION_NONE) 1812 cbuf[0] = 0; 1813 1814 else /* compression == PNG_ITXT_COMPRESSION_zTXt */ 1815 cbuf[0] = 1; 1816 1817 /* Set the compression method */ 1818 cbuf[1] = 0; 1819 1820 png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); 1821 1822 cbuf[0] = 0; 1823 png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), 1824 (png_size_t)(lang_len + 1)); 1825 1826 png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), 1827 (png_size_t)(lang_key_len + 1)); 1828 1829 png_write_compressed_data_out(png_ptr, &comp, text_len); 1830 1831 png_write_chunk_end(png_ptr); 1832 1833 png_free(png_ptr, new_key); 1834 png_free(png_ptr, new_lang); 1835} 1836#endif 1837 1838#ifdef PNG_WRITE_oFFs_SUPPORTED 1839/* Write the oFFs chunk */ 1840void /* PRIVATE */ 1841png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, 1842 int unit_type) 1843{ 1844 png_byte buf[9]; 1845 1846 png_debug(1, "in png_write_oFFs"); 1847 1848 if (unit_type >= PNG_OFFSET_LAST) 1849 png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); 1850 1851 png_save_int_32(buf, x_offset); 1852 png_save_int_32(buf + 4, y_offset); 1853 buf[8] = (png_byte)unit_type; 1854 1855 png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); 1856} 1857#endif 1858#ifdef PNG_WRITE_pCAL_SUPPORTED 1859/* Write the pCAL chunk (described in the PNG extensions document) */ 1860void /* PRIVATE */ 1861png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, 1862 png_int_32 X1, int type, int nparams, png_const_charp units, 1863 png_charpp params) 1864{ 1865 png_size_t purpose_len, units_len, total_len; 1866 png_size_tp params_len; 1867 png_byte buf[10]; 1868 png_charp new_purpose; 1869 int i; 1870 1871 png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); 1872 1873 if (type >= PNG_EQUATION_LAST) 1874 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 1875 1876 purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; 1877 png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); 1878 units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); 1879 png_debug1(3, "pCAL units length = %d", (int)units_len); 1880 total_len = purpose_len + units_len + 10; 1881 1882 params_len = (png_size_tp)png_malloc(png_ptr, 1883 (png_alloc_size_t)(nparams * png_sizeof(png_size_t))); 1884 1885 /* Find the length of each parameter, making sure we don't count the 1886 * null terminator for the last parameter. 1887 */ 1888 for (i = 0; i < nparams; i++) 1889 { 1890 params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); 1891 png_debug2(3, "pCAL parameter %d length = %lu", i, 1892 (unsigned long)params_len[i]); 1893 total_len += params_len[i]; 1894 } 1895 1896 png_debug1(3, "pCAL total length = %d", (int)total_len); 1897 png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); 1898 png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len); 1899 png_save_int_32(buf, X0); 1900 png_save_int_32(buf + 4, X1); 1901 buf[8] = (png_byte)type; 1902 buf[9] = (png_byte)nparams; 1903 png_write_chunk_data(png_ptr, buf, (png_size_t)10); 1904 png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); 1905 1906 png_free(png_ptr, new_purpose); 1907 1908 for (i = 0; i < nparams; i++) 1909 { 1910 png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); 1911 } 1912 1913 png_free(png_ptr, params_len); 1914 png_write_chunk_end(png_ptr); 1915} 1916#endif 1917 1918#ifdef PNG_WRITE_sCAL_SUPPORTED 1919/* Write the sCAL chunk */ 1920void /* PRIVATE */ 1921png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, 1922 png_const_charp height) 1923{ 1924 png_byte buf[64]; 1925 png_size_t wlen, hlen, total_len; 1926 1927 png_debug(1, "in png_write_sCAL_s"); 1928 1929 wlen = png_strlen(width); 1930 hlen = png_strlen(height); 1931 total_len = wlen + hlen + 2; 1932 1933 if (total_len > 64) 1934 { 1935 png_warning(png_ptr, "Can't write sCAL (buffer too small)"); 1936 return; 1937 } 1938 1939 buf[0] = (png_byte)unit; 1940 png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ 1941 png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ 1942 1943 png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); 1944 png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); 1945} 1946#endif 1947 1948#ifdef PNG_WRITE_pHYs_SUPPORTED 1949/* Write the pHYs chunk */ 1950void /* PRIVATE */ 1951png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, 1952 png_uint_32 y_pixels_per_unit, 1953 int unit_type) 1954{ 1955 png_byte buf[9]; 1956 1957 png_debug(1, "in png_write_pHYs"); 1958 1959 if (unit_type >= PNG_RESOLUTION_LAST) 1960 png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); 1961 1962 png_save_uint_32(buf, x_pixels_per_unit); 1963 png_save_uint_32(buf + 4, y_pixels_per_unit); 1964 buf[8] = (png_byte)unit_type; 1965 1966 png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); 1967} 1968#endif 1969 1970#ifdef PNG_WRITE_tIME_SUPPORTED 1971/* Write the tIME chunk. Use either png_convert_from_struct_tm() 1972 * or png_convert_from_time_t(), or fill in the structure yourself. 1973 */ 1974void /* PRIVATE */ 1975png_write_tIME(png_structp png_ptr, png_const_timep mod_time) 1976{ 1977 png_byte buf[7]; 1978 1979 png_debug(1, "in png_write_tIME"); 1980 1981 if (mod_time->month > 12 || mod_time->month < 1 || 1982 mod_time->day > 31 || mod_time->day < 1 || 1983 mod_time->hour > 23 || mod_time->second > 60) 1984 { 1985 png_warning(png_ptr, "Invalid time specified for tIME chunk"); 1986 return; 1987 } 1988 1989 png_save_uint_16(buf, mod_time->year); 1990 buf[2] = mod_time->month; 1991 buf[3] = mod_time->day; 1992 buf[4] = mod_time->hour; 1993 buf[5] = mod_time->minute; 1994 buf[6] = mod_time->second; 1995 1996 png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); 1997} 1998#endif 1999 2000/* Initializes the row writing capability of libpng */ 2001void /* PRIVATE */ 2002png_write_start_row(png_structp png_ptr) 2003{ 2004#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2005 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2006 2007 /* Start of interlace block */ 2008 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 2009 2010 /* Offset to next interlace block */ 2011 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2012 2013 /* Start of interlace block in the y direction */ 2014 static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 2015 2016 /* Offset to next interlace block in the y direction */ 2017 static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 2018#endif 2019 2020 png_alloc_size_t buf_size; 2021 int usr_pixel_depth; 2022 2023 png_debug(1, "in png_write_start_row"); 2024 2025 usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; 2026 buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; 2027 2028 /* 1.5.6: added to allow checking in the row write code. */ 2029 png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; 2030 png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; 2031 2032 /* Set up row buffer */ 2033 png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size); 2034 2035 png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; 2036 2037#ifdef PNG_WRITE_FILTER_SUPPORTED 2038 /* Set up filtering buffer, if using this filter */ 2039 if (png_ptr->do_filter & PNG_FILTER_SUB) 2040 { 2041 png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); 2042 2043 png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; 2044 } 2045 2046 /* We only need to keep the previous row if we are using one of these. */ 2047 if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) 2048 { 2049 /* Set up previous row buffer */ 2050 png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size); 2051 2052 if (png_ptr->do_filter & PNG_FILTER_UP) 2053 { 2054 png_ptr->up_row = (png_bytep)png_malloc(png_ptr, 2055 png_ptr->rowbytes + 1); 2056 2057 png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; 2058 } 2059 2060 if (png_ptr->do_filter & PNG_FILTER_AVG) 2061 { 2062 png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, 2063 png_ptr->rowbytes + 1); 2064 2065 png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; 2066 } 2067 2068 if (png_ptr->do_filter & PNG_FILTER_PAETH) 2069 { 2070 png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, 2071 png_ptr->rowbytes + 1); 2072 2073 png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; 2074 } 2075 } 2076#endif /* PNG_WRITE_FILTER_SUPPORTED */ 2077 2078#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2079 /* If interlaced, we need to set up width and height of pass */ 2080 if (png_ptr->interlaced) 2081 { 2082 if (!(png_ptr->transformations & PNG_INTERLACE)) 2083 { 2084 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 2085 png_pass_ystart[0]) / png_pass_yinc[0]; 2086 2087 png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - 2088 png_pass_start[0]) / png_pass_inc[0]; 2089 } 2090 2091 else 2092 { 2093 png_ptr->num_rows = png_ptr->height; 2094 png_ptr->usr_width = png_ptr->width; 2095 } 2096 } 2097 2098 else 2099#endif 2100 { 2101 png_ptr->num_rows = png_ptr->height; 2102 png_ptr->usr_width = png_ptr->width; 2103 } 2104 2105 png_zlib_claim(png_ptr, PNG_ZLIB_FOR_IDAT); 2106 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 2107 png_ptr->zstream.next_out = png_ptr->zbuf; 2108} 2109 2110/* Internal use only. Called when finished processing a row of data. */ 2111void /* PRIVATE */ 2112png_write_finish_row(png_structp png_ptr) 2113{ 2114#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2115 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2116 2117 /* Start of interlace block */ 2118 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 2119 2120 /* Offset to next interlace block */ 2121 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2122 2123 /* Start of interlace block in the y direction */ 2124 static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 2125 2126 /* Offset to next interlace block in the y direction */ 2127 static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 2128#endif 2129 2130 int ret; 2131 2132 png_debug(1, "in png_write_finish_row"); 2133 2134 /* Next row */ 2135 png_ptr->row_number++; 2136 2137 /* See if we are done */ 2138 if (png_ptr->row_number < png_ptr->num_rows) 2139 return; 2140 2141#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2142 /* If interlaced, go to next pass */ 2143 if (png_ptr->interlaced) 2144 { 2145 png_ptr->row_number = 0; 2146 if (png_ptr->transformations & PNG_INTERLACE) 2147 { 2148 png_ptr->pass++; 2149 } 2150 2151 else 2152 { 2153 /* Loop until we find a non-zero width or height pass */ 2154 do 2155 { 2156 png_ptr->pass++; 2157 2158 if (png_ptr->pass >= 7) 2159 break; 2160 2161 png_ptr->usr_width = (png_ptr->width + 2162 png_pass_inc[png_ptr->pass] - 1 - 2163 png_pass_start[png_ptr->pass]) / 2164 png_pass_inc[png_ptr->pass]; 2165 2166 png_ptr->num_rows = (png_ptr->height + 2167 png_pass_yinc[png_ptr->pass] - 1 - 2168 png_pass_ystart[png_ptr->pass]) / 2169 png_pass_yinc[png_ptr->pass]; 2170 2171 if (png_ptr->transformations & PNG_INTERLACE) 2172 break; 2173 2174 } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); 2175 2176 } 2177 2178 /* Reset the row above the image for the next pass */ 2179 if (png_ptr->pass < 7) 2180 { 2181 if (png_ptr->prev_row != NULL) 2182 png_memset(png_ptr->prev_row, 0, 2183 (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* 2184 png_ptr->usr_bit_depth, png_ptr->width)) + 1); 2185 2186 return; 2187 } 2188 } 2189#endif 2190 2191 /* If we get here, we've just written the last row, so we need 2192 to flush the compressor */ 2193 do 2194 { 2195 /* Tell the compressor we are done */ 2196 ret = deflate(&png_ptr->zstream, Z_FINISH); 2197 2198 /* Check for an error */ 2199 if (ret == Z_OK) 2200 { 2201 /* Check to see if we need more room */ 2202 if (!(png_ptr->zstream.avail_out)) 2203 { 2204 png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 2205 png_ptr->zstream.next_out = png_ptr->zbuf; 2206 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 2207 } 2208 } 2209 2210 else if (ret != Z_STREAM_END) 2211 { 2212 if (png_ptr->zstream.msg != NULL) 2213 png_error(png_ptr, png_ptr->zstream.msg); 2214 2215 else 2216 png_error(png_ptr, "zlib error"); 2217 } 2218 } while (ret != Z_STREAM_END); 2219 2220 /* Write any extra space */ 2221 if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) 2222 { 2223 png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - 2224 png_ptr->zstream.avail_out); 2225 } 2226 2227 png_zlib_release(png_ptr); 2228 png_ptr->zstream.data_type = Z_BINARY; 2229} 2230 2231#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2232/* Pick out the correct pixels for the interlace pass. 2233 * The basic idea here is to go through the row with a source 2234 * pointer and a destination pointer (sp and dp), and copy the 2235 * correct pixels for the pass. As the row gets compacted, 2236 * sp will always be >= dp, so we should never overwrite anything. 2237 * See the default: case for the easiest code to understand. 2238 */ 2239void /* PRIVATE */ 2240png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) 2241{ 2242 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2243 2244 /* Start of interlace block */ 2245 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 2246 2247 /* Offset to next interlace block */ 2248 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2249 2250 png_debug(1, "in png_do_write_interlace"); 2251 2252 /* We don't have to do anything on the last pass (6) */ 2253 if (pass < 6) 2254 { 2255 /* Each pixel depth is handled separately */ 2256 switch (row_info->pixel_depth) 2257 { 2258 case 1: 2259 { 2260 png_bytep sp; 2261 png_bytep dp; 2262 int shift; 2263 int d; 2264 int value; 2265 png_uint_32 i; 2266 png_uint_32 row_width = row_info->width; 2267 2268 dp = row; 2269 d = 0; 2270 shift = 7; 2271 2272 for (i = png_pass_start[pass]; i < row_width; 2273 i += png_pass_inc[pass]) 2274 { 2275 sp = row + (png_size_t)(i >> 3); 2276 value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; 2277 d |= (value << shift); 2278 2279 if (shift == 0) 2280 { 2281 shift = 7; 2282 *dp++ = (png_byte)d; 2283 d = 0; 2284 } 2285 2286 else 2287 shift--; 2288 2289 } 2290 if (shift != 7) 2291 *dp = (png_byte)d; 2292 2293 break; 2294 } 2295 2296 case 2: 2297 { 2298 png_bytep sp; 2299 png_bytep dp; 2300 int shift; 2301 int d; 2302 int value; 2303 png_uint_32 i; 2304 png_uint_32 row_width = row_info->width; 2305 2306 dp = row; 2307 shift = 6; 2308 d = 0; 2309 2310 for (i = png_pass_start[pass]; i < row_width; 2311 i += png_pass_inc[pass]) 2312 { 2313 sp = row + (png_size_t)(i >> 2); 2314 value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; 2315 d |= (value << shift); 2316 2317 if (shift == 0) 2318 { 2319 shift = 6; 2320 *dp++ = (png_byte)d; 2321 d = 0; 2322 } 2323 2324 else 2325 shift -= 2; 2326 } 2327 if (shift != 6) 2328 *dp = (png_byte)d; 2329 2330 break; 2331 } 2332 2333 case 4: 2334 { 2335 png_bytep sp; 2336 png_bytep dp; 2337 int shift; 2338 int d; 2339 int value; 2340 png_uint_32 i; 2341 png_uint_32 row_width = row_info->width; 2342 2343 dp = row; 2344 shift = 4; 2345 d = 0; 2346 for (i = png_pass_start[pass]; i < row_width; 2347 i += png_pass_inc[pass]) 2348 { 2349 sp = row + (png_size_t)(i >> 1); 2350 value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; 2351 d |= (value << shift); 2352 2353 if (shift == 0) 2354 { 2355 shift = 4; 2356 *dp++ = (png_byte)d; 2357 d = 0; 2358 } 2359 2360 else 2361 shift -= 4; 2362 } 2363 if (shift != 4) 2364 *dp = (png_byte)d; 2365 2366 break; 2367 } 2368 2369 default: 2370 { 2371 png_bytep sp; 2372 png_bytep dp; 2373 png_uint_32 i; 2374 png_uint_32 row_width = row_info->width; 2375 png_size_t pixel_bytes; 2376 2377 /* Start at the beginning */ 2378 dp = row; 2379 2380 /* Find out how many bytes each pixel takes up */ 2381 pixel_bytes = (row_info->pixel_depth >> 3); 2382 2383 /* Loop through the row, only looking at the pixels that matter */ 2384 for (i = png_pass_start[pass]; i < row_width; 2385 i += png_pass_inc[pass]) 2386 { 2387 /* Find out where the original pixel is */ 2388 sp = row + (png_size_t)i * pixel_bytes; 2389 2390 /* Move the pixel */ 2391 if (dp != sp) 2392 png_memcpy(dp, sp, pixel_bytes); 2393 2394 /* Next pixel */ 2395 dp += pixel_bytes; 2396 } 2397 break; 2398 } 2399 } 2400 /* Set new row width */ 2401 row_info->width = (row_info->width + 2402 png_pass_inc[pass] - 1 - 2403 png_pass_start[pass]) / 2404 png_pass_inc[pass]; 2405 2406 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 2407 row_info->width); 2408 } 2409} 2410#endif 2411 2412/* This filters the row, chooses which filter to use, if it has not already 2413 * been specified by the application, and then writes the row out with the 2414 * chosen filter. 2415 */ 2416static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, 2417 png_size_t row_bytes); 2418 2419#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) 2420#define PNG_HISHIFT 10 2421#define PNG_LOMASK ((png_uint_32)0xffffL) 2422#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) 2423void /* PRIVATE */ 2424png_write_find_filter(png_structp png_ptr, png_row_infop row_info) 2425{ 2426 png_bytep best_row; 2427#ifdef PNG_WRITE_FILTER_SUPPORTED 2428 png_bytep prev_row, row_buf; 2429 png_uint_32 mins, bpp; 2430 png_byte filter_to_do = png_ptr->do_filter; 2431 png_size_t row_bytes = row_info->rowbytes; 2432#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2433 int num_p_filters = png_ptr->num_prev_filters; 2434#endif 2435 2436 png_debug(1, "in png_write_find_filter"); 2437 2438#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2439 if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) 2440 { 2441 /* These will never be selected so we need not test them. */ 2442 filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); 2443 } 2444#endif 2445 2446 /* Find out how many bytes offset each pixel is */ 2447 bpp = (row_info->pixel_depth + 7) >> 3; 2448 2449 prev_row = png_ptr->prev_row; 2450#endif 2451 best_row = png_ptr->row_buf; 2452#ifdef PNG_WRITE_FILTER_SUPPORTED 2453 row_buf = best_row; 2454 mins = PNG_MAXSUM; 2455 2456 /* The prediction method we use is to find which method provides the 2457 * smallest value when summing the absolute values of the distances 2458 * from zero, using anything >= 128 as negative numbers. This is known 2459 * as the "minimum sum of absolute differences" heuristic. Other 2460 * heuristics are the "weighted minimum sum of absolute differences" 2461 * (experimental and can in theory improve compression), and the "zlib 2462 * predictive" method (not implemented yet), which does test compressions 2463 * of lines using different filter methods, and then chooses the 2464 * (series of) filter(s) that give minimum compressed data size (VERY 2465 * computationally expensive). 2466 * 2467 * GRR 980525: consider also 2468 * 2469 * (1) minimum sum of absolute differences from running average (i.e., 2470 * keep running sum of non-absolute differences & count of bytes) 2471 * [track dispersion, too? restart average if dispersion too large?] 2472 * 2473 * (1b) minimum sum of absolute differences from sliding average, probably 2474 * with window size <= deflate window (usually 32K) 2475 * 2476 * (2) minimum sum of squared differences from zero or running average 2477 * (i.e., ~ root-mean-square approach) 2478 */ 2479 2480 2481 /* We don't need to test the 'no filter' case if this is the only filter 2482 * that has been chosen, as it doesn't actually do anything to the data. 2483 */ 2484 if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) 2485 { 2486 png_bytep rp; 2487 png_uint_32 sum = 0; 2488 png_size_t i; 2489 int v; 2490 2491 for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) 2492 { 2493 v = *rp; 2494 sum += (v < 128) ? v : 256 - v; 2495 } 2496 2497#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2498 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2499 { 2500 png_uint_32 sumhi, sumlo; 2501 int j; 2502 sumlo = sum & PNG_LOMASK; 2503 sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ 2504 2505 /* Reduce the sum if we match any of the previous rows */ 2506 for (j = 0; j < num_p_filters; j++) 2507 { 2508 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) 2509 { 2510 sumlo = (sumlo * png_ptr->filter_weights[j]) >> 2511 PNG_WEIGHT_SHIFT; 2512 2513 sumhi = (sumhi * png_ptr->filter_weights[j]) >> 2514 PNG_WEIGHT_SHIFT; 2515 } 2516 } 2517 2518 /* Factor in the cost of this filter (this is here for completeness, 2519 * but it makes no sense to have a "cost" for the NONE filter, as 2520 * it has the minimum possible computational cost - none). 2521 */ 2522 sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> 2523 PNG_COST_SHIFT; 2524 2525 sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> 2526 PNG_COST_SHIFT; 2527 2528 if (sumhi > PNG_HIMASK) 2529 sum = PNG_MAXSUM; 2530 2531 else 2532 sum = (sumhi << PNG_HISHIFT) + sumlo; 2533 } 2534#endif 2535 mins = sum; 2536 } 2537 2538 /* Sub filter */ 2539 if (filter_to_do == PNG_FILTER_SUB) 2540 /* It's the only filter so no testing is needed */ 2541 { 2542 png_bytep rp, lp, dp; 2543 png_size_t i; 2544 2545 for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; 2546 i++, rp++, dp++) 2547 { 2548 *dp = *rp; 2549 } 2550 2551 for (lp = row_buf + 1; i < row_bytes; 2552 i++, rp++, lp++, dp++) 2553 { 2554 *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 2555 } 2556 2557 best_row = png_ptr->sub_row; 2558 } 2559 2560 else if (filter_to_do & PNG_FILTER_SUB) 2561 { 2562 png_bytep rp, dp, lp; 2563 png_uint_32 sum = 0, lmins = mins; 2564 png_size_t i; 2565 int v; 2566 2567#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2568 /* We temporarily increase the "minimum sum" by the factor we 2569 * would reduce the sum of this filter, so that we can do the 2570 * early exit comparison without scaling the sum each time. 2571 */ 2572 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2573 { 2574 int j; 2575 png_uint_32 lmhi, lmlo; 2576 lmlo = lmins & PNG_LOMASK; 2577 lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 2578 2579 for (j = 0; j < num_p_filters; j++) 2580 { 2581 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) 2582 { 2583 lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 2584 PNG_WEIGHT_SHIFT; 2585 2586 lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 2587 PNG_WEIGHT_SHIFT; 2588 } 2589 } 2590 2591 lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 2592 PNG_COST_SHIFT; 2593 2594 lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 2595 PNG_COST_SHIFT; 2596 2597 if (lmhi > PNG_HIMASK) 2598 lmins = PNG_MAXSUM; 2599 2600 else 2601 lmins = (lmhi << PNG_HISHIFT) + lmlo; 2602 } 2603#endif 2604 2605 for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; 2606 i++, rp++, dp++) 2607 { 2608 v = *dp = *rp; 2609 2610 sum += (v < 128) ? v : 256 - v; 2611 } 2612 2613 for (lp = row_buf + 1; i < row_bytes; 2614 i++, rp++, lp++, dp++) 2615 { 2616 v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 2617 2618 sum += (v < 128) ? v : 256 - v; 2619 2620 if (sum > lmins) /* We are already worse, don't continue. */ 2621 break; 2622 } 2623 2624#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2625 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2626 { 2627 int j; 2628 png_uint_32 sumhi, sumlo; 2629 sumlo = sum & PNG_LOMASK; 2630 sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 2631 2632 for (j = 0; j < num_p_filters; j++) 2633 { 2634 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) 2635 { 2636 sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> 2637 PNG_WEIGHT_SHIFT; 2638 2639 sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> 2640 PNG_WEIGHT_SHIFT; 2641 } 2642 } 2643 2644 sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 2645 PNG_COST_SHIFT; 2646 2647 sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 2648 PNG_COST_SHIFT; 2649 2650 if (sumhi > PNG_HIMASK) 2651 sum = PNG_MAXSUM; 2652 2653 else 2654 sum = (sumhi << PNG_HISHIFT) + sumlo; 2655 } 2656#endif 2657 2658 if (sum < mins) 2659 { 2660 mins = sum; 2661 best_row = png_ptr->sub_row; 2662 } 2663 } 2664 2665 /* Up filter */ 2666 if (filter_to_do == PNG_FILTER_UP) 2667 { 2668 png_bytep rp, dp, pp; 2669 png_size_t i; 2670 2671 for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, 2672 pp = prev_row + 1; i < row_bytes; 2673 i++, rp++, pp++, dp++) 2674 { 2675 *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); 2676 } 2677 2678 best_row = png_ptr->up_row; 2679 } 2680 2681 else if (filter_to_do & PNG_FILTER_UP) 2682 { 2683 png_bytep rp, dp, pp; 2684 png_uint_32 sum = 0, lmins = mins; 2685 png_size_t i; 2686 int v; 2687 2688 2689#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2690 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2691 { 2692 int j; 2693 png_uint_32 lmhi, lmlo; 2694 lmlo = lmins & PNG_LOMASK; 2695 lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 2696 2697 for (j = 0; j < num_p_filters; j++) 2698 { 2699 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) 2700 { 2701 lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 2702 PNG_WEIGHT_SHIFT; 2703 2704 lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 2705 PNG_WEIGHT_SHIFT; 2706 } 2707 } 2708 2709 lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> 2710 PNG_COST_SHIFT; 2711 2712 lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> 2713 PNG_COST_SHIFT; 2714 2715 if (lmhi > PNG_HIMASK) 2716 lmins = PNG_MAXSUM; 2717 2718 else 2719 lmins = (lmhi << PNG_HISHIFT) + lmlo; 2720 } 2721#endif 2722 2723 for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, 2724 pp = prev_row + 1; i < row_bytes; i++) 2725 { 2726 v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 2727 2728 sum += (v < 128) ? v : 256 - v; 2729 2730 if (sum > lmins) /* We are already worse, don't continue. */ 2731 break; 2732 } 2733 2734#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2735 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2736 { 2737 int j; 2738 png_uint_32 sumhi, sumlo; 2739 sumlo = sum & PNG_LOMASK; 2740 sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 2741 2742 for (j = 0; j < num_p_filters; j++) 2743 { 2744 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) 2745 { 2746 sumlo = (sumlo * png_ptr->filter_weights[j]) >> 2747 PNG_WEIGHT_SHIFT; 2748 2749 sumhi = (sumhi * png_ptr->filter_weights[j]) >> 2750 PNG_WEIGHT_SHIFT; 2751 } 2752 } 2753 2754 sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> 2755 PNG_COST_SHIFT; 2756 2757 sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> 2758 PNG_COST_SHIFT; 2759 2760 if (sumhi > PNG_HIMASK) 2761 sum = PNG_MAXSUM; 2762 2763 else 2764 sum = (sumhi << PNG_HISHIFT) + sumlo; 2765 } 2766#endif 2767 2768 if (sum < mins) 2769 { 2770 mins = sum; 2771 best_row = png_ptr->up_row; 2772 } 2773 } 2774 2775 /* Avg filter */ 2776 if (filter_to_do == PNG_FILTER_AVG) 2777 { 2778 png_bytep rp, dp, pp, lp; 2779 png_uint_32 i; 2780 2781 for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, 2782 pp = prev_row + 1; i < bpp; i++) 2783 { 2784 *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); 2785 } 2786 2787 for (lp = row_buf + 1; i < row_bytes; i++) 2788 { 2789 *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) 2790 & 0xff); 2791 } 2792 best_row = png_ptr->avg_row; 2793 } 2794 2795 else if (filter_to_do & PNG_FILTER_AVG) 2796 { 2797 png_bytep rp, dp, pp, lp; 2798 png_uint_32 sum = 0, lmins = mins; 2799 png_size_t i; 2800 int v; 2801 2802#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2803 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2804 { 2805 int j; 2806 png_uint_32 lmhi, lmlo; 2807 lmlo = lmins & PNG_LOMASK; 2808 lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 2809 2810 for (j = 0; j < num_p_filters; j++) 2811 { 2812 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) 2813 { 2814 lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 2815 PNG_WEIGHT_SHIFT; 2816 2817 lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 2818 PNG_WEIGHT_SHIFT; 2819 } 2820 } 2821 2822 lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> 2823 PNG_COST_SHIFT; 2824 2825 lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> 2826 PNG_COST_SHIFT; 2827 2828 if (lmhi > PNG_HIMASK) 2829 lmins = PNG_MAXSUM; 2830 2831 else 2832 lmins = (lmhi << PNG_HISHIFT) + lmlo; 2833 } 2834#endif 2835 2836 for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, 2837 pp = prev_row + 1; i < bpp; i++) 2838 { 2839 v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); 2840 2841 sum += (v < 128) ? v : 256 - v; 2842 } 2843 2844 for (lp = row_buf + 1; i < row_bytes; i++) 2845 { 2846 v = *dp++ = 2847 (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); 2848 2849 sum += (v < 128) ? v : 256 - v; 2850 2851 if (sum > lmins) /* We are already worse, don't continue. */ 2852 break; 2853 } 2854 2855#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2856 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2857 { 2858 int j; 2859 png_uint_32 sumhi, sumlo; 2860 sumlo = sum & PNG_LOMASK; 2861 sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 2862 2863 for (j = 0; j < num_p_filters; j++) 2864 { 2865 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) 2866 { 2867 sumlo = (sumlo * png_ptr->filter_weights[j]) >> 2868 PNG_WEIGHT_SHIFT; 2869 2870 sumhi = (sumhi * png_ptr->filter_weights[j]) >> 2871 PNG_WEIGHT_SHIFT; 2872 } 2873 } 2874 2875 sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> 2876 PNG_COST_SHIFT; 2877 2878 sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> 2879 PNG_COST_SHIFT; 2880 2881 if (sumhi > PNG_HIMASK) 2882 sum = PNG_MAXSUM; 2883 2884 else 2885 sum = (sumhi << PNG_HISHIFT) + sumlo; 2886 } 2887#endif 2888 2889 if (sum < mins) 2890 { 2891 mins = sum; 2892 best_row = png_ptr->avg_row; 2893 } 2894 } 2895 2896 /* Paeth filter */ 2897 if (filter_to_do == PNG_FILTER_PAETH) 2898 { 2899 png_bytep rp, dp, pp, cp, lp; 2900 png_size_t i; 2901 2902 for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, 2903 pp = prev_row + 1; i < bpp; i++) 2904 { 2905 *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 2906 } 2907 2908 for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) 2909 { 2910 int a, b, c, pa, pb, pc, p; 2911 2912 b = *pp++; 2913 c = *cp++; 2914 a = *lp++; 2915 2916 p = b - c; 2917 pc = a - c; 2918 2919#ifdef PNG_USE_ABS 2920 pa = abs(p); 2921 pb = abs(pc); 2922 pc = abs(p + pc); 2923#else 2924 pa = p < 0 ? -p : p; 2925 pb = pc < 0 ? -pc : pc; 2926 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 2927#endif 2928 2929 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; 2930 2931 *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 2932 } 2933 best_row = png_ptr->paeth_row; 2934 } 2935 2936 else if (filter_to_do & PNG_FILTER_PAETH) 2937 { 2938 png_bytep rp, dp, pp, cp, lp; 2939 png_uint_32 sum = 0, lmins = mins; 2940 png_size_t i; 2941 int v; 2942 2943#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 2944 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 2945 { 2946 int j; 2947 png_uint_32 lmhi, lmlo; 2948 lmlo = lmins & PNG_LOMASK; 2949 lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 2950 2951 for (j = 0; j < num_p_filters; j++) 2952 { 2953 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) 2954 { 2955 lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 2956 PNG_WEIGHT_SHIFT; 2957 2958 lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 2959 PNG_WEIGHT_SHIFT; 2960 } 2961 } 2962 2963 lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> 2964 PNG_COST_SHIFT; 2965 2966 lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> 2967 PNG_COST_SHIFT; 2968 2969 if (lmhi > PNG_HIMASK) 2970 lmins = PNG_MAXSUM; 2971 2972 else 2973 lmins = (lmhi << PNG_HISHIFT) + lmlo; 2974 } 2975#endif 2976 2977 for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, 2978 pp = prev_row + 1; i < bpp; i++) 2979 { 2980 v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 2981 2982 sum += (v < 128) ? v : 256 - v; 2983 } 2984 2985 for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) 2986 { 2987 int a, b, c, pa, pb, pc, p; 2988 2989 b = *pp++; 2990 c = *cp++; 2991 a = *lp++; 2992 2993#ifndef PNG_SLOW_PAETH 2994 p = b - c; 2995 pc = a - c; 2996#ifdef PNG_USE_ABS 2997 pa = abs(p); 2998 pb = abs(pc); 2999 pc = abs(p + pc); 3000#else 3001 pa = p < 0 ? -p : p; 3002 pb = pc < 0 ? -pc : pc; 3003 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3004#endif 3005 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; 3006#else /* PNG_SLOW_PAETH */ 3007 p = a + b - c; 3008 pa = abs(p - a); 3009 pb = abs(p - b); 3010 pc = abs(p - c); 3011 3012 if (pa <= pb && pa <= pc) 3013 p = a; 3014 3015 else if (pb <= pc) 3016 p = b; 3017 3018 else 3019 p = c; 3020#endif /* PNG_SLOW_PAETH */ 3021 3022 v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 3023 3024 sum += (v < 128) ? v : 256 - v; 3025 3026 if (sum > lmins) /* We are already worse, don't continue. */ 3027 break; 3028 } 3029 3030#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 3031 if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 3032 { 3033 int j; 3034 png_uint_32 sumhi, sumlo; 3035 sumlo = sum & PNG_LOMASK; 3036 sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 3037 3038 for (j = 0; j < num_p_filters; j++) 3039 { 3040 if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) 3041 { 3042 sumlo = (sumlo * png_ptr->filter_weights[j]) >> 3043 PNG_WEIGHT_SHIFT; 3044 3045 sumhi = (sumhi * png_ptr->filter_weights[j]) >> 3046 PNG_WEIGHT_SHIFT; 3047 } 3048 } 3049 3050 sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> 3051 PNG_COST_SHIFT; 3052 3053 sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> 3054 PNG_COST_SHIFT; 3055 3056 if (sumhi > PNG_HIMASK) 3057 sum = PNG_MAXSUM; 3058 3059 else 3060 sum = (sumhi << PNG_HISHIFT) + sumlo; 3061 } 3062#endif 3063 3064 if (sum < mins) 3065 { 3066 best_row = png_ptr->paeth_row; 3067 } 3068 } 3069#endif /* PNG_WRITE_FILTER_SUPPORTED */ 3070 3071 /* Do the actual writing of the filtered row data from the chosen filter. */ 3072 png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); 3073 3074#ifdef PNG_WRITE_FILTER_SUPPORTED 3075#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 3076 /* Save the type of filter we picked this time for future calculations */ 3077 if (png_ptr->num_prev_filters > 0) 3078 { 3079 int j; 3080 3081 for (j = 1; j < num_p_filters; j++) 3082 { 3083 png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; 3084 } 3085 3086 png_ptr->prev_filters[j] = best_row[0]; 3087 } 3088#endif 3089#endif /* PNG_WRITE_FILTER_SUPPORTED */ 3090} 3091 3092 3093/* Do the actual writing of a previously filtered row. */ 3094static void 3095png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row, 3096 png_size_t avail/*includes filter byte*/) 3097{ 3098 png_debug(1, "in png_write_filtered_row"); 3099 3100 png_debug1(2, "filter = %d", filtered_row[0]); 3101 /* Set up the zlib input buffer */ 3102 3103 png_ptr->zstream.next_in = filtered_row; 3104 png_ptr->zstream.avail_in = 0; 3105 /* Repeat until we have compressed all the data */ 3106 do 3107 { 3108 int ret; /* Return of zlib */ 3109 3110 /* Record the number of bytes available - zlib supports at least 65535 3111 * bytes at one step, depending on the size of the zlib type 'uInt', the 3112 * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). 3113 * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. 3114 * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a 3115 * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called 3116 * with smaller chunks of data. 3117 */ 3118 if (png_ptr->zstream.avail_in == 0) 3119 { 3120 if (avail > ZLIB_IO_MAX) 3121 { 3122 png_ptr->zstream.avail_in = ZLIB_IO_MAX; 3123 avail -= ZLIB_IO_MAX; 3124 } 3125 3126 else 3127 { 3128 /* So this will fit in the available uInt space: */ 3129 png_ptr->zstream.avail_in = (uInt)avail; 3130 avail = 0; 3131 } 3132 } 3133 3134 /* Compress the data */ 3135 ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); 3136 3137 /* Check for compression errors */ 3138 if (ret != Z_OK) 3139 { 3140 if (png_ptr->zstream.msg != NULL) 3141 png_error(png_ptr, png_ptr->zstream.msg); 3142 3143 else 3144 png_error(png_ptr, "zlib error"); 3145 } 3146 3147 /* See if it is time to write another IDAT */ 3148 if (!(png_ptr->zstream.avail_out)) 3149 { 3150 /* Write the IDAT and reset the zlib output buffer */ 3151 png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 3152 } 3153 /* Repeat until all data has been compressed */ 3154 } while (avail > 0 || png_ptr->zstream.avail_in > 0); 3155 3156 /* Swap the current and previous rows */ 3157 if (png_ptr->prev_row != NULL) 3158 { 3159 png_bytep tptr; 3160 3161 tptr = png_ptr->prev_row; 3162 png_ptr->prev_row = png_ptr->row_buf; 3163 png_ptr->row_buf = tptr; 3164 } 3165 3166 /* Finish row - updates counters and flushes zlib if last row */ 3167 png_write_finish_row(png_ptr); 3168 3169#ifdef PNG_WRITE_FLUSH_SUPPORTED 3170 png_ptr->flush_rows++; 3171 3172 if (png_ptr->flush_dist > 0 && 3173 png_ptr->flush_rows >= png_ptr->flush_dist) 3174 { 3175 png_write_flush(png_ptr); 3176 } 3177#endif 3178} 3179#endif /* PNG_WRITE_SUPPORTED */ 3180