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