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 "SkOpts.h"
     11 #include "SkSwizzler.h"
     12 #include "SkTemplates.h"
     13 
     14 static void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     15         const SkPMColor ctable[]) {
     16     // This function must not be called if we are sampling.  If we are not
     17     // sampling, deltaSrc should equal bpp.
     18     SkASSERT(deltaSrc == bpp);
     19 
     20     memcpy(dst, src + offset, width * bpp);
     21 }
     22 
     23 static void sample1(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     24         const SkPMColor ctable[]) {
     25     src += offset;
     26     uint8_t* dst8 = (uint8_t*) dst;
     27     for (int x = 0; x < width; x++) {
     28         dst8[x] = *src;
     29         src += deltaSrc;
     30     }
     31 }
     32 
     33 static void sample2(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     34         const SkPMColor ctable[]) {
     35     src += offset;
     36     uint16_t* dst16 = (uint16_t*) dst;
     37     for (int x = 0; x < width; x++) {
     38         dst16[x] = *((const uint16_t*) src);
     39         src += deltaSrc;
     40     }
     41 }
     42 
     43 static void sample4(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
     44         const SkPMColor ctable[]) {
     45     src += offset;
     46     uint32_t* dst32 = (uint32_t*) dst;
     47     for (int x = 0; x < width; x++) {
     48         dst32[x] = *((const uint32_t*) src);
     49         src += deltaSrc;
     50     }
     51 }
     52 
     53 // kBit
     54 // These routines exclusively choose between white and black
     55 
     56 #define GRAYSCALE_BLACK 0
     57 #define GRAYSCALE_WHITE 0xFF
     58 
     59 
     60 // same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
     61 static void swizzle_bit_to_grayscale(
     62         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
     63         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
     64 
     65     uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
     66 
     67     // increment src by byte offset and bitIndex by bit offset
     68     src += offset / 8;
     69     int bitIndex = offset % 8;
     70     uint8_t currByte = *src;
     71 
     72     dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
     73 
     74     for (int x = 1; x < dstWidth; x++) {
     75         int bitOffset = bitIndex + deltaSrc;
     76         bitIndex = bitOffset % 8;
     77         currByte = *(src += bitOffset / 8);
     78         dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
     79     }
     80 }
     81 
     82 #undef GRAYSCALE_BLACK
     83 #undef GRAYSCALE_WHITE
     84 
     85 // same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x]
     86 static void swizzle_bit_to_index(
     87         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
     88         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
     89     uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
     90 
     91     // increment src by byte offset and bitIndex by bit offset
     92     src += offset / 8;
     93     int bitIndex = offset % 8;
     94     uint8_t currByte = *src;
     95 
     96     dst[0] = ((currByte >> (7-bitIndex)) & 1);
     97 
     98     for (int x = 1; x < dstWidth; x++) {
     99         int bitOffset = bitIndex + deltaSrc;
    100         bitIndex = bitOffset % 8;
    101         currByte = *(src += bitOffset / 8);
    102         dst[x] = ((currByte >> (7-bitIndex)) & 1);
    103     }
    104 }
    105 
    106 // same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
    107 static void swizzle_bit_to_n32(
    108         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    109         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
    110     SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
    111 
    112     // increment src by byte offset and bitIndex by bit offset
    113     src += offset / 8;
    114     int bitIndex = offset % 8;
    115     uint8_t currByte = *src;
    116 
    117     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
    118 
    119     for (int x = 1; x < dstWidth; x++) {
    120         int bitOffset = bitIndex + deltaSrc;
    121         bitIndex = bitOffset % 8;
    122         currByte = *(src += bitOffset / 8);
    123         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
    124     }
    125 }
    126 
    127 #define RGB565_BLACK 0
    128 #define RGB565_WHITE 0xFFFF
    129 
    130 static void swizzle_bit_to_565(
    131         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    132         int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
    133     uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
    134 
    135     // increment src by byte offset and bitIndex by bit offset
    136     src += offset / 8;
    137     int bitIndex = offset % 8;
    138     uint8_t currByte = *src;
    139 
    140     dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
    141 
    142     for (int x = 1; x < dstWidth; x++) {
    143         int bitOffset = bitIndex + deltaSrc;
    144         bitIndex = bitOffset % 8;
    145         currByte = *(src += bitOffset / 8);
    146         dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? RGB565_WHITE : RGB565_BLACK;
    147     }
    148 }
    149 
    150 #undef RGB565_BLACK
    151 #undef RGB565_WHITE
    152 
    153 // kIndex1, kIndex2, kIndex4
    154 
    155 static void swizzle_small_index_to_index(
    156         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    157         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    158 
    159     uint8_t* dst = (uint8_t*) dstRow;
    160     src += offset / 8;
    161     int bitIndex = offset % 8;
    162     uint8_t currByte = *src;
    163     const uint8_t mask = (1 << bpp) - 1;
    164     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
    165     dst[0] = index;
    166 
    167     for (int x = 1; x < dstWidth; x++) {
    168         int bitOffset = bitIndex + deltaSrc;
    169         bitIndex = bitOffset % 8;
    170         currByte = *(src += bitOffset / 8);
    171         index = (currByte >> (8 - bpp - bitIndex)) & mask;
    172         dst[x] = index;
    173     }
    174 }
    175 
    176 static void swizzle_small_index_to_565(
    177         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    178         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    179 
    180     uint16_t* dst = (uint16_t*) dstRow;
    181     src += offset / 8;
    182     int bitIndex = offset % 8;
    183     uint8_t currByte = *src;
    184     const uint8_t mask = (1 << bpp) - 1;
    185     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
    186     dst[0] = SkPixel32ToPixel16(ctable[index]);
    187 
    188     for (int x = 1; x < dstWidth; x++) {
    189         int bitOffset = bitIndex + deltaSrc;
    190         bitIndex = bitOffset % 8;
    191         currByte = *(src += bitOffset / 8);
    192         index = (currByte >> (8 - bpp - bitIndex)) & mask;
    193         dst[x] = SkPixel32ToPixel16(ctable[index]);
    194     }
    195 }
    196 
    197 static void swizzle_small_index_to_n32(
    198         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    199         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    200 
    201     SkPMColor* dst = (SkPMColor*) dstRow;
    202     src += offset / 8;
    203     int bitIndex = offset % 8;
    204     uint8_t currByte = *src;
    205     const uint8_t mask = (1 << bpp) - 1;
    206     uint8_t index = (currByte >> (8 - bpp - bitIndex)) & mask;
    207     dst[0] = ctable[index];
    208 
    209     for (int x = 1; x < dstWidth; x++) {
    210         int bitOffset = bitIndex + deltaSrc;
    211         bitIndex = bitOffset % 8;
    212         currByte = *(src += bitOffset / 8);
    213         index = (currByte >> (8 - bpp - bitIndex)) & mask;
    214         dst[x] = ctable[index];
    215     }
    216 }
    217 
    218 // kIndex
    219 
    220 static void swizzle_index_to_n32(
    221         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    222         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    223 
    224     src += offset;
    225     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    226     for (int x = 0; x < dstWidth; x++) {
    227         SkPMColor c = ctable[*src];
    228         dst[x] = c;
    229         src += deltaSrc;
    230     }
    231 }
    232 
    233 static void swizzle_index_to_n32_skipZ(
    234         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    235         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    236 
    237     src += offset;
    238     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    239     for (int x = 0; x < dstWidth; x++) {
    240         SkPMColor c = ctable[*src];
    241         if (c != 0) {
    242             dst[x] = c;
    243         }
    244         src += deltaSrc;
    245     }
    246 }
    247 
    248 static void swizzle_index_to_565(
    249       void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    250       int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    251     src += offset;
    252     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    253     for (int x = 0; x < dstWidth; x++) {
    254         dst[x] = SkPixel32ToPixel16(ctable[*src]);
    255         src += deltaSrc;
    256     }
    257 }
    258 
    259 // kGray
    260 
    261 static void swizzle_gray_to_n32(
    262         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    263         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    264 
    265     src += offset;
    266     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    267     for (int x = 0; x < dstWidth; x++) {
    268         dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
    269         src += deltaSrc;
    270     }
    271 }
    272 
    273 static void fast_swizzle_gray_to_n32(
    274         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    275         const SkPMColor ctable[]) {
    276 
    277     // This function must not be called if we are sampling.  If we are not
    278     // sampling, deltaSrc should equal bpp.
    279     SkASSERT(deltaSrc == bpp);
    280 
    281     // Note that there is no need to distinguish between RGB and BGR.
    282     // Each color channel will get the same value.
    283     SkOpts::gray_to_RGB1((uint32_t*) dst, src + offset, width);
    284 }
    285 
    286 static void swizzle_gray_to_565(
    287         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    288         int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    289 
    290     src += offset;
    291     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    292     for (int x = 0; x < dstWidth; x++) {
    293         dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
    294         src += deltaSrc;
    295     }
    296 }
    297 
    298 // kGrayAlpha
    299 
    300 static void swizzle_grayalpha_to_n32_unpremul(
    301         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    302         const SkPMColor ctable[]) {
    303 
    304     src += offset;
    305     SkPMColor* dst32 = (SkPMColor*) dst;
    306     for (int x = 0; x < width; x++) {
    307         dst32[x] = SkPackARGB32NoCheck(src[1], src[0], src[0], src[0]);
    308         src += deltaSrc;
    309     }
    310 }
    311 
    312 static void fast_swizzle_grayalpha_to_n32_unpremul(
    313         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    314         const SkPMColor ctable[]) {
    315 
    316     // This function must not be called if we are sampling.  If we are not
    317     // sampling, deltaSrc should equal bpp.
    318     SkASSERT(deltaSrc == bpp);
    319 
    320     // Note that there is no need to distinguish between RGB and BGR.
    321     // Each color channel will get the same value.
    322     SkOpts::grayA_to_RGBA((uint32_t*) dst, src + offset, width);
    323 }
    324 
    325 static void swizzle_grayalpha_to_n32_premul(
    326         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    327         const SkPMColor ctable[]) {
    328 
    329     src += offset;
    330     SkPMColor* dst32 = (SkPMColor*) dst;
    331     for (int x = 0; x < width; x++) {
    332         uint8_t pmgray = SkMulDiv255Round(src[1], src[0]);
    333         dst32[x] = SkPackARGB32NoCheck(src[1], pmgray, pmgray, pmgray);
    334         src += deltaSrc;
    335     }
    336 }
    337 
    338 static void fast_swizzle_grayalpha_to_n32_premul(
    339         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    340         const SkPMColor ctable[]) {
    341 
    342     // This function must not be called if we are sampling.  If we are not
    343     // sampling, deltaSrc should equal bpp.
    344     SkASSERT(deltaSrc == bpp);
    345 
    346     // Note that there is no need to distinguish between rgb and bgr.
    347     // Each color channel will get the same value.
    348     SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
    349 }
    350 
    351 // kBGRX
    352 
    353 static void swizzle_bgrx_to_n32(
    354         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    355         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    356 
    357     src += offset;
    358     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    359     for (int x = 0; x < dstWidth; x++) {
    360         dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
    361         src += deltaSrc;
    362     }
    363 }
    364 
    365 static void swizzle_bgrx_to_565(
    366         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    367         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    368 
    369     src += offset;
    370     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    371     for (int x = 0; x < dstWidth; x++) {
    372         dst[x] = SkPack888ToRGB16(src[2], src[1], src[0]);
    373         src += deltaSrc;
    374     }
    375 }
    376 
    377 // kBGRA
    378 
    379 static void swizzle_bgra_to_n32_unpremul(
    380         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    381         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    382 
    383     src += offset;
    384     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    385     for (int x = 0; x < dstWidth; x++) {
    386         uint8_t alpha = src[3];
    387         dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
    388         src += deltaSrc;
    389     }
    390 }
    391 
    392 static void fast_swizzle_bgra_to_n32_unpremul(
    393         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    394         const SkPMColor ctable[]) {
    395 
    396     // This function must not be called if we are sampling.  If we are not
    397     // sampling, deltaSrc should equal bpp.
    398     SkASSERT(deltaSrc == bpp);
    399 
    400 #ifdef SK_PMCOLOR_IS_RGBA
    401     SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
    402 #else
    403     memcpy(dst, src + offset, width * bpp);
    404 #endif
    405 }
    406 
    407 static void swizzle_bgra_to_n32_premul(
    408         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    409         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    410 
    411     src += offset;
    412     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    413     for (int x = 0; x < dstWidth; x++) {
    414         uint8_t alpha = src[3];
    415         dst[x] = SkPremultiplyARGBInline(alpha, src[2], src[1], src[0]);
    416         src += deltaSrc;
    417     }
    418 }
    419 
    420 static void fast_swizzle_bgra_to_n32_premul(
    421         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    422         const SkPMColor ctable[]) {
    423 
    424     // This function must not be called if we are sampling.  If we are not
    425     // sampling, deltaSrc should equal bpp.
    426     SkASSERT(deltaSrc == bpp);
    427 
    428 #ifdef SK_PMCOLOR_IS_RGBA
    429     SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
    430 #else
    431     SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
    432 #endif
    433 }
    434 
    435 // kRGB
    436 
    437 static void swizzle_rgb_to_n32(
    438         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    439         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    440 
    441     src += offset;
    442     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    443     for (int x = 0; x < dstWidth; x++) {
    444         dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[1], src[2]);
    445         src += deltaSrc;
    446     }
    447 }
    448 
    449 static void fast_swizzle_rgb_to_n32(
    450         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    451         int offset, const SkPMColor ctable[]) {
    452 
    453     // This function must not be called if we are sampling.  If we are not
    454     // sampling, deltaSrc should equal bpp.
    455     SkASSERT(deltaSrc == bpp);
    456 
    457 #ifdef SK_PMCOLOR_IS_RGBA
    458     SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
    459 #else
    460     SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
    461 #endif
    462 }
    463 
    464 static void swizzle_rgb_to_565(
    465        void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    466        int bytesPerPixel, int deltaSrc, int offset, const SkPMColor ctable[]) {
    467 
    468     src += offset;
    469     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    470     for (int x = 0; x < dstWidth; x++) {
    471         dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
    472         src += deltaSrc;
    473     }
    474 }
    475 
    476 // kRGBA
    477 
    478 static void swizzle_rgba_to_n32_premul(
    479         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    480         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    481 
    482     src += offset;
    483     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    484     for (int x = 0; x < dstWidth; x++) {
    485         unsigned alpha = src[3];
    486         dst[x] = SkPremultiplyARGBInline(alpha, src[0], src[1], src[2]);
    487         src += deltaSrc;
    488     }
    489 }
    490 
    491 static void fast_swizzle_rgba_to_n32_premul(
    492         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
    493         int offset, const SkPMColor ctable[]) {
    494 
    495     // This function must not be called if we are sampling.  If we are not
    496     // sampling, deltaSrc should equal bpp.
    497     SkASSERT(deltaSrc == bpp);
    498 
    499 #ifdef SK_PMCOLOR_IS_RGBA
    500     SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
    501 #else
    502     SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
    503 #endif
    504 }
    505 
    506 static void swizzle_rgba_to_n32_unpremul(
    507         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    508         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    509 
    510     src += offset;
    511     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
    512     for (int x = 0; x < dstWidth; x++) {
    513         unsigned alpha = src[3];
    514         dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
    515         src += deltaSrc;
    516     }
    517 }
    518 
    519 static void fast_swizzle_rgba_to_n32_unpremul(
    520         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    521         const SkPMColor ctable[]) {
    522 
    523     // This function must not be called if we are sampling.  If we are not
    524     // sampling, deltaSrc should equal bpp.
    525     SkASSERT(deltaSrc == bpp);
    526 
    527 #ifdef SK_PMCOLOR_IS_RGBA
    528     memcpy(dst, src + offset, width * bpp);
    529 #else
    530     SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
    531 #endif
    532 }
    533 
    534 // kCMYK
    535 //
    536 // CMYK is stored as four bytes per pixel.
    537 //
    538 // We will implement a crude conversion from CMYK -> RGB using formulas
    539 // from easyrgb.com.
    540 //
    541 // CMYK -> CMY
    542 // C = C * (1 - K) + K
    543 // M = M * (1 - K) + K
    544 // Y = Y * (1 - K) + K
    545 //
    546 // libjpeg actually gives us inverted CMYK, so we must subtract the
    547 // original terms from 1.
    548 // CMYK -> CMY
    549 // C = (1 - C) * (1 - (1 - K)) + (1 - K)
    550 // M = (1 - M) * (1 - (1 - K)) + (1 - K)
    551 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
    552 //
    553 // Simplifying the above expression.
    554 // CMYK -> CMY
    555 // C = 1 - CK
    556 // M = 1 - MK
    557 // Y = 1 - YK
    558 //
    559 // CMY -> RGB
    560 // R = (1 - C) * 255
    561 // G = (1 - M) * 255
    562 // B = (1 - Y) * 255
    563 //
    564 // Therefore the full conversion is below.  This can be verified at
    565 // www.rapidtables.com (assuming inverted CMYK).
    566 // CMYK -> RGB
    567 // R = C * K * 255
    568 // G = M * K * 255
    569 // B = Y * K * 255
    570 //
    571 // As a final note, we have treated the CMYK values as if they were on
    572 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
    573 // We must divide each CMYK component by 255 to obtain the true conversion
    574 // we should perform.
    575 // CMYK -> RGB
    576 // R = C * K / 255
    577 // G = M * K / 255
    578 // B = Y * K / 255
    579 static void swizzle_cmyk_to_n32(
    580         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    581         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    582 
    583     src += offset;
    584     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
    585     for (int x = 0; x < dstWidth; x++) {
    586         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    587         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    588         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    589 
    590         dst[x] = SkPackARGB32NoCheck(0xFF, r, g, b);
    591         src += deltaSrc;
    592     }
    593 }
    594 
    595 static void fast_swizzle_cmyk_to_n32(
    596         void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
    597         const SkPMColor ctable[]) {
    598 
    599     // This function must not be called if we are sampling.  If we are not
    600     // sampling, deltaSrc should equal bpp.
    601     SkASSERT(deltaSrc == bpp);
    602 
    603 #ifdef SK_PMCOLOR_IS_RGBA
    604     SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width);
    605 #else
    606     SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
    607 #endif
    608 }
    609 
    610 static void swizzle_cmyk_to_565(
    611         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    612         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    613 
    614     src += offset;
    615     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
    616     for (int x = 0; x < dstWidth; x++) {
    617         const uint8_t r = SkMulDiv255Round(src[0], src[3]);
    618         const uint8_t g = SkMulDiv255Round(src[1], src[3]);
    619         const uint8_t b = SkMulDiv255Round(src[2], src[3]);
    620 
    621         dst[x] = SkPack888ToRGB16(r, g, b);
    622         src += deltaSrc;
    623     }
    624 }
    625 
    626 template <SkSwizzler::RowProc proc>
    627 void SkSwizzler::SkipLeadingGrayAlphaZerosThen(
    628         void* dst, const uint8_t* src, int width,
    629         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    630     SkASSERT(!ctable);
    631 
    632     const uint16_t* src16 = (const uint16_t*) (src + offset);
    633     uint32_t* dst32 = (uint32_t*) dst;
    634 
    635     // This may miss opportunities to skip when the output is premultiplied,
    636     // e.g. for a src pixel 0x00FF which is not zero but becomes zero after premultiplication.
    637     while (width > 0 && *src16 == 0x0000) {
    638         width--;
    639         dst32++;
    640         src16 += deltaSrc / 2;
    641     }
    642     proc(dst32, (const uint8_t*)src16, width, bpp, deltaSrc, 0, ctable);
    643 }
    644 
    645 template <SkSwizzler::RowProc proc>
    646 void SkSwizzler::SkipLeading8888ZerosThen(
    647         void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
    648         int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
    649     SkASSERT(!ctable);
    650 
    651     auto src32 = (const uint32_t*)(src+offset);
    652     auto dst32 = (uint32_t*)dstRow;
    653 
    654     // This may miss opportunities to skip when the output is premultiplied,
    655     // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after premultiplication.
    656     while (dstWidth > 0 && *src32 == 0x00000000) {
    657         dstWidth--;
    658         dst32++;
    659         src32 += deltaSrc/4;
    660     }
    661     proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
    662 }
    663 
    664 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
    665                                        const SkPMColor* ctable,
    666                                        const SkImageInfo& dstInfo,
    667                                        const SkCodec::Options& options,
    668                                        const SkIRect* frame) {
    669     if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
    670         return nullptr;
    671     }
    672     if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
    673             && nullptr == ctable) {
    674         return nullptr;
    675     }
    676     RowProc fastProc = nullptr;
    677     RowProc proc = nullptr;
    678     SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
    679     switch (sc) {
    680         case kBit:
    681             switch (dstInfo.colorType()) {
    682                 case kN32_SkColorType:
    683                     proc = &swizzle_bit_to_n32;
    684                     break;
    685                 case kIndex_8_SkColorType:
    686                     proc = &swizzle_bit_to_index;
    687                     break;
    688                 case kRGB_565_SkColorType:
    689                     proc = &swizzle_bit_to_565;
    690                     break;
    691                 case kGray_8_SkColorType:
    692                     proc = &swizzle_bit_to_grayscale;
    693                     break;
    694                 default:
    695                     break;
    696             }
    697             break;
    698         case kIndex1:
    699         case kIndex2:
    700         case kIndex4:
    701             switch (dstInfo.colorType()) {
    702                 case kN32_SkColorType:
    703                     proc = &swizzle_small_index_to_n32;
    704                     break;
    705                 case kRGB_565_SkColorType:
    706                     proc = &swizzle_small_index_to_565;
    707                     break;
    708                 case kIndex_8_SkColorType:
    709                     proc = &swizzle_small_index_to_index;
    710                     break;
    711                 default:
    712                     break;
    713             }
    714             break;
    715         case kIndex:
    716             switch (dstInfo.colorType()) {
    717                 case kN32_SkColorType:
    718                     // We assume the color premultiplied ctable (or not) as desired.
    719                     if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    720                         proc = &swizzle_index_to_n32_skipZ;
    721                         break;
    722                     } else {
    723                         proc = &swizzle_index_to_n32;
    724                         break;
    725                     }
    726                     break;
    727                 case kRGB_565_SkColorType:
    728                     proc = &swizzle_index_to_565;
    729                     break;
    730                 case kIndex_8_SkColorType:
    731                     proc = &sample1;
    732                     fastProc = &copy;
    733                     break;
    734                 default:
    735                     break;
    736             }
    737             break;
    738         case kGray:
    739             switch (dstInfo.colorType()) {
    740                 case kN32_SkColorType:
    741                     proc = &swizzle_gray_to_n32;
    742                     fastProc = &fast_swizzle_gray_to_n32;
    743                     break;
    744                 case kGray_8_SkColorType:
    745                     proc = &sample1;
    746                     fastProc = &copy;
    747                     break;
    748                 case kRGB_565_SkColorType:
    749                     proc = &swizzle_gray_to_565;
    750                     break;
    751                 default:
    752                     break;
    753             }
    754             break;
    755         case kGrayAlpha:
    756             switch (dstInfo.colorType()) {
    757                 case kN32_SkColorType:
    758                     if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
    759                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    760                             proc = &SkipLeadingGrayAlphaZerosThen
    761                                     <swizzle_grayalpha_to_n32_unpremul>;
    762                             fastProc = &SkipLeadingGrayAlphaZerosThen
    763                                     <fast_swizzle_grayalpha_to_n32_unpremul>;
    764                         } else {
    765                             proc = &swizzle_grayalpha_to_n32_unpremul;
    766                             fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
    767                         }
    768                     } else {
    769                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    770                             proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>;
    771                             fastProc = &SkipLeadingGrayAlphaZerosThen
    772                                     <fast_swizzle_grayalpha_to_n32_premul>;
    773                         } else {
    774                             proc = &swizzle_grayalpha_to_n32_premul;
    775                             fastProc = &fast_swizzle_grayalpha_to_n32_premul;
    776                         }
    777                     }
    778                     break;
    779                 default:
    780                     break;
    781             }
    782             break;
    783         case kBGR:
    784         case kBGRX:
    785             switch (dstInfo.colorType()) {
    786                 case kN32_SkColorType:
    787                     proc = &swizzle_bgrx_to_n32;
    788                     break;
    789                 case kRGB_565_SkColorType:
    790                     proc = &swizzle_bgrx_to_565;
    791                     break;
    792                 default:
    793                     break;
    794             }
    795             break;
    796         case kBGRA:
    797             switch (dstInfo.colorType()) {
    798                 case kN32_SkColorType:
    799                     if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
    800                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    801                             proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_unpremul>;
    802                             fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_unpremul>;
    803                         } else {
    804                             proc = &swizzle_bgra_to_n32_unpremul;
    805                             fastProc = &fast_swizzle_bgra_to_n32_unpremul;
    806                         }
    807                     } else {
    808                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    809                             proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>;
    810                             fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>;
    811                         } else {
    812                             proc = &swizzle_bgra_to_n32_premul;
    813                             fastProc = &fast_swizzle_bgra_to_n32_premul;
    814                         }
    815                     }
    816                     break;
    817                 default:
    818                     break;
    819             }
    820             break;
    821         case kRGB:
    822             switch (dstInfo.colorType()) {
    823                 case kN32_SkColorType:
    824                     proc = &swizzle_rgb_to_n32;
    825                     fastProc = &fast_swizzle_rgb_to_n32;
    826                     break;
    827                 case kRGB_565_SkColorType:
    828                     proc = &swizzle_rgb_to_565;
    829                     break;
    830                 default:
    831                     break;
    832             }
    833             break;
    834         case kRGBA:
    835             switch (dstInfo.colorType()) {
    836                 case kN32_SkColorType:
    837                     if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
    838                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    839                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>;
    840                             fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_unpremul>;
    841                         } else {
    842                             proc = &swizzle_rgba_to_n32_unpremul;
    843                             fastProc = &fast_swizzle_rgba_to_n32_unpremul;
    844                         }
    845                     } else {
    846                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
    847                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>;
    848                             fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>;
    849                         } else {
    850                             proc = &swizzle_rgba_to_n32_premul;
    851                             fastProc = &fast_swizzle_rgba_to_n32_premul;
    852                         }
    853                     }
    854                     break;
    855                 default:
    856                     break;
    857             }
    858             break;
    859         case kCMYK:
    860             switch (dstInfo.colorType()) {
    861                 case kN32_SkColorType:
    862                     proc = &swizzle_cmyk_to_n32;
    863                     fastProc = &fast_swizzle_cmyk_to_n32;
    864                     break;
    865                 case kRGB_565_SkColorType:
    866                     proc = &swizzle_cmyk_to_565;
    867                     break;
    868                 default:
    869                     break;
    870             }
    871             break;
    872         case kNoOp8:
    873             proc = &sample1;
    874             fastProc = &copy;
    875             break;
    876         case kNoOp16:
    877             proc = sample2;
    878             fastProc = &copy;
    879             break;
    880         case kNoOp32:
    881             proc = &sample4;
    882             fastProc = &copy;
    883             break;
    884         default:
    885             break;
    886     }
    887 
    888     // Store bpp in bytes if it is an even multiple, otherwise use bits
    889     int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
    890     int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
    891 
    892     int srcOffset = 0;
    893     int srcWidth = dstInfo.width();
    894     int dstOffset = 0;
    895     int dstWidth = srcWidth;
    896     if (options.fSubset) {
    897         // We do not currently support subset decodes for image types that may have
    898         // frames (gif).
    899         SkASSERT(!frame);
    900         srcOffset = options.fSubset->left();
    901         srcWidth = options.fSubset->width();
    902         dstWidth = srcWidth;
    903     } else if (frame) {
    904         dstOffset = frame->left();
    905         srcWidth = frame->width();
    906     }
    907 
    908     return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth,
    909             srcBPP, dstBPP);
    910 }
    911 
    912 SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
    913         int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP)
    914     : fFastProc(fastProc)
    915     , fSlowProc(proc)
    916     , fActualProc(fFastProc ? fFastProc : fSlowProc)
    917     , fColorTable(ctable)
    918     , fSrcOffset(srcOffset)
    919     , fDstOffset(dstOffset)
    920     , fSrcOffsetUnits(srcOffset * srcBPP)
    921     , fDstOffsetBytes(dstOffset * dstBPP)
    922     , fSrcWidth(srcWidth)
    923     , fDstWidth(dstWidth)
    924     , fSwizzleWidth(srcWidth)
    925     , fAllocatedWidth(dstWidth)
    926     , fSampleX(1)
    927     , fSrcBPP(srcBPP)
    928     , fDstBPP(dstBPP)
    929 {}
    930 
    931 int SkSwizzler::onSetSampleX(int sampleX) {
    932     SkASSERT(sampleX > 0);
    933 
    934     fSampleX = sampleX;
    935     fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
    936     fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
    937     fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
    938     fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
    939 
    940     // The optimized swizzler functions do not support sampling.  Sampled swizzles
    941     // are already fast because they skip pixels.  We haven't seen a situation
    942     // where speeding up sampling has a significant impact on total decode time.
    943     if (1 == fSampleX && fFastProc) {
    944         fActualProc = fFastProc;
    945     } else {
    946         fActualProc = fSlowProc;
    947     }
    948 
    949     return fAllocatedWidth;
    950 }
    951 
    952 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
    953     SkASSERT(nullptr != dst && nullptr != src);
    954     fActualProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
    955             fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
    956 }
    957