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 "SkCodecPriv.h"
9 #include "SkColorPriv.h"
10 #include "SkOpts.h"
11 #include "SkSwizzler.h"
12 #include "SkTemplates.h"
13 
copy(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])14 static void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
15         const SkPMColor ctable[]) {
16     // This function must not be called if we are sampling.  If we are not
17     // sampling, deltaSrc should equal bpp.
18     SkASSERT(deltaSrc == bpp);
19 
20     memcpy(dst, src + offset, width * bpp);
21 }
22 
sample1(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])23 static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
24         const SkPMColor ctable[]) {
25     src += offset;
26     uint8_t* dst8 = (uint8_t*) dst;
27     for (int x = 0; x < width; x++) {
28         dst8[x] = *src;
29         src += deltaSrc;
30     }
31 }
32 
sample2(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])33 static void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
34         const SkPMColor ctable[]) {
35     src += offset;
36     uint16_t* dst16 = (uint16_t*) dst;
37     for (int x = 0; x < width; x++) {
38         dst16[x] = *((const uint16_t*) src);
39         src += deltaSrc;
40     }
41 }
42 
sample4(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])43 static void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
44         const SkPMColor ctable[]) {
45     src += offset;
46     uint32_t* dst32 = (uint32_t*) dst;
47     for (int x = 0; x < width; x++) {
48         dst32[x] = *((const uint32_t*) src);
49         src += deltaSrc;
50     }
51 }
52 
53 // kBit
54 // These routines exclusively choose between white and black
55 
56 #define GRAYSCALE_BLACK 0
57 #define GRAYSCALE_WHITE 0xFF
58 
59 
60 // same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
swizzle_bit_to_grayscale(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor *)61 static void swizzle_bit_to_grayscale(
62         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
63         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
64 
65     uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
66 
67     // increment src by byte offset and bitIndex by bit offset
68     src += offset / 8;
69     int bitIndex = offset % 8;
70     uint8_t currByte = *src;
71 
72     dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
73 
74     for (int x = 1; x < dstWidth; x++) {
75         int bitOffset = bitIndex + deltaSrc;
76         bitIndex = bitOffset % 8;
77         currByte = *(src += bitOffset / 8);
78         dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
79     }
80 }
81 
82 #undef GRAYSCALE_BLACK
83 #undef GRAYSCALE_WHITE
84 
85 // same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x]
swizzle_bit_to_index(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor *)86 static void swizzle_bit_to_index(
87         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
88         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
89     uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
90 
91     // increment src by byte offset and bitIndex by bit offset
92     src += offset / 8;
93     int bitIndex = offset % 8;
94     uint8_t currByte = *src;
95 
96     dst[0] = ((currByte >> (7-bitIndex)) & 1);
97 
98     for (int x = 1; x < dstWidth; x++) {
99         int bitOffset = bitIndex + deltaSrc;
100         bitIndex = bitOffset % 8;
101         currByte = *(src += bitOffset / 8);
102         dst[x] = ((currByte >> (7-bitIndex)) & 1);
103     }
104 }
105 
106 // same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
swizzle_bit_to_n32(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor *)107 static void swizzle_bit_to_n32(
108         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
109         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
110     SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
111 
112     // increment src by byte offset and bitIndex by bit offset
113     src += offset / 8;
114     int bitIndex = offset % 8;
115     uint8_t currByte = *src;
116 
117     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
118 
119     for (int x = 1; x < dstWidth; x++) {
120         int bitOffset = bitIndex + deltaSrc;
121         bitIndex = bitOffset % 8;
122         currByte = *(src += bitOffset / 8);
123         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
124     }
125 }
126 
127 #define RGB565_BLACK 0
128 #define RGB565_WHITE 0xFFFF
129 
swizzle_bit_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor *)130 static void swizzle_bit_to_565(
131         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
132         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
133     uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
134 
135     // increment src by byte offset and bitIndex by bit offset
136     src += offset / 8;
137     int bitIndex = offset % 8;
138     uint8_t currByte = *src;
139 
140     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
141 
142     for (int x = 1; x < dstWidth; x++) {
143         int bitOffset = bitIndex + deltaSrc;
144         bitIndex = bitOffset % 8;
145         currByte = *(src += bitOffset / 8);
146         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
147     }
148 }
149 
150 #undef RGB565_BLACK
151 #undef RGB565_WHITE
152 
153 // kIndex1, kIndex2, kIndex4
154 
swizzle_small_index_to_index(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])155 static void swizzle_small_index_to_index(
156         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
157         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
158 
159     uint8_t* dst = (uint8_t*) dstRow;
160     src += offset / 8;
161     int bitIndex = offset % 8;
162     uint8_t currByte = *src;
163     const uint8_t mask = (1 << bpp) - 1;
164     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
165     dst[0] = index;
166 
167     for (int x = 1; x < dstWidth; x++) {
168         int bitOffset = bitIndex + deltaSrc;
169         bitIndex = bitOffset % 8;
170         currByte = *(src += bitOffset / 8);
171         index = (currByte >> (8 - bpp - bitIndex)) & mask;
172         dst[x] = index;
173     }
174 }
175 
swizzle_small_index_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])176 static void swizzle_small_index_to_565(
177         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
178         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
179 
180     uint16_t* dst = (uint16_t*) dstRow;
181     src += offset / 8;
182     int bitIndex = offset % 8;
183     uint8_t currByte = *src;
184     const uint8_t mask = (1 << bpp) - 1;
185     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
186     dst[0] = SkPixel32ToPixel16(ctable[index]);
187 
188     for (int x = 1; x < dstWidth; x++) {
189         int bitOffset = bitIndex + deltaSrc;
190         bitIndex = bitOffset % 8;
191         currByte = *(src += bitOffset / 8);
192         index = (currByte >> (8 - bpp - bitIndex)) & mask;
193         dst[x] = SkPixel32ToPixel16(ctable[index]);
194     }
195 }
196 
swizzle_small_index_to_n32(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])197 static void swizzle_small_index_to_n32(
198         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
199         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
200 
201     SkPMColor* dst = (SkPMColor*) dstRow;
202     src += offset / 8;
203     int bitIndex = offset % 8;
204     uint8_t currByte = *src;
205     const uint8_t mask = (1 << bpp) - 1;
206     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
207     dst[0] = ctable[index];
208 
209     for (int x = 1; x < dstWidth; x++) {
210         int bitOffset = bitIndex + deltaSrc;
211         bitIndex = bitOffset % 8;
212         currByte = *(src += bitOffset / 8);
213         index = (currByte >> (8 - bpp - bitIndex)) & mask;
214         dst[x] = ctable[index];
215     }
216 }
217 
218 // kIndex
219 
swizzle_index_to_n32(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])220 static void swizzle_index_to_n32(
221         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
222         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
223 
224     src += offset;
225     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
226     for (int x = 0; x < dstWidth; x++) {
227         SkPMColor c = ctable[*src];
228         dst[x] = c;
229         src += deltaSrc;
230     }
231 }
232 
swizzle_index_to_n32_skipZ(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])233 static void swizzle_index_to_n32_skipZ(
234         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
235         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
236 
237     src += offset;
238     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
239     for (int x = 0; x < dstWidth; x++) {
240         SkPMColor c = ctable[*src];
241         if (c != 0) {
242             dst[x] = c;
243         }
244         src += deltaSrc;
245     }
246 }
247 
swizzle_index_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bytesPerPixel,int deltaSrc,int offset,const SkPMColor ctable[])248 static void swizzle_index_to_565(
249       void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
250       int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
251     src += offset;
252     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
253     for (int x = 0; x < dstWidth; x++) {
254         dst[x] = SkPixel32ToPixel16(ctable[*src]);
255         src += deltaSrc;
256     }
257 }
258 
259 // kGray
260 
swizzle_gray_to_n32(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])261 static void swizzle_gray_to_n32(
262         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
263         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
264 
265     src += offset;
266     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
267     for (int x = 0; x < dstWidth; x++) {
268         dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
269         src += deltaSrc;
270     }
271 }
272 
fast_swizzle_gray_to_n32(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])273 static void fast_swizzle_gray_to_n32(
274         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
275         const SkPMColor ctable[]) {
276 
277     // This function must not be called if we are sampling.  If we are not
278     // sampling, deltaSrc should equal bpp.
279     SkASSERT(deltaSrc == bpp);
280 
281     // Note that there is no need to distinguish between RGB and BGR.
282     // Each color channel will get the same value.
283     SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
284 }
285 
swizzle_gray_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bytesPerPixel,int deltaSrc,int offset,const SkPMColor ctable[])286 static void swizzle_gray_to_565(
287         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
288         int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
289 
290     src += offset;
291     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
292     for (int x = 0; x < dstWidth; x++) {
293         dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
294         src += deltaSrc;
295     }
296 }
297 
298 // kGrayAlpha
299 
swizzle_grayalpha_to_n32_unpremul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])300 static void swizzle_grayalpha_to_n32_unpremul(
301         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
302         const SkPMColor ctable[]) {
303 
304     src += offset;
305     SkPMColor* dst32 = (SkPMColor*) dst;
306     for (int x = 0; x < width; x++) {
307         dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
308         src += deltaSrc;
309     }
310 }
311 
fast_swizzle_grayalpha_to_n32_unpremul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])312 static void fast_swizzle_grayalpha_to_n32_unpremul(
313         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
314         const SkPMColor ctable[]) {
315 
316     // This function must not be called if we are sampling.  If we are not
317     // sampling, deltaSrc should equal bpp.
318     SkASSERT(deltaSrc == bpp);
319 
320     // Note that there is no need to distinguish between RGB and BGR.
321     // Each color channel will get the same value.
322     SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
323 }
324 
swizzle_grayalpha_to_n32_premul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])325 static void swizzle_grayalpha_to_n32_premul(
326         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
327         const SkPMColor ctable[]) {
328 
329     src += offset;
330     SkPMColor* dst32 = (SkPMColor*) dst;
331     for (int x = 0; x < width; x++) {
332         uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
333         dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
334         src += deltaSrc;
335     }
336 }
337 
fast_swizzle_grayalpha_to_n32_premul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])338 static void fast_swizzle_grayalpha_to_n32_premul(
339         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
340         const SkPMColor ctable[]) {
341 
342     // This function must not be called if we are sampling.  If we are not
343     // sampling, deltaSrc should equal bpp.
344     SkASSERT(deltaSrc == bpp);
345 
346     // Note that there is no need to distinguish between rgb and bgr.
347     // Each color channel will get the same value.
348     SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
349 }
350 
351 // kBGR
352 
swizzle_bgr_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])353 static void swizzle_bgr_to_565(
354         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
355         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
356 
357     src += offset;
358     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
359     for (int x = 0; x < dstWidth; x++) {
360         dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
361         src += deltaSrc;
362     }
363 }
364 
365 // kRGB
366 
swizzle_rgb_to_rgba(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])367 static void swizzle_rgb_to_rgba(
368         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
369         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
370 
371     src += offset;
372     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
373     for (int x = 0; x < dstWidth; x++) {
374         dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
375         src += deltaSrc;
376     }
377 }
378 
swizzle_rgb_to_bgra(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])379 static void swizzle_rgb_to_bgra(
380         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
381         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
382 
383     src += offset;
384     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
385     for (int x = 0; x < dstWidth; x++) {
386         dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
387         src += deltaSrc;
388     }
389 }
390 
fast_swizzle_rgb_to_rgba(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])391 static void fast_swizzle_rgb_to_rgba(
392         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
393         int offset, const SkPMColor ctable[]) {
394 
395     // This function must not be called if we are sampling.  If we are not
396     // sampling, deltaSrc should equal bpp.
397     SkASSERT(deltaSrc == bpp);
398 
399     SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
400 }
401 
fast_swizzle_rgb_to_bgra(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])402 static void fast_swizzle_rgb_to_bgra(
403         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
404         int offset, const SkPMColor ctable[]) {
405 
406     // This function must not be called if we are sampling.  If we are not
407     // sampling, deltaSrc should equal bpp.
408     SkASSERT(deltaSrc == bpp);
409 
410     SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
411 }
412 
swizzle_rgb_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bytesPerPixel,int deltaSrc,int offset,const SkPMColor ctable[])413 static void swizzle_rgb_to_565(
414        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
415        int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
416 
417     src += offset;
418     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
419     for (int x = 0; x < dstWidth; x++) {
420         dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
421         src += deltaSrc;
422     }
423 }
424 
425 // kRGBA
426 
swizzle_rgba_to_rgba_premul(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])427 static void swizzle_rgba_to_rgba_premul(
428         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
429         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
430 
431     src += offset;
432     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
433     for (int x = 0; x < dstWidth; x++) {
434         dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
435         src += deltaSrc;
436     }
437 }
438 
swizzle_rgba_to_bgra_premul(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])439 static void swizzle_rgba_to_bgra_premul(
440         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
441         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
442 
443     src += offset;
444     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
445     for (int x = 0; x < dstWidth; x++) {
446         dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
447         src += deltaSrc;
448     }
449 }
450 
fast_swizzle_rgba_to_rgba_premul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])451 static void fast_swizzle_rgba_to_rgba_premul(
452         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
453         int offset, const SkPMColor ctable[]) {
454 
455     // This function must not be called if we are sampling.  If we are not
456     // sampling, deltaSrc should equal bpp.
457     SkASSERT(deltaSrc == bpp);
458 
459     SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
460 }
461 
fast_swizzle_rgba_to_bgra_premul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])462 static void fast_swizzle_rgba_to_bgra_premul(
463         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
464         int offset, const SkPMColor ctable[]) {
465 
466     // This function must not be called if we are sampling.  If we are not
467     // sampling, deltaSrc should equal bpp.
468     SkASSERT(deltaSrc == bpp);
469 
470     SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
471 }
472 
swizzle_rgba_to_bgra_unpremul(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])473 static void swizzle_rgba_to_bgra_unpremul(
474         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
475         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
476 
477     src += offset;
478     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
479     for (int x = 0; x < dstWidth; x++) {
480         unsigned alpha = src[3];
481         dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
482         src += deltaSrc;
483     }
484 }
485 
fast_swizzle_rgba_to_bgra_unpremul(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])486 static void fast_swizzle_rgba_to_bgra_unpremul(
487         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
488         const SkPMColor ctable[]) {
489 
490     // This function must not be called if we are sampling.  If we are not
491     // sampling, deltaSrc should equal bpp.
492     SkASSERT(deltaSrc == bpp);
493 
494     SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
495 }
496 
497 // kCMYK
498 //
499 // CMYK is stored as four bytes per pixel.
500 //
501 // We will implement a crude conversion from CMYK -> RGB using formulas
502 // from easyrgb.com.
503 //
504 // CMYK -> CMY
505 // C = C * (1 - K) + K
506 // M = M * (1 - K) + K
507 // Y = Y * (1 - K) + K
508 //
509 // libjpeg actually gives us inverted CMYK, so we must subtract the
510 // original terms from 1.
511 // CMYK -> CMY
512 // C = (1 - C) * (1 - (1 - K)) + (1 - K)
513 // M = (1 - M) * (1 - (1 - K)) + (1 - K)
514 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
515 //
516 // Simplifying the above expression.
517 // CMYK -> CMY
518 // C = 1 - CK
519 // M = 1 - MK
520 // Y = 1 - YK
521 //
522 // CMY -> RGB
523 // R = (1 - C) * 255
524 // G = (1 - M) * 255
525 // B = (1 - Y) * 255
526 //
527 // Therefore the full conversion is below.  This can be verified at
528 // www.rapidtables.com (assuming inverted CMYK).
529 // CMYK -> RGB
530 // R = C * K * 255
531 // G = M * K * 255
532 // B = Y * K * 255
533 //
534 // As a final note, we have treated the CMYK values as if they were on
535 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
536 // We must divide each CMYK component by 255 to obtain the true conversion
537 // we should perform.
538 // CMYK -> RGB
539 // R = C * K / 255
540 // G = M * K / 255
541 // B = Y * K / 255
swizzle_cmyk_to_rgba(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])542 static void swizzle_cmyk_to_rgba(
543         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
544         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
545 
546     src += offset;
547     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
548     for (int x = 0; x < dstWidth; x++) {
549         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
550         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
551         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
552 
553         dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
554         src += deltaSrc;
555     }
556 }
557 
swizzle_cmyk_to_bgra(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])558 static void swizzle_cmyk_to_bgra(
559         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
560         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
561 
562     src += offset;
563     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
564     for (int x = 0; x < dstWidth; x++) {
565         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
566         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
567         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
568 
569         dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
570         src += deltaSrc;
571     }
572 }
573 
fast_swizzle_cmyk_to_rgba(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])574 static void fast_swizzle_cmyk_to_rgba(
575         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
576         const SkPMColor ctable[]) {
577 
578     // This function must not be called if we are sampling.  If we are not
579     // sampling, deltaSrc should equal bpp.
580     SkASSERT(deltaSrc == bpp);
581 
582     SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
583 }
584 
fast_swizzle_cmyk_to_bgra(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])585 static void fast_swizzle_cmyk_to_bgra(
586         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
587         const SkPMColor ctable[]) {
588 
589     // This function must not be called if we are sampling.  If we are not
590     // sampling, deltaSrc should equal bpp.
591     SkASSERT(deltaSrc == bpp);
592 
593     SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
594 }
595 
swizzle_cmyk_to_565(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])596 static void swizzle_cmyk_to_565(
597         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
598         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
599 
600     src += offset;
601     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
602     for (int x = 0; x < dstWidth; x++) {
603         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
604         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
605         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
606 
607         dst[x] = SkPack888ToRGB16(r, g, b);
608         src += deltaSrc;
609     }
610 }
611 
612 template <SkSwizzler::RowProc proc>
SkipLeadingGrayAlphaZerosThen(void * dst,const uint8_t * src,int width,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])613 void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
614         void* dst, const uint8_t* src, int width,
615         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
616     SkASSERT(!ctable);
617 
618     const uint16_t* src16 = (const uint16_t*) (src + offset);
619     uint32_t* dst32 = (uint32_t*) dst;
620 
621     // This may miss opportunities to skip when the output is premultiplied,
622     // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
623     while (width > 0 && *src16 == 0x0000) {
624         width--;
625         dst32++;
626         src16 += deltaSrc / 2;
627     }
628     proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
629 }
630 
631 template <SkSwizzler::RowProc proc>
SkipLeading8888ZerosThen(void * SK_RESTRICT dstRow,const uint8_t * SK_RESTRICT src,int dstWidth,int bpp,int deltaSrc,int offset,const SkPMColor ctable[])632 void SkSwizzler::SkipLeading8888ZerosThen(
633         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
634         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
635     SkASSERT(!ctable);
636 
637     auto src32 = (const uint32_t*)(src+offset);
638     auto dst32 = (uint32_t*)dstRow;
639 
640     // This may miss opportunities to skip when the output is premultiplied,
641     // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
642     while (dstWidth > 0 && *src32 == 0x00000000) {
643         dstWidth--;
644         dst32++;
645         src32 += deltaSrc/4;
646     }
647     proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
648 }
649 
CreateSwizzler(const SkEncodedInfo & encodedInfo,const SkPMColor * ctable,const SkImageInfo & dstInfo,const SkCodec::Options & options,const SkIRect * frame,bool preSwizzled)650 SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
651                                        const SkPMColor* ctable,
652                                        const SkImageInfo& dstInfo,
653                                        const SkCodec::Options& options,
654                                        const SkIRect* frame,
655                                        bool preSwizzled) {
656     if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
657         return nullptr;
658     }
659 
660     RowProc fastProc = nullptr;
661     RowProc proc = nullptr;
662     if (preSwizzled) {
663         switch (dstInfo.colorType()) {
664             case kGray_8_SkColorType:
665                 proc = &sample1;
666                 fastProc = &copy;
667                 break;
668             case kRGB_565_SkColorType:
669                 proc = &sample2;
670                 fastProc = &copy;
671                 break;
672             case kRGBA_8888_SkColorType:
673             case kBGRA_8888_SkColorType:
674                 proc = &sample4;
675                 fastProc = &copy;
676                 break;
677             default:
678                 return nullptr;
679         }
680     } else {
681         SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
682         const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
683                 (kPremul_SkAlphaType == dstInfo.alphaType());
684 
685         switch (encodedInfo.color()) {
686             case SkEncodedInfo::kGray_Color:
687                 switch (encodedInfo.bitsPerComponent()) {
688                     case 1:
689                         switch (dstInfo.colorType()) {
690                             case kRGBA_8888_SkColorType:
691                             case kBGRA_8888_SkColorType:
692                                 proc = &swizzle_bit_to_n32;
693                                 break;
694                             case kIndex_8_SkColorType:
695                                 proc = &swizzle_bit_to_index;
696                                 break;
697                             case kRGB_565_SkColorType:
698                                 proc = &swizzle_bit_to_565;
699                                 break;
700                             case kGray_8_SkColorType:
701                                 proc = &swizzle_bit_to_grayscale;
702                                 break;
703                             default:
704                                 return nullptr;
705                         }
706                         break;
707                     case 8:
708                         switch (dstInfo.colorType()) {
709                             case kRGBA_8888_SkColorType:
710                             case kBGRA_8888_SkColorType:
711                                 proc = &swizzle_gray_to_n32;
712                                 fastProc = &fast_swizzle_gray_to_n32;
713                                 break;
714                             case kGray_8_SkColorType:
715                                 proc = &sample1;
716                                 fastProc = &copy;
717                                 break;
718                             case kRGB_565_SkColorType:
719                                 proc = &swizzle_gray_to_565;
720                                 break;
721                             default:
722                                 return nullptr;
723                         }
724                         break;
725                     default:
726                         return nullptr;
727                 }
728                 break;
729             case SkEncodedInfo::kGrayAlpha_Color:
730                 switch (dstInfo.colorType()) {
731                     case kRGBA_8888_SkColorType:
732                     case kBGRA_8888_SkColorType:
733                         if (premultiply) {
734                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
735                                 proc = &SkipLeadingGrayAlphaZerosThen
736                                         <swizzle_grayalpha_to_n32_premul>;
737                                 fastProc = &SkipLeadingGrayAlphaZerosThen
738                                         <fast_swizzle_grayalpha_to_n32_premul>;
739                             } else {
740                                 proc = &swizzle_grayalpha_to_n32_premul;
741                                 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
742                             }
743                         } else {
744                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
745                                 proc = &SkipLeadingGrayAlphaZerosThen
746                                         <swizzle_grayalpha_to_n32_unpremul>;
747                                 fastProc = &SkipLeadingGrayAlphaZerosThen
748                                         <fast_swizzle_grayalpha_to_n32_unpremul>;
749                             } else {
750                                 proc = &swizzle_grayalpha_to_n32_unpremul;
751                                 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
752                             }
753                         }
754                         break;
755                     default:
756                         return nullptr;
757                 }
758                 break;
759             case SkEncodedInfo::kPalette_Color:
760                 // We assume that the color table is premultiplied and swizzled
761                 // as desired.
762                 switch (encodedInfo.bitsPerComponent()) {
763                     case 1:
764                     case 2:
765                     case 4:
766                         switch (dstInfo.colorType()) {
767                             case kRGBA_8888_SkColorType:
768                             case kBGRA_8888_SkColorType:
769                                 proc = &swizzle_small_index_to_n32;
770                                 break;
771                             case kRGB_565_SkColorType:
772                                 proc = &swizzle_small_index_to_565;
773                                 break;
774                             case kIndex_8_SkColorType:
775                                 proc = &swizzle_small_index_to_index;
776                                 break;
777                             default:
778                                 return nullptr;
779                         }
780                         break;
781                     case 8:
782                         switch (dstInfo.colorType()) {
783                             case kRGBA_8888_SkColorType:
784                             case kBGRA_8888_SkColorType:
785                                 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
786                                     proc = &swizzle_index_to_n32_skipZ;
787                                 } else {
788                                     proc = &swizzle_index_to_n32;
789                                 }
790                                 break;
791                             case kRGB_565_SkColorType:
792                                 proc = &swizzle_index_to_565;
793                                 break;
794                             case kIndex_8_SkColorType:
795                                 proc = &sample1;
796                                 fastProc = &copy;
797                                 break;
798                             default:
799                                 return nullptr;
800                         }
801                         break;
802                     default:
803                         return nullptr;
804                 }
805                 break;
806             case SkEncodedInfo::kRGB_Color:
807                 switch (dstInfo.colorType()) {
808                     case kRGBA_8888_SkColorType:
809                         proc = &swizzle_rgb_to_rgba;
810                         fastProc = &fast_swizzle_rgb_to_rgba;
811                         break;
812                     case kBGRA_8888_SkColorType:
813                         proc = &swizzle_rgb_to_bgra;
814                         fastProc = &fast_swizzle_rgb_to_bgra;
815                         break;
816                     case kRGB_565_SkColorType:
817                         proc = &swizzle_rgb_to_565;
818                         break;
819                     default:
820                         return nullptr;
821                 }
822                 break;
823             case SkEncodedInfo::kRGBA_Color:
824                 switch (dstInfo.colorType()) {
825                     case kRGBA_8888_SkColorType:
826                         if (premultiply) {
827                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
828                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
829                                 fastProc = &SkipLeading8888ZerosThen
830                                         <fast_swizzle_rgba_to_rgba_premul>;
831                             } else {
832                                 proc = &swizzle_rgba_to_rgba_premul;
833                                 fastProc = &fast_swizzle_rgba_to_rgba_premul;
834                             }
835                         } else {
836                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
837                                 proc = &SkipLeading8888ZerosThen<sample4>;
838                                 fastProc = &SkipLeading8888ZerosThen<copy>;
839                             } else {
840                                 proc = &sample4;
841                                 fastProc = &copy;
842                             }
843                         }
844                         break;
845                     case kBGRA_8888_SkColorType:
846                         if (premultiply) {
847                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
848                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
849                                 fastProc = &SkipLeading8888ZerosThen
850                                         <fast_swizzle_rgba_to_bgra_premul>;
851                             } else {
852                                 proc = &swizzle_rgba_to_bgra_premul;
853                                 fastProc = &fast_swizzle_rgba_to_bgra_premul;
854                             }
855                         } else {
856                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
857                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
858                                 fastProc = &SkipLeading8888ZerosThen
859                                         <fast_swizzle_rgba_to_bgra_unpremul>;
860                             } else {
861                                 proc = &swizzle_rgba_to_bgra_unpremul;
862                                 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
863                             }
864                         }
865                         break;
866                     default:
867                         return nullptr;
868                 }
869                 break;
870             case SkEncodedInfo::kBGR_Color:
871                 switch (dstInfo.colorType()) {
872                     case kBGRA_8888_SkColorType:
873                         proc = &swizzle_rgb_to_rgba;
874                         fastProc = &fast_swizzle_rgb_to_rgba;
875                         break;
876                     case kRGBA_8888_SkColorType:
877                         proc = &swizzle_rgb_to_bgra;
878                         fastProc = &fast_swizzle_rgb_to_bgra;
879                         break;
880                     case kRGB_565_SkColorType:
881                         proc = &swizzle_bgr_to_565;
882                         break;
883                     default:
884                         return nullptr;
885                 }
886                 break;
887             case SkEncodedInfo::kBGRX_Color:
888                 switch (dstInfo.colorType()) {
889                     case kBGRA_8888_SkColorType:
890                         proc = &swizzle_rgb_to_rgba;
891                         break;
892                     case kRGBA_8888_SkColorType:
893                         proc = &swizzle_rgb_to_bgra;
894                         break;
895                     case kRGB_565_SkColorType:
896                         proc = &swizzle_bgr_to_565;
897                         break;
898                     default:
899                         return nullptr;
900                 }
901                 break;
902             case SkEncodedInfo::kBGRA_Color:
903                 switch (dstInfo.colorType()) {
904                     case kBGRA_8888_SkColorType:
905                         if (premultiply) {
906                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
907                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
908                                 fastProc = &SkipLeading8888ZerosThen
909                                         <fast_swizzle_rgba_to_rgba_premul>;
910                             } else {
911                                 proc = &swizzle_rgba_to_rgba_premul;
912                                 fastProc = &fast_swizzle_rgba_to_rgba_premul;
913                             }
914                         } else {
915                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
916                                 proc = &SkipLeading8888ZerosThen<sample4>;
917                                 fastProc = &SkipLeading8888ZerosThen<copy>;
918                             } else {
919                                 proc = &sample4;
920                                 fastProc = &copy;
921                             }
922                         }
923                         break;
924                     case kRGBA_8888_SkColorType:
925                         if (premultiply) {
926                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
927                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
928                                 fastProc = &SkipLeading8888ZerosThen
929                                         <fast_swizzle_rgba_to_bgra_premul>;
930                             } else {
931                                 proc = &swizzle_rgba_to_bgra_premul;
932                                 fastProc = &fast_swizzle_rgba_to_bgra_premul;
933                             }
934                         } else {
935                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
936                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
937                                 fastProc = &SkipLeading8888ZerosThen
938                                         <fast_swizzle_rgba_to_bgra_unpremul>;
939                             } else {
940                                 proc = &swizzle_rgba_to_bgra_unpremul;
941                                 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
942                             }
943                         }
944                         break;
945                     default:
946                         return nullptr;
947                 }
948                 break;
949             case SkEncodedInfo::kInvertedCMYK_Color:
950                 switch (dstInfo.colorType()) {
951                     case kRGBA_8888_SkColorType:
952                         proc = &swizzle_cmyk_to_rgba;
953                         fastProc = &fast_swizzle_cmyk_to_rgba;
954                         break;
955                     case kBGRA_8888_SkColorType:
956                         proc = &swizzle_cmyk_to_bgra;
957                         fastProc = &fast_swizzle_cmyk_to_bgra;
958                         break;
959                     case kRGB_565_SkColorType:
960                         proc = &swizzle_cmyk_to_565;
961                         break;
962                     default:
963                         return nullptr;
964                 }
965                 break;
966             default:
967                 return nullptr;
968         }
969     }
970 
971     int srcBPP;
972     const int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
973     if (preSwizzled) {
974         srcBPP = dstBPP;
975     } else {
976         // Store bpp in bytes if it is an even multiple, otherwise use bits
977         uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
978         srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
979     }
980 
981     int srcOffset = 0;
982     int srcWidth = dstInfo.width();
983     int dstOffset = 0;
984     int dstWidth = srcWidth;
985     if (options.fSubset) {
986         // We do not currently support subset decodes for image types that may have
987         // frames (gif).
988         SkASSERT(!frame);
989         srcOffset = options.fSubset->left();
990         srcWidth = options.fSubset->width();
991         dstWidth = srcWidth;
992     } else if (frame) {
993         dstOffset = frame->left();
994         srcWidth = frame->width();
995     }
996 
997     return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
998             srcBPP, dstBPP);
999 }
1000 
SkSwizzler(RowProc fastProc,RowProc proc,const SkPMColor * ctable,int srcOffset,int srcWidth,int dstOffset,int dstWidth,int srcBPP,int dstBPP)1001 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1002         int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1003     : fFastProc(fastProc)
1004     , fSlowProc(proc)
1005     , fActualProc(fFastProc ? fFastProc : fSlowProc)
1006     , fColorTable(ctable)
1007     , fSrcOffset(srcOffset)
1008     , fDstOffset(dstOffset)
1009     , fSrcOffsetUnits(srcOffset * srcBPP)
1010     , fDstOffsetBytes(dstOffset * dstBPP)
1011     , fSrcWidth(srcWidth)
1012     , fDstWidth(dstWidth)
1013     , fSwizzleWidth(srcWidth)
1014     , fAllocatedWidth(dstWidth)
1015     , fSampleX(1)
1016     , fSrcBPP(srcBPP)
1017     , fDstBPP(dstBPP)
1018 {}
1019 
onSetSampleX(int sampleX)1020 int SkSwizzler::onSetSampleX(int sampleX) {
1021     SkASSERT(sampleX > 0);
1022 
1023     fSampleX = sampleX;
1024     fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
1025     fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
1026     fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
1027     fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
1028 
1029     // The optimized swizzler functions do not support sampling.  Sampled swizzles
1030     // are already fast because they skip pixels.  We haven't seen a situation
1031     // where speeding up sampling has a significant impact on total decode time.
1032     if (1 == fSampleX && fFastProc) {
1033         fActualProc = fFastProc;
1034     } else {
1035         fActualProc = fSlowProc;
1036     }
1037 
1038     return fAllocatedWidth;
1039 }
1040 
swizzle(void * dst,const uint8_t * SK_RESTRICT src)1041 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
1042     SkASSERT(nullptr != dst && nullptr != src);
1043     fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
1044             fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
1045 }
1046