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