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