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