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