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