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