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

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