xref: /aosp_15_r20/external/skia/src/codec/SkMaskSwizzler.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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