Home | History | Annotate | Download | only in codec
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkCodecPriv.h"
      9 #include "SkColorPriv.h"
     10 #include "SkHalf.h"
     11 #include "SkOpts.h"
     12 #include "SkSwizzler.h"
     13 #include "SkTemplates.h"
     14 
     15 static void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     16         const SkPMColor ctable[]) {
     17     // This function must not be called if we are sampling.  If we are not
     18     // sampling, deltaSrc should equal bpp.
     19     SkASSERT(deltaSrc == bpp);
     20 
     21     memcpy(dst, src + offset, width * bpp);
     22 }
     23 
     24 static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     25         const SkPMColor ctable[]) {
     26     src += offset;
     27     uint8_t* dst8 = (uint8_t*) dst;
     28     for (int x = 0; x < width; x++) {
     29         dst8[x] = *src;
     30         src += deltaSrc;
     31     }
     32 }
     33 
     34 static void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     35         const SkPMColor ctable[]) {
     36     src += offset;
     37     uint16_t* dst16 = (uint16_t*) dst;
     38     for (int x = 0; x < width; x++) {
     39         dst16[x] = *((const uint16_t*) src);
     40         src += deltaSrc;
     41     }
     42 }
     43 
     44 static void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     45         const SkPMColor ctable[]) {
     46     src += offset;
     47     uint32_t* dst32 = (uint32_t*) dst;
     48     for (int x = 0; x < width; x++) {
     49         dst32[x] = *((const uint32_t*) src);
     50         src += deltaSrc;
     51     }
     52 }
     53 
     54 static void sample6(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     55         const SkPMColor ctable[]) {
     56     src += offset;
     57     uint8_t* dst8 = (uint8_t*) dst;
     58     for (int x = 0; x < width; x++) {
     59         memcpy(dst8, src, 6);
     60         dst8 += 6;
     61         src += deltaSrc;
     62     }
     63 }
     64 
     65 static void sample8(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     66         const SkPMColor ctable[]) {
     67     src += offset;
     68     uint64_t* dst64 = (uint64_t*) dst;
     69     for (int x = 0; x < width; x++) {
     70         dst64[x] = *((const uint64_t*) src);
     71         src += deltaSrc;
     72     }
     73 }
     74 
     75 // kBit
     76 // These routines exclusively choose between white and black
     77 
     78 #define GRAYSCALE_BLACK 0
     79 #define GRAYSCALE_WHITE 0xFF
     80 
     81 
     82 // same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
     83 static void swizzle_bit_to_grayscale(
     84         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
     85         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
     86 
     87     uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
     88 
     89     // increment src by byte offset and bitIndex by bit offset
     90     src += offset / 8;
     91     int bitIndex = offset % 8;
     92     uint8_t currByte = *src;
     93 
     94     dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
     95 
     96     for (int x = 1; x < dstWidth; x++) {
     97         int bitOffset = bitIndex + deltaSrc;
     98         bitIndex = bitOffset % 8;
     99         currByte = *(src += bitOffset / 8);
    100         dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
    101     }
    102 }
    103 
    104 #undef GRAYSCALE_BLACK
    105 #undef GRAYSCALE_WHITE
    106 
    107 // same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
    108 static void swizzle_bit_to_n32(
    109         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    110         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
    111     SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
    112 
    113     // increment src by byte offset and bitIndex by bit offset
    114     src += offset / 8;
    115     int bitIndex = offset % 8;
    116     uint8_t currByte = *src;
    117 
    118     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
    119 
    120     for (int x = 1; x < dstWidth; x++) {
    121         int bitOffset = bitIndex + deltaSrc;
    122         bitIndex = bitOffset % 8;
    123         currByte = *(src += bitOffset / 8);
    124         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
    125     }
    126 }
    127 
    128 #define RGB565_BLACK 0
    129 #define RGB565_WHITE 0xFFFF
    130 
    131 static void swizzle_bit_to_565(
    132         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    133         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
    134     uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
    135 
    136     // increment src by byte offset and bitIndex by bit offset
    137     src += offset / 8;
    138     int bitIndex = offset % 8;
    139     uint8_t currByte = *src;
    140 
    141     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
    142 
    143     for (int x = 1; x < dstWidth; x++) {
    144         int bitOffset = bitIndex + deltaSrc;
    145         bitIndex = bitOffset % 8;
    146         currByte = *(src += bitOffset / 8);
    147         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
    148     }
    149 }
    150 
    151 #undef RGB565_BLACK
    152 #undef RGB565_WHITE
    153 
    154 static void swizzle_bit_to_f16(
    155         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    156         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
    157     static const uint64_t kWhite = (((uint64_t) SK_Half1) <<  0) |
    158                                    (((uint64_t) SK_Half1) << 16) |
    159                                    (((uint64_t) SK_Half1) << 32) |
    160                                    (((uint64_t) SK_Half1) << 48);
    161     static const uint64_t kBlack = (((uint64_t)        0) <<  0) |
    162                                    (((uint64_t)        0) << 16) |
    163                                    (((uint64_t)        0) << 32) |
    164                                    (((uint64_t) SK_Half1) << 48);
    165 
    166     uint64_t* SK_RESTRICT dst = (uint64_t*) dstRow;
    167 
    168     // increment src by byte offset and bitIndex by bit offset
    169     src += offset / 8;
    170     int bitIndex = offset % 8;
    171     uint8_t currByte = *src;
    172 
    173     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
    174 
    175     for (int x = 1; x < dstWidth; x++) {
    176         int bitOffset = bitIndex + deltaSrc;
    177         bitIndex = bitOffset % 8;
    178         currByte = *(src += bitOffset / 8);
    179         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack;
    180     }
    181 }
    182 
    183 // kIndex1, kIndex2, kIndex4
    184 
    185 static void swizzle_small_index_to_565(
    186         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    187         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    188 
    189     uint16_t* dst = (uint16_t*) dstRow;
    190     src += offset / 8;
    191     int bitIndex = offset % 8;
    192     uint8_t currByte = *src;
    193     const uint8_t mask = (1 << bpp) - 1;
    194     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
    195     dst[0] = SkPixel32ToPixel16(ctable[index]);
    196 
    197     for (int x = 1; x < dstWidth; x++) {
    198         int bitOffset = bitIndex + deltaSrc;
    199         bitIndex = bitOffset % 8;
    200         currByte = *(src += bitOffset / 8);
    201         index = (currByte >> (8 - bpp - bitIndex)) & mask;
    202         dst[x] = SkPixel32ToPixel16(ctable[index]);
    203     }
    204 }
    205 
    206 static void swizzle_small_index_to_n32(
    207         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    208         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    209 
    210     SkPMColor* dst = (SkPMColor*) dstRow;
    211     src += offset / 8;
    212     int bitIndex = offset % 8;
    213     uint8_t currByte = *src;
    214     const uint8_t mask = (1 << bpp) - 1;
    215     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
    216     dst[0] = ctable[index];
    217 
    218     for (int x = 1; x < dstWidth; x++) {
    219         int bitOffset = bitIndex + deltaSrc;
    220         bitIndex = bitOffset % 8;
    221         currByte = *(src += bitOffset / 8);
    222         index = (currByte >> (8 - bpp - bitIndex)) & mask;
    223         dst[x] = ctable[index];
    224     }
    225 }
    226 
    227 // kIndex
    228 
    229 static void swizzle_index_to_n32(
    230         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    231         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    232 
    233     src += offset;
    234     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    235     for (int x = 0; x < dstWidth; x++) {
    236         SkPMColor c = ctable[*src];
    237         dst[x] = c;
    238         src += deltaSrc;
    239     }
    240 }
    241 
    242 static void swizzle_index_to_n32_skipZ(
    243         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    244         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    245 
    246     src += offset;
    247     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    248     for (int x = 0; x < dstWidth; x++) {
    249         SkPMColor c = ctable[*src];
    250         if (c != 0) {
    251             dst[x] = c;
    252         }
    253         src += deltaSrc;
    254     }
    255 }
    256 
    257 static void swizzle_index_to_565(
    258       void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    259       int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    260     src += offset;
    261     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    262     for (int x = 0; x < dstWidth; x++) {
    263         dst[x] = SkPixel32ToPixel16(ctable[*src]);
    264         src += deltaSrc;
    265     }
    266 }
    267 
    268 // kGray
    269 
    270 static void swizzle_gray_to_n32(
    271         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    272         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    273 
    274     src += offset;
    275     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    276     for (int x = 0; x < dstWidth; x++) {
    277         dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
    278         src += deltaSrc;
    279     }
    280 }
    281 
    282 static void fast_swizzle_gray_to_n32(
    283         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    284         const SkPMColor ctable[]) {
    285 
    286     // This function must not be called if we are sampling.  If we are not
    287     // sampling, deltaSrc should equal bpp.
    288     SkASSERT(deltaSrc == bpp);
    289 
    290     // Note that there is no need to distinguish between RGB and BGR.
    291     // Each color channel will get the same value.
    292     SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
    293 }
    294 
    295 static void swizzle_gray_to_565(
    296         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    297         int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    298 
    299     src += offset;
    300     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    301     for (int x = 0; x < dstWidth; x++) {
    302         dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
    303         src += deltaSrc;
    304     }
    305 }
    306 
    307 // kGrayAlpha
    308 
    309 static void swizzle_grayalpha_to_n32_unpremul(
    310         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    311         const SkPMColor ctable[]) {
    312 
    313     src += offset;
    314     SkPMColor* dst32 = (SkPMColor*) dst;
    315     for (int x = 0; x < width; x++) {
    316         dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
    317         src += deltaSrc;
    318     }
    319 }
    320 
    321 static void fast_swizzle_grayalpha_to_n32_unpremul(
    322         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    323         const SkPMColor ctable[]) {
    324 
    325     // This function must not be called if we are sampling.  If we are not
    326     // sampling, deltaSrc should equal bpp.
    327     SkASSERT(deltaSrc == bpp);
    328 
    329     // Note that there is no need to distinguish between RGB and BGR.
    330     // Each color channel will get the same value.
    331     SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
    332 }
    333 
    334 static void swizzle_grayalpha_to_n32_premul(
    335         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    336         const SkPMColor ctable[]) {
    337 
    338     src += offset;
    339     SkPMColor* dst32 = (SkPMColor*) dst;
    340     for (int x = 0; x < width; x++) {
    341         uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
    342         dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
    343         src += deltaSrc;
    344     }
    345 }
    346 
    347 static void fast_swizzle_grayalpha_to_n32_premul(
    348         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    349         const SkPMColor ctable[]) {
    350 
    351     // This function must not be called if we are sampling.  If we are not
    352     // sampling, deltaSrc should equal bpp.
    353     SkASSERT(deltaSrc == bpp);
    354 
    355     // Note that there is no need to distinguish between rgb and bgr.
    356     // Each color channel will get the same value.
    357     SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
    358 }
    359 
    360 // kBGR
    361 
    362 static void swizzle_bgr_to_565(
    363         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    364         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    365 
    366     src += offset;
    367     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    368     for (int x = 0; x < dstWidth; x++) {
    369         dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
    370         src += deltaSrc;
    371     }
    372 }
    373 
    374 // kRGB
    375 
    376 static void swizzle_rgb_to_rgba(
    377         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    378         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    379 
    380     src += offset;
    381     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    382     for (int x = 0; x < dstWidth; x++) {
    383         dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
    384         src += deltaSrc;
    385     }
    386 }
    387 
    388 static void swizzle_rgb_to_bgra(
    389         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    390         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    391 
    392     src += offset;
    393     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    394     for (int x = 0; x < dstWidth; x++) {
    395         dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
    396         src += deltaSrc;
    397     }
    398 }
    399 
    400 static void fast_swizzle_rgb_to_rgba(
    401         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    402         int offset, const SkPMColor ctable[]) {
    403 
    404     // This function must not be called if we are sampling.  If we are not
    405     // sampling, deltaSrc should equal bpp.
    406     SkASSERT(deltaSrc == bpp);
    407 
    408     SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
    409 }
    410 
    411 static void fast_swizzle_rgb_to_bgra(
    412         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    413         int offset, const SkPMColor ctable[]) {
    414 
    415     // This function must not be called if we are sampling.  If we are not
    416     // sampling, deltaSrc should equal bpp.
    417     SkASSERT(deltaSrc == bpp);
    418 
    419     SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
    420 }
    421 
    422 static void swizzle_rgb_to_565(
    423        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    424        int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    425 
    426     src += offset;
    427     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    428     for (int x = 0; x < dstWidth; x++) {
    429         dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
    430         src += deltaSrc;
    431     }
    432 }
    433 
    434 // kRGBA
    435 
    436 static void swizzle_rgba_to_rgba_premul(
    437         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    438         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    439 
    440     src += offset;
    441     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    442     for (int x = 0; x < dstWidth; x++) {
    443         dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
    444         src += deltaSrc;
    445     }
    446 }
    447 
    448 static void swizzle_rgba_to_bgra_premul(
    449         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    450         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    451 
    452     src += offset;
    453     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    454     for (int x = 0; x < dstWidth; x++) {
    455         dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
    456         src += deltaSrc;
    457     }
    458 }
    459 
    460 static void fast_swizzle_rgba_to_rgba_premul(
    461         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    462         int offset, const SkPMColor ctable[]) {
    463 
    464     // This function must not be called if we are sampling.  If we are not
    465     // sampling, deltaSrc should equal bpp.
    466     SkASSERT(deltaSrc == bpp);
    467 
    468     SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
    469 }
    470 
    471 static void fast_swizzle_rgba_to_bgra_premul(
    472         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    473         int offset, const SkPMColor ctable[]) {
    474 
    475     // This function must not be called if we are sampling.  If we are not
    476     // sampling, deltaSrc should equal bpp.
    477     SkASSERT(deltaSrc == bpp);
    478 
    479     SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
    480 }
    481 
    482 static void swizzle_rgba_to_bgra_unpremul(
    483         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    484         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    485 
    486     src += offset;
    487     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
    488     for (int x = 0; x < dstWidth; x++) {
    489         unsigned alpha = src[3];
    490         dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
    491         src += deltaSrc;
    492     }
    493 }
    494 
    495 static void fast_swizzle_rgba_to_bgra_unpremul(
    496         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    497         const SkPMColor ctable[]) {
    498 
    499     // This function must not be called if we are sampling.  If we are not
    500     // sampling, deltaSrc should equal bpp.
    501     SkASSERT(deltaSrc == bpp);
    502 
    503     SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
    504 }
    505 
    506 // 16-bits per component kRGB and kRGBA
    507 
    508 static void swizzle_rgb16_to_rgba(
    509         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    510         const SkPMColor ctable[]) {
    511     auto strip16to8 = [](const uint8_t* ptr) {
    512         return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
    513     };
    514 
    515     src += offset;
    516     uint32_t* dst32 = (uint32_t*) dst;
    517     for (int x = 0; x < width; x++) {
    518         dst32[x] = strip16to8(src);
    519         src += deltaSrc;
    520     }
    521 }
    522 
    523 static void swizzle_rgb16_to_bgra(
    524         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    525         const SkPMColor ctable[]) {
    526     auto strip16to8 = [](const uint8_t* ptr) {
    527         return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
    528     };
    529 
    530     src += offset;
    531     uint32_t* dst32 = (uint32_t*) dst;
    532     for (int x = 0; x < width; x++) {
    533         dst32[x] = strip16to8(src);
    534         src += deltaSrc;
    535     }
    536 }
    537 
    538 static void swizzle_rgb16_to_565(
    539         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    540         const SkPMColor ctable[]) {
    541     auto strip16to565 = [](const uint8_t* ptr) {
    542         return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]);
    543     };
    544 
    545     src += offset;
    546     uint16_t* dst16 = (uint16_t*) dst;
    547     for (int x = 0; x < width; x++) {
    548         dst16[x] = strip16to565(src);
    549         src += deltaSrc;
    550     }
    551 }
    552 
    553 static void swizzle_rgba16_to_rgba_unpremul(
    554         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    555         const SkPMColor ctable[]) {
    556     auto strip16to8 = [](const uint8_t* ptr) {
    557         return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
    558     };
    559 
    560     src += offset;
    561     uint32_t* dst32 = (uint32_t*) dst;
    562     for (int x = 0; x < width; x++) {
    563         dst32[x] = strip16to8(src);
    564         src += deltaSrc;
    565     }
    566 }
    567 
    568 static void swizzle_rgba16_to_rgba_premul(
    569         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    570         const SkPMColor ctable[]) {
    571     auto stripAndPremul16to8 = [](const uint8_t* ptr) {
    572         return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]);
    573     };
    574 
    575     src += offset;
    576     uint32_t* dst32 = (uint32_t*) dst;
    577     for (int x = 0; x < width; x++) {
    578         dst32[x] = stripAndPremul16to8(src);
    579         src += deltaSrc;
    580     }
    581 }
    582 
    583 static void swizzle_rgba16_to_bgra_unpremul(
    584         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    585         const SkPMColor ctable[]) {
    586     auto strip16to8 = [](const uint8_t* ptr) {
    587         return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
    588     };
    589 
    590     src += offset;
    591     uint32_t* dst32 = (uint32_t*) dst;
    592     for (int x = 0; x < width; x++) {
    593         dst32[x] = strip16to8(src);
    594         src += deltaSrc;
    595     }
    596 }
    597 
    598 static void swizzle_rgba16_to_bgra_premul(
    599         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    600         const SkPMColor ctable[]) {
    601     auto stripAndPremul16to8 = [](const uint8_t* ptr) {
    602         return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]);
    603     };
    604 
    605     src += offset;
    606     uint32_t* dst32 = (uint32_t*) dst;
    607     for (int x = 0; x < width; x++) {
    608         dst32[x] = stripAndPremul16to8(src);
    609         src += deltaSrc;
    610     }
    611 }
    612 
    613 // kCMYK
    614 //
    615 // CMYK is stored as four bytes per pixel.
    616 //
    617 // We will implement a crude conversion from CMYK -> RGB using formulas
    618 // from easyrgb.com.
    619 //
    620 // CMYK -> CMY
    621 // C = C * (1 - K) + K
    622 // M = M * (1 - K) + K
    623 // Y = Y * (1 - K) + K
    624 //
    625 // libjpeg actually gives us inverted CMYK, so we must subtract the
    626 // original terms from 1.
    627 // CMYK -> CMY
    628 // C = (1 - C) * (1 - (1 - K)) + (1 - K)
    629 // M = (1 - M) * (1 - (1 - K)) + (1 - K)
    630 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
    631 //
    632 // Simplifying the above expression.
    633 // CMYK -> CMY
    634 // C = 1 - CK
    635 // M = 1 - MK
    636 // Y = 1 - YK
    637 //
    638 // CMY -> RGB
    639 // R = (1 - C) * 255
    640 // G = (1 - M) * 255
    641 // B = (1 - Y) * 255
    642 //
    643 // Therefore the full conversion is below.  This can be verified at
    644 // www.rapidtables.com (assuming inverted CMYK).
    645 // CMYK -> RGB
    646 // R = C * K * 255
    647 // G = M * K * 255
    648 // B = Y * K * 255
    649 //
    650 // As a final note, we have treated the CMYK values as if they were on
    651 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
    652 // We must divide each CMYK component by 255 to obtain the true conversion
    653 // we should perform.
    654 // CMYK -> RGB
    655 // R = C * K / 255
    656 // G = M * K / 255
    657 // B = Y * K / 255
    658 static void swizzle_cmyk_to_rgba(
    659         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    660         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    661 
    662     src += offset;
    663     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    664     for (int x = 0; x < dstWidth; x++) {
    665         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    666         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    667         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    668 
    669         dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
    670         src += deltaSrc;
    671     }
    672 }
    673 
    674 static void swizzle_cmyk_to_bgra(
    675         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    676         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    677 
    678     src += offset;
    679     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    680     for (int x = 0; x < dstWidth; x++) {
    681         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    682         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    683         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    684 
    685         dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
    686         src += deltaSrc;
    687     }
    688 }
    689 
    690 static void fast_swizzle_cmyk_to_rgba(
    691         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    692         const SkPMColor ctable[]) {
    693 
    694     // This function must not be called if we are sampling.  If we are not
    695     // sampling, deltaSrc should equal bpp.
    696     SkASSERT(deltaSrc == bpp);
    697 
    698     SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
    699 }
    700 
    701 static void fast_swizzle_cmyk_to_bgra(
    702         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    703         const SkPMColor ctable[]) {
    704 
    705     // This function must not be called if we are sampling.  If we are not
    706     // sampling, deltaSrc should equal bpp.
    707     SkASSERT(deltaSrc == bpp);
    708 
    709     SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
    710 }
    711 
    712 static void swizzle_cmyk_to_565(
    713         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    714         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    715 
    716     src += offset;
    717     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    718     for (int x = 0; x < dstWidth; x++) {
    719         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    720         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    721         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    722 
    723         dst[x] = SkPack888ToRGB16(r, g, b);
    724         src += deltaSrc;
    725     }
    726 }
    727 
    728 template <SkSwizzler::RowProc proc>
    729 void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
    730         void* dst, const uint8_t* src, int width,
    731         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    732     SkASSERT(!ctable);
    733 
    734     const uint16_t* src16 = (const uint16_t*) (src + offset);
    735     uint32_t* dst32 = (uint32_t*) dst;
    736 
    737     // This may miss opportunities to skip when the output is premultiplied,
    738     // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
    739     while (width > 0 && *src16 == 0x0000) {
    740         width--;
    741         dst32++;
    742         src16 += deltaSrc / 2;
    743     }
    744     proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
    745 }
    746 
    747 template <SkSwizzler::RowProc proc>
    748 void SkSwizzler::SkipLeading8888ZerosThen(
    749         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    750         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    751     SkASSERT(!ctable);
    752 
    753     auto src32 = (const uint32_t*)(src+offset);
    754     auto dst32 = (uint32_t*)dstRow;
    755 
    756     // This may miss opportunities to skip when the output is premultiplied,
    757     // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
    758     while (dstWidth > 0 && *src32 == 0x00000000) {
    759         dstWidth--;
    760         dst32++;
    761         src32 += deltaSrc/4;
    762     }
    763     proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
    764 }
    765 
    766 SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
    767                                        const SkPMColor* ctable,
    768                                        const SkImageInfo& dstInfo,
    769                                        const SkCodec::Options& options,
    770                                        const SkIRect* frame,
    771                                        bool skipFormatConversion) {
    772     if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
    773         return nullptr;
    774     }
    775 
    776     RowProc fastProc = nullptr;
    777     RowProc proc = nullptr;
    778     int srcBPP;
    779     const int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
    780     if (skipFormatConversion) {
    781         switch (encodedInfo.color()) {
    782             case SkEncodedInfo::kGray_Color:
    783             case SkEncodedInfo::kYUV_Color:
    784                 // We have a jpeg that has already been converted to the dstColorType.
    785                 srcBPP = dstBPP;
    786                 switch (dstInfo.colorType()) {
    787                     case kGray_8_SkColorType:
    788                         proc = &sample1;
    789                         fastProc = &copy;
    790                         break;
    791                     case kRGB_565_SkColorType:
    792                         proc = &sample2;
    793                         fastProc = &copy;
    794                         break;
    795                     case kRGBA_8888_SkColorType:
    796                     case kBGRA_8888_SkColorType:
    797                         proc = &sample4;
    798                         fastProc = &copy;
    799                         break;
    800                     default:
    801                         return nullptr;
    802                 }
    803                 break;
    804             case SkEncodedInfo::kInvertedCMYK_Color:
    805             case SkEncodedInfo::kYCCK_Color:
    806                 // We have a jpeg that remains in its original format.
    807                 srcBPP = 4;
    808                 proc = &sample4;
    809                 fastProc = &copy;
    810                 break;
    811             case SkEncodedInfo::kRGBA_Color:
    812                 // We have a png that should remain in its original format.
    813                 SkASSERT(16 == encodedInfo.bitsPerComponent() ||
    814                           8 == encodedInfo.bitsPerComponent());
    815                 if (8 == encodedInfo.bitsPerComponent()) {
    816                     srcBPP = 4;
    817                     proc = &sample4;
    818                 } else {
    819                     srcBPP = 8;
    820                     proc = &sample8;
    821                 }
    822                 fastProc = &copy;
    823                 break;
    824             case SkEncodedInfo::kRGB_Color:
    825                 // We have a png that remains in its original format.
    826                 SkASSERT(16 == encodedInfo.bitsPerComponent());
    827                 srcBPP = 6;
    828                 proc = &sample6;
    829                 fastProc = &copy;
    830                 break;
    831             default:
    832                 return nullptr;
    833         }
    834     } else {
    835         SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
    836         const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
    837                 (kPremul_SkAlphaType == dstInfo.alphaType());
    838 
    839         switch (encodedInfo.color()) {
    840             case SkEncodedInfo::kGray_Color:
    841                 switch (encodedInfo.bitsPerComponent()) {
    842                     case 1:
    843                         switch (dstInfo.colorType()) {
    844                             case kRGBA_8888_SkColorType:
    845                             case kBGRA_8888_SkColorType:
    846                                 proc = &swizzle_bit_to_n32;
    847                                 break;
    848                             case kRGB_565_SkColorType:
    849                                 proc = &swizzle_bit_to_565;
    850                                 break;
    851                             case kGray_8_SkColorType:
    852                                 proc = &swizzle_bit_to_grayscale;
    853                                 break;
    854                             case kRGBA_F16_SkColorType:
    855                                 proc = &swizzle_bit_to_f16;
    856                                 break;
    857                             default:
    858                                 return nullptr;
    859                         }
    860                         break;
    861                     case 8:
    862                         switch (dstInfo.colorType()) {
    863                             case kRGBA_8888_SkColorType:
    864                             case kBGRA_8888_SkColorType:
    865                                 proc = &swizzle_gray_to_n32;
    866                                 fastProc = &fast_swizzle_gray_to_n32;
    867                                 break;
    868                             case kGray_8_SkColorType:
    869                                 proc = &sample1;
    870                                 fastProc = &copy;
    871                                 break;
    872                             case kRGB_565_SkColorType:
    873                                 proc = &swizzle_gray_to_565;
    874                                 break;
    875                             default:
    876                                 return nullptr;
    877                         }
    878                         break;
    879                     default:
    880                         return nullptr;
    881                 }
    882                 break;
    883             case SkEncodedInfo::kGrayAlpha_Color:
    884                 switch (dstInfo.colorType()) {
    885                     case kRGBA_8888_SkColorType:
    886                     case kBGRA_8888_SkColorType:
    887                         if (premultiply) {
    888                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    889                                 proc = &SkipLeadingGrayAlphaZerosThen
    890                                         <swizzle_grayalpha_to_n32_premul>;
    891                                 fastProc = &SkipLeadingGrayAlphaZerosThen
    892                                         <fast_swizzle_grayalpha_to_n32_premul>;
    893                             } else {
    894                                 proc = &swizzle_grayalpha_to_n32_premul;
    895                                 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
    896                             }
    897                         } else {
    898                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    899                                 proc = &SkipLeadingGrayAlphaZerosThen
    900                                         <swizzle_grayalpha_to_n32_unpremul>;
    901                                 fastProc = &SkipLeadingGrayAlphaZerosThen
    902                                         <fast_swizzle_grayalpha_to_n32_unpremul>;
    903                             } else {
    904                                 proc = &swizzle_grayalpha_to_n32_unpremul;
    905                                 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
    906                             }
    907                         }
    908                         break;
    909                     default:
    910                         return nullptr;
    911                 }
    912                 break;
    913             case SkEncodedInfo::kPalette_Color:
    914                 // We assume that the color table is premultiplied and swizzled
    915                 // as desired.
    916                 switch (encodedInfo.bitsPerComponent()) {
    917                     case 1:
    918                     case 2:
    919                     case 4:
    920                         switch (dstInfo.colorType()) {
    921                             case kRGBA_8888_SkColorType:
    922                             case kBGRA_8888_SkColorType:
    923                                 proc = &swizzle_small_index_to_n32;
    924                                 break;
    925                             case kRGB_565_SkColorType:
    926                                 proc = &swizzle_small_index_to_565;
    927                                 break;
    928                             default:
    929                                 return nullptr;
    930                         }
    931                         break;
    932                     case 8:
    933                         switch (dstInfo.colorType()) {
    934                             case kRGBA_8888_SkColorType:
    935                             case kBGRA_8888_SkColorType:
    936                                 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    937                                     proc = &swizzle_index_to_n32_skipZ;
    938                                 } else {
    939                                     proc = &swizzle_index_to_n32;
    940                                 }
    941                                 break;
    942                             case kRGB_565_SkColorType:
    943                                 proc = &swizzle_index_to_565;
    944                                 break;
    945                             default:
    946                                 return nullptr;
    947                         }
    948                         break;
    949                     default:
    950                         return nullptr;
    951                 }
    952                 break;
    953             case SkEncodedInfo::kRGB_Color:
    954                 switch (dstInfo.colorType()) {
    955                     case kRGBA_8888_SkColorType:
    956                         if (16 == encodedInfo.bitsPerComponent()) {
    957                             proc = &swizzle_rgb16_to_rgba;
    958                             break;
    959                         }
    960 
    961                         SkASSERT(8 == encodedInfo.bitsPerComponent());
    962                         proc = &swizzle_rgb_to_rgba;
    963                         fastProc = &fast_swizzle_rgb_to_rgba;
    964                         break;
    965                     case kBGRA_8888_SkColorType:
    966                         if (16 == encodedInfo.bitsPerComponent()) {
    967                             proc = &swizzle_rgb16_to_bgra;
    968                             break;
    969                         }
    970 
    971                         SkASSERT(8 == encodedInfo.bitsPerComponent());
    972                         proc = &swizzle_rgb_to_bgra;
    973                         fastProc = &fast_swizzle_rgb_to_bgra;
    974                         break;
    975                     case kRGB_565_SkColorType:
    976                         if (16 == encodedInfo.bitsPerComponent()) {
    977                             proc = &swizzle_rgb16_to_565;
    978                             break;
    979                         }
    980 
    981                         proc = &swizzle_rgb_to_565;
    982                         break;
    983                     default:
    984                         return nullptr;
    985                 }
    986                 break;
    987             case SkEncodedInfo::kRGBA_Color:
    988                 switch (dstInfo.colorType()) {
    989                     case kRGBA_8888_SkColorType:
    990                         if (16 == encodedInfo.bitsPerComponent()) {
    991                             proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
    992                                                  &swizzle_rgba16_to_rgba_unpremul;
    993                             break;
    994                         }
    995 
    996                         SkASSERT(8 == encodedInfo.bitsPerComponent());
    997                         if (premultiply) {
    998                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    999                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
   1000                                 fastProc = &SkipLeading8888ZerosThen
   1001                                         <fast_swizzle_rgba_to_rgba_premul>;
   1002                             } else {
   1003                                 proc = &swizzle_rgba_to_rgba_premul;
   1004                                 fastProc = &fast_swizzle_rgba_to_rgba_premul;
   1005                             }
   1006                         } else {
   1007                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1008                                 proc = &SkipLeading8888ZerosThen<sample4>;
   1009                                 fastProc = &SkipLeading8888ZerosThen<copy>;
   1010                             } else {
   1011                                 proc = &sample4;
   1012                                 fastProc = &copy;
   1013                             }
   1014                         }
   1015                         break;
   1016                     case kBGRA_8888_SkColorType:
   1017                         if (16 == encodedInfo.bitsPerComponent()) {
   1018                             proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
   1019                                                  &swizzle_rgba16_to_bgra_unpremul;
   1020                             break;
   1021                         }
   1022 
   1023                         SkASSERT(8 == encodedInfo.bitsPerComponent());
   1024                         if (premultiply) {
   1025                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1026                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
   1027                                 fastProc = &SkipLeading8888ZerosThen
   1028                                         <fast_swizzle_rgba_to_bgra_premul>;
   1029                             } else {
   1030                                 proc = &swizzle_rgba_to_bgra_premul;
   1031                                 fastProc = &fast_swizzle_rgba_to_bgra_premul;
   1032                             }
   1033                         } else {
   1034                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1035                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
   1036                                 fastProc = &SkipLeading8888ZerosThen
   1037                                         <fast_swizzle_rgba_to_bgra_unpremul>;
   1038                             } else {
   1039                                 proc = &swizzle_rgba_to_bgra_unpremul;
   1040                                 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
   1041                             }
   1042                         }
   1043                         break;
   1044                     default:
   1045                         return nullptr;
   1046                 }
   1047                 break;
   1048             case SkEncodedInfo::kBGR_Color:
   1049                 switch (dstInfo.colorType()) {
   1050                     case kBGRA_8888_SkColorType:
   1051                         proc = &swizzle_rgb_to_rgba;
   1052                         fastProc = &fast_swizzle_rgb_to_rgba;
   1053                         break;
   1054                     case kRGBA_8888_SkColorType:
   1055                         proc = &swizzle_rgb_to_bgra;
   1056                         fastProc = &fast_swizzle_rgb_to_bgra;
   1057                         break;
   1058                     case kRGB_565_SkColorType:
   1059                         proc = &swizzle_bgr_to_565;
   1060                         break;
   1061                     default:
   1062                         return nullptr;
   1063                 }
   1064                 break;
   1065             case SkEncodedInfo::kBGRX_Color:
   1066                 switch (dstInfo.colorType()) {
   1067                     case kBGRA_8888_SkColorType:
   1068                         proc = &swizzle_rgb_to_rgba;
   1069                         break;
   1070                     case kRGBA_8888_SkColorType:
   1071                         proc = &swizzle_rgb_to_bgra;
   1072                         break;
   1073                     case kRGB_565_SkColorType:
   1074                         proc = &swizzle_bgr_to_565;
   1075                         break;
   1076                     default:
   1077                         return nullptr;
   1078                 }
   1079                 break;
   1080             case SkEncodedInfo::kBGRA_Color:
   1081                 switch (dstInfo.colorType()) {
   1082                     case kBGRA_8888_SkColorType:
   1083                         if (premultiply) {
   1084                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1085                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
   1086                                 fastProc = &SkipLeading8888ZerosThen
   1087                                         <fast_swizzle_rgba_to_rgba_premul>;
   1088                             } else {
   1089                                 proc = &swizzle_rgba_to_rgba_premul;
   1090                                 fastProc = &fast_swizzle_rgba_to_rgba_premul;
   1091                             }
   1092                         } else {
   1093                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1094                                 proc = &SkipLeading8888ZerosThen<sample4>;
   1095                                 fastProc = &SkipLeading8888ZerosThen<copy>;
   1096                             } else {
   1097                                 proc = &sample4;
   1098                                 fastProc = &copy;
   1099                             }
   1100                         }
   1101                         break;
   1102                     case kRGBA_8888_SkColorType:
   1103                         if (premultiply) {
   1104                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1105                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
   1106                                 fastProc = &SkipLeading8888ZerosThen
   1107                                         <fast_swizzle_rgba_to_bgra_premul>;
   1108                             } else {
   1109                                 proc = &swizzle_rgba_to_bgra_premul;
   1110                                 fastProc = &fast_swizzle_rgba_to_bgra_premul;
   1111                             }
   1112                         } else {
   1113                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1114                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
   1115                                 fastProc = &SkipLeading8888ZerosThen
   1116                                         <fast_swizzle_rgba_to_bgra_unpremul>;
   1117                             } else {
   1118                                 proc = &swizzle_rgba_to_bgra_unpremul;
   1119                                 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
   1120                             }
   1121                         }
   1122                         break;
   1123                     default:
   1124                         return nullptr;
   1125                 }
   1126                 break;
   1127             case SkEncodedInfo::kInvertedCMYK_Color:
   1128                 switch (dstInfo.colorType()) {
   1129                     case kRGBA_8888_SkColorType:
   1130                         proc = &swizzle_cmyk_to_rgba;
   1131                         fastProc = &fast_swizzle_cmyk_to_rgba;
   1132                         break;
   1133                     case kBGRA_8888_SkColorType:
   1134                         proc = &swizzle_cmyk_to_bgra;
   1135                         fastProc = &fast_swizzle_cmyk_to_bgra;
   1136                         break;
   1137                     case kRGB_565_SkColorType:
   1138                         proc = &swizzle_cmyk_to_565;
   1139                         break;
   1140                     default:
   1141                         return nullptr;
   1142                 }
   1143                 break;
   1144             default:
   1145                 return nullptr;
   1146         }
   1147 
   1148         // Store bpp in bytes if it is an even multiple, otherwise use bits
   1149         uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
   1150         srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
   1151     }
   1152 
   1153     int srcOffset = 0;
   1154     int srcWidth = dstInfo.width();
   1155     int dstOffset = 0;
   1156     int dstWidth = srcWidth;
   1157     if (options.fSubset) {
   1158         // We do not currently support subset decodes for image types that may have
   1159         // frames (gif).
   1160         SkASSERT(!frame);
   1161         srcOffset = options.fSubset->left();
   1162         srcWidth = options.fSubset->width();
   1163         dstWidth = srcWidth;
   1164     } else if (frame) {
   1165         dstOffset = frame->left();
   1166         srcWidth = frame->width();
   1167     }
   1168 
   1169     return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
   1170             srcBPP, dstBPP);
   1171 }
   1172 
   1173 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
   1174         int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
   1175     : fFastProc(fastProc)
   1176     , fSlowProc(proc)
   1177     , fActualProc(fFastProc ? fFastProc : fSlowProc)
   1178     , fColorTable(ctable)
   1179     , fSrcOffset(srcOffset)
   1180     , fDstOffset(dstOffset)
   1181     , fSrcOffsetUnits(srcOffset * srcBPP)
   1182     , fDstOffsetBytes(dstOffset * dstBPP)
   1183     , fSrcWidth(srcWidth)
   1184     , fDstWidth(dstWidth)
   1185     , fSwizzleWidth(srcWidth)
   1186     , fAllocatedWidth(dstWidth)
   1187     , fSampleX(1)
   1188     , fSrcBPP(srcBPP)
   1189     , fDstBPP(dstBPP)
   1190 {}
   1191 
   1192 int SkSwizzler::onSetSampleX(int sampleX) {
   1193     SkASSERT(sampleX > 0);
   1194 
   1195     fSampleX = sampleX;
   1196     fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
   1197     fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
   1198     fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
   1199     fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
   1200 
   1201     // The optimized swizzler functions do not support sampling.  Sampled swizzles
   1202     // are already fast because they skip pixels.  We haven't seen a situation
   1203     // where speeding up sampling has a significant impact on total decode time.
   1204     if (1 == fSampleX && fFastProc) {
   1205         fActualProc = fFastProc;
   1206     } else {
   1207         fActualProc = fSlowProc;
   1208     }
   1209 
   1210     return fAllocatedWidth;
   1211 }
   1212 
   1213 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
   1214     SkASSERT(nullptr != dst && nullptr != src);
   1215     fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
   1216             fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
   1217 }
   1218