blob: 9cada7b39de74eeb4a0c1dcbada61a1685f6b1dd [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
msarett99f567e2015-08-05 12:58:26 -070054// kBit
55// These routines exclusively choose between white and black
56
57#define GRAYSCALE_BLACK 0
58#define GRAYSCALE_WHITE 0xFF
59
emmaleer8f4ba762015-08-14 07:44:46 -070060
61// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -080062static void swizzle_bit_to_grayscale(
emmaleer8f4ba762015-08-14 07:44:46 -070063 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -070064 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
emmaleer8f4ba762015-08-14 07:44:46 -070065
msarett99f567e2015-08-05 12:58:26 -070066 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
67
emmaleer8f4ba762015-08-14 07:44:46 -070068 // increment src by byte offset and bitIndex by bit offset
69 src += offset / 8;
70 int bitIndex = offset % 8;
71 uint8_t currByte = *src;
72
73 dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
74
75 for (int x = 1; x < dstWidth; x++) {
76 int bitOffset = bitIndex + deltaSrc;
77 bitIndex = bitOffset % 8;
78 currByte = *(src += bitOffset / 8);
79 dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
msarett99f567e2015-08-05 12:58:26 -070080 }
msarett99f567e2015-08-05 12:58:26 -070081}
82
83#undef GRAYSCALE_BLACK
84#undef GRAYSCALE_WHITE
85
emmaleer8f4ba762015-08-14 07:44:46 -070086// same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x]
msaretta4970dc2016-01-11 07:23:23 -080087static void swizzle_bit_to_index(
emmaleer8f4ba762015-08-14 07:44:46 -070088 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -070089 int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
msarett99f567e2015-08-05 12:58:26 -070090 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
91
emmaleer8f4ba762015-08-14 07:44:46 -070092 // increment src by byte offset and bitIndex by bit offset
93 src += offset / 8;
94 int bitIndex = offset % 8;
95 uint8_t currByte = *src;
96
97 dst[0] = ((currByte >> (7-bitIndex)) & 1);
98
99 for (int x = 1; x < dstWidth; x++) {
100 int bitOffset = bitIndex + deltaSrc;
101 bitIndex = bitOffset % 8;
102 currByte = *(src += bitOffset / 8);
103 dst[x] = ((currByte >> (7-bitIndex)) & 1);
msarett99f567e2015-08-05 12:58:26 -0700104 }
msarett99f567e2015-08-05 12:58:26 -0700105}
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*/) {
157 static const 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 static const uint64_t kBlack = (((uint64_t) 0) << 0) |
162 (((uint64_t) 0) << 16) |
163 (((uint64_t) 0) << 32) |
164 (((uint64_t) SK_Half1) << 48);
165
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_index(
emmaleer8f4ba762015-08-14 07:44: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[]) {
msarett438b2ad2015-04-09 12:43:10 -0700188
msarett5406d6f2015-08-31 06:55:13 -0700189 uint8_t* dst = (uint8_t*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700190 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] = index;
msarett5406d6f2015-08-31 06:55:13 -0700196
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] = index;
msarett438b2ad2015-04-09 12:43:10 -0700203 }
msarett438b2ad2015-04-09 12:43:10 -0700204}
205
msaretta4970dc2016-01-11 07:23:23 -0800206static void swizzle_small_index_to_565(
scroggocc2feb12015-08-14 08:32: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[]) {
scroggocc2feb12015-08-14 08:32:46 -0700209
msarett5406d6f2015-08-31 06:55:13 -0700210 uint16_t* dst = (uint16_t*) dstRow;
211 src += offset / 8;
212 int bitIndex = offset % 8;
213 uint8_t currByte = *src;
214 const uint8_t mask = (1 << bpp) - 1;
215 uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
216 dst[0] = SkPixel32ToPixel16(ctable[index]);
217
218 for (int x = 1; x < dstWidth; x++) {
219 int bitOffset = bitIndex + deltaSrc;
220 bitIndex = bitOffset % 8;
221 currByte = *(src += bitOffset / 8);
222 index = (currByte >> (8 - bpp - bitIndex)) & mask;
223 dst[x] = SkPixel32ToPixel16(ctable[index]);
scroggocc2feb12015-08-14 08:32:46 -0700224 }
scroggocc2feb12015-08-14 08:32:46 -0700225}
226
msaretta4970dc2016-01-11 07:23:23 -0800227static void swizzle_small_index_to_n32(
emmaleer8f4ba762015-08-14 07:44: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[]) {
msarett74114382015-03-16 11:55:18 -0700230
msarett5406d6f2015-08-31 06:55:13 -0700231 SkPMColor* dst = (SkPMColor*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700232 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] = ctable[index];
msarett5406d6f2015-08-31 06:55:13 -0700238
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] = ctable[index];
msarett74114382015-03-16 11:55:18 -0700245 }
msarett74114382015-03-16 11:55:18 -0700246}
247
msarette16b04a2015-04-15 07:32:19 -0700248// kIndex
249
msaretta4970dc2016-01-11 07:23:23 -0800250static void swizzle_index_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700251 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700252 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700253
254 src += offset;
255 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700256 for (int x = 0; x < dstWidth; x++) {
257 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700258 dst[x] = c;
259 src += deltaSrc;
260 }
emmaleer8f4ba762015-08-14 07:44:46 -0700261}
262
msaretta4970dc2016-01-11 07:23:23 -0800263static void swizzle_index_to_n32_skipZ(
emmaleer8f4ba762015-08-14 07:44:46 -0700264 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700265 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700266
267 src += offset;
268 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700269 for (int x = 0; x < dstWidth; x++) {
270 SkPMColor c = ctable[*src];
emmaleer8f4ba762015-08-14 07:44:46 -0700271 if (c != 0) {
272 dst[x] = c;
273 }
274 src += deltaSrc;
275 }
emmaleer8f4ba762015-08-14 07:44:46 -0700276}
277
msaretta4970dc2016-01-11 07:23:23 -0800278static void swizzle_index_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700279 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700280 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
emmaleer8f4ba762015-08-14 07:44:46 -0700281 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700282 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700283 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700284 dst[x] = SkPixel32ToPixel16(ctable[*src]);
msarett5406d6f2015-08-31 06:55:13 -0700285 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700286 }
scroggoab60c5b2015-08-06 06:08:18 -0700287}
288
msarette16b04a2015-04-15 07:32:19 -0700289// kGray
290
msaretta4970dc2016-01-11 07:23:23 -0800291static void swizzle_gray_to_n32(
emmaleer8f4ba762015-08-14 07:44:46 -0700292 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700293 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarette16b04a2015-04-15 07:32:19 -0700294
emmaleer8f4ba762015-08-14 07:44:46 -0700295 src += offset;
msarette16b04a2015-04-15 07:32:19 -0700296 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700297 for (int x = 0; x < dstWidth; x++) {
298 dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
299 src += deltaSrc;
msarette16b04a2015-04-15 07:32:19 -0700300 }
msarette16b04a2015-04-15 07:32:19 -0700301}
302
msarett2eff71c2016-02-02 12:59:45 -0800303static void fast_swizzle_gray_to_n32(
304 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
305 const SkPMColor ctable[]) {
306
307 // This function must not be called if we are sampling. If we are not
308 // sampling, deltaSrc should equal bpp.
309 SkASSERT(deltaSrc == bpp);
310
311 // Note that there is no need to distinguish between RGB and BGR.
312 // Each color channel will get the same value.
313 SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
314}
315
msaretta4970dc2016-01-11 07:23:23 -0800316static void swizzle_gray_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700317 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700318 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800319
emmaleer8f4ba762015-08-14 07:44:46 -0700320 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700321 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700322 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700323 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
msarett5406d6f2015-08-31 06:55:13 -0700324 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700325 }
scroggoab60c5b2015-08-06 06:08:18 -0700326}
327
msarett93e613d2016-02-03 10:44:46 -0800328// kGrayAlpha
329
330static void swizzle_grayalpha_to_n32_unpremul(
331 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
332 const SkPMColor ctable[]) {
333
334 src += offset;
335 SkPMColor* dst32 = (SkPMColor*) dst;
336 for (int x = 0; x < width; x++) {
337 dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
338 src += deltaSrc;
339 }
340}
341
msarett1e060792016-02-03 11:17:43 -0800342static void fast_swizzle_grayalpha_to_n32_unpremul(
343 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
344 const SkPMColor ctable[]) {
345
346 // This function must not be called if we are sampling. If we are not
347 // sampling, deltaSrc should equal bpp.
348 SkASSERT(deltaSrc == bpp);
349
350 // Note that there is no need to distinguish between RGB and BGR.
351 // Each color channel will get the same value.
352 SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
353}
354
msarett93e613d2016-02-03 10:44:46 -0800355static void swizzle_grayalpha_to_n32_premul(
356 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
357 const SkPMColor ctable[]) {
358
359 src += offset;
360 SkPMColor* dst32 = (SkPMColor*) dst;
361 for (int x = 0; x < width; x++) {
362 uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
363 dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
364 src += deltaSrc;
365 }
366}
367
msarett1e060792016-02-03 11:17:43 -0800368static void fast_swizzle_grayalpha_to_n32_premul(
369 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
370 const SkPMColor ctable[]) {
371
372 // This function must not be called if we are sampling. If we are not
373 // sampling, deltaSrc should equal bpp.
374 SkASSERT(deltaSrc == bpp);
375
376 // Note that there is no need to distinguish between rgb and bgr.
377 // Each color channel will get the same value.
378 SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
379}
380
msarett34e0ec42016-04-22 16:27:24 -0700381// kBGR
msarette16b04a2015-04-15 07:32:19 -0700382
msarett34e0ec42016-04-22 16:27:24 -0700383static void swizzle_bgr_to_565(
scroggocc2feb12015-08-14 08:32:46 -0700384 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700385 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800386
scroggocc2feb12015-08-14 08:32:46 -0700387 src += offset;
388 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
389 for (int x = 0; x < dstWidth; x++) {
390 dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
391 src += deltaSrc;
392 }
scroggocc2feb12015-08-14 08:32:46 -0700393}
394
msarettbda86092016-01-19 10:40:12 -0800395// kRGB
msarett03108de2016-01-15 11:02:36 -0800396
msarett34e0ec42016-04-22 16:27:24 -0700397static void swizzle_rgb_to_rgba(
emmaleer8f4ba762015-08-14 07:44:46 -0700398 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700399 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700400
emmaleer8f4ba762015-08-14 07:44:46 -0700401 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800402 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700403 for (int x = 0; x < dstWidth; x++) {
msarett34e0ec42016-04-22 16:27:24 -0700404 dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700405 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800406 }
scroggof24f2242015-03-03 08:59:20 -0800407}
408
msarett34e0ec42016-04-22 16:27:24 -0700409static void swizzle_rgb_to_bgra(
410 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
411 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
412
413 src += offset;
414 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
415 for (int x = 0; x < dstWidth; x++) {
416 dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
417 src += deltaSrc;
418 }
419}
420
421static void fast_swizzle_rgb_to_rgba(
msarettf1b8b6a2016-01-22 09:54:21 -0800422 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
423 int offset, const SkPMColor ctable[]) {
msarett03108de2016-01-15 11:02:36 -0800424
msarettf1b8b6a2016-01-22 09:54:21 -0800425 // This function must not be called if we are sampling. If we are not
426 // sampling, deltaSrc should equal bpp.
427 SkASSERT(deltaSrc == bpp);
428
msarettf1b8b6a2016-01-22 09:54:21 -0800429 SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
msarett34e0ec42016-04-22 16:27:24 -0700430}
431
432static void fast_swizzle_rgb_to_bgra(
433 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
434 int offset, const SkPMColor ctable[]) {
435
436 // This function must not be called if we are sampling. If we are not
437 // sampling, deltaSrc should equal bpp.
438 SkASSERT(deltaSrc == bpp);
439
msarettf1b8b6a2016-01-22 09:54:21 -0800440 SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
msarettf1b8b6a2016-01-22 09:54:21 -0800441}
msarett03108de2016-01-15 11:02:36 -0800442
msarettbda86092016-01-19 10:40:12 -0800443static void swizzle_rgb_to_565(
emmaleer8f4ba762015-08-14 07:44:46 -0700444 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700445 int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
msaretta4970dc2016-01-11 07:23:23 -0800446
emmaleer8f4ba762015-08-14 07:44:46 -0700447 src += offset;
scroggoab60c5b2015-08-06 06:08:18 -0700448 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700449 for (int x = 0; x < dstWidth; x++) {
scroggoab60c5b2015-08-06 06:08:18 -0700450 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
msarett5406d6f2015-08-31 06:55:13 -0700451 src += deltaSrc;
scroggoab60c5b2015-08-06 06:08:18 -0700452 }
scroggoab60c5b2015-08-06 06:08:18 -0700453}
454
scroggoab60c5b2015-08-06 06:08:18 -0700455// kRGBA
msarett03108de2016-01-15 11:02:36 -0800456
msarett34e0ec42016-04-22 16:27:24 -0700457static void swizzle_rgba_to_rgba_premul(
emmaleer8f4ba762015-08-14 07:44:46 -0700458 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700459 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700460
emmaleer8f4ba762015-08-14 07:44:46 -0700461 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800462 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
emmaleer8f4ba762015-08-14 07:44:46 -0700463 for (int x = 0; x < dstWidth; x++) {
msarett34e0ec42016-04-22 16:27:24 -0700464 dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700465 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800466 }
scroggof24f2242015-03-03 08:59:20 -0800467}
468
msarett34e0ec42016-04-22 16:27:24 -0700469static void swizzle_rgba_to_bgra_premul(
470 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
471 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
472
473 src += offset;
474 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
475 for (int x = 0; x < dstWidth; x++) {
476 dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
477 src += deltaSrc;
478 }
479}
480
481static void fast_swizzle_rgba_to_rgba_premul(
msaretta51e7782016-01-12 06:51:11 -0800482 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
483 int offset, const SkPMColor ctable[]) {
484
485 // This function must not be called if we are sampling. If we are not
486 // sampling, deltaSrc should equal bpp.
487 SkASSERT(deltaSrc == bpp);
488
mtklein8bf7b792016-01-22 07:42:53 -0800489 SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
msaretta51e7782016-01-12 06:51:11 -0800490}
491
msarett34e0ec42016-04-22 16:27:24 -0700492static void fast_swizzle_rgba_to_bgra_premul(
493 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
494 int offset, const SkPMColor ctable[]) {
495
496 // This function must not be called if we are sampling. If we are not
497 // sampling, deltaSrc should equal bpp.
498 SkASSERT(deltaSrc == bpp);
499
500 SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
501}
502
503static void swizzle_rgba_to_bgra_unpremul(
emmaleer8f4ba762015-08-14 07:44:46 -0700504 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
msarett5406d6f2015-08-31 06:55:13 -0700505 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
msarett74114382015-03-16 11:55:18 -0700506
emmaleer8f4ba762015-08-14 07:44:46 -0700507 src += offset;
scroggof24f2242015-03-03 08:59:20 -0800508 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
emmaleer8f4ba762015-08-14 07:44:46 -0700509 for (int x = 0; x < dstWidth; x++) {
scroggof24f2242015-03-03 08:59:20 -0800510 unsigned alpha = src[3];
msarett34e0ec42016-04-22 16:27:24 -0700511 dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
emmaleer8f4ba762015-08-14 07:44:46 -0700512 src += deltaSrc;
scroggof24f2242015-03-03 08:59:20 -0800513 }
scroggof24f2242015-03-03 08:59:20 -0800514}
515
msarett34e0ec42016-04-22 16:27:24 -0700516static void fast_swizzle_rgba_to_bgra_unpremul(
msarettbda86092016-01-19 10:40:12 -0800517 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
518 const SkPMColor ctable[]) {
519
520 // This function must not be called if we are sampling. If we are not
521 // sampling, deltaSrc should equal bpp.
522 SkASSERT(deltaSrc == bpp);
523
mtklein8bf7b792016-01-22 07:42:53 -0800524 SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
msarettbda86092016-01-19 10:40:12 -0800525}
526
scroggoef27d892015-10-23 09:29:22 -0700527// kCMYK
528//
529// CMYK is stored as four bytes per pixel.
530//
531// We will implement a crude conversion from CMYK -> RGB using formulas
532// from easyrgb.com.
533//
534// CMYK -> CMY
535// C = C * (1 - K) + K
536// M = M * (1 - K) + K
537// Y = Y * (1 - K) + K
538//
539// libjpeg actually gives us inverted CMYK, so we must subtract the
540// original terms from 1.
541// CMYK -> CMY
542// C = (1 - C) * (1 - (1 - K)) + (1 - K)
543// M = (1 - M) * (1 - (1 - K)) + (1 - K)
544// Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
545//
546// Simplifying the above expression.
547// CMYK -> CMY
548// C = 1 - CK
549// M = 1 - MK
550// Y = 1 - YK
551//
552// CMY -> RGB
553// R = (1 - C) * 255
554// G = (1 - M) * 255
555// B = (1 - Y) * 255
556//
557// Therefore the full conversion is below. This can be verified at
558// www.rapidtables.com (assuming inverted CMYK).
559// CMYK -> RGB
560// R = C * K * 255
561// G = M * K * 255
562// B = Y * K * 255
563//
564// As a final note, we have treated the CMYK values as if they were on
565// a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
566// We must divide each CMYK component by 255 to obtain the true conversion
567// we should perform.
568// CMYK -> RGB
569// R = C * K / 255
570// G = M * K / 255
571// B = Y * K / 255
msarett34e0ec42016-04-22 16:27:24 -0700572static void swizzle_cmyk_to_rgba(
scroggoef27d892015-10-23 09:29:22 -0700573 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
574 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
575
576 src += offset;
577 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
578 for (int x = 0; x < dstWidth; x++) {
579 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
580 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
581 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
582
msarett34e0ec42016-04-22 16:27:24 -0700583 dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
scroggoef27d892015-10-23 09:29:22 -0700584 src += deltaSrc;
585 }
scroggoef27d892015-10-23 09:29:22 -0700586}
587
msarett34e0ec42016-04-22 16:27:24 -0700588static void swizzle_cmyk_to_bgra(
589 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
590 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
591
592 src += offset;
593 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
594 for (int x = 0; x < dstWidth; x++) {
595 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
596 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
597 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
598
599 dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
600 src += deltaSrc;
601 }
602}
603
604static void fast_swizzle_cmyk_to_rgba(
msarettc5c322d2016-02-08 13:26:25 -0800605 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
606 const SkPMColor ctable[]) {
607
608 // This function must not be called if we are sampling. If we are not
609 // sampling, deltaSrc should equal bpp.
610 SkASSERT(deltaSrc == bpp);
611
msarettc5c322d2016-02-08 13:26:25 -0800612 SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
msarett34e0ec42016-04-22 16:27:24 -0700613}
614
615static void fast_swizzle_cmyk_to_bgra(
616 void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
617 const SkPMColor ctable[]) {
618
619 // This function must not be called if we are sampling. If we are not
620 // sampling, deltaSrc should equal bpp.
621 SkASSERT(deltaSrc == bpp);
622
msarettc5c322d2016-02-08 13:26:25 -0800623 SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
msarettc5c322d2016-02-08 13:26:25 -0800624}
625
msaretta4970dc2016-01-11 07:23:23 -0800626static void swizzle_cmyk_to_565(
scroggoef27d892015-10-23 09:29:22 -0700627 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
628 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
629
630 src += offset;
631 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
632 for (int x = 0; x < dstWidth; x++) {
633 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
634 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
635 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
636
637 dst[x] = SkPack888ToRGB16(r, g, b);
638 src += deltaSrc;
639 }
scroggoef27d892015-10-23 09:29:22 -0700640}
641
mtklein8604ca22016-01-11 13:13:55 -0800642template <SkSwizzler::RowProc proc>
msarett93e613d2016-02-03 10:44:46 -0800643void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
644 void* dst, const uint8_t* src, int width,
645 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
646 SkASSERT(!ctable);
647
648 const uint16_t* src16 = (const uint16_t*) (src + offset);
649 uint32_t* dst32 = (uint32_t*) dst;
650
651 // This may miss opportunities to skip when the output is premultiplied,
652 // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
653 while (width > 0 && *src16 == 0x0000) {
654 width--;
655 dst32++;
656 src16 += deltaSrc / 2;
657 }
658 proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
659}
660
661template <SkSwizzler::RowProc proc>
mtklein8604ca22016-01-11 13:13:55 -0800662void SkSwizzler::SkipLeading8888ZerosThen(
663 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
664 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
665 SkASSERT(!ctable);
666
667 auto src32 = (const uint32_t*)(src+offset);
668 auto dst32 = (uint32_t*)dstRow;
669
670 // This may miss opportunities to skip when the output is premultiplied,
671 // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
672 while (dstWidth > 0 && *src32 == 0x00000000) {
673 dstWidth--;
674 dst32++;
675 src32 += deltaSrc/4;
scroggof24f2242015-03-03 08:59:20 -0800676 }
mtklein8604ca22016-01-11 13:13:55 -0800677 proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
scroggof24f2242015-03-03 08:59:20 -0800678}
scroggof24f2242015-03-03 08:59:20 -0800679
msaretta45a6682016-04-22 13:18:37 -0700680SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
msarett74114382015-03-16 11:55:18 -0700681 const SkPMColor* ctable,
msarettfdb47572015-10-13 12:50:14 -0700682 const SkImageInfo& dstInfo,
msarett5af4e0b2015-11-17 11:18:03 -0800683 const SkCodec::Options& options,
msarett68758ae2016-04-25 11:41:15 -0700684 const SkIRect* frame,
Matt Sarett9bf39c22016-12-13 13:29:54 -0500685 bool skipFormatConversion) {
msaretta45a6682016-04-22 13:18:37 -0700686 if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
halcanary96fcdcc2015-08-27 07:41:13 -0700687 return nullptr;
scroggof24f2242015-03-03 08:59:20 -0800688 }
msaretta45a6682016-04-22 13:18:37 -0700689
msaretta51e7782016-01-12 06:51:11 -0800690 RowProc fastProc = nullptr;
halcanary96fcdcc2015-08-27 07:41:13 -0700691 RowProc proc = nullptr;
Matt Sarett9bf39c22016-12-13 13:29:54 -0500692 if (skipFormatConversion) {
msarett68758ae2016-04-25 11:41:15 -0700693 switch (dstInfo.colorType()) {
694 case kGray_8_SkColorType:
695 proc = &sample1;
696 fastProc = &copy;
697 break;
698 case kRGB_565_SkColorType:
699 proc = &sample2;
700 fastProc = &copy;
701 break;
702 case kRGBA_8888_SkColorType:
703 case kBGRA_8888_SkColorType:
704 proc = &sample4;
705 fastProc = &copy;
706 break;
707 default:
708 return nullptr;
709 }
710 } else {
711 SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
712 const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
713 (kPremul_SkAlphaType == dstInfo.alphaType());
714
715 switch (encodedInfo.color()) {
716 case SkEncodedInfo::kGray_Color:
717 switch (encodedInfo.bitsPerComponent()) {
718 case 1:
719 switch (dstInfo.colorType()) {
720 case kRGBA_8888_SkColorType:
721 case kBGRA_8888_SkColorType:
722 proc = &swizzle_bit_to_n32;
723 break;
724 case kIndex_8_SkColorType:
725 proc = &swizzle_bit_to_index;
726 break;
727 case kRGB_565_SkColorType:
728 proc = &swizzle_bit_to_565;
729 break;
730 case kGray_8_SkColorType:
731 proc = &swizzle_bit_to_grayscale;
732 break;
Matt Saretta225e9b2016-11-07 10:26:17 -0500733 case kRGBA_F16_SkColorType:
734 proc = &swizzle_bit_to_f16;
735 break;
msarett68758ae2016-04-25 11:41:15 -0700736 default:
737 return nullptr;
msaretta45a6682016-04-22 13:18:37 -0700738 }
msarett68758ae2016-04-25 11:41:15 -0700739 break;
740 case 8:
741 switch (dstInfo.colorType()) {
742 case kRGBA_8888_SkColorType:
743 case kBGRA_8888_SkColorType:
744 proc = &swizzle_gray_to_n32;
745 fastProc = &fast_swizzle_gray_to_n32;
746 break;
747 case kGray_8_SkColorType:
748 proc = &sample1;
749 fastProc = &copy;
750 break;
751 case kRGB_565_SkColorType:
752 proc = &swizzle_gray_to_565;
753 break;
754 default:
755 return nullptr;
msarett93e613d2016-02-03 10:44:46 -0800756 }
msarett68758ae2016-04-25 11:41:15 -0700757 break;
758 default:
759 return nullptr;
760 }
761 break;
762 case SkEncodedInfo::kGrayAlpha_Color:
763 switch (dstInfo.colorType()) {
764 case kRGBA_8888_SkColorType:
765 case kBGRA_8888_SkColorType:
766 if (premultiply) {
msaretta45a6682016-04-22 13:18:37 -0700767 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
msarett68758ae2016-04-25 11:41:15 -0700768 proc = &SkipLeadingGrayAlphaZerosThen
769 <swizzle_grayalpha_to_n32_premul>;
770 fastProc = &SkipLeadingGrayAlphaZerosThen
771 <fast_swizzle_grayalpha_to_n32_premul>;
msaretta45a6682016-04-22 13:18:37 -0700772 } else {
msarett68758ae2016-04-25 11:41:15 -0700773 proc = &swizzle_grayalpha_to_n32_premul;
774 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
msaretta45a6682016-04-22 13:18:37 -0700775 }
scroggof24f2242015-03-03 08:59:20 -0800776 } else {
msarett68758ae2016-04-25 11:41:15 -0700777 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
778 proc = &SkipLeadingGrayAlphaZerosThen
779 <swizzle_grayalpha_to_n32_unpremul>;
780 fastProc = &SkipLeadingGrayAlphaZerosThen
781 <fast_swizzle_grayalpha_to_n32_unpremul>;
782 } else {
783 proc = &swizzle_grayalpha_to_n32_unpremul;
784 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
785 }
scroggof24f2242015-03-03 08:59:20 -0800786 }
msarett68758ae2016-04-25 11:41:15 -0700787 break;
788 default:
789 return nullptr;
790 }
791 break;
792 case SkEncodedInfo::kPalette_Color:
793 // We assume that the color table is premultiplied and swizzled
794 // as desired.
795 switch (encodedInfo.bitsPerComponent()) {
796 case 1:
797 case 2:
798 case 4:
799 switch (dstInfo.colorType()) {
800 case kRGBA_8888_SkColorType:
801 case kBGRA_8888_SkColorType:
802 proc = &swizzle_small_index_to_n32;
803 break;
804 case kRGB_565_SkColorType:
805 proc = &swizzle_small_index_to_565;
806 break;
807 case kIndex_8_SkColorType:
808 proc = &swizzle_small_index_to_index;
809 break;
810 default:
811 return nullptr;
812 }
813 break;
814 case 8:
815 switch (dstInfo.colorType()) {
816 case kRGBA_8888_SkColorType:
817 case kBGRA_8888_SkColorType:
818 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
819 proc = &swizzle_index_to_n32_skipZ;
820 } else {
821 proc = &swizzle_index_to_n32;
822 }
823 break;
824 case kRGB_565_SkColorType:
825 proc = &swizzle_index_to_565;
826 break;
827 case kIndex_8_SkColorType:
828 proc = &sample1;
829 fastProc = &copy;
830 break;
831 default:
832 return nullptr;
833 }
834 break;
835 default:
836 return nullptr;
837 }
838 break;
839 case SkEncodedInfo::kRGB_Color:
840 switch (dstInfo.colorType()) {
841 case kRGBA_8888_SkColorType:
842 proc = &swizzle_rgb_to_rgba;
843 fastProc = &fast_swizzle_rgb_to_rgba;
844 break;
845 case kBGRA_8888_SkColorType:
846 proc = &swizzle_rgb_to_bgra;
847 fastProc = &fast_swizzle_rgb_to_bgra;
848 break;
849 case kRGB_565_SkColorType:
850 proc = &swizzle_rgb_to_565;
851 break;
852 default:
853 return nullptr;
854 }
855 break;
856 case SkEncodedInfo::kRGBA_Color:
857 switch (dstInfo.colorType()) {
858 case kRGBA_8888_SkColorType:
859 if (premultiply) {
860 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
861 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
862 fastProc = &SkipLeading8888ZerosThen
863 <fast_swizzle_rgba_to_rgba_premul>;
864 } else {
865 proc = &swizzle_rgba_to_rgba_premul;
866 fastProc = &fast_swizzle_rgba_to_rgba_premul;
867 }
msaretta45a6682016-04-22 13:18:37 -0700868 } else {
msarett68758ae2016-04-25 11:41:15 -0700869 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
870 proc = &SkipLeading8888ZerosThen<sample4>;
871 fastProc = &SkipLeading8888ZerosThen<copy>;
872 } else {
873 proc = &sample4;
874 fastProc = &copy;
875 }
msarett34e0ec42016-04-22 16:27:24 -0700876 }
msarett68758ae2016-04-25 11:41:15 -0700877 break;
878 case kBGRA_8888_SkColorType:
879 if (premultiply) {
880 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
881 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
882 fastProc = &SkipLeading8888ZerosThen
883 <fast_swizzle_rgba_to_bgra_premul>;
884 } else {
885 proc = &swizzle_rgba_to_bgra_premul;
886 fastProc = &fast_swizzle_rgba_to_bgra_premul;
887 }
msarett34e0ec42016-04-22 16:27:24 -0700888 } else {
msarett68758ae2016-04-25 11:41:15 -0700889 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
890 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
891 fastProc = &SkipLeading8888ZerosThen
892 <fast_swizzle_rgba_to_bgra_unpremul>;
893 } else {
894 proc = &swizzle_rgba_to_bgra_unpremul;
895 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
896 }
msarett34e0ec42016-04-22 16:27:24 -0700897 }
msarett68758ae2016-04-25 11:41:15 -0700898 break;
899 default:
900 return nullptr;
901 }
902 break;
903 case SkEncodedInfo::kBGR_Color:
904 switch (dstInfo.colorType()) {
905 case kBGRA_8888_SkColorType:
906 proc = &swizzle_rgb_to_rgba;
907 fastProc = &fast_swizzle_rgb_to_rgba;
908 break;
909 case kRGBA_8888_SkColorType:
910 proc = &swizzle_rgb_to_bgra;
911 fastProc = &fast_swizzle_rgb_to_bgra;
912 break;
913 case kRGB_565_SkColorType:
914 proc = &swizzle_bgr_to_565;
915 break;
916 default:
917 return nullptr;
918 }
919 break;
920 case SkEncodedInfo::kBGRX_Color:
921 switch (dstInfo.colorType()) {
922 case kBGRA_8888_SkColorType:
923 proc = &swizzle_rgb_to_rgba;
924 break;
925 case kRGBA_8888_SkColorType:
926 proc = &swizzle_rgb_to_bgra;
927 break;
928 case kRGB_565_SkColorType:
929 proc = &swizzle_bgr_to_565;
930 break;
931 default:
932 return nullptr;
933 }
934 break;
935 case SkEncodedInfo::kBGRA_Color:
936 switch (dstInfo.colorType()) {
937 case kBGRA_8888_SkColorType:
938 if (premultiply) {
939 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
940 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
941 fastProc = &SkipLeading8888ZerosThen
942 <fast_swizzle_rgba_to_rgba_premul>;
943 } else {
944 proc = &swizzle_rgba_to_rgba_premul;
945 fastProc = &fast_swizzle_rgba_to_rgba_premul;
946 }
msarett34e0ec42016-04-22 16:27:24 -0700947 } else {
msarett68758ae2016-04-25 11:41:15 -0700948 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
949 proc = &SkipLeading8888ZerosThen<sample4>;
950 fastProc = &SkipLeading8888ZerosThen<copy>;
951 } else {
952 proc = &sample4;
953 fastProc = &copy;
954 }
msaretta45a6682016-04-22 13:18:37 -0700955 }
msarett68758ae2016-04-25 11:41:15 -0700956 break;
957 case kRGBA_8888_SkColorType:
958 if (premultiply) {
959 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
960 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
961 fastProc = &SkipLeading8888ZerosThen
962 <fast_swizzle_rgba_to_bgra_premul>;
963 } else {
964 proc = &swizzle_rgba_to_bgra_premul;
965 fastProc = &fast_swizzle_rgba_to_bgra_premul;
966 }
msaretta45a6682016-04-22 13:18:37 -0700967 } else {
msarett68758ae2016-04-25 11:41:15 -0700968 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
969 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
970 fastProc = &SkipLeading8888ZerosThen
971 <fast_swizzle_rgba_to_bgra_unpremul>;
972 } else {
973 proc = &swizzle_rgba_to_bgra_unpremul;
974 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
975 }
msaretta45a6682016-04-22 13:18:37 -0700976 }
msarett68758ae2016-04-25 11:41:15 -0700977 break;
978 default:
979 return nullptr;
980 }
981 break;
982 case SkEncodedInfo::kInvertedCMYK_Color:
983 switch (dstInfo.colorType()) {
984 case kRGBA_8888_SkColorType:
985 proc = &swizzle_cmyk_to_rgba;
986 fastProc = &fast_swizzle_cmyk_to_rgba;
987 break;
988 case kBGRA_8888_SkColorType:
989 proc = &swizzle_cmyk_to_bgra;
990 fastProc = &fast_swizzle_cmyk_to_bgra;
991 break;
992 case kRGB_565_SkColorType:
993 proc = &swizzle_cmyk_to_565;
994 break;
995 default:
996 return nullptr;
997 }
998 break;
999 default:
1000 return nullptr;
1001 }
scroggof24f2242015-03-03 08:59:20 -08001002 }
msarett74114382015-03-16 11:55:18 -07001003
msaretta45a6682016-04-22 13:18:37 -07001004 int srcBPP;
msarett68758ae2016-04-25 11:41:15 -07001005 const int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
Matt Sarett9bf39c22016-12-13 13:29:54 -05001006 if (skipFormatConversion) {
msaretta45a6682016-04-22 13:18:37 -07001007 srcBPP = dstBPP;
1008 } else {
1009 // Store bpp in bytes if it is an even multiple, otherwise use bits
1010 uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
1011 srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
1012 }
mtklein3d00db32016-01-11 06:16:26 -08001013
msarettfdb47572015-10-13 12:50:14 -07001014 int srcOffset = 0;
1015 int srcWidth = dstInfo.width();
msarett5af4e0b2015-11-17 11:18:03 -08001016 int dstOffset = 0;
1017 int dstWidth = srcWidth;
msarettfdb47572015-10-13 12:50:14 -07001018 if (options.fSubset) {
msarett5af4e0b2015-11-17 11:18:03 -08001019 // We do not currently support subset decodes for image types that may have
1020 // frames (gif).
1021 SkASSERT(!frame);
msarettfdb47572015-10-13 12:50:14 -07001022 srcOffset = options.fSubset->left();
1023 srcWidth = options.fSubset->width();
msarett5af4e0b2015-11-17 11:18:03 -08001024 dstWidth = srcWidth;
1025 } else if (frame) {
1026 dstOffset = frame->left();
1027 srcWidth = frame->width();
msarettfdb47572015-10-13 12:50:14 -07001028 }
emmaleer8f4ba762015-08-14 07:44:46 -07001029
msaretta51e7782016-01-12 06:51:11 -08001030 return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
1031 srcBPP, dstBPP);
scroggof24f2242015-03-03 08:59:20 -08001032}
1033
msaretta51e7782016-01-12 06:51:11 -08001034SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1035 int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1036 : fFastProc(fastProc)
msarett19032f72016-01-21 09:59:38 -08001037 , fSlowProc(proc)
1038 , fActualProc(fFastProc ? fFastProc : fSlowProc)
scroggof24f2242015-03-03 08:59:20 -08001039 , fColorTable(ctable)
msarettfdb47572015-10-13 12:50:14 -07001040 , fSrcOffset(srcOffset)
msarett5af4e0b2015-11-17 11:18:03 -08001041 , fDstOffset(dstOffset)
1042 , fSrcOffsetUnits(srcOffset * srcBPP)
1043 , fDstOffsetBytes(dstOffset * dstBPP)
1044 , fSrcWidth(srcWidth)
1045 , fDstWidth(dstWidth)
1046 , fSwizzleWidth(srcWidth)
1047 , fAllocatedWidth(dstWidth)
scroggoe7fc14b2015-10-02 13:14:46 -07001048 , fSampleX(1)
msarett5af4e0b2015-11-17 11:18:03 -08001049 , fSrcBPP(srcBPP)
1050 , fDstBPP(dstBPP)
scroggoe7fc14b2015-10-02 13:14:46 -07001051{}
1052
1053int SkSwizzler::onSetSampleX(int sampleX) {
msarett9972c422016-02-10 08:39:37 -08001054 SkASSERT(sampleX > 0);
1055
scroggoe7fc14b2015-10-02 13:14:46 -07001056 fSampleX = sampleX;
msarett5af4e0b2015-11-17 11:18:03 -08001057 fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
1058 fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
1059 fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
1060 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
scroggoe7fc14b2015-10-02 13:14:46 -07001061
msarett9972c422016-02-10 08:39:37 -08001062 // The optimized swizzler functions do not support sampling. Sampled swizzles
1063 // are already fast because they skip pixels. We haven't seen a situation
1064 // where speeding up sampling has a significant impact on total decode time.
msarett19032f72016-01-21 09:59:38 -08001065 if (1 == fSampleX && fFastProc) {
1066 fActualProc = fFastProc;
1067 } else {
1068 fActualProc = fSlowProc;
1069 }
msaretta51e7782016-01-12 06:51:11 -08001070
msarett5af4e0b2015-11-17 11:18:03 -08001071 return fAllocatedWidth;
emmaleer8f4ba762015-08-14 07:44:46 -07001072}
scroggof24f2242015-03-03 08:59:20 -08001073
msaretta4970dc2016-01-11 07:23:23 -08001074void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -07001075 SkASSERT(nullptr != dst && nullptr != src);
msarett19032f72016-01-21 09:59:38 -08001076 fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
msarett5af4e0b2015-11-17 11:18:03 -08001077 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
scroggof24f2242015-03-03 08:59:20 -08001078}