blob: 944042d1abd1e084c8c0049e3c0060700abed843 [file] [log] [blame]
msarett74114382015-03-16 11:55:18 -07001/*
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 "SkCodecPriv.h"
9#include "SkColorPriv.h"
10#include "SkMaskSwizzler.h"
11
msaretteed039b2015-03-18 11:11:19 -070012static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -070013 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
14
15 // Use the masks to decode to the destination
16 uint16_t* srcPtr = (uint16_t*) srcRow;
17 SkPMColor* dstPtr = (SkPMColor*) dstRow;
18 for (int i = 0; i < width; i++) {
19 uint16_t p = srcPtr[i];
20 uint8_t red = masks->getRed(p);
21 uint8_t green = masks->getGreen(p);
22 uint8_t blue = masks->getBlue(p);
23 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
24 }
25 return SkSwizzler::kOpaque_ResultAlpha;
26}
27
msaretteed039b2015-03-18 11:11:19 -070028static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -070029 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
30
31 // Use the masks to decode to the destination
32 uint16_t* srcPtr = (uint16_t*) srcRow;
33 SkPMColor* dstPtr = (SkPMColor*) dstRow;
34 INIT_RESULT_ALPHA;
35 for (int i = 0; i < width; i++) {
36 uint16_t p = srcPtr[i];
37 uint8_t red = masks->getRed(p);
38 uint8_t green = masks->getGreen(p);
39 uint8_t blue = masks->getBlue(p);
40 uint8_t alpha = masks->getAlpha(p);
41 UPDATE_RESULT_ALPHA(alpha);
42 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
43 }
44 return COMPUTE_RESULT_ALPHA;
45}
46
msaretteed039b2015-03-18 11:11:19 -070047static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_premul(
48 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
49
50 // Use the masks to decode to the destination
51 uint16_t* srcPtr = (uint16_t*) srcRow;
52 SkPMColor* dstPtr = (SkPMColor*) dstRow;
53 INIT_RESULT_ALPHA;
54 for (int i = 0; i < width; i++) {
55 uint16_t p = srcPtr[i];
56 uint8_t red = masks->getRed(p);
57 uint8_t green = masks->getGreen(p);
58 uint8_t blue = masks->getBlue(p);
59 uint8_t alpha = masks->getAlpha(p);
60 UPDATE_RESULT_ALPHA(alpha);
61 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
62 }
63 return COMPUTE_RESULT_ALPHA;
64}
65
66static SkSwizzler::ResultAlpha swizzle_mask16_to_565(
67 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
68
69 // Use the masks to decode to the destination
70 uint16_t* srcPtr = (uint16_t*) srcRow;
71 uint16_t* dstPtr = (uint16_t*) dstRow;
72 for (int i = 0; i < width; i++) {
73 uint16_t p = srcPtr[i];
74 uint8_t red = masks->getRed(p);
75 uint8_t green = masks->getGreen(p);
76 uint8_t blue = masks->getBlue(p);
77 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
78 }
79 return SkSwizzler::kOpaque_ResultAlpha;
80}
81
82static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -070083 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
84
85 // Use the masks to decode to the destination
86 SkPMColor* dstPtr = (SkPMColor*) dstRow;
87 for (int i = 0; i < 3*width; i += 3) {
88 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
89 uint8_t red = masks->getRed(p);
90 uint8_t green = masks->getGreen(p);
91 uint8_t blue = masks->getBlue(p);
92 dstPtr[i/3] = SkPackARGB32NoCheck(0xFF, red, green, blue);
93 }
94 return SkSwizzler::kOpaque_ResultAlpha;
95}
96
msaretteed039b2015-03-18 11:11:19 -070097static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -070098 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
99
100 // Use the masks to decode to the destination
101 SkPMColor* dstPtr = (SkPMColor*) dstRow;
102 INIT_RESULT_ALPHA;
103 for (int i = 0; i < 3*width; i += 3) {
104 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
105 uint8_t red = masks->getRed(p);
106 uint8_t green = masks->getGreen(p);
107 uint8_t blue = masks->getBlue(p);
108 uint8_t alpha = masks->getAlpha(p);
109 UPDATE_RESULT_ALPHA(alpha);
110 dstPtr[i/3] = SkPackARGB32NoCheck(alpha, red, green, blue);
111 }
112 return COMPUTE_RESULT_ALPHA;
113}
114
msaretteed039b2015-03-18 11:11:19 -0700115static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_premul(
116 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
117
118 // Use the masks to decode to the destination
119 SkPMColor* dstPtr = (SkPMColor*) dstRow;
120 INIT_RESULT_ALPHA;
121 for (int i = 0; i < 3*width; i += 3) {
122 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
123 uint8_t red = masks->getRed(p);
124 uint8_t green = masks->getGreen(p);
125 uint8_t blue = masks->getBlue(p);
126 uint8_t alpha = masks->getAlpha(p);
127 UPDATE_RESULT_ALPHA(alpha);
128 dstPtr[i/3] = SkPreMultiplyARGB(alpha, red, green, blue);
129 }
130 return COMPUTE_RESULT_ALPHA;
131}
132
133static SkSwizzler::ResultAlpha swizzle_mask24_to_565(
134 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
135
136 // Use the masks to decode to the destination
137 uint16_t* dstPtr = (uint16_t*) dstRow;
138 for (int i = 0; i < 3*width; i += 3) {
139 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
140 uint8_t red = masks->getRed(p);
141 uint8_t green = masks->getGreen(p);
142 uint8_t blue = masks->getBlue(p);
143 dstPtr[i/3] = SkPack888ToRGB16(red, green, blue);
144 }
145 return SkSwizzler::kOpaque_ResultAlpha;
146}
147
148static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -0700149 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
150
151 // Use the masks to decode to the destination
152 uint32_t* srcPtr = (uint32_t*) srcRow;
153 SkPMColor* dstPtr = (SkPMColor*) dstRow;
154 for (int i = 0; i < width; i++) {
155 uint32_t p = srcPtr[i];
156 uint8_t red = masks->getRed(p);
157 uint8_t green = masks->getGreen(p);
158 uint8_t blue = masks->getBlue(p);
159 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
160 }
161 return SkSwizzler::kOpaque_ResultAlpha;
162}
163
msaretteed039b2015-03-18 11:11:19 -0700164static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -0700165 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
166
167 // Use the masks to decode to the destination
168 uint32_t* srcPtr = (uint32_t*) srcRow;
169 SkPMColor* dstPtr = (SkPMColor*) dstRow;
170 INIT_RESULT_ALPHA;
171 for (int i = 0; i < width; i++) {
172 uint32_t p = srcPtr[i];
173 uint8_t red = masks->getRed(p);
174 uint8_t green = masks->getGreen(p);
175 uint8_t blue = masks->getBlue(p);
176 uint8_t alpha = masks->getAlpha(p);
177 UPDATE_RESULT_ALPHA(alpha);
178 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
179 }
180 return COMPUTE_RESULT_ALPHA;
181}
182
msaretteed039b2015-03-18 11:11:19 -0700183static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_premul(
184 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
185
186 // Use the masks to decode to the destination
187 uint32_t* srcPtr = (uint32_t*) srcRow;
188 SkPMColor* dstPtr = (SkPMColor*) dstRow;
189 INIT_RESULT_ALPHA;
190 for (int i = 0; i < width; i++) {
191 uint32_t p = srcPtr[i];
192 uint8_t red = masks->getRed(p);
193 uint8_t green = masks->getGreen(p);
194 uint8_t blue = masks->getBlue(p);
195 uint8_t alpha = masks->getAlpha(p);
196 UPDATE_RESULT_ALPHA(alpha);
197 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
198 }
199 return COMPUTE_RESULT_ALPHA;
200}
201
202static SkSwizzler::ResultAlpha swizzle_mask32_to_565(
203 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
204
205 // Use the masks to decode to the destination
206 uint32_t* srcPtr = (uint32_t*) srcRow;
207 uint16_t* dstPtr = (uint16_t*) dstRow;
208 for (int i = 0; i < width; i++) {
209 uint32_t p = srcPtr[i];
210 uint8_t red = masks->getRed(p);
211 uint8_t green = masks->getGreen(p);
212 uint8_t blue = masks->getBlue(p);
213 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
214 }
215 return SkSwizzler::kOpaque_ResultAlpha;
216}
217
msarett74114382015-03-16 11:55:18 -0700218/*
219 *
220 * Create a new mask swizzler
221 *
222 */
223SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
msaretteed039b2015-03-18 11:11:19 -0700224 const SkImageInfo& info, void* dst, size_t dstRowBytes, SkMasks* masks,
225 uint32_t bitsPerPixel) {
msarett74114382015-03-16 11:55:18 -0700226
227 // Choose the appropriate row procedure
228 RowProc proc = NULL;
msarett74114382015-03-16 11:55:18 -0700229 switch (bitsPerPixel) {
230 case 16:
msaretteed039b2015-03-18 11:11:19 -0700231 switch (info.colorType()) {
232 case kN32_SkColorType:
233 switch (info.alphaType()) {
234 case kUnpremul_SkAlphaType:
235 proc = &swizzle_mask16_to_n32_unpremul;
236 break;
237 case kPremul_SkAlphaType:
238 proc = &swizzle_mask16_to_n32_premul;
239 break;
240 case kOpaque_SkAlphaType:
241 proc = &swizzle_mask16_to_n32_opaque;
242 break;
243 default:
244 break;
245 }
246 break;
247 case kRGB_565_SkColorType:
248 switch (info.alphaType()) {
249 case kOpaque_SkAlphaType:
250 proc = &swizzle_mask16_to_565;
251 break;
252 default:
253 break;
254 }
255 break;
256 default:
257 break;
msarett74114382015-03-16 11:55:18 -0700258 }
259 break;
260 case 24:
msaretteed039b2015-03-18 11:11:19 -0700261 switch (info.colorType()) {
262 case kN32_SkColorType:
263 switch (info.alphaType()) {
264 case kUnpremul_SkAlphaType:
265 proc = &swizzle_mask24_to_n32_unpremul;
266 break;
267 case kPremul_SkAlphaType:
268 proc = &swizzle_mask24_to_n32_premul;
269 break;
270 case kOpaque_SkAlphaType:
271 proc = &swizzle_mask24_to_n32_opaque;
272 break;
273 default:
274 break;
275 }
276 break;
277 case kRGB_565_SkColorType:
278 switch (info.alphaType()) {
279 case kOpaque_SkAlphaType:
280 proc = &swizzle_mask24_to_565;
281 break;
282 default:
283 break;
284 }
285 break;
286 default:
287 break;
msarett74114382015-03-16 11:55:18 -0700288 }
289 break;
290 case 32:
msaretteed039b2015-03-18 11:11:19 -0700291 switch (info.colorType()) {
292 case kN32_SkColorType:
293 switch (info.alphaType()) {
294 case kUnpremul_SkAlphaType:
295 proc = &swizzle_mask32_to_n32_unpremul;
296 break;
297 case kPremul_SkAlphaType:
298 proc = &swizzle_mask32_to_n32_premul;
299 break;
300 case kOpaque_SkAlphaType:
301 proc = &swizzle_mask32_to_n32_opaque;
302 break;
303 default:
304 break;
305 }
306 break;
307 case kRGB_565_SkColorType:
308 switch (info.alphaType()) {
309 case kOpaque_SkAlphaType:
310 proc = &swizzle_mask32_to_565;
311 break;
312 default:
313 break;
314 }
315 break;
316 default:
317 break;
msarett74114382015-03-16 11:55:18 -0700318 }
319 break;
320 default:
321 SkASSERT(false);
322 return NULL;
323 }
msaretteed039b2015-03-18 11:11:19 -0700324 return SkNEW_ARGS(SkMaskSwizzler, (info, dst, dstRowBytes, masks, proc));
msarett74114382015-03-16 11:55:18 -0700325}
326
327/*
328 *
329 * Constructor for mask swizzler
330 *
331 */
msaretteed039b2015-03-18 11:11:19 -0700332SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, void* dst,
333 size_t dstRowBytes, SkMasks* masks, RowProc proc)
334 : fDstInfo(dstInfo)
335 , fDst(dst)
336 , fDstRowBytes(dstRowBytes)
msarett74114382015-03-16 11:55:18 -0700337 , fMasks(masks)
338 , fRowProc(proc)
339{}
340
341/*
342 *
msaretteed039b2015-03-18 11:11:19 -0700343 * Swizzle the specified row
msarett74114382015-03-16 11:55:18 -0700344 *
345 */
msaretteed039b2015-03-18 11:11:19 -0700346SkSwizzler::ResultAlpha SkMaskSwizzler::next(const uint8_t* SK_RESTRICT src,
347 int y) {
348 // Choose the row
349 void* row = SkTAddOffset<void>(fDst, y*fDstRowBytes);
350
351 // Decode the row
352 return fRowProc(row, src, fDstInfo.width(), fMasks);
msarett74114382015-03-16 11:55:18 -0700353}