1 |
1 |
2 /* pngwutil.c - utilities to write a PNG file |
2 /* pngwutil.c - utilities to write a PNG file |
3 * |
3 * |
4 * Last changed in libpng 1.2.40 [September 10, 2009] |
4 * Last changed in libpng 1.4.0 [January 3, 2010] |
5 * Copyright (c) 1998-2009 Glenn Randers-Pehrson |
5 * Copyright (c) 1998-2010 Glenn Randers-Pehrson |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
8 * |
8 * |
9 * This code is released under the libpng license. |
9 * This code is released under the libpng license. |
10 * For conditions of distribution and use, see the disclaimer |
10 * For conditions of distribution and use, see the disclaimer |
11 * and license in png.h |
11 * and license in png.h |
12 */ |
12 */ |
13 |
13 |
14 #define PNG_INTERNAL |
14 #define PNG_NO_PEDANTIC_WARNINGS |
15 #include "png.h" |
15 #include "png.h" |
16 #ifdef PNG_WRITE_SUPPORTED |
16 #ifdef PNG_WRITE_SUPPORTED |
|
17 #include "pngpriv.h" |
17 |
18 |
18 /* Place a 32-bit number into a buffer in PNG byte order. We work |
19 /* Place a 32-bit number into a buffer in PNG byte order. We work |
19 * with unsigned numbers for convenience, although one supported |
20 * with unsigned numbers for convenience, although one supported |
20 * ancillary chunk uses signed (two's complement) numbers. |
21 * ancillary chunk uses signed (two's complement) numbers. |
21 */ |
22 */ |
56 * the magic bytes of the signature, or more likely, the PNG stream is |
59 * the magic bytes of the signature, or more likely, the PNG stream is |
57 * being embedded into another stream and doesn't need its own signature, |
60 * being embedded into another stream and doesn't need its own signature, |
58 * we should call png_set_sig_bytes() to tell libpng how many of the |
61 * we should call png_set_sig_bytes() to tell libpng how many of the |
59 * bytes have already been written. |
62 * bytes have already been written. |
60 */ |
63 */ |
61 void /* PRIVATE */ |
64 void PNGAPI |
62 png_write_sig(png_structp png_ptr) |
65 png_write_sig(png_structp png_ptr) |
63 { |
66 { |
64 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; |
67 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; |
|
68 |
|
69 #ifdef PNG_IO_STATE_SUPPORTED |
|
70 /* Inform the I/O callback that the signature is being written */ |
|
71 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; |
|
72 #endif |
65 |
73 |
66 /* Write the rest of the 8 byte signature */ |
74 /* Write the rest of the 8 byte signature */ |
67 png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], |
75 png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], |
68 (png_size_t)(8 - png_ptr->sig_bytes)); |
76 (png_size_t)(8 - png_ptr->sig_bytes)); |
69 if (png_ptr->sig_bytes < 3) |
77 if (png_ptr->sig_bytes < 3) |
104 (unsigned long)length); |
112 (unsigned long)length); |
105 |
113 |
106 if (png_ptr == NULL) |
114 if (png_ptr == NULL) |
107 return; |
115 return; |
108 |
116 |
|
117 #ifdef PNG_IO_STATE_SUPPORTED |
|
118 /* Inform the I/O callback that the chunk header is being written. |
|
119 * PNG_IO_CHUNK_HDR requires a single I/O call. |
|
120 */ |
|
121 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; |
|
122 #endif |
|
123 |
109 /* Write the length and the chunk name */ |
124 /* Write the length and the chunk name */ |
110 png_save_uint_32(buf, length); |
125 png_save_uint_32(buf, length); |
111 png_memcpy(buf + 4, chunk_name, 4); |
126 png_memcpy(buf + 4, chunk_name, 4); |
112 png_write_data(png_ptr, buf, (png_size_t)8); |
127 png_write_data(png_ptr, buf, (png_size_t)8); |
113 /* Put the chunk name into png_ptr->chunk_name */ |
128 /* Put the chunk name into png_ptr->chunk_name */ |
114 png_memcpy(png_ptr->chunk_name, chunk_name, 4); |
129 png_memcpy(png_ptr->chunk_name, chunk_name, 4); |
115 /* Reset the crc and run it over the chunk name */ |
130 /* Reset the crc and run it over the chunk name */ |
116 png_reset_crc(png_ptr); |
131 png_reset_crc(png_ptr); |
117 png_calculate_crc(png_ptr, chunk_name, (png_size_t)4); |
132 png_calculate_crc(png_ptr, chunk_name, 4); |
|
133 |
|
134 #ifdef PNG_IO_STATE_SUPPORTED |
|
135 /* Inform the I/O callback that chunk data will (possibly) be written. |
|
136 * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. |
|
137 */ |
|
138 png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; |
|
139 #endif |
118 } |
140 } |
119 |
141 |
120 /* Write the data of a PNG chunk started with png_write_chunk_start(). |
142 /* Write the data of a PNG chunk started with png_write_chunk_start(). |
121 * Note that multiple calls to this function are allowed, and that the |
143 * Note that multiple calls to this function are allowed, and that the |
122 * sum of the lengths from these calls *must* add up to the total_length |
144 * sum of the lengths from these calls *must* add up to the total_length |
249 { |
278 { |
250 png_charpp old_ptr; |
279 png_charpp old_ptr; |
251 |
280 |
252 old_ptr = comp->output_ptr; |
281 old_ptr = comp->output_ptr; |
253 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
282 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
254 (png_uint_32) |
283 (png_alloc_size_t) |
255 (comp->max_output_ptr * png_sizeof(png_charpp))); |
284 (comp->max_output_ptr * png_sizeof(png_charpp))); |
256 png_memcpy(comp->output_ptr, old_ptr, old_max |
285 png_memcpy(comp->output_ptr, old_ptr, old_max |
257 * png_sizeof(png_charp)); |
286 * png_sizeof(png_charp)); |
258 png_free(png_ptr, old_ptr); |
287 png_free(png_ptr, old_ptr); |
259 } |
288 } |
260 else |
289 else |
261 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
290 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
262 (png_uint_32) |
291 (png_alloc_size_t) |
263 (comp->max_output_ptr * png_sizeof(png_charp))); |
292 (comp->max_output_ptr * png_sizeof(png_charp))); |
264 } |
293 } |
265 |
294 |
266 /* Save the data */ |
295 /* Save the data */ |
267 comp->output_ptr[comp->num_output_ptr] = |
296 comp->output_ptr[comp->num_output_ptr] = |
268 (png_charp)png_malloc(png_ptr, |
297 (png_charp)png_malloc(png_ptr, |
269 (png_uint_32)png_ptr->zbuf_size); |
298 (png_alloc_size_t)png_ptr->zbuf_size); |
270 png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, |
299 png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, |
271 png_ptr->zbuf_size); |
300 png_ptr->zbuf_size); |
272 comp->num_output_ptr++; |
301 comp->num_output_ptr++; |
273 |
302 |
274 /* and reset the buffer */ |
303 /* and reset the buffer */ |
301 png_charpp old_ptr; |
330 png_charpp old_ptr; |
302 |
331 |
303 old_ptr = comp->output_ptr; |
332 old_ptr = comp->output_ptr; |
304 /* This could be optimized to realloc() */ |
333 /* This could be optimized to realloc() */ |
305 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
334 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
306 (png_uint_32)(comp->max_output_ptr * |
335 (png_alloc_size_t)(comp->max_output_ptr * |
307 png_sizeof(png_charp))); |
336 png_sizeof(png_charp))); |
308 png_memcpy(comp->output_ptr, old_ptr, |
337 png_memcpy(comp->output_ptr, old_ptr, |
309 old_max * png_sizeof(png_charp)); |
338 old_max * png_sizeof(png_charp)); |
310 png_free(png_ptr, old_ptr); |
339 png_free(png_ptr, old_ptr); |
311 } |
340 } |
312 else |
341 else |
313 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
342 comp->output_ptr = (png_charpp)png_malloc(png_ptr, |
314 (png_uint_32)(comp->max_output_ptr * |
343 (png_alloc_size_t)(comp->max_output_ptr * |
315 png_sizeof(png_charp))); |
344 png_sizeof(png_charp))); |
316 } |
345 } |
317 |
346 |
318 /* Save the data */ |
347 /* Save the data */ |
319 comp->output_ptr[comp->num_output_ptr] = |
348 comp->output_ptr[comp->num_output_ptr] = |
320 (png_charp)png_malloc(png_ptr, |
349 (png_charp)png_malloc(png_ptr, |
321 (png_uint_32)png_ptr->zbuf_size); |
350 (png_alloc_size_t)png_ptr->zbuf_size); |
322 png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, |
351 png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, |
323 png_ptr->zbuf_size); |
352 png_ptr->zbuf_size); |
324 comp->num_output_ptr++; |
353 comp->num_output_ptr++; |
325 |
354 |
326 /* and reset the buffer pointers */ |
355 /* and reset the buffer pointers */ |
364 for (i = 0; i < comp->num_output_ptr; i++) |
393 for (i = 0; i < comp->num_output_ptr; i++) |
365 { |
394 { |
366 png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i], |
395 png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i], |
367 (png_size_t)png_ptr->zbuf_size); |
396 (png_size_t)png_ptr->zbuf_size); |
368 png_free(png_ptr, comp->output_ptr[i]); |
397 png_free(png_ptr, comp->output_ptr[i]); |
369 comp->output_ptr[i]=NULL; |
|
370 } |
398 } |
371 if (comp->max_output_ptr != 0) |
399 if (comp->max_output_ptr != 0) |
372 png_free(png_ptr, comp->output_ptr); |
400 png_free(png_ptr, comp->output_ptr); |
373 comp->output_ptr=NULL; |
|
374 /* Write anything left in zbuf */ |
401 /* Write anything left in zbuf */ |
375 if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) |
402 if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) |
376 png_write_chunk_data(png_ptr, png_ptr->zbuf, |
403 png_write_chunk_data(png_ptr, png_ptr->zbuf, |
377 (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); |
404 (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); |
378 |
405 |
605 png_ptr->num_palette = (png_uint_16)num_pal; |
628 png_ptr->num_palette = (png_uint_16)num_pal; |
606 png_debug1(3, "num_palette = %d", png_ptr->num_palette); |
629 png_debug1(3, "num_palette = %d", png_ptr->num_palette); |
607 |
630 |
608 png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, |
631 png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, |
609 (png_uint_32)(num_pal * 3)); |
632 (png_uint_32)(num_pal * 3)); |
610 #ifndef PNG_NO_POINTER_INDEXING |
633 #ifdef PNG_POINTER_INDEXING_SUPPORTED |
611 for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) |
634 for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) |
612 { |
635 { |
613 buf[0] = pal_ptr->red; |
636 buf[0] = pal_ptr->red; |
614 buf[1] = pal_ptr->green; |
637 buf[1] = pal_ptr->green; |
615 buf[2] = pal_ptr->blue; |
638 buf[2] = pal_ptr->blue; |
687 |
708 |
688 /* Write an IEND chunk */ |
709 /* Write an IEND chunk */ |
689 void /* PRIVATE */ |
710 void /* PRIVATE */ |
690 png_write_IEND(png_structp png_ptr) |
711 png_write_IEND(png_structp png_ptr) |
691 { |
712 { |
692 #ifdef PNG_USE_LOCAL_ARRAYS |
|
693 PNG_IEND; |
713 PNG_IEND; |
694 #endif |
|
695 |
714 |
696 png_debug(1, "in png_write_IEND"); |
715 png_debug(1, "in png_write_IEND"); |
697 |
716 |
698 png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, |
717 png_write_chunk(png_ptr, (png_bytep)png_IEND, NULL, |
699 (png_size_t)0); |
718 (png_size_t)0); |
700 png_ptr->mode |= PNG_HAVE_IEND; |
719 png_ptr->mode |= PNG_HAVE_IEND; |
701 } |
720 } |
702 |
721 |
703 #if defined(PNG_WRITE_gAMA_SUPPORTED) |
722 #ifdef PNG_WRITE_gAMA_SUPPORTED |
704 /* Write a gAMA chunk */ |
723 /* Write a gAMA chunk */ |
705 #ifdef PNG_FLOATING_POINT_SUPPORTED |
724 #ifdef PNG_FLOATING_POINT_SUPPORTED |
706 void /* PRIVATE */ |
725 void /* PRIVATE */ |
707 png_write_gAMA(png_structp png_ptr, double file_gamma) |
726 png_write_gAMA(png_structp png_ptr, double file_gamma) |
708 { |
727 { |
709 #ifdef PNG_USE_LOCAL_ARRAYS |
|
710 PNG_gAMA; |
728 PNG_gAMA; |
711 #endif |
|
712 png_uint_32 igamma; |
729 png_uint_32 igamma; |
713 png_byte buf[4]; |
730 png_byte buf[4]; |
714 |
731 |
715 png_debug(1, "in png_write_gAMA"); |
732 png_debug(1, "in png_write_gAMA"); |
716 |
733 |
756 buf[0]=(png_byte)srgb_intent; |
769 buf[0]=(png_byte)srgb_intent; |
757 png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); |
770 png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); |
758 } |
771 } |
759 #endif |
772 #endif |
760 |
773 |
761 #if defined(PNG_WRITE_iCCP_SUPPORTED) |
774 #ifdef PNG_WRITE_iCCP_SUPPORTED |
762 /* Write an iCCP chunk */ |
775 /* Write an iCCP chunk */ |
763 void /* PRIVATE */ |
776 void /* PRIVATE */ |
764 png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, |
777 png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, |
765 png_charp profile, int profile_len) |
778 png_charp profile, int profile_len) |
766 { |
779 { |
767 #ifdef PNG_USE_LOCAL_ARRAYS |
|
768 PNG_iCCP; |
780 PNG_iCCP; |
769 #endif |
|
770 png_size_t name_len; |
781 png_size_t name_len; |
771 png_charp new_name; |
782 png_charp new_name; |
772 compression_state comp; |
783 compression_state comp; |
773 int embedded_profile_len = 0; |
784 int embedded_profile_len = 0; |
774 |
785 |
837 png_write_chunk_end(png_ptr); |
848 png_write_chunk_end(png_ptr); |
838 png_free(png_ptr, new_name); |
849 png_free(png_ptr, new_name); |
839 } |
850 } |
840 #endif |
851 #endif |
841 |
852 |
842 #if defined(PNG_WRITE_sPLT_SUPPORTED) |
853 #ifdef PNG_WRITE_sPLT_SUPPORTED |
843 /* Write a sPLT chunk */ |
854 /* Write a sPLT chunk */ |
844 void /* PRIVATE */ |
855 void /* PRIVATE */ |
845 png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) |
856 png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) |
846 { |
857 { |
847 #ifdef PNG_USE_LOCAL_ARRAYS |
|
848 PNG_sPLT; |
858 PNG_sPLT; |
849 #endif |
|
850 png_size_t name_len; |
859 png_size_t name_len; |
851 png_charp new_name; |
860 png_charp new_name; |
852 png_byte entrybuf[10]; |
861 png_byte entrybuf[10]; |
853 int entry_size = (spalette->depth == 8 ? 6 : 10); |
862 png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); |
854 int palette_size = entry_size * spalette->nentries; |
863 png_size_t palette_size = entry_size * spalette->nentries; |
855 png_sPLT_entryp ep; |
864 png_sPLT_entryp ep; |
856 #ifdef PNG_NO_POINTER_INDEXING |
865 #ifndef PNG_POINTER_INDEXING_SUPPORTED |
857 int i; |
866 int i; |
858 #endif |
867 #endif |
859 |
868 |
860 png_debug(1, "in png_write_sPLT"); |
869 png_debug(1, "in png_write_sPLT"); |
861 |
870 |
868 png_write_chunk_data(png_ptr, (png_bytep)new_name, |
877 png_write_chunk_data(png_ptr, (png_bytep)new_name, |
869 (png_size_t)(name_len + 1)); |
878 (png_size_t)(name_len + 1)); |
870 png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1); |
879 png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1); |
871 |
880 |
872 /* Loop through each palette entry, writing appropriately */ |
881 /* Loop through each palette entry, writing appropriately */ |
873 #ifndef PNG_NO_POINTER_INDEXING |
882 #ifdef PNG_POINTER_INDEXING_SUPPORTED |
874 for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++) |
883 for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++) |
875 { |
884 { |
876 if (spalette->depth == 8) |
885 if (spalette->depth == 8) |
877 { |
886 { |
878 entrybuf[0] = (png_byte)ep->red; |
887 entrybuf[0] = (png_byte)ep->red; |
975 |
982 |
976 png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); |
983 png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); |
977 } |
984 } |
978 #endif |
985 #endif |
979 |
986 |
980 #if defined(PNG_WRITE_cHRM_SUPPORTED) |
987 #ifdef PNG_WRITE_cHRM_SUPPORTED |
981 /* Write the cHRM chunk */ |
988 /* Write the cHRM chunk */ |
982 #ifdef PNG_FLOATING_POINT_SUPPORTED |
989 #ifdef PNG_FLOATING_POINT_SUPPORTED |
983 void /* PRIVATE */ |
990 void /* PRIVATE */ |
984 png_write_cHRM(png_structp png_ptr, double white_x, double white_y, |
991 png_write_cHRM(png_structp png_ptr, double white_x, double white_y, |
985 double red_x, double red_y, double green_x, double green_y, |
992 double red_x, double red_y, double green_x, double green_y, |
986 double blue_x, double blue_y) |
993 double blue_x, double blue_y) |
987 { |
994 { |
988 #ifdef PNG_USE_LOCAL_ARRAYS |
|
989 PNG_cHRM; |
995 PNG_cHRM; |
990 #endif |
|
991 png_byte buf[32]; |
996 png_byte buf[32]; |
992 |
997 |
993 png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, |
998 png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, |
994 int_green_x, int_green_y, int_blue_x, int_blue_y; |
999 int_green_x, int_green_y, int_blue_x, int_blue_y; |
995 |
1000 |
1002 int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5); |
1007 int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5); |
1003 int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5); |
1008 int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5); |
1004 int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5); |
1009 int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5); |
1005 int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5); |
1010 int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5); |
1006 |
1011 |
1007 #if !defined(PNG_NO_CHECK_cHRM) |
1012 #ifdef PNG_CHECK_cHRM_SUPPORTED |
1008 if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y, |
1013 if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y, |
1009 int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y)) |
1014 int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y)) |
1010 #endif |
1015 #endif |
1011 { |
1016 { |
1012 /* Each value is saved in 1/100,000ths */ |
1017 /* Each value is saved in 1/100,000ths */ |
1032 png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, |
1037 png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, |
1033 png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, |
1038 png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, |
1034 png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, |
1039 png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, |
1035 png_fixed_point blue_y) |
1040 png_fixed_point blue_y) |
1036 { |
1041 { |
1037 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1038 PNG_cHRM; |
1042 PNG_cHRM; |
1039 #endif |
|
1040 png_byte buf[32]; |
1043 png_byte buf[32]; |
1041 |
1044 |
1042 png_debug(1, "in png_write_cHRM"); |
1045 png_debug(1, "in png_write_cHRM"); |
1043 |
1046 |
1044 /* Each value is saved in 1/100,000ths */ |
1047 /* Each value is saved in 1/100,000ths */ |
1045 #if !defined(PNG_NO_CHECK_cHRM) |
1048 #ifdef PNG_CHECK_cHRM_SUPPORTED |
1046 if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, |
1049 if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, |
1047 green_x, green_y, blue_x, blue_y)) |
1050 green_x, green_y, blue_x, blue_y)) |
1048 #endif |
1051 #endif |
1049 { |
1052 { |
1050 png_save_uint_32(buf, (png_uint_32)white_x); |
1053 png_save_uint_32(buf, (png_uint_32)white_x); |
1120 png_warning(png_ptr, "Can't write tRNS with an alpha channel"); |
1121 png_warning(png_ptr, "Can't write tRNS with an alpha channel"); |
1121 } |
1122 } |
1122 } |
1123 } |
1123 #endif |
1124 #endif |
1124 |
1125 |
1125 #if defined(PNG_WRITE_bKGD_SUPPORTED) |
1126 #ifdef PNG_WRITE_bKGD_SUPPORTED |
1126 /* Write the background chunk */ |
1127 /* Write the background chunk */ |
1127 void /* PRIVATE */ |
1128 void /* PRIVATE */ |
1128 png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) |
1129 png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) |
1129 { |
1130 { |
1130 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1131 PNG_bKGD; |
1131 PNG_bKGD; |
1132 #endif |
|
1133 png_byte buf[6]; |
1132 png_byte buf[6]; |
1134 |
1133 |
1135 png_debug(1, "in png_write_bKGD"); |
1134 png_debug(1, "in png_write_bKGD"); |
1136 |
1135 |
1137 if (color_type == PNG_COLOR_TYPE_PALETTE) |
1136 if (color_type == PNG_COLOR_TYPE_PALETTE) |
1138 { |
1137 { |
1139 if ( |
1138 if ( |
1140 #if defined(PNG_MNG_FEATURES_SUPPORTED) |
1139 #ifdef PNG_MNG_FEATURES_SUPPORTED |
1141 (png_ptr->num_palette || |
1140 (png_ptr->num_palette || |
1142 (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && |
1141 (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && |
1143 #endif |
1142 #endif |
1144 back->index >= png_ptr->num_palette) |
1143 back->index >= png_ptr->num_palette) |
1145 { |
1144 { |
1439 /* Close the chunk */ |
1431 /* Close the chunk */ |
1440 png_write_chunk_end(png_ptr); |
1432 png_write_chunk_end(png_ptr); |
1441 } |
1433 } |
1442 #endif |
1434 #endif |
1443 |
1435 |
1444 #if defined(PNG_WRITE_iTXt_SUPPORTED) |
1436 #ifdef PNG_WRITE_iTXt_SUPPORTED |
1445 /* Write an iTXt chunk */ |
1437 /* Write an iTXt chunk */ |
1446 void /* PRIVATE */ |
1438 void /* PRIVATE */ |
1447 png_write_iTXt(png_structp png_ptr, int compression, png_charp key, |
1439 png_write_iTXt(png_structp png_ptr, int compression, png_charp key, |
1448 png_charp lang, png_charp lang_key, png_charp text) |
1440 png_charp lang, png_charp lang_key, png_charp text) |
1449 { |
1441 { |
1450 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1451 PNG_iTXt; |
1442 PNG_iTXt; |
1452 #endif |
|
1453 png_size_t lang_len, key_len, lang_key_len, text_len; |
1443 png_size_t lang_len, key_len, lang_key_len, text_len; |
1454 png_charp new_lang; |
1444 png_charp new_lang; |
1455 png_charp new_key = NULL; |
1445 png_charp new_key = NULL; |
1456 png_byte cbuf[2]; |
1446 png_byte cbuf[2]; |
1457 compression_state comp; |
1447 compression_state comp; |
1551 buf[8] = (png_byte)unit_type; |
1539 buf[8] = (png_byte)unit_type; |
1552 |
1540 |
1553 png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); |
1541 png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); |
1554 } |
1542 } |
1555 #endif |
1543 #endif |
1556 #if defined(PNG_WRITE_pCAL_SUPPORTED) |
1544 #ifdef PNG_WRITE_pCAL_SUPPORTED |
1557 /* Write the pCAL chunk (described in the PNG extensions document) */ |
1545 /* Write the pCAL chunk (described in the PNG extensions document) */ |
1558 void /* PRIVATE */ |
1546 void /* PRIVATE */ |
1559 png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, |
1547 png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, |
1560 png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) |
1548 png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) |
1561 { |
1549 { |
1562 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1563 PNG_pCAL; |
1550 PNG_pCAL; |
1564 #endif |
|
1565 png_size_t purpose_len, units_len, total_len; |
1551 png_size_t purpose_len, units_len, total_len; |
1566 png_uint_32p params_len; |
1552 png_uint_32p params_len; |
1567 png_byte buf[10]; |
1553 png_byte buf[10]; |
1568 png_charp new_purpose; |
1554 png_charp new_purpose; |
1569 int i; |
1555 int i; |
1578 units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); |
1564 units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); |
1579 png_debug1(3, "pCAL units length = %d", (int)units_len); |
1565 png_debug1(3, "pCAL units length = %d", (int)units_len); |
1580 total_len = purpose_len + units_len + 10; |
1566 total_len = purpose_len + units_len + 10; |
1581 |
1567 |
1582 params_len = (png_uint_32p)png_malloc(png_ptr, |
1568 params_len = (png_uint_32p)png_malloc(png_ptr, |
1583 (png_uint_32)(nparams * png_sizeof(png_uint_32))); |
1569 (png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); |
1584 |
1570 |
1585 /* Find the length of each parameter, making sure we don't count the |
1571 /* Find the length of each parameter, making sure we don't count the |
1586 null terminator for the last parameter. */ |
1572 null terminator for the last parameter. */ |
1587 for (i = 0; i < nparams; i++) |
1573 for (i = 0; i < nparams; i++) |
1588 { |
1574 { |
1614 png_free(png_ptr, params_len); |
1600 png_free(png_ptr, params_len); |
1615 png_write_chunk_end(png_ptr); |
1601 png_write_chunk_end(png_ptr); |
1616 } |
1602 } |
1617 #endif |
1603 #endif |
1618 |
1604 |
1619 #if defined(PNG_WRITE_sCAL_SUPPORTED) |
1605 #ifdef PNG_WRITE_sCAL_SUPPORTED |
1620 /* Write the sCAL chunk */ |
1606 /* Write the sCAL chunk */ |
1621 #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) |
1607 #if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) |
1622 void /* PRIVATE */ |
1608 void /* PRIVATE */ |
1623 png_write_sCAL(png_structp png_ptr, int unit, double width, double height) |
1609 png_write_sCAL(png_structp png_ptr, int unit, double width, double height) |
1624 { |
1610 { |
1625 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1626 PNG_sCAL; |
1611 PNG_sCAL; |
1627 #endif |
|
1628 char buf[64]; |
1612 char buf[64]; |
1629 png_size_t total_len; |
1613 png_size_t total_len; |
1630 |
1614 |
1631 png_debug(1, "in png_write_sCAL"); |
1615 png_debug(1, "in png_write_sCAL"); |
1632 |
1616 |
1633 buf[0] = (char)unit; |
1617 buf[0] = (char)unit; |
1634 #if defined(_WIN32_WCE) |
|
1635 /* sprintf() function is not supported on WindowsCE */ |
|
1636 { |
|
1637 wchar_t wc_buf[32]; |
|
1638 size_t wc_len; |
|
1639 swprintf(wc_buf, TEXT("%12.12e"), width); |
|
1640 wc_len = wcslen(wc_buf); |
|
1641 WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL); |
|
1642 total_len = wc_len + 2; |
|
1643 swprintf(wc_buf, TEXT("%12.12e"), height); |
|
1644 wc_len = wcslen(wc_buf); |
|
1645 WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len, |
|
1646 NULL, NULL); |
|
1647 total_len += wc_len; |
|
1648 } |
|
1649 #else |
|
1650 png_snprintf(buf + 1, 63, "%12.12e", width); |
1618 png_snprintf(buf + 1, 63, "%12.12e", width); |
1651 total_len = 1 + png_strlen(buf + 1) + 1; |
1619 total_len = 1 + png_strlen(buf + 1) + 1; |
1652 png_snprintf(buf + total_len, 64-total_len, "%12.12e", height); |
1620 png_snprintf(buf + total_len, 64-total_len, "%12.12e", height); |
1653 total_len += png_strlen(buf + total_len); |
1621 total_len += png_strlen(buf + total_len); |
1654 #endif |
|
1655 |
1622 |
1656 png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); |
1623 png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); |
1657 png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len); |
1624 png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len); |
1658 } |
1625 } |
1659 #else |
1626 #else |
1660 #ifdef PNG_FIXED_POINT_SUPPORTED |
1627 #ifdef PNG_FIXED_POINT_SUPPORTED |
1661 void /* PRIVATE */ |
1628 void /* PRIVATE */ |
1662 png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, |
1629 png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, |
1663 png_charp height) |
1630 png_charp height) |
1664 { |
1631 { |
1665 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1666 PNG_sCAL; |
1632 PNG_sCAL; |
1667 #endif |
|
1668 png_byte buf[64]; |
1633 png_byte buf[64]; |
1669 png_size_t wlen, hlen, total_len; |
1634 png_size_t wlen, hlen, total_len; |
1670 |
1635 |
1671 png_debug(1, "in png_write_sCAL_s"); |
1636 png_debug(1, "in png_write_sCAL_s"); |
1672 |
1637 |
1713 |
1676 |
1714 png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9); |
1677 png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9); |
1715 } |
1678 } |
1716 #endif |
1679 #endif |
1717 |
1680 |
1718 #if defined(PNG_WRITE_tIME_SUPPORTED) |
1681 #ifdef PNG_WRITE_tIME_SUPPORTED |
1719 /* Write the tIME chunk. Use either png_convert_from_struct_tm() |
1682 /* Write the tIME chunk. Use either png_convert_from_struct_tm() |
1720 * or png_convert_from_time_t(), or fill in the structure yourself. |
1683 * or png_convert_from_time_t(), or fill in the structure yourself. |
1721 */ |
1684 */ |
1722 void /* PRIVATE */ |
1685 void /* PRIVATE */ |
1723 png_write_tIME(png_structp png_ptr, png_timep mod_time) |
1686 png_write_tIME(png_structp png_ptr, png_timep mod_time) |
1724 { |
1687 { |
1725 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1726 PNG_tIME; |
1688 PNG_tIME; |
1727 #endif |
|
1728 png_byte buf[7]; |
1689 png_byte buf[7]; |
1729 |
1690 |
1730 png_debug(1, "in png_write_tIME"); |
1691 png_debug(1, "in png_write_tIME"); |
1731 |
1692 |
1732 if (mod_time->month > 12 || mod_time->month < 1 || |
1693 if (mod_time->month > 12 || mod_time->month < 1 || |
1766 int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
1726 int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
1767 |
1727 |
1768 /* Offset to next interlace block in the y direction */ |
1728 /* Offset to next interlace block in the y direction */ |
1769 int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
1729 int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
1770 #endif |
1730 #endif |
1771 #endif |
|
1772 |
1731 |
1773 png_size_t buf_size; |
1732 png_size_t buf_size; |
1774 |
1733 |
1775 png_debug(1, "in png_write_start_row"); |
1734 png_debug(1, "in png_write_start_row"); |
1776 |
1735 |
1777 buf_size = (png_size_t)(PNG_ROWBYTES( |
1736 buf_size = (png_size_t)(PNG_ROWBYTES( |
1778 png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); |
1737 png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); |
1779 |
1738 |
1780 /* Set up row buffer */ |
1739 /* Set up row buffer */ |
1781 png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, |
1740 png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, |
1782 (png_uint_32)buf_size); |
1741 (png_alloc_size_t)buf_size); |
1783 png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; |
1742 png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; |
1784 |
1743 |
1785 #ifndef PNG_NO_WRITE_FILTER |
1744 #ifdef PNG_WRITE_FILTER_SUPPORTED |
1786 /* Set up filtering buffer, if using this filter */ |
1745 /* Set up filtering buffer, if using this filter */ |
1787 if (png_ptr->do_filter & PNG_FILTER_SUB) |
1746 if (png_ptr->do_filter & PNG_FILTER_SUB) |
1788 { |
1747 { |
1789 png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, |
1748 png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, |
1790 (png_uint_32)(png_ptr->rowbytes + 1)); |
1749 (png_alloc_size_t)(png_ptr->rowbytes + 1)); |
1791 png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; |
1750 png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; |
1792 } |
1751 } |
1793 |
1752 |
1794 /* We only need to keep the previous row if we are using one of these. */ |
1753 /* We only need to keep the previous row if we are using one of these. */ |
1795 if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) |
1754 if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) |
1796 { |
1755 { |
1797 /* Set up previous row buffer */ |
1756 /* Set up previous row buffer */ |
1798 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, |
1757 png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, |
1799 (png_uint_32)buf_size); |
1758 (png_alloc_size_t)buf_size); |
1800 png_memset(png_ptr->prev_row, 0, buf_size); |
|
1801 |
1759 |
1802 if (png_ptr->do_filter & PNG_FILTER_UP) |
1760 if (png_ptr->do_filter & PNG_FILTER_UP) |
1803 { |
1761 { |
1804 png_ptr->up_row = (png_bytep)png_malloc(png_ptr, |
1762 png_ptr->up_row = (png_bytep)png_malloc(png_ptr, |
1805 (png_uint_32)(png_ptr->rowbytes + 1)); |
1763 (png_size_t)(png_ptr->rowbytes + 1)); |
1806 png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; |
1764 png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; |
1807 } |
1765 } |
1808 |
1766 |
1809 if (png_ptr->do_filter & PNG_FILTER_AVG) |
1767 if (png_ptr->do_filter & PNG_FILTER_AVG) |
1810 { |
1768 { |
1811 png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, |
1769 png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, |
1812 (png_uint_32)(png_ptr->rowbytes + 1)); |
1770 (png_alloc_size_t)(png_ptr->rowbytes + 1)); |
1813 png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; |
1771 png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; |
1814 } |
1772 } |
1815 |
1773 |
1816 if (png_ptr->do_filter & PNG_FILTER_PAETH) |
1774 if (png_ptr->do_filter & PNG_FILTER_PAETH) |
1817 { |
1775 { |
1818 png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, |
1776 png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, |
1819 (png_uint_32)(png_ptr->rowbytes + 1)); |
1777 (png_size_t)(png_ptr->rowbytes + 1)); |
1820 png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; |
1778 png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; |
1821 } |
1779 } |
1822 } |
1780 } |
1823 #endif /* PNG_NO_WRITE_FILTER */ |
1781 #endif /* PNG_WRITE_FILTER_SUPPORTED */ |
1824 |
1782 |
1825 #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
1783 #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
1826 /* If interlaced, we need to set up width and height of pass */ |
1784 /* If interlaced, we need to set up width and height of pass */ |
1827 if (png_ptr->interlaced) |
1785 if (png_ptr->interlaced) |
1828 { |
1786 { |
1866 /* Start of interlace block in the y direction */ |
1823 /* Start of interlace block in the y direction */ |
1867 int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
1824 int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; |
1868 |
1825 |
1869 /* Offset to next interlace block in the y direction */ |
1826 /* Offset to next interlace block in the y direction */ |
1870 int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
1827 int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; |
1871 #endif |
|
1872 #endif |
1828 #endif |
1873 |
1829 |
1874 int ret; |
1830 int ret; |
1875 |
1831 |
1876 png_debug(1, "in png_write_finish_row"); |
1832 png_debug(1, "in png_write_finish_row"); |
1960 |
1916 |
1961 deflateReset(&png_ptr->zstream); |
1917 deflateReset(&png_ptr->zstream); |
1962 png_ptr->zstream.data_type = Z_BINARY; |
1918 png_ptr->zstream.data_type = Z_BINARY; |
1963 } |
1919 } |
1964 |
1920 |
1965 #if defined(PNG_WRITE_INTERLACING_SUPPORTED) |
1921 #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
1966 /* Pick out the correct pixels for the interlace pass. |
1922 /* Pick out the correct pixels for the interlace pass. |
1967 * The basic idea here is to go through the row with a source |
1923 * The basic idea here is to go through the row with a source |
1968 * pointer and a destination pointer (sp and dp), and copy the |
1924 * pointer and a destination pointer (sp and dp), and copy the |
1969 * correct pixels for the pass. As the row gets compacted, |
1925 * correct pixels for the pass. As the row gets compacted, |
1970 * sp will always be >= dp, so we should never overwrite anything. |
1926 * sp will always be >= dp, so we should never overwrite anything. |
1971 * See the default: case for the easiest code to understand. |
1927 * See the default: case for the easiest code to understand. |
1972 */ |
1928 */ |
1973 void /* PRIVATE */ |
1929 void /* PRIVATE */ |
1974 png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) |
1930 png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) |
1975 { |
1931 { |
1976 #ifdef PNG_USE_LOCAL_ARRAYS |
|
1977 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
1932 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
1978 |
1933 |
1979 /* Start of interlace block */ |
1934 /* Start of interlace block */ |
1980 int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; |
1935 int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; |
1981 |
1936 |
1982 /* Offset to next interlace block */ |
1937 /* Offset to next interlace block */ |
1983 int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; |
1938 int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; |
1984 #endif |
|
1985 |
1939 |
1986 png_debug(1, "in png_do_write_interlace"); |
1940 png_debug(1, "in png_do_write_interlace"); |
1987 |
1941 |
1988 /* We don't have to do anything on the last pass (6) */ |
1942 /* We don't have to do anything on the last pass (6) */ |
1989 #if defined(PNG_USELESS_TESTS_SUPPORTED) |
|
1990 if (row != NULL && row_info != NULL && pass < 6) |
|
1991 #else |
|
1992 if (pass < 6) |
1943 if (pass < 6) |
1993 #endif |
|
1994 { |
1944 { |
1995 /* Each pixel depth is handled separately */ |
1945 /* Each pixel depth is handled separately */ |
1996 switch (row_info->pixel_depth) |
1946 switch (row_info->pixel_depth) |
1997 { |
1947 { |
1998 case 1: |
1948 case 1: |
2144 #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) |
2094 #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) |
2145 void /* PRIVATE */ |
2095 void /* PRIVATE */ |
2146 png_write_find_filter(png_structp png_ptr, png_row_infop row_info) |
2096 png_write_find_filter(png_structp png_ptr, png_row_infop row_info) |
2147 { |
2097 { |
2148 png_bytep best_row; |
2098 png_bytep best_row; |
2149 #ifndef PNG_NO_WRITE_FILTER |
2099 #ifdef PNG_WRITE_FILTER_SUPPORTED |
2150 png_bytep prev_row, row_buf; |
2100 png_bytep prev_row, row_buf; |
2151 png_uint_32 mins, bpp; |
2101 png_uint_32 mins, bpp; |
2152 png_byte filter_to_do = png_ptr->do_filter; |
2102 png_byte filter_to_do = png_ptr->do_filter; |
2153 png_uint_32 row_bytes = row_info->rowbytes; |
2103 png_uint_32 row_bytes = row_info->rowbytes; |
2154 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |
2104 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |
2155 int num_p_filters = (int)png_ptr->num_prev_filters; |
2105 int num_p_filters = (int)png_ptr->num_prev_filters; |
2156 #endif |
2106 #endif |
2157 |
2107 |
2158 png_debug(1, "in png_write_find_filter"); |
2108 png_debug(1, "in png_write_find_filter"); |
2159 |
2109 |
|
2110 #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |
|
2111 if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) |
|
2112 { |
|
2113 /* These will never be selected so we need not test them. */ |
|
2114 filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); |
|
2115 } |
|
2116 #endif |
|
2117 |
2160 /* Find out how many bytes offset each pixel is */ |
2118 /* Find out how many bytes offset each pixel is */ |
2161 bpp = (row_info->pixel_depth + 7) >> 3; |
2119 bpp = (row_info->pixel_depth + 7) >> 3; |
2162 |
2120 |
2163 prev_row = png_ptr->prev_row; |
2121 prev_row = png_ptr->prev_row; |
2164 #endif |
2122 #endif |
2165 best_row = png_ptr->row_buf; |
2123 best_row = png_ptr->row_buf; |
2166 #ifndef PNG_NO_WRITE_FILTER |
2124 #ifdef PNG_WRITE_FILTER_SUPPORTED |
2167 row_buf = best_row; |
2125 row_buf = best_row; |
2168 mins = PNG_MAXSUM; |
2126 mins = PNG_MAXSUM; |
2169 |
2127 |
2170 /* The prediction method we use is to find which method provides the |
2128 /* The prediction method we use is to find which method provides the |
2171 * smallest value when summing the absolute values of the distances |
2129 * smallest value when summing the absolute values of the distances |