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

Side by Side Diff: src/codec/SkMaskSwizzler.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
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkColorPriv.h"
9 #include "SkMaskSwizzler.h"
10
11 /*
12 *
13 * Used to convert 1-7 bit color components into 8-bit color components
14 *
15 */
16 const static uint8_t n_bit_to_8_bit_lookup_table[] = {
17 // 1 bit
18 0, 255,
19 // 2 bits
20 0, 85, 170, 255,
21 // 3 bits
22 0, 36, 73, 109, 146, 182, 219, 255,
23 // 4 bits
24 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
25 // 5 bits
26 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
27 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
28 // 6 bits
29 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
30 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
31 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
32 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
33 // 7 bits
34 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
35 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
36 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
37 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
38 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
39 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
40 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
41 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
42 };
43
44 /*
45 *
46 * Convert an n bit component to an 8-bit component
47 *
48 */
49 static uint8_t convert_to_8(uint32_t component, uint32_t n) {
50 if (0 == n) {
51 return 0;
52 } else if (8 > n) {
53 return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component];
54 } else {
55 SkASSERT(8 == n);
56 return component;
57 }
58 }
59
60 /*
61 *
62 * Get the color component
63 *
64 */
65 static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift,
66 uint32_t size) {
67 return convert_to_8((pixel & mask) >> shift, size);
68 }
69
70 /*
71 *
72 * Row procedure for masked color components with 16 bits per pixel
73 *
74 */
75 static SkSwizzler::ResultAlpha swizzle_mask16_to_n32(
76 void* dstRow, const uint8_t* srcRow, int width,
77 const SkMaskSwizzler::Masks& masks) {
78
79 // Use the masks to decode to the destination
80 uint16_t* srcPtr = (uint16_t*) srcRow;
81 SkPMColor* dstPtr = (SkPMColor*) dstRow;
82 for (uint32_t i = 0; i < width; i++) {
83 uint16_t p = srcPtr[i];
84 uint8_t red = get_comp(p, masks.red.mask, masks.red.shift,
scroggo 2015/03/11 14:23:10 get_comp is a step in the right direction. What i
msarett 2015/03/11 18:53:05 Agreed this is done.
85 masks.red.size);
86 uint8_t green = get_comp(p, masks.green.mask, masks.green.shift,
87 masks.green.size);
88 uint8_t blue = get_comp(p, masks.blue.mask, masks.blue.shift,
89 masks.blue.size);
90 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
91 }
92 return SkSwizzler::kOpaque_ResultAlpha;
93 }
94
95 /*
96 *
97 * Row procedure for masked color components with 16 bits per pixel with alpha
98 *
99 */
100 static SkSwizzler::ResultAlpha swizzle_mask16_alpha_to_n32(
101 void* dstRow, const uint8_t* srcRow, int width,
102 const SkMaskSwizzler::Masks& masks) {
103
104 // Use the masks to decode to the destination
105 uint16_t* srcPtr = (uint16_t*) srcRow;
106 SkPMColor* dstPtr = (SkPMColor*) dstRow;
107 uint8_t zeroAlpha = 0;
108 uint8_t maxAlpha = 0xFF;
109 for (uint32_t i = 0; i < width; i++) {
110 uint16_t p = srcPtr[i];
111 uint8_t red = get_comp(p, masks.red.mask, masks.red.shift,
112 masks.red.size);
113 uint8_t green = get_comp(p, masks.green.mask, masks.green.shift,
114 masks.green.size);
115 uint8_t blue = get_comp(p, masks.blue.mask, masks.blue.shift,
116 masks.blue.size);
117 uint8_t alpha = get_comp(p, masks.alpha.mask, masks.alpha.shift,
118 masks.alpha.size);
119 zeroAlpha |= alpha;
120 maxAlpha &= alpha;
121 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
122 }
123 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
124 }
125
126 /*
127 *
128 * Row procedure for masked color components with 24 bits per pixel
129 *
130 */
131 static SkSwizzler::ResultAlpha swizzle_mask24_to_n32(
132 void* dstRow, const uint8_t* srcRow, int width,
133 const SkMaskSwizzler::Masks& masks) {
134
135 // Use the masks to decode to the destination
136 SkPMColor* dstPtr = (SkPMColor*) dstRow;
137 for (uint32_t i = 0; i < 3*width; i += 3) {
138 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
139 uint8_t red = get_comp(p, masks.red.mask, masks.red.shift,
140 masks.red.size);
141 uint8_t green = get_comp(p, masks.green.mask, masks.green.shift,
142 masks.green.size);
143 uint8_t blue = get_comp(p, masks.blue.mask, masks.blue.shift,
144 masks.blue.size);
145 dstPtr[i/3] = SkPackARGB32NoCheck(0xFF, red, green, blue);
146 }
147 return SkSwizzler::kOpaque_ResultAlpha;
148 }
149
150 /*
151 *
152 * Row procedure for masked color components with 24 bits per pixel with alpha
153 *
154 */
155 static SkSwizzler::ResultAlpha swizzle_mask24_alpha_to_n32(
156 void* dstRow, const uint8_t* srcRow, int width,
157 const SkMaskSwizzler::Masks& masks) {
158
159 // Use the masks to decode to the destination
160 SkPMColor* dstPtr = (SkPMColor*) dstRow;
161 uint8_t zeroAlpha = 0;
162 uint8_t maxAlpha = 0xFF;
163 for (uint32_t i = 0; i < 3*width; i += 3) {
164 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
165 uint8_t red = get_comp(p, masks.red.mask, masks.red.shift,
166 masks.red.size);
167 uint8_t green = get_comp(p, masks.green.mask, masks.green.shift,
168 masks.green.size);
169 uint8_t blue = get_comp(p, masks.blue.mask, masks.blue.shift,
170 masks.blue.size);
171 uint8_t alpha = get_comp(p, masks.alpha.mask, masks.alpha.shift,
172 masks.alpha.size);
173 zeroAlpha |= alpha;
174 maxAlpha &= alpha;
175 dstPtr[i/3] = SkPackARGB32NoCheck(alpha, red, green, blue);
176 }
177 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
178 }
179
180 /*
181 *
182 * Row procedure for masked color components with 32 bits per pixel
183 *
184 */
185 static SkSwizzler::ResultAlpha swizzle_mask32_to_n32(
186 void* dstRow, const uint8_t* srcRow, int width,
187 const SkMaskSwizzler::Masks& masks) {
188
189 // Use the masks to decode to the destination
190 uint32_t* srcPtr = (uint32_t*) srcRow;
191 SkPMColor* dstPtr = (SkPMColor*) dstRow;
192 for (uint32_t i = 0; i < width; i++) {
193 uint32_t p = srcPtr[i];
194 uint8_t red = get_comp(p, masks.red.mask, masks.red.shift,
195 masks.red.size);
196 uint8_t green = get_comp(p, masks.green.mask, masks.green.shift,
197 masks.green.size);
198 uint8_t blue = get_comp(p, masks.blue.mask, masks.blue.shift,
199 masks.blue.size);
200 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
201 }
202 return SkSwizzler::kOpaque_ResultAlpha;
203 }
204
205 /*
206 *
207 * Row procedure for masked color components with 32 bits per pixel
208 *
209 */
210 static SkSwizzler::ResultAlpha swizzle_mask32_alpha_to_n32(
211 void* dstRow, const uint8_t* srcRow, int width,
212 const SkMaskSwizzler::Masks& masks) {
213
214 // Use the masks to decode to the destination
215 uint32_t* srcPtr = (uint32_t*) srcRow;
216 SkPMColor* dstPtr = (SkPMColor*) dstRow;
217 uint8_t zeroAlpha = 0;
218 uint8_t maxAlpha = 0xFF;
219 for (uint32_t i = 0; i < width; i++) {
220 uint32_t p = srcPtr[i];
221 uint8_t red = get_comp(p, masks.red.mask, masks.red.shift,
222 masks.red.size);
223 uint8_t green = get_comp(p, masks.green.mask, masks.green.shift,
224 masks.green.size);
225 uint8_t blue = get_comp(p, masks.blue.mask, masks.blue.shift,
226 masks.blue.size);
227 uint8_t alpha = get_comp(p, masks.alpha.mask, masks.alpha.shift,
228 masks.alpha.size);
229 zeroAlpha |= alpha;
230 maxAlpha &= alpha;
231 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
232 }
233 return SkSwizzler::GetResult(zeroAlpha, maxAlpha);
234 }
235
236 /*
237 *
238 * Process an input mask to obtain the necessary information
239 *
240 */
241 const SkMaskSwizzler::MaskInfo& SkMaskSwizzler::ProcessMask(uint32_t mask,
242 uint32_t bpp) {
243 // Trim the masks to the allowed number of bits
244 if (bpp < 32) {
245 mask &= (1 << bpp) - 1;
246 }
247
248 // Determine properties of the mask
249 uint32_t tempMask = mask;
250 uint32_t shift = 0;
251 uint32_t size = 0;
252 if (tempMask != 0) {
253 // Count trailing zeros on masks
254 for (; (tempMask & 1) == 0; tempMask >>= 1) {
255 shift++;
256 }
257 // Count the size of the mask
258 for (; tempMask & 1; tempMask >>= 1) {
259 size++;
260 }
261 // Truncate masks greater than 8 bits
262 if (size > 8) {
263 shift += size - 8;
264 size = 8;
265 }
266 }
267
268 // Save the calculated values
269 const MaskInfo info = { mask, shift, size };
270 return info;
271 }
272
273 /*
274 *
275 * Create a new mask swizzler
276 *
277 */
278 SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
279 const SkImageInfo& imageInfo, InputMasks input, uint32_t bitsPerPixel) {
280 // Process input masks
281 const MaskInfo red = ProcessMask(input.red, bitsPerPixel);
282 const MaskInfo green = ProcessMask(input.green, bitsPerPixel);
283 const MaskInfo blue = ProcessMask(input.blue, bitsPerPixel);
284 const MaskInfo alpha = ProcessMask(input.alpha, bitsPerPixel);
285 const Masks masks = { red, green, blue, alpha };
286
287 // Choose the appropriate row procedure
288 RowProc proc = NULL;
289 switch (bitsPerPixel) {
290 case 16:
291 if (masks.alpha.mask == 0) {
292 proc = &swizzle_mask16_to_n32;
293 } else {
294 proc = &swizzle_mask16_alpha_to_n32;
295 }
296 break;
297 case 24:
298 if (masks.alpha.mask == 0) {
299 proc = &swizzle_mask24_to_n32;
300 } else {
301 proc = &swizzle_mask24_alpha_to_n32;
302 }
303 break;
304 case 32:
305 if (masks.alpha.mask == 0) {
306 proc = &swizzle_mask32_to_n32;
307 } else {
308 proc = &swizzle_mask32_alpha_to_n32;
309 }
310 break;
311 default:
312 SkASSERT(false);
313 return NULL;
314 }
315 return SkNEW_ARGS(SkMaskSwizzler, (imageInfo, masks, proc));
316 }
317
318 /*
319 *
320 * Constructor for mask swizzler
321 *
322 */
323 SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& imageInfo, const Masks& masks,
324 RowProc proc)
325 : fImageInfo(imageInfo)
326 , fMasks(masks)
327 , fRowProc(proc)
328 {}
329
330 /*
331 *
332 * Swizzle the next row
333 *
334 */
335 SkSwizzler::ResultAlpha SkMaskSwizzler::next(void* dst,
336 const uint8_t* src) {
337 return fRowProc(dst, src, fImageInfo.width(), fMasks);
338 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698