blob: 58be0c67af441660664b5e25466d6a205b04d92c [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
scroggocc2feb12015-08-14 08:32:46 -070066// TODO (msarett): We have promoted a two byte per pixel image to 8888, only to
67// convert it back to 565. Instead, we should swizzle to 565 directly.
68static SkSwizzler::ResultAlpha swizzle_mask16_to_565(
69 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
70
71 // Use the masks to decode to the destination
72 uint16_t* srcPtr = (uint16_t*) srcRow;
73 uint16_t* dstPtr = (uint16_t*) dstRow;
74 for (int i = 0; i < width; i++) {
75 uint16_t p = srcPtr[i];
76 uint8_t red = masks->getRed(p);
77 uint8_t green = masks->getGreen(p);
78 uint8_t blue = masks->getBlue(p);
79 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
80 }
81 return SkSwizzler::kOpaque_ResultAlpha;
82}
83
msaretteed039b2015-03-18 11:11:19 -070084static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -070085 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
86
87 // Use the masks to decode to the destination
88 SkPMColor* dstPtr = (SkPMColor*) dstRow;
89 for (int i = 0; i < 3*width; i += 3) {
90 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
91 uint8_t red = masks->getRed(p);
92 uint8_t green = masks->getGreen(p);
93 uint8_t blue = masks->getBlue(p);
94 dstPtr[i/3] = SkPackARGB32NoCheck(0xFF, red, green, blue);
95 }
96 return SkSwizzler::kOpaque_ResultAlpha;
97}
98
msaretteed039b2015-03-18 11:11:19 -070099static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -0700100 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
101
102 // Use the masks to decode to the destination
103 SkPMColor* dstPtr = (SkPMColor*) dstRow;
104 INIT_RESULT_ALPHA;
105 for (int i = 0; i < 3*width; i += 3) {
106 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
107 uint8_t red = masks->getRed(p);
108 uint8_t green = masks->getGreen(p);
109 uint8_t blue = masks->getBlue(p);
110 uint8_t alpha = masks->getAlpha(p);
111 UPDATE_RESULT_ALPHA(alpha);
112 dstPtr[i/3] = SkPackARGB32NoCheck(alpha, red, green, blue);
113 }
114 return COMPUTE_RESULT_ALPHA;
115}
116
msaretteed039b2015-03-18 11:11:19 -0700117static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_premul(
118 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
119
120 // Use the masks to decode to the destination
121 SkPMColor* dstPtr = (SkPMColor*) dstRow;
122 INIT_RESULT_ALPHA;
123 for (int i = 0; i < 3*width; i += 3) {
124 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
125 uint8_t red = masks->getRed(p);
126 uint8_t green = masks->getGreen(p);
127 uint8_t blue = masks->getBlue(p);
128 uint8_t alpha = masks->getAlpha(p);
129 UPDATE_RESULT_ALPHA(alpha);
130 dstPtr[i/3] = SkPreMultiplyARGB(alpha, red, green, blue);
131 }
132 return COMPUTE_RESULT_ALPHA;
133}
134
scroggocc2feb12015-08-14 08:32:46 -0700135static SkSwizzler::ResultAlpha swizzle_mask24_to_565(
136 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
137
138 // Use the masks to decode to the destination
139 uint16_t* dstPtr = (uint16_t*) dstRow;
140 for (int i = 0; i < 3*width; i += 3) {
141 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
142 uint8_t red = masks->getRed(p);
143 uint8_t green = masks->getGreen(p);
144 uint8_t blue = masks->getBlue(p);
145 dstPtr[i/3] = SkPack888ToRGB16(red, green, blue);
146 }
147 return SkSwizzler::kOpaque_ResultAlpha;
148}
149
msaretteed039b2015-03-18 11:11:19 -0700150static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -0700151 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
152
153 // Use the masks to decode to the destination
154 uint32_t* srcPtr = (uint32_t*) srcRow;
155 SkPMColor* dstPtr = (SkPMColor*) dstRow;
156 for (int i = 0; i < width; i++) {
157 uint32_t p = srcPtr[i];
158 uint8_t red = masks->getRed(p);
159 uint8_t green = masks->getGreen(p);
160 uint8_t blue = masks->getBlue(p);
161 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
162 }
163 return SkSwizzler::kOpaque_ResultAlpha;
164}
165
msaretteed039b2015-03-18 11:11:19 -0700166static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -0700167 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
168
169 // Use the masks to decode to the destination
170 uint32_t* srcPtr = (uint32_t*) srcRow;
171 SkPMColor* dstPtr = (SkPMColor*) dstRow;
172 INIT_RESULT_ALPHA;
173 for (int i = 0; i < width; i++) {
174 uint32_t p = srcPtr[i];
175 uint8_t red = masks->getRed(p);
176 uint8_t green = masks->getGreen(p);
177 uint8_t blue = masks->getBlue(p);
178 uint8_t alpha = masks->getAlpha(p);
179 UPDATE_RESULT_ALPHA(alpha);
180 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
181 }
182 return COMPUTE_RESULT_ALPHA;
183}
184
msaretteed039b2015-03-18 11:11:19 -0700185static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_premul(
186 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
187
188 // Use the masks to decode to the destination
189 uint32_t* srcPtr = (uint32_t*) srcRow;
190 SkPMColor* dstPtr = (SkPMColor*) dstRow;
191 INIT_RESULT_ALPHA;
192 for (int i = 0; i < width; i++) {
193 uint32_t p = srcPtr[i];
194 uint8_t red = masks->getRed(p);
195 uint8_t green = masks->getGreen(p);
196 uint8_t blue = masks->getBlue(p);
197 uint8_t alpha = masks->getAlpha(p);
198 UPDATE_RESULT_ALPHA(alpha);
199 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
200 }
201 return COMPUTE_RESULT_ALPHA;
202}
203
scroggocc2feb12015-08-14 08:32:46 -0700204static SkSwizzler::ResultAlpha swizzle_mask32_to_565(
205 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
206 // Use the masks to decode to the destination
207 uint32_t* srcPtr = (uint32_t*) srcRow;
208 uint16_t* dstPtr = (uint16_t*) dstRow;
209 for (int i = 0; i < width; i++) {
210 uint32_t p = srcPtr[i];
211 uint8_t red = masks->getRed(p);
212 uint8_t green = masks->getGreen(p);
213 uint8_t blue = masks->getBlue(p);
214 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
215 }
216 return SkSwizzler::kOpaque_ResultAlpha;
217}
218
msarett74114382015-03-16 11:55:18 -0700219/*
220 *
221 * Create a new mask swizzler
222 *
223 */
224SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
msarett614aa072015-07-27 15:13:17 -0700225 const SkImageInfo& info, SkMasks* masks, uint32_t bitsPerPixel) {
msarett74114382015-03-16 11:55:18 -0700226
227 // Choose the appropriate row procedure
halcanary96fcdcc2015-08-27 07:41:13 -0700228 RowProc proc = nullptr;
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;
scroggocc2feb12015-08-14 08:32:46 -0700247 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;
msaretteed039b2015-03-18 11:11:19 -0700256 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;
scroggocc2feb12015-08-14 08:32:46 -0700277 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;
msaretteed039b2015-03-18 11:11:19 -0700286 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;
scroggocc2feb12015-08-14 08:32:46 -0700307 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;
msaretteed039b2015-03-18 11:11:19 -0700316 default:
317 break;
msarett74114382015-03-16 11:55:18 -0700318 }
319 break;
320 default:
321 SkASSERT(false);
halcanary96fcdcc2015-08-27 07:41:13 -0700322 return nullptr;
msarett74114382015-03-16 11:55:18 -0700323 }
halcanary385fe4d2015-08-26 13:07:48 -0700324 return new SkMaskSwizzler(info, masks, proc);
msarett74114382015-03-16 11:55:18 -0700325}
326
327/*
328 *
329 * Constructor for mask swizzler
330 *
331 */
msarett614aa072015-07-27 15:13:17 -0700332SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, SkMasks* masks,
333 RowProc proc)
msaretteed039b2015-03-18 11:11:19 -0700334 : fDstInfo(dstInfo)
msarett74114382015-03-16 11:55:18 -0700335 , fMasks(masks)
336 , fRowProc(proc)
337{}
338
339/*
340 *
msaretteed039b2015-03-18 11:11:19 -0700341 * Swizzle the specified row
msarett74114382015-03-16 11:55:18 -0700342 *
343 */
msarett614aa072015-07-27 15:13:17 -0700344SkSwizzler::ResultAlpha SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -0700345 SkASSERT(nullptr != dst && nullptr != src);
msarett614aa072015-07-27 15:13:17 -0700346 return fRowProc(dst, src, fDstInfo.width(), fMasks);
msarett74114382015-03-16 11:55:18 -0700347}