blob: 31fc063aec94e006429f2a2f2253042dbbe92b78 [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"
Matt Saretta225e9b2016-11-07 10:26:17 -050010#include "SkHalf.h"
msaretta51e7782016-01-12 06:51:11 -080011#include "SkOpts.h"
scroggof24f2242015-03-03 08:59:20 -080012#include "SkSwizzler.h"
13#include "SkTemplates.h"
14
msarettbda86092016-01-19 10:40:12 -080015static 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);
emmaleer8f4ba762015-08-14 07:44:46 -070020
msarettbda86092016-01-19 10:40:12 -080021 memcpy(dst, src + offset, width * bpp);
22}
23
24static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
25 const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -070026 src += offset;
msarettbda86092016-01-19 10:40:12 -080027 uint8_t* dst8 = (uint8_t*) dst;
emmaleer8f4ba762015-08-14 07:44:46 -070028 for (int x = 0; x < width; x++) {
msarettbda86092016-01-19 10:40:12 -080029 dst8[x] = *src;
emmaleer8f4ba762015-08-14 07:44:46 -070030 src += deltaSrc;
31 }
emmaleer8f4ba762015-08-14 07:44:46 -070032}
33
msarettbda86092016-01-19 10:40:12 -080034static 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
44static 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}
msarett5406d6f2015-08-31 06:55:13 -070053
Matt Sarett34c69d62017-01-19 17:42:23 -050054static 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
Matt Sarett379938e2017-01-12 18:34:29 -050065static 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
msarett99f567e2015-08-05 12:58:26 -070075// kBit
76// These routines exclusively choose between white and black
77
78#define GRAYSCALE_BLACK 0
79#define GRAYSCALE_WHITE 0xFF
80
emmaleer8f4ba762015-08-14 07:44:46 -070081
82// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -080083static void swizzle_bit_to_grayscale(
emmaleer8f4ba762015-08-14 07:44:46 -070084 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -070085 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
emmaleer8f4ba762015-08-14 07:44:46 -070086
msarett99f567e2015-08-05 12:58:26 -070087 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
88
emmaleer8f4ba762015-08-14 07:44:46 -070089 // 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;
msarett99f567e2015-08-05 12:58:26 -0700101 }
msarett99f567e2015-08-05 12:58:26 -0700102}
103
104#undef GRAYSCALE_BLACK
105#undef GRAYSCALE_WHITE
106
emmaleer8f4ba762015-08-14 07:44:46 -0700107// same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -0800108static void swizzle_bit_to_index(
emmaleer8f4ba762015-08-14 07:44:46 -0700109 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700110 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
msarett99f567e2015-08-05 12:58:26 -0700111 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
112
emmaleer8f4ba762015-08-14 07:44:46 -0700113 // 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);
msarett99f567e2015-08-05 12:58:26 -0700125 }
msarett99f567e2015-08-05 12:58:26 -0700126}
127
emmaleer8f4ba762015-08-14 07:44:46 -0700128// same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -0800129static void swizzle_bit_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700130 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700131 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
msarett99f567e2015-08-05 12:58:26 -0700132 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
133
emmaleer8f4ba762015-08-14 07:44:46 -0700134 // 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;
msarett99f567e2015-08-05 12:58:26 -0700146 }
msarett99f567e2015-08-05 12:58:26 -0700147}
148
scroggocc2feb12015-08-14 08:32:46 -0700149#define RGB565_BLACK 0
150#define RGB565_WHITE 0xFFFF
151
msaretta4970dc2016-01-11 07:23:23 -0800152static void swizzle_bit_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700153 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700154 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
scroggocc2feb12015-08-14 08:32:46 -0700155 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 }
scroggocc2feb12015-08-14 08:32:46 -0700170}
171
172#undef RGB565_BLACK
173#undef RGB565_WHITE
174
Matt Saretta225e9b2016-11-07 10:26:17 -0500175static 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
msarett74114382015-03-16 11:55:18 -0700204// kIndex1, kIndex2, kIndex4
205
msaretta4970dc2016-01-11 07:23:23 -0800206static void swizzle_small_index_to_index(
emmaleer8f4ba762015-08-14 07:44:46 -0700207 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700208 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett438b2ad2015-04-09 12:43:10 -0700209
msarett5406d6f2015-08-31 06:55:13 -0700210 uint8_t* dst = (uint8_t*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700211 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;
msarett5406d6f2015-08-31 06:55:13 -0700217
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;
msarett438b2ad2015-04-09 12:43:10 -0700224 }
msarett438b2ad2015-04-09 12:43:10 -0700225}
226
msaretta4970dc2016-01-11 07:23:23 -0800227static void swizzle_small_index_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700228 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700229 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
scroggocc2feb12015-08-14 08:32:46 -0700230
msarett5406d6f2015-08-31 06:55:13 -0700231 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]);
scroggocc2feb12015-08-14 08:32:46 -0700245 }
scroggocc2feb12015-08-14 08:32:46 -0700246}
247
msaretta4970dc2016-01-11 07:23:23 -0800248static void swizzle_small_index_to_n32(
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 bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700251
msarett5406d6f2015-08-31 06:55:13 -0700252 SkPMColor* dst = (SkPMColor*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700253 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];
msarett5406d6f2015-08-31 06:55:13 -0700259
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];
msarett74114382015-03-16 11:55:18 -0700266 }
msarett74114382015-03-16 11:55:18 -0700267}
268
msarette16b04a2015-04-15 07:32:19 -0700269// kIndex
270
msaretta4970dc2016-01-11 07:23:23 -0800271static void swizzle_index_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700272 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700273 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700274
275 src += offset;
276 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700277 for (int x = 0; x < dstWidth; x++) {
278 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700279 dst[x] = c;
280 src += deltaSrc;
281 }
emmaleer8f4ba762015-08-14 07:44:46 -0700282}
283
msaretta4970dc2016-01-11 07:23:23 -0800284static void swizzle_index_to_n32_skipZ(
emmaleer8f4ba762015-08-14 07:44:46 -0700285 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700286 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700287
288 src += offset;
289 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700290 for (int x = 0; x < dstWidth; x++) {
291 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700292 if (c != 0) {
293 dst[x] = c;
294 }
295 src += deltaSrc;
296 }
emmaleer8f4ba762015-08-14 07:44:46 -0700297}
298
msaretta4970dc2016-01-11 07:23:23 -0800299static void swizzle_index_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700300 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700301 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700302 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700303 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700304 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700305 dst[x] = SkPixel32ToPixel16(ctable[*src]);
msarett5406d6f2015-08-31 06:55:13 -0700306 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700307 }
scroggoab60c5b2015-08-06 06:08:18 -0700308}
309
msarette16b04a2015-04-15 07:32:19 -0700310// kGray
311
msaretta4970dc2016-01-11 07:23:23 -0800312static void swizzle_gray_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700313 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700314 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarette16b04a2015-04-15 07:32:19 -0700315
emmaleer8f4ba762015-08-14 07:44:46 -0700316 src += offset;
msarette16b04a2015-04-15 07:32:19 -0700317 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700318 for (int x = 0; x < dstWidth; x++) {
319 dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
320 src += deltaSrc;
msarette16b04a2015-04-15 07:32:19 -0700321 }
msarette16b04a2015-04-15 07:32:19 -0700322}
323
msarett2eff71c2016-02-02 12:59:45 -0800324static 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
msaretta4970dc2016-01-11 07:23:23 -0800337static void swizzle_gray_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700338 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700339 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800340
emmaleer8f4ba762015-08-14 07:44:46 -0700341 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700342 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700343 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700344 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
msarett5406d6f2015-08-31 06:55:13 -0700345 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700346 }
scroggoab60c5b2015-08-06 06:08:18 -0700347}
348
msarett93e613d2016-02-03 10:44:46 -0800349// kGrayAlpha
350
351static 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
msarett1e060792016-02-03 11:17:43 -0800363static 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
msarett93e613d2016-02-03 10:44:46 -0800376static 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
msarett1e060792016-02-03 11:17:43 -0800389static 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
msarett34e0ec42016-04-22 16:27:24 -0700402// kBGR
msarette16b04a2015-04-15 07:32:19 -0700403
msarett34e0ec42016-04-22 16:27:24 -0700404static void swizzle_bgr_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700405 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700406 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800407
scroggocc2feb12015-08-14 08:32:46 -0700408 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 }
scroggocc2feb12015-08-14 08:32:46 -0700414}
415
msarettbda86092016-01-19 10:40:12 -0800416// kRGB
msarett03108de2016-01-15 11:02:36 -0800417
msarett34e0ec42016-04-22 16:27:24 -0700418static void swizzle_rgb_to_rgba(
emmaleer8f4ba762015-08-14 07:44:46 -0700419 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700420 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700421
emmaleer8f4ba762015-08-14 07:44:46 -0700422 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800423 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700424 for (int x = 0; x < dstWidth; x++) {
msarett34e0ec42016-04-22 16:27:24 -0700425 dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700426 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800427 }
scroggof24f2242015-03-03 08:59:20 -0800428}
429
msarett34e0ec42016-04-22 16:27:24 -0700430static 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
442static void fast_swizzle_rgb_to_rgba(
msarettf1b8b6a2016-01-22 09:54:21 -0800443 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
444 int offset, const SkPMColor ctable[]) {
msarett03108de2016-01-15 11:02:36 -0800445
msarettf1b8b6a2016-01-22 09:54:21 -0800446 // 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
msarettf1b8b6a2016-01-22 09:54:21 -0800450 SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
msarett34e0ec42016-04-22 16:27:24 -0700451}
452
453static 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
msarettf1b8b6a2016-01-22 09:54:21 -0800461 SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
msarettf1b8b6a2016-01-22 09:54:21 -0800462}
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
msarett34e0ec42016-04-22 16:27:24 -0700478static void swizzle_rgba_to_rgba_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++) {
msarett34e0ec42016-04-22 16:27:24 -0700485 dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700486 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800487 }
scroggof24f2242015-03-03 08:59:20 -0800488}
489
msarett34e0ec42016-04-22 16:27:24 -0700490static 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
502static void fast_swizzle_rgba_to_rgba_premul(
msaretta51e7782016-01-12 06:51:11 -0800503 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
mtklein8bf7b792016-01-22 07:42:53 -0800510 SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
msaretta51e7782016-01-12 06:51:11 -0800511}
512
msarett34e0ec42016-04-22 16:27:24 -0700513static 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
524static void swizzle_rgba_to_bgra_unpremul(
emmaleer8f4ba762015-08-14 07:44:46 -0700525 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700526 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700527
emmaleer8f4ba762015-08-14 07:44:46 -0700528 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800529 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
emmaleer8f4ba762015-08-14 07:44:46 -0700530 for (int x = 0; x < dstWidth; x++) {
scroggof24f2242015-03-03 08:59:20 -0800531 unsigned alpha = src[3];
msarett34e0ec42016-04-22 16:27:24 -0700532 dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700533 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800534 }
scroggof24f2242015-03-03 08:59:20 -0800535}
536
msarett34e0ec42016-04-22 16:27:24 -0700537static void fast_swizzle_rgba_to_bgra_unpremul(
msarettbda86092016-01-19 10:40:12 -0800538 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
mtklein8bf7b792016-01-22 07:42:53 -0800545 SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
msarettbda86092016-01-19 10:40:12 -0800546}
547
Matt Sarett7a1cc672016-12-14 11:48:31 -0500548// 16-bits per component kRGB and kRGBA
549
550static 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
565static 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
580static 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
595static 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
610static 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
625static 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
640static 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
scroggoef27d892015-10-23 09:29:22 -0700655// 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
msarett34e0ec42016-04-22 16:27:24 -0700700static void swizzle_cmyk_to_rgba(
scroggoef27d892015-10-23 09:29:22 -0700701 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
msarett34e0ec42016-04-22 16:27:24 -0700711 dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
scroggoef27d892015-10-23 09:29:22 -0700712 src += deltaSrc;
713 }
scroggoef27d892015-10-23 09:29:22 -0700714}
715
msarett34e0ec42016-04-22 16:27:24 -0700716static 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
732static void fast_swizzle_cmyk_to_rgba(
msarettc5c322d2016-02-08 13:26:25 -0800733 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
msarettc5c322d2016-02-08 13:26:25 -0800740 SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
msarett34e0ec42016-04-22 16:27:24 -0700741}
742
743static 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
msarettc5c322d2016-02-08 13:26:25 -0800751 SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
msarettc5c322d2016-02-08 13:26:25 -0800752}
753
msaretta4970dc2016-01-11 07:23:23 -0800754static void swizzle_cmyk_to_565(
scroggoef27d892015-10-23 09:29:22 -0700755 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 }
scroggoef27d892015-10-23 09:29:22 -0700768}
769
mtklein8604ca22016-01-11 13:13:55 -0800770template <SkSwizzler::RowProc proc>
msarett93e613d2016-02-03 10:44:46 -0800771void 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
789template <SkSwizzler::RowProc proc>
mtklein8604ca22016-01-11 13:13:55 -0800790void 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;
scroggof24f2242015-03-03 08:59:20 -0800804 }
mtklein8604ca22016-01-11 13:13:55 -0800805 proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
scroggof24f2242015-03-03 08:59:20 -0800806}
scroggof24f2242015-03-03 08:59:20 -0800807
msaretta45a6682016-04-22 13:18:37 -0700808SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
msarett74114382015-03-16 11:55:18 -0700809 const SkPMColor* ctable,
msarettfdb47572015-10-13 12:50:14 -0700810 const SkImageInfo& dstInfo,
msarett5af4e0b2015-11-17 11:18:03 -0800811 const SkCodec::Options& options,
msarett68758ae2016-04-25 11:41:15 -0700812 const SkIRect* frame,
Matt Sarett9bf39c22016-12-13 13:29:54 -0500813 bool skipFormatConversion) {
msaretta45a6682016-04-22 13:18:37 -0700814 if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
halcanary96fcdcc2015-08-27 07:41:13 -0700815 return nullptr;
scroggof24f2242015-03-03 08:59:20 -0800816 }
msaretta45a6682016-04-22 13:18:37 -0700817
msaretta51e7782016-01-12 06:51:11 -0800818 RowProc fastProc = nullptr;
halcanary96fcdcc2015-08-27 07:41:13 -0700819 RowProc proc = nullptr;
Matt Sarett379938e2017-01-12 18:34:29 -0500820 int srcBPP;
821 const int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
Matt Sarett9bf39c22016-12-13 13:29:54 -0500822 if (skipFormatConversion) {
Matt Sarett34c69d62017-01-19 17:42:23 -0500823 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 = &copy;
832 break;
833 case kRGB_565_SkColorType:
834 proc = &sample2;
835 fastProc = &copy;
836 break;
837 case kRGBA_8888_SkColorType:
838 case kBGRA_8888_SkColorType:
839 proc = &sample4;
840 fastProc = &copy;
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;
msarett68758ae2016-04-25 11:41:15 -0700851 fastProc = &copy;
852 break;
Matt Sarett34c69d62017-01-19 17:42:23 -0500853 case SkEncodedInfo::kRGBA_Color:
854 // We have a png that should remain in its original format.
Matt Sarett379938e2017-01-12 18:34:29 -0500855 SkASSERT(16 == encodedInfo.bitsPerComponent() ||
856 8 == encodedInfo.bitsPerComponent());
857 if (8 == encodedInfo.bitsPerComponent()) {
Matt Sarett34c69d62017-01-19 17:42:23 -0500858 srcBPP = 4;
Matt Sarett379938e2017-01-12 18:34:29 -0500859 proc = &sample4;
860 } else {
861 srcBPP = 8;
862 proc = &sample8;
863 }
msarett68758ae2016-04-25 11:41:15 -0700864 fastProc = &copy;
865 break;
Matt Sarett34c69d62017-01-19 17:42:23 -0500866 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 = &copy;
872 break;
msarett68758ae2016-04-25 11:41:15 -0700873 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;
Matt Saretta225e9b2016-11-07 10:26:17 -0500899 case kRGBA_F16_SkColorType:
900 proc = &swizzle_bit_to_f16;
901 break;
msarett68758ae2016-04-25 11:41:15 -0700902 default:
903 return nullptr;
msaretta45a6682016-04-22 13:18:37 -0700904 }
msarett68758ae2016-04-25 11:41:15 -0700905 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 = &copy;
916 break;
917 case kRGB_565_SkColorType:
918 proc = &swizzle_gray_to_565;
919 break;
920 default:
921 return nullptr;
msarett93e613d2016-02-03 10:44:46 -0800922 }
msarett68758ae2016-04-25 11:41:15 -0700923 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) {
msaretta45a6682016-04-22 13:18:37 -0700933 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
msarett68758ae2016-04-25 11:41:15 -0700934 proc = &SkipLeadingGrayAlphaZerosThen
935 <swizzle_grayalpha_to_n32_premul>;
936 fastProc = &SkipLeadingGrayAlphaZerosThen
937 <fast_swizzle_grayalpha_to_n32_premul>;
msaretta45a6682016-04-22 13:18:37 -0700938 } else {
msarett68758ae2016-04-25 11:41:15 -0700939 proc = &swizzle_grayalpha_to_n32_premul;
940 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
msaretta45a6682016-04-22 13:18:37 -0700941 }
scroggof24f2242015-03-03 08:59:20 -0800942 } else {
msarett68758ae2016-04-25 11:41:15 -0700943 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 }
scroggof24f2242015-03-03 08:59:20 -0800952 }
msarett68758ae2016-04-25 11:41:15 -0700953 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 = &copy;
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:
Matt Sarett7a1cc672016-12-14 11:48:31 -05001008 if (16 == encodedInfo.bitsPerComponent()) {
1009 proc = &swizzle_rgb16_to_rgba;
1010 break;
1011 }
1012
1013 SkASSERT(8 == encodedInfo.bitsPerComponent());
msarett68758ae2016-04-25 11:41:15 -07001014 proc = &swizzle_rgb_to_rgba;
1015 fastProc = &fast_swizzle_rgb_to_rgba;
1016 break;
1017 case kBGRA_8888_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -05001018 if (16 == encodedInfo.bitsPerComponent()) {
1019 proc = &swizzle_rgb16_to_bgra;
1020 break;
1021 }
1022
1023 SkASSERT(8 == encodedInfo.bitsPerComponent());
msarett68758ae2016-04-25 11:41:15 -07001024 proc = &swizzle_rgb_to_bgra;
1025 fastProc = &fast_swizzle_rgb_to_bgra;
1026 break;
1027 case kRGB_565_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -05001028 if (16 == encodedInfo.bitsPerComponent()) {
1029 proc = &swizzle_rgb16_to_565;
1030 break;
1031 }
1032
msarett68758ae2016-04-25 11:41:15 -07001033 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:
Matt Sarett7a1cc672016-12-14 11:48:31 -05001042 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());
msarett68758ae2016-04-25 11:41:15 -07001049 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 }
msaretta45a6682016-04-22 13:18:37 -07001058 } else {
msarett68758ae2016-04-25 11:41:15 -07001059 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1060 proc = &SkipLeading8888ZerosThen<sample4>;
1061 fastProc = &SkipLeading8888ZerosThen<copy>;
1062 } else {
1063 proc = &sample4;
1064 fastProc = &copy;
1065 }
msarett34e0ec42016-04-22 16:27:24 -07001066 }
msarett68758ae2016-04-25 11:41:15 -07001067 break;
1068 case kBGRA_8888_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -05001069 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());
msarett68758ae2016-04-25 11:41:15 -07001076 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 }
msarett34e0ec42016-04-22 16:27:24 -07001085 } else {
msarett68758ae2016-04-25 11:41:15 -07001086 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 }
msarett34e0ec42016-04-22 16:27:24 -07001094 }
msarett68758ae2016-04-25 11:41:15 -07001095 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 }
msarett34e0ec42016-04-22 16:27:24 -07001144 } else {
msarett68758ae2016-04-25 11:41:15 -07001145 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1146 proc = &SkipLeading8888ZerosThen<sample4>;
1147 fastProc = &SkipLeading8888ZerosThen<copy>;
1148 } else {
1149 proc = &sample4;
1150 fastProc = &copy;
1151 }
msaretta45a6682016-04-22 13:18:37 -07001152 }
msarett68758ae2016-04-25 11:41:15 -07001153 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 }
msaretta45a6682016-04-22 13:18:37 -07001164 } else {
msarett68758ae2016-04-25 11:41:15 -07001165 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 }
msaretta45a6682016-04-22 13:18:37 -07001173 }
msarett68758ae2016-04-25 11:41:15 -07001174 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 }
msarett74114382015-03-16 11:55:18 -07001199
msaretta45a6682016-04-22 13:18:37 -07001200 // 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 }
mtklein3d00db32016-01-11 06:16:26 -08001204
msarettfdb47572015-10-13 12:50:14 -07001205 int srcOffset = 0;
1206 int srcWidth = dstInfo.width();
msarett5af4e0b2015-11-17 11:18:03 -08001207 int dstOffset = 0;
1208 int dstWidth = srcWidth;
msarettfdb47572015-10-13 12:50:14 -07001209 if (options.fSubset) {
msarett5af4e0b2015-11-17 11:18:03 -08001210 // We do not currently support subset decodes for image types that may have
1211 // frames (gif).
1212 SkASSERT(!frame);
msarettfdb47572015-10-13 12:50:14 -07001213 srcOffset = options.fSubset->left();
1214 srcWidth = options.fSubset->width();
msarett5af4e0b2015-11-17 11:18:03 -08001215 dstWidth = srcWidth;
1216 } else if (frame) {
1217 dstOffset = frame->left();
1218 srcWidth = frame->width();
msarettfdb47572015-10-13 12:50:14 -07001219 }
emmaleer8f4ba762015-08-14 07:44:46 -07001220
msaretta51e7782016-01-12 06:51:11 -08001221 return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
1222 srcBPP, dstBPP);
scroggof24f2242015-03-03 08:59:20 -08001223}
1224
msaretta51e7782016-01-12 06:51:11 -08001225SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1226 int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1227 : fFastProc(fastProc)
msarett19032f72016-01-21 09:59:38 -08001228 , fSlowProc(proc)
1229 , fActualProc(fFastProc ? fFastProc : fSlowProc)
scroggof24f2242015-03-03 08:59:20 -08001230 , fColorTable(ctable)
msarettfdb47572015-10-13 12:50:14 -07001231 , fSrcOffset(srcOffset)
msarett5af4e0b2015-11-17 11:18:03 -08001232 , fDstOffset(dstOffset)
1233 , fSrcOffsetUnits(srcOffset * srcBPP)
1234 , fDstOffsetBytes(dstOffset * dstBPP)
1235 , fSrcWidth(srcWidth)
1236 , fDstWidth(dstWidth)
1237 , fSwizzleWidth(srcWidth)
1238 , fAllocatedWidth(dstWidth)
scroggoe7fc14b2015-10-02 13:14:46 -07001239 , fSampleX(1)
msarett5af4e0b2015-11-17 11:18:03 -08001240 , fSrcBPP(srcBPP)
1241 , fDstBPP(dstBPP)
scroggoe7fc14b2015-10-02 13:14:46 -07001242{}
1243
1244int SkSwizzler::onSetSampleX(int sampleX) {
msarett9972c422016-02-10 08:39:37 -08001245 SkASSERT(sampleX > 0);
1246
scroggoe7fc14b2015-10-02 13:14:46 -07001247 fSampleX = sampleX;
msarett5af4e0b2015-11-17 11:18:03 -08001248 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);
scroggoe7fc14b2015-10-02 13:14:46 -07001252
msarett9972c422016-02-10 08:39:37 -08001253 // 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.
msarett19032f72016-01-21 09:59:38 -08001256 if (1 == fSampleX && fFastProc) {
1257 fActualProc = fFastProc;
1258 } else {
1259 fActualProc = fSlowProc;
1260 }
msaretta51e7782016-01-12 06:51:11 -08001261
msarett5af4e0b2015-11-17 11:18:03 -08001262 return fAllocatedWidth;
emmaleer8f4ba762015-08-14 07:44:46 -07001263}
scroggof24f2242015-03-03 08:59:20 -08001264
msaretta4970dc2016-01-11 07:23:23 -08001265void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -07001266 SkASSERT(nullptr != dst && nullptr != src);
msarett19032f72016-01-21 09:59:38 -08001267 fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
msarett5af4e0b2015-11-17 11:18:03 -08001268 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
scroggof24f2242015-03-03 08:59:20 -08001269}