blob: d0bb646740a10a2a484a324524a85f2e1d9daee9 [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
msaretteed039b2015-03-18 11:11:19 -070066static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -070067 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
68
69 // Use the masks to decode to the destination
70 SkPMColor* dstPtr = (SkPMColor*) dstRow;
71 for (int i = 0; i < 3*width; i += 3) {
72 uint32_t p = srcRow[i] | (srcRow[i + 1] << 8) | srcRow[i + 2] << 16;
73 uint8_t red = masks->getRed(p);
74 uint8_t green = masks->getGreen(p);
75 uint8_t blue = masks->getBlue(p);
76 dstPtr[i/3] = SkPackARGB32NoCheck(0xFF, red, green, blue);
77 }
78 return SkSwizzler::kOpaque_ResultAlpha;
79}
80
msaretteed039b2015-03-18 11:11:19 -070081static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -070082 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
83
84 // Use the masks to decode to the destination
85 SkPMColor* dstPtr = (SkPMColor*) dstRow;
86 INIT_RESULT_ALPHA;
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 uint8_t alpha = masks->getAlpha(p);
93 UPDATE_RESULT_ALPHA(alpha);
94 dstPtr[i/3] = SkPackARGB32NoCheck(alpha, red, green, blue);
95 }
96 return COMPUTE_RESULT_ALPHA;
97}
98
msaretteed039b2015-03-18 11:11:19 -070099static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_premul(
100 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] = SkPreMultiplyARGB(alpha, red, green, blue);
113 }
114 return COMPUTE_RESULT_ALPHA;
115}
116
msaretteed039b2015-03-18 11:11:19 -0700117static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque(
msarett74114382015-03-16 11:55:18 -0700118 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
119
120 // Use the masks to decode to the destination
121 uint32_t* srcPtr = (uint32_t*) srcRow;
122 SkPMColor* dstPtr = (SkPMColor*) dstRow;
123 for (int i = 0; i < width; i++) {
124 uint32_t p = srcPtr[i];
125 uint8_t red = masks->getRed(p);
126 uint8_t green = masks->getGreen(p);
127 uint8_t blue = masks->getBlue(p);
128 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
129 }
130 return SkSwizzler::kOpaque_ResultAlpha;
131}
132
msaretteed039b2015-03-18 11:11:19 -0700133static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_unpremul(
msarett74114382015-03-16 11:55:18 -0700134 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
135
136 // Use the masks to decode to the destination
137 uint32_t* srcPtr = (uint32_t*) srcRow;
138 SkPMColor* dstPtr = (SkPMColor*) dstRow;
139 INIT_RESULT_ALPHA;
140 for (int i = 0; i < width; i++) {
141 uint32_t p = srcPtr[i];
142 uint8_t red = masks->getRed(p);
143 uint8_t green = masks->getGreen(p);
144 uint8_t blue = masks->getBlue(p);
145 uint8_t alpha = masks->getAlpha(p);
146 UPDATE_RESULT_ALPHA(alpha);
147 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
148 }
149 return COMPUTE_RESULT_ALPHA;
150}
151
msaretteed039b2015-03-18 11:11:19 -0700152static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_premul(
153 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks) {
154
155 // Use the masks to decode to the destination
156 uint32_t* srcPtr = (uint32_t*) srcRow;
157 SkPMColor* dstPtr = (SkPMColor*) dstRow;
158 INIT_RESULT_ALPHA;
159 for (int i = 0; i < width; i++) {
160 uint32_t p = srcPtr[i];
161 uint8_t red = masks->getRed(p);
162 uint8_t green = masks->getGreen(p);
163 uint8_t blue = masks->getBlue(p);
164 uint8_t alpha = masks->getAlpha(p);
165 UPDATE_RESULT_ALPHA(alpha);
166 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
167 }
168 return COMPUTE_RESULT_ALPHA;
169}
170
msarett74114382015-03-16 11:55:18 -0700171/*
172 *
173 * Create a new mask swizzler
174 *
175 */
176SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
msarett614aa072015-07-27 15:13:17 -0700177 const SkImageInfo& info, SkMasks* masks, uint32_t bitsPerPixel) {
msarett74114382015-03-16 11:55:18 -0700178
179 // Choose the appropriate row procedure
180 RowProc proc = NULL;
msarett74114382015-03-16 11:55:18 -0700181 switch (bitsPerPixel) {
182 case 16:
msaretteed039b2015-03-18 11:11:19 -0700183 switch (info.colorType()) {
184 case kN32_SkColorType:
185 switch (info.alphaType()) {
186 case kUnpremul_SkAlphaType:
187 proc = &swizzle_mask16_to_n32_unpremul;
188 break;
189 case kPremul_SkAlphaType:
190 proc = &swizzle_mask16_to_n32_premul;
191 break;
192 case kOpaque_SkAlphaType:
193 proc = &swizzle_mask16_to_n32_opaque;
194 break;
195 default:
196 break;
197 }
198 break;
msaretteed039b2015-03-18 11:11:19 -0700199 default:
200 break;
msarett74114382015-03-16 11:55:18 -0700201 }
202 break;
203 case 24:
msaretteed039b2015-03-18 11:11:19 -0700204 switch (info.colorType()) {
205 case kN32_SkColorType:
206 switch (info.alphaType()) {
207 case kUnpremul_SkAlphaType:
208 proc = &swizzle_mask24_to_n32_unpremul;
209 break;
210 case kPremul_SkAlphaType:
211 proc = &swizzle_mask24_to_n32_premul;
212 break;
213 case kOpaque_SkAlphaType:
214 proc = &swizzle_mask24_to_n32_opaque;
215 break;
216 default:
217 break;
218 }
219 break;
msaretteed039b2015-03-18 11:11:19 -0700220 default:
221 break;
msarett74114382015-03-16 11:55:18 -0700222 }
223 break;
224 case 32:
msaretteed039b2015-03-18 11:11:19 -0700225 switch (info.colorType()) {
226 case kN32_SkColorType:
227 switch (info.alphaType()) {
228 case kUnpremul_SkAlphaType:
229 proc = &swizzle_mask32_to_n32_unpremul;
230 break;
231 case kPremul_SkAlphaType:
232 proc = &swizzle_mask32_to_n32_premul;
233 break;
234 case kOpaque_SkAlphaType:
235 proc = &swizzle_mask32_to_n32_opaque;
236 break;
237 default:
238 break;
239 }
240 break;
msaretteed039b2015-03-18 11:11:19 -0700241 default:
242 break;
msarett74114382015-03-16 11:55:18 -0700243 }
244 break;
245 default:
246 SkASSERT(false);
247 return NULL;
248 }
msarett614aa072015-07-27 15:13:17 -0700249 return SkNEW_ARGS(SkMaskSwizzler, (info, masks, proc));
msarett74114382015-03-16 11:55:18 -0700250}
251
252/*
253 *
254 * Constructor for mask swizzler
255 *
256 */
msarett614aa072015-07-27 15:13:17 -0700257SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, SkMasks* masks,
258 RowProc proc)
msaretteed039b2015-03-18 11:11:19 -0700259 : fDstInfo(dstInfo)
msarett74114382015-03-16 11:55:18 -0700260 , fMasks(masks)
261 , fRowProc(proc)
262{}
263
264/*
265 *
msaretteed039b2015-03-18 11:11:19 -0700266 * Swizzle the specified row
msarett74114382015-03-16 11:55:18 -0700267 *
268 */
msarett614aa072015-07-27 15:13:17 -0700269SkSwizzler::ResultAlpha SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
270 SkASSERT(NULL != dst && NULL != src);
271 return fRowProc(dst, src, fDstInfo.width(), fMasks);
msarett74114382015-03-16 11:55:18 -0700272}