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 "SkColorData.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     constexpr uint64_t kWhite = (((uint64_t) SK_Half1) <<  0) |
    158                                 (((uint64_t) SK_Half1) << 16) |
    159                                 (((uint64_t) SK_Half1) << 32) |
    160                                 (((uint64_t) SK_Half1) << 48);
    161     constexpr uint64_t kBlack = (((uint64_t)        0) <<  0) |
    162                                 (((uint64_t)        0) << 16) |
    163                                 (((uint64_t)        0) << 32) |
    164                                 (((uint64_t) SK_Half1) << 48);
    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 static void swizzle_grayalpha_to_a8(void* dst, const uint8_t* src, int width, int bpp,
    361                                     int deltaSrc, int offset, const SkPMColor[]) {
    362     src += offset;
    363     uint8_t* dst8 = (uint8_t*)dst;
    364     for (int x = 0; x < width; ++x) {
    365         dst8[x] = src[1];   // src[0] is gray, ignored
    366         src += deltaSrc;
    367     }
    368 }
    369 
    370 // kBGR
    371 
    372 static void swizzle_bgr_to_565(
    373         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    374         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    375 
    376     src += offset;
    377     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    378     for (int x = 0; x < dstWidth; x++) {
    379         dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
    380         src += deltaSrc;
    381     }
    382 }
    383 
    384 // kRGB
    385 
    386 static void swizzle_rgb_to_rgba(
    387         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    388         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    389 
    390     src += offset;
    391     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    392     for (int x = 0; x < dstWidth; x++) {
    393         dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
    394         src += deltaSrc;
    395     }
    396 }
    397 
    398 static void swizzle_rgb_to_bgra(
    399         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    400         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    401 
    402     src += offset;
    403     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    404     for (int x = 0; x < dstWidth; x++) {
    405         dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
    406         src += deltaSrc;
    407     }
    408 }
    409 
    410 static void fast_swizzle_rgb_to_rgba(
    411         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    412         int offset, const SkPMColor ctable[]) {
    413 
    414     // This function must not be called if we are sampling.  If we are not
    415     // sampling, deltaSrc should equal bpp.
    416     SkASSERT(deltaSrc == bpp);
    417 
    418     SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
    419 }
    420 
    421 static void fast_swizzle_rgb_to_bgra(
    422         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    423         int offset, const SkPMColor ctable[]) {
    424 
    425     // This function must not be called if we are sampling.  If we are not
    426     // sampling, deltaSrc should equal bpp.
    427     SkASSERT(deltaSrc == bpp);
    428 
    429     SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
    430 }
    431 
    432 static void swizzle_rgb_to_565(
    433        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    434        int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    435 
    436     src += offset;
    437     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    438     for (int x = 0; x < dstWidth; x++) {
    439         dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
    440         src += deltaSrc;
    441     }
    442 }
    443 
    444 // kRGBA
    445 
    446 static void swizzle_rgba_to_rgba_premul(
    447         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    448         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    449 
    450     src += offset;
    451     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    452     for (int x = 0; x < dstWidth; x++) {
    453         dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
    454         src += deltaSrc;
    455     }
    456 }
    457 
    458 static void swizzle_rgba_to_bgra_premul(
    459         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    460         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    461 
    462     src += offset;
    463     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    464     for (int x = 0; x < dstWidth; x++) {
    465         dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]);
    466         src += deltaSrc;
    467     }
    468 }
    469 
    470 static void fast_swizzle_rgba_to_rgba_premul(
    471         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    472         int offset, const SkPMColor ctable[]) {
    473 
    474     // This function must not be called if we are sampling.  If we are not
    475     // sampling, deltaSrc should equal bpp.
    476     SkASSERT(deltaSrc == bpp);
    477 
    478     SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
    479 }
    480 
    481 static void fast_swizzle_rgba_to_bgra_premul(
    482         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    483         int offset, const SkPMColor ctable[]) {
    484 
    485     // This function must not be called if we are sampling.  If we are not
    486     // sampling, deltaSrc should equal bpp.
    487     SkASSERT(deltaSrc == bpp);
    488 
    489     SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
    490 }
    491 
    492 static void swizzle_rgba_to_bgra_unpremul(
    493         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    494         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    495 
    496     src += offset;
    497     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
    498     for (int x = 0; x < dstWidth; x++) {
    499         unsigned alpha = src[3];
    500         dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]);
    501         src += deltaSrc;
    502     }
    503 }
    504 
    505 static void fast_swizzle_rgba_to_bgra_unpremul(
    506         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    507         const SkPMColor ctable[]) {
    508 
    509     // This function must not be called if we are sampling.  If we are not
    510     // sampling, deltaSrc should equal bpp.
    511     SkASSERT(deltaSrc == bpp);
    512 
    513     SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
    514 }
    515 
    516 // 16-bits per component kRGB and kRGBA
    517 
    518 static void swizzle_rgb16_to_rgba(
    519         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    520         const SkPMColor ctable[]) {
    521     auto strip16to8 = [](const uint8_t* ptr) {
    522         return 0xFF000000 | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
    523     };
    524 
    525     src += offset;
    526     uint32_t* dst32 = (uint32_t*) dst;
    527     for (int x = 0; x < width; x++) {
    528         dst32[x] = strip16to8(src);
    529         src += deltaSrc;
    530     }
    531 }
    532 
    533 static void swizzle_rgb16_to_bgra(
    534         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    535         const SkPMColor ctable[]) {
    536     auto strip16to8 = [](const uint8_t* ptr) {
    537         return 0xFF000000 | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
    538     };
    539 
    540     src += offset;
    541     uint32_t* dst32 = (uint32_t*) dst;
    542     for (int x = 0; x < width; x++) {
    543         dst32[x] = strip16to8(src);
    544         src += deltaSrc;
    545     }
    546 }
    547 
    548 static void swizzle_rgb16_to_565(
    549         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    550         const SkPMColor ctable[]) {
    551     auto strip16to565 = [](const uint8_t* ptr) {
    552         return SkPack888ToRGB16(ptr[0], ptr[2], ptr[4]);
    553     };
    554 
    555     src += offset;
    556     uint16_t* dst16 = (uint16_t*) dst;
    557     for (int x = 0; x < width; x++) {
    558         dst16[x] = strip16to565(src);
    559         src += deltaSrc;
    560     }
    561 }
    562 
    563 static void swizzle_rgba16_to_rgba_unpremul(
    564         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    565         const SkPMColor ctable[]) {
    566     auto strip16to8 = [](const uint8_t* ptr) {
    567         return (ptr[6] << 24) | (ptr[4] << 16) | (ptr[2] << 8) | ptr[0];
    568     };
    569 
    570     src += offset;
    571     uint32_t* dst32 = (uint32_t*) dst;
    572     for (int x = 0; x < width; x++) {
    573         dst32[x] = strip16to8(src);
    574         src += deltaSrc;
    575     }
    576 }
    577 
    578 static void swizzle_rgba16_to_rgba_premul(
    579         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    580         const SkPMColor ctable[]) {
    581     auto stripAndPremul16to8 = [](const uint8_t* ptr) {
    582         return premultiply_argb_as_rgba(ptr[6], ptr[0], ptr[2], ptr[4]);
    583     };
    584 
    585     src += offset;
    586     uint32_t* dst32 = (uint32_t*) dst;
    587     for (int x = 0; x < width; x++) {
    588         dst32[x] = stripAndPremul16to8(src);
    589         src += deltaSrc;
    590     }
    591 }
    592 
    593 static void swizzle_rgba16_to_bgra_unpremul(
    594         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    595         const SkPMColor ctable[]) {
    596     auto strip16to8 = [](const uint8_t* ptr) {
    597         return (ptr[6] << 24) | (ptr[0] << 16) | (ptr[2] << 8) | ptr[4];
    598     };
    599 
    600     src += offset;
    601     uint32_t* dst32 = (uint32_t*) dst;
    602     for (int x = 0; x < width; x++) {
    603         dst32[x] = strip16to8(src);
    604         src += deltaSrc;
    605     }
    606 }
    607 
    608 static void swizzle_rgba16_to_bgra_premul(
    609         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    610         const SkPMColor ctable[]) {
    611     auto stripAndPremul16to8 = [](const uint8_t* ptr) {
    612         return premultiply_argb_as_bgra(ptr[6], ptr[0], ptr[2], ptr[4]);
    613     };
    614 
    615     src += offset;
    616     uint32_t* dst32 = (uint32_t*) dst;
    617     for (int x = 0; x < width; x++) {
    618         dst32[x] = stripAndPremul16to8(src);
    619         src += deltaSrc;
    620     }
    621 }
    622 
    623 // kCMYK
    624 //
    625 // CMYK is stored as four bytes per pixel.
    626 //
    627 // We will implement a crude conversion from CMYK -> RGB using formulas
    628 // from easyrgb.com.
    629 //
    630 // CMYK -> CMY
    631 // C = C * (1 - K) + K
    632 // M = M * (1 - K) + K
    633 // Y = Y * (1 - K) + K
    634 //
    635 // libjpeg actually gives us inverted CMYK, so we must subtract the
    636 // original terms from 1.
    637 // CMYK -> CMY
    638 // C = (1 - C) * (1 - (1 - K)) + (1 - K)
    639 // M = (1 - M) * (1 - (1 - K)) + (1 - K)
    640 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
    641 //
    642 // Simplifying the above expression.
    643 // CMYK -> CMY
    644 // C = 1 - CK
    645 // M = 1 - MK
    646 // Y = 1 - YK
    647 //
    648 // CMY -> RGB
    649 // R = (1 - C) * 255
    650 // G = (1 - M) * 255
    651 // B = (1 - Y) * 255
    652 //
    653 // Therefore the full conversion is below.  This can be verified at
    654 // www.rapidtables.com (assuming inverted CMYK).
    655 // CMYK -> RGB
    656 // R = C * K * 255
    657 // G = M * K * 255
    658 // B = Y * K * 255
    659 //
    660 // As a final note, we have treated the CMYK values as if they were on
    661 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
    662 // We must divide each CMYK component by 255 to obtain the true conversion
    663 // we should perform.
    664 // CMYK -> RGB
    665 // R = C * K / 255
    666 // G = M * K / 255
    667 // B = Y * K / 255
    668 static void swizzle_cmyk_to_rgba(
    669         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    670         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    671 
    672     src += offset;
    673     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    674     for (int x = 0; x < dstWidth; x++) {
    675         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    676         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    677         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    678 
    679         dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
    680         src += deltaSrc;
    681     }
    682 }
    683 
    684 static void swizzle_cmyk_to_bgra(
    685         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    686         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    687 
    688     src += offset;
    689     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    690     for (int x = 0; x < dstWidth; x++) {
    691         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    692         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    693         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    694 
    695         dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b);
    696         src += deltaSrc;
    697     }
    698 }
    699 
    700 static void fast_swizzle_cmyk_to_rgba(
    701         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    702         const SkPMColor ctable[]) {
    703 
    704     // This function must not be called if we are sampling.  If we are not
    705     // sampling, deltaSrc should equal bpp.
    706     SkASSERT(deltaSrc == bpp);
    707 
    708     SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
    709 }
    710 
    711 static void fast_swizzle_cmyk_to_bgra(
    712         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    713         const SkPMColor ctable[]) {
    714 
    715     // This function must not be called if we are sampling.  If we are not
    716     // sampling, deltaSrc should equal bpp.
    717     SkASSERT(deltaSrc == bpp);
    718 
    719     SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
    720 }
    721 
    722 static void swizzle_cmyk_to_565(
    723         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    724         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    725 
    726     src += offset;
    727     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    728     for (int x = 0; x < dstWidth; x++) {
    729         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    730         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    731         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    732 
    733         dst[x] = SkPack888ToRGB16(r, g, b);
    734         src += deltaSrc;
    735     }
    736 }
    737 
    738 template <SkSwizzler::RowProc proc>
    739 void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
    740         void* dst, const uint8_t* src, int width,
    741         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    742     SkASSERT(!ctable);
    743 
    744     const uint16_t* src16 = (const uint16_t*) (src + offset);
    745     uint32_t* dst32 = (uint32_t*) dst;
    746 
    747     // This may miss opportunities to skip when the output is premultiplied,
    748     // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
    749     while (width > 0 && *src16 == 0x0000) {
    750         width--;
    751         dst32++;
    752         src16 += deltaSrc / 2;
    753     }
    754     proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
    755 }
    756 
    757 template <SkSwizzler::RowProc proc>
    758 void SkSwizzler::SkipLeading8888ZerosThen(
    759         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    760         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    761     SkASSERT(!ctable);
    762 
    763     auto src32 = (const uint32_t*)(src+offset);
    764     auto dst32 = (uint32_t*)dstRow;
    765 
    766     // This may miss opportunities to skip when the output is premultiplied,
    767     // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
    768     while (dstWidth > 0 && *src32 == 0x00000000) {
    769         dstWidth--;
    770         dst32++;
    771         src32 += deltaSrc/4;
    772     }
    773     proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
    774 }
    775 
    776 SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
    777                                        const SkPMColor* ctable,
    778                                        const SkImageInfo& dstInfo,
    779                                        const SkCodec::Options& options,
    780                                        const SkIRect* frame,
    781                                        bool skipFormatConversion) {
    782     if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
    783         return nullptr;
    784     }
    785 
    786     RowProc fastProc = nullptr;
    787     RowProc proc = nullptr;
    788     int srcBPP;
    789     const int dstBPP = dstInfo.bytesPerPixel();
    790     if (skipFormatConversion) {
    791         switch (encodedInfo.color()) {
    792             case SkEncodedInfo::kGray_Color:
    793             case SkEncodedInfo::kYUV_Color:
    794                 // We have a jpeg that has already been converted to the dstColorType.
    795                 srcBPP = dstBPP;
    796                 switch (dstInfo.colorType()) {
    797                     case kGray_8_SkColorType:
    798                         proc = &sample1;
    799                         fastProc = &copy;
    800                         break;
    801                     case kRGB_565_SkColorType:
    802                         proc = &sample2;
    803                         fastProc = &copy;
    804                         break;
    805                     case kRGBA_8888_SkColorType:
    806                     case kBGRA_8888_SkColorType:
    807                         proc = &sample4;
    808                         fastProc = &copy;
    809                         break;
    810                     default:
    811                         return nullptr;
    812                 }
    813                 break;
    814             case SkEncodedInfo::kInvertedCMYK_Color:
    815             case SkEncodedInfo::kYCCK_Color:
    816                 // We have a jpeg that remains in its original format.
    817                 srcBPP = 4;
    818                 proc = &sample4;
    819                 fastProc = &copy;
    820                 break;
    821             case SkEncodedInfo::kRGBA_Color:
    822                 // We have a png that should remain in its original format.
    823                 SkASSERT(16 == encodedInfo.bitsPerComponent() ||
    824                           8 == encodedInfo.bitsPerComponent());
    825                 if (8 == encodedInfo.bitsPerComponent()) {
    826                     srcBPP = 4;
    827                     proc = &sample4;
    828                 } else {
    829                     srcBPP = 8;
    830                     proc = &sample8;
    831                 }
    832                 fastProc = &copy;
    833                 break;
    834             case SkEncodedInfo::kRGB_Color:
    835                 // We have a png that remains in its original format.
    836                 SkASSERT(16 == encodedInfo.bitsPerComponent());
    837                 srcBPP = 6;
    838                 proc = &sample6;
    839                 fastProc = &copy;
    840                 break;
    841             default:
    842                 return nullptr;
    843         }
    844     } else {
    845         SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
    846         const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
    847                 (kPremul_SkAlphaType == dstInfo.alphaType());
    848 
    849         switch (encodedInfo.color()) {
    850             case SkEncodedInfo::kGray_Color:
    851                 switch (encodedInfo.bitsPerComponent()) {
    852                     case 1:
    853                         switch (dstInfo.colorType()) {
    854                             case kRGBA_8888_SkColorType:
    855                             case kBGRA_8888_SkColorType:
    856                                 proc = &swizzle_bit_to_n32;
    857                                 break;
    858                             case kRGB_565_SkColorType:
    859                                 proc = &swizzle_bit_to_565;
    860                                 break;
    861                             case kGray_8_SkColorType:
    862                                 proc = &swizzle_bit_to_grayscale;
    863                                 break;
    864                             case kRGBA_F16_SkColorType:
    865                                 proc = &swizzle_bit_to_f16;
    866                                 break;
    867                             default:
    868                                 return nullptr;
    869                         }
    870                         break;
    871                     case 8:
    872                         switch (dstInfo.colorType()) {
    873                             case kRGBA_8888_SkColorType:
    874                             case kBGRA_8888_SkColorType:
    875                                 proc = &swizzle_gray_to_n32;
    876                                 fastProc = &fast_swizzle_gray_to_n32;
    877                                 break;
    878                             case kGray_8_SkColorType:
    879                                 proc = &sample1;
    880                                 fastProc = &copy;
    881                                 break;
    882                             case kRGB_565_SkColorType:
    883                                 proc = &swizzle_gray_to_565;
    884                                 break;
    885                             default:
    886                                 return nullptr;
    887                         }
    888                         break;
    889                     default:
    890                         return nullptr;
    891                 }
    892                 break;
    893             case SkEncodedInfo::kGrayAlpha_Color:
    894                 switch (dstInfo.colorType()) {
    895                     case kRGBA_8888_SkColorType:
    896                     case kBGRA_8888_SkColorType:
    897                         if (premultiply) {
    898                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    899                                 proc = &SkipLeadingGrayAlphaZerosThen
    900                                         <swizzle_grayalpha_to_n32_premul>;
    901                                 fastProc = &SkipLeadingGrayAlphaZerosThen
    902                                         <fast_swizzle_grayalpha_to_n32_premul>;
    903                             } else {
    904                                 proc = &swizzle_grayalpha_to_n32_premul;
    905                                 fastProc = &fast_swizzle_grayalpha_to_n32_premul;
    906                             }
    907                         } else {
    908                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    909                                 proc = &SkipLeadingGrayAlphaZerosThen
    910                                         <swizzle_grayalpha_to_n32_unpremul>;
    911                                 fastProc = &SkipLeadingGrayAlphaZerosThen
    912                                         <fast_swizzle_grayalpha_to_n32_unpremul>;
    913                             } else {
    914                                 proc = &swizzle_grayalpha_to_n32_unpremul;
    915                                 fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
    916                             }
    917                         }
    918                         break;
    919                     case kAlpha_8_SkColorType:
    920                         proc = &swizzle_grayalpha_to_a8;
    921                         break;
    922                     default:
    923                         return nullptr;
    924                 }
    925                 break;
    926             case SkEncodedInfo::kPalette_Color:
    927                 // We assume that the color table is premultiplied and swizzled
    928                 // as desired.
    929                 switch (encodedInfo.bitsPerComponent()) {
    930                     case 1:
    931                     case 2:
    932                     case 4:
    933                         switch (dstInfo.colorType()) {
    934                             case kRGBA_8888_SkColorType:
    935                             case kBGRA_8888_SkColorType:
    936                                 proc = &swizzle_small_index_to_n32;
    937                                 break;
    938                             case kRGB_565_SkColorType:
    939                                 proc = &swizzle_small_index_to_565;
    940                                 break;
    941                             default:
    942                                 return nullptr;
    943                         }
    944                         break;
    945                     case 8:
    946                         switch (dstInfo.colorType()) {
    947                             case kRGBA_8888_SkColorType:
    948                             case kBGRA_8888_SkColorType:
    949                                 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    950                                     proc = &swizzle_index_to_n32_skipZ;
    951                                 } else {
    952                                     proc = &swizzle_index_to_n32;
    953                                 }
    954                                 break;
    955                             case kRGB_565_SkColorType:
    956                                 proc = &swizzle_index_to_565;
    957                                 break;
    958                             default:
    959                                 return nullptr;
    960                         }
    961                         break;
    962                     default:
    963                         return nullptr;
    964                 }
    965                 break;
    966             case SkEncodedInfo::kRGB_Color:
    967                 switch (dstInfo.colorType()) {
    968                     case kRGBA_8888_SkColorType:
    969                         if (16 == encodedInfo.bitsPerComponent()) {
    970                             proc = &swizzle_rgb16_to_rgba;
    971                             break;
    972                         }
    973 
    974                         SkASSERT(8 == encodedInfo.bitsPerComponent());
    975                         proc = &swizzle_rgb_to_rgba;
    976                         fastProc = &fast_swizzle_rgb_to_rgba;
    977                         break;
    978                     case kBGRA_8888_SkColorType:
    979                         if (16 == encodedInfo.bitsPerComponent()) {
    980                             proc = &swizzle_rgb16_to_bgra;
    981                             break;
    982                         }
    983 
    984                         SkASSERT(8 == encodedInfo.bitsPerComponent());
    985                         proc = &swizzle_rgb_to_bgra;
    986                         fastProc = &fast_swizzle_rgb_to_bgra;
    987                         break;
    988                     case kRGB_565_SkColorType:
    989                         if (16 == encodedInfo.bitsPerComponent()) {
    990                             proc = &swizzle_rgb16_to_565;
    991                             break;
    992                         }
    993 
    994                         proc = &swizzle_rgb_to_565;
    995                         break;
    996                     default:
    997                         return nullptr;
    998                 }
    999                 break;
   1000             case SkEncodedInfo::kRGBA_Color:
   1001                 switch (dstInfo.colorType()) {
   1002                     case kRGBA_8888_SkColorType:
   1003                         if (16 == encodedInfo.bitsPerComponent()) {
   1004                             proc = premultiply ? &swizzle_rgba16_to_rgba_premul :
   1005                                                  &swizzle_rgba16_to_rgba_unpremul;
   1006                             break;
   1007                         }
   1008 
   1009                         SkASSERT(8 == encodedInfo.bitsPerComponent());
   1010                         if (premultiply) {
   1011                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1012                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
   1013                                 fastProc = &SkipLeading8888ZerosThen
   1014                                         <fast_swizzle_rgba_to_rgba_premul>;
   1015                             } else {
   1016                                 proc = &swizzle_rgba_to_rgba_premul;
   1017                                 fastProc = &fast_swizzle_rgba_to_rgba_premul;
   1018                             }
   1019                         } else {
   1020                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1021                                 proc = &SkipLeading8888ZerosThen<sample4>;
   1022                                 fastProc = &SkipLeading8888ZerosThen<copy>;
   1023                             } else {
   1024                                 proc = &sample4;
   1025                                 fastProc = &copy;
   1026                             }
   1027                         }
   1028                         break;
   1029                     case kBGRA_8888_SkColorType:
   1030                         if (16 == encodedInfo.bitsPerComponent()) {
   1031                             proc = premultiply ? &swizzle_rgba16_to_bgra_premul :
   1032                                                  &swizzle_rgba16_to_bgra_unpremul;
   1033                             break;
   1034                         }
   1035 
   1036                         SkASSERT(8 == encodedInfo.bitsPerComponent());
   1037                         if (premultiply) {
   1038                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1039                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
   1040                                 fastProc = &SkipLeading8888ZerosThen
   1041                                         <fast_swizzle_rgba_to_bgra_premul>;
   1042                             } else {
   1043                                 proc = &swizzle_rgba_to_bgra_premul;
   1044                                 fastProc = &fast_swizzle_rgba_to_bgra_premul;
   1045                             }
   1046                         } else {
   1047                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1048                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
   1049                                 fastProc = &SkipLeading8888ZerosThen
   1050                                         <fast_swizzle_rgba_to_bgra_unpremul>;
   1051                             } else {
   1052                                 proc = &swizzle_rgba_to_bgra_unpremul;
   1053                                 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
   1054                             }
   1055                         }
   1056                         break;
   1057                     default:
   1058                         return nullptr;
   1059                 }
   1060                 break;
   1061             case SkEncodedInfo::kBGR_Color:
   1062                 switch (dstInfo.colorType()) {
   1063                     case kBGRA_8888_SkColorType:
   1064                         proc = &swizzle_rgb_to_rgba;
   1065                         fastProc = &fast_swizzle_rgb_to_rgba;
   1066                         break;
   1067                     case kRGBA_8888_SkColorType:
   1068                         proc = &swizzle_rgb_to_bgra;
   1069                         fastProc = &fast_swizzle_rgb_to_bgra;
   1070                         break;
   1071                     case kRGB_565_SkColorType:
   1072                         proc = &swizzle_bgr_to_565;
   1073                         break;
   1074                     default:
   1075                         return nullptr;
   1076                 }
   1077                 break;
   1078             case SkEncodedInfo::kBGRX_Color:
   1079                 switch (dstInfo.colorType()) {
   1080                     case kBGRA_8888_SkColorType:
   1081                         proc = &swizzle_rgb_to_rgba;
   1082                         break;
   1083                     case kRGBA_8888_SkColorType:
   1084                         proc = &swizzle_rgb_to_bgra;
   1085                         break;
   1086                     case kRGB_565_SkColorType:
   1087                         proc = &swizzle_bgr_to_565;
   1088                         break;
   1089                     default:
   1090                         return nullptr;
   1091                 }
   1092                 break;
   1093             case SkEncodedInfo::kBGRA_Color:
   1094                 switch (dstInfo.colorType()) {
   1095                     case kBGRA_8888_SkColorType:
   1096                         if (premultiply) {
   1097                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1098                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
   1099                                 fastProc = &SkipLeading8888ZerosThen
   1100                                         <fast_swizzle_rgba_to_rgba_premul>;
   1101                             } else {
   1102                                 proc = &swizzle_rgba_to_rgba_premul;
   1103                                 fastProc = &fast_swizzle_rgba_to_rgba_premul;
   1104                             }
   1105                         } else {
   1106                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1107                                 proc = &SkipLeading8888ZerosThen<sample4>;
   1108                                 fastProc = &SkipLeading8888ZerosThen<copy>;
   1109                             } else {
   1110                                 proc = &sample4;
   1111                                 fastProc = &copy;
   1112                             }
   1113                         }
   1114                         break;
   1115                     case kRGBA_8888_SkColorType:
   1116                         if (premultiply) {
   1117                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1118                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
   1119                                 fastProc = &SkipLeading8888ZerosThen
   1120                                         <fast_swizzle_rgba_to_bgra_premul>;
   1121                             } else {
   1122                                 proc = &swizzle_rgba_to_bgra_premul;
   1123                                 fastProc = &fast_swizzle_rgba_to_bgra_premul;
   1124                             }
   1125                         } else {
   1126                             if (SkCodec::kYes_ZeroInitialized == zeroInit) {
   1127                                 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
   1128                                 fastProc = &SkipLeading8888ZerosThen
   1129                                         <fast_swizzle_rgba_to_bgra_unpremul>;
   1130                             } else {
   1131                                 proc = &swizzle_rgba_to_bgra_unpremul;
   1132                                 fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
   1133                             }
   1134                         }
   1135                         break;
   1136                     default:
   1137                         return nullptr;
   1138                 }
   1139                 break;
   1140             case SkEncodedInfo::kInvertedCMYK_Color:
   1141                 switch (dstInfo.colorType()) {
   1142                     case kRGBA_8888_SkColorType:
   1143                         proc = &swizzle_cmyk_to_rgba;
   1144                         fastProc = &fast_swizzle_cmyk_to_rgba;
   1145                         break;
   1146                     case kBGRA_8888_SkColorType:
   1147                         proc = &swizzle_cmyk_to_bgra;
   1148                         fastProc = &fast_swizzle_cmyk_to_bgra;
   1149                         break;
   1150                     case kRGB_565_SkColorType:
   1151                         proc = &swizzle_cmyk_to_565;
   1152                         break;
   1153                     default:
   1154                         return nullptr;
   1155                 }
   1156                 break;
   1157             default:
   1158                 return nullptr;
   1159         }
   1160 
   1161         // Store bpp in bytes if it is an even multiple, otherwise use bits
   1162         uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
   1163         srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
   1164     }
   1165 
   1166     int srcOffset = 0;
   1167     int srcWidth = dstInfo.width();
   1168     int dstOffset = 0;
   1169     int dstWidth = srcWidth;
   1170     if (options.fSubset) {
   1171         // We do not currently support subset decodes for image types that may have
   1172         // frames (gif).
   1173         SkASSERT(!frame);
   1174         srcOffset = options.fSubset->left();
   1175         srcWidth = options.fSubset->width();
   1176         dstWidth = srcWidth;
   1177     } else if (frame) {
   1178         dstOffset = frame->left();
   1179         srcWidth = frame->width();
   1180     }
   1181 
   1182     return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
   1183             srcBPP, dstBPP);
   1184 }
   1185 
   1186 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
   1187         int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
   1188     : fFastProc(fastProc)
   1189     , fSlowProc(proc)
   1190     , fActualProc(fFastProc ? fFastProc : fSlowProc)
   1191     , fColorTable(ctable)
   1192     , fSrcOffset(srcOffset)
   1193     , fDstOffset(dstOffset)
   1194     , fSrcOffsetUnits(srcOffset * srcBPP)
   1195     , fDstOffsetBytes(dstOffset * dstBPP)
   1196     , fSrcWidth(srcWidth)
   1197     , fDstWidth(dstWidth)
   1198     , fSwizzleWidth(srcWidth)
   1199     , fAllocatedWidth(dstWidth)
   1200     , fSampleX(1)
   1201     , fSrcBPP(srcBPP)
   1202     , fDstBPP(dstBPP)
   1203 {}
   1204 
   1205 int SkSwizzler::onSetSampleX(int sampleX) {
   1206     SkASSERT(sampleX > 0);
   1207 
   1208     fSampleX = sampleX;
   1209     fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
   1210     fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
   1211     fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
   1212     fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
   1213 
   1214     // The optimized swizzler functions do not support sampling.  Sampled swizzles
   1215     // are already fast because they skip pixels.  We haven't seen a situation
   1216     // where speeding up sampling has a significant impact on total decode time.
   1217     if (1 == fSampleX && fFastProc) {
   1218         fActualProc = fFastProc;
   1219     } else {
   1220         fActualProc = fSlowProc;
   1221     }
   1222 
   1223     return fAllocatedWidth;
   1224 }
   1225 
   1226 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
   1227     SkASSERT(nullptr != dst && nullptr != src);
   1228     fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
   1229             fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
   1230 }
   1231