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 "src/codec/SkMaskSwizzler.h"
9
10 #include "include/core/SkAlphaType.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkColorType.h"
13 #include "include/core/SkImageInfo.h"
14 #include "include/core/SkRect.h"
15 #include "include/private/SkColorData.h"
16 #include "src/codec/SkCodecPriv.h"
17 #include "src/core/SkMasks.h"
18
swizzle_mask16_to_rgba_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)19 static void swizzle_mask16_to_rgba_opaque(
20 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
21 uint32_t startX, uint32_t sampleX) {
22
23 // Use the masks to decode to the destination
24 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
25 SkPMColor* dstPtr = (SkPMColor*) dstRow;
26 for (int i = 0; i < width; i++) {
27 uint16_t p = srcPtr[0];
28 uint8_t red = masks->getRed(p);
29 uint8_t green = masks->getGreen(p);
30 uint8_t blue = masks->getBlue(p);
31 dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
32 srcPtr += sampleX;
33 }
34 }
35
swizzle_mask16_to_bgra_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)36 static void swizzle_mask16_to_bgra_opaque(
37 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
38 uint32_t startX, uint32_t sampleX) {
39
40 // Use the masks to decode to the destination
41 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
42 SkPMColor* dstPtr = (SkPMColor*) dstRow;
43 for (int i = 0; i < width; i++) {
44 uint16_t p = srcPtr[0];
45 uint8_t red = masks->getRed(p);
46 uint8_t green = masks->getGreen(p);
47 uint8_t blue = masks->getBlue(p);
48 dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue);
49 srcPtr += sampleX;
50 }
51 }
52
swizzle_mask16_to_rgba_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)53 static void swizzle_mask16_to_rgba_unpremul(
54 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
55 uint32_t startX, uint32_t sampleX) {
56
57 // Use the masks to decode to the destination
58 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
59 SkPMColor* dstPtr = (SkPMColor*) dstRow;
60 for (int i = 0; i < width; i++) {
61 uint16_t p = srcPtr[0];
62 uint8_t red = masks->getRed(p);
63 uint8_t green = masks->getGreen(p);
64 uint8_t blue = masks->getBlue(p);
65 uint8_t alpha = masks->getAlpha(p);
66 dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
67 srcPtr += sampleX;
68 }
69 }
70
swizzle_mask16_to_bgra_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)71 static void swizzle_mask16_to_bgra_unpremul(
72 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
73 uint32_t startX, uint32_t sampleX) {
74
75 // Use the masks to decode to the destination
76 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
77 SkPMColor* dstPtr = (SkPMColor*) dstRow;
78 for (int i = 0; i < width; i++) {
79 uint16_t p = srcPtr[0];
80 uint8_t red = masks->getRed(p);
81 uint8_t green = masks->getGreen(p);
82 uint8_t blue = masks->getBlue(p);
83 uint8_t alpha = masks->getAlpha(p);
84 dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
85 srcPtr += sampleX;
86 }
87 }
88
swizzle_mask16_to_rgba_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)89 static void swizzle_mask16_to_rgba_premul(
90 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
91 uint32_t startX, uint32_t sampleX) {
92
93 // Use the masks to decode to the destination
94 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
95 SkPMColor* dstPtr = (SkPMColor*) dstRow;
96 for (int i = 0; i < width; i++) {
97 uint16_t p = srcPtr[0];
98 uint8_t red = masks->getRed(p);
99 uint8_t green = masks->getGreen(p);
100 uint8_t blue = masks->getBlue(p);
101 uint8_t alpha = masks->getAlpha(p);
102 dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue);
103 srcPtr += sampleX;
104 }
105 }
106
swizzle_mask16_to_bgra_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)107 static void swizzle_mask16_to_bgra_premul(
108 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
109 uint32_t startX, uint32_t sampleX) {
110
111 // Use the masks to decode to the destination
112 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
113 SkPMColor* dstPtr = (SkPMColor*) dstRow;
114 for (int i = 0; i < width; i++) {
115 uint16_t p = srcPtr[0];
116 uint8_t red = masks->getRed(p);
117 uint8_t green = masks->getGreen(p);
118 uint8_t blue = masks->getBlue(p);
119 uint8_t alpha = masks->getAlpha(p);
120 dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue);
121 srcPtr += sampleX;
122 }
123 }
124
125 // TODO (msarett): We have promoted a two byte per pixel image to 8888, only to
126 // convert it back to 565. Instead, we should swizzle to 565 directly.
swizzle_mask16_to_565(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)127 static void swizzle_mask16_to_565(
128 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
129 uint32_t startX, uint32_t sampleX) {
130
131 // Use the masks to decode to the destination
132 const uint16_t* srcPtr = ((const uint16_t*) srcRow) + startX;
133 uint16_t* dstPtr = (uint16_t*) dstRow;
134 for (int i = 0; i < width; i++) {
135 uint16_t p = srcPtr[0];
136 uint8_t red = masks->getRed(p);
137 uint8_t green = masks->getGreen(p);
138 uint8_t blue = masks->getBlue(p);
139 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
140 srcPtr += sampleX;
141 }
142 }
143
swizzle_mask24_to_rgba_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)144 static void swizzle_mask24_to_rgba_opaque(
145 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
146 uint32_t startX, uint32_t sampleX) {
147
148 // Use the masks to decode to the destination
149 srcRow += 3 * startX;
150 SkPMColor* dstPtr = (SkPMColor*) dstRow;
151 for (int i = 0; i < width; i++) {
152 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
153 uint8_t red = masks->getRed(p);
154 uint8_t green = masks->getGreen(p);
155 uint8_t blue = masks->getBlue(p);
156 dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
157 srcRow += 3 * sampleX;
158 }
159 }
160
swizzle_mask24_to_bgra_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)161 static void swizzle_mask24_to_bgra_opaque(
162 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
163 uint32_t startX, uint32_t sampleX) {
164
165 // Use the masks to decode to the destination
166 srcRow += 3 * startX;
167 SkPMColor* dstPtr = (SkPMColor*) dstRow;
168 for (int i = 0; i < width; i++) {
169 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
170 uint8_t red = masks->getRed(p);
171 uint8_t green = masks->getGreen(p);
172 uint8_t blue = masks->getBlue(p);
173 dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue);
174 srcRow += 3 * sampleX;
175 }
176 }
177
swizzle_mask24_to_rgba_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)178 static void swizzle_mask24_to_rgba_unpremul(
179 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
180 uint32_t startX, uint32_t sampleX) {
181
182 // Use the masks to decode to the destination
183 srcRow += 3 * startX;
184 SkPMColor* dstPtr = (SkPMColor*) dstRow;
185 for (int i = 0; i < width; i++) {
186 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
187 uint8_t red = masks->getRed(p);
188 uint8_t green = masks->getGreen(p);
189 uint8_t blue = masks->getBlue(p);
190 uint8_t alpha = masks->getAlpha(p);
191 dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
192 srcRow += 3 * sampleX;
193 }
194 }
195
swizzle_mask24_to_bgra_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)196 static void swizzle_mask24_to_bgra_unpremul(
197 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
198 uint32_t startX, uint32_t sampleX) {
199
200 // Use the masks to decode to the destination
201 srcRow += 3 * startX;
202 SkPMColor* dstPtr = (SkPMColor*) dstRow;
203 for (int i = 0; i < width; i++) {
204 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
205 uint8_t red = masks->getRed(p);
206 uint8_t green = masks->getGreen(p);
207 uint8_t blue = masks->getBlue(p);
208 uint8_t alpha = masks->getAlpha(p);
209 dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
210 srcRow += 3 * sampleX;
211 }
212 }
213
swizzle_mask24_to_rgba_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)214 static void swizzle_mask24_to_rgba_premul(
215 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
216 uint32_t startX, uint32_t sampleX) {
217
218 // Use the masks to decode to the destination
219 srcRow += 3 * startX;
220 SkPMColor* dstPtr = (SkPMColor*) dstRow;
221 for (int i = 0; i < width; i++) {
222 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
223 uint8_t red = masks->getRed(p);
224 uint8_t green = masks->getGreen(p);
225 uint8_t blue = masks->getBlue(p);
226 uint8_t alpha = masks->getAlpha(p);
227 dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue);
228 srcRow += 3 * sampleX;
229 }
230 }
231
swizzle_mask24_to_bgra_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)232 static void swizzle_mask24_to_bgra_premul(
233 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
234 uint32_t startX, uint32_t sampleX) {
235
236 // Use the masks to decode to the destination
237 srcRow += 3 * startX;
238 SkPMColor* dstPtr = (SkPMColor*) dstRow;
239 for (int i = 0; i < width; i++) {
240 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
241 uint8_t red = masks->getRed(p);
242 uint8_t green = masks->getGreen(p);
243 uint8_t blue = masks->getBlue(p);
244 uint8_t alpha = masks->getAlpha(p);
245 dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue);
246 srcRow += 3 * sampleX;
247 }
248 }
249
swizzle_mask24_to_565(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)250 static void swizzle_mask24_to_565(
251 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
252 uint32_t startX, uint32_t sampleX) {
253
254 // Use the masks to decode to the destination
255 srcRow += 3 * startX;
256 uint16_t* dstPtr = (uint16_t*) dstRow;
257 for (int i = 0; i < width; i++) {
258 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
259 uint8_t red = masks->getRed(p);
260 uint8_t green = masks->getGreen(p);
261 uint8_t blue = masks->getBlue(p);
262 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
263 srcRow += 3 * sampleX;
264 }
265 }
266
swizzle_mask32_to_rgba_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)267 static void swizzle_mask32_to_rgba_opaque(
268 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
269 uint32_t startX, uint32_t sampleX) {
270
271 // Use the masks to decode to the destination
272 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
273 SkPMColor* dstPtr = (SkPMColor*) dstRow;
274 for (int i = 0; i < width; i++) {
275 uint32_t p = srcPtr[0];
276 uint8_t red = masks->getRed(p);
277 uint8_t green = masks->getGreen(p);
278 uint8_t blue = masks->getBlue(p);
279 dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
280 srcPtr += sampleX;
281 }
282 }
283
swizzle_mask32_to_bgra_opaque(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)284 static void swizzle_mask32_to_bgra_opaque(
285 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
286 uint32_t startX, uint32_t sampleX) {
287
288 // Use the masks to decode to the destination
289 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
290 SkPMColor* dstPtr = (SkPMColor*) dstRow;
291 for (int i = 0; i < width; i++) {
292 uint32_t p = srcPtr[0];
293 uint8_t red = masks->getRed(p);
294 uint8_t green = masks->getGreen(p);
295 uint8_t blue = masks->getBlue(p);
296 dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue);
297 srcPtr += sampleX;
298 }
299 }
300
swizzle_mask32_to_rgba_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)301 static void swizzle_mask32_to_rgba_unpremul(
302 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
303 uint32_t startX, uint32_t sampleX) {
304
305 // Use the masks to decode to the destination
306 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
307 SkPMColor* dstPtr = (SkPMColor*) dstRow;
308 for (int i = 0; i < width; i++) {
309 uint32_t p = srcPtr[0];
310 uint8_t red = masks->getRed(p);
311 uint8_t green = masks->getGreen(p);
312 uint8_t blue = masks->getBlue(p);
313 uint8_t alpha = masks->getAlpha(p);
314 dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
315 srcPtr += sampleX;
316 }
317 }
318
swizzle_mask32_to_bgra_unpremul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)319 static void swizzle_mask32_to_bgra_unpremul(
320 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
321 uint32_t startX, uint32_t sampleX) {
322
323 // Use the masks to decode to the destination
324 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
325 SkPMColor* dstPtr = (SkPMColor*) dstRow;
326 for (int i = 0; i < width; i++) {
327 uint32_t p = srcPtr[0];
328 uint8_t red = masks->getRed(p);
329 uint8_t green = masks->getGreen(p);
330 uint8_t blue = masks->getBlue(p);
331 uint8_t alpha = masks->getAlpha(p);
332 dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
333 srcPtr += sampleX;
334 }
335 }
336
swizzle_mask32_to_rgba_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)337 static void swizzle_mask32_to_rgba_premul(
338 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
339 uint32_t startX, uint32_t sampleX) {
340
341 // Use the masks to decode to the destination
342 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
343 SkPMColor* dstPtr = (SkPMColor*) dstRow;
344 for (int i = 0; i < width; i++) {
345 uint32_t p = srcPtr[0];
346 uint8_t red = masks->getRed(p);
347 uint8_t green = masks->getGreen(p);
348 uint8_t blue = masks->getBlue(p);
349 uint8_t alpha = masks->getAlpha(p);
350 dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue);
351 srcPtr += sampleX;
352 }
353 }
354
swizzle_mask32_to_bgra_premul(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)355 static void swizzle_mask32_to_bgra_premul(
356 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
357 uint32_t startX, uint32_t sampleX) {
358
359 // Use the masks to decode to the destination
360 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
361 SkPMColor* dstPtr = (SkPMColor*) dstRow;
362 for (int i = 0; i < width; i++) {
363 uint32_t p = srcPtr[0];
364 uint8_t red = masks->getRed(p);
365 uint8_t green = masks->getGreen(p);
366 uint8_t blue = masks->getBlue(p);
367 uint8_t alpha = masks->getAlpha(p);
368 dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue);
369 srcPtr += sampleX;
370 }
371 }
372
swizzle_mask32_to_565(void * dstRow,const uint8_t * srcRow,int width,SkMasks * masks,uint32_t startX,uint32_t sampleX)373 static void swizzle_mask32_to_565(
374 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
375 uint32_t startX, uint32_t sampleX) {
376 // Use the masks to decode to the destination
377 const uint32_t* srcPtr = ((const uint32_t*) srcRow) + startX;
378 uint16_t* dstPtr = (uint16_t*) dstRow;
379 for (int i = 0; i < width; i++) {
380 uint32_t p = srcPtr[0];
381 uint8_t red = masks->getRed(p);
382 uint8_t green = masks->getGreen(p);
383 uint8_t blue = masks->getBlue(p);
384 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
385 srcPtr += sampleX;
386 }
387 }
388
389 /*
390 *
391 * Create a new mask swizzler
392 *
393 */
CreateMaskSwizzler(const SkImageInfo & dstInfo,bool srcIsOpaque,SkMasks * masks,uint32_t bitsPerPixel,const SkCodec::Options & options)394 SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
395 bool srcIsOpaque, SkMasks* masks, uint32_t bitsPerPixel,
396 const SkCodec::Options& options) {
397
398 // Choose the appropriate row procedure
399 RowProc proc = nullptr;
400 switch (bitsPerPixel) {
401 case 16:
402 switch (dstInfo.colorType()) {
403 case kRGBA_8888_SkColorType:
404 if (srcIsOpaque) {
405 proc = &swizzle_mask16_to_rgba_opaque;
406 } else {
407 switch (dstInfo.alphaType()) {
408 case kUnpremul_SkAlphaType:
409 proc = &swizzle_mask16_to_rgba_unpremul;
410 break;
411 case kPremul_SkAlphaType:
412 proc = &swizzle_mask16_to_rgba_premul;
413 break;
414 default:
415 break;
416 }
417 }
418 break;
419 case kBGRA_8888_SkColorType:
420 if (srcIsOpaque) {
421 proc = &swizzle_mask16_to_bgra_opaque;
422 } else {
423 switch (dstInfo.alphaType()) {
424 case kUnpremul_SkAlphaType:
425 proc = &swizzle_mask16_to_bgra_unpremul;
426 break;
427 case kPremul_SkAlphaType:
428 proc = &swizzle_mask16_to_bgra_premul;
429 break;
430 default:
431 break;
432 }
433 }
434 break;
435 case kRGB_565_SkColorType:
436 proc = &swizzle_mask16_to_565;
437 break;
438 default:
439 break;
440 }
441 break;
442 case 24:
443 switch (dstInfo.colorType()) {
444 case kRGBA_8888_SkColorType:
445 if (srcIsOpaque) {
446 proc = &swizzle_mask24_to_rgba_opaque;
447 } else {
448 switch (dstInfo.alphaType()) {
449 case kUnpremul_SkAlphaType:
450 proc = &swizzle_mask24_to_rgba_unpremul;
451 break;
452 case kPremul_SkAlphaType:
453 proc = &swizzle_mask24_to_rgba_premul;
454 break;
455 default:
456 break;
457 }
458 }
459 break;
460 case kBGRA_8888_SkColorType:
461 if (srcIsOpaque) {
462 proc = &swizzle_mask24_to_bgra_opaque;
463 } else {
464 switch (dstInfo.alphaType()) {
465 case kUnpremul_SkAlphaType:
466 proc = &swizzle_mask24_to_bgra_unpremul;
467 break;
468 case kPremul_SkAlphaType:
469 proc = &swizzle_mask24_to_bgra_premul;
470 break;
471 default:
472 break;
473 }
474 }
475 break;
476 case kRGB_565_SkColorType:
477 proc = &swizzle_mask24_to_565;
478 break;
479 default:
480 break;
481 }
482 break;
483 case 32:
484 switch (dstInfo.colorType()) {
485 case kRGBA_8888_SkColorType:
486 if (srcIsOpaque) {
487 proc = &swizzle_mask32_to_rgba_opaque;
488 } else {
489 switch (dstInfo.alphaType()) {
490 case kUnpremul_SkAlphaType:
491 proc = &swizzle_mask32_to_rgba_unpremul;
492 break;
493 case kPremul_SkAlphaType:
494 proc = &swizzle_mask32_to_rgba_premul;
495 break;
496 default:
497 break;
498 }
499 }
500 break;
501 case kBGRA_8888_SkColorType:
502 if (srcIsOpaque) {
503 proc = &swizzle_mask32_to_bgra_opaque;
504 } else {
505 switch (dstInfo.alphaType()) {
506 case kUnpremul_SkAlphaType:
507 proc = &swizzle_mask32_to_bgra_unpremul;
508 break;
509 case kPremul_SkAlphaType:
510 proc = &swizzle_mask32_to_bgra_premul;
511 break;
512 default:
513 break;
514 }
515 }
516 break;
517 case kRGB_565_SkColorType:
518 proc = &swizzle_mask32_to_565;
519 break;
520 default:
521 break;
522 }
523 break;
524 default:
525 SkASSERT(false);
526 return nullptr;
527 }
528
529 int srcOffset = 0;
530 int srcWidth = dstInfo.width();
531 if (options.fSubset) {
532 srcOffset = options.fSubset->left();
533 srcWidth = options.fSubset->width();
534 }
535
536 return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth);
537 }
538
539 /*
540 *
541 * Constructor for mask swizzler
542 *
543 */
SkMaskSwizzler(SkMasks * masks,RowProc proc,int srcOffset,int subsetWidth)544 SkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int subsetWidth)
545 : fMasks(masks)
546 , fRowProc(proc)
547 , fSubsetWidth(subsetWidth)
548 , fDstWidth(subsetWidth)
549 , fSampleX(1)
550 , fSrcOffset(srcOffset)
551 , fX0(srcOffset)
552 {}
553
onSetSampleX(int sampleX)554 int SkMaskSwizzler::onSetSampleX(int sampleX) {
555 // FIXME: Share this function with SkSwizzler?
556 SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
557 // way to report failure?
558 fSampleX = sampleX;
559 fX0 = get_start_coord(sampleX) + fSrcOffset;
560 fDstWidth = get_scaled_dimension(fSubsetWidth, sampleX);
561
562 // check that fX0 is valid
563 SkASSERT(fX0 >= 0);
564 return fDstWidth;
565 }
566
567 /*
568 *
569 * Swizzle the specified row
570 *
571 */
swizzle(void * dst,const uint8_t * SK_RESTRICT src)572 void SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
573 SkASSERT(nullptr != dst && nullptr != src);
574 fRowProc(dst, src, fDstWidth, fMasks, fX0, fSampleX);
575 }
576