1 | ␍␊ |
2 | /* pngrtran.c - transforms the data in a row for PNG readers␍␊ |
3 | *␍␊ |
4 | * Last changed in libpng 1.5.11 [June 14, 2012]␍␊ |
5 | * Copyright (c) 1998-2012 Glenn Randers-Pehrson␍␊ |
6 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)␍␊ |
7 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)␍␊ |
8 | *␍␊ |
9 | * This code is released under the libpng license.␍␊ |
10 | * For conditions of distribution and use, see the disclaimer␍␊ |
11 | * and license in png.h␍␊ |
12 | *␍␊ |
13 | * This file contains functions optionally called by an application␍␊ |
14 | * in order to tell libpng how to handle data when reading a PNG.␍␊ |
15 | * Transformations that are used in both reading and writing are␍␊ |
16 | * in pngtrans.c.␍␊ |
17 | */␍␊ |
18 | ␍␊ |
19 | #include "pngpriv.h"␍␊ |
20 | ␍␊ |
21 | #ifdef PNG_READ_SUPPORTED␍␊ |
22 | ␍␊ |
23 | /* Set the action on getting a CRC error for an ancillary or critical chunk. */␍␊ |
24 | void PNGAPI␍␊ |
25 | png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)␍␊ |
26 | {␍␊ |
27 | png_debug(1, "in png_set_crc_action");␍␊ |
28 | ␍␊ |
29 | if (png_ptr == NULL)␍␊ |
30 | return;␍␊ |
31 | ␍␊ |
32 | /* Tell libpng how we react to CRC errors in critical chunks */␍␊ |
33 | switch (crit_action)␍␊ |
34 | {␍␊ |
35 | case PNG_CRC_NO_CHANGE: /* Leave setting as is */␍␊ |
36 | break;␍␊ |
37 | ␍␊ |
38 | case PNG_CRC_WARN_USE: /* Warn/use data */␍␊ |
39 | png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;␍␊ |
40 | png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;␍␊ |
41 | break;␍␊ |
42 | ␍␊ |
43 | case PNG_CRC_QUIET_USE: /* Quiet/use data */␍␊ |
44 | png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;␍␊ |
45 | png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |␍␊ |
46 | PNG_FLAG_CRC_CRITICAL_IGNORE;␍␊ |
47 | break;␍␊ |
48 | ␍␊ |
49 | case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */␍␊ |
50 | png_warning(png_ptr,␍␊ |
51 | "Can't discard critical data on CRC error");␍␊ |
52 | case PNG_CRC_ERROR_QUIT: /* Error/quit */␍␊ |
53 | ␍␊ |
54 | case PNG_CRC_DEFAULT:␍␊ |
55 | default:␍␊ |
56 | png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;␍␊ |
57 | break;␍␊ |
58 | }␍␊ |
59 | ␍␊ |
60 | /* Tell libpng how we react to CRC errors in ancillary chunks */␍␊ |
61 | switch (ancil_action)␍␊ |
62 | {␍␊ |
63 | case PNG_CRC_NO_CHANGE: /* Leave setting as is */␍␊ |
64 | break;␍␊ |
65 | ␍␊ |
66 | case PNG_CRC_WARN_USE: /* Warn/use data */␍␊ |
67 | png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;␍␊ |
68 | png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;␍␊ |
69 | break;␍␊ |
70 | ␍␊ |
71 | case PNG_CRC_QUIET_USE: /* Quiet/use data */␍␊ |
72 | png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;␍␊ |
73 | png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |␍␊ |
74 | PNG_FLAG_CRC_ANCILLARY_NOWARN;␍␊ |
75 | break;␍␊ |
76 | ␍␊ |
77 | case PNG_CRC_ERROR_QUIT: /* Error/quit */␍␊ |
78 | png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;␍␊ |
79 | png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;␍␊ |
80 | break;␍␊ |
81 | ␍␊ |
82 | case PNG_CRC_WARN_DISCARD: /* Warn/discard data */␍␊ |
83 | ␍␊ |
84 | case PNG_CRC_DEFAULT:␍␊ |
85 | default:␍␊ |
86 | png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;␍␊ |
87 | break;␍␊ |
88 | }␍␊ |
89 | }␍␊ |
90 | ␍␊ |
91 | #ifdef PNG_READ_BACKGROUND_SUPPORTED␍␊ |
92 | /* Handle alpha and tRNS via a background color */␍␊ |
93 | void PNGFAPI␍␊ |
94 | png_set_background_fixed(png_structp png_ptr,␍␊ |
95 | png_const_color_16p background_color, int background_gamma_code,␍␊ |
96 | int need_expand, png_fixed_point background_gamma)␍␊ |
97 | {␍␊ |
98 | png_debug(1, "in png_set_background_fixed");␍␊ |
99 | ␍␊ |
100 | if (png_ptr == NULL)␍␊ |
101 | return;␍␊ |
102 | ␍␊ |
103 | if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)␍␊ |
104 | {␍␊ |
105 | png_warning(png_ptr, "Application must supply a known background gamma");␍␊ |
106 | return;␍␊ |
107 | }␍␊ |
108 | ␍␊ |
109 | png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;␍␊ |
110 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
111 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
112 | ␍␊ |
113 | png_memcpy(&(png_ptr->background), background_color,␍␊ |
114 | png_sizeof(png_color_16));␍␊ |
115 | png_ptr->background_gamma = background_gamma;␍␊ |
116 | png_ptr->background_gamma_type = (png_byte)(background_gamma_code);␍␊ |
117 | if (need_expand)␍␊ |
118 | png_ptr->transformations |= PNG_BACKGROUND_EXPAND;␍␊ |
119 | else␍␊ |
120 | png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;␍␊ |
121 | }␍␊ |
122 | ␍␊ |
123 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
124 | void PNGAPI␍␊ |
125 | png_set_background(png_structp png_ptr,␍␊ |
126 | png_const_color_16p background_color, int background_gamma_code,␍␊ |
127 | int need_expand, double background_gamma)␍␊ |
128 | {␍␊ |
129 | png_set_background_fixed(png_ptr, background_color, background_gamma_code,␍␊ |
130 | need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));␍␊ |
131 | }␍␊ |
132 | # endif /* FLOATING_POINT */␍␊ |
133 | #endif /* READ_BACKGROUND */␍␊ |
134 | ␍␊ |
135 | /* Scale 16-bit depth files to 8-bit depth. If both of these are set then the␍␊ |
136 | * one that pngrtran does first (scale) happens. This is necessary to allow the␍␊ |
137 | * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.␍␊ |
138 | */␍␊ |
139 | #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED␍␊ |
140 | void PNGAPI␍␊ |
141 | png_set_scale_16(png_structp png_ptr)␍␊ |
142 | {␍␊ |
143 | png_debug(1, "in png_set_scale_16");␍␊ |
144 | ␍␊ |
145 | if (png_ptr == NULL)␍␊ |
146 | return;␍␊ |
147 | ␍␊ |
148 | png_ptr->transformations |= PNG_SCALE_16_TO_8;␍␊ |
149 | }␍␊ |
150 | #endif␍␊ |
151 | ␍␊ |
152 | #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED␍␊ |
153 | /* Chop 16-bit depth files to 8-bit depth */␍␊ |
154 | void PNGAPI␍␊ |
155 | png_set_strip_16(png_structp png_ptr)␍␊ |
156 | {␍␊ |
157 | png_debug(1, "in png_set_strip_16");␍␊ |
158 | ␍␊ |
159 | if (png_ptr == NULL)␍␊ |
160 | return;␍␊ |
161 | ␍␊ |
162 | png_ptr->transformations |= PNG_16_TO_8;␍␊ |
163 | }␍␊ |
164 | #endif␍␊ |
165 | ␍␊ |
166 | #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED␍␊ |
167 | void PNGAPI␍␊ |
168 | png_set_strip_alpha(png_structp png_ptr)␍␊ |
169 | {␍␊ |
170 | png_debug(1, "in png_set_strip_alpha");␍␊ |
171 | ␍␊ |
172 | if (png_ptr == NULL)␍␊ |
173 | return;␍␊ |
174 | ␍␊ |
175 | png_ptr->transformations |= PNG_STRIP_ALPHA;␍␊ |
176 | }␍␊ |
177 | #endif␍␊ |
178 | ␍␊ |
179 | #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)␍␊ |
180 | static png_fixed_point␍␊ |
181 | translate_gamma_flags(png_structp png_ptr, png_fixed_point output_gamma,␍␊ |
182 | int is_screen)␍␊ |
183 | {␍␊ |
184 | /* Check for flag values. The main reason for having the old Mac value as a␍␊ |
185 | * flag is that it is pretty near impossible to work out what the correct␍␊ |
186 | * value is from Apple documentation - a working Mac system is needed to␍␊ |
187 | * discover the value!␍␊ |
188 | */␍␊ |
189 | if (output_gamma == PNG_DEFAULT_sRGB ||␍␊ |
190 | output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)␍␊ |
191 | {␍␊ |
192 | /* If there is no sRGB support this just sets the gamma to the standard␍␊ |
193 | * sRGB value. (This is a side effect of using this function!)␍␊ |
194 | */␍␊ |
195 | # ifdef PNG_READ_sRGB_SUPPORTED␍␊ |
196 | png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;␍␊ |
197 | # endif␍␊ |
198 | if (is_screen)␍␊ |
199 | output_gamma = PNG_GAMMA_sRGB;␍␊ |
200 | else␍␊ |
201 | output_gamma = PNG_GAMMA_sRGB_INVERSE;␍␊ |
202 | }␍␊ |
203 | ␍␊ |
204 | else if (output_gamma == PNG_GAMMA_MAC_18 ||␍␊ |
205 | output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)␍␊ |
206 | {␍␊ |
207 | if (is_screen)␍␊ |
208 | output_gamma = PNG_GAMMA_MAC_OLD;␍␊ |
209 | else␍␊ |
210 | output_gamma = PNG_GAMMA_MAC_INVERSE;␍␊ |
211 | }␍␊ |
212 | ␍␊ |
213 | return output_gamma;␍␊ |
214 | }␍␊ |
215 | ␍␊ |
216 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
217 | static png_fixed_point␍␊ |
218 | convert_gamma_value(png_structp png_ptr, double output_gamma)␍␊ |
219 | {␍␊ |
220 | /* The following silently ignores cases where fixed point (times 100,000)␍␊ |
221 | * gamma values are passed to the floating point API. This is safe and it␍␊ |
222 | * means the fixed point constants work just fine with the floating point␍␊ |
223 | * API. The alternative would just lead to undetected errors and spurious␍␊ |
224 | * bug reports. Negative values fail inside the _fixed API unless they␍␊ |
225 | * correspond to the flag values.␍␊ |
226 | */␍␊ |
227 | if (output_gamma > 0 && output_gamma < 128)␍␊ |
228 | output_gamma *= PNG_FP_1;␍␊ |
229 | ␍␊ |
230 | /* This preserves -1 and -2 exactly: */␍␊ |
231 | output_gamma = floor(output_gamma + .5);␍␊ |
232 | ␍␊ |
233 | if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)␍␊ |
234 | png_fixed_error(png_ptr, "gamma value");␍␊ |
235 | ␍␊ |
236 | return (png_fixed_point)output_gamma;␍␊ |
237 | }␍␊ |
238 | # endif␍␊ |
239 | #endif /* READ_ALPHA_MODE || READ_GAMMA */␍␊ |
240 | ␍␊ |
241 | #ifdef PNG_READ_ALPHA_MODE_SUPPORTED␍␊ |
242 | void PNGFAPI␍␊ |
243 | png_set_alpha_mode_fixed(png_structp png_ptr, int mode,␍␊ |
244 | png_fixed_point output_gamma)␍␊ |
245 | {␍␊ |
246 | int compose = 0;␍␊ |
247 | png_fixed_point file_gamma;␍␊ |
248 | ␍␊ |
249 | png_debug(1, "in png_set_alpha_mode");␍␊ |
250 | ␍␊ |
251 | if (png_ptr == NULL)␍␊ |
252 | return;␍␊ |
253 | ␍␊ |
254 | output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);␍␊ |
255 | ␍␊ |
256 | /* Validate the value to ensure it is in a reasonable range. The value␍␊ |
257 | * is expected to be 1 or greater, but this range test allows for some␍␊ |
258 | * viewing correction values. The intent is to weed out users of this API␍␊ |
259 | * who use the inverse of the gamma value accidentally! Since some of these␍␊ |
260 | * values are reasonable this may have to be changed.␍␊ |
261 | */␍␊ |
262 | if (output_gamma < 70000 || output_gamma > 300000)␍␊ |
263 | png_error(png_ptr, "output gamma out of expected range");␍␊ |
264 | ␍␊ |
265 | /* The default file gamma is the inverse of the output gamma; the output␍␊ |
266 | * gamma may be changed below so get the file value first:␍␊ |
267 | */␍␊ |
268 | file_gamma = png_reciprocal(output_gamma);␍␊ |
269 | ␍␊ |
270 | /* There are really 8 possibilities here, composed of any combination␍␊ |
271 | * of:␍␊ |
272 | *␍␊ |
273 | * premultiply the color channels␍␊ |
274 | * do not encode non-opaque pixels␍␊ |
275 | * encode the alpha as well as the color channels␍␊ |
276 | *␍␊ |
277 | * The differences disappear if the input/output ('screen') gamma is 1.0,␍␊ |
278 | * because then the encoding is a no-op and there is only the choice of␍␊ |
279 | * premultiplying the color channels or not.␍␊ |
280 | *␍␊ |
281 | * png_set_alpha_mode and png_set_background interact because both use␍␊ |
282 | * png_compose to do the work. Calling both is only useful when␍␊ |
283 | * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along␍␊ |
284 | * with a default gamma value. Otherwise PNG_COMPOSE must not be set.␍␊ |
285 | */␍␊ |
286 | switch (mode)␍␊ |
287 | {␍␊ |
288 | case PNG_ALPHA_PNG: /* default: png standard */␍␊ |
289 | /* No compose, but it may be set by png_set_background! */␍␊ |
290 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
291 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
292 | break;␍␊ |
293 | ␍␊ |
294 | case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */␍␊ |
295 | compose = 1;␍␊ |
296 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
297 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
298 | /* The output is linear: */␍␊ |
299 | output_gamma = PNG_FP_1;␍␊ |
300 | break;␍␊ |
301 | ␍␊ |
302 | case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */␍␊ |
303 | compose = 1;␍␊ |
304 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
305 | png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
306 | /* output_gamma records the encoding of opaque pixels! */␍␊ |
307 | break;␍␊ |
308 | ␍␊ |
309 | case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */␍␊ |
310 | compose = 1;␍␊ |
311 | png_ptr->transformations |= PNG_ENCODE_ALPHA;␍␊ |
312 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
313 | break;␍␊ |
314 | ␍␊ |
315 | default:␍␊ |
316 | png_error(png_ptr, "invalid alpha mode");␍␊ |
317 | }␍␊ |
318 | ␍␊ |
319 | /* Only set the default gamma if the file gamma has not been set (this has␍␊ |
320 | * the side effect that the gamma in a second call to png_set_alpha_mode will␍␊ |
321 | * be ignored.)␍␊ |
322 | */␍␊ |
323 | if (png_ptr->gamma == 0)␍␊ |
324 | png_ptr->gamma = file_gamma;␍␊ |
325 | ␍␊ |
326 | /* But always set the output gamma: */␍␊ |
327 | png_ptr->screen_gamma = output_gamma;␍␊ |
328 | ␍␊ |
329 | /* Finally, if pre-multiplying, set the background fields to achieve the␍␊ |
330 | * desired result.␍␊ |
331 | */␍␊ |
332 | if (compose)␍␊ |
333 | {␍␊ |
334 | /* And obtain alpha pre-multiplication by composing on black: */␍␊ |
335 | png_memset(&png_ptr->background, 0, sizeof png_ptr->background);␍␊ |
336 | png_ptr->background_gamma = png_ptr->gamma; /* just in case */␍␊ |
337 | png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;␍␊ |
338 | png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;␍␊ |
339 | ␍␊ |
340 | if (png_ptr->transformations & PNG_COMPOSE)␍␊ |
341 | png_error(png_ptr,␍␊ |
342 | "conflicting calls to set alpha mode and background");␍␊ |
343 | ␍␊ |
344 | png_ptr->transformations |= PNG_COMPOSE;␍␊ |
345 | }␍␊ |
346 | ␍␊ |
347 | /* New API, make sure apps call the correct initializers: */␍␊ |
348 | png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;␍␊ |
349 | }␍␊ |
350 | ␍␊ |
351 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
352 | void PNGAPI␍␊ |
353 | png_set_alpha_mode(png_structp png_ptr, int mode, double output_gamma)␍␊ |
354 | {␍␊ |
355 | png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,␍␊ |
356 | output_gamma));␍␊ |
357 | }␍␊ |
358 | # endif␍␊ |
359 | #endif␍␊ |
360 | ␍␊ |
361 | #ifdef PNG_READ_QUANTIZE_SUPPORTED␍␊ |
362 | /* Dither file to 8-bit. Supply a palette, the current number␍␊ |
363 | * of elements in the palette, the maximum number of elements␍␊ |
364 | * allowed, and a histogram if possible. If the current number␍␊ |
365 | * of colors is greater then the maximum number, the palette will be␍␊ |
366 | * modified to fit in the maximum number. "full_quantize" indicates␍␊ |
367 | * whether we need a quantizing cube set up for RGB images, or if we␍␊ |
368 | * simply are reducing the number of colors in a paletted image.␍␊ |
369 | */␍␊ |
370 | ␍␊ |
371 | typedef struct png_dsort_struct␍␊ |
372 | {␍␊ |
373 | struct png_dsort_struct FAR * next;␍␊ |
374 | png_byte left;␍␊ |
375 | png_byte right;␍␊ |
376 | } png_dsort;␍␊ |
377 | typedef png_dsort FAR * png_dsortp;␍␊ |
378 | typedef png_dsort FAR * FAR * png_dsortpp;␍␊ |
379 | ␍␊ |
380 | void PNGAPI␍␊ |
381 | png_set_quantize(png_structp png_ptr, png_colorp palette,␍␊ |
382 | int num_palette, int maximum_colors, png_const_uint_16p histogram,␍␊ |
383 | int full_quantize)␍␊ |
384 | {␍␊ |
385 | png_debug(1, "in png_set_quantize");␍␊ |
386 | ␍␊ |
387 | if (png_ptr == NULL)␍␊ |
388 | return;␍␊ |
389 | ␍␊ |
390 | png_ptr->transformations |= PNG_QUANTIZE;␍␊ |
391 | ␍␊ |
392 | if (!full_quantize)␍␊ |
393 | {␍␊ |
394 | int i;␍␊ |
395 | ␍␊ |
396 | png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,␍␊ |
397 | (png_uint_32)(num_palette * png_sizeof(png_byte)));␍␊ |
398 | for (i = 0; i < num_palette; i++)␍␊ |
399 | png_ptr->quantize_index[i] = (png_byte)i;␍␊ |
400 | }␍␊ |
401 | ␍␊ |
402 | if (num_palette > maximum_colors)␍␊ |
403 | {␍␊ |
404 | if (histogram != NULL)␍␊ |
405 | {␍␊ |
406 | /* This is easy enough, just throw out the least used colors.␍␊ |
407 | * Perhaps not the best solution, but good enough.␍␊ |
408 | */␍␊ |
409 | ␍␊ |
410 | int i;␍␊ |
411 | ␍␊ |
412 | /* Initialize an array to sort colors */␍␊ |
413 | png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,␍␊ |
414 | (png_uint_32)(num_palette * png_sizeof(png_byte)));␍␊ |
415 | ␍␊ |
416 | /* Initialize the quantize_sort array */␍␊ |
417 | for (i = 0; i < num_palette; i++)␍␊ |
418 | png_ptr->quantize_sort[i] = (png_byte)i;␍␊ |
419 | ␍␊ |
420 | /* Find the least used palette entries by starting a␍␊ |
421 | * bubble sort, and running it until we have sorted␍␊ |
422 | * out enough colors. Note that we don't care about␍␊ |
423 | * sorting all the colors, just finding which are␍␊ |
424 | * least used.␍␊ |
425 | */␍␊ |
426 | ␍␊ |
427 | for (i = num_palette - 1; i >= maximum_colors; i--)␍␊ |
428 | {␍␊ |
429 | int done; /* To stop early if the list is pre-sorted */␍␊ |
430 | int j;␍␊ |
431 | ␍␊ |
432 | done = 1;␍␊ |
433 | for (j = 0; j < i; j++)␍␊ |
434 | {␍␊ |
435 | if (histogram[png_ptr->quantize_sort[j]]␍␊ |
436 | < histogram[png_ptr->quantize_sort[j + 1]])␍␊ |
437 | {␍␊ |
438 | png_byte t;␍␊ |
439 | ␍␊ |
440 | t = png_ptr->quantize_sort[j];␍␊ |
441 | png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];␍␊ |
442 | png_ptr->quantize_sort[j + 1] = t;␍␊ |
443 | done = 0;␍␊ |
444 | }␍␊ |
445 | }␍␊ |
446 | ␍␊ |
447 | if (done)␍␊ |
448 | break;␍␊ |
449 | }␍␊ |
450 | ␍␊ |
451 | /* Swap the palette around, and set up a table, if necessary */␍␊ |
452 | if (full_quantize)␍␊ |
453 | {␍␊ |
454 | int j = num_palette;␍␊ |
455 | ␍␊ |
456 | /* Put all the useful colors within the max, but don't␍␊ |
457 | * move the others.␍␊ |
458 | */␍␊ |
459 | for (i = 0; i < maximum_colors; i++)␍␊ |
460 | {␍␊ |
461 | if ((int)png_ptr->quantize_sort[i] >= maximum_colors)␍␊ |
462 | {␍␊ |
463 | do␍␊ |
464 | j--;␍␊ |
465 | while ((int)png_ptr->quantize_sort[j] >= maximum_colors);␍␊ |
466 | ␍␊ |
467 | palette[i] = palette[j];␍␊ |
468 | }␍␊ |
469 | }␍␊ |
470 | }␍␊ |
471 | else␍␊ |
472 | {␍␊ |
473 | int j = num_palette;␍␊ |
474 | ␍␊ |
475 | /* Move all the used colors inside the max limit, and␍␊ |
476 | * develop a translation table.␍␊ |
477 | */␍␊ |
478 | for (i = 0; i < maximum_colors; i++)␍␊ |
479 | {␍␊ |
480 | /* Only move the colors we need to */␍␊ |
481 | if ((int)png_ptr->quantize_sort[i] >= maximum_colors)␍␊ |
482 | {␍␊ |
483 | png_color tmp_color;␍␊ |
484 | ␍␊ |
485 | do␍␊ |
486 | j--;␍␊ |
487 | while ((int)png_ptr->quantize_sort[j] >= maximum_colors);␍␊ |
488 | ␍␊ |
489 | tmp_color = palette[j];␍␊ |
490 | palette[j] = palette[i];␍␊ |
491 | palette[i] = tmp_color;␍␊ |
492 | /* Indicate where the color went */␍␊ |
493 | png_ptr->quantize_index[j] = (png_byte)i;␍␊ |
494 | png_ptr->quantize_index[i] = (png_byte)j;␍␊ |
495 | }␍␊ |
496 | }␍␊ |
497 | ␍␊ |
498 | /* Find closest color for those colors we are not using */␍␊ |
499 | for (i = 0; i < num_palette; i++)␍␊ |
500 | {␍␊ |
501 | if ((int)png_ptr->quantize_index[i] >= maximum_colors)␍␊ |
502 | {␍␊ |
503 | int min_d, k, min_k, d_index;␍␊ |
504 | ␍␊ |
505 | /* Find the closest color to one we threw out */␍␊ |
506 | d_index = png_ptr->quantize_index[i];␍␊ |
507 | min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);␍␊ |
508 | for (k = 1, min_k = 0; k < maximum_colors; k++)␍␊ |
509 | {␍␊ |
510 | int d;␍␊ |
511 | ␍␊ |
512 | d = PNG_COLOR_DIST(palette[d_index], palette[k]);␍␊ |
513 | ␍␊ |
514 | if (d < min_d)␍␊ |
515 | {␍␊ |
516 | min_d = d;␍␊ |
517 | min_k = k;␍␊ |
518 | }␍␊ |
519 | }␍␊ |
520 | /* Point to closest color */␍␊ |
521 | png_ptr->quantize_index[i] = (png_byte)min_k;␍␊ |
522 | }␍␊ |
523 | }␍␊ |
524 | }␍␊ |
525 | png_free(png_ptr, png_ptr->quantize_sort);␍␊ |
526 | png_ptr->quantize_sort = NULL;␍␊ |
527 | }␍␊ |
528 | else␍␊ |
529 | {␍␊ |
530 | /* This is much harder to do simply (and quickly). Perhaps␍␊ |
531 | * we need to go through a median cut routine, but those␍␊ |
532 | * don't always behave themselves with only a few colors␍␊ |
533 | * as input. So we will just find the closest two colors,␍␊ |
534 | * and throw out one of them (chosen somewhat randomly).␍␊ |
535 | * [We don't understand this at all, so if someone wants to␍␊ |
536 | * work on improving it, be our guest - AED, GRP]␍␊ |
537 | */␍␊ |
538 | int i;␍␊ |
539 | int max_d;␍␊ |
540 | int num_new_palette;␍␊ |
541 | png_dsortp t;␍␊ |
542 | png_dsortpp hash;␍␊ |
543 | ␍␊ |
544 | t = NULL;␍␊ |
545 | ␍␊ |
546 | /* Initialize palette index arrays */␍␊ |
547 | png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,␍␊ |
548 | (png_uint_32)(num_palette * png_sizeof(png_byte)));␍␊ |
549 | png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,␍␊ |
550 | (png_uint_32)(num_palette * png_sizeof(png_byte)));␍␊ |
551 | ␍␊ |
552 | /* Initialize the sort array */␍␊ |
553 | for (i = 0; i < num_palette; i++)␍␊ |
554 | {␍␊ |
555 | png_ptr->index_to_palette[i] = (png_byte)i;␍␊ |
556 | png_ptr->palette_to_index[i] = (png_byte)i;␍␊ |
557 | }␍␊ |
558 | ␍␊ |
559 | hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *␍␊ |
560 | png_sizeof(png_dsortp)));␍␊ |
561 | ␍␊ |
562 | num_new_palette = num_palette;␍␊ |
563 | ␍␊ |
564 | /* Initial wild guess at how far apart the farthest pixel␍␊ |
565 | * pair we will be eliminating will be. Larger␍␊ |
566 | * numbers mean more areas will be allocated, Smaller␍␊ |
567 | * numbers run the risk of not saving enough data, and␍␊ |
568 | * having to do this all over again.␍␊ |
569 | *␍␊ |
570 | * I have not done extensive checking on this number.␍␊ |
571 | */␍␊ |
572 | max_d = 96;␍␊ |
573 | ␍␊ |
574 | while (num_new_palette > maximum_colors)␍␊ |
575 | {␍␊ |
576 | for (i = 0; i < num_new_palette - 1; i++)␍␊ |
577 | {␍␊ |
578 | int j;␍␊ |
579 | ␍␊ |
580 | for (j = i + 1; j < num_new_palette; j++)␍␊ |
581 | {␍␊ |
582 | int d;␍␊ |
583 | ␍␊ |
584 | d = PNG_COLOR_DIST(palette[i], palette[j]);␍␊ |
585 | ␍␊ |
586 | if (d <= max_d)␍␊ |
587 | {␍␊ |
588 | ␍␊ |
589 | t = (png_dsortp)png_malloc_warn(png_ptr,␍␊ |
590 | (png_uint_32)(png_sizeof(png_dsort)));␍␊ |
591 | ␍␊ |
592 | if (t == NULL)␍␊ |
593 | break;␍␊ |
594 | ␍␊ |
595 | t->next = hash[d];␍␊ |
596 | t->left = (png_byte)i;␍␊ |
597 | t->right = (png_byte)j;␍␊ |
598 | hash[d] = t;␍␊ |
599 | }␍␊ |
600 | }␍␊ |
601 | if (t == NULL)␍␊ |
602 | break;␍␊ |
603 | }␍␊ |
604 | ␍␊ |
605 | if (t != NULL)␍␊ |
606 | for (i = 0; i <= max_d; i++)␍␊ |
607 | {␍␊ |
608 | if (hash[i] != NULL)␍␊ |
609 | {␍␊ |
610 | png_dsortp p;␍␊ |
611 | ␍␊ |
612 | for (p = hash[i]; p; p = p->next)␍␊ |
613 | {␍␊ |
614 | if ((int)png_ptr->index_to_palette[p->left]␍␊ |
615 | < num_new_palette &&␍␊ |
616 | (int)png_ptr->index_to_palette[p->right]␍␊ |
617 | < num_new_palette)␍␊ |
618 | {␍␊ |
619 | int j, next_j;␍␊ |
620 | ␍␊ |
621 | if (num_new_palette & 0x01)␍␊ |
622 | {␍␊ |
623 | j = p->left;␍␊ |
624 | next_j = p->right;␍␊ |
625 | }␍␊ |
626 | else␍␊ |
627 | {␍␊ |
628 | j = p->right;␍␊ |
629 | next_j = p->left;␍␊ |
630 | }␍␊ |
631 | ␍␊ |
632 | num_new_palette--;␍␊ |
633 | palette[png_ptr->index_to_palette[j]]␍␊ |
634 | = palette[num_new_palette];␍␊ |
635 | if (!full_quantize)␍␊ |
636 | {␍␊ |
637 | int k;␍␊ |
638 | ␍␊ |
639 | for (k = 0; k < num_palette; k++)␍␊ |
640 | {␍␊ |
641 | if (png_ptr->quantize_index[k] ==␍␊ |
642 | png_ptr->index_to_palette[j])␍␊ |
643 | png_ptr->quantize_index[k] =␍␊ |
644 | png_ptr->index_to_palette[next_j];␍␊ |
645 | ␍␊ |
646 | if ((int)png_ptr->quantize_index[k] ==␍␊ |
647 | num_new_palette)␍␊ |
648 | png_ptr->quantize_index[k] =␍␊ |
649 | png_ptr->index_to_palette[j];␍␊ |
650 | }␍␊ |
651 | }␍␊ |
652 | ␍␊ |
653 | png_ptr->index_to_palette[png_ptr->palette_to_index␍␊ |
654 | [num_new_palette]] = png_ptr->index_to_palette[j];␍␊ |
655 | ␍␊ |
656 | png_ptr->palette_to_index[png_ptr->index_to_palette[j]]␍␊ |
657 | = png_ptr->palette_to_index[num_new_palette];␍␊ |
658 | ␍␊ |
659 | png_ptr->index_to_palette[j] =␍␊ |
660 | (png_byte)num_new_palette;␍␊ |
661 | ␍␊ |
662 | png_ptr->palette_to_index[num_new_palette] =␍␊ |
663 | (png_byte)j;␍␊ |
664 | }␍␊ |
665 | if (num_new_palette <= maximum_colors)␍␊ |
666 | break;␍␊ |
667 | }␍␊ |
668 | if (num_new_palette <= maximum_colors)␍␊ |
669 | break;␍␊ |
670 | }␍␊ |
671 | }␍␊ |
672 | ␍␊ |
673 | for (i = 0; i < 769; i++)␍␊ |
674 | {␍␊ |
675 | if (hash[i] != NULL)␍␊ |
676 | {␍␊ |
677 | png_dsortp p = hash[i];␍␊ |
678 | while (p)␍␊ |
679 | {␍␊ |
680 | t = p->next;␍␊ |
681 | png_free(png_ptr, p);␍␊ |
682 | p = t;␍␊ |
683 | }␍␊ |
684 | }␍␊ |
685 | hash[i] = 0;␍␊ |
686 | }␍␊ |
687 | max_d += 96;␍␊ |
688 | }␍␊ |
689 | png_free(png_ptr, hash);␍␊ |
690 | png_free(png_ptr, png_ptr->palette_to_index);␍␊ |
691 | png_free(png_ptr, png_ptr->index_to_palette);␍␊ |
692 | png_ptr->palette_to_index = NULL;␍␊ |
693 | png_ptr->index_to_palette = NULL;␍␊ |
694 | }␍␊ |
695 | num_palette = maximum_colors;␍␊ |
696 | }␍␊ |
697 | if (png_ptr->palette == NULL)␍␊ |
698 | {␍␊ |
699 | png_ptr->palette = palette;␍␊ |
700 | }␍␊ |
701 | png_ptr->num_palette = (png_uint_16)num_palette;␍␊ |
702 | ␍␊ |
703 | if (full_quantize)␍␊ |
704 | {␍␊ |
705 | int i;␍␊ |
706 | png_bytep distance;␍␊ |
707 | int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +␍␊ |
708 | PNG_QUANTIZE_BLUE_BITS;␍␊ |
709 | int num_red = (1 << PNG_QUANTIZE_RED_BITS);␍␊ |
710 | int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);␍␊ |
711 | int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);␍␊ |
712 | png_size_t num_entries = ((png_size_t)1 << total_bits);␍␊ |
713 | ␍␊ |
714 | png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,␍␊ |
715 | (png_uint_32)(num_entries * png_sizeof(png_byte)));␍␊ |
716 | ␍␊ |
717 | distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *␍␊ |
718 | png_sizeof(png_byte)));␍␊ |
719 | ␍␊ |
720 | png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));␍␊ |
721 | ␍␊ |
722 | for (i = 0; i < num_palette; i++)␍␊ |
723 | {␍␊ |
724 | int ir, ig, ib;␍␊ |
725 | int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));␍␊ |
726 | int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));␍␊ |
727 | int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));␍␊ |
728 | ␍␊ |
729 | for (ir = 0; ir < num_red; ir++)␍␊ |
730 | {␍␊ |
731 | /* int dr = abs(ir - r); */␍␊ |
732 | int dr = ((ir > r) ? ir - r : r - ir);␍␊ |
733 | int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +␍␊ |
734 | PNG_QUANTIZE_GREEN_BITS));␍␊ |
735 | ␍␊ |
736 | for (ig = 0; ig < num_green; ig++)␍␊ |
737 | {␍␊ |
738 | /* int dg = abs(ig - g); */␍␊ |
739 | int dg = ((ig > g) ? ig - g : g - ig);␍␊ |
740 | int dt = dr + dg;␍␊ |
741 | int dm = ((dr > dg) ? dr : dg);␍␊ |
742 | int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);␍␊ |
743 | ␍␊ |
744 | for (ib = 0; ib < num_blue; ib++)␍␊ |
745 | {␍␊ |
746 | int d_index = index_g | ib;␍␊ |
747 | /* int db = abs(ib - b); */␍␊ |
748 | int db = ((ib > b) ? ib - b : b - ib);␍␊ |
749 | int dmax = ((dm > db) ? dm : db);␍␊ |
750 | int d = dmax + dt + db;␍␊ |
751 | ␍␊ |
752 | if (d < (int)distance[d_index])␍␊ |
753 | {␍␊ |
754 | distance[d_index] = (png_byte)d;␍␊ |
755 | png_ptr->palette_lookup[d_index] = (png_byte)i;␍␊ |
756 | }␍␊ |
757 | }␍␊ |
758 | }␍␊ |
759 | }␍␊ |
760 | }␍␊ |
761 | ␍␊ |
762 | png_free(png_ptr, distance);␍␊ |
763 | }␍␊ |
764 | }␍␊ |
765 | #endif /* PNG_READ_QUANTIZE_SUPPORTED */␍␊ |
766 | ␍␊ |
767 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
768 | void PNGFAPI␍␊ |
769 | png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma,␍␊ |
770 | png_fixed_point file_gamma)␍␊ |
771 | {␍␊ |
772 | png_debug(1, "in png_set_gamma_fixed");␍␊ |
773 | ␍␊ |
774 | if (png_ptr == NULL)␍␊ |
775 | return;␍␊ |
776 | ␍␊ |
777 | /* New in libpng-1.5.4 - reserve particular negative values as flags. */␍␊ |
778 | scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);␍␊ |
779 | file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);␍␊ |
780 | ␍␊ |
781 | #if PNG_LIBPNG_VER >= 10600␍␊ |
782 | /* Checking the gamma values for being >0 was added in 1.5.4 along with the␍␊ |
783 | * premultiplied alpha support; this actually hides an undocumented feature␍␊ |
784 | * of the previous implementation which allowed gamma processing to be␍␊ |
785 | * disabled in background handling. There is no evidence (so far) that this␍␊ |
786 | * was being used; however, png_set_background itself accepted and must still␍␊ |
787 | * accept '0' for the gamma value it takes, because it isn't always used.␍␊ |
788 | *␍␊ |
789 | * Since this is an API change (albeit a very minor one that removes an␍␊ |
790 | * undocumented API feature) it will not be made until libpng-1.6.0.␍␊ |
791 | */␍␊ |
792 | if (file_gamma <= 0)␍␊ |
793 | png_error(png_ptr, "invalid file gamma in png_set_gamma");␍␊ |
794 | ␍␊ |
795 | if (scrn_gamma <= 0)␍␊ |
796 | png_error(png_ptr, "invalid screen gamma in png_set_gamma");␍␊ |
797 | #endif␍␊ |
798 | ␍␊ |
799 | /* Set the gamma values unconditionally - this overrides the value in the PNG␍␊ |
800 | * file if a gAMA chunk was present. png_set_alpha_mode provides a␍␊ |
801 | * different, easier, way to default the file gamma.␍␊ |
802 | */␍␊ |
803 | png_ptr->gamma = file_gamma;␍␊ |
804 | png_ptr->screen_gamma = scrn_gamma;␍␊ |
805 | }␍␊ |
806 | ␍␊ |
807 | # ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
808 | void PNGAPI␍␊ |
809 | png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)␍␊ |
810 | {␍␊ |
811 | png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),␍␊ |
812 | convert_gamma_value(png_ptr, file_gamma));␍␊ |
813 | }␍␊ |
814 | # endif /* FLOATING_POINT_SUPPORTED */␍␊ |
815 | #endif /* READ_GAMMA */␍␊ |
816 | ␍␊ |
817 | #ifdef PNG_READ_EXPAND_SUPPORTED␍␊ |
818 | /* Expand paletted images to RGB, expand grayscale images of␍␊ |
819 | * less than 8-bit depth to 8-bit depth, and expand tRNS chunks␍␊ |
820 | * to alpha channels.␍␊ |
821 | */␍␊ |
822 | void PNGAPI␍␊ |
823 | png_set_expand(png_structp png_ptr)␍␊ |
824 | {␍␊ |
825 | png_debug(1, "in png_set_expand");␍␊ |
826 | ␍␊ |
827 | if (png_ptr == NULL)␍␊ |
828 | return;␍␊ |
829 | ␍␊ |
830 | png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);␍␊ |
831 | png_ptr->flags &= ~PNG_FLAG_ROW_INIT;␍␊ |
832 | }␍␊ |
833 | ␍␊ |
834 | /* GRR 19990627: the following three functions currently are identical␍␊ |
835 | * to png_set_expand(). However, it is entirely reasonable that someone␍␊ |
836 | * might wish to expand an indexed image to RGB but *not* expand a single,␍␊ |
837 | * fully transparent palette entry to a full alpha channel--perhaps instead␍␊ |
838 | * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace␍␊ |
839 | * the transparent color with a particular RGB value, or drop tRNS entirely.␍␊ |
840 | * IOW, a future version of the library may make the transformations flag␍␊ |
841 | * a bit more fine-grained, with separate bits for each of these three␍␊ |
842 | * functions.␍␊ |
843 | *␍␊ |
844 | * More to the point, these functions make it obvious what libpng will be␍␊ |
845 | * doing, whereas "expand" can (and does) mean any number of things.␍␊ |
846 | *␍␊ |
847 | * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified␍␊ |
848 | * to expand only the sample depth but not to expand the tRNS to alpha␍␊ |
849 | * and its name was changed to png_set_expand_gray_1_2_4_to_8().␍␊ |
850 | */␍␊ |
851 | ␍␊ |
852 | /* Expand paletted images to RGB. */␍␊ |
853 | void PNGAPI␍␊ |
854 | png_set_palette_to_rgb(png_structp png_ptr)␍␊ |
855 | {␍␊ |
856 | png_debug(1, "in png_set_palette_to_rgb");␍␊ |
857 | ␍␊ |
858 | if (png_ptr == NULL)␍␊ |
859 | return;␍␊ |
860 | ␍␊ |
861 | png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);␍␊ |
862 | png_ptr->flags &= ~PNG_FLAG_ROW_INIT;␍␊ |
863 | }␍␊ |
864 | ␍␊ |
865 | /* Expand grayscale images of less than 8-bit depth to 8 bits. */␍␊ |
866 | void PNGAPI␍␊ |
867 | png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)␍␊ |
868 | {␍␊ |
869 | png_debug(1, "in png_set_expand_gray_1_2_4_to_8");␍␊ |
870 | ␍␊ |
871 | if (png_ptr == NULL)␍␊ |
872 | return;␍␊ |
873 | ␍␊ |
874 | png_ptr->transformations |= PNG_EXPAND;␍␊ |
875 | png_ptr->flags &= ~PNG_FLAG_ROW_INIT;␍␊ |
876 | }␍␊ |
877 | ␍␊ |
878 | ␍␊ |
879 | ␍␊ |
880 | /* Expand tRNS chunks to alpha channels. */␍␊ |
881 | void PNGAPI␍␊ |
882 | png_set_tRNS_to_alpha(png_structp png_ptr)␍␊ |
883 | {␍␊ |
884 | png_debug(1, "in png_set_tRNS_to_alpha");␍␊ |
885 | ␍␊ |
886 | png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);␍␊ |
887 | png_ptr->flags &= ~PNG_FLAG_ROW_INIT;␍␊ |
888 | }␍␊ |
889 | #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */␍␊ |
890 | ␍␊ |
891 | #ifdef PNG_READ_EXPAND_16_SUPPORTED␍␊ |
892 | /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise␍␊ |
893 | * it may not work correctly.)␍␊ |
894 | */␍␊ |
895 | void PNGAPI␍␊ |
896 | png_set_expand_16(png_structp png_ptr)␍␊ |
897 | {␍␊ |
898 | png_debug(1, "in png_set_expand_16");␍␊ |
899 | ␍␊ |
900 | if (png_ptr == NULL)␍␊ |
901 | return;␍␊ |
902 | ␍␊ |
903 | png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);␍␊ |
904 | png_ptr->flags &= ~PNG_FLAG_ROW_INIT;␍␊ |
905 | ␍␊ |
906 | /* New API, make sure apps call the correct initializers: */␍␊ |
907 | png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;␍␊ |
908 | }␍␊ |
909 | #endif␍␊ |
910 | ␍␊ |
911 | #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED␍␊ |
912 | void PNGAPI␍␊ |
913 | png_set_gray_to_rgb(png_structp png_ptr)␍␊ |
914 | {␍␊ |
915 | png_debug(1, "in png_set_gray_to_rgb");␍␊ |
916 | ␍␊ |
917 | if (png_ptr != NULL)␍␊ |
918 | {␍␊ |
919 | /* Because rgb must be 8 bits or more: */␍␊ |
920 | png_set_expand_gray_1_2_4_to_8(png_ptr);␍␊ |
921 | png_ptr->transformations |= PNG_GRAY_TO_RGB;␍␊ |
922 | png_ptr->flags &= ~PNG_FLAG_ROW_INIT;␍␊ |
923 | }␍␊ |
924 | }␍␊ |
925 | #endif␍␊ |
926 | ␍␊ |
927 | #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED␍␊ |
928 | void PNGFAPI␍␊ |
929 | png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,␍␊ |
930 | png_fixed_point red, png_fixed_point green)␍␊ |
931 | {␍␊ |
932 | png_debug(1, "in png_set_rgb_to_gray");␍␊ |
933 | ␍␊ |
934 | if (png_ptr == NULL)␍␊ |
935 | return;␍␊ |
936 | ␍␊ |
937 | switch(error_action)␍␊ |
938 | {␍␊ |
939 | case PNG_ERROR_ACTION_NONE:␍␊ |
940 | png_ptr->transformations |= PNG_RGB_TO_GRAY;␍␊ |
941 | break;␍␊ |
942 | ␍␊ |
943 | case PNG_ERROR_ACTION_WARN:␍␊ |
944 | png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;␍␊ |
945 | break;␍␊ |
946 | ␍␊ |
947 | case PNG_ERROR_ACTION_ERROR:␍␊ |
948 | png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;␍␊ |
949 | break;␍␊ |
950 | ␍␊ |
951 | default:␍␊ |
952 | png_error(png_ptr, "invalid error action to rgb_to_gray");␍␊ |
953 | break;␍␊ |
954 | }␍␊ |
955 | if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
956 | #ifdef PNG_READ_EXPAND_SUPPORTED␍␊ |
957 | png_ptr->transformations |= PNG_EXPAND;␍␊ |
958 | #else␍␊ |
959 | {␍␊ |
960 | png_warning(png_ptr,␍␊ |
961 | "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");␍␊ |
962 | ␍␊ |
963 | png_ptr->transformations &= ~PNG_RGB_TO_GRAY;␍␊ |
964 | }␍␊ |
965 | #endif␍␊ |
966 | {␍␊ |
967 | if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)␍␊ |
968 | {␍␊ |
969 | png_uint_16 red_int, green_int;␍␊ |
970 | ␍␊ |
971 | /* NOTE: this calculation does not round, but this behavior is retained␍␊ |
972 | * for consistency, the inaccuracy is very small. The code here always␍␊ |
973 | * overwrites the coefficients, regardless of whether they have been␍␊ |
974 | * defaulted or set already.␍␊ |
975 | */␍␊ |
976 | red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);␍␊ |
977 | green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);␍␊ |
978 | ␍␊ |
979 | png_ptr->rgb_to_gray_red_coeff = red_int;␍␊ |
980 | png_ptr->rgb_to_gray_green_coeff = green_int;␍␊ |
981 | png_ptr->rgb_to_gray_coefficients_set = 1;␍␊ |
982 | }␍␊ |
983 | ␍␊ |
984 | else␍␊ |
985 | {␍␊ |
986 | if (red >= 0 && green >= 0)␍␊ |
987 | png_warning(png_ptr,␍␊ |
988 | "ignoring out of range rgb_to_gray coefficients");␍␊ |
989 | ␍␊ |
990 | /* Use the defaults, from the cHRM chunk if set, else the historical␍␊ |
991 | * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See␍␊ |
992 | * png_do_rgb_to_gray for more discussion of the values. In this case␍␊ |
993 | * the coefficients are not marked as 'set' and are not overwritten if␍␊ |
994 | * something has already provided a default.␍␊ |
995 | */␍␊ |
996 | if (png_ptr->rgb_to_gray_red_coeff == 0 &&␍␊ |
997 | png_ptr->rgb_to_gray_green_coeff == 0)␍␊ |
998 | {␍␊ |
999 | png_ptr->rgb_to_gray_red_coeff = 6968;␍␊ |
1000 | png_ptr->rgb_to_gray_green_coeff = 23434;␍␊ |
1001 | /* png_ptr->rgb_to_gray_blue_coeff = 2366; */␍␊ |
1002 | }␍␊ |
1003 | }␍␊ |
1004 | }␍␊ |
1005 | }␍␊ |
1006 | ␍␊ |
1007 | #ifdef PNG_FLOATING_POINT_SUPPORTED␍␊ |
1008 | /* Convert a RGB image to a grayscale of the same width. This allows us,␍␊ |
1009 | * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.␍␊ |
1010 | */␍␊ |
1011 | ␍␊ |
1012 | void PNGAPI␍␊ |
1013 | png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,␍␊ |
1014 | double green)␍␊ |
1015 | {␍␊ |
1016 | if (png_ptr == NULL)␍␊ |
1017 | return;␍␊ |
1018 | ␍␊ |
1019 | png_set_rgb_to_gray_fixed(png_ptr, error_action,␍␊ |
1020 | png_fixed(png_ptr, red, "rgb to gray red coefficient"),␍␊ |
1021 | png_fixed(png_ptr, green, "rgb to gray green coefficient"));␍␊ |
1022 | }␍␊ |
1023 | #endif /* FLOATING POINT */␍␊ |
1024 | ␍␊ |
1025 | #endif␍␊ |
1026 | ␍␊ |
1027 | #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \␍␊ |
1028 | defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)␍␊ |
1029 | void PNGAPI␍␊ |
1030 | png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr␍␊ |
1031 | read_user_transform_fn)␍␊ |
1032 | {␍␊ |
1033 | png_debug(1, "in png_set_read_user_transform_fn");␍␊ |
1034 | ␍␊ |
1035 | if (png_ptr == NULL)␍␊ |
1036 | return;␍␊ |
1037 | ␍␊ |
1038 | #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED␍␊ |
1039 | png_ptr->transformations |= PNG_USER_TRANSFORM;␍␊ |
1040 | png_ptr->read_user_transform_fn = read_user_transform_fn;␍␊ |
1041 | #endif␍␊ |
1042 | }␍␊ |
1043 | #endif␍␊ |
1044 | ␍␊ |
1045 | #ifdef PNG_READ_TRANSFORMS_SUPPORTED␍␊ |
1046 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
1047 | /* In the case of gamma transformations only do transformations on images where␍␊ |
1048 | * the [file] gamma and screen_gamma are not close reciprocals, otherwise it␍␊ |
1049 | * slows things down slightly, and also needlessly introduces small errors.␍␊ |
1050 | */␍␊ |
1051 | static int /* PRIVATE */␍␊ |
1052 | png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)␍␊ |
1053 | {␍␊ |
1054 | /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma␍␊ |
1055 | * correction as a difference of the overall transform from 1.0␍␊ |
1056 | *␍␊ |
1057 | * We want to compare the threshold with s*f - 1, if we get␍␊ |
1058 | * overflow here it is because of wacky gamma values so we␍␊ |
1059 | * turn on processing anyway.␍␊ |
1060 | */␍␊ |
1061 | png_fixed_point gtest;␍␊ |
1062 | return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) ||␍␊ |
1063 | png_gamma_significant(gtest);␍␊ |
1064 | }␍␊ |
1065 | #endif␍␊ |
1066 | ␍␊ |
1067 | /* Initialize everything needed for the read. This includes modifying␍␊ |
1068 | * the palette.␍␊ |
1069 | */␍␊ |
1070 | ␍␊ |
1071 | /*For the moment 'png_init_palette_transformations' and␍␊ |
1072 | * 'png_init_rgb_transformations' only do some flag canceling optimizations.␍␊ |
1073 | * The intent is that these two routines should have palette or rgb operations␍␊ |
1074 | * extracted from 'png_init_read_transformations'.␍␊ |
1075 | */␍␊ |
1076 | static void /* PRIVATE */␍␊ |
1077 | png_init_palette_transformations(png_structp png_ptr)␍␊ |
1078 | {␍␊ |
1079 | /* Called to handle the (input) palette case. In png_do_read_transformations␍␊ |
1080 | * the first step is to expand the palette if requested, so this code must␍␊ |
1081 | * take care to only make changes that are invariant with respect to the␍␊ |
1082 | * palette expansion, or only do them if there is no expansion.␍␊ |
1083 | *␍␊ |
1084 | * STRIP_ALPHA has already been handled in the caller (by setting num_trans␍␊ |
1085 | * to 0.)␍␊ |
1086 | */␍␊ |
1087 | int input_has_alpha = 0;␍␊ |
1088 | int input_has_transparency = 0;␍␊ |
1089 | ␍␊ |
1090 | if (png_ptr->num_trans > 0)␍␊ |
1091 | {␍␊ |
1092 | int i;␍␊ |
1093 | ␍␊ |
1094 | /* Ignore if all the entries are opaque (unlikely!) */␍␊ |
1095 | for (i=0; i<png_ptr->num_trans; ++i)␍␊ |
1096 | if (png_ptr->trans_alpha[i] == 255)␍␊ |
1097 | continue;␍␊ |
1098 | else if (png_ptr->trans_alpha[i] == 0)␍␊ |
1099 | input_has_transparency = 1;␍␊ |
1100 | else␍␊ |
1101 | input_has_alpha = 1;␍␊ |
1102 | }␍␊ |
1103 | ␍␊ |
1104 | /* If no alpha we can optimize. */␍␊ |
1105 | if (!input_has_alpha)␍␊ |
1106 | {␍␊ |
1107 | /* Any alpha means background and associative alpha processing is␍␊ |
1108 | * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA␍␊ |
1109 | * and ENCODE_ALPHA are irrelevant.␍␊ |
1110 | */␍␊ |
1111 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
1112 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
1113 | ␍␊ |
1114 | if (!input_has_transparency)␍␊ |
1115 | png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);␍␊ |
1116 | }␍␊ |
1117 | ␍␊ |
1118 | #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)␍␊ |
1119 | /* png_set_background handling - deals with the complexity of whether the␍␊ |
1120 | * background color is in the file format or the screen format in the case␍␊ |
1121 | * where an 'expand' will happen.␍␊ |
1122 | */␍␊ |
1123 | ␍␊ |
1124 | /* The following code cannot be entered in the alpha pre-multiplication case␍␊ |
1125 | * because PNG_BACKGROUND_EXPAND is cancelled below.␍␊ |
1126 | */␍␊ |
1127 | if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&␍␊ |
1128 | (png_ptr->transformations & PNG_EXPAND))␍␊ |
1129 | {␍␊ |
1130 | {␍␊ |
1131 | png_ptr->background.red =␍␊ |
1132 | png_ptr->palette[png_ptr->background.index].red;␍␊ |
1133 | png_ptr->background.green =␍␊ |
1134 | png_ptr->palette[png_ptr->background.index].green;␍␊ |
1135 | png_ptr->background.blue =␍␊ |
1136 | png_ptr->palette[png_ptr->background.index].blue;␍␊ |
1137 | ␍␊ |
1138 | #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED␍␊ |
1139 | if (png_ptr->transformations & PNG_INVERT_ALPHA)␍␊ |
1140 | {␍␊ |
1141 | if (!(png_ptr->transformations & PNG_EXPAND_tRNS))␍␊ |
1142 | {␍␊ |
1143 | /* Invert the alpha channel (in tRNS) unless the pixels are␍␊ |
1144 | * going to be expanded, in which case leave it for later␍␊ |
1145 | */␍␊ |
1146 | int i, istop = png_ptr->num_trans;␍␊ |
1147 | ␍␊ |
1148 | for (i=0; i<istop; i++)␍␊ |
1149 | png_ptr->trans_alpha[i] = (png_byte)(255 -␍␊ |
1150 | png_ptr->trans_alpha[i]);␍␊ |
1151 | }␍␊ |
1152 | }␍␊ |
1153 | #endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */␍␊ |
1154 | }␍␊ |
1155 | } /* background expand and (therefore) no alpha association. */␍␊ |
1156 | #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */␍␊ |
1157 | }␍␊ |
1158 | ␍␊ |
1159 | static void /* PRIVATE */␍␊ |
1160 | png_init_rgb_transformations(png_structp png_ptr)␍␊ |
1161 | {␍␊ |
1162 | /* Added to libpng-1.5.4: check the color type to determine whether there␍␊ |
1163 | * is any alpha or transparency in the image and simply cancel the␍␊ |
1164 | * background and alpha mode stuff if there isn't.␍␊ |
1165 | */␍␊ |
1166 | int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;␍␊ |
1167 | int input_has_transparency = png_ptr->num_trans > 0;␍␊ |
1168 | ␍␊ |
1169 | /* If no alpha we can optimize. */␍␊ |
1170 | if (!input_has_alpha)␍␊ |
1171 | {␍␊ |
1172 | /* Any alpha means background and associative alpha processing is␍␊ |
1173 | * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA␍␊ |
1174 | * and ENCODE_ALPHA are irrelevant.␍␊ |
1175 | */␍␊ |
1176 | # ifdef PNG_READ_ALPHA_MODE_SUPPORTED␍␊ |
1177 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
1178 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
1179 | # endif␍␊ |
1180 | ␍␊ |
1181 | if (!input_has_transparency)␍␊ |
1182 | png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);␍␊ |
1183 | }␍␊ |
1184 | ␍␊ |
1185 | #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)␍␊ |
1186 | /* png_set_background handling - deals with the complexity of whether the␍␊ |
1187 | * background color is in the file format or the screen format in the case␍␊ |
1188 | * where an 'expand' will happen.␍␊ |
1189 | */␍␊ |
1190 | ␍␊ |
1191 | /* The following code cannot be entered in the alpha pre-multiplication case␍␊ |
1192 | * because PNG_BACKGROUND_EXPAND is cancelled below.␍␊ |
1193 | */␍␊ |
1194 | if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&␍␊ |
1195 | (png_ptr->transformations & PNG_EXPAND) &&␍␊ |
1196 | !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))␍␊ |
1197 | /* i.e., GRAY or GRAY_ALPHA */␍␊ |
1198 | {␍␊ |
1199 | {␍␊ |
1200 | /* Expand background and tRNS chunks */␍␊ |
1201 | int gray = png_ptr->background.gray;␍␊ |
1202 | int trans_gray = png_ptr->trans_color.gray;␍␊ |
1203 | ␍␊ |
1204 | switch (png_ptr->bit_depth)␍␊ |
1205 | {␍␊ |
1206 | case 1:␍␊ |
1207 | gray *= 0xff;␍␊ |
1208 | trans_gray *= 0xff;␍␊ |
1209 | break;␍␊ |
1210 | ␍␊ |
1211 | case 2:␍␊ |
1212 | gray *= 0x55;␍␊ |
1213 | trans_gray *= 0x55;␍␊ |
1214 | break;␍␊ |
1215 | ␍␊ |
1216 | case 4:␍␊ |
1217 | gray *= 0x11;␍␊ |
1218 | trans_gray *= 0x11;␍␊ |
1219 | break;␍␊ |
1220 | ␍␊ |
1221 | default:␍␊ |
1222 | ␍␊ |
1223 | case 8:␍␊ |
1224 | /* Already 8 bits, fall through */␍␊ |
1225 | ␍␊ |
1226 | case 16:␍␊ |
1227 | /* Already a full 16 bits */␍␊ |
1228 | break;␍␊ |
1229 | }␍␊ |
1230 | ␍␊ |
1231 | png_ptr->background.red = png_ptr->background.green =␍␊ |
1232 | png_ptr->background.blue = (png_uint_16)gray;␍␊ |
1233 | ␍␊ |
1234 | if (!(png_ptr->transformations & PNG_EXPAND_tRNS))␍␊ |
1235 | {␍␊ |
1236 | png_ptr->trans_color.red = png_ptr->trans_color.green =␍␊ |
1237 | png_ptr->trans_color.blue = (png_uint_16)trans_gray;␍␊ |
1238 | }␍␊ |
1239 | }␍␊ |
1240 | } /* background expand and (therefore) no alpha association. */␍␊ |
1241 | #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */␍␊ |
1242 | }␍␊ |
1243 | ␍␊ |
1244 | void /* PRIVATE */␍␊ |
1245 | png_init_read_transformations(png_structp png_ptr)␍␊ |
1246 | {␍␊ |
1247 | png_debug(1, "in png_init_read_transformations");␍␊ |
1248 | ␍␊ |
1249 | /* This internal function is called from png_read_start_row in pngrutil.c␍␊ |
1250 | * and it is called before the 'rowbytes' calculation is done, so the code␍␊ |
1251 | * in here can change or update the transformations flags.␍␊ |
1252 | *␍␊ |
1253 | * First do updates that do not depend on the details of the PNG image data␍␊ |
1254 | * being processed.␍␊ |
1255 | */␍␊ |
1256 | ␍␊ |
1257 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
1258 | /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds␍␊ |
1259 | * png_set_alpha_mode and this is another source for a default file gamma so␍␊ |
1260 | * the test needs to be performed later - here. In addition prior to 1.5.4␍␊ |
1261 | * the tests were repeated for the PALETTE color type here - this is no␍␊ |
1262 | * longer necessary (and doesn't seem to have been necessary before.)␍␊ |
1263 | */␍␊ |
1264 | {␍␊ |
1265 | /* The following temporary indicates if overall gamma correction is␍␊ |
1266 | * required.␍␊ |
1267 | */␍␊ |
1268 | int gamma_correction = 0;␍␊ |
1269 | ␍␊ |
1270 | if (png_ptr->gamma != 0) /* has been set */␍␊ |
1271 | {␍␊ |
1272 | if (png_ptr->screen_gamma != 0) /* screen set too */␍␊ |
1273 | gamma_correction = png_gamma_threshold(png_ptr->gamma,␍␊ |
1274 | png_ptr->screen_gamma);␍␊ |
1275 | ␍␊ |
1276 | else␍␊ |
1277 | /* Assume the output matches the input; a long time default behavior␍␊ |
1278 | * of libpng, although the standard has nothing to say about this.␍␊ |
1279 | */␍␊ |
1280 | png_ptr->screen_gamma = png_reciprocal(png_ptr->gamma);␍␊ |
1281 | }␍␊ |
1282 | ␍␊ |
1283 | else if (png_ptr->screen_gamma != 0)␍␊ |
1284 | /* The converse - assume the file matches the screen, note that this␍␊ |
1285 | * perhaps undesireable default can (from 1.5.4) be changed by calling␍␊ |
1286 | * png_set_alpha_mode (even if the alpha handling mode isn't required␍␊ |
1287 | * or isn't changed from the default.)␍␊ |
1288 | */␍␊ |
1289 | png_ptr->gamma = png_reciprocal(png_ptr->screen_gamma);␍␊ |
1290 | ␍␊ |
1291 | else /* neither are set */␍␊ |
1292 | /* Just in case the following prevents any processing - file and screen␍␊ |
1293 | * are both assumed to be linear and there is no way to introduce a␍␊ |
1294 | * third gamma value other than png_set_background with 'UNIQUE', and,␍␊ |
1295 | * prior to 1.5.4␍␊ |
1296 | */␍␊ |
1297 | png_ptr->screen_gamma = png_ptr->gamma = PNG_FP_1;␍␊ |
1298 | ␍␊ |
1299 | /* Now turn the gamma transformation on or off as appropriate. Notice␍␊ |
1300 | * that PNG_GAMMA just refers to the file->screen correction. Alpha␍␊ |
1301 | * composition may independently cause gamma correction because it needs␍␊ |
1302 | * linear data (e.g. if the file has a gAMA chunk but the screen gamma␍␊ |
1303 | * hasn't been specified.) In any case this flag may get turned off in␍␊ |
1304 | * the code immediately below if the transform can be handled outside the␍␊ |
1305 | * row loop.␍␊ |
1306 | */␍␊ |
1307 | if (gamma_correction)␍␊ |
1308 | png_ptr->transformations |= PNG_GAMMA;␍␊ |
1309 | ␍␊ |
1310 | else␍␊ |
1311 | png_ptr->transformations &= ~PNG_GAMMA;␍␊ |
1312 | }␍␊ |
1313 | #endif␍␊ |
1314 | ␍␊ |
1315 | /* Certain transformations have the effect of preventing other␍␊ |
1316 | * transformations that happen afterward in png_do_read_transformations,␍␊ |
1317 | * resolve the interdependencies here. From the code of␍␊ |
1318 | * png_do_read_transformations the order is:␍␊ |
1319 | *␍␊ |
1320 | * 1) PNG_EXPAND (including PNG_EXPAND_tRNS)␍␊ |
1321 | * 2) PNG_STRIP_ALPHA (if no compose)␍␊ |
1322 | * 3) PNG_RGB_TO_GRAY␍␊ |
1323 | * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY␍␊ |
1324 | * 5) PNG_COMPOSE␍␊ |
1325 | * 6) PNG_GAMMA␍␊ |
1326 | * 7) PNG_STRIP_ALPHA (if compose)␍␊ |
1327 | * 8) PNG_ENCODE_ALPHA␍␊ |
1328 | * 9) PNG_SCALE_16_TO_8␍␊ |
1329 | * 10) PNG_16_TO_8␍␊ |
1330 | * 11) PNG_QUANTIZE (converts to palette)␍␊ |
1331 | * 12) PNG_EXPAND_16␍␊ |
1332 | * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY␍␊ |
1333 | * 14) PNG_INVERT_MONO␍␊ |
1334 | * 15) PNG_SHIFT␍␊ |
1335 | * 16) PNG_PACK␍␊ |
1336 | * 17) PNG_BGR␍␊ |
1337 | * 18) PNG_PACKSWAP␍␊ |
1338 | * 19) PNG_FILLER (includes PNG_ADD_ALPHA)␍␊ |
1339 | * 20) PNG_INVERT_ALPHA␍␊ |
1340 | * 21) PNG_SWAP_ALPHA␍␊ |
1341 | * 22) PNG_SWAP_BYTES␍␊ |
1342 | * 23) PNG_USER_TRANSFORM [must be last]␍␊ |
1343 | */␍␊ |
1344 | #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED␍␊ |
1345 | if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&␍␊ |
1346 | !(png_ptr->transformations & PNG_COMPOSE))␍␊ |
1347 | {␍␊ |
1348 | /* Stripping the alpha channel happens immediately after the 'expand'␍␊ |
1349 | * transformations, before all other transformation, so it cancels out␍␊ |
1350 | * the alpha handling. It has the side effect negating the effect of␍␊ |
1351 | * PNG_EXPAND_tRNS too:␍␊ |
1352 | */␍␊ |
1353 | png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |␍␊ |
1354 | PNG_EXPAND_tRNS);␍␊ |
1355 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
1356 | ␍␊ |
1357 | /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen␍␊ |
1358 | * so transparency information would remain just so long as it wasn't␍␊ |
1359 | * expanded. This produces unexpected API changes if the set of things␍␊ |
1360 | * that do PNG_EXPAND_tRNS changes (perfectly possible given the␍␊ |
1361 | * documentation - which says ask for what you want, accept what you␍␊ |
1362 | * get.) This makes the behavior consistent from 1.5.4:␍␊ |
1363 | */␍␊ |
1364 | png_ptr->num_trans = 0;␍␊ |
1365 | }␍␊ |
1366 | #endif /* STRIP_ALPHA supported, no COMPOSE */␍␊ |
1367 | ␍␊ |
1368 | #ifdef PNG_READ_ALPHA_MODE_SUPPORTED␍␊ |
1369 | /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA␍␊ |
1370 | * settings will have no effect.␍␊ |
1371 | */␍␊ |
1372 | if (!png_gamma_significant(png_ptr->screen_gamma))␍␊ |
1373 | {␍␊ |
1374 | png_ptr->transformations &= ~PNG_ENCODE_ALPHA;␍␊ |
1375 | png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;␍␊ |
1376 | }␍␊ |
1377 | #endif␍␊ |
1378 | ␍␊ |
1379 | #if defined(PNG_READ_EXPAND_SUPPORTED) && \␍␊ |
1380 | defined(PNG_READ_BACKGROUND_SUPPORTED) && \␍␊ |
1381 | defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)␍␊ |
1382 | /* Detect gray background and attempt to enable optimization for␍␊ |
1383 | * gray --> RGB case.␍␊ |
1384 | *␍␊ |
1385 | * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or␍␊ |
1386 | * RGB_ALPHA (in which case need_expand is superfluous anyway), the␍␊ |
1387 | * background color might actually be gray yet not be flagged as such.␍␊ |
1388 | * This is not a problem for the current code, which uses␍␊ |
1389 | * PNG_BACKGROUND_IS_GRAY only to decide when to do the␍␊ |
1390 | * png_do_gray_to_rgb() transformation.␍␊ |
1391 | *␍␊ |
1392 | * TODO: this code needs to be revised to avoid the complexity and␍␊ |
1393 | * interdependencies. The color type of the background should be recorded in␍␊ |
1394 | * png_set_background, along with the bit depth, then the code has a record␍␊ |
1395 | * of exactly what color space the background is currently in.␍␊ |
1396 | */␍␊ |
1397 | if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)␍␊ |
1398 | {␍␊ |
1399 | /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if␍␊ |
1400 | * the file was grayscale the background value is gray.␍␊ |
1401 | */␍␊ |
1402 | if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))␍␊ |
1403 | png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;␍␊ |
1404 | }␍␊ |
1405 | ␍␊ |
1406 | else if (png_ptr->transformations & PNG_COMPOSE)␍␊ |
1407 | {␍␊ |
1408 | /* PNG_COMPOSE: png_set_background was called with need_expand false,␍␊ |
1409 | * so the color is in the color space of the output or png_set_alpha_mode␍␊ |
1410 | * was called and the color is black. Ignore RGB_TO_GRAY because that␍␊ |
1411 | * happens before GRAY_TO_RGB.␍␊ |
1412 | */␍␊ |
1413 | if (png_ptr->transformations & PNG_GRAY_TO_RGB)␍␊ |
1414 | {␍␊ |
1415 | if (png_ptr->background.red == png_ptr->background.green &&␍␊ |
1416 | png_ptr->background.red == png_ptr->background.blue)␍␊ |
1417 | {␍␊ |
1418 | png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;␍␊ |
1419 | png_ptr->background.gray = png_ptr->background.red;␍␊ |
1420 | }␍␊ |
1421 | }␍␊ |
1422 | }␍␊ |
1423 | #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED (etc) */␍␊ |
1424 | ␍␊ |
1425 | /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations␍␊ |
1426 | * can be performed directly on the palette, and some (such as rgb to gray)␍␊ |
1427 | * can be optimized inside the palette. This is particularly true of the␍␊ |
1428 | * composite (background and alpha) stuff, which can be pretty much all done␍␊ |
1429 | * in the palette even if the result is expanded to RGB or gray afterward.␍␊ |
1430 | *␍␊ |
1431 | * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and␍␊ |
1432 | * earlier and the palette stuff is actually handled on the first row. This␍␊ |
1433 | * leads to the reported bug that the palette returned by png_get_PLTE is not␍␊ |
1434 | * updated.␍␊ |
1435 | */␍␊ |
1436 | if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
1437 | png_init_palette_transformations(png_ptr);␍␊ |
1438 | ␍␊ |
1439 | else␍␊ |
1440 | png_init_rgb_transformations(png_ptr);␍␊ |
1441 | ␍␊ |
1442 | #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \␍␊ |
1443 | defined(PNG_READ_EXPAND_16_SUPPORTED)␍␊ |
1444 | if ((png_ptr->transformations & PNG_EXPAND_16) &&␍␊ |
1445 | (png_ptr->transformations & PNG_COMPOSE) &&␍␊ |
1446 | !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&␍␊ |
1447 | png_ptr->bit_depth != 16)␍␊ |
1448 | {␍␊ |
1449 | /* TODO: fix this. Because the expand_16 operation is after the compose␍␊ |
1450 | * handling the background color must be 8, not 16, bits deep, but the␍␊ |
1451 | * application will supply a 16-bit value so reduce it here.␍␊ |
1452 | *␍␊ |
1453 | * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at␍␊ |
1454 | * present, so that case is ok (until do_expand_16 is moved.)␍␊ |
1455 | *␍␊ |
1456 | * NOTE: this discards the low 16 bits of the user supplied background␍␊ |
1457 | * color, but until expand_16 works properly there is no choice!␍␊ |
1458 | */␍␊ |
1459 | # define CHOP(x) (x)=((png_uint_16)(((png_uint_32)(x)*255+32895) >> 16))␍␊ |
1460 | CHOP(png_ptr->background.red);␍␊ |
1461 | CHOP(png_ptr->background.green);␍␊ |
1462 | CHOP(png_ptr->background.blue);␍␊ |
1463 | CHOP(png_ptr->background.gray);␍␊ |
1464 | # undef CHOP␍␊ |
1465 | }␍␊ |
1466 | #endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */␍␊ |
1467 | ␍␊ |
1468 | #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \␍␊ |
1469 | (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \␍␊ |
1470 | defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))␍␊ |
1471 | if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&␍␊ |
1472 | (png_ptr->transformations & PNG_COMPOSE) &&␍␊ |
1473 | !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&␍␊ |
1474 | png_ptr->bit_depth == 16)␍␊ |
1475 | {␍␊ |
1476 | /* On the other hand, if a 16-bit file is to be reduced to 8-bits per␍␊ |
1477 | * component this will also happen after PNG_COMPOSE and so the background␍␊ |
1478 | * color must be pre-expanded here.␍␊ |
1479 | *␍␊ |
1480 | * TODO: fix this too.␍␊ |
1481 | */␍␊ |
1482 | png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);␍␊ |
1483 | png_ptr->background.green =␍␊ |
1484 | (png_uint_16)(png_ptr->background.green * 257);␍␊ |
1485 | png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);␍␊ |
1486 | png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);␍␊ |
1487 | }␍␊ |
1488 | #endif␍␊ |
1489 | ␍␊ |
1490 | /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the␍␊ |
1491 | * background support (see the comments in scripts/pnglibconf.dfa), this␍␊ |
1492 | * allows pre-multiplication of the alpha channel to be implemented as␍␊ |
1493 | * compositing on black. This is probably sub-optimal and has been done in␍␊ |
1494 | * 1.5.4 betas simply to enable external critique and testing (i.e. to␍␊ |
1495 | * implement the new API quickly, without lots of internal changes.)␍␊ |
1496 | */␍␊ |
1497 | ␍␊ |
1498 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
1499 | # ifdef PNG_READ_BACKGROUND_SUPPORTED␍␊ |
1500 | /* Includes ALPHA_MODE */␍␊ |
1501 | png_ptr->background_1 = png_ptr->background;␍␊ |
1502 | # endif␍␊ |
1503 | ␍␊ |
1504 | /* This needs to change - in the palette image case a whole set of tables are␍␊ |
1505 | * built when it would be quicker to just calculate the correct value for␍␊ |
1506 | * each palette entry directly. Also, the test is too tricky - why check␍␊ |
1507 | * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that␍␊ |
1508 | * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the␍␊ |
1509 | * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction␍␊ |
1510 | * the gamma tables will not be built even if composition is required on a␍␊ |
1511 | * gamma encoded value.␍␊ |
1512 | *␍␊ |
1513 | * In 1.5.4 this is addressed below by an additional check on the individual␍␊ |
1514 | * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the␍␊ |
1515 | * tables.␍␊ |
1516 | */␍␊ |
1517 | if ((png_ptr->transformations & PNG_GAMMA)␍␊ |
1518 | || ((png_ptr->transformations & PNG_RGB_TO_GRAY)␍␊ |
1519 | && (png_gamma_significant(png_ptr->gamma) ||␍␊ |
1520 | png_gamma_significant(png_ptr->screen_gamma)))␍␊ |
1521 | || ((png_ptr->transformations & PNG_COMPOSE)␍␊ |
1522 | && (png_gamma_significant(png_ptr->gamma)␍␊ |
1523 | || png_gamma_significant(png_ptr->screen_gamma)␍␊ |
1524 | # ifdef PNG_READ_BACKGROUND_SUPPORTED␍␊ |
1525 | || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE␍␊ |
1526 | && png_gamma_significant(png_ptr->background_gamma))␍␊ |
1527 | # endif␍␊ |
1528 | )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)␍␊ |
1529 | && png_gamma_significant(png_ptr->screen_gamma))␍␊ |
1530 | )␍␊ |
1531 | {␍␊ |
1532 | png_build_gamma_table(png_ptr, png_ptr->bit_depth);␍␊ |
1533 | ␍␊ |
1534 | #ifdef PNG_READ_BACKGROUND_SUPPORTED␍␊ |
1535 | if (png_ptr->transformations & PNG_COMPOSE)␍␊ |
1536 | {␍␊ |
1537 | /* Issue a warning about this combination: because RGB_TO_GRAY is␍␊ |
1538 | * optimized to do the gamma transform if present yet do_background has␍␊ |
1539 | * to do the same thing if both options are set a␍␊ |
1540 | * double-gamma-correction happens. This is true in all versions of␍␊ |
1541 | * libpng to date.␍␊ |
1542 | */␍␊ |
1543 | if (png_ptr->transformations & PNG_RGB_TO_GRAY)␍␊ |
1544 | png_warning(png_ptr,␍␊ |
1545 | "libpng does not support gamma+background+rgb_to_gray");␍␊ |
1546 | ␍␊ |
1547 | if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
1548 | {␍␊ |
1549 | /* We don't get to here unless there is a tRNS chunk with non-opaque␍␊ |
1550 | * entries - see the checking code at the start of this function.␍␊ |
1551 | */␍␊ |
1552 | png_color back, back_1;␍␊ |
1553 | png_colorp palette = png_ptr->palette;␍␊ |
1554 | int num_palette = png_ptr->num_palette;␍␊ |
1555 | int i;␍␊ |
1556 | if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)␍␊ |
1557 | {␍␊ |
1558 | ␍␊ |
1559 | back.red = png_ptr->gamma_table[png_ptr->background.red];␍␊ |
1560 | back.green = png_ptr->gamma_table[png_ptr->background.green];␍␊ |
1561 | back.blue = png_ptr->gamma_table[png_ptr->background.blue];␍␊ |
1562 | ␍␊ |
1563 | back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];␍␊ |
1564 | back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];␍␊ |
1565 | back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];␍␊ |
1566 | }␍␊ |
1567 | else␍␊ |
1568 | {␍␊ |
1569 | png_fixed_point g, gs;␍␊ |
1570 | ␍␊ |
1571 | switch (png_ptr->background_gamma_type)␍␊ |
1572 | {␍␊ |
1573 | case PNG_BACKGROUND_GAMMA_SCREEN:␍␊ |
1574 | g = (png_ptr->screen_gamma);␍␊ |
1575 | gs = PNG_FP_1;␍␊ |
1576 | break;␍␊ |
1577 | ␍␊ |
1578 | case PNG_BACKGROUND_GAMMA_FILE:␍␊ |
1579 | g = png_reciprocal(png_ptr->gamma);␍␊ |
1580 | gs = png_reciprocal2(png_ptr->gamma,␍␊ |
1581 | png_ptr->screen_gamma);␍␊ |
1582 | break;␍␊ |
1583 | ␍␊ |
1584 | case PNG_BACKGROUND_GAMMA_UNIQUE:␍␊ |
1585 | g = png_reciprocal(png_ptr->background_gamma);␍␊ |
1586 | gs = png_reciprocal2(png_ptr->background_gamma,␍␊ |
1587 | png_ptr->screen_gamma);␍␊ |
1588 | break;␍␊ |
1589 | default:␍␊ |
1590 | g = PNG_FP_1; /* back_1 */␍␊ |
1591 | gs = PNG_FP_1; /* back */␍␊ |
1592 | break;␍␊ |
1593 | }␍␊ |
1594 | ␍␊ |
1595 | if (png_gamma_significant(gs))␍␊ |
1596 | {␍␊ |
1597 | back.red = png_gamma_8bit_correct(png_ptr->background.red,␍␊ |
1598 | gs);␍␊ |
1599 | back.green = png_gamma_8bit_correct(png_ptr->background.green,␍␊ |
1600 | gs);␍␊ |
1601 | back.blue = png_gamma_8bit_correct(png_ptr->background.blue,␍␊ |
1602 | gs);␍␊ |
1603 | }␍␊ |
1604 | ␍␊ |
1605 | else␍␊ |
1606 | {␍␊ |
1607 | back.red = (png_byte)png_ptr->background.red;␍␊ |
1608 | back.green = (png_byte)png_ptr->background.green;␍␊ |
1609 | back.blue = (png_byte)png_ptr->background.blue;␍␊ |
1610 | }␍␊ |
1611 | ␍␊ |
1612 | if (png_gamma_significant(g))␍␊ |
1613 | {␍␊ |
1614 | back_1.red = png_gamma_8bit_correct(png_ptr->background.red,␍␊ |
1615 | g);␍␊ |
1616 | back_1.green = png_gamma_8bit_correct(␍␊ |
1617 | png_ptr->background.green, g);␍␊ |
1618 | back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,␍␊ |
1619 | g);␍␊ |
1620 | }␍␊ |
1621 | ␍␊ |
1622 | else␍␊ |
1623 | {␍␊ |
1624 | back_1.red = (png_byte)png_ptr->background.red;␍␊ |
1625 | back_1.green = (png_byte)png_ptr->background.green;␍␊ |
1626 | back_1.blue = (png_byte)png_ptr->background.blue;␍␊ |
1627 | }␍␊ |
1628 | }␍␊ |
1629 | ␍␊ |
1630 | for (i = 0; i < num_palette; i++)␍␊ |
1631 | {␍␊ |
1632 | if (i < (int)png_ptr->num_trans &&␍␊ |
1633 | png_ptr->trans_alpha[i] != 0xff)␍␊ |
1634 | {␍␊ |
1635 | if (png_ptr->trans_alpha[i] == 0)␍␊ |
1636 | {␍␊ |
1637 | palette[i] = back;␍␊ |
1638 | }␍␊ |
1639 | else /* if (png_ptr->trans_alpha[i] != 0xff) */␍␊ |
1640 | {␍␊ |
1641 | png_byte v, w;␍␊ |
1642 | ␍␊ |
1643 | v = png_ptr->gamma_to_1[palette[i].red];␍␊ |
1644 | png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);␍␊ |
1645 | palette[i].red = png_ptr->gamma_from_1[w];␍␊ |
1646 | ␍␊ |
1647 | v = png_ptr->gamma_to_1[palette[i].green];␍␊ |
1648 | png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);␍␊ |
1649 | palette[i].green = png_ptr->gamma_from_1[w];␍␊ |
1650 | ␍␊ |
1651 | v = png_ptr->gamma_to_1[palette[i].blue];␍␊ |
1652 | png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);␍␊ |
1653 | palette[i].blue = png_ptr->gamma_from_1[w];␍␊ |
1654 | }␍␊ |
1655 | }␍␊ |
1656 | else␍␊ |
1657 | {␍␊ |
1658 | palette[i].red = png_ptr->gamma_table[palette[i].red];␍␊ |
1659 | palette[i].green = png_ptr->gamma_table[palette[i].green];␍␊ |
1660 | palette[i].blue = png_ptr->gamma_table[palette[i].blue];␍␊ |
1661 | }␍␊ |
1662 | }␍␊ |
1663 | ␍␊ |
1664 | /* Prevent the transformations being done again.␍␊ |
1665 | *␍␊ |
1666 | * NOTE: this is highly dubious; it removes the transformations in␍␊ |
1667 | * place. This seems inconsistent with the general treatment of the␍␊ |
1668 | * transformations elsewhere.␍␊ |
1669 | */␍␊ |
1670 | png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);␍␊ |
1671 | } /* color_type == PNG_COLOR_TYPE_PALETTE */␍␊ |
1672 | ␍␊ |
1673 | /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */␍␊ |
1674 | else /* color_type != PNG_COLOR_TYPE_PALETTE */␍␊ |
1675 | {␍␊ |
1676 | int gs_sig, g_sig;␍␊ |
1677 | png_fixed_point g = PNG_FP_1; /* Correction to linear */␍␊ |
1678 | png_fixed_point gs = PNG_FP_1; /* Correction to screen */␍␊ |
1679 | ␍␊ |
1680 | switch (png_ptr->background_gamma_type)␍␊ |
1681 | {␍␊ |
1682 | case PNG_BACKGROUND_GAMMA_SCREEN:␍␊ |
1683 | g = png_ptr->screen_gamma;␍␊ |
1684 | /* gs = PNG_FP_1; */␍␊ |
1685 | break;␍␊ |
1686 | ␍␊ |
1687 | case PNG_BACKGROUND_GAMMA_FILE:␍␊ |
1688 | g = png_reciprocal(png_ptr->gamma);␍␊ |
1689 | gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma);␍␊ |
1690 | break;␍␊ |
1691 | ␍␊ |
1692 | case PNG_BACKGROUND_GAMMA_UNIQUE:␍␊ |
1693 | g = png_reciprocal(png_ptr->background_gamma);␍␊ |
1694 | gs = png_reciprocal2(png_ptr->background_gamma,␍␊ |
1695 | png_ptr->screen_gamma);␍␊ |
1696 | break;␍␊ |
1697 | ␍␊ |
1698 | default:␍␊ |
1699 | png_error(png_ptr, "invalid background gamma type");␍␊ |
1700 | }␍␊ |
1701 | ␍␊ |
1702 | g_sig = png_gamma_significant(g);␍␊ |
1703 | gs_sig = png_gamma_significant(gs);␍␊ |
1704 | ␍␊ |
1705 | if (g_sig)␍␊ |
1706 | png_ptr->background_1.gray = png_gamma_correct(png_ptr,␍␊ |
1707 | png_ptr->background.gray, g);␍␊ |
1708 | ␍␊ |
1709 | if (gs_sig)␍␊ |
1710 | png_ptr->background.gray = png_gamma_correct(png_ptr,␍␊ |
1711 | png_ptr->background.gray, gs);␍␊ |
1712 | ␍␊ |
1713 | if ((png_ptr->background.red != png_ptr->background.green) ||␍␊ |
1714 | (png_ptr->background.red != png_ptr->background.blue) ||␍␊ |
1715 | (png_ptr->background.red != png_ptr->background.gray))␍␊ |
1716 | {␍␊ |
1717 | /* RGB or RGBA with color background */␍␊ |
1718 | if (g_sig)␍␊ |
1719 | {␍␊ |
1720 | png_ptr->background_1.red = png_gamma_correct(png_ptr,␍␊ |
1721 | png_ptr->background.red, g);␍␊ |
1722 | ␍␊ |
1723 | png_ptr->background_1.green = png_gamma_correct(png_ptr,␍␊ |
1724 | png_ptr->background.green, g);␍␊ |
1725 | ␍␊ |
1726 | png_ptr->background_1.blue = png_gamma_correct(png_ptr,␍␊ |
1727 | png_ptr->background.blue, g);␍␊ |
1728 | }␍␊ |
1729 | ␍␊ |
1730 | if (gs_sig)␍␊ |
1731 | {␍␊ |
1732 | png_ptr->background.red = png_gamma_correct(png_ptr,␍␊ |
1733 | png_ptr->background.red, gs);␍␊ |
1734 | ␍␊ |
1735 | png_ptr->background.green = png_gamma_correct(png_ptr,␍␊ |
1736 | png_ptr->background.green, gs);␍␊ |
1737 | ␍␊ |
1738 | png_ptr->background.blue = png_gamma_correct(png_ptr,␍␊ |
1739 | png_ptr->background.blue, gs);␍␊ |
1740 | }␍␊ |
1741 | }␍␊ |
1742 | ␍␊ |
1743 | else␍␊ |
1744 | {␍␊ |
1745 | /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */␍␊ |
1746 | png_ptr->background_1.red = png_ptr->background_1.green␍␊ |
1747 | = png_ptr->background_1.blue = png_ptr->background_1.gray;␍␊ |
1748 | ␍␊ |
1749 | png_ptr->background.red = png_ptr->background.green␍␊ |
1750 | = png_ptr->background.blue = png_ptr->background.gray;␍␊ |
1751 | }␍␊ |
1752 | ␍␊ |
1753 | /* The background is now in screen gamma: */␍␊ |
1754 | png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;␍␊ |
1755 | } /* color_type != PNG_COLOR_TYPE_PALETTE */␍␊ |
1756 | }/* png_ptr->transformations & PNG_BACKGROUND */␍␊ |
1757 | ␍␊ |
1758 | else␍␊ |
1759 | /* Transformation does not include PNG_BACKGROUND */␍␊ |
1760 | #endif /* PNG_READ_BACKGROUND_SUPPORTED */␍␊ |
1761 | if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE␍␊ |
1762 | #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED␍␊ |
1763 | /* RGB_TO_GRAY needs to have non-gamma-corrected values! */␍␊ |
1764 | && ((png_ptr->transformations & PNG_EXPAND) == 0 ||␍␊ |
1765 | (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)␍␊ |
1766 | #endif␍␊ |
1767 | )␍␊ |
1768 | {␍␊ |
1769 | png_colorp palette = png_ptr->palette;␍␊ |
1770 | int num_palette = png_ptr->num_palette;␍␊ |
1771 | int i;␍␊ |
1772 | ␍␊ |
1773 | /* NOTE: there are other transformations that should probably be in␍␊ |
1774 | * here too.␍␊ |
1775 | */␍␊ |
1776 | for (i = 0; i < num_palette; i++)␍␊ |
1777 | {␍␊ |
1778 | palette[i].red = png_ptr->gamma_table[palette[i].red];␍␊ |
1779 | palette[i].green = png_ptr->gamma_table[palette[i].green];␍␊ |
1780 | palette[i].blue = png_ptr->gamma_table[palette[i].blue];␍␊ |
1781 | }␍␊ |
1782 | ␍␊ |
1783 | /* Done the gamma correction. */␍␊ |
1784 | png_ptr->transformations &= ~PNG_GAMMA;␍␊ |
1785 | } /* color_type == PALETTE && !PNG_BACKGROUND transformation */␍␊ |
1786 | }␍␊ |
1787 | #ifdef PNG_READ_BACKGROUND_SUPPORTED␍␊ |
1788 | else␍␊ |
1789 | #endif␍␊ |
1790 | #endif /* PNG_READ_GAMMA_SUPPORTED */␍␊ |
1791 | ␍␊ |
1792 | #ifdef PNG_READ_BACKGROUND_SUPPORTED␍␊ |
1793 | /* No GAMMA transformation (see the hanging else 4 lines above) */␍␊ |
1794 | if ((png_ptr->transformations & PNG_COMPOSE) &&␍␊ |
1795 | (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))␍␊ |
1796 | {␍␊ |
1797 | int i;␍␊ |
1798 | int istop = (int)png_ptr->num_trans;␍␊ |
1799 | png_color back;␍␊ |
1800 | png_colorp palette = png_ptr->palette;␍␊ |
1801 | ␍␊ |
1802 | back.red = (png_byte)png_ptr->background.red;␍␊ |
1803 | back.green = (png_byte)png_ptr->background.green;␍␊ |
1804 | back.blue = (png_byte)png_ptr->background.blue;␍␊ |
1805 | ␍␊ |
1806 | for (i = 0; i < istop; i++)␍␊ |
1807 | {␍␊ |
1808 | if (png_ptr->trans_alpha[i] == 0)␍␊ |
1809 | {␍␊ |
1810 | palette[i] = back;␍␊ |
1811 | }␍␊ |
1812 | ␍␊ |
1813 | else if (png_ptr->trans_alpha[i] != 0xff)␍␊ |
1814 | {␍␊ |
1815 | /* The png_composite() macro is defined in png.h */␍␊ |
1816 | png_composite(palette[i].red, palette[i].red,␍␊ |
1817 | png_ptr->trans_alpha[i], back.red);␍␊ |
1818 | ␍␊ |
1819 | png_composite(palette[i].green, palette[i].green,␍␊ |
1820 | png_ptr->trans_alpha[i], back.green);␍␊ |
1821 | ␍␊ |
1822 | png_composite(palette[i].blue, palette[i].blue,␍␊ |
1823 | png_ptr->trans_alpha[i], back.blue);␍␊ |
1824 | }␍␊ |
1825 | }␍␊ |
1826 | ␍␊ |
1827 | png_ptr->transformations &= ~PNG_COMPOSE;␍␊ |
1828 | }␍␊ |
1829 | #endif /* PNG_READ_BACKGROUND_SUPPORTED */␍␊ |
1830 | ␍␊ |
1831 | #ifdef PNG_READ_SHIFT_SUPPORTED␍␊ |
1832 | if ((png_ptr->transformations & PNG_SHIFT) &&␍␊ |
1833 | !(png_ptr->transformations & PNG_EXPAND) &&␍␊ |
1834 | (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))␍␊ |
1835 | {␍␊ |
1836 | int i;␍␊ |
1837 | int istop = png_ptr->num_palette;␍␊ |
1838 | int shift = 8 - png_ptr->sig_bit.red;␍␊ |
1839 | ␍␊ |
1840 | png_ptr->transformations &= ~PNG_SHIFT;␍␊ |
1841 | ␍␊ |
1842 | /* significant bits can be in the range 1 to 7 for a meaninful result, if␍␊ |
1843 | * the number of significant bits is 0 then no shift is done (this is an␍␊ |
1844 | * error condition which is silently ignored.)␍␊ |
1845 | */␍␊ |
1846 | if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)␍␊ |
1847 | {␍␊ |
1848 | int component = png_ptr->palette[i].red;␍␊ |
1849 | ␍␊ |
1850 | component >>= shift;␍␊ |
1851 | png_ptr->palette[i].red = (png_byte)component;␍␊ |
1852 | }␍␊ |
1853 | ␍␊ |
1854 | shift = 8 - png_ptr->sig_bit.green;␍␊ |
1855 | if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)␍␊ |
1856 | {␍␊ |
1857 | int component = png_ptr->palette[i].green;␍␊ |
1858 | ␍␊ |
1859 | component >>= shift;␍␊ |
1860 | png_ptr->palette[i].green = (png_byte)component;␍␊ |
1861 | }␍␊ |
1862 | ␍␊ |
1863 | shift = 8 - png_ptr->sig_bit.blue;␍␊ |
1864 | if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)␍␊ |
1865 | {␍␊ |
1866 | int component = png_ptr->palette[i].blue;␍␊ |
1867 | ␍␊ |
1868 | component >>= shift;␍␊ |
1869 | png_ptr->palette[i].blue = (png_byte)component;␍␊ |
1870 | }␍␊ |
1871 | }␍␊ |
1872 | #endif /* PNG_READ_SHIFT_SUPPORTED */␍␊ |
1873 | }␍␊ |
1874 | ␍␊ |
1875 | /* Modify the info structure to reflect the transformations. The␍␊ |
1876 | * info should be updated so a PNG file could be written with it,␍␊ |
1877 | * assuming the transformations result in valid PNG data.␍␊ |
1878 | */␍␊ |
1879 | void /* PRIVATE */␍␊ |
1880 | png_read_transform_info(png_structp png_ptr, png_infop info_ptr)␍␊ |
1881 | {␍␊ |
1882 | png_debug(1, "in png_read_transform_info");␍␊ |
1883 | ␍␊ |
1884 | #ifdef PNG_READ_EXPAND_SUPPORTED␍␊ |
1885 | if (png_ptr->transformations & PNG_EXPAND)␍␊ |
1886 | {␍␊ |
1887 | if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
1888 | {␍␊ |
1889 | /* This check must match what actually happens in␍␊ |
1890 | * png_do_expand_palette; if it ever checks the tRNS chunk to see if␍␊ |
1891 | * it is all opaque we must do the same (at present it does not.)␍␊ |
1892 | */␍␊ |
1893 | if (png_ptr->num_trans > 0)␍␊ |
1894 | info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;␍␊ |
1895 | ␍␊ |
1896 | else␍␊ |
1897 | info_ptr->color_type = PNG_COLOR_TYPE_RGB;␍␊ |
1898 | ␍␊ |
1899 | info_ptr->bit_depth = 8;␍␊ |
1900 | info_ptr->num_trans = 0;␍␊ |
1901 | }␍␊ |
1902 | else␍␊ |
1903 | {␍␊ |
1904 | if (png_ptr->num_trans)␍␊ |
1905 | {␍␊ |
1906 | if (png_ptr->transformations & PNG_EXPAND_tRNS)␍␊ |
1907 | info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;␍␊ |
1908 | }␍␊ |
1909 | if (info_ptr->bit_depth < 8)␍␊ |
1910 | info_ptr->bit_depth = 8;␍␊ |
1911 | ␍␊ |
1912 | info_ptr->num_trans = 0;␍␊ |
1913 | }␍␊ |
1914 | }␍␊ |
1915 | #endif␍␊ |
1916 | ␍␊ |
1917 | #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\␍␊ |
1918 | defined(PNG_READ_ALPHA_MODE_SUPPORTED)␍␊ |
1919 | /* The following is almost certainly wrong unless the background value is in␍␊ |
1920 | * the screen space!␍␊ |
1921 | */␍␊ |
1922 | if (png_ptr->transformations & PNG_COMPOSE)␍␊ |
1923 | info_ptr->background = png_ptr->background;␍␊ |
1924 | #endif␍␊ |
1925 | ␍␊ |
1926 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
1927 | /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),␍␊ |
1928 | * however it seems that the code in png_init_read_transformations, which has␍␊ |
1929 | * been called before this from png_read_update_info->png_read_start_row␍␊ |
1930 | * sometimes does the gamma transform and cancels the flag.␍␊ |
1931 | */␍␊ |
1932 | info_ptr->gamma = png_ptr->gamma;␍␊ |
1933 | #endif␍␊ |
1934 | ␍␊ |
1935 | if (info_ptr->bit_depth == 16)␍␊ |
1936 | {␍␊ |
1937 | # ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
1938 | # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED␍␊ |
1939 | if (png_ptr->transformations & PNG_SCALE_16_TO_8)␍␊ |
1940 | info_ptr->bit_depth = 8;␍␊ |
1941 | # endif␍␊ |
1942 | ␍␊ |
1943 | # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED␍␊ |
1944 | if (png_ptr->transformations & PNG_16_TO_8)␍␊ |
1945 | info_ptr->bit_depth = 8;␍␊ |
1946 | # endif␍␊ |
1947 | ␍␊ |
1948 | # else␍␊ |
1949 | /* No 16 bit support: force chopping 16-bit input down to 8, in this case␍␊ |
1950 | * the app program can chose if both APIs are available by setting the␍␊ |
1951 | * correct scaling to use.␍␊ |
1952 | */␍␊ |
1953 | # ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED␍␊ |
1954 | /* For compatibility with previous versions use the strip method by␍␊ |
1955 | * default. This code works because if PNG_SCALE_16_TO_8 is already␍␊ |
1956 | * set the code below will do that in preference to the chop.␍␊ |
1957 | */␍␊ |
1958 | png_ptr->transformations |= PNG_16_TO_8;␍␊ |
1959 | info_ptr->bit_depth = 8;␍␊ |
1960 | # else␍␊ |
1961 | ␍␊ |
1962 | # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED␍␊ |
1963 | png_ptr->transformations |= PNG_SCALE_16_TO_8;␍␊ |
1964 | info_ptr->bit_depth = 8;␍␊ |
1965 | # else␍␊ |
1966 | ␍␊ |
1967 | CONFIGURATION ERROR: you must enable at least one 16 to 8 method␍␊ |
1968 | # endif␍␊ |
1969 | # endif␍␊ |
1970 | #endif /* !READ_16BIT_SUPPORTED */␍␊ |
1971 | }␍␊ |
1972 | ␍␊ |
1973 | #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED␍␊ |
1974 | if (png_ptr->transformations & PNG_GRAY_TO_RGB)␍␊ |
1975 | info_ptr->color_type = (png_byte)(info_ptr->color_type |␍␊ |
1976 | PNG_COLOR_MASK_COLOR);␍␊ |
1977 | #endif␍␊ |
1978 | ␍␊ |
1979 | #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED␍␊ |
1980 | if (png_ptr->transformations & PNG_RGB_TO_GRAY)␍␊ |
1981 | info_ptr->color_type = (png_byte)(info_ptr->color_type &␍␊ |
1982 | ~PNG_COLOR_MASK_COLOR);␍␊ |
1983 | #endif␍␊ |
1984 | ␍␊ |
1985 | #ifdef PNG_READ_QUANTIZE_SUPPORTED␍␊ |
1986 | if (png_ptr->transformations & PNG_QUANTIZE)␍␊ |
1987 | {␍␊ |
1988 | if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||␍␊ |
1989 | (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&␍␊ |
1990 | png_ptr->palette_lookup && info_ptr->bit_depth == 8)␍␊ |
1991 | {␍␊ |
1992 | info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;␍␊ |
1993 | }␍␊ |
1994 | }␍␊ |
1995 | #endif␍␊ |
1996 | ␍␊ |
1997 | #ifdef PNG_READ_EXPAND_16_SUPPORTED␍␊ |
1998 | if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&␍␊ |
1999 | info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)␍␊ |
2000 | {␍␊ |
2001 | info_ptr->bit_depth = 16;␍␊ |
2002 | }␍␊ |
2003 | #endif␍␊ |
2004 | ␍␊ |
2005 | #ifdef PNG_READ_PACK_SUPPORTED␍␊ |
2006 | if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))␍␊ |
2007 | info_ptr->bit_depth = 8;␍␊ |
2008 | #endif␍␊ |
2009 | ␍␊ |
2010 | if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
2011 | info_ptr->channels = 1;␍␊ |
2012 | ␍␊ |
2013 | else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)␍␊ |
2014 | info_ptr->channels = 3;␍␊ |
2015 | ␍␊ |
2016 | else␍␊ |
2017 | info_ptr->channels = 1;␍␊ |
2018 | ␍␊ |
2019 | #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED␍␊ |
2020 | if (png_ptr->transformations & PNG_STRIP_ALPHA)␍␊ |
2021 | {␍␊ |
2022 | info_ptr->color_type = (png_byte)(info_ptr->color_type &␍␊ |
2023 | ~PNG_COLOR_MASK_ALPHA);␍␊ |
2024 | info_ptr->num_trans = 0;␍␊ |
2025 | }␍␊ |
2026 | #endif␍␊ |
2027 | ␍␊ |
2028 | if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)␍␊ |
2029 | info_ptr->channels++;␍␊ |
2030 | ␍␊ |
2031 | #ifdef PNG_READ_FILLER_SUPPORTED␍␊ |
2032 | /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */␍␊ |
2033 | if ((png_ptr->transformations & PNG_FILLER) &&␍␊ |
2034 | ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||␍␊ |
2035 | (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))␍␊ |
2036 | {␍␊ |
2037 | info_ptr->channels++;␍␊ |
2038 | /* If adding a true alpha channel not just filler */␍␊ |
2039 | if (png_ptr->transformations & PNG_ADD_ALPHA)␍␊ |
2040 | info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;␍␊ |
2041 | }␍␊ |
2042 | #endif␍␊ |
2043 | ␍␊ |
2044 | #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \␍␊ |
2045 | defined(PNG_READ_USER_TRANSFORM_SUPPORTED)␍␊ |
2046 | if (png_ptr->transformations & PNG_USER_TRANSFORM)␍␊ |
2047 | {␍␊ |
2048 | if (info_ptr->bit_depth < png_ptr->user_transform_depth)␍␊ |
2049 | info_ptr->bit_depth = png_ptr->user_transform_depth;␍␊ |
2050 | ␍␊ |
2051 | if (info_ptr->channels < png_ptr->user_transform_channels)␍␊ |
2052 | info_ptr->channels = png_ptr->user_transform_channels;␍␊ |
2053 | }␍␊ |
2054 | #endif␍␊ |
2055 | ␍␊ |
2056 | info_ptr->pixel_depth = (png_byte)(info_ptr->channels *␍␊ |
2057 | info_ptr->bit_depth);␍␊ |
2058 | ␍␊ |
2059 | info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);␍␊ |
2060 | ␍␊ |
2061 | /* Adding in 1.5.4: cache the above value in png_struct so that we can later␍␊ |
2062 | * check in png_rowbytes that the user buffer won't get overwritten. Note␍␊ |
2063 | * that the field is not always set - if png_read_update_info isn't called␍␊ |
2064 | * the application has to either not do any transforms or get the calculation␍␊ |
2065 | * right itself.␍␊ |
2066 | */␍␊ |
2067 | png_ptr->info_rowbytes = info_ptr->rowbytes;␍␊ |
2068 | ␍␊ |
2069 | #ifndef PNG_READ_EXPAND_SUPPORTED␍␊ |
2070 | if (png_ptr)␍␊ |
2071 | return;␍␊ |
2072 | #endif␍␊ |
2073 | }␍␊ |
2074 | ␍␊ |
2075 | /* Transform the row. The order of transformations is significant,␍␊ |
2076 | * and is very touchy. If you add a transformation, take care to␍␊ |
2077 | * decide how it fits in with the other transformations here.␍␊ |
2078 | */␍␊ |
2079 | void /* PRIVATE */␍␊ |
2080 | png_do_read_transformations(png_structp png_ptr, png_row_infop row_info)␍␊ |
2081 | {␍␊ |
2082 | png_debug(1, "in png_do_read_transformations");␍␊ |
2083 | ␍␊ |
2084 | if (png_ptr->row_buf == NULL)␍␊ |
2085 | {␍␊ |
2086 | /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this␍␊ |
2087 | * error is incredibly rare and incredibly easy to debug without this␍␊ |
2088 | * information.␍␊ |
2089 | */␍␊ |
2090 | png_error(png_ptr, "NULL row buffer");␍␊ |
2091 | }␍␊ |
2092 | ␍␊ |
2093 | /* The following is debugging; prior to 1.5.4 the code was never compiled in;␍␊ |
2094 | * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro␍␊ |
2095 | * PNG_WARN_UNINITIALIZED_ROW removed. In 1.5 the new flag is set only for␍␊ |
2096 | * selected new APIs to ensure that there is no API change.␍␊ |
2097 | */␍␊ |
2098 | if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&␍␊ |
2099 | !(png_ptr->flags & PNG_FLAG_ROW_INIT))␍␊ |
2100 | {␍␊ |
2101 | /* Application has failed to call either png_read_start_image() or␍␊ |
2102 | * png_read_update_info() after setting transforms that expand pixels.␍␊ |
2103 | * This check added to libpng-1.2.19 (but not enabled until 1.5.4).␍␊ |
2104 | */␍␊ |
2105 | png_error(png_ptr, "Uninitialized row");␍␊ |
2106 | }␍␊ |
2107 | ␍␊ |
2108 | #ifdef PNG_READ_EXPAND_SUPPORTED␍␊ |
2109 | if (png_ptr->transformations & PNG_EXPAND)␍␊ |
2110 | {␍␊ |
2111 | if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
2112 | {␍␊ |
2113 | png_do_expand_palette(row_info, png_ptr->row_buf + 1,␍␊ |
2114 | png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);␍␊ |
2115 | }␍␊ |
2116 | ␍␊ |
2117 | else␍␊ |
2118 | {␍␊ |
2119 | if (png_ptr->num_trans &&␍␊ |
2120 | (png_ptr->transformations & PNG_EXPAND_tRNS))␍␊ |
2121 | png_do_expand(row_info, png_ptr->row_buf + 1,␍␊ |
2122 | &(png_ptr->trans_color));␍␊ |
2123 | ␍␊ |
2124 | else␍␊ |
2125 | png_do_expand(row_info, png_ptr->row_buf + 1,␍␊ |
2126 | NULL);␍␊ |
2127 | }␍␊ |
2128 | }␍␊ |
2129 | #endif␍␊ |
2130 | ␍␊ |
2131 | #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED␍␊ |
2132 | if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&␍␊ |
2133 | !(png_ptr->transformations & PNG_COMPOSE) &&␍␊ |
2134 | (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||␍␊ |
2135 | row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))␍␊ |
2136 | png_do_strip_channel(row_info, png_ptr->row_buf + 1,␍␊ |
2137 | 0 /* at_start == false, because SWAP_ALPHA happens later */);␍␊ |
2138 | #endif␍␊ |
2139 | ␍␊ |
2140 | #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED␍␊ |
2141 | if (png_ptr->transformations & PNG_RGB_TO_GRAY)␍␊ |
2142 | {␍␊ |
2143 | int rgb_error =␍␊ |
2144 | png_do_rgb_to_gray(png_ptr, row_info,␍␊ |
2145 | png_ptr->row_buf + 1);␍␊ |
2146 | ␍␊ |
2147 | if (rgb_error)␍␊ |
2148 | {␍␊ |
2149 | png_ptr->rgb_to_gray_status=1;␍␊ |
2150 | if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==␍␊ |
2151 | PNG_RGB_TO_GRAY_WARN)␍␊ |
2152 | png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");␍␊ |
2153 | ␍␊ |
2154 | if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==␍␊ |
2155 | PNG_RGB_TO_GRAY_ERR)␍␊ |
2156 | png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");␍␊ |
2157 | }␍␊ |
2158 | }␍␊ |
2159 | #endif␍␊ |
2160 | ␍␊ |
2161 | /* From Andreas Dilger e-mail to png-implement, 26 March 1998:␍␊ |
2162 | *␍␊ |
2163 | * In most cases, the "simple transparency" should be done prior to doing␍␊ |
2164 | * gray-to-RGB, or you will have to test 3x as many bytes to check if a␍␊ |
2165 | * pixel is transparent. You would also need to make sure that the␍␊ |
2166 | * transparency information is upgraded to RGB.␍␊ |
2167 | *␍␊ |
2168 | * To summarize, the current flow is:␍␊ |
2169 | * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite␍␊ |
2170 | * with background "in place" if transparent,␍␊ |
2171 | * convert to RGB if necessary␍␊ |
2172 | * - Gray + alpha -> composite with gray background and remove alpha bytes,␍␊ |
2173 | * convert to RGB if necessary␍␊ |
2174 | *␍␊ |
2175 | * To support RGB backgrounds for gray images we need:␍␊ |
2176 | * - Gray + simple transparency -> convert to RGB + simple transparency,␍␊ |
2177 | * compare 3 or 6 bytes and composite with␍␊ |
2178 | * background "in place" if transparent␍␊ |
2179 | * (3x compare/pixel compared to doing␍␊ |
2180 | * composite with gray bkgrnd)␍␊ |
2181 | * - Gray + alpha -> convert to RGB + alpha, composite with background and␍␊ |
2182 | * remove alpha bytes (3x float␍␊ |
2183 | * operations/pixel compared with composite␍␊ |
2184 | * on gray background)␍␊ |
2185 | *␍␊ |
2186 | * Greg's change will do this. The reason it wasn't done before is for␍␊ |
2187 | * performance, as this increases the per-pixel operations. If we would check␍␊ |
2188 | * in advance if the background was gray or RGB, and position the gray-to-RGB␍␊ |
2189 | * transform appropriately, then it would save a lot of work/time.␍␊ |
2190 | */␍␊ |
2191 | ␍␊ |
2192 | #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED␍␊ |
2193 | /* If gray -> RGB, do so now only if background is non-gray; else do later␍␊ |
2194 | * for performance reasons␍␊ |
2195 | */␍␊ |
2196 | if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&␍␊ |
2197 | !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))␍␊ |
2198 | png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);␍␊ |
2199 | #endif␍␊ |
2200 | ␍␊ |
2201 | #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\␍␊ |
2202 | (defined PNG_READ_ALPHA_MODE_SUPPORTED)␍␊ |
2203 | if (png_ptr->transformations & PNG_COMPOSE)␍␊ |
2204 | png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);␍␊ |
2205 | #endif␍␊ |
2206 | ␍␊ |
2207 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
2208 | if ((png_ptr->transformations & PNG_GAMMA) &&␍␊ |
2209 | #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED␍␊ |
2210 | /* Because RGB_TO_GRAY does the gamma transform. */␍␊ |
2211 | !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&␍␊ |
2212 | #endif␍␊ |
2213 | #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\␍␊ |
2214 | (defined PNG_READ_ALPHA_MODE_SUPPORTED)␍␊ |
2215 | /* Because PNG_COMPOSE does the gamma transform if there is something to␍␊ |
2216 | * do (if there is an alpha channel or transparency.)␍␊ |
2217 | */␍␊ |
2218 | !((png_ptr->transformations & PNG_COMPOSE) &&␍␊ |
2219 | ((png_ptr->num_trans != 0) ||␍␊ |
2220 | (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&␍␊ |
2221 | #endif␍␊ |
2222 | /* Because png_init_read_transformations transforms the palette, unless␍␊ |
2223 | * RGB_TO_GRAY will do the transform.␍␊ |
2224 | */␍␊ |
2225 | (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))␍␊ |
2226 | png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);␍␊ |
2227 | #endif␍␊ |
2228 | ␍␊ |
2229 | #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED␍␊ |
2230 | if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&␍␊ |
2231 | (png_ptr->transformations & PNG_COMPOSE) &&␍␊ |
2232 | (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||␍␊ |
2233 | row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))␍␊ |
2234 | png_do_strip_channel(row_info, png_ptr->row_buf + 1,␍␊ |
2235 | 0 /* at_start == false, because SWAP_ALPHA happens later */);␍␊ |
2236 | #endif␍␊ |
2237 | ␍␊ |
2238 | #ifdef PNG_READ_ALPHA_MODE_SUPPORTED␍␊ |
2239 | if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&␍␊ |
2240 | (row_info->color_type & PNG_COLOR_MASK_ALPHA))␍␊ |
2241 | png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);␍␊ |
2242 | #endif␍␊ |
2243 | ␍␊ |
2244 | #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED␍␊ |
2245 | if (png_ptr->transformations & PNG_SCALE_16_TO_8)␍␊ |
2246 | png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);␍␊ |
2247 | #endif␍␊ |
2248 | ␍␊ |
2249 | #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED␍␊ |
2250 | /* There is no harm in doing both of these because only one has any effect,␍␊ |
2251 | * by putting the 'scale' option first if the app asks for scale (either by␍␊ |
2252 | * calling the API or in a TRANSFORM flag) this is what happens.␍␊ |
2253 | */␍␊ |
2254 | if (png_ptr->transformations & PNG_16_TO_8)␍␊ |
2255 | png_do_chop(row_info, png_ptr->row_buf + 1);␍␊ |
2256 | #endif␍␊ |
2257 | ␍␊ |
2258 | #ifdef PNG_READ_QUANTIZE_SUPPORTED␍␊ |
2259 | if (png_ptr->transformations & PNG_QUANTIZE)␍␊ |
2260 | {␍␊ |
2261 | png_do_quantize(row_info, png_ptr->row_buf + 1,␍␊ |
2262 | png_ptr->palette_lookup, png_ptr->quantize_index);␍␊ |
2263 | ␍␊ |
2264 | if (row_info->rowbytes == 0)␍␊ |
2265 | png_error(png_ptr, "png_do_quantize returned rowbytes=0");␍␊ |
2266 | }␍␊ |
2267 | #endif /* PNG_READ_QUANTIZE_SUPPORTED */␍␊ |
2268 | ␍␊ |
2269 | #ifdef PNG_READ_EXPAND_16_SUPPORTED␍␊ |
2270 | /* Do the expansion now, after all the arithmetic has been done. Notice␍␊ |
2271 | * that previous transformations can handle the PNG_EXPAND_16 flag if this␍␊ |
2272 | * is efficient (particularly true in the case of gamma correction, where␍␊ |
2273 | * better accuracy results faster!)␍␊ |
2274 | */␍␊ |
2275 | if (png_ptr->transformations & PNG_EXPAND_16)␍␊ |
2276 | png_do_expand_16(row_info, png_ptr->row_buf + 1);␍␊ |
2277 | #endif␍␊ |
2278 | ␍␊ |
2279 | #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED␍␊ |
2280 | /* NOTE: moved here in 1.5.4 (from much later in this list.) */␍␊ |
2281 | if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&␍␊ |
2282 | (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))␍␊ |
2283 | png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);␍␊ |
2284 | #endif␍␊ |
2285 | ␍␊ |
2286 | #ifdef PNG_READ_INVERT_SUPPORTED␍␊ |
2287 | if (png_ptr->transformations & PNG_INVERT_MONO)␍␊ |
2288 | png_do_invert(row_info, png_ptr->row_buf + 1);␍␊ |
2289 | #endif␍␊ |
2290 | ␍␊ |
2291 | #ifdef PNG_READ_SHIFT_SUPPORTED␍␊ |
2292 | if (png_ptr->transformations & PNG_SHIFT)␍␊ |
2293 | png_do_unshift(row_info, png_ptr->row_buf + 1,␍␊ |
2294 | &(png_ptr->shift));␍␊ |
2295 | #endif␍␊ |
2296 | ␍␊ |
2297 | #ifdef PNG_READ_PACK_SUPPORTED␍␊ |
2298 | if (png_ptr->transformations & PNG_PACK)␍␊ |
2299 | png_do_unpack(row_info, png_ptr->row_buf + 1);␍␊ |
2300 | #endif␍␊ |
2301 | ␍␊ |
2302 | #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED␍␊ |
2303 | /* Added at libpng-1.5.10 */␍␊ |
2304 | if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&␍␊ |
2305 | png_ptr->num_palette_max >= 0)␍␊ |
2306 | png_do_check_palette_indexes(png_ptr, row_info);␍␊ |
2307 | #endif␍␊ |
2308 | ␍␊ |
2309 | #ifdef PNG_READ_BGR_SUPPORTED␍␊ |
2310 | if (png_ptr->transformations & PNG_BGR)␍␊ |
2311 | png_do_bgr(row_info, png_ptr->row_buf + 1);␍␊ |
2312 | #endif␍␊ |
2313 | ␍␊ |
2314 | #ifdef PNG_READ_PACKSWAP_SUPPORTED␍␊ |
2315 | if (png_ptr->transformations & PNG_PACKSWAP)␍␊ |
2316 | png_do_packswap(row_info, png_ptr->row_buf + 1);␍␊ |
2317 | #endif␍␊ |
2318 | ␍␊ |
2319 | #ifdef PNG_READ_FILLER_SUPPORTED␍␊ |
2320 | if (png_ptr->transformations & PNG_FILLER)␍␊ |
2321 | png_do_read_filler(row_info, png_ptr->row_buf + 1,␍␊ |
2322 | (png_uint_32)png_ptr->filler, png_ptr->flags);␍␊ |
2323 | #endif␍␊ |
2324 | ␍␊ |
2325 | #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED␍␊ |
2326 | if (png_ptr->transformations & PNG_INVERT_ALPHA)␍␊ |
2327 | png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);␍␊ |
2328 | #endif␍␊ |
2329 | ␍␊ |
2330 | #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED␍␊ |
2331 | if (png_ptr->transformations & PNG_SWAP_ALPHA)␍␊ |
2332 | png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);␍␊ |
2333 | #endif␍␊ |
2334 | ␍␊ |
2335 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2336 | #ifdef PNG_READ_SWAP_SUPPORTED␍␊ |
2337 | if (png_ptr->transformations & PNG_SWAP_BYTES)␍␊ |
2338 | png_do_swap(row_info, png_ptr->row_buf + 1);␍␊ |
2339 | #endif␍␊ |
2340 | #endif␍␊ |
2341 | ␍␊ |
2342 | #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED␍␊ |
2343 | if (png_ptr->transformations & PNG_USER_TRANSFORM)␍␊ |
2344 | {␍␊ |
2345 | if (png_ptr->read_user_transform_fn != NULL)␍␊ |
2346 | (*(png_ptr->read_user_transform_fn)) /* User read transform function */␍␊ |
2347 | (png_ptr, /* png_ptr */␍␊ |
2348 | row_info, /* row_info: */␍␊ |
2349 | /* png_uint_32 width; width of row */␍␊ |
2350 | /* png_size_t rowbytes; number of bytes in row */␍␊ |
2351 | /* png_byte color_type; color type of pixels */␍␊ |
2352 | /* png_byte bit_depth; bit depth of samples */␍␊ |
2353 | /* png_byte channels; number of channels (1-4) */␍␊ |
2354 | /* png_byte pixel_depth; bits per pixel (depth*channels) */␍␊ |
2355 | png_ptr->row_buf + 1); /* start of pixel data for row */␍␊ |
2356 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED␍␊ |
2357 | if (png_ptr->user_transform_depth)␍␊ |
2358 | row_info->bit_depth = png_ptr->user_transform_depth;␍␊ |
2359 | ␍␊ |
2360 | if (png_ptr->user_transform_channels)␍␊ |
2361 | row_info->channels = png_ptr->user_transform_channels;␍␊ |
2362 | #endif␍␊ |
2363 | row_info->pixel_depth = (png_byte)(row_info->bit_depth *␍␊ |
2364 | row_info->channels);␍␊ |
2365 | ␍␊ |
2366 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);␍␊ |
2367 | }␍␊ |
2368 | #endif␍␊ |
2369 | }␍␊ |
2370 | ␍␊ |
2371 | #ifdef PNG_READ_PACK_SUPPORTED␍␊ |
2372 | /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,␍␊ |
2373 | * without changing the actual values. Thus, if you had a row with␍␊ |
2374 | * a bit depth of 1, you would end up with bytes that only contained␍␊ |
2375 | * the numbers 0 or 1. If you would rather they contain 0 and 255, use␍␊ |
2376 | * png_do_shift() after this.␍␊ |
2377 | */␍␊ |
2378 | void /* PRIVATE */␍␊ |
2379 | png_do_unpack(png_row_infop row_info, png_bytep row)␍␊ |
2380 | {␍␊ |
2381 | png_debug(1, "in png_do_unpack");␍␊ |
2382 | ␍␊ |
2383 | if (row_info->bit_depth < 8)␍␊ |
2384 | {␍␊ |
2385 | png_uint_32 i;␍␊ |
2386 | png_uint_32 row_width=row_info->width;␍␊ |
2387 | ␍␊ |
2388 | switch (row_info->bit_depth)␍␊ |
2389 | {␍␊ |
2390 | case 1:␍␊ |
2391 | {␍␊ |
2392 | png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);␍␊ |
2393 | png_bytep dp = row + (png_size_t)row_width - 1;␍␊ |
2394 | png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);␍␊ |
2395 | for (i = 0; i < row_width; i++)␍␊ |
2396 | {␍␊ |
2397 | *dp = (png_byte)((*sp >> shift) & 0x01);␍␊ |
2398 | ␍␊ |
2399 | if (shift == 7)␍␊ |
2400 | {␍␊ |
2401 | shift = 0;␍␊ |
2402 | sp--;␍␊ |
2403 | }␍␊ |
2404 | ␍␊ |
2405 | else␍␊ |
2406 | shift++;␍␊ |
2407 | ␍␊ |
2408 | dp--;␍␊ |
2409 | }␍␊ |
2410 | break;␍␊ |
2411 | }␍␊ |
2412 | ␍␊ |
2413 | case 2:␍␊ |
2414 | {␍␊ |
2415 | ␍␊ |
2416 | png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);␍␊ |
2417 | png_bytep dp = row + (png_size_t)row_width - 1;␍␊ |
2418 | png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);␍␊ |
2419 | for (i = 0; i < row_width; i++)␍␊ |
2420 | {␍␊ |
2421 | *dp = (png_byte)((*sp >> shift) & 0x03);␍␊ |
2422 | ␍␊ |
2423 | if (shift == 6)␍␊ |
2424 | {␍␊ |
2425 | shift = 0;␍␊ |
2426 | sp--;␍␊ |
2427 | }␍␊ |
2428 | ␍␊ |
2429 | else␍␊ |
2430 | shift += 2;␍␊ |
2431 | ␍␊ |
2432 | dp--;␍␊ |
2433 | }␍␊ |
2434 | break;␍␊ |
2435 | }␍␊ |
2436 | ␍␊ |
2437 | case 4:␍␊ |
2438 | {␍␊ |
2439 | png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);␍␊ |
2440 | png_bytep dp = row + (png_size_t)row_width - 1;␍␊ |
2441 | png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);␍␊ |
2442 | for (i = 0; i < row_width; i++)␍␊ |
2443 | {␍␊ |
2444 | *dp = (png_byte)((*sp >> shift) & 0x0f);␍␊ |
2445 | ␍␊ |
2446 | if (shift == 4)␍␊ |
2447 | {␍␊ |
2448 | shift = 0;␍␊ |
2449 | sp--;␍␊ |
2450 | }␍␊ |
2451 | ␍␊ |
2452 | else␍␊ |
2453 | shift = 4;␍␊ |
2454 | ␍␊ |
2455 | dp--;␍␊ |
2456 | }␍␊ |
2457 | break;␍␊ |
2458 | }␍␊ |
2459 | ␍␊ |
2460 | default:␍␊ |
2461 | break;␍␊ |
2462 | }␍␊ |
2463 | row_info->bit_depth = 8;␍␊ |
2464 | row_info->pixel_depth = (png_byte)(8 * row_info->channels);␍␊ |
2465 | row_info->rowbytes = row_width * row_info->channels;␍␊ |
2466 | }␍␊ |
2467 | }␍␊ |
2468 | #endif␍␊ |
2469 | ␍␊ |
2470 | #ifdef PNG_READ_SHIFT_SUPPORTED␍␊ |
2471 | /* Reverse the effects of png_do_shift. This routine merely shifts the␍␊ |
2472 | * pixels back to their significant bits values. Thus, if you have␍␊ |
2473 | * a row of bit depth 8, but only 5 are significant, this will shift␍␊ |
2474 | * the values back to 0 through 31.␍␊ |
2475 | */␍␊ |
2476 | void /* PRIVATE */␍␊ |
2477 | png_do_unshift(png_row_infop row_info, png_bytep row,␍␊ |
2478 | png_const_color_8p sig_bits)␍␊ |
2479 | {␍␊ |
2480 | int color_type;␍␊ |
2481 | ␍␊ |
2482 | png_debug(1, "in png_do_unshift");␍␊ |
2483 | ␍␊ |
2484 | /* The palette case has already been handled in the _init routine. */␍␊ |
2485 | color_type = row_info->color_type;␍␊ |
2486 | ␍␊ |
2487 | if (color_type != PNG_COLOR_TYPE_PALETTE)␍␊ |
2488 | {␍␊ |
2489 | int shift[4];␍␊ |
2490 | int channels = 0;␍␊ |
2491 | int bit_depth = row_info->bit_depth;␍␊ |
2492 | ␍␊ |
2493 | if (color_type & PNG_COLOR_MASK_COLOR)␍␊ |
2494 | {␍␊ |
2495 | shift[channels++] = bit_depth - sig_bits->red;␍␊ |
2496 | shift[channels++] = bit_depth - sig_bits->green;␍␊ |
2497 | shift[channels++] = bit_depth - sig_bits->blue;␍␊ |
2498 | }␍␊ |
2499 | ␍␊ |
2500 | else␍␊ |
2501 | {␍␊ |
2502 | shift[channels++] = bit_depth - sig_bits->gray;␍␊ |
2503 | }␍␊ |
2504 | ␍␊ |
2505 | if (color_type & PNG_COLOR_MASK_ALPHA)␍␊ |
2506 | {␍␊ |
2507 | shift[channels++] = bit_depth - sig_bits->alpha;␍␊ |
2508 | }␍␊ |
2509 | ␍␊ |
2510 | {␍␊ |
2511 | int c, have_shift;␍␊ |
2512 | ␍␊ |
2513 | for (c = have_shift = 0; c < channels; ++c)␍␊ |
2514 | {␍␊ |
2515 | /* A shift of more than the bit depth is an error condition but it␍␊ |
2516 | * gets ignored here.␍␊ |
2517 | */␍␊ |
2518 | if (shift[c] <= 0 || shift[c] >= bit_depth)␍␊ |
2519 | shift[c] = 0;␍␊ |
2520 | ␍␊ |
2521 | else␍␊ |
2522 | have_shift = 1;␍␊ |
2523 | }␍␊ |
2524 | ␍␊ |
2525 | if (!have_shift)␍␊ |
2526 | return;␍␊ |
2527 | }␍␊ |
2528 | ␍␊ |
2529 | switch (bit_depth)␍␊ |
2530 | {␍␊ |
2531 | default:␍␊ |
2532 | /* Must be 1bpp gray: should not be here! */␍␊ |
2533 | /* NOTREACHED */␍␊ |
2534 | break;␍␊ |
2535 | ␍␊ |
2536 | case 2:␍␊ |
2537 | /* Must be 2bpp gray */␍␊ |
2538 | /* assert(channels == 1 && shift[0] == 1) */␍␊ |
2539 | {␍␊ |
2540 | png_bytep bp = row;␍␊ |
2541 | png_bytep bp_end = bp + row_info->rowbytes;␍␊ |
2542 | ␍␊ |
2543 | while (bp < bp_end)␍␊ |
2544 | {␍␊ |
2545 | int b = (*bp >> 1) & 0x55;␍␊ |
2546 | *bp++ = (png_byte)b;␍␊ |
2547 | }␍␊ |
2548 | break;␍␊ |
2549 | }␍␊ |
2550 | ␍␊ |
2551 | case 4:␍␊ |
2552 | /* Must be 4bpp gray */␍␊ |
2553 | /* assert(channels == 1) */␍␊ |
2554 | {␍␊ |
2555 | png_bytep bp = row;␍␊ |
2556 | png_bytep bp_end = bp + row_info->rowbytes;␍␊ |
2557 | int gray_shift = shift[0];␍␊ |
2558 | int mask = 0xf >> gray_shift;␍␊ |
2559 | ␍␊ |
2560 | mask |= mask << 4;␍␊ |
2561 | ␍␊ |
2562 | while (bp < bp_end)␍␊ |
2563 | {␍␊ |
2564 | int b = (*bp >> gray_shift) & mask;␍␊ |
2565 | *bp++ = (png_byte)b;␍␊ |
2566 | }␍␊ |
2567 | break;␍␊ |
2568 | }␍␊ |
2569 | ␍␊ |
2570 | case 8:␍␊ |
2571 | /* Single byte components, G, GA, RGB, RGBA */␍␊ |
2572 | {␍␊ |
2573 | png_bytep bp = row;␍␊ |
2574 | png_bytep bp_end = bp + row_info->rowbytes;␍␊ |
2575 | int channel = 0;␍␊ |
2576 | ␍␊ |
2577 | while (bp < bp_end)␍␊ |
2578 | {␍␊ |
2579 | int b = *bp >> shift[channel];␍␊ |
2580 | if (++channel >= channels)␍␊ |
2581 | channel = 0;␍␊ |
2582 | *bp++ = (png_byte)b;␍␊ |
2583 | }␍␊ |
2584 | break;␍␊ |
2585 | }␍␊ |
2586 | ␍␊ |
2587 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2588 | case 16:␍␊ |
2589 | /* Double byte components, G, GA, RGB, RGBA */␍␊ |
2590 | {␍␊ |
2591 | png_bytep bp = row;␍␊ |
2592 | png_bytep bp_end = bp + row_info->rowbytes;␍␊ |
2593 | int channel = 0;␍␊ |
2594 | ␍␊ |
2595 | while (bp < bp_end)␍␊ |
2596 | {␍␊ |
2597 | int value = (bp[0] << 8) + bp[1];␍␊ |
2598 | ␍␊ |
2599 | value >>= shift[channel];␍␊ |
2600 | if (++channel >= channels)␍␊ |
2601 | channel = 0;␍␊ |
2602 | *bp++ = (png_byte)(value >> 8);␍␊ |
2603 | *bp++ = (png_byte)(value & 0xff);␍␊ |
2604 | }␍␊ |
2605 | break;␍␊ |
2606 | }␍␊ |
2607 | #endif␍␊ |
2608 | }␍␊ |
2609 | }␍␊ |
2610 | }␍␊ |
2611 | #endif␍␊ |
2612 | ␍␊ |
2613 | #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED␍␊ |
2614 | /* Scale rows of bit depth 16 down to 8 accurately */␍␊ |
2615 | void /* PRIVATE */␍␊ |
2616 | png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)␍␊ |
2617 | {␍␊ |
2618 | png_debug(1, "in png_do_scale_16_to_8");␍␊ |
2619 | ␍␊ |
2620 | if (row_info->bit_depth == 16)␍␊ |
2621 | {␍␊ |
2622 | png_bytep sp = row; /* source */␍␊ |
2623 | png_bytep dp = row; /* destination */␍␊ |
2624 | png_bytep ep = sp + row_info->rowbytes; /* end+1 */␍␊ |
2625 | ␍␊ |
2626 | while (sp < ep)␍␊ |
2627 | {␍␊ |
2628 | /* The input is an array of 16 bit components, these must be scaled to␍␊ |
2629 | * 8 bits each. For a 16 bit value V the required value (from the PNG␍␊ |
2630 | * specification) is:␍␊ |
2631 | *␍␊ |
2632 | * (V * 255) / 65535␍␊ |
2633 | *␍␊ |
2634 | * This reduces to round(V / 257), or floor((V + 128.5)/257)␍␊ |
2635 | *␍␊ |
2636 | * Represent V as the two byte value vhi.vlo. Make a guess that the␍␊ |
2637 | * result is the top byte of V, vhi, then the correction to this value␍␊ |
2638 | * is:␍␊ |
2639 | *␍␊ |
2640 | * error = floor(((V-vhi.vhi) + 128.5) / 257)␍␊ |
2641 | * = floor(((vlo-vhi) + 128.5) / 257)␍␊ |
2642 | *␍␊ |
2643 | * This can be approximated using integer arithmetic (and a signed␍␊ |
2644 | * shift):␍␊ |
2645 | *␍␊ |
2646 | * error = (vlo-vhi+128) >> 8;␍␊ |
2647 | *␍␊ |
2648 | * The approximate differs from the exact answer only when (vlo-vhi) is␍␊ |
2649 | * 128; it then gives a correction of +1 when the exact correction is␍␊ |
2650 | * 0. This gives 128 errors. The exact answer (correct for all 16 bit␍␊ |
2651 | * input values) is:␍␊ |
2652 | *␍␊ |
2653 | * error = (vlo-vhi+128)*65535 >> 24;␍␊ |
2654 | *␍␊ |
2655 | * An alternative arithmetic calculation which also gives no errors is:␍␊ |
2656 | *␍␊ |
2657 | * (V * 255 + 32895) >> 16␍␊ |
2658 | */␍␊ |
2659 | ␍␊ |
2660 | png_int_32 tmp = *sp++; /* must be signed! */␍␊ |
2661 | tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;␍␊ |
2662 | *dp++ = (png_byte)tmp;␍␊ |
2663 | }␍␊ |
2664 | ␍␊ |
2665 | row_info->bit_depth = 8;␍␊ |
2666 | row_info->pixel_depth = (png_byte)(8 * row_info->channels);␍␊ |
2667 | row_info->rowbytes = row_info->width * row_info->channels;␍␊ |
2668 | }␍␊ |
2669 | }␍␊ |
2670 | #endif␍␊ |
2671 | ␍␊ |
2672 | #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED␍␊ |
2673 | void /* PRIVATE */␍␊ |
2674 | /* Simply discard the low byte. This was the default behavior prior␍␊ |
2675 | * to libpng-1.5.4.␍␊ |
2676 | */␍␊ |
2677 | png_do_chop(png_row_infop row_info, png_bytep row)␍␊ |
2678 | {␍␊ |
2679 | png_debug(1, "in png_do_chop");␍␊ |
2680 | ␍␊ |
2681 | if (row_info->bit_depth == 16)␍␊ |
2682 | {␍␊ |
2683 | png_bytep sp = row; /* source */␍␊ |
2684 | png_bytep dp = row; /* destination */␍␊ |
2685 | png_bytep ep = sp + row_info->rowbytes; /* end+1 */␍␊ |
2686 | ␍␊ |
2687 | while (sp < ep)␍␊ |
2688 | {␍␊ |
2689 | *dp++ = *sp;␍␊ |
2690 | sp += 2; /* skip low byte */␍␊ |
2691 | }␍␊ |
2692 | ␍␊ |
2693 | row_info->bit_depth = 8;␍␊ |
2694 | row_info->pixel_depth = (png_byte)(8 * row_info->channels);␍␊ |
2695 | row_info->rowbytes = row_info->width * row_info->channels;␍␊ |
2696 | }␍␊ |
2697 | }␍␊ |
2698 | #endif␍␊ |
2699 | ␍␊ |
2700 | #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED␍␊ |
2701 | void /* PRIVATE */␍␊ |
2702 | png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)␍␊ |
2703 | {␍␊ |
2704 | png_debug(1, "in png_do_read_swap_alpha");␍␊ |
2705 | ␍␊ |
2706 | {␍␊ |
2707 | png_uint_32 row_width = row_info->width;␍␊ |
2708 | if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)␍␊ |
2709 | {␍␊ |
2710 | /* This converts from RGBA to ARGB */␍␊ |
2711 | if (row_info->bit_depth == 8)␍␊ |
2712 | {␍␊ |
2713 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2714 | png_bytep dp = sp;␍␊ |
2715 | png_byte save;␍␊ |
2716 | png_uint_32 i;␍␊ |
2717 | ␍␊ |
2718 | for (i = 0; i < row_width; i++)␍␊ |
2719 | {␍␊ |
2720 | save = *(--sp);␍␊ |
2721 | *(--dp) = *(--sp);␍␊ |
2722 | *(--dp) = *(--sp);␍␊ |
2723 | *(--dp) = *(--sp);␍␊ |
2724 | *(--dp) = save;␍␊ |
2725 | }␍␊ |
2726 | }␍␊ |
2727 | ␍␊ |
2728 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2729 | /* This converts from RRGGBBAA to AARRGGBB */␍␊ |
2730 | else␍␊ |
2731 | {␍␊ |
2732 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2733 | png_bytep dp = sp;␍␊ |
2734 | png_byte save[2];␍␊ |
2735 | png_uint_32 i;␍␊ |
2736 | ␍␊ |
2737 | for (i = 0; i < row_width; i++)␍␊ |
2738 | {␍␊ |
2739 | save[0] = *(--sp);␍␊ |
2740 | save[1] = *(--sp);␍␊ |
2741 | *(--dp) = *(--sp);␍␊ |
2742 | *(--dp) = *(--sp);␍␊ |
2743 | *(--dp) = *(--sp);␍␊ |
2744 | *(--dp) = *(--sp);␍␊ |
2745 | *(--dp) = *(--sp);␍␊ |
2746 | *(--dp) = *(--sp);␍␊ |
2747 | *(--dp) = save[0];␍␊ |
2748 | *(--dp) = save[1];␍␊ |
2749 | }␍␊ |
2750 | }␍␊ |
2751 | #endif␍␊ |
2752 | }␍␊ |
2753 | ␍␊ |
2754 | else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)␍␊ |
2755 | {␍␊ |
2756 | /* This converts from GA to AG */␍␊ |
2757 | if (row_info->bit_depth == 8)␍␊ |
2758 | {␍␊ |
2759 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2760 | png_bytep dp = sp;␍␊ |
2761 | png_byte save;␍␊ |
2762 | png_uint_32 i;␍␊ |
2763 | ␍␊ |
2764 | for (i = 0; i < row_width; i++)␍␊ |
2765 | {␍␊ |
2766 | save = *(--sp);␍␊ |
2767 | *(--dp) = *(--sp);␍␊ |
2768 | *(--dp) = save;␍␊ |
2769 | }␍␊ |
2770 | }␍␊ |
2771 | ␍␊ |
2772 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2773 | /* This converts from GGAA to AAGG */␍␊ |
2774 | else␍␊ |
2775 | {␍␊ |
2776 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2777 | png_bytep dp = sp;␍␊ |
2778 | png_byte save[2];␍␊ |
2779 | png_uint_32 i;␍␊ |
2780 | ␍␊ |
2781 | for (i = 0; i < row_width; i++)␍␊ |
2782 | {␍␊ |
2783 | save[0] = *(--sp);␍␊ |
2784 | save[1] = *(--sp);␍␊ |
2785 | *(--dp) = *(--sp);␍␊ |
2786 | *(--dp) = *(--sp);␍␊ |
2787 | *(--dp) = save[0];␍␊ |
2788 | *(--dp) = save[1];␍␊ |
2789 | }␍␊ |
2790 | }␍␊ |
2791 | #endif␍␊ |
2792 | }␍␊ |
2793 | }␍␊ |
2794 | }␍␊ |
2795 | #endif␍␊ |
2796 | ␍␊ |
2797 | #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED␍␊ |
2798 | void /* PRIVATE */␍␊ |
2799 | png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)␍␊ |
2800 | {␍␊ |
2801 | png_uint_32 row_width;␍␊ |
2802 | png_debug(1, "in png_do_read_invert_alpha");␍␊ |
2803 | ␍␊ |
2804 | row_width = row_info->width;␍␊ |
2805 | if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)␍␊ |
2806 | {␍␊ |
2807 | if (row_info->bit_depth == 8)␍␊ |
2808 | {␍␊ |
2809 | /* This inverts the alpha channel in RGBA */␍␊ |
2810 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2811 | png_bytep dp = sp;␍␊ |
2812 | png_uint_32 i;␍␊ |
2813 | ␍␊ |
2814 | for (i = 0; i < row_width; i++)␍␊ |
2815 | {␍␊ |
2816 | *(--dp) = (png_byte)(255 - *(--sp));␍␊ |
2817 | ␍␊ |
2818 | /* This does nothing:␍␊ |
2819 | *(--dp) = *(--sp);␍␊ |
2820 | *(--dp) = *(--sp);␍␊ |
2821 | *(--dp) = *(--sp);␍␊ |
2822 | We can replace it with:␍␊ |
2823 | */␍␊ |
2824 | sp-=3;␍␊ |
2825 | dp=sp;␍␊ |
2826 | }␍␊ |
2827 | }␍␊ |
2828 | ␍␊ |
2829 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2830 | /* This inverts the alpha channel in RRGGBBAA */␍␊ |
2831 | else␍␊ |
2832 | {␍␊ |
2833 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2834 | png_bytep dp = sp;␍␊ |
2835 | png_uint_32 i;␍␊ |
2836 | ␍␊ |
2837 | for (i = 0; i < row_width; i++)␍␊ |
2838 | {␍␊ |
2839 | *(--dp) = (png_byte)(255 - *(--sp));␍␊ |
2840 | *(--dp) = (png_byte)(255 - *(--sp));␍␊ |
2841 | ␍␊ |
2842 | /* This does nothing:␍␊ |
2843 | *(--dp) = *(--sp);␍␊ |
2844 | *(--dp) = *(--sp);␍␊ |
2845 | *(--dp) = *(--sp);␍␊ |
2846 | *(--dp) = *(--sp);␍␊ |
2847 | *(--dp) = *(--sp);␍␊ |
2848 | *(--dp) = *(--sp);␍␊ |
2849 | We can replace it with:␍␊ |
2850 | */␍␊ |
2851 | sp-=6;␍␊ |
2852 | dp=sp;␍␊ |
2853 | }␍␊ |
2854 | }␍␊ |
2855 | #endif␍␊ |
2856 | }␍␊ |
2857 | else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)␍␊ |
2858 | {␍␊ |
2859 | if (row_info->bit_depth == 8)␍␊ |
2860 | {␍␊ |
2861 | /* This inverts the alpha channel in GA */␍␊ |
2862 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2863 | png_bytep dp = sp;␍␊ |
2864 | png_uint_32 i;␍␊ |
2865 | ␍␊ |
2866 | for (i = 0; i < row_width; i++)␍␊ |
2867 | {␍␊ |
2868 | *(--dp) = (png_byte)(255 - *(--sp));␍␊ |
2869 | *(--dp) = *(--sp);␍␊ |
2870 | }␍␊ |
2871 | }␍␊ |
2872 | ␍␊ |
2873 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2874 | else␍␊ |
2875 | {␍␊ |
2876 | /* This inverts the alpha channel in GGAA */␍␊ |
2877 | png_bytep sp = row + row_info->rowbytes;␍␊ |
2878 | png_bytep dp = sp;␍␊ |
2879 | png_uint_32 i;␍␊ |
2880 | ␍␊ |
2881 | for (i = 0; i < row_width; i++)␍␊ |
2882 | {␍␊ |
2883 | *(--dp) = (png_byte)(255 - *(--sp));␍␊ |
2884 | *(--dp) = (png_byte)(255 - *(--sp));␍␊ |
2885 | /*␍␊ |
2886 | *(--dp) = *(--sp);␍␊ |
2887 | *(--dp) = *(--sp);␍␊ |
2888 | */␍␊ |
2889 | sp-=2;␍␊ |
2890 | dp=sp;␍␊ |
2891 | }␍␊ |
2892 | }␍␊ |
2893 | #endif␍␊ |
2894 | }␍␊ |
2895 | }␍␊ |
2896 | #endif␍␊ |
2897 | ␍␊ |
2898 | #ifdef PNG_READ_FILLER_SUPPORTED␍␊ |
2899 | /* Add filler channel if we have RGB color */␍␊ |
2900 | void /* PRIVATE */␍␊ |
2901 | png_do_read_filler(png_row_infop row_info, png_bytep row,␍␊ |
2902 | png_uint_32 filler, png_uint_32 flags)␍␊ |
2903 | {␍␊ |
2904 | png_uint_32 i;␍␊ |
2905 | png_uint_32 row_width = row_info->width;␍␊ |
2906 | ␍␊ |
2907 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2908 | png_byte hi_filler = (png_byte)((filler>>8) & 0xff);␍␊ |
2909 | #endif␍␊ |
2910 | png_byte lo_filler = (png_byte)(filler & 0xff);␍␊ |
2911 | ␍␊ |
2912 | png_debug(1, "in png_do_read_filler");␍␊ |
2913 | ␍␊ |
2914 | if (␍␊ |
2915 | row_info->color_type == PNG_COLOR_TYPE_GRAY)␍␊ |
2916 | {␍␊ |
2917 | if (row_info->bit_depth == 8)␍␊ |
2918 | {␍␊ |
2919 | if (flags & PNG_FLAG_FILLER_AFTER)␍␊ |
2920 | {␍␊ |
2921 | /* This changes the data from G to GX */␍␊ |
2922 | png_bytep sp = row + (png_size_t)row_width;␍␊ |
2923 | png_bytep dp = sp + (png_size_t)row_width;␍␊ |
2924 | for (i = 1; i < row_width; i++)␍␊ |
2925 | {␍␊ |
2926 | *(--dp) = lo_filler;␍␊ |
2927 | *(--dp) = *(--sp);␍␊ |
2928 | }␍␊ |
2929 | *(--dp) = lo_filler;␍␊ |
2930 | row_info->channels = 2;␍␊ |
2931 | row_info->pixel_depth = 16;␍␊ |
2932 | row_info->rowbytes = row_width * 2;␍␊ |
2933 | }␍␊ |
2934 | ␍␊ |
2935 | else␍␊ |
2936 | {␍␊ |
2937 | /* This changes the data from G to XG */␍␊ |
2938 | png_bytep sp = row + (png_size_t)row_width;␍␊ |
2939 | png_bytep dp = sp + (png_size_t)row_width;␍␊ |
2940 | for (i = 0; i < row_width; i++)␍␊ |
2941 | {␍␊ |
2942 | *(--dp) = *(--sp);␍␊ |
2943 | *(--dp) = lo_filler;␍␊ |
2944 | }␍␊ |
2945 | row_info->channels = 2;␍␊ |
2946 | row_info->pixel_depth = 16;␍␊ |
2947 | row_info->rowbytes = row_width * 2;␍␊ |
2948 | }␍␊ |
2949 | }␍␊ |
2950 | ␍␊ |
2951 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
2952 | else if (row_info->bit_depth == 16)␍␊ |
2953 | {␍␊ |
2954 | if (flags & PNG_FLAG_FILLER_AFTER)␍␊ |
2955 | {␍␊ |
2956 | /* This changes the data from GG to GGXX */␍␊ |
2957 | png_bytep sp = row + (png_size_t)row_width * 2;␍␊ |
2958 | png_bytep dp = sp + (png_size_t)row_width * 2;␍␊ |
2959 | for (i = 1; i < row_width; i++)␍␊ |
2960 | {␍␊ |
2961 | *(--dp) = hi_filler;␍␊ |
2962 | *(--dp) = lo_filler;␍␊ |
2963 | *(--dp) = *(--sp);␍␊ |
2964 | *(--dp) = *(--sp);␍␊ |
2965 | }␍␊ |
2966 | *(--dp) = hi_filler;␍␊ |
2967 | *(--dp) = lo_filler;␍␊ |
2968 | row_info->channels = 2;␍␊ |
2969 | row_info->pixel_depth = 32;␍␊ |
2970 | row_info->rowbytes = row_width * 4;␍␊ |
2971 | }␍␊ |
2972 | ␍␊ |
2973 | else␍␊ |
2974 | {␍␊ |
2975 | /* This changes the data from GG to XXGG */␍␊ |
2976 | png_bytep sp = row + (png_size_t)row_width * 2;␍␊ |
2977 | png_bytep dp = sp + (png_size_t)row_width * 2;␍␊ |
2978 | for (i = 0; i < row_width; i++)␍␊ |
2979 | {␍␊ |
2980 | *(--dp) = *(--sp);␍␊ |
2981 | *(--dp) = *(--sp);␍␊ |
2982 | *(--dp) = hi_filler;␍␊ |
2983 | *(--dp) = lo_filler;␍␊ |
2984 | }␍␊ |
2985 | row_info->channels = 2;␍␊ |
2986 | row_info->pixel_depth = 32;␍␊ |
2987 | row_info->rowbytes = row_width * 4;␍␊ |
2988 | }␍␊ |
2989 | }␍␊ |
2990 | #endif␍␊ |
2991 | } /* COLOR_TYPE == GRAY */␍␊ |
2992 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB)␍␊ |
2993 | {␍␊ |
2994 | if (row_info->bit_depth == 8)␍␊ |
2995 | {␍␊ |
2996 | if (flags & PNG_FLAG_FILLER_AFTER)␍␊ |
2997 | {␍␊ |
2998 | /* This changes the data from RGB to RGBX */␍␊ |
2999 | png_bytep sp = row + (png_size_t)row_width * 3;␍␊ |
3000 | png_bytep dp = sp + (png_size_t)row_width;␍␊ |
3001 | for (i = 1; i < row_width; i++)␍␊ |
3002 | {␍␊ |
3003 | *(--dp) = lo_filler;␍␊ |
3004 | *(--dp) = *(--sp);␍␊ |
3005 | *(--dp) = *(--sp);␍␊ |
3006 | *(--dp) = *(--sp);␍␊ |
3007 | }␍␊ |
3008 | *(--dp) = lo_filler;␍␊ |
3009 | row_info->channels = 4;␍␊ |
3010 | row_info->pixel_depth = 32;␍␊ |
3011 | row_info->rowbytes = row_width * 4;␍␊ |
3012 | }␍␊ |
3013 | ␍␊ |
3014 | else␍␊ |
3015 | {␍␊ |
3016 | /* This changes the data from RGB to XRGB */␍␊ |
3017 | png_bytep sp = row + (png_size_t)row_width * 3;␍␊ |
3018 | png_bytep dp = sp + (png_size_t)row_width;␍␊ |
3019 | for (i = 0; i < row_width; i++)␍␊ |
3020 | {␍␊ |
3021 | *(--dp) = *(--sp);␍␊ |
3022 | *(--dp) = *(--sp);␍␊ |
3023 | *(--dp) = *(--sp);␍␊ |
3024 | *(--dp) = lo_filler;␍␊ |
3025 | }␍␊ |
3026 | row_info->channels = 4;␍␊ |
3027 | row_info->pixel_depth = 32;␍␊ |
3028 | row_info->rowbytes = row_width * 4;␍␊ |
3029 | }␍␊ |
3030 | }␍␊ |
3031 | ␍␊ |
3032 | #ifdef PNG_READ_16BIT_SUPPORTED␍␊ |
3033 | else if (row_info->bit_depth == 16)␍␊ |
3034 | {␍␊ |
3035 | if (flags & PNG_FLAG_FILLER_AFTER)␍␊ |
3036 | {␍␊ |
3037 | /* This changes the data from RRGGBB to RRGGBBXX */␍␊ |
3038 | png_bytep sp = row + (png_size_t)row_width * 6;␍␊ |
3039 | png_bytep dp = sp + (png_size_t)row_width * 2;␍␊ |
3040 | for (i = 1; i < row_width; i++)␍␊ |
3041 | {␍␊ |
3042 | *(--dp) = hi_filler;␍␊ |
3043 | *(--dp) = lo_filler;␍␊ |
3044 | *(--dp) = *(--sp);␍␊ |
3045 | *(--dp) = *(--sp);␍␊ |
3046 | *(--dp) = *(--sp);␍␊ |
3047 | *(--dp) = *(--sp);␍␊ |
3048 | *(--dp) = *(--sp);␍␊ |
3049 | *(--dp) = *(--sp);␍␊ |
3050 | }␍␊ |
3051 | *(--dp) = hi_filler;␍␊ |
3052 | *(--dp) = lo_filler;␍␊ |
3053 | row_info->channels = 4;␍␊ |
3054 | row_info->pixel_depth = 64;␍␊ |
3055 | row_info->rowbytes = row_width * 8;␍␊ |
3056 | }␍␊ |
3057 | ␍␊ |
3058 | else␍␊ |
3059 | {␍␊ |
3060 | /* This changes the data from RRGGBB to XXRRGGBB */␍␊ |
3061 | png_bytep sp = row + (png_size_t)row_width * 6;␍␊ |
3062 | png_bytep dp = sp + (png_size_t)row_width * 2;␍␊ |
3063 | for (i = 0; i < row_width; i++)␍␊ |
3064 | {␍␊ |
3065 | *(--dp) = *(--sp);␍␊ |
3066 | *(--dp) = *(--sp);␍␊ |
3067 | *(--dp) = *(--sp);␍␊ |
3068 | *(--dp) = *(--sp);␍␊ |
3069 | *(--dp) = *(--sp);␍␊ |
3070 | *(--dp) = *(--sp);␍␊ |
3071 | *(--dp) = hi_filler;␍␊ |
3072 | *(--dp) = lo_filler;␍␊ |
3073 | }␍␊ |
3074 | ␍␊ |
3075 | row_info->channels = 4;␍␊ |
3076 | row_info->pixel_depth = 64;␍␊ |
3077 | row_info->rowbytes = row_width * 8;␍␊ |
3078 | }␍␊ |
3079 | }␍␊ |
3080 | #endif␍␊ |
3081 | } /* COLOR_TYPE == RGB */␍␊ |
3082 | }␍␊ |
3083 | #endif␍␊ |
3084 | ␍␊ |
3085 | #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED␍␊ |
3086 | /* Expand grayscale files to RGB, with or without alpha */␍␊ |
3087 | void /* PRIVATE */␍␊ |
3088 | png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)␍␊ |
3089 | {␍␊ |
3090 | png_uint_32 i;␍␊ |
3091 | png_uint_32 row_width = row_info->width;␍␊ |
3092 | ␍␊ |
3093 | png_debug(1, "in png_do_gray_to_rgb");␍␊ |
3094 | ␍␊ |
3095 | if (row_info->bit_depth >= 8 &&␍␊ |
3096 | !(row_info->color_type & PNG_COLOR_MASK_COLOR))␍␊ |
3097 | {␍␊ |
3098 | if (row_info->color_type == PNG_COLOR_TYPE_GRAY)␍␊ |
3099 | {␍␊ |
3100 | if (row_info->bit_depth == 8)␍␊ |
3101 | {␍␊ |
3102 | /* This changes G to RGB */␍␊ |
3103 | png_bytep sp = row + (png_size_t)row_width - 1;␍␊ |
3104 | png_bytep dp = sp + (png_size_t)row_width * 2;␍␊ |
3105 | for (i = 0; i < row_width; i++)␍␊ |
3106 | {␍␊ |
3107 | *(dp--) = *sp;␍␊ |
3108 | *(dp--) = *sp;␍␊ |
3109 | *(dp--) = *(sp--);␍␊ |
3110 | }␍␊ |
3111 | }␍␊ |
3112 | ␍␊ |
3113 | else␍␊ |
3114 | {␍␊ |
3115 | /* This changes GG to RRGGBB */␍␊ |
3116 | png_bytep sp = row + (png_size_t)row_width * 2 - 1;␍␊ |
3117 | png_bytep dp = sp + (png_size_t)row_width * 4;␍␊ |
3118 | for (i = 0; i < row_width; i++)␍␊ |
3119 | {␍␊ |
3120 | *(dp--) = *sp;␍␊ |
3121 | *(dp--) = *(sp - 1);␍␊ |
3122 | *(dp--) = *sp;␍␊ |
3123 | *(dp--) = *(sp - 1);␍␊ |
3124 | *(dp--) = *(sp--);␍␊ |
3125 | *(dp--) = *(sp--);␍␊ |
3126 | }␍␊ |
3127 | }␍␊ |
3128 | }␍␊ |
3129 | ␍␊ |
3130 | else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)␍␊ |
3131 | {␍␊ |
3132 | if (row_info->bit_depth == 8)␍␊ |
3133 | {␍␊ |
3134 | /* This changes GA to RGBA */␍␊ |
3135 | png_bytep sp = row + (png_size_t)row_width * 2 - 1;␍␊ |
3136 | png_bytep dp = sp + (png_size_t)row_width * 2;␍␊ |
3137 | for (i = 0; i < row_width; i++)␍␊ |
3138 | {␍␊ |
3139 | *(dp--) = *(sp--);␍␊ |
3140 | *(dp--) = *sp;␍␊ |
3141 | *(dp--) = *sp;␍␊ |
3142 | *(dp--) = *(sp--);␍␊ |
3143 | }␍␊ |
3144 | }␍␊ |
3145 | ␍␊ |
3146 | else␍␊ |
3147 | {␍␊ |
3148 | /* This changes GGAA to RRGGBBAA */␍␊ |
3149 | png_bytep sp = row + (png_size_t)row_width * 4 - 1;␍␊ |
3150 | png_bytep dp = sp + (png_size_t)row_width * 4;␍␊ |
3151 | for (i = 0; i < row_width; i++)␍␊ |
3152 | {␍␊ |
3153 | *(dp--) = *(sp--);␍␊ |
3154 | *(dp--) = *(sp--);␍␊ |
3155 | *(dp--) = *sp;␍␊ |
3156 | *(dp--) = *(sp - 1);␍␊ |
3157 | *(dp--) = *sp;␍␊ |
3158 | *(dp--) = *(sp - 1);␍␊ |
3159 | *(dp--) = *(sp--);␍␊ |
3160 | *(dp--) = *(sp--);␍␊ |
3161 | }␍␊ |
3162 | }␍␊ |
3163 | }␍␊ |
3164 | row_info->channels = (png_byte)(row_info->channels + 2);␍␊ |
3165 | row_info->color_type |= PNG_COLOR_MASK_COLOR;␍␊ |
3166 | row_info->pixel_depth = (png_byte)(row_info->channels *␍␊ |
3167 | row_info->bit_depth);␍␊ |
3168 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);␍␊ |
3169 | }␍␊ |
3170 | }␍␊ |
3171 | #endif␍␊ |
3172 | ␍␊ |
3173 | #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED␍␊ |
3174 | /* Reduce RGB files to grayscale, with or without alpha␍␊ |
3175 | * using the equation given in Poynton's ColorFAQ of 1998-01-04 at␍␊ |
3176 | * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but␍␊ |
3177 | * versions dated 1998 through November 2002 have been archived at␍␊ |
3178 | * http://web.archive.org/web/20000816232553/http://www.inforamp.net/␍␊ |
3179 | * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )␍␊ |
3180 | * Charles Poynton poynton at poynton.com␍␊ |
3181 | *␍␊ |
3182 | * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B␍␊ |
3183 | *␍␊ |
3184 | * which can be expressed with integers as␍␊ |
3185 | *␍␊ |
3186 | * Y = (6969 * R + 23434 * G + 2365 * B)/32768␍␊ |
3187 | *␍␊ |
3188 | * Poynton's current link (as of January 2003 through July 2011):␍␊ |
3189 | * <http://www.poynton.com/notes/colour_and_gamma/>␍␊ |
3190 | * has changed the numbers slightly:␍␊ |
3191 | *␍␊ |
3192 | * Y = 0.2126*R + 0.7152*G + 0.0722*B␍␊ |
3193 | *␍␊ |
3194 | * which can be expressed with integers as␍␊ |
3195 | *␍␊ |
3196 | * Y = (6966 * R + 23436 * G + 2366 * B)/32768␍␊ |
3197 | *␍␊ |
3198 | * Historically, however, libpng uses numbers derived from the ITU-R Rec 709␍␊ |
3199 | * end point chromaticities and the D65 white point. Depending on the␍␊ |
3200 | * precision used for the D65 white point this produces a variety of different␍␊ |
3201 | * numbers, however if the four decimal place value used in ITU-R Rec 709 is␍␊ |
3202 | * used (0.3127,0.3290) the Y calculation would be:␍␊ |
3203 | *␍␊ |
3204 | * Y = (6968 * R + 23435 * G + 2366 * B)/32768␍␊ |
3205 | *␍␊ |
3206 | * While this is correct the rounding results in an overflow for white, because␍␊ |
3207 | * the sum of the rounded coefficients is 32769, not 32768. Consequently␍␊ |
3208 | * libpng uses, instead, the closest non-overflowing approximation:␍␊ |
3209 | *␍␊ |
3210 | * Y = (6968 * R + 23434 * G + 2366 * B)/32768␍␊ |
3211 | *␍␊ |
3212 | * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk␍␊ |
3213 | * (including an sRGB chunk) then the chromaticities are used to calculate the␍␊ |
3214 | * coefficients. See the chunk handling in pngrutil.c for more information.␍␊ |
3215 | *␍␊ |
3216 | * In all cases the calculation is to be done in a linear colorspace. If no␍␊ |
3217 | * gamma information is available to correct the encoding of the original RGB␍␊ |
3218 | * values this results in an implicit assumption that the original PNG RGB␍␊ |
3219 | * values were linear.␍␊ |
3220 | *␍␊ |
3221 | * Other integer coefficents can be used via png_set_rgb_to_gray(). Because␍␊ |
3222 | * the API takes just red and green coefficients the blue coefficient is␍␊ |
3223 | * calculated to make the sum 32768. This will result in different rounding␍␊ |
3224 | * to that used above.␍␊ |
3225 | */␍␊ |
3226 | int /* PRIVATE */␍␊ |
3227 | png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)␍␊ |
3228 | ␍␊ |
3229 | {␍␊ |
3230 | int rgb_error = 0;␍␊ |
3231 | ␍␊ |
3232 | png_debug(1, "in png_do_rgb_to_gray");␍␊ |
3233 | ␍␊ |
3234 | if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&␍␊ |
3235 | (row_info->color_type & PNG_COLOR_MASK_COLOR))␍␊ |
3236 | {␍␊ |
3237 | PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;␍␊ |
3238 | PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;␍␊ |
3239 | PNG_CONST png_uint_32 bc = 32768 - rc - gc;␍␊ |
3240 | PNG_CONST png_uint_32 row_width = row_info->width;␍␊ |
3241 | PNG_CONST int have_alpha =␍␊ |
3242 | (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;␍␊ |
3243 | ␍␊ |
3244 | if (row_info->bit_depth == 8)␍␊ |
3245 | {␍␊ |
3246 | #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)␍␊ |
3247 | /* Notice that gamma to/from 1 are not necessarily inverses (if␍␊ |
3248 | * there is an overall gamma correction). Prior to 1.5.5 this code␍␊ |
3249 | * checked the linearized values for equality; this doesn't match␍␊ |
3250 | * the documentation, the original values must be checked.␍␊ |
3251 | */␍␊ |
3252 | if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)␍␊ |
3253 | {␍␊ |
3254 | png_bytep sp = row;␍␊ |
3255 | png_bytep dp = row;␍␊ |
3256 | png_uint_32 i;␍␊ |
3257 | ␍␊ |
3258 | for (i = 0; i < row_width; i++)␍␊ |
3259 | {␍␊ |
3260 | png_byte red = *(sp++);␍␊ |
3261 | png_byte green = *(sp++);␍␊ |
3262 | png_byte blue = *(sp++);␍␊ |
3263 | ␍␊ |
3264 | if (red != green || red != blue)␍␊ |
3265 | {␍␊ |
3266 | red = png_ptr->gamma_to_1[red];␍␊ |
3267 | green = png_ptr->gamma_to_1[green];␍␊ |
3268 | blue = png_ptr->gamma_to_1[blue];␍␊ |
3269 | ␍␊ |
3270 | rgb_error |= 1;␍␊ |
3271 | *(dp++) = png_ptr->gamma_from_1[␍␊ |
3272 | (rc*red + gc*green + bc*blue + 16384)>>15];␍␊ |
3273 | }␍␊ |
3274 | ␍␊ |
3275 | else␍␊ |
3276 | {␍␊ |
3277 | /* If there is no overall correction the table will not be␍␊ |
3278 | * set.␍␊ |
3279 | */␍␊ |
3280 | if (png_ptr->gamma_table != NULL)␍␊ |
3281 | red = png_ptr->gamma_table[red];␍␊ |
3282 | ␍␊ |
3283 | *(dp++) = red;␍␊ |
3284 | }␍␊ |
3285 | ␍␊ |
3286 | if (have_alpha)␍␊ |
3287 | *(dp++) = *(sp++);␍␊ |
3288 | }␍␊ |
3289 | }␍␊ |
3290 | else␍␊ |
3291 | #endif␍␊ |
3292 | {␍␊ |
3293 | png_bytep sp = row;␍␊ |
3294 | png_bytep dp = row;␍␊ |
3295 | png_uint_32 i;␍␊ |
3296 | ␍␊ |
3297 | for (i = 0; i < row_width; i++)␍␊ |
3298 | {␍␊ |
3299 | png_byte red = *(sp++);␍␊ |
3300 | png_byte green = *(sp++);␍␊ |
3301 | png_byte blue = *(sp++);␍␊ |
3302 | ␍␊ |
3303 | if (red != green || red != blue)␍␊ |
3304 | {␍␊ |
3305 | rgb_error |= 1;␍␊ |
3306 | /* NOTE: this is the historical approach which simply␍␊ |
3307 | * truncates the results.␍␊ |
3308 | */␍␊ |
3309 | *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);␍␊ |
3310 | }␍␊ |
3311 | ␍␊ |
3312 | else␍␊ |
3313 | *(dp++) = red;␍␊ |
3314 | ␍␊ |
3315 | if (have_alpha)␍␊ |
3316 | *(dp++) = *(sp++);␍␊ |
3317 | }␍␊ |
3318 | }␍␊ |
3319 | }␍␊ |
3320 | ␍␊ |
3321 | else /* RGB bit_depth == 16 */␍␊ |
3322 | {␍␊ |
3323 | #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)␍␊ |
3324 | if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)␍␊ |
3325 | {␍␊ |
3326 | png_bytep sp = row;␍␊ |
3327 | png_bytep dp = row;␍␊ |
3328 | png_uint_32 i;␍␊ |
3329 | ␍␊ |
3330 | for (i = 0; i < row_width; i++)␍␊ |
3331 | {␍␊ |
3332 | png_uint_16 red, green, blue, w;␍␊ |
3333 | ␍␊ |
3334 | red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;␍␊ |
3335 | green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;␍␊ |
3336 | blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;␍␊ |
3337 | ␍␊ |
3338 | if (red == green && red == blue)␍␊ |
3339 | {␍␊ |
3340 | if (png_ptr->gamma_16_table != NULL)␍␊ |
3341 | w = png_ptr->gamma_16_table[(red&0xff)␍␊ |
3342 | >> png_ptr->gamma_shift][red>>8];␍␊ |
3343 | ␍␊ |
3344 | else␍␊ |
3345 | w = red;␍␊ |
3346 | }␍␊ |
3347 | ␍␊ |
3348 | else␍␊ |
3349 | {␍␊ |
3350 | png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff)␍␊ |
3351 | >> png_ptr->gamma_shift][red>>8];␍␊ |
3352 | png_uint_16 green_1 =␍␊ |
3353 | png_ptr->gamma_16_to_1[(green&0xff) >>␍␊ |
3354 | png_ptr->gamma_shift][green>>8];␍␊ |
3355 | png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff)␍␊ |
3356 | >> png_ptr->gamma_shift][blue>>8];␍␊ |
3357 | png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1␍␊ |
3358 | + bc*blue_1 + 16384)>>15);␍␊ |
3359 | w = png_ptr->gamma_16_from_1[(gray16&0xff) >>␍␊ |
3360 | png_ptr->gamma_shift][gray16 >> 8];␍␊ |
3361 | rgb_error |= 1;␍␊ |
3362 | }␍␊ |
3363 | ␍␊ |
3364 | *(dp++) = (png_byte)((w>>8) & 0xff);␍␊ |
3365 | *(dp++) = (png_byte)(w & 0xff);␍␊ |
3366 | ␍␊ |
3367 | if (have_alpha)␍␊ |
3368 | {␍␊ |
3369 | *(dp++) = *(sp++);␍␊ |
3370 | *(dp++) = *(sp++);␍␊ |
3371 | }␍␊ |
3372 | }␍␊ |
3373 | }␍␊ |
3374 | else␍␊ |
3375 | #endif␍␊ |
3376 | {␍␊ |
3377 | png_bytep sp = row;␍␊ |
3378 | png_bytep dp = row;␍␊ |
3379 | png_uint_32 i;␍␊ |
3380 | ␍␊ |
3381 | for (i = 0; i < row_width; i++)␍␊ |
3382 | {␍␊ |
3383 | png_uint_16 red, green, blue, gray16;␍␊ |
3384 | ␍␊ |
3385 | red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;␍␊ |
3386 | green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;␍␊ |
3387 | blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;␍␊ |
3388 | ␍␊ |
3389 | if (red != green || red != blue)␍␊ |
3390 | rgb_error |= 1;␍␊ |
3391 | ␍␊ |
3392 | /* From 1.5.5 in the 16 bit case do the accurate conversion even␍␊ |
3393 | * in the 'fast' case - this is because this is where the code␍␊ |
3394 | * ends up when handling linear 16 bit data.␍␊ |
3395 | */␍␊ |
3396 | gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>␍␊ |
3397 | 15);␍␊ |
3398 | *(dp++) = (png_byte)((gray16>>8) & 0xff);␍␊ |
3399 | *(dp++) = (png_byte)(gray16 & 0xff);␍␊ |
3400 | ␍␊ |
3401 | if (have_alpha)␍␊ |
3402 | {␍␊ |
3403 | *(dp++) = *(sp++);␍␊ |
3404 | *(dp++) = *(sp++);␍␊ |
3405 | }␍␊ |
3406 | }␍␊ |
3407 | }␍␊ |
3408 | }␍␊ |
3409 | ␍␊ |
3410 | row_info->channels = (png_byte)(row_info->channels - 2);␍␊ |
3411 | row_info->color_type = (png_byte)(row_info->color_type &␍␊ |
3412 | ~PNG_COLOR_MASK_COLOR);␍␊ |
3413 | row_info->pixel_depth = (png_byte)(row_info->channels *␍␊ |
3414 | row_info->bit_depth);␍␊ |
3415 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);␍␊ |
3416 | }␍␊ |
3417 | return rgb_error;␍␊ |
3418 | }␍␊ |
3419 | #endif␍␊ |
3420 | #endif /* PNG_READ_TRANSFORMS_SUPPORTED */␍␊ |
3421 | ␍␊ |
3422 | #ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED␍␊ |
3423 | /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth␍␊ |
3424 | * large of png_color. This lets grayscale images be treated as␍␊ |
3425 | * paletted. Most useful for gamma correction and simplification␍␊ |
3426 | * of code. This API is not used internally.␍␊ |
3427 | */␍␊ |
3428 | void PNGAPI␍␊ |
3429 | png_build_grayscale_palette(int bit_depth, png_colorp palette)␍␊ |
3430 | {␍␊ |
3431 | int num_palette;␍␊ |
3432 | int color_inc;␍␊ |
3433 | int i;␍␊ |
3434 | int v;␍␊ |
3435 | ␍␊ |
3436 | png_debug(1, "in png_do_build_grayscale_palette");␍␊ |
3437 | ␍␊ |
3438 | if (palette == NULL)␍␊ |
3439 | return;␍␊ |
3440 | ␍␊ |
3441 | switch (bit_depth)␍␊ |
3442 | {␍␊ |
3443 | case 1:␍␊ |
3444 | num_palette = 2;␍␊ |
3445 | color_inc = 0xff;␍␊ |
3446 | break;␍␊ |
3447 | ␍␊ |
3448 | case 2:␍␊ |
3449 | num_palette = 4;␍␊ |
3450 | color_inc = 0x55;␍␊ |
3451 | break;␍␊ |
3452 | ␍␊ |
3453 | case 4:␍␊ |
3454 | num_palette = 16;␍␊ |
3455 | color_inc = 0x11;␍␊ |
3456 | break;␍␊ |
3457 | ␍␊ |
3458 | case 8:␍␊ |
3459 | num_palette = 256;␍␊ |
3460 | color_inc = 1;␍␊ |
3461 | break;␍␊ |
3462 | ␍␊ |
3463 | default:␍␊ |
3464 | num_palette = 0;␍␊ |
3465 | color_inc = 0;␍␊ |
3466 | break;␍␊ |
3467 | }␍␊ |
3468 | ␍␊ |
3469 | for (i = 0, v = 0; i < num_palette; i++, v += color_inc)␍␊ |
3470 | {␍␊ |
3471 | palette[i].red = (png_byte)v;␍␊ |
3472 | palette[i].green = (png_byte)v;␍␊ |
3473 | palette[i].blue = (png_byte)v;␍␊ |
3474 | }␍␊ |
3475 | }␍␊ |
3476 | #endif␍␊ |
3477 | ␍␊ |
3478 | ␍␊ |
3479 | #ifdef PNG_READ_TRANSFORMS_SUPPORTED␍␊ |
3480 | #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\␍␊ |
3481 | (defined PNG_READ_ALPHA_MODE_SUPPORTED)␍␊ |
3482 | /* Replace any alpha or transparency with the supplied background color.␍␊ |
3483 | * "background" is already in the screen gamma, while "background_1" is␍␊ |
3484 | * at a gamma of 1.0. Paletted files have already been taken care of.␍␊ |
3485 | */␍␊ |
3486 | void /* PRIVATE */␍␊ |
3487 | png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr)␍␊ |
3488 | {␍␊ |
3489 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3490 | png_const_bytep gamma_table = png_ptr->gamma_table;␍␊ |
3491 | png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;␍␊ |
3492 | png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;␍␊ |
3493 | png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;␍␊ |
3494 | png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;␍␊ |
3495 | png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;␍␊ |
3496 | int gamma_shift = png_ptr->gamma_shift;␍␊ |
3497 | #endif␍␊ |
3498 | ␍␊ |
3499 | png_bytep sp;␍␊ |
3500 | png_uint_32 i;␍␊ |
3501 | png_uint_32 row_width = row_info->width;␍␊ |
3502 | int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;␍␊ |
3503 | int shift;␍␊ |
3504 | ␍␊ |
3505 | png_debug(1, "in png_do_compose");␍␊ |
3506 | ␍␊ |
3507 | {␍␊ |
3508 | switch (row_info->color_type)␍␊ |
3509 | {␍␊ |
3510 | case PNG_COLOR_TYPE_GRAY:␍␊ |
3511 | {␍␊ |
3512 | switch (row_info->bit_depth)␍␊ |
3513 | {␍␊ |
3514 | case 1:␍␊ |
3515 | {␍␊ |
3516 | sp = row;␍␊ |
3517 | shift = 7;␍␊ |
3518 | for (i = 0; i < row_width; i++)␍␊ |
3519 | {␍␊ |
3520 | if ((png_uint_16)((*sp >> shift) & 0x01)␍␊ |
3521 | == png_ptr->trans_color.gray)␍␊ |
3522 | {␍␊ |
3523 | *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);␍␊ |
3524 | *sp |= (png_byte)(png_ptr->background.gray << shift);␍␊ |
3525 | }␍␊ |
3526 | ␍␊ |
3527 | if (!shift)␍␊ |
3528 | {␍␊ |
3529 | shift = 7;␍␊ |
3530 | sp++;␍␊ |
3531 | }␍␊ |
3532 | ␍␊ |
3533 | else␍␊ |
3534 | shift--;␍␊ |
3535 | }␍␊ |
3536 | break;␍␊ |
3537 | }␍␊ |
3538 | ␍␊ |
3539 | case 2:␍␊ |
3540 | {␍␊ |
3541 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3542 | if (gamma_table != NULL)␍␊ |
3543 | {␍␊ |
3544 | sp = row;␍␊ |
3545 | shift = 6;␍␊ |
3546 | for (i = 0; i < row_width; i++)␍␊ |
3547 | {␍␊ |
3548 | if ((png_uint_16)((*sp >> shift) & 0x03)␍␊ |
3549 | == png_ptr->trans_color.gray)␍␊ |
3550 | {␍␊ |
3551 | *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);␍␊ |
3552 | *sp |= (png_byte)(png_ptr->background.gray << shift);␍␊ |
3553 | }␍␊ |
3554 | ␍␊ |
3555 | else␍␊ |
3556 | {␍␊ |
3557 | png_byte p = (png_byte)((*sp >> shift) & 0x03);␍␊ |
3558 | png_byte g = (png_byte)((gamma_table [p | (p << 2) |␍␊ |
3559 | (p << 4) | (p << 6)] >> 6) & 0x03);␍␊ |
3560 | *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);␍␊ |
3561 | *sp |= (png_byte)(g << shift);␍␊ |
3562 | }␍␊ |
3563 | ␍␊ |
3564 | if (!shift)␍␊ |
3565 | {␍␊ |
3566 | shift = 6;␍␊ |
3567 | sp++;␍␊ |
3568 | }␍␊ |
3569 | ␍␊ |
3570 | else␍␊ |
3571 | shift -= 2;␍␊ |
3572 | }␍␊ |
3573 | }␍␊ |
3574 | ␍␊ |
3575 | else␍␊ |
3576 | #endif␍␊ |
3577 | {␍␊ |
3578 | sp = row;␍␊ |
3579 | shift = 6;␍␊ |
3580 | for (i = 0; i < row_width; i++)␍␊ |
3581 | {␍␊ |
3582 | if ((png_uint_16)((*sp >> shift) & 0x03)␍␊ |
3583 | == png_ptr->trans_color.gray)␍␊ |
3584 | {␍␊ |
3585 | *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);␍␊ |
3586 | *sp |= (png_byte)(png_ptr->background.gray << shift);␍␊ |
3587 | }␍␊ |
3588 | ␍␊ |
3589 | if (!shift)␍␊ |
3590 | {␍␊ |
3591 | shift = 6;␍␊ |
3592 | sp++;␍␊ |
3593 | }␍␊ |
3594 | ␍␊ |
3595 | else␍␊ |
3596 | shift -= 2;␍␊ |
3597 | }␍␊ |
3598 | }␍␊ |
3599 | break;␍␊ |
3600 | }␍␊ |
3601 | ␍␊ |
3602 | case 4:␍␊ |
3603 | {␍␊ |
3604 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3605 | if (gamma_table != NULL)␍␊ |
3606 | {␍␊ |
3607 | sp = row;␍␊ |
3608 | shift = 4;␍␊ |
3609 | for (i = 0; i < row_width; i++)␍␊ |
3610 | {␍␊ |
3611 | if ((png_uint_16)((*sp >> shift) & 0x0f)␍␊ |
3612 | == png_ptr->trans_color.gray)␍␊ |
3613 | {␍␊ |
3614 | *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);␍␊ |
3615 | *sp |= (png_byte)(png_ptr->background.gray << shift);␍␊ |
3616 | }␍␊ |
3617 | ␍␊ |
3618 | else␍␊ |
3619 | {␍␊ |
3620 | png_byte p = (png_byte)((*sp >> shift) & 0x0f);␍␊ |
3621 | png_byte g = (png_byte)((gamma_table[p |␍␊ |
3622 | (p << 4)] >> 4) & 0x0f);␍␊ |
3623 | *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);␍␊ |
3624 | *sp |= (png_byte)(g << shift);␍␊ |
3625 | }␍␊ |
3626 | ␍␊ |
3627 | if (!shift)␍␊ |
3628 | {␍␊ |
3629 | shift = 4;␍␊ |
3630 | sp++;␍␊ |
3631 | }␍␊ |
3632 | ␍␊ |
3633 | else␍␊ |
3634 | shift -= 4;␍␊ |
3635 | }␍␊ |
3636 | }␍␊ |
3637 | ␍␊ |
3638 | else␍␊ |
3639 | #endif␍␊ |
3640 | {␍␊ |
3641 | sp = row;␍␊ |
3642 | shift = 4;␍␊ |
3643 | for (i = 0; i < row_width; i++)␍␊ |
3644 | {␍␊ |
3645 | if ((png_uint_16)((*sp >> shift) & 0x0f)␍␊ |
3646 | == png_ptr->trans_color.gray)␍␊ |
3647 | {␍␊ |
3648 | *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);␍␊ |
3649 | *sp |= (png_byte)(png_ptr->background.gray << shift);␍␊ |
3650 | }␍␊ |
3651 | ␍␊ |
3652 | if (!shift)␍␊ |
3653 | {␍␊ |
3654 | shift = 4;␍␊ |
3655 | sp++;␍␊ |
3656 | }␍␊ |
3657 | ␍␊ |
3658 | else␍␊ |
3659 | shift -= 4;␍␊ |
3660 | }␍␊ |
3661 | }␍␊ |
3662 | break;␍␊ |
3663 | }␍␊ |
3664 | ␍␊ |
3665 | case 8:␍␊ |
3666 | {␍␊ |
3667 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3668 | if (gamma_table != NULL)␍␊ |
3669 | {␍␊ |
3670 | sp = row;␍␊ |
3671 | for (i = 0; i < row_width; i++, sp++)␍␊ |
3672 | {␍␊ |
3673 | if (*sp == png_ptr->trans_color.gray)␍␊ |
3674 | *sp = (png_byte)png_ptr->background.gray;␍␊ |
3675 | ␍␊ |
3676 | else␍␊ |
3677 | *sp = gamma_table[*sp];␍␊ |
3678 | }␍␊ |
3679 | }␍␊ |
3680 | else␍␊ |
3681 | #endif␍␊ |
3682 | {␍␊ |
3683 | sp = row;␍␊ |
3684 | for (i = 0; i < row_width; i++, sp++)␍␊ |
3685 | {␍␊ |
3686 | if (*sp == png_ptr->trans_color.gray)␍␊ |
3687 | *sp = (png_byte)png_ptr->background.gray;␍␊ |
3688 | }␍␊ |
3689 | }␍␊ |
3690 | break;␍␊ |
3691 | }␍␊ |
3692 | ␍␊ |
3693 | case 16:␍␊ |
3694 | {␍␊ |
3695 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3696 | if (gamma_16 != NULL)␍␊ |
3697 | {␍␊ |
3698 | sp = row;␍␊ |
3699 | for (i = 0; i < row_width; i++, sp += 2)␍␊ |
3700 | {␍␊ |
3701 | png_uint_16 v;␍␊ |
3702 | ␍␊ |
3703 | v = (png_uint_16)(((*sp) << 8) + *(sp + 1));␍␊ |
3704 | ␍␊ |
3705 | if (v == png_ptr->trans_color.gray)␍␊ |
3706 | {␍␊ |
3707 | /* Background is already in screen gamma */␍␊ |
3708 | *sp = (png_byte)((png_ptr->background.gray >> 8)␍␊ |
3709 | & 0xff);␍␊ |
3710 | *(sp + 1) = (png_byte)(png_ptr->background.gray␍␊ |
3711 | & 0xff);␍␊ |
3712 | }␍␊ |
3713 | ␍␊ |
3714 | else␍␊ |
3715 | {␍␊ |
3716 | v = gamma_16[*(sp + 1) >> gamma_shift][*sp];␍␊ |
3717 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
3718 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
3719 | }␍␊ |
3720 | }␍␊ |
3721 | }␍␊ |
3722 | else␍␊ |
3723 | #endif␍␊ |
3724 | {␍␊ |
3725 | sp = row;␍␊ |
3726 | for (i = 0; i < row_width; i++, sp += 2)␍␊ |
3727 | {␍␊ |
3728 | png_uint_16 v;␍␊ |
3729 | ␍␊ |
3730 | v = (png_uint_16)(((*sp) << 8) + *(sp + 1));␍␊ |
3731 | ␍␊ |
3732 | if (v == png_ptr->trans_color.gray)␍␊ |
3733 | {␍␊ |
3734 | *sp = (png_byte)((png_ptr->background.gray >> 8)␍␊ |
3735 | & 0xff);␍␊ |
3736 | *(sp + 1) = (png_byte)(png_ptr->background.gray␍␊ |
3737 | & 0xff);␍␊ |
3738 | }␍␊ |
3739 | }␍␊ |
3740 | }␍␊ |
3741 | break;␍␊ |
3742 | }␍␊ |
3743 | ␍␊ |
3744 | default:␍␊ |
3745 | break;␍␊ |
3746 | }␍␊ |
3747 | break;␍␊ |
3748 | }␍␊ |
3749 | ␍␊ |
3750 | case PNG_COLOR_TYPE_RGB:␍␊ |
3751 | {␍␊ |
3752 | if (row_info->bit_depth == 8)␍␊ |
3753 | {␍␊ |
3754 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3755 | if (gamma_table != NULL)␍␊ |
3756 | {␍␊ |
3757 | sp = row;␍␊ |
3758 | for (i = 0; i < row_width; i++, sp += 3)␍␊ |
3759 | {␍␊ |
3760 | if (*sp == png_ptr->trans_color.red &&␍␊ |
3761 | *(sp + 1) == png_ptr->trans_color.green &&␍␊ |
3762 | *(sp + 2) == png_ptr->trans_color.blue)␍␊ |
3763 | {␍␊ |
3764 | *sp = (png_byte)png_ptr->background.red;␍␊ |
3765 | *(sp + 1) = (png_byte)png_ptr->background.green;␍␊ |
3766 | *(sp + 2) = (png_byte)png_ptr->background.blue;␍␊ |
3767 | }␍␊ |
3768 | ␍␊ |
3769 | else␍␊ |
3770 | {␍␊ |
3771 | *sp = gamma_table[*sp];␍␊ |
3772 | *(sp + 1) = gamma_table[*(sp + 1)];␍␊ |
3773 | *(sp + 2) = gamma_table[*(sp + 2)];␍␊ |
3774 | }␍␊ |
3775 | }␍␊ |
3776 | }␍␊ |
3777 | else␍␊ |
3778 | #endif␍␊ |
3779 | {␍␊ |
3780 | sp = row;␍␊ |
3781 | for (i = 0; i < row_width; i++, sp += 3)␍␊ |
3782 | {␍␊ |
3783 | if (*sp == png_ptr->trans_color.red &&␍␊ |
3784 | *(sp + 1) == png_ptr->trans_color.green &&␍␊ |
3785 | *(sp + 2) == png_ptr->trans_color.blue)␍␊ |
3786 | {␍␊ |
3787 | *sp = (png_byte)png_ptr->background.red;␍␊ |
3788 | *(sp + 1) = (png_byte)png_ptr->background.green;␍␊ |
3789 | *(sp + 2) = (png_byte)png_ptr->background.blue;␍␊ |
3790 | }␍␊ |
3791 | }␍␊ |
3792 | }␍␊ |
3793 | }␍␊ |
3794 | else /* if (row_info->bit_depth == 16) */␍␊ |
3795 | {␍␊ |
3796 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3797 | if (gamma_16 != NULL)␍␊ |
3798 | {␍␊ |
3799 | sp = row;␍␊ |
3800 | for (i = 0; i < row_width; i++, sp += 6)␍␊ |
3801 | {␍␊ |
3802 | png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));␍␊ |
3803 | ␍␊ |
3804 | png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)␍␊ |
3805 | + *(sp + 3));␍␊ |
3806 | ␍␊ |
3807 | png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)␍␊ |
3808 | + *(sp + 5));␍␊ |
3809 | ␍␊ |
3810 | if (r == png_ptr->trans_color.red &&␍␊ |
3811 | g == png_ptr->trans_color.green &&␍␊ |
3812 | b == png_ptr->trans_color.blue)␍␊ |
3813 | {␍␊ |
3814 | /* Background is already in screen gamma */␍␊ |
3815 | *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);␍␊ |
3816 | *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);␍␊ |
3817 | *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)␍␊ |
3818 | & 0xff);␍␊ |
3819 | *(sp + 3) = (png_byte)(png_ptr->background.green␍␊ |
3820 | & 0xff);␍␊ |
3821 | *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)␍␊ |
3822 | & 0xff);␍␊ |
3823 | *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);␍␊ |
3824 | }␍␊ |
3825 | ␍␊ |
3826 | else␍␊ |
3827 | {␍␊ |
3828 | png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];␍␊ |
3829 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
3830 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
3831 | ␍␊ |
3832 | v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];␍␊ |
3833 | *(sp + 2) = (png_byte)((v >> 8) & 0xff);␍␊ |
3834 | *(sp + 3) = (png_byte)(v & 0xff);␍␊ |
3835 | ␍␊ |
3836 | v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];␍␊ |
3837 | *(sp + 4) = (png_byte)((v >> 8) & 0xff);␍␊ |
3838 | *(sp + 5) = (png_byte)(v & 0xff);␍␊ |
3839 | }␍␊ |
3840 | }␍␊ |
3841 | }␍␊ |
3842 | ␍␊ |
3843 | else␍␊ |
3844 | #endif␍␊ |
3845 | {␍␊ |
3846 | sp = row;␍␊ |
3847 | for (i = 0; i < row_width; i++, sp += 6)␍␊ |
3848 | {␍␊ |
3849 | png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));␍␊ |
3850 | ␍␊ |
3851 | png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)␍␊ |
3852 | + *(sp + 3));␍␊ |
3853 | ␍␊ |
3854 | png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)␍␊ |
3855 | + *(sp + 5));␍␊ |
3856 | ␍␊ |
3857 | if (r == png_ptr->trans_color.red &&␍␊ |
3858 | g == png_ptr->trans_color.green &&␍␊ |
3859 | b == png_ptr->trans_color.blue)␍␊ |
3860 | {␍␊ |
3861 | *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);␍␊ |
3862 | *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);␍␊ |
3863 | *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)␍␊ |
3864 | & 0xff);␍␊ |
3865 | *(sp + 3) = (png_byte)(png_ptr->background.green␍␊ |
3866 | & 0xff);␍␊ |
3867 | *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)␍␊ |
3868 | & 0xff);␍␊ |
3869 | *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);␍␊ |
3870 | }␍␊ |
3871 | }␍␊ |
3872 | }␍␊ |
3873 | }␍␊ |
3874 | break;␍␊ |
3875 | }␍␊ |
3876 | ␍␊ |
3877 | case PNG_COLOR_TYPE_GRAY_ALPHA:␍␊ |
3878 | {␍␊ |
3879 | if (row_info->bit_depth == 8)␍␊ |
3880 | {␍␊ |
3881 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3882 | if (gamma_to_1 != NULL && gamma_from_1 != NULL &&␍␊ |
3883 | gamma_table != NULL)␍␊ |
3884 | {␍␊ |
3885 | sp = row;␍␊ |
3886 | for (i = 0; i < row_width; i++, sp += 2)␍␊ |
3887 | {␍␊ |
3888 | png_uint_16 a = *(sp + 1);␍␊ |
3889 | ␍␊ |
3890 | if (a == 0xff)␍␊ |
3891 | *sp = gamma_table[*sp];␍␊ |
3892 | ␍␊ |
3893 | else if (a == 0)␍␊ |
3894 | {␍␊ |
3895 | /* Background is already in screen gamma */␍␊ |
3896 | *sp = (png_byte)png_ptr->background.gray;␍␊ |
3897 | }␍␊ |
3898 | ␍␊ |
3899 | else␍␊ |
3900 | {␍␊ |
3901 | png_byte v, w;␍␊ |
3902 | ␍␊ |
3903 | v = gamma_to_1[*sp];␍␊ |
3904 | png_composite(w, v, a, png_ptr->background_1.gray);␍␊ |
3905 | if (!optimize)␍␊ |
3906 | w = gamma_from_1[w];␍␊ |
3907 | *sp = w;␍␊ |
3908 | }␍␊ |
3909 | }␍␊ |
3910 | }␍␊ |
3911 | else␍␊ |
3912 | #endif␍␊ |
3913 | {␍␊ |
3914 | sp = row;␍␊ |
3915 | for (i = 0; i < row_width; i++, sp += 2)␍␊ |
3916 | {␍␊ |
3917 | png_byte a = *(sp + 1);␍␊ |
3918 | ␍␊ |
3919 | if (a == 0)␍␊ |
3920 | *sp = (png_byte)png_ptr->background.gray;␍␊ |
3921 | ␍␊ |
3922 | else if (a < 0xff)␍␊ |
3923 | png_composite(*sp, *sp, a, png_ptr->background_1.gray);␍␊ |
3924 | }␍␊ |
3925 | }␍␊ |
3926 | }␍␊ |
3927 | else /* if (png_ptr->bit_depth == 16) */␍␊ |
3928 | {␍␊ |
3929 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
3930 | if (gamma_16 != NULL && gamma_16_from_1 != NULL &&␍␊ |
3931 | gamma_16_to_1 != NULL)␍␊ |
3932 | {␍␊ |
3933 | sp = row;␍␊ |
3934 | for (i = 0; i < row_width; i++, sp += 4)␍␊ |
3935 | {␍␊ |
3936 | png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)␍␊ |
3937 | + *(sp + 3));␍␊ |
3938 | ␍␊ |
3939 | if (a == (png_uint_16)0xffff)␍␊ |
3940 | {␍␊ |
3941 | png_uint_16 v;␍␊ |
3942 | ␍␊ |
3943 | v = gamma_16[*(sp + 1) >> gamma_shift][*sp];␍␊ |
3944 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
3945 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
3946 | }␍␊ |
3947 | ␍␊ |
3948 | else if (a == 0)␍␊ |
3949 | {␍␊ |
3950 | /* Background is already in screen gamma */␍␊ |
3951 | *sp = (png_byte)((png_ptr->background.gray >> 8)␍␊ |
3952 | & 0xff);␍␊ |
3953 | *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);␍␊ |
3954 | }␍␊ |
3955 | ␍␊ |
3956 | else␍␊ |
3957 | {␍␊ |
3958 | png_uint_16 g, v, w;␍␊ |
3959 | ␍␊ |
3960 | g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];␍␊ |
3961 | png_composite_16(v, g, a, png_ptr->background_1.gray);␍␊ |
3962 | if (optimize)␍␊ |
3963 | w = v;␍␊ |
3964 | else␍␊ |
3965 | w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];␍␊ |
3966 | *sp = (png_byte)((w >> 8) & 0xff);␍␊ |
3967 | *(sp + 1) = (png_byte)(w & 0xff);␍␊ |
3968 | }␍␊ |
3969 | }␍␊ |
3970 | }␍␊ |
3971 | else␍␊ |
3972 | #endif␍␊ |
3973 | {␍␊ |
3974 | sp = row;␍␊ |
3975 | for (i = 0; i < row_width; i++, sp += 4)␍␊ |
3976 | {␍␊ |
3977 | png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)␍␊ |
3978 | + *(sp + 3));␍␊ |
3979 | ␍␊ |
3980 | if (a == 0)␍␊ |
3981 | {␍␊ |
3982 | *sp = (png_byte)((png_ptr->background.gray >> 8)␍␊ |
3983 | & 0xff);␍␊ |
3984 | *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);␍␊ |
3985 | }␍␊ |
3986 | ␍␊ |
3987 | else if (a < 0xffff)␍␊ |
3988 | {␍␊ |
3989 | png_uint_16 g, v;␍␊ |
3990 | ␍␊ |
3991 | g = (png_uint_16)(((*sp) << 8) + *(sp + 1));␍␊ |
3992 | png_composite_16(v, g, a, png_ptr->background_1.gray);␍␊ |
3993 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
3994 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
3995 | }␍␊ |
3996 | }␍␊ |
3997 | }␍␊ |
3998 | }␍␊ |
3999 | break;␍␊ |
4000 | }␍␊ |
4001 | ␍␊ |
4002 | case PNG_COLOR_TYPE_RGB_ALPHA:␍␊ |
4003 | {␍␊ |
4004 | if (row_info->bit_depth == 8)␍␊ |
4005 | {␍␊ |
4006 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
4007 | if (gamma_to_1 != NULL && gamma_from_1 != NULL &&␍␊ |
4008 | gamma_table != NULL)␍␊ |
4009 | {␍␊ |
4010 | sp = row;␍␊ |
4011 | for (i = 0; i < row_width; i++, sp += 4)␍␊ |
4012 | {␍␊ |
4013 | png_byte a = *(sp + 3);␍␊ |
4014 | ␍␊ |
4015 | if (a == 0xff)␍␊ |
4016 | {␍␊ |
4017 | *sp = gamma_table[*sp];␍␊ |
4018 | *(sp + 1) = gamma_table[*(sp + 1)];␍␊ |
4019 | *(sp + 2) = gamma_table[*(sp + 2)];␍␊ |
4020 | }␍␊ |
4021 | ␍␊ |
4022 | else if (a == 0)␍␊ |
4023 | {␍␊ |
4024 | /* Background is already in screen gamma */␍␊ |
4025 | *sp = (png_byte)png_ptr->background.red;␍␊ |
4026 | *(sp + 1) = (png_byte)png_ptr->background.green;␍␊ |
4027 | *(sp + 2) = (png_byte)png_ptr->background.blue;␍␊ |
4028 | }␍␊ |
4029 | ␍␊ |
4030 | else␍␊ |
4031 | {␍␊ |
4032 | png_byte v, w;␍␊ |
4033 | ␍␊ |
4034 | v = gamma_to_1[*sp];␍␊ |
4035 | png_composite(w, v, a, png_ptr->background_1.red);␍␊ |
4036 | if (!optimize) w = gamma_from_1[w];␍␊ |
4037 | *sp = w;␍␊ |
4038 | ␍␊ |
4039 | v = gamma_to_1[*(sp + 1)];␍␊ |
4040 | png_composite(w, v, a, png_ptr->background_1.green);␍␊ |
4041 | if (!optimize) w = gamma_from_1[w];␍␊ |
4042 | *(sp + 1) = w;␍␊ |
4043 | ␍␊ |
4044 | v = gamma_to_1[*(sp + 2)];␍␊ |
4045 | png_composite(w, v, a, png_ptr->background_1.blue);␍␊ |
4046 | if (!optimize) w = gamma_from_1[w];␍␊ |
4047 | *(sp + 2) = w;␍␊ |
4048 | }␍␊ |
4049 | }␍␊ |
4050 | }␍␊ |
4051 | else␍␊ |
4052 | #endif␍␊ |
4053 | {␍␊ |
4054 | sp = row;␍␊ |
4055 | for (i = 0; i < row_width; i++, sp += 4)␍␊ |
4056 | {␍␊ |
4057 | png_byte a = *(sp + 3);␍␊ |
4058 | ␍␊ |
4059 | if (a == 0)␍␊ |
4060 | {␍␊ |
4061 | *sp = (png_byte)png_ptr->background.red;␍␊ |
4062 | *(sp + 1) = (png_byte)png_ptr->background.green;␍␊ |
4063 | *(sp + 2) = (png_byte)png_ptr->background.blue;␍␊ |
4064 | }␍␊ |
4065 | ␍␊ |
4066 | else if (a < 0xff)␍␊ |
4067 | {␍␊ |
4068 | png_composite(*sp, *sp, a, png_ptr->background.red);␍␊ |
4069 | ␍␊ |
4070 | png_composite(*(sp + 1), *(sp + 1), a,␍␊ |
4071 | png_ptr->background.green);␍␊ |
4072 | ␍␊ |
4073 | png_composite(*(sp + 2), *(sp + 2), a,␍␊ |
4074 | png_ptr->background.blue);␍␊ |
4075 | }␍␊ |
4076 | }␍␊ |
4077 | }␍␊ |
4078 | }␍␊ |
4079 | else /* if (row_info->bit_depth == 16) */␍␊ |
4080 | {␍␊ |
4081 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
4082 | if (gamma_16 != NULL && gamma_16_from_1 != NULL &&␍␊ |
4083 | gamma_16_to_1 != NULL)␍␊ |
4084 | {␍␊ |
4085 | sp = row;␍␊ |
4086 | for (i = 0; i < row_width; i++, sp += 8)␍␊ |
4087 | {␍␊ |
4088 | png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))␍␊ |
4089 | << 8) + (png_uint_16)(*(sp + 7)));␍␊ |
4090 | ␍␊ |
4091 | if (a == (png_uint_16)0xffff)␍␊ |
4092 | {␍␊ |
4093 | png_uint_16 v;␍␊ |
4094 | ␍␊ |
4095 | v = gamma_16[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4096 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4097 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4098 | ␍␊ |
4099 | v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];␍␊ |
4100 | *(sp + 2) = (png_byte)((v >> 8) & 0xff);␍␊ |
4101 | *(sp + 3) = (png_byte)(v & 0xff);␍␊ |
4102 | ␍␊ |
4103 | v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];␍␊ |
4104 | *(sp + 4) = (png_byte)((v >> 8) & 0xff);␍␊ |
4105 | *(sp + 5) = (png_byte)(v & 0xff);␍␊ |
4106 | }␍␊ |
4107 | ␍␊ |
4108 | else if (a == 0)␍␊ |
4109 | {␍␊ |
4110 | /* Background is already in screen gamma */␍␊ |
4111 | *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);␍␊ |
4112 | *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);␍␊ |
4113 | *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)␍␊ |
4114 | & 0xff);␍␊ |
4115 | *(sp + 3) = (png_byte)(png_ptr->background.green␍␊ |
4116 | & 0xff);␍␊ |
4117 | *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)␍␊ |
4118 | & 0xff);␍␊ |
4119 | *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);␍␊ |
4120 | }␍␊ |
4121 | ␍␊ |
4122 | else␍␊ |
4123 | {␍␊ |
4124 | png_uint_16 v, w;␍␊ |
4125 | ␍␊ |
4126 | v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4127 | png_composite_16(w, v, a, png_ptr->background_1.red);␍␊ |
4128 | if (!optimize)␍␊ |
4129 | w = gamma_16_from_1[((w&0xff) >> gamma_shift)]␍␊ |
4130 | [w >> 8];␍␊ |
4131 | *sp = (png_byte)((w >> 8) & 0xff);␍␊ |
4132 | *(sp + 1) = (png_byte)(w & 0xff);␍␊ |
4133 | ␍␊ |
4134 | v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];␍␊ |
4135 | png_composite_16(w, v, a, png_ptr->background_1.green);␍␊ |
4136 | if (!optimize)␍␊ |
4137 | w = gamma_16_from_1[((w&0xff) >> gamma_shift)]␍␊ |
4138 | [w >> 8];␍␊ |
4139 | ␍␊ |
4140 | *(sp + 2) = (png_byte)((w >> 8) & 0xff);␍␊ |
4141 | *(sp + 3) = (png_byte)(w & 0xff);␍␊ |
4142 | ␍␊ |
4143 | v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];␍␊ |
4144 | png_composite_16(w, v, a, png_ptr->background_1.blue);␍␊ |
4145 | if (!optimize)␍␊ |
4146 | w = gamma_16_from_1[((w&0xff) >> gamma_shift)]␍␊ |
4147 | [w >> 8];␍␊ |
4148 | ␍␊ |
4149 | *(sp + 4) = (png_byte)((w >> 8) & 0xff);␍␊ |
4150 | *(sp + 5) = (png_byte)(w & 0xff);␍␊ |
4151 | }␍␊ |
4152 | }␍␊ |
4153 | }␍␊ |
4154 | ␍␊ |
4155 | else␍␊ |
4156 | #endif␍␊ |
4157 | {␍␊ |
4158 | sp = row;␍␊ |
4159 | for (i = 0; i < row_width; i++, sp += 8)␍␊ |
4160 | {␍␊ |
4161 | png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))␍␊ |
4162 | << 8) + (png_uint_16)(*(sp + 7)));␍␊ |
4163 | ␍␊ |
4164 | if (a == 0)␍␊ |
4165 | {␍␊ |
4166 | *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);␍␊ |
4167 | *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);␍␊ |
4168 | *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)␍␊ |
4169 | & 0xff);␍␊ |
4170 | *(sp + 3) = (png_byte)(png_ptr->background.green␍␊ |
4171 | & 0xff);␍␊ |
4172 | *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)␍␊ |
4173 | & 0xff);␍␊ |
4174 | *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);␍␊ |
4175 | }␍␊ |
4176 | ␍␊ |
4177 | else if (a < 0xffff)␍␊ |
4178 | {␍␊ |
4179 | png_uint_16 v;␍␊ |
4180 | ␍␊ |
4181 | png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));␍␊ |
4182 | png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)␍␊ |
4183 | + *(sp + 3));␍␊ |
4184 | png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)␍␊ |
4185 | + *(sp + 5));␍␊ |
4186 | ␍␊ |
4187 | png_composite_16(v, r, a, png_ptr->background.red);␍␊ |
4188 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4189 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4190 | ␍␊ |
4191 | png_composite_16(v, g, a, png_ptr->background.green);␍␊ |
4192 | *(sp + 2) = (png_byte)((v >> 8) & 0xff);␍␊ |
4193 | *(sp + 3) = (png_byte)(v & 0xff);␍␊ |
4194 | ␍␊ |
4195 | png_composite_16(v, b, a, png_ptr->background.blue);␍␊ |
4196 | *(sp + 4) = (png_byte)((v >> 8) & 0xff);␍␊ |
4197 | *(sp + 5) = (png_byte)(v & 0xff);␍␊ |
4198 | }␍␊ |
4199 | }␍␊ |
4200 | }␍␊ |
4201 | }␍␊ |
4202 | break;␍␊ |
4203 | }␍␊ |
4204 | ␍␊ |
4205 | default:␍␊ |
4206 | break;␍␊ |
4207 | }␍␊ |
4208 | }␍␊ |
4209 | }␍␊ |
4210 | #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */␍␊ |
4211 | ␍␊ |
4212 | #ifdef PNG_READ_GAMMA_SUPPORTED␍␊ |
4213 | /* Gamma correct the image, avoiding the alpha channel. Make sure␍␊ |
4214 | * you do this after you deal with the transparency issue on grayscale␍␊ |
4215 | * or RGB images. If your bit depth is 8, use gamma_table, if it␍␊ |
4216 | * is 16, use gamma_16_table and gamma_shift. Build these with␍␊ |
4217 | * build_gamma_table().␍␊ |
4218 | */␍␊ |
4219 | void /* PRIVATE */␍␊ |
4220 | png_do_gamma(png_row_infop row_info, png_bytep row, png_structp png_ptr)␍␊ |
4221 | {␍␊ |
4222 | png_const_bytep gamma_table = png_ptr->gamma_table;␍␊ |
4223 | png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;␍␊ |
4224 | int gamma_shift = png_ptr->gamma_shift;␍␊ |
4225 | ␍␊ |
4226 | png_bytep sp;␍␊ |
4227 | png_uint_32 i;␍␊ |
4228 | png_uint_32 row_width=row_info->width;␍␊ |
4229 | ␍␊ |
4230 | png_debug(1, "in png_do_gamma");␍␊ |
4231 | ␍␊ |
4232 | if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||␍␊ |
4233 | (row_info->bit_depth == 16 && gamma_16_table != NULL)))␍␊ |
4234 | {␍␊ |
4235 | switch (row_info->color_type)␍␊ |
4236 | {␍␊ |
4237 | case PNG_COLOR_TYPE_RGB:␍␊ |
4238 | {␍␊ |
4239 | if (row_info->bit_depth == 8)␍␊ |
4240 | {␍␊ |
4241 | sp = row;␍␊ |
4242 | for (i = 0; i < row_width; i++)␍␊ |
4243 | {␍␊ |
4244 | *sp = gamma_table[*sp];␍␊ |
4245 | sp++;␍␊ |
4246 | *sp = gamma_table[*sp];␍␊ |
4247 | sp++;␍␊ |
4248 | *sp = gamma_table[*sp];␍␊ |
4249 | sp++;␍␊ |
4250 | }␍␊ |
4251 | }␍␊ |
4252 | ␍␊ |
4253 | else /* if (row_info->bit_depth == 16) */␍␊ |
4254 | {␍␊ |
4255 | sp = row;␍␊ |
4256 | for (i = 0; i < row_width; i++)␍␊ |
4257 | {␍␊ |
4258 | png_uint_16 v;␍␊ |
4259 | ␍␊ |
4260 | v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4261 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4262 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4263 | sp += 2;␍␊ |
4264 | ␍␊ |
4265 | v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4266 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4267 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4268 | sp += 2;␍␊ |
4269 | ␍␊ |
4270 | v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4271 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4272 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4273 | sp += 2;␍␊ |
4274 | }␍␊ |
4275 | }␍␊ |
4276 | break;␍␊ |
4277 | }␍␊ |
4278 | ␍␊ |
4279 | case PNG_COLOR_TYPE_RGB_ALPHA:␍␊ |
4280 | {␍␊ |
4281 | if (row_info->bit_depth == 8)␍␊ |
4282 | {␍␊ |
4283 | sp = row;␍␊ |
4284 | for (i = 0; i < row_width; i++)␍␊ |
4285 | {␍␊ |
4286 | *sp = gamma_table[*sp];␍␊ |
4287 | sp++;␍␊ |
4288 | ␍␊ |
4289 | *sp = gamma_table[*sp];␍␊ |
4290 | sp++;␍␊ |
4291 | ␍␊ |
4292 | *sp = gamma_table[*sp];␍␊ |
4293 | sp++;␍␊ |
4294 | ␍␊ |
4295 | sp++;␍␊ |
4296 | }␍␊ |
4297 | }␍␊ |
4298 | ␍␊ |
4299 | else /* if (row_info->bit_depth == 16) */␍␊ |
4300 | {␍␊ |
4301 | sp = row;␍␊ |
4302 | for (i = 0; i < row_width; i++)␍␊ |
4303 | {␍␊ |
4304 | png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4305 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4306 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4307 | sp += 2;␍␊ |
4308 | ␍␊ |
4309 | v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4310 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4311 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4312 | sp += 2;␍␊ |
4313 | ␍␊ |
4314 | v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4315 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4316 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4317 | sp += 4;␍␊ |
4318 | }␍␊ |
4319 | }␍␊ |
4320 | break;␍␊ |
4321 | }␍␊ |
4322 | ␍␊ |
4323 | case PNG_COLOR_TYPE_GRAY_ALPHA:␍␊ |
4324 | {␍␊ |
4325 | if (row_info->bit_depth == 8)␍␊ |
4326 | {␍␊ |
4327 | sp = row;␍␊ |
4328 | for (i = 0; i < row_width; i++)␍␊ |
4329 | {␍␊ |
4330 | *sp = gamma_table[*sp];␍␊ |
4331 | sp += 2;␍␊ |
4332 | }␍␊ |
4333 | }␍␊ |
4334 | ␍␊ |
4335 | else /* if (row_info->bit_depth == 16) */␍␊ |
4336 | {␍␊ |
4337 | sp = row;␍␊ |
4338 | for (i = 0; i < row_width; i++)␍␊ |
4339 | {␍␊ |
4340 | png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4341 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4342 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4343 | sp += 4;␍␊ |
4344 | }␍␊ |
4345 | }␍␊ |
4346 | break;␍␊ |
4347 | }␍␊ |
4348 | ␍␊ |
4349 | case PNG_COLOR_TYPE_GRAY:␍␊ |
4350 | {␍␊ |
4351 | if (row_info->bit_depth == 2)␍␊ |
4352 | {␍␊ |
4353 | sp = row;␍␊ |
4354 | for (i = 0; i < row_width; i += 4)␍␊ |
4355 | {␍␊ |
4356 | int a = *sp & 0xc0;␍␊ |
4357 | int b = *sp & 0x30;␍␊ |
4358 | int c = *sp & 0x0c;␍␊ |
4359 | int d = *sp & 0x03;␍␊ |
4360 | ␍␊ |
4361 | *sp = (png_byte)(␍␊ |
4362 | ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|␍␊ |
4363 | ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|␍␊ |
4364 | ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|␍␊ |
4365 | ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));␍␊ |
4366 | sp++;␍␊ |
4367 | }␍␊ |
4368 | }␍␊ |
4369 | ␍␊ |
4370 | if (row_info->bit_depth == 4)␍␊ |
4371 | {␍␊ |
4372 | sp = row;␍␊ |
4373 | for (i = 0; i < row_width; i += 2)␍␊ |
4374 | {␍␊ |
4375 | int msb = *sp & 0xf0;␍␊ |
4376 | int lsb = *sp & 0x0f;␍␊ |
4377 | ␍␊ |
4378 | *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)␍␊ |
4379 | | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));␍␊ |
4380 | sp++;␍␊ |
4381 | }␍␊ |
4382 | }␍␊ |
4383 | ␍␊ |
4384 | else if (row_info->bit_depth == 8)␍␊ |
4385 | {␍␊ |
4386 | sp = row;␍␊ |
4387 | for (i = 0; i < row_width; i++)␍␊ |
4388 | {␍␊ |
4389 | *sp = gamma_table[*sp];␍␊ |
4390 | sp++;␍␊ |
4391 | }␍␊ |
4392 | }␍␊ |
4393 | ␍␊ |
4394 | else if (row_info->bit_depth == 16)␍␊ |
4395 | {␍␊ |
4396 | sp = row;␍␊ |
4397 | for (i = 0; i < row_width; i++)␍␊ |
4398 | {␍␊ |
4399 | png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];␍␊ |
4400 | *sp = (png_byte)((v >> 8) & 0xff);␍␊ |
4401 | *(sp + 1) = (png_byte)(v & 0xff);␍␊ |
4402 | sp += 2;␍␊ |
4403 | }␍␊ |
4404 | }␍␊ |
4405 | break;␍␊ |
4406 | }␍␊ |
4407 | ␍␊ |
4408 | default:␍␊ |
4409 | break;␍␊ |
4410 | }␍␊ |
4411 | }␍␊ |
4412 | }␍␊ |
4413 | #endif␍␊ |
4414 | ␍␊ |
4415 | #ifdef PNG_READ_ALPHA_MODE_SUPPORTED␍␊ |
4416 | /* Encode the alpha channel to the output gamma (the input channel is always␍␊ |
4417 | * linear.) Called only with color types that have an alpha channel. Needs the␍␊ |
4418 | * from_1 tables.␍␊ |
4419 | */␍␊ |
4420 | void /* PRIVATE */␍␊ |
4421 | png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structp png_ptr)␍␊ |
4422 | {␍␊ |
4423 | png_uint_32 row_width = row_info->width;␍␊ |
4424 | ␍␊ |
4425 | png_debug(1, "in png_do_encode_alpha");␍␊ |
4426 | ␍␊ |
4427 | if (row_info->color_type & PNG_COLOR_MASK_ALPHA)␍␊ |
4428 | {␍␊ |
4429 | if (row_info->bit_depth == 8)␍␊ |
4430 | {␍␊ |
4431 | PNG_CONST png_bytep table = png_ptr->gamma_from_1;␍␊ |
4432 | ␍␊ |
4433 | if (table != NULL)␍␊ |
4434 | {␍␊ |
4435 | PNG_CONST int step =␍␊ |
4436 | (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;␍␊ |
4437 | ␍␊ |
4438 | /* The alpha channel is the last component: */␍␊ |
4439 | row += step - 1;␍␊ |
4440 | ␍␊ |
4441 | for (; row_width > 0; --row_width, row += step)␍␊ |
4442 | *row = table[*row];␍␊ |
4443 | ␍␊ |
4444 | return;␍␊ |
4445 | }␍␊ |
4446 | }␍␊ |
4447 | ␍␊ |
4448 | else if (row_info->bit_depth == 16)␍␊ |
4449 | {␍␊ |
4450 | PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;␍␊ |
4451 | PNG_CONST int gamma_shift = png_ptr->gamma_shift;␍␊ |
4452 | ␍␊ |
4453 | if (table != NULL)␍␊ |
4454 | {␍␊ |
4455 | PNG_CONST int step =␍␊ |
4456 | (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;␍␊ |
4457 | ␍␊ |
4458 | /* The alpha channel is the last component: */␍␊ |
4459 | row += step - 2;␍␊ |
4460 | ␍␊ |
4461 | for (; row_width > 0; --row_width, row += step)␍␊ |
4462 | {␍␊ |
4463 | png_uint_16 v;␍␊ |
4464 | ␍␊ |
4465 | v = table[*(row + 1) >> gamma_shift][*row];␍␊ |
4466 | *row = (png_byte)((v >> 8) & 0xff);␍␊ |
4467 | *(row + 1) = (png_byte)(v & 0xff);␍␊ |
4468 | }␍␊ |
4469 | ␍␊ |
4470 | return;␍␊ |
4471 | }␍␊ |
4472 | }␍␊ |
4473 | }␍␊ |
4474 | ␍␊ |
4475 | /* Only get to here if called with a weird row_info; no harm has been done,␍␊ |
4476 | * so just issue a warning.␍␊ |
4477 | */␍␊ |
4478 | png_warning(png_ptr, "png_do_encode_alpha: unexpected call");␍␊ |
4479 | }␍␊ |
4480 | #endif␍␊ |
4481 | ␍␊ |
4482 | #ifdef PNG_READ_EXPAND_SUPPORTED␍␊ |
4483 | /* Expands a palette row to an RGB or RGBA row depending␍␊ |
4484 | * upon whether you supply trans and num_trans.␍␊ |
4485 | */␍␊ |
4486 | void /* PRIVATE */␍␊ |
4487 | png_do_expand_palette(png_row_infop row_info, png_bytep row,␍␊ |
4488 | png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)␍␊ |
4489 | {␍␊ |
4490 | int shift, value;␍␊ |
4491 | png_bytep sp, dp;␍␊ |
4492 | png_uint_32 i;␍␊ |
4493 | png_uint_32 row_width=row_info->width;␍␊ |
4494 | ␍␊ |
4495 | png_debug(1, "in png_do_expand_palette");␍␊ |
4496 | ␍␊ |
4497 | if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)␍␊ |
4498 | {␍␊ |
4499 | if (row_info->bit_depth < 8)␍␊ |
4500 | {␍␊ |
4501 | switch (row_info->bit_depth)␍␊ |
4502 | {␍␊ |
4503 | case 1:␍␊ |
4504 | {␍␊ |
4505 | sp = row + (png_size_t)((row_width - 1) >> 3);␍␊ |
4506 | dp = row + (png_size_t)row_width - 1;␍␊ |
4507 | shift = 7 - (int)((row_width + 7) & 0x07);␍␊ |
4508 | for (i = 0; i < row_width; i++)␍␊ |
4509 | {␍␊ |
4510 | if ((*sp >> shift) & 0x01)␍␊ |
4511 | *dp = 1;␍␊ |
4512 | ␍␊ |
4513 | else␍␊ |
4514 | *dp = 0;␍␊ |
4515 | ␍␊ |
4516 | if (shift == 7)␍␊ |
4517 | {␍␊ |
4518 | shift = 0;␍␊ |
4519 | sp--;␍␊ |
4520 | }␍␊ |
4521 | ␍␊ |
4522 | else␍␊ |
4523 | shift++;␍␊ |
4524 | ␍␊ |
4525 | dp--;␍␊ |
4526 | }␍␊ |
4527 | break;␍␊ |
4528 | }␍␊ |
4529 | ␍␊ |
4530 | case 2:␍␊ |
4531 | {␍␊ |
4532 | sp = row + (png_size_t)((row_width - 1) >> 2);␍␊ |
4533 | dp = row + (png_size_t)row_width - 1;␍␊ |
4534 | shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);␍␊ |
4535 | for (i = 0; i < row_width; i++)␍␊ |
4536 | {␍␊ |
4537 | value = (*sp >> shift) & 0x03;␍␊ |
4538 | *dp = (png_byte)value;␍␊ |
4539 | if (shift == 6)␍␊ |
4540 | {␍␊ |
4541 | shift = 0;␍␊ |
4542 | sp--;␍␊ |
4543 | }␍␊ |
4544 | ␍␊ |
4545 | else␍␊ |
4546 | shift += 2;␍␊ |
4547 | ␍␊ |
4548 | dp--;␍␊ |
4549 | }␍␊ |
4550 | break;␍␊ |
4551 | }␍␊ |
4552 | ␍␊ |
4553 | case 4:␍␊ |
4554 | {␍␊ |
4555 | sp = row + (png_size_t)((row_width - 1) >> 1);␍␊ |
4556 | dp = row + (png_size_t)row_width - 1;␍␊ |
4557 | shift = (int)((row_width & 0x01) << 2);␍␊ |
4558 | for (i = 0; i < row_width; i++)␍␊ |
4559 | {␍␊ |
4560 | value = (*sp >> shift) & 0x0f;␍␊ |
4561 | *dp = (png_byte)value;␍␊ |
4562 | if (shift == 4)␍␊ |
4563 | {␍␊ |
4564 | shift = 0;␍␊ |
4565 | sp--;␍␊ |
4566 | }␍␊ |
4567 | ␍␊ |
4568 | else␍␊ |
4569 | shift += 4;␍␊ |
4570 | ␍␊ |
4571 | dp--;␍␊ |
4572 | }␍␊ |
4573 | break;␍␊ |
4574 | }␍␊ |
4575 | ␍␊ |
4576 | default:␍␊ |
4577 | break;␍␊ |
4578 | }␍␊ |
4579 | row_info->bit_depth = 8;␍␊ |
4580 | row_info->pixel_depth = 8;␍␊ |
4581 | row_info->rowbytes = row_width;␍␊ |
4582 | }␍␊ |
4583 | ␍␊ |
4584 | if (row_info->bit_depth == 8)␍␊ |
4585 | {␍␊ |
4586 | {␍␊ |
4587 | if (num_trans > 0)␍␊ |
4588 | {␍␊ |
4589 | sp = row + (png_size_t)row_width - 1;␍␊ |
4590 | dp = row + (png_size_t)(row_width << 2) - 1;␍␊ |
4591 | ␍␊ |
4592 | for (i = 0; i < row_width; i++)␍␊ |
4593 | {␍␊ |
4594 | if ((int)(*sp) >= num_trans)␍␊ |
4595 | *dp-- = 0xff;␍␊ |
4596 | ␍␊ |
4597 | else␍␊ |
4598 | *dp-- = trans_alpha[*sp];␍␊ |
4599 | ␍␊ |
4600 | *dp-- = palette[*sp].blue;␍␊ |
4601 | *dp-- = palette[*sp].green;␍␊ |
4602 | *dp-- = palette[*sp].red;␍␊ |
4603 | sp--;␍␊ |
4604 | }␍␊ |
4605 | row_info->bit_depth = 8;␍␊ |
4606 | row_info->pixel_depth = 32;␍␊ |
4607 | row_info->rowbytes = row_width * 4;␍␊ |
4608 | row_info->color_type = 6;␍␊ |
4609 | row_info->channels = 4;␍␊ |
4610 | }␍␊ |
4611 | ␍␊ |
4612 | else␍␊ |
4613 | {␍␊ |
4614 | sp = row + (png_size_t)row_width - 1;␍␊ |
4615 | dp = row + (png_size_t)(row_width * 3) - 1;␍␊ |
4616 | ␍␊ |
4617 | for (i = 0; i < row_width; i++)␍␊ |
4618 | {␍␊ |
4619 | *dp-- = palette[*sp].blue;␍␊ |
4620 | *dp-- = palette[*sp].green;␍␊ |
4621 | *dp-- = palette[*sp].red;␍␊ |
4622 | sp--;␍␊ |
4623 | }␍␊ |
4624 | ␍␊ |
4625 | row_info->bit_depth = 8;␍␊ |
4626 | row_info->pixel_depth = 24;␍␊ |
4627 | row_info->rowbytes = row_width * 3;␍␊ |
4628 | row_info->color_type = 2;␍␊ |
4629 | row_info->channels = 3;␍␊ |
4630 | }␍␊ |
4631 | }␍␊ |
4632 | }␍␊ |
4633 | }␍␊ |
4634 | }␍␊ |
4635 | ␍␊ |
4636 | /* If the bit depth < 8, it is expanded to 8. Also, if the already␍␊ |
4637 | * expanded transparency value is supplied, an alpha channel is built.␍␊ |
4638 | */␍␊ |
4639 | void /* PRIVATE */␍␊ |
4640 | png_do_expand(png_row_infop row_info, png_bytep row,␍␊ |
4641 | png_const_color_16p trans_color)␍␊ |
4642 | {␍␊ |
4643 | int shift, value;␍␊ |
4644 | png_bytep sp, dp;␍␊ |
4645 | png_uint_32 i;␍␊ |
4646 | png_uint_32 row_width=row_info->width;␍␊ |
4647 | ␍␊ |
4648 | png_debug(1, "in png_do_expand");␍␊ |
4649 | ␍␊ |
4650 | {␍␊ |
4651 | if (row_info->color_type == PNG_COLOR_TYPE_GRAY)␍␊ |
4652 | {␍␊ |
4653 | png_uint_16 gray = (png_uint_16)(trans_color ? trans_color->gray : 0);␍␊ |
4654 | ␍␊ |
4655 | if (row_info->bit_depth < 8)␍␊ |
4656 | {␍␊ |
4657 | switch (row_info->bit_depth)␍␊ |
4658 | {␍␊ |
4659 | case 1:␍␊ |
4660 | {␍␊ |
4661 | gray = (png_uint_16)((gray & 0x01) * 0xff);␍␊ |
4662 | sp = row + (png_size_t)((row_width - 1) >> 3);␍␊ |
4663 | dp = row + (png_size_t)row_width - 1;␍␊ |
4664 | shift = 7 - (int)((row_width + 7) & 0x07);␍␊ |
4665 | for (i = 0; i < row_width; i++)␍␊ |
4666 | {␍␊ |
4667 | if ((*sp >> shift) & 0x01)␍␊ |
4668 | *dp = 0xff;␍␊ |
4669 | ␍␊ |
4670 | else␍␊ |
4671 | *dp = 0;␍␊ |
4672 | ␍␊ |
4673 | if (shift == 7)␍␊ |
4674 | {␍␊ |
4675 | shift = 0;␍␊ |
4676 | sp--;␍␊ |
4677 | }␍␊ |
4678 | ␍␊ |
4679 | else␍␊ |
4680 | shift++;␍␊ |
4681 | ␍␊ |
4682 | dp--;␍␊ |
4683 | }␍␊ |
4684 | break;␍␊ |
4685 | }␍␊ |
4686 | ␍␊ |
4687 | case 2:␍␊ |
4688 | {␍␊ |
4689 | gray = (png_uint_16)((gray & 0x03) * 0x55);␍␊ |
4690 | sp = row + (png_size_t)((row_width - 1) >> 2);␍␊ |
4691 | dp = row + (png_size_t)row_width - 1;␍␊ |
4692 | shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);␍␊ |
4693 | for (i = 0; i < row_width; i++)␍␊ |
4694 | {␍␊ |
4695 | value = (*sp >> shift) & 0x03;␍␊ |
4696 | *dp = (png_byte)(value | (value << 2) | (value << 4) |␍␊ |
4697 | (value << 6));␍␊ |
4698 | if (shift == 6)␍␊ |
4699 | {␍␊ |
4700 | shift = 0;␍␊ |
4701 | sp--;␍␊ |
4702 | }␍␊ |
4703 | ␍␊ |
4704 | else␍␊ |
4705 | shift += 2;␍␊ |
4706 | ␍␊ |
4707 | dp--;␍␊ |
4708 | }␍␊ |
4709 | break;␍␊ |
4710 | }␍␊ |
4711 | ␍␊ |
4712 | case 4:␍␊ |
4713 | {␍␊ |
4714 | gray = (png_uint_16)((gray & 0x0f) * 0x11);␍␊ |
4715 | sp = row + (png_size_t)((row_width - 1) >> 1);␍␊ |
4716 | dp = row + (png_size_t)row_width - 1;␍␊ |
4717 | shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);␍␊ |
4718 | for (i = 0; i < row_width; i++)␍␊ |
4719 | {␍␊ |
4720 | value = (*sp >> shift) & 0x0f;␍␊ |
4721 | *dp = (png_byte)(value | (value << 4));␍␊ |
4722 | if (shift == 4)␍␊ |
4723 | {␍␊ |
4724 | shift = 0;␍␊ |
4725 | sp--;␍␊ |
4726 | }␍␊ |
4727 | ␍␊ |
4728 | else␍␊ |
4729 | shift = 4;␍␊ |
4730 | ␍␊ |
4731 | dp--;␍␊ |
4732 | }␍␊ |
4733 | break;␍␊ |
4734 | }␍␊ |
4735 | ␍␊ |
4736 | default:␍␊ |
4737 | break;␍␊ |
4738 | }␍␊ |
4739 | ␍␊ |
4740 | row_info->bit_depth = 8;␍␊ |
4741 | row_info->pixel_depth = 8;␍␊ |
4742 | row_info->rowbytes = row_width;␍␊ |
4743 | }␍␊ |
4744 | ␍␊ |
4745 | if (trans_color != NULL)␍␊ |
4746 | {␍␊ |
4747 | if (row_info->bit_depth == 8)␍␊ |
4748 | {␍␊ |
4749 | gray = gray & 0xff;␍␊ |
4750 | sp = row + (png_size_t)row_width - 1;␍␊ |
4751 | dp = row + (png_size_t)(row_width << 1) - 1;␍␊ |
4752 | ␍␊ |
4753 | for (i = 0; i < row_width; i++)␍␊ |
4754 | {␍␊ |
4755 | if (*sp == gray)␍␊ |
4756 | *dp-- = 0;␍␊ |
4757 | ␍␊ |
4758 | else␍␊ |
4759 | *dp-- = 0xff;␍␊ |
4760 | ␍␊ |
4761 | *dp-- = *sp--;␍␊ |
4762 | }␍␊ |
4763 | }␍␊ |
4764 | ␍␊ |
4765 | else if (row_info->bit_depth == 16)␍␊ |
4766 | {␍␊ |
4767 | png_byte gray_high = (png_byte)((gray >> 8) & 0xff);␍␊ |
4768 | png_byte gray_low = (png_byte)(gray & 0xff);␍␊ |
4769 | sp = row + row_info->rowbytes - 1;␍␊ |
4770 | dp = row + (row_info->rowbytes << 1) - 1;␍␊ |
4771 | for (i = 0; i < row_width; i++)␍␊ |
4772 | {␍␊ |
4773 | if (*(sp - 1) == gray_high && *(sp) == gray_low)␍␊ |
4774 | {␍␊ |
4775 | *dp-- = 0;␍␊ |
4776 | *dp-- = 0;␍␊ |
4777 | }␍␊ |
4778 | ␍␊ |
4779 | else␍␊ |
4780 | {␍␊ |
4781 | *dp-- = 0xff;␍␊ |
4782 | *dp-- = 0xff;␍␊ |
4783 | }␍␊ |
4784 | ␍␊ |
4785 | *dp-- = *sp--;␍␊ |
4786 | *dp-- = *sp--;␍␊ |
4787 | }␍␊ |
4788 | }␍␊ |
4789 | ␍␊ |
4790 | row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;␍␊ |
4791 | row_info->channels = 2;␍␊ |
4792 | row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);␍␊ |
4793 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,␍␊ |
4794 | row_width);␍␊ |
4795 | }␍␊ |
4796 | }␍␊ |
4797 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color)␍␊ |
4798 | {␍␊ |
4799 | if (row_info->bit_depth == 8)␍␊ |
4800 | {␍␊ |
4801 | png_byte red = (png_byte)(trans_color->red & 0xff);␍␊ |
4802 | png_byte green = (png_byte)(trans_color->green & 0xff);␍␊ |
4803 | png_byte blue = (png_byte)(trans_color->blue & 0xff);␍␊ |
4804 | sp = row + (png_size_t)row_info->rowbytes - 1;␍␊ |
4805 | dp = row + (png_size_t)(row_width << 2) - 1;␍␊ |
4806 | for (i = 0; i < row_width; i++)␍␊ |
4807 | {␍␊ |
4808 | if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)␍␊ |
4809 | *dp-- = 0;␍␊ |
4810 | ␍␊ |
4811 | else␍␊ |
4812 | *dp-- = 0xff;␍␊ |
4813 | ␍␊ |
4814 | *dp-- = *sp--;␍␊ |
4815 | *dp-- = *sp--;␍␊ |
4816 | *dp-- = *sp--;␍␊ |
4817 | }␍␊ |
4818 | }␍␊ |
4819 | else if (row_info->bit_depth == 16)␍␊ |
4820 | {␍␊ |
4821 | png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);␍␊ |
4822 | png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);␍␊ |
4823 | png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);␍␊ |
4824 | png_byte red_low = (png_byte)(trans_color->red & 0xff);␍␊ |
4825 | png_byte green_low = (png_byte)(trans_color->green & 0xff);␍␊ |
4826 | png_byte blue_low = (png_byte)(trans_color->blue & 0xff);␍␊ |
4827 | sp = row + row_info->rowbytes - 1;␍␊ |
4828 | dp = row + (png_size_t)(row_width << 3) - 1;␍␊ |
4829 | for (i = 0; i < row_width; i++)␍␊ |
4830 | {␍␊ |
4831 | if (*(sp - 5) == red_high &&␍␊ |
4832 | *(sp - 4) == red_low &&␍␊ |
4833 | *(sp - 3) == green_high &&␍␊ |
4834 | *(sp - 2) == green_low &&␍␊ |
4835 | *(sp - 1) == blue_high &&␍␊ |
4836 | *(sp ) == blue_low)␍␊ |
4837 | {␍␊ |
4838 | *dp-- = 0;␍␊ |
4839 | *dp-- = 0;␍␊ |
4840 | }␍␊ |
4841 | ␍␊ |
4842 | else␍␊ |
4843 | {␍␊ |
4844 | *dp-- = 0xff;␍␊ |
4845 | *dp-- = 0xff;␍␊ |
4846 | }␍␊ |
4847 | ␍␊ |
4848 | *dp-- = *sp--;␍␊ |
4849 | *dp-- = *sp--;␍␊ |
4850 | *dp-- = *sp--;␍␊ |
4851 | *dp-- = *sp--;␍␊ |
4852 | *dp-- = *sp--;␍␊ |
4853 | *dp-- = *sp--;␍␊ |
4854 | }␍␊ |
4855 | }␍␊ |
4856 | row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;␍␊ |
4857 | row_info->channels = 4;␍␊ |
4858 | row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);␍␊ |
4859 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);␍␊ |
4860 | }␍␊ |
4861 | }␍␊ |
4862 | }␍␊ |
4863 | #endif␍␊ |
4864 | ␍␊ |
4865 | #ifdef PNG_READ_EXPAND_16_SUPPORTED␍␊ |
4866 | /* If the bit depth is 8 and the color type is not a palette type expand the␍␊ |
4867 | * whole row to 16 bits. Has no effect otherwise.␍␊ |
4868 | */␍␊ |
4869 | void /* PRIVATE */␍␊ |
4870 | png_do_expand_16(png_row_infop row_info, png_bytep row)␍␊ |
4871 | {␍␊ |
4872 | if (row_info->bit_depth == 8 &&␍␊ |
4873 | row_info->color_type != PNG_COLOR_TYPE_PALETTE)␍␊ |
4874 | {␍␊ |
4875 | /* The row have a sequence of bytes containing [0..255] and we need␍␊ |
4876 | * to turn it into another row containing [0..65535], to do this we␍␊ |
4877 | * calculate:␍␊ |
4878 | *␍␊ |
4879 | * (input / 255) * 65535␍␊ |
4880 | *␍␊ |
4881 | * Which happens to be exactly input * 257 and this can be achieved␍␊ |
4882 | * simply by byte replication in place (copying backwards).␍␊ |
4883 | */␍␊ |
4884 | png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */␍␊ |
4885 | png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */␍␊ |
4886 | while (dp > sp)␍␊ |
4887 | dp[-2] = dp[-1] = *--sp, dp -= 2;␍␊ |
4888 | ␍␊ |
4889 | row_info->rowbytes *= 2;␍␊ |
4890 | row_info->bit_depth = 16;␍␊ |
4891 | row_info->pixel_depth = (png_byte)(row_info->channels * 16);␍␊ |
4892 | }␍␊ |
4893 | }␍␊ |
4894 | #endif␍␊ |
4895 | ␍␊ |
4896 | #ifdef PNG_READ_QUANTIZE_SUPPORTED␍␊ |
4897 | void /* PRIVATE */␍␊ |
4898 | png_do_quantize(png_row_infop row_info, png_bytep row,␍␊ |
4899 | png_const_bytep palette_lookup, png_const_bytep quantize_lookup)␍␊ |
4900 | {␍␊ |
4901 | png_bytep sp, dp;␍␊ |
4902 | png_uint_32 i;␍␊ |
4903 | png_uint_32 row_width=row_info->width;␍␊ |
4904 | ␍␊ |
4905 | png_debug(1, "in png_do_quantize");␍␊ |
4906 | ␍␊ |
4907 | if (row_info->bit_depth == 8)␍␊ |
4908 | {␍␊ |
4909 | if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)␍␊ |
4910 | {␍␊ |
4911 | int r, g, b, p;␍␊ |
4912 | sp = row;␍␊ |
4913 | dp = row;␍␊ |
4914 | for (i = 0; i < row_width; i++)␍␊ |
4915 | {␍␊ |
4916 | r = *sp++;␍␊ |
4917 | g = *sp++;␍␊ |
4918 | b = *sp++;␍␊ |
4919 | ␍␊ |
4920 | /* This looks real messy, but the compiler will reduce␍␊ |
4921 | * it down to a reasonable formula. For example, with␍␊ |
4922 | * 5 bits per color, we get:␍␊ |
4923 | * p = (((r >> 3) & 0x1f) << 10) |␍␊ |
4924 | * (((g >> 3) & 0x1f) << 5) |␍␊ |
4925 | * ((b >> 3) & 0x1f);␍␊ |
4926 | */␍␊ |
4927 | p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &␍␊ |
4928 | ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<␍␊ |
4929 | (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |␍␊ |
4930 | (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &␍␊ |
4931 | ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<␍␊ |
4932 | (PNG_QUANTIZE_BLUE_BITS)) |␍␊ |
4933 | ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &␍␊ |
4934 | ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));␍␊ |
4935 | ␍␊ |
4936 | *dp++ = palette_lookup[p];␍␊ |
4937 | }␍␊ |
4938 | ␍␊ |
4939 | row_info->color_type = PNG_COLOR_TYPE_PALETTE;␍␊ |
4940 | row_info->channels = 1;␍␊ |
4941 | row_info->pixel_depth = row_info->bit_depth;␍␊ |
4942 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);␍␊ |
4943 | }␍␊ |
4944 | ␍␊ |
4945 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&␍␊ |
4946 | palette_lookup != NULL)␍␊ |
4947 | {␍␊ |
4948 | int r, g, b, p;␍␊ |
4949 | sp = row;␍␊ |
4950 | dp = row;␍␊ |
4951 | for (i = 0; i < row_width; i++)␍␊ |
4952 | {␍␊ |
4953 | r = *sp++;␍␊ |
4954 | g = *sp++;␍␊ |
4955 | b = *sp++;␍␊ |
4956 | sp++;␍␊ |
4957 | ␍␊ |
4958 | p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &␍␊ |
4959 | ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<␍␊ |
4960 | (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |␍␊ |
4961 | (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &␍␊ |
4962 | ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<␍␊ |
4963 | (PNG_QUANTIZE_BLUE_BITS)) |␍␊ |
4964 | ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &␍␊ |
4965 | ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));␍␊ |
4966 | ␍␊ |
4967 | *dp++ = palette_lookup[p];␍␊ |
4968 | }␍␊ |
4969 | ␍␊ |
4970 | row_info->color_type = PNG_COLOR_TYPE_PALETTE;␍␊ |
4971 | row_info->channels = 1;␍␊ |
4972 | row_info->pixel_depth = row_info->bit_depth;␍␊ |
4973 | row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);␍␊ |
4974 | }␍␊ |
4975 | ␍␊ |
4976 | else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&␍␊ |
4977 | quantize_lookup)␍␊ |
4978 | {␍␊ |
4979 | sp = row;␍␊ |
4980 | ␍␊ |
4981 | for (i = 0; i < row_width; i++, sp++)␍␊ |
4982 | {␍␊ |
4983 | *sp = quantize_lookup[*sp];␍␊ |
4984 | }␍␊ |
4985 | }␍␊ |
4986 | }␍␊ |
4987 | }␍␊ |
4988 | #endif /* PNG_READ_QUANTIZE_SUPPORTED */␍␊ |
4989 | #endif /* PNG_READ_TRANSFORMS_SUPPORTED */␍␊ |
4990 | ␍␊ |
4991 | #ifdef PNG_MNG_FEATURES_SUPPORTED␍␊ |
4992 | /* Undoes intrapixel differencing */␍␊ |
4993 | void /* PRIVATE */␍␊ |
4994 | png_do_read_intrapixel(png_row_infop row_info, png_bytep row)␍␊ |
4995 | {␍␊ |
4996 | png_debug(1, "in png_do_read_intrapixel");␍␊ |
4997 | ␍␊ |
4998 | if (␍␊ |
4999 | (row_info->color_type & PNG_COLOR_MASK_COLOR))␍␊ |
5000 | {␍␊ |
5001 | int bytes_per_pixel;␍␊ |
5002 | png_uint_32 row_width = row_info->width;␍␊ |
5003 | ␍␊ |
5004 | if (row_info->bit_depth == 8)␍␊ |
5005 | {␍␊ |
5006 | png_bytep rp;␍␊ |
5007 | png_uint_32 i;␍␊ |
5008 | ␍␊ |
5009 | if (row_info->color_type == PNG_COLOR_TYPE_RGB)␍␊ |
5010 | bytes_per_pixel = 3;␍␊ |
5011 | ␍␊ |
5012 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)␍␊ |
5013 | bytes_per_pixel = 4;␍␊ |
5014 | ␍␊ |
5015 | else␍␊ |
5016 | return;␍␊ |
5017 | ␍␊ |
5018 | for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)␍␊ |
5019 | {␍␊ |
5020 | *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);␍␊ |
5021 | *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);␍␊ |
5022 | }␍␊ |
5023 | }␍␊ |
5024 | else if (row_info->bit_depth == 16)␍␊ |
5025 | {␍␊ |
5026 | png_bytep rp;␍␊ |
5027 | png_uint_32 i;␍␊ |
5028 | ␍␊ |
5029 | if (row_info->color_type == PNG_COLOR_TYPE_RGB)␍␊ |
5030 | bytes_per_pixel = 6;␍␊ |
5031 | ␍␊ |
5032 | else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)␍␊ |
5033 | bytes_per_pixel = 8;␍␊ |
5034 | ␍␊ |
5035 | else␍␊ |
5036 | return;␍␊ |
5037 | ␍␊ |
5038 | for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)␍␊ |
5039 | {␍␊ |
5040 | png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);␍␊ |
5041 | png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);␍␊ |
5042 | png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);␍␊ |
5043 | png_uint_32 red = (s0 + s1 + 65536) & 0xffff;␍␊ |
5044 | png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;␍␊ |
5045 | *(rp ) = (png_byte)((red >> 8) & 0xff);␍␊ |
5046 | *(rp + 1) = (png_byte)(red & 0xff);␍␊ |
5047 | *(rp + 4) = (png_byte)((blue >> 8) & 0xff);␍␊ |
5048 | *(rp + 5) = (png_byte)(blue & 0xff);␍␊ |
5049 | }␍␊ |
5050 | }␍␊ |
5051 | }␍␊ |
5052 | }␍␊ |
5053 | #endif /* PNG_MNG_FEATURES_SUPPORTED */␍␊ |
5054 | #endif /* PNG_READ_SUPPORTED */␍␊ |
5055 | |