diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/libpng/pngwrite.c')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/libpng/pngwrite.c | 3310 |
1 files changed, 1655 insertions, 1655 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngwrite.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngwrite.c index dc12a20..6d3fd4c 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngwrite.c +++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngwrite.c | |||
@@ -1,1655 +1,1655 @@ | |||
1 | 1 | ||
2 | /* pngwrite.c - general routines to write a PNG file | 2 | /* pngwrite.c - general routines to write a PNG file |
3 | * | 3 | * |
4 | * Last changed in libpng 1.5.7 [December 15, 2011] | 4 | * Last changed in libpng 1.5.7 [December 15, 2011] |
5 | * Copyright (c) 1998-2011 Glenn Randers-Pehrson | 5 | * Copyright (c) 1998-2011 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 | #include "pngpriv.h" | 14 | #include "pngpriv.h" |
15 | 15 | ||
16 | #ifdef PNG_WRITE_SUPPORTED | 16 | #ifdef PNG_WRITE_SUPPORTED |
17 | 17 | ||
18 | /* Writes all the PNG information. This is the suggested way to use the | 18 | /* Writes all the PNG information. This is the suggested way to use the |
19 | * library. If you have a new chunk to add, make a function to write it, | 19 | * library. If you have a new chunk to add, make a function to write it, |
20 | * and put it in the correct location here. If you want the chunk written | 20 | * and put it in the correct location here. If you want the chunk written |
21 | * after the image data, put it in png_write_end(). I strongly encourage | 21 | * after the image data, put it in png_write_end(). I strongly encourage |
22 | * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing | 22 | * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing |
23 | * the chunk, as that will keep the code from breaking if you want to just | 23 | * the chunk, as that will keep the code from breaking if you want to just |
24 | * write a plain PNG file. If you have long comments, I suggest writing | 24 | * write a plain PNG file. If you have long comments, I suggest writing |
25 | * them in png_write_end(), and compressing them. | 25 | * them in png_write_end(), and compressing them. |
26 | */ | 26 | */ |
27 | void PNGAPI | 27 | void PNGAPI |
28 | png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) | 28 | png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) |
29 | { | 29 | { |
30 | png_debug(1, "in png_write_info_before_PLTE"); | 30 | png_debug(1, "in png_write_info_before_PLTE"); |
31 | 31 | ||
32 | if (png_ptr == NULL || info_ptr == NULL) | 32 | if (png_ptr == NULL || info_ptr == NULL) |
33 | return; | 33 | return; |
34 | 34 | ||
35 | if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) | 35 | if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) |
36 | { | 36 | { |
37 | /* Write PNG signature */ | 37 | /* Write PNG signature */ |
38 | png_write_sig(png_ptr); | 38 | png_write_sig(png_ptr); |
39 | 39 | ||
40 | #ifdef PNG_MNG_FEATURES_SUPPORTED | 40 | #ifdef PNG_MNG_FEATURES_SUPPORTED |
41 | if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ | 41 | if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ |
42 | (png_ptr->mng_features_permitted)) | 42 | (png_ptr->mng_features_permitted)) |
43 | { | 43 | { |
44 | png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); | 44 | png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); |
45 | png_ptr->mng_features_permitted = 0; | 45 | png_ptr->mng_features_permitted = 0; |
46 | } | 46 | } |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | /* Write IHDR information. */ | 49 | /* Write IHDR information. */ |
50 | png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, | 50 | png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, |
51 | info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, | 51 | info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, |
52 | info_ptr->filter_type, | 52 | info_ptr->filter_type, |
53 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED | 53 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
54 | info_ptr->interlace_type); | 54 | info_ptr->interlace_type); |
55 | #else | 55 | #else |
56 | 0); | 56 | 0); |
57 | #endif | 57 | #endif |
58 | /* The rest of these check to see if the valid field has the appropriate | 58 | /* The rest of these check to see if the valid field has the appropriate |
59 | * flag set, and if it does, writes the chunk. | 59 | * flag set, and if it does, writes the chunk. |
60 | */ | 60 | */ |
61 | #ifdef PNG_WRITE_gAMA_SUPPORTED | 61 | #ifdef PNG_WRITE_gAMA_SUPPORTED |
62 | if (info_ptr->valid & PNG_INFO_gAMA) | 62 | if (info_ptr->valid & PNG_INFO_gAMA) |
63 | png_write_gAMA_fixed(png_ptr, info_ptr->gamma); | 63 | png_write_gAMA_fixed(png_ptr, info_ptr->gamma); |
64 | #endif | 64 | #endif |
65 | #ifdef PNG_WRITE_sRGB_SUPPORTED | 65 | #ifdef PNG_WRITE_sRGB_SUPPORTED |
66 | if (info_ptr->valid & PNG_INFO_sRGB) | 66 | if (info_ptr->valid & PNG_INFO_sRGB) |
67 | png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); | 67 | png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #ifdef PNG_WRITE_iCCP_SUPPORTED | 70 | #ifdef PNG_WRITE_iCCP_SUPPORTED |
71 | if (info_ptr->valid & PNG_INFO_iCCP) | 71 | if (info_ptr->valid & PNG_INFO_iCCP) |
72 | png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, | 72 | png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, |
73 | (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); | 73 | (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); |
74 | #endif | 74 | #endif |
75 | #ifdef PNG_WRITE_sBIT_SUPPORTED | 75 | #ifdef PNG_WRITE_sBIT_SUPPORTED |
76 | if (info_ptr->valid & PNG_INFO_sBIT) | 76 | if (info_ptr->valid & PNG_INFO_sBIT) |
77 | png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); | 77 | png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); |
78 | #endif | 78 | #endif |
79 | #ifdef PNG_WRITE_cHRM_SUPPORTED | 79 | #ifdef PNG_WRITE_cHRM_SUPPORTED |
80 | if (info_ptr->valid & PNG_INFO_cHRM) | 80 | if (info_ptr->valid & PNG_INFO_cHRM) |
81 | png_write_cHRM_fixed(png_ptr, | 81 | png_write_cHRM_fixed(png_ptr, |
82 | info_ptr->x_white, info_ptr->y_white, | 82 | info_ptr->x_white, info_ptr->y_white, |
83 | info_ptr->x_red, info_ptr->y_red, | 83 | info_ptr->x_red, info_ptr->y_red, |
84 | info_ptr->x_green, info_ptr->y_green, | 84 | info_ptr->x_green, info_ptr->y_green, |
85 | info_ptr->x_blue, info_ptr->y_blue); | 85 | info_ptr->x_blue, info_ptr->y_blue); |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED | 88 | #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED |
89 | if (info_ptr->unknown_chunks_num) | 89 | if (info_ptr->unknown_chunks_num) |
90 | { | 90 | { |
91 | png_unknown_chunk *up; | 91 | png_unknown_chunk *up; |
92 | 92 | ||
93 | png_debug(5, "writing extra chunks"); | 93 | png_debug(5, "writing extra chunks"); |
94 | 94 | ||
95 | for (up = info_ptr->unknown_chunks; | 95 | for (up = info_ptr->unknown_chunks; |
96 | up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; | 96 | up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; |
97 | up++) | 97 | up++) |
98 | { | 98 | { |
99 | int keep = png_handle_as_unknown(png_ptr, up->name); | 99 | int keep = png_handle_as_unknown(png_ptr, up->name); |
100 | 100 | ||
101 | if (keep != PNG_HANDLE_CHUNK_NEVER && | 101 | if (keep != PNG_HANDLE_CHUNK_NEVER && |
102 | up->location && | 102 | up->location && |
103 | !(up->location & PNG_HAVE_PLTE) && | 103 | !(up->location & PNG_HAVE_PLTE) && |
104 | !(up->location & PNG_HAVE_IDAT) && | 104 | !(up->location & PNG_HAVE_IDAT) && |
105 | !(up->location & PNG_AFTER_IDAT) && | 105 | !(up->location & PNG_AFTER_IDAT) && |
106 | ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || | 106 | ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || |
107 | (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) | 107 | (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) |
108 | { | 108 | { |
109 | if (up->size == 0) | 109 | if (up->size == 0) |
110 | png_warning(png_ptr, "Writing zero-length unknown chunk"); | 110 | png_warning(png_ptr, "Writing zero-length unknown chunk"); |
111 | 111 | ||
112 | png_write_chunk(png_ptr, up->name, up->data, up->size); | 112 | png_write_chunk(png_ptr, up->name, up->data, up->size); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | } | 115 | } |
116 | #endif | 116 | #endif |
117 | png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; | 117 | png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; |
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
121 | void PNGAPI | 121 | void PNGAPI |
122 | png_write_info(png_structp png_ptr, png_infop info_ptr) | 122 | png_write_info(png_structp png_ptr, png_infop info_ptr) |
123 | { | 123 | { |
124 | #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) | 124 | #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) |
125 | int i; | 125 | int i; |
126 | #endif | 126 | #endif |
127 | 127 | ||
128 | png_debug(1, "in png_write_info"); | 128 | png_debug(1, "in png_write_info"); |
129 | 129 | ||
130 | if (png_ptr == NULL || info_ptr == NULL) | 130 | if (png_ptr == NULL || info_ptr == NULL) |
131 | return; | 131 | return; |
132 | 132 | ||
133 | png_write_info_before_PLTE(png_ptr, info_ptr); | 133 | png_write_info_before_PLTE(png_ptr, info_ptr); |
134 | 134 | ||
135 | if (info_ptr->valid & PNG_INFO_PLTE) | 135 | if (info_ptr->valid & PNG_INFO_PLTE) |
136 | png_write_PLTE(png_ptr, info_ptr->palette, | 136 | png_write_PLTE(png_ptr, info_ptr->palette, |
137 | (png_uint_32)info_ptr->num_palette); | 137 | (png_uint_32)info_ptr->num_palette); |
138 | 138 | ||
139 | else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | 139 | else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
140 | png_error(png_ptr, "Valid palette required for paletted images"); | 140 | png_error(png_ptr, "Valid palette required for paletted images"); |
141 | 141 | ||
142 | #ifdef PNG_WRITE_tRNS_SUPPORTED | 142 | #ifdef PNG_WRITE_tRNS_SUPPORTED |
143 | if (info_ptr->valid & PNG_INFO_tRNS) | 143 | if (info_ptr->valid & PNG_INFO_tRNS) |
144 | { | 144 | { |
145 | #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED | 145 | #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED |
146 | /* Invert the alpha channel (in tRNS) */ | 146 | /* Invert the alpha channel (in tRNS) */ |
147 | if ((png_ptr->transformations & PNG_INVERT_ALPHA) && | 147 | if ((png_ptr->transformations & PNG_INVERT_ALPHA) && |
148 | info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) | 148 | info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) |
149 | { | 149 | { |
150 | int j; | 150 | int j; |
151 | for (j = 0; j<(int)info_ptr->num_trans; j++) | 151 | for (j = 0; j<(int)info_ptr->num_trans; j++) |
152 | info_ptr->trans_alpha[j] = | 152 | info_ptr->trans_alpha[j] = |
153 | (png_byte)(255 - info_ptr->trans_alpha[j]); | 153 | (png_byte)(255 - info_ptr->trans_alpha[j]); |
154 | } | 154 | } |
155 | #endif | 155 | #endif |
156 | png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), | 156 | png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), |
157 | info_ptr->num_trans, info_ptr->color_type); | 157 | info_ptr->num_trans, info_ptr->color_type); |
158 | } | 158 | } |
159 | #endif | 159 | #endif |
160 | #ifdef PNG_WRITE_bKGD_SUPPORTED | 160 | #ifdef PNG_WRITE_bKGD_SUPPORTED |
161 | if (info_ptr->valid & PNG_INFO_bKGD) | 161 | if (info_ptr->valid & PNG_INFO_bKGD) |
162 | png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); | 162 | png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); |
163 | #endif | 163 | #endif |
164 | 164 | ||
165 | #ifdef PNG_WRITE_hIST_SUPPORTED | 165 | #ifdef PNG_WRITE_hIST_SUPPORTED |
166 | if (info_ptr->valid & PNG_INFO_hIST) | 166 | if (info_ptr->valid & PNG_INFO_hIST) |
167 | png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); | 167 | png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); |
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | #ifdef PNG_WRITE_oFFs_SUPPORTED | 170 | #ifdef PNG_WRITE_oFFs_SUPPORTED |
171 | if (info_ptr->valid & PNG_INFO_oFFs) | 171 | if (info_ptr->valid & PNG_INFO_oFFs) |
172 | png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, | 172 | png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, |
173 | info_ptr->offset_unit_type); | 173 | info_ptr->offset_unit_type); |
174 | #endif | 174 | #endif |
175 | 175 | ||
176 | #ifdef PNG_WRITE_pCAL_SUPPORTED | 176 | #ifdef PNG_WRITE_pCAL_SUPPORTED |
177 | if (info_ptr->valid & PNG_INFO_pCAL) | 177 | if (info_ptr->valid & PNG_INFO_pCAL) |
178 | png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, | 178 | png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, |
179 | info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, | 179 | info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, |
180 | info_ptr->pcal_units, info_ptr->pcal_params); | 180 | info_ptr->pcal_units, info_ptr->pcal_params); |
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | #ifdef PNG_WRITE_sCAL_SUPPORTED | 183 | #ifdef PNG_WRITE_sCAL_SUPPORTED |
184 | if (info_ptr->valid & PNG_INFO_sCAL) | 184 | if (info_ptr->valid & PNG_INFO_sCAL) |
185 | png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, | 185 | png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, |
186 | info_ptr->scal_s_width, info_ptr->scal_s_height); | 186 | info_ptr->scal_s_width, info_ptr->scal_s_height); |
187 | #endif /* sCAL */ | 187 | #endif /* sCAL */ |
188 | 188 | ||
189 | #ifdef PNG_WRITE_pHYs_SUPPORTED | 189 | #ifdef PNG_WRITE_pHYs_SUPPORTED |
190 | if (info_ptr->valid & PNG_INFO_pHYs) | 190 | if (info_ptr->valid & PNG_INFO_pHYs) |
191 | png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, | 191 | png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, |
192 | info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); | 192 | info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); |
193 | #endif /* pHYs */ | 193 | #endif /* pHYs */ |
194 | 194 | ||
195 | #ifdef PNG_WRITE_tIME_SUPPORTED | 195 | #ifdef PNG_WRITE_tIME_SUPPORTED |
196 | if (info_ptr->valid & PNG_INFO_tIME) | 196 | if (info_ptr->valid & PNG_INFO_tIME) |
197 | { | 197 | { |
198 | png_write_tIME(png_ptr, &(info_ptr->mod_time)); | 198 | png_write_tIME(png_ptr, &(info_ptr->mod_time)); |
199 | png_ptr->mode |= PNG_WROTE_tIME; | 199 | png_ptr->mode |= PNG_WROTE_tIME; |
200 | } | 200 | } |
201 | #endif /* tIME */ | 201 | #endif /* tIME */ |
202 | 202 | ||
203 | #ifdef PNG_WRITE_sPLT_SUPPORTED | 203 | #ifdef PNG_WRITE_sPLT_SUPPORTED |
204 | if (info_ptr->valid & PNG_INFO_sPLT) | 204 | if (info_ptr->valid & PNG_INFO_sPLT) |
205 | for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) | 205 | for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) |
206 | png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); | 206 | png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); |
207 | #endif /* sPLT */ | 207 | #endif /* sPLT */ |
208 | 208 | ||
209 | #ifdef PNG_WRITE_TEXT_SUPPORTED | 209 | #ifdef PNG_WRITE_TEXT_SUPPORTED |
210 | /* Check to see if we need to write text chunks */ | 210 | /* Check to see if we need to write text chunks */ |
211 | for (i = 0; i < info_ptr->num_text; i++) | 211 | for (i = 0; i < info_ptr->num_text; i++) |
212 | { | 212 | { |
213 | png_debug2(2, "Writing header text chunk %d, type %d", i, | 213 | png_debug2(2, "Writing header text chunk %d, type %d", i, |
214 | info_ptr->text[i].compression); | 214 | info_ptr->text[i].compression); |
215 | /* An internationalized chunk? */ | 215 | /* An internationalized chunk? */ |
216 | if (info_ptr->text[i].compression > 0) | 216 | if (info_ptr->text[i].compression > 0) |
217 | { | 217 | { |
218 | #ifdef PNG_WRITE_iTXt_SUPPORTED | 218 | #ifdef PNG_WRITE_iTXt_SUPPORTED |
219 | /* Write international chunk */ | 219 | /* Write international chunk */ |
220 | png_write_iTXt(png_ptr, | 220 | png_write_iTXt(png_ptr, |
221 | info_ptr->text[i].compression, | 221 | info_ptr->text[i].compression, |
222 | info_ptr->text[i].key, | 222 | info_ptr->text[i].key, |
223 | info_ptr->text[i].lang, | 223 | info_ptr->text[i].lang, |
224 | info_ptr->text[i].lang_key, | 224 | info_ptr->text[i].lang_key, |
225 | info_ptr->text[i].text); | 225 | info_ptr->text[i].text); |
226 | #else | 226 | #else |
227 | png_warning(png_ptr, "Unable to write international text"); | 227 | png_warning(png_ptr, "Unable to write international text"); |
228 | #endif | 228 | #endif |
229 | /* Mark this chunk as written */ | 229 | /* Mark this chunk as written */ |
230 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; | 230 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; |
231 | } | 231 | } |
232 | 232 | ||
233 | /* If we want a compressed text chunk */ | 233 | /* If we want a compressed text chunk */ |
234 | else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) | 234 | else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) |
235 | { | 235 | { |
236 | #ifdef PNG_WRITE_zTXt_SUPPORTED | 236 | #ifdef PNG_WRITE_zTXt_SUPPORTED |
237 | /* Write compressed chunk */ | 237 | /* Write compressed chunk */ |
238 | png_write_zTXt(png_ptr, info_ptr->text[i].key, | 238 | png_write_zTXt(png_ptr, info_ptr->text[i].key, |
239 | info_ptr->text[i].text, 0, | 239 | info_ptr->text[i].text, 0, |
240 | info_ptr->text[i].compression); | 240 | info_ptr->text[i].compression); |
241 | #else | 241 | #else |
242 | png_warning(png_ptr, "Unable to write compressed text"); | 242 | png_warning(png_ptr, "Unable to write compressed text"); |
243 | #endif | 243 | #endif |
244 | /* Mark this chunk as written */ | 244 | /* Mark this chunk as written */ |
245 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; | 245 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; |
246 | } | 246 | } |
247 | 247 | ||
248 | else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) | 248 | else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) |
249 | { | 249 | { |
250 | #ifdef PNG_WRITE_tEXt_SUPPORTED | 250 | #ifdef PNG_WRITE_tEXt_SUPPORTED |
251 | /* Write uncompressed chunk */ | 251 | /* Write uncompressed chunk */ |
252 | png_write_tEXt(png_ptr, info_ptr->text[i].key, | 252 | png_write_tEXt(png_ptr, info_ptr->text[i].key, |
253 | info_ptr->text[i].text, | 253 | info_ptr->text[i].text, |
254 | 0); | 254 | 0); |
255 | /* Mark this chunk as written */ | 255 | /* Mark this chunk as written */ |
256 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; | 256 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; |
257 | #else | 257 | #else |
258 | /* Can't get here */ | 258 | /* Can't get here */ |
259 | png_warning(png_ptr, "Unable to write uncompressed text"); | 259 | png_warning(png_ptr, "Unable to write uncompressed text"); |
260 | #endif | 260 | #endif |
261 | } | 261 | } |
262 | } | 262 | } |
263 | #endif /* tEXt */ | 263 | #endif /* tEXt */ |
264 | 264 | ||
265 | #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED | 265 | #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED |
266 | if (info_ptr->unknown_chunks_num) | 266 | if (info_ptr->unknown_chunks_num) |
267 | { | 267 | { |
268 | png_unknown_chunk *up; | 268 | png_unknown_chunk *up; |
269 | 269 | ||
270 | png_debug(5, "writing extra chunks"); | 270 | png_debug(5, "writing extra chunks"); |
271 | 271 | ||
272 | for (up = info_ptr->unknown_chunks; | 272 | for (up = info_ptr->unknown_chunks; |
273 | up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; | 273 | up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; |
274 | up++) | 274 | up++) |
275 | { | 275 | { |
276 | int keep = png_handle_as_unknown(png_ptr, up->name); | 276 | int keep = png_handle_as_unknown(png_ptr, up->name); |
277 | if (keep != PNG_HANDLE_CHUNK_NEVER && | 277 | if (keep != PNG_HANDLE_CHUNK_NEVER && |
278 | up->location && | 278 | up->location && |
279 | (up->location & PNG_HAVE_PLTE) && | 279 | (up->location & PNG_HAVE_PLTE) && |
280 | !(up->location & PNG_HAVE_IDAT) && | 280 | !(up->location & PNG_HAVE_IDAT) && |
281 | !(up->location & PNG_AFTER_IDAT) && | 281 | !(up->location & PNG_AFTER_IDAT) && |
282 | ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || | 282 | ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || |
283 | (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) | 283 | (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) |
284 | { | 284 | { |
285 | png_write_chunk(png_ptr, up->name, up->data, up->size); | 285 | png_write_chunk(png_ptr, up->name, up->data, up->size); |
286 | } | 286 | } |
287 | } | 287 | } |
288 | } | 288 | } |
289 | #endif | 289 | #endif |
290 | } | 290 | } |
291 | 291 | ||
292 | /* Writes the end of the PNG file. If you don't want to write comments or | 292 | /* Writes the end of the PNG file. If you don't want to write comments or |
293 | * time information, you can pass NULL for info. If you already wrote these | 293 | * time information, you can pass NULL for info. If you already wrote these |
294 | * in png_write_info(), do not write them again here. If you have long | 294 | * in png_write_info(), do not write them again here. If you have long |
295 | * comments, I suggest writing them here, and compressing them. | 295 | * comments, I suggest writing them here, and compressing them. |
296 | */ | 296 | */ |
297 | void PNGAPI | 297 | void PNGAPI |
298 | png_write_end(png_structp png_ptr, png_infop info_ptr) | 298 | png_write_end(png_structp png_ptr, png_infop info_ptr) |
299 | { | 299 | { |
300 | png_debug(1, "in png_write_end"); | 300 | png_debug(1, "in png_write_end"); |
301 | 301 | ||
302 | if (png_ptr == NULL) | 302 | if (png_ptr == NULL) |
303 | return; | 303 | return; |
304 | 304 | ||
305 | if (!(png_ptr->mode & PNG_HAVE_IDAT)) | 305 | if (!(png_ptr->mode & PNG_HAVE_IDAT)) |
306 | png_error(png_ptr, "No IDATs written into file"); | 306 | png_error(png_ptr, "No IDATs written into file"); |
307 | 307 | ||
308 | /* See if user wants us to write information chunks */ | 308 | /* See if user wants us to write information chunks */ |
309 | if (info_ptr != NULL) | 309 | if (info_ptr != NULL) |
310 | { | 310 | { |
311 | #ifdef PNG_WRITE_TEXT_SUPPORTED | 311 | #ifdef PNG_WRITE_TEXT_SUPPORTED |
312 | int i; /* local index variable */ | 312 | int i; /* local index variable */ |
313 | #endif | 313 | #endif |
314 | #ifdef PNG_WRITE_tIME_SUPPORTED | 314 | #ifdef PNG_WRITE_tIME_SUPPORTED |
315 | /* Check to see if user has supplied a time chunk */ | 315 | /* Check to see if user has supplied a time chunk */ |
316 | if ((info_ptr->valid & PNG_INFO_tIME) && | 316 | if ((info_ptr->valid & PNG_INFO_tIME) && |
317 | !(png_ptr->mode & PNG_WROTE_tIME)) | 317 | !(png_ptr->mode & PNG_WROTE_tIME)) |
318 | png_write_tIME(png_ptr, &(info_ptr->mod_time)); | 318 | png_write_tIME(png_ptr, &(info_ptr->mod_time)); |
319 | 319 | ||
320 | #endif | 320 | #endif |
321 | #ifdef PNG_WRITE_TEXT_SUPPORTED | 321 | #ifdef PNG_WRITE_TEXT_SUPPORTED |
322 | /* Loop through comment chunks */ | 322 | /* Loop through comment chunks */ |
323 | for (i = 0; i < info_ptr->num_text; i++) | 323 | for (i = 0; i < info_ptr->num_text; i++) |
324 | { | 324 | { |
325 | png_debug2(2, "Writing trailer text chunk %d, type %d", i, | 325 | png_debug2(2, "Writing trailer text chunk %d, type %d", i, |
326 | info_ptr->text[i].compression); | 326 | info_ptr->text[i].compression); |
327 | /* An internationalized chunk? */ | 327 | /* An internationalized chunk? */ |
328 | if (info_ptr->text[i].compression > 0) | 328 | if (info_ptr->text[i].compression > 0) |
329 | { | 329 | { |
330 | #ifdef PNG_WRITE_iTXt_SUPPORTED | 330 | #ifdef PNG_WRITE_iTXt_SUPPORTED |
331 | /* Write international chunk */ | 331 | /* Write international chunk */ |
332 | png_write_iTXt(png_ptr, | 332 | png_write_iTXt(png_ptr, |
333 | info_ptr->text[i].compression, | 333 | info_ptr->text[i].compression, |
334 | info_ptr->text[i].key, | 334 | info_ptr->text[i].key, |
335 | info_ptr->text[i].lang, | 335 | info_ptr->text[i].lang, |
336 | info_ptr->text[i].lang_key, | 336 | info_ptr->text[i].lang_key, |
337 | info_ptr->text[i].text); | 337 | info_ptr->text[i].text); |
338 | #else | 338 | #else |
339 | png_warning(png_ptr, "Unable to write international text"); | 339 | png_warning(png_ptr, "Unable to write international text"); |
340 | #endif | 340 | #endif |
341 | /* Mark this chunk as written */ | 341 | /* Mark this chunk as written */ |
342 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; | 342 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; |
343 | } | 343 | } |
344 | 344 | ||
345 | else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) | 345 | else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) |
346 | { | 346 | { |
347 | #ifdef PNG_WRITE_zTXt_SUPPORTED | 347 | #ifdef PNG_WRITE_zTXt_SUPPORTED |
348 | /* Write compressed chunk */ | 348 | /* Write compressed chunk */ |
349 | png_write_zTXt(png_ptr, info_ptr->text[i].key, | 349 | png_write_zTXt(png_ptr, info_ptr->text[i].key, |
350 | info_ptr->text[i].text, 0, | 350 | info_ptr->text[i].text, 0, |
351 | info_ptr->text[i].compression); | 351 | info_ptr->text[i].compression); |
352 | #else | 352 | #else |
353 | png_warning(png_ptr, "Unable to write compressed text"); | 353 | png_warning(png_ptr, "Unable to write compressed text"); |
354 | #endif | 354 | #endif |
355 | /* Mark this chunk as written */ | 355 | /* Mark this chunk as written */ |
356 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; | 356 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; |
357 | } | 357 | } |
358 | 358 | ||
359 | else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) | 359 | else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) |
360 | { | 360 | { |
361 | #ifdef PNG_WRITE_tEXt_SUPPORTED | 361 | #ifdef PNG_WRITE_tEXt_SUPPORTED |
362 | /* Write uncompressed chunk */ | 362 | /* Write uncompressed chunk */ |
363 | png_write_tEXt(png_ptr, info_ptr->text[i].key, | 363 | png_write_tEXt(png_ptr, info_ptr->text[i].key, |
364 | info_ptr->text[i].text, 0); | 364 | info_ptr->text[i].text, 0); |
365 | #else | 365 | #else |
366 | png_warning(png_ptr, "Unable to write uncompressed text"); | 366 | png_warning(png_ptr, "Unable to write uncompressed text"); |
367 | #endif | 367 | #endif |
368 | 368 | ||
369 | /* Mark this chunk as written */ | 369 | /* Mark this chunk as written */ |
370 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; | 370 | info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; |
371 | } | 371 | } |
372 | } | 372 | } |
373 | #endif | 373 | #endif |
374 | #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED | 374 | #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED |
375 | if (info_ptr->unknown_chunks_num) | 375 | if (info_ptr->unknown_chunks_num) |
376 | { | 376 | { |
377 | png_unknown_chunk *up; | 377 | png_unknown_chunk *up; |
378 | 378 | ||
379 | png_debug(5, "writing extra chunks"); | 379 | png_debug(5, "writing extra chunks"); |
380 | 380 | ||
381 | for (up = info_ptr->unknown_chunks; | 381 | for (up = info_ptr->unknown_chunks; |
382 | up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; | 382 | up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; |
383 | up++) | 383 | up++) |
384 | { | 384 | { |
385 | int keep = png_handle_as_unknown(png_ptr, up->name); | 385 | int keep = png_handle_as_unknown(png_ptr, up->name); |
386 | if (keep != PNG_HANDLE_CHUNK_NEVER && | 386 | if (keep != PNG_HANDLE_CHUNK_NEVER && |
387 | up->location && | 387 | up->location && |
388 | (up->location & PNG_AFTER_IDAT) && | 388 | (up->location & PNG_AFTER_IDAT) && |
389 | ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || | 389 | ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || |
390 | (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) | 390 | (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) |
391 | { | 391 | { |
392 | png_write_chunk(png_ptr, up->name, up->data, up->size); | 392 | png_write_chunk(png_ptr, up->name, up->data, up->size); |
393 | } | 393 | } |
394 | } | 394 | } |
395 | } | 395 | } |
396 | #endif | 396 | #endif |
397 | } | 397 | } |
398 | 398 | ||
399 | png_ptr->mode |= PNG_AFTER_IDAT; | 399 | png_ptr->mode |= PNG_AFTER_IDAT; |
400 | 400 | ||
401 | /* Write end of PNG file */ | 401 | /* Write end of PNG file */ |
402 | png_write_IEND(png_ptr); | 402 | png_write_IEND(png_ptr); |
403 | /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, | 403 | /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, |
404 | * and restored again in libpng-1.2.30, may cause some applications that | 404 | * and restored again in libpng-1.2.30, may cause some applications that |
405 | * do not set png_ptr->output_flush_fn to crash. If your application | 405 | * do not set png_ptr->output_flush_fn to crash. If your application |
406 | * experiences a problem, please try building libpng with | 406 | * experiences a problem, please try building libpng with |
407 | * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to | 407 | * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to |
408 | * png-mng-implement at lists.sf.net . | 408 | * png-mng-implement at lists.sf.net . |
409 | */ | 409 | */ |
410 | #ifdef PNG_WRITE_FLUSH_SUPPORTED | 410 | #ifdef PNG_WRITE_FLUSH_SUPPORTED |
411 | # ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED | 411 | # ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED |
412 | png_flush(png_ptr); | 412 | png_flush(png_ptr); |
413 | # endif | 413 | # endif |
414 | #endif | 414 | #endif |
415 | } | 415 | } |
416 | 416 | ||
417 | #ifdef PNG_CONVERT_tIME_SUPPORTED | 417 | #ifdef PNG_CONVERT_tIME_SUPPORTED |
418 | /* "tm" structure is not supported on WindowsCE */ | 418 | /* "tm" structure is not supported on WindowsCE */ |
419 | void PNGAPI | 419 | void PNGAPI |
420 | png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) | 420 | png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) |
421 | { | 421 | { |
422 | png_debug(1, "in png_convert_from_struct_tm"); | 422 | png_debug(1, "in png_convert_from_struct_tm"); |
423 | 423 | ||
424 | ptime->year = (png_uint_16)(1900 + ttime->tm_year); | 424 | ptime->year = (png_uint_16)(1900 + ttime->tm_year); |
425 | ptime->month = (png_byte)(ttime->tm_mon + 1); | 425 | ptime->month = (png_byte)(ttime->tm_mon + 1); |
426 | ptime->day = (png_byte)ttime->tm_mday; | 426 | ptime->day = (png_byte)ttime->tm_mday; |
427 | ptime->hour = (png_byte)ttime->tm_hour; | 427 | ptime->hour = (png_byte)ttime->tm_hour; |
428 | ptime->minute = (png_byte)ttime->tm_min; | 428 | ptime->minute = (png_byte)ttime->tm_min; |
429 | ptime->second = (png_byte)ttime->tm_sec; | 429 | ptime->second = (png_byte)ttime->tm_sec; |
430 | } | 430 | } |
431 | 431 | ||
432 | void PNGAPI | 432 | void PNGAPI |
433 | png_convert_from_time_t(png_timep ptime, time_t ttime) | 433 | png_convert_from_time_t(png_timep ptime, time_t ttime) |
434 | { | 434 | { |
435 | struct tm *tbuf; | 435 | struct tm *tbuf; |
436 | 436 | ||
437 | png_debug(1, "in png_convert_from_time_t"); | 437 | png_debug(1, "in png_convert_from_time_t"); |
438 | 438 | ||
439 | tbuf = gmtime(&ttime); | 439 | tbuf = gmtime(&ttime); |
440 | png_convert_from_struct_tm(ptime, tbuf); | 440 | png_convert_from_struct_tm(ptime, tbuf); |
441 | } | 441 | } |
442 | #endif | 442 | #endif |
443 | 443 | ||
444 | /* Initialize png_ptr structure, and allocate any memory needed */ | 444 | /* Initialize png_ptr structure, and allocate any memory needed */ |
445 | PNG_FUNCTION(png_structp,PNGAPI | 445 | PNG_FUNCTION(png_structp,PNGAPI |
446 | png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, | 446 | png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, |
447 | png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) | 447 | png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) |
448 | { | 448 | { |
449 | #ifdef PNG_USER_MEM_SUPPORTED | 449 | #ifdef PNG_USER_MEM_SUPPORTED |
450 | return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, | 450 | return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, |
451 | warn_fn, NULL, NULL, NULL)); | 451 | warn_fn, NULL, NULL, NULL)); |
452 | } | 452 | } |
453 | 453 | ||
454 | /* Alternate initialize png_ptr structure, and allocate any memory needed */ | 454 | /* Alternate initialize png_ptr structure, and allocate any memory needed */ |
455 | static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ | 455 | static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ |
456 | 456 | ||
457 | PNG_FUNCTION(png_structp,PNGAPI | 457 | PNG_FUNCTION(png_structp,PNGAPI |
458 | png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, | 458 | png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, |
459 | png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, | 459 | png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, |
460 | png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) | 460 | png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) |
461 | { | 461 | { |
462 | #endif /* PNG_USER_MEM_SUPPORTED */ | 462 | #endif /* PNG_USER_MEM_SUPPORTED */ |
463 | volatile int png_cleanup_needed = 0; | 463 | volatile int png_cleanup_needed = 0; |
464 | #ifdef PNG_SETJMP_SUPPORTED | 464 | #ifdef PNG_SETJMP_SUPPORTED |
465 | volatile | 465 | volatile |
466 | #endif | 466 | #endif |
467 | png_structp png_ptr; | 467 | png_structp png_ptr; |
468 | #ifdef PNG_SETJMP_SUPPORTED | 468 | #ifdef PNG_SETJMP_SUPPORTED |
469 | #ifdef USE_FAR_KEYWORD | 469 | #ifdef USE_FAR_KEYWORD |
470 | jmp_buf tmp_jmpbuf; | 470 | jmp_buf tmp_jmpbuf; |
471 | #endif | 471 | #endif |
472 | #endif | 472 | #endif |
473 | 473 | ||
474 | png_debug(1, "in png_create_write_struct"); | 474 | png_debug(1, "in png_create_write_struct"); |
475 | 475 | ||
476 | #ifdef PNG_USER_MEM_SUPPORTED | 476 | #ifdef PNG_USER_MEM_SUPPORTED |
477 | png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, | 477 | png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, |
478 | (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); | 478 | (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); |
479 | #else | 479 | #else |
480 | png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); | 480 | png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); |
481 | #endif /* PNG_USER_MEM_SUPPORTED */ | 481 | #endif /* PNG_USER_MEM_SUPPORTED */ |
482 | if (png_ptr == NULL) | 482 | if (png_ptr == NULL) |
483 | return (NULL); | 483 | return (NULL); |
484 | 484 | ||
485 | /* Added at libpng-1.2.6 */ | 485 | /* Added at libpng-1.2.6 */ |
486 | #ifdef PNG_SET_USER_LIMITS_SUPPORTED | 486 | #ifdef PNG_SET_USER_LIMITS_SUPPORTED |
487 | png_ptr->user_width_max = PNG_USER_WIDTH_MAX; | 487 | png_ptr->user_width_max = PNG_USER_WIDTH_MAX; |
488 | png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; | 488 | png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; |
489 | #endif | 489 | #endif |
490 | 490 | ||
491 | #ifdef PNG_SETJMP_SUPPORTED | 491 | #ifdef PNG_SETJMP_SUPPORTED |
492 | /* Applications that neglect to set up their own setjmp() and then | 492 | /* Applications that neglect to set up their own setjmp() and then |
493 | * encounter a png_error() will longjmp here. Since the jmpbuf is | 493 | * encounter a png_error() will longjmp here. Since the jmpbuf is |
494 | * then meaningless we abort instead of returning. | 494 | * then meaningless we abort instead of returning. |
495 | */ | 495 | */ |
496 | #ifdef USE_FAR_KEYWORD | 496 | #ifdef USE_FAR_KEYWORD |
497 | if (setjmp(tmp_jmpbuf)) | 497 | if (setjmp(tmp_jmpbuf)) |
498 | #else | 498 | #else |
499 | if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ | 499 | if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ |
500 | #endif | 500 | #endif |
501 | #ifdef USE_FAR_KEYWORD | 501 | #ifdef USE_FAR_KEYWORD |
502 | png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); | 502 | png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf)); |
503 | #endif | 503 | #endif |
504 | PNG_ABORT(); | 504 | PNG_ABORT(); |
505 | #endif | 505 | #endif |
506 | 506 | ||
507 | #ifdef PNG_USER_MEM_SUPPORTED | 507 | #ifdef PNG_USER_MEM_SUPPORTED |
508 | png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); | 508 | png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); |
509 | #endif /* PNG_USER_MEM_SUPPORTED */ | 509 | #endif /* PNG_USER_MEM_SUPPORTED */ |
510 | png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); | 510 | png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); |
511 | 511 | ||
512 | if (!png_user_version_check(png_ptr, user_png_ver)) | 512 | if (!png_user_version_check(png_ptr, user_png_ver)) |
513 | png_cleanup_needed = 1; | 513 | png_cleanup_needed = 1; |
514 | 514 | ||
515 | /* Initialize zbuf - compression buffer */ | 515 | /* Initialize zbuf - compression buffer */ |
516 | png_ptr->zbuf_size = PNG_ZBUF_SIZE; | 516 | png_ptr->zbuf_size = PNG_ZBUF_SIZE; |
517 | 517 | ||
518 | if (!png_cleanup_needed) | 518 | if (!png_cleanup_needed) |
519 | { | 519 | { |
520 | png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, | 520 | png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, |
521 | png_ptr->zbuf_size); | 521 | png_ptr->zbuf_size); |
522 | if (png_ptr->zbuf == NULL) | 522 | if (png_ptr->zbuf == NULL) |
523 | png_cleanup_needed = 1; | 523 | png_cleanup_needed = 1; |
524 | } | 524 | } |
525 | 525 | ||
526 | if (png_cleanup_needed) | 526 | if (png_cleanup_needed) |
527 | { | 527 | { |
528 | /* Clean up PNG structure and deallocate any memory. */ | 528 | /* Clean up PNG structure and deallocate any memory. */ |
529 | png_free(png_ptr, png_ptr->zbuf); | 529 | png_free(png_ptr, png_ptr->zbuf); |
530 | png_ptr->zbuf = NULL; | 530 | png_ptr->zbuf = NULL; |
531 | #ifdef PNG_USER_MEM_SUPPORTED | 531 | #ifdef PNG_USER_MEM_SUPPORTED |
532 | png_destroy_struct_2((png_voidp)png_ptr, | 532 | png_destroy_struct_2((png_voidp)png_ptr, |
533 | (png_free_ptr)free_fn, (png_voidp)mem_ptr); | 533 | (png_free_ptr)free_fn, (png_voidp)mem_ptr); |
534 | #else | 534 | #else |
535 | png_destroy_struct((png_voidp)png_ptr); | 535 | png_destroy_struct((png_voidp)png_ptr); |
536 | #endif | 536 | #endif |
537 | return (NULL); | 537 | return (NULL); |
538 | } | 538 | } |
539 | 539 | ||
540 | png_set_write_fn(png_ptr, NULL, NULL, NULL); | 540 | png_set_write_fn(png_ptr, NULL, NULL, NULL); |
541 | 541 | ||
542 | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED | 542 | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |
543 | png_reset_filter_heuristics(png_ptr); | 543 | png_reset_filter_heuristics(png_ptr); |
544 | #endif | 544 | #endif |
545 | 545 | ||
546 | return (png_ptr); | 546 | return (png_ptr); |
547 | } | 547 | } |
548 | 548 | ||
549 | 549 | ||
550 | /* Write a few rows of image data. If the image is interlaced, | 550 | /* Write a few rows of image data. If the image is interlaced, |
551 | * either you will have to write the 7 sub images, or, if you | 551 | * either you will have to write the 7 sub images, or, if you |
552 | * have called png_set_interlace_handling(), you will have to | 552 | * have called png_set_interlace_handling(), you will have to |
553 | * "write" the image seven times. | 553 | * "write" the image seven times. |
554 | */ | 554 | */ |
555 | void PNGAPI | 555 | void PNGAPI |
556 | png_write_rows(png_structp png_ptr, png_bytepp row, | 556 | png_write_rows(png_structp png_ptr, png_bytepp row, |
557 | png_uint_32 num_rows) | 557 | png_uint_32 num_rows) |
558 | { | 558 | { |
559 | png_uint_32 i; /* row counter */ | 559 | png_uint_32 i; /* row counter */ |
560 | png_bytepp rp; /* row pointer */ | 560 | png_bytepp rp; /* row pointer */ |
561 | 561 | ||
562 | png_debug(1, "in png_write_rows"); | 562 | png_debug(1, "in png_write_rows"); |
563 | 563 | ||
564 | if (png_ptr == NULL) | 564 | if (png_ptr == NULL) |
565 | return; | 565 | return; |
566 | 566 | ||
567 | /* Loop through the rows */ | 567 | /* Loop through the rows */ |
568 | for (i = 0, rp = row; i < num_rows; i++, rp++) | 568 | for (i = 0, rp = row; i < num_rows; i++, rp++) |
569 | { | 569 | { |
570 | png_write_row(png_ptr, *rp); | 570 | png_write_row(png_ptr, *rp); |
571 | } | 571 | } |
572 | } | 572 | } |
573 | 573 | ||
574 | /* Write the image. You only need to call this function once, even | 574 | /* Write the image. You only need to call this function once, even |
575 | * if you are writing an interlaced image. | 575 | * if you are writing an interlaced image. |
576 | */ | 576 | */ |
577 | void PNGAPI | 577 | void PNGAPI |
578 | png_write_image(png_structp png_ptr, png_bytepp image) | 578 | png_write_image(png_structp png_ptr, png_bytepp image) |
579 | { | 579 | { |
580 | png_uint_32 i; /* row index */ | 580 | png_uint_32 i; /* row index */ |
581 | int pass, num_pass; /* pass variables */ | 581 | int pass, num_pass; /* pass variables */ |
582 | png_bytepp rp; /* points to current row */ | 582 | png_bytepp rp; /* points to current row */ |
583 | 583 | ||
584 | if (png_ptr == NULL) | 584 | if (png_ptr == NULL) |
585 | return; | 585 | return; |
586 | 586 | ||
587 | png_debug(1, "in png_write_image"); | 587 | png_debug(1, "in png_write_image"); |
588 | 588 | ||
589 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED | 589 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
590 | /* Initialize interlace handling. If image is not interlaced, | 590 | /* Initialize interlace handling. If image is not interlaced, |
591 | * this will set pass to 1 | 591 | * this will set pass to 1 |
592 | */ | 592 | */ |
593 | num_pass = png_set_interlace_handling(png_ptr); | 593 | num_pass = png_set_interlace_handling(png_ptr); |
594 | #else | 594 | #else |
595 | num_pass = 1; | 595 | num_pass = 1; |
596 | #endif | 596 | #endif |
597 | /* Loop through passes */ | 597 | /* Loop through passes */ |
598 | for (pass = 0; pass < num_pass; pass++) | 598 | for (pass = 0; pass < num_pass; pass++) |
599 | { | 599 | { |
600 | /* Loop through image */ | 600 | /* Loop through image */ |
601 | for (i = 0, rp = image; i < png_ptr->height; i++, rp++) | 601 | for (i = 0, rp = image; i < png_ptr->height; i++, rp++) |
602 | { | 602 | { |
603 | png_write_row(png_ptr, *rp); | 603 | png_write_row(png_ptr, *rp); |
604 | } | 604 | } |
605 | } | 605 | } |
606 | } | 606 | } |
607 | 607 | ||
608 | /* Called by user to write a row of image data */ | 608 | /* Called by user to write a row of image data */ |
609 | void PNGAPI | 609 | void PNGAPI |
610 | png_write_row(png_structp png_ptr, png_const_bytep row) | 610 | png_write_row(png_structp png_ptr, png_const_bytep row) |
611 | { | 611 | { |
612 | /* 1.5.6: moved from png_struct to be a local structure: */ | 612 | /* 1.5.6: moved from png_struct to be a local structure: */ |
613 | png_row_info row_info; | 613 | png_row_info row_info; |
614 | 614 | ||
615 | if (png_ptr == NULL) | 615 | if (png_ptr == NULL) |
616 | return; | 616 | return; |
617 | 617 | ||
618 | png_debug2(1, "in png_write_row (row %u, pass %d)", | 618 | png_debug2(1, "in png_write_row (row %u, pass %d)", |
619 | png_ptr->row_number, png_ptr->pass); | 619 | png_ptr->row_number, png_ptr->pass); |
620 | 620 | ||
621 | /* Initialize transformations and other stuff if first time */ | 621 | /* Initialize transformations and other stuff if first time */ |
622 | if (png_ptr->row_number == 0 && png_ptr->pass == 0) | 622 | if (png_ptr->row_number == 0 && png_ptr->pass == 0) |
623 | { | 623 | { |
624 | /* Make sure we wrote the header info */ | 624 | /* Make sure we wrote the header info */ |
625 | if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) | 625 | if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) |
626 | png_error(png_ptr, | 626 | png_error(png_ptr, |
627 | "png_write_info was never called before png_write_row"); | 627 | "png_write_info was never called before png_write_row"); |
628 | 628 | ||
629 | /* Check for transforms that have been set but were defined out */ | 629 | /* Check for transforms that have been set but were defined out */ |
630 | #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) | 630 | #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) |
631 | if (png_ptr->transformations & PNG_INVERT_MONO) | 631 | if (png_ptr->transformations & PNG_INVERT_MONO) |
632 | png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); | 632 | png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); |
633 | #endif | 633 | #endif |
634 | 634 | ||
635 | #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) | 635 | #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) |
636 | if (png_ptr->transformations & PNG_FILLER) | 636 | if (png_ptr->transformations & PNG_FILLER) |
637 | png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); | 637 | png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); |
638 | #endif | 638 | #endif |
639 | #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ | 639 | #if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ |
640 | defined(PNG_READ_PACKSWAP_SUPPORTED) | 640 | defined(PNG_READ_PACKSWAP_SUPPORTED) |
641 | if (png_ptr->transformations & PNG_PACKSWAP) | 641 | if (png_ptr->transformations & PNG_PACKSWAP) |
642 | png_warning(png_ptr, | 642 | png_warning(png_ptr, |
643 | "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); | 643 | "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); |
644 | #endif | 644 | #endif |
645 | 645 | ||
646 | #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) | 646 | #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) |
647 | if (png_ptr->transformations & PNG_PACK) | 647 | if (png_ptr->transformations & PNG_PACK) |
648 | png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); | 648 | png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); |
649 | #endif | 649 | #endif |
650 | 650 | ||
651 | #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) | 651 | #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) |
652 | if (png_ptr->transformations & PNG_SHIFT) | 652 | if (png_ptr->transformations & PNG_SHIFT) |
653 | png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); | 653 | png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); |
654 | #endif | 654 | #endif |
655 | 655 | ||
656 | #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) | 656 | #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) |
657 | if (png_ptr->transformations & PNG_BGR) | 657 | if (png_ptr->transformations & PNG_BGR) |
658 | png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); | 658 | png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); |
659 | #endif | 659 | #endif |
660 | 660 | ||
661 | #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) | 661 | #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) |
662 | if (png_ptr->transformations & PNG_SWAP_BYTES) | 662 | if (png_ptr->transformations & PNG_SWAP_BYTES) |
663 | png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); | 663 | png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); |
664 | #endif | 664 | #endif |
665 | 665 | ||
666 | png_write_start_row(png_ptr); | 666 | png_write_start_row(png_ptr); |
667 | } | 667 | } |
668 | 668 | ||
669 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED | 669 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
670 | /* If interlaced and not interested in row, return */ | 670 | /* If interlaced and not interested in row, return */ |
671 | if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) | 671 | if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) |
672 | { | 672 | { |
673 | switch (png_ptr->pass) | 673 | switch (png_ptr->pass) |
674 | { | 674 | { |
675 | case 0: | 675 | case 0: |
676 | if (png_ptr->row_number & 0x07) | 676 | if (png_ptr->row_number & 0x07) |
677 | { | 677 | { |
678 | png_write_finish_row(png_ptr); | 678 | png_write_finish_row(png_ptr); |
679 | return; | 679 | return; |
680 | } | 680 | } |
681 | break; | 681 | break; |
682 | 682 | ||
683 | case 1: | 683 | case 1: |
684 | if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) | 684 | if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) |
685 | { | 685 | { |
686 | png_write_finish_row(png_ptr); | 686 | png_write_finish_row(png_ptr); |
687 | return; | 687 | return; |
688 | } | 688 | } |
689 | break; | 689 | break; |
690 | 690 | ||
691 | case 2: | 691 | case 2: |
692 | if ((png_ptr->row_number & 0x07) != 4) | 692 | if ((png_ptr->row_number & 0x07) != 4) |
693 | { | 693 | { |
694 | png_write_finish_row(png_ptr); | 694 | png_write_finish_row(png_ptr); |
695 | return; | 695 | return; |
696 | } | 696 | } |
697 | break; | 697 | break; |
698 | 698 | ||
699 | case 3: | 699 | case 3: |
700 | if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) | 700 | if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) |
701 | { | 701 | { |
702 | png_write_finish_row(png_ptr); | 702 | png_write_finish_row(png_ptr); |
703 | return; | 703 | return; |
704 | } | 704 | } |
705 | break; | 705 | break; |
706 | 706 | ||
707 | case 4: | 707 | case 4: |
708 | if ((png_ptr->row_number & 0x03) != 2) | 708 | if ((png_ptr->row_number & 0x03) != 2) |
709 | { | 709 | { |
710 | png_write_finish_row(png_ptr); | 710 | png_write_finish_row(png_ptr); |
711 | return; | 711 | return; |
712 | } | 712 | } |
713 | break; | 713 | break; |
714 | 714 | ||
715 | case 5: | 715 | case 5: |
716 | if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) | 716 | if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) |
717 | { | 717 | { |
718 | png_write_finish_row(png_ptr); | 718 | png_write_finish_row(png_ptr); |
719 | return; | 719 | return; |
720 | } | 720 | } |
721 | break; | 721 | break; |
722 | 722 | ||
723 | case 6: | 723 | case 6: |
724 | if (!(png_ptr->row_number & 0x01)) | 724 | if (!(png_ptr->row_number & 0x01)) |
725 | { | 725 | { |
726 | png_write_finish_row(png_ptr); | 726 | png_write_finish_row(png_ptr); |
727 | return; | 727 | return; |
728 | } | 728 | } |
729 | break; | 729 | break; |
730 | 730 | ||
731 | default: /* error: ignore it */ | 731 | default: /* error: ignore it */ |
732 | break; | 732 | break; |
733 | } | 733 | } |
734 | } | 734 | } |
735 | #endif | 735 | #endif |
736 | 736 | ||
737 | /* Set up row info for transformations */ | 737 | /* Set up row info for transformations */ |
738 | row_info.color_type = png_ptr->color_type; | 738 | row_info.color_type = png_ptr->color_type; |
739 | row_info.width = png_ptr->usr_width; | 739 | row_info.width = png_ptr->usr_width; |
740 | row_info.channels = png_ptr->usr_channels; | 740 | row_info.channels = png_ptr->usr_channels; |
741 | row_info.bit_depth = png_ptr->usr_bit_depth; | 741 | row_info.bit_depth = png_ptr->usr_bit_depth; |
742 | row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); | 742 | row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); |
743 | row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); | 743 | row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); |
744 | 744 | ||
745 | png_debug1(3, "row_info->color_type = %d", row_info.color_type); | 745 | png_debug1(3, "row_info->color_type = %d", row_info.color_type); |
746 | png_debug1(3, "row_info->width = %u", row_info.width); | 746 | png_debug1(3, "row_info->width = %u", row_info.width); |
747 | png_debug1(3, "row_info->channels = %d", row_info.channels); | 747 | png_debug1(3, "row_info->channels = %d", row_info.channels); |
748 | png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); | 748 | png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); |
749 | png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); | 749 | png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); |
750 | png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); | 750 | png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); |
751 | 751 | ||
752 | /* Copy user's row into buffer, leaving room for filter byte. */ | 752 | /* Copy user's row into buffer, leaving room for filter byte. */ |
753 | png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); | 753 | png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); |
754 | 754 | ||
755 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED | 755 | #ifdef PNG_WRITE_INTERLACING_SUPPORTED |
756 | /* Handle interlacing */ | 756 | /* Handle interlacing */ |
757 | if (png_ptr->interlaced && png_ptr->pass < 6 && | 757 | if (png_ptr->interlaced && png_ptr->pass < 6 && |
758 | (png_ptr->transformations & PNG_INTERLACE)) | 758 | (png_ptr->transformations & PNG_INTERLACE)) |
759 | { | 759 | { |
760 | png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); | 760 | png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); |
761 | /* This should always get caught above, but still ... */ | 761 | /* This should always get caught above, but still ... */ |
762 | if (!(row_info.width)) | 762 | if (!(row_info.width)) |
763 | { | 763 | { |
764 | png_write_finish_row(png_ptr); | 764 | png_write_finish_row(png_ptr); |
765 | return; | 765 | return; |
766 | } | 766 | } |
767 | } | 767 | } |
768 | #endif | 768 | #endif |
769 | 769 | ||
770 | #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED | 770 | #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED |
771 | /* Handle other transformations */ | 771 | /* Handle other transformations */ |
772 | if (png_ptr->transformations) | 772 | if (png_ptr->transformations) |
773 | png_do_write_transformations(png_ptr, &row_info); | 773 | png_do_write_transformations(png_ptr, &row_info); |
774 | #endif | 774 | #endif |
775 | 775 | ||
776 | /* At this point the row_info pixel depth must match the 'transformed' depth, | 776 | /* At this point the row_info pixel depth must match the 'transformed' depth, |
777 | * which is also the output depth. | 777 | * which is also the output depth. |
778 | */ | 778 | */ |
779 | if (row_info.pixel_depth != png_ptr->pixel_depth || | 779 | if (row_info.pixel_depth != png_ptr->pixel_depth || |
780 | row_info.pixel_depth != png_ptr->transformed_pixel_depth) | 780 | row_info.pixel_depth != png_ptr->transformed_pixel_depth) |
781 | png_error(png_ptr, "internal write transform logic error"); | 781 | png_error(png_ptr, "internal write transform logic error"); |
782 | 782 | ||
783 | #ifdef PNG_MNG_FEATURES_SUPPORTED | 783 | #ifdef PNG_MNG_FEATURES_SUPPORTED |
784 | /* Write filter_method 64 (intrapixel differencing) only if | 784 | /* Write filter_method 64 (intrapixel differencing) only if |
785 | * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and | 785 | * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and |
786 | * 2. Libpng did not write a PNG signature (this filter_method is only | 786 | * 2. Libpng did not write a PNG signature (this filter_method is only |
787 | * used in PNG datastreams that are embedded in MNG datastreams) and | 787 | * used in PNG datastreams that are embedded in MNG datastreams) and |
788 | * 3. The application called png_permit_mng_features with a mask that | 788 | * 3. The application called png_permit_mng_features with a mask that |
789 | * included PNG_FLAG_MNG_FILTER_64 and | 789 | * included PNG_FLAG_MNG_FILTER_64 and |
790 | * 4. The filter_method is 64 and | 790 | * 4. The filter_method is 64 and |
791 | * 5. The color_type is RGB or RGBA | 791 | * 5. The color_type is RGB or RGBA |
792 | */ | 792 | */ |
793 | if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && | 793 | if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && |
794 | (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) | 794 | (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) |
795 | { | 795 | { |
796 | /* Intrapixel differencing */ | 796 | /* Intrapixel differencing */ |
797 | png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); | 797 | png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); |
798 | } | 798 | } |
799 | #endif | 799 | #endif |
800 | 800 | ||
801 | /* Find a filter if necessary, filter the row and write it out. */ | 801 | /* Find a filter if necessary, filter the row and write it out. */ |
802 | png_write_find_filter(png_ptr, &row_info); | 802 | png_write_find_filter(png_ptr, &row_info); |
803 | 803 | ||
804 | if (png_ptr->write_row_fn != NULL) | 804 | if (png_ptr->write_row_fn != NULL) |
805 | (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); | 805 | (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); |
806 | } | 806 | } |
807 | 807 | ||
808 | #ifdef PNG_WRITE_FLUSH_SUPPORTED | 808 | #ifdef PNG_WRITE_FLUSH_SUPPORTED |
809 | /* Set the automatic flush interval or 0 to turn flushing off */ | 809 | /* Set the automatic flush interval or 0 to turn flushing off */ |
810 | void PNGAPI | 810 | void PNGAPI |
811 | png_set_flush(png_structp png_ptr, int nrows) | 811 | png_set_flush(png_structp png_ptr, int nrows) |
812 | { | 812 | { |
813 | png_debug(1, "in png_set_flush"); | 813 | png_debug(1, "in png_set_flush"); |
814 | 814 | ||
815 | if (png_ptr == NULL) | 815 | if (png_ptr == NULL) |
816 | return; | 816 | return; |
817 | 817 | ||
818 | png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); | 818 | png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); |
819 | } | 819 | } |
820 | 820 | ||
821 | /* Flush the current output buffers now */ | 821 | /* Flush the current output buffers now */ |
822 | void PNGAPI | 822 | void PNGAPI |
823 | png_write_flush(png_structp png_ptr) | 823 | png_write_flush(png_structp png_ptr) |
824 | { | 824 | { |
825 | int wrote_IDAT; | 825 | int wrote_IDAT; |
826 | 826 | ||
827 | png_debug(1, "in png_write_flush"); | 827 | png_debug(1, "in png_write_flush"); |
828 | 828 | ||
829 | if (png_ptr == NULL) | 829 | if (png_ptr == NULL) |
830 | return; | 830 | return; |
831 | 831 | ||
832 | /* We have already written out all of the data */ | 832 | /* We have already written out all of the data */ |
833 | if (png_ptr->row_number >= png_ptr->num_rows) | 833 | if (png_ptr->row_number >= png_ptr->num_rows) |
834 | return; | 834 | return; |
835 | 835 | ||
836 | do | 836 | do |
837 | { | 837 | { |
838 | int ret; | 838 | int ret; |
839 | 839 | ||
840 | /* Compress the data */ | 840 | /* Compress the data */ |
841 | ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); | 841 | ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); |
842 | wrote_IDAT = 0; | 842 | wrote_IDAT = 0; |
843 | 843 | ||
844 | /* Check for compression errors */ | 844 | /* Check for compression errors */ |
845 | if (ret != Z_OK) | 845 | if (ret != Z_OK) |
846 | { | 846 | { |
847 | if (png_ptr->zstream.msg != NULL) | 847 | if (png_ptr->zstream.msg != NULL) |
848 | png_error(png_ptr, png_ptr->zstream.msg); | 848 | png_error(png_ptr, png_ptr->zstream.msg); |
849 | 849 | ||
850 | else | 850 | else |
851 | png_error(png_ptr, "zlib error"); | 851 | png_error(png_ptr, "zlib error"); |
852 | } | 852 | } |
853 | 853 | ||
854 | if (!(png_ptr->zstream.avail_out)) | 854 | if (!(png_ptr->zstream.avail_out)) |
855 | { | 855 | { |
856 | /* Write the IDAT and reset the zlib output buffer */ | 856 | /* Write the IDAT and reset the zlib output buffer */ |
857 | png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); | 857 | png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); |
858 | wrote_IDAT = 1; | 858 | wrote_IDAT = 1; |
859 | } | 859 | } |
860 | } while (wrote_IDAT == 1); | 860 | } while (wrote_IDAT == 1); |
861 | 861 | ||
862 | /* If there is any data left to be output, write it into a new IDAT */ | 862 | /* If there is any data left to be output, write it into a new IDAT */ |
863 | if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) | 863 | if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) |
864 | { | 864 | { |
865 | /* Write the IDAT and reset the zlib output buffer */ | 865 | /* Write the IDAT and reset the zlib output buffer */ |
866 | png_write_IDAT(png_ptr, png_ptr->zbuf, | 866 | png_write_IDAT(png_ptr, png_ptr->zbuf, |
867 | png_ptr->zbuf_size - png_ptr->zstream.avail_out); | 867 | png_ptr->zbuf_size - png_ptr->zstream.avail_out); |
868 | } | 868 | } |
869 | png_ptr->flush_rows = 0; | 869 | png_ptr->flush_rows = 0; |
870 | png_flush(png_ptr); | 870 | png_flush(png_ptr); |
871 | } | 871 | } |
872 | #endif /* PNG_WRITE_FLUSH_SUPPORTED */ | 872 | #endif /* PNG_WRITE_FLUSH_SUPPORTED */ |
873 | 873 | ||
874 | /* Free all memory used by the write */ | 874 | /* Free all memory used by the write */ |
875 | void PNGAPI | 875 | void PNGAPI |
876 | png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) | 876 | png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) |
877 | { | 877 | { |
878 | png_structp png_ptr = NULL; | 878 | png_structp png_ptr = NULL; |
879 | png_infop info_ptr = NULL; | 879 | png_infop info_ptr = NULL; |
880 | #ifdef PNG_USER_MEM_SUPPORTED | 880 | #ifdef PNG_USER_MEM_SUPPORTED |
881 | png_free_ptr free_fn = NULL; | 881 | png_free_ptr free_fn = NULL; |
882 | png_voidp mem_ptr = NULL; | 882 | png_voidp mem_ptr = NULL; |
883 | #endif | 883 | #endif |
884 | 884 | ||
885 | png_debug(1, "in png_destroy_write_struct"); | 885 | png_debug(1, "in png_destroy_write_struct"); |
886 | 886 | ||
887 | if (png_ptr_ptr != NULL) | 887 | if (png_ptr_ptr != NULL) |
888 | png_ptr = *png_ptr_ptr; | 888 | png_ptr = *png_ptr_ptr; |
889 | 889 | ||
890 | #ifdef PNG_USER_MEM_SUPPORTED | 890 | #ifdef PNG_USER_MEM_SUPPORTED |
891 | if (png_ptr != NULL) | 891 | if (png_ptr != NULL) |
892 | { | 892 | { |
893 | free_fn = png_ptr->free_fn; | 893 | free_fn = png_ptr->free_fn; |
894 | mem_ptr = png_ptr->mem_ptr; | 894 | mem_ptr = png_ptr->mem_ptr; |
895 | } | 895 | } |
896 | #endif | 896 | #endif |
897 | 897 | ||
898 | if (info_ptr_ptr != NULL) | 898 | if (info_ptr_ptr != NULL) |
899 | info_ptr = *info_ptr_ptr; | 899 | info_ptr = *info_ptr_ptr; |
900 | 900 | ||
901 | if (info_ptr != NULL) | 901 | if (info_ptr != NULL) |
902 | { | 902 | { |
903 | if (png_ptr != NULL) | 903 | if (png_ptr != NULL) |
904 | { | 904 | { |
905 | png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); | 905 | png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); |
906 | 906 | ||
907 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED | 907 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
908 | if (png_ptr->num_chunk_list) | 908 | if (png_ptr->num_chunk_list) |
909 | { | 909 | { |
910 | png_free(png_ptr, png_ptr->chunk_list); | 910 | png_free(png_ptr, png_ptr->chunk_list); |
911 | png_ptr->num_chunk_list = 0; | 911 | png_ptr->num_chunk_list = 0; |
912 | } | 912 | } |
913 | #endif | 913 | #endif |
914 | } | 914 | } |
915 | 915 | ||
916 | #ifdef PNG_USER_MEM_SUPPORTED | 916 | #ifdef PNG_USER_MEM_SUPPORTED |
917 | png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, | 917 | png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, |
918 | (png_voidp)mem_ptr); | 918 | (png_voidp)mem_ptr); |
919 | #else | 919 | #else |
920 | png_destroy_struct((png_voidp)info_ptr); | 920 | png_destroy_struct((png_voidp)info_ptr); |
921 | #endif | 921 | #endif |
922 | *info_ptr_ptr = NULL; | 922 | *info_ptr_ptr = NULL; |
923 | } | 923 | } |
924 | 924 | ||
925 | if (png_ptr != NULL) | 925 | if (png_ptr != NULL) |
926 | { | 926 | { |
927 | png_write_destroy(png_ptr); | 927 | png_write_destroy(png_ptr); |
928 | #ifdef PNG_USER_MEM_SUPPORTED | 928 | #ifdef PNG_USER_MEM_SUPPORTED |
929 | png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, | 929 | png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, |
930 | (png_voidp)mem_ptr); | 930 | (png_voidp)mem_ptr); |
931 | #else | 931 | #else |
932 | png_destroy_struct((png_voidp)png_ptr); | 932 | png_destroy_struct((png_voidp)png_ptr); |
933 | #endif | 933 | #endif |
934 | *png_ptr_ptr = NULL; | 934 | *png_ptr_ptr = NULL; |
935 | } | 935 | } |
936 | } | 936 | } |
937 | 937 | ||
938 | 938 | ||
939 | /* Free any memory used in png_ptr struct (old method) */ | 939 | /* Free any memory used in png_ptr struct (old method) */ |
940 | void /* PRIVATE */ | 940 | void /* PRIVATE */ |
941 | png_write_destroy(png_structp png_ptr) | 941 | png_write_destroy(png_structp png_ptr) |
942 | { | 942 | { |
943 | #ifdef PNG_SETJMP_SUPPORTED | 943 | #ifdef PNG_SETJMP_SUPPORTED |
944 | jmp_buf tmp_jmp; /* Save jump buffer */ | 944 | jmp_buf tmp_jmp; /* Save jump buffer */ |
945 | #endif | 945 | #endif |
946 | png_error_ptr error_fn; | 946 | png_error_ptr error_fn; |
947 | #ifdef PNG_WARNINGS_SUPPORTED | 947 | #ifdef PNG_WARNINGS_SUPPORTED |
948 | png_error_ptr warning_fn; | 948 | png_error_ptr warning_fn; |
949 | #endif | 949 | #endif |
950 | png_voidp error_ptr; | 950 | png_voidp error_ptr; |
951 | #ifdef PNG_USER_MEM_SUPPORTED | 951 | #ifdef PNG_USER_MEM_SUPPORTED |
952 | png_free_ptr free_fn; | 952 | png_free_ptr free_fn; |
953 | #endif | 953 | #endif |
954 | 954 | ||
955 | png_debug(1, "in png_write_destroy"); | 955 | png_debug(1, "in png_write_destroy"); |
956 | 956 | ||
957 | /* Free any memory zlib uses */ | 957 | /* Free any memory zlib uses */ |
958 | if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) | 958 | if (png_ptr->zlib_state != PNG_ZLIB_UNINITIALIZED) |
959 | deflateEnd(&png_ptr->zstream); | 959 | deflateEnd(&png_ptr->zstream); |
960 | 960 | ||
961 | /* Free our memory. png_free checks NULL for us. */ | 961 | /* Free our memory. png_free checks NULL for us. */ |
962 | png_free(png_ptr, png_ptr->zbuf); | 962 | png_free(png_ptr, png_ptr->zbuf); |
963 | png_free(png_ptr, png_ptr->row_buf); | 963 | png_free(png_ptr, png_ptr->row_buf); |
964 | #ifdef PNG_WRITE_FILTER_SUPPORTED | 964 | #ifdef PNG_WRITE_FILTER_SUPPORTED |
965 | png_free(png_ptr, png_ptr->prev_row); | 965 | png_free(png_ptr, png_ptr->prev_row); |
966 | png_free(png_ptr, png_ptr->sub_row); | 966 | png_free(png_ptr, png_ptr->sub_row); |
967 | png_free(png_ptr, png_ptr->up_row); | 967 | png_free(png_ptr, png_ptr->up_row); |
968 | png_free(png_ptr, png_ptr->avg_row); | 968 | png_free(png_ptr, png_ptr->avg_row); |
969 | png_free(png_ptr, png_ptr->paeth_row); | 969 | png_free(png_ptr, png_ptr->paeth_row); |
970 | #endif | 970 | #endif |
971 | 971 | ||
972 | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED | 972 | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |
973 | /* Use this to save a little code space, it doesn't free the filter_costs */ | 973 | /* Use this to save a little code space, it doesn't free the filter_costs */ |
974 | png_reset_filter_heuristics(png_ptr); | 974 | png_reset_filter_heuristics(png_ptr); |
975 | png_free(png_ptr, png_ptr->filter_costs); | 975 | png_free(png_ptr, png_ptr->filter_costs); |
976 | png_free(png_ptr, png_ptr->inv_filter_costs); | 976 | png_free(png_ptr, png_ptr->inv_filter_costs); |
977 | #endif | 977 | #endif |
978 | 978 | ||
979 | #ifdef PNG_SETJMP_SUPPORTED | 979 | #ifdef PNG_SETJMP_SUPPORTED |
980 | /* Reset structure */ | 980 | /* Reset structure */ |
981 | png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); | 981 | png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); |
982 | #endif | 982 | #endif |
983 | 983 | ||
984 | error_fn = png_ptr->error_fn; | 984 | error_fn = png_ptr->error_fn; |
985 | #ifdef PNG_WARNINGS_SUPPORTED | 985 | #ifdef PNG_WARNINGS_SUPPORTED |
986 | warning_fn = png_ptr->warning_fn; | 986 | warning_fn = png_ptr->warning_fn; |
987 | #endif | 987 | #endif |
988 | error_ptr = png_ptr->error_ptr; | 988 | error_ptr = png_ptr->error_ptr; |
989 | #ifdef PNG_USER_MEM_SUPPORTED | 989 | #ifdef PNG_USER_MEM_SUPPORTED |
990 | free_fn = png_ptr->free_fn; | 990 | free_fn = png_ptr->free_fn; |
991 | #endif | 991 | #endif |
992 | 992 | ||
993 | png_memset(png_ptr, 0, png_sizeof(png_struct)); | 993 | png_memset(png_ptr, 0, png_sizeof(png_struct)); |
994 | 994 | ||
995 | png_ptr->error_fn = error_fn; | 995 | png_ptr->error_fn = error_fn; |
996 | #ifdef PNG_WARNINGS_SUPPORTED | 996 | #ifdef PNG_WARNINGS_SUPPORTED |
997 | png_ptr->warning_fn = warning_fn; | 997 | png_ptr->warning_fn = warning_fn; |
998 | #endif | 998 | #endif |
999 | png_ptr->error_ptr = error_ptr; | 999 | png_ptr->error_ptr = error_ptr; |
1000 | #ifdef PNG_USER_MEM_SUPPORTED | 1000 | #ifdef PNG_USER_MEM_SUPPORTED |
1001 | png_ptr->free_fn = free_fn; | 1001 | png_ptr->free_fn = free_fn; |
1002 | #endif | 1002 | #endif |
1003 | 1003 | ||
1004 | #ifdef PNG_SETJMP_SUPPORTED | 1004 | #ifdef PNG_SETJMP_SUPPORTED |
1005 | png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); | 1005 | png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); |
1006 | #endif | 1006 | #endif |
1007 | } | 1007 | } |
1008 | 1008 | ||
1009 | /* Allow the application to select one or more row filters to use. */ | 1009 | /* Allow the application to select one or more row filters to use. */ |
1010 | void PNGAPI | 1010 | void PNGAPI |
1011 | png_set_filter(png_structp png_ptr, int method, int filters) | 1011 | png_set_filter(png_structp png_ptr, int method, int filters) |
1012 | { | 1012 | { |
1013 | png_debug(1, "in png_set_filter"); | 1013 | png_debug(1, "in png_set_filter"); |
1014 | 1014 | ||
1015 | if (png_ptr == NULL) | 1015 | if (png_ptr == NULL) |
1016 | return; | 1016 | return; |
1017 | 1017 | ||
1018 | #ifdef PNG_MNG_FEATURES_SUPPORTED | 1018 | #ifdef PNG_MNG_FEATURES_SUPPORTED |
1019 | if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && | 1019 | if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && |
1020 | (method == PNG_INTRAPIXEL_DIFFERENCING)) | 1020 | (method == PNG_INTRAPIXEL_DIFFERENCING)) |
1021 | method = PNG_FILTER_TYPE_BASE; | 1021 | method = PNG_FILTER_TYPE_BASE; |
1022 | 1022 | ||
1023 | #endif | 1023 | #endif |
1024 | if (method == PNG_FILTER_TYPE_BASE) | 1024 | if (method == PNG_FILTER_TYPE_BASE) |
1025 | { | 1025 | { |
1026 | switch (filters & (PNG_ALL_FILTERS | 0x07)) | 1026 | switch (filters & (PNG_ALL_FILTERS | 0x07)) |
1027 | { | 1027 | { |
1028 | #ifdef PNG_WRITE_FILTER_SUPPORTED | 1028 | #ifdef PNG_WRITE_FILTER_SUPPORTED |
1029 | case 5: | 1029 | case 5: |
1030 | case 6: | 1030 | case 6: |
1031 | case 7: png_warning(png_ptr, "Unknown row filter for method 0"); | 1031 | case 7: png_warning(png_ptr, "Unknown row filter for method 0"); |
1032 | #endif /* PNG_WRITE_FILTER_SUPPORTED */ | 1032 | #endif /* PNG_WRITE_FILTER_SUPPORTED */ |
1033 | case PNG_FILTER_VALUE_NONE: | 1033 | case PNG_FILTER_VALUE_NONE: |
1034 | png_ptr->do_filter = PNG_FILTER_NONE; break; | 1034 | png_ptr->do_filter = PNG_FILTER_NONE; break; |
1035 | 1035 | ||
1036 | #ifdef PNG_WRITE_FILTER_SUPPORTED | 1036 | #ifdef PNG_WRITE_FILTER_SUPPORTED |
1037 | case PNG_FILTER_VALUE_SUB: | 1037 | case PNG_FILTER_VALUE_SUB: |
1038 | png_ptr->do_filter = PNG_FILTER_SUB; break; | 1038 | png_ptr->do_filter = PNG_FILTER_SUB; break; |
1039 | 1039 | ||
1040 | case PNG_FILTER_VALUE_UP: | 1040 | case PNG_FILTER_VALUE_UP: |
1041 | png_ptr->do_filter = PNG_FILTER_UP; break; | 1041 | png_ptr->do_filter = PNG_FILTER_UP; break; |
1042 | 1042 | ||
1043 | case PNG_FILTER_VALUE_AVG: | 1043 | case PNG_FILTER_VALUE_AVG: |
1044 | png_ptr->do_filter = PNG_FILTER_AVG; break; | 1044 | png_ptr->do_filter = PNG_FILTER_AVG; break; |
1045 | 1045 | ||
1046 | case PNG_FILTER_VALUE_PAETH: | 1046 | case PNG_FILTER_VALUE_PAETH: |
1047 | png_ptr->do_filter = PNG_FILTER_PAETH; break; | 1047 | png_ptr->do_filter = PNG_FILTER_PAETH; break; |
1048 | 1048 | ||
1049 | default: | 1049 | default: |
1050 | png_ptr->do_filter = (png_byte)filters; break; | 1050 | png_ptr->do_filter = (png_byte)filters; break; |
1051 | #else | 1051 | #else |
1052 | default: | 1052 | default: |
1053 | png_warning(png_ptr, "Unknown row filter for method 0"); | 1053 | png_warning(png_ptr, "Unknown row filter for method 0"); |
1054 | #endif /* PNG_WRITE_FILTER_SUPPORTED */ | 1054 | #endif /* PNG_WRITE_FILTER_SUPPORTED */ |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | /* If we have allocated the row_buf, this means we have already started | 1057 | /* If we have allocated the row_buf, this means we have already started |
1058 | * with the image and we should have allocated all of the filter buffers | 1058 | * with the image and we should have allocated all of the filter buffers |
1059 | * that have been selected. If prev_row isn't already allocated, then | 1059 | * that have been selected. If prev_row isn't already allocated, then |
1060 | * it is too late to start using the filters that need it, since we | 1060 | * it is too late to start using the filters that need it, since we |
1061 | * will be missing the data in the previous row. If an application | 1061 | * will be missing the data in the previous row. If an application |
1062 | * wants to start and stop using particular filters during compression, | 1062 | * wants to start and stop using particular filters during compression, |
1063 | * it should start out with all of the filters, and then add and | 1063 | * it should start out with all of the filters, and then add and |
1064 | * remove them after the start of compression. | 1064 | * remove them after the start of compression. |
1065 | */ | 1065 | */ |
1066 | if (png_ptr->row_buf != NULL) | 1066 | if (png_ptr->row_buf != NULL) |
1067 | { | 1067 | { |
1068 | #ifdef PNG_WRITE_FILTER_SUPPORTED | 1068 | #ifdef PNG_WRITE_FILTER_SUPPORTED |
1069 | if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) | 1069 | if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) |
1070 | { | 1070 | { |
1071 | png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, | 1071 | png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, |
1072 | (png_ptr->rowbytes + 1)); | 1072 | (png_ptr->rowbytes + 1)); |
1073 | png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; | 1073 | png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; |
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) | 1076 | if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) |
1077 | { | 1077 | { |
1078 | if (png_ptr->prev_row == NULL) | 1078 | if (png_ptr->prev_row == NULL) |
1079 | { | 1079 | { |
1080 | png_warning(png_ptr, "Can't add Up filter after starting"); | 1080 | png_warning(png_ptr, "Can't add Up filter after starting"); |
1081 | png_ptr->do_filter = (png_byte)(png_ptr->do_filter & | 1081 | png_ptr->do_filter = (png_byte)(png_ptr->do_filter & |
1082 | ~PNG_FILTER_UP); | 1082 | ~PNG_FILTER_UP); |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | else | 1085 | else |
1086 | { | 1086 | { |
1087 | png_ptr->up_row = (png_bytep)png_malloc(png_ptr, | 1087 | png_ptr->up_row = (png_bytep)png_malloc(png_ptr, |
1088 | (png_ptr->rowbytes + 1)); | 1088 | (png_ptr->rowbytes + 1)); |
1089 | png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; | 1089 | png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; |
1090 | } | 1090 | } |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) | 1093 | if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) |
1094 | { | 1094 | { |
1095 | if (png_ptr->prev_row == NULL) | 1095 | if (png_ptr->prev_row == NULL) |
1096 | { | 1096 | { |
1097 | png_warning(png_ptr, "Can't add Average filter after starting"); | 1097 | png_warning(png_ptr, "Can't add Average filter after starting"); |
1098 | png_ptr->do_filter = (png_byte)(png_ptr->do_filter & | 1098 | png_ptr->do_filter = (png_byte)(png_ptr->do_filter & |
1099 | ~PNG_FILTER_AVG); | 1099 | ~PNG_FILTER_AVG); |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | else | 1102 | else |
1103 | { | 1103 | { |
1104 | png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, | 1104 | png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, |
1105 | (png_ptr->rowbytes + 1)); | 1105 | (png_ptr->rowbytes + 1)); |
1106 | png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; | 1106 | png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; |
1107 | } | 1107 | } |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | if ((png_ptr->do_filter & PNG_FILTER_PAETH) && | 1110 | if ((png_ptr->do_filter & PNG_FILTER_PAETH) && |
1111 | png_ptr->paeth_row == NULL) | 1111 | png_ptr->paeth_row == NULL) |
1112 | { | 1112 | { |
1113 | if (png_ptr->prev_row == NULL) | 1113 | if (png_ptr->prev_row == NULL) |
1114 | { | 1114 | { |
1115 | png_warning(png_ptr, "Can't add Paeth filter after starting"); | 1115 | png_warning(png_ptr, "Can't add Paeth filter after starting"); |
1116 | png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); | 1116 | png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); |
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | else | 1119 | else |
1120 | { | 1120 | { |
1121 | png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, | 1121 | png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, |
1122 | (png_ptr->rowbytes + 1)); | 1122 | (png_ptr->rowbytes + 1)); |
1123 | png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; | 1123 | png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; |
1124 | } | 1124 | } |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | if (png_ptr->do_filter == PNG_NO_FILTERS) | 1127 | if (png_ptr->do_filter == PNG_NO_FILTERS) |
1128 | #endif /* PNG_WRITE_FILTER_SUPPORTED */ | 1128 | #endif /* PNG_WRITE_FILTER_SUPPORTED */ |
1129 | png_ptr->do_filter = PNG_FILTER_NONE; | 1129 | png_ptr->do_filter = PNG_FILTER_NONE; |
1130 | } | 1130 | } |
1131 | } | 1131 | } |
1132 | else | 1132 | else |
1133 | png_error(png_ptr, "Unknown custom filter method"); | 1133 | png_error(png_ptr, "Unknown custom filter method"); |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | /* This allows us to influence the way in which libpng chooses the "best" | 1136 | /* This allows us to influence the way in which libpng chooses the "best" |
1137 | * filter for the current scanline. While the "minimum-sum-of-absolute- | 1137 | * filter for the current scanline. While the "minimum-sum-of-absolute- |
1138 | * differences metric is relatively fast and effective, there is some | 1138 | * differences metric is relatively fast and effective, there is some |
1139 | * question as to whether it can be improved upon by trying to keep the | 1139 | * question as to whether it can be improved upon by trying to keep the |
1140 | * filtered data going to zlib more consistent, hopefully resulting in | 1140 | * filtered data going to zlib more consistent, hopefully resulting in |
1141 | * better compression. | 1141 | * better compression. |
1142 | */ | 1142 | */ |
1143 | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ | 1143 | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ |
1144 | /* Convenience reset API. */ | 1144 | /* Convenience reset API. */ |
1145 | static void | 1145 | static void |
1146 | png_reset_filter_heuristics(png_structp png_ptr) | 1146 | png_reset_filter_heuristics(png_structp png_ptr) |
1147 | { | 1147 | { |
1148 | /* Clear out any old values in the 'weights' - this must be done because if | 1148 | /* Clear out any old values in the 'weights' - this must be done because if |
1149 | * the app calls set_filter_heuristics multiple times with different | 1149 | * the app calls set_filter_heuristics multiple times with different |
1150 | * 'num_weights' values we would otherwise potentially have wrong sized | 1150 | * 'num_weights' values we would otherwise potentially have wrong sized |
1151 | * arrays. | 1151 | * arrays. |
1152 | */ | 1152 | */ |
1153 | png_ptr->num_prev_filters = 0; | 1153 | png_ptr->num_prev_filters = 0; |
1154 | png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; | 1154 | png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; |
1155 | if (png_ptr->prev_filters != NULL) | 1155 | if (png_ptr->prev_filters != NULL) |
1156 | { | 1156 | { |
1157 | png_bytep old = png_ptr->prev_filters; | 1157 | png_bytep old = png_ptr->prev_filters; |
1158 | png_ptr->prev_filters = NULL; | 1158 | png_ptr->prev_filters = NULL; |
1159 | png_free(png_ptr, old); | 1159 | png_free(png_ptr, old); |
1160 | } | 1160 | } |
1161 | if (png_ptr->filter_weights != NULL) | 1161 | if (png_ptr->filter_weights != NULL) |
1162 | { | 1162 | { |
1163 | png_uint_16p old = png_ptr->filter_weights; | 1163 | png_uint_16p old = png_ptr->filter_weights; |
1164 | png_ptr->filter_weights = NULL; | 1164 | png_ptr->filter_weights = NULL; |
1165 | png_free(png_ptr, old); | 1165 | png_free(png_ptr, old); |
1166 | } | 1166 | } |
1167 | 1167 | ||
1168 | if (png_ptr->inv_filter_weights != NULL) | 1168 | if (png_ptr->inv_filter_weights != NULL) |
1169 | { | 1169 | { |
1170 | png_uint_16p old = png_ptr->inv_filter_weights; | 1170 | png_uint_16p old = png_ptr->inv_filter_weights; |
1171 | png_ptr->inv_filter_weights = NULL; | 1171 | png_ptr->inv_filter_weights = NULL; |
1172 | png_free(png_ptr, old); | 1172 | png_free(png_ptr, old); |
1173 | } | 1173 | } |
1174 | 1174 | ||
1175 | /* Leave the filter_costs - this array is fixed size. */ | 1175 | /* Leave the filter_costs - this array is fixed size. */ |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | static int | 1178 | static int |
1179 | png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, | 1179 | png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, |
1180 | int num_weights) | 1180 | int num_weights) |
1181 | { | 1181 | { |
1182 | if (png_ptr == NULL) | 1182 | if (png_ptr == NULL) |
1183 | return 0; | 1183 | return 0; |
1184 | 1184 | ||
1185 | /* Clear out the arrays */ | 1185 | /* Clear out the arrays */ |
1186 | png_reset_filter_heuristics(png_ptr); | 1186 | png_reset_filter_heuristics(png_ptr); |
1187 | 1187 | ||
1188 | /* Check arguments; the 'reset' function makes the correct settings for the | 1188 | /* Check arguments; the 'reset' function makes the correct settings for the |
1189 | * unweighted case, but we must handle the weight case by initializing the | 1189 | * unweighted case, but we must handle the weight case by initializing the |
1190 | * arrays for the caller. | 1190 | * arrays for the caller. |
1191 | */ | 1191 | */ |
1192 | if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) | 1192 | if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |
1193 | { | 1193 | { |
1194 | int i; | 1194 | int i; |
1195 | 1195 | ||
1196 | if (num_weights > 0) | 1196 | if (num_weights > 0) |
1197 | { | 1197 | { |
1198 | png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, | 1198 | png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, |
1199 | (png_uint_32)(png_sizeof(png_byte) * num_weights)); | 1199 | (png_uint_32)(png_sizeof(png_byte) * num_weights)); |
1200 | 1200 | ||
1201 | /* To make sure that the weighting starts out fairly */ | 1201 | /* To make sure that the weighting starts out fairly */ |
1202 | for (i = 0; i < num_weights; i++) | 1202 | for (i = 0; i < num_weights; i++) |
1203 | { | 1203 | { |
1204 | png_ptr->prev_filters[i] = 255; | 1204 | png_ptr->prev_filters[i] = 255; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, | 1207 | png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, |
1208 | (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); | 1208 | (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); |
1209 | 1209 | ||
1210 | png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, | 1210 | png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, |
1211 | (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); | 1211 | (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); |
1212 | 1212 | ||
1213 | for (i = 0; i < num_weights; i++) | 1213 | for (i = 0; i < num_weights; i++) |
1214 | { | 1214 | { |
1215 | png_ptr->inv_filter_weights[i] = | 1215 | png_ptr->inv_filter_weights[i] = |
1216 | png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; | 1216 | png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; |
1217 | } | 1217 | } |
1218 | 1218 | ||
1219 | /* Safe to set this now */ | 1219 | /* Safe to set this now */ |
1220 | png_ptr->num_prev_filters = (png_byte)num_weights; | 1220 | png_ptr->num_prev_filters = (png_byte)num_weights; |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | /* If, in the future, there are other filter methods, this would | 1223 | /* If, in the future, there are other filter methods, this would |
1224 | * need to be based on png_ptr->filter. | 1224 | * need to be based on png_ptr->filter. |
1225 | */ | 1225 | */ |
1226 | if (png_ptr->filter_costs == NULL) | 1226 | if (png_ptr->filter_costs == NULL) |
1227 | { | 1227 | { |
1228 | png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, | 1228 | png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, |
1229 | (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); | 1229 | (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); |
1230 | 1230 | ||
1231 | png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, | 1231 | png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, |
1232 | (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); | 1232 | (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) | 1235 | for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) |
1236 | { | 1236 | { |
1237 | png_ptr->inv_filter_costs[i] = | 1237 | png_ptr->inv_filter_costs[i] = |
1238 | png_ptr->filter_costs[i] = PNG_COST_FACTOR; | 1238 | png_ptr->filter_costs[i] = PNG_COST_FACTOR; |
1239 | } | 1239 | } |
1240 | 1240 | ||
1241 | /* All the arrays are inited, safe to set this: */ | 1241 | /* All the arrays are inited, safe to set this: */ |
1242 | png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; | 1242 | png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; |
1243 | 1243 | ||
1244 | /* Return the 'ok' code. */ | 1244 | /* Return the 'ok' code. */ |
1245 | return 1; | 1245 | return 1; |
1246 | } | 1246 | } |
1247 | else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || | 1247 | else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || |
1248 | heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) | 1248 | heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) |
1249 | { | 1249 | { |
1250 | return 1; | 1250 | return 1; |
1251 | } | 1251 | } |
1252 | else | 1252 | else |
1253 | { | 1253 | { |
1254 | png_warning(png_ptr, "Unknown filter heuristic method"); | 1254 | png_warning(png_ptr, "Unknown filter heuristic method"); |
1255 | return 0; | 1255 | return 0; |
1256 | } | 1256 | } |
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | /* Provide floating and fixed point APIs */ | 1259 | /* Provide floating and fixed point APIs */ |
1260 | #ifdef PNG_FLOATING_POINT_SUPPORTED | 1260 | #ifdef PNG_FLOATING_POINT_SUPPORTED |
1261 | void PNGAPI | 1261 | void PNGAPI |
1262 | png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, | 1262 | png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, |
1263 | int num_weights, png_const_doublep filter_weights, | 1263 | int num_weights, png_const_doublep filter_weights, |
1264 | png_const_doublep filter_costs) | 1264 | png_const_doublep filter_costs) |
1265 | { | 1265 | { |
1266 | png_debug(1, "in png_set_filter_heuristics"); | 1266 | png_debug(1, "in png_set_filter_heuristics"); |
1267 | 1267 | ||
1268 | /* The internal API allocates all the arrays and ensures that the elements of | 1268 | /* The internal API allocates all the arrays and ensures that the elements of |
1269 | * those arrays are set to the default value. | 1269 | * those arrays are set to the default value. |
1270 | */ | 1270 | */ |
1271 | if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) | 1271 | if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) |
1272 | return; | 1272 | return; |
1273 | 1273 | ||
1274 | /* If using the weighted method copy in the weights. */ | 1274 | /* If using the weighted method copy in the weights. */ |
1275 | if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) | 1275 | if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |
1276 | { | 1276 | { |
1277 | int i; | 1277 | int i; |
1278 | for (i = 0; i < num_weights; i++) | 1278 | for (i = 0; i < num_weights; i++) |
1279 | { | 1279 | { |
1280 | if (filter_weights[i] <= 0.0) | 1280 | if (filter_weights[i] <= 0.0) |
1281 | { | 1281 | { |
1282 | png_ptr->inv_filter_weights[i] = | 1282 | png_ptr->inv_filter_weights[i] = |
1283 | png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; | 1283 | png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | else | 1286 | else |
1287 | { | 1287 | { |
1288 | png_ptr->inv_filter_weights[i] = | 1288 | png_ptr->inv_filter_weights[i] = |
1289 | (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); | 1289 | (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); |
1290 | 1290 | ||
1291 | png_ptr->filter_weights[i] = | 1291 | png_ptr->filter_weights[i] = |
1292 | (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); | 1292 | (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); |
1293 | } | 1293 | } |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | /* Here is where we set the relative costs of the different filters. We | 1296 | /* Here is where we set the relative costs of the different filters. We |
1297 | * should take the desired compression level into account when setting | 1297 | * should take the desired compression level into account when setting |
1298 | * the costs, so that Paeth, for instance, has a high relative cost at low | 1298 | * the costs, so that Paeth, for instance, has a high relative cost at low |
1299 | * compression levels, while it has a lower relative cost at higher | 1299 | * compression levels, while it has a lower relative cost at higher |
1300 | * compression settings. The filter types are in order of increasing | 1300 | * compression settings. The filter types are in order of increasing |
1301 | * relative cost, so it would be possible to do this with an algorithm. | 1301 | * relative cost, so it would be possible to do this with an algorithm. |
1302 | */ | 1302 | */ |
1303 | for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) | 1303 | for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) |
1304 | { | 1304 | { |
1305 | png_ptr->inv_filter_costs[i] = | 1305 | png_ptr->inv_filter_costs[i] = |
1306 | (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); | 1306 | (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); |
1307 | 1307 | ||
1308 | png_ptr->filter_costs[i] = | 1308 | png_ptr->filter_costs[i] = |
1309 | (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); | 1309 | (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); |
1310 | } | 1310 | } |
1311 | } | 1311 | } |
1312 | } | 1312 | } |
1313 | #endif /* FLOATING_POINT */ | 1313 | #endif /* FLOATING_POINT */ |
1314 | 1314 | ||
1315 | #ifdef PNG_FIXED_POINT_SUPPORTED | 1315 | #ifdef PNG_FIXED_POINT_SUPPORTED |
1316 | void PNGAPI | 1316 | void PNGAPI |
1317 | png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, | 1317 | png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, |
1318 | int num_weights, png_const_fixed_point_p filter_weights, | 1318 | int num_weights, png_const_fixed_point_p filter_weights, |
1319 | png_const_fixed_point_p filter_costs) | 1319 | png_const_fixed_point_p filter_costs) |
1320 | { | 1320 | { |
1321 | png_debug(1, "in png_set_filter_heuristics_fixed"); | 1321 | png_debug(1, "in png_set_filter_heuristics_fixed"); |
1322 | 1322 | ||
1323 | /* The internal API allocates all the arrays and ensures that the elements of | 1323 | /* The internal API allocates all the arrays and ensures that the elements of |
1324 | * those arrays are set to the default value. | 1324 | * those arrays are set to the default value. |
1325 | */ | 1325 | */ |
1326 | if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) | 1326 | if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) |
1327 | return; | 1327 | return; |
1328 | 1328 | ||
1329 | /* If using the weighted method copy in the weights. */ | 1329 | /* If using the weighted method copy in the weights. */ |
1330 | if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) | 1330 | if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |
1331 | { | 1331 | { |
1332 | int i; | 1332 | int i; |
1333 | for (i = 0; i < num_weights; i++) | 1333 | for (i = 0; i < num_weights; i++) |
1334 | { | 1334 | { |
1335 | if (filter_weights[i] <= 0) | 1335 | if (filter_weights[i] <= 0) |
1336 | { | 1336 | { |
1337 | png_ptr->inv_filter_weights[i] = | 1337 | png_ptr->inv_filter_weights[i] = |
1338 | png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; | 1338 | png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; |
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | else | 1341 | else |
1342 | { | 1342 | { |
1343 | png_ptr->inv_filter_weights[i] = (png_uint_16) | 1343 | png_ptr->inv_filter_weights[i] = (png_uint_16) |
1344 | ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); | 1344 | ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); |
1345 | 1345 | ||
1346 | png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* | 1346 | png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* |
1347 | PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); | 1347 | PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); |
1348 | } | 1348 | } |
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | /* Here is where we set the relative costs of the different filters. We | 1351 | /* Here is where we set the relative costs of the different filters. We |
1352 | * should take the desired compression level into account when setting | 1352 | * should take the desired compression level into account when setting |
1353 | * the costs, so that Paeth, for instance, has a high relative cost at low | 1353 | * the costs, so that Paeth, for instance, has a high relative cost at low |
1354 | * compression levels, while it has a lower relative cost at higher | 1354 | * compression levels, while it has a lower relative cost at higher |
1355 | * compression settings. The filter types are in order of increasing | 1355 | * compression settings. The filter types are in order of increasing |
1356 | * relative cost, so it would be possible to do this with an algorithm. | 1356 | * relative cost, so it would be possible to do this with an algorithm. |
1357 | */ | 1357 | */ |
1358 | for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) | 1358 | for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) |
1359 | if (filter_costs[i] >= PNG_FP_1) | 1359 | if (filter_costs[i] >= PNG_FP_1) |
1360 | { | 1360 | { |
1361 | png_uint_32 tmp; | 1361 | png_uint_32 tmp; |
1362 | 1362 | ||
1363 | /* Use a 32 bit unsigned temporary here because otherwise the | 1363 | /* Use a 32 bit unsigned temporary here because otherwise the |
1364 | * intermediate value will be a 32 bit *signed* integer (ANSI rules) | 1364 | * intermediate value will be a 32 bit *signed* integer (ANSI rules) |
1365 | * and this will get the wrong answer on division. | 1365 | * and this will get the wrong answer on division. |
1366 | */ | 1366 | */ |
1367 | tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); | 1367 | tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); |
1368 | tmp /= filter_costs[i]; | 1368 | tmp /= filter_costs[i]; |
1369 | 1369 | ||
1370 | png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; | 1370 | png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; |
1371 | 1371 | ||
1372 | tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; | 1372 | tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; |
1373 | tmp /= PNG_FP_1; | 1373 | tmp /= PNG_FP_1; |
1374 | 1374 | ||
1375 | png_ptr->filter_costs[i] = (png_uint_16)tmp; | 1375 | png_ptr->filter_costs[i] = (png_uint_16)tmp; |
1376 | } | 1376 | } |
1377 | } | 1377 | } |
1378 | } | 1378 | } |
1379 | #endif /* FIXED_POINT */ | 1379 | #endif /* FIXED_POINT */ |
1380 | #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ | 1380 | #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ |
1381 | 1381 | ||
1382 | void PNGAPI | 1382 | void PNGAPI |
1383 | png_set_compression_level(png_structp png_ptr, int level) | 1383 | png_set_compression_level(png_structp png_ptr, int level) |
1384 | { | 1384 | { |
1385 | png_debug(1, "in png_set_compression_level"); | 1385 | png_debug(1, "in png_set_compression_level"); |
1386 | 1386 | ||
1387 | if (png_ptr == NULL) | 1387 | if (png_ptr == NULL) |
1388 | return; | 1388 | return; |
1389 | 1389 | ||
1390 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; | 1390 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; |
1391 | png_ptr->zlib_level = level; | 1391 | png_ptr->zlib_level = level; |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | void PNGAPI | 1394 | void PNGAPI |
1395 | png_set_compression_mem_level(png_structp png_ptr, int mem_level) | 1395 | png_set_compression_mem_level(png_structp png_ptr, int mem_level) |
1396 | { | 1396 | { |
1397 | png_debug(1, "in png_set_compression_mem_level"); | 1397 | png_debug(1, "in png_set_compression_mem_level"); |
1398 | 1398 | ||
1399 | if (png_ptr == NULL) | 1399 | if (png_ptr == NULL) |
1400 | return; | 1400 | return; |
1401 | 1401 | ||
1402 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; | 1402 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; |
1403 | png_ptr->zlib_mem_level = mem_level; | 1403 | png_ptr->zlib_mem_level = mem_level; |
1404 | } | 1404 | } |
1405 | 1405 | ||
1406 | void PNGAPI | 1406 | void PNGAPI |
1407 | png_set_compression_strategy(png_structp png_ptr, int strategy) | 1407 | png_set_compression_strategy(png_structp png_ptr, int strategy) |
1408 | { | 1408 | { |
1409 | png_debug(1, "in png_set_compression_strategy"); | 1409 | png_debug(1, "in png_set_compression_strategy"); |
1410 | 1410 | ||
1411 | if (png_ptr == NULL) | 1411 | if (png_ptr == NULL) |
1412 | return; | 1412 | return; |
1413 | 1413 | ||
1414 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; | 1414 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; |
1415 | png_ptr->zlib_strategy = strategy; | 1415 | png_ptr->zlib_strategy = strategy; |
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a | 1418 | /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a |
1419 | * smaller value of window_bits if it can do so safely. | 1419 | * smaller value of window_bits if it can do so safely. |
1420 | */ | 1420 | */ |
1421 | void PNGAPI | 1421 | void PNGAPI |
1422 | png_set_compression_window_bits(png_structp png_ptr, int window_bits) | 1422 | png_set_compression_window_bits(png_structp png_ptr, int window_bits) |
1423 | { | 1423 | { |
1424 | if (png_ptr == NULL) | 1424 | if (png_ptr == NULL) |
1425 | return; | 1425 | return; |
1426 | 1426 | ||
1427 | if (window_bits > 15) | 1427 | if (window_bits > 15) |
1428 | png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); | 1428 | png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); |
1429 | 1429 | ||
1430 | else if (window_bits < 8) | 1430 | else if (window_bits < 8) |
1431 | png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); | 1431 | png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); |
1432 | 1432 | ||
1433 | #ifndef WBITS_8_OK | 1433 | #ifndef WBITS_8_OK |
1434 | /* Avoid libpng bug with 256-byte windows */ | 1434 | /* Avoid libpng bug with 256-byte windows */ |
1435 | if (window_bits == 8) | 1435 | if (window_bits == 8) |
1436 | { | 1436 | { |
1437 | png_warning(png_ptr, "Compression window is being reset to 512"); | 1437 | png_warning(png_ptr, "Compression window is being reset to 512"); |
1438 | window_bits = 9; | 1438 | window_bits = 9; |
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | #endif | 1441 | #endif |
1442 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; | 1442 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; |
1443 | png_ptr->zlib_window_bits = window_bits; | 1443 | png_ptr->zlib_window_bits = window_bits; |
1444 | } | 1444 | } |
1445 | 1445 | ||
1446 | void PNGAPI | 1446 | void PNGAPI |
1447 | png_set_compression_method(png_structp png_ptr, int method) | 1447 | png_set_compression_method(png_structp png_ptr, int method) |
1448 | { | 1448 | { |
1449 | png_debug(1, "in png_set_compression_method"); | 1449 | png_debug(1, "in png_set_compression_method"); |
1450 | 1450 | ||
1451 | if (png_ptr == NULL) | 1451 | if (png_ptr == NULL) |
1452 | return; | 1452 | return; |
1453 | 1453 | ||
1454 | if (method != 8) | 1454 | if (method != 8) |
1455 | png_warning(png_ptr, "Only compression method 8 is supported by PNG"); | 1455 | png_warning(png_ptr, "Only compression method 8 is supported by PNG"); |
1456 | 1456 | ||
1457 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; | 1457 | png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; |
1458 | png_ptr->zlib_method = method; | 1458 | png_ptr->zlib_method = method; |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | /* The following were added to libpng-1.5.4 */ | 1461 | /* The following were added to libpng-1.5.4 */ |
1462 | #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED | 1462 | #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED |
1463 | void PNGAPI | 1463 | void PNGAPI |
1464 | png_set_text_compression_level(png_structp png_ptr, int level) | 1464 | png_set_text_compression_level(png_structp png_ptr, int level) |
1465 | { | 1465 | { |
1466 | png_debug(1, "in png_set_text_compression_level"); | 1466 | png_debug(1, "in png_set_text_compression_level"); |
1467 | 1467 | ||
1468 | if (png_ptr == NULL) | 1468 | if (png_ptr == NULL) |
1469 | return; | 1469 | return; |
1470 | 1470 | ||
1471 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; | 1471 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_LEVEL; |
1472 | png_ptr->zlib_text_level = level; | 1472 | png_ptr->zlib_text_level = level; |
1473 | } | 1473 | } |
1474 | 1474 | ||
1475 | void PNGAPI | 1475 | void PNGAPI |
1476 | png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) | 1476 | png_set_text_compression_mem_level(png_structp png_ptr, int mem_level) |
1477 | { | 1477 | { |
1478 | png_debug(1, "in png_set_text_compression_mem_level"); | 1478 | png_debug(1, "in png_set_text_compression_mem_level"); |
1479 | 1479 | ||
1480 | if (png_ptr == NULL) | 1480 | if (png_ptr == NULL) |
1481 | return; | 1481 | return; |
1482 | 1482 | ||
1483 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; | 1483 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL; |
1484 | png_ptr->zlib_text_mem_level = mem_level; | 1484 | png_ptr->zlib_text_mem_level = mem_level; |
1485 | } | 1485 | } |
1486 | 1486 | ||
1487 | void PNGAPI | 1487 | void PNGAPI |
1488 | png_set_text_compression_strategy(png_structp png_ptr, int strategy) | 1488 | png_set_text_compression_strategy(png_structp png_ptr, int strategy) |
1489 | { | 1489 | { |
1490 | png_debug(1, "in png_set_text_compression_strategy"); | 1490 | png_debug(1, "in png_set_text_compression_strategy"); |
1491 | 1491 | ||
1492 | if (png_ptr == NULL) | 1492 | if (png_ptr == NULL) |
1493 | return; | 1493 | return; |
1494 | 1494 | ||
1495 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; | 1495 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_STRATEGY; |
1496 | png_ptr->zlib_text_strategy = strategy; | 1496 | png_ptr->zlib_text_strategy = strategy; |
1497 | } | 1497 | } |
1498 | 1498 | ||
1499 | /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a | 1499 | /* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a |
1500 | * smaller value of window_bits if it can do so safely. | 1500 | * smaller value of window_bits if it can do so safely. |
1501 | */ | 1501 | */ |
1502 | void PNGAPI | 1502 | void PNGAPI |
1503 | png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) | 1503 | png_set_text_compression_window_bits(png_structp png_ptr, int window_bits) |
1504 | { | 1504 | { |
1505 | if (png_ptr == NULL) | 1505 | if (png_ptr == NULL) |
1506 | return; | 1506 | return; |
1507 | 1507 | ||
1508 | if (window_bits > 15) | 1508 | if (window_bits > 15) |
1509 | png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); | 1509 | png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); |
1510 | 1510 | ||
1511 | else if (window_bits < 8) | 1511 | else if (window_bits < 8) |
1512 | png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); | 1512 | png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); |
1513 | 1513 | ||
1514 | #ifndef WBITS_8_OK | 1514 | #ifndef WBITS_8_OK |
1515 | /* Avoid libpng bug with 256-byte windows */ | 1515 | /* Avoid libpng bug with 256-byte windows */ |
1516 | if (window_bits == 8) | 1516 | if (window_bits == 8) |
1517 | { | 1517 | { |
1518 | png_warning(png_ptr, "Text compression window is being reset to 512"); | 1518 | png_warning(png_ptr, "Text compression window is being reset to 512"); |
1519 | window_bits = 9; | 1519 | window_bits = 9; |
1520 | } | 1520 | } |
1521 | 1521 | ||
1522 | #endif | 1522 | #endif |
1523 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; | 1523 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS; |
1524 | png_ptr->zlib_text_window_bits = window_bits; | 1524 | png_ptr->zlib_text_window_bits = window_bits; |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | void PNGAPI | 1527 | void PNGAPI |
1528 | png_set_text_compression_method(png_structp png_ptr, int method) | 1528 | png_set_text_compression_method(png_structp png_ptr, int method) |
1529 | { | 1529 | { |
1530 | png_debug(1, "in png_set_text_compression_method"); | 1530 | png_debug(1, "in png_set_text_compression_method"); |
1531 | 1531 | ||
1532 | if (png_ptr == NULL) | 1532 | if (png_ptr == NULL) |
1533 | return; | 1533 | return; |
1534 | 1534 | ||
1535 | if (method != 8) | 1535 | if (method != 8) |
1536 | png_warning(png_ptr, "Only compression method 8 is supported by PNG"); | 1536 | png_warning(png_ptr, "Only compression method 8 is supported by PNG"); |
1537 | 1537 | ||
1538 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; | 1538 | png_ptr->flags |= PNG_FLAG_ZTXT_CUSTOM_METHOD; |
1539 | png_ptr->zlib_text_method = method; | 1539 | png_ptr->zlib_text_method = method; |
1540 | } | 1540 | } |
1541 | #endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ | 1541 | #endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */ |
1542 | /* end of API added to libpng-1.5.4 */ | 1542 | /* end of API added to libpng-1.5.4 */ |
1543 | 1543 | ||
1544 | void PNGAPI | 1544 | void PNGAPI |
1545 | png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) | 1545 | png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) |
1546 | { | 1546 | { |
1547 | if (png_ptr == NULL) | 1547 | if (png_ptr == NULL) |
1548 | return; | 1548 | return; |
1549 | 1549 | ||
1550 | png_ptr->write_row_fn = write_row_fn; | 1550 | png_ptr->write_row_fn = write_row_fn; |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED | 1553 | #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED |
1554 | void PNGAPI | 1554 | void PNGAPI |
1555 | png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr | 1555 | png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr |
1556 | write_user_transform_fn) | 1556 | write_user_transform_fn) |
1557 | { | 1557 | { |
1558 | png_debug(1, "in png_set_write_user_transform_fn"); | 1558 | png_debug(1, "in png_set_write_user_transform_fn"); |
1559 | 1559 | ||
1560 | if (png_ptr == NULL) | 1560 | if (png_ptr == NULL) |
1561 | return; | 1561 | return; |
1562 | 1562 | ||
1563 | png_ptr->transformations |= PNG_USER_TRANSFORM; | 1563 | png_ptr->transformations |= PNG_USER_TRANSFORM; |
1564 | png_ptr->write_user_transform_fn = write_user_transform_fn; | 1564 | png_ptr->write_user_transform_fn = write_user_transform_fn; |
1565 | } | 1565 | } |
1566 | #endif | 1566 | #endif |
1567 | 1567 | ||
1568 | 1568 | ||
1569 | #ifdef PNG_INFO_IMAGE_SUPPORTED | 1569 | #ifdef PNG_INFO_IMAGE_SUPPORTED |
1570 | void PNGAPI | 1570 | void PNGAPI |
1571 | png_write_png(png_structp png_ptr, png_infop info_ptr, | 1571 | png_write_png(png_structp png_ptr, png_infop info_ptr, |
1572 | int transforms, voidp params) | 1572 | int transforms, voidp params) |
1573 | { | 1573 | { |
1574 | if (png_ptr == NULL || info_ptr == NULL) | 1574 | if (png_ptr == NULL || info_ptr == NULL) |
1575 | return; | 1575 | return; |
1576 | 1576 | ||
1577 | /* Write the file header information. */ | 1577 | /* Write the file header information. */ |
1578 | png_write_info(png_ptr, info_ptr); | 1578 | png_write_info(png_ptr, info_ptr); |
1579 | 1579 | ||
1580 | /* ------ these transformations don't touch the info structure ------- */ | 1580 | /* ------ these transformations don't touch the info structure ------- */ |
1581 | 1581 | ||
1582 | #ifdef PNG_WRITE_INVERT_SUPPORTED | 1582 | #ifdef PNG_WRITE_INVERT_SUPPORTED |
1583 | /* Invert monochrome pixels */ | 1583 | /* Invert monochrome pixels */ |
1584 | if (transforms & PNG_TRANSFORM_INVERT_MONO) | 1584 | if (transforms & PNG_TRANSFORM_INVERT_MONO) |
1585 | png_set_invert_mono(png_ptr); | 1585 | png_set_invert_mono(png_ptr); |
1586 | #endif | 1586 | #endif |
1587 | 1587 | ||
1588 | #ifdef PNG_WRITE_SHIFT_SUPPORTED | 1588 | #ifdef PNG_WRITE_SHIFT_SUPPORTED |
1589 | /* Shift the pixels up to a legal bit depth and fill in | 1589 | /* Shift the pixels up to a legal bit depth and fill in |
1590 | * as appropriate to correctly scale the image. | 1590 | * as appropriate to correctly scale the image. |
1591 | */ | 1591 | */ |
1592 | if ((transforms & PNG_TRANSFORM_SHIFT) | 1592 | if ((transforms & PNG_TRANSFORM_SHIFT) |
1593 | && (info_ptr->valid & PNG_INFO_sBIT)) | 1593 | && (info_ptr->valid & PNG_INFO_sBIT)) |
1594 | png_set_shift(png_ptr, &info_ptr->sig_bit); | 1594 | png_set_shift(png_ptr, &info_ptr->sig_bit); |
1595 | #endif | 1595 | #endif |
1596 | 1596 | ||
1597 | #ifdef PNG_WRITE_PACK_SUPPORTED | 1597 | #ifdef PNG_WRITE_PACK_SUPPORTED |
1598 | /* Pack pixels into bytes */ | 1598 | /* Pack pixels into bytes */ |
1599 | if (transforms & PNG_TRANSFORM_PACKING) | 1599 | if (transforms & PNG_TRANSFORM_PACKING) |
1600 | png_set_packing(png_ptr); | 1600 | png_set_packing(png_ptr); |
1601 | #endif | 1601 | #endif |
1602 | 1602 | ||
1603 | #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED | 1603 | #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED |
1604 | /* Swap location of alpha bytes from ARGB to RGBA */ | 1604 | /* Swap location of alpha bytes from ARGB to RGBA */ |
1605 | if (transforms & PNG_TRANSFORM_SWAP_ALPHA) | 1605 | if (transforms & PNG_TRANSFORM_SWAP_ALPHA) |
1606 | png_set_swap_alpha(png_ptr); | 1606 | png_set_swap_alpha(png_ptr); |
1607 | #endif | 1607 | #endif |
1608 | 1608 | ||
1609 | #ifdef PNG_WRITE_FILLER_SUPPORTED | 1609 | #ifdef PNG_WRITE_FILLER_SUPPORTED |
1610 | /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ | 1610 | /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */ |
1611 | if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) | 1611 | if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) |
1612 | png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); | 1612 | png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); |
1613 | 1613 | ||
1614 | else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) | 1614 | else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) |
1615 | png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); | 1615 | png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); |
1616 | #endif | 1616 | #endif |
1617 | 1617 | ||
1618 | #ifdef PNG_WRITE_BGR_SUPPORTED | 1618 | #ifdef PNG_WRITE_BGR_SUPPORTED |
1619 | /* Flip BGR pixels to RGB */ | 1619 | /* Flip BGR pixels to RGB */ |
1620 | if (transforms & PNG_TRANSFORM_BGR) | 1620 | if (transforms & PNG_TRANSFORM_BGR) |
1621 | png_set_bgr(png_ptr); | 1621 | png_set_bgr(png_ptr); |
1622 | #endif | 1622 | #endif |
1623 | 1623 | ||
1624 | #ifdef PNG_WRITE_SWAP_SUPPORTED | 1624 | #ifdef PNG_WRITE_SWAP_SUPPORTED |
1625 | /* Swap bytes of 16-bit files to most significant byte first */ | 1625 | /* Swap bytes of 16-bit files to most significant byte first */ |
1626 | if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) | 1626 | if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) |
1627 | png_set_swap(png_ptr); | 1627 | png_set_swap(png_ptr); |
1628 | #endif | 1628 | #endif |
1629 | 1629 | ||
1630 | #ifdef PNG_WRITE_PACKSWAP_SUPPORTED | 1630 | #ifdef PNG_WRITE_PACKSWAP_SUPPORTED |
1631 | /* Swap bits of 1, 2, 4 bit packed pixel formats */ | 1631 | /* Swap bits of 1, 2, 4 bit packed pixel formats */ |
1632 | if (transforms & PNG_TRANSFORM_PACKSWAP) | 1632 | if (transforms & PNG_TRANSFORM_PACKSWAP) |
1633 | png_set_packswap(png_ptr); | 1633 | png_set_packswap(png_ptr); |
1634 | #endif | 1634 | #endif |
1635 | 1635 | ||
1636 | #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED | 1636 | #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED |
1637 | /* Invert the alpha channel from opacity to transparency */ | 1637 | /* Invert the alpha channel from opacity to transparency */ |
1638 | if (transforms & PNG_TRANSFORM_INVERT_ALPHA) | 1638 | if (transforms & PNG_TRANSFORM_INVERT_ALPHA) |
1639 | png_set_invert_alpha(png_ptr); | 1639 | png_set_invert_alpha(png_ptr); |
1640 | #endif | 1640 | #endif |
1641 | 1641 | ||
1642 | /* ----------------------- end of transformations ------------------- */ | 1642 | /* ----------------------- end of transformations ------------------- */ |
1643 | 1643 | ||
1644 | /* Write the bits */ | 1644 | /* Write the bits */ |
1645 | if (info_ptr->valid & PNG_INFO_IDAT) | 1645 | if (info_ptr->valid & PNG_INFO_IDAT) |
1646 | png_write_image(png_ptr, info_ptr->row_pointers); | 1646 | png_write_image(png_ptr, info_ptr->row_pointers); |
1647 | 1647 | ||
1648 | /* It is REQUIRED to call this to finish writing the rest of the file */ | 1648 | /* It is REQUIRED to call this to finish writing the rest of the file */ |
1649 | png_write_end(png_ptr, info_ptr); | 1649 | png_write_end(png_ptr, info_ptr); |
1650 | 1650 | ||
1651 | PNG_UNUSED(transforms) /* Quiet compiler warnings */ | 1651 | PNG_UNUSED(transforms) /* Quiet compiler warnings */ |
1652 | PNG_UNUSED(params) | 1652 | PNG_UNUSED(params) |
1653 | } | 1653 | } |
1654 | #endif | 1654 | #endif |
1655 | #endif /* PNG_WRITE_SUPPORTED */ | 1655 | #endif /* PNG_WRITE_SUPPORTED */ |