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 "SkCodecPriv.h"
9 #include "SkColorPriv.h"
10 #include "SkMaskSwizzler.h"
11
swizzle_mask16_to_n32_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)12 static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_opaque(
13 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
swizzle_mask16_to_n32_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)28 static SkSwizzler::ResultAlpha swizzle_mask16_to_n32_unpremul(
29 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
swizzle_mask16_to_n32_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)47 static 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
swizzle_mask24_to_n32_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)66 static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_opaque(
67 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
swizzle_mask24_to_n32_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)81 static SkSwizzler::ResultAlpha swizzle_mask24_to_n32_unpremul(
82 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
swizzle_mask24_to_n32_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)99 static 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
swizzle_mask32_to_n32_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)117 static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_opaque(
118 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
swizzle_mask32_to_n32_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)133 static SkSwizzler::ResultAlpha swizzle_mask32_to_n32_unpremul(
134 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
swizzle_mask32_to_n32_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks)152 static 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
171 /*
172 *
173 * Create a new mask swizzler
174 *
175 */
CreateMaskSwizzler(const SkImageInfo & info,void * dst,size_t dstRowBytes,SkMasks * masks,uint32_t bitsPerPixel)176 SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
177 const SkImageInfo& info, void* dst, size_t dstRowBytes, SkMasks* masks,
178 uint32_t bitsPerPixel) {
179
180 // Choose the appropriate row procedure
181 RowProc proc = NULL;
182 switch (bitsPerPixel) {
183 case 16:
184 switch (info.colorType()) {
185 case kN32_SkColorType:
186 switch (info.alphaType()) {
187 case kUnpremul_SkAlphaType:
188 proc = &swizzle_mask16_to_n32_unpremul;
189 break;
190 case kPremul_SkAlphaType:
191 proc = &swizzle_mask16_to_n32_premul;
192 break;
193 case kOpaque_SkAlphaType:
194 proc = &swizzle_mask16_to_n32_opaque;
195 break;
196 default:
197 break;
198 }
199 break;
200 default:
201 break;
202 }
203 break;
204 case 24:
205 switch (info.colorType()) {
206 case kN32_SkColorType:
207 switch (info.alphaType()) {
208 case kUnpremul_SkAlphaType:
209 proc = &swizzle_mask24_to_n32_unpremul;
210 break;
211 case kPremul_SkAlphaType:
212 proc = &swizzle_mask24_to_n32_premul;
213 break;
214 case kOpaque_SkAlphaType:
215 proc = &swizzle_mask24_to_n32_opaque;
216 break;
217 default:
218 break;
219 }
220 break;
221 default:
222 break;
223 }
224 break;
225 case 32:
226 switch (info.colorType()) {
227 case kN32_SkColorType:
228 switch (info.alphaType()) {
229 case kUnpremul_SkAlphaType:
230 proc = &swizzle_mask32_to_n32_unpremul;
231 break;
232 case kPremul_SkAlphaType:
233 proc = &swizzle_mask32_to_n32_premul;
234 break;
235 case kOpaque_SkAlphaType:
236 proc = &swizzle_mask32_to_n32_opaque;
237 break;
238 default:
239 break;
240 }
241 break;
242 default:
243 break;
244 }
245 break;
246 default:
247 SkASSERT(false);
248 return NULL;
249 }
250 return SkNEW_ARGS(SkMaskSwizzler, (info, dst, dstRowBytes, masks, proc));
251 }
252
253 /*
254 *
255 * Constructor for mask swizzler
256 *
257 */
SkMaskSwizzler(const SkImageInfo & dstInfo,void * dst,size_t dstRowBytes,SkMasks * masks,RowProc proc)258 SkMaskSwizzler::SkMaskSwizzler(const SkImageInfo& dstInfo, void* dst,
259 size_t dstRowBytes, SkMasks* masks, RowProc proc)
260 : fDstInfo(dstInfo)
261 , fDst(dst)
262 , fDstRowBytes(dstRowBytes)
263 , fMasks(masks)
264 , fRowProc(proc)
265 {}
266
267 /*
268 *
269 * Swizzle the specified row
270 *
271 */
next(const uint8_t * SK_RESTRICT src,int y)272 SkSwizzler::ResultAlpha SkMaskSwizzler::next(const uint8_t* SK_RESTRICT src,
273 int y) {
274 // Choose the row
275 void* row = SkTAddOffset<void>(fDst, y*fDstRowBytes);
276
277 // Decode the row
278 return fRowProc(row, src, fDstInfo.width(), fMasks);
279 }
280