Rev 1897 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1897 | Rev 3928 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* pngtrans.c - transforms the data in a row (used by both readers and writers) |
1 | /* pngtrans.c - transforms the data in a row (used by both readers and writers) |
2 | * |
2 | * |
3 | * Last changed in libpng 1.5.1 [February 3, 2011] |
3 | * Last changed in libpng 1.6.2 [April 25, 2013] |
4 | * Copyright (c) 1998-2011 Glenn Randers-Pehrson |
4 | * Copyright (c) 1998-2013 Glenn Randers-Pehrson |
5 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
5 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
6 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
6 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
7 | * |
7 | * |
8 | * This code is released under the libpng license. |
8 | * This code is released under the libpng license. |
9 | * For conditions of distribution and use, see the disclaimer |
9 | * For conditions of distribution and use, see the disclaimer |
Line 16... | Line 16... | ||
16 | 16 | ||
Line 17... | Line 17... | ||
17 | #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) |
17 | #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) |
18 | /* Turn on BGR-to-RGB mapping */ |
18 | /* Turn on BGR-to-RGB mapping */ |
19 | void PNGAPI |
19 | void PNGAPI |
20 | png_set_bgr(png_structp png_ptr) |
20 | png_set_bgr(png_structrp png_ptr) |
21 | { |
21 | { |
22 | png_debug(1, "in png_set_bgr"); |
22 | png_debug(1, "in png_set_bgr"); |
Line 23... | Line 23... | ||
23 | 23 | ||
24 | if (png_ptr == NULL) |
24 | if (png_ptr == NULL) |
Line 30... | Line 30... | ||
30 | 30 | ||
Line 31... | Line 31... | ||
31 | #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) |
31 | #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) |
32 | /* Turn on 16 bit byte swapping */ |
32 | /* Turn on 16 bit byte swapping */ |
33 | void PNGAPI |
33 | void PNGAPI |
34 | png_set_swap(png_structp png_ptr) |
34 | png_set_swap(png_structrp png_ptr) |
35 | { |
35 | { |
36 | png_debug(1, "in png_set_swap"); |
36 | png_debug(1, "in png_set_swap"); |
Line 37... | Line 37... | ||
37 | 37 | ||
38 | if (png_ptr == NULL) |
38 | if (png_ptr == NULL) |
Line 45... | Line 45... | ||
45 | 45 | ||
Line 46... | Line 46... | ||
46 | #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) |
46 | #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) |
47 | /* Turn on pixel packing */ |
47 | /* Turn on pixel packing */ |
48 | void PNGAPI |
48 | void PNGAPI |
49 | png_set_packing(png_structp png_ptr) |
49 | png_set_packing(png_structrp png_ptr) |
50 | { |
50 | { |
51 | png_debug(1, "in png_set_packing"); |
51 | png_debug(1, "in png_set_packing"); |
Line 52... | Line 52... | ||
52 | 52 | ||
53 | if (png_ptr == NULL) |
53 | if (png_ptr == NULL) |
Line 63... | Line 63... | ||
63 | 63 | ||
Line 64... | Line 64... | ||
64 | #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) |
64 | #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) |
65 | /* Turn on packed pixel swapping */ |
65 | /* Turn on packed pixel swapping */ |
66 | void PNGAPI |
66 | void PNGAPI |
67 | png_set_packswap(png_structp png_ptr) |
67 | png_set_packswap(png_structrp png_ptr) |
68 | { |
68 | { |
69 | png_debug(1, "in png_set_packswap"); |
69 | png_debug(1, "in png_set_packswap"); |
Line 70... | Line 70... | ||
70 | 70 | ||
71 | if (png_ptr == NULL) |
71 | if (png_ptr == NULL) |
Line 77... | Line 77... | ||
77 | #endif |
77 | #endif |
78 | 78 | ||
Line 79... | Line 79... | ||
79 | #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) |
79 | #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) |
80 | void PNGAPI |
80 | void PNGAPI |
81 | png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) |
81 | png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) |
82 | { |
82 | { |
83 | png_debug(1, "in png_set_shift"); |
83 | png_debug(1, "in png_set_shift"); |
Line 84... | Line 84... | ||
84 | 84 | ||
85 | if (png_ptr == NULL) |
85 | if (png_ptr == NULL) |
Line 92... | Line 92... | ||
92 | 92 | ||
Line 93... | Line 93... | ||
93 | #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ |
93 | #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ |
94 | defined(PNG_WRITE_INTERLACING_SUPPORTED) |
94 | defined(PNG_WRITE_INTERLACING_SUPPORTED) |
95 | int PNGAPI |
95 | int PNGAPI |
96 | png_set_interlace_handling(png_structp png_ptr) |
96 | png_set_interlace_handling(png_structrp png_ptr) |
97 | { |
97 | { |
98 | png_debug(1, "in png_set_interlace handling"); |
98 | png_debug(1, "in png_set_interlace handling"); |
Line 99... | Line 99... | ||
99 | 99 | ||
100 | if (png_ptr && png_ptr->interlaced) |
100 | if (png_ptr && png_ptr->interlaced) |
Line 113... | Line 113... | ||
113 | * for 48-bit input data, as well as to avoid problems with some compilers |
113 | * for 48-bit input data, as well as to avoid problems with some compilers |
114 | * that don't like bytes as parameters. |
114 | * that don't like bytes as parameters. |
115 | */ |
115 | */ |
116 | void PNGAPI |
116 | void PNGAPI |
117 | png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) |
117 | png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) |
118 | { |
118 | { |
119 | png_debug(1, "in png_set_filler"); |
119 | png_debug(1, "in png_set_filler"); |
120 | 120 | ||
Line 121... | Line 121... | ||
121 | if (png_ptr == NULL) |
121 | if (png_ptr == NULL) |
122 | return; |
122 | return; |
Line -... | Line 123... | ||
- | 123 | ||
- | 124 | /* In libpng 1.6 it is possible to determine whether this is a read or write |
|
- | 125 | * operation and therefore to do more checking here for a valid call. |
|
123 | 126 | */ |
|
- | 127 | if (png_ptr->mode & PNG_IS_READ_STRUCT) |
|
- | 128 | { |
|
- | 129 | # ifdef PNG_READ_FILLER_SUPPORTED |
|
- | 130 | /* On read png_set_filler is always valid, regardless of the base PNG |
|
- | 131 | * format, because other transformations can give a format where the |
|
- | 132 | * filler code can execute (basically an 8 or 16-bit component RGB or G |
|
- | 133 | * format.) |
|
- | 134 | * |
|
- | 135 | * NOTE: usr_channels is not used by the read code! (This has led to |
|
- | 136 | * confusion in the past.) The filler is only used in the read code. |
|
124 | png_ptr->transformations |= PNG_FILLER; |
137 | */ |
- | 138 | png_ptr->filler = (png_uint_16)filler; |
|
- | 139 | # else |
|
- | 140 | png_app_error(png_ptr, "png_set_filler not supported on read"); |
|
- | 141 | PNG_UNUSED(filler) /* not used in the write case */ |
|
- | 142 | return; |
|
- | 143 | # endif |
|
Line 125... | Line 144... | ||
125 | png_ptr->filler = (png_uint_16)filler; |
144 | } |
126 | - | ||
127 | if (filler_loc == PNG_FILLER_AFTER) |
- | |
128 | png_ptr->flags |= PNG_FLAG_FILLER_AFTER; |
145 | |
129 | 146 | else /* write */ |
|
130 | else |
- | |
131 | png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; |
147 | { |
132 | 148 | # ifdef PNG_WRITE_FILLER_SUPPORTED |
|
133 | /* This should probably go in the "do_read_filler" routine. |
- | |
134 | * I attempted to do that in libpng-1.0.1a but that caused problems |
149 | /* On write the usr_channels parameter must be set correctly at the |
135 | * so I restored it in libpng-1.0.2a |
- | |
136 | */ |
150 | * start to record the number of channels in the app-supplied data. |
137 | 151 | */ |
|
- | 152 | switch (png_ptr->color_type) |
|
138 | if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) |
153 | { |
139 | { |
- | |
140 | png_ptr->usr_channels = 4; |
- | |
141 | } |
- | |
142 | 154 | case PNG_COLOR_TYPE_RGB: |
|
Line -... | Line 155... | ||
- | 155 | png_ptr->usr_channels = 4; |
|
143 | /* Also I added this in libpng-1.0.2a (what happens when we expand |
156 | break; |
144 | * a less-than-8-bit grayscale to GA?) */ |
157 | |
145 | 158 | case PNG_COLOR_TYPE_GRAY: |
|
- | 159 | if (png_ptr->bit_depth >= 8) |
|
146 | if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) |
160 | { |
- | 161 | png_ptr->usr_channels = 2; |
|
- | 162 | break; |
|
- | 163 | } |
|
- | 164 | ||
- | 165 | else |
|
- | 166 | { |
|
- | 167 | /* There simply isn't any code in libpng to strip out bits |
|
- | 168 | * from bytes when the components are less than a byte in |
|
- | 169 | * size! |
|
- | 170 | */ |
|
- | 171 | png_app_error(png_ptr, |
|
- | 172 | "png_set_filler is invalid for low bit depth gray output"); |
|
- | 173 | return; |
|
- | 174 | } |
|
- | 175 | ||
- | 176 | default: |
|
- | 177 | png_app_error(png_ptr, |
|
- | 178 | "png_set_filler: inappropriate color type"); |
|
- | 179 | return; |
|
- | 180 | } |
|
- | 181 | # else |
|
- | 182 | png_app_error(png_ptr, "png_set_filler not supported on write"); |
|
- | 183 | return; |
|
- | 184 | # endif |
|
- | 185 | } |
|
- | 186 | ||
- | 187 | /* Here on success - libpng supports the operation, set the transformation |
|
- | 188 | * and the flag to say where the filler channel is. |
|
- | 189 | */ |
|
- | 190 | png_ptr->transformations |= PNG_FILLER; |
|
- | 191 | ||
- | 192 | if (filler_loc == PNG_FILLER_AFTER) |
|
- | 193 | png_ptr->flags |= PNG_FLAG_FILLER_AFTER; |
|
147 | { |
194 | |
Line 148... | Line 195... | ||
148 | png_ptr->usr_channels = 2; |
195 | else |
149 | } |
196 | png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; |
150 | } |
197 | } |
151 | 198 | ||
152 | /* Added to libpng-1.2.7 */ |
199 | /* Added to libpng-1.2.7 */ |
Line 153... | Line 200... | ||
153 | void PNGAPI |
200 | void PNGAPI |
154 | png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) |
201 | png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) |
Line 155... | Line 202... | ||
155 | { |
202 | { |
- | 203 | png_debug(1, "in png_set_add_alpha"); |
|
- | 204 | ||
156 | png_debug(1, "in png_set_add_alpha"); |
205 | if (png_ptr == NULL) |
157 | 206 | return; |
|
Line 158... | Line 207... | ||
158 | if (png_ptr == NULL) |
207 | |
Line 159... | Line 208... | ||
159 | return; |
208 | png_set_filler(png_ptr, filler, filler_loc); |
160 | 209 | /* The above may fail to do anything. */ |
|
161 | png_set_filler(png_ptr, filler, filler_loc); |
210 | if (png_ptr->transformations & PNG_FILLER) |
162 | png_ptr->transformations |= PNG_ADD_ALPHA; |
211 | png_ptr->transformations |= PNG_ADD_ALPHA; |
163 | } |
212 | } |
164 | 213 | ||
Line 165... | Line 214... | ||
165 | #endif |
214 | #endif |
166 | 215 | ||
Line 180... | Line 229... | ||
180 | 229 | ||
Line 181... | Line 230... | ||
181 | #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ |
230 | #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ |
182 | defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) |
231 | defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) |
183 | void PNGAPI |
232 | void PNGAPI |
184 | png_set_invert_alpha(png_structp png_ptr) |
233 | png_set_invert_alpha(png_structrp png_ptr) |
185 | { |
234 | { |
186 | png_debug(1, "in png_set_invert_alpha"); |
235 | png_debug(1, "in png_set_invert_alpha"); |
Line 187... | Line 236... | ||
187 | 236 | ||
188 | if (png_ptr == NULL) |
237 | if (png_ptr == NULL) |
Line 193... | Line 242... | ||
193 | #endif |
242 | #endif |
194 | 243 | ||
Line 195... | Line 244... | ||
195 | #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) |
244 | #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) |
196 | void PNGAPI |
245 | void PNGAPI |
197 | png_set_invert_mono(png_structp png_ptr) |
246 | png_set_invert_mono(png_structrp png_ptr) |
198 | { |
247 | { |
199 | png_debug(1, "in png_set_invert_mono"); |
248 | png_debug(1, "in png_set_invert_mono"); |
Line 200... | Line 249... | ||
200 | 249 | ||
201 | if (png_ptr == NULL) |
250 | if (png_ptr == NULL) |
Line 422... | Line 471... | ||
422 | #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ |
471 | #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */ |
423 | 472 | ||
Line 424... | Line 473... | ||
424 | #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ |
473 | #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ |
425 | defined(PNG_READ_STRIP_ALPHA_SUPPORTED) |
474 | defined(PNG_READ_STRIP_ALPHA_SUPPORTED) |
- | 475 | /* Remove a channel - this used to be 'png_do_strip_filler' but it used a |
|
- | 476 | * somewhat weird combination of flags to determine what to do. All the calls |
|
- | 477 | * to png_do_strip_filler are changed in 1.5.2 to call this instead with the |
|
- | 478 | * correct arguments. |
|
- | 479 | * |
|
- | 480 | * The routine isn't general - the channel must be the channel at the start or |
|
426 | /* Remove filler or alpha byte(s) */ |
481 | * end (not in the middle) of each pixel. |
- | 482 | */ |
|
427 | void /* PRIVATE */ |
483 | void /* PRIVATE */ |
428 | png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) |
484 | png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) |
429 | { |
485 | { |
430 | png_debug(1, "in png_do_strip_filler"); |
486 | png_bytep sp = row; /* source pointer */ |
- | 487 | png_bytep dp = row; /* destination pointer */ |
|
- | 488 | png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ |
|
431 | 489 | ||
- | 490 | /* At the start sp will point to the first byte to copy and dp to where |
|
- | 491 | * it is copied to. ep always points just beyond the end of the row, so |
|
- | 492 | * the loop simply copies (channels-1) channels until sp reaches ep. |
|
432 | { |
493 | * |
433 | png_bytep sp = row; |
- | |
434 | png_bytep dp = row; |
494 | * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. |
435 | png_uint_32 row_width = row_info->width; |
495 | * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. |
436 | png_uint_32 i; |
496 | */ |
Line 437... | Line -... | ||
437 | - | ||
438 | if ((row_info->color_type == PNG_COLOR_TYPE_RGB || |
- | |
439 | (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && |
497 | |
440 | (flags & PNG_FLAG_STRIP_ALPHA))) && |
498 | /* GA, GX, XG cases */ |
441 | row_info->channels == 4) |
499 | if (row_info->channels == 2) |
442 | { |
500 | { |
443 | if (row_info->bit_depth == 8) |
501 | if (row_info->bit_depth == 8) |
444 | { |
502 | { |
445 | /* This converts from RGBX or RGBA to RGB */ |
- | |
446 | if (flags & PNG_FLAG_FILLER_AFTER) |
503 | if (at_start) /* Skip initial filler */ |
447 | { |
- | |
448 | dp += 3; sp += 4; |
504 | ++sp; |
449 | for (i = 1; i < row_width; i++) |
505 | else /* Skip initial channel and, for sp, the filler */ |
- | 506 | sp += 2, ++dp; |
|
450 | { |
507 | |
451 | *dp++ = *sp++; |
508 | /* For a 1 pixel wide image there is nothing to do */ |
452 | *dp++ = *sp++; |
509 | while (sp < ep) |
453 | *dp++ = *sp++; |
- | |
454 | sp++; |
- | |
455 | } |
- | |
Line 456... | Line -... | ||
456 | } |
- | |
457 | - | ||
458 | /* This converts from XRGB or ARGB to RGB */ |
- | |
459 | else |
- | |
460 | { |
- | |
461 | for (i = 0; i < row_width; i++) |
- | |
462 | { |
- | |
463 | sp++; |
- | |
464 | *dp++ = *sp++; |
- | |
465 | *dp++ = *sp++; |
- | |
466 | *dp++ = *sp++; |
- | |
467 | } |
510 | *dp++ = *sp, sp += 2; |
468 | } |
- | |
469 | row_info->pixel_depth = 24; |
511 | |
Line 470... | Line 512... | ||
470 | row_info->rowbytes = row_width * 3; |
512 | row_info->pixel_depth = 8; |
471 | } |
- | |
472 | - | ||
473 | else /* if (row_info->bit_depth == 16) */ |
- | |
474 | { |
- | |
475 | if (flags & PNG_FLAG_FILLER_AFTER) |
- | |
476 | { |
- | |
477 | /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */ |
513 | } |
478 | sp += 8; dp += 6; |
- | |
479 | for (i = 1; i < row_width; i++) |
514 | |
480 | { |
- | |
481 | /* This could be (although png_memcpy is probably slower): |
- | |
482 | png_memcpy(dp, sp, 6); |
- | |
483 | sp += 8; |
- | |
484 | dp += 6; |
- | |
485 | */ |
- | |
486 | - | ||
487 | *dp++ = *sp++; |
- | |
488 | *dp++ = *sp++; |
- | |
489 | *dp++ = *sp++; |
- | |
490 | *dp++ = *sp++; |
515 | else if (row_info->bit_depth == 16) |
- | 516 | { |
|
- | 517 | if (at_start) /* Skip initial filler */ |
|
- | 518 | sp += 2; |
|
491 | *dp++ = *sp++; |
519 | else /* Skip initial channel and, for sp, the filler */ |
- | 520 | sp += 4, dp += 2; |
|
- | 521 | ||
- | 522 | while (sp < ep) |
|
492 | *dp++ = *sp++; |
523 | *dp++ = *sp++, *dp++ = *sp, sp += 3; |
Line 493... | Line 524... | ||
493 | sp += 2; |
524 | |
494 | } |
- | |
495 | } |
- | |
496 | - | ||
497 | else |
- | |
498 | { |
- | |
499 | /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */ |
- | |
500 | for (i = 0; i < row_width; i++) |
- | |
501 | { |
525 | row_info->pixel_depth = 16; |
502 | /* This could be (although png_memcpy is probably slower): |
- | |
Line 503... | Line 526... | ||
503 | png_memcpy(dp, sp, 6); |
526 | } |
504 | sp += 8; |
- | |
505 | dp += 6; |
- | |
506 | */ |
- | |
507 | - | ||
508 | sp += 2; |
- | |
509 | *dp++ = *sp++; |
- | |
510 | *dp++ = *sp++; |
- | |
511 | *dp++ = *sp++; |
- | |
Line 512... | Line 527... | ||
512 | *dp++ = *sp++; |
527 | |
513 | *dp++ = *sp++; |
528 | else |
514 | *dp++ = *sp++; |
- | |
515 | } |
529 | return; /* bad bit depth */ |
516 | } |
530 | |
Line 517... | Line -... | ||
517 | - | ||
518 | row_info->pixel_depth = 48; |
- | |
519 | row_info->rowbytes = row_width * 6; |
531 | row_info->channels = 1; |
520 | } |
532 | |
521 | row_info->channels = 3; |
533 | /* Finally fix the color type if it records an alpha channel */ |
522 | } |
534 | if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
523 | 535 | row_info->color_type = PNG_COLOR_TYPE_GRAY; |
|
524 | else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || |
536 | } |
525 | (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && |
537 | |
526 | (flags & PNG_FLAG_STRIP_ALPHA))) && |
538 | /* RGBA, RGBX, XRGB cases */ |
527 | row_info->channels == 2) |
- | |
528 | { |
- | |
529 | if (row_info->bit_depth == 8) |
- | |
530 | { |
539 | else if (row_info->channels == 4) |
531 | if (flags & PNG_FLAG_FILLER_AFTER) |
- | |
532 | { |
- | |
533 | /* This converts from GX or GA to G */ |
540 | { |
534 | for (i = 0; i < row_width; i++) |
- | |
535 | { |
- | |
536 | *dp++ = *sp++; |
541 | if (row_info->bit_depth == 8) |
537 | sp++; |
- | |
538 | } |
- | |
539 | } |
542 | { |
540 | 543 | if (at_start) /* Skip initial filler */ |
|
541 | else |
- | |
542 | { |
- | |
Line 543... | Line 544... | ||
543 | /* This converts from XG or AG to G */ |
544 | ++sp; |
544 | for (i = 0; i < row_width; i++) |
- | |
545 | { |
545 | else /* Skip initial channels and, for sp, the filler */ |
Line 546... | Line 546... | ||
546 | sp++; |
546 | sp += 4, dp += 3; |
547 | *dp++ = *sp++; |
- | |
548 | } |
- | |
549 | } |
- | |
550 | - | ||
551 | row_info->pixel_depth = 8; |
- | |
552 | row_info->rowbytes = row_width; |
- | |
553 | } |
547 | |
554 | - | ||
555 | else /* if (row_info->bit_depth == 16) */ |
548 | /* Note that the loop adds 3 to dp and 4 to sp each time. */ |
556 | { |
549 | while (sp < ep) |
557 | if (flags & PNG_FLAG_FILLER_AFTER) |
550 | *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; |
558 | { |
551 | |
Line 559... | Line 552... | ||
559 | /* This converts from GGXX or GGAA to GG */ |
552 | row_info->pixel_depth = 24; |
560 | sp += 4; dp += 2; |
- | |
561 | for (i = 1; i < row_width; i++) |
- | |
562 | { |
- | |
563 | *dp++ = *sp++; |
553 | } |
564 | *dp++ = *sp++; |
554 | |
565 | sp += 2; |
555 | else if (row_info->bit_depth == 16) |
566 | } |
556 | { |
567 | } |
557 | if (at_start) /* Skip initial filler */ |
568 | 558 | sp += 2; |
|
Line 569... | Line 559... | ||
569 | else |
559 | else /* Skip initial channels and, for sp, the filler */ |
570 | { |
- | |
571 | /* This converts from XXGG or AAGG to GG */ |
- | |
572 | for (i = 0; i < row_width; i++) |
- | |
573 | { |
560 | sp += 8, dp += 6; |
Line -... | Line 561... | ||
- | 561 | ||
574 | sp += 2; |
562 | while (sp < ep) |
- | 563 | { |
|
- | 564 | /* Copy 6 bytes, skip 2 */ |
|
- | 565 | *dp++ = *sp++, *dp++ = *sp++; |
|
- | 566 | *dp++ = *sp++, *dp++ = *sp++; |
|
575 | *dp++ = *sp++; |
567 | *dp++ = *sp++, *dp++ = *sp, sp += 3; |
576 | *dp++ = *sp++; |
568 | } |
577 | } |
569 | |
- | 570 | row_info->pixel_depth = 48; |
|
- | 571 | } |
|
- | 572 | ||
- | 573 | else |
|
- | 574 | return; /* bad bit depth */ |
|
- | 575 | ||
578 | } |
576 | row_info->channels = 3; |
579 | 577 | ||
Line 580... | Line 578... | ||
580 | row_info->pixel_depth = 16; |
578 | /* Finally fix the color type if it records an alpha channel */ |
581 | row_info->rowbytes = row_width * 2; |
579 | if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) |
Line 668... | Line 666... | ||
668 | } |
666 | } |
669 | } |
667 | } |
670 | #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ |
668 | #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ |
671 | 669 | ||
Line -... | Line 670... | ||
- | 670 | #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ |
|
- | 671 | defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) |
|
- | 672 | /* Added at libpng-1.5.10 */ |
|
- | 673 | void /* PRIVATE */ |
|
- | 674 | png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) |
|
- | 675 | { |
|
- | 676 | if (png_ptr->num_palette < (1 << row_info->bit_depth) && |
|
- | 677 | png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ |
|
- | 678 | { |
|
- | 679 | /* Calculations moved outside switch in an attempt to stop different |
|
- | 680 | * compiler warnings. 'padding' is in *bits* within the last byte, it is |
|
- | 681 | * an 'int' because pixel_depth becomes an 'int' in the expression below, |
|
- | 682 | * and this calculation is used because it avoids warnings that other |
|
- | 683 | * forms produced on either GCC or MSVC. |
|
- | 684 | */ |
|
- | 685 | int padding = (-row_info->pixel_depth * row_info->width) & 7; |
|
- | 686 | png_bytep rp = png_ptr->row_buf + row_info->rowbytes; |
|
- | 687 | ||
- | 688 | switch (row_info->bit_depth) |
|
- | 689 | { |
|
- | 690 | case 1: |
|
- | 691 | { |
|
- | 692 | /* in this case, all bytes must be 0 so we don't need |
|
- | 693 | * to unpack the pixels except for the rightmost one. |
|
- | 694 | */ |
|
- | 695 | for (; rp > png_ptr->row_buf; rp--) |
|
- | 696 | { |
|
- | 697 | if (*rp >> padding != 0) |
|
- | 698 | png_ptr->num_palette_max = 1; |
|
- | 699 | padding = 0; |
|
- | 700 | } |
|
- | 701 | ||
- | 702 | break; |
|
- | 703 | } |
|
- | 704 | ||
- | 705 | case 2: |
|
- | 706 | { |
|
- | 707 | for (; rp > png_ptr->row_buf; rp--) |
|
- | 708 | { |
|
- | 709 | int i = ((*rp >> padding) & 0x03); |
|
- | 710 | ||
- | 711 | if (i > png_ptr->num_palette_max) |
|
- | 712 | png_ptr->num_palette_max = i; |
|
- | 713 | ||
- | 714 | i = (((*rp >> padding) >> 2) & 0x03); |
|
- | 715 | ||
- | 716 | if (i > png_ptr->num_palette_max) |
|
- | 717 | png_ptr->num_palette_max = i; |
|
- | 718 | ||
- | 719 | i = (((*rp >> padding) >> 4) & 0x03); |
|
- | 720 | ||
- | 721 | if (i > png_ptr->num_palette_max) |
|
- | 722 | png_ptr->num_palette_max = i; |
|
- | 723 | ||
- | 724 | i = (((*rp >> padding) >> 6) & 0x03); |
|
- | 725 | ||
- | 726 | if (i > png_ptr->num_palette_max) |
|
- | 727 | png_ptr->num_palette_max = i; |
|
- | 728 | ||
- | 729 | padding = 0; |
|
- | 730 | } |
|
- | 731 | ||
- | 732 | break; |
|
- | 733 | } |
|
- | 734 | ||
- | 735 | case 4: |
|
- | 736 | { |
|
- | 737 | for (; rp > png_ptr->row_buf; rp--) |
|
- | 738 | { |
|
- | 739 | int i = ((*rp >> padding) & 0x0f); |
|
- | 740 | ||
- | 741 | if (i > png_ptr->num_palette_max) |
|
- | 742 | png_ptr->num_palette_max = i; |
|
- | 743 | ||
- | 744 | i = (((*rp >> padding) >> 4) & 0x0f); |
|
- | 745 | ||
- | 746 | if (i > png_ptr->num_palette_max) |
|
- | 747 | png_ptr->num_palette_max = i; |
|
- | 748 | ||
- | 749 | padding = 0; |
|
- | 750 | } |
|
- | 751 | ||
- | 752 | break; |
|
- | 753 | } |
|
- | 754 | ||
- | 755 | case 8: |
|
- | 756 | { |
|
- | 757 | for (; rp > png_ptr->row_buf; rp--) |
|
- | 758 | { |
|
- | 759 | if (*rp > png_ptr->num_palette_max) |
|
- | 760 | png_ptr->num_palette_max = (int) *rp; |
|
- | 761 | } |
|
- | 762 | ||
- | 763 | break; |
|
- | 764 | } |
|
- | 765 | ||
- | 766 | default: |
|
- | 767 | break; |
|
- | 768 | } |
|
- | 769 | } |
|
- | 770 | } |
|
- | 771 | #endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */ |
|
- | 772 | ||
672 | #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
773 | #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ |
673 | defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
774 | defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) |
674 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
775 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
675 | void PNGAPI |
776 | void PNGAPI |
676 | png_set_user_transform_info(png_structp png_ptr, png_voidp |
777 | png_set_user_transform_info(png_structrp png_ptr, png_voidp |
677 | user_transform_ptr, int user_transform_depth, int user_transform_channels) |
778 | user_transform_ptr, int user_transform_depth, int user_transform_channels) |
678 | { |
779 | { |
679 | png_debug(1, "in png_set_user_transform_info"); |
780 | png_debug(1, "in png_set_user_transform_info"); |
Line 680... | Line 781... | ||
680 | 781 | ||
681 | if (png_ptr == NULL) |
782 | if (png_ptr == NULL) |
- | 783 | return; |
|
- | 784 | ||
- | 785 | #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED |
|
- | 786 | if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && |
|
- | 787 | (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) |
|
- | 788 | { |
|
- | 789 | png_app_error(png_ptr, |
|
- | 790 | "info change after png_start_read_image or png_read_update_info"); |
|
- | 791 | return; |
|
- | 792 | } |
|
- | 793 | #endif |
|
682 | return; |
794 | |
683 | png_ptr->user_transform_ptr = user_transform_ptr; |
795 | png_ptr->user_transform_ptr = user_transform_ptr; |
684 | png_ptr->user_transform_depth = (png_byte)user_transform_depth; |
796 | png_ptr->user_transform_depth = (png_byte)user_transform_depth; |
685 | png_ptr->user_transform_channels = (png_byte)user_transform_channels; |
797 | png_ptr->user_transform_channels = (png_byte)user_transform_channels; |
686 | } |
798 | } |
Line 692... | Line 804... | ||
692 | * are called. |
804 | * are called. |
693 | */ |
805 | */ |
694 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
806 | #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED |
695 | png_voidp PNGAPI |
807 | png_voidp PNGAPI |
696 | png_get_user_transform_ptr(png_const_structp png_ptr) |
808 | png_get_user_transform_ptr(png_const_structrp png_ptr) |
697 | { |
809 | { |
698 | if (png_ptr == NULL) |
810 | if (png_ptr == NULL) |
699 | return (NULL); |
811 | return (NULL); |
700 | 812 | ||
Line 701... | Line 813... | ||
701 | return ((png_voidp)png_ptr->user_transform_ptr); |
813 | return png_ptr->user_transform_ptr; |
702 | } |
814 | } |
703 | #endif |
815 | #endif |
Line -... | Line 816... | ||
- | 816 | ||
704 | 817 | #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED |
|
705 | png_uint_32 PNGAPI |
818 | png_uint_32 PNGAPI |
706 | png_get_current_row_number(png_const_structp png_ptr) |
819 | png_get_current_row_number(png_const_structrp png_ptr) |
- | 820 | { |
|
- | 821 | /* See the comments in png.h - this is the sub-image row when reading and |
|
- | 822 | * interlaced image. |
|
707 | { |
823 | */ |
708 | if (png_ptr != NULL) |
824 | if (png_ptr != NULL) |
- | 825 | return png_ptr->row_number; |
|
709 | return png_ptr->row_number; |
826 | |
710 | return PNG_UINT_32_MAX; /* help the app not to fail silently */ |
827 | return PNG_UINT_32_MAX; /* help the app not to fail silently */ |
Line 711... | Line 828... | ||
711 | } |
828 | } |
712 | 829 | ||
713 | png_byte PNGAPI |
830 | png_byte PNGAPI |
714 | png_get_current_pass_number(png_const_structp png_ptr) |
831 | png_get_current_pass_number(png_const_structrp png_ptr) |
715 | { |
832 | { |
716 | if (png_ptr != NULL) |
833 | if (png_ptr != NULL) |
717 | return png_ptr->pass; |
834 | return png_ptr->pass; |
- | 835 | return 8; /* invalid */ |
|
718 | return 8; /* invalid */ |
836 | } |
719 | } |
837 | #endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */ |
720 | #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || |
838 | #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED || |