pngrtran.c
Go to the documentation of this file.
1 
2 /* pngrtran.c - transforms the data in a row for PNG readers
3  *
4  * Last changed in libpng 1.2.30 [August 15, 2008]
5  * For conditions of distribution and use, see copyright notice in png.h
6  * Copyright (c) 1998-2008 Glenn Randers-Pehrson
7  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9  *
10  * This file contains functions optionally called by an application
11  * in order to tell libpng how to handle data when reading a PNG.
12  * Transformations that are used in both reading and writing are
13  * in pngtrans.c.
14  */
15 
16 #define PNG_INTERNAL
17 #include "png.h"
18 #if defined(PNG_READ_SUPPORTED)
19 
20 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
21 void PNGAPI
23 {
24  png_debug(1, "in png_set_crc_action\n");
25  /* Tell libpng how we react to CRC errors in critical chunks */
26  if (png_ptr == NULL) return;
27  switch (crit_action)
28  {
29  case PNG_CRC_NO_CHANGE: /* leave setting as is */
30  break;
31  case PNG_CRC_WARN_USE: /* warn/use data */
32  png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
33  png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
34  break;
35  case PNG_CRC_QUIET_USE: /* quiet/use data */
36  png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
37  png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
38  PNG_FLAG_CRC_CRITICAL_IGNORE;
39  break;
40  case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
41  png_warning(png_ptr,
42  "Can't discard critical data on CRC error.");
43  case PNG_CRC_ERROR_QUIT: /* error/quit */
44  case PNG_CRC_DEFAULT:
45  default:
46  png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
47  break;
48  }
49 
50  switch (ancil_action)
51  {
52  case PNG_CRC_NO_CHANGE: /* leave setting as is */
53  break;
54  case PNG_CRC_WARN_USE: /* warn/use data */
55  png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
56  png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
57  break;
58  case PNG_CRC_QUIET_USE: /* quiet/use data */
59  png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
60  png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
61  PNG_FLAG_CRC_ANCILLARY_NOWARN;
62  break;
63  case PNG_CRC_ERROR_QUIT: /* error/quit */
64  png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
65  png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
66  break;
67  case PNG_CRC_WARN_DISCARD: /* warn/discard data */
68  case PNG_CRC_DEFAULT:
69  default:
70  png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
71  break;
72  }
73 }
74 
75 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
76  defined(PNG_FLOATING_POINT_SUPPORTED)
77 /* handle alpha and tRNS via a background color */
78 void PNGAPI
81  int need_expand, double background_gamma)
82 {
83  png_debug(1, "in png_set_background\n");
84  if (png_ptr == NULL) return;
85  if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
86  {
87  png_warning(png_ptr, "Application must supply a known background gamma");
88  return;
89  }
90 
91  png_ptr->transformations |= PNG_BACKGROUND;
92  png_memcpy(&(png_ptr->background), background_color,
94  png_ptr->background_gamma = (float)background_gamma;
95  png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
96  png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
97 }
98 #endif
99 
100 #if defined(PNG_READ_16_TO_8_SUPPORTED)
101 /* strip 16 bit depth files to 8 bit depth */
102 void PNGAPI
104 {
105  png_debug(1, "in png_set_strip_16\n");
106  if (png_ptr == NULL) return;
107  png_ptr->transformations |= PNG_16_TO_8;
108 }
109 #endif
110 
111 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
112 void PNGAPI
114 {
115  png_debug(1, "in png_set_strip_alpha\n");
116  if (png_ptr == NULL) return;
117  png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
118 }
119 #endif
120 
121 #if defined(PNG_READ_DITHER_SUPPORTED)
122 /* Dither file to 8 bit. Supply a palette, the current number
123  * of elements in the palette, the maximum number of elements
124  * allowed, and a histogram if possible. If the current number
125  * of colors is greater then the maximum number, the palette will be
126  * modified to fit in the maximum number. "full_dither" indicates
127  * whether we need a dithering cube set up for RGB images, or if we
128  * simply are reducing the number of colors in a paletted image.
129  */
130 
131 typedef struct png_dsort_struct
132 {
136 } png_dsort;
139 
140 void PNGAPI
143  int full_dither)
144 {
145  png_debug(1, "in png_set_dither\n");
146  if (png_ptr == NULL) return;
147  png_ptr->transformations |= PNG_DITHER;
148 
149  if (!full_dither)
150  {
151  int i;
152 
153  png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
154  (png_uint_32)(num_palette * png_sizeof(png_byte)));
155  for (i = 0; i < num_palette; i++)
156  png_ptr->dither_index[i] = (png_byte)i;
157  }
158 
159  if (num_palette > maximum_colors)
160  {
161  if (histogram != NULL)
162  {
163  /* This is easy enough, just throw out the least used colors.
164  Perhaps not the best solution, but good enough. */
165 
166  int i;
167 
168  /* initialize an array to sort colors */
169  png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
170  (png_uint_32)(num_palette * png_sizeof(png_byte)));
171 
172  /* initialize the dither_sort array */
173  for (i = 0; i < num_palette; i++)
174  png_ptr->dither_sort[i] = (png_byte)i;
175 
176  /* Find the least used palette entries by starting a
177  bubble sort, and running it until we have sorted
178  out enough colors. Note that we don't care about
179  sorting all the colors, just finding which are
180  least used. */
181 
182  for (i = num_palette - 1; i >= maximum_colors; i--)
183  {
184  int done; /* to stop early if the list is pre-sorted */
185  int j;
186 
187  done = 1;
188  for (j = 0; j < i; j++)
189  {
190  if (histogram[png_ptr->dither_sort[j]]
191  < histogram[png_ptr->dither_sort[j + 1]])
192  {
193  png_byte t;
194 
195  t = png_ptr->dither_sort[j];
196  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
197  png_ptr->dither_sort[j + 1] = t;
198  done = 0;
199  }
200  }
201  if (done)
202  break;
203  }
204 
205  /* swap the palette around, and set up a table, if necessary */
206  if (full_dither)
207  {
208  int j = num_palette;
209 
210  /* put all the useful colors within the max, but don't
211  move the others */
212  for (i = 0; i < maximum_colors; i++)
213  {
214  if ((int)png_ptr->dither_sort[i] >= maximum_colors)
215  {
216  do
217  j--;
218  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
219  palette[i] = palette[j];
220  }
221  }
222  }
223  else
224  {
225  int j = num_palette;
226 
227  /* move all the used colors inside the max limit, and
228  develop a translation table */
229  for (i = 0; i < maximum_colors; i++)
230  {
231  /* only move the colors we need to */
232  if ((int)png_ptr->dither_sort[i] >= maximum_colors)
233  {
234  png_color tmp_color;
235 
236  do
237  j--;
238  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
239 
240  tmp_color = palette[j];
241  palette[j] = palette[i];
242  palette[i] = tmp_color;
243  /* indicate where the color went */
244  png_ptr->dither_index[j] = (png_byte)i;
245  png_ptr->dither_index[i] = (png_byte)j;
246  }
247  }
248 
249  /* find closest color for those colors we are not using */
250  for (i = 0; i < num_palette; i++)
251  {
252  if ((int)png_ptr->dither_index[i] >= maximum_colors)
253  {
254  int min_d, k, min_k, d_index;
255 
256  /* find the closest color to one we threw out */
257  d_index = png_ptr->dither_index[i];
258  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
259  for (k = 1, min_k = 0; k < maximum_colors; k++)
260  {
261  int d;
262 
263  d = PNG_COLOR_DIST(palette[d_index], palette[k]);
264 
265  if (d < min_d)
266  {
267  min_d = d;
268  min_k = k;
269  }
270  }
271  /* point to closest color */
272  png_ptr->dither_index[i] = (png_byte)min_k;
273  }
274  }
275  }
276  png_free(png_ptr, png_ptr->dither_sort);
277  png_ptr->dither_sort = NULL;
278  }
279  else
280  {
281  /* This is much harder to do simply (and quickly). Perhaps
282  we need to go through a median cut routine, but those
283  don't always behave themselves with only a few colors
284  as input. So we will just find the closest two colors,
285  and throw out one of them (chosen somewhat randomly).
286  [We don't understand this at all, so if someone wants to
287  work on improving it, be our guest - AED, GRP]
288  */
289  int i;
290  int max_d;
291  int num_new_palette;
292  png_dsortp t;
293  png_dsortpp hash;
294 
295  t = NULL;
296 
297  /* initialize palette index arrays */
298  png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
299  (png_uint_32)(num_palette * png_sizeof(png_byte)));
300  png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
301  (png_uint_32)(num_palette * png_sizeof(png_byte)));
302 
303  /* initialize the sort array */
304  for (i = 0; i < num_palette; i++)
305  {
306  png_ptr->index_to_palette[i] = (png_byte)i;
307  png_ptr->palette_to_index[i] = (png_byte)i;
308  }
309 
310  hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
312  for (i = 0; i < 769; i++)
313  hash[i] = NULL;
314 /* png_memset(hash, 0, 769 * png_sizeof(png_dsortp)); */
315 
316  num_new_palette = num_palette;
317 
318  /* initial wild guess at how far apart the farthest pixel
319  pair we will be eliminating will be. Larger
320  numbers mean more areas will be allocated, Smaller
321  numbers run the risk of not saving enough data, and
322  having to do this all over again.
323 
324  I have not done extensive checking on this number.
325  */
326  max_d = 96;
327 
328  while (num_new_palette > maximum_colors)
329  {
330  for (i = 0; i < num_new_palette - 1; i++)
331  {
332  int j;
333 
334  for (j = i + 1; j < num_new_palette; j++)
335  {
336  int d;
337 
338  d = PNG_COLOR_DIST(palette[i], palette[j]);
339 
340  if (d <= max_d)
341  {
342 
343  t = (png_dsortp)png_malloc_warn(png_ptr,
345  if (t == NULL)
346  break;
347  t->next = hash[d];
348  t->left = (png_byte)i;
349  t->right = (png_byte)j;
350  hash[d] = t;
351  }
352  }
353  if (t == NULL)
354  break;
355  }
356 
357  if (t != NULL)
358  for (i = 0; i <= max_d; i++)
359  {
360  if (hash[i] != NULL)
361  {
362  png_dsortp p;
363 
364  for (p = hash[i]; p; p = p->next)
365  {
366  if ((int)png_ptr->index_to_palette[p->left]
367  < num_new_palette &&
368  (int)png_ptr->index_to_palette[p->right]
369  < num_new_palette)
370  {
371  int j, next_j;
372 
373  if (num_new_palette & 0x01)
374  {
375  j = p->left;
376  next_j = p->right;
377  }
378  else
379  {
380  j = p->right;
381  next_j = p->left;
382  }
383 
384  num_new_palette--;
385  palette[png_ptr->index_to_palette[j]]
386  = palette[num_new_palette];
387  if (!full_dither)
388  {
389  int k;
390 
391  for (k = 0; k < num_palette; k++)
392  {
393  if (png_ptr->dither_index[k] ==
394  png_ptr->index_to_palette[j])
395  png_ptr->dither_index[k] =
396  png_ptr->index_to_palette[next_j];
397  if ((int)png_ptr->dither_index[k] ==
398  num_new_palette)
399  png_ptr->dither_index[k] =
400  png_ptr->index_to_palette[j];
401  }
402  }
403 
404  png_ptr->index_to_palette[png_ptr->palette_to_index
405  [num_new_palette]] = png_ptr->index_to_palette[j];
406  png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
407  = png_ptr->palette_to_index[num_new_palette];
408 
409  png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
410  png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
411  }
412  if (num_new_palette <= maximum_colors)
413  break;
414  }
415  if (num_new_palette <= maximum_colors)
416  break;
417  }
418  }
419 
420  for (i = 0; i < 769; i++)
421  {
422  if (hash[i] != NULL)
423  {
424  png_dsortp p = hash[i];
425  while (p)
426  {
427  t = p->next;
428  png_free(png_ptr, p);
429  p = t;
430  }
431  }
432  hash[i] = 0;
433  }
434  max_d += 96;
435  }
436  png_free(png_ptr, hash);
437  png_free(png_ptr, png_ptr->palette_to_index);
438  png_free(png_ptr, png_ptr->index_to_palette);
439  png_ptr->palette_to_index = NULL;
440  png_ptr->index_to_palette = NULL;
441  }
442  num_palette = maximum_colors;
443  }
444  if (png_ptr->palette == NULL)
445  {
446  png_ptr->palette = palette;
447  }
448  png_ptr->num_palette = (png_uint_16)num_palette;
449 
450  if (full_dither)
451  {
452  int i;
453  png_bytep distance;
454  int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
455  PNG_DITHER_BLUE_BITS;
456  int num_red = (1 << PNG_DITHER_RED_BITS);
457  int num_green = (1 << PNG_DITHER_GREEN_BITS);
458  int num_blue = (1 << PNG_DITHER_BLUE_BITS);
459  png_size_t num_entries = ((png_size_t)1 << total_bits);
460 
461  png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
462  (png_uint_32)(num_entries * png_sizeof(png_byte)));
463 
464  png_memset(png_ptr->palette_lookup, 0, num_entries *
466 
467  distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
468  png_sizeof(png_byte)));
469 
470  png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
471 
472  for (i = 0; i < num_palette; i++)
473  {
474  int ir, ig, ib;
475  int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
476  int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
477  int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
478 
479  for (ir = 0; ir < num_red; ir++)
480  {
481  /* int dr = abs(ir - r); */
482  int dr = ((ir > r) ? ir - r : r - ir);
483  int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
484 
485  for (ig = 0; ig < num_green; ig++)
486  {
487  /* int dg = abs(ig - g); */
488  int dg = ((ig > g) ? ig - g : g - ig);
489  int dt = dr + dg;
490  int dm = ((dr > dg) ? dr : dg);
491  int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
492 
493  for (ib = 0; ib < num_blue; ib++)
494  {
495  int d_index = index_g | ib;
496  /* int db = abs(ib - b); */
497  int db = ((ib > b) ? ib - b : b - ib);
498  int dmax = ((dm > db) ? dm : db);
499  int d = dmax + dt + db;
500 
501  if (d < (int)distance[d_index])
502  {
503  distance[d_index] = (png_byte)d;
504  png_ptr->palette_lookup[d_index] = (png_byte)i;
505  }
506  }
507  }
508  }
509  }
510 
511  png_free(png_ptr, distance);
512  }
513 }
514 #endif
515 
516 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
517 /* Transform the image from the file_gamma to the screen_gamma. We
518  * only do transformations on images where the file_gamma and screen_gamma
519  * are not close reciprocals, otherwise it slows things down slightly, and
520  * also needlessly introduces small errors.
521  *
522  * We will turn off gamma transformation later if no semitransparent entries
523  * are present in the tRNS array for palette images. We can't do it here
524  * because we don't necessarily have the tRNS chunk yet.
525  */
526 void PNGAPI
527 png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
528 {
529  png_debug(1, "in png_set_gamma\n");
530  if (png_ptr == NULL) return;
531  if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
532  (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
533  (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
534  png_ptr->transformations |= PNG_GAMMA;
535  png_ptr->gamma = (float)file_gamma;
536  png_ptr->screen_gamma = (float)scrn_gamma;
537 }
538 #endif
539 
540 #if defined(PNG_READ_EXPAND_SUPPORTED)
541 /* Expand paletted images to RGB, expand grayscale images of
542  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
543  * to alpha channels.
544  */
545 void PNGAPI
547 {
548  png_debug(1, "in png_set_expand\n");
549  if (png_ptr == NULL) return;
550  png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
551  png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
552 }
553 
554 /* GRR 19990627: the following three functions currently are identical
555  * to png_set_expand(). However, it is entirely reasonable that someone
556  * might wish to expand an indexed image to RGB but *not* expand a single,
557  * fully transparent palette entry to a full alpha channel--perhaps instead
558  * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
559  * the transparent color with a particular RGB value, or drop tRNS entirely.
560  * IOW, a future version of the library may make the transformations flag
561  * a bit more fine-grained, with separate bits for each of these three
562  * functions.
563  *
564  * More to the point, these functions make it obvious what libpng will be
565  * doing, whereas "expand" can (and does) mean any number of things.
566  *
567  * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
568  * to expand only the sample depth but not to expand the tRNS to alpha.
569  */
570 
571 /* Expand paletted images to RGB. */
572 void PNGAPI
574 {
575  png_debug(1, "in png_set_palette_to_rgb\n");
576  if (png_ptr == NULL) return;
577  png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
578  png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
579 }
580 
581 #if !defined(PNG_1_0_X)
582 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
583 void PNGAPI
585 {
586  png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
587  if (png_ptr == NULL) return;
588  png_ptr->transformations |= PNG_EXPAND;
589  png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
590 }
591 #endif
592 
593 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
594 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
595 /* Deprecated as of libpng-1.2.9 */
596 void PNGAPI
598 {
599  png_debug(1, "in png_set_gray_1_2_4_to_8\n");
600  if (png_ptr == NULL) return;
601  png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
602 }
603 #endif
604 
605 
606 /* Expand tRNS chunks to alpha channels. */
607 void PNGAPI
609 {
610  png_debug(1, "in png_set_tRNS_to_alpha\n");
611  png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
612  png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
613 }
614 #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
615 
616 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
617 void PNGAPI
619 {
620  png_debug(1, "in png_set_gray_to_rgb\n");
621  png_ptr->transformations |= PNG_GRAY_TO_RGB;
622  png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
623 }
624 #endif
625 
626 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
627 #if defined(PNG_FLOATING_POINT_SUPPORTED)
628 /* Convert a RGB image to a grayscale of the same width. This allows us,
629  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
630  */
631 
632 void PNGAPI
634  double green)
635 {
636  int red_fixed = (int)((float)red*100000.0 + 0.5);
637  int green_fixed = (int)((float)green*100000.0 + 0.5);
638  if (png_ptr == NULL) return;
639  png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
640 }
641 #endif
642 
643 void PNGAPI
646 {
647  png_debug(1, "in png_set_rgb_to_gray\n");
648  if (png_ptr == NULL) return;
649  switch(error_action)
650  {
651  case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
652  break;
653  case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
654  break;
655  case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
656  }
657  if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
658 #if defined(PNG_READ_EXPAND_SUPPORTED)
659  png_ptr->transformations |= PNG_EXPAND;
660 #else
661  {
662  png_warning(png_ptr,
663  "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
664  png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
665  }
666 #endif
667  {
668  png_uint_16 red_int, green_int;
669  if (red < 0 || green < 0)
670  {
671  red_int = 6968; /* .212671 * 32768 + .5 */
672  green_int = 23434; /* .715160 * 32768 + .5 */
673  }
674  else if (red + green < 100000L)
675  {
676  red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
677  green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
678  }
679  else
680  {
681  png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
682  red_int = 6968;
683  green_int = 23434;
684  }
685  png_ptr->rgb_to_gray_red_coeff = red_int;
686  png_ptr->rgb_to_gray_green_coeff = green_int;
687  png_ptr->rgb_to_gray_blue_coeff =
688  (png_uint_16)(32768 - red_int - green_int);
689  }
690 }
691 #endif
692 
693 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
694  defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
695  defined(PNG_LEGACY_SUPPORTED)
696 void PNGAPI
697 png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
699 {
700  png_debug(1, "in png_set_read_user_transform_fn\n");
701  if (png_ptr == NULL) return;
702 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
703  png_ptr->transformations |= PNG_USER_TRANSFORM;
704  png_ptr->read_user_transform_fn = read_user_transform_fn;
705 #endif
706 #ifdef PNG_LEGACY_SUPPORTED
707  if (read_user_transform_fn)
708  png_warning(png_ptr,
709  "This version of libpng does not support user transforms");
710 #endif
711 }
712 #endif
713 
714 /* Initialize everything needed for the read. This includes modifying
715  * the palette.
716  */
717 void /* PRIVATE */
719 {
720  png_debug(1, "in png_init_read_transformations\n");
721 #if defined(PNG_USELESS_TESTS_SUPPORTED)
722  if (png_ptr != NULL)
723 #endif
724  {
725 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
726  || defined(PNG_READ_GAMMA_SUPPORTED)
727  int color_type = png_ptr->color_type;
728 #endif
729 
730 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
731 
732 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
733  /* Detect gray background and attempt to enable optimization
734  * for gray --> RGB case */
735  /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
736  * RGB_ALPHA (in which case need_expand is superfluous anyway), the
737  * background color might actually be gray yet not be flagged as such.
738  * This is not a problem for the current code, which uses
739  * PNG_BACKGROUND_IS_GRAY only to decide when to do the
740  * png_do_gray_to_rgb() transformation.
741  */
742  if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
743  !(color_type & PNG_COLOR_MASK_COLOR))
744  {
745  png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
746  } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
747  !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
748  (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
749  png_ptr->background.red == png_ptr->background.green &&
750  png_ptr->background.red == png_ptr->background.blue)
751  {
752  png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
753  png_ptr->background.gray = png_ptr->background.red;
754  }
755 #endif
756 
757  if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
758  (png_ptr->transformations & PNG_EXPAND))
759  {
760  if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
761  {
762  /* expand background and tRNS chunks */
763  switch (png_ptr->bit_depth)
764  {
765  case 1:
766  png_ptr->background.gray *= (png_uint_16)0xff;
767  png_ptr->background.red = png_ptr->background.green
768  = png_ptr->background.blue = png_ptr->background.gray;
769  if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
770  {
771  png_ptr->trans_values.gray *= (png_uint_16)0xff;
772  png_ptr->trans_values.red = png_ptr->trans_values.green
773  = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
774  }
775  break;
776  case 2:
777  png_ptr->background.gray *= (png_uint_16)0x55;
778  png_ptr->background.red = png_ptr->background.green
779  = png_ptr->background.blue = png_ptr->background.gray;
780  if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
781  {
782  png_ptr->trans_values.gray *= (png_uint_16)0x55;
783  png_ptr->trans_values.red = png_ptr->trans_values.green
784  = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
785  }
786  break;
787  case 4:
788  png_ptr->background.gray *= (png_uint_16)0x11;
789  png_ptr->background.red = png_ptr->background.green
790  = png_ptr->background.blue = png_ptr->background.gray;
791  if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
792  {
793  png_ptr->trans_values.gray *= (png_uint_16)0x11;
794  png_ptr->trans_values.red = png_ptr->trans_values.green
795  = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
796  }
797  break;
798  case 8:
799  case 16:
800  png_ptr->background.red = png_ptr->background.green
801  = png_ptr->background.blue = png_ptr->background.gray;
802  break;
803  }
804  }
805  else if (color_type == PNG_COLOR_TYPE_PALETTE)
806  {
807  png_ptr->background.red =
808  png_ptr->palette[png_ptr->background.index].red;
809  png_ptr->background.green =
810  png_ptr->palette[png_ptr->background.index].green;
811  png_ptr->background.blue =
812  png_ptr->palette[png_ptr->background.index].blue;
813 
814 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
815  if (png_ptr->transformations & PNG_INVERT_ALPHA)
816  {
817 #if defined(PNG_READ_EXPAND_SUPPORTED)
818  if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
819 #endif
820  {
821  /* invert the alpha channel (in tRNS) unless the pixels are
822  going to be expanded, in which case leave it for later */
823  int i, istop;
824  istop=(int)png_ptr->num_trans;
825  for (i=0; i<istop; i++)
826  png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
827  }
828  }
829 #endif
830 
831  }
832  }
833 #endif
834 
835 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
836  png_ptr->background_1 = png_ptr->background;
837 #endif
838 #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
839 
840  if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
841  && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
842  < PNG_GAMMA_THRESHOLD))
843  {
844  int i, k;
845  k=0;
846  for (i=0; i<png_ptr->num_trans; i++)
847  {
848  if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
849  k=1; /* partial transparency is present */
850  }
851  if (k == 0)
852  png_ptr->transformations &= ~PNG_GAMMA;
853  }
854 
855  if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
856  png_ptr->gamma != 0.0)
857  {
858  png_build_gamma_table(png_ptr);
859 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
860  if (png_ptr->transformations & PNG_BACKGROUND)
861  {
862  if (color_type == PNG_COLOR_TYPE_PALETTE)
863  {
864  /* could skip if no transparency and
865  */
866  png_color back, back_1;
867  png_colorp palette = png_ptr->palette;
868  int num_palette = png_ptr->num_palette;
869  int i;
870  if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
871  {
872  back.red = png_ptr->gamma_table[png_ptr->background.red];
873  back.green = png_ptr->gamma_table[png_ptr->background.green];
874  back.blue = png_ptr->gamma_table[png_ptr->background.blue];
875 
876  back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
877  back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
878  back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
879  }
880  else
881  {
882  double g, gs;
883 
884  switch (png_ptr->background_gamma_type)
885  {
887  g = (png_ptr->screen_gamma);
888  gs = 1.0;
889  break;
891  g = 1.0 / (png_ptr->gamma);
892  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
893  break;
895  g = 1.0 / (png_ptr->background_gamma);
896  gs = 1.0 / (png_ptr->background_gamma *
897  png_ptr->screen_gamma);
898  break;
899  default:
900  g = 1.0; /* back_1 */
901  gs = 1.0; /* back */
902  }
903 
904  if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
905  {
906  back.red = (png_byte)png_ptr->background.red;
907  back.green = (png_byte)png_ptr->background.green;
908  back.blue = (png_byte)png_ptr->background.blue;
909  }
910  else
911  {
912  back.red = (png_byte)(pow(
913  (double)png_ptr->background.red/255, gs) * 255.0 + .5);
914  back.green = (png_byte)(pow(
915  (double)png_ptr->background.green/255, gs) * 255.0 + .5);
916  back.blue = (png_byte)(pow(
917  (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
918  }
919 
920  back_1.red = (png_byte)(pow(
921  (double)png_ptr->background.red/255, g) * 255.0 + .5);
922  back_1.green = (png_byte)(pow(
923  (double)png_ptr->background.green/255, g) * 255.0 + .5);
924  back_1.blue = (png_byte)(pow(
925  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
926  }
927  for (i = 0; i < num_palette; i++)
928  {
929  if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
930  {
931  if (png_ptr->trans[i] == 0)
932  {
933  palette[i] = back;
934  }
935  else /* if (png_ptr->trans[i] != 0xff) */
936  {
937  png_byte v, w;
938 
939  v = png_ptr->gamma_to_1[palette[i].red];
940  png_composite(w, v, png_ptr->trans[i], back_1.red);
941  palette[i].red = png_ptr->gamma_from_1[w];
942 
943  v = png_ptr->gamma_to_1[palette[i].green];
944  png_composite(w, v, png_ptr->trans[i], back_1.green);
945  palette[i].green = png_ptr->gamma_from_1[w];
946 
947  v = png_ptr->gamma_to_1[palette[i].blue];
948  png_composite(w, v, png_ptr->trans[i], back_1.blue);
949  palette[i].blue = png_ptr->gamma_from_1[w];
950  }
951  }
952  else
953  {
954  palette[i].red = png_ptr->gamma_table[palette[i].red];
955  palette[i].green = png_ptr->gamma_table[palette[i].green];
956  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
957  }
958  }
959  /* Prevent the transformations being done again, and make sure
960  * that the now spurious alpha channel is stripped - the code
961  * has just reduced background composition and gamma correction
962  * to a simple alpha channel strip.
963  */
964  png_ptr->transformations &= ~PNG_BACKGROUND;
965  png_ptr->transformations &= ~PNG_GAMMA;
966  png_ptr->transformations |= PNG_STRIP_ALPHA;
967  }
968  /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
969  else
970  /* color_type != PNG_COLOR_TYPE_PALETTE */
971  {
972  double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
973  double g = 1.0;
974  double gs = 1.0;
975 
976  switch (png_ptr->background_gamma_type)
977  {
979  g = (png_ptr->screen_gamma);
980  gs = 1.0;
981  break;
983  g = 1.0 / (png_ptr->gamma);
984  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
985  break;
987  g = 1.0 / (png_ptr->background_gamma);
988  gs = 1.0 / (png_ptr->background_gamma *
989  png_ptr->screen_gamma);
990  break;
991  }
992 
993  png_ptr->background_1.gray = (png_uint_16)(pow(
994  (double)png_ptr->background.gray / m, g) * m + .5);
995  png_ptr->background.gray = (png_uint_16)(pow(
996  (double)png_ptr->background.gray / m, gs) * m + .5);
997 
998  if ((png_ptr->background.red != png_ptr->background.green) ||
999  (png_ptr->background.red != png_ptr->background.blue) ||
1000  (png_ptr->background.red != png_ptr->background.gray))
1001  {
1002  /* RGB or RGBA with color background */
1003  png_ptr->background_1.red = (png_uint_16)(pow(
1004  (double)png_ptr->background.red / m, g) * m + .5);
1005  png_ptr->background_1.green = (png_uint_16)(pow(
1006  (double)png_ptr->background.green / m, g) * m + .5);
1007  png_ptr->background_1.blue = (png_uint_16)(pow(
1008  (double)png_ptr->background.blue / m, g) * m + .5);
1009  png_ptr->background.red = (png_uint_16)(pow(
1010  (double)png_ptr->background.red / m, gs) * m + .5);
1011  png_ptr->background.green = (png_uint_16)(pow(
1012  (double)png_ptr->background.green / m, gs) * m + .5);
1013  png_ptr->background.blue = (png_uint_16)(pow(
1014  (double)png_ptr->background.blue / m, gs) * m + .5);
1015  }
1016  else
1017  {
1018  /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1019  png_ptr->background_1.red = png_ptr->background_1.green
1020  = png_ptr->background_1.blue = png_ptr->background_1.gray;
1021  png_ptr->background.red = png_ptr->background.green
1022  = png_ptr->background.blue = png_ptr->background.gray;
1023  }
1024  }
1025  }
1026  else
1027  /* transformation does not include PNG_BACKGROUND */
1028 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1029  if (color_type == PNG_COLOR_TYPE_PALETTE)
1030  {
1031  png_colorp palette = png_ptr->palette;
1032  int num_palette = png_ptr->num_palette;
1033  int i;
1034 
1035  for (i = 0; i < num_palette; i++)
1036  {
1037  palette[i].red = png_ptr->gamma_table[palette[i].red];
1038  palette[i].green = png_ptr->gamma_table[palette[i].green];
1039  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1040  }
1041 
1042  /* Done the gamma correction. */
1043  png_ptr->transformations &= ~PNG_GAMMA;
1044  }
1045  }
1046 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1047  else
1048 #endif
1049 #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
1050 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1051  /* No GAMMA transformation */
1052  if ((png_ptr->transformations & PNG_BACKGROUND) &&
1053  (color_type == PNG_COLOR_TYPE_PALETTE))
1054  {
1055  int i;
1056  int istop = (int)png_ptr->num_trans;
1057  png_color back;
1058  png_colorp palette = png_ptr->palette;
1059 
1060  back.red = (png_byte)png_ptr->background.red;
1061  back.green = (png_byte)png_ptr->background.green;
1062  back.blue = (png_byte)png_ptr->background.blue;
1063 
1064  for (i = 0; i < istop; i++)
1065  {
1066  if (png_ptr->trans[i] == 0)
1067  {
1068  palette[i] = back;
1069  }
1070  else if (png_ptr->trans[i] != 0xff)
1071  {
1072  /* The png_composite() macro is defined in png.h */
1073  png_composite(palette[i].red, palette[i].red,
1074  png_ptr->trans[i], back.red);
1075  png_composite(palette[i].green, palette[i].green,
1076  png_ptr->trans[i], back.green);
1077  png_composite(palette[i].blue, palette[i].blue,
1078  png_ptr->trans[i], back.blue);
1079  }
1080  }
1081 
1082  /* Handled alpha, still need to strip the channel. */
1083  png_ptr->transformations &= ~PNG_BACKGROUND;
1084  png_ptr->transformations |= PNG_STRIP_ALPHA;
1085  }
1086 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
1087 
1088 #if defined(PNG_READ_SHIFT_SUPPORTED)
1089  if ((png_ptr->transformations & PNG_SHIFT) &&
1090  (color_type == PNG_COLOR_TYPE_PALETTE))
1091  {
1092  png_uint_16 i;
1093  png_uint_16 istop = png_ptr->num_palette;
1094  int sr = 8 - png_ptr->sig_bit.red;
1095  int sg = 8 - png_ptr->sig_bit.green;
1096  int sb = 8 - png_ptr->sig_bit.blue;
1097 
1098  if (sr < 0 || sr > 8)
1099  sr = 0;
1100  if (sg < 0 || sg > 8)
1101  sg = 0;
1102  if (sb < 0 || sb > 8)
1103  sb = 0;
1104  for (i = 0; i < istop; i++)
1105  {
1106  png_ptr->palette[i].red >>= sr;
1107  png_ptr->palette[i].green >>= sg;
1108  png_ptr->palette[i].blue >>= sb;
1109  }
1110  }
1111 #endif /* PNG_READ_SHIFT_SUPPORTED */
1112  }
1113 #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1114  && !defined(PNG_READ_BACKGROUND_SUPPORTED)
1115  if (png_ptr)
1116  return;
1117 #endif
1118 }
1119 
1120 /* Modify the info structure to reflect the transformations. The
1121  * info should be updated so a PNG file could be written with it,
1122  * assuming the transformations result in valid PNG data.
1123  */
1124 void /* PRIVATE */
1126 {
1127  png_debug(1, "in png_read_transform_info\n");
1128 #if defined(PNG_READ_EXPAND_SUPPORTED)
1129  if (png_ptr->transformations & PNG_EXPAND)
1130  {
1131  if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1132  {
1133  if (png_ptr->num_trans &&
1134  (png_ptr->transformations & PNG_EXPAND_tRNS))
1135  info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1136  else
1137  info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1138  info_ptr->bit_depth = 8;
1139  info_ptr->num_trans = 0;
1140  }
1141  else
1142  {
1143  if (png_ptr->num_trans)
1144  {
1145  if (png_ptr->transformations & PNG_EXPAND_tRNS)
1146  info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1147 #if 0 /* Removed from libpng-1.2.27 */
1148  else
1149  info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
1150 #endif
1151  }
1152  if (info_ptr->bit_depth < 8)
1153  info_ptr->bit_depth = 8;
1154  info_ptr->num_trans = 0;
1155  }
1156  }
1157 #endif
1158 
1159 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1160  if (png_ptr->transformations & PNG_BACKGROUND)
1161  {
1162  info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1163  info_ptr->num_trans = 0;
1164  info_ptr->background = png_ptr->background;
1165  }
1166 #endif
1167 
1168 #if defined(PNG_READ_GAMMA_SUPPORTED)
1169  if (png_ptr->transformations & PNG_GAMMA)
1170  {
1171 #ifdef PNG_FLOATING_POINT_SUPPORTED
1172  info_ptr->gamma = png_ptr->gamma;
1173 #endif
1174 #ifdef PNG_FIXED_POINT_SUPPORTED
1175  info_ptr->int_gamma = png_ptr->int_gamma;
1176 #endif
1177  }
1178 #endif
1179 
1180 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1181  if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
1182  info_ptr->bit_depth = 8;
1183 #endif
1184 
1185 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1186  if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1187  info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
1188 #endif
1189 
1190 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1191  if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1192  info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
1193 #endif
1194 
1195 #if defined(PNG_READ_DITHER_SUPPORTED)
1196  if (png_ptr->transformations & PNG_DITHER)
1197  {
1198  if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1199  (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
1200  png_ptr->palette_lookup && info_ptr->bit_depth == 8)
1201  {
1202  info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
1203  }
1204  }
1205 #endif
1206 
1207 #if defined(PNG_READ_PACK_SUPPORTED)
1208  if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
1209  info_ptr->bit_depth = 8;
1210 #endif
1211 
1212  if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1213  info_ptr->channels = 1;
1214  else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
1215  info_ptr->channels = 3;
1216  else
1217  info_ptr->channels = 1;
1218 
1219 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1220  if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
1221  info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1222 #endif
1223 
1224  if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
1225  info_ptr->channels++;
1226 
1227 #if defined(PNG_READ_FILLER_SUPPORTED)
1228  /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
1229  if ((png_ptr->transformations & PNG_FILLER) &&
1230  ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1231  (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
1232  {
1233  info_ptr->channels++;
1234  /* if adding a true alpha channel not just filler */
1235 #if !defined(PNG_1_0_X)
1236  if (png_ptr->transformations & PNG_ADD_ALPHA)
1237  info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1238 #endif
1239  }
1240 #endif
1241 
1242 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1243 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1244  if (png_ptr->transformations & PNG_USER_TRANSFORM)
1245  {
1246  if (info_ptr->bit_depth < png_ptr->user_transform_depth)
1247  info_ptr->bit_depth = png_ptr->user_transform_depth;
1248  if (info_ptr->channels < png_ptr->user_transform_channels)
1249  info_ptr->channels = png_ptr->user_transform_channels;
1250  }
1251 #endif
1252 
1253  info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
1254  info_ptr->bit_depth);
1255 
1256  info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
1257 
1258 #if !defined(PNG_READ_EXPAND_SUPPORTED)
1259  if (png_ptr)
1260  return;
1261 #endif
1262 }
1263 
1264 /* Transform the row. The order of transformations is significant,
1265  * and is very touchy. If you add a transformation, take care to
1266  * decide how it fits in with the other transformations here.
1267  */
1268 void /* PRIVATE */
1270 {
1271  png_debug(1, "in png_do_read_transformations\n");
1272  if (png_ptr->row_buf == NULL)
1273  {
1274 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1275  char msg[50];
1276 
1277  png_snprintf2(msg, 50,
1278  "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
1279  png_ptr->pass);
1280  png_error(png_ptr, msg);
1281 #else
1282  png_error(png_ptr, "NULL row buffer");
1283 #endif
1284  }
1285 #ifdef PNG_WARN_UNINITIALIZED_ROW
1286  if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
1287  /* Application has failed to call either png_read_start_image()
1288  * or png_read_update_info() after setting transforms that expand
1289  * pixels. This check added to libpng-1.2.19 */
1290 #if (PNG_WARN_UNINITIALIZED_ROW==1)
1291  png_error(png_ptr, "Uninitialized row");
1292 #else
1293  png_warning(png_ptr, "Uninitialized row");
1294 #endif
1295 #endif
1296 
1297 #if defined(PNG_READ_EXPAND_SUPPORTED)
1298  if (png_ptr->transformations & PNG_EXPAND)
1299  {
1300  if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
1301  {
1302  png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
1303  png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
1304  }
1305  else
1306  {
1307  if (png_ptr->num_trans &&
1308  (png_ptr->transformations & PNG_EXPAND_tRNS))
1309  png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1310  &(png_ptr->trans_values));
1311  else
1312  png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1313  NULL);
1314  }
1315  }
1316 #endif
1317 
1318 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1319  if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
1320  png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1321  PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
1322 #endif
1323 
1324 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1325  if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1326  {
1327  int rgb_error =
1328  png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
1329  if (rgb_error)
1330  {
1331  png_ptr->rgb_to_gray_status=1;
1332  if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
1333  PNG_RGB_TO_GRAY_WARN)
1334  png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
1335  if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
1336  PNG_RGB_TO_GRAY_ERR)
1337  png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
1338  }
1339  }
1340 #endif
1341 
1342 /*
1343 From Andreas Dilger e-mail to png-implement, 26 March 1998:
1344 
1345  In most cases, the "simple transparency" should be done prior to doing
1346  gray-to-RGB, or you will have to test 3x as many bytes to check if a
1347  pixel is transparent. You would also need to make sure that the
1348  transparency information is upgraded to RGB.
1349 
1350  To summarize, the current flow is:
1351  - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1352  with background "in place" if transparent,
1353  convert to RGB if necessary
1354  - Gray + alpha -> composite with gray background and remove alpha bytes,
1355  convert to RGB if necessary
1356 
1357  To support RGB backgrounds for gray images we need:
1358  - Gray + simple transparency -> convert to RGB + simple transparency, compare
1359  3 or 6 bytes and composite with background
1360  "in place" if transparent (3x compare/pixel
1361  compared to doing composite with gray bkgrnd)
1362  - Gray + alpha -> convert to RGB + alpha, composite with background and
1363  remove alpha bytes (3x float operations/pixel
1364  compared with composite on gray background)
1365 
1366  Greg's change will do this. The reason it wasn't done before is for
1367  performance, as this increases the per-pixel operations. If we would check
1368  in advance if the background was gray or RGB, and position the gray-to-RGB
1369  transform appropriately, then it would save a lot of work/time.
1370  */
1371 
1372 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1373  /* if gray -> RGB, do so now only if background is non-gray; else do later
1374  * for performance reasons */
1375  if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1376  !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1377  png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1378 #endif
1379 
1380 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1381  if ((png_ptr->transformations & PNG_BACKGROUND) &&
1382  ((png_ptr->num_trans != 0 ) ||
1383  (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
1384  png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
1385  &(png_ptr->trans_values), &(png_ptr->background)
1386 #if defined(PNG_READ_GAMMA_SUPPORTED)
1387  , &(png_ptr->background_1),
1388  png_ptr->gamma_table, png_ptr->gamma_from_1,
1389  png_ptr->gamma_to_1, png_ptr->gamma_16_table,
1390  png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
1391  png_ptr->gamma_shift
1392 #endif
1393 );
1394 #endif
1395 
1396 #if defined(PNG_READ_GAMMA_SUPPORTED)
1397  if ((png_ptr->transformations & PNG_GAMMA) &&
1398 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1399  !((png_ptr->transformations & PNG_BACKGROUND) &&
1400  ((png_ptr->num_trans != 0) ||
1401  (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
1402 #endif
1403  (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
1404  png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
1405  png_ptr->gamma_table, png_ptr->gamma_16_table,
1406  png_ptr->gamma_shift);
1407 #endif
1408 
1409 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1410  if (png_ptr->transformations & PNG_16_TO_8)
1411  png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
1412 #endif
1413 
1414 #if defined(PNG_READ_DITHER_SUPPORTED)
1415  if (png_ptr->transformations & PNG_DITHER)
1416  {
1417  png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
1418  png_ptr->palette_lookup, png_ptr->dither_index);
1419  if (png_ptr->row_info.rowbytes == (png_uint_32)0)
1420  png_error(png_ptr, "png_do_dither returned rowbytes=0");
1421  }
1422 #endif
1423 
1424 #if defined(PNG_READ_INVERT_SUPPORTED)
1425  if (png_ptr->transformations & PNG_INVERT_MONO)
1426  png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
1427 #endif
1428 
1429 #if defined(PNG_READ_SHIFT_SUPPORTED)
1430  if (png_ptr->transformations & PNG_SHIFT)
1431  png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
1432  &(png_ptr->shift));
1433 #endif
1434 
1435 #if defined(PNG_READ_PACK_SUPPORTED)
1436  if (png_ptr->transformations & PNG_PACK)
1437  png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
1438 #endif
1439 
1440 #if defined(PNG_READ_BGR_SUPPORTED)
1441  if (png_ptr->transformations & PNG_BGR)
1442  png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
1443 #endif
1444 
1445 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1446  if (png_ptr->transformations & PNG_PACKSWAP)
1447  png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1448 #endif
1449 
1450 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1451  /* if gray -> RGB, do so now only if we did not do so above */
1452  if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1453  (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1454  png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1455 #endif
1456 
1457 #if defined(PNG_READ_FILLER_SUPPORTED)
1458  if (png_ptr->transformations & PNG_FILLER)
1459  png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1460  (png_uint_32)png_ptr->filler, png_ptr->flags);
1461 #endif
1462 
1463 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1464  if (png_ptr->transformations & PNG_INVERT_ALPHA)
1465  png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1466 #endif
1467 
1468 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1469  if (png_ptr->transformations & PNG_SWAP_ALPHA)
1470  png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1471 #endif
1472 
1473 #if defined(PNG_READ_SWAP_SUPPORTED)
1474  if (png_ptr->transformations & PNG_SWAP_BYTES)
1475  png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1476 #endif
1477 
1478 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1479  if (png_ptr->transformations & PNG_USER_TRANSFORM)
1480  {
1481  if (png_ptr->read_user_transform_fn != NULL)
1482  (*(png_ptr->read_user_transform_fn)) /* user read transform function */
1483  (png_ptr, /* png_ptr */
1484  &(png_ptr->row_info), /* row_info: */
1485  /* png_uint_32 width; width of row */
1486  /* png_uint_32 rowbytes; number of bytes in row */
1487  /* png_byte color_type; color type of pixels */
1488  /* png_byte bit_depth; bit depth of samples */
1489  /* png_byte channels; number of channels (1-4) */
1490  /* png_byte pixel_depth; bits per pixel (depth*channels) */
1491  png_ptr->row_buf + 1); /* start of pixel data for row */
1492 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
1493  if (png_ptr->user_transform_depth)
1494  png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
1495  if (png_ptr->user_transform_channels)
1496  png_ptr->row_info.channels = png_ptr->user_transform_channels;
1497 #endif
1498  png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
1499  png_ptr->row_info.channels);
1500  png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
1501  png_ptr->row_info.width);
1502  }
1503 #endif
1504 
1505 }
1506 
1507 #if defined(PNG_READ_PACK_SUPPORTED)
1508 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1509  * without changing the actual values. Thus, if you had a row with
1510  * a bit depth of 1, you would end up with bytes that only contained
1511  * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1512  * png_do_shift() after this.
1513  */
1514 void /* PRIVATE */
1516 {
1517  png_debug(1, "in png_do_unpack\n");
1518 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1519  if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
1520 #else
1521  if (row_info->bit_depth < 8)
1522 #endif
1523  {
1524  png_uint_32 i;
1525  png_uint_32 row_width=row_info->width;
1526 
1527  switch (row_info->bit_depth)
1528  {
1529  case 1:
1530  {
1531  png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
1532  png_bytep dp = row + (png_size_t)row_width - 1;
1533  png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
1534  for (i = 0; i < row_width; i++)
1535  {
1536  *dp = (png_byte)((*sp >> shift) & 0x01);
1537  if (shift == 7)
1538  {
1539  shift = 0;
1540  sp--;
1541  }
1542  else
1543  shift++;
1544 
1545  dp--;
1546  }
1547  break;
1548  }
1549  case 2:
1550  {
1551 
1552  png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
1553  png_bytep dp = row + (png_size_t)row_width - 1;
1554  png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
1555  for (i = 0; i < row_width; i++)
1556  {
1557  *dp = (png_byte)((*sp >> shift) & 0x03);
1558  if (shift == 6)
1559  {
1560  shift = 0;
1561  sp--;
1562  }
1563  else
1564  shift += 2;
1565 
1566  dp--;
1567  }
1568  break;
1569  }
1570  case 4:
1571  {
1572  png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
1573  png_bytep dp = row + (png_size_t)row_width - 1;
1574  png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
1575  for (i = 0; i < row_width; i++)
1576  {
1577  *dp = (png_byte)((*sp >> shift) & 0x0f);
1578  if (shift == 4)
1579  {
1580  shift = 0;
1581  sp--;
1582  }
1583  else
1584  shift = 4;
1585 
1586  dp--;
1587  }
1588  break;
1589  }
1590  }
1591  row_info->bit_depth = 8;
1592  row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1593  row_info->rowbytes = row_width * row_info->channels;
1594  }
1595 }
1596 #endif
1597 
1598 #if defined(PNG_READ_SHIFT_SUPPORTED)
1599 /* Reverse the effects of png_do_shift. This routine merely shifts the
1600  * pixels back to their significant bits values. Thus, if you have
1601  * a row of bit depth 8, but only 5 are significant, this will shift
1602  * the values back to 0 through 31.
1603  */
1604 void /* PRIVATE */
1606 {
1607  png_debug(1, "in png_do_unshift\n");
1608  if (
1609 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1610  row != NULL && row_info != NULL && sig_bits != NULL &&
1611 #endif
1612  row_info->color_type != PNG_COLOR_TYPE_PALETTE)
1613  {
1614  int shift[4];
1615  int channels = 0;
1616  int c;
1617  png_uint_16 value = 0;
1618  png_uint_32 row_width = row_info->width;
1619 
1620  if (row_info->color_type & PNG_COLOR_MASK_COLOR)
1621  {
1622  shift[channels++] = row_info->bit_depth - sig_bits->red;
1623  shift[channels++] = row_info->bit_depth - sig_bits->green;
1624  shift[channels++] = row_info->bit_depth - sig_bits->blue;
1625  }
1626  else
1627  {
1628  shift[channels++] = row_info->bit_depth - sig_bits->gray;
1629  }
1630  if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
1631  {
1632  shift[channels++] = row_info->bit_depth - sig_bits->alpha;
1633  }
1634 
1635  for (c = 0; c < channels; c++)
1636  {
1637  if (shift[c] <= 0)
1638  shift[c] = 0;
1639  else
1640  value = 1;
1641  }
1642 
1643  if (!value)
1644  return;
1645 
1646  switch (row_info->bit_depth)
1647  {
1648  case 2:
1649  {
1650  png_bytep bp;
1651  png_uint_32 i;
1652  png_uint_32 istop = row_info->rowbytes;
1653 
1654  for (bp = row, i = 0; i < istop; i++)
1655  {
1656  *bp >>= 1;
1657  *bp++ &= 0x55;
1658  }
1659  break;
1660  }
1661  case 4:
1662  {
1663  png_bytep bp = row;
1664  png_uint_32 i;
1665  png_uint_32 istop = row_info->rowbytes;
1666  png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
1667  (png_byte)((int)0xf >> shift[0]));
1668 
1669  for (i = 0; i < istop; i++)
1670  {
1671  *bp >>= shift[0];
1672  *bp++ &= mask;
1673  }
1674  break;
1675  }
1676  case 8:
1677  {
1678  png_bytep bp = row;
1679  png_uint_32 i;
1680  png_uint_32 istop = row_width * channels;
1681 
1682  for (i = 0; i < istop; i++)
1683  {
1684  *bp++ >>= shift[i%channels];
1685  }
1686  break;
1687  }
1688  case 16:
1689  {
1690  png_bytep bp = row;
1691  png_uint_32 i;
1692  png_uint_32 istop = channels * row_width;
1693 
1694  for (i = 0; i < istop; i++)
1695  {
1696  value = (png_uint_16)((*bp << 8) + *(bp + 1));
1697  value >>= shift[i%channels];
1698  *bp++ = (png_byte)(value >> 8);
1699  *bp++ = (png_byte)(value & 0xff);
1700  }
1701  break;
1702  }
1703  }
1704  }
1705 }
1706 #endif
1707 
1708 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1709 /* chop rows of bit depth 16 down to 8 */
1710 void /* PRIVATE */
1712 {
1713  png_debug(1, "in png_do_chop\n");
1714 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1715  if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
1716 #else
1717  if (row_info->bit_depth == 16)
1718 #endif
1719  {
1720  png_bytep sp = row;
1721  png_bytep dp = row;
1722  png_uint_32 i;
1723  png_uint_32 istop = row_info->width * row_info->channels;
1724 
1725  for (i = 0; i<istop; i++, sp += 2, dp++)
1726  {
1727 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1728  /* This does a more accurate scaling of the 16-bit color
1729  * value, rather than a simple low-byte truncation.
1730  *
1731  * What the ideal calculation should be:
1732  * *dp = (((((png_uint_32)(*sp) << 8) |
1733  * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1734  *
1735  * GRR: no, I think this is what it really should be:
1736  * *dp = (((((png_uint_32)(*sp) << 8) |
1737  * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1738  *
1739  * GRR: here's the exact calculation with shifts:
1740  * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1741  * *dp = (temp - (temp >> 8)) >> 8;
1742  *
1743  * Approximate calculation with shift/add instead of multiply/divide:
1744  * *dp = ((((png_uint_32)(*sp) << 8) |
1745  * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1746  *
1747  * What we actually do to avoid extra shifting and conversion:
1748  */
1749 
1750  *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
1751 #else
1752  /* Simply discard the low order byte */
1753  *dp = *sp;
1754 #endif
1755  }
1756  row_info->bit_depth = 8;
1757  row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1758  row_info->rowbytes = row_info->width * row_info->channels;
1759  }
1760 }
1761 #endif
1762 
1763 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1764 void /* PRIVATE */
1766 {
1767  png_debug(1, "in png_do_read_swap_alpha\n");
1768 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1769  if (row != NULL && row_info != NULL)
1770 #endif
1771  {
1772  png_uint_32 row_width = row_info->width;
1773  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1774  {
1775  /* This converts from RGBA to ARGB */
1776  if (row_info->bit_depth == 8)
1777  {
1778  png_bytep sp = row + row_info->rowbytes;
1779  png_bytep dp = sp;
1780  png_byte save;
1781  png_uint_32 i;
1782 
1783  for (i = 0; i < row_width; i++)
1784  {
1785  save = *(--sp);
1786  *(--dp) = *(--sp);
1787  *(--dp) = *(--sp);
1788  *(--dp) = *(--sp);
1789  *(--dp) = save;
1790  }
1791  }
1792  /* This converts from RRGGBBAA to AARRGGBB */
1793  else
1794  {
1795  png_bytep sp = row + row_info->rowbytes;
1796  png_bytep dp = sp;
1797  png_byte save[2];
1798  png_uint_32 i;
1799 
1800  for (i = 0; i < row_width; i++)
1801  {
1802  save[0] = *(--sp);
1803  save[1] = *(--sp);
1804  *(--dp) = *(--sp);
1805  *(--dp) = *(--sp);
1806  *(--dp) = *(--sp);
1807  *(--dp) = *(--sp);
1808  *(--dp) = *(--sp);
1809  *(--dp) = *(--sp);
1810  *(--dp) = save[0];
1811  *(--dp) = save[1];
1812  }
1813  }
1814  }
1815  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1816  {
1817  /* This converts from GA to AG */
1818  if (row_info->bit_depth == 8)
1819  {
1820  png_bytep sp = row + row_info->rowbytes;
1821  png_bytep dp = sp;
1822  png_byte save;
1823  png_uint_32 i;
1824 
1825  for (i = 0; i < row_width; i++)
1826  {
1827  save = *(--sp);
1828  *(--dp) = *(--sp);
1829  *(--dp) = save;
1830  }
1831  }
1832  /* This converts from GGAA to AAGG */
1833  else
1834  {
1835  png_bytep sp = row + row_info->rowbytes;
1836  png_bytep dp = sp;
1837  png_byte save[2];
1838  png_uint_32 i;
1839 
1840  for (i = 0; i < row_width; i++)
1841  {
1842  save[0] = *(--sp);
1843  save[1] = *(--sp);
1844  *(--dp) = *(--sp);
1845  *(--dp) = *(--sp);
1846  *(--dp) = save[0];
1847  *(--dp) = save[1];
1848  }
1849  }
1850  }
1851  }
1852 }
1853 #endif
1854 
1855 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1856 void /* PRIVATE */
1858 {
1859  png_debug(1, "in png_do_read_invert_alpha\n");
1860 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1861  if (row != NULL && row_info != NULL)
1862 #endif
1863  {
1864  png_uint_32 row_width = row_info->width;
1865  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1866  {
1867  /* This inverts the alpha channel in RGBA */
1868  if (row_info->bit_depth == 8)
1869  {
1870  png_bytep sp = row + row_info->rowbytes;
1871  png_bytep dp = sp;
1872  png_uint_32 i;
1873 
1874  for (i = 0; i < row_width; i++)
1875  {
1876  *(--dp) = (png_byte)(255 - *(--sp));
1877 
1878 /* This does nothing:
1879  *(--dp) = *(--sp);
1880  *(--dp) = *(--sp);
1881  *(--dp) = *(--sp);
1882  We can replace it with:
1883 */
1884  sp-=3;
1885  dp=sp;
1886  }
1887  }
1888  /* This inverts the alpha channel in RRGGBBAA */
1889  else
1890  {
1891  png_bytep sp = row + row_info->rowbytes;
1892  png_bytep dp = sp;
1893  png_uint_32 i;
1894 
1895  for (i = 0; i < row_width; i++)
1896  {
1897  *(--dp) = (png_byte)(255 - *(--sp));
1898  *(--dp) = (png_byte)(255 - *(--sp));
1899 
1900 /* This does nothing:
1901  *(--dp) = *(--sp);
1902  *(--dp) = *(--sp);
1903  *(--dp) = *(--sp);
1904  *(--dp) = *(--sp);
1905  *(--dp) = *(--sp);
1906  *(--dp) = *(--sp);
1907  We can replace it with:
1908 */
1909  sp-=6;
1910  dp=sp;
1911  }
1912  }
1913  }
1914  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1915  {
1916  /* This inverts the alpha channel in GA */
1917  if (row_info->bit_depth == 8)
1918  {
1919  png_bytep sp = row + row_info->rowbytes;
1920  png_bytep dp = sp;
1921  png_uint_32 i;
1922 
1923  for (i = 0; i < row_width; i++)
1924  {
1925  *(--dp) = (png_byte)(255 - *(--sp));
1926  *(--dp) = *(--sp);
1927  }
1928  }
1929  /* This inverts the alpha channel in GGAA */
1930  else
1931  {
1932  png_bytep sp = row + row_info->rowbytes;
1933  png_bytep dp = sp;
1934  png_uint_32 i;
1935 
1936  for (i = 0; i < row_width; i++)
1937  {
1938  *(--dp) = (png_byte)(255 - *(--sp));
1939  *(--dp) = (png_byte)(255 - *(--sp));
1940 /*
1941  *(--dp) = *(--sp);
1942  *(--dp) = *(--sp);
1943 */
1944  sp-=2;
1945  dp=sp;
1946  }
1947  }
1948  }
1949  }
1950 }
1951 #endif
1952 
1953 #if defined(PNG_READ_FILLER_SUPPORTED)
1954 /* Add filler channel if we have RGB color */
1955 void /* PRIVATE */
1958 {
1959  png_uint_32 i;
1960  png_uint_32 row_width = row_info->width;
1961 
1962  png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
1963  png_byte lo_filler = (png_byte)(filler & 0xff);
1964 
1965  png_debug(1, "in png_do_read_filler\n");
1966  if (
1967 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1968  row != NULL && row_info != NULL &&
1969 #endif
1970  row_info->color_type == PNG_COLOR_TYPE_GRAY)
1971  {
1972  if (row_info->bit_depth == 8)
1973  {
1974  /* This changes the data from G to GX */
1975  if (flags & PNG_FLAG_FILLER_AFTER)
1976  {
1977  png_bytep sp = row + (png_size_t)row_width;
1978  png_bytep dp = sp + (png_size_t)row_width;
1979  for (i = 1; i < row_width; i++)
1980  {
1981  *(--dp) = lo_filler;
1982  *(--dp) = *(--sp);
1983  }
1984  *(--dp) = lo_filler;
1985  row_info->channels = 2;
1986  row_info->pixel_depth = 16;
1987  row_info->rowbytes = row_width * 2;
1988  }
1989  /* This changes the data from G to XG */
1990  else
1991  {
1992  png_bytep sp = row + (png_size_t)row_width;
1993  png_bytep dp = sp + (png_size_t)row_width;
1994  for (i = 0; i < row_width; i++)
1995  {
1996  *(--dp) = *(--sp);
1997  *(--dp) = lo_filler;
1998  }
1999  row_info->channels = 2;
2000  row_info->pixel_depth = 16;
2001  row_info->rowbytes = row_width * 2;
2002  }
2003  }
2004  else if (row_info->bit_depth == 16)
2005  {
2006  /* This changes the data from GG to GGXX */
2007  if (flags & PNG_FLAG_FILLER_AFTER)
2008  {
2009  png_bytep sp = row + (png_size_t)row_width * 2;
2010  png_bytep dp = sp + (png_size_t)row_width * 2;
2011  for (i = 1; i < row_width; i++)
2012  {
2013  *(--dp) = hi_filler;
2014  *(--dp) = lo_filler;
2015  *(--dp) = *(--sp);
2016  *(--dp) = *(--sp);
2017  }
2018  *(--dp) = hi_filler;
2019  *(--dp) = lo_filler;
2020  row_info->channels = 2;
2021  row_info->pixel_depth = 32;
2022  row_info->rowbytes = row_width * 4;
2023  }
2024  /* This changes the data from GG to XXGG */
2025  else
2026  {
2027  png_bytep sp = row + (png_size_t)row_width * 2;
2028  png_bytep dp = sp + (png_size_t)row_width * 2;
2029  for (i = 0; i < row_width; i++)
2030  {
2031  *(--dp) = *(--sp);
2032  *(--dp) = *(--sp);
2033  *(--dp) = hi_filler;
2034  *(--dp) = lo_filler;
2035  }
2036  row_info->channels = 2;
2037  row_info->pixel_depth = 32;
2038  row_info->rowbytes = row_width * 4;
2039  }
2040  }
2041  } /* COLOR_TYPE == GRAY */
2042  else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2043  {
2044  if (row_info->bit_depth == 8)
2045  {
2046  /* This changes the data from RGB to RGBX */
2047  if (flags & PNG_FLAG_FILLER_AFTER)
2048  {
2049  png_bytep sp = row + (png_size_t)row_width * 3;
2050  png_bytep dp = sp + (png_size_t)row_width;
2051  for (i = 1; i < row_width; i++)
2052  {
2053  *(--dp) = lo_filler;
2054  *(--dp) = *(--sp);
2055  *(--dp) = *(--sp);
2056  *(--dp) = *(--sp);
2057  }
2058  *(--dp) = lo_filler;
2059  row_info->channels = 4;
2060  row_info->pixel_depth = 32;
2061  row_info->rowbytes = row_width * 4;
2062  }
2063  /* This changes the data from RGB to XRGB */
2064  else
2065  {
2066  png_bytep sp = row + (png_size_t)row_width * 3;
2067  png_bytep dp = sp + (png_size_t)row_width;
2068  for (i = 0; i < row_width; i++)
2069  {
2070  *(--dp) = *(--sp);
2071  *(--dp) = *(--sp);
2072  *(--dp) = *(--sp);
2073  *(--dp) = lo_filler;
2074  }
2075  row_info->channels = 4;
2076  row_info->pixel_depth = 32;
2077  row_info->rowbytes = row_width * 4;
2078  }
2079  }
2080  else if (row_info->bit_depth == 16)
2081  {
2082  /* This changes the data from RRGGBB to RRGGBBXX */
2083  if (flags & PNG_FLAG_FILLER_AFTER)
2084  {
2085  png_bytep sp = row + (png_size_t)row_width * 6;
2086  png_bytep dp = sp + (png_size_t)row_width * 2;
2087  for (i = 1; i < row_width; i++)
2088  {
2089  *(--dp) = hi_filler;
2090  *(--dp) = lo_filler;
2091  *(--dp) = *(--sp);
2092  *(--dp) = *(--sp);
2093  *(--dp) = *(--sp);
2094  *(--dp) = *(--sp);
2095  *(--dp) = *(--sp);
2096  *(--dp) = *(--sp);
2097  }
2098  *(--dp) = hi_filler;
2099  *(--dp) = lo_filler;
2100  row_info->channels = 4;
2101  row_info->pixel_depth = 64;
2102  row_info->rowbytes = row_width * 8;
2103  }
2104  /* This changes the data from RRGGBB to XXRRGGBB */
2105  else
2106  {
2107  png_bytep sp = row + (png_size_t)row_width * 6;
2108  png_bytep dp = sp + (png_size_t)row_width * 2;
2109  for (i = 0; i < row_width; i++)
2110  {
2111  *(--dp) = *(--sp);
2112  *(--dp) = *(--sp);
2113  *(--dp) = *(--sp);
2114  *(--dp) = *(--sp);
2115  *(--dp) = *(--sp);
2116  *(--dp) = *(--sp);
2117  *(--dp) = hi_filler;
2118  *(--dp) = lo_filler;
2119  }
2120  row_info->channels = 4;
2121  row_info->pixel_depth = 64;
2122  row_info->rowbytes = row_width * 8;
2123  }
2124  }
2125  } /* COLOR_TYPE == RGB */
2126 }
2127 #endif
2128 
2129 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2130 /* expand grayscale files to RGB, with or without alpha */
2131 void /* PRIVATE */
2133 {
2134  png_uint_32 i;
2135  png_uint_32 row_width = row_info->width;
2136 
2137  png_debug(1, "in png_do_gray_to_rgb\n");
2138  if (row_info->bit_depth >= 8 &&
2139 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2140  row != NULL && row_info != NULL &&
2141 #endif
2142  !(row_info->color_type & PNG_COLOR_MASK_COLOR))
2143  {
2144  if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2145  {
2146  if (row_info->bit_depth == 8)
2147  {
2148  png_bytep sp = row + (png_size_t)row_width - 1;
2149  png_bytep dp = sp + (png_size_t)row_width * 2;
2150  for (i = 0; i < row_width; i++)
2151  {
2152  *(dp--) = *sp;
2153  *(dp--) = *sp;
2154  *(dp--) = *(sp--);
2155  }
2156  }
2157  else
2158  {
2159  png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2160  png_bytep dp = sp + (png_size_t)row_width * 4;
2161  for (i = 0; i < row_width; i++)
2162  {
2163  *(dp--) = *sp;
2164  *(dp--) = *(sp - 1);
2165  *(dp--) = *sp;
2166  *(dp--) = *(sp - 1);
2167  *(dp--) = *(sp--);
2168  *(dp--) = *(sp--);
2169  }
2170  }
2171  }
2172  else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2173  {
2174  if (row_info->bit_depth == 8)
2175  {
2176  png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2177  png_bytep dp = sp + (png_size_t)row_width * 2;
2178  for (i = 0; i < row_width; i++)
2179  {
2180  *(dp--) = *(sp--);
2181  *(dp--) = *sp;
2182  *(dp--) = *sp;
2183  *(dp--) = *(sp--);
2184  }
2185  }
2186  else
2187  {
2188  png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2189  png_bytep dp = sp + (png_size_t)row_width * 4;
2190  for (i = 0; i < row_width; i++)
2191  {
2192  *(dp--) = *(sp--);
2193  *(dp--) = *(sp--);
2194  *(dp--) = *sp;
2195  *(dp--) = *(sp - 1);
2196  *(dp--) = *sp;
2197  *(dp--) = *(sp - 1);
2198  *(dp--) = *(sp--);
2199  *(dp--) = *(sp--);
2200  }
2201  }
2202  }
2203  row_info->channels += (png_byte)2;
2204  row_info->color_type |= PNG_COLOR_MASK_COLOR;
2205  row_info->pixel_depth = (png_byte)(row_info->channels *
2206  row_info->bit_depth);
2207  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2208  }
2209 }
2210 #endif
2211 
2212 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2213 /* reduce RGB files to grayscale, with or without alpha
2214  * using the equation given in Poynton's ColorFAQ at
2215  * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008)
2216  * New link:
2217  * <http://www.poynton.com/notes/colour_and_gamma/>
2218  * Charles Poynton poynton at poynton.com
2219  *
2220  * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2221  *
2222  * We approximate this with
2223  *
2224  * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
2225  *
2226  * which can be expressed with integers as
2227  *
2228  * Y = (6969 * R + 23434 * G + 2365 * B)/32768
2229  *
2230  * The calculation is to be done in a linear colorspace.
2231  *
2232  * Other integer coefficents can be used via png_set_rgb_to_gray().
2233  */
2234 int /* PRIVATE */
2236 
2237 {
2238  png_uint_32 i;
2239 
2240  png_uint_32 row_width = row_info->width;
2241  int rgb_error = 0;
2242 
2243  png_debug(1, "in png_do_rgb_to_gray\n");
2244  if (
2245 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2246  row != NULL && row_info != NULL &&
2247 #endif
2248  (row_info->color_type & PNG_COLOR_MASK_COLOR))
2249  {
2250  png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
2251  png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
2252  png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
2253 
2254  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2255  {
2256  if (row_info->bit_depth == 8)
2257  {
2258 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2259  if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2260  {
2261  png_bytep sp = row;
2262  png_bytep dp = row;
2263 
2264  for (i = 0; i < row_width; i++)
2265  {
2266  png_byte red = png_ptr->gamma_to_1[*(sp++)];
2267  png_byte green = png_ptr->gamma_to_1[*(sp++)];
2268  png_byte blue = png_ptr->gamma_to_1[*(sp++)];
2269  if (red != green || red != blue)
2270  {
2271  rgb_error |= 1;
2272  *(dp++) = png_ptr->gamma_from_1[
2273  (rc*red + gc*green + bc*blue)>>15];
2274  }
2275  else
2276  *(dp++) = *(sp - 1);
2277  }
2278  }
2279  else
2280 #endif
2281  {
2282  png_bytep sp = row;
2283  png_bytep dp = row;
2284  for (i = 0; i < row_width; i++)
2285  {
2286  png_byte red = *(sp++);
2287  png_byte green = *(sp++);
2288  png_byte blue = *(sp++);
2289  if (red != green || red != blue)
2290  {
2291  rgb_error |= 1;
2292  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
2293  }
2294  else
2295  *(dp++) = *(sp - 1);
2296  }
2297  }
2298  }
2299 
2300  else /* RGB bit_depth == 16 */
2301  {
2302 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2303  if (png_ptr->gamma_16_to_1 != NULL &&
2304  png_ptr->gamma_16_from_1 != NULL)
2305  {
2306  png_bytep sp = row;
2307  png_bytep dp = row;
2308  for (i = 0; i < row_width; i++)
2309  {
2310  png_uint_16 red, green, blue, w;
2311 
2312  red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2313  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2314  blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2315 
2316  if (red == green && red == blue)
2317  w = red;
2318  else
2319  {
2320  png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
2321  png_ptr->gamma_shift][red>>8];
2322  png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
2323  png_ptr->gamma_shift][green>>8];
2324  png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
2325  png_ptr->gamma_shift][blue>>8];
2326  png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
2327  + bc*blue_1)>>15);
2328  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2329  png_ptr->gamma_shift][gray16 >> 8];
2330  rgb_error |= 1;
2331  }
2332 
2333  *(dp++) = (png_byte)((w>>8) & 0xff);
2334  *(dp++) = (png_byte)(w & 0xff);
2335  }
2336  }
2337  else
2338 #endif
2339  {
2340  png_bytep sp = row;
2341  png_bytep dp = row;
2342  for (i = 0; i < row_width; i++)
2343  {
2344  png_uint_16 red, green, blue, gray16;
2345 
2346  red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2347  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2348  blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2349 
2350  if (red != green || red != blue)
2351  rgb_error |= 1;
2352  gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2353  *(dp++) = (png_byte)((gray16>>8) & 0xff);
2354  *(dp++) = (png_byte)(gray16 & 0xff);
2355  }
2356  }
2357  }
2358  }
2359  if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2360  {
2361  if (row_info->bit_depth == 8)
2362  {
2363 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2364  if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2365  {
2366  png_bytep sp = row;
2367  png_bytep dp = row;
2368  for (i = 0; i < row_width; i++)
2369  {
2370  png_byte red = png_ptr->gamma_to_1[*(sp++)];
2371  png_byte green = png_ptr->gamma_to_1[*(sp++)];
2372  png_byte blue = png_ptr->gamma_to_1[*(sp++)];
2373  if (red != green || red != blue)
2374  rgb_error |= 1;
2375  *(dp++) = png_ptr->gamma_from_1
2376  [(rc*red + gc*green + bc*blue)>>15];
2377  *(dp++) = *(sp++); /* alpha */
2378  }
2379  }
2380  else
2381 #endif
2382  {
2383  png_bytep sp = row;
2384  png_bytep dp = row;
2385  for (i = 0; i < row_width; i++)
2386  {
2387  png_byte red = *(sp++);
2388  png_byte green = *(sp++);
2389  png_byte blue = *(sp++);
2390  if (red != green || red != blue)
2391  rgb_error |= 1;
2392  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
2393  *(dp++) = *(sp++); /* alpha */
2394  }
2395  }
2396  }
2397  else /* RGBA bit_depth == 16 */
2398  {
2399 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2400  if (png_ptr->gamma_16_to_1 != NULL &&
2401  png_ptr->gamma_16_from_1 != NULL)
2402  {
2403  png_bytep sp = row;
2404  png_bytep dp = row;
2405  for (i = 0; i < row_width; i++)
2406  {
2407  png_uint_16 red, green, blue, w;
2408 
2409  red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2410  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2411  blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2412 
2413  if (red == green && red == blue)
2414  w = red;
2415  else
2416  {
2417  png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
2418  png_ptr->gamma_shift][red>>8];
2419  png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
2420  png_ptr->gamma_shift][green>>8];
2421  png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
2422  png_ptr->gamma_shift][blue>>8];
2423  png_uint_16 gray16 = (png_uint_16)((rc * red_1
2424  + gc * green_1 + bc * blue_1)>>15);
2425  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2426  png_ptr->gamma_shift][gray16 >> 8];
2427  rgb_error |= 1;
2428  }
2429 
2430  *(dp++) = (png_byte)((w>>8) & 0xff);
2431  *(dp++) = (png_byte)(w & 0xff);
2432  *(dp++) = *(sp++); /* alpha */
2433  *(dp++) = *(sp++);
2434  }
2435  }
2436  else
2437 #endif
2438  {
2439  png_bytep sp = row;
2440  png_bytep dp = row;
2441  for (i = 0; i < row_width; i++)
2442  {
2443  png_uint_16 red, green, blue, gray16;
2444  red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2445  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2446  blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2447  if (red != green || red != blue)
2448  rgb_error |= 1;
2449  gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2450  *(dp++) = (png_byte)((gray16>>8) & 0xff);
2451  *(dp++) = (png_byte)(gray16 & 0xff);
2452  *(dp++) = *(sp++); /* alpha */
2453  *(dp++) = *(sp++);
2454  }
2455  }
2456  }
2457  }
2458  row_info->channels -= (png_byte)2;
2459  row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
2460  row_info->pixel_depth = (png_byte)(row_info->channels *
2461  row_info->bit_depth);
2462  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2463  }
2464  return rgb_error;
2465 }
2466 #endif
2467 
2468 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
2469  * large of png_color. This lets grayscale images be treated as
2470  * paletted. Most useful for gamma correction and simplification
2471  * of code.
2472  */
2473 void PNGAPI
2475 {
2476  int num_palette;
2477  int color_inc;
2478  int i;
2479  int v;
2480 
2481  png_debug(1, "in png_do_build_grayscale_palette\n");
2482  if (palette == NULL)
2483  return;
2484 
2485  switch (bit_depth)
2486  {
2487  case 1:
2488  num_palette = 2;
2489  color_inc = 0xff;
2490  break;
2491  case 2:
2492  num_palette = 4;
2493  color_inc = 0x55;
2494  break;
2495  case 4:
2496  num_palette = 16;
2497  color_inc = 0x11;
2498  break;
2499  case 8:
2500  num_palette = 256;
2501  color_inc = 1;
2502  break;
2503  default:
2504  num_palette = 0;
2505  color_inc = 0;
2506  break;
2507  }
2508 
2509  for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
2510  {
2511  palette[i].red = (png_byte)v;
2512  palette[i].green = (png_byte)v;
2513  palette[i].blue = (png_byte)v;
2514  }
2515 }
2516 
2517 /* This function is currently unused. Do we really need it? */
2518 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2519 void /* PRIVATE */
2520 png_correct_palette(png_structp png_ptr, png_colorp palette,
2521  int num_palette)
2522 {
2523  png_debug(1, "in png_correct_palette\n");
2524 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2525  defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2526  if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
2527  {
2528  png_color back, back_1;
2529 
2530  if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
2531  {
2532  back.red = png_ptr->gamma_table[png_ptr->background.red];
2533  back.green = png_ptr->gamma_table[png_ptr->background.green];
2534  back.blue = png_ptr->gamma_table[png_ptr->background.blue];
2535 
2536  back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
2537  back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
2538  back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
2539  }
2540  else
2541  {
2542  double g;
2543 
2544  g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
2545 
2546  if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
2547  fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
2548  {
2549  back.red = png_ptr->background.red;
2550  back.green = png_ptr->background.green;
2551  back.blue = png_ptr->background.blue;
2552  }
2553  else
2554  {
2555  back.red =
2556  (png_byte)(pow((double)png_ptr->background.red/255, g) *
2557  255.0 + 0.5);
2558  back.green =
2559  (png_byte)(pow((double)png_ptr->background.green/255, g) *
2560  255.0 + 0.5);
2561  back.blue =
2562  (png_byte)(pow((double)png_ptr->background.blue/255, g) *
2563  255.0 + 0.5);
2564  }
2565 
2566  g = 1.0 / png_ptr->background_gamma;
2567 
2568  back_1.red =
2569  (png_byte)(pow((double)png_ptr->background.red/255, g) *
2570  255.0 + 0.5);
2571  back_1.green =
2572  (png_byte)(pow((double)png_ptr->background.green/255, g) *
2573  255.0 + 0.5);
2574  back_1.blue =
2575  (png_byte)(pow((double)png_ptr->background.blue/255, g) *
2576  255.0 + 0.5);
2577  }
2578 
2579  if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2580  {
2581  png_uint_32 i;
2582 
2583  for (i = 0; i < (png_uint_32)num_palette; i++)
2584  {
2585  if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
2586  {
2587  palette[i] = back;
2588  }
2589  else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
2590  {
2591  png_byte v, w;
2592 
2593  v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
2594  png_composite(w, v, png_ptr->trans[i], back_1.red);
2595  palette[i].red = png_ptr->gamma_from_1[w];
2596 
2597  v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
2598  png_composite(w, v, png_ptr->trans[i], back_1.green);
2599  palette[i].green = png_ptr->gamma_from_1[w];
2600 
2601  v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
2602  png_composite(w, v, png_ptr->trans[i], back_1.blue);
2603  palette[i].blue = png_ptr->gamma_from_1[w];
2604  }
2605  else
2606  {
2607  palette[i].red = png_ptr->gamma_table[palette[i].red];
2608  palette[i].green = png_ptr->gamma_table[palette[i].green];
2609  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2610  }
2611  }
2612  }
2613  else
2614  {
2615  int i;
2616 
2617  for (i = 0; i < num_palette; i++)
2618  {
2619  if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
2620  {
2621  palette[i] = back;
2622  }
2623  else
2624  {
2625  palette[i].red = png_ptr->gamma_table[palette[i].red];
2626  palette[i].green = png_ptr->gamma_table[palette[i].green];
2627  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2628  }
2629  }
2630  }
2631  }
2632  else
2633 #endif
2634 #if defined(PNG_READ_GAMMA_SUPPORTED)
2635  if (png_ptr->transformations & PNG_GAMMA)
2636  {
2637  int i;
2638 
2639  for (i = 0; i < num_palette; i++)
2640  {
2641  palette[i].red = png_ptr->gamma_table[palette[i].red];
2642  palette[i].green = png_ptr->gamma_table[palette[i].green];
2643  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2644  }
2645  }
2646 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2647  else
2648 #endif
2649 #endif
2650 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2651  if (png_ptr->transformations & PNG_BACKGROUND)
2652  {
2653  if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2654  {
2655  png_color back;
2656 
2657  back.red = (png_byte)png_ptr->background.red;
2658  back.green = (png_byte)png_ptr->background.green;
2659  back.blue = (png_byte)png_ptr->background.blue;
2660 
2661  for (i = 0; i < (int)png_ptr->num_trans; i++)
2662  {
2663  if (png_ptr->trans[i] == 0)
2664  {
2665  palette[i].red = back.red;
2666  palette[i].green = back.green;
2667  palette[i].blue = back.blue;
2668  }
2669  else if (png_ptr->trans[i] != 0xff)
2670  {
2671  png_composite(palette[i].red, png_ptr->palette[i].red,
2672  png_ptr->trans[i], back.red);
2673  png_composite(palette[i].green, png_ptr->palette[i].green,
2674  png_ptr->trans[i], back.green);
2675  png_composite(palette[i].blue, png_ptr->palette[i].blue,
2676  png_ptr->trans[i], back.blue);
2677  }
2678  }
2679  }
2680  else /* assume grayscale palette (what else could it be?) */
2681  {
2682  int i;
2683 
2684  for (i = 0; i < num_palette; i++)
2685  {
2686  if (i == (png_byte)png_ptr->trans_values.gray)
2687  {
2688  palette[i].red = (png_byte)png_ptr->background.red;
2689  palette[i].green = (png_byte)png_ptr->background.green;
2690  palette[i].blue = (png_byte)png_ptr->background.blue;
2691  }
2692  }
2693  }
2694  }
2695 #endif
2696 }
2697 #endif
2698 
2699 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
2700 /* Replace any alpha or transparency with the supplied background color.
2701  * "background" is already in the screen gamma, while "background_1" is
2702  * at a gamma of 1.0. Paletted files have already been taken care of.
2703  */
2704 void /* PRIVATE */
2707 #if defined(PNG_READ_GAMMA_SUPPORTED)
2708  , png_color_16p background_1,
2709  png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
2710  png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
2711  png_uint_16pp gamma_16_to_1, int gamma_shift
2712 #endif
2713  )
2714 {
2715  png_bytep sp, dp;
2716  png_uint_32 i;
2717  png_uint_32 row_width=row_info->width;
2718  int shift;
2719 
2720  png_debug(1, "in png_do_background\n");
2721  if (background != NULL &&
2722 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2723  row != NULL && row_info != NULL &&
2724 #endif
2725  (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
2726  (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
2727  {
2728  switch (row_info->color_type)
2729  {
2730  case PNG_COLOR_TYPE_GRAY:
2731  {
2732  switch (row_info->bit_depth)
2733  {
2734  case 1:
2735  {
2736  sp = row;
2737  shift = 7;
2738  for (i = 0; i < row_width; i++)
2739  {
2740  if ((png_uint_16)((*sp >> shift) & 0x01)
2741  == trans_values->gray)
2742  {
2743  *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2744  *sp |= (png_byte)(background->gray << shift);
2745  }
2746  if (!shift)
2747  {
2748  shift = 7;
2749  sp++;
2750  }
2751  else
2752  shift--;
2753  }
2754  break;
2755  }
2756  case 2:
2757  {
2758 #if defined(PNG_READ_GAMMA_SUPPORTED)
2759  if (gamma_table != NULL)
2760  {
2761  sp = row;
2762  shift = 6;
2763  for (i = 0; i < row_width; i++)
2764  {
2765  if ((png_uint_16)((*sp >> shift) & 0x03)
2766  == trans_values->gray)
2767  {
2768  *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2769  *sp |= (png_byte)(background->gray << shift);
2770  }
2771  else
2772  {
2773  png_byte p = (png_byte)((*sp >> shift) & 0x03);
2774  png_byte g = (png_byte)((gamma_table [p | (p << 2) |
2775  (p << 4) | (p << 6)] >> 6) & 0x03);
2776  *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2777  *sp |= (png_byte)(g << shift);
2778  }
2779  if (!shift)
2780  {
2781  shift = 6;
2782  sp++;
2783  }
2784  else
2785  shift -= 2;
2786  }
2787  }
2788  else
2789 #endif
2790  {
2791  sp = row;
2792  shift = 6;
2793  for (i = 0; i < row_width; i++)
2794  {
2795  if ((png_uint_16)((*sp >> shift) & 0x03)
2796  == trans_values->gray)
2797  {
2798  *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2799  *sp |= (png_byte)(background->gray << shift);
2800  }
2801  if (!shift)
2802  {
2803  shift = 6;
2804  sp++;
2805  }
2806  else
2807  shift -= 2;
2808  }
2809  }
2810  break;
2811  }
2812  case 4:
2813  {
2814 #if defined(PNG_READ_GAMMA_SUPPORTED)
2815  if (gamma_table != NULL)
2816  {
2817  sp = row;
2818  shift = 4;
2819  for (i = 0; i < row_width; i++)
2820  {
2821  if ((png_uint_16)((*sp >> shift) & 0x0f)
2822  == trans_values->gray)
2823  {
2824  *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2825  *sp |= (png_byte)(background->gray << shift);
2826  }
2827  else
2828  {
2829  png_byte p = (png_byte)((*sp >> shift) & 0x0f);
2830  png_byte g = (png_byte)((gamma_table[p |
2831  (p << 4)] >> 4) & 0x0f);
2832  *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2833  *sp |= (png_byte)(g << shift);
2834  }
2835  if (!shift)
2836  {
2837  shift = 4;
2838  sp++;
2839  }
2840  else
2841  shift -= 4;
2842  }
2843  }
2844  else
2845 #endif
2846  {
2847  sp = row;
2848  shift = 4;
2849  for (i = 0; i < row_width; i++)
2850  {
2851  if ((png_uint_16)((*sp >> shift) & 0x0f)
2852  == trans_values->gray)
2853  {
2854  *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2855  *sp |= (png_byte)(background->gray << shift);
2856  }
2857  if (!shift)
2858  {
2859  shift = 4;
2860  sp++;
2861  }
2862  else
2863  shift -= 4;
2864  }
2865  }
2866  break;
2867  }
2868  case 8:
2869  {
2870 #if defined(PNG_READ_GAMMA_SUPPORTED)
2871  if (gamma_table != NULL)
2872  {
2873  sp = row;
2874  for (i = 0; i < row_width; i++, sp++)
2875  {
2876  if (*sp == trans_values->gray)
2877  {
2878  *sp = (png_byte)background->gray;
2879  }
2880  else
2881  {
2882  *sp = gamma_table[*sp];
2883  }
2884  }
2885  }
2886  else
2887 #endif
2888  {
2889  sp = row;
2890  for (i = 0; i < row_width; i++, sp++)
2891  {
2892  if (*sp == trans_values->gray)
2893  {
2894  *sp = (png_byte)background->gray;
2895  }
2896  }
2897  }
2898  break;
2899  }
2900  case 16:
2901  {
2902 #if defined(PNG_READ_GAMMA_SUPPORTED)
2903  if (gamma_16 != NULL)
2904  {
2905  sp = row;
2906  for (i = 0; i < row_width; i++, sp += 2)
2907  {
2908  png_uint_16 v;
2909 
2910  v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2911  if (v == trans_values->gray)
2912  {
2913  /* background is already in screen gamma */
2914  *sp = (png_byte)((background->gray >> 8) & 0xff);
2915  *(sp + 1) = (png_byte)(background->gray & 0xff);
2916  }
2917  else
2918  {
2919  v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
2920  *sp = (png_byte)((v >> 8) & 0xff);
2921  *(sp + 1) = (png_byte)(v & 0xff);
2922  }
2923  }
2924  }
2925  else
2926 #endif
2927  {
2928  sp = row;
2929  for (i = 0; i < row_width; i++, sp += 2)
2930  {
2931  png_uint_16 v;
2932 
2933  v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2934  if (v == trans_values->gray)
2935  {
2936  *sp = (png_byte)((background->gray >> 8) & 0xff);
2937  *(sp + 1) = (png_byte)(background->gray & 0xff);
2938  }
2939  }
2940  }
2941  break;
2942  }
2943  }
2944  break;
2945  }
2946  case PNG_COLOR_TYPE_RGB:
2947  {
2948  if (row_info->bit_depth == 8)
2949  {
2950 #if defined(PNG_READ_GAMMA_SUPPORTED)
2951  if (gamma_table != NULL)
2952  {
2953  sp = row;
2954  for (i = 0; i < row_width; i++, sp += 3)
2955  {
2956  if (*sp == trans_values->red &&
2957  *(sp + 1) == trans_values->green &&
2958  *(sp + 2) == trans_values->blue)
2959  {
2960  *sp = (png_byte)background->red;
2961  *(sp + 1) = (png_byte)background->green;
2962  *(sp + 2) = (png_byte)background->blue;
2963  }
2964  else
2965  {
2966  *sp = gamma_table[*sp];
2967  *(sp + 1) = gamma_table[*(sp + 1)];
2968  *(sp + 2) = gamma_table[*(sp + 2)];
2969  }
2970  }
2971  }
2972  else
2973 #endif
2974  {
2975  sp = row;
2976  for (i = 0; i < row_width; i++, sp += 3)
2977  {
2978  if (*sp == trans_values->red &&
2979  *(sp + 1) == trans_values->green &&
2980  *(sp + 2) == trans_values->blue)
2981  {
2982  *sp = (png_byte)background->red;
2983  *(sp + 1) = (png_byte)background->green;
2984  *(sp + 2) = (png_byte)background->blue;
2985  }
2986  }
2987  }
2988  }
2989  else /* if (row_info->bit_depth == 16) */
2990  {
2991 #if defined(PNG_READ_GAMMA_SUPPORTED)
2992  if (gamma_16 != NULL)
2993  {
2994  sp = row;
2995  for (i = 0; i < row_width; i++, sp += 6)
2996  {
2997  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2998  png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
2999  png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
3000  if (r == trans_values->red && g == trans_values->green &&
3001  b == trans_values->blue)
3002  {
3003  /* background is already in screen gamma */
3004  *sp = (png_byte)((background->red >> 8) & 0xff);
3005  *(sp + 1) = (png_byte)(background->red & 0xff);
3006  *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
3007  *(sp + 3) = (png_byte)(background->green & 0xff);
3008  *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3009  *(sp + 5) = (png_byte)(background->blue & 0xff);
3010  }
3011  else
3012  {
3013  png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3014  *sp = (png_byte)((v >> 8) & 0xff);
3015  *(sp + 1) = (png_byte)(v & 0xff);
3016  v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3017  *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3018  *(sp + 3) = (png_byte)(v & 0xff);
3019  v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3020  *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3021  *(sp + 5) = (png_byte)(v & 0xff);
3022  }
3023  }
3024  }
3025  else
3026 #endif
3027  {
3028  sp = row;
3029  for (i = 0; i < row_width; i++, sp += 6)
3030  {
3031  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
3032  png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3033  png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
3034 
3035  if (r == trans_values->red && g == trans_values->green &&
3036  b == trans_values->blue)
3037  {
3038  *sp = (png_byte)((background->red >> 8) & 0xff);
3039  *(sp + 1) = (png_byte)(background->red & 0xff);
3040  *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
3041  *(sp + 3) = (png_byte)(background->green & 0xff);
3042  *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3043  *(sp + 5) = (png_byte)(background->blue & 0xff);
3044  }
3045  }
3046  }
3047  }
3048  break;
3049  }
3051  {
3052  if (row_info->bit_depth == 8)
3053  {
3054 #if defined(PNG_READ_GAMMA_SUPPORTED)
3055  if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3056  gamma_table != NULL)
3057  {
3058  sp = row;
3059  dp = row;
3060  for (i = 0; i < row_width; i++, sp += 2, dp++)
3061  {
3062  png_uint_16 a = *(sp + 1);
3063 
3064  if (a == 0xff)
3065  {
3066  *dp = gamma_table[*sp];
3067  }
3068  else if (a == 0)
3069  {
3070  /* background is already in screen gamma */
3071  *dp = (png_byte)background->gray;
3072  }
3073  else
3074  {
3075  png_byte v, w;
3076 
3077  v = gamma_to_1[*sp];
3078  png_composite(w, v, a, background_1->gray);
3079  *dp = gamma_from_1[w];
3080  }
3081  }
3082  }
3083  else
3084 #endif
3085  {
3086  sp = row;
3087  dp = row;
3088  for (i = 0; i < row_width; i++, sp += 2, dp++)
3089  {
3090  png_byte a = *(sp + 1);
3091 
3092  if (a == 0xff)
3093  {
3094  *dp = *sp;
3095  }
3096 #if defined(PNG_READ_GAMMA_SUPPORTED)
3097  else if (a == 0)
3098  {
3099  *dp = (png_byte)background->gray;
3100  }
3101  else
3102  {
3103  png_composite(*dp, *sp, a, background_1->gray);
3104  }
3105 #else
3106  *dp = (png_byte)background->gray;
3107 #endif
3108  }
3109  }
3110  }
3111  else /* if (png_ptr->bit_depth == 16) */
3112  {
3113 #if defined(PNG_READ_GAMMA_SUPPORTED)
3114  if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3115  gamma_16_to_1 != NULL)
3116  {
3117  sp = row;
3118  dp = row;
3119  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
3120  {
3121  png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3122 
3123  if (a == (png_uint_16)0xffff)
3124  {
3125  png_uint_16 v;
3126 
3127  v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3128  *dp = (png_byte)((v >> 8) & 0xff);
3129  *(dp + 1) = (png_byte)(v & 0xff);
3130  }
3131 #if defined(PNG_READ_GAMMA_SUPPORTED)
3132  else if (a == 0)
3133 #else
3134  else
3135 #endif
3136  {
3137  /* background is already in screen gamma */
3138  *dp = (png_byte)((background->gray >> 8) & 0xff);
3139  *(dp + 1) = (png_byte)(background->gray & 0xff);
3140  }
3141 #if defined(PNG_READ_GAMMA_SUPPORTED)
3142  else
3143  {
3144  png_uint_16 g, v, w;
3145 
3146  g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3147  png_composite_16(v, g, a, background_1->gray);
3148  w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
3149  *dp = (png_byte)((w >> 8) & 0xff);
3150  *(dp + 1) = (png_byte)(w & 0xff);
3151  }
3152 #endif
3153  }
3154  }
3155  else
3156 #endif
3157  {
3158  sp = row;
3159  dp = row;
3160  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
3161  {
3162  png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3163  if (a == (png_uint_16)0xffff)
3164  {
3165  png_memcpy(dp, sp, 2);
3166  }
3167 #if defined(PNG_READ_GAMMA_SUPPORTED)
3168  else if (a == 0)
3169 #else
3170  else
3171 #endif
3172  {
3173  *dp = (png_byte)((background->gray >> 8) & 0xff);
3174  *(dp + 1) = (png_byte)(background->gray & 0xff);
3175  }
3176 #if defined(PNG_READ_GAMMA_SUPPORTED)
3177  else
3178  {
3179  png_uint_16 g, v;
3180 
3181  g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3182  png_composite_16(v, g, a, background_1->gray);
3183  *dp = (png_byte)((v >> 8) & 0xff);
3184  *(dp + 1) = (png_byte)(v & 0xff);
3185  }
3186 #endif
3187  }
3188  }
3189  }
3190  break;
3191  }
3193  {
3194  if (row_info->bit_depth == 8)
3195  {
3196 #if defined(PNG_READ_GAMMA_SUPPORTED)
3197  if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3198  gamma_table != NULL)
3199  {
3200  sp = row;
3201  dp = row;
3202  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3203  {
3204  png_byte a = *(sp + 3);
3205 
3206  if (a == 0xff)
3207  {
3208  *dp = gamma_table[*sp];
3209  *(dp + 1) = gamma_table[*(sp + 1)];
3210  *(dp + 2) = gamma_table[*(sp + 2)];
3211  }
3212  else if (a == 0)
3213  {
3214  /* background is already in screen gamma */
3215  *dp = (png_byte)background->red;
3216  *(dp + 1) = (png_byte)background->green;
3217  *(dp + 2) = (png_byte)background->blue;
3218  }
3219  else
3220  {
3221  png_byte v, w;
3222 
3223  v = gamma_to_1[*sp];
3224  png_composite(w, v, a, background_1->red);
3225  *dp = gamma_from_1[w];
3226  v = gamma_to_1[*(sp + 1)];
3227  png_composite(w, v, a, background_1->green);
3228  *(dp + 1) = gamma_from_1[w];
3229  v = gamma_to_1[*(sp + 2)];
3230  png_composite(w, v, a, background_1->blue);
3231  *(dp + 2) = gamma_from_1[w];
3232  }
3233  }
3234  }
3235  else
3236 #endif
3237  {
3238  sp = row;
3239  dp = row;
3240  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3241  {
3242  png_byte a = *(sp + 3);
3243 
3244  if (a == 0xff)
3245  {
3246  *dp = *sp;
3247  *(dp + 1) = *(sp + 1);
3248  *(dp + 2) = *(sp + 2);
3249  }
3250  else if (a == 0)
3251  {
3252  *dp = (png_byte)background->red;
3253  *(dp + 1) = (png_byte)background->green;
3254  *(dp + 2) = (png_byte)background->blue;
3255  }
3256  else
3257  {
3258  png_composite(*dp, *sp, a, background->red);
3259  png_composite(*(dp + 1), *(sp + 1), a,
3260  background->green);
3261  png_composite(*(dp + 2), *(sp + 2), a,
3262  background->blue);
3263  }
3264  }
3265  }
3266  }
3267  else /* if (row_info->bit_depth == 16) */
3268  {
3269 #if defined(PNG_READ_GAMMA_SUPPORTED)
3270  if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3271  gamma_16_to_1 != NULL)
3272  {
3273  sp = row;
3274  dp = row;
3275  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3276  {
3277  png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3278  << 8) + (png_uint_16)(*(sp + 7)));
3279  if (a == (png_uint_16)0xffff)
3280  {
3281  png_uint_16 v;
3282 
3283  v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3284  *dp = (png_byte)((v >> 8) & 0xff);
3285  *(dp + 1) = (png_byte)(v & 0xff);
3286  v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3287  *(dp + 2) = (png_byte)((v >> 8) & 0xff);
3288  *(dp + 3) = (png_byte)(v & 0xff);
3289  v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3290  *(dp + 4) = (png_byte)((v >> 8) & 0xff);
3291  *(dp + 5) = (png_byte)(v & 0xff);
3292  }
3293  else if (a == 0)
3294  {
3295  /* background is already in screen gamma */
3296  *dp = (png_byte)((background->red >> 8) & 0xff);
3297  *(dp + 1) = (png_byte)(background->red & 0xff);
3298  *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3299  *(dp + 3) = (png_byte)(background->green & 0xff);
3300  *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3301  *(dp + 5) = (png_byte)(background->blue & 0xff);
3302  }
3303  else
3304  {
3305  png_uint_16 v, w, x;
3306 
3307  v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3308  png_composite_16(w, v, a, background_1->red);
3309  x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3310  *dp = (png_byte)((x >> 8) & 0xff);
3311  *(dp + 1) = (png_byte)(x & 0xff);
3312  v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3313  png_composite_16(w, v, a, background_1->green);
3314  x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3315  *(dp + 2) = (png_byte)((x >> 8) & 0xff);
3316  *(dp + 3) = (png_byte)(x & 0xff);
3317  v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3318  png_composite_16(w, v, a, background_1->blue);
3319  x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
3320  *(dp + 4) = (png_byte)((x >> 8) & 0xff);
3321  *(dp + 5) = (png_byte)(x & 0xff);
3322  }
3323  }
3324  }
3325  else
3326 #endif
3327  {
3328  sp = row;
3329  dp = row;
3330  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3331  {
3332  png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3333  << 8) + (png_uint_16)(*(sp + 7)));
3334  if (a == (png_uint_16)0xffff)
3335  {
3336  png_memcpy(dp, sp, 6);
3337  }
3338  else if (a == 0)
3339  {
3340  *dp = (png_byte)((background->red >> 8) & 0xff);
3341  *(dp + 1) = (png_byte)(background->red & 0xff);
3342  *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3343  *(dp + 3) = (png_byte)(background->green & 0xff);
3344  *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3345  *(dp + 5) = (png_byte)(background->blue & 0xff);
3346  }
3347  else
3348  {
3349  png_uint_16 v;
3350 
3351  png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3352  png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3353  + *(sp + 3));
3354  png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3355  + *(sp + 5));
3356 
3357  png_composite_16(v, r, a, background->red);
3358  *dp = (png_byte)((v >> 8) & 0xff);
3359  *(dp + 1) = (png_byte)(v & 0xff);
3360  png_composite_16(v, g, a, background->green);
3361  *(dp + 2) = (png_byte)((v >> 8) & 0xff);
3362  *(dp + 3) = (png_byte)(v & 0xff);
3363  png_composite_16(v, b, a, background->blue);
3364  *(dp + 4) = (png_byte)((v >> 8) & 0xff);
3365  *(dp + 5) = (png_byte)(v & 0xff);
3366  }
3367  }
3368  }
3369  }
3370  break;
3371  }
3372  }
3373 
3374  if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
3375  {
3376  row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
3377  row_info->channels--;
3378  row_info->pixel_depth = (png_byte)(row_info->channels *
3379  row_info->bit_depth);
3380  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3381  }
3382  }
3383 }
3384 #endif
3385 
3386 #if defined(PNG_READ_GAMMA_SUPPORTED)
3387 /* Gamma correct the image, avoiding the alpha channel. Make sure
3388  * you do this after you deal with the transparency issue on grayscale
3389  * or RGB images. If your bit depth is 8, use gamma_table, if it
3390  * is 16, use gamma_16_table and gamma_shift. Build these with
3391  * build_gamma_table().
3392  */
3393 void /* PRIVATE */
3395  png_bytep gamma_table, png_uint_16pp gamma_16_table,
3396  int gamma_shift)
3397 {
3398  png_bytep sp;
3399  png_uint_32 i;
3400  png_uint_32 row_width=row_info->width;
3401 
3402  png_debug(1, "in png_do_gamma\n");
3403  if (
3404 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3405  row != NULL && row_info != NULL &&
3406 #endif
3407  ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3408  (row_info->bit_depth == 16 && gamma_16_table != NULL)))
3409  {
3410  switch (row_info->color_type)
3411  {
3412  case PNG_COLOR_TYPE_RGB:
3413  {
3414  if (row_info->bit_depth == 8)
3415  {
3416  sp = row;
3417  for (i = 0; i < row_width; i++)
3418  {
3419  *sp = gamma_table[*sp];
3420  sp++;
3421  *sp = gamma_table[*sp];
3422  sp++;
3423  *sp = gamma_table[*sp];
3424  sp++;
3425  }
3426  }
3427  else /* if (row_info->bit_depth == 16) */
3428  {
3429  sp = row;
3430  for (i = 0; i < row_width; i++)
3431  {
3432  png_uint_16 v;
3433 
3434  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3435  *sp = (png_byte)((v >> 8) & 0xff);
3436  *(sp + 1) = (png_byte)(v & 0xff);
3437  sp += 2;
3438  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3439  *sp = (png_byte)((v >> 8) & 0xff);
3440  *(sp + 1) = (png_byte)(v & 0xff);
3441  sp += 2;
3442  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3443  *sp = (png_byte)((v >> 8) & 0xff);
3444  *(sp + 1) = (png_byte)(v & 0xff);
3445  sp += 2;
3446  }
3447  }
3448  break;
3449  }
3451  {
3452  if (row_info->bit_depth == 8)
3453  {
3454  sp = row;
3455  for (i = 0; i < row_width; i++)
3456  {
3457  *sp = gamma_table[*sp];
3458  sp++;
3459  *sp = gamma_table[*sp];
3460  sp++;
3461  *sp = gamma_table[*sp];
3462  sp++;
3463  sp++;
3464  }
3465  }
3466  else /* if (row_info->bit_depth == 16) */
3467  {
3468  sp = row;
3469  for (i = 0; i < row_width; i++)
3470  {
3471  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3472  *sp = (png_byte)((v >> 8) & 0xff);
3473  *(sp + 1) = (png_byte)(v & 0xff);
3474  sp += 2;
3475  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3476  *sp = (png_byte)((v >> 8) & 0xff);
3477  *(sp + 1) = (png_byte)(v & 0xff);
3478  sp += 2;
3479  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3480  *sp = (png_byte)((v >> 8) & 0xff);
3481  *(sp + 1) = (png_byte)(v & 0xff);
3482  sp += 4;
3483  }
3484  }
3485  break;
3486  }
3488  {
3489  if (row_info->bit_depth == 8)
3490  {
3491  sp = row;
3492  for (i = 0; i < row_width; i++)
3493  {
3494  *sp = gamma_table[*sp];
3495  sp += 2;
3496  }
3497  }
3498  else /* if (row_info->bit_depth == 16) */
3499  {
3500  sp = row;
3501  for (i = 0; i < row_width; i++)
3502  {
3503  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3504  *sp = (png_byte)((v >> 8) & 0xff);
3505  *(sp + 1) = (png_byte)(v & 0xff);
3506  sp += 4;
3507  }
3508  }
3509  break;
3510  }
3511  case PNG_COLOR_TYPE_GRAY:
3512  {
3513  if (row_info->bit_depth == 2)
3514  {
3515  sp = row;
3516  for (i = 0; i < row_width; i += 4)
3517  {
3518  int a = *sp & 0xc0;
3519  int b = *sp & 0x30;
3520  int c = *sp & 0x0c;
3521  int d = *sp & 0x03;
3522 
3523  *sp = (png_byte)(
3524  ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
3525  ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
3526  ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
3527  ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
3528  sp++;
3529  }
3530  }
3531  if (row_info->bit_depth == 4)
3532  {
3533  sp = row;
3534  for (i = 0; i < row_width; i += 2)
3535  {
3536  int msb = *sp & 0xf0;
3537  int lsb = *sp & 0x0f;
3538 
3539  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
3540  | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
3541  sp++;
3542  }
3543  }
3544  else if (row_info->bit_depth == 8)
3545  {
3546  sp = row;
3547  for (i = 0; i < row_width; i++)
3548  {
3549  *sp = gamma_table[*sp];
3550  sp++;
3551  }
3552  }
3553  else if (row_info->bit_depth == 16)
3554  {
3555  sp = row;
3556  for (i = 0; i < row_width; i++)
3557  {
3558  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3559  *sp = (png_byte)((v >> 8) & 0xff);
3560  *(sp + 1) = (png_byte)(v & 0xff);
3561  sp += 2;
3562  }
3563  }
3564  break;
3565  }
3566  }
3567  }
3568 }
3569 #endif
3570 
3571 #if defined(PNG_READ_EXPAND_SUPPORTED)
3572 /* Expands a palette row to an RGB or RGBA row depending
3573  * upon whether you supply trans and num_trans.
3574  */
3575 void /* PRIVATE */
3578 {
3579  int shift, value;
3580  png_bytep sp, dp;
3581  png_uint_32 i;
3582  png_uint_32 row_width=row_info->width;
3583 
3584  png_debug(1, "in png_do_expand_palette\n");
3585  if (
3586 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3587  row != NULL && row_info != NULL &&
3588 #endif
3589  row_info->color_type == PNG_COLOR_TYPE_PALETTE)
3590  {
3591  if (row_info->bit_depth < 8)
3592  {
3593  switch (row_info->bit_depth)
3594  {
3595  case 1:
3596  {
3597  sp = row + (png_size_t)((row_width - 1) >> 3);
3598  dp = row + (png_size_t)row_width - 1;
3599  shift = 7 - (int)((row_width + 7) & 0x07);
3600  for (i = 0; i < row_width; i++)
3601  {
3602  if ((*sp >> shift) & 0x01)
3603  *dp = 1;
3604  else
3605  *dp = 0;
3606  if (shift == 7)
3607  {
3608  shift = 0;
3609  sp--;
3610  }
3611  else
3612  shift++;
3613 
3614  dp--;
3615  }
3616  break;
3617  }
3618  case 2:
3619  {
3620  sp = row + (png_size_t)((row_width - 1) >> 2);
3621  dp = row + (png_size_t)row_width - 1;
3622  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3623  for (i = 0; i < row_width; i++)
3624  {
3625  value = (*sp >> shift) & 0x03;
3626  *dp = (png_byte)value;
3627  if (shift == 6)
3628  {
3629  shift = 0;
3630  sp--;
3631  }
3632  else
3633  shift += 2;
3634 
3635  dp--;
3636  }
3637  break;
3638  }
3639  case 4:
3640  {
3641  sp = row + (png_size_t)((row_width - 1) >> 1);
3642  dp = row + (png_size_t)row_width - 1;
3643  shift = (int)((row_width & 0x01) << 2);
3644  for (i = 0; i < row_width; i++)
3645  {
3646  value = (*sp >> shift) & 0x0f;
3647  *dp = (png_byte)value;
3648  if (shift == 4)
3649  {
3650  shift = 0;
3651  sp--;
3652  }
3653  else
3654  shift += 4;
3655 
3656  dp--;
3657  }
3658  break;
3659  }
3660  }
3661  row_info->bit_depth = 8;
3662  row_info->pixel_depth = 8;
3663  row_info->rowbytes = row_width;
3664  }
3665  switch (row_info->bit_depth)
3666  {
3667  case 8:
3668  {
3669  if (trans != NULL)
3670  {
3671  sp = row + (png_size_t)row_width - 1;
3672  dp = row + (png_size_t)(row_width << 2) - 1;
3673 
3674  for (i = 0; i < row_width; i++)
3675  {
3676  if ((int)(*sp) >= num_trans)
3677  *dp-- = 0xff;
3678  else
3679  *dp-- = trans[*sp];
3680  *dp-- = palette[*sp].blue;
3681  *dp-- = palette[*sp].green;
3682  *dp-- = palette[*sp].red;
3683  sp--;
3684  }
3685  row_info->bit_depth = 8;
3686  row_info->pixel_depth = 32;
3687  row_info->rowbytes = row_width * 4;
3688  row_info->color_type = 6;
3689  row_info->channels = 4;
3690  }
3691  else
3692  {
3693  sp = row + (png_size_t)row_width - 1;
3694  dp = row + (png_size_t)(row_width * 3) - 1;
3695 
3696  for (i = 0; i < row_width; i++)
3697  {
3698  *dp-- = palette[*sp].blue;
3699  *dp-- = palette[*sp].green;
3700  *dp-- = palette[*sp].red;
3701  sp--;
3702  }
3703  row_info->bit_depth = 8;
3704  row_info->pixel_depth = 24;
3705  row_info->rowbytes = row_width * 3;
3706  row_info->color_type = 2;
3707  row_info->channels = 3;
3708  }
3709  break;
3710  }
3711  }
3712  }
3713 }
3714 
3715 /* If the bit depth < 8, it is expanded to 8. Also, if the already
3716  * expanded transparency value is supplied, an alpha channel is built.
3717  */
3718 void /* PRIVATE */
3720  png_color_16p trans_value)
3721 {
3722  int shift, value;
3723  png_bytep sp, dp;
3724  png_uint_32 i;
3725  png_uint_32 row_width=row_info->width;
3726 
3727  png_debug(1, "in png_do_expand\n");
3728 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3729  if (row != NULL && row_info != NULL)
3730 #endif
3731  {
3732  if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
3733  {
3734  png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
3735 
3736  if (row_info->bit_depth < 8)
3737  {
3738  switch (row_info->bit_depth)
3739  {
3740  case 1:
3741  {
3742  gray = (png_uint_16)((gray&0x01)*0xff);
3743  sp = row + (png_size_t)((row_width - 1) >> 3);
3744  dp = row + (png_size_t)row_width - 1;
3745  shift = 7 - (int)((row_width + 7) & 0x07);
3746  for (i = 0; i < row_width; i++)
3747  {
3748  if ((*sp >> shift) & 0x01)
3749  *dp = 0xff;
3750  else
3751  *dp = 0;
3752  if (shift == 7)
3753  {
3754  shift = 0;
3755  sp--;
3756  }
3757  else
3758  shift++;
3759 
3760  dp--;
3761  }
3762  break;
3763  }
3764  case 2:
3765  {
3766  gray = (png_uint_16)((gray&0x03)*0x55);
3767  sp = row + (png_size_t)((row_width - 1) >> 2);
3768  dp = row + (png_size_t)row_width - 1;
3769  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3770  for (i = 0; i < row_width; i++)
3771  {
3772  value = (*sp >> shift) & 0x03;
3773  *dp = (png_byte)(value | (value << 2) | (value << 4) |
3774  (value << 6));
3775  if (shift == 6)
3776  {
3777  shift = 0;
3778  sp--;
3779  }
3780  else
3781  shift += 2;
3782 
3783  dp--;
3784  }
3785  break;
3786  }
3787  case 4:
3788  {
3789  gray = (png_uint_16)((gray&0x0f)*0x11);
3790  sp = row + (png_size_t)((row_width - 1) >> 1);
3791  dp = row + (png_size_t)row_width - 1;
3792  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
3793  for (i = 0; i < row_width; i++)
3794  {
3795  value = (*sp >> shift) & 0x0f;
3796  *dp = (png_byte)(value | (value << 4));
3797  if (shift == 4)
3798  {
3799  shift = 0;
3800  sp--;
3801  }
3802  else
3803  shift = 4;
3804 
3805  dp--;
3806  }
3807  break;
3808  }
3809  }
3810  row_info->bit_depth = 8;
3811  row_info->pixel_depth = 8;
3812  row_info->rowbytes = row_width;
3813  }
3814 
3815  if (trans_value != NULL)
3816  {
3817  if (row_info->bit_depth == 8)
3818  {
3819  gray = gray & 0xff;
3820  sp = row + (png_size_t)row_width - 1;
3821  dp = row + (png_size_t)(row_width << 1) - 1;
3822  for (i = 0; i < row_width; i++)
3823  {
3824  if (*sp == gray)
3825  *dp-- = 0;
3826  else
3827  *dp-- = 0xff;
3828  *dp-- = *sp--;
3829  }
3830  }
3831  else if (row_info->bit_depth == 16)
3832  {
3833  png_byte gray_high = (gray >> 8) & 0xff;
3834  png_byte gray_low = gray & 0xff;
3835  sp = row + row_info->rowbytes - 1;
3836  dp = row + (row_info->rowbytes << 1) - 1;
3837  for (i = 0; i < row_width; i++)
3838  {
3839  if (*(sp - 1) == gray_high && *(sp) == gray_low)
3840  {
3841  *dp-- = 0;
3842  *dp-- = 0;
3843  }
3844  else
3845  {
3846  *dp-- = 0xff;
3847  *dp-- = 0xff;
3848  }
3849  *dp-- = *sp--;
3850  *dp-- = *sp--;
3851  }
3852  }
3853  row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3854  row_info->channels = 2;
3855  row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
3856  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
3857  row_width);
3858  }
3859  }
3860  else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
3861  {
3862  if (row_info->bit_depth == 8)
3863  {
3864  png_byte red = trans_value->red & 0xff;
3865  png_byte green = trans_value->green & 0xff;
3866  png_byte blue = trans_value->blue & 0xff;
3867  sp = row + (png_size_t)row_info->rowbytes - 1;
3868  dp = row + (png_size_t)(row_width << 2) - 1;
3869  for (i = 0; i < row_width; i++)
3870  {
3871  if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
3872  *dp-- = 0;
3873  else
3874  *dp-- = 0xff;
3875  *dp-- = *sp--;
3876  *dp-- = *sp--;
3877  *dp-- = *sp--;
3878  }
3879  }
3880  else if (row_info->bit_depth == 16)
3881  {
3882  png_byte red_high = (trans_value->red >> 8) & 0xff;
3883  png_byte green_high = (trans_value->green >> 8) & 0xff;
3884  png_byte blue_high = (trans_value->blue >> 8) & 0xff;
3885  png_byte red_low = trans_value->red & 0xff;
3886  png_byte green_low = trans_value->green & 0xff;
3887  png_byte blue_low = trans_value->blue & 0xff;
3888  sp = row + row_info->rowbytes - 1;
3889  dp = row + (png_size_t)(row_width << 3) - 1;
3890  for (i = 0; i < row_width; i++)
3891  {
3892  if (*(sp - 5) == red_high &&
3893  *(sp - 4) == red_low &&
3894  *(sp - 3) == green_high &&
3895  *(sp - 2) == green_low &&
3896  *(sp - 1) == blue_high &&
3897  *(sp ) == blue_low)
3898  {
3899  *dp-- = 0;
3900  *dp-- = 0;
3901  }
3902  else
3903  {
3904  *dp-- = 0xff;
3905  *dp-- = 0xff;
3906  }
3907  *dp-- = *sp--;
3908  *dp-- = *sp--;
3909  *dp-- = *sp--;
3910  *dp-- = *sp--;
3911  *dp-- = *sp--;
3912  *dp-- = *sp--;
3913  }
3914  }
3915  row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
3916  row_info->channels = 4;
3917  row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
3918  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3919  }
3920  }
3921 }
3922 #endif
3923 
3924 #if defined(PNG_READ_DITHER_SUPPORTED)
3925 void /* PRIVATE */
3927  png_bytep palette_lookup, png_bytep dither_lookup)
3928 {
3929  png_bytep sp, dp;
3930  png_uint_32 i;
3931  png_uint_32 row_width=row_info->width;
3932 
3933  png_debug(1, "in png_do_dither\n");
3934 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3935  if (row != NULL && row_info != NULL)
3936 #endif
3937  {
3938  if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
3939  palette_lookup && row_info->bit_depth == 8)
3940  {
3941  int r, g, b, p;
3942  sp = row;
3943  dp = row;
3944  for (i = 0; i < row_width; i++)
3945  {
3946  r = *sp++;
3947  g = *sp++;
3948  b = *sp++;
3949 
3950  /* this looks real messy, but the compiler will reduce
3951  it down to a reasonable formula. For example, with
3952  5 bits per color, we get:
3953  p = (((r >> 3) & 0x1f) << 10) |
3954  (((g >> 3) & 0x1f) << 5) |
3955  ((b >> 3) & 0x1f);
3956  */
3957  p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
3958  ((1 << PNG_DITHER_RED_BITS) - 1)) <<
3959  (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
3960  (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
3961  ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
3962  (PNG_DITHER_BLUE_BITS)) |
3963  ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
3964  ((1 << PNG_DITHER_BLUE_BITS) - 1));
3965 
3966  *dp++ = palette_lookup[p];
3967  }
3968  row_info->color_type = PNG_COLOR_TYPE_PALETTE;
3969  row_info->channels = 1;
3970  row_info->pixel_depth = row_info->bit_depth;
3971  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3972  }
3973  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
3974  palette_lookup != NULL && row_info->bit_depth == 8)
3975  {
3976  int r, g, b, p;
3977  sp = row;
3978  dp = row;
3979  for (i = 0; i < row_width; i++)
3980  {
3981  r = *sp++;
3982  g = *sp++;
3983  b = *sp++;
3984  sp++;
3985 
3986  p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
3987  ((1 << PNG_DITHER_RED_BITS) - 1)) <<
3988  (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
3989  (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
3990  ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
3991  (PNG_DITHER_BLUE_BITS)) |
3992  ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
3993  ((1 << PNG_DITHER_BLUE_BITS) - 1));
3994 
3995  *dp++ = palette_lookup[p];
3996  }
3997  row_info->color_type = PNG_COLOR_TYPE_PALETTE;
3998  row_info->channels = 1;
3999  row_info->pixel_depth = row_info->bit_depth;
4000  row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4001  }
4002  else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4003  dither_lookup && row_info->bit_depth == 8)
4004  {
4005  sp = row;
4006  for (i = 0; i < row_width; i++, sp++)
4007  {
4008  *sp = dither_lookup[*sp];
4009  }
4010  }
4011  }
4012 }
4013 #endif
4014 
4015 #ifdef PNG_FLOATING_POINT_SUPPORTED
4016 #if defined(PNG_READ_GAMMA_SUPPORTED)
4018  {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
4019 
4020 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
4021  * tables, we don't make a full table if we are reducing to 8-bit in
4022  * the future. Note also how the gamma_16 tables are segmented so that
4023  * we don't need to allocate > 64K chunks for a full 16-bit table.
4024  */
4025 void /* PRIVATE */
4027 {
4028  png_debug(1, "in png_build_gamma_table\n");
4029 
4030  if (png_ptr->bit_depth <= 8)
4031  {
4032  int i;
4033  double g;
4034 
4035  if (png_ptr->screen_gamma > .000001)
4036  g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
4037  else
4038  g = 1.0;
4039 
4040  png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
4041  (png_uint_32)256);
4042 
4043  for (i = 0; i < 256; i++)
4044  {
4045  png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
4046  g) * 255.0 + .5);
4047  }
4048 
4049 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4050  defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4051  if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
4052  {
4053 
4054  g = 1.0 / (png_ptr->gamma);
4055 
4056  png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
4057  (png_uint_32)256);
4058 
4059  for (i = 0; i < 256; i++)
4060  {
4061  png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
4062  g) * 255.0 + .5);
4063  }
4064 
4065 
4066  png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
4067  (png_uint_32)256);
4068 
4069  if (png_ptr->screen_gamma > 0.000001)
4070  g = 1.0 / png_ptr->screen_gamma;
4071  else
4072  g = png_ptr->gamma; /* probably doing rgb_to_gray */
4073 
4074  for (i = 0; i < 256; i++)
4075  {
4076  png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
4077  g) * 255.0 + .5);
4078 
4079  }
4080  }
4081 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4082  }
4083  else
4084  {
4085  double g;
4086  int i, j, shift, num;
4087  int sig_bit;
4088  png_uint_32 ig;
4089 
4090  if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
4091  {
4092  sig_bit = (int)png_ptr->sig_bit.red;
4093  if ((int)png_ptr->sig_bit.green > sig_bit)
4094  sig_bit = png_ptr->sig_bit.green;
4095  if ((int)png_ptr->sig_bit.blue > sig_bit)
4096  sig_bit = png_ptr->sig_bit.blue;
4097  }
4098  else
4099  {
4100  sig_bit = (int)png_ptr->sig_bit.gray;
4101  }
4102 
4103  if (sig_bit > 0)
4104  shift = 16 - sig_bit;
4105  else
4106  shift = 0;
4107 
4108  if (png_ptr->transformations & PNG_16_TO_8)
4109  {
4110  if (shift < (16 - PNG_MAX_GAMMA_8))
4111  shift = (16 - PNG_MAX_GAMMA_8);
4112  }
4113 
4114  if (shift > 8)
4115  shift = 8;
4116  if (shift < 0)
4117  shift = 0;
4118 
4119  png_ptr->gamma_shift = (png_byte)shift;
4120 
4121  num = (1 << (8 - shift));
4122 
4123  if (png_ptr->screen_gamma > .000001)
4124  g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
4125  else
4126  g = 1.0;
4127 
4128  png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
4129  (png_uint_32)(num * png_sizeof(png_uint_16p)));
4130 
4131  if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
4132  {
4133  double fin, fout;
4134  png_uint_32 last, max;
4135 
4136  for (i = 0; i < num; i++)
4137  {
4138  png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
4139  (png_uint_32)(256 * png_sizeof(png_uint_16)));
4140  }
4141 
4142  g = 1.0 / g;
4143  last = 0;
4144  for (i = 0; i < 256; i++)
4145  {
4146  fout = ((double)i + 0.5) / 256.0;
4147  fin = pow(fout, g);
4148  max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
4149  while (last <= max)
4150  {
4151  png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
4152  [(int)(last >> (8 - shift))] = (png_uint_16)(
4153  (png_uint_16)i | ((png_uint_16)i << 8));
4154  last++;
4155  }
4156  }
4157  while (last < ((png_uint_32)num << 8))
4158  {
4159  png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
4160  [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
4161  last++;
4162  }
4163  }
4164  else
4165  {
4166  for (i = 0; i < num; i++)
4167  {
4168  png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
4169  (png_uint_32)(256 * png_sizeof(png_uint_16)));
4170 
4171  ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
4172  for (j = 0; j < 256; j++)
4173  {
4174  png_ptr->gamma_16_table[i][j] =
4175  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4176  65535.0, g) * 65535.0 + .5);
4177  }
4178  }
4179  }
4180 
4181 #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4182  defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4183  if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
4184  {
4185 
4186  g = 1.0 / (png_ptr->gamma);
4187 
4188  png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
4189  (png_uint_32)(num * png_sizeof(png_uint_16p )));
4190 
4191  for (i = 0; i < num; i++)
4192  {
4193  png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
4194  (png_uint_32)(256 * png_sizeof(png_uint_16)));
4195 
4196  ig = (((png_uint_32)i *
4197  (png_uint_32)png_gamma_shift[shift]) >> 4);
4198  for (j = 0; j < 256; j++)
4199  {
4200  png_ptr->gamma_16_to_1[i][j] =
4201  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4202  65535.0, g) * 65535.0 + .5);
4203  }
4204  }
4205 
4206  if (png_ptr->screen_gamma > 0.000001)
4207  g = 1.0 / png_ptr->screen_gamma;
4208  else
4209  g = png_ptr->gamma; /* probably doing rgb_to_gray */
4210 
4211  png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
4212  (png_uint_32)(num * png_sizeof(png_uint_16p)));
4213 
4214  for (i = 0; i < num; i++)
4215  {
4216  png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
4217  (png_uint_32)(256 * png_sizeof(png_uint_16)));
4218 
4219  ig = (((png_uint_32)i *
4220  (png_uint_32)png_gamma_shift[shift]) >> 4);
4221  for (j = 0; j < 256; j++)
4222  {
4223  png_ptr->gamma_16_from_1[i][j] =
4224  (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4225  65535.0, g) * 65535.0 + .5);
4226  }
4227  }
4228  }
4229 #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4230  }
4231 }
4232 #endif
4233 /* To do: install integer version of png_build_gamma_table here */
4234 #endif
4235 
4236 #if defined(PNG_MNG_FEATURES_SUPPORTED)
4237 /* undoes intrapixel differencing */
4238 void /* PRIVATE */
4240 {
4241  png_debug(1, "in png_do_read_intrapixel\n");
4242  if (
4243 #if defined(PNG_USELESS_TESTS_SUPPORTED)
4244  row != NULL && row_info != NULL &&
4245 #endif
4246  (row_info->color_type & PNG_COLOR_MASK_COLOR))
4247  {
4248  int bytes_per_pixel;
4249  png_uint_32 row_width = row_info->width;
4250  if (row_info->bit_depth == 8)
4251  {
4252  png_bytep rp;
4253  png_uint_32 i;
4254 
4255  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
4256  bytes_per_pixel = 3;
4257  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4258  bytes_per_pixel = 4;
4259  else
4260  return;
4261 
4262  for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
4263  {
4264  *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
4265  *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
4266  }
4267  }
4268  else if (row_info->bit_depth == 16)
4269  {
4270  png_bytep rp;
4271  png_uint_32 i;
4272 
4273  if (row_info->color_type == PNG_COLOR_TYPE_RGB)
4274  bytes_per_pixel = 6;
4275  else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4276  bytes_per_pixel = 8;
4277  else
4278  return;
4279 
4280  for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
4281  {
4282  png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
4283  png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
4284  png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
4285  png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
4286  png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
4287  *(rp ) = (png_byte)((red >> 8) & 0xff);
4288  *(rp+1) = (png_byte)(red & 0xff);
4289  *(rp+4) = (png_byte)((blue >> 8) & 0xff);
4290  *(rp+5) = (png_byte)(blue & 0xff);
4291  }
4292  }
4293  }
4294 }
4295 #endif /* PNG_MNG_FEATURES_SUPPORTED */
4296 #endif /* PNG_READ_SUPPORTED */
void png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:4239
#define PNG_CRC_NO_CHANGE
Definition: png.h:1834
struct png_dsort_struct png_dsort
#define PNG_BACKGROUND_GAMMA_UNIQUE
Definition: png.h:1709
void png_do_packswap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:362
int c
Definition: autoplay.py:16
void PNGAPI png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green)
Definition: pngrtran.c:644
png_byte left
Definition: pngrtran.c:134
png_color_16p int int double background_gamma
Definition: png.h:1703
png_colorp int int png_uint_16p int full_dither
Definition: png.h:1720
void PNGAPI png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
Definition: pngrtran.c:584
void png_do_background(png_row_infop row_info, png_bytep row, png_color_16p trans_values, png_color_16p background, png_color_16p background_1, png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int gamma_shift)
Definition: pngrtran.c:2705
void png_do_gamma(png_row_infop row_info, png_bytep row, png_bytep gamma_table, png_uint_16pp gamma_16_table, int gamma_shift)
Definition: pngrtran.c:3394
#define PNG_CRC_DEFAULT
Definition: png.h:1829
void png_do_invert(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:176
png_voidp s1
Definition: png.h:2110
void png_do_expand(png_row_infop row_info, png_bytep row, png_color_16p trans_value)
Definition: pngrtran.c:3719
#define png_composite(composite, fg, alpha, bg)
Definition: png.h:2685
void png_do_read_filler(png_row_infop row_info, png_bytep row, png_uint_32 filler, png_uint_32 flags)
Definition: pngrtran.c:1956
png_colorp int num_palette
Definition: png.h:1720
* x
Definition: IceUtils.h:98
#define PNG_BACKGROUND_GAMMA_SCREEN
Definition: png.h:1707
void PNGAPI png_set_palette_to_rgb(png_structp png_ptr)
Definition: pngrtran.c:573
png_color_16 FAR * png_color_16p
Definition: png.h:582
void png_build_gamma_table(png_structp png_ptr)
Definition: pngrtran.c:4026
#define PNG_CRC_WARN_USE
Definition: png.h:1832
#define PNG_COLOR_TYPE_RGB
Definition: png.h:1005
#define png_snprintf2
Definition: pngconf.h:1449
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:1007
png_byte FAR * png_bytep
Definition: pngconf.h:1197
png_infop png_color_16p * background
Definition: png.h:2241
#define png_memset
Definition: pngconf.h:1466
void png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
Definition: pngtrans.c:394
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:1004
png_colorp int int png_uint_16p histogram
Definition: png.h:1720
void PNGAPI png_set_dither(png_structp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_uint_16p histogram, int full_dither)
Definition: pngrtran.c:141
#define PNG_CRC_WARN_DISCARD
Definition: png.h:1831
int double double green
Definition: png.h:1628
void PNGAPI png_set_background(png_structp png_ptr, png_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma)
Definition: pngrtran.c:79
void png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:1857
png_voidp int value
Definition: png.h:2113
png_byte red
Definition: png.h:567
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:1006
void png_do_read_transformations(png_structp png_ptr)
Definition: pngrtran.c:1269
png_color_16p int int need_expand
Definition: png.h:1703
void PNGAPI png_set_strip_16(png_structp png_ptr)
Definition: pngrtran.c:103
w
void png_do_chop(png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:1711
#define for
png_uint_32 i
Definition: png.h:2735
#define PNG_BACKGROUND_GAMMA_FILE
Definition: png.h:1708
int png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:2235
long b
Definition: jpegint.h:371
png_infop png_bytep * trans
Definition: png.h:2435
png_uint_32 int flags
Definition: png.h:1656
void PNGAPI png_set_gray_1_2_4_to_8(png_structp png_ptr)
Definition: pngrtran.c:597
fout
png_infop png_bytep int png_color_16p * trans_values
Definition: png.h:2435
void png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:2132
void png_init_read_transformations(png_structp png_ptr)
Definition: pngrtran.c:718
void png_do_dither(png_row_infop row_info, png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)
Definition: pngrtran.c:3926
void PNGAPI png_build_grayscale_palette(int bit_depth, png_colorp palette)
Definition: pngrtran.c:2474
void png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
Definition: pngrtran.c:1125
#define png_debug(l, m)
Definition: png.h:2556
#define PNGAPI
Definition: pngconf.h:1386
SequenceElement & back(CorbaSequence &seq)
png_struct FAR * png_structp
Definition: png.h:1108
#define PNG_READ_BACKGROUND_SUPPORTED
Definition: pngconf.h:576
#define PNG_COLOR_MASK_COLOR
Definition: png.h:999
png_dsort FAR *FAR * png_dsortpp
Definition: pngrtran.c:138
void PNGAPI png_error(png_structp png_ptr, png_const_charp error_message)
Definition: pngerror.c:36
#define PNG_CONST
Definition: pngconf.h:445
void png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:1765
unsigned char png_byte
Definition: pngconf.h:1120
#define png_memcpy
Definition: pngconf.h:1465
unsigned short png_uint_16
Definition: pngconf.h:1118
png_infop int png_uint_32 mask
Definition: png.h:2081
#define PNG_CRC_QUIET_USE
Definition: png.h:1833
png_infop png_bytep int * num_trans
Definition: png.h:2435
#define PNG_COLOR_TYPE_GRAY
Definition: png.h:1003
struct png_dsort_struct FAR * next
Definition: pngrtran.c:133
void PNGAPI png_warning(png_structp png_ptr, png_const_charp warning_message)
Definition: pngerror.c:102
png_dsort FAR * png_dsortp
Definition: pngrtran.c:137
#define FAR
Definition: jmorecfg.h:215
void png_do_bgr(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:552
string a
png_uint_16 FAR * png_uint_16p
Definition: pngconf.h:1200
png_colorp palette
Definition: png.h:1637
t
png_bytepp row
Definition: png.h:1759
void PNGAPI png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
Definition: pngrtran.c:527
void PNGAPI png_set_strip_alpha(png_structp png_ptr)
Definition: pngrtran.c:113
png_byte right
Definition: pngrtran.c:135
void png_do_expand_palette(png_row_infop row_info, png_bytep row, png_colorp palette, png_bytep trans, int num_trans)
Definition: pngrtran.c:3576
png_infop png_uint_32 png_uint_32 int * bit_depth
Definition: png.h:2309
png_infop double * file_gamma
Definition: png.h:2283
png_voidp png_voidp s2
Definition: png.h:2110
#define PNG_CRC_ERROR_QUIT
Definition: png.h:1830
void png_do_unpack(png_row_infop row_info, png_bytep row)
Definition: pngrtran.c:1515
png_uint_16 FAR *FAR * png_uint_16pp
Definition: pngconf.h:1222
typedef int
Definition: png.h:1113
#define PNG_COLOR_MASK_ALPHA
Definition: png.h:1000
int crit_action
Definition: png.h:1818
void png_do_swap(png_row_infop row_info, png_bytep row)
Definition: pngtrans.c:231
png_infop png_uint_32 png_uint_32 int int * color_type
Definition: png.h:2309
void PNGAPI png_set_expand(png_structp png_ptr)
Definition: pngrtran.c:546
png_color_8 FAR * png_color_8p
Definition: png.h:593
int int ancil_action
Definition: png.h:1818
#define png_composite_16(composite, fg, alpha, bg)
Definition: png.h:2691
void PNGAPI png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
Definition: pngrtran.c:22
void PNGAPI png_set_tRNS_to_alpha(png_structp png_ptr)
Definition: pngrtran.c:608
png_int_32 png_fixed_point
Definition: pngconf.h:1193
png_color_16p background_color
Definition: png.h:1703
size_t png_size_t
Definition: pngconf.h:1128
#define PNG_BACKGROUND_GAMMA_UNKNOWN
Definition: png.h:1706
int num
Definition: png.h:1502
static PNG_CONST int png_gamma_shift[]
Definition: pngrtran.c:4017
png_colorp int int maximum_colors
Definition: png.h:1720
void PNGAPI png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr read_user_transform_fn)
Definition: pngrtran.c:697
int double red
Definition: png.h:1628
png_infop info_ptr
Definition: png.h:1571
unsigned long png_uint_32
Definition: pngconf.h:1116
png_row_info FAR * png_row_infop
Definition: png.h:1098
void png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
Definition: pngrtran.c:1605
void PNGAPI png_free(png_structp png_ptr, png_voidp ptr)
Definition: pngmem.c:498
png_color_16p int background_gamma_code
Definition: png.h:1703
void PNGAPI png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, double green)
Definition: pngrtran.c:633
int error_action
Definition: png.h:1628
png_uint_32 filler
Definition: png.h:1656
static int max(int a, int b)
png_voidp PNGAPI png_malloc(png_structp png_ptr, png_uint_32 size)
Definition: pngmem.c:429
png_voidp PNGAPI png_malloc_warn(png_structp png_ptr, png_uint_32 size)
Definition: pngmem.c:541
png_byte green
Definition: png.h:568
void PNGAPI png_set_gray_to_rgb(png_structp png_ptr)
Definition: pngrtran.c:618
png_byte blue
Definition: png.h:569
#define png_sizeof(x)
Definition: pngconf.h:1129
png_user_transform_ptr read_user_transform_fn
Definition: png.h:2000
#define PNG_READ_GAMMA_SUPPORTED
Definition: pngconf.h:585
png_infop png_color_8p * sig_bit
Definition: png.h:2360
png_color FAR * png_colorp
Definition: png.h:571
png_info FAR * png_infop
Definition: png.h:984


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Sep 8 2022 02:24:05