Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/codec/SkSwizzler.cpp

Issue 947283002: Bmp Image Decoding (Closed) Base URL: https://skia.googlesource.com/skia.git@decode-leon-3
Patch Set: Tested bmp and swizzler design Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/codec/SkSwizzler.h ('K') | « src/codec/SkSwizzler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkColorPriv.h" 8 #include "SkColorPriv.h"
9 #include "SkSwizzler.h" 9 #include "SkSwizzler.h"
10 #include "SkTemplates.h" 10 #include "SkTemplates.h"
11 11
12 // index 12 // index
13 13
14 #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT) 14 #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
15 15
16 static bool swizzle_index_to_n32(void* SK_RESTRICT dstRow, 16 static bool swizzle_index_to_n32(void* SK_RESTRICT dstRow,
17 const uint8_t* SK_RESTRICT src, 17 const uint8_t* SK_RESTRICT src,
18 int width, int deltaSrc, int, const SkPMColor c table[]) { 18 int width, int deltaSrc, int bPP, int,
19 const SkPMColor ctable[], const uint32_t*,
20 const bool, bool*, bool*) {
19 21
20 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 22 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
21 SkPMColor cc = A32_MASK_IN_PLACE; 23 SkPMColor cc = A32_MASK_IN_PLACE;
22 for (int x = 0; x < width; x++) { 24 const uint32_t pixelsPerByte = 8 / bPP;
23 SkPMColor c = ctable[*src]; 25 const uint32_t rowBytes = (width + pixelsPerByte - 1) / pixelsPerByte;
24 cc &= c; 26 const uint8_t mask = (1 << bPP) - 1;
25 dst[x] = c; 27
26 src += deltaSrc; 28 uint32_t x = 0;
29 for (uint32_t byte = 0; byte < rowBytes; byte++) {
30 uint8_t pixelData = src[byte];
31 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
32 uint8_t index = (pixelData >> (8 - bPP)) & mask;
33 dst[x] = ctable[index];
34 cc &= ctable[index];
35 pixelData <<= bPP;
36 x++;
37 }
27 } 38 }
28 return cc != A32_MASK_IN_PLACE; 39 return cc != A32_MASK_IN_PLACE;
29 } 40 }
30 41
42 // TODO: this is only valid for kIndex8
31 static bool swizzle_index_to_n32_skipZ(void* SK_RESTRICT dstRow, 43 static bool swizzle_index_to_n32_skipZ(void* SK_RESTRICT dstRow,
32 const uint8_t* SK_RESTRICT src, 44 const uint8_t* SK_RESTRICT src,
33 int width, int deltaSrc, int, 45 int width, int deltaSrc, int bPP, int,
34 const SkPMColor ctable[]) { 46 const SkPMColor ctable[],
47 const uint32_t*, const bool, bool*,
48 bool*) {
35 49
36 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 50 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
37 SkPMColor cc = A32_MASK_IN_PLACE; 51 SkPMColor cc = A32_MASK_IN_PLACE;
38 for (int x = 0; x < width; x++) { 52 for (int x = 0; x < width; x++) {
39 SkPMColor c = ctable[*src]; 53 SkPMColor c = ctable[*src];
40 cc &= c; 54 cc &= c;
41 if (c != 0) { 55 if (c != 0) {
42 dst[x] = c; 56 dst[x] = c;
43 } 57 }
44 src += deltaSrc; 58 src += deltaSrc;
45 } 59 }
46 return cc != A32_MASK_IN_PLACE; 60 return cc != A32_MASK_IN_PLACE;
47 } 61 }
48 62
49 #undef A32_MASK_IN_PLACE 63 #undef A32_MASK_IN_PLACE
50 64
65 // mask
66
67 /**
68 *
69 * Used to convert 1-7 bit color components into 8-bit color components
70 *
71 */
72 const uint8_t nBitTo8BitlookupTable[] = {
73 // 1 bit
74 0, 255,
75 // 2 bits
76 0, 85, 170, 255,
77 // 3 bits
78 0, 36, 73, 109, 146, 182, 219, 255,
79 // 4 bits
80 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
81 // 5 bits
82 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
83 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
84 // 6 bits
85 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
86 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
87 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
88 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
89 // 7 bits
90 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
91 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
92 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
93 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
94 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
95 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
96 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
97 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
98 };
99
100 /*
101 *
102 * Convert an n bit component to an 8-bit component
103 *
104 */
105 static uint8_t convertNTo8(uint32_t component, uint32_t n) {
106 if (n == 0) {
107 return 0;
108 } else if (n < 8) {
109 return nBitTo8BitlookupTable[(1 << n) - 2 + component];
110 } else if (n == 8) {
111 return component;
112 } else {
113 SkDebugf("Error: too many bits for lookup table.\n");
114 return 0;
115 }
116 }
117
118 /*
119 *
120 * For a continuous bit mask (ex: 0011100), retrieves the size of the mask and
121 * the trailing zeros
122 *
123 */
124 static void getMaskInfo(uint32_t mask, uint32_t bPP, uint32_t* size,
125 uint32_t* shift) {
126 // Trim mask based on pixel size
127 if (bPP < 32) {
128 mask &= (1 << bPP) - 1;
129 }
130
131 // For empty masks, set zeros and return
132 uint32_t tempMask = mask;
133 if (!tempMask) {
134 *size = 0;
135 *shift = 0;
136 return;
137 }
138
139 // Count trailing zeros
140 int zeros = 0;
141 for (; !(tempMask & 1); tempMask >>= 1) {
142 zeros++;
143 }
144
145 // Count mask size
146 int count = 0;
147 for (; tempMask & 1; tempMask >>= 1) {
148 count++;
149 }
150
151 // We will use a maximum of 8 bits for the size, truncate some of the mask
152 // bits if necessary
153 if (count > 8) {
154 *shift = count - 8 + zeros;
155 *size = 8;
156 } else {
157 *shift = zeros;
158 *size = count;
159 }
160 return;
161 }
162
163 static bool swizzle_mask_to_n32(void* SK_RESTRICT dstRow,
164 const uint8_t* SK_RESTRICT src,
165 int width, int deltaSrc, int bPP, int,
166 const SkPMColor ctable[],
167 const uint32_t* masks, const bool,
168 bool* fSeenNonZeroAlphaPtr,
169 bool* fZeroPrevRowsPtr) {
170 // Load the bit masks
171 uint32_t redMask = masks[0];
172 uint32_t greenMask = masks[1];
173 uint32_t blueMask = masks[2];
174 uint32_t alphaMask = masks[3];
175 uint32_t rBits, rShift, gBits, gShift, bBits, bShift, aBits, aShift;
176 getMaskInfo(redMask, bPP, &rBits, &rShift);
177 getMaskInfo(greenMask, bPP, &gBits, &gShift);
178 getMaskInfo(blueMask, bPP, &bBits, &bShift);
179 getMaskInfo(alphaMask, bPP, &aBits, &aShift);
180
181 // Use the masks to decode to the destination
182 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
183 int x = 0;
184 for (uint32_t p = 0; p < width * deltaSrc; p += deltaSrc) {
185 uint32_t pixel;
186 switch (deltaSrc) {
scroggo 2015/02/25 17:22:43 these static functions are intended to be specific
msarett 2015/02/26 23:58:18 Yes we can. My concern is an explosion in the num
scroggo 2015/02/27 17:04:00 In general, my preference is to avoid duplicated c
187 case 2:
188 pixel = src[p] | (src[p + 1] << 8);
189 break;
190 case 3:
191 pixel = src[p] | (src[p + 1] << 8) | (src[p + 2] << 16);
192 break;
193 case 4:
194 pixel = src[p] | (src[p + 1] << 8) | (src[p + 2] << 16) |
195 (src[p + 3] << 24);
196 break;
197 default:
198 SkDebugf("Error: invalid number of bytes per pixel.\n");
199 return false;
200 }
201 uint8_t red = convertNTo8((pixel & redMask) >> rShift, rBits);
202 uint8_t green = convertNTo8((pixel & greenMask) >> gShift, gBits);
203 uint8_t blue = convertNTo8((pixel & blueMask) >> bShift, bBits);
204 uint8_t alpha = convertNTo8((pixel & alphaMask) >> aShift, aBits);
205
206 // We must respect the alpha channel for V4 and V5. However, if it is
207 // all zeros, we will display the image as opaque rather than
208 // transparent. This may require redoing some of the processing.
209 if (*fSeenNonZeroAlphaPtr) {
210 dst[x] = SkPackARGB32(alpha, red, blue, green);
211 x++;
212 } else if (!alpha) {
213 dst[x] = SkPackARGB32(0xFF, red, blue, green);
214 x++;
215 } else {
216 *fZeroPrevRowsPtr = true;
217 *fSeenNonZeroAlphaPtr = true;
218 x = 0;
219 p = -1;
220 }
221 }
222 return false;
223 }
224
225 // bgrx and bgra
226
227 static bool swizzle_bgrx_to_n32(void* SK_RESTRICT dstRow,
228 const uint8_t* SK_RESTRICT src,
229 int width, int deltaSrc, int,
230 int, const SkPMColor[], const uint32_t*,
231 const bool, bool*, bool*) {
232 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
233 for (int x = 0; x < width; x++) {
234 dst[x] = SkPackARGB32(0xFF, src[2], src[1], src[0]);
235 src += deltaSrc;
236 }
237 return false;
238 }
239
240 static bool swizzle_bgra_to_n32(void* SK_RESTRICT dstRow,
241 const uint8_t* SK_RESTRICT src,
242 int width, int deltaSrc, int, int,
243 const SkPMColor[], const uint32_t* masks,
244 const bool fixAlpha, bool* fSeenNonZeroAlphaPtr,
245 bool* fZeroPrevRowsPtr) {
246 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
247 uint32_t alphaMask = masks[3];
248 const uint8_t* srcStart = src;
249 for (int x = 0; x < width; x++) {
250 uint8_t alpha = alphaMask & src[3];
251 // We must respect the alpha channel for V4 and V5. However, if it is
252 // all zeros, we will display the image as opaque rather than
253 // transparent. This may require redoing some of the processing.
254 if (*fSeenNonZeroAlphaPtr) {
255 dst[x] = SkPackARGB32(alpha, src[2], src[1], src[0]);
256 src += deltaSrc;
257 } else if (!alpha) {
258 dst[x] = SkPackARGB32(0xFF, src[2], src[1], src[0]);
259 src += deltaSrc;
260 } else {
261 *fZeroPrevRowsPtr = true;
262 *fSeenNonZeroAlphaPtr = true;
263 int x = -1;
264 src = srcStart;
265 }
266 }
267 return false;
scroggo 2015/02/25 17:22:43 Sorry, I thought I had documented this, but the re
268 }
269
51 // n32 270 // n32
52 static bool swizzle_rgbx_to_n32(void* SK_RESTRICT dstRow, 271 static bool swizzle_rgbx_to_n32(void* SK_RESTRICT dstRow,
53 const uint8_t* SK_RESTRICT src, 272 const uint8_t* SK_RESTRICT src,
54 int width, int deltaSrc, int, const SkPMColor[]) { 273 int width, int deltaSrc, int, int,
274 const SkPMColor[], const uint32_t*,
275 const bool, bool*, bool*) {
55 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 276 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
56 for (int x = 0; x < width; x++) { 277 for (int x = 0; x < width; x++) {
57 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); 278 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
58 src += deltaSrc; 279 src += deltaSrc;
59 } 280 }
60 return false; 281 return false;
61 } 282 }
62 283
63 static bool swizzle_rgba_to_n32_premul(void* SK_RESTRICT dstRow, 284 static bool swizzle_rgba_to_n32_premul(void* SK_RESTRICT dstRow,
64 const uint8_t* SK_RESTRICT src, 285 const uint8_t* SK_RESTRICT src,
65 int width, int deltaSrc, int, const SkPMC olor[]) { 286 int width, int deltaSrc, int, int,
287 const SkPMColor[], const uint32_t*,
288 const bool, bool*, bool*) {
66 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 289 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
67 unsigned alphaMask = 0xFF; 290 unsigned alphaMask = 0xFF;
68 for (int x = 0; x < width; x++) { 291 for (int x = 0; x < width; x++) {
69 unsigned alpha = src[3]; 292 unsigned alpha = src[3];
70 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 293 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
71 src += deltaSrc; 294 src += deltaSrc;
72 alphaMask &= alpha; 295 alphaMask &= alpha;
73 } 296 }
74 return alphaMask != 0xFF; 297 return alphaMask != 0xFF;
75 } 298 }
76 299
77 static bool swizzle_rgba_to_n32_unpremul(void* SK_RESTRICT dstRow, 300 static bool swizzle_rgba_to_n32_unpremul(void* SK_RESTRICT dstRow,
78 const uint8_t* SK_RESTRICT src, 301 const uint8_t* SK_RESTRICT src,
79 int width, int deltaSrc, int, 302 int width, int deltaSrc, int, int,
80 const SkPMColor[]) { 303 const SkPMColor[], const uint32_t*,
304 const bool, bool*, bool*) {
81 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); 305 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
82 unsigned alphaMask = 0xFF; 306 unsigned alphaMask = 0xFF;
83 for (int x = 0; x < width; x++) { 307 for (int x = 0; x < width; x++) {
84 unsigned alpha = src[3]; 308 unsigned alpha = src[3];
85 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 309 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
86 src += deltaSrc; 310 src += deltaSrc;
87 alphaMask &= alpha; 311 alphaMask &= alpha;
88 } 312 }
89 return alphaMask != 0xFF; 313 return alphaMask != 0xFF;
90 } 314 }
91 315
92 static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow, 316 static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow,
93 const uint8_t* SK_RESTRICT src, 317 const uint8_t* SK_RESTRICT src,
94 int width, int deltaSrc, int, 318 int width, int deltaSrc, int, int,
95 const SkPMColor[]) { 319 const SkPMColor[],
320 const uint32_t*, const bool,
321 bool*, bool*) {
96 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 322 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
97 unsigned alphaMask = 0xFF; 323 unsigned alphaMask = 0xFF;
98 for (int x = 0; x < width; x++) { 324 for (int x = 0; x < width; x++) {
99 unsigned alpha = src[3]; 325 unsigned alpha = src[3];
100 if (0 != alpha) { 326 if (0 != alpha) {
101 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 327 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
102 } 328 }
103 src += deltaSrc; 329 src += deltaSrc;
104 alphaMask &= alpha; 330 alphaMask &= alpha;
105 } 331 }
(...skipping 22 matching lines...) Expand all
128 } 354 }
129 src += deltaSrc; 355 src += deltaSrc;
130 alphaMask &= alpha; 356 alphaMask &= alpha;
131 } 357 }
132 return alphaMask != 0xFF; 358 return alphaMask != 0xFF;
133 } 359 }
134 */ 360 */
135 361
136 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor * ctable, 362 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor * ctable,
137 const SkImageInfo& info, void* dst, 363 const SkImageInfo& info, void* dst,
138 size_t dstRowBytes, bool skipZeroes) { 364 size_t dstRowBytes, bool skipZeroes,
365 const uint32_t* bitMasks,
366 const bool fixAlpha,
367 const bool inverted) {
139 if (info.colorType() == kUnknown_SkColorType) { 368 if (info.colorType() == kUnknown_SkColorType) {
140 return NULL; 369 return NULL;
141 } 370 }
142 if (info.minRowBytes() > dstRowBytes) { 371 if (info.minRowBytes() > dstRowBytes) {
143 return NULL; 372 return NULL;
144 } 373 }
145 if (kIndex == sc && NULL == ctable) { 374 if ((kIndex8 == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
375 && NULL == ctable) {
146 return NULL; 376 return NULL;
147 } 377 }
148 RowProc proc = NULL; 378 RowProc proc = NULL;
149 switch (sc) { 379 switch (sc) {
150 case kIndex: 380 case kIndex1:
381 case kIndex2:
382 case kIndex4:
383 case kIndex8:
151 switch (info.colorType()) { 384 switch (info.colorType()) {
152 case kN32_SkColorType: 385 case kN32_SkColorType:
153 // We assume the color premultiplied ctable (or not) as desi red. 386 proc = &swizzle_index_to_n32;
154 if (skipZeroes) {
155 proc = &swizzle_index_to_n32_skipZ;
156 } else {
157 proc = &swizzle_index_to_n32;
158 }
159 break; 387 break;
160
161 default: 388 default:
162 break; 389 break;
163 } 390 }
391 break;
392 case kMask16:
393 case kMask24:
394 case kMask32:
395 switch (info.colorType()) {
396 case kN32_SkColorType:
397 proc = &swizzle_mask_to_n32;
398 break;
399 default:
400 break;
401 }
402 break;
403 case kBGR:
404 case kBGRX:
405 switch (info.colorType()) {
406 case kN32_SkColorType:
407 proc = &swizzle_bgrx_to_n32;
408 break;
409 default:
410 break;
411 }
412 break;
413 case kBGRA:
414 switch (info.colorType()) {
415 case kN32_SkColorType:
416 proc = &swizzle_bgra_to_n32;
417 break;
418 default:
419 break;
420 }
164 break; 421 break;
165 case kRGBX: 422 case kRGBX:
166 // TODO: Support other swizzles. 423 // TODO: Support other swizzles.
167 switch (info.colorType()) { 424 switch (info.colorType()) {
168 case kN32_SkColorType: 425 case kN32_SkColorType:
169 proc = &swizzle_rgbx_to_n32; 426 proc = &swizzle_rgbx_to_n32;
170 break; 427 break;
171 default: 428 default:
172 break; 429 break;
173 } 430 }
174 break; 431 break;
175 case kRGBA: 432 case kRGBA:
176 switch (info.colorType()) { 433 switch (info.colorType()) {
177 case kN32_SkColorType: 434 case kN32_SkColorType:
178 if (info.alphaType() == kUnpremul_SkAlphaType) { 435 if (info.alphaType() == kUnpremul_SkAlphaType) {
179 // Respect skipZeroes? 436 // Respect skipZeroes?
180 proc = &swizzle_rgba_to_n32_unpremul; 437 proc = &swizzle_rgba_to_n32_unpremul;
181 } else { 438 } else {
182 if (skipZeroes) { 439 if (skipZeroes) {
183 proc = &swizzle_rgba_to_n32_premul_skipZ; 440 proc = &swizzle_rgba_to_n32_premul_skipZ;
184 } else { 441 } else {
185 proc = &swizzle_rgba_to_n32_premul; 442 proc = &swizzle_rgba_to_n32_premul;
186 } 443 }
187 } 444 }
188 break; 445 break;
189 default: 446 default:
190 break; 447 break;
191 } 448 }
192 break; 449 break;
450 case kRGB:
451 switch (info.colorType()) {
452 case kN32_SkColorType:
453 proc = &swizzle_rgbx_to_n32;
454 break;
455 default:
456 break;
457 }
458 break;
193 default: 459 default:
194 break; 460 break;
195 } 461 }
196 if (NULL == proc) { 462 if (NULL == proc) {
197 return NULL; 463 return NULL;
198 } 464 }
199 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BytesPerPixel(sc), info, dst, d stRowBytes)); 465 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BytesPerPixel(sc),
466 BitsPerPixel(sc), info, dst, dstRowBytes,
467 bitMasks, fixAlpha, inverted));
200 } 468 }
201 469
202 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcBpp, 470 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcBpp,
203 const SkImageInfo& info, void* dst, size_t rowBytes) 471 int srcBitsPerPixel, const SkImageInfo& info, void* dst,
472 size_t rowBytes, const uint32_t* bitMasks,
473 const bool fixAlpha, const bool inverted)
204 : fRowProc(proc) 474 : fRowProc(proc)
205 , fColorTable(ctable) 475 , fColorTable(ctable)
206 , fSrcPixelSize(srcBpp) 476 , fSrcPixelSize(srcBpp)
477 , fSrcBitsPerPixel(srcBitsPerPixel)
207 , fDstInfo(info) 478 , fDstInfo(info)
208 , fDstRow(dst) 479 , fDstRow(dst)
209 , fDstRowBytes(rowBytes) 480 , fDstRowBytes(rowBytes)
210 , fCurrY(0) 481 , fCurrY(0)
482 , fBitMasks(bitMasks)
483 , fFixAlpha(fixAlpha)
484 , fInverted(inverted)
485 , fSeenNonZeroAlpha(false)
486 , fZeroPrevRows(false)
211 { 487 {
212 } 488 }
213 489
214 bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) { 490 bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
215 SkASSERT(fCurrY < fDstInfo.height()); 491 SkASSERT(fCurrY < fDstInfo.height());
216 const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(), fSrcPixelSize , 492
217 fCurrY, fColorTable); 493 // On the first iteration, if the image is inverted, start at the bottom
494 if (fCurrY == 0 && fInverted) {
495 fDstRow = SkTAddOffset<void>(fDstRow,
496 fDstRowBytes * (fDstInfo.height() - 1));
497 }
498
499 // Decode a row
500 const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(),
501 fSrcPixelSize, fSrcBitsPerPixel, fCurrY, fColorTable, fBitMasks,
502 fFixAlpha, &fSeenNonZeroAlpha, &fZeroPrevRows);
msarett 2015/02/24 21:56:06 The row procedure may need to let the caller know
503
504 // This flag indicates that we have decoded the image as opaque instead of
505 // transparent, and we just realized that it should have been transparent.
506 // To fix this, we zero the rows that have already been decoded.
507 if (fZeroPrevRows) {
508 SkDebugf("TESTING FIX ALPHA DECODE\n");
509 void* dstRow;
510 if (!fInverted) {
511 void* dstStart = SkTAddOffset<void>(fDstRow, -fCurrY*fDstRowBytes);
512 memset(dstStart, 0, fCurrY*fDstRowBytes);
513 } else {
514 void* dstStart = SkTAddOffset<void>(fDstRow, fDstRowBytes);
515 memset(dstStart, 0, fCurrY*fDstRowBytes);
516 }
517 fZeroPrevRows = false;
518 }
519
520 // Move to the next row and return the result
218 fCurrY++; 521 fCurrY++;
219 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes); 522 if (!fInverted) {
523 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
524 } else {
525 fDstRow = SkTAddOffset<void>(fDstRow, -fDstRowBytes);
526 }
220 return hadAlpha; 527 return hadAlpha;
221 } 528 }
222 529
OLDNEW
« src/codec/SkSwizzler.h ('K') | « src/codec/SkSwizzler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698