2 /* pngrtran.c - transforms the data in a row for PNG readers
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
8 * Copyright (c) 1998, Glenn Randers-Pehrson
11 * This file contains functions optionally called by an application
12 * in order to tell libpng how to handle data when reading a PNG.
13 * Transformations which are used in both reading and writing are
18 #include "../png/png.h"
20 #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
21 /* With these routines, we avoid an integer divide, which will be slower on
22 * many machines. However, it does take more operations than the corresponding
23 * divide method, so it may be slower on some RISC systems. There are two
24 * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
26 * Note that the rounding factors are NOT supposed to be the same! 128 and
27 * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
30 * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
33 /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
34 # define png_composite(composite, fg, alpha, bg) \
35 { png_uint_16 temp = ((png_uint_16)(fg) * (png_uint_16)(alpha) + \
36 (png_uint_16)(bg)*(png_uint_16)(255 - \
37 (png_uint_16)(alpha)) + (png_uint_16)128); \
38 (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
39 # define png_composite_16(composite, fg, alpha, bg) \
40 { png_uint_32 temp = ((png_uint_32)(fg) * (png_uint_32)(alpha) + \
41 (png_uint_32)(bg)*(png_uint_32)(65535L - \
42 (png_uint_32)(alpha)) + (png_uint_32)32768L); \
43 (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
45 #else /* standard method using integer division */
47 /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
48 # define png_composite(composite, fg, alpha, bg) \
49 (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
50 (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
51 (png_uint_16)127) / 255)
52 # define png_composite_16(composite, fg, alpha, bg) \
53 (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
54 (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
55 (png_uint_32)32767) / (png_uint_32)65535L)
57 #endif /* ?PNG_READ_COMPOSITE_NODIV_SUPPORTED */
60 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
62 png_set_crc_action(png_structp png_ptr
, int crit_action
, int ancil_action
)
64 png_debug(1, "in png_set_crc_action\n");
65 /* Tell libpng how we react to CRC errors in critical chunks */
68 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
70 case PNG_CRC_WARN_USE
: /* warn/use data */
71 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
72 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
;
74 case PNG_CRC_QUIET_USE
: /* quiet/use data */
75 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
76 png_ptr
->flags
|= PNG_FLAG_CRC_CRITICAL_USE
|
77 PNG_FLAG_CRC_CRITICAL_IGNORE
;
79 case PNG_CRC_WARN_DISCARD
: /* not a valid action for critical data */
80 png_warning(png_ptr
, "Can't discard critical data on CRC error.");
81 case PNG_CRC_ERROR_QUIT
: /* error/quit */
84 png_ptr
->flags
&= ~PNG_FLAG_CRC_CRITICAL_MASK
;
90 case PNG_CRC_NO_CHANGE
: /* leave setting as is */
92 case PNG_CRC_WARN_USE
: /* warn/use data */
93 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
94 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
;
96 case PNG_CRC_QUIET_USE
: /* quiet/use data */
97 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
98 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_USE
|
99 PNG_FLAG_CRC_ANCILLARY_NOWARN
;
101 case PNG_CRC_ERROR_QUIT
: /* error/quit */
102 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
103 png_ptr
->flags
|= PNG_FLAG_CRC_ANCILLARY_NOWARN
;
105 case PNG_CRC_WARN_DISCARD
: /* warn/discard data */
106 case PNG_CRC_DEFAULT
:
108 png_ptr
->flags
&= ~PNG_FLAG_CRC_ANCILLARY_MASK
;
113 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
114 /* handle alpha and tRNS via a background color */
116 png_set_background(png_structp png_ptr
,
117 png_color_16p background_color
, int background_gamma_code
,
118 int need_expand
, double background_gamma
)
120 png_debug(1, "in png_set_background\n");
121 if (background_gamma_code
== PNG_BACKGROUND_GAMMA_UNKNOWN
)
123 png_warning(png_ptr
, "Application must supply a known background gamma");
127 png_ptr
->transformations
|= PNG_BACKGROUND
;
128 png_memcpy(&(png_ptr
->background
), background_color
,
129 sizeof(png_color_16
));
130 png_ptr
->background_gamma
= (float)background_gamma
;
131 png_ptr
->background_gamma_type
= (png_byte
)(background_gamma_code
);
132 png_ptr
->transformations
|= (need_expand
? PNG_BACKGROUND_EXPAND
: 0);
136 #if defined(PNG_READ_16_TO_8_SUPPORTED)
137 /* strip 16 bit depth files to 8 bit depth */
139 png_set_strip_16(png_structp png_ptr
)
141 png_debug(1, "in png_set_strip_16\n");
142 png_ptr
->transformations
|= PNG_16_TO_8
;
146 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
148 png_set_strip_alpha(png_structp png_ptr
)
150 png_debug(1, "in png_set_strip_alpha\n");
151 png_ptr
->transformations
|= PNG_STRIP_ALPHA
;
155 #if defined(PNG_READ_DITHER_SUPPORTED)
156 /* Dither file to 8 bit. Supply a palette, the current number
157 * of elements in the palette, the maximum number of elements
158 * allowed, and a histogram if possible. If the current number
159 * of colors is greater then the maximum number, the palette will be
160 * modified to fit in the maximum number. "full_dither" indicates
161 * whether we need a dithering cube set up for RGB images, or if we
162 * simply are reducing the number of colors in a paletted image.
165 typedef struct png_dsort_struct
167 struct png_dsort_struct FAR
* next
;
171 typedef png_dsort FAR
* png_dsortp
;
172 typedef png_dsort FAR
* FAR
* png_dsortpp
;
175 png_set_dither(png_structp png_ptr
, png_colorp palette
,
176 int num_palette
, int maximum_colors
, png_uint_16p histogram
,
179 png_debug(1, "in png_set_dither\n");
180 png_ptr
->transformations
|= PNG_DITHER
;
186 png_ptr
->dither_index
= (png_bytep
)png_malloc(png_ptr
,
187 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
188 for (i
= 0; i
< num_palette
; i
++)
189 png_ptr
->dither_index
[i
] = (png_byte
)i
;
192 if (num_palette
> maximum_colors
)
194 if (histogram
!= NULL
)
196 /* This is easy enough, just throw out the least used colors.
197 Perhaps not the best solution, but good enough. */
202 /* initialize an array to sort colors */
203 sort
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_palette
204 * sizeof (png_byte
)));
206 /* initialize the sort array */
207 for (i
= 0; i
< num_palette
; i
++)
208 sort
[i
] = (png_byte
)i
;
210 /* Find the least used palette entries by starting a
211 bubble sort, and running it until we have sorted
212 out enough colors. Note that we don't care about
213 sorting all the colors, just finding which are
216 for (i
= num_palette
- 1; i
>= maximum_colors
; i
--)
218 int done
; /* to stop early if the list is pre-sorted */
222 for (j
= 0; j
< i
; j
++)
224 if (histogram
[sort
[j
]] < histogram
[sort
[j
+ 1]])
229 sort
[j
] = sort
[j
+ 1];
238 /* swap the palette around, and set up a table, if necessary */
243 /* put all the useful colors within the max, but don't
245 for (i
= 0, j
= num_palette
; i
< maximum_colors
; i
++)
247 if ((int)sort
[i
] >= maximum_colors
)
251 while ((int)sort
[j
] >= maximum_colors
);
252 palette
[i
] = palette
[j
];
260 /* move all the used colors inside the max limit, and
261 develop a translation table */
262 for (i
= 0, j
= num_palette
; i
< maximum_colors
; i
++)
264 /* only move the colors we need to */
265 if ((int)sort
[i
] >= maximum_colors
)
271 while ((int)sort
[j
] >= maximum_colors
);
273 tmp_color
= palette
[j
];
274 palette
[j
] = palette
[i
];
275 palette
[i
] = tmp_color
;
276 /* indicate where the color went */
277 png_ptr
->dither_index
[j
] = (png_byte
)i
;
278 png_ptr
->dither_index
[i
] = (png_byte
)j
;
282 /* find closest color for those colors we are not using */
283 for (i
= 0; i
< num_palette
; i
++)
285 if ((int)png_ptr
->dither_index
[i
] >= maximum_colors
)
287 int min_d
, k
, min_k
, d_index
;
289 /* find the closest color to one we threw out */
290 d_index
= png_ptr
->dither_index
[i
];
291 min_d
= PNG_COLOR_DIST(palette
[d_index
], palette
[0]);
292 for (k
= 1, min_k
= 0; k
< maximum_colors
; k
++)
296 d
= PNG_COLOR_DIST(palette
[d_index
], palette
[k
]);
304 /* point to closest color */
305 png_ptr
->dither_index
[i
] = (png_byte
)min_k
;
309 png_free(png_ptr
, sort
);
313 /* This is much harder to do simply (and quickly). Perhaps
314 we need to go through a median cut routine, but those
315 don't always behave themselves with only a few colors
316 as input. So we will just find the closest two colors,
317 and throw out one of them (chosen somewhat randomly).
318 [I don't understand this at all, so if someone wants to
319 work on improving it, be my guest - AED]
325 png_bytep index_to_palette
;
326 /* where the original index currently is in the palette */
327 png_bytep palette_to_index
;
328 /* which original index points to this palette color */
330 /* initialize palette index arrays */
331 index_to_palette
= (png_bytep
)png_malloc(png_ptr
,
332 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
333 palette_to_index
= (png_bytep
)png_malloc(png_ptr
,
334 (png_uint_32
)(num_palette
* sizeof (png_byte
)));
336 /* initialize the sort array */
337 for (i
= 0; i
< num_palette
; i
++)
339 index_to_palette
[i
] = (png_byte
)i
;
340 palette_to_index
[i
] = (png_byte
)i
;
343 hash
= (png_dsortpp
)png_malloc(png_ptr
, (png_uint_32
)(769 *
344 sizeof (png_dsortp
)));
345 for (i
= 0; i
< 769; i
++)
347 /* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
349 num_new_palette
= num_palette
;
351 /* initial wild guess at how far apart the farthest pixel
352 pair we will be eliminating will be. Larger
353 numbers mean more areas will be allocated, Smaller
354 numbers run the risk of not saving enough data, and
355 having to do this all over again.
357 I have not done extensive checking on this number.
361 while (num_new_palette
> maximum_colors
)
363 for (i
= 0; i
< num_new_palette
- 1; i
++)
367 for (j
= i
+ 1; j
< num_new_palette
; j
++)
371 d
= PNG_COLOR_DIST(palette
[i
], palette
[j
]);
377 t
= (png_dsortp
)png_malloc(png_ptr
, (png_uint_32
)(sizeof
380 t
->left
= (png_byte
)i
;
381 t
->right
= (png_byte
)j
;
387 for (i
= 0; i
<= max_d
; i
++)
393 for (p
= hash
[i
]; p
; p
= p
->next
)
395 if ((int)index_to_palette
[p
->left
] < num_new_palette
&&
396 (int)index_to_palette
[p
->right
] < num_new_palette
)
400 if (num_new_palette
& 1)
412 palette
[index_to_palette
[j
]] = palette
[num_new_palette
];
417 for (k
= 0; k
< num_palette
; k
++)
419 if (png_ptr
->dither_index
[k
] ==
421 png_ptr
->dither_index
[k
] =
422 index_to_palette
[next_j
];
423 if ((int)png_ptr
->dither_index
[k
] ==
425 png_ptr
->dither_index
[k
] =
430 index_to_palette
[palette_to_index
[num_new_palette
]] =
432 palette_to_index
[index_to_palette
[j
]] =
433 palette_to_index
[num_new_palette
];
435 index_to_palette
[j
] = (png_byte
)num_new_palette
;
436 palette_to_index
[num_new_palette
] = (png_byte
)j
;
438 if (num_new_palette
<= maximum_colors
)
441 if (num_new_palette
<= maximum_colors
)
446 for (i
= 0; i
< 769; i
++)
458 png_free(png_ptr
, p
);
466 png_free(png_ptr
, hash
);
467 png_free(png_ptr
, palette_to_index
);
468 png_free(png_ptr
, index_to_palette
);
470 num_palette
= maximum_colors
;
472 if (png_ptr
->palette
== NULL
)
474 png_ptr
->palette
= palette
;
476 png_ptr
->num_palette
= (png_uint_16
)num_palette
;
481 int total_bits
, num_red
, num_green
, num_blue
;
482 png_size_t num_entries
;
485 total_bits
= PNG_DITHER_RED_BITS
+ PNG_DITHER_GREEN_BITS
+
486 PNG_DITHER_BLUE_BITS
;
488 num_red
= (1 << PNG_DITHER_RED_BITS
);
489 num_green
= (1 << PNG_DITHER_GREEN_BITS
);
490 num_blue
= (1 << PNG_DITHER_BLUE_BITS
);
491 num_entries
= ((png_size_t
)1 << total_bits
);
493 png_ptr
->palette_lookup
= (png_bytep
)png_malloc(png_ptr
,
494 (png_uint_32
)(num_entries
* sizeof (png_byte
)));
496 png_memset(png_ptr
->palette_lookup
, 0, num_entries
* sizeof (png_byte
));
498 distance
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(num_entries
*
501 png_memset(distance
, 0xff, num_entries
* sizeof(png_byte
));
503 for (i
= 0; i
< num_palette
; i
++)
505 int r
, g
, b
, ir
, ig
, ib
;
507 r
= (palette
[i
].red
>> (8 - PNG_DITHER_RED_BITS
));
508 g
= (palette
[i
].green
>> (8 - PNG_DITHER_GREEN_BITS
));
509 b
= (palette
[i
].blue
>> (8 - PNG_DITHER_BLUE_BITS
));
511 for (ir
= 0; ir
< num_red
; ir
++)
516 index_r
= (ir
<< (PNG_DITHER_BLUE_BITS
+ PNG_DITHER_GREEN_BITS
));
517 for (ig
= 0; ig
< num_green
; ig
++)
519 int dg
, dt
, dm
, index_g
;
523 dm
= ((dr
> dg
) ? dr
: dg
);
524 index_g
= index_r
| (ig
<< PNG_DITHER_BLUE_BITS
);
525 for (ib
= 0; ib
< num_blue
; ib
++)
527 int d_index
, db
, dmax
, d
;
529 d_index
= index_g
| ib
;
531 dmax
= ((dm
> db
) ? dm
: db
);
534 if (d
< (int)distance
[d_index
])
536 distance
[d_index
] = (png_byte
)d
;
537 png_ptr
->palette_lookup
[d_index
] = (png_byte
)i
;
544 png_free(png_ptr
, distance
);
549 #if defined(PNG_READ_GAMMA_SUPPORTED)
550 /* Transform the image from the file_gamma to the screen_gamma. We
551 * only do transformations on images where the file_gamma and screen_gamma
552 * are not close reciprocals, otherwise it slows things down slightly, and
553 * also needlessly introduces small errors.
556 png_set_gamma(png_structp png_ptr
, double scrn_gamma
, double file_gamma
)
558 png_debug(1, "in png_set_gamma\n");
559 if (fabs(scrn_gamma
* file_gamma
- 1.0) > PNG_GAMMA_THRESHOLD
)
560 png_ptr
->transformations
|= PNG_GAMMA
;
561 png_ptr
->gamma
= (float)file_gamma
;
562 png_ptr
->screen_gamma
= (float)scrn_gamma
;
566 #if defined(PNG_READ_EXPAND_SUPPORTED)
567 /* Expand paletted images to rgb, expand grayscale images of
568 * less then 8 bit depth to 8 bit depth, and expand tRNS chunks
572 png_set_expand(png_structp png_ptr
)
574 png_debug(1, "in png_set_expand\n");
575 png_ptr
->transformations
|= PNG_EXPAND
;
579 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
581 png_set_gray_to_rgb(png_structp png_ptr
)
583 png_debug(1, "in png_set_gray_to_rgb\n");
584 png_ptr
->transformations
|= PNG_GRAY_TO_RGB
;
588 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
589 /* Convert a RGB image to a grayscale of the given width. This would
590 * allow us, for example, to convert a 24 bpp RGB image into an 8 or
591 * 16 bpp grayscale image. (Not yet implemented.)
594 png_set_rgb_to_gray(png_structp png_ptr
, int gray_bits
)
596 png_debug(1, "in png_set_rgb_to_gray\n");
597 png_ptr
->transformations
|= PNG_RGB_TO_GRAY
;
598 /* Need to do something with gray_bits here. */
599 png_warning(png_ptr
, "RGB to GRAY transformation is not yet implemented.");
603 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
605 png_set_read_user_transform_fn(png_structp png_ptr
, png_user_transform_ptr
606 read_user_transform_fn
)
608 png_debug(1, "in png_set_read_user_transform_fn\n");
609 png_ptr
->transformations
|= PNG_USER_TRANSFORM
;
610 png_ptr
->read_user_transform_fn
= read_user_transform_fn
;
614 /* Initialize everything needed for the read. This includes modifying
618 png_init_read_transformations(png_structp png_ptr
)
622 png_debug(1, "in png_init_read_transformations\n");
623 color_type
= png_ptr
->color_type
;
625 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
626 if (png_ptr
->transformations
& PNG_BACKGROUND_EXPAND
)
628 if (color_type
== PNG_COLOR_TYPE_GRAY
)
630 /* expand background chunk. */
631 switch (png_ptr
->bit_depth
)
634 png_ptr
->background
.gray
*= (png_uint_16
)0xff;
635 png_ptr
->background
.red
= png_ptr
->background
.green
=
636 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
639 png_ptr
->background
.gray
*= (png_uint_16
)0x55;
640 png_ptr
->background
.red
= png_ptr
->background
.green
=
641 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
644 png_ptr
->background
.gray
*= (png_uint_16
)0x11;
645 png_ptr
->background
.red
= png_ptr
->background
.green
=
646 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
650 png_ptr
->background
.red
= png_ptr
->background
.green
=
651 png_ptr
->background
.blue
= png_ptr
->background
.gray
;
655 else if (color_type
== PNG_COLOR_TYPE_PALETTE
)
657 png_ptr
->background
.red
=
658 png_ptr
->palette
[png_ptr
->background
.index
].red
;
659 png_ptr
->background
.green
=
660 png_ptr
->palette
[png_ptr
->background
.index
].green
;
661 png_ptr
->background
.blue
=
662 png_ptr
->palette
[png_ptr
->background
.index
].blue
;
664 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
665 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
667 #if defined(PNG_READ_EXPAND_SUPPORTED)
668 if (!(png_ptr
->transformations
& PNG_EXPAND
))
671 /* invert the alpha channel (in tRNS) unless the pixels are
672 going to be expanded, in which case leave it for later */
674 for (i
=0; i
<(int)png_ptr
->num_trans
; i
++)
675 png_ptr
->trans
[i
] = 255 - png_ptr
->trans
[i
];
684 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
685 png_ptr
->background_1
= png_ptr
->background
;
687 #if defined(PNG_READ_GAMMA_SUPPORTED)
688 if (png_ptr
->transformations
& PNG_GAMMA
)
690 png_build_gamma_table(png_ptr
);
691 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
692 if (png_ptr
->transformations
& PNG_BACKGROUND
)
694 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
697 png_color back
, back_1
;
700 palette
= png_ptr
->palette
;
701 num_palette
= png_ptr
->num_palette
;
703 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
705 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
706 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
707 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
709 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
710 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
711 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
717 switch (png_ptr
->background_gamma_type
)
719 case PNG_BACKGROUND_GAMMA_SCREEN
:
720 g
= (png_ptr
->screen_gamma
);
723 case PNG_BACKGROUND_GAMMA_FILE
:
724 g
= 1.0 / (png_ptr
->gamma
);
725 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
727 case PNG_BACKGROUND_GAMMA_UNIQUE
:
728 g
= 1.0 / (png_ptr
->background_gamma
);
729 gs
= 1.0 / (png_ptr
->background_gamma
*
730 png_ptr
->screen_gamma
);
733 g
= 1.0; /* back_1 */
737 if ( fabs(gs
- 1.0) < PNG_GAMMA_THRESHOLD
)
739 back
.red
= (png_byte
)png_ptr
->background
.red
;
740 back
.green
= (png_byte
)png_ptr
->background
.green
;
741 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
745 back
.red
= (png_byte
)(pow(
746 (double)png_ptr
->background
.red
/255, gs
) * 255.0 + .5);
747 back
.green
= (png_byte
)(pow(
748 (double)png_ptr
->background
.green
/255, gs
) * 255.0 + .5);
749 back
.blue
= (png_byte
)(pow(
750 (double)png_ptr
->background
.blue
/255, gs
) * 255.0 + .5);
753 back_1
.red
= (png_byte
)(pow(
754 (double)png_ptr
->background
.red
/255, g
) * 255.0 + .5);
755 back_1
.green
= (png_byte
)(pow(
756 (double)png_ptr
->background
.green
/255, g
) * 255.0 + .5);
757 back_1
.blue
= (png_byte
)(pow(
758 (double)png_ptr
->background
.blue
/255, g
) * 255.0 + .5);
761 for (i
= 0; i
< num_palette
; i
++)
763 if (i
< (int)png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
765 if (png_ptr
->trans
[i
] == 0)
769 else /* if (png_ptr->trans[i] != 0xff) */
773 v
= png_ptr
->gamma_to_1
[palette
[i
].red
];
774 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
775 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
777 v
= png_ptr
->gamma_to_1
[palette
[i
].green
];
778 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
779 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
781 v
= png_ptr
->gamma_to_1
[palette
[i
].blue
];
782 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
783 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
788 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
789 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
790 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
794 /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/
796 /* color_type != PNG_COLOR_TYPE_PALETTE */
800 m
= (double)(((png_uint_32
)1 << png_ptr
->bit_depth
) - 1);
804 switch (png_ptr
->background_gamma_type
)
806 case PNG_BACKGROUND_GAMMA_SCREEN
:
807 g
= (png_ptr
->screen_gamma
);
810 case PNG_BACKGROUND_GAMMA_FILE
:
811 g
= 1.0 / (png_ptr
->gamma
);
812 gs
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
814 case PNG_BACKGROUND_GAMMA_UNIQUE
:
815 g
= 1.0 / (png_ptr
->background_gamma
);
816 gs
= 1.0 / (png_ptr
->background_gamma
*
817 png_ptr
->screen_gamma
);
821 if (color_type
& PNG_COLOR_MASK_COLOR
)
824 png_ptr
->background_1
.red
= (png_uint_16
)(pow(
825 (double)png_ptr
->background
.red
/ m
, g
) * m
+ .5);
826 png_ptr
->background_1
.green
= (png_uint_16
)(pow(
827 (double)png_ptr
->background
.green
/ m
, g
) * m
+ .5);
828 png_ptr
->background_1
.blue
= (png_uint_16
)(pow(
829 (double)png_ptr
->background
.blue
/ m
, g
) * m
+ .5);
830 png_ptr
->background
.red
= (png_uint_16
)(pow(
831 (double)png_ptr
->background
.red
/ m
, gs
) * m
+ .5);
832 png_ptr
->background
.green
= (png_uint_16
)(pow(
833 (double)png_ptr
->background
.green
/ m
, gs
) * m
+ .5);
834 png_ptr
->background
.blue
= (png_uint_16
)(pow(
835 (double)png_ptr
->background
.blue
/ m
, gs
) * m
+ .5);
839 /* GRAY or GRAY ALPHA */
840 png_ptr
->background_1
.gray
= (png_uint_16
)(pow(
841 (double)png_ptr
->background
.gray
/ m
, g
) * m
+ .5);
842 png_ptr
->background
.gray
= (png_uint_16
)(pow(
843 (double)png_ptr
->background
.gray
/ m
, gs
) * m
+ .5);
848 /* transformation does not include PNG_BACKGROUND */
850 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
855 palette
= png_ptr
->palette
;
856 num_palette
= png_ptr
->num_palette
;
858 for (i
= 0; i
< num_palette
; i
++)
860 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
861 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
862 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
866 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
870 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
871 /* No GAMMA transformation */
872 if (png_ptr
->transformations
& PNG_BACKGROUND
&&
873 color_type
== PNG_COLOR_TYPE_PALETTE
)
879 palette
= png_ptr
->palette
;
880 back
.red
= (png_byte
)png_ptr
->background
.red
;
881 back
.green
= (png_byte
)png_ptr
->background
.green
;
882 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
884 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
886 if (png_ptr
->trans
[i
] == 0)
890 else if (png_ptr
->trans
[i
] != 0xff)
892 png_composite(palette
[i
].red
, palette
[i
].red
,
893 png_ptr
->trans
[i
], back
.red
);
894 png_composite(palette
[i
].green
, palette
[i
].green
,
895 png_ptr
->trans
[i
], back
.green
);
896 png_composite(palette
[i
].blue
, palette
[i
].blue
,
897 png_ptr
->trans
[i
], back
.blue
);
903 #if defined(PNG_READ_SHIFT_SUPPORTED)
904 if ((png_ptr
->transformations
& PNG_SHIFT
) &&
905 color_type
== PNG_COLOR_TYPE_PALETTE
)
910 sr
= 8 - png_ptr
->sig_bit
.red
;
911 if (sr
< 0 || sr
> 8)
913 sg
= 8 - png_ptr
->sig_bit
.green
;
914 if (sg
< 0 || sg
> 8)
916 sb
= 8 - png_ptr
->sig_bit
.blue
;
917 if (sb
< 0 || sb
> 8)
919 for (i
= 0; i
< png_ptr
->num_palette
; i
++)
921 png_ptr
->palette
[i
].red
>>= sr
;
922 png_ptr
->palette
[i
].green
>>= sg
;
923 png_ptr
->palette
[i
].blue
>>= sb
;
929 /* Modify the info structure to reflect the transformations. The
930 * info should be updated so a PNG file could be written with it,
931 * assuming the transformations result in valid PNG data.
934 png_read_transform_info(png_structp png_ptr
, png_infop info_ptr
)
936 png_debug(1, "in png_read_transform_info\n");
937 #if defined(PNG_READ_EXPAND_SUPPORTED)
938 if (png_ptr
->transformations
& PNG_EXPAND
)
940 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
942 if (png_ptr
->num_trans
)
943 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
945 info_ptr
->color_type
= PNG_COLOR_TYPE_RGB
;
946 info_ptr
->bit_depth
= 8;
947 info_ptr
->num_trans
= 0;
951 if (png_ptr
->num_trans
)
952 info_ptr
->color_type
|= PNG_COLOR_MASK_ALPHA
;
953 if (info_ptr
->bit_depth
< 8)
954 info_ptr
->bit_depth
= 8;
955 info_ptr
->num_trans
= 0;
960 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
961 if (png_ptr
->transformations
& PNG_BACKGROUND
)
963 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
964 info_ptr
->num_trans
= 0;
965 info_ptr
->background
= png_ptr
->background
;
969 #if defined(PNG_READ_16_TO_8_SUPPORTED)
970 if ((png_ptr
->transformations
& PNG_16_TO_8
) && info_ptr
->bit_depth
== 16)
971 info_ptr
->bit_depth
= 8;
974 #if defined(PNG_READ_DITHER_SUPPORTED)
975 if (png_ptr
->transformations
& PNG_DITHER
)
977 if (((info_ptr
->color_type
== PNG_COLOR_TYPE_RGB
) ||
978 (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)) &&
979 png_ptr
->palette_lookup
&& info_ptr
->bit_depth
== 8)
981 info_ptr
->color_type
= PNG_COLOR_TYPE_PALETTE
;
986 #if defined(PNG_READ_PACK_SUPPORTED)
987 if ((png_ptr
->transformations
& PNG_PACK
) && info_ptr
->bit_depth
< 8)
988 info_ptr
->bit_depth
= 8;
991 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
992 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
993 info_ptr
->color_type
|= PNG_COLOR_MASK_COLOR
;
996 if (info_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
997 info_ptr
->channels
= 1;
998 else if (info_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
999 info_ptr
->channels
= 3;
1001 info_ptr
->channels
= 1;
1003 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1004 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1005 info_ptr
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
1008 #if defined(PNG_READ_FILLER_SUPPORTED)
1009 if ((png_ptr
->transformations
& PNG_FILLER
) &&
1010 info_ptr
->color_type
& PNG_COLOR_TYPE_RGB
&&
1011 info_ptr
->channels
== 3)
1013 info_ptr
->channels
= 4;
1017 if (info_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)
1018 info_ptr
->channels
++;
1019 info_ptr
->pixel_depth
= (png_byte
)(info_ptr
->channels
*
1020 info_ptr
->bit_depth
);
1022 info_ptr
->rowbytes
= ((info_ptr
->width
* info_ptr
->pixel_depth
+ 7) >> 3);
1025 /* Transform the row. The order of transformations is significant,
1026 * and is very touchy. If you add a transformation, take care to
1027 * decide how it fits in with the other transformations here.
1030 png_do_read_transformations(png_structp png_ptr
)
1032 png_debug(1, "in png_do_read_transformations\n");
1033 #if !defined(PNG_USELESS_TESTS_SUPPORTED)
1034 if (png_ptr
->row_buf
== NULL
)
1036 #if !defined(PNG_NO_STDIO)
1039 sprintf(msg
, "NULL row buffer for row %ld, pass %d", png_ptr
->row_number
,
1041 png_error(png_ptr
, msg
);
1043 png_error(png_ptr
, "NULL row buffer");
1048 #if defined(PNG_READ_EXPAND_SUPPORTED)
1049 if (png_ptr
->transformations
& PNG_EXPAND
)
1051 if (png_ptr
->row_info
.color_type
== PNG_COLOR_TYPE_PALETTE
)
1053 png_do_expand_palette(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1054 png_ptr
->palette
, png_ptr
->trans
, png_ptr
->num_trans
);
1056 else if (png_ptr
->transformations
& PNG_EXPAND
)
1058 if (png_ptr
->num_trans
)
1059 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1060 &(png_ptr
->trans_values
));
1062 png_do_expand(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1068 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1069 if (png_ptr
->transformations
& PNG_STRIP_ALPHA
)
1070 png_do_strip_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1071 PNG_FLAG_FILLER_AFTER
);
1074 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1075 if ((png_ptr
->transformations
& PNG_BACKGROUND
) &&
1076 ((png_ptr
->num_trans
!= 0 ) ||
1077 (png_ptr
->color_type
& PNG_COLOR_MASK_ALPHA
)))
1078 png_do_background(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1079 &(png_ptr
->trans_values
), &(png_ptr
->background
),
1080 &(png_ptr
->background_1
),
1081 png_ptr
->gamma_table
, png_ptr
->gamma_from_1
,
1082 png_ptr
->gamma_to_1
, png_ptr
->gamma_16_table
,
1083 png_ptr
->gamma_16_from_1
, png_ptr
->gamma_16_to_1
,
1084 png_ptr
->gamma_shift
);
1087 #if defined(PNG_READ_GAMMA_SUPPORTED)
1088 if ((png_ptr
->transformations
& PNG_GAMMA
) &&
1089 !(png_ptr
->transformations
& PNG_BACKGROUND
) &&
1090 (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
))
1091 png_do_gamma(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1092 png_ptr
->gamma_table
, png_ptr
->gamma_16_table
,
1093 png_ptr
->gamma_shift
);
1096 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1097 if (png_ptr
->transformations
& PNG_RGB_TO_GRAY
)
1098 png_do_rgb_to_gray(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1101 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1102 if (png_ptr
->transformations
& PNG_16_TO_8
)
1103 png_do_chop(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1106 #if defined(PNG_READ_DITHER_SUPPORTED)
1107 if (png_ptr
->transformations
& PNG_DITHER
)
1109 png_do_dither((png_row_infop
)&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1110 png_ptr
->palette_lookup
, png_ptr
->dither_index
);
1111 if(png_ptr
->row_info
.rowbytes
== (png_uint_32
)0)
1112 png_error(png_ptr
, "png_do_dither returned rowbytes=0");
1116 #if defined(PNG_READ_INVERT_SUPPORTED)
1117 if (png_ptr
->transformations
& PNG_INVERT_MONO
)
1118 png_do_invert(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1121 #if defined(PNG_READ_SHIFT_SUPPORTED)
1122 if (png_ptr
->transformations
& PNG_SHIFT
)
1123 png_do_unshift(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1127 #if defined(PNG_READ_PACK_SUPPORTED)
1128 if (png_ptr
->transformations
& PNG_PACK
)
1129 png_do_unpack(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1132 #if defined(PNG_READ_BGR_SUPPORTED)
1133 if (png_ptr
->transformations
& PNG_BGR
)
1134 png_do_bgr(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1137 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1138 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1139 png_do_packswap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1142 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1143 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
1144 png_do_gray_to_rgb(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1147 #if defined(PNG_READ_FILLER_SUPPORTED)
1148 if (png_ptr
->transformations
& PNG_FILLER
)
1149 png_do_read_filler(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1,
1150 (png_uint_32
)png_ptr
->filler
, png_ptr
->flags
);
1153 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1154 if (png_ptr
->transformations
& PNG_INVERT_ALPHA
)
1155 png_do_read_invert_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1158 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1159 if (png_ptr
->transformations
& PNG_SWAP_ALPHA
)
1160 png_do_read_swap_alpha(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1163 #if defined(PNG_READ_SWAP_SUPPORTED)
1164 if (png_ptr
->transformations
& PNG_SWAP_BYTES
)
1165 png_do_swap(&(png_ptr
->row_info
), png_ptr
->row_buf
+ 1);
1168 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1169 if (png_ptr
->transformations
& PNG_USER_TRANSFORM
)
1170 if(png_ptr
->read_user_transform_fn
!= NULL
)
1171 (*(png_ptr
->read_user_transform_fn
)) /* user read transform function */
1172 (png_ptr
, /* png_ptr */
1173 &(png_ptr
->row_info
), /* row_info: */
1174 /* png_uint_32 width; width of row */
1175 /* png_uint_32 rowbytes; number of bytes in row */
1176 /* png_byte color_type; color type of pixels */
1177 /* png_byte bit_depth; bit depth of samples */
1178 /* png_byte channels; number of channels (1-4) */
1179 /* png_byte pixel_depth; bits per pixel (depth*channels) */
1180 png_ptr
->row_buf
+ 1); /* start of pixel data for row */
1185 #if defined(PNG_READ_PACK_SUPPORTED)
1186 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1187 * without changing the actual values. Thus, if you had a row with
1188 * a bit depth of 1, you would end up with bytes that only contained
1189 * the numbers 0 or 1. If you would rather they contain 0 and 255, use
1190 * png_do_shift() after this.
1193 png_do_unpack(png_row_infop row_info
, png_bytep row
)
1195 png_debug(1, "in png_do_unpack\n");
1196 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1197 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
< 8)
1199 if (row_info
->bit_depth
< 8)
1202 png_uint_32 shift
, i
;
1205 switch (row_info
->bit_depth
)
1209 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
1210 dp
= row
+ (png_size_t
)row_info
->width
- 1;
1211 shift
= 7 - (int)((row_info
->width
+ 7) & 7);
1212 for (i
= 0; i
< row_info
->width
; i
++)
1214 *dp
= (png_byte
)((*sp
>> shift
) & 0x1);
1230 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 2);
1231 dp
= row
+ (png_size_t
)row_info
->width
- 1;
1232 shift
= (int)((3 - ((row_info
->width
+ 3) & 3)) << 1);
1233 for (i
= 0; i
< row_info
->width
; i
++)
1235 *dp
= (png_byte
)((*sp
>> shift
) & 0x3);
1250 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
1251 dp
= row
+ (png_size_t
)row_info
->width
- 1;
1252 shift
= (int)((1 - ((row_info
->width
+ 1) & 1)) << 2);
1253 for (i
= 0; i
< row_info
->width
; i
++)
1255 *dp
= (png_byte
)((*sp
>> shift
) & 0xf);
1269 row_info
->bit_depth
= 8;
1270 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1271 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1276 #if defined(PNG_READ_SHIFT_SUPPORTED)
1277 /* Reverse the effects of png_do_shift. This routine merely shifts the
1278 * pixels back to their significant bits values. Thus, if you have
1279 * a row of bit depth 8, but only 5 are significant, this will shift
1280 * the values back to 0 through 31.
1283 png_do_unshift(png_row_infop row_info
, png_bytep row
, png_color_8p sig_bits
)
1285 png_debug(1, "in png_do_unshift\n");
1287 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1288 row
!= NULL
&& row_info
!= NULL
&& sig_bits
!= NULL
&&
1290 row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
1297 if (row_info
->color_type
& PNG_COLOR_MASK_COLOR
)
1299 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->red
;
1300 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->green
;
1301 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->blue
;
1305 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->gray
;
1307 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
1309 shift
[channels
++] = row_info
->bit_depth
- sig_bits
->alpha
;
1314 for (c
= 0; c
< channels
; c
++)
1325 switch (row_info
->bit_depth
)
1332 for (bp
= row
, i
= 0; i
< row_info
->rowbytes
; i
++, bp
++)
1345 mask
= (png_byte
)(((int)0xf0 >> shift
[0]) & (int)0xf0) |
1346 (png_byte
)((int)0xf >> shift
[0]);
1347 for (bp
= row
, i
= 0; i
< row_info
->rowbytes
; i
++, bp
++)
1359 for (bp
= row
, i
= 0; i
< row_info
->width
; i
++)
1361 for (c
= 0; c
< (int)row_info
->channels
; c
++, bp
++)
1373 for (bp
= row
, i
= 0; i
< row_info
->width
; i
++)
1375 for (c
= 0; c
< (int)row_info
->channels
; c
++, bp
+= 2)
1377 value
= (png_uint_16
)((*bp
<< 8) + *(bp
+ 1));
1379 *bp
= (png_byte
)(value
>> 8);
1380 *(bp
+ 1) = (png_byte
)(value
& 0xff);
1390 #if defined(PNG_READ_16_TO_8_SUPPORTED)
1391 /* chop rows of bit depth 16 down to 8 */
1393 png_do_chop(png_row_infop row_info
, png_bytep row
)
1395 png_debug(1, "in png_do_chop\n");
1396 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1397 if (row
!= NULL
&& row_info
!= NULL
&& row_info
->bit_depth
== 16)
1399 if (row_info
->bit_depth
== 16)
1407 for (i
= 0; i
< row_info
->width
* row_info
->channels
; i
++, sp
+= 2, dp
++)
1409 #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1410 /* This does a more accurate scaling of the 16-bit color
1411 * value, rather than a simple low-byte truncation.
1413 * What the ideal calculation should be:
1414 *dp = (((((png_uint_32)(*sp) << 8) |
1415 (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1418 * GRR: no, I think this is what it really should be:
1419 *dp = (((((png_uint_32)(*sp) << 8) |
1420 (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1422 * GRR: here's the exact calculation with shifts:
1423 temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1424 *dp = (temp - (temp >> 8)) >> 8;
1427 * Approximate calculation with shift/add instead of multiply/divide:
1428 *dp = ((((png_uint_32)(*sp) << 8) |
1429 (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1431 * What we actually do to avoid extra shifting and conversion: */
1432 *dp
= *sp
+ ((((int)(*(sp
+ 1)) - *sp
) > 128) ? 1 : 0);
1437 row_info
->bit_depth
= 8;
1438 row_info
->pixel_depth
= (png_byte
)(8 * row_info
->channels
);
1439 row_info
->rowbytes
= row_info
->width
* row_info
->channels
;
1444 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1446 png_do_read_swap_alpha(png_row_infop row_info
, png_bytep row
)
1448 png_debug(1, "in png_do_read_swap_alpha\n");
1449 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1450 if (row
!= NULL
&& row_info
!= NULL
)
1453 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1455 /* This converts from RGBA to ARGB */
1456 if (row_info
->bit_depth
== 8)
1462 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1463 i
< row_info
->width
; i
++)
1472 /* This converts from RRGGBBAA to AARRGGBB */
1479 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1480 i
< row_info
->width
; i
++)
1495 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1497 /* This converts from GA to AG */
1498 if (row_info
->bit_depth
== 8)
1504 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1505 i
< row_info
->width
; i
++)
1512 /* This converts from GGAA to AAGG */
1519 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1520 i
< row_info
->width
; i
++)
1535 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1537 png_do_read_invert_alpha(png_row_infop row_info
, png_bytep row
)
1539 png_debug(1, "in png_do_read_invert_alpha\n");
1540 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1541 if (row
!= NULL
&& row_info
!= NULL
)
1544 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
1546 /* This inverts the alpha channel in RGBA */
1547 if (row_info
->bit_depth
== 8)
1552 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1553 i
< row_info
->width
; i
++)
1555 *(--dp
) = 255 - *(--sp
);
1561 /* This inverts the alpha channel in RRGGBBAA */
1567 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1568 i
< row_info
->width
; i
++)
1570 *(--dp
) = 255 - *(--sp
);
1571 *(--dp
) = 255 - *(--sp
);
1581 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1583 /* This inverts the alpha channel in GA */
1584 if (row_info
->bit_depth
== 8)
1589 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1590 i
< row_info
->width
; i
++)
1592 *(--dp
) = 255 - *(--sp
);
1596 /* This inverts the alpha channel in GGAA */
1602 for (i
= 0, sp
= dp
= row
+ row_info
->rowbytes
;
1603 i
< row_info
->width
; i
++)
1605 *(--dp
) = 255 - *(--sp
);
1606 *(--dp
) = 255 - *(--sp
);
1616 #if defined(PNG_READ_FILLER_SUPPORTED)
1617 /* Add filler channel if we have RGB color */
1619 png_do_read_filler(png_row_infop row_info
, png_bytep row
,
1620 png_uint_32 filler
, png_uint_32 flags
)
1625 png_debug(1, "in png_do_read_filler\n");
1627 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1628 row
!= NULL
&& row_info
!= NULL
&&
1630 row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& row_info
->bit_depth
== 8)
1632 /* This changes the data from RGB to RGBX */
1633 if (flags
& PNG_FLAG_FILLER_AFTER
)
1635 for (i
= 1, sp
= row
+ (png_size_t
)row_info
->width
* 3,
1636 dp
= row
+ (png_size_t
)row_info
->width
* 4;
1637 i
< row_info
->width
;
1640 *(--dp
) = (png_byte
)filler
;
1645 *(--dp
) = (png_byte
)filler
;
1646 row_info
->channels
= 4;
1647 row_info
->pixel_depth
= 32;
1648 row_info
->rowbytes
= row_info
->width
* 4;
1650 /* This changes the data from RGB to XRGB */
1653 for (i
= 0, sp
= row
+ (png_size_t
)row_info
->width
* 3,
1654 dp
= row
+ (png_size_t
)row_info
->width
* 4;
1655 i
< row_info
->width
;
1661 *(--dp
) = (png_byte
)filler
;
1663 row_info
->channels
= 4;
1664 row_info
->pixel_depth
= 32;
1665 row_info
->rowbytes
= row_info
->width
* 4;
1671 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1672 /* expand grayscale files to RGB, with or without alpha */
1674 png_do_gray_to_rgb(png_row_infop row_info
, png_bytep row
)
1679 png_debug(1, "in png_do_gray_to_rgb\n");
1680 if (row_info
->bit_depth
>= 8 &&
1681 #if defined(PNG_USELESS_TESTS_SUPPORTED)
1682 row
!= NULL
&& row_info
!= NULL
&&
1684 !(row_info
->color_type
& PNG_COLOR_MASK_COLOR
))
1686 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
1688 if (row_info
->bit_depth
== 8)
1690 for (i
= 0, sp
= row
+ (png_size_t
)row_info
->width
- 1,
1691 dp
= row
+ (png_size_t
)row_info
->width
* 3 - 1;
1692 i
< row_info
->width
;
1703 for (i
= 0, sp
= row
+ (png_size_t
)row_info
->width
* 2 - 1,
1704 dp
= row
+ (png_size_t
)row_info
->width
* 6 - 1;
1705 i
< row_info
->width
;
1709 *(dp
--) = *(sp
- 1);
1711 *(dp
--) = *(sp
- 1);
1713 *(dp
--) = *(sp
- 1);
1719 else if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
1721 if (row_info
->bit_depth
== 8)
1723 for (i
= 0, sp
= row
+ (png_size_t
)row_info
->width
* 2 - 1,
1724 dp
= row
+ (png_size_t
)row_info
->width
* 4 - 1;
1725 i
< row_info
->width
;
1737 for (i
= 0, sp
= row
+ (png_size_t
)row_info
->width
* 4 - 1,
1738 dp
= row
+ (png_size_t
)row_info
->width
* 8 - 1;
1739 i
< row_info
->width
;
1745 *(dp
--) = *(sp
- 1);
1747 *(dp
--) = *(sp
- 1);
1749 *(dp
--) = *(sp
- 1);
1755 row_info
->channels
+= (png_byte
)2;
1756 row_info
->color_type
|= PNG_COLOR_MASK_COLOR
;
1757 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
1758 row_info
->bit_depth
);
1759 row_info
->rowbytes
= ((row_info
->width
*
1760 row_info
->pixel_depth
+ 7) >> 3);
1765 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
1766 * large of png_color. This lets grayscale images be treated as
1767 * paletted. Most useful for gamma correction and simplification
1771 png_build_grayscale_palette(int bit_depth
, png_colorp palette
)
1778 png_debug(1, "in png_do_build_grayscale_palette\n");
1779 if (palette
== NULL
)
1806 for (i
= 0, v
= 0; i
< num_palette
; i
++, v
+= color_inc
)
1808 palette
[i
].red
= (png_byte
)v
;
1809 palette
[i
].green
= (png_byte
)v
;
1810 palette
[i
].blue
= (png_byte
)v
;
1814 /* This function is currently unused. Do we really need it? */
1815 #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
1817 png_correct_palette(png_structp png_ptr
, png_colorp palette
,
1820 png_debug(1, "in png_correct_palette\n");
1821 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1822 if ((png_ptr
->transformations
& (PNG_GAMMA
)) &&
1823 (png_ptr
->transformations
& (PNG_BACKGROUND
)))
1825 png_color back
, back_1
;
1827 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_FILE
)
1829 back
.red
= png_ptr
->gamma_table
[png_ptr
->background
.red
];
1830 back
.green
= png_ptr
->gamma_table
[png_ptr
->background
.green
];
1831 back
.blue
= png_ptr
->gamma_table
[png_ptr
->background
.blue
];
1833 back_1
.red
= png_ptr
->gamma_to_1
[png_ptr
->background
.red
];
1834 back_1
.green
= png_ptr
->gamma_to_1
[png_ptr
->background
.green
];
1835 back_1
.blue
= png_ptr
->gamma_to_1
[png_ptr
->background
.blue
];
1841 g
= 1.0 / (png_ptr
->background_gamma
* png_ptr
->screen_gamma
);
1843 if (png_ptr
->background_gamma_type
== PNG_BACKGROUND_GAMMA_SCREEN
||
1844 fabs(g
- 1.0) < PNG_GAMMA_THRESHOLD
)
1846 back
.red
= png_ptr
->background
.red
;
1847 back
.green
= png_ptr
->background
.green
;
1848 back
.blue
= png_ptr
->background
.blue
;
1853 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
1856 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
1859 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
1863 g
= 1.0 / png_ptr
->background_gamma
;
1866 (png_byte
)(pow((double)png_ptr
->background
.red
/255, g
) *
1869 (png_byte
)(pow((double)png_ptr
->background
.green
/255, g
) *
1872 (png_byte
)(pow((double)png_ptr
->background
.blue
/255, g
) *
1876 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1880 for (i
= 0; i
< (png_uint_32
)num_palette
; i
++)
1882 if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] == 0)
1886 else if (i
< png_ptr
->num_trans
&& png_ptr
->trans
[i
] != 0xff)
1890 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].red
];
1891 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.red
);
1892 palette
[i
].red
= png_ptr
->gamma_from_1
[w
];
1894 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].green
];
1895 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.green
);
1896 palette
[i
].green
= png_ptr
->gamma_from_1
[w
];
1898 v
= png_ptr
->gamma_to_1
[png_ptr
->palette
[i
].blue
];
1899 png_composite(w
, v
, png_ptr
->trans
[i
], back_1
.blue
);
1900 palette
[i
].blue
= png_ptr
->gamma_from_1
[w
];
1904 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1905 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1906 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1914 for (i
= 0; i
< num_palette
; i
++)
1916 if (palette
[i
].red
== (png_byte
)png_ptr
->trans_values
.gray
)
1922 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1923 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1924 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1931 #if defined(PNG_READ_GAMMA_SUPPORTED)
1932 if (png_ptr
->transformations
& PNG_GAMMA
)
1936 for (i
= 0; i
< num_palette
; i
++)
1938 palette
[i
].red
= png_ptr
->gamma_table
[palette
[i
].red
];
1939 palette
[i
].green
= png_ptr
->gamma_table
[palette
[i
].green
];
1940 palette
[i
].blue
= png_ptr
->gamma_table
[palette
[i
].blue
];
1943 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1947 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1948 if (png_ptr
->transformations
& PNG_BACKGROUND
)
1950 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1954 back
.red
= (png_byte
)png_ptr
->background
.red
;
1955 back
.green
= (png_byte
)png_ptr
->background
.green
;
1956 back
.blue
= (png_byte
)png_ptr
->background
.blue
;
1958 for (i
= 0; i
< (int)png_ptr
->num_trans
; i
++)
1960 if (png_ptr
->trans
[i
] == 0)
1962 palette
[i
].red
= back
.red
;
1963 palette
[i
].green
= back
.green
;
1964 palette
[i
].blue
= back
.blue
;
1966 else if (png_ptr
->trans
[i
] != 0xff)
1968 png_composite(palette
[i
].red
, png_ptr
->palette
[i
].red
,
1969 png_ptr
->trans
[i
], back
.red
);
1970 png_composite(palette
[i
].green
, png_ptr
->palette
[i
].green
,
1971 png_ptr
->trans
[i
], back
.green
);
1972 png_composite(palette
[i
].blue
, png_ptr
->palette
[i
].blue
,
1973 png_ptr
->trans
[i
], back
.blue
);
1977 else /* assume grayscale palette (what else could it be?) */
1981 for (i
= 0; i
< num_palette
; i
++)
1983 if (i
== (png_byte
)png_ptr
->trans_values
.gray
)
1985 palette
[i
].red
= (png_byte
)png_ptr
->background
.red
;
1986 palette
[i
].green
= (png_byte
)png_ptr
->background
.green
;
1987 palette
[i
].blue
= (png_byte
)png_ptr
->background
.blue
;
1996 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
1997 /* Replace any alpha or transparency with the supplied background color.
1998 * "background" is already in the screen gamma, while "background_1" is
1999 * at a gamma of 1.0. Paletted files have already been taken care of.
2002 png_do_background(png_row_infop row_info
, png_bytep row
,
2003 png_color_16p trans_values
, png_color_16p background
,
2004 png_color_16p background_1
,
2005 png_bytep gamma_table
, png_bytep gamma_from_1
, png_bytep gamma_to_1
,
2006 png_uint_16pp gamma_16
, png_uint_16pp gamma_16_from_1
,
2007 png_uint_16pp gamma_16_to_1
, int gamma_shift
)
2013 png_debug(1, "in png_do_background\n");
2014 if (background
!= NULL
&&
2015 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2016 row
!= NULL
&& row_info
!= NULL
&&
2018 (!(row_info
->color_type
& PNG_COLOR_MASK_ALPHA
) ||
2019 (row_info
->color_type
!= PNG_COLOR_TYPE_PALETTE
&& trans_values
)))
2021 switch (row_info
->color_type
)
2023 case PNG_COLOR_TYPE_GRAY
:
2025 switch (row_info
->bit_depth
)
2031 for (i
= 0; i
< row_info
->width
; i
++)
2033 if ((png_uint_16
)((*sp
>> shift
) & 0x1)
2034 == trans_values
->gray
)
2036 *sp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2037 *sp
|= (png_byte
)(background
->gray
<< shift
);
2053 for (i
= 0; i
< row_info
->width
; i
++)
2055 if ((png_uint_16
)((*sp
>> shift
) & 0x3)
2056 == trans_values
->gray
)
2058 *sp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2059 *sp
|= (png_byte
)(background
->gray
<< shift
);
2075 for (i
= 0; i
< row_info
->width
; i
++)
2077 if ((png_uint_16
)((*sp
>> shift
) & 0xf)
2078 == trans_values
->gray
)
2080 *sp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2081 *sp
|= (png_byte
)(background
->gray
<< shift
);
2095 #if defined(PNG_READ_GAMMA_SUPPORTED)
2096 if (gamma_table
!= NULL
)
2098 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
++)
2100 if (*sp
== trans_values
->gray
)
2102 *sp
= (png_byte
)background
->gray
;
2106 *sp
= gamma_table
[*sp
];
2113 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
++)
2115 if (*sp
== trans_values
->gray
)
2117 *sp
= (png_byte
)background
->gray
;
2125 #if defined(PNG_READ_GAMMA_SUPPORTED)
2126 if (gamma_16
!= NULL
)
2128 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
+= 2)
2132 v
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2133 if (v
== trans_values
->gray
)
2135 /* background is already in screen gamma */
2136 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2137 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2141 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2142 *sp
= (png_byte
)((v
>> 8) & 0xff);
2143 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2150 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
+= 2)
2154 v
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2155 if (v
== trans_values
->gray
)
2157 *sp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2158 *(sp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2167 case PNG_COLOR_TYPE_RGB
:
2169 if (row_info
->bit_depth
== 8)
2171 #if defined(PNG_READ_GAMMA_SUPPORTED)
2172 if (gamma_table
!= NULL
)
2174 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
+= 3)
2176 if (*sp
== trans_values
->red
&&
2177 *(sp
+ 1) == trans_values
->green
&&
2178 *(sp
+ 2) == trans_values
->blue
)
2180 *sp
= (png_byte
)background
->red
;
2181 *(sp
+ 1) = (png_byte
)background
->green
;
2182 *(sp
+ 2) = (png_byte
)background
->blue
;
2186 *sp
= gamma_table
[*sp
];
2187 *(sp
+ 1) = gamma_table
[*(sp
+ 1)];
2188 *(sp
+ 2) = gamma_table
[*(sp
+ 2)];
2195 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
+= 3)
2197 if (*sp
== trans_values
->red
&&
2198 *(sp
+ 1) == trans_values
->green
&&
2199 *(sp
+ 2) == trans_values
->blue
)
2201 *sp
= (png_byte
)background
->red
;
2202 *(sp
+ 1) = (png_byte
)background
->green
;
2203 *(sp
+ 2) = (png_byte
)background
->blue
;
2208 else /* if (row_info->bit_depth == 16) */
2210 #if defined(PNG_READ_GAMMA_SUPPORTED)
2211 if (gamma_16
!= NULL
)
2213 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
+= 6)
2215 png_uint_16 r
, g
, b
;
2217 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2218 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2219 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2220 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2221 b
== trans_values
->blue
)
2223 /* background is already in screen gamma */
2224 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2225 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2226 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2227 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2228 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2229 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2234 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2235 *sp
= (png_byte
)((v
>> 8) & 0xff);
2236 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2237 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2238 *(sp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2239 *(sp
+ 3) = (png_byte
)(v
& 0xff);
2240 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2241 *(sp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2242 *(sp
+ 5) = (png_byte
)(v
& 0xff);
2249 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++, sp
+= 6)
2251 png_uint_16 r
, g
, b
;
2253 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2254 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2255 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2256 if (r
== trans_values
->red
&& g
== trans_values
->green
&&
2257 b
== trans_values
->blue
)
2259 *sp
= (png_byte
)((background
->red
>> 8) & 0xff);
2260 *(sp
+ 1) = (png_byte
)(background
->red
& 0xff);
2261 *(sp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2262 *(sp
+ 3) = (png_byte
)(background
->green
& 0xff);
2263 *(sp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2264 *(sp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2271 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2273 if (row_info
->bit_depth
== 8)
2275 #if defined(PNG_READ_GAMMA_SUPPORTED)
2276 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2277 gamma_table
!= NULL
)
2279 for (i
= 0, sp
= row
, dp
= row
;
2280 i
< row_info
->width
; i
++, sp
+= 2, dp
++)
2287 *dp
= gamma_table
[*sp
];
2291 /* background is already in screen gamma */
2292 *dp
= (png_byte
)background
->gray
;
2298 v
= gamma_to_1
[*sp
];
2299 png_composite(w
, v
, a
, background_1
->gray
);
2300 *dp
= gamma_from_1
[w
];
2307 for (i
= 0, sp
= row
, dp
= row
;
2308 i
< row_info
->width
; i
++, sp
+= 2, dp
++)
2319 *dp
= (png_byte
)background
->gray
;
2323 png_composite(*dp
, *sp
, a
, background_1
->gray
);
2328 else /* if (png_ptr->bit_depth == 16) */
2330 #if defined(PNG_READ_GAMMA_SUPPORTED)
2331 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2332 gamma_16_to_1
!= NULL
)
2334 for (i
= 0, sp
= row
, dp
= row
;
2335 i
< row_info
->width
; i
++, sp
+= 4, dp
+= 2)
2339 a
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2340 if (a
== (png_uint_16
)0xffff)
2344 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2345 *dp
= (png_byte
)((v
>> 8) & 0xff);
2346 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2350 /* background is already in screen gamma */
2351 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2352 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2356 png_uint_16 g
, v
, w
;
2358 g
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
2359 png_composite_16(v
, g
, a
, background_1
->gray
);
2360 w
= gamma_16_from_1
[(v
&0xff) >> gamma_shift
][v
>> 8];
2361 *dp
= (png_byte
)((w
>> 8) & 0xff);
2362 *(dp
+ 1) = (png_byte
)(w
& 0xff);
2369 for (i
= 0, sp
= row
, dp
= row
;
2370 i
< row_info
->width
; i
++, sp
+= 4, dp
+= 2)
2374 a
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2375 if (a
== (png_uint_16
)0xffff)
2377 png_memcpy(dp
, sp
, 2);
2381 *dp
= (png_byte
)((background
->gray
>> 8) & 0xff);
2382 *(dp
+ 1) = (png_byte
)(background
->gray
& 0xff);
2388 g
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2389 png_composite_16(v
, g
, a
, background_1
->gray
);
2390 *dp
= (png_byte
)((v
>> 8) & 0xff);
2391 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2398 case PNG_COLOR_TYPE_RGB_ALPHA
:
2400 if (row_info
->bit_depth
== 8)
2402 #if defined(PNG_READ_GAMMA_SUPPORTED)
2403 if (gamma_to_1
!= NULL
&& gamma_from_1
!= NULL
&&
2404 gamma_table
!= NULL
)
2406 for (i
= 0, sp
= row
, dp
= row
;
2407 i
< row_info
->width
; i
++, sp
+= 4, dp
+= 3)
2414 *dp
= gamma_table
[*sp
];
2415 *(dp
+ 1) = gamma_table
[*(sp
+ 1)];
2416 *(dp
+ 2) = gamma_table
[*(sp
+ 2)];
2420 /* background is already in screen gamma */
2421 *dp
= (png_byte
)background
->red
;
2422 *(dp
+ 1) = (png_byte
)background
->green
;
2423 *(dp
+ 2) = (png_byte
)background
->blue
;
2429 v
= gamma_to_1
[*sp
];
2430 png_composite(w
, v
, a
, background_1
->red
);
2431 *dp
= gamma_from_1
[w
];
2432 v
= gamma_to_1
[*(sp
+ 1)];
2433 png_composite(w
, v
, a
, background_1
->green
);
2434 *(dp
+ 1) = gamma_from_1
[w
];
2435 v
= gamma_to_1
[*(sp
+ 2)];
2436 png_composite(w
, v
, a
, background_1
->blue
);
2437 *(dp
+ 2) = gamma_from_1
[w
];
2444 for (i
= 0, sp
= row
, dp
= row
;
2445 i
< row_info
->width
; i
++, sp
+= 4, dp
+= 3)
2453 *(dp
+ 1) = *(sp
+ 1);
2454 *(dp
+ 2) = *(sp
+ 2);
2458 *dp
= (png_byte
)background
->red
;
2459 *(dp
+ 1) = (png_byte
)background
->green
;
2460 *(dp
+ 2) = (png_byte
)background
->blue
;
2464 png_composite(*dp
, *sp
, a
, background
->red
);
2465 png_composite(*(dp
+ 1), *(sp
+ 1), a
,
2467 png_composite(*(dp
+ 2), *(sp
+ 2), a
,
2473 else /* if (row_info->bit_depth == 16) */
2475 #if defined(PNG_READ_GAMMA_SUPPORTED)
2476 if (gamma_16
!= NULL
&& gamma_16_from_1
!= NULL
&&
2477 gamma_16_to_1
!= NULL
)
2479 for (i
= 0, sp
= row
, dp
= row
;
2480 i
< row_info
->width
; i
++, sp
+= 8, dp
+= 6)
2484 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6)) << 8) +
2485 (png_uint_16
)(*(sp
+ 7)));
2486 if (a
== (png_uint_16
)0xffff)
2490 v
= gamma_16
[*(sp
+ 1) >> gamma_shift
][*sp
];
2491 *dp
= (png_byte
)((v
>> 8) & 0xff);
2492 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2493 v
= gamma_16
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2494 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2495 *(dp
+ 3) = (png_byte
)(v
& 0xff);
2496 v
= gamma_16
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2497 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2498 *(dp
+ 5) = (png_byte
)(v
& 0xff);
2502 /* background is already in screen gamma */
2503 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
2504 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
2505 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2506 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
2507 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2508 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2512 png_uint_16 v
, w
, x
;
2514 v
= gamma_16_to_1
[*(sp
+ 1) >> gamma_shift
][*sp
];
2515 png_composite_16(w
, v
, a
, background
->red
);
2516 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
2517 *dp
= (png_byte
)((x
>> 8) & 0xff);
2518 *(dp
+ 1) = (png_byte
)(x
& 0xff);
2519 v
= gamma_16_to_1
[*(sp
+ 3) >> gamma_shift
][*(sp
+ 2)];
2520 png_composite_16(w
, v
, a
, background
->green
);
2521 x
= gamma_16_from_1
[((w
&0xff) >> gamma_shift
)][w
>> 8];
2522 *(dp
+ 2) = (png_byte
)((x
>> 8) & 0xff);
2523 *(dp
+ 3) = (png_byte
)(x
& 0xff);
2524 v
= gamma_16_to_1
[*(sp
+ 5) >> gamma_shift
][*(sp
+ 4)];
2525 png_composite_16(w
, v
, a
, background
->blue
);
2526 x
= gamma_16_from_1
[(w
& 0xff) >> gamma_shift
][w
>> 8];
2527 *(dp
+ 4) = (png_byte
)((x
>> 8) & 0xff);
2528 *(dp
+ 5) = (png_byte
)(x
& 0xff);
2535 for (i
= 0, sp
= row
, dp
= row
;
2536 i
< row_info
->width
; i
++, sp
+= 8, dp
+= 6)
2540 a
= (png_uint_16
)(((png_uint_16
)(*(sp
+ 6)) << 8) +
2541 (png_uint_16
)(*(sp
+ 7)));
2542 if (a
== (png_uint_16
)0xffff)
2544 png_memcpy(dp
, sp
, 6);
2548 *dp
= (png_byte
)((background
->red
>> 8) & 0xff);
2549 *(dp
+ 1) = (png_byte
)(background
->red
& 0xff);
2550 *(dp
+ 2) = (png_byte
)((background
->green
>> 8) & 0xff);
2551 *(dp
+ 3) = (png_byte
)(background
->green
& 0xff);
2552 *(dp
+ 4) = (png_byte
)((background
->blue
>> 8) & 0xff);
2553 *(dp
+ 5) = (png_byte
)(background
->blue
& 0xff);
2557 png_uint_16 r
, g
, b
, v
;
2559 r
= ((png_uint_16
)(*sp
) << 8) + *(sp
+ 1);
2560 g
= ((png_uint_16
)(*(sp
+ 2)) << 8) + *(sp
+ 3);
2561 b
= ((png_uint_16
)(*(sp
+ 4)) << 8) + *(sp
+ 5);
2563 png_composite_16(v
, r
, a
, background
->red
);
2564 *dp
= (png_byte
)((v
>> 8) & 0xff);
2565 *(dp
+ 1) = (png_byte
)(v
& 0xff);
2566 png_composite_16(v
, g
, a
, background
->green
);
2567 *(dp
+ 2) = (png_byte
)((v
>> 8) & 0xff);
2568 *(dp
+ 3) = (png_byte
)(v
& 0xff);
2569 png_composite_16(v
, b
, a
, background
->blue
);
2570 *(dp
+ 4) = (png_byte
)((v
>> 8) & 0xff);
2571 *(dp
+ 5) = (png_byte
)(v
& 0xff);
2580 if (row_info
->color_type
& PNG_COLOR_MASK_ALPHA
)
2582 row_info
->color_type
&= ~PNG_COLOR_MASK_ALPHA
;
2583 row_info
->channels
--;
2584 row_info
->pixel_depth
= (png_byte
)(row_info
->channels
*
2585 row_info
->bit_depth
);
2586 row_info
->rowbytes
= ((row_info
->width
*
2587 row_info
->pixel_depth
+ 7) >> 3);
2593 #if defined(PNG_READ_GAMMA_SUPPORTED)
2594 /* Gamma correct the image, avoiding the alpha channel. Make sure
2595 * you do this after you deal with the trasparency issue on grayscale
2596 * or rgb images. If your bit depth is 8, use gamma_table, if it
2597 * is 16, use gamma_16_table and gamma_shift. Build these with
2598 * build_gamma_table().
2601 png_do_gamma(png_row_infop row_info
, png_bytep row
,
2602 png_bytep gamma_table
, png_uint_16pp gamma_16_table
,
2608 png_debug(1, "in png_do_gamma\n");
2610 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2611 row
!= NULL
&& row_info
!= NULL
&&
2613 ((row_info
->bit_depth
<= 8 && gamma_table
!= NULL
) ||
2614 (row_info
->bit_depth
== 16 && gamma_16_table
!= NULL
)))
2616 switch (row_info
->color_type
)
2618 case PNG_COLOR_TYPE_RGB
:
2620 if (row_info
->bit_depth
== 8)
2622 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++)
2624 *sp
= gamma_table
[*sp
];
2626 *sp
= gamma_table
[*sp
];
2628 *sp
= gamma_table
[*sp
];
2632 else /* if (row_info->bit_depth == 16) */
2634 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++)
2638 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2639 *sp
= (png_byte
)((v
>> 8) & 0xff);
2640 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2642 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2643 *sp
= (png_byte
)((v
>> 8) & 0xff);
2644 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2646 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2647 *sp
= (png_byte
)((v
>> 8) & 0xff);
2648 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2654 case PNG_COLOR_TYPE_RGB_ALPHA
:
2656 if (row_info
->bit_depth
== 8)
2658 for (i
= 0, sp
= row
;
2659 i
< row_info
->width
; i
++)
2661 *sp
= gamma_table
[*sp
];
2663 *sp
= gamma_table
[*sp
];
2665 *sp
= gamma_table
[*sp
];
2670 else /* if (row_info->bit_depth == 16) */
2672 for (i
= 0, sp
= row
;
2673 i
< row_info
->width
; i
++)
2677 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2678 *sp
= (png_byte
)((v
>> 8) & 0xff);
2679 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2681 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2682 *sp
= (png_byte
)((v
>> 8) & 0xff);
2683 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2685 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2686 *sp
= (png_byte
)((v
>> 8) & 0xff);
2687 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2693 case PNG_COLOR_TYPE_GRAY_ALPHA
:
2695 if (row_info
->bit_depth
== 8)
2697 for (i
= 0, sp
= row
;
2698 i
< row_info
->width
; i
++)
2700 *sp
= gamma_table
[*sp
];
2704 else /* if (row_info->bit_depth == 16) */
2706 for (i
= 0, sp
= row
;
2707 i
< row_info
->width
; i
++)
2711 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2712 *sp
= (png_byte
)((v
>> 8) & 0xff);
2713 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2719 case PNG_COLOR_TYPE_GRAY
:
2721 if (row_info
->bit_depth
== 2)
2723 for (i
= 0, sp
= row
; i
< row_info
->width
; i
+= 4)
2730 *sp
= ((((int)gamma_table
[a
|(a
>>2)|(a
>>4)|(a
>>6)]) ) & 0xc0)|
2731 ((((int)gamma_table
[(b
<<2)|b
|(b
>>2)|(b
>>4)])>>2) & 0x30)|
2732 ((((int)gamma_table
[(c
<<4)|(c
<<2)|c
|(c
>>2)])>>4) & 0x0c)|
2733 ((((int)gamma_table
[(d
<<6)|(d
<<4)|(d
<<2)|d
])>>6) );
2737 if (row_info
->bit_depth
== 4)
2739 for (i
= 0, sp
= row
; i
< row_info
->width
; i
+= 2)
2741 int msb
= *sp
& 0xf0;
2742 int lsb
= *sp
& 0x0f;
2744 *sp
= (((int)gamma_table
[msb
| (msb
>> 4)]) & 0xf0) |
2745 (((int)gamma_table
[(lsb
<< 4) | lsb
]) >> 4);
2749 else if (row_info
->bit_depth
== 8)
2751 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++)
2753 *sp
= gamma_table
[*sp
];
2757 else if (row_info
->bit_depth
== 16)
2759 for (i
= 0, sp
= row
; i
< row_info
->width
; i
++)
2763 v
= gamma_16_table
[*(sp
+ 1) >> gamma_shift
][*sp
];
2764 *sp
= (png_byte
)((v
>> 8) & 0xff);
2765 *(sp
+ 1) = (png_byte
)(v
& 0xff);
2776 #if defined(PNG_READ_EXPAND_SUPPORTED)
2777 /* Expands a palette row to an rgb or rgba row depending
2778 * upon whether you supply trans and num_trans.
2781 png_do_expand_palette(png_row_infop row_info
, png_bytep row
,
2782 png_colorp palette
, png_bytep trans
, int num_trans
)
2788 png_debug(1, "in png_do_expand_palette\n");
2790 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2791 row
!= NULL
&& row_info
!= NULL
&&
2793 row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2795 if (row_info
->bit_depth
< 8)
2797 switch (row_info
->bit_depth
)
2801 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2802 dp
= row
+ (png_size_t
)row_info
->width
- 1;
2803 shift
= 7 - (int)((row_info
->width
+ 7) & 7);
2804 for (i
= 0; i
< row_info
->width
; i
++)
2806 if ((*sp
>> shift
) & 0x1)
2824 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 2);
2825 dp
= row
+ (png_size_t
)row_info
->width
- 1;
2826 shift
= (int)((3 - ((row_info
->width
+ 3) & 3)) << 1);
2827 for (i
= 0; i
< row_info
->width
; i
++)
2829 value
= (*sp
>> shift
) & 0x3;
2830 *dp
= (png_byte
)value
;
2845 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2846 dp
= row
+ (png_size_t
)row_info
->width
- 1;
2847 shift
= (int)((row_info
->width
& 1) << 2);
2848 for (i
= 0; i
< row_info
->width
; i
++)
2850 value
= (*sp
>> shift
) & 0xf;
2851 *dp
= (png_byte
)value
;
2865 row_info
->bit_depth
= 8;
2866 row_info
->pixel_depth
= 8;
2867 row_info
->rowbytes
= row_info
->width
;
2869 switch (row_info
->bit_depth
)
2875 sp
= row
+ (png_size_t
)row_info
->width
- 1;
2876 dp
= row
+ (png_size_t
)(row_info
->width
<< 2) - 1;
2878 for (i
= 0; i
< row_info
->width
; i
++)
2880 if ((int)(*sp
) >= num_trans
)
2884 *dp
-- = palette
[*sp
].blue
;
2885 *dp
-- = palette
[*sp
].green
;
2886 *dp
-- = palette
[*sp
].red
;
2889 row_info
->bit_depth
= 8;
2890 row_info
->pixel_depth
= 32;
2891 row_info
->rowbytes
= row_info
->width
* 4;
2892 row_info
->color_type
= 6;
2893 row_info
->channels
= 4;
2897 sp
= row
+ (png_size_t
)row_info
->width
- 1;
2898 dp
= row
+ (png_size_t
)(row_info
->width
* 3) - 1;
2900 for (i
= 0; i
< row_info
->width
; i
++)
2902 *dp
-- = palette
[*sp
].blue
;
2903 *dp
-- = palette
[*sp
].green
;
2904 *dp
-- = palette
[*sp
].red
;
2907 row_info
->bit_depth
= 8;
2908 row_info
->pixel_depth
= 24;
2909 row_info
->rowbytes
= row_info
->width
* 3;
2910 row_info
->color_type
= 2;
2911 row_info
->channels
= 3;
2919 /* If the bit depth < 8, it is expanded to 8. Also, if the
2920 * transparency value is supplied, an alpha channel is built.
2923 png_do_expand(png_row_infop row_info
, png_bytep row
,
2924 png_color_16p trans_value
)
2930 png_debug(1, "in png_do_expand\n");
2931 #if defined(PNG_USELESS_TESTS_SUPPORTED)
2932 if (row
!= NULL
&& row_info
!= NULL
)
2935 if (row_info
->color_type
== PNG_COLOR_TYPE_GRAY
)
2937 png_uint_16 gray
= trans_value
? trans_value
->gray
: 0;
2939 if (row_info
->bit_depth
< 8)
2941 switch (row_info
->bit_depth
)
2946 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2947 dp
= row
+ (png_size_t
)row_info
->width
- 1;
2948 shift
= 7 - (int)((row_info
->width
+ 7) & 7);
2949 for (i
= 0; i
< row_info
->width
; i
++)
2951 if ((*sp
>> shift
) & 0x1)
2970 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 2);
2971 dp
= row
+ (png_size_t
)row_info
->width
- 1;
2972 shift
= (int)((3 - ((row_info
->width
+ 3) & 3)) << 1);
2973 for (i
= 0; i
< row_info
->width
; i
++)
2975 value
= (*sp
>> shift
) & 0x3;
2976 *dp
= (png_byte
)(value
| (value
<< 2) | (value
<< 4) |
2993 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2994 dp
= row
+ (png_size_t
)row_info
->width
- 1;
2995 shift
= (int)((1 - ((row_info
->width
+ 1) & 1)) << 2);
2996 for (i
= 0; i
< row_info
->width
; i
++)
2998 value
= (*sp
>> shift
) & 0xf;
2999 *dp
= (png_byte
)(value
| (value
<< 4));
3013 row_info
->bit_depth
= 8;
3014 row_info
->pixel_depth
= 8;
3015 row_info
->rowbytes
= row_info
->width
;
3018 if (trans_value
!= NULL
)
3020 if (row_info
->bit_depth
== 8)
3022 sp
= row
+ (png_size_t
)row_info
->width
- 1;
3023 dp
= row
+ (png_size_t
)(row_info
->width
<< 1) - 1;
3024 for (i
= 0; i
< row_info
->width
; i
++)
3033 else if (row_info
->bit_depth
== 16)
3035 sp
= row
+ row_info
->rowbytes
- 1;
3036 dp
= row
+ (row_info
->rowbytes
<< 1) - 1;
3037 for (i
= 0; i
< row_info
->width
; i
++)
3039 if (((png_uint_16
)*(sp
) |
3040 ((png_uint_16
)*(sp
- 1) << 8)) == gray
)
3054 row_info
->color_type
= PNG_COLOR_TYPE_GRAY_ALPHA
;
3055 row_info
->channels
= 2;
3056 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 1);
3057 row_info
->rowbytes
=
3058 ((row_info
->width
* row_info
->pixel_depth
) >> 3);
3061 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&& trans_value
)
3063 if (row_info
->bit_depth
== 8)
3065 sp
= row
+ (png_size_t
)row_info
->rowbytes
- 1;
3066 dp
= row
+ (png_size_t
)(row_info
->width
<< 2) - 1;
3067 for (i
= 0; i
< row_info
->width
; i
++)
3069 if (*(sp
- 2) == trans_value
->red
&&
3070 *(sp
- 1) == trans_value
->green
&&
3071 *(sp
- 0) == trans_value
->blue
)
3080 else if (row_info
->bit_depth
== 16)
3082 sp
= row
+ row_info
->rowbytes
- 1;
3083 dp
= row
+ (png_size_t
)(row_info
->width
<< 3) - 1;
3084 for (i
= 0; i
< row_info
->width
; i
++)
3086 if ((((png_uint_16
)*(sp
- 4) |
3087 ((png_uint_16
)*(sp
- 5) << 8)) == trans_value
->red
) &&
3088 (((png_uint_16
)*(sp
- 2) |
3089 ((png_uint_16
)*(sp
- 3) << 8)) == trans_value
->green
) &&
3090 (((png_uint_16
)*(sp
- 0) |
3091 ((png_uint_16
)*(sp
- 1) << 8)) == trans_value
->blue
))
3109 row_info
->color_type
= PNG_COLOR_TYPE_RGB_ALPHA
;
3110 row_info
->channels
= 4;
3111 row_info
->pixel_depth
= (png_byte
)(row_info
->bit_depth
<< 2);
3112 row_info
->rowbytes
=
3113 ((row_info
->width
* row_info
->pixel_depth
) >> 3);
3119 #if defined(PNG_READ_DITHER_SUPPORTED)
3121 png_do_dither(png_row_infop row_info
, png_bytep row
,
3122 png_bytep palette_lookup
, png_bytep dither_lookup
)
3127 png_debug(1, "in png_do_dither\n");
3128 #if defined(PNG_USELESS_TESTS_SUPPORTED)
3129 if (row
!= NULL
&& row_info
!= NULL
)
3132 if (row_info
->color_type
== PNG_COLOR_TYPE_RGB
&&
3133 palette_lookup
&& row_info
->bit_depth
== 8)
3138 for (i
= 0; i
< row_info
->width
; i
++)
3144 /* this looks real messy, but the compiler will reduce
3145 it down to a reasonable formula. For example, with
3146 5 bits per color, we get:
3147 p = (((r >> 3) & 0x1f) << 10) |
3148 (((g >> 3) & 0x1f) << 5) |
3151 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3152 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3153 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3154 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3155 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3156 (PNG_DITHER_BLUE_BITS
)) |
3157 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3158 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3160 *dp
++ = palette_lookup
[p
];
3162 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3163 row_info
->channels
= 1;
3164 row_info
->pixel_depth
= row_info
->bit_depth
;
3165 row_info
->rowbytes
=
3166 ((row_info
->width
* row_info
->pixel_depth
+ 7) >> 3);
3168 else if (row_info
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
&&
3169 palette_lookup
!= NULL
&& row_info
->bit_depth
== 8)
3174 for (i
= 0; i
< row_info
->width
; i
++)
3181 p
= (((r
>> (8 - PNG_DITHER_RED_BITS
)) &
3182 ((1 << PNG_DITHER_RED_BITS
) - 1)) <<
3183 (PNG_DITHER_GREEN_BITS
+ PNG_DITHER_BLUE_BITS
)) |
3184 (((g
>> (8 - PNG_DITHER_GREEN_BITS
)) &
3185 ((1 << PNG_DITHER_GREEN_BITS
) - 1)) <<
3186 (PNG_DITHER_BLUE_BITS
)) |
3187 ((b
>> (8 - PNG_DITHER_BLUE_BITS
)) &
3188 ((1 << PNG_DITHER_BLUE_BITS
) - 1));
3190 *dp
++ = palette_lookup
[p
];
3192 row_info
->color_type
= PNG_COLOR_TYPE_PALETTE
;
3193 row_info
->channels
= 1;
3194 row_info
->pixel_depth
= row_info
->bit_depth
;
3195 row_info
->rowbytes
=
3196 ((row_info
->width
* row_info
->pixel_depth
+ 7) >> 3);
3198 else if (row_info
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
3199 dither_lookup
&& row_info
->bit_depth
== 8)
3202 for (i
= 0; i
< row_info
->width
; i
++, sp
++)
3204 *sp
= dither_lookup
[*sp
];
3211 #if defined(PNG_READ_GAMMA_SUPPORTED)
3212 static int png_gamma_shift
[] =
3213 {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
3215 /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
3216 * tables, we don't make a full table if we are reducing to 8-bit in
3217 * the future. Note also how the gamma_16 tables are segmented so that
3218 * we don't need to allocate > 64K chunks for a full 16-bit table.
3221 png_build_gamma_table(png_structp png_ptr
)
3223 png_debug(1, "in png_build_gamma_table\n");
3224 if (png_ptr
->bit_depth
<= 8)
3229 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3231 png_ptr
->gamma_table
= (png_bytep
)png_malloc(png_ptr
,
3234 for (i
= 0; i
< 256; i
++)
3236 png_ptr
->gamma_table
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3240 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
3241 if (png_ptr
->transformations
& PNG_BACKGROUND
)
3243 g
= 1.0 / (png_ptr
->gamma
);
3245 png_ptr
->gamma_to_1
= (png_bytep
)png_malloc(png_ptr
,
3248 for (i
= 0; i
< 256; i
++)
3250 png_ptr
->gamma_to_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3254 g
= 1.0 / (png_ptr
->screen_gamma
);
3256 png_ptr
->gamma_from_1
= (png_bytep
)png_malloc(png_ptr
,
3259 for (i
= 0; i
< 256; i
++)
3261 png_ptr
->gamma_from_1
[i
] = (png_byte
)(pow((double)i
/ 255.0,
3265 #endif /* PNG_BACKGROUND_SUPPORTED */
3270 int i
, j
, shift
, num
;
3274 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
3276 sig_bit
= (int)png_ptr
->sig_bit
.red
;
3277 if ((int)png_ptr
->sig_bit
.green
> sig_bit
)
3278 sig_bit
= png_ptr
->sig_bit
.green
;
3279 if ((int)png_ptr
->sig_bit
.blue
> sig_bit
)
3280 sig_bit
= png_ptr
->sig_bit
.blue
;
3284 sig_bit
= (int)png_ptr
->sig_bit
.gray
;
3288 shift
= 16 - sig_bit
;
3292 if (png_ptr
->transformations
& PNG_16_TO_8
)
3294 if (shift
< (16 - PNG_MAX_GAMMA_8
))
3295 shift
= (16 - PNG_MAX_GAMMA_8
);
3303 png_ptr
->gamma_shift
= (png_byte
)shift
;
3305 num
= (1 << (8 - shift
));
3307 g
= 1.0 / (png_ptr
->gamma
* png_ptr
->screen_gamma
);
3309 png_ptr
->gamma_16_table
= (png_uint_16pp
)png_malloc(png_ptr
,
3310 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3312 if ((png_ptr
->transformations
& PNG_16_TO_8
) &&
3313 !(png_ptr
->transformations
& PNG_BACKGROUND
))
3316 png_uint_32 last
, max
;
3318 for (i
= 0; i
< num
; i
++)
3320 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3321 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3326 for (i
= 0; i
< 256; i
++)
3328 fout
= ((double)i
+ 0.5) / 256.0;
3330 max
= (png_uint_32
)(fin
* (double)((png_uint_32
)num
<< 8));
3333 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3334 [(int)(last
>> (8 - shift
))] = (png_uint_16
)(
3335 (png_uint_16
)i
| ((png_uint_16
)i
<< 8));
3339 while (last
< ((png_uint_32
)num
<< 8))
3341 png_ptr
->gamma_16_table
[(int)(last
& (0xff >> shift
))]
3342 [(int)(last
>> (8 - shift
))] = (png_uint_16
)65535L;
3348 for (i
= 0; i
< num
; i
++)
3350 png_ptr
->gamma_16_table
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3351 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3353 ig
= (((png_uint_32
)i
* (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3354 for (j
= 0; j
< 256; j
++)
3356 png_ptr
->gamma_16_table
[i
][j
] =
3357 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3358 65535.0, g
) * 65535.0 + .5);
3363 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
3364 if (png_ptr
->transformations
& PNG_BACKGROUND
)
3366 g
= 1.0 / (png_ptr
->gamma
);
3368 png_ptr
->gamma_16_to_1
= (png_uint_16pp
)png_malloc(png_ptr
,
3369 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3371 for (i
= 0; i
< num
; i
++)
3373 png_ptr
->gamma_16_to_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3374 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3376 ig
= (((png_uint_32
)i
*
3377 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3378 for (j
= 0; j
< 256; j
++)
3380 png_ptr
->gamma_16_to_1
[i
][j
] =
3381 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3382 65535.0, g
) * 65535.0 + .5);
3385 g
= 1.0 / (png_ptr
->screen_gamma
);
3387 png_ptr
->gamma_16_from_1
= (png_uint_16pp
)png_malloc(png_ptr
,
3388 (png_uint_32
)(num
* sizeof (png_uint_16p
)));
3390 for (i
= 0; i
< num
; i
++)
3392 png_ptr
->gamma_16_from_1
[i
] = (png_uint_16p
)png_malloc(png_ptr
,
3393 (png_uint_32
)(256 * sizeof (png_uint_16
)));
3395 ig
= (((png_uint_32
)i
*
3396 (png_uint_32
)png_gamma_shift
[shift
]) >> 4);
3397 for (j
= 0; j
< 256; j
++)
3399 png_ptr
->gamma_16_from_1
[i
][j
] =
3400 (png_uint_16
)(pow((double)(ig
+ ((png_uint_32
)j
<< 8)) /
3401 65535.0, g
) * 65535.0 + .5);
3405 #endif /* PNG_BACKGROUND_SUPPORTED */