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