Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / core / src / fxcodec / fx_lpng / lpng_v163 / fx_pngrtran.c
1 #if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)\r
2 /* pngrtran.c - transforms the data in a row for PNG readers\r
3  *\r
4  * Last changed in libpng 1.6.2 [April 25, 2013]\r
5  * Copyright (c) 1998-2013 Glenn Randers-Pehrson\r
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\r
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\r
8  *\r
9  * This code is released under the libpng license.\r
10  * For conditions of distribution and use, see the disclaimer\r
11  * and license in png.h\r
12  *\r
13  * This file contains functions optionally called by an application\r
14  * in order to tell libpng how to handle data when reading a PNG.\r
15  * Transformations that are used in both reading and writing are\r
16  * in pngtrans.c.\r
17  */\r
18 \r
19 #include "pngpriv.h"\r
20 \r
21 #ifdef PNG_READ_SUPPORTED\r
22 \r
23 /* Set the action on getting a CRC error for an ancillary or critical chunk. */\r
24 void PNGAPI\r
25 png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)\r
26 {\r
27    png_debug(1, "in png_set_crc_action");\r
28 \r
29    if (png_ptr == NULL)\r
30       return;\r
31 \r
32    /* Tell libpng how we react to CRC errors in critical chunks */\r
33    switch (crit_action)\r
34    {\r
35       case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */\r
36          break;\r
37 \r
38       case PNG_CRC_WARN_USE:                               /* Warn/use data */\r
39          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;\r
40          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;\r
41          break;\r
42 \r
43       case PNG_CRC_QUIET_USE:                             /* Quiet/use data */\r
44          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;\r
45          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |\r
46                            PNG_FLAG_CRC_CRITICAL_IGNORE;\r
47          break;\r
48 \r
49       case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */\r
50          png_warning(png_ptr,\r
51             "Can't discard critical data on CRC error");\r
52       case PNG_CRC_ERROR_QUIT:                                /* Error/quit */\r
53 \r
54       case PNG_CRC_DEFAULT:\r
55       default:\r
56          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;\r
57          break;\r
58    }\r
59 \r
60    /* Tell libpng how we react to CRC errors in ancillary chunks */\r
61    switch (ancil_action)\r
62    {\r
63       case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */\r
64          break;\r
65 \r
66       case PNG_CRC_WARN_USE:                              /* Warn/use data */\r
67          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\r
68          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;\r
69          break;\r
70 \r
71       case PNG_CRC_QUIET_USE:                            /* Quiet/use data */\r
72          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\r
73          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |\r
74                            PNG_FLAG_CRC_ANCILLARY_NOWARN;\r
75          break;\r
76 \r
77       case PNG_CRC_ERROR_QUIT:                               /* Error/quit */\r
78          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\r
79          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;\r
80          break;\r
81 \r
82       case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */\r
83 \r
84       case PNG_CRC_DEFAULT:\r
85       default:\r
86          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;\r
87          break;\r
88    }\r
89 }\r
90 \r
91 #ifdef PNG_READ_TRANSFORMS_SUPPORTED\r
92 /* Is it OK to set a transformation now?  Only if png_start_read_image or\r
93  * png_read_update_info have not been called.  It is not necessary for the IHDR\r
94  * to have been read in all cases, the parameter allows for this check too.\r
95  */\r
96 static int\r
97 png_rtran_ok(png_structrp png_ptr, int need_IHDR)\r
98 {\r
99    if (png_ptr != NULL)\r
100    {\r
101       if (png_ptr->flags & PNG_FLAG_ROW_INIT)\r
102          png_app_error(png_ptr,\r
103             "invalid after png_start_read_image or png_read_update_info");\r
104 \r
105       else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)\r
106          png_app_error(png_ptr, "invalid before the PNG header has been read");\r
107 \r
108       else\r
109       {\r
110          /* Turn on failure to initialize correctly for all transforms. */\r
111          png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;\r
112 \r
113          return 1; /* Ok */\r
114       }\r
115    }\r
116 \r
117    return 0; /* no png_error possible! */\r
118 }\r
119 #endif\r
120 \r
121 #ifdef PNG_READ_BACKGROUND_SUPPORTED\r
122 /* Handle alpha and tRNS via a background color */\r
123 void PNGFAPI\r
124 png_set_background_fixed(png_structrp png_ptr,\r
125     png_const_color_16p background_color, int background_gamma_code,\r
126     int need_expand, png_fixed_point background_gamma)\r
127 {\r
128    png_debug(1, "in png_set_background_fixed");\r
129 \r
130    if (!png_rtran_ok(png_ptr, 0) || background_color == NULL)\r
131       return;\r
132 \r
133    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)\r
134    {\r
135       png_warning(png_ptr, "Application must supply a known background gamma");\r
136       return;\r
137    }\r
138 \r
139    png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;\r
140    png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
141    png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
142 \r
143    png_ptr->background = *background_color;\r
144    png_ptr->background_gamma = background_gamma;\r
145    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);\r
146    if (need_expand)\r
147       png_ptr->transformations |= PNG_BACKGROUND_EXPAND;\r
148    else\r
149       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;\r
150 }\r
151 \r
152 #  ifdef PNG_FLOATING_POINT_SUPPORTED\r
153 void PNGAPI\r
154 png_set_background(png_structrp png_ptr,\r
155     png_const_color_16p background_color, int background_gamma_code,\r
156     int need_expand, double background_gamma)\r
157 {\r
158    png_set_background_fixed(png_ptr, background_color, background_gamma_code,\r
159       need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));\r
160 }\r
161 #  endif  /* FLOATING_POINT */\r
162 #endif /* READ_BACKGROUND */\r
163 \r
164 /* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the\r
165  * one that pngrtran does first (scale) happens.  This is necessary to allow the\r
166  * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.\r
167  */\r
168 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\r
169 void PNGAPI\r
170 png_set_scale_16(png_structrp png_ptr)\r
171 {\r
172    png_debug(1, "in png_set_scale_16");\r
173 \r
174    if (!png_rtran_ok(png_ptr, 0))\r
175       return;\r
176 \r
177    png_ptr->transformations |= PNG_SCALE_16_TO_8;\r
178 }\r
179 #endif\r
180 \r
181 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\r
182 /* Chop 16-bit depth files to 8-bit depth */\r
183 void PNGAPI\r
184 png_set_strip_16(png_structrp png_ptr)\r
185 {\r
186    png_debug(1, "in png_set_strip_16");\r
187 \r
188    if (!png_rtran_ok(png_ptr, 0))\r
189       return;\r
190 \r
191    png_ptr->transformations |= PNG_16_TO_8;\r
192 }\r
193 #endif\r
194 \r
195 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\r
196 void PNGAPI\r
197 png_set_strip_alpha(png_structrp png_ptr)\r
198 {\r
199    png_debug(1, "in png_set_strip_alpha");\r
200 \r
201    if (!png_rtran_ok(png_ptr, 0))\r
202       return;\r
203 \r
204    png_ptr->transformations |= PNG_STRIP_ALPHA;\r
205 }\r
206 #endif\r
207 \r
208 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)\r
209 static png_fixed_point\r
210 translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,\r
211    int is_screen)\r
212 {\r
213    /* Check for flag values.  The main reason for having the old Mac value as a\r
214     * flag is that it is pretty near impossible to work out what the correct\r
215     * value is from Apple documentation - a working Mac system is needed to\r
216     * discover the value!\r
217     */\r
218    if (output_gamma == PNG_DEFAULT_sRGB ||\r
219       output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)\r
220    {\r
221       /* If there is no sRGB support this just sets the gamma to the standard\r
222        * sRGB value.  (This is a side effect of using this function!)\r
223        */\r
224 #     ifdef PNG_READ_sRGB_SUPPORTED\r
225          png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;\r
226 #     else\r
227          PNG_UNUSED(png_ptr)\r
228 #     endif\r
229       if (is_screen)\r
230          output_gamma = PNG_GAMMA_sRGB;\r
231       else\r
232          output_gamma = PNG_GAMMA_sRGB_INVERSE;\r
233    }\r
234 \r
235    else if (output_gamma == PNG_GAMMA_MAC_18 ||\r
236       output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)\r
237    {\r
238       if (is_screen)\r
239          output_gamma = PNG_GAMMA_MAC_OLD;\r
240       else\r
241          output_gamma = PNG_GAMMA_MAC_INVERSE;\r
242    }\r
243 \r
244    return output_gamma;\r
245 }\r
246 \r
247 #  ifdef PNG_FLOATING_POINT_SUPPORTED\r
248 static png_fixed_point\r
249 convert_gamma_value(png_structrp png_ptr, double output_gamma)\r
250 {\r
251    /* The following silently ignores cases where fixed point (times 100,000)\r
252     * gamma values are passed to the floating point API.  This is safe and it\r
253     * means the fixed point constants work just fine with the floating point\r
254     * API.  The alternative would just lead to undetected errors and spurious\r
255     * bug reports.  Negative values fail inside the _fixed API unless they\r
256     * correspond to the flag values.\r
257     */\r
258    if (output_gamma > 0 && output_gamma < 128)\r
259       output_gamma *= PNG_FP_1;\r
260 \r
261    /* This preserves -1 and -2 exactly: */\r
262    output_gamma = floor(output_gamma + .5);\r
263 \r
264    if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)\r
265       png_fixed_error(png_ptr, "gamma value");\r
266 \r
267    return (png_fixed_point)output_gamma;\r
268 }\r
269 #  endif\r
270 #endif /* READ_ALPHA_MODE || READ_GAMMA */\r
271 \r
272 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED\r
273 void PNGFAPI\r
274 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,\r
275    png_fixed_point output_gamma)\r
276 {\r
277    int compose = 0;\r
278    png_fixed_point file_gamma;\r
279 \r
280    png_debug(1, "in png_set_alpha_mode");\r
281 \r
282    if (!png_rtran_ok(png_ptr, 0))\r
283       return;\r
284 \r
285    output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);\r
286 \r
287    /* Validate the value to ensure it is in a reasonable range. The value\r
288     * is expected to be 1 or greater, but this range test allows for some\r
289     * viewing correction values.  The intent is to weed out users of this API\r
290     * who use the inverse of the gamma value accidentally!  Since some of these\r
291     * values are reasonable this may have to be changed.\r
292     */\r
293    if (output_gamma < 70000 || output_gamma > 300000)\r
294       png_error(png_ptr, "output gamma out of expected range");\r
295 \r
296    /* The default file gamma is the inverse of the output gamma; the output\r
297     * gamma may be changed below so get the file value first:\r
298     */\r
299    file_gamma = png_reciprocal(output_gamma);\r
300 \r
301    /* There are really 8 possibilities here, composed of any combination\r
302     * of:\r
303     *\r
304     *    premultiply the color channels\r
305     *    do not encode non-opaque pixels\r
306     *    encode the alpha as well as the color channels\r
307     *\r
308     * The differences disappear if the input/output ('screen') gamma is 1.0,\r
309     * because then the encoding is a no-op and there is only the choice of\r
310     * premultiplying the color channels or not.\r
311     *\r
312     * png_set_alpha_mode and png_set_background interact because both use\r
313     * png_compose to do the work.  Calling both is only useful when\r
314     * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along\r
315     * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.\r
316     */\r
317    switch (mode)\r
318    {\r
319       case PNG_ALPHA_PNG:        /* default: png standard */\r
320          /* No compose, but it may be set by png_set_background! */\r
321          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
322          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
323          break;\r
324 \r
325       case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */\r
326          compose = 1;\r
327          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
328          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
329          /* The output is linear: */\r
330          output_gamma = PNG_FP_1;\r
331          break;\r
332 \r
333       case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */\r
334          compose = 1;\r
335          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
336          png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;\r
337          /* output_gamma records the encoding of opaque pixels! */\r
338          break;\r
339 \r
340       case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */\r
341          compose = 1;\r
342          png_ptr->transformations |= PNG_ENCODE_ALPHA;\r
343          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
344          break;\r
345 \r
346       default:\r
347          png_error(png_ptr, "invalid alpha mode");\r
348    }\r
349 \r
350    /* Only set the default gamma if the file gamma has not been set (this has\r
351     * the side effect that the gamma in a second call to png_set_alpha_mode will\r
352     * be ignored.)\r
353     */\r
354    if (png_ptr->colorspace.gamma == 0)\r
355    {\r
356       png_ptr->colorspace.gamma = file_gamma;\r
357       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\r
358    }\r
359 \r
360    /* But always set the output gamma: */\r
361    png_ptr->screen_gamma = output_gamma;\r
362 \r
363    /* Finally, if pre-multiplying, set the background fields to achieve the\r
364     * desired result.\r
365     */\r
366    if (compose)\r
367    {\r
368       /* And obtain alpha pre-multiplication by composing on black: */\r
369       memset(&png_ptr->background, 0, (sizeof png_ptr->background));\r
370       png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */\r
371       png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;\r
372       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;\r
373 \r
374       if (png_ptr->transformations & PNG_COMPOSE)\r
375          png_error(png_ptr,\r
376             "conflicting calls to set alpha mode and background");\r
377 \r
378       png_ptr->transformations |= PNG_COMPOSE;\r
379    }\r
380 }\r
381 \r
382 #  ifdef PNG_FLOATING_POINT_SUPPORTED\r
383 void PNGAPI\r
384 png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)\r
385 {\r
386    png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,\r
387       output_gamma));\r
388 }\r
389 #  endif\r
390 #endif\r
391 \r
392 #ifdef PNG_READ_QUANTIZE_SUPPORTED\r
393 /* Dither file to 8-bit.  Supply a palette, the current number\r
394  * of elements in the palette, the maximum number of elements\r
395  * allowed, and a histogram if possible.  If the current number\r
396  * of colors is greater then the maximum number, the palette will be\r
397  * modified to fit in the maximum number.  "full_quantize" indicates\r
398  * whether we need a quantizing cube set up for RGB images, or if we\r
399  * simply are reducing the number of colors in a paletted image.\r
400  */\r
401 \r
402 typedef struct png_dsort_struct\r
403 {\r
404    struct png_dsort_struct * next;\r
405    png_byte left;\r
406    png_byte right;\r
407 } png_dsort;\r
408 typedef png_dsort *   png_dsortp;\r
409 typedef png_dsort * * png_dsortpp;\r
410 \r
411 void PNGAPI\r
412 png_set_quantize(png_structrp png_ptr, png_colorp palette,\r
413     int num_palette, int maximum_colors, png_const_uint_16p histogram,\r
414     int full_quantize)\r
415 {\r
416    png_debug(1, "in png_set_quantize");\r
417 \r
418    if (!png_rtran_ok(png_ptr, 0))\r
419       return;\r
420 \r
421    png_ptr->transformations |= PNG_QUANTIZE;\r
422 \r
423    if (!full_quantize)\r
424    {\r
425       int i;\r
426 \r
427       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,\r
428           (png_uint_32)(num_palette * (sizeof (png_byte))));\r
429       for (i = 0; i < num_palette; i++)\r
430          png_ptr->quantize_index[i] = (png_byte)i;\r
431    }\r
432 \r
433    if (num_palette > maximum_colors)\r
434    {\r
435       if (histogram != NULL)\r
436       {\r
437          /* This is easy enough, just throw out the least used colors.\r
438           * Perhaps not the best solution, but good enough.\r
439           */\r
440 \r
441          int i;\r
442 \r
443          /* Initialize an array to sort colors */\r
444          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,\r
445              (png_uint_32)(num_palette * (sizeof (png_byte))));\r
446 \r
447          /* Initialize the quantize_sort array */\r
448          for (i = 0; i < num_palette; i++)\r
449             png_ptr->quantize_sort[i] = (png_byte)i;\r
450 \r
451          /* Find the least used palette entries by starting a\r
452           * bubble sort, and running it until we have sorted\r
453           * out enough colors.  Note that we don't care about\r
454           * sorting all the colors, just finding which are\r
455           * least used.\r
456           */\r
457 \r
458          for (i = num_palette - 1; i >= maximum_colors; i--)\r
459          {\r
460             int done; /* To stop early if the list is pre-sorted */\r
461             int j;\r
462 \r
463             done = 1;\r
464             for (j = 0; j < i; j++)\r
465             {\r
466                if (histogram[png_ptr->quantize_sort[j]]\r
467                    < histogram[png_ptr->quantize_sort[j + 1]])\r
468                {\r
469                   png_byte t;\r
470 \r
471                   t = png_ptr->quantize_sort[j];\r
472                   png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];\r
473                   png_ptr->quantize_sort[j + 1] = t;\r
474                   done = 0;\r
475                }\r
476             }\r
477 \r
478             if (done)\r
479                break;\r
480          }\r
481 \r
482          /* Swap the palette around, and set up a table, if necessary */\r
483          if (full_quantize)\r
484          {\r
485             int j = num_palette;\r
486 \r
487             /* Put all the useful colors within the max, but don't\r
488              * move the others.\r
489              */\r
490             for (i = 0; i < maximum_colors; i++)\r
491             {\r
492                if ((int)png_ptr->quantize_sort[i] >= maximum_colors)\r
493                {\r
494                   do\r
495                      j--;\r
496                   while ((int)png_ptr->quantize_sort[j] >= maximum_colors);\r
497 \r
498                   palette[i] = palette[j];\r
499                }\r
500             }\r
501          }\r
502          else\r
503          {\r
504             int j = num_palette;\r
505 \r
506             /* Move all the used colors inside the max limit, and\r
507              * develop a translation table.\r
508              */\r
509             for (i = 0; i < maximum_colors; i++)\r
510             {\r
511                /* Only move the colors we need to */\r
512                if ((int)png_ptr->quantize_sort[i] >= maximum_colors)\r
513                {\r
514                   png_color tmp_color;\r
515 \r
516                   do\r
517                      j--;\r
518                   while ((int)png_ptr->quantize_sort[j] >= maximum_colors);\r
519 \r
520                   tmp_color = palette[j];\r
521                   palette[j] = palette[i];\r
522                   palette[i] = tmp_color;\r
523                   /* Indicate where the color went */\r
524                   png_ptr->quantize_index[j] = (png_byte)i;\r
525                   png_ptr->quantize_index[i] = (png_byte)j;\r
526                }\r
527             }\r
528 \r
529             /* Find closest color for those colors we are not using */\r
530             for (i = 0; i < num_palette; i++)\r
531             {\r
532                if ((int)png_ptr->quantize_index[i] >= maximum_colors)\r
533                {\r
534                   int min_d, k, min_k, d_index;\r
535 \r
536                   /* Find the closest color to one we threw out */\r
537                   d_index = png_ptr->quantize_index[i];\r
538                   min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);\r
539                   for (k = 1, min_k = 0; k < maximum_colors; k++)\r
540                   {\r
541                      int d;\r
542 \r
543                      d = PNG_COLOR_DIST(palette[d_index], palette[k]);\r
544 \r
545                      if (d < min_d)\r
546                      {\r
547                         min_d = d;\r
548                         min_k = k;\r
549                      }\r
550                   }\r
551                   /* Point to closest color */\r
552                   png_ptr->quantize_index[i] = (png_byte)min_k;\r
553                }\r
554             }\r
555          }\r
556          png_free(png_ptr, png_ptr->quantize_sort);\r
557          png_ptr->quantize_sort = NULL;\r
558       }\r
559       else\r
560       {\r
561          /* This is much harder to do simply (and quickly).  Perhaps\r
562           * we need to go through a median cut routine, but those\r
563           * don't always behave themselves with only a few colors\r
564           * as input.  So we will just find the closest two colors,\r
565           * and throw out one of them (chosen somewhat randomly).\r
566           * [We don't understand this at all, so if someone wants to\r
567           *  work on improving it, be our guest - AED, GRP]\r
568           */\r
569          int i;\r
570          int max_d;\r
571          int num_new_palette;\r
572          png_dsortp t;\r
573          png_dsortpp hash;\r
574 \r
575          t = NULL;\r
576 \r
577          /* Initialize palette index arrays */\r
578          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,\r
579              (png_uint_32)(num_palette * (sizeof (png_byte))));\r
580          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,\r
581              (png_uint_32)(num_palette * (sizeof (png_byte))));\r
582 \r
583          /* Initialize the sort array */\r
584          for (i = 0; i < num_palette; i++)\r
585          {\r
586             png_ptr->index_to_palette[i] = (png_byte)i;\r
587             png_ptr->palette_to_index[i] = (png_byte)i;\r
588          }\r
589 \r
590          hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *\r
591              (sizeof (png_dsortp))));\r
592 \r
593          num_new_palette = num_palette;\r
594 \r
595          /* Initial wild guess at how far apart the farthest pixel\r
596           * pair we will be eliminating will be.  Larger\r
597           * numbers mean more areas will be allocated, Smaller\r
598           * numbers run the risk of not saving enough data, and\r
599           * having to do this all over again.\r
600           *\r
601           * I have not done extensive checking on this number.\r
602           */\r
603          max_d = 96;\r
604 \r
605          while (num_new_palette > maximum_colors)\r
606          {\r
607             for (i = 0; i < num_new_palette - 1; i++)\r
608             {\r
609                int j;\r
610 \r
611                for (j = i + 1; j < num_new_palette; j++)\r
612                {\r
613                   int d;\r
614 \r
615                   d = PNG_COLOR_DIST(palette[i], palette[j]);\r
616 \r
617                   if (d <= max_d)\r
618                   {\r
619 \r
620                      t = (png_dsortp)png_malloc_warn(png_ptr,\r
621                          (png_uint_32)(sizeof (png_dsort)));\r
622 \r
623                      if (t == NULL)\r
624                          break;\r
625 \r
626                      t->next = hash[d];\r
627                      t->left = (png_byte)i;\r
628                      t->right = (png_byte)j;\r
629                      hash[d] = t;\r
630                   }\r
631                }\r
632                if (t == NULL)\r
633                   break;\r
634             }\r
635 \r
636             if (t != NULL)\r
637             for (i = 0; i <= max_d; i++)\r
638             {\r
639                if (hash[i] != NULL)\r
640                {\r
641                   png_dsortp p;\r
642 \r
643                   for (p = hash[i]; p; p = p->next)\r
644                   {\r
645                      if ((int)png_ptr->index_to_palette[p->left]\r
646                          < num_new_palette &&\r
647                          (int)png_ptr->index_to_palette[p->right]\r
648                          < num_new_palette)\r
649                      {\r
650                         int j, next_j;\r
651 \r
652                         if (num_new_palette & 0x01)\r
653                         {\r
654                            j = p->left;\r
655                            next_j = p->right;\r
656                         }\r
657                         else\r
658                         {\r
659                            j = p->right;\r
660                            next_j = p->left;\r
661                         }\r
662 \r
663                         num_new_palette--;\r
664                         palette[png_ptr->index_to_palette[j]]\r
665                             = palette[num_new_palette];\r
666                         if (!full_quantize)\r
667                         {\r
668                            int k;\r
669 \r
670                            for (k = 0; k < num_palette; k++)\r
671                            {\r
672                               if (png_ptr->quantize_index[k] ==\r
673                                   png_ptr->index_to_palette[j])\r
674                                  png_ptr->quantize_index[k] =\r
675                                      png_ptr->index_to_palette[next_j];\r
676 \r
677                               if ((int)png_ptr->quantize_index[k] ==\r
678                                   num_new_palette)\r
679                                  png_ptr->quantize_index[k] =\r
680                                      png_ptr->index_to_palette[j];\r
681                            }\r
682                         }\r
683 \r
684                         png_ptr->index_to_palette[png_ptr->palette_to_index\r
685                             [num_new_palette]] = png_ptr->index_to_palette[j];\r
686 \r
687                         png_ptr->palette_to_index[png_ptr->index_to_palette[j]]\r
688                             = png_ptr->palette_to_index[num_new_palette];\r
689 \r
690                         png_ptr->index_to_palette[j] =\r
691                             (png_byte)num_new_palette;\r
692 \r
693                         png_ptr->palette_to_index[num_new_palette] =\r
694                             (png_byte)j;\r
695                      }\r
696                      if (num_new_palette <= maximum_colors)\r
697                         break;\r
698                   }\r
699                   if (num_new_palette <= maximum_colors)\r
700                      break;\r
701                }\r
702             }\r
703 \r
704             for (i = 0; i < 769; i++)\r
705             {\r
706                if (hash[i] != NULL)\r
707                {\r
708                   png_dsortp p = hash[i];\r
709                   while (p)\r
710                   {\r
711                      t = p->next;\r
712                      png_free(png_ptr, p);\r
713                      p = t;\r
714                   }\r
715                }\r
716                hash[i] = 0;\r
717             }\r
718             max_d += 96;\r
719          }\r
720          png_free(png_ptr, hash);\r
721          png_free(png_ptr, png_ptr->palette_to_index);\r
722          png_free(png_ptr, png_ptr->index_to_palette);\r
723          png_ptr->palette_to_index = NULL;\r
724          png_ptr->index_to_palette = NULL;\r
725       }\r
726       num_palette = maximum_colors;\r
727    }\r
728    if (png_ptr->palette == NULL)\r
729    {\r
730       png_ptr->palette = palette;\r
731    }\r
732    png_ptr->num_palette = (png_uint_16)num_palette;\r
733 \r
734    if (full_quantize)\r
735    {\r
736       int i;\r
737       png_bytep distance;\r
738       int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +\r
739           PNG_QUANTIZE_BLUE_BITS;\r
740       int num_red = (1 << PNG_QUANTIZE_RED_BITS);\r
741       int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);\r
742       int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);\r
743       png_size_t num_entries = ((png_size_t)1 << total_bits);\r
744 \r
745       png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,\r
746           (png_uint_32)(num_entries * (sizeof (png_byte))));\r
747 \r
748       distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *\r
749           (sizeof (png_byte))));\r
750 \r
751       memset(distance, 0xff, num_entries * (sizeof (png_byte)));\r
752 \r
753       for (i = 0; i < num_palette; i++)\r
754       {\r
755          int ir, ig, ib;\r
756          int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));\r
757          int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));\r
758          int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));\r
759 \r
760          for (ir = 0; ir < num_red; ir++)\r
761          {\r
762             /* int dr = abs(ir - r); */\r
763             int dr = ((ir > r) ? ir - r : r - ir);\r
764             int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +\r
765                 PNG_QUANTIZE_GREEN_BITS));\r
766 \r
767             for (ig = 0; ig < num_green; ig++)\r
768             {\r
769                /* int dg = abs(ig - g); */\r
770                int dg = ((ig > g) ? ig - g : g - ig);\r
771                int dt = dr + dg;\r
772                int dm = ((dr > dg) ? dr : dg);\r
773                int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);\r
774 \r
775                for (ib = 0; ib < num_blue; ib++)\r
776                {\r
777                   int d_index = index_g | ib;\r
778                   /* int db = abs(ib - b); */\r
779                   int db = ((ib > b) ? ib - b : b - ib);\r
780                   int dmax = ((dm > db) ? dm : db);\r
781                   int d = dmax + dt + db;\r
782 \r
783                   if (d < (int)distance[d_index])\r
784                   {\r
785                      distance[d_index] = (png_byte)d;\r
786                      png_ptr->palette_lookup[d_index] = (png_byte)i;\r
787                   }\r
788                }\r
789             }\r
790          }\r
791       }\r
792 \r
793       png_free(png_ptr, distance);\r
794    }\r
795 }\r
796 #endif /* PNG_READ_QUANTIZE_SUPPORTED */\r
797 \r
798 #ifdef PNG_READ_GAMMA_SUPPORTED\r
799 void PNGFAPI\r
800 png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,\r
801    png_fixed_point file_gamma)\r
802 {\r
803    png_debug(1, "in png_set_gamma_fixed");\r
804 \r
805    if (!png_rtran_ok(png_ptr, 0))\r
806       return;\r
807 \r
808    /* New in libpng-1.5.4 - reserve particular negative values as flags. */\r
809    scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);\r
810    file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);\r
811 \r
812    /* Checking the gamma values for being >0 was added in 1.5.4 along with the\r
813     * premultiplied alpha support; this actually hides an undocumented feature\r
814     * of the previous implementation which allowed gamma processing to be\r
815     * disabled in background handling.  There is no evidence (so far) that this\r
816     * was being used; however, png_set_background itself accepted and must still\r
817     * accept '0' for the gamma value it takes, because it isn't always used.\r
818     *\r
819     * Since this is an API change (albeit a very minor one that removes an\r
820     * undocumented API feature) the following checks were only enabled in\r
821     * libpng-1.6.0.\r
822     */\r
823    if (file_gamma <= 0)\r
824       png_error(png_ptr, "invalid file gamma in png_set_gamma");\r
825 \r
826    if (scrn_gamma <= 0)\r
827       png_error(png_ptr, "invalid screen gamma in png_set_gamma");\r
828 \r
829    /* Set the gamma values unconditionally - this overrides the value in the PNG\r
830     * file if a gAMA chunk was present.  png_set_alpha_mode provides a\r
831     * different, easier, way to default the file gamma.\r
832     */\r
833    png_ptr->colorspace.gamma = file_gamma;\r
834    png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\r
835    png_ptr->screen_gamma = scrn_gamma;\r
836 }\r
837 \r
838 #  ifdef PNG_FLOATING_POINT_SUPPORTED\r
839 void PNGAPI\r
840 png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)\r
841 {\r
842    png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),\r
843       convert_gamma_value(png_ptr, file_gamma));\r
844 }\r
845 #  endif /* FLOATING_POINT_SUPPORTED */\r
846 #endif /* READ_GAMMA */\r
847 \r
848 #ifdef PNG_READ_EXPAND_SUPPORTED\r
849 /* Expand paletted images to RGB, expand grayscale images of\r
850  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks\r
851  * to alpha channels.\r
852  */\r
853 void PNGAPI\r
854 png_set_expand(png_structrp png_ptr)\r
855 {\r
856    png_debug(1, "in png_set_expand");\r
857 \r
858    if (!png_rtran_ok(png_ptr, 0))\r
859       return;\r
860 \r
861    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);\r
862 }\r
863 \r
864 /* GRR 19990627:  the following three functions currently are identical\r
865  *  to png_set_expand().  However, it is entirely reasonable that someone\r
866  *  might wish to expand an indexed image to RGB but *not* expand a single,\r
867  *  fully transparent palette entry to a full alpha channel--perhaps instead\r
868  *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace\r
869  *  the transparent color with a particular RGB value, or drop tRNS entirely.\r
870  *  IOW, a future version of the library may make the transformations flag\r
871  *  a bit more fine-grained, with separate bits for each of these three\r
872  *  functions.\r
873  *\r
874  *  More to the point, these functions make it obvious what libpng will be\r
875  *  doing, whereas "expand" can (and does) mean any number of things.\r
876  *\r
877  *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified\r
878  *  to expand only the sample depth but not to expand the tRNS to alpha\r
879  *  and its name was changed to png_set_expand_gray_1_2_4_to_8().\r
880  */\r
881 \r
882 /* Expand paletted images to RGB. */\r
883 void PNGAPI\r
884 png_set_palette_to_rgb(png_structrp png_ptr)\r
885 {\r
886    png_debug(1, "in png_set_palette_to_rgb");\r
887 \r
888    if (!png_rtran_ok(png_ptr, 0))\r
889       return;\r
890 \r
891    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);\r
892 }\r
893 \r
894 /* Expand grayscale images of less than 8-bit depth to 8 bits. */\r
895 void PNGAPI\r
896 png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)\r
897 {\r
898    png_debug(1, "in png_set_expand_gray_1_2_4_to_8");\r
899 \r
900    if (!png_rtran_ok(png_ptr, 0))\r
901       return;\r
902 \r
903    png_ptr->transformations |= PNG_EXPAND;\r
904 }\r
905 \r
906 /* Expand tRNS chunks to alpha channels. */\r
907 void PNGAPI\r
908 png_set_tRNS_to_alpha(png_structrp png_ptr)\r
909 {\r
910    png_debug(1, "in png_set_tRNS_to_alpha");\r
911 \r
912    if (!png_rtran_ok(png_ptr, 0))\r
913       return;\r
914 \r
915    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);\r
916 }\r
917 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */\r
918 \r
919 #ifdef PNG_READ_EXPAND_16_SUPPORTED\r
920 /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise\r
921  * it may not work correctly.)\r
922  */\r
923 void PNGAPI\r
924 png_set_expand_16(png_structrp png_ptr)\r
925 {\r
926    png_debug(1, "in png_set_expand_16");\r
927 \r
928    if (!png_rtran_ok(png_ptr, 0))\r
929       return;\r
930 \r
931    png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);\r
932 }\r
933 #endif\r
934 \r
935 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\r
936 void PNGAPI\r
937 png_set_gray_to_rgb(png_structrp png_ptr)\r
938 {\r
939    png_debug(1, "in png_set_gray_to_rgb");\r
940 \r
941    if (!png_rtran_ok(png_ptr, 0))\r
942       return;\r
943 \r
944    /* Because rgb must be 8 bits or more: */\r
945    png_set_expand_gray_1_2_4_to_8(png_ptr);\r
946    png_ptr->transformations |= PNG_GRAY_TO_RGB;\r
947 }\r
948 #endif\r
949 \r
950 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\r
951 void PNGFAPI\r
952 png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,\r
953     png_fixed_point red, png_fixed_point green)\r
954 {\r
955    png_debug(1, "in png_set_rgb_to_gray");\r
956 \r
957    /* Need the IHDR here because of the check on color_type below. */\r
958    /* TODO: fix this */\r
959    if (!png_rtran_ok(png_ptr, 1))\r
960       return;\r
961 \r
962    switch(error_action)\r
963    {\r
964       case PNG_ERROR_ACTION_NONE:\r
965          png_ptr->transformations |= PNG_RGB_TO_GRAY;\r
966          break;\r
967 \r
968       case PNG_ERROR_ACTION_WARN:\r
969          png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;\r
970          break;\r
971 \r
972       case PNG_ERROR_ACTION_ERROR:\r
973          png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;\r
974          break;\r
975 \r
976       default:\r
977          png_error(png_ptr, "invalid error action to rgb_to_gray");\r
978          break;\r
979    }\r
980 \r
981    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\r
982 #ifdef PNG_READ_EXPAND_SUPPORTED\r
983       png_ptr->transformations |= PNG_EXPAND;\r
984 #else\r
985    {\r
986       /* Make this an error in 1.6 because otherwise the application may assume\r
987        * that it just worked and get a memory overwrite.\r
988        */\r
989       png_error(png_ptr,\r
990         "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");\r
991 \r
992       /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */\r
993    }\r
994 #endif\r
995    {\r
996       if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)\r
997       {\r
998          png_uint_16 red_int, green_int;\r
999 \r
1000          /* NOTE: this calculation does not round, but this behavior is retained\r
1001           * for consistency, the inaccuracy is very small.  The code here always\r
1002           * overwrites the coefficients, regardless of whether they have been\r
1003           * defaulted or set already.\r
1004           */\r
1005          red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);\r
1006          green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);\r
1007 \r
1008          png_ptr->rgb_to_gray_red_coeff   = red_int;\r
1009          png_ptr->rgb_to_gray_green_coeff = green_int;\r
1010          png_ptr->rgb_to_gray_coefficients_set = 1;\r
1011       }\r
1012 \r
1013       else\r
1014       {\r
1015          if (red >= 0 && green >= 0)\r
1016             png_app_warning(png_ptr,\r
1017                "ignoring out of range rgb_to_gray coefficients");\r
1018 \r
1019          /* Use the defaults, from the cHRM chunk if set, else the historical\r
1020           * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See\r
1021           * png_do_rgb_to_gray for more discussion of the values.  In this case\r
1022           * the coefficients are not marked as 'set' and are not overwritten if\r
1023           * something has already provided a default.\r
1024           */\r
1025          if (png_ptr->rgb_to_gray_red_coeff == 0 &&\r
1026             png_ptr->rgb_to_gray_green_coeff == 0)\r
1027          {\r
1028             png_ptr->rgb_to_gray_red_coeff   = 6968;\r
1029             png_ptr->rgb_to_gray_green_coeff = 23434;\r
1030             /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */\r
1031          }\r
1032       }\r
1033    }\r
1034 }\r
1035 \r
1036 #ifdef PNG_FLOATING_POINT_SUPPORTED\r
1037 /* Convert a RGB image to a grayscale of the same width.  This allows us,\r
1038  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.\r
1039  */\r
1040 \r
1041 void PNGAPI\r
1042 png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,\r
1043    double green)\r
1044 {\r
1045    png_set_rgb_to_gray_fixed(png_ptr, error_action,\r
1046       png_fixed(png_ptr, red, "rgb to gray red coefficient"),\r
1047       png_fixed(png_ptr, green, "rgb to gray green coefficient"));\r
1048 }\r
1049 #endif /* FLOATING POINT */\r
1050 \r
1051 #endif /* RGB_TO_GRAY */\r
1052 \r
1053 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \\r
1054     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)\r
1055 void PNGAPI\r
1056 png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr\r
1057     read_user_transform_fn)\r
1058 {\r
1059    png_debug(1, "in png_set_read_user_transform_fn");\r
1060 \r
1061 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\r
1062    png_ptr->transformations |= PNG_USER_TRANSFORM;\r
1063    png_ptr->read_user_transform_fn = read_user_transform_fn;\r
1064 #endif\r
1065 }\r
1066 #endif\r
1067 \r
1068 #ifdef PNG_READ_TRANSFORMS_SUPPORTED\r
1069 #ifdef PNG_READ_GAMMA_SUPPORTED\r
1070 /* In the case of gamma transformations only do transformations on images where\r
1071  * the [file] gamma and screen_gamma are not close reciprocals, otherwise it\r
1072  * slows things down slightly, and also needlessly introduces small errors.\r
1073  */\r
1074 static int /* PRIVATE */\r
1075 png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)\r
1076 {\r
1077    /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma\r
1078     * correction as a difference of the overall transform from 1.0\r
1079     *\r
1080     * We want to compare the threshold with s*f - 1, if we get\r
1081     * overflow here it is because of wacky gamma values so we\r
1082     * turn on processing anyway.\r
1083     */\r
1084    png_fixed_point gtest;\r
1085    return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||\r
1086        png_gamma_significant(gtest);\r
1087 }\r
1088 #endif\r
1089 \r
1090 /* Initialize everything needed for the read.  This includes modifying\r
1091  * the palette.\r
1092  */\r
1093 \r
1094 /*For the moment 'png_init_palette_transformations' and\r
1095  * 'png_init_rgb_transformations' only do some flag canceling optimizations.\r
1096  * The intent is that these two routines should have palette or rgb operations\r
1097  * extracted from 'png_init_read_transformations'.\r
1098  */\r
1099 static void /* PRIVATE */\r
1100 png_init_palette_transformations(png_structrp png_ptr)\r
1101 {\r
1102    /* Called to handle the (input) palette case.  In png_do_read_transformations\r
1103     * the first step is to expand the palette if requested, so this code must\r
1104     * take care to only make changes that are invariant with respect to the\r
1105     * palette expansion, or only do them if there is no expansion.\r
1106     *\r
1107     * STRIP_ALPHA has already been handled in the caller (by setting num_trans\r
1108     * to 0.)\r
1109     */\r
1110    int input_has_alpha = 0;\r
1111    int input_has_transparency = 0;\r
1112 \r
1113    if (png_ptr->num_trans > 0)\r
1114    {\r
1115       int i;\r
1116 \r
1117       /* Ignore if all the entries are opaque (unlikely!) */\r
1118       for (i=0; i<png_ptr->num_trans; ++i)\r
1119          if (png_ptr->trans_alpha[i] == 255)\r
1120             continue;\r
1121          else if (png_ptr->trans_alpha[i] == 0)\r
1122             input_has_transparency = 1;\r
1123          else\r
1124             input_has_alpha = 1;\r
1125    }\r
1126 \r
1127    /* If no alpha we can optimize. */\r
1128    if (!input_has_alpha)\r
1129    {\r
1130       /* Any alpha means background and associative alpha processing is\r
1131        * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA\r
1132        * and ENCODE_ALPHA are irrelevant.\r
1133        */\r
1134       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
1135       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
1136 \r
1137       if (!input_has_transparency)\r
1138          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);\r
1139    }\r
1140 \r
1141 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)\r
1142    /* png_set_background handling - deals with the complexity of whether the\r
1143     * background color is in the file format or the screen format in the case\r
1144     * where an 'expand' will happen.\r
1145     */\r
1146 \r
1147    /* The following code cannot be entered in the alpha pre-multiplication case\r
1148     * because PNG_BACKGROUND_EXPAND is cancelled below.\r
1149     */\r
1150    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&\r
1151        (png_ptr->transformations & PNG_EXPAND))\r
1152    {\r
1153       {\r
1154          png_ptr->background.red   =\r
1155              png_ptr->palette[png_ptr->background.index].red;\r
1156          png_ptr->background.green =\r
1157              png_ptr->palette[png_ptr->background.index].green;\r
1158          png_ptr->background.blue  =\r
1159              png_ptr->palette[png_ptr->background.index].blue;\r
1160 \r
1161 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\r
1162         if (png_ptr->transformations & PNG_INVERT_ALPHA)\r
1163         {\r
1164            if (!(png_ptr->transformations & PNG_EXPAND_tRNS))\r
1165            {\r
1166               /* Invert the alpha channel (in tRNS) unless the pixels are\r
1167                * going to be expanded, in which case leave it for later\r
1168                */\r
1169               int i, istop = png_ptr->num_trans;\r
1170 \r
1171               for (i=0; i<istop; i++)\r
1172                  png_ptr->trans_alpha[i] = (png_byte)(255 -\r
1173                     png_ptr->trans_alpha[i]);\r
1174            }\r
1175         }\r
1176 #endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */\r
1177       }\r
1178    } /* background expand and (therefore) no alpha association. */\r
1179 #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */\r
1180 }\r
1181 \r
1182 static void /* PRIVATE */\r
1183 png_init_rgb_transformations(png_structrp png_ptr)\r
1184 {\r
1185    /* Added to libpng-1.5.4: check the color type to determine whether there\r
1186     * is any alpha or transparency in the image and simply cancel the\r
1187     * background and alpha mode stuff if there isn't.\r
1188     */\r
1189    int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;\r
1190    int input_has_transparency = png_ptr->num_trans > 0;\r
1191 \r
1192    /* If no alpha we can optimize. */\r
1193    if (!input_has_alpha)\r
1194    {\r
1195       /* Any alpha means background and associative alpha processing is\r
1196        * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA\r
1197        * and ENCODE_ALPHA are irrelevant.\r
1198        */\r
1199 #     ifdef PNG_READ_ALPHA_MODE_SUPPORTED\r
1200          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
1201          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
1202 #     endif\r
1203 \r
1204       if (!input_has_transparency)\r
1205          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);\r
1206    }\r
1207 \r
1208 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)\r
1209    /* png_set_background handling - deals with the complexity of whether the\r
1210     * background color is in the file format or the screen format in the case\r
1211     * where an 'expand' will happen.\r
1212     */\r
1213 \r
1214    /* The following code cannot be entered in the alpha pre-multiplication case\r
1215     * because PNG_BACKGROUND_EXPAND is cancelled below.\r
1216     */\r
1217    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&\r
1218        (png_ptr->transformations & PNG_EXPAND) &&\r
1219        !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))\r
1220        /* i.e., GRAY or GRAY_ALPHA */\r
1221    {\r
1222       {\r
1223          /* Expand background and tRNS chunks */\r
1224          int gray = png_ptr->background.gray;\r
1225          int trans_gray = png_ptr->trans_color.gray;\r
1226 \r
1227          switch (png_ptr->bit_depth)\r
1228          {\r
1229             case 1:\r
1230                gray *= 0xff;\r
1231                trans_gray *= 0xff;\r
1232                break;\r
1233 \r
1234             case 2:\r
1235                gray *= 0x55;\r
1236                trans_gray *= 0x55;\r
1237                break;\r
1238 \r
1239             case 4:\r
1240                gray *= 0x11;\r
1241                trans_gray *= 0x11;\r
1242                break;\r
1243 \r
1244             default:\r
1245 \r
1246             case 8:\r
1247                /* FALL THROUGH (Already 8 bits) */\r
1248 \r
1249             case 16:\r
1250                /* Already a full 16 bits */\r
1251                break;\r
1252          }\r
1253 \r
1254          png_ptr->background.red = png_ptr->background.green =\r
1255             png_ptr->background.blue = (png_uint_16)gray;\r
1256 \r
1257          if (!(png_ptr->transformations & PNG_EXPAND_tRNS))\r
1258          {\r
1259             png_ptr->trans_color.red = png_ptr->trans_color.green =\r
1260                png_ptr->trans_color.blue = (png_uint_16)trans_gray;\r
1261          }\r
1262       }\r
1263    } /* background expand and (therefore) no alpha association. */\r
1264 #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */\r
1265 }\r
1266 \r
1267 void /* PRIVATE */\r
1268 png_init_read_transformations(png_structrp png_ptr)\r
1269 {\r
1270    png_debug(1, "in png_init_read_transformations");\r
1271 \r
1272    /* This internal function is called from png_read_start_row in pngrutil.c\r
1273     * and it is called before the 'rowbytes' calculation is done, so the code\r
1274     * in here can change or update the transformations flags.\r
1275     *\r
1276     * First do updates that do not depend on the details of the PNG image data\r
1277     * being processed.\r
1278     */\r
1279 \r
1280 #ifdef PNG_READ_GAMMA_SUPPORTED\r
1281    /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds\r
1282     * png_set_alpha_mode and this is another source for a default file gamma so\r
1283     * the test needs to be performed later - here.  In addition prior to 1.5.4\r
1284     * the tests were repeated for the PALETTE color type here - this is no\r
1285     * longer necessary (and doesn't seem to have been necessary before.)\r
1286     */\r
1287    {\r
1288       /* The following temporary indicates if overall gamma correction is\r
1289        * required.\r
1290        */\r
1291       int gamma_correction = 0;\r
1292 \r
1293       if (png_ptr->colorspace.gamma != 0) /* has been set */\r
1294       {\r
1295          if (png_ptr->screen_gamma != 0) /* screen set too */\r
1296             gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,\r
1297                png_ptr->screen_gamma);\r
1298 \r
1299          else\r
1300             /* Assume the output matches the input; a long time default behavior\r
1301              * of libpng, although the standard has nothing to say about this.\r
1302              */\r
1303             png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);\r
1304       }\r
1305 \r
1306       else if (png_ptr->screen_gamma != 0)\r
1307          /* The converse - assume the file matches the screen, note that this\r
1308           * perhaps undesireable default can (from 1.5.4) be changed by calling\r
1309           * png_set_alpha_mode (even if the alpha handling mode isn't required\r
1310           * or isn't changed from the default.)\r
1311           */\r
1312          png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);\r
1313 \r
1314       else /* neither are set */\r
1315          /* Just in case the following prevents any processing - file and screen\r
1316           * are both assumed to be linear and there is no way to introduce a\r
1317           * third gamma value other than png_set_background with 'UNIQUE', and,\r
1318           * prior to 1.5.4\r
1319           */\r
1320          png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;\r
1321 \r
1322       /* We have a gamma value now. */\r
1323       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;\r
1324 \r
1325       /* Now turn the gamma transformation on or off as appropriate.  Notice\r
1326        * that PNG_GAMMA just refers to the file->screen correction.  Alpha\r
1327        * composition may independently cause gamma correction because it needs\r
1328        * linear data (e.g. if the file has a gAMA chunk but the screen gamma\r
1329        * hasn't been specified.)  In any case this flag may get turned off in\r
1330        * the code immediately below if the transform can be handled outside the\r
1331        * row loop.\r
1332        */\r
1333       if (gamma_correction)\r
1334          png_ptr->transformations |= PNG_GAMMA;\r
1335 \r
1336       else\r
1337          png_ptr->transformations &= ~PNG_GAMMA;\r
1338    }\r
1339 #endif\r
1340 \r
1341    /* Certain transformations have the effect of preventing other\r
1342     * transformations that happen afterward in png_do_read_transformations,\r
1343     * resolve the interdependencies here.  From the code of\r
1344     * png_do_read_transformations the order is:\r
1345     *\r
1346     *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)\r
1347     *  2) PNG_STRIP_ALPHA (if no compose)\r
1348     *  3) PNG_RGB_TO_GRAY\r
1349     *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY\r
1350     *  5) PNG_COMPOSE\r
1351     *  6) PNG_GAMMA\r
1352     *  7) PNG_STRIP_ALPHA (if compose)\r
1353     *  8) PNG_ENCODE_ALPHA\r
1354     *  9) PNG_SCALE_16_TO_8\r
1355     * 10) PNG_16_TO_8\r
1356     * 11) PNG_QUANTIZE (converts to palette)\r
1357     * 12) PNG_EXPAND_16\r
1358     * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY\r
1359     * 14) PNG_INVERT_MONO\r
1360     * 15) PNG_SHIFT\r
1361     * 16) PNG_PACK\r
1362     * 17) PNG_BGR\r
1363     * 18) PNG_PACKSWAP\r
1364     * 19) PNG_FILLER (includes PNG_ADD_ALPHA)\r
1365     * 20) PNG_INVERT_ALPHA\r
1366     * 21) PNG_SWAP_ALPHA\r
1367     * 22) PNG_SWAP_BYTES\r
1368     * 23) PNG_USER_TRANSFORM [must be last]\r
1369     */\r
1370 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\r
1371    if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&\r
1372       !(png_ptr->transformations & PNG_COMPOSE))\r
1373    {\r
1374       /* Stripping the alpha channel happens immediately after the 'expand'\r
1375        * transformations, before all other transformation, so it cancels out\r
1376        * the alpha handling.  It has the side effect negating the effect of\r
1377        * PNG_EXPAND_tRNS too:\r
1378        */\r
1379       png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |\r
1380          PNG_EXPAND_tRNS);\r
1381       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
1382 \r
1383       /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen\r
1384        * so transparency information would remain just so long as it wasn't\r
1385        * expanded.  This produces unexpected API changes if the set of things\r
1386        * that do PNG_EXPAND_tRNS changes (perfectly possible given the\r
1387        * documentation - which says ask for what you want, accept what you\r
1388        * get.)  This makes the behavior consistent from 1.5.4:\r
1389        */\r
1390       png_ptr->num_trans = 0;\r
1391    }\r
1392 #endif /* STRIP_ALPHA supported, no COMPOSE */\r
1393 \r
1394 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED\r
1395    /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA\r
1396     * settings will have no effect.\r
1397     */\r
1398    if (!png_gamma_significant(png_ptr->screen_gamma))\r
1399    {\r
1400       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;\r
1401       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;\r
1402    }\r
1403 #endif\r
1404 \r
1405 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\r
1406    /* Make sure the coefficients for the rgb to gray conversion are set\r
1407     * appropriately.\r
1408     */\r
1409    if (png_ptr->transformations & PNG_RGB_TO_GRAY)\r
1410       png_colorspace_set_rgb_coefficients(png_ptr);\r
1411 #endif\r
1412 \r
1413 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\r
1414 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)\r
1415    /* Detect gray background and attempt to enable optimization for\r
1416     * gray --> RGB case.\r
1417     *\r
1418     * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or\r
1419     * RGB_ALPHA (in which case need_expand is superfluous anyway), the\r
1420     * background color might actually be gray yet not be flagged as such.\r
1421     * This is not a problem for the current code, which uses\r
1422     * PNG_BACKGROUND_IS_GRAY only to decide when to do the\r
1423     * png_do_gray_to_rgb() transformation.\r
1424     *\r
1425     * TODO: this code needs to be revised to avoid the complexity and\r
1426     * interdependencies.  The color type of the background should be recorded in\r
1427     * png_set_background, along with the bit depth, then the code has a record\r
1428     * of exactly what color space the background is currently in.\r
1429     */\r
1430    if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)\r
1431    {\r
1432       /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if\r
1433        * the file was grayscale the background value is gray.\r
1434        */\r
1435       if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))\r
1436          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;\r
1437    }\r
1438 \r
1439    else if (png_ptr->transformations & PNG_COMPOSE)\r
1440    {\r
1441       /* PNG_COMPOSE: png_set_background was called with need_expand false,\r
1442        * so the color is in the color space of the output or png_set_alpha_mode\r
1443        * was called and the color is black.  Ignore RGB_TO_GRAY because that\r
1444        * happens before GRAY_TO_RGB.\r
1445        */\r
1446       if (png_ptr->transformations & PNG_GRAY_TO_RGB)\r
1447       {\r
1448          if (png_ptr->background.red == png_ptr->background.green &&\r
1449              png_ptr->background.red == png_ptr->background.blue)\r
1450          {\r
1451             png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;\r
1452             png_ptr->background.gray = png_ptr->background.red;\r
1453          }\r
1454       }\r
1455    }\r
1456 #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */\r
1457 #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */\r
1458 \r
1459    /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations\r
1460     * can be performed directly on the palette, and some (such as rgb to gray)\r
1461     * can be optimized inside the palette.  This is particularly true of the\r
1462     * composite (background and alpha) stuff, which can be pretty much all done\r
1463     * in the palette even if the result is expanded to RGB or gray afterward.\r
1464     *\r
1465     * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and\r
1466     * earlier and the palette stuff is actually handled on the first row.  This\r
1467     * leads to the reported bug that the palette returned by png_get_PLTE is not\r
1468     * updated.\r
1469     */\r
1470    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\r
1471       png_init_palette_transformations(png_ptr);\r
1472 \r
1473    else\r
1474       png_init_rgb_transformations(png_ptr);\r
1475 \r
1476 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \\r
1477    defined(PNG_READ_EXPAND_16_SUPPORTED)\r
1478    if ((png_ptr->transformations & PNG_EXPAND_16) &&\r
1479       (png_ptr->transformations & PNG_COMPOSE) &&\r
1480       !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&\r
1481       png_ptr->bit_depth != 16)\r
1482    {\r
1483       /* TODO: fix this.  Because the expand_16 operation is after the compose\r
1484        * handling the background color must be 8, not 16, bits deep, but the\r
1485        * application will supply a 16-bit value so reduce it here.\r
1486        *\r
1487        * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at\r
1488        * present, so that case is ok (until do_expand_16 is moved.)\r
1489        *\r
1490        * NOTE: this discards the low 16 bits of the user supplied background\r
1491        * color, but until expand_16 works properly there is no choice!\r
1492        */\r
1493 #     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))\r
1494       CHOP(png_ptr->background.red);\r
1495       CHOP(png_ptr->background.green);\r
1496       CHOP(png_ptr->background.blue);\r
1497       CHOP(png_ptr->background.gray);\r
1498 #     undef CHOP\r
1499    }\r
1500 #endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */\r
1501 \r
1502 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \\r
1503    (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \\r
1504    defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))\r
1505    if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&\r
1506       (png_ptr->transformations & PNG_COMPOSE) &&\r
1507       !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&\r
1508       png_ptr->bit_depth == 16)\r
1509    {\r
1510       /* On the other hand, if a 16-bit file is to be reduced to 8-bits per\r
1511        * component this will also happen after PNG_COMPOSE and so the background\r
1512        * color must be pre-expanded here.\r
1513        *\r
1514        * TODO: fix this too.\r
1515        */\r
1516       png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);\r
1517       png_ptr->background.green =\r
1518          (png_uint_16)(png_ptr->background.green * 257);\r
1519       png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);\r
1520       png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);\r
1521    }\r
1522 #endif\r
1523 \r
1524    /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the\r
1525     * background support (see the comments in scripts/pnglibconf.dfa), this\r
1526     * allows pre-multiplication of the alpha channel to be implemented as\r
1527     * compositing on black.  This is probably sub-optimal and has been done in\r
1528     * 1.5.4 betas simply to enable external critique and testing (i.e. to\r
1529     * implement the new API quickly, without lots of internal changes.)\r
1530     */\r
1531 \r
1532 #ifdef PNG_READ_GAMMA_SUPPORTED\r
1533 #  ifdef PNG_READ_BACKGROUND_SUPPORTED\r
1534       /* Includes ALPHA_MODE */\r
1535       png_ptr->background_1 = png_ptr->background;\r
1536 #  endif\r
1537 \r
1538    /* This needs to change - in the palette image case a whole set of tables are\r
1539     * built when it would be quicker to just calculate the correct value for\r
1540     * each palette entry directly.  Also, the test is too tricky - why check\r
1541     * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that\r
1542     * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the\r
1543     * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction\r
1544     * the gamma tables will not be built even if composition is required on a\r
1545     * gamma encoded value.\r
1546     *\r
1547     * In 1.5.4 this is addressed below by an additional check on the individual\r
1548     * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the\r
1549     * tables.\r
1550     */\r
1551    if ((png_ptr->transformations & PNG_GAMMA)\r
1552       || ((png_ptr->transformations & PNG_RGB_TO_GRAY)\r
1553          && (png_gamma_significant(png_ptr->colorspace.gamma) ||\r
1554             png_gamma_significant(png_ptr->screen_gamma)))\r
1555       || ((png_ptr->transformations & PNG_COMPOSE)\r
1556          && (png_gamma_significant(png_ptr->colorspace.gamma)\r
1557             || png_gamma_significant(png_ptr->screen_gamma)\r
1558 #  ifdef PNG_READ_BACKGROUND_SUPPORTED\r
1559             || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE\r
1560                && png_gamma_significant(png_ptr->background_gamma))\r
1561 #  endif\r
1562       )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)\r
1563          && png_gamma_significant(png_ptr->screen_gamma))\r
1564       )\r
1565    {\r
1566       png_build_gamma_table(png_ptr, png_ptr->bit_depth);\r
1567 \r
1568 #ifdef PNG_READ_BACKGROUND_SUPPORTED\r
1569       if (png_ptr->transformations & PNG_COMPOSE)\r
1570       {\r
1571          /* Issue a warning about this combination: because RGB_TO_GRAY is\r
1572           * optimized to do the gamma transform if present yet do_background has\r
1573           * to do the same thing if both options are set a\r
1574           * double-gamma-correction happens.  This is true in all versions of\r
1575           * libpng to date.\r
1576           */\r
1577          if (png_ptr->transformations & PNG_RGB_TO_GRAY)\r
1578             png_warning(png_ptr,\r
1579                "libpng does not support gamma+background+rgb_to_gray");\r
1580 \r
1581          if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\r
1582          {\r
1583             /* We don't get to here unless there is a tRNS chunk with non-opaque\r
1584              * entries - see the checking code at the start of this function.\r
1585              */\r
1586             png_color back, back_1;\r
1587             png_colorp palette = png_ptr->palette;\r
1588             int num_palette = png_ptr->num_palette;\r
1589             int i;\r
1590             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)\r
1591             {\r
1592 \r
1593                back.red = png_ptr->gamma_table[png_ptr->background.red];\r
1594                back.green = png_ptr->gamma_table[png_ptr->background.green];\r
1595                back.blue = png_ptr->gamma_table[png_ptr->background.blue];\r
1596 \r
1597                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];\r
1598                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];\r
1599                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];\r
1600             }\r
1601             else\r
1602             {\r
1603                png_fixed_point g, gs;\r
1604 \r
1605                switch (png_ptr->background_gamma_type)\r
1606                {\r
1607                   case PNG_BACKGROUND_GAMMA_SCREEN:\r
1608                      g = (png_ptr->screen_gamma);\r
1609                      gs = PNG_FP_1;\r
1610                      break;\r
1611 \r
1612                   case PNG_BACKGROUND_GAMMA_FILE:\r
1613                      g = png_reciprocal(png_ptr->colorspace.gamma);\r
1614                      gs = png_reciprocal2(png_ptr->colorspace.gamma,\r
1615                         png_ptr->screen_gamma);\r
1616                      break;\r
1617 \r
1618                   case PNG_BACKGROUND_GAMMA_UNIQUE:\r
1619                      g = png_reciprocal(png_ptr->background_gamma);\r
1620                      gs = png_reciprocal2(png_ptr->background_gamma,\r
1621                         png_ptr->screen_gamma);\r
1622                      break;\r
1623                   default:\r
1624                      g = PNG_FP_1;    /* back_1 */\r
1625                      gs = PNG_FP_1;   /* back */\r
1626                      break;\r
1627                }\r
1628 \r
1629                if (png_gamma_significant(gs))\r
1630                {\r
1631                   back.red = png_gamma_8bit_correct(png_ptr->background.red,\r
1632                       gs);\r
1633                   back.green = png_gamma_8bit_correct(png_ptr->background.green,\r
1634                       gs);\r
1635                   back.blue = png_gamma_8bit_correct(png_ptr->background.blue,\r
1636                       gs);\r
1637                }\r
1638 \r
1639                else\r
1640                {\r
1641                   back.red   = (png_byte)png_ptr->background.red;\r
1642                   back.green = (png_byte)png_ptr->background.green;\r
1643                   back.blue  = (png_byte)png_ptr->background.blue;\r
1644                }\r
1645 \r
1646                if (png_gamma_significant(g))\r
1647                {\r
1648                   back_1.red = png_gamma_8bit_correct(png_ptr->background.red,\r
1649                      g);\r
1650                   back_1.green = png_gamma_8bit_correct(\r
1651                      png_ptr->background.green, g);\r
1652                   back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,\r
1653                      g);\r
1654                }\r
1655 \r
1656                else\r
1657                {\r
1658                   back_1.red   = (png_byte)png_ptr->background.red;\r
1659                   back_1.green = (png_byte)png_ptr->background.green;\r
1660                   back_1.blue  = (png_byte)png_ptr->background.blue;\r
1661                }\r
1662             }\r
1663 \r
1664             for (i = 0; i < num_palette; i++)\r
1665             {\r
1666                if (i < (int)png_ptr->num_trans &&\r
1667                    png_ptr->trans_alpha[i] != 0xff)\r
1668                {\r
1669                   if (png_ptr->trans_alpha[i] == 0)\r
1670                   {\r
1671                      palette[i] = back;\r
1672                   }\r
1673                   else /* if (png_ptr->trans_alpha[i] != 0xff) */\r
1674                   {\r
1675                      png_byte v, w;\r
1676 \r
1677                      v = png_ptr->gamma_to_1[palette[i].red];\r
1678                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);\r
1679                      palette[i].red = png_ptr->gamma_from_1[w];\r
1680 \r
1681                      v = png_ptr->gamma_to_1[palette[i].green];\r
1682                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);\r
1683                      palette[i].green = png_ptr->gamma_from_1[w];\r
1684 \r
1685                      v = png_ptr->gamma_to_1[palette[i].blue];\r
1686                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);\r
1687                      palette[i].blue = png_ptr->gamma_from_1[w];\r
1688                   }\r
1689                }\r
1690                else\r
1691                {\r
1692                   palette[i].red = png_ptr->gamma_table[palette[i].red];\r
1693                   palette[i].green = png_ptr->gamma_table[palette[i].green];\r
1694                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];\r
1695                }\r
1696             }\r
1697 \r
1698             /* Prevent the transformations being done again.\r
1699              *\r
1700              * NOTE: this is highly dubious; it removes the transformations in\r
1701              * place.  This seems inconsistent with the general treatment of the\r
1702              * transformations elsewhere.\r
1703              */\r
1704             png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);\r
1705          } /* color_type == PNG_COLOR_TYPE_PALETTE */\r
1706 \r
1707          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */\r
1708          else /* color_type != PNG_COLOR_TYPE_PALETTE */\r
1709          {\r
1710             int gs_sig, g_sig;\r
1711             png_fixed_point g = PNG_FP_1;  /* Correction to linear */\r
1712             png_fixed_point gs = PNG_FP_1; /* Correction to screen */\r
1713 \r
1714             switch (png_ptr->background_gamma_type)\r
1715             {\r
1716                case PNG_BACKGROUND_GAMMA_SCREEN:\r
1717                   g = png_ptr->screen_gamma;\r
1718                   /* gs = PNG_FP_1; */\r
1719                   break;\r
1720 \r
1721                case PNG_BACKGROUND_GAMMA_FILE:\r
1722                   g = png_reciprocal(png_ptr->colorspace.gamma);\r
1723                   gs = png_reciprocal2(png_ptr->colorspace.gamma,\r
1724                      png_ptr->screen_gamma);\r
1725                   break;\r
1726 \r
1727                case PNG_BACKGROUND_GAMMA_UNIQUE:\r
1728                   g = png_reciprocal(png_ptr->background_gamma);\r
1729                   gs = png_reciprocal2(png_ptr->background_gamma,\r
1730                       png_ptr->screen_gamma);\r
1731                   break;\r
1732 \r
1733                default:\r
1734                   png_error(png_ptr, "invalid background gamma type");\r
1735             }\r
1736 \r
1737             g_sig = png_gamma_significant(g);\r
1738             gs_sig = png_gamma_significant(gs);\r
1739 \r
1740             if (g_sig)\r
1741                png_ptr->background_1.gray = png_gamma_correct(png_ptr,\r
1742                    png_ptr->background.gray, g);\r
1743 \r
1744             if (gs_sig)\r
1745                png_ptr->background.gray = png_gamma_correct(png_ptr,\r
1746                    png_ptr->background.gray, gs);\r
1747 \r
1748             if ((png_ptr->background.red != png_ptr->background.green) ||\r
1749                 (png_ptr->background.red != png_ptr->background.blue) ||\r
1750                 (png_ptr->background.red != png_ptr->background.gray))\r
1751             {\r
1752                /* RGB or RGBA with color background */\r
1753                if (g_sig)\r
1754                {\r
1755                   png_ptr->background_1.red = png_gamma_correct(png_ptr,\r
1756                       png_ptr->background.red, g);\r
1757 \r
1758                   png_ptr->background_1.green = png_gamma_correct(png_ptr,\r
1759                       png_ptr->background.green, g);\r
1760 \r
1761                   png_ptr->background_1.blue = png_gamma_correct(png_ptr,\r
1762                       png_ptr->background.blue, g);\r
1763                }\r
1764 \r
1765                if (gs_sig)\r
1766                {\r
1767                   png_ptr->background.red = png_gamma_correct(png_ptr,\r
1768                       png_ptr->background.red, gs);\r
1769 \r
1770                   png_ptr->background.green = png_gamma_correct(png_ptr,\r
1771                       png_ptr->background.green, gs);\r
1772 \r
1773                   png_ptr->background.blue = png_gamma_correct(png_ptr,\r
1774                       png_ptr->background.blue, gs);\r
1775                }\r
1776             }\r
1777 \r
1778             else\r
1779             {\r
1780                /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */\r
1781                png_ptr->background_1.red = png_ptr->background_1.green\r
1782                    = png_ptr->background_1.blue = png_ptr->background_1.gray;\r
1783 \r
1784                png_ptr->background.red = png_ptr->background.green\r
1785                    = png_ptr->background.blue = png_ptr->background.gray;\r
1786             }\r
1787 \r
1788             /* The background is now in screen gamma: */\r
1789             png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;\r
1790          } /* color_type != PNG_COLOR_TYPE_PALETTE */\r
1791       }/* png_ptr->transformations & PNG_BACKGROUND */\r
1792 \r
1793       else\r
1794       /* Transformation does not include PNG_BACKGROUND */\r
1795 #endif /* PNG_READ_BACKGROUND_SUPPORTED */\r
1796       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE\r
1797 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\r
1798          /* RGB_TO_GRAY needs to have non-gamma-corrected values! */\r
1799          && ((png_ptr->transformations & PNG_EXPAND) == 0 ||\r
1800          (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)\r
1801 #endif\r
1802          )\r
1803       {\r
1804          png_colorp palette = png_ptr->palette;\r
1805          int num_palette = png_ptr->num_palette;\r
1806          int i;\r
1807 \r
1808          /* NOTE: there are other transformations that should probably be in\r
1809           * here too.\r
1810           */\r
1811          for (i = 0; i < num_palette; i++)\r
1812          {\r
1813             palette[i].red = png_ptr->gamma_table[palette[i].red];\r
1814             palette[i].green = png_ptr->gamma_table[palette[i].green];\r
1815             palette[i].blue = png_ptr->gamma_table[palette[i].blue];\r
1816          }\r
1817 \r
1818          /* Done the gamma correction. */\r
1819          png_ptr->transformations &= ~PNG_GAMMA;\r
1820       } /* color_type == PALETTE && !PNG_BACKGROUND transformation */\r
1821    }\r
1822 #ifdef PNG_READ_BACKGROUND_SUPPORTED\r
1823    else\r
1824 #endif\r
1825 #endif /* PNG_READ_GAMMA_SUPPORTED */\r
1826 \r
1827 #ifdef PNG_READ_BACKGROUND_SUPPORTED\r
1828    /* No GAMMA transformation (see the hanging else 4 lines above) */\r
1829    if ((png_ptr->transformations & PNG_COMPOSE) &&\r
1830        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))\r
1831    {\r
1832       int i;\r
1833       int istop = (int)png_ptr->num_trans;\r
1834       png_color back;\r
1835       png_colorp palette = png_ptr->palette;\r
1836 \r
1837       back.red   = (png_byte)png_ptr->background.red;\r
1838       back.green = (png_byte)png_ptr->background.green;\r
1839       back.blue  = (png_byte)png_ptr->background.blue;\r
1840 \r
1841       for (i = 0; i < istop; i++)\r
1842       {\r
1843          if (png_ptr->trans_alpha[i] == 0)\r
1844          {\r
1845             palette[i] = back;\r
1846          }\r
1847 \r
1848          else if (png_ptr->trans_alpha[i] != 0xff)\r
1849          {\r
1850             /* The png_composite() macro is defined in png.h */\r
1851             png_composite(palette[i].red, palette[i].red,\r
1852                 png_ptr->trans_alpha[i], back.red);\r
1853 \r
1854             png_composite(palette[i].green, palette[i].green,\r
1855                 png_ptr->trans_alpha[i], back.green);\r
1856 \r
1857             png_composite(palette[i].blue, palette[i].blue,\r
1858                 png_ptr->trans_alpha[i], back.blue);\r
1859          }\r
1860       }\r
1861 \r
1862       png_ptr->transformations &= ~PNG_COMPOSE;\r
1863           \r
1864           //png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; /* Add by Sunliang.Liu */\r
1865    }\r
1866 #endif /* PNG_READ_BACKGROUND_SUPPORTED */\r
1867 \r
1868 #ifdef PNG_READ_SHIFT_SUPPORTED\r
1869    if ((png_ptr->transformations & PNG_SHIFT) &&\r
1870       !(png_ptr->transformations & PNG_EXPAND) &&\r
1871        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))\r
1872    {\r
1873       int i;\r
1874       int istop = png_ptr->num_palette;\r
1875       int shift = 8 - png_ptr->sig_bit.red;\r
1876 \r
1877       png_ptr->transformations &= ~PNG_SHIFT;\r
1878 \r
1879       /* significant bits can be in the range 1 to 7 for a meaninful result, if\r
1880        * the number of significant bits is 0 then no shift is done (this is an\r
1881        * error condition which is silently ignored.)\r
1882        */\r
1883       if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)\r
1884       {\r
1885          int component = png_ptr->palette[i].red;\r
1886 \r
1887          component >>= shift;\r
1888          png_ptr->palette[i].red = (png_byte)component;\r
1889       }\r
1890 \r
1891       shift = 8 - png_ptr->sig_bit.green;\r
1892       if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)\r
1893       {\r
1894          int component = png_ptr->palette[i].green;\r
1895 \r
1896          component >>= shift;\r
1897          png_ptr->palette[i].green = (png_byte)component;\r
1898       }\r
1899 \r
1900       shift = 8 - png_ptr->sig_bit.blue;\r
1901       if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)\r
1902       {\r
1903          int component = png_ptr->palette[i].blue;\r
1904 \r
1905          component >>= shift;\r
1906          png_ptr->palette[i].blue = (png_byte)component;\r
1907       }\r
1908    }\r
1909 #endif  /* PNG_READ_SHIFT_SUPPORTED */\r
1910 }\r
1911 \r
1912 /* Modify the info structure to reflect the transformations.  The\r
1913  * info should be updated so a PNG file could be written with it,\r
1914  * assuming the transformations result in valid PNG data.\r
1915  */\r
1916 void /* PRIVATE */\r
1917 png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)\r
1918 {\r
1919    png_debug(1, "in png_read_transform_info");\r
1920 \r
1921 #ifdef PNG_READ_EXPAND_SUPPORTED\r
1922    if (png_ptr->transformations & PNG_EXPAND)\r
1923    {\r
1924       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\r
1925       {\r
1926          /* This check must match what actually happens in\r
1927           * png_do_expand_palette; if it ever checks the tRNS chunk to see if\r
1928           * it is all opaque we must do the same (at present it does not.)\r
1929           */\r
1930          if (png_ptr->num_trans > 0)\r
1931             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;\r
1932 \r
1933          else\r
1934             info_ptr->color_type = PNG_COLOR_TYPE_RGB;\r
1935 \r
1936          info_ptr->bit_depth = 8;\r
1937          info_ptr->num_trans = 0;\r
1938       }\r
1939       else\r
1940       {\r
1941          if (png_ptr->num_trans)\r
1942          {\r
1943             if (png_ptr->transformations & PNG_EXPAND_tRNS)\r
1944                info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;\r
1945          }\r
1946          if (info_ptr->bit_depth < 8)\r
1947             info_ptr->bit_depth = 8;\r
1948 \r
1949          info_ptr->num_trans = 0;\r
1950       }\r
1951    }\r
1952 #endif\r
1953 \r
1954 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\r
1955    defined(PNG_READ_ALPHA_MODE_SUPPORTED)\r
1956    /* The following is almost certainly wrong unless the background value is in\r
1957     * the screen space!\r
1958     */\r
1959    if (png_ptr->transformations & PNG_COMPOSE)\r
1960       info_ptr->background = png_ptr->background;\r
1961 #endif\r
1962 \r
1963 #ifdef PNG_READ_GAMMA_SUPPORTED\r
1964    /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),\r
1965     * however it seems that the code in png_init_read_transformations, which has\r
1966     * been called before this from png_read_update_info->png_read_start_row\r
1967     * sometimes does the gamma transform and cancels the flag.\r
1968     *\r
1969     * TODO: this looks wrong; the info_ptr should end up with a gamma equal to\r
1970     * the screen_gamma value.  The following probably results in weirdness if\r
1971     * the info_ptr is used by the app after the rows have been read.\r
1972     */\r
1973    info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;\r
1974 #endif\r
1975 \r
1976    if (info_ptr->bit_depth == 16)\r
1977    {\r
1978 #  ifdef PNG_READ_16BIT_SUPPORTED\r
1979 #     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\r
1980          if (png_ptr->transformations & PNG_SCALE_16_TO_8)\r
1981             info_ptr->bit_depth = 8;\r
1982 #     endif\r
1983 \r
1984 #     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\r
1985          if (png_ptr->transformations & PNG_16_TO_8)\r
1986             info_ptr->bit_depth = 8;\r
1987 #     endif\r
1988 \r
1989 #  else\r
1990       /* No 16 bit support: force chopping 16-bit input down to 8, in this case\r
1991        * the app program can chose if both APIs are available by setting the\r
1992        * correct scaling to use.\r
1993        */\r
1994 #     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\r
1995          /* For compatibility with previous versions use the strip method by\r
1996           * default.  This code works because if PNG_SCALE_16_TO_8 is already\r
1997           * set the code below will do that in preference to the chop.\r
1998           */\r
1999          png_ptr->transformations |= PNG_16_TO_8;\r
2000          info_ptr->bit_depth = 8;\r
2001 #     else\r
2002 \r
2003 #        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\r
2004             png_ptr->transformations |= PNG_SCALE_16_TO_8;\r
2005             info_ptr->bit_depth = 8;\r
2006 #        else\r
2007 \r
2008             CONFIGURATION ERROR: you must enable at least one 16 to 8 method\r
2009 #        endif\r
2010 #    endif\r
2011 #endif /* !READ_16BIT_SUPPORTED */\r
2012    }\r
2013 \r
2014 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\r
2015    if (png_ptr->transformations & PNG_GRAY_TO_RGB)\r
2016       info_ptr->color_type = (png_byte)(info_ptr->color_type |\r
2017          PNG_COLOR_MASK_COLOR);\r
2018 #endif\r
2019 \r
2020 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\r
2021    if (png_ptr->transformations & PNG_RGB_TO_GRAY)\r
2022       info_ptr->color_type = (png_byte)(info_ptr->color_type &\r
2023          ~PNG_COLOR_MASK_COLOR);\r
2024 #endif\r
2025 \r
2026 #ifdef PNG_READ_QUANTIZE_SUPPORTED\r
2027    if (png_ptr->transformations & PNG_QUANTIZE)\r
2028    {\r
2029       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||\r
2030           (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&\r
2031           png_ptr->palette_lookup && info_ptr->bit_depth == 8)\r
2032       {\r
2033          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;\r
2034       }\r
2035    }\r
2036 #endif\r
2037 \r
2038 #ifdef PNG_READ_EXPAND_16_SUPPORTED\r
2039    if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&\r
2040       info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)\r
2041    {\r
2042       info_ptr->bit_depth = 16;\r
2043    }\r
2044 #endif\r
2045 \r
2046 #ifdef PNG_READ_PACK_SUPPORTED\r
2047    if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))\r
2048       info_ptr->bit_depth = 8;\r
2049 #endif\r
2050 \r
2051    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)\r
2052       info_ptr->channels = 1;\r
2053 \r
2054    else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)\r
2055       info_ptr->channels = 3;\r
2056 \r
2057    else\r
2058       info_ptr->channels = 1;\r
2059 \r
2060 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\r
2061    if (png_ptr->transformations & PNG_STRIP_ALPHA)\r
2062    {\r
2063       info_ptr->color_type = (png_byte)(info_ptr->color_type &\r
2064          ~PNG_COLOR_MASK_ALPHA);\r
2065       info_ptr->num_trans = 0;\r
2066    }\r
2067 #endif\r
2068 \r
2069    if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)\r
2070       info_ptr->channels++;\r
2071 \r
2072 #ifdef PNG_READ_FILLER_SUPPORTED\r
2073    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */\r
2074    if ((png_ptr->transformations & PNG_FILLER) &&\r
2075        ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||\r
2076        (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))\r
2077    {\r
2078       info_ptr->channels++;\r
2079       /* If adding a true alpha channel not just filler */\r
2080       if (png_ptr->transformations & PNG_ADD_ALPHA)\r
2081          info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;\r
2082    }\r
2083 #endif\r
2084 \r
2085 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \\r
2086 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)\r
2087    if (png_ptr->transformations & PNG_USER_TRANSFORM)\r
2088    {\r
2089       if (info_ptr->bit_depth < png_ptr->user_transform_depth)\r
2090          info_ptr->bit_depth = png_ptr->user_transform_depth;\r
2091 \r
2092       if (info_ptr->channels < png_ptr->user_transform_channels)\r
2093          info_ptr->channels = png_ptr->user_transform_channels;\r
2094    }\r
2095 #endif\r
2096 \r
2097    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *\r
2098        info_ptr->bit_depth);\r
2099 \r
2100    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);\r
2101 \r
2102    /* Adding in 1.5.4: cache the above value in png_struct so that we can later\r
2103     * check in png_rowbytes that the user buffer won't get overwritten.  Note\r
2104     * that the field is not always set - if png_read_update_info isn't called\r
2105     * the application has to either not do any transforms or get the calculation\r
2106     * right itself.\r
2107     */\r
2108    png_ptr->info_rowbytes = info_ptr->rowbytes;\r
2109 \r
2110 #ifndef PNG_READ_EXPAND_SUPPORTED\r
2111    if (png_ptr)\r
2112       return;\r
2113 #endif\r
2114 }\r
2115 \r
2116 /* Transform the row.  The order of transformations is significant,\r
2117  * and is very touchy.  If you add a transformation, take care to\r
2118  * decide how it fits in with the other transformations here.\r
2119  */\r
2120 void /* PRIVATE */\r
2121 png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)\r
2122 {\r
2123    png_debug(1, "in png_do_read_transformations");\r
2124 \r
2125    if (png_ptr->row_buf == NULL)\r
2126    {\r
2127       /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this\r
2128        * error is incredibly rare and incredibly easy to debug without this\r
2129        * information.\r
2130        */\r
2131       png_error(png_ptr, "NULL row buffer");\r
2132    }\r
2133 \r
2134    /* The following is debugging; prior to 1.5.4 the code was never compiled in;\r
2135     * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro\r
2136     * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for\r
2137     * all transformations, however in practice the ROW_INIT always gets done on\r
2138     * demand, if necessary.\r
2139     */\r
2140    if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&\r
2141       !(png_ptr->flags & PNG_FLAG_ROW_INIT))\r
2142    {\r
2143       /* Application has failed to call either png_read_start_image() or\r
2144        * png_read_update_info() after setting transforms that expand pixels.\r
2145        * This check added to libpng-1.2.19 (but not enabled until 1.5.4).\r
2146        */\r
2147       png_error(png_ptr, "Uninitialized row");\r
2148    }\r
2149 \r
2150 #ifdef PNG_READ_EXPAND_SUPPORTED\r
2151    if (png_ptr->transformations & PNG_EXPAND)\r
2152    {\r
2153       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)\r
2154       {\r
2155          png_do_expand_palette(row_info, png_ptr->row_buf + 1,\r
2156              png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);\r
2157       }\r
2158 \r
2159       else\r
2160       {\r
2161          if (png_ptr->num_trans &&\r
2162              (png_ptr->transformations & PNG_EXPAND_tRNS))\r
2163             png_do_expand(row_info, png_ptr->row_buf + 1,\r
2164                 &(png_ptr->trans_color));\r
2165 \r
2166          else\r
2167             png_do_expand(row_info, png_ptr->row_buf + 1,\r
2168                 NULL);\r
2169       }\r
2170    }\r
2171 #endif\r
2172 \r
2173 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\r
2174    if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&\r
2175       !(png_ptr->transformations & PNG_COMPOSE) &&\r
2176       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\r
2177       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))\r
2178       png_do_strip_channel(row_info, png_ptr->row_buf + 1,\r
2179          0 /* at_start == false, because SWAP_ALPHA happens later */);\r
2180 #endif\r
2181 \r
2182 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\r
2183    if (png_ptr->transformations & PNG_RGB_TO_GRAY)\r
2184    {\r
2185       int rgb_error =\r
2186           png_do_rgb_to_gray(png_ptr, row_info,\r
2187               png_ptr->row_buf + 1);\r
2188 \r
2189       if (rgb_error)\r
2190       {\r
2191          png_ptr->rgb_to_gray_status=1;\r
2192          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==\r
2193              PNG_RGB_TO_GRAY_WARN)\r
2194             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");\r
2195 \r
2196          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==\r
2197              PNG_RGB_TO_GRAY_ERR)\r
2198             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");\r
2199       }\r
2200    }\r
2201 #endif\r
2202 \r
2203 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:\r
2204  *\r
2205  *   In most cases, the "simple transparency" should be done prior to doing\r
2206  *   gray-to-RGB, or you will have to test 3x as many bytes to check if a\r
2207  *   pixel is transparent.  You would also need to make sure that the\r
2208  *   transparency information is upgraded to RGB.\r
2209  *\r
2210  *   To summarize, the current flow is:\r
2211  *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite\r
2212  *                                   with background "in place" if transparent,\r
2213  *                                   convert to RGB if necessary\r
2214  *   - Gray + alpha -> composite with gray background and remove alpha bytes,\r
2215  *                                   convert to RGB if necessary\r
2216  *\r
2217  *   To support RGB backgrounds for gray images we need:\r
2218  *   - Gray + simple transparency -> convert to RGB + simple transparency,\r
2219  *                                   compare 3 or 6 bytes and composite with\r
2220  *                                   background "in place" if transparent\r
2221  *                                   (3x compare/pixel compared to doing\r
2222  *                                   composite with gray bkgrnd)\r
2223  *   - Gray + alpha -> convert to RGB + alpha, composite with background and\r
2224  *                                   remove alpha bytes (3x float\r
2225  *                                   operations/pixel compared with composite\r
2226  *                                   on gray background)\r
2227  *\r
2228  *  Greg's change will do this.  The reason it wasn't done before is for\r
2229  *  performance, as this increases the per-pixel operations.  If we would check\r
2230  *  in advance if the background was gray or RGB, and position the gray-to-RGB\r
2231  *  transform appropriately, then it would save a lot of work/time.\r
2232  */\r
2233 \r
2234 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\r
2235    /* If gray -> RGB, do so now only if background is non-gray; else do later\r
2236     * for performance reasons\r
2237     */\r
2238    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&\r
2239        !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))\r
2240       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);\r
2241 #endif\r
2242 \r
2243 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\r
2244    defined(PNG_READ_ALPHA_MODE_SUPPORTED)\r
2245    if (png_ptr->transformations & PNG_COMPOSE)\r
2246       png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);\r
2247 #endif\r
2248 \r
2249 #ifdef PNG_READ_GAMMA_SUPPORTED\r
2250    if ((png_ptr->transformations & PNG_GAMMA) &&\r
2251 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED\r
2252       /* Because RGB_TO_GRAY does the gamma transform. */\r
2253       !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&\r
2254 #endif\r
2255 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\\r
2256    defined(PNG_READ_ALPHA_MODE_SUPPORTED)\r
2257       /* Because PNG_COMPOSE does the gamma transform if there is something to\r
2258        * do (if there is an alpha channel or transparency.)\r
2259        */\r
2260        !((png_ptr->transformations & PNG_COMPOSE) &&\r
2261        ((png_ptr->num_trans != 0) ||\r
2262        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&\r
2263 #endif\r
2264       /* Because png_init_read_transformations transforms the palette, unless\r
2265        * RGB_TO_GRAY will do the transform.\r
2266        */\r
2267        (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))\r
2268       png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);\r
2269 #endif\r
2270 \r
2271 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED\r
2272    if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&\r
2273       (png_ptr->transformations & PNG_COMPOSE) &&\r
2274       (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||\r
2275       row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))\r
2276       png_do_strip_channel(row_info, png_ptr->row_buf + 1,\r
2277          0 /* at_start == false, because SWAP_ALPHA happens later */);\r
2278 #endif\r
2279 \r
2280 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED\r
2281    if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&\r
2282       (row_info->color_type & PNG_COLOR_MASK_ALPHA))\r
2283       png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);\r
2284 #endif\r
2285 \r
2286 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\r
2287    if (png_ptr->transformations & PNG_SCALE_16_TO_8)\r
2288       png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);\r
2289 #endif\r
2290 \r
2291 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\r
2292    /* There is no harm in doing both of these because only one has any effect,\r
2293     * by putting the 'scale' option first if the app asks for scale (either by\r
2294     * calling the API or in a TRANSFORM flag) this is what happens.\r
2295     */\r
2296    if (png_ptr->transformations & PNG_16_TO_8)\r
2297       png_do_chop(row_info, png_ptr->row_buf + 1);\r
2298 #endif\r
2299 \r
2300 #ifdef PNG_READ_QUANTIZE_SUPPORTED\r
2301    if (png_ptr->transformations & PNG_QUANTIZE)\r
2302    {\r
2303       png_do_quantize(row_info, png_ptr->row_buf + 1,\r
2304           png_ptr->palette_lookup, png_ptr->quantize_index);\r
2305 \r
2306       if (row_info->rowbytes == 0)\r
2307          png_error(png_ptr, "png_do_quantize returned rowbytes=0");\r
2308    }\r
2309 #endif /* PNG_READ_QUANTIZE_SUPPORTED */\r
2310 \r
2311 #ifdef PNG_READ_EXPAND_16_SUPPORTED\r
2312    /* Do the expansion now, after all the arithmetic has been done.  Notice\r
2313     * that previous transformations can handle the PNG_EXPAND_16 flag if this\r
2314     * is efficient (particularly true in the case of gamma correction, where\r
2315     * better accuracy results faster!)\r
2316     */\r
2317    if (png_ptr->transformations & PNG_EXPAND_16)\r
2318       png_do_expand_16(row_info, png_ptr->row_buf + 1);\r
2319 #endif\r
2320 \r
2321 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED\r
2322    /* NOTE: moved here in 1.5.4 (from much later in this list.) */\r
2323    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&\r
2324        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))\r
2325       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);\r
2326 #endif\r
2327 \r
2328 #ifdef PNG_READ_INVERT_SUPPORTED\r
2329    if (png_ptr->transformations & PNG_INVERT_MONO)\r
2330       png_do_invert(row_info, png_ptr->row_buf + 1);\r
2331 #endif\r
2332 \r
2333 #ifdef PNG_READ_SHIFT_SUPPORTED\r
2334    if (png_ptr->transformations & PNG_SHIFT)\r
2335       png_do_unshift(row_info, png_ptr->row_buf + 1,\r
2336           &(png_ptr->shift));\r
2337 #endif\r
2338 \r
2339 #ifdef PNG_READ_PACK_SUPPORTED\r
2340    if (png_ptr->transformations & PNG_PACK)\r
2341       png_do_unpack(row_info, png_ptr->row_buf + 1);\r
2342 #endif\r
2343 \r
2344 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED\r
2345    /* Added at libpng-1.5.10 */\r
2346    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&\r
2347        png_ptr->num_palette_max >= 0)\r
2348       png_do_check_palette_indexes(png_ptr, row_info);\r
2349 #endif\r
2350 \r
2351 #ifdef PNG_READ_BGR_SUPPORTED\r
2352    if (png_ptr->transformations & PNG_BGR)\r
2353       png_do_bgr(row_info, png_ptr->row_buf + 1);\r
2354 #endif\r
2355 \r
2356 #ifdef PNG_READ_PACKSWAP_SUPPORTED\r
2357    if (png_ptr->transformations & PNG_PACKSWAP)\r
2358       png_do_packswap(row_info, png_ptr->row_buf + 1);\r
2359 #endif\r
2360 \r
2361 #ifdef PNG_READ_FILLER_SUPPORTED\r
2362    if (png_ptr->transformations & PNG_FILLER)\r
2363       png_do_read_filler(row_info, png_ptr->row_buf + 1,\r
2364           (png_uint_32)png_ptr->filler, png_ptr->flags);\r
2365 #endif\r
2366 \r
2367 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\r
2368    if (png_ptr->transformations & PNG_INVERT_ALPHA)\r
2369       png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);\r
2370 #endif\r
2371 \r
2372 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\r
2373    if (png_ptr->transformations & PNG_SWAP_ALPHA)\r
2374       png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);\r
2375 #endif\r
2376 \r
2377 #ifdef PNG_READ_16BIT_SUPPORTED\r
2378 #ifdef PNG_READ_SWAP_SUPPORTED\r
2379    if (png_ptr->transformations & PNG_SWAP_BYTES)\r
2380       png_do_swap(row_info, png_ptr->row_buf + 1);\r
2381 #endif\r
2382 #endif\r
2383 \r
2384 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\r
2385    if (png_ptr->transformations & PNG_USER_TRANSFORM)\r
2386     {\r
2387       if (png_ptr->read_user_transform_fn != NULL)\r
2388          (*(png_ptr->read_user_transform_fn)) /* User read transform function */\r
2389              (png_ptr,     /* png_ptr */\r
2390              row_info,     /* row_info: */\r
2391                 /*  png_uint_32 width;       width of row */\r
2392                 /*  png_size_t rowbytes;     number of bytes in row */\r
2393                 /*  png_byte color_type;     color type of pixels */\r
2394                 /*  png_byte bit_depth;      bit depth of samples */\r
2395                 /*  png_byte channels;       number of channels (1-4) */\r
2396                 /*  png_byte pixel_depth;    bits per pixel (depth*channels) */\r
2397              png_ptr->row_buf + 1);    /* start of pixel data for row */\r
2398 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\r
2399       if (png_ptr->user_transform_depth)\r
2400          row_info->bit_depth = png_ptr->user_transform_depth;\r
2401 \r
2402       if (png_ptr->user_transform_channels)\r
2403          row_info->channels = png_ptr->user_transform_channels;\r
2404 #endif\r
2405       row_info->pixel_depth = (png_byte)(row_info->bit_depth *\r
2406           row_info->channels);\r
2407 \r
2408       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);\r
2409    }\r
2410 #endif\r
2411 }\r
2412 \r
2413 #ifdef PNG_READ_PACK_SUPPORTED\r
2414 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,\r
2415  * without changing the actual values.  Thus, if you had a row with\r
2416  * a bit depth of 1, you would end up with bytes that only contained\r
2417  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use\r
2418  * png_do_shift() after this.\r
2419  */\r
2420 void /* PRIVATE */\r
2421 png_do_unpack(png_row_infop row_info, png_bytep row)\r
2422 {\r
2423    png_debug(1, "in png_do_unpack");\r
2424 \r
2425    if (row_info->bit_depth < 8)\r
2426    {\r
2427       png_uint_32 i;\r
2428       png_uint_32 row_width=row_info->width;\r
2429 \r
2430       switch (row_info->bit_depth)\r
2431       {\r
2432          case 1:\r
2433          {\r
2434             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);\r
2435             png_bytep dp = row + (png_size_t)row_width - 1;\r
2436             png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);\r
2437             for (i = 0; i < row_width; i++)\r
2438             {\r
2439                *dp = (png_byte)((*sp >> shift) & 0x01);\r
2440 \r
2441                if (shift == 7)\r
2442                {\r
2443                   shift = 0;\r
2444                   sp--;\r
2445                }\r
2446 \r
2447                else\r
2448                   shift++;\r
2449 \r
2450                dp--;\r
2451             }\r
2452             break;\r
2453          }\r
2454 \r
2455          case 2:\r
2456          {\r
2457 \r
2458             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);\r
2459             png_bytep dp = row + (png_size_t)row_width - 1;\r
2460             png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);\r
2461             for (i = 0; i < row_width; i++)\r
2462             {\r
2463                *dp = (png_byte)((*sp >> shift) & 0x03);\r
2464 \r
2465                if (shift == 6)\r
2466                {\r
2467                   shift = 0;\r
2468                   sp--;\r
2469                }\r
2470 \r
2471                else\r
2472                   shift += 2;\r
2473 \r
2474                dp--;\r
2475             }\r
2476             break;\r
2477          }\r
2478 \r
2479          case 4:\r
2480          {\r
2481             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);\r
2482             png_bytep dp = row + (png_size_t)row_width - 1;\r
2483             png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);\r
2484             for (i = 0; i < row_width; i++)\r
2485             {\r
2486                *dp = (png_byte)((*sp >> shift) & 0x0f);\r
2487 \r
2488                if (shift == 4)\r
2489                {\r
2490                   shift = 0;\r
2491                   sp--;\r
2492                }\r
2493 \r
2494                else\r
2495                   shift = 4;\r
2496 \r
2497                dp--;\r
2498             }\r
2499             break;\r
2500          }\r
2501 \r
2502          default:\r
2503             break;\r
2504       }\r
2505       row_info->bit_depth = 8;\r
2506       row_info->pixel_depth = (png_byte)(8 * row_info->channels);\r
2507       row_info->rowbytes = row_width * row_info->channels;\r
2508    }\r
2509 }\r
2510 #endif\r
2511 \r
2512 #ifdef PNG_READ_SHIFT_SUPPORTED\r
2513 /* Reverse the effects of png_do_shift.  This routine merely shifts the\r
2514  * pixels back to their significant bits values.  Thus, if you have\r
2515  * a row of bit depth 8, but only 5 are significant, this will shift\r
2516  * the values back to 0 through 31.\r
2517  */\r
2518 void /* PRIVATE */\r
2519 png_do_unshift(png_row_infop row_info, png_bytep row,\r
2520     png_const_color_8p sig_bits)\r
2521 {\r
2522    int color_type;\r
2523 \r
2524    png_debug(1, "in png_do_unshift");\r
2525 \r
2526    /* The palette case has already been handled in the _init routine. */\r
2527    color_type = row_info->color_type;\r
2528 \r
2529    if (color_type != PNG_COLOR_TYPE_PALETTE)\r
2530    {\r
2531       int shift[4];\r
2532       int channels = 0;\r
2533       int bit_depth = row_info->bit_depth;\r
2534 \r
2535       if (color_type & PNG_COLOR_MASK_COLOR)\r
2536       {\r
2537          shift[channels++] = bit_depth - sig_bits->red;\r
2538          shift[channels++] = bit_depth - sig_bits->green;\r
2539          shift[channels++] = bit_depth - sig_bits->blue;\r
2540       }\r
2541 \r
2542       else\r
2543       {\r
2544          shift[channels++] = bit_depth - sig_bits->gray;\r
2545       }\r
2546 \r
2547       if (color_type & PNG_COLOR_MASK_ALPHA)\r
2548       {\r
2549          shift[channels++] = bit_depth - sig_bits->alpha;\r
2550       }\r
2551 \r
2552       {\r
2553          int c, have_shift;\r
2554 \r
2555          for (c = have_shift = 0; c < channels; ++c)\r
2556          {\r
2557             /* A shift of more than the bit depth is an error condition but it\r
2558              * gets ignored here.\r
2559              */\r
2560             if (shift[c] <= 0 || shift[c] >= bit_depth)\r
2561                shift[c] = 0;\r
2562 \r
2563             else\r
2564                have_shift = 1;\r
2565          }\r
2566 \r
2567          if (!have_shift)\r
2568             return;\r
2569       }\r
2570 \r
2571       switch (bit_depth)\r
2572       {\r
2573          default:\r
2574          /* Must be 1bpp gray: should not be here! */\r
2575             /* NOTREACHED */\r
2576             break;\r
2577 \r
2578          case 2:\r
2579          /* Must be 2bpp gray */\r
2580          /* assert(channels == 1 && shift[0] == 1) */\r
2581          {\r
2582             png_bytep bp = row;\r
2583             png_bytep bp_end = bp + row_info->rowbytes;\r
2584 \r
2585             while (bp < bp_end)\r
2586             {\r
2587                int b = (*bp >> 1) & 0x55;\r
2588                *bp++ = (png_byte)b;\r
2589             }\r
2590             break;\r
2591          }\r
2592 \r
2593          case 4:\r
2594          /* Must be 4bpp gray */\r
2595          /* assert(channels == 1) */\r
2596          {\r
2597             png_bytep bp = row;\r
2598             png_bytep bp_end = bp + row_info->rowbytes;\r
2599             int gray_shift = shift[0];\r
2600             int mask =  0xf >> gray_shift;\r
2601 \r
2602             mask |= mask << 4;\r
2603 \r
2604             while (bp < bp_end)\r
2605             {\r
2606                int b = (*bp >> gray_shift) & mask;\r
2607                *bp++ = (png_byte)b;\r
2608             }\r
2609             break;\r
2610          }\r
2611 \r
2612          case 8:\r
2613          /* Single byte components, G, GA, RGB, RGBA */\r
2614          {\r
2615             png_bytep bp = row;\r
2616             png_bytep bp_end = bp + row_info->rowbytes;\r
2617             int channel = 0;\r
2618 \r
2619             while (bp < bp_end)\r
2620             {\r
2621                int b = *bp >> shift[channel];\r
2622                if (++channel >= channels)\r
2623                   channel = 0;\r
2624                *bp++ = (png_byte)b;\r
2625             }\r
2626             break;\r
2627          }\r
2628 \r
2629 #ifdef PNG_READ_16BIT_SUPPORTED\r
2630          case 16:\r
2631          /* Double byte components, G, GA, RGB, RGBA */\r
2632          {\r
2633             png_bytep bp = row;\r
2634             png_bytep bp_end = bp + row_info->rowbytes;\r
2635             int channel = 0;\r
2636 \r
2637             while (bp < bp_end)\r
2638             {\r
2639                int value = (bp[0] << 8) + bp[1];\r
2640 \r
2641                value >>= shift[channel];\r
2642                if (++channel >= channels)\r
2643                   channel = 0;\r
2644                *bp++ = (png_byte)(value >> 8);\r
2645                *bp++ = (png_byte)(value & 0xff);\r
2646             }\r
2647             break;\r
2648          }\r
2649 #endif\r
2650       }\r
2651    }\r
2652 }\r
2653 #endif\r
2654 \r
2655 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED\r
2656 /* Scale rows of bit depth 16 down to 8 accurately */\r
2657 void /* PRIVATE */\r
2658 png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)\r
2659 {\r
2660    png_debug(1, "in png_do_scale_16_to_8");\r
2661 \r
2662    if (row_info->bit_depth == 16)\r
2663    {\r
2664       png_bytep sp = row; /* source */\r
2665       png_bytep dp = row; /* destination */\r
2666       png_bytep ep = sp + row_info->rowbytes; /* end+1 */\r
2667 \r
2668       while (sp < ep)\r
2669       {\r
2670          /* The input is an array of 16 bit components, these must be scaled to\r
2671           * 8 bits each.  For a 16 bit value V the required value (from the PNG\r
2672           * specification) is:\r
2673           *\r
2674           *    (V * 255) / 65535\r
2675           *\r
2676           * This reduces to round(V / 257), or floor((V + 128.5)/257)\r
2677           *\r
2678           * Represent V as the two byte value vhi.vlo.  Make a guess that the\r
2679           * result is the top byte of V, vhi, then the correction to this value\r
2680           * is:\r
2681           *\r
2682           *    error = floor(((V-vhi.vhi) + 128.5) / 257)\r
2683           *          = floor(((vlo-vhi) + 128.5) / 257)\r
2684           *\r
2685           * This can be approximated using integer arithmetic (and a signed\r
2686           * shift):\r
2687           *\r
2688           *    error = (vlo-vhi+128) >> 8;\r
2689           *\r
2690           * The approximate differs from the exact answer only when (vlo-vhi) is\r
2691           * 128; it then gives a correction of +1 when the exact correction is\r
2692           * 0.  This gives 128 errors.  The exact answer (correct for all 16 bit\r
2693           * input values) is:\r
2694           *\r
2695           *    error = (vlo-vhi+128)*65535 >> 24;\r
2696           *\r
2697           * An alternative arithmetic calculation which also gives no errors is:\r
2698           *\r
2699           *    (V * 255 + 32895) >> 16\r
2700           */\r
2701 \r
2702          png_int_32 tmp = *sp++; /* must be signed! */\r
2703          tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;\r
2704          *dp++ = (png_byte)tmp;\r
2705       }\r
2706 \r
2707       row_info->bit_depth = 8;\r
2708       row_info->pixel_depth = (png_byte)(8 * row_info->channels);\r
2709       row_info->rowbytes = row_info->width * row_info->channels;\r
2710    }\r
2711 }\r
2712 #endif\r
2713 \r
2714 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED\r
2715 void /* PRIVATE */\r
2716 /* Simply discard the low byte.  This was the default behavior prior\r
2717  * to libpng-1.5.4.\r
2718  */\r
2719 png_do_chop(png_row_infop row_info, png_bytep row)\r
2720 {\r
2721    png_debug(1, "in png_do_chop");\r
2722 \r
2723    if (row_info->bit_depth == 16)\r
2724    {\r
2725       png_bytep sp = row; /* source */\r
2726       png_bytep dp = row; /* destination */\r
2727       png_bytep ep = sp + row_info->rowbytes; /* end+1 */\r
2728 \r
2729       while (sp < ep)\r
2730       {\r
2731          *dp++ = *sp;\r
2732          sp += 2; /* skip low byte */\r
2733       }\r
2734 \r
2735       row_info->bit_depth = 8;\r
2736       row_info->pixel_depth = (png_byte)(8 * row_info->channels);\r
2737       row_info->rowbytes = row_info->width * row_info->channels;\r
2738    }\r
2739 }\r
2740 #endif\r
2741 \r
2742 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED\r
2743 void /* PRIVATE */\r
2744 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)\r
2745 {\r
2746    png_debug(1, "in png_do_read_swap_alpha");\r
2747 \r
2748    {\r
2749       png_uint_32 row_width = row_info->width;\r
2750       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\r
2751       {\r
2752          /* This converts from RGBA to ARGB */\r
2753          if (row_info->bit_depth == 8)\r
2754          {\r
2755             png_bytep sp = row + row_info->rowbytes;\r
2756             png_bytep dp = sp;\r
2757             png_byte save;\r
2758             png_uint_32 i;\r
2759 \r
2760             for (i = 0; i < row_width; i++)\r
2761             {\r
2762                save = *(--sp);\r
2763                *(--dp) = *(--sp);\r
2764                *(--dp) = *(--sp);\r
2765                *(--dp) = *(--sp);\r
2766                *(--dp) = save;\r
2767             }\r
2768          }\r
2769 \r
2770 #ifdef PNG_READ_16BIT_SUPPORTED\r
2771          /* This converts from RRGGBBAA to AARRGGBB */\r
2772          else\r
2773          {\r
2774             png_bytep sp = row + row_info->rowbytes;\r
2775             png_bytep dp = sp;\r
2776             png_byte save[2];\r
2777             png_uint_32 i;\r
2778 \r
2779             for (i = 0; i < row_width; i++)\r
2780             {\r
2781                save[0] = *(--sp);\r
2782                save[1] = *(--sp);\r
2783                *(--dp) = *(--sp);\r
2784                *(--dp) = *(--sp);\r
2785                *(--dp) = *(--sp);\r
2786                *(--dp) = *(--sp);\r
2787                *(--dp) = *(--sp);\r
2788                *(--dp) = *(--sp);\r
2789                *(--dp) = save[0];\r
2790                *(--dp) = save[1];\r
2791             }\r
2792          }\r
2793 #endif\r
2794       }\r
2795 \r
2796       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\r
2797       {\r
2798          /* This converts from GA to AG */\r
2799          if (row_info->bit_depth == 8)\r
2800          {\r
2801             png_bytep sp = row + row_info->rowbytes;\r
2802             png_bytep dp = sp;\r
2803             png_byte save;\r
2804             png_uint_32 i;\r
2805 \r
2806             for (i = 0; i < row_width; i++)\r
2807             {\r
2808                save = *(--sp);\r
2809                *(--dp) = *(--sp);\r
2810                *(--dp) = save;\r
2811             }\r
2812          }\r
2813 \r
2814 #ifdef PNG_READ_16BIT_SUPPORTED\r
2815          /* This converts from GGAA to AAGG */\r
2816          else\r
2817          {\r
2818             png_bytep sp = row + row_info->rowbytes;\r
2819             png_bytep dp = sp;\r
2820             png_byte save[2];\r
2821             png_uint_32 i;\r
2822 \r
2823             for (i = 0; i < row_width; i++)\r
2824             {\r
2825                save[0] = *(--sp);\r
2826                save[1] = *(--sp);\r
2827                *(--dp) = *(--sp);\r
2828                *(--dp) = *(--sp);\r
2829                *(--dp) = save[0];\r
2830                *(--dp) = save[1];\r
2831             }\r
2832          }\r
2833 #endif\r
2834       }\r
2835    }\r
2836 }\r
2837 #endif\r
2838 \r
2839 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED\r
2840 void /* PRIVATE */\r
2841 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)\r
2842 {\r
2843    png_uint_32 row_width;\r
2844    png_debug(1, "in png_do_read_invert_alpha");\r
2845 \r
2846    row_width = row_info->width;\r
2847    if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\r
2848    {\r
2849       if (row_info->bit_depth == 8)\r
2850       {\r
2851          /* This inverts the alpha channel in RGBA */\r
2852          png_bytep sp = row + row_info->rowbytes;\r
2853          png_bytep dp = sp;\r
2854          png_uint_32 i;\r
2855 \r
2856          for (i = 0; i < row_width; i++)\r
2857          {\r
2858             *(--dp) = (png_byte)(255 - *(--sp));\r
2859 \r
2860 /*          This does nothing:\r
2861             *(--dp) = *(--sp);\r
2862             *(--dp) = *(--sp);\r
2863             *(--dp) = *(--sp);\r
2864             We can replace it with:\r
2865 */\r
2866             sp-=3;\r
2867             dp=sp;\r
2868          }\r
2869       }\r
2870 \r
2871 #ifdef PNG_READ_16BIT_SUPPORTED\r
2872       /* This inverts the alpha channel in RRGGBBAA */\r
2873       else\r
2874       {\r
2875          png_bytep sp = row + row_info->rowbytes;\r
2876          png_bytep dp = sp;\r
2877          png_uint_32 i;\r
2878 \r
2879          for (i = 0; i < row_width; i++)\r
2880          {\r
2881             *(--dp) = (png_byte)(255 - *(--sp));\r
2882             *(--dp) = (png_byte)(255 - *(--sp));\r
2883 \r
2884 /*          This does nothing:\r
2885             *(--dp) = *(--sp);\r
2886             *(--dp) = *(--sp);\r
2887             *(--dp) = *(--sp);\r
2888             *(--dp) = *(--sp);\r
2889             *(--dp) = *(--sp);\r
2890             *(--dp) = *(--sp);\r
2891             We can replace it with:\r
2892 */\r
2893             sp-=6;\r
2894             dp=sp;\r
2895          }\r
2896       }\r
2897 #endif\r
2898    }\r
2899    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\r
2900    {\r
2901       if (row_info->bit_depth == 8)\r
2902       {\r
2903          /* This inverts the alpha channel in GA */\r
2904          png_bytep sp = row + row_info->rowbytes;\r
2905          png_bytep dp = sp;\r
2906          png_uint_32 i;\r
2907 \r
2908          for (i = 0; i < row_width; i++)\r
2909          {\r
2910             *(--dp) = (png_byte)(255 - *(--sp));\r
2911             *(--dp) = *(--sp);\r
2912          }\r
2913       }\r
2914 \r
2915 #ifdef PNG_READ_16BIT_SUPPORTED\r
2916       else\r
2917       {\r
2918          /* This inverts the alpha channel in GGAA */\r
2919          png_bytep sp  = row + row_info->rowbytes;\r
2920          png_bytep dp = sp;\r
2921          png_uint_32 i;\r
2922 \r
2923          for (i = 0; i < row_width; i++)\r
2924          {\r
2925             *(--dp) = (png_byte)(255 - *(--sp));\r
2926             *(--dp) = (png_byte)(255 - *(--sp));\r
2927 /*\r
2928             *(--dp) = *(--sp);\r
2929             *(--dp) = *(--sp);\r
2930 */\r
2931             sp-=2;\r
2932             dp=sp;\r
2933          }\r
2934       }\r
2935 #endif\r
2936    }\r
2937 }\r
2938 #endif\r
2939 \r
2940 #ifdef PNG_READ_FILLER_SUPPORTED\r
2941 /* Add filler channel if we have RGB color */\r
2942 void /* PRIVATE */\r
2943 png_do_read_filler(png_row_infop row_info, png_bytep row,\r
2944     png_uint_32 filler, png_uint_32 flags)\r
2945 {\r
2946    png_uint_32 i;\r
2947    png_uint_32 row_width = row_info->width;\r
2948 \r
2949 #ifdef PNG_READ_16BIT_SUPPORTED\r
2950    png_byte hi_filler = (png_byte)((filler>>8) & 0xff);\r
2951 #endif\r
2952    png_byte lo_filler = (png_byte)(filler & 0xff);\r
2953 \r
2954    png_debug(1, "in png_do_read_filler");\r
2955 \r
2956    if (\r
2957        row_info->color_type == PNG_COLOR_TYPE_GRAY)\r
2958    {\r
2959       if (row_info->bit_depth == 8)\r
2960       {\r
2961          if (flags & PNG_FLAG_FILLER_AFTER)\r
2962          {\r
2963             /* This changes the data from G to GX */\r
2964             png_bytep sp = row + (png_size_t)row_width;\r
2965             png_bytep dp =  sp + (png_size_t)row_width;\r
2966             for (i = 1; i < row_width; i++)\r
2967             {\r
2968                *(--dp) = lo_filler;\r
2969                *(--dp) = *(--sp);\r
2970             }\r
2971             *(--dp) = lo_filler;\r
2972             row_info->channels = 2;\r
2973             row_info->pixel_depth = 16;\r
2974             row_info->rowbytes = row_width * 2;\r
2975          }\r
2976 \r
2977          else\r
2978          {\r
2979             /* This changes the data from G to XG */\r
2980             png_bytep sp = row + (png_size_t)row_width;\r
2981             png_bytep dp = sp  + (png_size_t)row_width;\r
2982             for (i = 0; i < row_width; i++)\r
2983             {\r
2984                *(--dp) = *(--sp);\r
2985                *(--dp) = lo_filler;\r
2986             }\r
2987             row_info->channels = 2;\r
2988             row_info->pixel_depth = 16;\r
2989             row_info->rowbytes = row_width * 2;\r
2990          }\r
2991    &n