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

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