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

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