1f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo/*
2f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo * Copyright 2015 Google Inc.
3f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo *
4f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo * Use of this source code is governed by a BSD-style license that can be
5f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo * found in the LICENSE file.
6f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo */
7f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
8741143878b23d22cd9cb7b9cba8055179115ce17msarett#include "SkCodecPriv.h"
9a4083c97d48e8a4f88e2797d7363f141e3d42553Cary Clark#include "SkColorData.h"
10a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett#include "SkHalf.h"
11a51e7782b2e028a38712a159c412e6151eca1666msarett#include "SkOpts.h"
12f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo#include "SkSwizzler.h"
13f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo#include "SkTemplates.h"
14f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
15bda86098ab2784968d0a1222dd1f4c18d18fe050msarettstatic void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
16bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        const SkPMColor ctable[]) {
17bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    // This function must not be called if we are sampling.  If we are not
18bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    // sampling, deltaSrc should equal bpp.
19bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    SkASSERT(deltaSrc == bpp);
208f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
21bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    memcpy(dst, src + offset, width * bpp);
22bda86098ab2784968d0a1222dd1f4c18d18fe050msarett}
23bda86098ab2784968d0a1222dd1f4c18d18fe050msarett
24bda86098ab2784968d0a1222dd1f4c18d18fe050msarettstatic void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
25bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        const SkPMColor ctable[]) {
268f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
27bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    uint8_t* dst8 = (uint8_t*) dst;
28bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    for (int x = 0; x < width; x++) {
29bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        dst8[x] = *src;
30bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        src += deltaSrc;
31bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    }
32bda86098ab2784968d0a1222dd1f4c18d18fe050msarett}
33bda86098ab2784968d0a1222dd1f4c18d18fe050msarett
34bda86098ab2784968d0a1222dd1f4c18d18fe050msarettstatic void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
35bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        const SkPMColor ctable[]) {
36bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    src += offset;
37bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    uint16_t* dst16 = (uint16_t*) dst;
388f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < width; x++) {
39bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        dst16[x] = *((const uint16_t*) src);
408f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
418f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    }
428f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer}
438f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
44bda86098ab2784968d0a1222dd1f4c18d18fe050msarettstatic void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
45bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        const SkPMColor ctable[]) {
46bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    src += offset;
47bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    uint32_t* dst32 = (uint32_t*) dst;
48bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    for (int x = 0; x < width; x++) {
49bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        dst32[x] = *((const uint32_t*) src);
50bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        src += deltaSrc;
51bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    }
52bda86098ab2784968d0a1222dd1f4c18d18fe050msarett}
535406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett
5434c69d63477c8992d3242c02899008810e04af6eMatt Sarettstatic void sample6(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5534c69d63477c8992d3242c02899008810e04af6eMatt Sarett        const SkPMColor ctable[]) {
5634c69d63477c8992d3242c02899008810e04af6eMatt Sarett    src += offset;
5734c69d63477c8992d3242c02899008810e04af6eMatt Sarett    uint8_t* dst8 = (uint8_t*) dst;
5834c69d63477c8992d3242c02899008810e04af6eMatt Sarett    for (int x = 0; x < width; x++) {
5934c69d63477c8992d3242c02899008810e04af6eMatt Sarett        memcpy(dst8, src, 6);
6034c69d63477c8992d3242c02899008810e04af6eMatt Sarett        dst8 += 6;
6134c69d63477c8992d3242c02899008810e04af6eMatt Sarett        src += deltaSrc;
6234c69d63477c8992d3242c02899008810e04af6eMatt Sarett    }
6334c69d63477c8992d3242c02899008810e04af6eMatt Sarett}
6434c69d63477c8992d3242c02899008810e04af6eMatt Sarett
65379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarettstatic void sample8(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
66379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett        const SkPMColor ctable[]) {
67379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    src += offset;
68379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    uint64_t* dst64 = (uint64_t*) dst;
69379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    for (int x = 0; x < width; x++) {
70379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett        dst64[x] = *((const uint64_t*) src);
71379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett        src += deltaSrc;
72379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    }
73379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett}
74379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett
7599f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett// kBit
7699f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett// These routines exclusively choose between white and black
7799f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
7899f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett#define GRAYSCALE_BLACK 0
7999f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett#define GRAYSCALE_WHITE 0xFF
8099f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
818f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
828f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
83a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_bit_to_grayscale(
848f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
855406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
868f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
8799f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett    uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
8899f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
898f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    // increment src by byte offset and bitIndex by bit offset
908f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset / 8;
918f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    int bitIndex = offset % 8;
928f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    uint8_t currByte = *src;
93b157917507d4f7d2651f0aeb566d31603cc02240emmaleer
948f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
958f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
968f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 1; x < dstWidth; x++) {
978f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        int bitOffset = bitIndex + deltaSrc;
988f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        bitIndex = bitOffset % 8;
998f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        currByte = *(src += bitOffset / 8);
1008f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
101b0a32cc38fcd8f37a23dfa19e928aeca529eaf14egdaniel    }
10299f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett}
10399f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
10499f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett#undef GRAYSCALE_BLACK
10599f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett#undef GRAYSCALE_WHITE
10699f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
1078f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer// same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
108a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_bit_to_n32(
1098f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
1105406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
11199f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
11299f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
1138f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    // increment src by byte offset and bitIndex by bit offset
1148f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset / 8;
1158f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    int bitIndex = offset % 8;
1168f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    uint8_t currByte = *src;
117b157917507d4f7d2651f0aeb566d31603cc02240emmaleer
1188f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
1198f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
1208f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 1; x < dstWidth; x++) {
1218f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        int bitOffset = bitIndex + deltaSrc;
1228f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        bitIndex = bitOffset % 8;
1238f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        currByte = *(src += bitOffset / 8);
1248f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
125b0a32cc38fcd8f37a23dfa19e928aeca529eaf14egdaniel    }
12699f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett}
12799f567e617b6c5a81e6b822c30ccb0d357db21fcmsarett
128cc2feb161f756c4035a407296567654d86bc7be7scroggo#define RGB565_BLACK 0
129cc2feb161f756c4035a407296567654d86bc7be7scroggo#define RGB565_WHITE 0xFFFF
130cc2feb161f756c4035a407296567654d86bc7be7scroggo
131a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_bit_to_565(
132cc2feb161f756c4035a407296567654d86bc7be7scroggo        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
1335406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
134cc2feb161f756c4035a407296567654d86bc7be7scroggo    uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
135cc2feb161f756c4035a407296567654d86bc7be7scroggo
136cc2feb161f756c4035a407296567654d86bc7be7scroggo    // increment src by byte offset and bitIndex by bit offset
137cc2feb161f756c4035a407296567654d86bc7be7scroggo    src += offset / 8;
138cc2feb161f756c4035a407296567654d86bc7be7scroggo    int bitIndex = offset % 8;
139cc2feb161f756c4035a407296567654d86bc7be7scroggo    uint8_t currByte = *src;
140cc2feb161f756c4035a407296567654d86bc7be7scroggo
141cc2feb161f756c4035a407296567654d86bc7be7scroggo    dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
142cc2feb161f756c4035a407296567654d86bc7be7scroggo
143cc2feb161f756c4035a407296567654d86bc7be7scroggo    for (int x = 1; x < dstWidth; x++) {
144cc2feb161f756c4035a407296567654d86bc7be7scroggo        int bitOffset = bitIndex + deltaSrc;
145cc2feb161f756c4035a407296567654d86bc7be7scroggo        bitIndex = bitOffset % 8;
146cc2feb161f756c4035a407296567654d86bc7be7scroggo        currByte = *(src += bitOffset / 8);
147cc2feb161f756c4035a407296567654d86bc7be7scroggo        dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
148cc2feb161f756c4035a407296567654d86bc7be7scroggo    }
149cc2feb161f756c4035a407296567654d86bc7be7scroggo}
150cc2feb161f756c4035a407296567654d86bc7be7scroggo
151cc2feb161f756c4035a407296567654d86bc7be7scroggo#undef RGB565_BLACK
152cc2feb161f756c4035a407296567654d86bc7be7scroggo#undef RGB565_WHITE
153cc2feb161f756c4035a407296567654d86bc7be7scroggo
154a225e9be53001a8397344ce1e272a7df2fced499Matt Sarettstatic void swizzle_bit_to_f16(
155a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
156a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett        int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
157862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III    constexpr uint64_t kWhite = (((uint64_t) SK_Half1) <<  0) |
158862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III                                (((uint64_t) SK_Half1) << 16) |
159862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III                                (((uint64_t) SK_Half1) << 32) |
160862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III                                (((uint64_t) SK_Half1) << 48);
161862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III    constexpr uint64_t kBlack = (((uint64_t)        0) <<  0) |
162862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III                                (((uint64_t)        0) << 16) |
163862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III                                (((uint64_t)        0) << 32) |
164862c19675edb26ed7cba56ae6ca9f98c1e4cbef1Leon Scroggins III                                (((uint64_t) SK_Half1) << 48);
165a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett
166a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    uint64_t* SK_RESTRICT dst = (uint64_t*) dstRow;
167a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett
168a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    // increment src by byte offset and bitIndex by bit offset
169a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    src += offset / 8;
170a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    int bitIndex = offset % 8;
171a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    uint8_t currByte = *src;
172a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett
173a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
174a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett
175a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    for (int x = 1; x < dstWidth; x++) {
176a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett        int bitOffset = bitIndex + deltaSrc;
177a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett        bitIndex = bitOffset % 8;
178a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett        currByte = *(src += bitOffset / 8);
179a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett        dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
180a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett    }
181a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett}
182a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett
183741143878b23d22cd9cb7b9cba8055179115ce17msarett// kIndex1, kIndex2, kIndex4
184741143878b23d22cd9cb7b9cba8055179115ce17msarett
185a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_small_index_to_565(
186cc2feb161f756c4035a407296567654d86bc7be7scroggo        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
1875406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
188cc2feb161f756c4035a407296567654d86bc7be7scroggo
1895406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    uint16_t* dst = (uint16_t*) dstRow;
1905406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    src += offset / 8;
1915406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    int bitIndex = offset % 8;
1925406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    uint8_t currByte = *src;
1935406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    const uint8_t mask = (1 << bpp) - 1;
1945406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
1955406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    dst[0] = SkPixel32ToPixel16(ctable[index]);
1965406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett
1975406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    for (int x = 1; x < dstWidth; x++) {
1985406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bitOffset = bitIndex + deltaSrc;
1995406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        bitIndex = bitOffset % 8;
2005406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        currByte = *(src += bitOffset / 8);
2015406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        index = (currByte >> (8 - bpp - bitIndex)) & mask;
2025406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        dst[x] = SkPixel32ToPixel16(ctable[index]);
203cc2feb161f756c4035a407296567654d86bc7be7scroggo    }
204cc2feb161f756c4035a407296567654d86bc7be7scroggo}
205cc2feb161f756c4035a407296567654d86bc7be7scroggo
206a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_small_index_to_n32(
2078f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
2085406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
209eed039b5ffbdff958053ac80b09451ad6caa1787msarett
2105406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    SkPMColor* dst = (SkPMColor*) dstRow;
2115406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    src += offset / 8;
2125406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    int bitIndex = offset % 8;
2135406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    uint8_t currByte = *src;
2145406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    const uint8_t mask = (1 << bpp) - 1;
2155406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
2165406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    dst[0] = ctable[index];
2175406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett
2185406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett    for (int x = 1; x < dstWidth; x++) {
2195406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bitOffset = bitIndex + deltaSrc;
2205406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        bitIndex = bitOffset % 8;
2215406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        currByte = *(src += bitOffset / 8);
2225406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        index = (currByte >> (8 - bpp - bitIndex)) & mask;
2235406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        dst[x] = ctable[index];
224eed039b5ffbdff958053ac80b09451ad6caa1787msarett    }
225438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett}
226438b2adefb9e9213e0ddaf0609405d3087a1cf0amsarett
227e16b04aa6041efb6507546547737e9603fa1606emsarett// kIndex
228e16b04aa6041efb6507546547737e9603fa1606emsarett
229a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_index_to_n32(
2308f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
2315406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
232f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
2338f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
234f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
2358f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
2368f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        SkPMColor c = ctable[*src];
237f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        dst[x] = c;
2388f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
239f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
240f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
241f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
242a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_index_to_n32_skipZ(
2438f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
2445406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
245f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
2468f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
247f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
2488f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
2498f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        SkPMColor c = ctable[*src];
250f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        if (c != 0) {
251f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo            dst[x] = c;
252f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        }
2538f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
254f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
255f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
256f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
257a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_index_to_565(
2588f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer      void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
2595406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett      int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
2608f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
261ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
2628f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
263ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo        dst[x] = SkPixel32ToPixel16(ctable[*src]);
2645406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        src += deltaSrc;
265ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo    }
266ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo}
267ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo
268e16b04aa6041efb6507546547737e9603fa1606emsarett// kGray
269e16b04aa6041efb6507546547737e9603fa1606emsarett
270a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_gray_to_n32(
2718f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
2725406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
273e16b04aa6041efb6507546547737e9603fa1606emsarett
2748f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
275e16b04aa6041efb6507546547737e9603fa1606emsarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
2768f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
2778f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
2788f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
279e16b04aa6041efb6507546547737e9603fa1606emsarett    }
280e16b04aa6041efb6507546547737e9603fa1606emsarett}
281e16b04aa6041efb6507546547737e9603fa1606emsarett
2822eff71c9b5f984b58961e5a6b4e66774c4385224msarettstatic void fast_swizzle_gray_to_n32(
2832eff71c9b5f984b58961e5a6b4e66774c4385224msarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
2842eff71c9b5f984b58961e5a6b4e66774c4385224msarett        const SkPMColor ctable[]) {
2852eff71c9b5f984b58961e5a6b4e66774c4385224msarett
2862eff71c9b5f984b58961e5a6b4e66774c4385224msarett    // This function must not be called if we are sampling.  If we are not
2872eff71c9b5f984b58961e5a6b4e66774c4385224msarett    // sampling, deltaSrc should equal bpp.
2882eff71c9b5f984b58961e5a6b4e66774c4385224msarett    SkASSERT(deltaSrc == bpp);
2892eff71c9b5f984b58961e5a6b4e66774c4385224msarett
2902eff71c9b5f984b58961e5a6b4e66774c4385224msarett    // Note that there is no need to distinguish between RGB and BGR.
2912eff71c9b5f984b58961e5a6b4e66774c4385224msarett    // Each color channel will get the same value.
2922eff71c9b5f984b58961e5a6b4e66774c4385224msarett    SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
2932eff71c9b5f984b58961e5a6b4e66774c4385224msarett}
2942eff71c9b5f984b58961e5a6b4e66774c4385224msarett
295a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_gray_to_565(
2968f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
2975406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
298a4970dc973459d2607ce80623452bf8470adf6f1msarett
2998f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
300ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
3018f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
302ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo        dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
3035406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        src += deltaSrc;
304ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo    }
305ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo}
306ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo
30793e613d6bdea05d96e232ed261d7bf886c91bb8emsarett// kGrayAlpha
30893e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
30993e613d6bdea05d96e232ed261d7bf886c91bb8emsarettstatic void swizzle_grayalpha_to_n32_unpremul(
31093e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
31193e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        const SkPMColor ctable[]) {
31293e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
31393e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    src += offset;
31493e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    SkPMColor* dst32 = (SkPMColor*) dst;
31593e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    for (int x = 0; x < width; x++) {
31693e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
31793e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        src += deltaSrc;
31893e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    }
31993e613d6bdea05d96e232ed261d7bf886c91bb8emsarett}
32093e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
3211e06079b259d1091b735492b2f71d9897c14c608msarettstatic void fast_swizzle_grayalpha_to_n32_unpremul(
3221e06079b259d1091b735492b2f71d9897c14c608msarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
3231e06079b259d1091b735492b2f71d9897c14c608msarett        const SkPMColor ctable[]) {
3241e06079b259d1091b735492b2f71d9897c14c608msarett
3251e06079b259d1091b735492b2f71d9897c14c608msarett    // This function must not be called if we are sampling.  If we are not
3261e06079b259d1091b735492b2f71d9897c14c608msarett    // sampling, deltaSrc should equal bpp.
3271e06079b259d1091b735492b2f71d9897c14c608msarett    SkASSERT(deltaSrc == bpp);
3281e06079b259d1091b735492b2f71d9897c14c608msarett
3291e06079b259d1091b735492b2f71d9897c14c608msarett    // Note that there is no need to distinguish between RGB and BGR.
3301e06079b259d1091b735492b2f71d9897c14c608msarett    // Each color channel will get the same value.
3311e06079b259d1091b735492b2f71d9897c14c608msarett    SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
3321e06079b259d1091b735492b2f71d9897c14c608msarett}
3331e06079b259d1091b735492b2f71d9897c14c608msarett
33493e613d6bdea05d96e232ed261d7bf886c91bb8emsarettstatic void swizzle_grayalpha_to_n32_premul(
33593e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
33693e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        const SkPMColor ctable[]) {
33793e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
33893e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    src += offset;
33993e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    SkPMColor* dst32 = (SkPMColor*) dst;
34093e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    for (int x = 0; x < width; x++) {
34193e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
34293e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
34393e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        src += deltaSrc;
34493e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    }
34593e613d6bdea05d96e232ed261d7bf886c91bb8emsarett}
34693e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
3471e06079b259d1091b735492b2f71d9897c14c608msarettstatic void fast_swizzle_grayalpha_to_n32_premul(
3481e06079b259d1091b735492b2f71d9897c14c608msarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
3491e06079b259d1091b735492b2f71d9897c14c608msarett        const SkPMColor ctable[]) {
3501e06079b259d1091b735492b2f71d9897c14c608msarett
3511e06079b259d1091b735492b2f71d9897c14c608msarett    // This function must not be called if we are sampling.  If we are not
3521e06079b259d1091b735492b2f71d9897c14c608msarett    // sampling, deltaSrc should equal bpp.
3531e06079b259d1091b735492b2f71d9897c14c608msarett    SkASSERT(deltaSrc == bpp);
3541e06079b259d1091b735492b2f71d9897c14c608msarett
3551e06079b259d1091b735492b2f71d9897c14c608msarett    // Note that there is no need to distinguish between rgb and bgr.
3561e06079b259d1091b735492b2f71d9897c14c608msarett    // Each color channel will get the same value.
3571e06079b259d1091b735492b2f71d9897c14c608msarett    SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
3581e06079b259d1091b735492b2f71d9897c14c608msarett}
3591e06079b259d1091b735492b2f71d9897c14c608msarett
360d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reedstatic void swizzle_grayalpha_to_a8(void* dst, const uint8_t* src, int width, int bpp,
361d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed                                    int deltaSrc, int offset, const SkPMColor[]) {
362d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed    src += offset;
363d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed    uint8_t* dst8 = (uint8_t*)dst;
364d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed    for (int x = 0; x < width; ++x) {
365d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed        dst8[x] = src[1];   // src[0] is gray, ignored
366d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed        src += deltaSrc;
367d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed    }
368d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed}
369d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed
37034e0ec40b10320765d4a4432f56e090556f9c75emsarett// kBGR
371e16b04aa6041efb6507546547737e9603fa1606emsarett
37234e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_bgr_to_565(
373cc2feb161f756c4035a407296567654d86bc7be7scroggo        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
3745406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
375a4970dc973459d2607ce80623452bf8470adf6f1msarett
376cc2feb161f756c4035a407296567654d86bc7be7scroggo    src += offset;
377cc2feb161f756c4035a407296567654d86bc7be7scroggo    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
378cc2feb161f756c4035a407296567654d86bc7be7scroggo    for (int x = 0; x < dstWidth; x++) {
379cc2feb161f756c4035a407296567654d86bc7be7scroggo        dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
380cc2feb161f756c4035a407296567654d86bc7be7scroggo        src += deltaSrc;
381cc2feb161f756c4035a407296567654d86bc7be7scroggo    }
382cc2feb161f756c4035a407296567654d86bc7be7scroggo}
383cc2feb161f756c4035a407296567654d86bc7be7scroggo
38434e0ec40b10320765d4a4432f56e090556f9c75emsarett// kRGB
385741143878b23d22cd9cb7b9cba8055179115ce17msarett
38634e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_rgb_to_rgba(
3878f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
3885406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
389741143878b23d22cd9cb7b9cba8055179115ce17msarett
3908f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
391741143878b23d22cd9cb7b9cba8055179115ce17msarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
3928f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
39334e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
3948f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
395741143878b23d22cd9cb7b9cba8055179115ce17msarett    }
396741143878b23d22cd9cb7b9cba8055179115ce17msarett}
397741143878b23d22cd9cb7b9cba8055179115ce17msarett
39834e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_rgb_to_bgra(
3998f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
4005406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
401eed039b5ffbdff958053ac80b09451ad6caa1787msarett
4028f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
403eed039b5ffbdff958053ac80b09451ad6caa1787msarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
4048f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
40534e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
4068f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
407eed039b5ffbdff958053ac80b09451ad6caa1787msarett    }
408eed039b5ffbdff958053ac80b09451ad6caa1787msarett}
409eed039b5ffbdff958053ac80b09451ad6caa1787msarett
41034e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_rgb_to_rgba(
41134e0ec40b10320765d4a4432f56e090556f9c75emsarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
41234e0ec40b10320765d4a4432f56e090556f9c75emsarett        int offset, const SkPMColor ctable[]) {
41303108de163354fa574679ad153b58ce57126b2bamsarett
41403108de163354fa574679ad153b58ce57126b2bamsarett    // This function must not be called if we are sampling.  If we are not
41503108de163354fa574679ad153b58ce57126b2bamsarett    // sampling, deltaSrc should equal bpp.
41603108de163354fa574679ad153b58ce57126b2bamsarett    SkASSERT(deltaSrc == bpp);
41703108de163354fa574679ad153b58ce57126b2bamsarett
41834e0ec40b10320765d4a4432f56e090556f9c75emsarett    SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
419f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
420f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
42134e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_rgb_to_bgra(
422f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
423f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett        int offset, const SkPMColor ctable[]) {
424f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett
425f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett    // This function must not be called if we are sampling.  If we are not
426f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett    // sampling, deltaSrc should equal bpp.
427f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett    SkASSERT(deltaSrc == bpp);
42803108de163354fa574679ad153b58ce57126b2bamsarett
429f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett    SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
430f1b8b6ae34e5a1f4b29e423401da39f88f0c117amsarett}
43103108de163354fa574679ad153b58ce57126b2bamsarett
432bda86098ab2784968d0a1222dd1f4c18d18fe050msarettstatic void swizzle_rgb_to_565(
4338f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer       void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
4345406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett       int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
435a4970dc973459d2607ce80623452bf8470adf6f1msarett
4368f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
437ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
4388f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
439ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo        dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
4405406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        src += deltaSrc;
441ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo    }
442ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo}
443ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo
444ab60c5bd9f360e9d58f0f34683b92fb841a514b1scroggo// kRGBA
44503108de163354fa574679ad153b58ce57126b2bamsarett
44634e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_rgba_to_rgba_premul(
4478f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
4485406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
449741143878b23d22cd9cb7b9cba8055179115ce17msarett
4508f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
451f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
4528f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
45334e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
45434e0ec40b10320765d4a4432f56e090556f9c75emsarett        src += deltaSrc;
45534e0ec40b10320765d4a4432f56e090556f9c75emsarett    }
45634e0ec40b10320765d4a4432f56e090556f9c75emsarett}
45734e0ec40b10320765d4a4432f56e090556f9c75emsarett
45834e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_rgba_to_bgra_premul(
45934e0ec40b10320765d4a4432f56e090556f9c75emsarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
46034e0ec40b10320765d4a4432f56e090556f9c75emsarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
46134e0ec40b10320765d4a4432f56e090556f9c75emsarett
46234e0ec40b10320765d4a4432f56e090556f9c75emsarett    src += offset;
46334e0ec40b10320765d4a4432f56e090556f9c75emsarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
46434e0ec40b10320765d4a4432f56e090556f9c75emsarett    for (int x = 0; x < dstWidth; x++) {
46534e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
4668f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
467f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
468f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
469f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
47034e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_rgba_to_rgba_premul(
471a51e7782b2e028a38712a159c412e6151eca1666msarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
472a51e7782b2e028a38712a159c412e6151eca1666msarett        int offset, const SkPMColor ctable[]) {
473a51e7782b2e028a38712a159c412e6151eca1666msarett
474a51e7782b2e028a38712a159c412e6151eca1666msarett    // This function must not be called if we are sampling.  If we are not
475a51e7782b2e028a38712a159c412e6151eca1666msarett    // sampling, deltaSrc should equal bpp.
476a51e7782b2e028a38712a159c412e6151eca1666msarett    SkASSERT(deltaSrc == bpp);
477a51e7782b2e028a38712a159c412e6151eca1666msarett
4788bf7b79cf9776b4edb3f6810e5ab8c80c49d3480mtklein    SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
47934e0ec40b10320765d4a4432f56e090556f9c75emsarett}
48034e0ec40b10320765d4a4432f56e090556f9c75emsarett
48134e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_rgba_to_bgra_premul(
48234e0ec40b10320765d4a4432f56e090556f9c75emsarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
48334e0ec40b10320765d4a4432f56e090556f9c75emsarett        int offset, const SkPMColor ctable[]) {
48434e0ec40b10320765d4a4432f56e090556f9c75emsarett
48534e0ec40b10320765d4a4432f56e090556f9c75emsarett    // This function must not be called if we are sampling.  If we are not
48634e0ec40b10320765d4a4432f56e090556f9c75emsarett    // sampling, deltaSrc should equal bpp.
48734e0ec40b10320765d4a4432f56e090556f9c75emsarett    SkASSERT(deltaSrc == bpp);
48834e0ec40b10320765d4a4432f56e090556f9c75emsarett
4898bf7b79cf9776b4edb3f6810e5ab8c80c49d3480mtklein    SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
490a51e7782b2e028a38712a159c412e6151eca1666msarett}
491a51e7782b2e028a38712a159c412e6151eca1666msarett
49234e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_rgba_to_bgra_unpremul(
4938f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
4945406d6f39ad042e7a0a0d4ea16beca4fe2b66492msarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
495741143878b23d22cd9cb7b9cba8055179115ce17msarett
4968f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    src += offset;
497f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
4988f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer    for (int x = 0; x < dstWidth; x++) {
499f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo        unsigned alpha = src[3];
50034e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
5018f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer        src += deltaSrc;
502f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
503f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
504f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
50534e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_rgba_to_bgra_unpremul(
506bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
507bda86098ab2784968d0a1222dd1f4c18d18fe050msarett        const SkPMColor ctable[]) {
508bda86098ab2784968d0a1222dd1f4c18d18fe050msarett
509bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    // This function must not be called if we are sampling.  If we are not
510bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    // sampling, deltaSrc should equal bpp.
511bda86098ab2784968d0a1222dd1f4c18d18fe050msarett    SkASSERT(deltaSrc == bpp);
512bda86098ab2784968d0a1222dd1f4c18d18fe050msarett
5138bf7b79cf9776b4edb3f6810e5ab8c80c49d3480mtklein    SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
514bda86098ab2784968d0a1222dd1f4c18d18fe050msarett}
515bda86098ab2784968d0a1222dd1f4c18d18fe050msarett
5167a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett// 16-bits per component kRGB and kRGBA
5177a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5187a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgb16_to_rgba(
5197a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5207a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
5217a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto strip16to8 = [](const uint8_t* ptr) {
5227a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
5237a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
5247a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5257a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
5267a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint32_t* dst32 = (uint32_t*) dst;
5277a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
5287a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst32[x] = strip16to8(src);
5297a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
5307a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
5317a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
5327a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5337a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgb16_to_bgra(
5347a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5357a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
5367a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto strip16to8 = [](const uint8_t* ptr) {
5377a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
5387a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
5397a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5407a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
5417a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint32_t* dst32 = (uint32_t*) dst;
5427a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
5437a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst32[x] = strip16to8(src);
5447a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
5457a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
5467a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
5477a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5487a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgb16_to_565(
5497a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5507a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
5517a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto strip16to565 = [](const uint8_t* ptr) {
5527a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]);
5537a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
5547a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5557a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
5567a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint16_t* dst16 = (uint16_t*) dst;
5577a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
5587a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst16[x] = strip16to565(src);
5597a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
5607a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
5617a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
5627a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5637a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgba16_to_rgba_unpremul(
5647a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5657a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
5667a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto strip16to8 = [](const uint8_t* ptr) {
5677a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
5687a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
5697a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5707a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
5717a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint32_t* dst32 = (uint32_t*) dst;
5727a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
5737a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst32[x] = strip16to8(src);
5747a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
5757a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
5767a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
5777a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5787a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgba16_to_rgba_premul(
5797a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5807a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
5817a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto stripAndPremul16to8 = [](const uint8_t* ptr) {
5827a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]);
5837a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
5847a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5857a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
5867a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint32_t* dst32 = (uint32_t*) dst;
5877a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
5887a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst32[x] = stripAndPremul16to8(src);
5897a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
5907a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
5917a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
5927a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
5937a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgba16_to_bgra_unpremul(
5947a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
5957a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
5967a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto strip16to8 = [](const uint8_t* ptr) {
5977a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
5987a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
5997a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
6007a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
6017a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint32_t* dst32 = (uint32_t*) dst;
6027a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
6037a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst32[x] = strip16to8(src);
6047a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
6057a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
6067a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
6077a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
6087a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarettstatic void swizzle_rgba16_to_bgra_premul(
6097a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
6107a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        const SkPMColor ctable[]) {
6117a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    auto stripAndPremul16to8 = [](const uint8_t* ptr) {
6127a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]);
6137a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    };
6147a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
6157a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    src += offset;
6167a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    uint32_t* dst32 = (uint32_t*) dst;
6177a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    for (int x = 0; x < width; x++) {
6187a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        dst32[x] = stripAndPremul16to8(src);
6197a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett        src += deltaSrc;
6207a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett    }
6217a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett}
6227a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
623ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// kCMYK
624ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
625ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMYK is stored as four bytes per pixel.
626ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
627ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// We will implement a crude conversion from CMYK -> RGB using formulas
628ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// from easyrgb.com.
629ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
630ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMYK -> CMY
631ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// C = C * (1 - K) + K
632ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// M = M * (1 - K) + K
633ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// Y = Y * (1 - K) + K
634ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
635ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// libjpeg actually gives us inverted CMYK, so we must subtract the
636ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// original terms from 1.
637ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMYK -> CMY
638ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// C = (1 - C) * (1 - (1 - K)) + (1 - K)
639ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// M = (1 - M) * (1 - (1 - K)) + (1 - K)
640ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
641ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
642ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// Simplifying the above expression.
643ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMYK -> CMY
644ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// C = 1 - CK
645ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// M = 1 - MK
646ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// Y = 1 - YK
647ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
648ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMY -> RGB
649ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// R = (1 - C) * 255
650ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// G = (1 - M) * 255
651ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// B = (1 - Y) * 255
652ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
653ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// Therefore the full conversion is below.  This can be verified at
654ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// www.rapidtables.com (assuming inverted CMYK).
655ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMYK -> RGB
656ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// R = C * K * 255
657ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// G = M * K * 255
658ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// B = Y * K * 255
659ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo//
660ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// As a final note, we have treated the CMYK values as if they were on
661ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
662ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// We must divide each CMYK component by 255 to obtain the true conversion
663ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// we should perform.
664ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// CMYK -> RGB
665ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// R = C * K / 255
666ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// G = M * K / 255
667ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo// B = Y * K / 255
66834e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_cmyk_to_rgba(
66934e0ec40b10320765d4a4432f56e090556f9c75emsarett        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
67034e0ec40b10320765d4a4432f56e090556f9c75emsarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
67134e0ec40b10320765d4a4432f56e090556f9c75emsarett
67234e0ec40b10320765d4a4432f56e090556f9c75emsarett    src += offset;
67334e0ec40b10320765d4a4432f56e090556f9c75emsarett    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
67434e0ec40b10320765d4a4432f56e090556f9c75emsarett    for (int x = 0; x < dstWidth; x++) {
67534e0ec40b10320765d4a4432f56e090556f9c75emsarett        const uint8_t r = SkMulDiv255Round(src[0], src[3]);
67634e0ec40b10320765d4a4432f56e090556f9c75emsarett        const uint8_t g = SkMulDiv255Round(src[1], src[3]);
67734e0ec40b10320765d4a4432f56e090556f9c75emsarett        const uint8_t b = SkMulDiv255Round(src[2], src[3]);
67834e0ec40b10320765d4a4432f56e090556f9c75emsarett
67934e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
68034e0ec40b10320765d4a4432f56e090556f9c75emsarett        src += deltaSrc;
68134e0ec40b10320765d4a4432f56e090556f9c75emsarett    }
68234e0ec40b10320765d4a4432f56e090556f9c75emsarett}
68334e0ec40b10320765d4a4432f56e090556f9c75emsarett
68434e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void swizzle_cmyk_to_bgra(
685ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
686ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
687ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo
688ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    src += offset;
689ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
690ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    for (int x = 0; x < dstWidth; x++) {
691ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        const uint8_t r = SkMulDiv255Round(src[0], src[3]);
692ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        const uint8_t g = SkMulDiv255Round(src[1], src[3]);
693ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        const uint8_t b = SkMulDiv255Round(src[2], src[3]);
694ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo
69534e0ec40b10320765d4a4432f56e090556f9c75emsarett        dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
696ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        src += deltaSrc;
697ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    }
698ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo}
699ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo
70034e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_cmyk_to_rgba(
701c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
702c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett        const SkPMColor ctable[]) {
703c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett
704c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett    // This function must not be called if we are sampling.  If we are not
705c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett    // sampling, deltaSrc should equal bpp.
706c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett    SkASSERT(deltaSrc == bpp);
707c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett
708c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett    SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
70934e0ec40b10320765d4a4432f56e090556f9c75emsarett}
71034e0ec40b10320765d4a4432f56e090556f9c75emsarett
71134e0ec40b10320765d4a4432f56e090556f9c75emsarettstatic void fast_swizzle_cmyk_to_bgra(
71234e0ec40b10320765d4a4432f56e090556f9c75emsarett        void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
71334e0ec40b10320765d4a4432f56e090556f9c75emsarett        const SkPMColor ctable[]) {
71434e0ec40b10320765d4a4432f56e090556f9c75emsarett
71534e0ec40b10320765d4a4432f56e090556f9c75emsarett    // This function must not be called if we are sampling.  If we are not
71634e0ec40b10320765d4a4432f56e090556f9c75emsarett    // sampling, deltaSrc should equal bpp.
71734e0ec40b10320765d4a4432f56e090556f9c75emsarett    SkASSERT(deltaSrc == bpp);
71834e0ec40b10320765d4a4432f56e090556f9c75emsarett
719c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett    SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
720c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett}
721c5c322d8ecfc05718f9f04360956c4f1f9dc33c1msarett
722a4970dc973459d2607ce80623452bf8470adf6f1msarettstatic void swizzle_cmyk_to_565(
723ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
724ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
725ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo
726ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    src += offset;
727ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
728ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    for (int x = 0; x < dstWidth; x++) {
729ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        const uint8_t r = SkMulDiv255Round(src[0], src[3]);
730ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        const uint8_t g = SkMulDiv255Round(src[1], src[3]);
731ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        const uint8_t b = SkMulDiv255Round(src[2], src[3]);
732ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo
733ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        dst[x] = SkPack888ToRGB16(r, g, b);
734ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo        src += deltaSrc;
735ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo    }
736ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo}
737ef27d89b076ce7ab81703c9c08ce1f5c44106ee6scroggo
7388604ca2d84cfa9527705c69d74a8449b532e0ee4mtkleintemplate <SkSwizzler::RowProc proc>
73993e613d6bdea05d96e232ed261d7bf886c91bb8emsarettvoid SkSwizzler::SkipLeadingGrayAlphaZerosThen(
74093e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        void* dst, const uint8_t* src, int width,
74193e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
74293e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    SkASSERT(!ctable);
74393e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
74493e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    const uint16_t* src16 = (const uint16_t*) (src + offset);
74593e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    uint32_t* dst32 = (uint32_t*) dst;
74693e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
74793e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    // This may miss opportunities to skip when the output is premultiplied,
74893e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
74993e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    while (width > 0 && *src16 == 0x0000) {
75093e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        width--;
75193e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        dst32++;
75293e613d6bdea05d96e232ed261d7bf886c91bb8emsarett        src16 += deltaSrc / 2;
75393e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    }
75493e613d6bdea05d96e232ed261d7bf886c91bb8emsarett    proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
75593e613d6bdea05d96e232ed261d7bf886c91bb8emsarett}
75693e613d6bdea05d96e232ed261d7bf886c91bb8emsarett
75793e613d6bdea05d96e232ed261d7bf886c91bb8emsaretttemplate <SkSwizzler::RowProc proc>
7588604ca2d84cfa9527705c69d74a8449b532e0ee4mtkleinvoid SkSwizzler::SkipLeading8888ZerosThen(
7598604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
7608604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein        int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
7618604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    SkASSERT(!ctable);
7628604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein
7638604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    auto src32 = (const uint32_t*)(src+offset);
7648604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    auto dst32 = (uint32_t*)dstRow;
7658604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein
7668604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    // This may miss opportunities to skip when the output is premultiplied,
7678604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
7688604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    while (dstWidth > 0 && *src32 == 0x00000000) {
7698604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein        dstWidth--;
7708604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein        dst32++;
7718604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein        src32 += deltaSrc/4;
772f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
7738604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein    proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
774f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
775f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
776a45a668fa57eb968e24f379eceb2e56324e2cca2msarettSkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
777741143878b23d22cd9cb7b9cba8055179115ce17msarett                                       const SkPMColor* ctable,
778fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett                                       const SkImageInfo& dstInfo,
7795af4e0bc8fd17944f3c0527462aeba367f6d590amsarett                                       const SkCodec::Options& options,
78068758aed88b16d67658f634e8dcd855404fedb8amsarett                                       const SkIRect* frame,
7819bf39c245e678e9b008ad2d97b98aecc05c6dc2bMatt Sarett                                       bool skipFormatConversion) {
782a45a668fa57eb968e24f379eceb2e56324e2cca2msarett    if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
78396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
784f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    }
785a45a668fa57eb968e24f379eceb2e56324e2cca2msarett
786a51e7782b2e028a38712a159c412e6151eca1666msarett    RowProc fastProc = nullptr;
78796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    RowProc proc = nullptr;
788379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett    int srcBPP;
7897fcfb621998648ba018e3b89e2cab3135bd46a1fMike Reed    const int dstBPP = dstInfo.bytesPerPixel();
7909bf39c245e678e9b008ad2d97b98aecc05c6dc2bMatt Sarett    if (skipFormatConversion) {
79134c69d63477c8992d3242c02899008810e04af6eMatt Sarett        switch (encodedInfo.color()) {
79234c69d63477c8992d3242c02899008810e04af6eMatt Sarett            case SkEncodedInfo::kGray_Color:
79334c69d63477c8992d3242c02899008810e04af6eMatt Sarett            case SkEncodedInfo::kYUV_Color:
79434c69d63477c8992d3242c02899008810e04af6eMatt Sarett                // We have a jpeg that has already been converted to the dstColorType.
79534c69d63477c8992d3242c02899008810e04af6eMatt Sarett                srcBPP = dstBPP;
79634c69d63477c8992d3242c02899008810e04af6eMatt Sarett                switch (dstInfo.colorType()) {
79734c69d63477c8992d3242c02899008810e04af6eMatt Sarett                    case kGray_8_SkColorType:
79834c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        proc = &sample1;
79934c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        fastProc = &copy;
80034c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        break;
80134c69d63477c8992d3242c02899008810e04af6eMatt Sarett                    case kRGB_565_SkColorType:
80234c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        proc = &sample2;
80334c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        fastProc = &copy;
80434c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        break;
80534c69d63477c8992d3242c02899008810e04af6eMatt Sarett                    case kRGBA_8888_SkColorType:
80634c69d63477c8992d3242c02899008810e04af6eMatt Sarett                    case kBGRA_8888_SkColorType:
80734c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        proc = &sample4;
80834c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        fastProc = &copy;
80934c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        break;
81034c69d63477c8992d3242c02899008810e04af6eMatt Sarett                    default:
81134c69d63477c8992d3242c02899008810e04af6eMatt Sarett                        return nullptr;
81234c69d63477c8992d3242c02899008810e04af6eMatt Sarett                }
81368758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
81434c69d63477c8992d3242c02899008810e04af6eMatt Sarett            case SkEncodedInfo::kInvertedCMYK_Color:
81534c69d63477c8992d3242c02899008810e04af6eMatt Sarett            case SkEncodedInfo::kYCCK_Color:
81634c69d63477c8992d3242c02899008810e04af6eMatt Sarett                // We have a jpeg that remains in its original format.
81734c69d63477c8992d3242c02899008810e04af6eMatt Sarett                srcBPP = 4;
81834c69d63477c8992d3242c02899008810e04af6eMatt Sarett                proc = &sample4;
81968758aed88b16d67658f634e8dcd855404fedb8amsarett                fastProc = &copy;
82068758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
82134c69d63477c8992d3242c02899008810e04af6eMatt Sarett            case SkEncodedInfo::kRGBA_Color:
82234c69d63477c8992d3242c02899008810e04af6eMatt Sarett                // We have a png that should remain in its original format.
823379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                SkASSERT(16 == encodedInfo.bitsPerComponent() ||
824379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                          8 == encodedInfo.bitsPerComponent());
825379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                if (8 == encodedInfo.bitsPerComponent()) {
82634c69d63477c8992d3242c02899008810e04af6eMatt Sarett                    srcBPP = 4;
827379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                    proc = &sample4;
828379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                } else {
829379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                    srcBPP = 8;
830379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                    proc = &sample8;
831379938e47bc9edb6edfd21aabefa01aed71dd135Matt Sarett                }
83268758aed88b16d67658f634e8dcd855404fedb8amsarett                fastProc = &copy;
83368758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
83434c69d63477c8992d3242c02899008810e04af6eMatt Sarett            case SkEncodedInfo::kRGB_Color:
83534c69d63477c8992d3242c02899008810e04af6eMatt Sarett                // We have a png that remains in its original format.
83634c69d63477c8992d3242c02899008810e04af6eMatt Sarett                SkASSERT(16 == encodedInfo.bitsPerComponent());
83734c69d63477c8992d3242c02899008810e04af6eMatt Sarett                srcBPP = 6;
83834c69d63477c8992d3242c02899008810e04af6eMatt Sarett                proc = &sample6;
83934c69d63477c8992d3242c02899008810e04af6eMatt Sarett                fastProc = &copy;
84034c69d63477c8992d3242c02899008810e04af6eMatt Sarett                break;
84168758aed88b16d67658f634e8dcd855404fedb8amsarett            default:
84268758aed88b16d67658f634e8dcd855404fedb8amsarett                return nullptr;
84368758aed88b16d67658f634e8dcd855404fedb8amsarett        }
84468758aed88b16d67658f634e8dcd855404fedb8amsarett    } else {
84568758aed88b16d67658f634e8dcd855404fedb8amsarett        SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
84668758aed88b16d67658f634e8dcd855404fedb8amsarett        const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
84768758aed88b16d67658f634e8dcd855404fedb8amsarett                (kPremul_SkAlphaType == dstInfo.alphaType());
84868758aed88b16d67658f634e8dcd855404fedb8amsarett
84968758aed88b16d67658f634e8dcd855404fedb8amsarett        switch (encodedInfo.color()) {
85068758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kGray_Color:
85168758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (encodedInfo.bitsPerComponent()) {
85268758aed88b16d67658f634e8dcd855404fedb8amsarett                    case 1:
85368758aed88b16d67658f634e8dcd855404fedb8amsarett                        switch (dstInfo.colorType()) {
85468758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGBA_8888_SkColorType:
85568758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kBGRA_8888_SkColorType:
85668758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_bit_to_n32;
85768758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
85868758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGB_565_SkColorType:
85968758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_bit_to_565;
86068758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
86168758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kGray_8_SkColorType:
86268758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_bit_to_grayscale;
86368758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
864a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett                            case kRGBA_F16_SkColorType:
865a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett                                proc = &swizzle_bit_to_f16;
866a225e9be53001a8397344ce1e272a7df2fced499Matt Sarett                                break;
86768758aed88b16d67658f634e8dcd855404fedb8amsarett                            default:
86868758aed88b16d67658f634e8dcd855404fedb8amsarett                                return nullptr;
869a45a668fa57eb968e24f379eceb2e56324e2cca2msarett                        }
87068758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
87168758aed88b16d67658f634e8dcd855404fedb8amsarett                    case 8:
87268758aed88b16d67658f634e8dcd855404fedb8amsarett                        switch (dstInfo.colorType()) {
87368758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGBA_8888_SkColorType:
87468758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kBGRA_8888_SkColorType:
87568758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_gray_to_n32;
87668758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_gray_to_n32;
87768758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
87868758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kGray_8_SkColorType:
87968758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &sample1;
88068758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &copy;
88168758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
88268758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGB_565_SkColorType:
88368758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_gray_to_565;
88468758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
88568758aed88b16d67658f634e8dcd855404fedb8amsarett                            default:
88668758aed88b16d67658f634e8dcd855404fedb8amsarett                                return nullptr;
887a45a668fa57eb968e24f379eceb2e56324e2cca2msarett                        }
88868758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
88968758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
89068758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
89168758aed88b16d67658f634e8dcd855404fedb8amsarett                }
89268758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
89368758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kGrayAlpha_Color:
89468758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
89568758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
89668758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
89768758aed88b16d67658f634e8dcd855404fedb8amsarett                        if (premultiply) {
898a45a668fa57eb968e24f379eceb2e56324e2cca2msarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
89968758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeadingGrayAlphaZerosThen
90068758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <swizzle_grayalpha_to_n32_premul>;
90168758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeadingGrayAlphaZerosThen
90268758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_grayalpha_to_n32_premul>;
903a45a668fa57eb968e24f379eceb2e56324e2cca2msarett                            } else {
90468758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_grayalpha_to_n32_premul;
90568758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_grayalpha_to_n32_premul;
906a45a668fa57eb968e24f379eceb2e56324e2cca2msarett                            }
90734e0ec40b10320765d4a4432f56e090556f9c75emsarett                        } else {
90868758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
90968758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeadingGrayAlphaZerosThen
91068758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <swizzle_grayalpha_to_n32_unpremul>;
91168758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeadingGrayAlphaZerosThen
91268758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_grayalpha_to_n32_unpremul>;
91368758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
91468758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_grayalpha_to_n32_unpremul;
91568758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
91668758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
91734e0ec40b10320765d4a4432f56e090556f9c75emsarett                        }
91868758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
919d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed                    case kAlpha_8_SkColorType:
920d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed                        proc = &swizzle_grayalpha_to_a8;
921d6cb11ee9df514a3a65b313725d3ac3bfd003e7fMike Reed                        break;
92268758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
92368758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
92468758aed88b16d67658f634e8dcd855404fedb8amsarett                }
92568758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
92668758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kPalette_Color:
92768758aed88b16d67658f634e8dcd855404fedb8amsarett                // We assume that the color table is premultiplied and swizzled
92868758aed88b16d67658f634e8dcd855404fedb8amsarett                // as desired.
92968758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (encodedInfo.bitsPerComponent()) {
93068758aed88b16d67658f634e8dcd855404fedb8amsarett                    case 1:
93168758aed88b16d67658f634e8dcd855404fedb8amsarett                    case 2:
93268758aed88b16d67658f634e8dcd855404fedb8amsarett                    case 4:
93368758aed88b16d67658f634e8dcd855404fedb8amsarett                        switch (dstInfo.colorType()) {
93468758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGBA_8888_SkColorType:
93568758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kBGRA_8888_SkColorType:
93668758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_small_index_to_n32;
93768758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
93868758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGB_565_SkColorType:
93968758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_small_index_to_565;
94068758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
94168758aed88b16d67658f634e8dcd855404fedb8amsarett                            default:
94268758aed88b16d67658f634e8dcd855404fedb8amsarett                                return nullptr;
94334e0ec40b10320765d4a4432f56e090556f9c75emsarett                        }
94468758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
94568758aed88b16d67658f634e8dcd855404fedb8amsarett                    case 8:
94668758aed88b16d67658f634e8dcd855404fedb8amsarett                        switch (dstInfo.colorType()) {
94768758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGBA_8888_SkColorType:
94868758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kBGRA_8888_SkColorType:
94968758aed88b16d67658f634e8dcd855404fedb8amsarett                                if (SkCodec::kYes_ZeroInitialized == zeroInit) {
95068758aed88b16d67658f634e8dcd855404fedb8amsarett                                    proc = &swizzle_index_to_n32_skipZ;
95168758aed88b16d67658f634e8dcd855404fedb8amsarett                                } else {
95268758aed88b16d67658f634e8dcd855404fedb8amsarett                                    proc = &swizzle_index_to_n32;
95368758aed88b16d67658f634e8dcd855404fedb8amsarett                                }
95468758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
95568758aed88b16d67658f634e8dcd855404fedb8amsarett                            case kRGB_565_SkColorType:
95668758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_index_to_565;
95768758aed88b16d67658f634e8dcd855404fedb8amsarett                                break;
95868758aed88b16d67658f634e8dcd855404fedb8amsarett                            default:
95968758aed88b16d67658f634e8dcd855404fedb8amsarett                                return nullptr;
96093e613d6bdea05d96e232ed261d7bf886c91bb8emsarett                        }
96168758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
96268758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
96368758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
96468758aed88b16d67658f634e8dcd855404fedb8amsarett                }
96568758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
96668758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kRGB_Color:
96768758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
96868758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
9697a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        if (16 == encodedInfo.bitsPerComponent()) {
9707a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            proc = &swizzle_rgb16_to_rgba;
9717a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            break;
9727a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        }
9737a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
9747a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        SkASSERT(8 == encodedInfo.bitsPerComponent());
97568758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_rgba;
97668758aed88b16d67658f634e8dcd855404fedb8amsarett                        fastProc = &fast_swizzle_rgb_to_rgba;
97768758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
97868758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
9797a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        if (16 == encodedInfo.bitsPerComponent()) {
9807a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            proc = &swizzle_rgb16_to_bgra;
9817a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            break;
9827a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        }
9837a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
9847a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        SkASSERT(8 == encodedInfo.bitsPerComponent());
98568758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_bgra;
98668758aed88b16d67658f634e8dcd855404fedb8amsarett                        fastProc = &fast_swizzle_rgb_to_bgra;
98768758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
98868758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGB_565_SkColorType:
9897a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        if (16 == encodedInfo.bitsPerComponent()) {
9907a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            proc = &swizzle_rgb16_to_565;
9917a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            break;
9927a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        }
9937a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
99468758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_565;
99568758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
99668758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
99768758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
99868758aed88b16d67658f634e8dcd855404fedb8amsarett                }
99968758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
100068758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kRGBA_Color:
100168758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
100268758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
10037a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        if (16 == encodedInfo.bitsPerComponent()) {
10047a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
10057a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                                                 &swizzle_rgba16_to_rgba_unpremul;
10067a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            break;
10077a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        }
10087a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
10097a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        SkASSERT(8 == encodedInfo.bitsPerComponent());
101068758aed88b16d67658f634e8dcd855404fedb8amsarett                        if (premultiply) {
101168758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
101268758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
101368758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen
101468758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_rgba_to_rgba_premul>;
101568758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
101668758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_rgba_to_rgba_premul;
101768758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_rgba_to_rgba_premul;
101868758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
101934e0ec40b10320765d4a4432f56e090556f9c75emsarett                        } else {
102068758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
102168758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<sample4>;
102268758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen<copy>;
102368758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
102468758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &sample4;
102568758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &copy;
102668758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
102734e0ec40b10320765d4a4432f56e090556f9c75emsarett                        }
102868758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
102968758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
10307a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        if (16 == encodedInfo.bitsPerComponent()) {
10317a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
10327a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                                                 &swizzle_rgba16_to_bgra_unpremul;
10337a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                            break;
10347a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        }
10357a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett
10367a1cc6766d07f343923587deaf14e1a3965c2b8fMatt Sarett                        SkASSERT(8 == encodedInfo.bitsPerComponent());
103768758aed88b16d67658f634e8dcd855404fedb8amsarett                        if (premultiply) {
103868758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
103968758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
104068758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen
104168758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_rgba_to_bgra_premul>;
104268758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
104368758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_rgba_to_bgra_premul;
104468758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_rgba_to_bgra_premul;
104568758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
104634e0ec40b10320765d4a4432f56e090556f9c75emsarett                        } else {
104768758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
104868758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
104968758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen
105068758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_rgba_to_bgra_unpremul>;
105168758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
105268758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_rgba_to_bgra_unpremul;
105368758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
105468758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
105534e0ec40b10320765d4a4432f56e090556f9c75emsarett                        }
105668758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
105768758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
105868758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
105968758aed88b16d67658f634e8dcd855404fedb8amsarett                }
106068758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
106168758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kBGR_Color:
106268758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
106368758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
106468758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_rgba;
106568758aed88b16d67658f634e8dcd855404fedb8amsarett                        fastProc = &fast_swizzle_rgb_to_rgba;
106668758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
106768758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
106868758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_bgra;
106968758aed88b16d67658f634e8dcd855404fedb8amsarett                        fastProc = &fast_swizzle_rgb_to_bgra;
107068758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
107168758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGB_565_SkColorType:
107268758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_bgr_to_565;
107368758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
107468758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
107568758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
107668758aed88b16d67658f634e8dcd855404fedb8amsarett                }
107768758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
107868758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kBGRX_Color:
107968758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
108068758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
108168758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_rgba;
108268758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
108368758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
108468758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_rgb_to_bgra;
108568758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
108668758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGB_565_SkColorType:
108768758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_bgr_to_565;
108868758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
108968758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
109068758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
109168758aed88b16d67658f634e8dcd855404fedb8amsarett                }
109268758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
109368758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kBGRA_Color:
109468758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
109568758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
109668758aed88b16d67658f634e8dcd855404fedb8amsarett                        if (premultiply) {
109768758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
109868758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
109968758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen
110068758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_rgba_to_rgba_premul>;
110168758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
110268758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_rgba_to_rgba_premul;
110368758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_rgba_to_rgba_premul;
110468758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
11058604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein                        } else {
110668758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
110768758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<sample4>;
110868758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen<copy>;
110968758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
111068758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &sample4;
111168758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &copy;
111268758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
11138604ca2d84cfa9527705c69d74a8449b532e0ee4mtklein                        }
111468758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
111568758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
111668758aed88b16d67658f634e8dcd855404fedb8amsarett                        if (premultiply) {
111768758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
111868758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
111968758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen
112068758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_rgba_to_bgra_premul>;
112168758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
112268758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_rgba_to_bgra_premul;
112368758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_rgba_to_bgra_premul;
112468758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
1125f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        } else {
112668758aed88b16d67658f634e8dcd855404fedb8amsarett                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
112768758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
112868758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &SkipLeading8888ZerosThen
112968758aed88b16d67658f634e8dcd855404fedb8amsarett                                        <fast_swizzle_rgba_to_bgra_unpremul>;
113068758aed88b16d67658f634e8dcd855404fedb8amsarett                            } else {
113168758aed88b16d67658f634e8dcd855404fedb8amsarett                                proc = &swizzle_rgba_to_bgra_unpremul;
113268758aed88b16d67658f634e8dcd855404fedb8amsarett                                fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
113368758aed88b16d67658f634e8dcd855404fedb8amsarett                            }
1134f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo                        }
113568758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
113668758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
113768758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
113868758aed88b16d67658f634e8dcd855404fedb8amsarett                }
113968758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
114068758aed88b16d67658f634e8dcd855404fedb8amsarett            case SkEncodedInfo::kInvertedCMYK_Color:
114168758aed88b16d67658f634e8dcd855404fedb8amsarett                switch (dstInfo.colorType()) {
114268758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGBA_8888_SkColorType:
114368758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_cmyk_to_rgba;
114468758aed88b16d67658f634e8dcd855404fedb8amsarett                        fastProc = &fast_swizzle_cmyk_to_rgba;
114568758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
114668758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kBGRA_8888_SkColorType:
114768758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_cmyk_to_bgra;
114868758aed88b16d67658f634e8dcd855404fedb8amsarett                        fastProc = &fast_swizzle_cmyk_to_bgra;
114968758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
115068758aed88b16d67658f634e8dcd855404fedb8amsarett                    case kRGB_565_SkColorType:
115168758aed88b16d67658f634e8dcd855404fedb8amsarett                        proc = &swizzle_cmyk_to_565;
115268758aed88b16d67658f634e8dcd855404fedb8amsarett                        break;
115368758aed88b16d67658f634e8dcd855404fedb8amsarett                    default:
115468758aed88b16d67658f634e8dcd855404fedb8amsarett                        return nullptr;
115568758aed88b16d67658f634e8dcd855404fedb8amsarett                }
115668758aed88b16d67658f634e8dcd855404fedb8amsarett                break;
115768758aed88b16d67658f634e8dcd855404fedb8amsarett            default:
115868758aed88b16d67658f634e8dcd855404fedb8amsarett                return nullptr;
115968758aed88b16d67658f634e8dcd855404fedb8amsarett        }
116068758aed88b16d67658f634e8dcd855404fedb8amsarett
1161a45a668fa57eb968e24f379eceb2e56324e2cca2msarett        // Store bpp in bytes if it is an even multiple, otherwise use bits
1162a45a668fa57eb968e24f379eceb2e56324e2cca2msarett        uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
1163a45a668fa57eb968e24f379eceb2e56324e2cca2msarett        srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
1164a45a668fa57eb968e24f379eceb2e56324e2cca2msarett    }
11653d00db39c6637607a2a1f184be2f31e4fe17d9admtklein
1166fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett    int srcOffset = 0;
1167fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett    int srcWidth = dstInfo.width();
11685af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    int dstOffset = 0;
11695af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    int dstWidth = srcWidth;
1170fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett    if (options.fSubset) {
11715af4e0bc8fd17944f3c0527462aeba367f6d590amsarett        // We do not currently support subset decodes for image types that may have
11725af4e0bc8fd17944f3c0527462aeba367f6d590amsarett        // frames (gif).
11735af4e0bc8fd17944f3c0527462aeba367f6d590amsarett        SkASSERT(!frame);
1174fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett        srcOffset = options.fSubset->left();
1175fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett        srcWidth = options.fSubset->width();
11765af4e0bc8fd17944f3c0527462aeba367f6d590amsarett        dstWidth = srcWidth;
11775af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    } else if (frame) {
11785af4e0bc8fd17944f3c0527462aeba367f6d590amsarett        dstOffset = frame->left();
11795af4e0bc8fd17944f3c0527462aeba367f6d590amsarett        srcWidth = frame->width();
1180fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett    }
11818f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer
1182a51e7782b2e028a38712a159c412e6151eca1666msarett    return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
1183a51e7782b2e028a38712a159c412e6151eca1666msarett            srcBPP, dstBPP);
1184f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
1185f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo
1186a51e7782b2e028a38712a159c412e6151eca1666msarettSkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
1187a51e7782b2e028a38712a159c412e6151eca1666msarett        int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
1188a51e7782b2e028a38712a159c412e6151eca1666msarett    : fFastProc(fastProc)
118919032f72165f5c6eab5c2149dae98905f41e3943msarett    , fSlowProc(proc)
119019032f72165f5c6eab5c2149dae98905f41e3943msarett    , fActualProc(fFastProc ? fFastProc : fSlowProc)
1191f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo    , fColorTable(ctable)
1192fdb47571a3b5e72469b67de44e32ac14d9352ab4msarett    , fSrcOffset(srcOffset)
11935af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fDstOffset(dstOffset)
11945af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fSrcOffsetUnits(srcOffset * srcBPP)
11955af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fDstOffsetBytes(dstOffset * dstBPP)
11965af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fSrcWidth(srcWidth)
11975af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fDstWidth(dstWidth)
11985af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fSwizzleWidth(srcWidth)
11995af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fAllocatedWidth(dstWidth)
1200e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo    , fSampleX(1)
12015af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fSrcBPP(srcBPP)
12025af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    , fDstBPP(dstBPP)
1203e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo{}
1204e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo
1205e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggoint SkSwizzler::onSetSampleX(int sampleX) {
12069972c424ea5eaa2d78e06ae068abc86fd408e0e3msarett    SkASSERT(sampleX > 0);
12079972c424ea5eaa2d78e06ae068abc86fd408e0e3msarett
1208e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo    fSampleX = sampleX;
12095af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
12105af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
12115af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
12125af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
1213e7fc14b55bb8c41ba054abf0bfa09cdd6ec84671scroggo
12149972c424ea5eaa2d78e06ae068abc86fd408e0e3msarett    // The optimized swizzler functions do not support sampling.  Sampled swizzles
12159972c424ea5eaa2d78e06ae068abc86fd408e0e3msarett    // are already fast because they skip pixels.  We haven't seen a situation
12169972c424ea5eaa2d78e06ae068abc86fd408e0e3msarett    // where speeding up sampling has a significant impact on total decode time.
121719032f72165f5c6eab5c2149dae98905f41e3943msarett    if (1 == fSampleX && fFastProc) {
121819032f72165f5c6eab5c2149dae98905f41e3943msarett        fActualProc = fFastProc;
121919032f72165f5c6eab5c2149dae98905f41e3943msarett    } else {
122019032f72165f5c6eab5c2149dae98905f41e3943msarett        fActualProc = fSlowProc;
122119032f72165f5c6eab5c2149dae98905f41e3943msarett    }
1222a51e7782b2e028a38712a159c412e6151eca1666msarett
12235af4e0bc8fd17944f3c0527462aeba367f6d590amsarett    return fAllocatedWidth;
12248f4ba76742c329bc4d5e1b8ca376d27922bd00b1emmaleer}
1225741143878b23d22cd9cb7b9cba8055179115ce17msarett
1226a4970dc973459d2607ce80623452bf8470adf6f1msarettvoid SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
122796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    SkASSERT(nullptr != dst && nullptr != src);
122819032f72165f5c6eab5c2149dae98905f41e3943msarett    fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
12295af4e0bc8fd17944f3c0527462aeba367f6d590amsarett            fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
1230f24f2247c25b842327e12c70e44efe4cc1b28dfascroggo}
1231