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

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: Creation of SkMasks 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 int 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 (int 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.
154 if (skipZeroes) { 250 if (skipZeroes) {
251 proc = &swizzle_index_to_n32;
252 } else {
155 proc = &swizzle_index_to_n32_skipZ; 253 proc = &swizzle_index_to_n32_skipZ;
156 } else {
157 proc = &swizzle_index_to_n32;
158 } 254 }
159 break; 255 break;
160
161 default: 256 default:
162 break; 257 break;
163 } 258 }
259 break;
260 case kBGR:
261 case kBGRX:
262 switch (info.colorType()) {
263 case kN32_SkColorType:
264 proc = &swizzle_bgrx_to_n32;
265 break;
266 default:
267 break;
268 }
269 break;
270 case kBGRA:
271 switch (info.colorType()) {
272 case kN32_SkColorType:
273 proc = &swizzle_bgra_to_n32;
274 break;
275 default:
276 break;
277 }
164 break; 278 break;
165 case kRGBX: 279 case kRGBX:
166 // TODO: Support other swizzles. 280 // TODO: Support other swizzles.
167 switch (info.colorType()) { 281 switch (info.colorType()) {
168 case kN32_SkColorType: 282 case kN32_SkColorType:
169 proc = &swizzle_rgbx_to_n32; 283 proc = &swizzle_rgbx_to_n32;
170 break; 284 break;
171 default: 285 default:
172 break; 286 break;
173 } 287 }
174 break; 288 break;
175 case kRGBA: 289 case kRGBA:
176 switch (info.colorType()) { 290 switch (info.colorType()) {
177 case kN32_SkColorType: 291 case kN32_SkColorType:
178 if (info.alphaType() == kUnpremul_SkAlphaType) { 292 if (info.alphaType() == kUnpremul_SkAlphaType) {
179 // Respect skipZeroes? 293 // Respect skipZeroes?
180 proc = &swizzle_rgba_to_n32_unpremul; 294 proc = &swizzle_rgba_to_n32_unpremul;
181 } else { 295 } else {
182 if (skipZeroes) { 296 if (skipZeroes) {
183 proc = &swizzle_rgba_to_n32_premul_skipZ; 297 proc = &swizzle_rgba_to_n32_premul_skipZ;
184 } else { 298 } else {
185 proc = &swizzle_rgba_to_n32_premul; 299 proc = &swizzle_rgba_to_n32_premul;
186 } 300 }
187 } 301 }
188 break; 302 break;
189 default: 303 default:
190 break; 304 break;
191 } 305 }
192 break; 306 break;
307 case kRGB:
308 switch (info.colorType()) {
309 case kN32_SkColorType:
310 proc = &swizzle_rgbx_to_n32;
311 break;
312 default:
313 break;
314 }
315 break;
193 default: 316 default:
194 break; 317 break;
195 } 318 }
196 if (NULL == proc) { 319 if (NULL == proc) {
197 return NULL; 320 return NULL;
198 } 321 }
199 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BytesPerPixel(sc), info, dst, d stRowBytes)); 322 return SkNEW_ARGS(SkSwizzler, (proc, ctable, BitsPerPixel(sc), info, dst,
323 dstRowBytes));
200 } 324 }
201 325
202 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcBpp, 326 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
203 const SkImageInfo& info, void* dst, size_t rowBytes) 327 int srcBitsPerPixel, const SkImageInfo& info, void* dst,
328 size_t rowBytes)
204 : fRowProc(proc) 329 : fRowProc(proc)
205 , fColorTable(ctable) 330 , fColorTable(ctable)
206 , fSrcPixelSize(srcBpp) 331 , fSrcBitsPerPixel(srcBitsPerPixel)
207 , fDstInfo(info) 332 , fDstInfo(info)
208 , fDstRow(dst) 333 , fDstRow(dst)
209 , fDstRowBytes(rowBytes) 334 , fDstRowBytes(rowBytes)
210 , fCurrY(0) 335 , fCurrY(0)
211 { 336 {
337 SkDEBUGCODE(fSwizzleMode = kUninitialized_SwizzleMode);
212 } 338 }
213 339
214 bool SkSwizzler::next(const uint8_t* SK_RESTRICT src) { 340 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) {
215 SkASSERT(fCurrY < fDstInfo.height()); 341 SkASSERT(0 <= fCurrY && fCurrY < fDstInfo.height());
216 const bool hadAlpha = fRowProc(fDstRow, src, fDstInfo.width(), fSrcPixelSize , 342 SkASSERT(kDesignateRow_SwizzleMode != fSwizzleMode);
217 fCurrY, fColorTable); 343 SkDEBUGCODE(fSwizzleMode = kConsecutive_SwizzleMode);
218 fCurrY++; 344
345 // Decode a row
346 const ResultAlpha result = fRowProc(fDstRow, src, fDstInfo.width(),
347 fSrcBitsPerPixel, fCurrY, fColorTable);
348
349 // Move to the next row and return the result
219 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes); 350 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes);
220 return hadAlpha; 351 return result;
221 } 352 }
353
354 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src,
355 int y) {
356 SkASSERT(0 <= y && y < fDstInfo.height());
357 SkASSERT(kConsecutive_SwizzleMode != fSwizzleMode);
358 SkDEBUGCODE(fSwizzleMode = kDesignateRow_SwizzleMode);
359
360 // Choose the row
361 void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes);
362
363 // Decode the row
364 return fRowProc(row, src, fDstInfo.width(), fSrcBitsPerPixel, fCurrY,
365 fColorTable);
366 }
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