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