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