pngwutil.c revision 06f1087a94f1e48298e89d77ccc51a0ced871958
1 2/* pngwutil.c - utilities to write a PNG file 3 * 4 * Last changed in libpng 1.6.19 [November 12, 2015] 5 * Copyright (c) 1998-2015 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); 27 buf[1] = (png_byte)(i >> 16); 28 buf[2] = (png_byte)(i >> 8); 29 buf[3] = (png_byte)(i ); 30} 31 32/* Place a 16-bit number into a buffer in PNG byte order. 33 * The parameter is declared unsigned int, not png_uint_16, 34 * just to avoid potential problems on pre-ANSI C compilers. 35 */ 36void PNGAPI 37png_save_uint_16(png_bytep buf, unsigned int i) 38{ 39 buf[0] = (png_byte)(i >> 8); 40 buf[1] = (png_byte)(i ); 41} 42#endif 43 44/* Simple function to write the signature. If we have already written 45 * the magic bytes of the signature, or more likely, the PNG stream is 46 * being embedded into another stream and doesn't need its own signature, 47 * we should call png_set_sig_bytes() to tell libpng how many of the 48 * bytes have already been written. 49 */ 50void PNGAPI 51png_write_sig(png_structrp png_ptr) 52{ 53 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 54 55#ifdef PNG_IO_STATE_SUPPORTED 56 /* Inform the I/O callback that the signature is being written */ 57 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; 58#endif 59 60 /* Write the rest of the 8 byte signature */ 61 png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], 62 (png_size_t)(8 - png_ptr->sig_bytes)); 63 64 if (png_ptr->sig_bytes < 3) 65 png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; 66} 67 68/* Write the start of a PNG chunk. The type is the chunk type. 69 * The total_length is the sum of the lengths of all the data you will be 70 * passing in png_write_chunk_data(). 71 */ 72static void 73png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, 74 png_uint_32 length) 75{ 76 png_byte buf[8]; 77 78#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) 79 PNG_CSTRING_FROM_CHUNK(buf, chunk_name); 80 png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); 81#endif 82 83 if (png_ptr == NULL) 84 return; 85 86#ifdef PNG_IO_STATE_SUPPORTED 87 /* Inform the I/O callback that the chunk header is being written. 88 * PNG_IO_CHUNK_HDR requires a single I/O call. 89 */ 90 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; 91#endif 92 93 /* Write the length and the chunk name */ 94 png_save_uint_32(buf, length); 95 png_save_uint_32(buf + 4, chunk_name); 96 png_write_data(png_ptr, buf, 8); 97 98 /* Put the chunk name into png_ptr->chunk_name */ 99 png_ptr->chunk_name = chunk_name; 100 101 /* Reset the crc and run it over the chunk name */ 102 png_reset_crc(png_ptr); 103 104 png_calculate_crc(png_ptr, buf + 4, 4); 105 106#ifdef PNG_IO_STATE_SUPPORTED 107 /* Inform the I/O callback that chunk data will (possibly) be written. 108 * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. 109 */ 110 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; 111#endif 112} 113 114void PNGAPI 115png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, 116 png_uint_32 length) 117{ 118 png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); 119} 120 121/* Write the data of a PNG chunk started with png_write_chunk_header(). 122 * Note that multiple calls to this function are allowed, and that the 123 * sum of the lengths from these calls *must* add up to the total_length 124 * given to png_write_chunk_header(). 125 */ 126void PNGAPI 127png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, 128 png_size_t length) 129{ 130 /* Write the data, and run the CRC over it */ 131 if (png_ptr == NULL) 132 return; 133 134 if (data != NULL && length > 0) 135 { 136 png_write_data(png_ptr, data, length); 137 138 /* Update the CRC after writing the data, 139 * in case the user I/O routine alters it. 140 */ 141 png_calculate_crc(png_ptr, data, length); 142 } 143} 144 145/* Finish a chunk started with png_write_chunk_header(). */ 146void PNGAPI 147png_write_chunk_end(png_structrp png_ptr) 148{ 149 png_byte buf[4]; 150 151 if (png_ptr == NULL) return; 152 153#ifdef PNG_IO_STATE_SUPPORTED 154 /* Inform the I/O callback that the chunk CRC is being written. 155 * PNG_IO_CHUNK_CRC requires a single I/O function call. 156 */ 157 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; 158#endif 159 160 /* Write the crc in a single operation */ 161 png_save_uint_32(buf, png_ptr->crc); 162 163 png_write_data(png_ptr, buf, (png_size_t)4); 164} 165 166/* Write a PNG chunk all at once. The type is an array of ASCII characters 167 * representing the chunk name. The array must be at least 4 bytes in 168 * length, and does not need to be null terminated. To be safe, pass the 169 * pre-defined chunk names here, and if you need a new one, define it 170 * where the others are defined. The length is the length of the data. 171 * All the data must be present. If that is not possible, use the 172 * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() 173 * functions instead. 174 */ 175static void 176png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, 177 png_const_bytep data, png_size_t length) 178{ 179 if (png_ptr == NULL) 180 return; 181 182 /* On 64-bit architectures 'length' may not fit in a png_uint_32. */ 183 if (length > PNG_UINT_31_MAX) 184 png_error(png_ptr, "length exceeds PNG maximum"); 185 186 png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); 187 png_write_chunk_data(png_ptr, data, length); 188 png_write_chunk_end(png_ptr); 189} 190 191/* This is the API that calls the internal function above. */ 192void PNGAPI 193png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, 194 png_const_bytep data, png_size_t length) 195{ 196 png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, 197 length); 198} 199 200/* This is used below to find the size of an image to pass to png_deflate_claim, 201 * so it only needs to be accurate if the size is less than 16384 bytes (the 202 * point at which a lower LZ window size can be used.) 203 */ 204static png_alloc_size_t 205png_image_size(png_structrp png_ptr) 206{ 207 /* Only return sizes up to the maximum of a png_uint_32; do this by limiting 208 * the width and height used to 15 bits. 209 */ 210 png_uint_32 h = png_ptr->height; 211 212 if (png_ptr->rowbytes < 32768 && h < 32768) 213 { 214 if (png_ptr->interlaced != 0) 215 { 216 /* Interlacing makes the image larger because of the replication of 217 * both the filter byte and the padding to a byte boundary. 218 */ 219 png_uint_32 w = png_ptr->width; 220 unsigned int pd = png_ptr->pixel_depth; 221 png_alloc_size_t cb_base; 222 int pass; 223 224 for (cb_base=0, pass=0; pass<=6; ++pass) 225 { 226 png_uint_32 pw = PNG_PASS_COLS(w, pass); 227 228 if (pw > 0) 229 cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); 230 } 231 232 return cb_base; 233 } 234 235 else 236 return (png_ptr->rowbytes+1) * h; 237 } 238 239 else 240 return 0xffffffffU; 241} 242 243#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED 244 /* This is the code to hack the first two bytes of the deflate stream (the 245 * deflate header) to correct the windowBits value to match the actual data 246 * size. Note that the second argument is the *uncompressed* size but the 247 * first argument is the *compressed* data (and it must be deflate 248 * compressed.) 249 */ 250static void 251optimize_cmf(png_bytep data, png_alloc_size_t data_size) 252{ 253 /* Optimize the CMF field in the zlib stream. The resultant zlib stream is 254 * still compliant to the stream specification. 255 */ 256 if (data_size <= 16384) /* else windowBits must be 15 */ 257 { 258 unsigned int z_cmf = data[0]; /* zlib compression method and flags */ 259 260 if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) 261 { 262 unsigned int z_cinfo; 263 unsigned int half_z_window_size; 264 265 z_cinfo = z_cmf >> 4; 266 half_z_window_size = 1U << (z_cinfo + 7); 267 268 if (data_size <= half_z_window_size) /* else no change */ 269 { 270 unsigned int tmp; 271 272 do 273 { 274 half_z_window_size >>= 1; 275 --z_cinfo; 276 } 277 while (z_cinfo > 0 && data_size <= half_z_window_size); 278 279 z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); 280 281 data[0] = (png_byte)z_cmf; 282 tmp = data[1] & 0xe0; 283 tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; 284 data[1] = (png_byte)tmp; 285 } 286 } 287 } 288} 289#endif /* WRITE_OPTIMIZE_CMF */ 290 291/* Initialize the compressor for the appropriate type of compression. */ 292static int 293png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, 294 png_alloc_size_t data_size) 295{ 296 if (png_ptr->zowner != 0) 297 { 298#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) 299 char msg[64]; 300 301 PNG_STRING_FROM_CHUNK(msg, owner); 302 msg[4] = ':'; 303 msg[5] = ' '; 304 PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); 305 /* So the message that results is "<chunk> using zstream"; this is an 306 * internal error, but is very useful for debugging. i18n requirements 307 * are minimal. 308 */ 309 (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); 310#endif 311#if PNG_RELEASE_BUILD 312 png_warning(png_ptr, msg); 313 314 /* Attempt sane error recovery */ 315 if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ 316 { 317 png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); 318 return Z_STREAM_ERROR; 319 } 320 321 png_ptr->zowner = 0; 322#else 323 png_error(png_ptr, msg); 324#endif 325 } 326 327 { 328 int level = png_ptr->zlib_level; 329 int method = png_ptr->zlib_method; 330 int windowBits = png_ptr->zlib_window_bits; 331 int memLevel = png_ptr->zlib_mem_level; 332 int strategy; /* set below */ 333 int ret; /* zlib return code */ 334 335 if (owner == png_IDAT) 336 { 337 if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) 338 strategy = png_ptr->zlib_strategy; 339 340 else if (png_ptr->do_filter != PNG_FILTER_NONE) 341 strategy = PNG_Z_DEFAULT_STRATEGY; 342 343 else 344 strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; 345 } 346 347 else 348 { 349#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED 350 level = png_ptr->zlib_text_level; 351 method = png_ptr->zlib_text_method; 352 windowBits = png_ptr->zlib_text_window_bits; 353 memLevel = png_ptr->zlib_text_mem_level; 354 strategy = png_ptr->zlib_text_strategy; 355#else 356 /* If customization is not supported the values all come from the 357 * IDAT values except for the strategy, which is fixed to the 358 * default. (This is the pre-1.6.0 behavior too, although it was 359 * implemented in a very different way.) 360 */ 361 strategy = Z_DEFAULT_STRATEGY; 362#endif 363 } 364 365 /* Adjust 'windowBits' down if larger than 'data_size'; to stop this 366 * happening just pass 32768 as the data_size parameter. Notice that zlib 367 * requires an extra 262 bytes in the window in addition to the data to be 368 * able to see the whole of the data, so if data_size+262 takes us to the 369 * next windowBits size we need to fix up the value later. (Because even 370 * though deflate needs the extra window, inflate does not!) 371 */ 372 if (data_size <= 16384) 373 { 374 /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to 375 * work round a Microsoft Visual C misbehavior which, contrary to C-90, 376 * widens the result of the following shift to 64-bits if (and, 377 * apparently, only if) it is used in a test. 378 */ 379 unsigned int half_window_size = 1U << (windowBits-1); 380 381 while (data_size + 262 <= half_window_size) 382 { 383 half_window_size >>= 1; 384 --windowBits; 385 } 386 } 387 388 /* Check against the previous initialized values, if any. */ 389 if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && 390 (png_ptr->zlib_set_level != level || 391 png_ptr->zlib_set_method != method || 392 png_ptr->zlib_set_window_bits != windowBits || 393 png_ptr->zlib_set_mem_level != memLevel || 394 png_ptr->zlib_set_strategy != strategy)) 395 { 396 if (deflateEnd(&png_ptr->zstream) != Z_OK) 397 png_warning(png_ptr, "deflateEnd failed (ignored)"); 398 399 png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; 400 } 401 402 /* For safety clear out the input and output pointers (currently zlib 403 * doesn't use them on Init, but it might in the future). 404 */ 405 png_ptr->zstream.next_in = NULL; 406 png_ptr->zstream.avail_in = 0; 407 png_ptr->zstream.next_out = NULL; 408 png_ptr->zstream.avail_out = 0; 409 410 /* Now initialize if required, setting the new parameters, otherwise just 411 * to a simple reset to the previous parameters. 412 */ 413 if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) 414 ret = deflateReset(&png_ptr->zstream); 415 416 else 417 { 418 ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, 419 memLevel, strategy); 420 421 if (ret == Z_OK) 422 png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; 423 } 424 425 /* The return code is from either deflateReset or deflateInit2; they have 426 * pretty much the same set of error codes. 427 */ 428 if (ret == Z_OK) 429 png_ptr->zowner = owner; 430 431 else 432 png_zstream_error(png_ptr, ret); 433 434 return ret; 435 } 436} 437 438/* Clean up (or trim) a linked list of compression buffers. */ 439void /* PRIVATE */ 440png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) 441{ 442 png_compression_bufferp list = *listp; 443 444 if (list != NULL) 445 { 446 *listp = NULL; 447 448 do 449 { 450 png_compression_bufferp next = list->next; 451 452 png_free(png_ptr, list); 453 list = next; 454 } 455 while (list != NULL); 456 } 457} 458 459#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED 460/* This pair of functions encapsulates the operation of (a) compressing a 461 * text string, and (b) issuing it later as a series of chunk data writes. 462 * The compression_state structure is shared context for these functions 463 * set up by the caller to allow access to the relevant local variables. 464 * 465 * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size 466 * temporary buffers. From 1.6.0 it is retained in png_struct so that it will 467 * be correctly freed in the event of a write error (previous implementations 468 * just leaked memory.) 469 */ 470typedef struct 471{ 472 png_const_bytep input; /* The uncompressed input data */ 473 png_alloc_size_t input_len; /* Its length */ 474 png_uint_32 output_len; /* Final compressed length */ 475 png_byte output[1024]; /* First block of output */ 476} compression_state; 477 478static void 479png_text_compress_init(compression_state *comp, png_const_bytep input, 480 png_alloc_size_t input_len) 481{ 482 comp->input = input; 483 comp->input_len = input_len; 484 comp->output_len = 0; 485} 486 487/* Compress the data in the compression state input */ 488static int 489png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, 490 compression_state *comp, png_uint_32 prefix_len) 491{ 492 int ret; 493 494 /* To find the length of the output it is necessary to first compress the 495 * input. The result is buffered rather than using the two-pass algorithm 496 * that is used on the inflate side; deflate is assumed to be slower and a 497 * PNG writer is assumed to have more memory available than a PNG reader. 498 * 499 * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an 500 * upper limit on the output size, but it is always bigger than the input 501 * size so it is likely to be more efficient to use this linked-list 502 * approach. 503 */ 504 ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); 505 506 if (ret != Z_OK) 507 return ret; 508 509 /* Set up the compression buffers, we need a loop here to avoid overflowing a 510 * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited 511 * by the output buffer size, so there is no need to check that. Since this 512 * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits 513 * in size. 514 */ 515 { 516 png_compression_bufferp *end = &png_ptr->zbuffer_list; 517 png_alloc_size_t input_len = comp->input_len; /* may be zero! */ 518 png_uint_32 output_len; 519 520 /* zlib updates these for us: */ 521 png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); 522 png_ptr->zstream.avail_in = 0; /* Set below */ 523 png_ptr->zstream.next_out = comp->output; 524 png_ptr->zstream.avail_out = (sizeof comp->output); 525 526 output_len = png_ptr->zstream.avail_out; 527 528 do 529 { 530 uInt avail_in = ZLIB_IO_MAX; 531 532 if (avail_in > input_len) 533 avail_in = (uInt)input_len; 534 535 input_len -= avail_in; 536 537 png_ptr->zstream.avail_in = avail_in; 538 539 if (png_ptr->zstream.avail_out == 0) 540 { 541 png_compression_buffer *next; 542 543 /* Chunk data is limited to 2^31 bytes in length, so the prefix 544 * length must be counted here. 545 */ 546 if (output_len + prefix_len > PNG_UINT_31_MAX) 547 { 548 ret = Z_MEM_ERROR; 549 break; 550 } 551 552 /* Need a new (malloc'ed) buffer, but there may be one present 553 * already. 554 */ 555 next = *end; 556 if (next == NULL) 557 { 558 next = png_voidcast(png_compression_bufferp, png_malloc_base 559 (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); 560 561 if (next == NULL) 562 { 563 ret = Z_MEM_ERROR; 564 break; 565 } 566 567 /* Link in this buffer (so that it will be freed later) */ 568 next->next = NULL; 569 *end = next; 570 } 571 572 png_ptr->zstream.next_out = next->output; 573 png_ptr->zstream.avail_out = png_ptr->zbuffer_size; 574 output_len += png_ptr->zstream.avail_out; 575 576 /* Move 'end' to the next buffer pointer. */ 577 end = &next->next; 578 } 579 580 /* Compress the data */ 581 ret = deflate(&png_ptr->zstream, 582 input_len > 0 ? Z_NO_FLUSH : Z_FINISH); 583 584 /* Claw back input data that was not consumed (because avail_in is 585 * reset above every time round the loop). 586 */ 587 input_len += png_ptr->zstream.avail_in; 588 png_ptr->zstream.avail_in = 0; /* safety */ 589 } 590 while (ret == Z_OK); 591 592 /* There may be some space left in the last output buffer. This needs to 593 * be subtracted from output_len. 594 */ 595 output_len -= png_ptr->zstream.avail_out; 596 png_ptr->zstream.avail_out = 0; /* safety */ 597 comp->output_len = output_len; 598 599 /* Now double check the output length, put in a custom message if it is 600 * too long. Otherwise ensure the z_stream::msg pointer is set to 601 * something. 602 */ 603 if (output_len + prefix_len >= PNG_UINT_31_MAX) 604 { 605 png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); 606 ret = Z_MEM_ERROR; 607 } 608 609 else 610 png_zstream_error(png_ptr, ret); 611 612 /* Reset zlib for another zTXt/iTXt or image data */ 613 png_ptr->zowner = 0; 614 615 /* The only success case is Z_STREAM_END, input_len must be 0; if not this 616 * is an internal error. 617 */ 618 if (ret == Z_STREAM_END && input_len == 0) 619 { 620#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED 621 /* Fix up the deflate header, if required */ 622 optimize_cmf(comp->output, comp->input_len); 623#endif 624 /* But Z_OK is returned, not Z_STREAM_END; this allows the claim 625 * function above to return Z_STREAM_END on an error (though it never 626 * does in the current versions of zlib.) 627 */ 628 return Z_OK; 629 } 630 631 else 632 return ret; 633 } 634} 635 636/* Ship the compressed text out via chunk writes */ 637static void 638png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) 639{ 640 png_uint_32 output_len = comp->output_len; 641 png_const_bytep output = comp->output; 642 png_uint_32 avail = (sizeof comp->output); 643 png_compression_buffer *next = png_ptr->zbuffer_list; 644 645 for (;;) 646 { 647 if (avail > output_len) 648 avail = output_len; 649 650 png_write_chunk_data(png_ptr, output, avail); 651 652 output_len -= avail; 653 654 if (output_len == 0 || next == NULL) 655 break; 656 657 avail = png_ptr->zbuffer_size; 658 output = next->output; 659 next = next->next; 660 } 661 662 /* This is an internal error; 'next' must have been NULL! */ 663 if (output_len > 0) 664 png_error(png_ptr, "error writing ancillary chunked compressed data"); 665} 666#endif /* WRITE_COMPRESSED_TEXT */ 667 668#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ 669 defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) 670/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, 671 * and if invalid, correct the keyword rather than discarding the entire 672 * chunk. The PNG 1.0 specification requires keywords 1-79 characters in 673 * length, forbids leading or trailing whitespace, multiple internal spaces, 674 * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. 675 * 676 * The 'new_key' buffer must be 80 characters in size (for the keyword plus a 677 * trailing '\0'). If this routine returns 0 then there was no keyword, or a 678 * valid one could not be generated, and the caller must png_error. 679 */ 680static png_uint_32 681png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) 682{ 683 png_const_charp orig_key = key; 684 png_uint_32 key_len = 0; 685 int bad_character = 0; 686 int space = 1; 687 688 png_debug(1, "in png_check_keyword"); 689 690 if (key == NULL) 691 { 692 *new_key = 0; 693 return 0; 694 } 695 696 while (*key && key_len < 79) 697 { 698 png_byte ch = (png_byte)*key++; 699 700 if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) 701 *new_key++ = ch, ++key_len, space = 0; 702 703 else if (space == 0) 704 { 705 /* A space or an invalid character when one wasn't seen immediately 706 * before; output just a space. 707 */ 708 *new_key++ = 32, ++key_len, space = 1; 709 710 /* If the character was not a space then it is invalid. */ 711 if (ch != 32) 712 bad_character = ch; 713 } 714 715 else if (bad_character == 0) 716 bad_character = ch; /* just skip it, record the first error */ 717 } 718 719 if (key_len > 0 && space != 0) /* trailing space */ 720 { 721 --key_len, --new_key; 722 if (bad_character == 0) 723 bad_character = 32; 724 } 725 726 /* Terminate the keyword */ 727 *new_key = 0; 728 729 if (key_len == 0) 730 return 0; 731 732#ifdef PNG_WARNINGS_SUPPORTED 733 /* Try to only output one warning per keyword: */ 734 if (*key != 0) /* keyword too long */ 735 png_warning(png_ptr, "keyword truncated"); 736 737 else if (bad_character != 0) 738 { 739 PNG_WARNING_PARAMETERS(p) 740 741 png_warning_parameter(p, 1, orig_key); 742 png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); 743 744 png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); 745 } 746#endif /* WARNINGS */ 747 748 return key_len; 749} 750#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */ 751 752/* Write the IHDR chunk, and update the png_struct with the necessary 753 * information. Note that the rest of this code depends upon this 754 * information being correct. 755 */ 756void /* PRIVATE */ 757png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, 758 int bit_depth, int color_type, int compression_type, int filter_type, 759 int interlace_type) 760{ 761 png_byte buf[13]; /* Buffer to store the IHDR info */ 762 763 png_debug(1, "in png_write_IHDR"); 764 765 /* Check that we have valid input data from the application info */ 766 switch (color_type) 767 { 768 case PNG_COLOR_TYPE_GRAY: 769 switch (bit_depth) 770 { 771 case 1: 772 case 2: 773 case 4: 774 case 8: 775#ifdef PNG_WRITE_16BIT_SUPPORTED 776 case 16: 777#endif 778 png_ptr->channels = 1; break; 779 780 default: 781 png_error(png_ptr, 782 "Invalid bit depth for grayscale image"); 783 } 784 break; 785 786 case PNG_COLOR_TYPE_RGB: 787#ifdef PNG_WRITE_16BIT_SUPPORTED 788 if (bit_depth != 8 && bit_depth != 16) 789#else 790 if (bit_depth != 8) 791#endif 792 png_error(png_ptr, "Invalid bit depth for RGB image"); 793 794 png_ptr->channels = 3; 795 break; 796 797 case PNG_COLOR_TYPE_PALETTE: 798 switch (bit_depth) 799 { 800 case 1: 801 case 2: 802 case 4: 803 case 8: 804 png_ptr->channels = 1; 805 break; 806 807 default: 808 png_error(png_ptr, "Invalid bit depth for paletted image"); 809 } 810 break; 811 812 case PNG_COLOR_TYPE_GRAY_ALPHA: 813 if (bit_depth != 8 && bit_depth != 16) 814 png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); 815 816 png_ptr->channels = 2; 817 break; 818 819 case PNG_COLOR_TYPE_RGB_ALPHA: 820#ifdef PNG_WRITE_16BIT_SUPPORTED 821 if (bit_depth != 8 && bit_depth != 16) 822#else 823 if (bit_depth != 8) 824#endif 825 png_error(png_ptr, "Invalid bit depth for RGBA image"); 826 827 png_ptr->channels = 4; 828 break; 829 830 default: 831 png_error(png_ptr, "Invalid image color type specified"); 832 } 833 834 if (compression_type != PNG_COMPRESSION_TYPE_BASE) 835 { 836 png_warning(png_ptr, "Invalid compression type specified"); 837 compression_type = PNG_COMPRESSION_TYPE_BASE; 838 } 839 840 /* Write filter_method 64 (intrapixel differencing) only if 841 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 842 * 2. Libpng did not write a PNG signature (this filter_method is only 843 * used in PNG datastreams that are embedded in MNG datastreams) and 844 * 3. The application called png_permit_mng_features with a mask that 845 * included PNG_FLAG_MNG_FILTER_64 and 846 * 4. The filter_method is 64 and 847 * 5. The color_type is RGB or RGBA 848 */ 849 if ( 850#ifdef PNG_MNG_FEATURES_SUPPORTED 851 !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && 852 ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && 853 (color_type == PNG_COLOR_TYPE_RGB || 854 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && 855 (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && 856#endif 857 filter_type != PNG_FILTER_TYPE_BASE) 858 { 859 png_warning(png_ptr, "Invalid filter type specified"); 860 filter_type = PNG_FILTER_TYPE_BASE; 861 } 862 863#ifdef PNG_WRITE_INTERLACING_SUPPORTED 864 if (interlace_type != PNG_INTERLACE_NONE && 865 interlace_type != PNG_INTERLACE_ADAM7) 866 { 867 png_warning(png_ptr, "Invalid interlace type specified"); 868 interlace_type = PNG_INTERLACE_ADAM7; 869 } 870#else 871 interlace_type=PNG_INTERLACE_NONE; 872#endif 873 874 /* Save the relevant information */ 875 png_ptr->bit_depth = (png_byte)bit_depth; 876 png_ptr->color_type = (png_byte)color_type; 877 png_ptr->interlaced = (png_byte)interlace_type; 878#ifdef PNG_MNG_FEATURES_SUPPORTED 879 png_ptr->filter_type = (png_byte)filter_type; 880#endif 881 png_ptr->compression_type = (png_byte)compression_type; 882 png_ptr->width = width; 883 png_ptr->height = height; 884 885 png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); 886 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); 887 /* Set the usr info, so any transformations can modify it */ 888 png_ptr->usr_width = png_ptr->width; 889 png_ptr->usr_bit_depth = png_ptr->bit_depth; 890 png_ptr->usr_channels = png_ptr->channels; 891 892 /* Pack the header information into the buffer */ 893 png_save_uint_32(buf, width); 894 png_save_uint_32(buf + 4, height); 895 buf[8] = (png_byte)bit_depth; 896 buf[9] = (png_byte)color_type; 897 buf[10] = (png_byte)compression_type; 898 buf[11] = (png_byte)filter_type; 899 buf[12] = (png_byte)interlace_type; 900 901 /* Write the chunk */ 902 png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); 903 904 if ((png_ptr->do_filter) == PNG_NO_FILTERS) 905 { 906 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || 907 png_ptr->bit_depth < 8) 908 png_ptr->do_filter = PNG_FILTER_NONE; 909 910 else 911 png_ptr->do_filter = PNG_ALL_FILTERS; 912 } 913 914 png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ 915} 916 917/* Write the palette. We are careful not to trust png_color to be in the 918 * correct order for PNG, so people can redefine it to any convenient 919 * structure. 920 */ 921void /* PRIVATE */ 922png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, 923 png_uint_32 num_pal) 924{ 925 png_uint_32 max_palette_length, i; 926 png_const_colorp pal_ptr; 927 png_byte buf[3]; 928 929 png_debug(1, "in png_write_PLTE"); 930 931 max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? 932 (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; 933 934 if (( 935#ifdef PNG_MNG_FEATURES_SUPPORTED 936 (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && 937#endif 938 num_pal == 0) || num_pal > max_palette_length) 939 { 940 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 941 { 942 png_error(png_ptr, "Invalid number of colors in palette"); 943 } 944 945 else 946 { 947 png_warning(png_ptr, "Invalid number of colors in palette"); 948 return; 949 } 950 } 951 952 if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) 953 { 954 png_warning(png_ptr, 955 "Ignoring request to write a PLTE chunk in grayscale PNG"); 956 957 return; 958 } 959 960 png_ptr->num_palette = (png_uint_16)num_pal; 961 png_debug1(3, "num_palette = %d", png_ptr->num_palette); 962 963 png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); 964#ifdef PNG_POINTER_INDEXING_SUPPORTED 965 966 for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) 967 { 968 buf[0] = pal_ptr->red; 969 buf[1] = pal_ptr->green; 970 buf[2] = pal_ptr->blue; 971 png_write_chunk_data(png_ptr, buf, (png_size_t)3); 972 } 973 974#else 975 /* This is a little slower but some buggy compilers need to do this 976 * instead 977 */ 978 pal_ptr=palette; 979 980 for (i = 0; i < num_pal; i++) 981 { 982 buf[0] = pal_ptr[i].red; 983 buf[1] = pal_ptr[i].green; 984 buf[2] = pal_ptr[i].blue; 985 png_write_chunk_data(png_ptr, buf, (png_size_t)3); 986 } 987 988#endif 989 png_write_chunk_end(png_ptr); 990 png_ptr->mode |= PNG_HAVE_PLTE; 991} 992 993/* This is similar to png_text_compress, above, except that it does not require 994 * all of the data at once and, instead of buffering the compressed result, 995 * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out 996 * because it calls the write interface. As a result it does its own error 997 * reporting and does not return an error code. In the event of error it will 998 * just call png_error. The input data length may exceed 32-bits. The 'flush' 999 * parameter is exactly the same as that to deflate, with the following 1000 * meanings: 1001 * 1002 * Z_NO_FLUSH: normal incremental output of compressed data 1003 * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush 1004 * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up 1005 * 1006 * The routine manages the acquire and release of the png_ptr->zstream by 1007 * checking and (at the end) clearing png_ptr->zowner; it does some sanity 1008 * checks on the 'mode' flags while doing this. 1009 */ 1010void /* PRIVATE */ 1011png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, 1012 png_alloc_size_t input_len, int flush) 1013{ 1014 if (png_ptr->zowner != png_IDAT) 1015 { 1016 /* First time. Ensure we have a temporary buffer for compression and 1017 * trim the buffer list if it has more than one entry to free memory. 1018 * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been 1019 * created at this point, but the check here is quick and safe. 1020 */ 1021 if (png_ptr->zbuffer_list == NULL) 1022 { 1023 png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, 1024 png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); 1025 png_ptr->zbuffer_list->next = NULL; 1026 } 1027 1028 else 1029 png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); 1030 1031 /* It is a terminal error if we can't claim the zstream. */ 1032 if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) 1033 png_error(png_ptr, png_ptr->zstream.msg); 1034 1035 /* The output state is maintained in png_ptr->zstream, so it must be 1036 * initialized here after the claim. 1037 */ 1038 png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; 1039 png_ptr->zstream.avail_out = png_ptr->zbuffer_size; 1040 } 1041 1042 /* Now loop reading and writing until all the input is consumed or an error 1043 * terminates the operation. The _out values are maintained across calls to 1044 * this function, but the input must be reset each time. 1045 */ 1046 png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); 1047 png_ptr->zstream.avail_in = 0; /* set below */ 1048 for (;;) 1049 { 1050 int ret; 1051 1052 /* INPUT: from the row data */ 1053 uInt avail = ZLIB_IO_MAX; 1054 1055 if (avail > input_len) 1056 avail = (uInt)input_len; /* safe because of the check */ 1057 1058 png_ptr->zstream.avail_in = avail; 1059 input_len -= avail; 1060 1061 ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); 1062 1063 /* Include as-yet unconsumed input */ 1064 input_len += png_ptr->zstream.avail_in; 1065 png_ptr->zstream.avail_in = 0; 1066 1067 /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note 1068 * that these two zstream fields are preserved across the calls, therefore 1069 * there is no need to set these up on entry to the loop. 1070 */ 1071 if (png_ptr->zstream.avail_out == 0) 1072 { 1073 png_bytep data = png_ptr->zbuffer_list->output; 1074 uInt size = png_ptr->zbuffer_size; 1075 1076 /* Write an IDAT containing the data then reset the buffer. The 1077 * first IDAT may need deflate header optimization. 1078 */ 1079#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED 1080 if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && 1081 png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) 1082 optimize_cmf(data, png_image_size(png_ptr)); 1083#endif 1084 1085 png_write_complete_chunk(png_ptr, png_IDAT, data, size); 1086 png_ptr->mode |= PNG_HAVE_IDAT; 1087 1088 png_ptr->zstream.next_out = data; 1089 png_ptr->zstream.avail_out = size; 1090 1091 /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with 1092 * the same flush parameter until it has finished output, for NO_FLUSH 1093 * it doesn't matter. 1094 */ 1095 if (ret == Z_OK && flush != Z_NO_FLUSH) 1096 continue; 1097 } 1098 1099 /* The order of these checks doesn't matter much; it just affects which 1100 * possible error might be detected if multiple things go wrong at once. 1101 */ 1102 if (ret == Z_OK) /* most likely return code! */ 1103 { 1104 /* If all the input has been consumed then just return. If Z_FINISH 1105 * was used as the flush parameter something has gone wrong if we get 1106 * here. 1107 */ 1108 if (input_len == 0) 1109 { 1110 if (flush == Z_FINISH) 1111 png_error(png_ptr, "Z_OK on Z_FINISH with output space"); 1112 1113 return; 1114 } 1115 } 1116 1117 else if (ret == Z_STREAM_END && flush == Z_FINISH) 1118 { 1119 /* This is the end of the IDAT data; any pending output must be 1120 * flushed. For small PNG files we may still be at the beginning. 1121 */ 1122 png_bytep data = png_ptr->zbuffer_list->output; 1123 uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; 1124 1125#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED 1126 if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && 1127 png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) 1128 optimize_cmf(data, png_image_size(png_ptr)); 1129#endif 1130 1131 png_write_complete_chunk(png_ptr, png_IDAT, data, size); 1132 png_ptr->zstream.avail_out = 0; 1133 png_ptr->zstream.next_out = NULL; 1134 png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; 1135 1136 png_ptr->zowner = 0; /* Release the stream */ 1137 return; 1138 } 1139 1140 else 1141 { 1142 /* This is an error condition. */ 1143 png_zstream_error(png_ptr, ret); 1144 png_error(png_ptr, png_ptr->zstream.msg); 1145 } 1146 } 1147} 1148 1149/* Write an IEND chunk */ 1150void /* PRIVATE */ 1151png_write_IEND(png_structrp png_ptr) 1152{ 1153 png_debug(1, "in png_write_IEND"); 1154 1155 png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); 1156 png_ptr->mode |= PNG_HAVE_IEND; 1157} 1158 1159#ifdef PNG_WRITE_gAMA_SUPPORTED 1160/* Write a gAMA chunk */ 1161void /* PRIVATE */ 1162png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) 1163{ 1164 png_byte buf[4]; 1165 1166 png_debug(1, "in png_write_gAMA"); 1167 1168 /* file_gamma is saved in 1/100,000ths */ 1169 png_save_uint_32(buf, (png_uint_32)file_gamma); 1170 png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); 1171} 1172#endif 1173 1174#ifdef PNG_WRITE_sRGB_SUPPORTED 1175/* Write a sRGB chunk */ 1176void /* PRIVATE */ 1177png_write_sRGB(png_structrp png_ptr, int srgb_intent) 1178{ 1179 png_byte buf[1]; 1180 1181 png_debug(1, "in png_write_sRGB"); 1182 1183 if (srgb_intent >= PNG_sRGB_INTENT_LAST) 1184 png_warning(png_ptr, 1185 "Invalid sRGB rendering intent specified"); 1186 1187 buf[0]=(png_byte)srgb_intent; 1188 png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); 1189} 1190#endif 1191 1192#ifdef PNG_WRITE_iCCP_SUPPORTED 1193/* Write an iCCP chunk */ 1194void /* PRIVATE */ 1195png_write_iCCP(png_structrp png_ptr, png_const_charp name, 1196 png_const_bytep profile) 1197{ 1198 png_uint_32 name_len; 1199 png_uint_32 profile_len; 1200 png_byte new_name[81]; /* 1 byte for the compression byte */ 1201 compression_state comp; 1202 png_uint_32 temp; 1203 1204 png_debug(1, "in png_write_iCCP"); 1205 1206 /* These are all internal problems: the profile should have been checked 1207 * before when it was stored. 1208 */ 1209 if (profile == NULL) 1210 png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ 1211 1212 profile_len = png_get_uint_32(profile); 1213 1214 if (profile_len < 132) 1215 png_error(png_ptr, "ICC profile too short"); 1216 1217 temp = (png_uint_32) (*(profile+8)); 1218 if (temp > 3 && (profile_len & 0x03)) 1219 png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); 1220 1221 { 1222 png_uint_32 embedded_profile_len = png_get_uint_32(profile); 1223 1224 if (profile_len != embedded_profile_len) 1225 png_error(png_ptr, "Profile length does not match profile"); 1226 } 1227 1228 name_len = png_check_keyword(png_ptr, name, new_name); 1229 1230 if (name_len == 0) 1231 png_error(png_ptr, "iCCP: invalid keyword"); 1232 1233 new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; 1234 1235 /* Make sure we include the NULL after the name and the compression type */ 1236 ++name_len; 1237 1238 png_text_compress_init(&comp, profile, profile_len); 1239 1240 /* Allow for keyword terminator and compression byte */ 1241 if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) 1242 png_error(png_ptr, png_ptr->zstream.msg); 1243 1244 png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); 1245 1246 png_write_chunk_data(png_ptr, new_name, name_len); 1247 1248 png_write_compressed_data_out(png_ptr, &comp); 1249 1250 png_write_chunk_end(png_ptr); 1251} 1252#endif 1253 1254#ifdef PNG_WRITE_sPLT_SUPPORTED 1255/* Write a sPLT chunk */ 1256void /* PRIVATE */ 1257png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) 1258{ 1259 png_uint_32 name_len; 1260 png_byte new_name[80]; 1261 png_byte entrybuf[10]; 1262 png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); 1263 png_size_t palette_size = entry_size * spalette->nentries; 1264 png_sPLT_entryp ep; 1265#ifndef PNG_POINTER_INDEXING_SUPPORTED 1266 int i; 1267#endif 1268 1269 png_debug(1, "in png_write_sPLT"); 1270 1271 name_len = png_check_keyword(png_ptr, spalette->name, new_name); 1272 1273 if (name_len == 0) 1274 png_error(png_ptr, "sPLT: invalid keyword"); 1275 1276 /* Make sure we include the NULL after the name */ 1277 png_write_chunk_header(png_ptr, png_sPLT, 1278 (png_uint_32)(name_len + 2 + palette_size)); 1279 1280 png_write_chunk_data(png_ptr, (png_bytep)new_name, 1281 (png_size_t)(name_len + 1)); 1282 1283 png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); 1284 1285 /* Loop through each palette entry, writing appropriately */ 1286#ifdef PNG_POINTER_INDEXING_SUPPORTED 1287 for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++) 1288 { 1289 if (spalette->depth == 8) 1290 { 1291 entrybuf[0] = (png_byte)ep->red; 1292 entrybuf[1] = (png_byte)ep->green; 1293 entrybuf[2] = (png_byte)ep->blue; 1294 entrybuf[3] = (png_byte)ep->alpha; 1295 png_save_uint_16(entrybuf + 4, ep->frequency); 1296 } 1297 1298 else 1299 { 1300 png_save_uint_16(entrybuf + 0, ep->red); 1301 png_save_uint_16(entrybuf + 2, ep->green); 1302 png_save_uint_16(entrybuf + 4, ep->blue); 1303 png_save_uint_16(entrybuf + 6, ep->alpha); 1304 png_save_uint_16(entrybuf + 8, ep->frequency); 1305 } 1306 1307 png_write_chunk_data(png_ptr, entrybuf, entry_size); 1308 } 1309#else 1310 ep=spalette->entries; 1311 for (i = 0; i>spalette->nentries; i++) 1312 { 1313 if (spalette->depth == 8) 1314 { 1315 entrybuf[0] = (png_byte)ep[i].red; 1316 entrybuf[1] = (png_byte)ep[i].green; 1317 entrybuf[2] = (png_byte)ep[i].blue; 1318 entrybuf[3] = (png_byte)ep[i].alpha; 1319 png_save_uint_16(entrybuf + 4, ep[i].frequency); 1320 } 1321 1322 else 1323 { 1324 png_save_uint_16(entrybuf + 0, ep[i].red); 1325 png_save_uint_16(entrybuf + 2, ep[i].green); 1326 png_save_uint_16(entrybuf + 4, ep[i].blue); 1327 png_save_uint_16(entrybuf + 6, ep[i].alpha); 1328 png_save_uint_16(entrybuf + 8, ep[i].frequency); 1329 } 1330 1331 png_write_chunk_data(png_ptr, entrybuf, entry_size); 1332 } 1333#endif 1334 1335 png_write_chunk_end(png_ptr); 1336} 1337#endif 1338 1339#ifdef PNG_WRITE_sBIT_SUPPORTED 1340/* Write the sBIT chunk */ 1341void /* PRIVATE */ 1342png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) 1343{ 1344 png_byte buf[4]; 1345 png_size_t size; 1346 1347 png_debug(1, "in png_write_sBIT"); 1348 1349 /* Make sure we don't depend upon the order of PNG_COLOR_8 */ 1350 if ((color_type & PNG_COLOR_MASK_COLOR) != 0) 1351 { 1352 png_byte maxbits; 1353 1354 maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : 1355 png_ptr->usr_bit_depth); 1356 1357 if (sbit->red == 0 || sbit->red > maxbits || 1358 sbit->green == 0 || sbit->green > maxbits || 1359 sbit->blue == 0 || sbit->blue > maxbits) 1360 { 1361 png_warning(png_ptr, "Invalid sBIT depth specified"); 1362 return; 1363 } 1364 1365 buf[0] = sbit->red; 1366 buf[1] = sbit->green; 1367 buf[2] = sbit->blue; 1368 size = 3; 1369 } 1370 1371 else 1372 { 1373 if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) 1374 { 1375 png_warning(png_ptr, "Invalid sBIT depth specified"); 1376 return; 1377 } 1378 1379 buf[0] = sbit->gray; 1380 size = 1; 1381 } 1382 1383 if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) 1384 { 1385 if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) 1386 { 1387 png_warning(png_ptr, "Invalid sBIT depth specified"); 1388 return; 1389 } 1390 1391 buf[size++] = sbit->alpha; 1392 } 1393 1394 png_write_complete_chunk(png_ptr, png_sBIT, buf, size); 1395} 1396#endif 1397 1398#ifdef PNG_WRITE_cHRM_SUPPORTED 1399/* Write the cHRM chunk */ 1400void /* PRIVATE */ 1401png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) 1402{ 1403 png_byte buf[32]; 1404 1405 png_debug(1, "in png_write_cHRM"); 1406 1407 /* Each value is saved in 1/100,000ths */ 1408 png_save_int_32(buf, xy->whitex); 1409 png_save_int_32(buf + 4, xy->whitey); 1410 1411 png_save_int_32(buf + 8, xy->redx); 1412 png_save_int_32(buf + 12, xy->redy); 1413 1414 png_save_int_32(buf + 16, xy->greenx); 1415 png_save_int_32(buf + 20, xy->greeny); 1416 1417 png_save_int_32(buf + 24, xy->bluex); 1418 png_save_int_32(buf + 28, xy->bluey); 1419 1420 png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); 1421} 1422#endif 1423 1424#ifdef PNG_WRITE_tRNS_SUPPORTED 1425/* Write the tRNS chunk */ 1426void /* PRIVATE */ 1427png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, 1428 png_const_color_16p tran, int num_trans, int color_type) 1429{ 1430 png_byte buf[6]; 1431 1432 png_debug(1, "in png_write_tRNS"); 1433 1434 if (color_type == PNG_COLOR_TYPE_PALETTE) 1435 { 1436 if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) 1437 { 1438 png_app_warning(png_ptr, 1439 "Invalid number of transparent colors specified"); 1440 return; 1441 } 1442 1443 /* Write the chunk out as it is */ 1444 png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, 1445 (png_size_t)num_trans); 1446 } 1447 1448 else if (color_type == PNG_COLOR_TYPE_GRAY) 1449 { 1450 /* One 16-bit value */ 1451 if (tran->gray >= (1 << png_ptr->bit_depth)) 1452 { 1453 png_app_warning(png_ptr, 1454 "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); 1455 1456 return; 1457 } 1458 1459 png_save_uint_16(buf, tran->gray); 1460 png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); 1461 } 1462 1463 else if (color_type == PNG_COLOR_TYPE_RGB) 1464 { 1465 /* Three 16-bit values */ 1466 png_save_uint_16(buf, tran->red); 1467 png_save_uint_16(buf + 2, tran->green); 1468 png_save_uint_16(buf + 4, tran->blue); 1469#ifdef PNG_WRITE_16BIT_SUPPORTED 1470 if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) 1471#else 1472 if ((buf[0] | buf[2] | buf[4]) != 0) 1473#endif 1474 { 1475 png_app_warning(png_ptr, 1476 "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); 1477 return; 1478 } 1479 1480 png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); 1481 } 1482 1483 else 1484 { 1485 png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); 1486 } 1487} 1488#endif 1489 1490#ifdef PNG_WRITE_bKGD_SUPPORTED 1491/* Write the background chunk */ 1492void /* PRIVATE */ 1493png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) 1494{ 1495 png_byte buf[6]; 1496 1497 png_debug(1, "in png_write_bKGD"); 1498 1499 if (color_type == PNG_COLOR_TYPE_PALETTE) 1500 { 1501 if ( 1502#ifdef PNG_MNG_FEATURES_SUPPORTED 1503 (png_ptr->num_palette != 0 || 1504 (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && 1505#endif 1506 back->index >= png_ptr->num_palette) 1507 { 1508 png_warning(png_ptr, "Invalid background palette index"); 1509 return; 1510 } 1511 1512 buf[0] = back->index; 1513 png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); 1514 } 1515 1516 else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) 1517 { 1518 png_save_uint_16(buf, back->red); 1519 png_save_uint_16(buf + 2, back->green); 1520 png_save_uint_16(buf + 4, back->blue); 1521#ifdef PNG_WRITE_16BIT_SUPPORTED 1522 if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) 1523#else 1524 if ((buf[0] | buf[2] | buf[4]) != 0) 1525#endif 1526 { 1527 png_warning(png_ptr, 1528 "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); 1529 1530 return; 1531 } 1532 1533 png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); 1534 } 1535 1536 else 1537 { 1538 if (back->gray >= (1 << png_ptr->bit_depth)) 1539 { 1540 png_warning(png_ptr, 1541 "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); 1542 1543 return; 1544 } 1545 1546 png_save_uint_16(buf, back->gray); 1547 png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); 1548 } 1549} 1550#endif 1551 1552#ifdef PNG_WRITE_hIST_SUPPORTED 1553/* Write the histogram */ 1554void /* PRIVATE */ 1555png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) 1556{ 1557 int i; 1558 png_byte buf[3]; 1559 1560 png_debug(1, "in png_write_hIST"); 1561 1562 if (num_hist > (int)png_ptr->num_palette) 1563 { 1564 png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, 1565 png_ptr->num_palette); 1566 1567 png_warning(png_ptr, "Invalid number of histogram entries specified"); 1568 return; 1569 } 1570 1571 png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); 1572 1573 for (i = 0; i < num_hist; i++) 1574 { 1575 png_save_uint_16(buf, hist[i]); 1576 png_write_chunk_data(png_ptr, buf, (png_size_t)2); 1577 } 1578 1579 png_write_chunk_end(png_ptr); 1580} 1581#endif 1582 1583#ifdef PNG_WRITE_tEXt_SUPPORTED 1584/* Write a tEXt chunk */ 1585void /* PRIVATE */ 1586png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, 1587 png_size_t text_len) 1588{ 1589 png_uint_32 key_len; 1590 png_byte new_key[80]; 1591 1592 png_debug(1, "in png_write_tEXt"); 1593 1594 key_len = png_check_keyword(png_ptr, key, new_key); 1595 1596 if (key_len == 0) 1597 png_error(png_ptr, "tEXt: invalid keyword"); 1598 1599 if (text == NULL || *text == '\0') 1600 text_len = 0; 1601 1602 else 1603 text_len = strlen(text); 1604 1605 if (text_len > PNG_UINT_31_MAX - (key_len+1)) 1606 png_error(png_ptr, "tEXt: text too long"); 1607 1608 /* Make sure we include the 0 after the key */ 1609 png_write_chunk_header(png_ptr, png_tEXt, 1610 (png_uint_32)/*checked above*/(key_len + text_len + 1)); 1611 /* 1612 * We leave it to the application to meet PNG-1.0 requirements on the 1613 * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of 1614 * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. 1615 * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. 1616 */ 1617 png_write_chunk_data(png_ptr, new_key, key_len + 1); 1618 1619 if (text_len != 0) 1620 png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); 1621 1622 png_write_chunk_end(png_ptr); 1623} 1624#endif 1625 1626#ifdef PNG_WRITE_zTXt_SUPPORTED 1627/* Write a compressed text chunk */ 1628void /* PRIVATE */ 1629png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, 1630 int compression) 1631{ 1632 png_uint_32 key_len; 1633 png_byte new_key[81]; 1634 compression_state comp; 1635 1636 png_debug(1, "in png_write_zTXt"); 1637 1638 if (compression == PNG_TEXT_COMPRESSION_NONE) 1639 { 1640 png_write_tEXt(png_ptr, key, text, 0); 1641 return; 1642 } 1643 1644 if (compression != PNG_TEXT_COMPRESSION_zTXt) 1645 png_error(png_ptr, "zTXt: invalid compression type"); 1646 1647 key_len = png_check_keyword(png_ptr, key, new_key); 1648 1649 if (key_len == 0) 1650 png_error(png_ptr, "zTXt: invalid keyword"); 1651 1652 /* Add the compression method and 1 for the keyword separator. */ 1653 new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; 1654 ++key_len; 1655 1656 /* Compute the compressed data; do it now for the length */ 1657 png_text_compress_init(&comp, (png_const_bytep)text, 1658 text == NULL ? 0 : strlen(text)); 1659 1660 if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) 1661 png_error(png_ptr, png_ptr->zstream.msg); 1662 1663 /* Write start of chunk */ 1664 png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); 1665 1666 /* Write key */ 1667 png_write_chunk_data(png_ptr, new_key, key_len); 1668 1669 /* Write the compressed data */ 1670 png_write_compressed_data_out(png_ptr, &comp); 1671 1672 /* Close the chunk */ 1673 png_write_chunk_end(png_ptr); 1674} 1675#endif 1676 1677#ifdef PNG_WRITE_iTXt_SUPPORTED 1678/* Write an iTXt chunk */ 1679void /* PRIVATE */ 1680png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, 1681 png_const_charp lang, png_const_charp lang_key, png_const_charp text) 1682{ 1683 png_uint_32 key_len, prefix_len; 1684 png_size_t lang_len, lang_key_len; 1685 png_byte new_key[82]; 1686 compression_state comp; 1687 1688 png_debug(1, "in png_write_iTXt"); 1689 1690 key_len = png_check_keyword(png_ptr, key, new_key); 1691 1692 if (key_len == 0) 1693 png_error(png_ptr, "iTXt: invalid keyword"); 1694 1695 /* Set the compression flag */ 1696 switch (compression) 1697 { 1698 case PNG_ITXT_COMPRESSION_NONE: 1699 case PNG_TEXT_COMPRESSION_NONE: 1700 compression = new_key[++key_len] = 0; /* no compression */ 1701 break; 1702 1703 case PNG_TEXT_COMPRESSION_zTXt: 1704 case PNG_ITXT_COMPRESSION_zTXt: 1705 compression = new_key[++key_len] = 1; /* compressed */ 1706 break; 1707 1708 default: 1709 png_error(png_ptr, "iTXt: invalid compression"); 1710 } 1711 1712 new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; 1713 ++key_len; /* for the keywod separator */ 1714 1715 /* We leave it to the application to meet PNG-1.0 requirements on the 1716 * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of 1717 * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, 1718 * specifies that the text is UTF-8 and this really doesn't require any 1719 * checking. 1720 * 1721 * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. 1722 * 1723 * TODO: validate the language tag correctly (see the spec.) 1724 */ 1725 if (lang == NULL) lang = ""; /* empty language is valid */ 1726 lang_len = strlen(lang)+1; 1727 if (lang_key == NULL) lang_key = ""; /* may be empty */ 1728 lang_key_len = strlen(lang_key)+1; 1729 if (text == NULL) text = ""; /* may be empty */ 1730 1731 prefix_len = key_len; 1732 if (lang_len > PNG_UINT_31_MAX-prefix_len) 1733 prefix_len = PNG_UINT_31_MAX; 1734 else 1735 prefix_len = (png_uint_32)(prefix_len + lang_len); 1736 1737 if (lang_key_len > PNG_UINT_31_MAX-prefix_len) 1738 prefix_len = PNG_UINT_31_MAX; 1739 else 1740 prefix_len = (png_uint_32)(prefix_len + lang_key_len); 1741 1742 png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); 1743 1744 if (compression != 0) 1745 { 1746 if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) 1747 png_error(png_ptr, png_ptr->zstream.msg); 1748 } 1749 1750 else 1751 { 1752 if (comp.input_len > PNG_UINT_31_MAX-prefix_len) 1753 png_error(png_ptr, "iTXt: uncompressed text too long"); 1754 1755 /* So the string will fit in a chunk: */ 1756 comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; 1757 } 1758 1759 png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); 1760 1761 png_write_chunk_data(png_ptr, new_key, key_len); 1762 1763 png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); 1764 1765 png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); 1766 1767 if (compression != 0) 1768 png_write_compressed_data_out(png_ptr, &comp); 1769 1770 else 1771 png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len); 1772 1773 png_write_chunk_end(png_ptr); 1774} 1775#endif 1776 1777#ifdef PNG_WRITE_oFFs_SUPPORTED 1778/* Write the oFFs chunk */ 1779void /* PRIVATE */ 1780png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, 1781 int unit_type) 1782{ 1783 png_byte buf[9]; 1784 1785 png_debug(1, "in png_write_oFFs"); 1786 1787 if (unit_type >= PNG_OFFSET_LAST) 1788 png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); 1789 1790 png_save_int_32(buf, x_offset); 1791 png_save_int_32(buf + 4, y_offset); 1792 buf[8] = (png_byte)unit_type; 1793 1794 png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); 1795} 1796#endif 1797#ifdef PNG_WRITE_pCAL_SUPPORTED 1798/* Write the pCAL chunk (described in the PNG extensions document) */ 1799void /* PRIVATE */ 1800png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, 1801 png_int_32 X1, int type, int nparams, png_const_charp units, 1802 png_charpp params) 1803{ 1804 png_uint_32 purpose_len; 1805 png_size_t units_len, total_len; 1806 png_size_tp params_len; 1807 png_byte buf[10]; 1808 png_byte new_purpose[80]; 1809 int i; 1810 1811 png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); 1812 1813 if (type >= PNG_EQUATION_LAST) 1814 png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); 1815 1816 purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); 1817 1818 if (purpose_len == 0) 1819 png_error(png_ptr, "pCAL: invalid keyword"); 1820 1821 ++purpose_len; /* terminator */ 1822 1823 png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); 1824 units_len = strlen(units) + (nparams == 0 ? 0 : 1); 1825 png_debug1(3, "pCAL units length = %d", (int)units_len); 1826 total_len = purpose_len + units_len + 10; 1827 1828 params_len = (png_size_tp)png_malloc(png_ptr, 1829 (png_alloc_size_t)(nparams * (sizeof (png_size_t)))); 1830 1831 /* Find the length of each parameter, making sure we don't count the 1832 * null terminator for the last parameter. 1833 */ 1834 for (i = 0; i < nparams; i++) 1835 { 1836 params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); 1837 png_debug2(3, "pCAL parameter %d length = %lu", i, 1838 (unsigned long)params_len[i]); 1839 total_len += params_len[i]; 1840 } 1841 1842 png_debug1(3, "pCAL total length = %d", (int)total_len); 1843 png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); 1844 png_write_chunk_data(png_ptr, new_purpose, purpose_len); 1845 png_save_int_32(buf, X0); 1846 png_save_int_32(buf + 4, X1); 1847 buf[8] = (png_byte)type; 1848 buf[9] = (png_byte)nparams; 1849 png_write_chunk_data(png_ptr, buf, (png_size_t)10); 1850 png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); 1851 1852 for (i = 0; i < nparams; i++) 1853 { 1854 png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); 1855 } 1856 1857 png_free(png_ptr, params_len); 1858 png_write_chunk_end(png_ptr); 1859} 1860#endif 1861 1862#ifdef PNG_WRITE_sCAL_SUPPORTED 1863/* Write the sCAL chunk */ 1864void /* PRIVATE */ 1865png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, 1866 png_const_charp height) 1867{ 1868 png_byte buf[64]; 1869 png_size_t wlen, hlen, total_len; 1870 1871 png_debug(1, "in png_write_sCAL_s"); 1872 1873 wlen = strlen(width); 1874 hlen = strlen(height); 1875 total_len = wlen + hlen + 2; 1876 1877 if (total_len > 64) 1878 { 1879 png_warning(png_ptr, "Can't write sCAL (buffer too small)"); 1880 return; 1881 } 1882 1883 buf[0] = (png_byte)unit; 1884 memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ 1885 memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ 1886 1887 png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); 1888 png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); 1889} 1890#endif 1891 1892#ifdef PNG_WRITE_pHYs_SUPPORTED 1893/* Write the pHYs chunk */ 1894void /* PRIVATE */ 1895png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, 1896 png_uint_32 y_pixels_per_unit, 1897 int unit_type) 1898{ 1899 png_byte buf[9]; 1900 1901 png_debug(1, "in png_write_pHYs"); 1902 1903 if (unit_type >= PNG_RESOLUTION_LAST) 1904 png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); 1905 1906 png_save_uint_32(buf, x_pixels_per_unit); 1907 png_save_uint_32(buf + 4, y_pixels_per_unit); 1908 buf[8] = (png_byte)unit_type; 1909 1910 png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); 1911} 1912#endif 1913 1914#ifdef PNG_WRITE_tIME_SUPPORTED 1915/* Write the tIME chunk. Use either png_convert_from_struct_tm() 1916 * or png_convert_from_time_t(), or fill in the structure yourself. 1917 */ 1918void /* PRIVATE */ 1919png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) 1920{ 1921 png_byte buf[7]; 1922 1923 png_debug(1, "in png_write_tIME"); 1924 1925 if (mod_time->month > 12 || mod_time->month < 1 || 1926 mod_time->day > 31 || mod_time->day < 1 || 1927 mod_time->hour > 23 || mod_time->second > 60) 1928 { 1929 png_warning(png_ptr, "Invalid time specified for tIME chunk"); 1930 return; 1931 } 1932 1933 png_save_uint_16(buf, mod_time->year); 1934 buf[2] = mod_time->month; 1935 buf[3] = mod_time->day; 1936 buf[4] = mod_time->hour; 1937 buf[5] = mod_time->minute; 1938 buf[6] = mod_time->second; 1939 1940 png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); 1941} 1942#endif 1943 1944/* Initializes the row writing capability of libpng */ 1945void /* PRIVATE */ 1946png_write_start_row(png_structrp png_ptr) 1947{ 1948#ifdef PNG_WRITE_INTERLACING_SUPPORTED 1949 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1950 1951 /* Start of interlace block */ 1952 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 1953 1954 /* Offset to next interlace block */ 1955 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 1956 1957 /* Start of interlace block in the y direction */ 1958 static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 1959 1960 /* Offset to next interlace block in the y direction */ 1961 static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 1962#endif 1963 1964 png_alloc_size_t buf_size; 1965 int usr_pixel_depth; 1966 1967#ifdef PNG_WRITE_FILTER_SUPPORTED 1968 png_byte filters; 1969#endif 1970 1971 png_debug(1, "in png_write_start_row"); 1972 1973 usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; 1974 buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; 1975 1976 /* 1.5.6: added to allow checking in the row write code. */ 1977 png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; 1978 png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; 1979 1980 /* Set up row buffer */ 1981 png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); 1982 1983 png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; 1984 1985#ifdef PNG_WRITE_FILTER_SUPPORTED 1986 filters = png_ptr->do_filter; 1987 1988 if (png_ptr->height == 1) 1989 filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); 1990 1991 if (png_ptr->width == 1) 1992 filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); 1993 1994 if (filters == 0) 1995 filters = PNG_FILTER_NONE; 1996 1997 png_ptr->do_filter = filters; 1998 1999 if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | 2000 PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL) 2001 { 2002 int num_filters = 0; 2003 2004 png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); 2005 2006 if (filters & PNG_FILTER_SUB) 2007 num_filters++; 2008 2009 if (filters & PNG_FILTER_UP) 2010 num_filters++; 2011 2012 if (filters & PNG_FILTER_AVG) 2013 num_filters++; 2014 2015 if (filters & PNG_FILTER_PAETH) 2016 num_filters++; 2017 2018 if (num_filters > 1) 2019 png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr, 2020 buf_size)); 2021 } 2022 2023 /* We only need to keep the previous row if we are using one of the following 2024 * filters. 2025 */ 2026 if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) 2027 png_ptr->prev_row = png_voidcast(png_bytep, 2028 png_calloc(png_ptr, buf_size)); 2029#endif /* WRITE_FILTER */ 2030 2031#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2032 /* If interlaced, we need to set up width and height of pass */ 2033 if (png_ptr->interlaced != 0) 2034 { 2035 if ((png_ptr->transformations & PNG_INTERLACE) == 0) 2036 { 2037 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 2038 png_pass_ystart[0]) / png_pass_yinc[0]; 2039 2040 png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - 2041 png_pass_start[0]) / png_pass_inc[0]; 2042 } 2043 2044 else 2045 { 2046 png_ptr->num_rows = png_ptr->height; 2047 png_ptr->usr_width = png_ptr->width; 2048 } 2049 } 2050 2051 else 2052#endif 2053 { 2054 png_ptr->num_rows = png_ptr->height; 2055 png_ptr->usr_width = png_ptr->width; 2056 } 2057} 2058 2059/* Internal use only. Called when finished processing a row of data. */ 2060void /* PRIVATE */ 2061png_write_finish_row(png_structrp png_ptr) 2062{ 2063#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2064 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2065 2066 /* Start of interlace block */ 2067 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 2068 2069 /* Offset to next interlace block */ 2070 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2071 2072 /* Start of interlace block in the y direction */ 2073 static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 2074 2075 /* Offset to next interlace block in the y direction */ 2076 static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 2077#endif 2078 2079 png_debug(1, "in png_write_finish_row"); 2080 2081 /* Next row */ 2082 png_ptr->row_number++; 2083 2084 /* See if we are done */ 2085 if (png_ptr->row_number < png_ptr->num_rows) 2086 return; 2087 2088#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2089 /* If interlaced, go to next pass */ 2090 if (png_ptr->interlaced != 0) 2091 { 2092 png_ptr->row_number = 0; 2093 if ((png_ptr->transformations & PNG_INTERLACE) != 0) 2094 { 2095 png_ptr->pass++; 2096 } 2097 2098 else 2099 { 2100 /* Loop until we find a non-zero width or height pass */ 2101 do 2102 { 2103 png_ptr->pass++; 2104 2105 if (png_ptr->pass >= 7) 2106 break; 2107 2108 png_ptr->usr_width = (png_ptr->width + 2109 png_pass_inc[png_ptr->pass] - 1 - 2110 png_pass_start[png_ptr->pass]) / 2111 png_pass_inc[png_ptr->pass]; 2112 2113 png_ptr->num_rows = (png_ptr->height + 2114 png_pass_yinc[png_ptr->pass] - 1 - 2115 png_pass_ystart[png_ptr->pass]) / 2116 png_pass_yinc[png_ptr->pass]; 2117 2118 if ((png_ptr->transformations & PNG_INTERLACE) != 0) 2119 break; 2120 2121 } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); 2122 2123 } 2124 2125 /* Reset the row above the image for the next pass */ 2126 if (png_ptr->pass < 7) 2127 { 2128 if (png_ptr->prev_row != NULL) 2129 memset(png_ptr->prev_row, 0, 2130 (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* 2131 png_ptr->usr_bit_depth, png_ptr->width)) + 1); 2132 2133 return; 2134 } 2135 } 2136#endif 2137 2138 /* If we get here, we've just written the last row, so we need 2139 to flush the compressor */ 2140 png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); 2141} 2142 2143#ifdef PNG_WRITE_INTERLACING_SUPPORTED 2144/* Pick out the correct pixels for the interlace pass. 2145 * The basic idea here is to go through the row with a source 2146 * pointer and a destination pointer (sp and dp), and copy the 2147 * correct pixels for the pass. As the row gets compacted, 2148 * sp will always be >= dp, so we should never overwrite anything. 2149 * See the default: case for the easiest code to understand. 2150 */ 2151void /* PRIVATE */ 2152png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) 2153{ 2154 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2155 2156 /* Start of interlace block */ 2157 static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 2158 2159 /* Offset to next interlace block */ 2160 static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2161 2162 png_debug(1, "in png_do_write_interlace"); 2163 2164 /* We don't have to do anything on the last pass (6) */ 2165 if (pass < 6) 2166 { 2167 /* Each pixel depth is handled separately */ 2168 switch (row_info->pixel_depth) 2169 { 2170 case 1: 2171 { 2172 png_bytep sp; 2173 png_bytep dp; 2174 unsigned int shift; 2175 int d; 2176 int value; 2177 png_uint_32 i; 2178 png_uint_32 row_width = row_info->width; 2179 2180 dp = row; 2181 d = 0; 2182 shift = 7; 2183 2184 for (i = png_pass_start[pass]; i < row_width; 2185 i += png_pass_inc[pass]) 2186 { 2187 sp = row + (png_size_t)(i >> 3); 2188 value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; 2189 d |= (value << shift); 2190 2191 if (shift == 0) 2192 { 2193 shift = 7; 2194 *dp++ = (png_byte)d; 2195 d = 0; 2196 } 2197 2198 else 2199 shift--; 2200 2201 } 2202 if (shift != 7) 2203 *dp = (png_byte)d; 2204 2205 break; 2206 } 2207 2208 case 2: 2209 { 2210 png_bytep sp; 2211 png_bytep dp; 2212 unsigned int shift; 2213 int d; 2214 int value; 2215 png_uint_32 i; 2216 png_uint_32 row_width = row_info->width; 2217 2218 dp = row; 2219 shift = 6; 2220 d = 0; 2221 2222 for (i = png_pass_start[pass]; i < row_width; 2223 i += png_pass_inc[pass]) 2224 { 2225 sp = row + (png_size_t)(i >> 2); 2226 value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; 2227 d |= (value << shift); 2228 2229 if (shift == 0) 2230 { 2231 shift = 6; 2232 *dp++ = (png_byte)d; 2233 d = 0; 2234 } 2235 2236 else 2237 shift -= 2; 2238 } 2239 if (shift != 6) 2240 *dp = (png_byte)d; 2241 2242 break; 2243 } 2244 2245 case 4: 2246 { 2247 png_bytep sp; 2248 png_bytep dp; 2249 unsigned int shift; 2250 int d; 2251 int value; 2252 png_uint_32 i; 2253 png_uint_32 row_width = row_info->width; 2254 2255 dp = row; 2256 shift = 4; 2257 d = 0; 2258 for (i = png_pass_start[pass]; i < row_width; 2259 i += png_pass_inc[pass]) 2260 { 2261 sp = row + (png_size_t)(i >> 1); 2262 value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; 2263 d |= (value << shift); 2264 2265 if (shift == 0) 2266 { 2267 shift = 4; 2268 *dp++ = (png_byte)d; 2269 d = 0; 2270 } 2271 2272 else 2273 shift -= 4; 2274 } 2275 if (shift != 4) 2276 *dp = (png_byte)d; 2277 2278 break; 2279 } 2280 2281 default: 2282 { 2283 png_bytep sp; 2284 png_bytep dp; 2285 png_uint_32 i; 2286 png_uint_32 row_width = row_info->width; 2287 png_size_t pixel_bytes; 2288 2289 /* Start at the beginning */ 2290 dp = row; 2291 2292 /* Find out how many bytes each pixel takes up */ 2293 pixel_bytes = (row_info->pixel_depth >> 3); 2294 2295 /* Loop through the row, only looking at the pixels that matter */ 2296 for (i = png_pass_start[pass]; i < row_width; 2297 i += png_pass_inc[pass]) 2298 { 2299 /* Find out where the original pixel is */ 2300 sp = row + (png_size_t)i * pixel_bytes; 2301 2302 /* Move the pixel */ 2303 if (dp != sp) 2304 memcpy(dp, sp, pixel_bytes); 2305 2306 /* Next pixel */ 2307 dp += pixel_bytes; 2308 } 2309 break; 2310 } 2311 } 2312 /* Set new row width */ 2313 row_info->width = (row_info->width + 2314 png_pass_inc[pass] - 1 - 2315 png_pass_start[pass]) / 2316 png_pass_inc[pass]; 2317 2318 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 2319 row_info->width); 2320 } 2321} 2322#endif 2323 2324 2325/* This filters the row, chooses which filter to use, if it has not already 2326 * been specified by the application, and then writes the row out with the 2327 * chosen filter. 2328 */ 2329static void /* PRIVATE */ 2330png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, 2331 png_size_t row_bytes); 2332 2333#ifdef PNG_WRITE_FILTER_SUPPORTED 2334static png_size_t /* PRIVATE */ 2335png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, 2336 const png_size_t row_bytes, const png_size_t lmins) 2337{ 2338 png_bytep rp, dp, lp; 2339 png_size_t i; 2340 png_size_t sum = 0; 2341 int v; 2342 2343 png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; 2344 2345 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; 2346 i++, rp++, dp++) 2347 { 2348 v = *dp = *rp; 2349 sum += (v < 128) ? v : 256 - v; 2350 } 2351 2352 for (lp = png_ptr->row_buf + 1; i < row_bytes; 2353 i++, rp++, lp++, dp++) 2354 { 2355 v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 2356 sum += (v < 128) ? v : 256 - v; 2357 2358 if (sum > lmins) /* We are already worse, don't continue. */ 2359 break; 2360 } 2361 2362 return (sum); 2363} 2364 2365static png_size_t /* PRIVATE */ 2366png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, 2367 const png_size_t lmins) 2368{ 2369 png_bytep rp, dp, pp; 2370 png_size_t i; 2371 png_size_t sum = 0; 2372 int v; 2373 2374 png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; 2375 2376 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, 2377 pp = png_ptr->prev_row + 1; i < row_bytes; 2378 i++, rp++, pp++, dp++) 2379 { 2380 v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); 2381 sum += (v < 128) ? v : 256 - v; 2382 2383 if (sum > lmins) /* We are already worse, don't continue. */ 2384 break; 2385 } 2386 2387 return (sum); 2388} 2389 2390static png_size_t /* PRIVATE */ 2391png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, 2392 const png_size_t row_bytes, const png_size_t lmins) 2393{ 2394 png_bytep rp, dp, pp, lp; 2395 png_uint_32 i; 2396 png_size_t sum = 0; 2397 int v; 2398 2399 png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; 2400 2401 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, 2402 pp = png_ptr->prev_row + 1; i < bpp; i++) 2403 { 2404 v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); 2405 2406 sum += (v < 128) ? v : 256 - v; 2407 } 2408 2409 for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) 2410 { 2411 v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) 2412 & 0xff); 2413 2414 sum += (v < 128) ? v : 256 - v; 2415 2416 if (sum > lmins) /* We are already worse, don't continue. */ 2417 break; 2418 } 2419 2420 return (sum); 2421} 2422 2423static png_size_t /* PRIVATE */ 2424png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, 2425 const png_size_t row_bytes, const png_size_t lmins) 2426{ 2427 png_bytep rp, dp, pp, cp, lp; 2428 png_size_t i; 2429 png_size_t sum = 0; 2430 int v; 2431 2432 png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; 2433 2434 for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, 2435 pp = png_ptr->prev_row + 1; i < bpp; i++) 2436 { 2437 v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 2438 2439 sum += (v < 128) ? v : 256 - v; 2440 } 2441 2442 for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; 2443 i++) 2444 { 2445 int a, b, c, pa, pb, pc, p; 2446 2447 b = *pp++; 2448 c = *cp++; 2449 a = *lp++; 2450 2451 p = b - c; 2452 pc = a - c; 2453 2454#ifdef PNG_USE_ABS 2455 pa = abs(p); 2456 pb = abs(pc); 2457 pc = abs(p + pc); 2458#else 2459 pa = p < 0 ? -p : p; 2460 pb = pc < 0 ? -pc : pc; 2461 pc = (p + pc) < 0 ? -(p + pc) : p + pc; 2462#endif 2463 2464 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; 2465 2466 v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 2467 2468 sum += (v < 128) ? v : 256 - v; 2469 2470 if (sum > lmins) /* We are already worse, don't continue. */ 2471 break; 2472 } 2473 2474 return (sum); 2475} 2476#endif /* WRITE_FILTER */ 2477 2478void /* PRIVATE */ 2479png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) 2480{ 2481#ifndef PNG_WRITE_FILTER_SUPPORTED 2482 png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); 2483#else 2484 png_byte filter_to_do = png_ptr->do_filter; 2485 png_bytep row_buf; 2486 png_bytep best_row; 2487 png_uint_32 bpp; 2488 png_size_t mins; 2489 png_size_t row_bytes = row_info->rowbytes; 2490 2491 png_debug(1, "in png_write_find_filter"); 2492 2493 /* Find out how many bytes offset each pixel is */ 2494 bpp = (row_info->pixel_depth + 7) >> 3; 2495 2496 row_buf = png_ptr->row_buf; 2497 mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the 2498 running sum */; 2499 2500 /* The prediction method we use is to find which method provides the 2501 * smallest value when summing the absolute values of the distances 2502 * from zero, using anything >= 128 as negative numbers. This is known 2503 * as the "minimum sum of absolute differences" heuristic. Other 2504 * heuristics are the "weighted minimum sum of absolute differences" 2505 * (experimental and can in theory improve compression), and the "zlib 2506 * predictive" method (not implemented yet), which does test compressions 2507 * of lines using different filter methods, and then chooses the 2508 * (series of) filter(s) that give minimum compressed data size (VERY 2509 * computationally expensive). 2510 * 2511 * GRR 980525: consider also 2512 * 2513 * (1) minimum sum of absolute differences from running average (i.e., 2514 * keep running sum of non-absolute differences & count of bytes) 2515 * [track dispersion, too? restart average if dispersion too large?] 2516 * 2517 * (1b) minimum sum of absolute differences from sliding average, probably 2518 * with window size <= deflate window (usually 32K) 2519 * 2520 * (2) minimum sum of squared differences from zero or running average 2521 * (i.e., ~ root-mean-square approach) 2522 */ 2523 2524 2525 /* We don't need to test the 'no filter' case if this is the only filter 2526 * that has been chosen, as it doesn't actually do anything to the data. 2527 */ 2528 best_row = png_ptr->row_buf; 2529 2530 2531 if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE) 2532 { 2533 png_bytep rp; 2534 png_size_t sum = 0; 2535 png_size_t i; 2536 int v; 2537 2538 if (PNG_SIZE_MAX/128 <= row_bytes) 2539 { 2540 for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) 2541 { 2542 /* Check for overflow */ 2543 if (sum > PNG_SIZE_MAX/128 - 256) 2544 break; 2545 2546 v = *rp; 2547 sum += (v < 128) ? v : 256 - v; 2548 } 2549 } 2550 else /* Overflow is not possible */ 2551 { 2552 for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) 2553 { 2554 v = *rp; 2555 sum += (v < 128) ? v : 256 - v; 2556 } 2557 } 2558 2559 mins = sum; 2560 } 2561 2562 /* Sub filter */ 2563 if (filter_to_do == PNG_FILTER_SUB) 2564 /* It's the only filter so no testing is needed */ 2565 { 2566 (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins); 2567 best_row = png_ptr->try_row; 2568 } 2569 2570 else if ((filter_to_do & PNG_FILTER_SUB) != 0) 2571 { 2572 png_size_t sum; 2573 png_size_t lmins = mins; 2574 2575 sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); 2576 2577 if (sum < mins) 2578 { 2579 mins = sum; 2580 best_row = png_ptr->try_row; 2581 if (png_ptr->tst_row != NULL) 2582 { 2583 png_ptr->try_row = png_ptr->tst_row; 2584 png_ptr->tst_row = best_row; 2585 } 2586 } 2587 } 2588 2589 /* Up filter */ 2590 if (filter_to_do == PNG_FILTER_UP) 2591 { 2592 (void) png_setup_up_row(png_ptr, row_bytes, mins); 2593 best_row = png_ptr->try_row; 2594 } 2595 2596 else if ((filter_to_do & PNG_FILTER_UP) != 0) 2597 { 2598 png_size_t sum; 2599 png_size_t lmins = mins; 2600 2601 sum = png_setup_up_row(png_ptr, row_bytes, lmins); 2602 2603 if (sum < mins) 2604 { 2605 mins = sum; 2606 best_row = png_ptr->try_row; 2607 if (png_ptr->tst_row != NULL) 2608 { 2609 png_ptr->try_row = png_ptr->tst_row; 2610 png_ptr->tst_row = best_row; 2611 } 2612 } 2613 } 2614 2615 /* Avg filter */ 2616 if (filter_to_do == PNG_FILTER_AVG) 2617 { 2618 (void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins); 2619 best_row = png_ptr->try_row; 2620 } 2621 2622 else if ((filter_to_do & PNG_FILTER_AVG) != 0) 2623 { 2624 png_size_t sum; 2625 png_size_t lmins = mins; 2626 2627 sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); 2628 2629 if (sum < mins) 2630 { 2631 mins = sum; 2632 best_row = png_ptr->try_row; 2633 if (png_ptr->tst_row != NULL) 2634 { 2635 png_ptr->try_row = png_ptr->tst_row; 2636 png_ptr->tst_row = best_row; 2637 } 2638 } 2639 } 2640 2641 /* Paeth filter */ 2642 if ((filter_to_do == PNG_FILTER_PAETH) != 0) 2643 { 2644 (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins); 2645 best_row = png_ptr->try_row; 2646 } 2647 2648 else if ((filter_to_do & PNG_FILTER_PAETH) != 0) 2649 { 2650 png_size_t sum; 2651 png_size_t lmins = mins; 2652 2653 sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); 2654 2655 if (sum < mins) 2656 { 2657 best_row = png_ptr->try_row; 2658 if (png_ptr->tst_row != NULL) 2659 { 2660 png_ptr->try_row = png_ptr->tst_row; 2661 png_ptr->tst_row = best_row; 2662 } 2663 } 2664 } 2665 2666 /* Do the actual writing of the filtered row data from the chosen filter. */ 2667 png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); 2668 2669#endif /* WRITE_FILTER */ 2670} 2671 2672 2673/* Do the actual writing of a previously filtered row. */ 2674static void 2675png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, 2676 png_size_t full_row_length/*includes filter byte*/) 2677{ 2678 png_debug(1, "in png_write_filtered_row"); 2679 2680 png_debug1(2, "filter = %d", filtered_row[0]); 2681 2682 png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); 2683 2684#ifdef PNG_WRITE_FILTER_SUPPORTED 2685 /* Swap the current and previous rows */ 2686 if (png_ptr->prev_row != NULL) 2687 { 2688 png_bytep tptr; 2689 2690 tptr = png_ptr->prev_row; 2691 png_ptr->prev_row = png_ptr->row_buf; 2692 png_ptr->row_buf = tptr; 2693 } 2694#endif /* WRITE_FILTER */ 2695 2696 /* Finish row - updates counters and flushes zlib if last row */ 2697 png_write_finish_row(png_ptr); 2698 2699#ifdef PNG_WRITE_FLUSH_SUPPORTED 2700 png_ptr->flush_rows++; 2701 2702 if (png_ptr->flush_dist > 0 && 2703 png_ptr->flush_rows >= png_ptr->flush_dist) 2704 { 2705 png_write_flush(png_ptr); 2706 } 2707#endif /* WRITE_FLUSH */ 2708} 2709#endif /* WRITE */ 2710