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

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