Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

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