Use SkEncodedInfo in place of SkSwizzler::SrcConfig

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1911613002

Review URL: https://codereview.chromium.org/1911613002
diff --git a/include/codec/SkEncodedInfo.h b/include/codec/SkEncodedInfo.h
index 807eeee..60bfdc5 100644
--- a/include/codec/SkEncodedInfo.h
+++ b/include/codec/SkEncodedInfo.h
@@ -69,6 +69,10 @@
         kInvertedCMYK_Color,
         kYCCK_Color,
 
+        // Used internally to indicate that the decoding library has
+        // pre-swizzled to the desired output format.
+        kPreSwizzled_Color,
+
         // Allows us to have a default constructor.  Should be treated as
         // invalid.
         kUnknown_Color,
@@ -162,6 +166,35 @@
         }
     }
 
+    Color color() const { return fColor; }
+    Alpha alpha() const { return fAlpha; }
+    uint8_t bitsPerComponent() const { return fBitsPerComponent; }
+
+    uint8_t bitsPerPixel() const {
+        switch (fColor) {
+            case kGray_Color:
+                return fBitsPerComponent;
+            case kGrayAlpha_Color:
+                return 2 * fBitsPerComponent;
+            case kPalette_Color:
+                return fBitsPerComponent;
+            case kRGB_Color:
+            case kBGR_Color:
+            case kYUV_Color:
+                return 3 * fBitsPerComponent;
+            case kRGBA_Color:
+            case kBGRA_Color:
+            case kBGRX_Color:
+            case kYUVA_Color:
+            case kInvertedCMYK_Color:
+            case kYCCK_Color:
+                return 4 * fBitsPerComponent;
+            default:
+                SkASSERT(false);
+                return 0;
+        }
+    }
+
     SkEncodedInfo()
         : fColor(kUnknown_Color)
         , fAlpha(kUnknown_Alpha)
@@ -176,9 +209,15 @@
         , fBitsPerComponent(bitsPerComponent)
     {}
 
+    void setColor(Color color) {
+        fColor = color;
+    }
+
     Color   fColor;
     Alpha   fAlpha;
     uint8_t fBitsPerComponent;
+
+    friend class SkJpegCodec;
 };
 
 #endif
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index a509c75..b2d8fc9 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -153,40 +153,20 @@
 }
 
 void SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) {
-    // Get swizzler configuration
-    SkSwizzler::SrcConfig config = SkSwizzler::kUnknown;
-    switch (this->bitsPerPixel()) {
-        case 1:
-            config = SkSwizzler::kIndex1;
-            break;
-        case 2:
-            config = SkSwizzler::kIndex2;
-            break;
-        case 4:
-            config = SkSwizzler::kIndex4;
-            break;
-        case 8:
-            config = SkSwizzler::kIndex;
-            break;
-        case 24:
-            config = SkSwizzler::kBGR;
-            break;
-        case 32:
-            if (fIsOpaque) {
-                config = SkSwizzler::kBGRX;
-            } else {
-                config = SkSwizzler::kBGRA;
-            }
-            break;
-        default:
-            SkASSERT(false);
+    // In the case of paletted ico-in-bmps, we will report BGRA to the client,
+    // since we may be required to apply an alpha mask after the decode.  But
+    // the swizzler needs to know the actual format of the bmp.
+    SkEncodedInfo swizzlerInfo = this->getEncodedInfo();
+    if (fInIco && this->bitsPerPixel() <= 8) {
+        swizzlerInfo = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color, swizzlerInfo.alpha(),
+                this->bitsPerPixel());
     }
 
     // Get a pointer to the color table if it exists
     const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
 
     // Create swizzler
-    fSwizzler.reset(SkSwizzler::CreateSwizzler(config, colorPtr, dstInfo, opts));
+    fSwizzler.reset(SkSwizzler::CreateSwizzler(swizzlerInfo, colorPtr, dstInfo, opts));
     SkASSERT(fSwizzler);
 }
 
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index cdd9d08..774131f 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -464,7 +464,7 @@
 void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) {
     const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
     const SkIRect* frameRect = fFrameIsSubset ? &fFrameRect : nullptr;
-    fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dstInfo, opts,
+    fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colorPtr, dstInfo, opts,
             frameRect));
     SkASSERT(fSwizzler);
 }
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 88b7fcb..8d32f2b 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -510,30 +510,19 @@
 }
 
 void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
-    SkSwizzler::SrcConfig srcConfig = SkSwizzler::kUnknown;
-    if (JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) {
-        srcConfig = SkSwizzler::kCMYK;
-    } else {
-        // If the out_color_space is not CMYK, the only reason we would need a swizzler is
-        // for sampling and/or subsetting.
-        switch (dstInfo.colorType()) {
-            case kGray_8_SkColorType:
-                srcConfig = SkSwizzler::kNoOp8;
-                break;
-            case kN32_SkColorType:
-                srcConfig = SkSwizzler::kNoOp32;
-                break;
-            case kRGB_565_SkColorType:
-                srcConfig = SkSwizzler::kNoOp16;
-                break;
-            default:
-                // This function should only be called if the colorType is supported by jpeg
-                SkASSERT(false);
-        }
-    }
-
-    if (JCS_RGB == fDecoderMgr->dinfo()->out_color_space) {
-        srcConfig = SkSwizzler::kRGB;
+    // libjpeg-turbo may have already performed color conversion.  We must indicate the
+    // appropriate format to the swizzler.
+    SkEncodedInfo swizzlerInfo = this->getEncodedInfo();
+    switch (fDecoderMgr->dinfo()->out_color_space) {
+        case JCS_RGB:
+            swizzlerInfo.setColor(SkEncodedInfo::kRGB_Color);
+            break;
+        case JCS_CMYK:
+            swizzlerInfo.setColor(SkEncodedInfo::kInvertedCMYK_Color);
+            break;
+        default:
+            swizzlerInfo.setColor(SkEncodedInfo::kPreSwizzled_Color);
+            break;
     }
 
     Options swizzlerOptions = options;
@@ -545,7 +534,7 @@
                 fSwizzlerSubset.width() == options.fSubset->width());
         swizzlerOptions.fSubset = &fSwizzlerSubset;
     }
-    fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, swizzlerOptions));
+    fSwizzler.reset(SkSwizzler::CreateSwizzler(swizzlerInfo, nullptr, dstInfo, swizzlerOptions));
     SkASSERT(fSwizzler);
     fStorage.reset(get_row_bytes(fDecoderMgr->dinfo()));
     fSrcRow = fStorage.get();
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 33c3b60..240902d 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -439,7 +439,6 @@
     , fPngChunkReader(SkSafeRef(chunkReader))
     , fPng_ptr(png_ptr)
     , fInfo_ptr(info_ptr)
-    , fSrcConfig(SkSwizzler::kUnknown)
     , fNumberPasses(numberPasses)
     , fBitDepth(bitDepth)
 {}
@@ -474,45 +473,10 @@
     }
     png_read_update_info(fPng_ptr, fInfo_ptr);
 
-    // suggestedColorType was determined in read_header() based on the encodedColorType
-    const SkColorType suggestedColorType = this->getInfo().colorType();
-
-    switch (suggestedColorType) {
-        case kIndex_8_SkColorType:
-            //decode palette to Skia format
-            fSrcConfig = SkSwizzler::kIndex;
-            if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(),
-                    ctableCount)) {
-                return kInvalidInput;
-            }
-            break;
-        case kGray_8_SkColorType:
-            fSrcConfig = SkSwizzler::kGray;
-            break;
-        case kN32_SkColorType: {
-            const uint8_t encodedColorType = png_get_color_type(fPng_ptr, fInfo_ptr);
-            if (PNG_COLOR_TYPE_GRAY_ALPHA == encodedColorType ||
-                    PNG_COLOR_TYPE_GRAY == encodedColorType) {
-                // If encodedColorType is GRAY, there must be a transparent chunk.
-                // Otherwise, suggestedColorType would be kGray.  We have already
-                // instructed libpng to convert the transparent chunk to alpha,
-                // so we can treat both GRAY and GRAY_ALPHA as kGrayAlpha.
-                SkASSERT(encodedColorType == PNG_COLOR_TYPE_GRAY_ALPHA ||
-                        png_get_valid(fPng_ptr, fInfo_ptr, PNG_INFO_tRNS));
-
-                fSrcConfig = SkSwizzler::kGrayAlpha;
-            } else {
-                if (this->getInfo().alphaType() == kOpaque_SkAlphaType) {
-                    fSrcConfig = SkSwizzler::kRGB;
-                } else {
-                    fSrcConfig = SkSwizzler::kRGBA;
-                }
-            }
-            break;
+    if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) {
+        if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(), ctableCount)) {
+            return kInvalidInput;
         }
-        default:
-            // We will always recommend one of the above colorTypes.
-            SkASSERT(false);
     }
 
     // Copy the color table to the client if they request kIndex8 mode
@@ -520,7 +484,8 @@
 
     // Create the swizzler.  SkPngCodec retains ownership of the color table.
     const SkPMColor* colors = get_color_ptr(fColorTable.get());
-    fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo, options));
+    fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, requestedInfo,
+            options));
     SkASSERT(fSwizzler);
 
     return kSuccess;
@@ -547,6 +512,12 @@
     return true;
 }
 
+static int bytes_per_pixel(int bitsPerPixel) {
+    // Note that we will have to change this implementation if we start
+    // supporting outputs from libpng that are less than 8-bits per component.
+    return bitsPerPixel / 8;
+}
+
 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst,
                                         size_t dstRowBytes, const Options& options,
                                         SkPMColor ctable[], int* ctableCount,
@@ -567,7 +538,7 @@
 
     const int width = requestedInfo.width();
     const int height = requestedInfo.height();
-    const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig);
+    const int bpp = bytes_per_pixel(this->getEncodedInfo().bitsPerPixel());
     const size_t srcRowBytes = width * bpp;
 
     // FIXME: Could we use the return value of setjmp to specify the type of
@@ -664,7 +635,8 @@
             return result;
         }
 
-        fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(this->srcConfig()));
+        fStorage.reset(this->getInfo().width() *
+                (bytes_per_pixel(this->getEncodedInfo().bitsPerPixel())));
         fSrcRow = fStorage.get();
 
         return kSuccess;
@@ -736,7 +708,8 @@
 
         fHeight = dstInfo.height();
         // FIXME: This need not be called on a second call to onStartScanlineDecode.
-        fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(this->srcConfig());
+        fSrcRowBytes = this->getInfo().width() *
+                (bytes_per_pixel(this->getEncodedInfo().bitsPerPixel()));
         fGarbageRow.reset(fSrcRowBytes);
         fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get());
         fCanSkipRewind = true;
diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h
index 8587bf8..934513a 100644
--- a/src/codec/SkPngCodec.h
+++ b/src/codec/SkPngCodec.h
@@ -46,7 +46,6 @@
 
     png_structp png_ptr() { return fPng_ptr; }
     SkSwizzler* swizzler() { return fSwizzler; }
-    SkSwizzler::SrcConfig srcConfig() const { return fSrcConfig; }
     int numberPasses() const { return fNumberPasses; }
 
 private:
@@ -58,7 +57,6 @@
     SkAutoTUnref<SkColorTable>      fColorTable;    // May be unpremul.
     SkAutoTDelete<SkSwizzler>       fSwizzler;
 
-    SkSwizzler::SrcConfig           fSrcConfig;
     const int                       fNumberPasses;
     int                             fBitDepth;
 
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index 51de2fc..dc638e6 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -688,7 +688,7 @@
     }
 
     SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(
-            SkSwizzler::kRGB, nullptr, requestedInfo, options));
+            this->getEncodedInfo(), nullptr, requestedInfo, options));
     SkASSERT(swizzler);
 
     const int width = requestedInfo.width();
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
index 1337368..a4b3028 100644
--- a/src/codec/SkSwizzler.cpp
+++ b/src/codec/SkSwizzler.cpp
@@ -661,101 +661,75 @@
     proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable);
 }
 
-SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
+SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
                                        const SkPMColor* ctable,
                                        const SkImageInfo& dstInfo,
                                        const SkCodec::Options& options,
                                        const SkIRect* frame) {
-    if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
+    if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) {
         return nullptr;
     }
-    if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
-            && nullptr == ctable) {
-        return nullptr;
-    }
+
     RowProc fastProc = nullptr;
     RowProc proc = nullptr;
     SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
-    switch (sc) {
-        case kBit:
-            switch (dstInfo.colorType()) {
-                case kN32_SkColorType:
-                    proc = &swizzle_bit_to_n32;
-                    break;
-                case kIndex_8_SkColorType:
-                    proc = &swizzle_bit_to_index;
-                    break;
-                case kRGB_565_SkColorType:
-                    proc = &swizzle_bit_to_565;
-                    break;
-                case kGray_8_SkColorType:
-                    proc = &swizzle_bit_to_grayscale;
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case kIndex1:
-        case kIndex2:
-        case kIndex4:
-            switch (dstInfo.colorType()) {
-                case kN32_SkColorType:
-                    proc = &swizzle_small_index_to_n32;
-                    break;
-                case kRGB_565_SkColorType:
-                    proc = &swizzle_small_index_to_565;
-                    break;
-                case kIndex_8_SkColorType:
-                    proc = &swizzle_small_index_to_index;
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case kIndex:
-            switch (dstInfo.colorType()) {
-                case kN32_SkColorType:
-                    // We assume the color premultiplied ctable (or not) as desired.
-                    if (SkCodec::kYes_ZeroInitialized == zeroInit) {
-                        proc = &swizzle_index_to_n32_skipZ;
-                        break;
-                    } else {
-                        proc = &swizzle_index_to_n32;
-                        break;
+    const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) &&
+            (kPremul_SkAlphaType == dstInfo.alphaType());
+    switch (encodedInfo.color()) {
+        case SkEncodedInfo::kGray_Color:
+            switch (encodedInfo.bitsPerComponent()) {
+                case 1:
+                    switch (dstInfo.colorType()) {
+                        case kN32_SkColorType:
+                            proc = &swizzle_bit_to_n32;
+                            break;
+                        case kIndex_8_SkColorType:
+                            proc = &swizzle_bit_to_index;
+                            break;
+                        case kRGB_565_SkColorType:
+                            proc = &swizzle_bit_to_565;
+                            break;
+                        case kGray_8_SkColorType:
+                            proc = &swizzle_bit_to_grayscale;
+                            break;
+                        default:
+                            return nullptr;
                     }
                     break;
-                case kRGB_565_SkColorType:
-                    proc = &swizzle_index_to_565;
-                    break;
-                case kIndex_8_SkColorType:
-                    proc = &sample1;
-                    fastProc = &copy;
+                case 8:
+                    switch (dstInfo.colorType()) {
+                        case kN32_SkColorType:
+                            proc = &swizzle_gray_to_n32;
+                            fastProc = &fast_swizzle_gray_to_n32;
+                            break;
+                        case kGray_8_SkColorType:
+                            proc = &sample1;
+                            fastProc = &copy;
+                            break;
+                        case kRGB_565_SkColorType:
+                            proc = &swizzle_gray_to_565;
+                            break;
+                        default:
+                            return nullptr;
+                    }
                     break;
                 default:
-                    break;
+                    return nullptr;
             }
             break;
-        case kGray:
+        case SkEncodedInfo::kGrayAlpha_Color:
             switch (dstInfo.colorType()) {
                 case kN32_SkColorType:
-                    proc = &swizzle_gray_to_n32;
-                    fastProc = &fast_swizzle_gray_to_n32;
-                    break;
-                case kGray_8_SkColorType:
-                    proc = &sample1;
-                    fastProc = &copy;
-                    break;
-                case kRGB_565_SkColorType:
-                    proc = &swizzle_gray_to_565;
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case kGrayAlpha:
-            switch (dstInfo.colorType()) {
-                case kN32_SkColorType:
-                    if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
+                    if (premultiply) {
+                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+                            proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>;
+                            fastProc = &SkipLeadingGrayAlphaZerosThen
+                                    <fast_swizzle_grayalpha_to_n32_premul>;
+                        } else {
+                            proc = &swizzle_grayalpha_to_n32_premul;
+                            fastProc = &fast_swizzle_grayalpha_to_n32_premul;
+                        }
+                    } else {
                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                             proc = &SkipLeadingGrayAlphaZerosThen
                                     <swizzle_grayalpha_to_n32_unpremul>;
@@ -765,60 +739,58 @@
                             proc = &swizzle_grayalpha_to_n32_unpremul;
                             fastProc = &fast_swizzle_grayalpha_to_n32_unpremul;
                         }
-                    } else {
-                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
-                            proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>;
-                            fastProc = &SkipLeadingGrayAlphaZerosThen
-                                    <fast_swizzle_grayalpha_to_n32_premul>;
-                        } else {
-                            proc = &swizzle_grayalpha_to_n32_premul;
-                            fastProc = &fast_swizzle_grayalpha_to_n32_premul;
-                        }
                     }
                     break;
                 default:
-                    break;
+                    return nullptr;
             }
             break;
-        case kBGR:
-        case kBGRX:
-            switch (dstInfo.colorType()) {
-                case kN32_SkColorType:
-                    proc = &swizzle_bgrx_to_n32;
+        case SkEncodedInfo::kPalette_Color:
+            // We assume that the color table is premultiplied and swizzled
+            // as desired.
+            switch (encodedInfo.bitsPerComponent()) {
+                case 1:
+                case 2:
+                case 4:
+                    switch (dstInfo.colorType()) {
+                        case kN32_SkColorType:
+                            proc = &swizzle_small_index_to_n32;
+                            break;
+                        case kRGB_565_SkColorType:
+                            proc = &swizzle_small_index_to_565;
+                            break;
+                        case kIndex_8_SkColorType:
+                            proc = &swizzle_small_index_to_index;
+                            break;
+                        default:
+                            return nullptr;
+                    }
                     break;
-                case kRGB_565_SkColorType:
-                    proc = &swizzle_bgrx_to_565;
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case kBGRA:
-            switch (dstInfo.colorType()) {
-                case kN32_SkColorType:
-                    if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
-                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
-                            proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_unpremul>;
-                            fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_unpremul>;
-                        } else {
-                            proc = &swizzle_bgra_to_n32_unpremul;
-                            fastProc = &fast_swizzle_bgra_to_n32_unpremul;
-                        }
-                    } else {
-                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
-                            proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>;
-                            fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>;
-                        } else {
-                            proc = &swizzle_bgra_to_n32_premul;
-                            fastProc = &fast_swizzle_bgra_to_n32_premul;
-                        }
+                case 8:
+                    switch (dstInfo.colorType()) {
+                        case kN32_SkColorType:
+                            if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+                                proc = &swizzle_index_to_n32_skipZ;
+                            } else {
+                                proc = &swizzle_index_to_n32;
+                            }
+                            break;
+                        case kRGB_565_SkColorType:
+                            proc = &swizzle_index_to_565;
+                            break;
+                        case kIndex_8_SkColorType:
+                            proc = &sample1;
+                            fastProc = &copy;
+                            break;
+                        default:
+                            return nullptr;
                     }
                     break;
                 default:
-                    break;
+                    return nullptr;
             }
             break;
-        case kRGB:
+        case SkEncodedInfo::kRGB_Color:
             switch (dstInfo.colorType()) {
                 case kN32_SkColorType:
                     proc = &swizzle_rgb_to_n32;
@@ -828,21 +800,13 @@
                     proc = &swizzle_rgb_to_565;
                     break;
                 default:
-                    break;
+                    return nullptr;
             }
             break;
-        case kRGBA:
+        case SkEncodedInfo::kRGBA_Color:
             switch (dstInfo.colorType()) {
                 case kN32_SkColorType:
-                    if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
-                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
-                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>;
-                            fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_unpremul>;
-                        } else {
-                            proc = &swizzle_rgba_to_n32_unpremul;
-                            fastProc = &fast_swizzle_rgba_to_n32_unpremul;
-                        }
-                    } else {
+                    if (premultiply) {
                         if (SkCodec::kYes_ZeroInitialized == zeroInit) {
                             proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>;
                             fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>;
@@ -850,13 +814,72 @@
                             proc = &swizzle_rgba_to_n32_premul;
                             fastProc = &fast_swizzle_rgba_to_n32_premul;
                         }
+                    } else {
+                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>;
+                            fastProc = &SkipLeading8888ZerosThen
+                                    <fast_swizzle_rgba_to_n32_unpremul>;
+                        } else {
+                            proc = &swizzle_rgba_to_n32_unpremul;
+                            fastProc = &fast_swizzle_rgba_to_n32_unpremul;
+                        }
                     }
                     break;
                 default:
-                    break;
+                    return nullptr;
             }
             break;
-        case kCMYK:
+        case SkEncodedInfo::kBGR_Color:
+            switch (dstInfo.colorType()) {
+                case kN32_SkColorType:
+                    proc = &swizzle_bgrx_to_n32;
+                    break;
+                case kRGB_565_SkColorType:
+                    proc = &swizzle_bgrx_to_565;
+                    break;
+                default:
+                    return nullptr;
+            }
+            break;
+        case SkEncodedInfo::kBGRX_Color:
+            switch (dstInfo.colorType()) {
+                case kN32_SkColorType:
+                    proc = &swizzle_bgrx_to_n32;
+                    break;
+                case kRGB_565_SkColorType:
+                    proc = &swizzle_bgrx_to_565;
+                    break;
+                default:
+                    return nullptr;
+            }
+            break;
+        case SkEncodedInfo::kBGRA_Color:
+            switch (dstInfo.colorType()) {
+                case kN32_SkColorType:
+                    if (premultiply) {
+                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+                            proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>;
+                            fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>;
+                        } else {
+                            proc = &swizzle_bgra_to_n32_premul;
+                            fastProc = &fast_swizzle_bgra_to_n32_premul;
+                        }
+                    } else {
+                        if (SkCodec::kYes_ZeroInitialized == zeroInit) {
+                            proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>;
+                            fastProc = &SkipLeading8888ZerosThen
+                                    <fast_swizzle_bgra_to_n32_unpremul>;
+                        } else {
+                            proc = &swizzle_bgra_to_n32_unpremul;
+                            fastProc = &fast_swizzle_bgra_to_n32_unpremul;
+                        }
+                    }
+                    break;
+                default:
+                    return nullptr;
+            }
+            break;
+        case SkEncodedInfo::kInvertedCMYK_Color:
             switch (dstInfo.colorType()) {
                 case kN32_SkColorType:
                     proc = &swizzle_cmyk_to_n32;
@@ -866,28 +889,40 @@
                     proc = &swizzle_cmyk_to_565;
                     break;
                 default:
-                    break;
+                    return nullptr;
             }
             break;
-        case kNoOp8:
-            proc = &sample1;
-            fastProc = &copy;
-            break;
-        case kNoOp16:
-            proc = sample2;
-            fastProc = &copy;
-            break;
-        case kNoOp32:
-            proc = &sample4;
-            fastProc = &copy;
+        case SkEncodedInfo::kPreSwizzled_Color:
+            switch (dstInfo.colorType()) {
+                case kGray_8_SkColorType:
+                    proc = &sample1;
+                    fastProc = &copy;
+                    break;
+                case kRGB_565_SkColorType:
+                    proc = &sample2;
+                    fastProc = &copy;
+                    break;
+                case kN32_SkColorType:
+                    proc = &sample4;
+                    fastProc = &copy;
+                    break;
+                default:
+                    return nullptr;
+            }
             break;
         default:
-            break;
+            return nullptr;
     }
 
-    // Store bpp in bytes if it is an even multiple, otherwise use bits
-    int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
     int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
+    int srcBPP;
+    if (SkEncodedInfo::kPreSwizzled_Color == encodedInfo.color()) {
+        srcBPP = dstBPP;
+    } else {
+        // Store bpp in bytes if it is an even multiple, otherwise use bits
+        uint8_t bitsPerPixel = encodedInfo.bitsPerPixel();
+        srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel;
+    }
 
     int srcOffset = 0;
     int srcWidth = dstInfo.width();
diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h
index 7eebe7f..070652c 100644
--- a/src/codec/SkSwizzler.h
+++ b/src/codec/SkSwizzler.h
@@ -16,78 +16,8 @@
 class SkSwizzler : public SkSampler {
 public:
     /**
-     *  Enum describing the config of the source data.
-     */
-    enum SrcConfig {
-        kUnknown,  // Invalid type.
-        kBit,      // A single bit to distinguish between white and black.
-        kGray,
-        kGrayAlpha,
-        kIndex1,
-        kIndex2,
-        kIndex4,
-        kIndex,
-        kRGB,
-        kBGR,
-        kBGRX,     // The alpha channel can be anything, but the image is opaque.
-        kRGBA,
-        kBGRA,
-        kCMYK,
-        kNoOp8,    // kNoOp modes are used exclusively for sampling, subsetting, and
-        kNoOp16,   // copying.  The pixels themselves do not need to be modified.
-        kNoOp32,
-    };
-
-    /*
-     *
-     * Returns bits per pixel for source config
-     *
-     */
-    static int BitsPerPixel(SrcConfig sc) {
-        switch (sc) {
-            case kBit:
-            case kIndex1:
-                return 1;
-            case kIndex2:
-                return 2;
-            case kIndex4:
-                return 4;
-            case kGray:
-            case kIndex:
-            case kNoOp8:
-                return 8;
-            case kGrayAlpha:
-            case kNoOp16:
-                return 16;
-            case kRGB:
-            case kBGR:
-                return 24;
-            case kRGBA:
-            case kBGRX:
-            case kBGRA:
-            case kCMYK:
-            case kNoOp32:
-                return 32;
-            default:
-                SkASSERT(false);
-                return 0;
-        }
-    }
-
-    /*
-     *
-     * Returns bytes per pixel for source config
-     * Raises an error if each pixel is not stored in an even number of bytes
-     *
-     */
-    static int BytesPerPixel(SrcConfig sc) {
-        SkASSERT(SkIsAlign8(BitsPerPixel(sc)));
-        return BitsPerPixel(sc) >> 3;
-    }
-
-    /**
      *  Create a new SkSwizzler.
-     *  @param SrcConfig Description of the format of the source.
+     *  @param encodedInfo Description of the format of the encoded data.
      *  @param ctable Unowned pointer to an array of up to 256 colors for an
      *                index source.
      *  @param dstInfo Describes the destination.
@@ -104,7 +34,7 @@
      *
      *  @return A new SkSwizzler or nullptr on failure.
      */
-    static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
+    static SkSwizzler* CreateSwizzler(const SkEncodedInfo& encodedInfo, const SkPMColor* ctable,
                                       const SkImageInfo& dstInfo, const SkCodec::Options&,
                                       const SkIRect* frame = nullptr);
 
diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp
index 9a842ac..1e165b4 100644
--- a/src/codec/SkWbmpCodec.cpp
+++ b/src/codec/SkWbmpCodec.cpp
@@ -97,7 +97,7 @@
 
 SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable,
         const Options& opts) {
-    return SkSwizzler::CreateSwizzler(SkSwizzler::kBit, ctable, info, opts);
+    return SkSwizzler::CreateSwizzler(this->getEncodedInfo(), ctable, info, opts);
 }
 
 bool SkWbmpCodec::readRow(uint8_t* row) {