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