xref: /aosp_15_r20/external/skia/src/codec/SkSwizzler.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "include/private/base/SkTemplates.h"
21 #include "src/base/SkHalf.h"
22 #include "src/codec/SkCodecPriv.h"
23 #include "src/core/SkSwizzlePriv.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] = SkPackARGB32(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] = SkPackARGB32(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] = SkPackARGB32(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,const SkIRect * frame)792 std::unique_ptr<SkSwizzler> SkSwizzler::MakeSimple(int srcBPP,
793                                                    const SkImageInfo& dstInfo,
794                                                    const SkCodec::Options& options,
795                                                    const SkIRect* frame) {
796     RowProc proc = nullptr;
797     switch (srcBPP) {
798         case 1:     // kGray_8_SkColorType
799             proc = &sample1;
800             break;
801         case 2:     // kRGB_565_SkColorType
802             proc = &sample2;
803             break;
804         case 4:     // kRGBA_8888_SkColorType
805                     // kBGRA_8888_SkColorType
806                     // kRGBA_1010102_SkColorType
807             proc = &sample4;
808             break;
809         case 6:     // 16 bit PNG no alpha
810             proc = &sample6;
811             break;
812         case 8:     // 16 bit PNG with alpha
813             proc = &sample8;
814             break;
815         default:
816             return nullptr;
817     }
818 
819     return Make(dstInfo,
820                 &copy,
821                 proc,
822                 nullptr /*ctable*/,
823                 srcBPP,
824                 dstInfo.bytesPerPixel(),
825                 options,
826                 frame);
827 }
828 
Make(const SkEncodedInfo & encodedInfo,const SkPMColor * ctable,const SkImageInfo & dstInfo,const SkCodec::Options & options,const SkIRect * frame)829 std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkEncodedInfo& encodedInfo,
830                                              const SkPMColor* ctable,
831                                              const SkImageInfo& dstInfo,
832                                              const SkCodec::Options& options,
833                                              const SkIRect* frame) {
834     if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
835         return nullptr;
836     }
837 
838     RowProc fastProc = nullptr;
839     RowProc proc = nullptr;
840     SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
841     const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
842             (kPremul_SkAlphaType == dstInfo.alphaType());
843 
844     switch (encodedInfo.color()) {
845         case SkEncodedInfo::kGray_Color:
846             switch (encodedInfo.bitsPerComponent()) {
847                 case 1:
848                     switch (dstInfo.colorType()) {
849                         case kRGBA_8888_SkColorType:
850                         case kBGRA_8888_SkColorType:
851                             proc = &swizzle_bit_to_n32;
852                             break;
853                         case kRGB_565_SkColorType:
854                             proc = &swizzle_bit_to_565;
855                             break;
856                         case kGray_8_SkColorType:
857                             proc = &swizzle_bit_to_grayscale;
858                             break;
859                         case kRGBA_F16_SkColorType:
860                             proc = &swizzle_bit_to_f16;
861                             break;
862                         default:
863                             return nullptr;
864                     }
865                     break;
866                 case 8:
867                     switch (dstInfo.colorType()) {
868                         case kRGBA_8888_SkColorType:
869                         case kBGRA_8888_SkColorType:
870                             proc = &swizzle_gray_to_n32;
871                             fastProc = &fast_swizzle_gray_to_n32;
872                             break;
873                         case kGray_8_SkColorType:
874                             proc = &sample1;
875                             fastProc = &copy;
876                             break;
877                         case kRGB_565_SkColorType:
878                             proc = &swizzle_gray_to_565;
879                             break;
880                         default:
881                             return nullptr;
882                     }
883                     break;
884                 default:
885                     return nullptr;
886             }
887             break;
888         case SkEncodedInfo::kXAlpha_Color:
889         case SkEncodedInfo::kGrayAlpha_Color:
890             switch (dstInfo.colorType()) {
891                 case kRGBA_8888_SkColorType:
892                 case kBGRA_8888_SkColorType:
893                     if (premultiply) {
894                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
895                             proc = &SkipLeadingGrayAlphaZerosThen
896                                     <swizzle_grayalpha_to_n32_premul>;
897                             fastProc = &SkipLeadingGrayAlphaZerosThen
898                                     <fast_swizzle_grayalpha_to_n32_premul>;
899                         } else {
900                             proc = &swizzle_grayalpha_to_n32_premul;
901                             fastProc = &fast_swizzle_grayalpha_to_n32_premul;
902                         }
903                     } else {
904                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
905                             proc = &SkipLeadingGrayAlphaZerosThen
906                                     <swizzle_grayalpha_to_n32_unpremul>;
907                             fastProc = &SkipLeadingGrayAlphaZerosThen
908                                     <fast_swizzle_grayalpha_to_n32_unpremul>;
909                         } else {
910                             proc = &swizzle_grayalpha_to_n32_unpremul;
911                             fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
912                         }
913                     }
914                     break;
915                 case kAlpha_8_SkColorType:
916                     proc = &swizzle_grayalpha_to_a8;
917                     break;
918                 default:
919                     return nullptr;
920             }
921             break;
922         case SkEncodedInfo::kPalette_Color:
923             // We assume that the color table is premultiplied and swizzled
924             // as desired.
925             switch (encodedInfo.bitsPerComponent()) {
926                 case 1:
927                 case 2:
928                 case 4:
929                     switch (dstInfo.colorType()) {
930                         case kRGBA_8888_SkColorType:
931                         case kBGRA_8888_SkColorType:
932                             proc = &swizzle_small_index_to_n32;
933                             break;
934                         case kRGB_565_SkColorType:
935                             proc = &swizzle_small_index_to_565;
936                             break;
937                         default:
938                             return nullptr;
939                     }
940                     break;
941                 case 8:
942                     switch (dstInfo.colorType()) {
943                         case kRGBA_8888_SkColorType:
944                         case kBGRA_8888_SkColorType:
945                         case kBGR_101010x_XR_SkColorType:
946                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
947                                 proc = &swizzle_index_to_n32_skipZ;
948                             } else {
949                                 proc = &swizzle_index_to_n32;
950                             }
951                             break;
952                         case kRGB_565_SkColorType:
953                             proc = &swizzle_index_to_565;
954                             break;
955                         default:
956                             return nullptr;
957                     }
958                     break;
959                 default:
960                     return nullptr;
961             }
962             break;
963         case SkEncodedInfo::k565_Color:
964             // Treat 565 exactly like RGB (since it's still encoded as 8 bits per component).
965             // We just mark as 565 when we have a hint that there are only 5/6/5 "significant"
966             // bits in each channel.
967         case SkEncodedInfo::kRGB_Color:
968             switch (dstInfo.colorType()) {
969                 case kRGBA_8888_SkColorType:
970                     if (16 == encodedInfo.bitsPerComponent()) {
971                         proc = &swizzle_rgb16_to_rgba;
972                         break;
973                     }
974 
975                     SkASSERT(8 == encodedInfo.bitsPerComponent());
976                     proc = &swizzle_rgb_to_rgba;
977                     fastProc = &fast_swizzle_rgb_to_rgba;
978                     break;
979                 case kBGRA_8888_SkColorType:
980                     if (16 == encodedInfo.bitsPerComponent()) {
981                         proc = &swizzle_rgb16_to_bgra;
982                         break;
983                     }
984 
985                     SkASSERT(8 == encodedInfo.bitsPerComponent());
986                     proc = &swizzle_rgb_to_bgra;
987                     fastProc = &fast_swizzle_rgb_to_bgra;
988                     break;
989                 case kRGB_565_SkColorType:
990                     if (16 == encodedInfo.bitsPerComponent()) {
991                         proc = &swizzle_rgb16_to_565;
992                         break;
993                     }
994 
995                     proc = &swizzle_rgb_to_565;
996                     break;
997                 default:
998                     return nullptr;
999             }
1000             break;
1001         case SkEncodedInfo::kRGBA_Color:
1002             switch (dstInfo.colorType()) {
1003                 case kRGBA_8888_SkColorType:
1004                     if (16 == encodedInfo.bitsPerComponent()) {
1005                         proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
1006                                              &swizzle_rgba16_to_rgba_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_rgba_premul>;
1014                             fastProc = &SkipLeading8888ZerosThen
1015                                     <fast_swizzle_rgba_to_rgba_premul>;
1016                         } else {
1017                             proc = &swizzle_rgba_to_rgba_premul;
1018                             fastProc = &fast_swizzle_rgba_to_rgba_premul;
1019                         }
1020                     } else {
1021                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1022                             proc = &SkipLeading8888ZerosThen<sample4>;
1023                             fastProc = &SkipLeading8888ZerosThen<copy>;
1024                         } else {
1025                             proc = &sample4;
1026                             fastProc = &copy;
1027                         }
1028                     }
1029                     break;
1030                 case kBGRA_8888_SkColorType:
1031                     if (16 == encodedInfo.bitsPerComponent()) {
1032                         proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
1033                                              &swizzle_rgba16_to_bgra_unpremul;
1034                         break;
1035                     }
1036 
1037                     SkASSERT(8 == encodedInfo.bitsPerComponent());
1038                     if (premultiply) {
1039                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1040                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
1041                             fastProc = &SkipLeading8888ZerosThen
1042                                     <fast_swizzle_rgba_to_bgra_premul>;
1043                         } else {
1044                             proc = &swizzle_rgba_to_bgra_premul;
1045                             fastProc = &fast_swizzle_rgba_to_bgra_premul;
1046                         }
1047                     } else {
1048                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1049                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
1050                             fastProc = &SkipLeading8888ZerosThen
1051                                     <fast_swizzle_rgba_to_bgra_unpremul>;
1052                         } else {
1053                             proc = &swizzle_rgba_to_bgra_unpremul;
1054                             fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
1055                         }
1056                     }
1057                     break;
1058                 default:
1059                     return nullptr;
1060             }
1061             break;
1062         case SkEncodedInfo::kBGR_Color:
1063             switch (dstInfo.colorType()) {
1064                 case kBGRA_8888_SkColorType:
1065                     proc = &swizzle_rgb_to_rgba;
1066                     fastProc = &fast_swizzle_rgb_to_rgba;
1067                     break;
1068                 case kRGBA_8888_SkColorType:
1069                     proc = &swizzle_rgb_to_bgra;
1070                     fastProc = &fast_swizzle_rgb_to_bgra;
1071                     break;
1072                 case kRGB_565_SkColorType:
1073                     proc = &swizzle_bgr_to_565;
1074                     break;
1075                 default:
1076                     return nullptr;
1077             }
1078             break;
1079         case SkEncodedInfo::kBGRX_Color:
1080             switch (dstInfo.colorType()) {
1081                 case kBGRA_8888_SkColorType:
1082                     proc = &swizzle_rgb_to_rgba;
1083                     break;
1084                 case kRGBA_8888_SkColorType:
1085                     proc = &swizzle_rgb_to_bgra;
1086                     break;
1087                 case kRGB_565_SkColorType:
1088                     proc = &swizzle_bgr_to_565;
1089                     break;
1090                 default:
1091                     return nullptr;
1092             }
1093             break;
1094         case SkEncodedInfo::kBGRA_Color:
1095             switch (dstInfo.colorType()) {
1096                 case kBGRA_8888_SkColorType:
1097                     if (premultiply) {
1098                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1099                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
1100                             fastProc = &SkipLeading8888ZerosThen
1101                                     <fast_swizzle_rgba_to_rgba_premul>;
1102                         } else {
1103                             proc = &swizzle_rgba_to_rgba_premul;
1104                             fastProc = &fast_swizzle_rgba_to_rgba_premul;
1105                         }
1106                     } else {
1107                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1108                             proc = &SkipLeading8888ZerosThen<sample4>;
1109                             fastProc = &SkipLeading8888ZerosThen<copy>;
1110                         } else {
1111                             proc = &sample4;
1112                             fastProc = &copy;
1113                         }
1114                     }
1115                     break;
1116                 case kRGBA_8888_SkColorType:
1117                     if (premultiply) {
1118                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1119                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
1120                             fastProc = &SkipLeading8888ZerosThen
1121                                     <fast_swizzle_rgba_to_bgra_premul>;
1122                         } else {
1123                             proc = &swizzle_rgba_to_bgra_premul;
1124                             fastProc = &fast_swizzle_rgba_to_bgra_premul;
1125                         }
1126                     } else {
1127                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1128                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
1129                             fastProc = &SkipLeading8888ZerosThen
1130                                     <fast_swizzle_rgba_to_bgra_unpremul>;
1131                         } else {
1132                             proc = &swizzle_rgba_to_bgra_unpremul;
1133                             fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
1134                         }
1135                     }
1136                     break;
1137                 default:
1138                     return nullptr;
1139             }
1140             break;
1141         case SkEncodedInfo::kInvertedCMYK_Color:
1142             switch (dstInfo.colorType()) {
1143                 case kRGBA_8888_SkColorType:
1144                     proc = &swizzle_cmyk_to_rgba;
1145                     fastProc = &fast_swizzle_cmyk_to_rgba;
1146                     break;
1147                 case kBGRA_8888_SkColorType:
1148                     proc = &swizzle_cmyk_to_bgra;
1149                     fastProc = &fast_swizzle_cmyk_to_bgra;
1150                     break;
1151                 case kRGB_565_SkColorType:
1152                     proc = &swizzle_cmyk_to_565;
1153                     break;
1154                 default:
1155                     return nullptr;
1156             }
1157             break;
1158         default:
1159             return nullptr;
1160     }
1161 
1162     // Store bpp in bytes if it is an even multiple, otherwise use bits
1163     uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
1164     int srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
1165     int dstBPP = dstInfo.bytesPerPixel();
1166     return Make(dstInfo, fastProc, proc, ctable, srcBPP, dstBPP, options, frame);
1167 }
1168 
Make(const SkImageInfo & dstInfo,RowProc fastProc,RowProc proc,const SkPMColor * ctable,int srcBPP,int dstBPP,const SkCodec::Options & options,const SkIRect * frame)1169 std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkImageInfo& dstInfo,
1170         RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcBPP,
1171         int dstBPP, const SkCodec::Options& options, const SkIRect* frame) {
1172     int srcOffset = 0;
1173     int srcWidth = dstInfo.width();
1174     int dstOffset = 0;
1175     int dstWidth = srcWidth;
1176     if (options.fSubset) {
1177         // We do not currently support subset decodes for image types that may have
1178         // frames (gif).
1179         SkASSERT(!frame);
1180         srcOffset = options.fSubset->left();
1181         srcWidth = options.fSubset->width();
1182         dstWidth = srcWidth;
1183     } else if (frame) {
1184         dstOffset = frame->left();
1185         srcWidth = frame->width();
1186     }
1187 
1188     return std::unique_ptr<SkSwizzler>(new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth,
1189                                                       dstOffset, dstWidth, srcBPP, dstBPP));
1190 }
1191 
SkSwizzler(RowProc fastProc,RowProc proc,const SkPMColor * ctable,int srcOffset,int srcWidth,int dstOffset,int dstWidth,int srcBPP,int dstBPP)1192 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1193         int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1194     : fFastProc(fastProc)
1195     , fSlowProc(proc)
1196     , fActualProc(fFastProc ? fFastProc : fSlowProc)
1197     , fColorTable(ctable)
1198     , fSrcOffset(srcOffset)
1199     , fDstOffset(dstOffset)
1200     , fSrcOffsetUnits(srcOffset * srcBPP)
1201     , fDstOffsetBytes(dstOffset * dstBPP)
1202     , fSrcWidth(srcWidth)
1203     , fDstWidth(dstWidth)
1204     , fSwizzleWidth(srcWidth)
1205     , fAllocatedWidth(dstWidth)
1206     , fSampleX(1)
1207     , fSrcBPP(srcBPP)
1208     , fDstBPP(dstBPP)
1209 {}
1210 
onSetSampleX(int sampleX)1211 int SkSwizzler::onSetSampleX(int sampleX) {
1212     SkASSERT(sampleX > 0);
1213 
1214     fSampleX = sampleX;
1215     fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
1216     fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
1217     fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
1218 
1219     int frameSampleX = sampleX;
1220     if (fSrcWidth < fDstWidth) {
1221         // Although SkSampledCodec adjusted sampleX so that it will never be
1222         // larger than the width of the image (or subset, if applicable), it
1223         // doesn't account for the width of a subset frame (i.e. gif). As a
1224         // result, get_start_coord(sampleX) could result in fSrcOffsetUnits
1225         // being wider than fSrcWidth. Compute a sampling rate based on the
1226         // frame width to ensure that fSrcOffsetUnits is sensible.
1227         frameSampleX = fSrcWidth / fSwizzleWidth;
1228     }
1229     fSrcOffsetUnits = (get_start_coord(frameSampleX) + fSrcOffset) * fSrcBPP;
1230 
1231     if (fDstOffsetBytes > 0) {
1232         const size_t dstSwizzleBytes   = fSwizzleWidth   * fDstBPP;
1233         const size_t dstAllocatedBytes = fAllocatedWidth * fDstBPP;
1234         if (fDstOffsetBytes + dstSwizzleBytes > dstAllocatedBytes) {
1235 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1236             SkAndroidFrameworkUtils::SafetyNetLog("118143775");
1237 #endif
1238             SkASSERT(dstSwizzleBytes <= dstAllocatedBytes);
1239             fDstOffsetBytes = dstAllocatedBytes - dstSwizzleBytes;
1240         }
1241     }
1242 
1243     // The optimized swizzler functions do not support sampling.  Sampled swizzles
1244     // are already fast because they skip pixels.  We haven't seen a situation
1245     // where speeding up sampling has a significant impact on total decode time.
1246     if (1 == fSampleX && fFastProc) {
1247         fActualProc = fFastProc;
1248     } else {
1249         fActualProc = fSlowProc;
1250     }
1251 
1252     return fAllocatedWidth;
1253 }
1254 
swizzle(void * dst,const uint8_t * SK_RESTRICT src)1255 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
1256     SkASSERT(nullptr != dst && nullptr != src);
1257     fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
1258             fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
1259 }
1260