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

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: Minor fixes Created 5 years, 9 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/SkCodec_libbmp.cpp ('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
13
14 #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT) 12 #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
15 13
16 static bool swizzle_index_to_n32(void* SK_RESTRICT dstRow, 14 // kIndex1, kIndex2, kIndex4
17 const uint8_t* SK_RESTRICT src, 15
18 int width, int deltaSrc, int, const SkPMColor c table[]) { 16 static bool swizzle_small_index_to_n32(void* SK_RESTRICT dstRow,
17 const uint8_t* SK_RESTRICT src,
18 int width, int bitsPerPixel, int,
19 const SkPMColor ctable[],
20 const SkSwizzler::ColorMasks*,
21 const SkSwizzler::ZeroAlpha, bool*,
22 bool*) {
19 23
20 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 24 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
21 SkPMColor cc = A32_MASK_IN_PLACE; 25 SkPMColor cc = A32_MASK_IN_PLACE;
26 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
27 const uint32_t rowBytes = (width + pixelsPerByte - 1) / pixelsPerByte;
28 const uint8_t mask = (1 << bitsPerPixel) - 1;
29
30 uint32_t x = 0;
31 for (uint32_t byte = 0; byte < rowBytes; byte++) {
32 uint8_t pixelData = src[byte];
33 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
34 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
35 dst[x] = ctable[index];
36 cc &= ctable[index];
37 pixelData <<= bitsPerPixel;
38 x++;
39 }
40 }
41 return cc != A32_MASK_IN_PLACE;
42 }
43
44 // kIndex
45
46 static bool swizzle_index_to_n32(void* SK_RESTRICT dstRow,
47 const uint8_t* SK_RESTRICT src,
48 int width, int bitsPerPixel, int,
49 const SkPMColor ctable[],
50 const SkSwizzler::ColorMasks*,
51 const SkSwizzler::ZeroAlpha, bool*, bool*) {
52
53 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
54 SkPMColor cc = A32_MASK_IN_PLACE;
22 for (int x = 0; x < width; x++) { 55 for (int x = 0; x < width; x++) {
23 SkPMColor c = ctable[*src]; 56 SkPMColor c = ctable[*src];
24 cc &= c; 57 cc &= c;
25 dst[x] = c; 58 dst[x] = c;
26 src += deltaSrc; 59 src++;
27 } 60 }
28 return cc != A32_MASK_IN_PLACE; 61 return cc != A32_MASK_IN_PLACE;
29 } 62 }
30 63
31 static bool swizzle_index_to_n32_skipZ(void* SK_RESTRICT dstRow, 64 static bool swizzle_index_to_n32_skipZ(void* SK_RESTRICT dstRow,
32 const uint8_t* SK_RESTRICT src, 65 const uint8_t* SK_RESTRICT src,
33 int width, int deltaSrc, int, 66 int width, int bitsPerPixel, int,
34 const SkPMColor ctable[]) { 67 const SkPMColor ctable[],
68 const SkSwizzler::ColorMasks*,
69 const SkSwizzler::ZeroAlpha, bool*,
70 bool*) {
35 71
36 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 72 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
37 SkPMColor cc = A32_MASK_IN_PLACE; 73 SkPMColor cc = A32_MASK_IN_PLACE;
38 for (int x = 0; x < width; x++) { 74 for (int x = 0; x < width; x++) {
39 SkPMColor c = ctable[*src]; 75 SkPMColor c = ctable[*src];
40 cc &= c; 76 cc &= c;
41 if (c != 0) { 77 if (c != 0) {
42 dst[x] = c; 78 dst[x] = c;
43 } 79 }
80 src++;
81 }
82 return cc != A32_MASK_IN_PLACE;
83 }
84
85 #undef A32_MASK_IN_PLACE
86
87 // mask
88
89 /**
90 *
91 * Used to convert 1-7 bit color components into 8-bit color components
92 *
93 */
94 const uint8_t nBitTo8BitlookupTable[] = {
95 // 1 bit
96 0, 255,
97 // 2 bits
98 0, 85, 170, 255,
99 // 3 bits
100 0, 36, 73, 109, 146, 182, 219, 255,
101 // 4 bits
102 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
103 // 5 bits
104 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
105 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
106 // 6 bits
107 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
108 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
109 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
110 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
111 // 7 bits
112 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
113 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
114 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
115 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
116 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
117 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
118 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
119 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
120 };
121
122 /*
123 *
124 * Convert an n bit component to an 8-bit component
125 *
126 */
127 static uint8_t convertNTo8(uint32_t component, uint32_t n) {
128 if (0 == n) {
129 return 0;
130 } else if (8 > n) {
131 return nBitTo8BitlookupTable[(1 << n) - 2 + component];
132 } else if (8 == n) {
133 return component;
134 } else {
135 SkDebugf("Error: too many bits for lookup table.\n");
136 return 0;
137 }
138 }
139
140 /*
141 *
142 * For a continuous bit mask (ex: 0011100), retrieves the size of the mask and
143 * the trailing zeros
144 *
145 */
146 static void getMaskInfo(uint32_t mask, uint32_t bPP, uint32_t* size,
147 uint32_t* shift) {
148 // For empty masks, set zeros and return
149 uint32_t tempMask = mask;
150 if (!tempMask) {
151 *size = 0;
152 *shift = 0;
153 return;
154 }
155
156 // Count trailing zeros
157 int zeros = 0;
158 for (; !(tempMask & 1); tempMask >>= 1) {
159 zeros++;
160 }
161
162 // Count mask size
163 int count = 0;
164 for (; tempMask & 1; tempMask >>= 1) {
165 count++;
166 }
167
168 // We will use a maximum of 8 bits for the size, truncate some of the mask
169 // bits if necessary
170 if (count > 8) {
171 *shift = count - 8 + zeros;
172 *size = 8;
173 } else {
174 *shift = zeros;
175 *size = count;
176 }
177 return;
178 }
179
180 // kMask16
181
182 static bool swizzle_mask16_to_n32(void* SK_RESTRICT dstRow,
183 const uint8_t* SK_RESTRICT src,
184 int width, int bitsPerPixel, int,
185 const SkPMColor ctable[],
186 const SkSwizzler::ColorMasks* masks,
187 const SkSwizzler::ZeroAlpha zeroAlpha,
188 bool* seenNonZeroAlphaPtr,
189 bool* zeroPrevRowsPtr) {
190 // Load the bit masks
191 uint32_t redMask = masks->redMask;
192 uint32_t greenMask = masks->greenMask;
193 uint32_t blueMask = masks->blueMask;
194 uint32_t alphaMask = masks->alphaMask;
195 uint32_t rBits, rShift, gBits, gShift, bBits, bShift, aBits, aShift;
196 getMaskInfo(redMask, bitsPerPixel, &rBits, &rShift);
197 getMaskInfo(greenMask, bitsPerPixel, &gBits, &gShift);
198 getMaskInfo(blueMask, bitsPerPixel, &bBits, &bShift);
199 getMaskInfo(alphaMask, bitsPerPixel, &aBits, &aShift);
200
201 // Use the masks to decode to the destination
202 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
203 int x = 0;
204 for (uint32_t p = 0; p < width * 2; p += 2) {
205 uint16_t pixel = src[p] | (src[p + 1] << 8);
206 uint8_t red = convertNTo8((pixel & redMask) >> rShift, rBits);
207 uint8_t green = convertNTo8((pixel & greenMask) >> gShift, gBits);
208 uint8_t blue = convertNTo8((pixel & blueMask) >> bShift, bBits);
209 uint8_t alpha = convertNTo8((pixel & alphaMask) >> aShift, aBits);
210
211 // We must respect the alpha channel for bmp V4+. However, if it is
212 // all zeros, we will display the image as opaque rather than
213 // transparent. This may require redoing some of the processing.
214 if (SkSwizzler::kTransparentAsOpaque == zeroAlpha &&
215 *seenNonZeroAlphaPtr) {
216 dst[x] = SkPackARGB32(alpha, red, blue, green);
217 x++;
218 } else if (!alpha) {
219 dst[x] = SkPackARGB32(0xFF, red, blue, green);
220 x++;
221 } else {
222 *zeroPrevRowsPtr = true;
223 *seenNonZeroAlphaPtr = true;
224 x = 0;
225 p = -1;
226 }
227 }
228 return *seenNonZeroAlphaPtr;
229 }
230
231 // kMask24
232
233 static bool swizzle_mask24_to_n32(void* SK_RESTRICT dstRow,
234 const uint8_t* SK_RESTRICT src,
235 int width, int bitsPerPixel, int,
236 const SkPMColor ctable[],
237 const SkSwizzler::ColorMasks* masks,
238 const SkSwizzler::ZeroAlpha zeroAlpha,
239 bool* seenNonZeroAlphaPtr,
240 bool* zeroPrevRowsPtr) {
241 // Load the bit masks
242 uint32_t redMask = masks->redMask;
243 uint32_t greenMask = masks->greenMask;
244 uint32_t blueMask = masks->blueMask;
245 uint32_t alphaMask = masks->alphaMask;
246 uint32_t rBits, rShift, gBits, gShift, bBits, bShift, aBits, aShift;
247 getMaskInfo(redMask, bitsPerPixel, &rBits, &rShift);
248 getMaskInfo(greenMask, bitsPerPixel, &gBits, &gShift);
249 getMaskInfo(blueMask, bitsPerPixel, &bBits, &bShift);
250 getMaskInfo(alphaMask, bitsPerPixel, &aBits, &aShift);
251
252 // Use the masks to decode to the destination
253 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
254 int x = 0;
255 for (uint32_t p = 0; p < width * 3; p += 3) {
256 uint32_t pixel = src[p] | (src[p + 1] << 8) | src[p + 2] << 16;
257 uint8_t red = convertNTo8((pixel & redMask) >> rShift, rBits);
258 uint8_t green = convertNTo8((pixel & greenMask) >> gShift, gBits);
259 uint8_t blue = convertNTo8((pixel & blueMask) >> bShift, bBits);
260 uint8_t alpha = convertNTo8((pixel & alphaMask) >> aShift, aBits);
261
262 // We must respect the alpha channel for bmp V4+. However, if it is
263 // all zeros, we will display the image as opaque rather than
264 // transparent. This may require redoing some of the processing.
265 if (SkSwizzler::kTransparentAsOpaque == zeroAlpha &&
266 *seenNonZeroAlphaPtr) {
267 dst[x] = SkPackARGB32(alpha, red, blue, green);
268 x++;
269 } else if (!alpha) {
270 dst[x] = SkPackARGB32(0xFF, red, blue, green);
271 x++;
272 } else {
273 *zeroPrevRowsPtr = true;
274 *seenNonZeroAlphaPtr = true;
275 x = 0;
276 p = -1;
277 }
278 }
279 return *seenNonZeroAlphaPtr;
280 }
281
282 // kMask32
283
284 static bool swizzle_mask32_to_n32(void* SK_RESTRICT dstRow,
285 const uint8_t* SK_RESTRICT src,
286 int width, int bitsPerPixel, int,
287 const SkPMColor ctable[],
288 const SkSwizzler::ColorMasks* masks,
289 const SkSwizzler::ZeroAlpha zeroAlpha,
290 bool* seenNonZeroAlphaPtr,
291 bool* zeroPrevRowsPtr) {
292 // Load the bit masks
293 uint32_t redMask = masks->redMask;
294 uint32_t greenMask = masks->greenMask;
295 uint32_t blueMask = masks->blueMask;
296 uint32_t alphaMask = masks->alphaMask;
297 uint32_t rBits, rShift, gBits, gShift, bBits, bShift, aBits, aShift;
298 getMaskInfo(redMask, bitsPerPixel, &rBits, &rShift);
299 getMaskInfo(greenMask, bitsPerPixel, &gBits, &gShift);
300 getMaskInfo(blueMask, bitsPerPixel, &bBits, &bShift);
301 getMaskInfo(alphaMask, bitsPerPixel, &aBits, &aShift);
302
303 // Use the masks to decode to the destination
304 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
305 int x = 0;
306 for (uint32_t p = 0; p < width * 4; p += 4) {
307 uint32_t pixel = src[p] | (src[p + 1] << 8) | src[p + 2] << 16 |
308 src[p + 3] << 24;
309 uint8_t red = convertNTo8((pixel & redMask) >> rShift, rBits);
310 uint8_t green = convertNTo8((pixel & greenMask) >> gShift, gBits);
311 uint8_t blue = convertNTo8((pixel & blueMask) >> bShift, bBits);
312 uint8_t alpha = convertNTo8((pixel & alphaMask) >> aShift, aBits);
313
314 // We must respect the alpha channel for bmp V4+. However, if it is
315 // all zeros, we will display the image as opaque rather than
316 // transparent. This may require redoing some of the processing.
317 if (SkSwizzler::kTransparentAsOpaque == zeroAlpha &&
318 *seenNonZeroAlphaPtr) {
319 dst[x] = SkPackARGB32(alpha, red, blue, green);
320 x++;
321 } else if (!alpha) {
322 dst[x] = SkPackARGB32(0xFF, red, blue, green);
323 x++;
324 } else {
325 *zeroPrevRowsPtr = true;
326 *seenNonZeroAlphaPtr = true;
327 x = 0;
328 p = -1;
329 }
330 }
331 return *seenNonZeroAlphaPtr;
332 }
333
334 // kBGRX and kBGR
335
336 static bool swizzle_bgrx_to_n32(void* SK_RESTRICT dstRow,
337 const uint8_t* SK_RESTRICT src,
338 int width, int bitsPerPixel, int,
339 const SkPMColor[],
340 const SkSwizzler::ColorMasks*,
341 const SkSwizzler::ZeroAlpha, bool*, bool*) {
342 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
343 int deltaSrc = bitsPerPixel / 8;
344 for (int x = 0; x < width; x++) {
345 dst[x] = SkPackARGB32(0xFF, src[2], src[1], src[0]);
44 src += deltaSrc; 346 src += deltaSrc;
45 } 347 }
46 return cc != A32_MASK_IN_PLACE; 348 return false;
47 } 349 }
48 350
49 #undef A32_MASK_IN_PLACE 351 // kBGRA
352
353 static bool swizzle_bgra_to_n32(void* SK_RESTRICT dstRow,
354 const uint8_t* SK_RESTRICT src,
355 int width, int bitsPerPixel, int,
356 const SkPMColor[],
357 const SkSwizzler::ColorMasks* masks,
358 const SkSwizzler::ZeroAlpha zeroAlpha,
359 bool* seenNonZeroAlphaPtr,
360 bool* zeroPrevRowsPtr) {
361 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
362 uint32_t alphaMask = masks->alphaMask;
363 int deltaSrc = bitsPerPixel / 8;
364 const uint8_t* srcStart = src;
365 for (int x = 0; x < width; x++) {
366 uint8_t alpha = alphaMask & src[3];
367 // We must respect the alpha channel for bmp V4+. However, if it is
368 // all zeros, we will display the image as opaque rather than
369 // transparent. This may require redoing some of the processing.
370 if (SkSwizzler::kNormal == zeroAlpha || *seenNonZeroAlphaPtr) {
371 dst[x] = SkPackARGB32(alpha, src[2], src[1], src[0]);
372 src += deltaSrc;
373 } else if (!alpha) {
374 dst[x] = SkPackARGB32(0xFF, src[2], src[1], src[0]);
375 src += deltaSrc;
376 } else {
377 *zeroPrevRowsPtr = true;
378 *seenNonZeroAlphaPtr = true;
379 int x = -1;
380 src = srcStart;
381 }
382 }
383 return *seenNonZeroAlphaPtr;
384 }
50 385
51 // n32 386 // n32
52 static bool swizzle_rgbx_to_n32(void* SK_RESTRICT dstRow, 387 static bool swizzle_rgbx_to_n32(void* SK_RESTRICT dstRow,
53 const uint8_t* SK_RESTRICT src, 388 const uint8_t* SK_RESTRICT src,
54 int width, int deltaSrc, int, const SkPMColor[]) { 389 int width, int bitsPerPixel, int,
55 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 390 const SkPMColor[],
391 const SkSwizzler::ColorMasks*,
392 const SkSwizzler::ZeroAlpha, bool*, bool*) {
393 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
394 int deltaSrc = bitsPerPixel / 8;
56 for (int x = 0; x < width; x++) { 395 for (int x = 0; x < width; x++) {
57 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); 396 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
58 src += deltaSrc; 397 src += deltaSrc;
59 } 398 }
60 return false; 399 return false;
61 } 400 }
62 401
63 static bool swizzle_rgba_to_n32_premul(void* SK_RESTRICT dstRow, 402 static bool swizzle_rgba_to_n32_premul(void* SK_RESTRICT dstRow,
64 const uint8_t* SK_RESTRICT src, 403 const uint8_t* SK_RESTRICT src,
65 int width, int deltaSrc, int, const SkPMC olor[]) { 404 int width, int bitsPerPixel, int,
405 const SkPMColor[], const SkSwizzler::Colo rMasks*,
406 const SkSwizzler::ZeroAlpha, bool*,
407 bool*) {
66 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 408 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
409 int deltaSrc = bitsPerPixel / 8;
67 unsigned alphaMask = 0xFF; 410 unsigned alphaMask = 0xFF;
68 for (int x = 0; x < width; x++) { 411 for (int x = 0; x < width; x++) {
69 unsigned alpha = src[3]; 412 unsigned alpha = src[3];
70 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 413 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
71 src += deltaSrc; 414 src += deltaSrc;
72 alphaMask &= alpha; 415 alphaMask &= alpha;
73 } 416 }
74 return alphaMask != 0xFF; 417 return alphaMask != 0xFF;
75 } 418 }
76 419
77 static bool swizzle_rgba_to_n32_unpremul(void* SK_RESTRICT dstRow, 420 static bool swizzle_rgba_to_n32_unpremul(void* SK_RESTRICT dstRow,
78 const uint8_t* SK_RESTRICT src, 421 const uint8_t* SK_RESTRICT src,
79 int width, int deltaSrc, int, 422 int width, int bitsPerPixel, int,
80 const SkPMColor[]) { 423 const SkPMColor[], const SkSwizzler::Co lorMasks*,
424 const SkSwizzler::ZeroAlpha, bool*,
425 bool*) {
81 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); 426 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
427 int deltaSrc = bitsPerPixel / 8;
82 unsigned alphaMask = 0xFF; 428 unsigned alphaMask = 0xFF;
83 for (int x = 0; x < width; x++) { 429 for (int x = 0; x < width; x++) {
84 unsigned alpha = src[3]; 430 unsigned alpha = src[3];
85 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 431 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
86 src += deltaSrc; 432 src += deltaSrc;
87 alphaMask &= alpha; 433 alphaMask &= alpha;
88 } 434 }
89 return alphaMask != 0xFF; 435 return alphaMask != 0xFF;
90 } 436 }
91 437
92 static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow, 438 static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow,
93 const uint8_t* SK_RESTRICT src, 439 const uint8_t* SK_RESTRICT src,
94 int width, int deltaSrc, int, 440 int width, int bitsPerPixel, int,
95 const SkPMColor[]) { 441 const SkPMColor[],
442 const SkSwizzler::ColorMasks*,
443 const SkSwizzler::ZeroAlpha,
444 bool*, bool*) {
96 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 445 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
446 int deltaSrc = bitsPerPixel / 8;
97 unsigned alphaMask = 0xFF; 447 unsigned alphaMask = 0xFF;
98 for (int x = 0; x < width; x++) { 448 for (int x = 0; x < width; x++) {
99 unsigned alpha = src[3]; 449 unsigned alpha = src[3];
100 if (0 != alpha) { 450 if (0 != alpha) {
101 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 451 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
102 } 452 }
103 src += deltaSrc; 453 src += deltaSrc;
104 alphaMask &= alpha; 454 alphaMask &= alpha;
105 } 455 }
106 return alphaMask != 0xFF; 456 return alphaMask != 0xFF;
107 } 457 }
108 458
109 /** 459 /**
110 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. 460 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes.
111 This would be fine for drawing normally, but not for drawing with transfer m odes. Being 461 This would be fine for drawing normally, but not for drawing with transfer m odes. Being
112 honest means we can draw correctly with transfer modes, with the cost of not being able 462 honest means we can draw correctly with transfer modes, with the cost of not being able
113 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we 463 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we
114 decide whether to switch to unpremul default. 464 decide whether to switch to unpremul default.
115 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, 465 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
116 const uint8_t* SK_RESTRICT src, 466 const uint8_t* SK_RESTRICT src,
117 int width, int deltaSrc, int, 467 int width, int bitsPerPixel,
118 const SkPMColor[]) { 468 const SkPMColor[]) {
119 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 469 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
120 unsigned alphaMask = 0xFF; 470 unsigned alphaMask = 0xFF;
121 for (int x = 0; x < width; x++) { 471 for (int x = 0; x < width; x++) {
122 unsigned alpha = src[3]; 472 unsigned alpha = src[3];
123 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible 473 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible
124 // the color components are not zero, but we skip them anyway, meaning t hey'll remain 474 // the color components are not zero, but we skip them anyway, meaning t hey'll remain
125 // zero (implied by the request to skip zeroes). 475 // zero (implied by the request to skip zeroes).
126 if (0 != alpha) { 476 if (0 != alpha) {
127 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 477 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
128 } 478 }
129 src += deltaSrc; 479 src += deltaSrc;
130 alphaMask &= alpha; 480 alphaMask &= alpha;
131 } 481 }
132 return alphaMask != 0xFF; 482 return alphaMask != 0xFF;
133 } 483 }
134 */ 484 */
135 485
136 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor * ctable, 486 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
487 const SkPMColor* ctable,
137 const SkImageInfo& info, void* dst, 488 const SkImageInfo& info, void* dst,
138 size_t dstRowBytes, bool skipZeroes) { 489 size_t dstRowBytes, bool skipZeroes,
139 if (info.colorType() == kUnknown_SkColorType) { 490 const ColorMasks* bitMasks,
491 const ZeroAlpha zeroAlpha,
492 const RowOrder rowOrder) {
493 if (kUnknown_SkColorType == info.colorType()) {
140 return NULL; 494 return NULL;
141 } 495 }
142 if (info.minRowBytes() > dstRowBytes) { 496 if (info.minRowBytes() > dstRowBytes) {
143 return NULL; 497 return NULL;
144 } 498 }
145 if (kIndex == sc && NULL == ctable) { 499 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
500 && NULL == ctable) {
146 return NULL; 501 return NULL;
147 } 502 }
148 RowProc proc = NULL; 503 RowProc proc = NULL;
149 switch (sc) { 504 switch (sc) {
505 case kIndex1:
506 case kIndex2:
507 case kIndex4:
508 switch (info.colorType()) {
509 case kN32_SkColorType:
510 proc = &swizzle_small_index_to_n32;
511 break;
512 default:
513 break;
514 }
515 break;
150 case kIndex: 516 case kIndex:
151 switch (info.colorType()) { 517 switch (info.colorType()) {
152 case kN32_SkColorType: 518 case kN32_SkColorType:
153 // We assume the color premultiplied ctable (or not) as desi red. 519 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; 520 break;
160
161 default: 521 default:
162 break; 522 break;
163 } 523 }
524 break;
525 case kMask16:
526 switch (info.colorType()) {
527 case kN32_SkColorType:
528 proc = &swizzle_mask16_to_n32;
529 break;
530 default:
531 break;
532 }
533 break;
534 case kMask24:
535 switch (info.colorType()) {
536 case kN32_SkColorType:
537 proc = &swizzle_mask24_to_n32;
538 break;
539 default:
540 break;
541 }
542 break;
543 case kMask32:
544 switch (info.colorType()) {
545 case kN32_SkColorType:
546 proc = &swizzle_mask32_to_n32;
547 break;
548 default:
549 break;
550 }
551 break;
552 case kBGR:
553 case kBGRX:
554 switch (info.colorType()) {
555 case kN32_SkColorType:
556 proc = &swizzle_bgrx_to_n32;
557 break;
558 default:
559 break;
560 }
561 break;
562 case kBGRA:
563 switch (info.colorType()) {
564 case kN32_SkColorType:
565 proc = &swizzle_bgra_to_n32;
566 break;
567 default:
568 break;
569 }
164 break; 570 break;
165 case kRGBX: 571 case kRGBX:
166 // TODO: Support other swizzles. 572 // TODO: Support other swizzles.
167 switch (info.colorType()) { 573 switch (info.colorType()) {
168 case kN32_SkColorType: 574 case kN32_SkColorType:
169 proc = &swizzle_rgbx_to_n32; 575 proc = &swizzle_rgbx_to_n32;
170 break; 576 break;
171 default: 577 default:
172 break; 578 break;
173 } 579 }
174 break; 580 break;
175 case kRGBA: 581 case kRGBA:
176 switch (info.colorType()) { 582 switch (info.colorType()) {
177 case kN32_SkColorType: 583 case kN32_SkColorType:
178 if (info.alphaType() == kUnpremul_SkAlphaType) { 584 if (info.alphaType() == kUnpremul_SkAlphaType) {
179 // Respect skipZeroes? 585 // Respect skipZeroes?
180 proc = &swizzle_rgba_to_n32_unpremul; 586 proc = &swizzle_rgba_to_n32_unpremul;
181 } else { 587 } else {
182 if (skipZeroes) { 588 if (skipZeroes) {
183 proc = &swizzle_rgba_to_n32_premul_skipZ; 589 proc = &swizzle_rgba_to_n32_premul_skipZ;
184 } else { 590 } else {
185 proc = &swizzle_rgba_to_n32_premul; 591 proc = &swizzle_rgba_to_n32_premul;
186 } 592 }
187 } 593 }
188 break; 594 break;
189 default: 595 default:
190 break; 596 break;
191 } 597 }
192 break; 598 break;
599 case kRGB:
600 switch (info.colorType()) {
601 case kN32_SkColorType:
602 proc = &swizzle_rgbx_to_n32;
603 break;
604 default:
605 break;
606 }
607 break;
193 default: 608 default:
194 break; 609 break;
195 } 610 }
196 if (NULL == proc) { 611 if (NULL == proc) {
197 return NULL; 612 return NULL;
198 } 613 }
199 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BytesPerPixel(sc), info, dst, d stRowBytes)); 614 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BitsPerPixel(sc), info, dst,
615 dstRowBytes, bitMasks, zeroAlpha, rowOrder));
200 } 616 }
201 617
202 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcBpp, 618 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
203 const SkImageInfo& info, void* dst, size_t rowBytes) 619 int srcBitsPerPixel, const SkImageInfo& info, void* dst,
620 size_t rowBytes, const ColorMasks* bitMasks,
621 const ZeroAlpha zeroAlpha, const RowOrder rowOrder)
204 : fRowProc(proc) 622 : fRowProc(proc)
205 , fColorTable(ctable) 623 , fColorTable(ctable)
206 , fSrcPixelSize(srcBpp) 624 , fSrcBitsPerPixel(srcBitsPerPixel)
207 , fDstInfo(info) 625 , fDstInfo(info)
208 , fDstRow(dst) 626 , fDstRow(dst)
209 , fDstRowBytes(rowBytes) 627 , fDstRowBytes(rowBytes)
210 , fCurrY(0) 628 , fCurrY(0)
629 , fBitMasks(bitMasks)
630 , fZeroAlpha(zeroAlpha)
631 , fRowOrder(rowOrder)
632 , fSeenNonZeroAlpha(false)
633 , fZeroPrevRows(false)
211 { 634 {
212 } 635 }
213 636
214 bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) { 637 bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
215 SkASSERT(fCurrY < fDstInfo.height()); 638 SkASSERT(fCurrY < fDstInfo.height());
216 const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(), fSrcPixelSize , 639
217 fCurrY, fColorTable); 640 // On the first iteration, if the image is inverted, start at the bottom
641 if (0 == fCurrY && kBottomUp == fRowOrder) {
642 fDstRow = SkTAddOffset<void>(fDstRow,
643 fDstRowBytes * (fDstInfo.height() - 1));
644 }
645
646 // Decode a row
647 const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(),
648 fSrcBitsPerPixel, fCurrY, fColorTable, fBitMasks, fZeroAlpha,
649 &fSeenNonZeroAlpha, &fZeroPrevRows);
650
651 // This flag indicates that we have decoded the image as opaque instead of
652 // transparent, and we just realized that it should have been transparent.
653 // To fix this, we zero the rows that have already been decoded.
654 if (fZeroPrevRows) {
655 SkDebugf("TESTING ZERO ALPHA DECODE\n");
656 void* dstRow;
657 if (kTopDown == fRowOrder) {
658 void* dstStart = SkTAddOffset<void>(fDstRow, -fCurrY*fDstRowBytes);
659 memset(dstStart, 0, fCurrY*fDstRowBytes);
660 } else {
661 void* dstStart = SkTAddOffset<void>(fDstRow, fDstRowBytes);
662 memset(dstStart, 0, fCurrY*fDstRowBytes);
663 }
664 fZeroPrevRows = false;
665 }
666
667 // Move to the next row and return the result
218 fCurrY++; 668 fCurrY++;
219 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes); 669 if (kTopDown == fRowOrder) {
670 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
671 } else {
672 fDstRow = SkTAddOffset<void>(fDstRow, -fDstRowBytes);
673 }
220 return hadAlpha; 674 return hadAlpha;
221 } 675 }
222 676
OLDNEW
« src/codec/SkCodec_libbmp.cpp ('K') | « src/codec/SkSwizzler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698