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