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

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: separate swizzler for masks 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 SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
17 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
18 int bitsPerPixel, int y, const SkPMColor ctable[]) {
19
20 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
21 SkPMColor maxAlpha = A32_MASK_IN_PLACE;
22 SkPMColor zeroAlpha = 0;
23 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
24 const uint32_t rowBytes = (width + pixelsPerByte - 1) / pixelsPerByte;
25 const uint8_t mask = (1 << bitsPerPixel) - 1;
26
27 uint32_t x = 0;
28 for (uint32_t byte = 0; byte < rowBytes; byte++) {
29 uint8_t pixelData = src[byte];
30 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
31 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
32 SkPMColor c = ctable[index];
33 dst[x] = c;
34 maxAlpha &= c;
35 zeroAlpha |= c & A32_MASK_IN_PLACE;
36 pixelData <<= bitsPerPixel;
37 x++;
38 }
39 }
40 return SkSwizzler::GetResult(zeroAlpha, maxAlpha >> SK_A32_SHIFT);
41 }
42
43 // kIndex
44
45 static SkSwizzler::ResultAlpha swizzle_index_to_n32(
46 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
47 int bitsPerPixel, int y, const SkPMColor ctable[]) {
19 48
20 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 49 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
21 SkPMColor cc = A32_MASK_IN_PLACE; 50 SkPMColor maxAlpha = A32_MASK_IN_PLACE;
51 SkPMColor zeroAlpha = 0;
22 for (int x = 0; x < width; x++) { 52 for (int x = 0; x < width; x++) {
23 SkPMColor c = ctable[*src]; 53 SkPMColor c = ctable[*src];
24 cc &= c; 54 maxAlpha &= c;
55 zeroAlpha |= c & A32_MASK_IN_PLACE;
25 dst[x] = c; 56 dst[x] = c;
26 src += deltaSrc; 57 src++;
27 } 58 }
28 return cc != A32_MASK_IN_PLACE; 59 return SkSwizzler::GetResult(zeroAlpha, maxAlpha >> SK_A32_SHIFT);
29 } 60 }
30 61
31 static bool swizzle_index_to_n32_skipZ(void* SK_RESTRICT dstRow, 62 static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ(
32 const uint8_t* SK_RESTRICT src, 63 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
33 int width, int deltaSrc, int, 64 int bitsPerPixel, int y, const SkPMColor ctable[]) {
34 const SkPMColor ctable[]) {
35 65
36 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 66 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
37 SkPMColor cc = A32_MASK_IN_PLACE; 67 SkPMColor maxAlpha = A32_MASK_IN_PLACE;
68 SkPMColor zeroAlpha = 0;
38 for (int x = 0; x < width; x++) { 69 for (int x = 0; x < width; x++) {
39 SkPMColor c = ctable[*src]; 70 SkPMColor c = ctable[*src];
40 cc &= c; 71 maxAlpha &= c;
72 zeroAlpha |= c & A32_MASK_IN_PLACE;
41 if (c != 0) { 73 if (c != 0) {
42 dst[x] = c; 74 dst[x] = c;
43 } 75 }
44 src += deltaSrc; 76 src++;
45 } 77 }
46 return cc != A32_MASK_IN_PLACE; 78 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
47 } 79 }
48 80
49 #undef A32_MASK_IN_PLACE 81 #undef A32_MASK_IN_PLACE
50 82
83 static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
84 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
85 int bitsPerPixel, int y, const SkPMColor ctable[]) {
86
87 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
88 int deltaSrc = bitsPerPixel / 8;
89 for (int x = 0; x < width; x++) {
90 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
91 src += deltaSrc;
92 }
93 return SkSwizzler::kOpaque_ResultAlpha;
94 }
95
96 // kBGRA
97
98 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32(
99 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
100 int bitsPerPixel, int y, const SkPMColor ctable[]) {
101
102 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
103 uint8_t maxAlpha = 0xFF;
104 uint8_t zeroAlpha = 0;
105 int deltaSrc = bitsPerPixel / 8;
106 for (uint32_t x = 0; x < width; x++) {
107 uint8_t alpha = src[3];
108 maxAlpha &= alpha;
109 zeroAlpha |= alpha;
110 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
111 src += deltaSrc;
112 }
113 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
114 }
115
51 // n32 116 // n32
52 static bool swizzle_rgbx_to_n32(void* SK_RESTRICT dstRow, 117 static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32(
53 const uint8_t* SK_RESTRICT src, 118 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
54 int width, int deltaSrc, int, const SkPMColor[]) { 119 int bitsPerPixel, int y, const SkPMColor ctable[]) {
120
55 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 121 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
122 int deltaSrc = bitsPerPixel / 8;
56 for (int x = 0; x < width; x++) { 123 for (int x = 0; x < width; x++) {
57 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); 124 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
58 src += deltaSrc; 125 src += deltaSrc;
59 } 126 }
60 return false; 127 return SkSwizzler::kOpaque_ResultAlpha;
61 } 128 }
62 129
63 static bool swizzle_rgba_to_n32_premul(void* SK_RESTRICT dstRow, 130 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul(
64 const uint8_t* SK_RESTRICT src, 131 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
65 int width, int deltaSrc, int, const SkPMC olor[]) { 132 int bitsPerPixel, int y, const SkPMColor ctable[]) {
133
66 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 134 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
67 unsigned alphaMask = 0xFF; 135 int deltaSrc = bitsPerPixel / 8;
136 uint8_t maxAlpha = 0xFF;
137 uint8_t zeroAlpha = 0;
68 for (int x = 0; x < width; x++) { 138 for (int x = 0; x < width; x++) {
69 unsigned alpha = src[3]; 139 unsigned alpha = src[3];
70 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 140 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
71 src += deltaSrc; 141 src += deltaSrc;
72 alphaMask &= alpha; 142 maxAlpha &= alpha;
143 zeroAlpha |= alpha;
73 } 144 }
74 return alphaMask != 0xFF; 145 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
75 } 146 }
76 147
77 static bool swizzle_rgba_to_n32_unpremul(void* SK_RESTRICT dstRow, 148 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul(
78 const uint8_t* SK_RESTRICT src, 149 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
79 int width, int deltaSrc, int, 150 int bitsPerPixel, int y, const SkPMColor ctable[]) {
80 const SkPMColor[]) { 151
81 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); 152 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
82 unsigned alphaMask = 0xFF; 153 int deltaSrc = bitsPerPixel / 8;
154 uint8_t maxAlpha = 0xFF;
155 uint8_t zeroAlpha = 0;
83 for (int x = 0; x < width; x++) { 156 for (int x = 0; x < width; x++) {
84 unsigned alpha = src[3]; 157 unsigned alpha = src[3];
85 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 158 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
86 src += deltaSrc; 159 src += deltaSrc;
87 alphaMask &= alpha; 160 maxAlpha &= alpha;
161 zeroAlpha |= alpha;
88 } 162 }
89 return alphaMask != 0xFF; 163 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
90 } 164 }
91 165
92 static bool swizzle_rgba_to_n32_premul_skipZ(void* SK_RESTRICT dstRow, 166 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
93 const uint8_t* SK_RESTRICT src, 167 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
94 int width, int deltaSrc, int, 168 int bitsPerPixel, int y, const SkPMColor ctable[]) {
95 const SkPMColor[]) { 169
96 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 170 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
97 unsigned alphaMask = 0xFF; 171 int deltaSrc = bitsPerPixel / 8;
172 uint8_t maxAlpha = 0xFF;
173 uint8_t zeroAlpha = 0;
98 for (int x = 0; x < width; x++) { 174 for (int x = 0; x < width; x++) {
99 unsigned alpha = src[3]; 175 unsigned alpha = src[3];
100 if (0 != alpha) { 176 if (0 != alpha) {
101 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 177 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
102 } 178 }
103 src += deltaSrc; 179 src += deltaSrc;
104 alphaMask &= alpha; 180 maxAlpha &= alpha;
181 zeroAlpha |= alpha;
105 } 182 }
106 return alphaMask != 0xFF; 183 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
107 } 184 }
108 185
109 /** 186 /**
110 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. 187 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 188 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 189 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 190 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. 191 decide whether to switch to unpremul default.
115 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, 192 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
116 const uint8_t* SK_RESTRICT src, 193 const uint8_t* SK_RESTRICT src,
117 int width, int deltaSrc, int, 194 int width, int bitsPerPixel,
118 const SkPMColor[]) { 195 const SkPMColor[]) {
119 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 196 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
120 unsigned alphaMask = 0xFF; 197 unsigned alphaMask = 0xFF;
121 for (int x = 0; x < width; x++) { 198 for (int x = 0; x < width; x++) {
122 unsigned alpha = src[3]; 199 unsigned alpha = src[3];
123 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible 200 // 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 201 // 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). 202 // zero (implied by the request to skip zeroes).
126 if (0 != alpha) { 203 if (0 != alpha) {
127 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 204 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
128 } 205 }
129 src += deltaSrc; 206 src += deltaSrc;
130 alphaMask &= alpha; 207 alphaMask &= alpha;
131 } 208 }
132 return alphaMask != 0xFF; 209 return alphaMask != 0xFF;
133 } 210 }
134 */ 211 */
135 212
136 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, const SkPMColor * ctable, 213 SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha,
214 uint8_t maxAlpha) {
215 return (maxAlpha == 0xFF) ? SkSwizzler::kOpaque_ResultAlpha :
216 ((zeroAlpha == 0) ? SkSwizzler::kTransparent_ResultAlpha :
217 SkSwizzler::kNeither_ResultAlpha);
218 }
219
220 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
221 const SkPMColor* ctable,
137 const SkImageInfo& info, void* dst, 222 const SkImageInfo& info, void* dst,
138 size_t dstRowBytes, bool skipZeroes) { 223 size_t dstRowBytes, bool skipZeroes) {
139 if (info.colorType() == kUnknown_SkColorType) { 224 if (kUnknown_SkColorType == info.colorType()) {
140 return NULL; 225 return NULL;
141 } 226 }
142 if (info.minRowBytes() > dstRowBytes) { 227 if (info.minRowBytes() > dstRowBytes) {
143 return NULL; 228 return NULL;
144 } 229 }
145 if (kIndex == sc && NULL == ctable) { 230 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
231 && NULL == ctable) {
146 return NULL; 232 return NULL;
147 } 233 }
148 RowProc proc = NULL; 234 RowProc proc = NULL;
149 switch (sc) { 235 switch (sc) {
236 case kIndex1:
237 case kIndex2:
238 case kIndex4:
239 switch (info.colorType()) {
240 case kN32_SkColorType:
241 proc = &swizzle_small_index_to_n32;
242 break;
243 default:
244 break;
245 }
246 break;
150 case kIndex: 247 case kIndex:
151 switch (info.colorType()) { 248 switch (info.colorType()) {
152 case kN32_SkColorType: 249 case kN32_SkColorType:
153 // We assume the color premultiplied ctable (or not) as desi red. 250 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; 251 break;
160
161 default: 252 default:
162 break; 253 break;
163 } 254 }
255 break;
256 case kBGR:
257 case kBGRX:
258 switch (info.colorType()) {
259 case kN32_SkColorType:
260 proc = &swizzle_bgrx_to_n32;
261 break;
262 default:
263 break;
264 }
265 break;
266 case kBGRA:
267 switch (info.colorType()) {
268 case kN32_SkColorType:
269 proc = &swizzle_bgra_to_n32;
270 break;
271 default:
272 break;
273 }
164 break; 274 break;
165 case kRGBX: 275 case kRGBX:
166 // TODO: Support other swizzles. 276 // TODO: Support other swizzles.
167 switch (info.colorType()) { 277 switch (info.colorType()) {
168 case kN32_SkColorType: 278 case kN32_SkColorType:
169 proc = &swizzle_rgbx_to_n32; 279 proc = &swizzle_rgbx_to_n32;
170 break; 280 break;
171 default: 281 default:
172 break; 282 break;
173 } 283 }
174 break; 284 break;
175 case kRGBA: 285 case kRGBA:
176 switch (info.colorType()) { 286 switch (info.colorType()) {
177 case kN32_SkColorType: 287 case kN32_SkColorType:
178 if (info.alphaType() == kUnpremul_SkAlphaType) { 288 if (info.alphaType() == kUnpremul_SkAlphaType) {
179 // Respect skipZeroes? 289 // Respect skipZeroes?
180 proc = &swizzle_rgba_to_n32_unpremul; 290 proc = &swizzle_rgba_to_n32_unpremul;
181 } else { 291 } else {
182 if (skipZeroes) { 292 if (skipZeroes) {
183 proc = &swizzle_rgba_to_n32_premul_skipZ; 293 proc = &swizzle_rgba_to_n32_premul_skipZ;
184 } else { 294 } else {
185 proc = &swizzle_rgba_to_n32_premul; 295 proc = &swizzle_rgba_to_n32_premul;
186 } 296 }
187 } 297 }
188 break; 298 break;
189 default: 299 default:
190 break; 300 break;
191 } 301 }
192 break; 302 break;
303 case kRGB:
304 switch (info.colorType()) {
305 case kN32_SkColorType:
306 proc = &swizzle_rgbx_to_n32;
307 break;
308 default:
309 break;
310 }
311 break;
193 default: 312 default:
194 break; 313 break;
195 } 314 }
196 if (NULL == proc) { 315 if (NULL == proc) {
197 return NULL; 316 return NULL;
198 } 317 }
199 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BytesPerPixel(sc), info, dst, d stRowBytes)); 318 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BitsPerPixel(sc), info, dst,
319 dstRowBytes));
200 } 320 }
201 321
202 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcBpp, 322 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
203 const SkImageInfo& info, void* dst, size_t rowBytes) 323 int srcBitsPerPixel, const SkImageInfo& info, void* dst,
324 size_t rowBytes)
204 : fRowProc(proc) 325 : fRowProc(proc)
205 , fColorTable(ctable) 326 , fColorTable(ctable)
206 , fSrcPixelSize(srcBpp) 327 , fSrcBitsPerPixel(srcBitsPerPixel)
207 , fDstInfo(info) 328 , fDstInfo(info)
208 , fDstRow(dst) 329 , fDstRow(dst)
209 , fDstRowBytes(rowBytes) 330 , fDstRowBytes(rowBytes)
210 , fCurrY(0) 331 , fCurrY(0)
211 { 332 {
212 } 333 }
213 334
214 bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) { 335 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
215 SkASSERT(fCurrY < fDstInfo.height()); 336 SkASSERT(fCurrY < fDstInfo.height());
216 const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(), fSrcPixelSize , 337
217 fCurrY, fColorTable); 338 // Decode a row
218 fCurrY++; 339 const ResultAlpha result = fRowProc(fDstRow, src, fDstInfo.width(),
340 fSrcBitsPerPixel, fCurrY, fColorTable);
341
342 // Move to the next row and return the result
219 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes); 343 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
220 return hadAlpha; 344 return result;
221 } 345 }
222 346
347 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src,
348 uint32_t y) {
349 SkASSERT(y < fDstInfo.height());
350
351 // Choose the row
352 void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes);
353
354 // Decode the row
355 return fRowProc(row, src, fDstInfo.width(), fSrcBitsPerPixel, fCurrY,
356 fColorTable);
357 }
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