blob: 84bb09702b3331b0dac2a2250e4cdf4d18b9ab8e [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"
Cary Clarka4083c92017-09-15 11:59:23 -04009#include "SkColorData.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_index except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -0800108static void swizzle_bit_to_n32(
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 SkPMColor* SK_RESTRICT dst = (SkPMColor*) 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) ? SK_ColorWHITE : SK_ColorBLACK;
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) ? SK_ColorWHITE : SK_ColorBLACK;
msarett99f567e2015-08-05 12:58:26 -0700125 }
msarett99f567e2015-08-05 12:58:26 -0700126}
127
scroggocc2feb12015-08-14 08:32:46 -0700128#define RGB565_BLACK 0
129#define RGB565_WHITE 0xFFFF
130
msaretta4970dc2016-01-11 07:23:23 -0800131static void swizzle_bit_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700132 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700133 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
scroggocc2feb12015-08-14 08:32:46 -0700134 uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
135
136 // increment src by byte offset and bitIndex by bit offset
137 src += offset / 8;
138 int bitIndex = offset % 8;
139 uint8_t currByte = *src;
140
141 dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
142
143 for (int x = 1; x < dstWidth; x++) {
144 int bitOffset = bitIndex + deltaSrc;
145 bitIndex = bitOffset % 8;
146 currByte = *(src += bitOffset / 8);
147 dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
148 }
scroggocc2feb12015-08-14 08:32:46 -0700149}
150
151#undef RGB565_BLACK
152#undef RGB565_WHITE
153
Matt Saretta225e9b2016-11-07 10:26:17 -0500154static void swizzle_bit_to_f16(
155 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
156 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
Leon Scroggins III862c1962017-10-02 16:28:49 -0400157 constexpr uint64_t kWhite = (((uint64_t) SK_Half1) << 0) |
158 (((uint64_t) SK_Half1) << 16) |
159 (((uint64_t) SK_Half1) << 32) |
160 (((uint64_t) SK_Half1) << 48);
161 constexpr uint64_t kBlack = (((uint64_t) 0) << 0) |
162 (((uint64_t) 0) << 16) |
163 (((uint64_t) 0) << 32) |
164 (((uint64_t) SK_Half1) << 48);
Matt Saretta225e9b2016-11-07 10:26:17 -0500165
166 uint64_t* SK_RESTRICT dst = (uint64_t*) dstRow;
167
168 // increment src by byte offset and bitIndex by bit offset
169 src += offset / 8;
170 int bitIndex = offset % 8;
171 uint8_t currByte = *src;
172
173 dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
174
175 for (int x = 1; x < dstWidth; x++) {
176 int bitOffset = bitIndex + deltaSrc;
177 bitIndex = bitOffset % 8;
178 currByte = *(src += bitOffset / 8);
179 dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
180 }
181}
182
msarett74114382015-03-16 11:55:18 -0700183// kIndex1, kIndex2, kIndex4
184
msaretta4970dc2016-01-11 07:23:23 -0800185static void swizzle_small_index_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700186 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700187 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
scroggocc2feb12015-08-14 08:32:46 -0700188
msarett5406d6f2015-08-31 06:55:13 -0700189 uint16_t* dst = (uint16_t*) dstRow;
190 src += offset / 8;
191 int bitIndex = offset % 8;
192 uint8_t currByte = *src;
193 const uint8_t mask = (1 << bpp) - 1;
194 uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
195 dst[0] = SkPixel32ToPixel16(ctable[index]);
196
197 for (int x = 1; x < dstWidth; x++) {
198 int bitOffset = bitIndex + deltaSrc;
199 bitIndex = bitOffset % 8;
200 currByte = *(src += bitOffset / 8);
201 index = (currByte >> (8 - bpp - bitIndex)) & mask;
202 dst[x] = SkPixel32ToPixel16(ctable[index]);
scroggocc2feb12015-08-14 08:32:46 -0700203 }
scroggocc2feb12015-08-14 08:32:46 -0700204}
205
msaretta4970dc2016-01-11 07:23:23 -0800206static void swizzle_small_index_to_n32(
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[]) {
msarett74114382015-03-16 11:55:18 -0700209
msarett5406d6f2015-08-31 06:55:13 -0700210 SkPMColor* dst = (SkPMColor*) 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] = ctable[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] = ctable[index];
msarett74114382015-03-16 11:55:18 -0700224 }
msarett74114382015-03-16 11:55:18 -0700225}
226
msarette16b04a2015-04-15 07:32:19 -0700227// kIndex
228
msaretta4970dc2016-01-11 07:23:23 -0800229static void swizzle_index_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700230 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700231 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700232
233 src += offset;
234 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700235 for (int x = 0; x < dstWidth; x++) {
236 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700237 dst[x] = c;
238 src += deltaSrc;
239 }
emmaleer8f4ba762015-08-14 07:44:46 -0700240}
241
msaretta4970dc2016-01-11 07:23:23 -0800242static void swizzle_index_to_n32_skipZ(
emmaleer8f4ba762015-08-14 07:44:46 -0700243 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700244 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700245
246 src += offset;
247 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700248 for (int x = 0; x < dstWidth; x++) {
249 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700250 if (c != 0) {
251 dst[x] = c;
252 }
253 src += deltaSrc;
254 }
emmaleer8f4ba762015-08-14 07:44:46 -0700255}
256
msaretta4970dc2016-01-11 07:23:23 -0800257static void swizzle_index_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700258 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700259 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700260 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700261 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700262 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700263 dst[x] = SkPixel32ToPixel16(ctable[*src]);
msarett5406d6f2015-08-31 06:55:13 -0700264 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700265 }
scroggoab60c5b2015-08-06 06:08:18 -0700266}
267
msarette16b04a2015-04-15 07:32:19 -0700268// kGray
269
msaretta4970dc2016-01-11 07:23:23 -0800270static void swizzle_gray_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700271 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700272 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarette16b04a2015-04-15 07:32:19 -0700273
emmaleer8f4ba762015-08-14 07:44:46 -0700274 src += offset;
msarette16b04a2015-04-15 07:32:19 -0700275 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700276 for (int x = 0; x < dstWidth; x++) {
277 dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
278 src += deltaSrc;
msarette16b04a2015-04-15 07:32:19 -0700279 }
msarette16b04a2015-04-15 07:32:19 -0700280}
281
msarett2eff71c2016-02-02 12:59:45 -0800282static void fast_swizzle_gray_to_n32(
283 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
284 const SkPMColor ctable[]) {
285
286 // This function must not be called if we are sampling. If we are not
287 // sampling, deltaSrc should equal bpp.
288 SkASSERT(deltaSrc == bpp);
289
290 // Note that there is no need to distinguish between RGB and BGR.
291 // Each color channel will get the same value.
292 SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
293}
294
msaretta4970dc2016-01-11 07:23:23 -0800295static void swizzle_gray_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700296 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700297 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800298
emmaleer8f4ba762015-08-14 07:44:46 -0700299 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700300 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700301 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700302 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
msarett5406d6f2015-08-31 06:55:13 -0700303 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700304 }
scroggoab60c5b2015-08-06 06:08:18 -0700305}
306
msarett93e613d2016-02-03 10:44:46 -0800307// kGrayAlpha
308
309static void swizzle_grayalpha_to_n32_unpremul(
310 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
311 const SkPMColor ctable[]) {
312
313 src += offset;
314 SkPMColor* dst32 = (SkPMColor*) dst;
315 for (int x = 0; x < width; x++) {
316 dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
317 src += deltaSrc;
318 }
319}
320
msarett1e060792016-02-03 11:17:43 -0800321static void fast_swizzle_grayalpha_to_n32_unpremul(
322 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
323 const SkPMColor ctable[]) {
324
325 // This function must not be called if we are sampling. If we are not
326 // sampling, deltaSrc should equal bpp.
327 SkASSERT(deltaSrc == bpp);
328
329 // Note that there is no need to distinguish between RGB and BGR.
330 // Each color channel will get the same value.
331 SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
332}
333
msarett93e613d2016-02-03 10:44:46 -0800334static void swizzle_grayalpha_to_n32_premul(
335 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
336 const SkPMColor ctable[]) {
337
338 src += offset;
339 SkPMColor* dst32 = (SkPMColor*) dst;
340 for (int x = 0; x < width; x++) {
341 uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
342 dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
343 src += deltaSrc;
344 }
345}
346
msarett1e060792016-02-03 11:17:43 -0800347static void fast_swizzle_grayalpha_to_n32_premul(
348 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
349 const SkPMColor ctable[]) {
350
351 // This function must not be called if we are sampling. If we are not
352 // sampling, deltaSrc should equal bpp.
353 SkASSERT(deltaSrc == bpp);
354
355 // Note that there is no need to distinguish between rgb and bgr.
356 // Each color channel will get the same value.
357 SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
358}
359
msarett34e0ec42016-04-22 16:27:24 -0700360// kBGR
msarette16b04a2015-04-15 07:32:19 -0700361
msarett34e0ec42016-04-22 16:27:24 -0700362static void swizzle_bgr_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700363 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700364 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800365
scroggocc2feb12015-08-14 08:32:46 -0700366 src += offset;
367 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
368 for (int x = 0; x < dstWidth; x++) {
369 dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
370 src += deltaSrc;
371 }
scroggocc2feb12015-08-14 08:32:46 -0700372}
373
msarettbda86092016-01-19 10:40:12 -0800374// kRGB
msarett03108de2016-01-15 11:02:36 -0800375
msarett34e0ec42016-04-22 16:27:24 -0700376static void swizzle_rgb_to_rgba(
emmaleer8f4ba762015-08-14 07:44:46 -0700377 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700378 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700379
emmaleer8f4ba762015-08-14 07:44:46 -0700380 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800381 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700382 for (int x = 0; x < dstWidth; x++) {
msarett34e0ec42016-04-22 16:27:24 -0700383 dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700384 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800385 }
scroggof24f2242015-03-03 08:59:20 -0800386}
387
msarett34e0ec42016-04-22 16:27:24 -0700388static void swizzle_rgb_to_bgra(
389 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
390 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
391
392 src += offset;
393 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
394 for (int x = 0; x < dstWidth; x++) {
395 dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
396 src += deltaSrc;
397 }
398}
399
400static void fast_swizzle_rgb_to_rgba(
msarettf1b8b6a2016-01-22 09:54:21 -0800401 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
402 int offset, const SkPMColor ctable[]) {
msarett03108de2016-01-15 11:02:36 -0800403
msarettf1b8b6a2016-01-22 09:54:21 -0800404 // This function must not be called if we are sampling. If we are not
405 // sampling, deltaSrc should equal bpp.
406 SkASSERT(deltaSrc == bpp);
407
msarettf1b8b6a2016-01-22 09:54:21 -0800408 SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
msarett34e0ec42016-04-22 16:27:24 -0700409}
410
411static void fast_swizzle_rgb_to_bgra(
412 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
413 int offset, const SkPMColor ctable[]) {
414
415 // This function must not be called if we are sampling. If we are not
416 // sampling, deltaSrc should equal bpp.
417 SkASSERT(deltaSrc == bpp);
418
msarettf1b8b6a2016-01-22 09:54:21 -0800419 SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
msarettf1b8b6a2016-01-22 09:54:21 -0800420}
msarett03108de2016-01-15 11:02:36 -0800421
msarettbda86092016-01-19 10:40:12 -0800422static void swizzle_rgb_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700423 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700424 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800425
emmaleer8f4ba762015-08-14 07:44:46 -0700426 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700427 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700428 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700429 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
msarett5406d6f2015-08-31 06:55:13 -0700430 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700431 }
scroggoab60c5b2015-08-06 06:08:18 -0700432}
433
scroggoab60c5b2015-08-06 06:08:18 -0700434// kRGBA
msarett03108de2016-01-15 11:02:36 -0800435
msarett34e0ec42016-04-22 16:27:24 -0700436static void swizzle_rgba_to_rgba_premul(
emmaleer8f4ba762015-08-14 07:44:46 -0700437 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700438 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700439
emmaleer8f4ba762015-08-14 07:44:46 -0700440 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800441 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700442 for (int x = 0; x < dstWidth; x++) {
msarett34e0ec42016-04-22 16:27:24 -0700443 dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700444 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800445 }
scroggof24f2242015-03-03 08:59:20 -0800446}
447
msarett34e0ec42016-04-22 16:27:24 -0700448static void swizzle_rgba_to_bgra_premul(
449 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
450 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
451
452 src += offset;
453 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
454 for (int x = 0; x < dstWidth; x++) {
455 dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
456 src += deltaSrc;
457 }
458}
459
460static void fast_swizzle_rgba_to_rgba_premul(
msaretta51e7782016-01-12 06:51:11 -0800461 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
462 int offset, const SkPMColor ctable[]) {
463
464 // This function must not be called if we are sampling. If we are not
465 // sampling, deltaSrc should equal bpp.
466 SkASSERT(deltaSrc == bpp);
467
mtklein8bf7b792016-01-22 07:42:53 -0800468 SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
msaretta51e7782016-01-12 06:51:11 -0800469}
470
msarett34e0ec42016-04-22 16:27:24 -0700471static void fast_swizzle_rgba_to_bgra_premul(
472 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
473 int offset, const SkPMColor ctable[]) {
474
475 // This function must not be called if we are sampling. If we are not
476 // sampling, deltaSrc should equal bpp.
477 SkASSERT(deltaSrc == bpp);
478
479 SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
480}
481
482static void swizzle_rgba_to_bgra_unpremul(
emmaleer8f4ba762015-08-14 07:44:46 -0700483 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700484 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700485
emmaleer8f4ba762015-08-14 07:44:46 -0700486 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800487 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
emmaleer8f4ba762015-08-14 07:44:46 -0700488 for (int x = 0; x < dstWidth; x++) {
scroggof24f2242015-03-03 08:59:20 -0800489 unsigned alpha = src[3];
msarett34e0ec42016-04-22 16:27:24 -0700490 dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700491 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800492 }
scroggof24f2242015-03-03 08:59:20 -0800493}
494
msarett34e0ec42016-04-22 16:27:24 -0700495static void fast_swizzle_rgba_to_bgra_unpremul(
msarettbda86092016-01-19 10:40:12 -0800496 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
497 const SkPMColor ctable[]) {
498
499 // This function must not be called if we are sampling. If we are not
500 // sampling, deltaSrc should equal bpp.
501 SkASSERT(deltaSrc == bpp);
502
mtklein8bf7b792016-01-22 07:42:53 -0800503 SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
msarettbda86092016-01-19 10:40:12 -0800504}
505
Matt Sarett7a1cc672016-12-14 11:48:31 -0500506// 16-bits per component kRGB and kRGBA
507
508static void swizzle_rgb16_to_rgba(
509 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
510 const SkPMColor ctable[]) {
511 auto strip16to8 = [](const uint8_t* ptr) {
512 return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
513 };
514
515 src += offset;
516 uint32_t* dst32 = (uint32_t*) dst;
517 for (int x = 0; x < width; x++) {
518 dst32[x] = strip16to8(src);
519 src += deltaSrc;
520 }
521}
522
523static void swizzle_rgb16_to_bgra(
524 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
525 const SkPMColor ctable[]) {
526 auto strip16to8 = [](const uint8_t* ptr) {
527 return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
528 };
529
530 src += offset;
531 uint32_t* dst32 = (uint32_t*) dst;
532 for (int x = 0; x < width; x++) {
533 dst32[x] = strip16to8(src);
534 src += deltaSrc;
535 }
536}
537
538static void swizzle_rgb16_to_565(
539 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
540 const SkPMColor ctable[]) {
541 auto strip16to565 = [](const uint8_t* ptr) {
542 return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]);
543 };
544
545 src += offset;
546 uint16_t* dst16 = (uint16_t*) dst;
547 for (int x = 0; x < width; x++) {
548 dst16[x] = strip16to565(src);
549 src += deltaSrc;
550 }
551}
552
553static void swizzle_rgba16_to_rgba_unpremul(
554 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
555 const SkPMColor ctable[]) {
556 auto strip16to8 = [](const uint8_t* ptr) {
557 return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
558 };
559
560 src += offset;
561 uint32_t* dst32 = (uint32_t*) dst;
562 for (int x = 0; x < width; x++) {
563 dst32[x] = strip16to8(src);
564 src += deltaSrc;
565 }
566}
567
568static void swizzle_rgba16_to_rgba_premul(
569 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
570 const SkPMColor ctable[]) {
571 auto stripAndPremul16to8 = [](const uint8_t* ptr) {
572 return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]);
573 };
574
575 src += offset;
576 uint32_t* dst32 = (uint32_t*) dst;
577 for (int x = 0; x < width; x++) {
578 dst32[x] = stripAndPremul16to8(src);
579 src += deltaSrc;
580 }
581}
582
583static void swizzle_rgba16_to_bgra_unpremul(
584 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
585 const SkPMColor ctable[]) {
586 auto strip16to8 = [](const uint8_t* ptr) {
587 return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
588 };
589
590 src += offset;
591 uint32_t* dst32 = (uint32_t*) dst;
592 for (int x = 0; x < width; x++) {
593 dst32[x] = strip16to8(src);
594 src += deltaSrc;
595 }
596}
597
598static void swizzle_rgba16_to_bgra_premul(
599 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
600 const SkPMColor ctable[]) {
601 auto stripAndPremul16to8 = [](const uint8_t* ptr) {
602 return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]);
603 };
604
605 src += offset;
606 uint32_t* dst32 = (uint32_t*) dst;
607 for (int x = 0; x < width; x++) {
608 dst32[x] = stripAndPremul16to8(src);
609 src += deltaSrc;
610 }
611}
612
scroggoef27d892015-10-23 09:29:22 -0700613// kCMYK
614//
615// CMYK is stored as four bytes per pixel.
616//
617// We will implement a crude conversion from CMYK -> RGB using formulas
618// from easyrgb.com.
619//
620// CMYK -> CMY
621// C = C * (1 - K) + K
622// M = M * (1 - K) + K
623// Y = Y * (1 - K) + K
624//
625// libjpeg actually gives us inverted CMYK, so we must subtract the
626// original terms from 1.
627// CMYK -> CMY
628// C = (1 - C) * (1 - (1 - K)) + (1 - K)
629// M = (1 - M) * (1 - (1 - K)) + (1 - K)
630// Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
631//
632// Simplifying the above expression.
633// CMYK -> CMY
634// C = 1 - CK
635// M = 1 - MK
636// Y = 1 - YK
637//
638// CMY -> RGB
639// R = (1 - C) * 255
640// G = (1 - M) * 255
641// B = (1 - Y) * 255
642//
643// Therefore the full conversion is below. This can be verified at
644// www.rapidtables.com (assuming inverted CMYK).
645// CMYK -> RGB
646// R = C * K * 255
647// G = M * K * 255
648// B = Y * K * 255
649//
650// As a final note, we have treated the CMYK values as if they were on
651// a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
652// We must divide each CMYK component by 255 to obtain the true conversion
653// we should perform.
654// CMYK -> RGB
655// R = C * K / 255
656// G = M * K / 255
657// B = Y * K / 255
msarett34e0ec42016-04-22 16:27:24 -0700658static void swizzle_cmyk_to_rgba(
scroggoef27d892015-10-23 09:29:22 -0700659 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
660 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
661
662 src += offset;
663 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
664 for (int x = 0; x < dstWidth; x++) {
665 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
666 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
667 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
668
msarett34e0ec42016-04-22 16:27:24 -0700669 dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
scroggoef27d892015-10-23 09:29:22 -0700670 src += deltaSrc;
671 }
scroggoef27d892015-10-23 09:29:22 -0700672}
673
msarett34e0ec42016-04-22 16:27:24 -0700674static void swizzle_cmyk_to_bgra(
675 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
676 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
677
678 src += offset;
679 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
680 for (int x = 0; x < dstWidth; x++) {
681 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
682 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
683 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
684
685 dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
686 src += deltaSrc;
687 }
688}
689
690static void fast_swizzle_cmyk_to_rgba(
msarettc5c322d2016-02-08 13:26:25 -0800691 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
692 const SkPMColor ctable[]) {
693
694 // This function must not be called if we are sampling. If we are not
695 // sampling, deltaSrc should equal bpp.
696 SkASSERT(deltaSrc == bpp);
697
msarettc5c322d2016-02-08 13:26:25 -0800698 SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
msarett34e0ec42016-04-22 16:27:24 -0700699}
700
701static void fast_swizzle_cmyk_to_bgra(
702 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
703 const SkPMColor ctable[]) {
704
705 // This function must not be called if we are sampling. If we are not
706 // sampling, deltaSrc should equal bpp.
707 SkASSERT(deltaSrc == bpp);
708
msarettc5c322d2016-02-08 13:26:25 -0800709 SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
msarettc5c322d2016-02-08 13:26:25 -0800710}
711
msaretta4970dc2016-01-11 07:23:23 -0800712static void swizzle_cmyk_to_565(
scroggoef27d892015-10-23 09:29:22 -0700713 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
714 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
715
716 src += offset;
717 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
718 for (int x = 0; x < dstWidth; x++) {
719 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
720 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
721 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
722
723 dst[x] = SkPack888ToRGB16(r, g, b);
724 src += deltaSrc;
725 }
scroggoef27d892015-10-23 09:29:22 -0700726}
727
mtklein8604ca22016-01-11 13:13:55 -0800728template <SkSwizzler::RowProc proc>
msarett93e613d2016-02-03 10:44:46 -0800729void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
730 void* dst, const uint8_t* src, int width,
731 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
732 SkASSERT(!ctable);
733
734 const uint16_t* src16 = (const uint16_t*) (src + offset);
735 uint32_t* dst32 = (uint32_t*) dst;
736
737 // This may miss opportunities to skip when the output is premultiplied,
738 // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
739 while (width > 0 && *src16 == 0x0000) {
740 width--;
741 dst32++;
742 src16 += deltaSrc / 2;
743 }
744 proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
745}
746
747template <SkSwizzler::RowProc proc>
mtklein8604ca22016-01-11 13:13:55 -0800748void SkSwizzler::SkipLeading8888ZerosThen(
749 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
750 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
751 SkASSERT(!ctable);
752
753 auto src32 = (const uint32_t*)(src+offset);
754 auto dst32 = (uint32_t*)dstRow;
755
756 // This may miss opportunities to skip when the output is premultiplied,
757 // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
758 while (dstWidth > 0 && *src32 == 0x00000000) {
759 dstWidth--;
760 dst32++;
761 src32 += deltaSrc/4;
scroggof24f2242015-03-03 08:59:20 -0800762 }
mtklein8604ca22016-01-11 13:13:55 -0800763 proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
scroggof24f2242015-03-03 08:59:20 -0800764}
scroggof24f2242015-03-03 08:59:20 -0800765
msaretta45a6682016-04-22 13:18:37 -0700766SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
msarett74114382015-03-16 11:55:18 -0700767 const SkPMColor* ctable,
msarettfdb47572015-10-13 12:50:14 -0700768 const SkImageInfo& dstInfo,
msarett5af4e0b2015-11-17 11:18:03 -0800769 const SkCodec::Options& options,
msarett68758ae2016-04-25 11:41:15 -0700770 const SkIRect* frame,
Matt Sarett9bf39c22016-12-13 13:29:54 -0500771 bool skipFormatConversion) {
msaretta45a6682016-04-22 13:18:37 -0700772 if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
halcanary96fcdcc2015-08-27 07:41:13 -0700773 return nullptr;
scroggof24f2242015-03-03 08:59:20 -0800774 }
msaretta45a6682016-04-22 13:18:37 -0700775
msaretta51e7782016-01-12 06:51:11 -0800776 RowProc fastProc = nullptr;
halcanary96fcdcc2015-08-27 07:41:13 -0700777 RowProc proc = nullptr;
Matt Sarett379938e2017-01-12 18:34:29 -0500778 int srcBPP;
779 const int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
Matt Sarett9bf39c22016-12-13 13:29:54 -0500780 if (skipFormatConversion) {
Matt Sarett34c69d62017-01-19 17:42:23 -0500781 switch (encodedInfo.color()) {
782 case SkEncodedInfo::kGray_Color:
783 case SkEncodedInfo::kYUV_Color:
784 // We have a jpeg that has already been converted to the dstColorType.
785 srcBPP = dstBPP;
786 switch (dstInfo.colorType()) {
787 case kGray_8_SkColorType:
788 proc = &sample1;
789 fastProc = &copy;
790 break;
791 case kRGB_565_SkColorType:
792 proc = &sample2;
793 fastProc = &copy;
794 break;
795 case kRGBA_8888_SkColorType:
796 case kBGRA_8888_SkColorType:
797 proc = &sample4;
798 fastProc = &copy;
799 break;
800 default:
801 return nullptr;
802 }
803 break;
804 case SkEncodedInfo::kInvertedCMYK_Color:
805 case SkEncodedInfo::kYCCK_Color:
806 // We have a jpeg that remains in its original format.
807 srcBPP = 4;
808 proc = &sample4;
msarett68758ae2016-04-25 11:41:15 -0700809 fastProc = &copy;
810 break;
Matt Sarett34c69d62017-01-19 17:42:23 -0500811 case SkEncodedInfo::kRGBA_Color:
812 // We have a png that should remain in its original format.
Matt Sarett379938e2017-01-12 18:34:29 -0500813 SkASSERT(16 == encodedInfo.bitsPerComponent() ||
814 8 == encodedInfo.bitsPerComponent());
815 if (8 == encodedInfo.bitsPerComponent()) {
Matt Sarett34c69d62017-01-19 17:42:23 -0500816 srcBPP = 4;
Matt Sarett379938e2017-01-12 18:34:29 -0500817 proc = &sample4;
818 } else {
819 srcBPP = 8;
820 proc = &sample8;
821 }
msarett68758ae2016-04-25 11:41:15 -0700822 fastProc = &copy;
823 break;
Matt Sarett34c69d62017-01-19 17:42:23 -0500824 case SkEncodedInfo::kRGB_Color:
825 // We have a png that remains in its original format.
826 SkASSERT(16 == encodedInfo.bitsPerComponent());
827 srcBPP = 6;
828 proc = &sample6;
829 fastProc = &copy;
830 break;
msarett68758ae2016-04-25 11:41:15 -0700831 default:
832 return nullptr;
833 }
834 } else {
835 SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
836 const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
837 (kPremul_SkAlphaType == dstInfo.alphaType());
838
839 switch (encodedInfo.color()) {
840 case SkEncodedInfo::kGray_Color:
841 switch (encodedInfo.bitsPerComponent()) {
842 case 1:
843 switch (dstInfo.colorType()) {
844 case kRGBA_8888_SkColorType:
845 case kBGRA_8888_SkColorType:
846 proc = &swizzle_bit_to_n32;
847 break;
msarett68758ae2016-04-25 11:41:15 -0700848 case kRGB_565_SkColorType:
849 proc = &swizzle_bit_to_565;
850 break;
851 case kGray_8_SkColorType:
852 proc = &swizzle_bit_to_grayscale;
853 break;
Matt Saretta225e9b2016-11-07 10:26:17 -0500854 case kRGBA_F16_SkColorType:
855 proc = &swizzle_bit_to_f16;
856 break;
msarett68758ae2016-04-25 11:41:15 -0700857 default:
858 return nullptr;
msaretta45a6682016-04-22 13:18:37 -0700859 }
msarett68758ae2016-04-25 11:41:15 -0700860 break;
861 case 8:
862 switch (dstInfo.colorType()) {
863 case kRGBA_8888_SkColorType:
864 case kBGRA_8888_SkColorType:
865 proc = &swizzle_gray_to_n32;
866 fastProc = &fast_swizzle_gray_to_n32;
867 break;
868 case kGray_8_SkColorType:
869 proc = &sample1;
870 fastProc = &copy;
871 break;
872 case kRGB_565_SkColorType:
873 proc = &swizzle_gray_to_565;
874 break;
875 default:
876 return nullptr;
msarett93e613d2016-02-03 10:44:46 -0800877 }
msarett68758ae2016-04-25 11:41:15 -0700878 break;
879 default:
880 return nullptr;
881 }
882 break;
883 case SkEncodedInfo::kGrayAlpha_Color:
884 switch (dstInfo.colorType()) {
885 case kRGBA_8888_SkColorType:
886 case kBGRA_8888_SkColorType:
887 if (premultiply) {
msaretta45a6682016-04-22 13:18:37 -0700888 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
msarett68758ae2016-04-25 11:41:15 -0700889 proc = &SkipLeadingGrayAlphaZerosThen
890 <swizzle_grayalpha_to_n32_premul>;
891 fastProc = &SkipLeadingGrayAlphaZerosThen
892 <fast_swizzle_grayalpha_to_n32_premul>;
msaretta45a6682016-04-22 13:18:37 -0700893 } else {
msarett68758ae2016-04-25 11:41:15 -0700894 proc = &swizzle_grayalpha_to_n32_premul;
895 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
msaretta45a6682016-04-22 13:18:37 -0700896 }
scroggof24f2242015-03-03 08:59:20 -0800897 } else {
msarett68758ae2016-04-25 11:41:15 -0700898 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
899 proc = &SkipLeadingGrayAlphaZerosThen
900 <swizzle_grayalpha_to_n32_unpremul>;
901 fastProc = &SkipLeadingGrayAlphaZerosThen
902 <fast_swizzle_grayalpha_to_n32_unpremul>;
903 } else {
904 proc = &swizzle_grayalpha_to_n32_unpremul;
905 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
906 }
scroggof24f2242015-03-03 08:59:20 -0800907 }
msarett68758ae2016-04-25 11:41:15 -0700908 break;
909 default:
910 return nullptr;
911 }
912 break;
913 case SkEncodedInfo::kPalette_Color:
914 // We assume that the color table is premultiplied and swizzled
915 // as desired.
916 switch (encodedInfo.bitsPerComponent()) {
917 case 1:
918 case 2:
919 case 4:
920 switch (dstInfo.colorType()) {
921 case kRGBA_8888_SkColorType:
922 case kBGRA_8888_SkColorType:
923 proc = &swizzle_small_index_to_n32;
924 break;
925 case kRGB_565_SkColorType:
926 proc = &swizzle_small_index_to_565;
927 break;
msarett68758ae2016-04-25 11:41:15 -0700928 default:
929 return nullptr;
930 }
931 break;
932 case 8:
933 switch (dstInfo.colorType()) {
934 case kRGBA_8888_SkColorType:
935 case kBGRA_8888_SkColorType:
936 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
937 proc = &swizzle_index_to_n32_skipZ;
938 } else {
939 proc = &swizzle_index_to_n32;
940 }
941 break;
942 case kRGB_565_SkColorType:
943 proc = &swizzle_index_to_565;
944 break;
msarett68758ae2016-04-25 11:41:15 -0700945 default:
946 return nullptr;
947 }
948 break;
949 default:
950 return nullptr;
951 }
952 break;
953 case SkEncodedInfo::kRGB_Color:
954 switch (dstInfo.colorType()) {
955 case kRGBA_8888_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -0500956 if (16 == encodedInfo.bitsPerComponent()) {
957 proc = &swizzle_rgb16_to_rgba;
958 break;
959 }
960
961 SkASSERT(8 == encodedInfo.bitsPerComponent());
msarett68758ae2016-04-25 11:41:15 -0700962 proc = &swizzle_rgb_to_rgba;
963 fastProc = &fast_swizzle_rgb_to_rgba;
964 break;
965 case kBGRA_8888_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -0500966 if (16 == encodedInfo.bitsPerComponent()) {
967 proc = &swizzle_rgb16_to_bgra;
968 break;
969 }
970
971 SkASSERT(8 == encodedInfo.bitsPerComponent());
msarett68758ae2016-04-25 11:41:15 -0700972 proc = &swizzle_rgb_to_bgra;
973 fastProc = &fast_swizzle_rgb_to_bgra;
974 break;
975 case kRGB_565_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -0500976 if (16 == encodedInfo.bitsPerComponent()) {
977 proc = &swizzle_rgb16_to_565;
978 break;
979 }
980
msarett68758ae2016-04-25 11:41:15 -0700981 proc = &swizzle_rgb_to_565;
982 break;
983 default:
984 return nullptr;
985 }
986 break;
987 case SkEncodedInfo::kRGBA_Color:
988 switch (dstInfo.colorType()) {
989 case kRGBA_8888_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -0500990 if (16 == encodedInfo.bitsPerComponent()) {
991 proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
992 &swizzle_rgba16_to_rgba_unpremul;
993 break;
994 }
995
996 SkASSERT(8 == encodedInfo.bitsPerComponent());
msarett68758ae2016-04-25 11:41:15 -0700997 if (premultiply) {
998 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
999 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
1000 fastProc = &SkipLeading8888ZerosThen
1001 <fast_swizzle_rgba_to_rgba_premul>;
1002 } else {
1003 proc = &swizzle_rgba_to_rgba_premul;
1004 fastProc = &fast_swizzle_rgba_to_rgba_premul;
1005 }
msaretta45a6682016-04-22 13:18:37 -07001006 } else {
msarett68758ae2016-04-25 11:41:15 -07001007 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1008 proc = &SkipLeading8888ZerosThen<sample4>;
1009 fastProc = &SkipLeading8888ZerosThen<copy>;
1010 } else {
1011 proc = &sample4;
1012 fastProc = &copy;
1013 }
msarett34e0ec42016-04-22 16:27:24 -07001014 }
msarett68758ae2016-04-25 11:41:15 -07001015 break;
1016 case kBGRA_8888_SkColorType:
Matt Sarett7a1cc672016-12-14 11:48:31 -05001017 if (16 == encodedInfo.bitsPerComponent()) {
1018 proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
1019 &swizzle_rgba16_to_bgra_unpremul;
1020 break;
1021 }
1022
1023 SkASSERT(8 == encodedInfo.bitsPerComponent());
msarett68758ae2016-04-25 11:41:15 -07001024 if (premultiply) {
1025 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1026 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
1027 fastProc = &SkipLeading8888ZerosThen
1028 <fast_swizzle_rgba_to_bgra_premul>;
1029 } else {
1030 proc = &swizzle_rgba_to_bgra_premul;
1031 fastProc = &fast_swizzle_rgba_to_bgra_premul;
1032 }
msarett34e0ec42016-04-22 16:27:24 -07001033 } else {
msarett68758ae2016-04-25 11:41:15 -07001034 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1035 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
1036 fastProc = &SkipLeading8888ZerosThen
1037 <fast_swizzle_rgba_to_bgra_unpremul>;
1038 } else {
1039 proc = &swizzle_rgba_to_bgra_unpremul;
1040 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
1041 }
msarett34e0ec42016-04-22 16:27:24 -07001042 }
msarett68758ae2016-04-25 11:41:15 -07001043 break;
1044 default:
1045 return nullptr;
1046 }
1047 break;
1048 case SkEncodedInfo::kBGR_Color:
1049 switch (dstInfo.colorType()) {
1050 case kBGRA_8888_SkColorType:
1051 proc = &swizzle_rgb_to_rgba;
1052 fastProc = &fast_swizzle_rgb_to_rgba;
1053 break;
1054 case kRGBA_8888_SkColorType:
1055 proc = &swizzle_rgb_to_bgra;
1056 fastProc = &fast_swizzle_rgb_to_bgra;
1057 break;
1058 case kRGB_565_SkColorType:
1059 proc = &swizzle_bgr_to_565;
1060 break;
1061 default:
1062 return nullptr;
1063 }
1064 break;
1065 case SkEncodedInfo::kBGRX_Color:
1066 switch (dstInfo.colorType()) {
1067 case kBGRA_8888_SkColorType:
1068 proc = &swizzle_rgb_to_rgba;
1069 break;
1070 case kRGBA_8888_SkColorType:
1071 proc = &swizzle_rgb_to_bgra;
1072 break;
1073 case kRGB_565_SkColorType:
1074 proc = &swizzle_bgr_to_565;
1075 break;
1076 default:
1077 return nullptr;
1078 }
1079 break;
1080 case SkEncodedInfo::kBGRA_Color:
1081 switch (dstInfo.colorType()) {
1082 case kBGRA_8888_SkColorType:
1083 if (premultiply) {
1084 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1085 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
1086 fastProc = &SkipLeading8888ZerosThen
1087 <fast_swizzle_rgba_to_rgba_premul>;
1088 } else {
1089 proc = &swizzle_rgba_to_rgba_premul;
1090 fastProc = &fast_swizzle_rgba_to_rgba_premul;
1091 }
msarett34e0ec42016-04-22 16:27:24 -07001092 } else {
msarett68758ae2016-04-25 11:41:15 -07001093 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1094 proc = &SkipLeading8888ZerosThen<sample4>;
1095 fastProc = &SkipLeading8888ZerosThen<copy>;
1096 } else {
1097 proc = &sample4;
1098 fastProc = &copy;
1099 }
msaretta45a6682016-04-22 13:18:37 -07001100 }
msarett68758ae2016-04-25 11:41:15 -07001101 break;
1102 case kRGBA_8888_SkColorType:
1103 if (premultiply) {
1104 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1105 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
1106 fastProc = &SkipLeading8888ZerosThen
1107 <fast_swizzle_rgba_to_bgra_premul>;
1108 } else {
1109 proc = &swizzle_rgba_to_bgra_premul;
1110 fastProc = &fast_swizzle_rgba_to_bgra_premul;
1111 }
msaretta45a6682016-04-22 13:18:37 -07001112 } else {
msarett68758ae2016-04-25 11:41:15 -07001113 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
1114 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
1115 fastProc = &SkipLeading8888ZerosThen
1116 <fast_swizzle_rgba_to_bgra_unpremul>;
1117 } else {
1118 proc = &swizzle_rgba_to_bgra_unpremul;
1119 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
1120 }
msaretta45a6682016-04-22 13:18:37 -07001121 }
msarett68758ae2016-04-25 11:41:15 -07001122 break;
1123 default:
1124 return nullptr;
1125 }
1126 break;
1127 case SkEncodedInfo::kInvertedCMYK_Color:
1128 switch (dstInfo.colorType()) {
1129 case kRGBA_8888_SkColorType:
1130 proc = &swizzle_cmyk_to_rgba;
1131 fastProc = &fast_swizzle_cmyk_to_rgba;
1132 break;
1133 case kBGRA_8888_SkColorType:
1134 proc = &swizzle_cmyk_to_bgra;
1135 fastProc = &fast_swizzle_cmyk_to_bgra;
1136 break;
1137 case kRGB_565_SkColorType:
1138 proc = &swizzle_cmyk_to_565;
1139 break;
1140 default:
1141 return nullptr;
1142 }
1143 break;
1144 default:
1145 return nullptr;
1146 }
msarett74114382015-03-16 11:55:18 -07001147
msaretta45a6682016-04-22 13:18:37 -07001148 // Store bpp in bytes if it is an even multiple, otherwise use bits
1149 uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
1150 srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
1151 }
mtklein3d00db32016-01-11 06:16:26 -08001152
msarettfdb47572015-10-13 12:50:14 -07001153 int srcOffset = 0;
1154 int srcWidth = dstInfo.width();
msarett5af4e0b2015-11-17 11:18:03 -08001155 int dstOffset = 0;
1156 int dstWidth = srcWidth;
msarettfdb47572015-10-13 12:50:14 -07001157 if (options.fSubset) {
msarett5af4e0b2015-11-17 11:18:03 -08001158 // We do not currently support subset decodes for image types that may have
1159 // frames (gif).
1160 SkASSERT(!frame);
msarettfdb47572015-10-13 12:50:14 -07001161 srcOffset = options.fSubset->left();
1162 srcWidth = options.fSubset->width();
msarett5af4e0b2015-11-17 11:18:03 -08001163 dstWidth = srcWidth;
1164 } else if (frame) {
1165 dstOffset = frame->left();
1166 srcWidth = frame->width();
msarettfdb47572015-10-13 12:50:14 -07001167 }
emmaleer8f4ba762015-08-14 07:44:46 -07001168
msaretta51e7782016-01-12 06:51:11 -08001169 return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
1170 srcBPP, dstBPP);
scroggof24f2242015-03-03 08:59:20 -08001171}
1172
msaretta51e7782016-01-12 06:51:11 -08001173SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1174 int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1175 : fFastProc(fastProc)
msarett19032f72016-01-21 09:59:38 -08001176 , fSlowProc(proc)
1177 , fActualProc(fFastProc ? fFastProc : fSlowProc)
scroggof24f2242015-03-03 08:59:20 -08001178 , fColorTable(ctable)
msarettfdb47572015-10-13 12:50:14 -07001179 , fSrcOffset(srcOffset)
msarett5af4e0b2015-11-17 11:18:03 -08001180 , fDstOffset(dstOffset)
1181 , fSrcOffsetUnits(srcOffset * srcBPP)
1182 , fDstOffsetBytes(dstOffset * dstBPP)
1183 , fSrcWidth(srcWidth)
1184 , fDstWidth(dstWidth)
1185 , fSwizzleWidth(srcWidth)
1186 , fAllocatedWidth(dstWidth)
scroggoe7fc14b2015-10-02 13:14:46 -07001187 , fSampleX(1)
msarett5af4e0b2015-11-17 11:18:03 -08001188 , fSrcBPP(srcBPP)
1189 , fDstBPP(dstBPP)
scroggoe7fc14b2015-10-02 13:14:46 -07001190{}
1191
1192int SkSwizzler::onSetSampleX(int sampleX) {
msarett9972c422016-02-10 08:39:37 -08001193 SkASSERT(sampleX > 0);
1194
scroggoe7fc14b2015-10-02 13:14:46 -07001195 fSampleX = sampleX;
msarett5af4e0b2015-11-17 11:18:03 -08001196 fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
1197 fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
1198 fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
1199 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
scroggoe7fc14b2015-10-02 13:14:46 -07001200
msarett9972c422016-02-10 08:39:37 -08001201 // The optimized swizzler functions do not support sampling. Sampled swizzles
1202 // are already fast because they skip pixels. We haven't seen a situation
1203 // where speeding up sampling has a significant impact on total decode time.
msarett19032f72016-01-21 09:59:38 -08001204 if (1 == fSampleX && fFastProc) {
1205 fActualProc = fFastProc;
1206 } else {
1207 fActualProc = fSlowProc;
1208 }
msaretta51e7782016-01-12 06:51:11 -08001209
msarett5af4e0b2015-11-17 11:18:03 -08001210 return fAllocatedWidth;
emmaleer8f4ba762015-08-14 07:44:46 -07001211}
scroggof24f2242015-03-03 08:59:20 -08001212
msaretta4970dc2016-01-11 07:23:23 -08001213void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -07001214 SkASSERT(nullptr != dst && nullptr != src);
msarett19032f72016-01-21 09:59:38 -08001215 fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
msarett5af4e0b2015-11-17 11:18:03 -08001216 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
scroggof24f2242015-03-03 08:59:20 -08001217}