• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkCodecPriv.h"
9 #include "SkColorData.h"
10 #include "SkHalf.h"
11 #include "SkOpts.h"
12 #include "SkSwizzler.h"
13 #include "SkTemplates.h"
14 
15 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
16     #include "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, 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, 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, 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, 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, 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::kGrayAlpha_Color:
868             switch (dstInfo.colorType()) {
869                 case kRGBA_8888_SkColorType:
870                 case kBGRA_8888_SkColorType:
871                     if (premultiply) {
872                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
873                             proc = &SkipLeadingGrayAlphaZerosThen
874                                     <swizzle_grayalpha_to_n32_premul>;
875                             fastProc = &SkipLeadingGrayAlphaZerosThen
876                                     <fast_swizzle_grayalpha_to_n32_premul>;
877                         } else {
878                             proc = &swizzle_grayalpha_to_n32_premul;
879                             fastProc = &fast_swizzle_grayalpha_to_n32_premul;
880                         }
881                     } else {
882                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
883                             proc = &SkipLeadingGrayAlphaZerosThen
884                                     <swizzle_grayalpha_to_n32_unpremul>;
885                             fastProc = &SkipLeadingGrayAlphaZerosThen
886                                     <fast_swizzle_grayalpha_to_n32_unpremul>;
887                         } else {
888                             proc = &swizzle_grayalpha_to_n32_unpremul;
889                             fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
890                         }
891                     }
892                     break;
893                 case kAlpha_8_SkColorType:
894                     proc = &swizzle_grayalpha_to_a8;
895                     break;
896                 default:
897                     return nullptr;
898             }
899             break;
900         case SkEncodedInfo::kPalette_Color:
901             // We assume that the color table is premultiplied and swizzled
902             // as desired.
903             switch (encodedInfo.bitsPerComponent()) {
904                 case 1:
905                 case 2:
906                 case 4:
907                     switch (dstInfo.colorType()) {
908                         case kRGBA_8888_SkColorType:
909                         case kBGRA_8888_SkColorType:
910                             proc = &swizzle_small_index_to_n32;
911                             break;
912                         case kRGB_565_SkColorType:
913                             proc = &swizzle_small_index_to_565;
914                             break;
915                         default:
916                             return nullptr;
917                     }
918                     break;
919                 case 8:
920                     switch (dstInfo.colorType()) {
921                         case kRGBA_8888_SkColorType:
922                         case kBGRA_8888_SkColorType:
923                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
924                                 proc = &swizzle_index_to_n32_skipZ;
925                             } else {
926                                 proc = &swizzle_index_to_n32;
927                             }
928                             break;
929                         case kRGB_565_SkColorType:
930                             proc = &swizzle_index_to_565;
931                             break;
932                         default:
933                             return nullptr;
934                     }
935                     break;
936                 default:
937                     return nullptr;
938             }
939             break;
940         case SkEncodedInfo::kRGB_Color:
941             switch (dstInfo.colorType()) {
942                 case kRGBA_8888_SkColorType:
943                     if (16 == encodedInfo.bitsPerComponent()) {
944                         proc = &swizzle_rgb16_to_rgba;
945                         break;
946                     }
947 
948                     SkASSERT(8 == encodedInfo.bitsPerComponent());
949                     proc = &swizzle_rgb_to_rgba;
950                     fastProc = &fast_swizzle_rgb_to_rgba;
951                     break;
952                 case kBGRA_8888_SkColorType:
953                     if (16 == encodedInfo.bitsPerComponent()) {
954                         proc = &swizzle_rgb16_to_bgra;
955                         break;
956                     }
957 
958                     SkASSERT(8 == encodedInfo.bitsPerComponent());
959                     proc = &swizzle_rgb_to_bgra;
960                     fastProc = &fast_swizzle_rgb_to_bgra;
961                     break;
962                 case kRGB_565_SkColorType:
963                     if (16 == encodedInfo.bitsPerComponent()) {
964                         proc = &swizzle_rgb16_to_565;
965                         break;
966                     }
967 
968                     proc = &swizzle_rgb_to_565;
969                     break;
970                 default:
971                     return nullptr;
972             }
973             break;
974         case SkEncodedInfo::kRGBA_Color:
975             switch (dstInfo.colorType()) {
976                 case kRGBA_8888_SkColorType:
977                     if (16 == encodedInfo.bitsPerComponent()) {
978                         proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
979                                              &swizzle_rgba16_to_rgba_unpremul;
980                         break;
981                     }
982 
983                     SkASSERT(8 == encodedInfo.bitsPerComponent());
984                     if (premultiply) {
985                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
986                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
987                             fastProc = &SkipLeading8888ZerosThen
988                                     <fast_swizzle_rgba_to_rgba_premul>;
989                         } else {
990                             proc = &swizzle_rgba_to_rgba_premul;
991                             fastProc = &fast_swizzle_rgba_to_rgba_premul;
992                         }
993                     } else {
994                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
995                             proc = &SkipLeading8888ZerosThen<sample4>;
996                             fastProc = &SkipLeading8888ZerosThen<copy>;
997                         } else {
998                             proc = &sample4;
999                             fastProc = &copy;
1000                         }
1001                     }
1002                     break;
1003                 case kBGRA_8888_SkColorType:
1004                     if (16 == encodedInfo.bitsPerComponent()) {
1005                         proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
1006                                              &swizzle_rgba16_to_bgra_unpremul;
1007                         break;
1008                     }
1009 
1010                     SkASSERT(8 == encodedInfo.bitsPerComponent());
1011                     if (premultiply) {
1012                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1013                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
1014                             fastProc = &SkipLeading8888ZerosThen
1015                                     <fast_swizzle_rgba_to_bgra_premul>;
1016                         } else {
1017                             proc = &swizzle_rgba_to_bgra_premul;
1018                             fastProc = &fast_swizzle_rgba_to_bgra_premul;
1019                         }
1020                     } else {
1021                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1022                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
1023                             fastProc = &SkipLeading8888ZerosThen
1024                                     <fast_swizzle_rgba_to_bgra_unpremul>;
1025                         } else {
1026                             proc = &swizzle_rgba_to_bgra_unpremul;
1027                             fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
1028                         }
1029                     }
1030                     break;
1031                 default:
1032                     return nullptr;
1033             }
1034             break;
1035         case SkEncodedInfo::kBGR_Color:
1036             switch (dstInfo.colorType()) {
1037                 case kBGRA_8888_SkColorType:
1038                     proc = &swizzle_rgb_to_rgba;
1039                     fastProc = &fast_swizzle_rgb_to_rgba;
1040                     break;
1041                 case kRGBA_8888_SkColorType:
1042                     proc = &swizzle_rgb_to_bgra;
1043                     fastProc = &fast_swizzle_rgb_to_bgra;
1044                     break;
1045                 case kRGB_565_SkColorType:
1046                     proc = &swizzle_bgr_to_565;
1047                     break;
1048                 default:
1049                     return nullptr;
1050             }
1051             break;
1052         case SkEncodedInfo::kBGRX_Color:
1053             switch (dstInfo.colorType()) {
1054                 case kBGRA_8888_SkColorType:
1055                     proc = &swizzle_rgb_to_rgba;
1056                     break;
1057                 case kRGBA_8888_SkColorType:
1058                     proc = &swizzle_rgb_to_bgra;
1059                     break;
1060                 case kRGB_565_SkColorType:
1061                     proc = &swizzle_bgr_to_565;
1062                     break;
1063                 default:
1064                     return nullptr;
1065             }
1066             break;
1067         case SkEncodedInfo::kBGRA_Color:
1068             switch (dstInfo.colorType()) {
1069                 case kBGRA_8888_SkColorType:
1070                     if (premultiply) {
1071                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1072                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
1073                             fastProc = &SkipLeading8888ZerosThen
1074                                     <fast_swizzle_rgba_to_rgba_premul>;
1075                         } else {
1076                             proc = &swizzle_rgba_to_rgba_premul;
1077                             fastProc = &fast_swizzle_rgba_to_rgba_premul;
1078                         }
1079                     } else {
1080                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1081                             proc = &SkipLeading8888ZerosThen<sample4>;
1082                             fastProc = &SkipLeading8888ZerosThen<copy>;
1083                         } else {
1084                             proc = &sample4;
1085                             fastProc = &copy;
1086                         }
1087                     }
1088                     break;
1089                 case kRGBA_8888_SkColorType:
1090                     if (premultiply) {
1091                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1092                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
1093                             fastProc = &SkipLeading8888ZerosThen
1094                                     <fast_swizzle_rgba_to_bgra_premul>;
1095                         } else {
1096                             proc = &swizzle_rgba_to_bgra_premul;
1097                             fastProc = &fast_swizzle_rgba_to_bgra_premul;
1098                         }
1099                     } else {
1100                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1101                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
1102                             fastProc = &SkipLeading8888ZerosThen
1103                                     <fast_swizzle_rgba_to_bgra_unpremul>;
1104                         } else {
1105                             proc = &swizzle_rgba_to_bgra_unpremul;
1106                             fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
1107                         }
1108                     }
1109                     break;
1110                 default:
1111                     return nullptr;
1112             }
1113             break;
1114         case SkEncodedInfo::kInvertedCMYK_Color:
1115             switch (dstInfo.colorType()) {
1116                 case kRGBA_8888_SkColorType:
1117                     proc = &swizzle_cmyk_to_rgba;
1118                     fastProc = &fast_swizzle_cmyk_to_rgba;
1119                     break;
1120                 case kBGRA_8888_SkColorType:
1121                     proc = &swizzle_cmyk_to_bgra;
1122                     fastProc = &fast_swizzle_cmyk_to_bgra;
1123                     break;
1124                 case kRGB_565_SkColorType:
1125                     proc = &swizzle_cmyk_to_565;
1126                     break;
1127                 default:
1128                     return nullptr;
1129             }
1130             break;
1131         default:
1132             return nullptr;
1133     }
1134 
1135     // Store bpp in bytes if it is an even multiple, otherwise use bits
1136     uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
1137     int srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
1138     int dstBPP = dstInfo.bytesPerPixel();
1139     return Make(dstInfo, fastProc, proc, ctable, srcBPP, dstBPP, options, frame);
1140 }
1141 
Make(const SkImageInfo & dstInfo,RowProc fastProc,RowProc proc,const SkPMColor * ctable,int srcBPP,int dstBPP,const SkCodec::Options & options,const SkIRect * frame)1142 std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkImageInfo& dstInfo,
1143         RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcBPP,
1144         int dstBPP, const SkCodec::Options& options, const SkIRect* frame) {
1145     int srcOffset = 0;
1146     int srcWidth = dstInfo.width();
1147     int dstOffset = 0;
1148     int dstWidth = srcWidth;
1149     if (options.fSubset) {
1150         // We do not currently support subset decodes for image types that may have
1151         // frames (gif).
1152         SkASSERT(!frame);
1153         srcOffset = options.fSubset->left();
1154         srcWidth = options.fSubset->width();
1155         dstWidth = srcWidth;
1156     } else if (frame) {
1157         dstOffset = frame->left();
1158         srcWidth = frame->width();
1159     }
1160 
1161     return std::unique_ptr<SkSwizzler>(new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth,
1162                                                       dstOffset, dstWidth, srcBPP, dstBPP));
1163 }
1164 
SkSwizzler(RowProc fastProc,RowProc proc,const SkPMColor * ctable,int srcOffset,int srcWidth,int dstOffset,int dstWidth,int srcBPP,int dstBPP)1165 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1166         int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1167     : fFastProc(fastProc)
1168     , fSlowProc(proc)
1169     , fActualProc(fFastProc ? fFastProc : fSlowProc)
1170     , fColorTable(ctable)
1171     , fSrcOffset(srcOffset)
1172     , fDstOffset(dstOffset)
1173     , fSrcOffsetUnits(srcOffset * srcBPP)
1174     , fDstOffsetBytes(dstOffset * dstBPP)
1175     , fSrcWidth(srcWidth)
1176     , fDstWidth(dstWidth)
1177     , fSwizzleWidth(srcWidth)
1178     , fAllocatedWidth(dstWidth)
1179     , fSampleX(1)
1180     , fSrcBPP(srcBPP)
1181     , fDstBPP(dstBPP)
1182 {}
1183 
onSetSampleX(int sampleX)1184 int SkSwizzler::onSetSampleX(int sampleX) {
1185     SkASSERT(sampleX > 0);
1186 
1187     fSampleX = sampleX;
1188     fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
1189     fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
1190     fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
1191     fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
1192 
1193     if (fDstOffsetBytes > 0) {
1194         const size_t dstSwizzleBytes   = fSwizzleWidth   * fDstBPP;
1195         const size_t dstAllocatedBytes = fAllocatedWidth * fDstBPP;
1196         if (fDstOffsetBytes + dstSwizzleBytes > dstAllocatedBytes) {
1197 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1198             SkAndroidFrameworkUtils::SafetyNetLog("118143775");
1199 #endif
1200             SkASSERT(dstSwizzleBytes < dstAllocatedBytes);
1201             fDstOffsetBytes = dstAllocatedBytes - dstSwizzleBytes;
1202         }
1203     }
1204 
1205     // The optimized swizzler functions do not support sampling.  Sampled swizzles
1206     // are already fast because they skip pixels.  We haven't seen a situation
1207     // where speeding up sampling has a significant impact on total decode time.
1208     if (1 == fSampleX && fFastProc) {
1209         fActualProc = fFastProc;
1210     } else {
1211         fActualProc = fSlowProc;
1212     }
1213 
1214     return fAllocatedWidth;
1215 }
1216 
swizzle(void * dst,const uint8_t * SK_RESTRICT src)1217 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
1218     SkASSERT(nullptr != dst && nullptr != src);
1219     fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
1220             fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
1221 }
1222