blob: 133736879f203e53e5962dab4a4530ad3f5f93f7 [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
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
msarett74114382015-03-16 11:55:18 -07008#include "SkCodecPriv.h"
scroggof24f2242015-03-03 08:59:20 -08009#include "SkColorPriv.h"
msaretta51e7782016-01-12 06:51:11 -080010#include "SkOpts.h"
scroggof24f2242015-03-03 08:59:20 -080011#include "SkSwizzler.h"
12#include "SkTemplates.h"
13
msarettbda86092016-01-19 10:40:12 -080014static 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);
emmaleer8f4ba762015-08-14 07:44:46 -070019
msarettbda86092016-01-19 10:40:12 -080020 memcpy(dst, src + offset, width * bpp);
21}
22
23static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
24 const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -070025 src += offset;
msarettbda86092016-01-19 10:40:12 -080026 uint8_t* dst8 = (uint8_t*) dst;
emmaleer8f4ba762015-08-14 07:44:46 -070027 for (int x = 0; x < width; x++) {
msarettbda86092016-01-19 10:40:12 -080028 dst8[x] = *src;
emmaleer8f4ba762015-08-14 07:44:46 -070029 src += deltaSrc;
30 }
emmaleer8f4ba762015-08-14 07:44:46 -070031}
32
msarettbda86092016-01-19 10:40:12 -080033static 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
43static 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}
msarett5406d6f2015-08-31 06:55:13 -070052
msarett99f567e2015-08-05 12:58:26 -070053// kBit
54// These routines exclusively choose between white and black
55
56#define GRAYSCALE_BLACK 0
57#define GRAYSCALE_WHITE 0xFF
58
emmaleer8f4ba762015-08-14 07:44:46 -070059
60// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -080061static void swizzle_bit_to_grayscale(
emmaleer8f4ba762015-08-14 07:44:46 -070062 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -070063 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
emmaleer8f4ba762015-08-14 07:44:46 -070064
msarett99f567e2015-08-05 12:58:26 -070065 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
66
emmaleer8f4ba762015-08-14 07:44:46 -070067 // 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;
msarett99f567e2015-08-05 12:58:26 -070079 }
msarett99f567e2015-08-05 12:58:26 -070080}
81
82#undef GRAYSCALE_BLACK
83#undef GRAYSCALE_WHITE
84
emmaleer8f4ba762015-08-14 07:44:46 -070085// same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -080086static void swizzle_bit_to_index(
emmaleer8f4ba762015-08-14 07:44:46 -070087 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -070088 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
msarett99f567e2015-08-05 12:58:26 -070089 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
90
emmaleer8f4ba762015-08-14 07:44:46 -070091 // 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);
msarett99f567e2015-08-05 12:58:26 -0700103 }
msarett99f567e2015-08-05 12:58:26 -0700104}
105
emmaleer8f4ba762015-08-14 07:44:46 -0700106// same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -0800107static void swizzle_bit_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700108 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700109 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
msarett99f567e2015-08-05 12:58:26 -0700110 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
111
emmaleer8f4ba762015-08-14 07:44:46 -0700112 // 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;
msarett99f567e2015-08-05 12:58:26 -0700124 }
msarett99f567e2015-08-05 12:58:26 -0700125}
126
scroggocc2feb12015-08-14 08:32:46 -0700127#define RGB565_BLACK 0
128#define RGB565_WHITE 0xFFFF
129
msaretta4970dc2016-01-11 07:23:23 -0800130static void swizzle_bit_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700131 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700132 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
scroggocc2feb12015-08-14 08:32:46 -0700133 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 }
scroggocc2feb12015-08-14 08:32:46 -0700148}
149
150#undef RGB565_BLACK
151#undef RGB565_WHITE
152
msarett74114382015-03-16 11:55:18 -0700153// kIndex1, kIndex2, kIndex4
154
msaretta4970dc2016-01-11 07:23:23 -0800155static void swizzle_small_index_to_index(
emmaleer8f4ba762015-08-14 07:44:46 -0700156 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700157 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett438b2ad2015-04-09 12:43:10 -0700158
msarett5406d6f2015-08-31 06:55:13 -0700159 uint8_t* dst = (uint8_t*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700160 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;
msarett5406d6f2015-08-31 06:55:13 -0700166
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;
msarett438b2ad2015-04-09 12:43:10 -0700173 }
msarett438b2ad2015-04-09 12:43:10 -0700174}
175
msaretta4970dc2016-01-11 07:23:23 -0800176static void swizzle_small_index_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700177 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700178 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
scroggocc2feb12015-08-14 08:32:46 -0700179
msarett5406d6f2015-08-31 06:55:13 -0700180 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]);
scroggocc2feb12015-08-14 08:32:46 -0700194 }
scroggocc2feb12015-08-14 08:32:46 -0700195}
196
msaretta4970dc2016-01-11 07:23:23 -0800197static void swizzle_small_index_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700198 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700199 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700200
msarett5406d6f2015-08-31 06:55:13 -0700201 SkPMColor* dst = (SkPMColor*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700202 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];
msarett5406d6f2015-08-31 06:55:13 -0700208
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];
msarett74114382015-03-16 11:55:18 -0700215 }
msarett74114382015-03-16 11:55:18 -0700216}
217
msarette16b04a2015-04-15 07:32:19 -0700218// kIndex
219
msaretta4970dc2016-01-11 07:23:23 -0800220static void swizzle_index_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700221 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700222 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700223
224 src += offset;
225 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700226 for (int x = 0; x < dstWidth; x++) {
227 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700228 dst[x] = c;
229 src += deltaSrc;
230 }
emmaleer8f4ba762015-08-14 07:44:46 -0700231}
232
msaretta4970dc2016-01-11 07:23:23 -0800233static void swizzle_index_to_n32_skipZ(
emmaleer8f4ba762015-08-14 07:44:46 -0700234 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700235 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700236
237 src += offset;
238 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700239 for (int x = 0; x < dstWidth; x++) {
240 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700241 if (c != 0) {
242 dst[x] = c;
243 }
244 src += deltaSrc;
245 }
emmaleer8f4ba762015-08-14 07:44:46 -0700246}
247
msaretta4970dc2016-01-11 07:23:23 -0800248static void swizzle_index_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700249 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700250 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700251 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700252 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700253 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700254 dst[x] = SkPixel32ToPixel16(ctable[*src]);
msarett5406d6f2015-08-31 06:55:13 -0700255 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700256 }
scroggoab60c5b2015-08-06 06:08:18 -0700257}
258
msarette16b04a2015-04-15 07:32:19 -0700259// kGray
260
msaretta4970dc2016-01-11 07:23:23 -0800261static void swizzle_gray_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700262 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700263 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarette16b04a2015-04-15 07:32:19 -0700264
emmaleer8f4ba762015-08-14 07:44:46 -0700265 src += offset;
msarette16b04a2015-04-15 07:32:19 -0700266 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700267 for (int x = 0; x < dstWidth; x++) {
268 dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
269 src += deltaSrc;
msarette16b04a2015-04-15 07:32:19 -0700270 }
msarette16b04a2015-04-15 07:32:19 -0700271}
272
msarett2eff71c2016-02-02 12:59:45 -0800273static 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
msaretta4970dc2016-01-11 07:23:23 -0800286static void swizzle_gray_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700287 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700288 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800289
emmaleer8f4ba762015-08-14 07:44:46 -0700290 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700291 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700292 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700293 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
msarett5406d6f2015-08-31 06:55:13 -0700294 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700295 }
scroggoab60c5b2015-08-06 06:08:18 -0700296}
297
msarett93e613d2016-02-03 10:44:46 -0800298// kGrayAlpha
299
300static 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
msarett1e060792016-02-03 11:17:43 -0800312static 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
msarett93e613d2016-02-03 10:44:46 -0800325static 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
msarett1e060792016-02-03 11:17:43 -0800338static 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
msarette16b04a2015-04-15 07:32:19 -0700351// kBGRX
352
msaretta4970dc2016-01-11 07:23:23 -0800353static void swizzle_bgrx_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700354 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700355 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700356
emmaleer8f4ba762015-08-14 07:44:46 -0700357 src += offset;
msarett74114382015-03-16 11:55:18 -0700358 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700359 for (int x = 0; x < dstWidth; x++) {
msarett74114382015-03-16 11:55:18 -0700360 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
emmaleer8f4ba762015-08-14 07:44:46 -0700361 src += deltaSrc;
msarett74114382015-03-16 11:55:18 -0700362 }
msarett74114382015-03-16 11:55:18 -0700363}
364
msaretta4970dc2016-01-11 07:23:23 -0800365static void swizzle_bgrx_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700366 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700367 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800368
scroggocc2feb12015-08-14 08:32:46 -0700369 src += offset;
370 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
371 for (int x = 0; x < dstWidth; x++) {
372 dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
373 src += deltaSrc;
374 }
scroggocc2feb12015-08-14 08:32:46 -0700375}
376
msarett74114382015-03-16 11:55:18 -0700377// kBGRA
378
msaretta4970dc2016-01-11 07:23:23 -0800379static void swizzle_bgra_to_n32_unpremul(
emmaleer8f4ba762015-08-14 07:44:46 -0700380 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700381 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700382
emmaleer8f4ba762015-08-14 07:44:46 -0700383 src += offset;
msarett74114382015-03-16 11:55:18 -0700384 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700385 for (int x = 0; x < dstWidth; x++) {
msarett74114382015-03-16 11:55:18 -0700386 uint8_t alpha = src[3];
msarett74114382015-03-16 11:55:18 -0700387 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
emmaleer8f4ba762015-08-14 07:44:46 -0700388 src += deltaSrc;
msarett74114382015-03-16 11:55:18 -0700389 }
msarett74114382015-03-16 11:55:18 -0700390}
391
msarettbda86092016-01-19 10:40:12 -0800392static void fast_swizzle_bgra_to_n32_unpremul(
393 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
394 const SkPMColor ctable[]) {
395
396 // This function must not be called if we are sampling. If we are not
397 // sampling, deltaSrc should equal bpp.
398 SkASSERT(deltaSrc == bpp);
399
msarettbda86092016-01-19 10:40:12 -0800400#ifdef SK_PMCOLOR_IS_RGBA
mtklein8bf7b792016-01-22 07:42:53 -0800401 SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
msarettbda86092016-01-19 10:40:12 -0800402#else
403 memcpy(dst, src + offset, width * bpp);
404#endif
405}
406
msaretta4970dc2016-01-11 07:23:23 -0800407static void swizzle_bgra_to_n32_premul(
emmaleer8f4ba762015-08-14 07:44:46 -0700408 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700409 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretteed039b2015-03-18 11:11:19 -0700410
emmaleer8f4ba762015-08-14 07:44:46 -0700411 src += offset;
msaretteed039b2015-03-18 11:11:19 -0700412 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700413 for (int x = 0; x < dstWidth; x++) {
msaretteed039b2015-03-18 11:11:19 -0700414 uint8_t alpha = src[3];
mtklein3d00db32016-01-11 06:16:26 -0800415 dst[x] = SkPremultiplyARGBInline(alpha, src[2], src[1], src[0]);
emmaleer8f4ba762015-08-14 07:44:46 -0700416 src += deltaSrc;
msaretteed039b2015-03-18 11:11:19 -0700417 }
msaretteed039b2015-03-18 11:11:19 -0700418}
419
msarett03108de2016-01-15 11:02:36 -0800420static void fast_swizzle_bgra_to_n32_premul(
421 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
422 const SkPMColor ctable[]) {
423
424 // This function must not be called if we are sampling. If we are not
425 // sampling, deltaSrc should equal bpp.
426 SkASSERT(deltaSrc == bpp);
427
428#ifdef SK_PMCOLOR_IS_RGBA
mtklein8bf7b792016-01-22 07:42:53 -0800429 SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
msarett03108de2016-01-15 11:02:36 -0800430#else
mtklein8bf7b792016-01-22 07:42:53 -0800431 SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
msarett03108de2016-01-15 11:02:36 -0800432#endif
433}
434
msarettbda86092016-01-19 10:40:12 -0800435// kRGB
msarett03108de2016-01-15 11:02:36 -0800436
msarettbda86092016-01-19 10:40:12 -0800437static void swizzle_rgb_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700438 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700439 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700440
emmaleer8f4ba762015-08-14 07:44:46 -0700441 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800442 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700443 for (int x = 0; x < dstWidth; x++) {
msarettf1b8b6a2016-01-22 09:54:21 -0800444 dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700445 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800446 }
scroggof24f2242015-03-03 08:59:20 -0800447}
448
msarettf1b8b6a2016-01-22 09:54:21 -0800449static void fast_swizzle_rgb_to_n32(
450 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
451 int offset, const SkPMColor ctable[]) {
msarett03108de2016-01-15 11:02:36 -0800452
msarettf1b8b6a2016-01-22 09:54:21 -0800453 // This function must not be called if we are sampling. If we are not
454 // sampling, deltaSrc should equal bpp.
455 SkASSERT(deltaSrc == bpp);
456
457#ifdef SK_PMCOLOR_IS_RGBA
458 SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
459#else
460 SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
461#endif
462}
msarett03108de2016-01-15 11:02:36 -0800463
msarettbda86092016-01-19 10:40:12 -0800464static void swizzle_rgb_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700465 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700466 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800467
emmaleer8f4ba762015-08-14 07:44:46 -0700468 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700469 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700470 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700471 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
msarett5406d6f2015-08-31 06:55:13 -0700472 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700473 }
scroggoab60c5b2015-08-06 06:08:18 -0700474}
475
scroggoab60c5b2015-08-06 06:08:18 -0700476// kRGBA
msarett03108de2016-01-15 11:02:36 -0800477
msaretta4970dc2016-01-11 07:23:23 -0800478static void swizzle_rgba_to_n32_premul(
emmaleer8f4ba762015-08-14 07:44:46 -0700479 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700480 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700481
emmaleer8f4ba762015-08-14 07:44:46 -0700482 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800483 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700484 for (int x = 0; x < dstWidth; x++) {
scroggof24f2242015-03-03 08:59:20 -0800485 unsigned alpha = src[3];
mtklein3d00db32016-01-11 06:16:26 -0800486 dst[x] = SkPremultiplyARGBInline(alpha, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700487 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800488 }
scroggof24f2242015-03-03 08:59:20 -0800489}
490
msaretta51e7782016-01-12 06:51:11 -0800491static void fast_swizzle_rgba_to_n32_premul(
492 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
493 int offset, const SkPMColor ctable[]) {
494
495 // This function must not be called if we are sampling. If we are not
496 // sampling, deltaSrc should equal bpp.
497 SkASSERT(deltaSrc == bpp);
498
499#ifdef SK_PMCOLOR_IS_RGBA
mtklein8bf7b792016-01-22 07:42:53 -0800500 SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
msaretta51e7782016-01-12 06:51:11 -0800501#else
mtklein8bf7b792016-01-22 07:42:53 -0800502 SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
msaretta51e7782016-01-12 06:51:11 -0800503#endif
504}
505
msaretta4970dc2016-01-11 07:23:23 -0800506static void swizzle_rgba_to_n32_unpremul(
emmaleer8f4ba762015-08-14 07:44:46 -0700507 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700508 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700509
emmaleer8f4ba762015-08-14 07:44:46 -0700510 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800511 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
emmaleer8f4ba762015-08-14 07:44:46 -0700512 for (int x = 0; x < dstWidth; x++) {
scroggof24f2242015-03-03 08:59:20 -0800513 unsigned alpha = src[3];
514 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700515 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800516 }
scroggof24f2242015-03-03 08:59:20 -0800517}
518
msarettbda86092016-01-19 10:40:12 -0800519static void fast_swizzle_rgba_to_n32_unpremul(
520 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
521 const SkPMColor ctable[]) {
522
523 // This function must not be called if we are sampling. If we are not
524 // sampling, deltaSrc should equal bpp.
525 SkASSERT(deltaSrc == bpp);
526
msarettbda86092016-01-19 10:40:12 -0800527#ifdef SK_PMCOLOR_IS_RGBA
528 memcpy(dst, src + offset, width * bpp);
529#else
mtklein8bf7b792016-01-22 07:42:53 -0800530 SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
msarettbda86092016-01-19 10:40:12 -0800531#endif
532}
533
scroggoef27d892015-10-23 09:29:22 -0700534// kCMYK
535//
536// CMYK is stored as four bytes per pixel.
537//
538// We will implement a crude conversion from CMYK -> RGB using formulas
539// from easyrgb.com.
540//
541// CMYK -> CMY
542// C = C * (1 - K) + K
543// M = M * (1 - K) + K
544// Y = Y * (1 - K) + K
545//
546// libjpeg actually gives us inverted CMYK, so we must subtract the
547// original terms from 1.
548// CMYK -> CMY
549// C = (1 - C) * (1 - (1 - K)) + (1 - K)
550// M = (1 - M) * (1 - (1 - K)) + (1 - K)
551// Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
552//
553// Simplifying the above expression.
554// CMYK -> CMY
555// C = 1 - CK
556// M = 1 - MK
557// Y = 1 - YK
558//
559// CMY -> RGB
560// R = (1 - C) * 255
561// G = (1 - M) * 255
562// B = (1 - Y) * 255
563//
564// Therefore the full conversion is below. This can be verified at
565// www.rapidtables.com (assuming inverted CMYK).
566// CMYK -> RGB
567// R = C * K * 255
568// G = M * K * 255
569// B = Y * K * 255
570//
571// As a final note, we have treated the CMYK values as if they were on
572// a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
573// We must divide each CMYK component by 255 to obtain the true conversion
574// we should perform.
575// CMYK -> RGB
576// R = C * K / 255
577// G = M * K / 255
578// B = Y * K / 255
msaretta4970dc2016-01-11 07:23:23 -0800579static void swizzle_cmyk_to_n32(
scroggoef27d892015-10-23 09:29:22 -0700580 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
581 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
582
583 src += offset;
584 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
585 for (int x = 0; x < dstWidth; x++) {
586 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
587 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
588 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
589
590 dst[x] = SkPackARGB32NoCheck(0xFF, r, g, b);
591 src += deltaSrc;
592 }
scroggoef27d892015-10-23 09:29:22 -0700593}
594
msarettc5c322d2016-02-08 13:26:25 -0800595static void fast_swizzle_cmyk_to_n32(
596 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
597 const SkPMColor ctable[]) {
598
599 // This function must not be called if we are sampling. If we are not
600 // sampling, deltaSrc should equal bpp.
601 SkASSERT(deltaSrc == bpp);
602
603#ifdef SK_PMCOLOR_IS_RGBA
604 SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
605#else
606 SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
607#endif
608}
609
msaretta4970dc2016-01-11 07:23:23 -0800610static void swizzle_cmyk_to_565(
scroggoef27d892015-10-23 09:29:22 -0700611 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
612 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
613
614 src += offset;
615 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
616 for (int x = 0; x < dstWidth; x++) {
617 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
618 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
619 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
620
621 dst[x] = SkPack888ToRGB16(r, g, b);
622 src += deltaSrc;
623 }
scroggoef27d892015-10-23 09:29:22 -0700624}
625
mtklein8604ca22016-01-11 13:13:55 -0800626template <SkSwizzler::RowProc proc>
msarett93e613d2016-02-03 10:44:46 -0800627void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
628 void* dst, const uint8_t* src, int width,
629 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
630 SkASSERT(!ctable);
631
632 const uint16_t* src16 = (const uint16_t*) (src + offset);
633 uint32_t* dst32 = (uint32_t*) dst;
634
635 // This may miss opportunities to skip when the output is premultiplied,
636 // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
637 while (width > 0 && *src16 == 0x0000) {
638 width--;
639 dst32++;
640 src16 += deltaSrc / 2;
641 }
642 proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
643}
644
645template <SkSwizzler::RowProc proc>
mtklein8604ca22016-01-11 13:13:55 -0800646void SkSwizzler::SkipLeading8888ZerosThen(
647 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
648 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
649 SkASSERT(!ctable);
650
651 auto src32 = (const uint32_t*)(src+offset);
652 auto dst32 = (uint32_t*)dstRow;
653
654 // This may miss opportunities to skip when the output is premultiplied,
655 // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
656 while (dstWidth > 0 && *src32 == 0x00000000) {
657 dstWidth--;
658 dst32++;
659 src32 += deltaSrc/4;
scroggof24f2242015-03-03 08:59:20 -0800660 }
mtklein8604ca22016-01-11 13:13:55 -0800661 proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
scroggof24f2242015-03-03 08:59:20 -0800662}
scroggof24f2242015-03-03 08:59:20 -0800663
msarett74114382015-03-16 11:55:18 -0700664SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
665 const SkPMColor* ctable,
msarettfdb47572015-10-13 12:50:14 -0700666 const SkImageInfo& dstInfo,
msarett5af4e0b2015-11-17 11:18:03 -0800667 const SkCodec::Options& options,
668 const SkIRect* frame) {
emmaleer8f4ba762015-08-14 07:44:46 -0700669 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
halcanary96fcdcc2015-08-27 07:41:13 -0700670 return nullptr;
scroggof24f2242015-03-03 08:59:20 -0800671 }
msarett74114382015-03-16 11:55:18 -0700672 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
halcanary96fcdcc2015-08-27 07:41:13 -0700673 && nullptr == ctable) {
674 return nullptr;
scroggof24f2242015-03-03 08:59:20 -0800675 }
msaretta51e7782016-01-12 06:51:11 -0800676 RowProc fastProc = nullptr;
halcanary96fcdcc2015-08-27 07:41:13 -0700677 RowProc proc = nullptr;
msarettfdb47572015-10-13 12:50:14 -0700678 SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
scroggof24f2242015-03-03 08:59:20 -0800679 switch (sc) {
msarett99f567e2015-08-05 12:58:26 -0700680 case kBit:
emmaleer8f4ba762015-08-14 07:44:46 -0700681 switch (dstInfo.colorType()) {
msarett99f567e2015-08-05 12:58:26 -0700682 case kN32_SkColorType:
683 proc = &swizzle_bit_to_n32;
684 break;
685 case kIndex_8_SkColorType:
686 proc = &swizzle_bit_to_index;
687 break;
scroggocc2feb12015-08-14 08:32:46 -0700688 case kRGB_565_SkColorType:
689 proc = &swizzle_bit_to_565;
690 break;
msarett99f567e2015-08-05 12:58:26 -0700691 case kGray_8_SkColorType:
692 proc = &swizzle_bit_to_grayscale;
693 break;
694 default:
695 break;
696 }
697 break;
msarett74114382015-03-16 11:55:18 -0700698 case kIndex1:
699 case kIndex2:
700 case kIndex4:
emmaleer8f4ba762015-08-14 07:44:46 -0700701 switch (dstInfo.colorType()) {
msarett74114382015-03-16 11:55:18 -0700702 case kN32_SkColorType:
703 proc = &swizzle_small_index_to_n32;
704 break;
scroggocc2feb12015-08-14 08:32:46 -0700705 case kRGB_565_SkColorType:
706 proc = &swizzle_small_index_to_565;
707 break;
msarett438b2ad2015-04-09 12:43:10 -0700708 case kIndex_8_SkColorType:
709 proc = &swizzle_small_index_to_index;
msaretteed039b2015-03-18 11:11:19 -0700710 break;
msarett74114382015-03-16 11:55:18 -0700711 default:
712 break;
713 }
714 break;
scroggof24f2242015-03-03 08:59:20 -0800715 case kIndex:
emmaleer8f4ba762015-08-14 07:44:46 -0700716 switch (dstInfo.colorType()) {
scroggof24f2242015-03-03 08:59:20 -0800717 case kN32_SkColorType:
scroggo95526622015-03-17 05:02:17 -0700718 // We assume the color premultiplied ctable (or not) as desired.
scroggoeb602a52015-07-09 08:16:03 -0700719 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
scroggof24f2242015-03-03 08:59:20 -0800720 proc = &swizzle_index_to_n32_skipZ;
msaretteed039b2015-03-18 11:11:19 -0700721 break;
scroggof24f2242015-03-03 08:59:20 -0800722 } else {
723 proc = &swizzle_index_to_n32;
msaretteed039b2015-03-18 11:11:19 -0700724 break;
scroggof24f2242015-03-03 08:59:20 -0800725 }
726 break;
scroggoab60c5b2015-08-06 06:08:18 -0700727 case kRGB_565_SkColorType:
728 proc = &swizzle_index_to_565;
729 break;
msarett438b2ad2015-04-09 12:43:10 -0700730 case kIndex_8_SkColorType:
msarettbda86092016-01-19 10:40:12 -0800731 proc = &sample1;
732 fastProc = &copy;
msaretteed039b2015-03-18 11:11:19 -0700733 break;
msarett74114382015-03-16 11:55:18 -0700734 default:
735 break;
736 }
737 break;
msarette16b04a2015-04-15 07:32:19 -0700738 case kGray:
emmaleer8f4ba762015-08-14 07:44:46 -0700739 switch (dstInfo.colorType()) {
msarette16b04a2015-04-15 07:32:19 -0700740 case kN32_SkColorType:
741 proc = &swizzle_gray_to_n32;
msarett2eff71c2016-02-02 12:59:45 -0800742 fastProc = &fast_swizzle_gray_to_n32;
msarette16b04a2015-04-15 07:32:19 -0700743 break;
744 case kGray_8_SkColorType:
msarettbda86092016-01-19 10:40:12 -0800745 proc = &sample1;
746 fastProc = &copy;
scroggoab60c5b2015-08-06 06:08:18 -0700747 break;
748 case kRGB_565_SkColorType:
749 proc = &swizzle_gray_to_565;
750 break;
msarette16b04a2015-04-15 07:32:19 -0700751 default:
752 break;
753 }
754 break;
msarett93e613d2016-02-03 10:44:46 -0800755 case kGrayAlpha:
756 switch (dstInfo.colorType()) {
757 case kN32_SkColorType:
758 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
759 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
760 proc = &SkipLeadingGrayAlphaZerosThen
761 <swizzle_grayalpha_to_n32_unpremul>;
msarett1e060792016-02-03 11:17:43 -0800762 fastProc = &SkipLeadingGrayAlphaZerosThen
763 <fast_swizzle_grayalpha_to_n32_unpremul>;
msarett93e613d2016-02-03 10:44:46 -0800764 } else {
765 proc = &swizzle_grayalpha_to_n32_unpremul;
msarett1e060792016-02-03 11:17:43 -0800766 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
msarett93e613d2016-02-03 10:44:46 -0800767 }
768 } else {
769 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
770 proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>;
msarett1e060792016-02-03 11:17:43 -0800771 fastProc = &SkipLeadingGrayAlphaZerosThen
772 <fast_swizzle_grayalpha_to_n32_premul>;
msarett93e613d2016-02-03 10:44:46 -0800773 } else {
774 proc = &swizzle_grayalpha_to_n32_premul;
msarett1e060792016-02-03 11:17:43 -0800775 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
msarett93e613d2016-02-03 10:44:46 -0800776 }
777 }
778 break;
779 default:
780 break;
781 }
782 break;
msarett74114382015-03-16 11:55:18 -0700783 case kBGR:
784 case kBGRX:
emmaleer8f4ba762015-08-14 07:44:46 -0700785 switch (dstInfo.colorType()) {
msarett74114382015-03-16 11:55:18 -0700786 case kN32_SkColorType:
787 proc = &swizzle_bgrx_to_n32;
788 break;
scroggocc2feb12015-08-14 08:32:46 -0700789 case kRGB_565_SkColorType:
790 proc = &swizzle_bgrx_to_565;
791 break;
msarett74114382015-03-16 11:55:18 -0700792 default:
793 break;
794 }
795 break;
796 case kBGRA:
emmaleer8f4ba762015-08-14 07:44:46 -0700797 switch (dstInfo.colorType()) {
msarett74114382015-03-16 11:55:18 -0700798 case kN32_SkColorType:
msarett03108de2016-01-15 11:02:36 -0800799 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
800 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
801 proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_unpremul>;
msarettbda86092016-01-19 10:40:12 -0800802 fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_unpremul>;
msarett03108de2016-01-15 11:02:36 -0800803 } else {
msaretteed039b2015-03-18 11:11:19 -0700804 proc = &swizzle_bgra_to_n32_unpremul;
msarettbda86092016-01-19 10:40:12 -0800805 fastProc = &fast_swizzle_bgra_to_n32_unpremul;
msarett03108de2016-01-15 11:02:36 -0800806 }
807 } else {
808 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
809 proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>;
810 fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>;
811 } else {
msaretteed039b2015-03-18 11:11:19 -0700812 proc = &swizzle_bgra_to_n32_premul;
msarett03108de2016-01-15 11:02:36 -0800813 fastProc = &fast_swizzle_bgra_to_n32_premul;
814 }
msaretteed039b2015-03-18 11:11:19 -0700815 }
msarett74114382015-03-16 11:55:18 -0700816 break;
scroggof24f2242015-03-03 08:59:20 -0800817 default:
818 break;
819 }
820 break;
msarettbda86092016-01-19 10:40:12 -0800821 case kRGB:
emmaleer8f4ba762015-08-14 07:44:46 -0700822 switch (dstInfo.colorType()) {
scroggof24f2242015-03-03 08:59:20 -0800823 case kN32_SkColorType:
msarettbda86092016-01-19 10:40:12 -0800824 proc = &swizzle_rgb_to_n32;
msarettf1b8b6a2016-01-22 09:54:21 -0800825 fastProc = &fast_swizzle_rgb_to_n32;
scroggof24f2242015-03-03 08:59:20 -0800826 break;
scroggoab60c5b2015-08-06 06:08:18 -0700827 case kRGB_565_SkColorType:
msarettbda86092016-01-19 10:40:12 -0800828 proc = &swizzle_rgb_to_565;
msarettc5c322d2016-02-08 13:26:25 -0800829 break;
scroggof24f2242015-03-03 08:59:20 -0800830 default:
831 break;
832 }
833 break;
834 case kRGBA:
emmaleer8f4ba762015-08-14 07:44:46 -0700835 switch (dstInfo.colorType()) {
scroggof24f2242015-03-03 08:59:20 -0800836 case kN32_SkColorType:
emmaleer8f4ba762015-08-14 07:44:46 -0700837 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
mtklein8604ca22016-01-11 13:13:55 -0800838 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
839 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>;
msarettbda86092016-01-19 10:40:12 -0800840 fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_unpremul>;
mtklein8604ca22016-01-11 13:13:55 -0800841 } else {
842 proc = &swizzle_rgba_to_n32_unpremul;
msarettbda86092016-01-19 10:40:12 -0800843 fastProc = &fast_swizzle_rgba_to_n32_unpremul;
mtklein8604ca22016-01-11 13:13:55 -0800844 }
scroggof24f2242015-03-03 08:59:20 -0800845 } else {
scroggoeb602a52015-07-09 08:16:03 -0700846 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
mtklein8604ca22016-01-11 13:13:55 -0800847 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>;
msaretta51e7782016-01-12 06:51:11 -0800848 fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>;
scroggof24f2242015-03-03 08:59:20 -0800849 } else {
850 proc = &swizzle_rgba_to_n32_premul;
msaretta51e7782016-01-12 06:51:11 -0800851 fastProc = &fast_swizzle_rgba_to_n32_premul;
scroggof24f2242015-03-03 08:59:20 -0800852 }
853 }
854 break;
855 default:
856 break;
857 }
858 break;
scroggoef27d892015-10-23 09:29:22 -0700859 case kCMYK:
860 switch (dstInfo.colorType()) {
861 case kN32_SkColorType:
862 proc = &swizzle_cmyk_to_n32;
msarettc5c322d2016-02-08 13:26:25 -0800863 fastProc = &fast_swizzle_cmyk_to_n32;
scroggoef27d892015-10-23 09:29:22 -0700864 break;
865 case kRGB_565_SkColorType:
866 proc = &swizzle_cmyk_to_565;
867 break;
868 default:
869 break;
870 }
871 break;
msarettbda86092016-01-19 10:40:12 -0800872 case kNoOp8:
873 proc = &sample1;
874 fastProc = &copy;
875 break;
876 case kNoOp16:
877 proc = sample2;
878 fastProc = &copy;
879 break;
880 case kNoOp32:
881 proc = &sample4;
882 fastProc = &copy;
883 break;
scroggof24f2242015-03-03 08:59:20 -0800884 default:
885 break;
886 }
msarett74114382015-03-16 11:55:18 -0700887
msarettfdb47572015-10-13 12:50:14 -0700888 // Store bpp in bytes if it is an even multiple, otherwise use bits
msarett5af4e0b2015-11-17 11:18:03 -0800889 int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
890 int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
mtklein3d00db32016-01-11 06:16:26 -0800891
msarettfdb47572015-10-13 12:50:14 -0700892 int srcOffset = 0;
893 int srcWidth = dstInfo.width();
msarett5af4e0b2015-11-17 11:18:03 -0800894 int dstOffset = 0;
895 int dstWidth = srcWidth;
msarettfdb47572015-10-13 12:50:14 -0700896 if (options.fSubset) {
msarett5af4e0b2015-11-17 11:18:03 -0800897 // We do not currently support subset decodes for image types that may have
898 // frames (gif).
899 SkASSERT(!frame);
msarettfdb47572015-10-13 12:50:14 -0700900 srcOffset = options.fSubset->left();
901 srcWidth = options.fSubset->width();
msarett5af4e0b2015-11-17 11:18:03 -0800902 dstWidth = srcWidth;
903 } else if (frame) {
904 dstOffset = frame->left();
905 srcWidth = frame->width();
msarettfdb47572015-10-13 12:50:14 -0700906 }
emmaleer8f4ba762015-08-14 07:44:46 -0700907
msaretta51e7782016-01-12 06:51:11 -0800908 return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
909 srcBPP, dstBPP);
scroggof24f2242015-03-03 08:59:20 -0800910}
911
msaretta51e7782016-01-12 06:51:11 -0800912SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
913 int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
914 : fFastProc(fastProc)
msarett19032f72016-01-21 09:59:38 -0800915 , fSlowProc(proc)
916 , fActualProc(fFastProc ? fFastProc : fSlowProc)
scroggof24f2242015-03-03 08:59:20 -0800917 , fColorTable(ctable)
msarettfdb47572015-10-13 12:50:14 -0700918 , fSrcOffset(srcOffset)
msarett5af4e0b2015-11-17 11:18:03 -0800919 , fDstOffset(dstOffset)
920 , fSrcOffsetUnits(srcOffset * srcBPP)
921 , fDstOffsetBytes(dstOffset * dstBPP)
922 , fSrcWidth(srcWidth)
923 , fDstWidth(dstWidth)
924 , fSwizzleWidth(srcWidth)
925 , fAllocatedWidth(dstWidth)
scroggoe7fc14b2015-10-02 13:14:46 -0700926 , fSampleX(1)
msarett5af4e0b2015-11-17 11:18:03 -0800927 , fSrcBPP(srcBPP)
928 , fDstBPP(dstBPP)
scroggoe7fc14b2015-10-02 13:14:46 -0700929{}
930
931int SkSwizzler::onSetSampleX(int sampleX) {
msarett9972c422016-02-10 08:39:37 -0800932 SkASSERT(sampleX > 0);
933
scroggoe7fc14b2015-10-02 13:14:46 -0700934 fSampleX = sampleX;
msarett5af4e0b2015-11-17 11:18:03 -0800935 fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
936 fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
937 fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
938 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
scroggoe7fc14b2015-10-02 13:14:46 -0700939
msarett9972c422016-02-10 08:39:37 -0800940 // The optimized swizzler functions do not support sampling. Sampled swizzles
941 // are already fast because they skip pixels. We haven't seen a situation
942 // where speeding up sampling has a significant impact on total decode time.
msarett19032f72016-01-21 09:59:38 -0800943 if (1 == fSampleX && fFastProc) {
944 fActualProc = fFastProc;
945 } else {
946 fActualProc = fSlowProc;
947 }
msaretta51e7782016-01-12 06:51:11 -0800948
msarett5af4e0b2015-11-17 11:18:03 -0800949 return fAllocatedWidth;
emmaleer8f4ba762015-08-14 07:44:46 -0700950}
scroggof24f2242015-03-03 08:59:20 -0800951
msaretta4970dc2016-01-11 07:23:23 -0800952void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -0700953 SkASSERT(nullptr != dst && nullptr != src);
msarett19032f72016-01-21 09:59:38 -0800954 fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
msarett5af4e0b2015-11-17 11:18:03 -0800955 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
scroggof24f2242015-03-03 08:59:20 -0800956}