diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index b375e59..9fc4ea5 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -200,6 +200,7 @@
     add_definitions(-DSK_CODEC_DECODES_PNG)
 else()
     remove_srcs(../src/images/*png*)
+    remove_srcs(../src/images/*ico*)
     remove_srcs(../src/codec/*Png*)
     remove_srcs(../src/codec/*Ico*)
 endif()
diff --git a/gm/downsamplebitmap.cpp b/gm/downsamplebitmap.cpp
index 5983824..a99bae0 100644
--- a/gm/downsamplebitmap.cpp
+++ b/gm/downsamplebitmap.cpp
@@ -183,15 +183,23 @@
 DEF_GM( return new DownsampleBitmapTextGM(72, kHigh_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kHigh_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kHigh_SkFilterQuality); )
+DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc",
+                                            kHigh_SkFilterQuality); )
 
 DEF_GM( return new DownsampleBitmapTextGM(72, kMedium_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kMedium_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kMedium_SkFilterQuality); )
+DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc",
+                                           kMedium_SkFilterQuality); )
 
 DEF_GM( return new DownsampleBitmapTextGM(72, kLow_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kLow_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kLow_SkFilterQuality); )
+DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc",
+                                           kLow_SkFilterQuality); )
 
 DEF_GM( return new DownsampleBitmapTextGM(72, kNone_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256, kNone_SkFilterQuality); )
 DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png", kNone_SkFilterQuality); )
+DEF_GM( return new DownsampleBitmapImageGM("mandrill_132x132_12x12.astc",
+                                           kNone_SkFilterQuality); )
diff --git a/gm/etc1bitmap.cpp b/gm/etc1bitmap.cpp
new file mode 100644
index 0000000..9d47999
--- /dev/null
+++ b/gm/etc1bitmap.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+
+#include "Resources.h"
+#include "SkCanvas.h"
+#include "SkData.h"
+#include "SkImage.h"
+#include "SkImageGenerator.h"
+#include "SkOSFile.h"
+#include "SkTemplates.h"
+
+#ifndef SK_IGNORE_ETC1_SUPPORT
+
+#include "etc1.h"
+
+/**
+ *  Remove the last row and column of ETC1 blocks, effectively
+ *  making a texture that started as power of two into a texture
+ *  that is no longer power of two...
+ */
+bool slice_etc1_data(void *data, int* width, int* height) {
+
+    // First, parse the data and get to it...
+    etc1_byte *origData = reinterpret_cast<etc1_byte *>(data);
+    if (!etc1_pkm_is_valid(origData)) {
+        return false;
+    }
+
+    int origW = etc1_pkm_get_width(origData);
+    int origH = etc1_pkm_get_height(origData);
+
+    int blockWidth = (origW + 3) >> 2;
+    int blockHeight = (origH + 3) >> 2;
+
+    // Make sure that we have blocks to trim off..
+    if (blockWidth < 2 || blockHeight < 2) {
+        return false;
+    }
+
+    int newWidth = (blockWidth - 1) << 2;
+    int newHeight = (blockHeight - 1) << 2;
+
+    size_t newDataSz = etc1_get_encoded_data_size(newWidth, newHeight) + ETC_PKM_HEADER_SIZE;
+    SkAutoTMalloc<etc1_byte> am(newDataSz);
+
+    etc1_byte* newData = am.get();
+
+    etc1_pkm_format_header(newData, newWidth, newHeight);
+    newData += ETC_PKM_HEADER_SIZE;
+    origData += ETC_PKM_HEADER_SIZE;
+
+    for (int j = 0; j < blockHeight - 1; ++j) {
+        memcpy(newData, origData, (blockWidth - 1)*ETC1_ENCODED_BLOCK_SIZE);
+        origData += blockWidth*ETC1_ENCODED_BLOCK_SIZE;
+        newData += (blockWidth - 1)*ETC1_ENCODED_BLOCK_SIZE;
+    }
+
+    // Stick the data back whence it came
+    memcpy(data, am.get(), newDataSz);
+    *width = newWidth;
+    *height = newHeight;
+
+    return true;
+}
+#endif  // SK_IGNORE_ETC1_SUPPORT
+
+namespace skiagm {
+
+/**
+ *  Test decoding an image from a PKM or KTX file and then
+ *  from compressed ETC1 data.
+ */
+class ETC1BitmapGM : public GM {
+public:
+    ETC1BitmapGM() { }
+    virtual ~ETC1BitmapGM() { }
+
+protected:
+    SkString onShortName() override {
+        SkString str = SkString("etc1bitmap_");
+        str.append(this->fileExtension());
+        return str;
+    }
+
+    SkISize onISize() override {
+        return SkISize::Make(128, 128);
+    }
+
+    virtual SkString fileExtension() const = 0;
+
+    void onDraw(SkCanvas* canvas) override {
+        SkBitmap bm;
+        SkString filename = GetResourcePath("mandrill_128.");
+        filename.append(this->fileExtension());
+        sk_sp<SkData> fileData(SkData::MakeFromFileName(filename.c_str()));
+        if (nullptr == fileData) {
+            SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
+            return;
+        }
+
+        sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(fileData)));
+        if (nullptr == image) {
+            SkDebugf("Could not decode the ETC file. ETC may not be included in this platform.\n");
+            return;
+        }
+        canvas->drawImage(image, 0, 0);
+    }
+
+private:
+    typedef GM INHERITED;
+};
+
+// This class specializes ETC1BitmapGM to load the mandrill_128.pkm file.
+class ETC1Bitmap_PKM_GM : public ETC1BitmapGM {
+public:
+    ETC1Bitmap_PKM_GM() : ETC1BitmapGM() { }
+    virtual ~ETC1Bitmap_PKM_GM() { }
+
+protected:
+
+    SkString fileExtension() const override { return SkString("pkm"); }
+
+private:
+    typedef ETC1BitmapGM INHERITED;
+};
+
+// This class specializes ETC1BitmapGM to load the mandrill_128.ktx file.
+class ETC1Bitmap_KTX_GM : public ETC1BitmapGM {
+public:
+    ETC1Bitmap_KTX_GM() : ETC1BitmapGM() { }
+    virtual ~ETC1Bitmap_KTX_GM() { }
+
+protected:
+
+    SkString fileExtension() const override { return SkString("ktx"); }
+
+private:
+    typedef ETC1BitmapGM INHERITED;
+};
+
+// This class specializes ETC1BitmapGM to load the mandrill_128.r11.ktx file.
+class ETC1Bitmap_R11_KTX_GM : public ETC1BitmapGM {
+public:
+    ETC1Bitmap_R11_KTX_GM() : ETC1BitmapGM() { }
+    virtual ~ETC1Bitmap_R11_KTX_GM() { }
+
+protected:
+
+    SkString fileExtension() const override { return SkString("r11.ktx"); }
+
+private:
+    typedef ETC1BitmapGM INHERITED;
+};
+
+#ifndef SK_IGNORE_ETC1_SUPPORT
+/**
+ *  Test decoding an image from a PKM file and then
+ *  from non-power-of-two compressed ETC1 data. First slice
+ *  off a row and column of blocks in order to make it non-power
+ *  of two.
+ */
+class ETC1Bitmap_NPOT_GM : public GM {
+public:
+    ETC1Bitmap_NPOT_GM() { }
+    virtual ~ETC1Bitmap_NPOT_GM() { }
+
+protected:
+    SkString onShortName() override {
+        return SkString("etc1bitmap_npot");
+    }
+
+    SkISize onISize() override {
+        return SkISize::Make(124, 124);
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        SkBitmap bm;
+        SkString pkmFilename = GetResourcePath("mandrill_128.pkm");
+        SkAutoDataUnref fileData(SkData::NewFromFileName(pkmFilename.c_str()));
+        if (nullptr == fileData) {
+            SkDebugf("Could not open the file. Did you forget to set the resourcePath?\n");
+            return;
+        }
+
+        SkAutoMalloc am(fileData->size());
+        memcpy(am.get(), fileData->data(), fileData->size());
+
+        int width, height;
+        if (!slice_etc1_data(am.get(), &width, &height)) {
+            SkDebugf("ETC1 Data is poorly formatted.\n");
+            return;
+        }
+
+        SkASSERT(124 == width);
+        SkASSERT(124 == height);
+
+        size_t dataSz = etc1_get_encoded_data_size(width, height) + ETC_PKM_HEADER_SIZE;
+        sk_sp<SkData> nonPOTData(SkData::MakeWithCopy(am.get(), dataSz));
+        canvas->drawImage(SkImage::MakeFromEncoded(std::move(nonPOTData)).get(), 0, 0);
+    }
+
+private:
+    typedef GM INHERITED;
+};
+#endif  // SK_IGNORE_ETC1_SUPPORT
+
+}  // namespace skiagm
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return new skiagm::ETC1Bitmap_PKM_GM;)
+DEF_GM(return new skiagm::ETC1Bitmap_KTX_GM;)
+DEF_GM(return new skiagm::ETC1Bitmap_R11_KTX_GM;)
+
+#ifndef SK_IGNORE_ETC1_SUPPORT
+DEF_GM(return new skiagm::ETC1Bitmap_NPOT_GM;)
+#endif  // SK_IGNORE_ETC1_SUPPORT
diff --git a/gyp/core.gypi b/gyp/core.gypi
index 8d558e1..443029d 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -360,6 +360,7 @@
         '<(skia_include_path)/core/SkFontStyle.h',
         '<(skia_include_path)/core/SkGraphics.h',
         '<(skia_include_path)/core/SkImage.h',
+        '<(skia_include_path)/core/SkImageDecoder.h',
         '<(skia_include_path)/core/SkImageEncoder.h',
         '<(skia_include_path)/core/SkImageFilter.h',
         '<(skia_include_path)/core/SkImageInfo.h',
diff --git a/gyp/images.gyp b/gyp/images.gyp
index 53f505d..8c5b0a7 100644
--- a/gyp/images.gyp
+++ b/gyp/images.gyp
@@ -31,17 +31,36 @@
       ],
       'sources': [
         '../include/images/SkForceLinking.h',
+        '../src/images/SkJpegUtility.h',
         '../include/images/SkMovie.h',
         '../include/images/SkPageFlipper.h',
 
-        '../src/images/SkForceLinking.cpp',
-        '../src/images/SkImageDecoder_FactoryDefault.cpp',
+        '../src/images/bmpdecoderhelper.cpp',
+        '../src/images/bmpdecoderhelper.h',
 
-        # If encoders are added/removed to/from (all/individual)
+        '../src/images/SkForceLinking.cpp',
+        '../src/images/SkImageDecoder.cpp',
+        '../src/images/SkImageDecoder_FactoryDefault.cpp',
+        '../src/images/SkImageDecoder_FactoryRegistrar.cpp',
+
+        # If decoders are added/removed to/from (all/individual)
         # platform(s), be sure to update SkForceLinking.cpp
         # so the right decoders will be forced to link.
 
+        # IMPORTANT: The build order of the SkImageDecoder_*.cpp files
+        # defines the order image decoders are tested when decoding a
+        # stream. The last decoder is the first one tested, so the .cpp
+        # files should be in listed in order from the least likely to be
+        # used, to the most likely (jpeg and png should be the last two
+        # for instance.) As a result, they are deliberately not in
+        # alphabetical order.
+        '../src/images/SkImageDecoder_wbmp.cpp',
+        '../src/images/SkImageDecoder_pkm.cpp',
         '../src/images/SkImageDecoder_ktx.cpp',
+        '../src/images/SkImageDecoder_astc.cpp',
+        '../src/images/SkImageDecoder_libbmp.cpp',
+        '../src/images/SkImageDecoder_libgif.cpp',
+        '../src/images/SkImageDecoder_libico.cpp',
         '../src/images/SkImageDecoder_libwebp.cpp',
         '../src/images/SkImageDecoder_libjpeg.cpp',
         '../src/images/SkImageDecoder_libpng.cpp',
@@ -53,6 +72,8 @@
         '../src/images/SkMovie.cpp',
         '../src/images/SkMovie_gif.cpp',
         '../src/images/SkPageFlipper.cpp',
+        '../src/images/SkScaledBitmapSampler.cpp',
+        '../src/images/SkScaledBitmapSampler.h',
 
         '../src/ports/SkImageDecoder_CG.cpp',
         '../src/ports/SkImageDecoder_WIC.cpp',
@@ -60,6 +81,8 @@
       'conditions': [
         [ 'skia_os == "win"', {
           'sources!': [
+            '../src/images/SkImageDecoder_FactoryDefault.cpp',
+            '../src/images/SkImageDecoder_libgif.cpp',
             '../src/images/SkImageDecoder_libpng.cpp',
             '../src/images/SkMovie_gif.cpp',
           ],
@@ -78,7 +101,9 @@
         }],
         [ 'skia_os in ["mac", "ios"]', {
           'sources!': [
+            '../src/images/SkImageDecoder_FactoryDefault.cpp',
             '../src/images/SkImageDecoder_libpng.cpp',
+            '../src/images/SkImageDecoder_libgif.cpp',
             '../src/images/SkMovie_gif.cpp',
           ],
         },{ #else if skia_os != mac
@@ -104,7 +129,9 @@
               # The android framework disables these decoders as they are of little use to
               # Java applications that can't take advantage of the compressed formats.
               'sources!': [
+                '../src/images/SkImageDecoder_pkm.cpp',
                 '../src/images/SkImageDecoder_ktx.cpp',
+                '../src/images/SkImageDecoder_astc.cpp',
               ],
             }],
           ],
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 95a5244..d551031 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -11,7 +11,6 @@
 #include "SkTypes.h"
 #include "SkBitmap.h"
 #include "SkDeque.h"
-#include "SkImage.h"
 #include "SkPaint.h"
 #include "SkRefCnt.h"
 #include "SkRegion.h"
@@ -27,6 +26,7 @@
 class SkDraw;
 class SkDrawable;
 class SkDrawFilter;
+class SkImage;
 class SkImageFilter;
 class SkMetaData;
 class SkPath;
diff --git a/include/core/SkImageDecoder.h b/include/core/SkImageDecoder.h
new file mode 100644
index 0000000..7a90964
--- /dev/null
+++ b/include/core/SkImageDecoder.h
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkImageDecoder_DEFINED
+#define SkImageDecoder_DEFINED
+
+#include "SkBitmap.h"
+#include "SkImage.h"
+#include "SkPngChunkReader.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkTRegistry.h"
+#include "SkTypes.h"
+
+class SkStream;
+class SkStreamRewindable;
+
+/** \class SkImageDecoder
+
+    DEPRECATED Please use SkImage::NewFromEncoded() or SkImageGenerator::NewFromEncoded().
+
+    Base class for decoding compressed images into a SkBitmap
+*/
+class SkImageDecoder : SkNoncopyable {
+public:
+    virtual ~SkImageDecoder();
+
+    // TODO (scroggo): Merge with SkEncodedFormat
+    enum Format {
+        kUnknown_Format,
+        kBMP_Format,
+        kGIF_Format,
+        kICO_Format,
+        kJPEG_Format,
+        kPNG_Format,
+        kWBMP_Format,
+        kWEBP_Format,
+        kPKM_Format,
+        kKTX_Format,
+        kASTC_Format,
+
+        kLastKnownFormat = kKTX_Format,
+    };
+
+    /** Return the format of image this decoder can decode. If this decoder can decode multiple
+        formats, kUnknown_Format will be returned.
+    */
+    virtual Format getFormat() const;
+
+    /** If planes or rowBytes is NULL, decodes the header and computes componentSizes
+        for memory allocation.
+        Otherwise, decodes the YUV planes into the provided image planes and
+        updates componentSizes to the final image size.
+        Returns whether the decoding was successful.
+    */
+    bool decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3],
+                          size_t rowBytes[3], SkYUVColorSpace*);
+
+    /** Return the format of the SkStreamRewindable or kUnknown_Format if it cannot be determined.
+        Rewinds the stream before returning.
+    */
+    static Format GetStreamFormat(SkStreamRewindable*);
+
+    /** Return a readable string of the Format provided.
+    */
+    static const char* GetFormatName(Format);
+
+    /** Return a readable string of the value returned by getFormat().
+    */
+    const char* getFormatName() const;
+
+    /** Whether the decoder should skip writing zeroes to output if possible.
+    */
+    bool getSkipWritingZeroes() const { return fSkipWritingZeroes; }
+
+    /** Set to true if the decoder should skip writing any zeroes when
+        creating the output image.
+        This is a hint that may not be respected by the decoder.
+        It should only be used if it is known that the memory to write
+        to has already been set to 0; otherwise the resulting image will
+        have garbage.
+        This is ideal for images that contain a lot of completely transparent
+        pixels, but may be a performance hit for an image that has only a
+        few transparent pixels.
+        The default is false.
+    */
+    void setSkipWritingZeroes(bool skip) { fSkipWritingZeroes = skip; }
+
+    /** Returns true if the decoder should try to dither the resulting image.
+        The default setting is true.
+    */
+    bool getDitherImage() const { return fDitherImage; }
+
+    /** Set to true if the the decoder should try to dither the resulting image.
+        The default setting is true.
+    */
+    void setDitherImage(bool dither) { fDitherImage = dither; }
+
+    /** Returns true if the decoder should try to decode the
+        resulting image to a higher quality even at the expense of
+        the decoding speed.
+    */
+    bool getPreferQualityOverSpeed() const { return fPreferQualityOverSpeed; }
+
+    /** Set to true if the the decoder should try to decode the
+        resulting image to a higher quality even at the expense of
+        the decoding speed.
+    */
+    void setPreferQualityOverSpeed(bool qualityOverSpeed) {
+        fPreferQualityOverSpeed = qualityOverSpeed;
+    }
+
+    /** Set to true to require the decoder to return a bitmap with unpremultiplied
+        colors. The default is false, meaning the resulting bitmap will have its
+        colors premultiplied.
+        NOTE: Passing true to this function may result in a bitmap which cannot
+        be properly used by Skia.
+    */
+    void setRequireUnpremultipliedColors(bool request) {
+        fRequireUnpremultipliedColors = request;
+    }
+
+    /** Returns true if the decoder will only return bitmaps with unpremultiplied
+        colors.
+    */
+    bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; }
+
+    SkPngChunkReader* getPeeker() const { return fPeeker; }
+    SkPngChunkReader* setPeeker(SkPngChunkReader*);
+
+    /**
+     *  By default, the codec will try to comply with the "pref" colortype
+     *  that is passed to decode() or decodeSubset(). However, this can be called
+     *  to override that, causing the codec to try to match the src depth instead
+     *  (as shown below).
+     *
+     *      src_8Index  -> kIndex_8_SkColorType
+     *      src_8Gray   -> kN32_SkColorType
+     *      src_8bpc    -> kN32_SkColorType
+     */
+    void setPreserveSrcDepth(bool preserve) {
+        fPreserveSrcDepth = preserve;
+    }
+
+    SkBitmap::Allocator* getAllocator() const { return fAllocator; }
+    SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
+
+    // sample-size, if set to > 1, tells the decoder to return a smaller than
+    // original bitmap, sampling 1 pixel for every size pixels. e.g. if sample
+    // size is set to 3, then the returned bitmap will be 1/3 as wide and high,
+    // and will contain 1/9 as many pixels as the original.
+    // Note: this is a hint, and the codec may choose to ignore this, or only
+    // approximate the sample size.
+    int getSampleSize() const { return fSampleSize; }
+    void setSampleSize(int size);
+
+    /** Reset the sampleSize to its default of 1
+     */
+    void resetSampleSize() { this->setSampleSize(1); }
+
+    /** Decoding is synchronous, but for long decodes, a different thread can
+        call this method safely. This sets a state that the decoders will
+        periodically check, and if they see it changed to cancel, they will
+        cancel. This will result in decode() returning false. However, there is
+        no guarantee that the decoder will see the state change in time, so
+        it is possible that cancelDecode() will be called, but will be ignored
+        and decode() will return true (assuming no other problems were
+        encountered).
+
+        This state is automatically reset at the beginning of decode().
+     */
+    void cancelDecode() {
+        // now the subclass must query shouldCancelDecode() to be informed
+        // of the request
+        fShouldCancelDecode = true;
+    }
+
+    /** Passed to the decode method. If kDecodeBounds_Mode is passed, then
+        only the bitmap's info need be set. If kDecodePixels_Mode
+        is passed, then the bitmap must have pixels or a pixelRef.
+    */
+    enum Mode {
+        kDecodeBounds_Mode, //!< only return info in bitmap
+        kDecodePixels_Mode  //!< return entire bitmap (including pixels)
+    };
+
+    /** Result of a decode. If read as a boolean, a partial success is
+        considered a success (true).
+    */
+    enum Result {
+        kFailure        = 0,    //!< Image failed to decode. bitmap will be
+                                //   unchanged.
+        kPartialSuccess = 1,    //!< Part of the image decoded. The rest is
+                                //   filled in automatically
+        kSuccess        = 2     //!< The entire image was decoded, if Mode is
+                                //   kDecodePixels_Mode, or the bounds were
+                                //   decoded, in kDecodeBounds_Mode.
+    };
+
+    /** Given a stream, decode it into the specified bitmap.
+        If the decoder can decompress the image, it calls bitmap.setInfo(),
+        and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
+        which will allocated a pixelRef. To access the pixel memory, the codec
+        needs to call lockPixels/unlockPixels on the
+        bitmap. It can then set the pixels with the decompressed image.
+    *   If the image cannot be decompressed, return kFailure. After the
+    *   decoding, the function converts the decoded colortype in bitmap
+    *   to pref if possible. Whether a conversion is feasible is
+    *   tested by Bitmap::canCopyTo(pref).
+
+        If an SkBitmap::Allocator is installed via setAllocator, it will be
+        used to allocate the pixel memory. A clever allocator can be used
+        to allocate the memory from a cache, volatile memory, or even from
+        an existing bitmap's memory.
+
+        If an SkPngChunkReader is installed via setPeeker, it may be used to
+        peek into meta data during the decode.
+    */
+    Result decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode);
+    Result decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
+        return this->decode(stream, bitmap, kUnknown_SkColorType, mode);
+    }
+
+    /** Given a stream, this will try to find an appropriate decoder object.
+        If none is found, the method returns NULL.
+
+        DEPRECATED Please use SkImage::NewFromEncoded() or SkImageGenerator::NewFromEncoded().
+    */
+    static SkImageDecoder* Factory(SkStreamRewindable*);
+
+    /** Decode the image stored in the specified file, and store the result
+        in bitmap. Return true for success or false on failure.
+
+        @param pref Prefer this colortype.
+
+        @param format On success, if format is non-null, it is set to the format
+                      of the decoded file. On failure it is ignored.
+
+        DEPRECATED Do not use.
+    */
+    static bool DecodeFile(const char file[], SkBitmap* bitmap, SkColorType pref, Mode,
+                           Format* format = NULL);
+    static bool DecodeFile(const char file[], SkBitmap* bitmap) {
+        return DecodeFile(file, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
+    }
+
+    /** Decode the image stored in the specified memory buffer, and store the
+        result in bitmap. Return true for success or false on failure.
+
+        @param pref Prefer this colortype.
+
+        @param format On success, if format is non-null, it is set to the format
+                       of the decoded buffer. On failure it is ignored.
+
+        DEPRECATED Please use SkImage::NewFromEncoded() or SkImageGenerator::NewFromEncoded().
+     */
+    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, SkColorType pref,
+                             Mode, Format* format = NULL);
+    static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){
+        return DecodeMemory(buffer, size, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
+    }
+
+    /** Decode the image stored in the specified SkStreamRewindable, and store the result
+        in bitmap. Return true for success or false on failure.
+
+        @param pref Prefer this colortype.
+
+        @param format On success, if format is non-null, it is set to the format
+                      of the decoded stream. On failure it is ignored.
+
+        DEPRECATED Please use SkImage::NewFromEncoded() or SkImageGenerator::NewFromEncoded().
+     */
+    static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, SkColorType pref, Mode,
+                             Format* format = NULL);
+    static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap) {
+        return DecodeStream(stream, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
+    }
+
+protected:
+    // must be overridden in subclasses. This guy is called by decode(...)
+    virtual Result onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
+
+    /** If planes or rowBytes is NULL, decodes the header and computes componentSizes
+        for memory allocation.
+        Otherwise, decodes the YUV planes into the provided image planes and
+        updates componentSizes to the final image size.
+        Returns whether the decoding was successful.
+    */
+    virtual bool onDecodeYUV8Planes(SkStream*, SkISize[3] /*componentSizes*/,
+                                    void*[3] /*planes*/, size_t[3] /*rowBytes*/,
+                                    SkYUVColorSpace*) {
+        return false;
+    }
+
+    /**
+     *  Copy all fields on this decoder to the other decoder. Used by subclasses
+     *  to decode a subimage using a different decoder, but with the same settings.
+     */
+    void copyFieldsToOther(SkImageDecoder* other);
+
+    /** Can be queried from within onDecode, to see if the user (possibly in
+        a different thread) has requested the decode to cancel. If this returns
+        true, your onDecode() should stop and return false.
+        Each subclass needs to decide how often it can query this, to balance
+        responsiveness with performance.
+
+        Calling this outside of onDecode() may return undefined values.
+     */
+
+public:
+    bool shouldCancelDecode() const { return fShouldCancelDecode; }
+
+protected:
+    SkImageDecoder();
+
+    /**
+     *  Return the default preference being used by the current or latest call to decode.
+     */
+    SkColorType getDefaultPref() { return fDefaultPref; }
+
+    /*  Helper for subclasses. Call this to allocate the pixel memory given the bitmap's info.
+        Returns true on success. This method handles checking for an optional Allocator.
+    */
+    bool allocPixelRef(SkBitmap*, SkColorTable*) const;
+
+    /**
+     *  The raw data of the src image.
+     */
+    enum SrcDepth {
+        // Color-indexed.
+        kIndex_SrcDepth,
+        // Grayscale in 8 bits.
+        k8BitGray_SrcDepth,
+        // 8 bits per component. Used for 24 bit if there is no alpha.
+        k32Bit_SrcDepth,
+    };
+    /** The subclass, inside onDecode(), calls this to determine the colorType of
+        the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
+        src image. This routine returns the caller's preference given
+        srcDepth and hasAlpha, or kUnknown_SkColorType if there is no preference.
+     */
+    SkColorType getPrefColorType(SrcDepth, bool hasAlpha) const;
+
+private:
+    SkPngChunkReader*       fPeeker;
+    SkBitmap::Allocator*    fAllocator;
+    int                     fSampleSize;
+    SkColorType             fDefaultPref;   // use if fUsePrefTable is false
+    bool                    fPreserveSrcDepth;
+    bool                    fDitherImage;
+    bool                    fSkipWritingZeroes;
+    mutable bool            fShouldCancelDecode;
+    bool                    fPreferQualityOverSpeed;
+    bool                    fRequireUnpremultipliedColors;
+};
+
+/** Calling newDecoder with a stream returns a new matching imagedecoder
+    instance, or NULL if none can be found. The caller must manage its ownership
+    of the stream as usual, calling unref() when it is done, as the returned
+    decoder may have called ref() (and if so, the decoder is responsible for
+    balancing its ownership when it is destroyed).
+ */
+class SkImageDecoderFactory : public SkRefCnt {
+public:
+    
+
+    virtual SkImageDecoder* newDecoder(SkStreamRewindable*) = 0;
+
+private:
+    typedef SkRefCnt INHERITED;
+};
+
+class SkDefaultImageDecoderFactory : SkImageDecoderFactory {
+public:
+    // calls SkImageDecoder::Factory(stream)
+    virtual SkImageDecoder* newDecoder(SkStreamRewindable* stream) {
+        return SkImageDecoder::Factory(stream);
+    }
+};
+
+// This macro declares a global (i.e., non-class owned) creation entry point
+// for each decoder (e.g., CreateJPEGImageDecoder)
+#define DECLARE_DECODER_CREATOR(codec)          \
+    SkImageDecoder *Create ## codec ();
+
+// This macro defines the global creation entry point for each decoder. Each
+// decoder implementation that registers with the decoder factory must call it.
+#define DEFINE_DECODER_CREATOR(codec) \
+    SkImageDecoder* Create##codec() { return new Sk##codec; }
+
+// All the decoders known by Skia. Note that, depending on the compiler settings,
+// not all of these will be available
+DECLARE_DECODER_CREATOR(BMPImageDecoder);
+DECLARE_DECODER_CREATOR(GIFImageDecoder);
+DECLARE_DECODER_CREATOR(ICOImageDecoder);
+DECLARE_DECODER_CREATOR(JPEGImageDecoder);
+DECLARE_DECODER_CREATOR(PNGImageDecoder);
+DECLARE_DECODER_CREATOR(WBMPImageDecoder);
+DECLARE_DECODER_CREATOR(WEBPImageDecoder);
+DECLARE_DECODER_CREATOR(PKMImageDecoder);
+DECLARE_DECODER_CREATOR(KTXImageDecoder);
+DECLARE_DECODER_CREATOR(ASTCImageDecoder);
+
+// Typedefs to make registering decoder and formatter callbacks easier.
+// These have to be defined outside SkImageDecoder. :(
+typedef SkTRegistry<SkImageDecoder*(*)(SkStreamRewindable*)>        SkImageDecoder_DecodeReg;
+typedef SkTRegistry<SkImageDecoder::Format(*)(SkStreamRewindable*)> SkImageDecoder_FormatReg;
+
+#endif
diff --git a/include/core/SkImageEncoder.h b/include/core/SkImageEncoder.h
index 1ccfae0..bb3341f 100644
--- a/include/core/SkImageEncoder.h
+++ b/include/core/SkImageEncoder.h
@@ -110,12 +110,8 @@
 DECLARE_ENCODER_CREATOR(KTXImageEncoder);
 DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
 
-#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
-DECLARE_ENCODER_CREATOR(PNGImageEncoder_CG);
-#endif
-
-#if defined(SK_BUILD_FOR_WIN)
-DECLARE_ENCODER_CREATOR(ImageEncoder_WIC);
+#ifdef SK_BUILD_FOR_IOS
+DECLARE_ENCODER_CREATOR(PNGImageEncoder_IOS);
 #endif
 
 // Typedef to make registering encoder callback easier
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 195ce24..6c0dda0 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -8,6 +8,7 @@
 #ifndef SkPicture_DEFINED
 #define SkPicture_DEFINED
 
+#include "SkImageDecoder.h"
 #include "SkRefCnt.h"
 #include "SkTypes.h"
 
@@ -15,17 +16,13 @@
 class SkBigPicture;
 class SkBitmap;
 class SkCanvas;
-class SkPath;
 class SkPictureData;
 class SkPixelSerializer;
-class SkReadBuffer;
 class SkRefCntSet;
 class SkStream;
 class SkTypefacePlayback;
 class SkWStream;
-class SkWriteBuffer;
 struct SkPictInfo;
-struct SkRect;
 
 #define SK_SUPPORT_LEGACY_PICTURE_PTR
 
diff --git a/include/core/SkPngChunkReader.h b/include/core/SkPngChunkReader.h
index 0cd6634..f424dd8 100644
--- a/include/core/SkPngChunkReader.h
+++ b/include/core/SkPngChunkReader.h
@@ -16,7 +16,7 @@
  *
  *  Base class for optional callbacks to retrieve meta/chunk data out of a PNG
  *  encoded image as it is being decoded.
- *  Used by SkCodec.
+ *  Used by SkImageDecoder and SkCodec.
  */
 class SkPngChunkReader : public SkRefCnt {
 public:
diff --git a/include/core/SkWriteBuffer.h b/include/core/SkWriteBuffer.h
index 6e9d043..8e46078 100644
--- a/include/core/SkWriteBuffer.h
+++ b/include/core/SkWriteBuffer.h
@@ -10,7 +10,6 @@
 #define SkWriteBuffer_DEFINED
 
 #include "SkData.h"
-#include "SkImage.h"
 #include "SkPath.h"
 #include "SkPicture.h"
 #include "SkPixelSerializer.h"
diff --git a/src/android/SkBitmapRegionDecoder.cpp b/src/android/SkBitmapRegionDecoder.cpp
index 101efbd..712034b 100644
--- a/src/android/SkBitmapRegionDecoder.cpp
+++ b/src/android/SkBitmapRegionDecoder.cpp
@@ -11,6 +11,7 @@
 #include "SkAndroidCodec.h"
 #include "SkCodec.h"
 #include "SkCodecPriv.h"
+#include "SkImageDecoder.h"
 
 SkBitmapRegionDecoder* SkBitmapRegionDecoder::Create(
         SkData* data, Strategy strategy) {
diff --git a/src/core/SkBigPicture.h b/src/core/SkBigPicture.h
index 0834709..2e42213 100644
--- a/src/core/SkBigPicture.h
+++ b/src/core/SkBigPicture.h
@@ -10,11 +10,9 @@
 
 #include "SkOncePtr.h"
 #include "SkPicture.h"
-#include "SkRect.h"
 #include "SkTemplates.h"
 
 class SkBBoxHierarchy;
-class SkMatrix;
 class SkRecord;
 
 // An implementation of SkPicture supporting an arbitrary number of drawing commands.
diff --git a/src/core/SkLayerInfo.h b/src/core/SkLayerInfo.h
index aa19ecb..04ae179 100644
--- a/src/core/SkLayerInfo.h
+++ b/src/core/SkLayerInfo.h
@@ -9,8 +9,6 @@
 #define SkLayerInfo_DEFINED
 
 #include "SkBigPicture.h"
-#include "SkMatrix.h"
-#include "SkPaint.h"
 #include "SkTArray.h"
 
 // This class stores information about the saveLayer/restore pairs found
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index 4f4317c..a606681 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -16,7 +16,6 @@
 #include "SkChecksum.h"
 #include "SkImageFilter.h"
 #include "SkMessageBus.h"
-#include "SkPaint.h"
 #include "SkPicture.h"
 #include "SkTDynamicHash.h"
 
diff --git a/src/images/SkForceLinking.cpp b/src/images/SkForceLinking.cpp
index 05fc7e0..55b7021 100644
--- a/src/images/SkForceLinking.cpp
+++ b/src/images/SkForceLinking.cpp
@@ -5,8 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SkImageEncoder.h"
 #include "SkForceLinking.h"
+#include "SkImageDecoder.h"
 
 // This method is required to fool the linker into not discarding the pre-main
 // initialization and registration of the decoder classes. Passing true will
@@ -14,22 +14,26 @@
 int SkForceLinking(bool doNotPassTrue) {
     if (doNotPassTrue) {
         SkASSERT(false);
-        CreateJPEGImageEncoder();
-        CreateWEBPImageEncoder();
-
+        CreateJPEGImageDecoder();
+        CreateWEBPImageDecoder();
+        CreateBMPImageDecoder();
+        CreateICOImageDecoder();
+        CreateWBMPImageDecoder();
         // Only link hardware texture codecs on platforms that build them. See images.gyp
 #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
-        CreateKTXImageEncoder();
+        CreatePKMImageDecoder();
+        CreateKTXImageDecoder();
+        CreateASTCImageDecoder();
 #endif
-
+        // Only link GIF and PNG on platforms that build them. See images.gyp
 #if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUILD_FOR_IOS)
-        CreatePNGImageEncoder();
+        CreateGIFImageDecoder();
 #endif
-#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
-        CreatePNGImageEncoder_CG();
+#if !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_WIN) && !defined(SK_BUILD_FOR_IOS)
+        CreatePNGImageDecoder();
 #endif
-#if defined(SK_BUILD_FOR_WIN)
-        CreateImageEncoder_WIC();
+#if defined(SK_BUILD_FOR_IOS)
+        CreatePNGImageEncoder_IOS();
 #endif
         return -1;
     }
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
new file mode 100644
index 0000000..221faf7
--- /dev/null
+++ b/src/images/SkImageDecoder.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkImageDecoder.h"
+#include "SkBitmap.h"
+#include "SkImagePriv.h"
+#include "SkPixelRef.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include "SkCanvas.h"
+
+SkImageDecoder::SkImageDecoder()
+    : fPeeker(nullptr)
+    , fAllocator(nullptr)
+    , fSampleSize(1)
+    , fDefaultPref(kUnknown_SkColorType)
+    , fPreserveSrcDepth(false)
+    , fDitherImage(true)
+    , fSkipWritingZeroes(false)
+    , fPreferQualityOverSpeed(false)
+    , fRequireUnpremultipliedColors(false) {
+}
+
+SkImageDecoder::~SkImageDecoder() {
+    SkSafeUnref(fPeeker);
+    SkSafeUnref(fAllocator);
+}
+
+void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) {
+    if (nullptr == other) {
+        return;
+    }
+    other->setPeeker(fPeeker);
+    other->setAllocator(fAllocator);
+    other->setSampleSize(fSampleSize);
+    other->setPreserveSrcDepth(fPreserveSrcDepth);
+    other->setDitherImage(fDitherImage);
+    other->setSkipWritingZeroes(fSkipWritingZeroes);
+    other->setPreferQualityOverSpeed(fPreferQualityOverSpeed);
+    other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors);
+}
+
+SkImageDecoder::Format SkImageDecoder::getFormat() const {
+    return kUnknown_Format;
+}
+
+const char* SkImageDecoder::getFormatName() const {
+    return GetFormatName(this->getFormat());
+}
+
+const char* SkImageDecoder::GetFormatName(Format format) {
+    switch (format) {
+        case kUnknown_Format:
+            return "Unknown Format";
+        case kBMP_Format:
+            return "BMP";
+        case kGIF_Format:
+            return "GIF";
+        case kICO_Format:
+            return "ICO";
+        case kPKM_Format:
+            return "PKM";
+        case kKTX_Format:
+            return "KTX";
+        case kASTC_Format:
+            return "ASTC";
+        case kJPEG_Format:
+            return "JPEG";
+        case kPNG_Format:
+            return "PNG";
+        case kWBMP_Format:
+            return "WBMP";
+        case kWEBP_Format:
+            return "WEBP";
+        default:
+            SkDEBUGFAIL("Invalid format type!");
+    }
+    return "Unknown Format";
+}
+
+SkPngChunkReader* SkImageDecoder::setPeeker(SkPngChunkReader* peeker) {
+    SkRefCnt_SafeAssign(fPeeker, peeker);
+    return peeker;
+}
+
+SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
+    SkRefCnt_SafeAssign(fAllocator, alloc);
+    return alloc;
+}
+
+void SkImageDecoder::setSampleSize(int size) {
+    if (size < 1) {
+        size = 1;
+    }
+    fSampleSize = size;
+}
+
+bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
+                                   SkColorTable* ctable) const {
+    return bitmap->tryAllocPixels(fAllocator, ctable);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkColorType SkImageDecoder::getPrefColorType(SrcDepth srcDepth, bool srcHasAlpha) const {
+    SkColorType ct = fDefaultPref;
+    if (fPreserveSrcDepth) {
+        switch (srcDepth) {
+            case kIndex_SrcDepth:
+                ct = kIndex_8_SkColorType;
+                break;
+            case k8BitGray_SrcDepth:
+                ct = kN32_SkColorType;
+                break;
+            case k32Bit_SrcDepth:
+                ct = kN32_SkColorType;
+                break;
+        }
+    }
+    return ct;
+}
+
+SkImageDecoder::Result SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, SkColorType pref,
+                                              Mode mode) {
+    // we reset this to false before calling onDecode
+    fShouldCancelDecode = false;
+    // assign this, for use by getPrefColorType(), in case fUsePrefTable is false
+    fDefaultPref = pref;
+
+    // pass a temporary bitmap, so that if we return false, we are assured of
+    // leaving the caller's bitmap untouched.
+    SkBitmap tmp;
+    const Result result = this->onDecode(stream, &tmp, mode);
+    if (kFailure != result) {
+        bm->swap(tmp);
+    }
+    return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, SkColorType pref,  Mode mode,
+                                Format* format) {
+    SkASSERT(file);
+    SkASSERT(bm);
+
+    SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(file));
+    if (stream.get()) {
+        if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) {
+            if (SkPixelRef* pr = bm->pixelRef()) {
+                pr->setURI(file);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, SkColorType pref,
+                                  Mode mode, Format* format) {
+    if (0 == size) {
+        return false;
+    }
+    SkASSERT(buffer);
+
+    SkMemoryStream  stream(buffer, size);
+    return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
+}
+
+bool SkImageDecoder::DecodeStream(SkStreamRewindable* stream, SkBitmap* bm, SkColorType pref,
+                                  Mode mode, Format* format) {
+    SkASSERT(stream);
+    SkASSERT(bm);
+
+    bool success = false;
+    SkImageDecoder* codec = SkImageDecoder::Factory(stream);
+
+    if (codec) {
+        success = codec->decode(stream, bm, pref, mode) != kFailure;
+        if (success && format) {
+            *format = codec->getFormat();
+            if (kUnknown_Format == *format) {
+                if (stream->rewind()) {
+                    *format = GetStreamFormat(stream);
+                }
+            }
+        }
+        delete codec;
+    }
+    return success;
+}
+
+bool SkImageDecoder::decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3],
+                                      size_t rowBytes[3], SkYUVColorSpace* colorSpace) {
+    // we reset this to false before calling onDecodeYUV8Planes
+    fShouldCancelDecode = false;
+
+    return this->onDecodeYUV8Planes(stream, componentSizes, planes, rowBytes, colorSpace);
+}
diff --git a/src/images/SkImageDecoder_FactoryDefault.cpp b/src/images/SkImageDecoder_FactoryDefault.cpp
index ef8ddda..77c0a0a 100644
--- a/src/images/SkImageDecoder_FactoryDefault.cpp
+++ b/src/images/SkImageDecoder_FactoryDefault.cpp
@@ -6,9 +6,18 @@
  * found in the LICENSE file.
  */
 
+#include "SkImageDecoder.h"
 #include "SkMovie.h"
 #include "SkStream.h"
 
+extern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*);
+
+SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) {
+    return image_decoder_from_stream(stream);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
 typedef SkTRegistry<SkMovie*(*)(SkStreamRewindable*)> MovieReg;
 
 SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) {
diff --git a/src/images/SkImageDecoder_FactoryRegistrar.cpp b/src/images/SkImageDecoder_FactoryRegistrar.cpp
new file mode 100644
index 0000000..36034d2
--- /dev/null
+++ b/src/images/SkImageDecoder_FactoryRegistrar.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkErrorInternals.h"
+#include "SkImageDecoder.h"
+#include "SkStream.h"
+#include "SkTRegistry.h"
+
+// This file is used for registration of SkImageDecoders. It also holds a function
+// for checking all the the registered SkImageDecoders for one that matches an
+// input SkStreamRewindable.
+
+template SkImageDecoder_DecodeReg* SkImageDecoder_DecodeReg::gHead;
+
+SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*);
+
+SkImageDecoder* image_decoder_from_stream(SkStreamRewindable* stream) {
+    SkImageDecoder* codec = nullptr;
+    const SkImageDecoder_DecodeReg* curr = SkImageDecoder_DecodeReg::Head();
+    while (curr) {
+        codec = curr->factory()(stream);
+        // we rewind here, because we promise later when we call "decode", that
+        // the stream will be at its beginning.
+        bool rewindSuceeded = stream->rewind();
+
+        // our image decoder's require that rewind is supported so we fail early
+        // if we are given a stream that does not support rewinding.
+        if (!rewindSuceeded) {
+            SkDEBUGF(("Unable to rewind the image stream."));
+            delete codec;
+            return nullptr;
+        }
+
+        if (codec) {
+            return codec;
+        }
+        curr = curr->next();
+    }
+    return nullptr;
+}
+
+template SkImageDecoder_FormatReg* SkImageDecoder_FormatReg::gHead;
+
+SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable* stream) {
+    const SkImageDecoder_FormatReg* curr = SkImageDecoder_FormatReg::Head();
+    while (curr != nullptr) {
+        Format format = curr->factory()(stream);
+        if (!stream->rewind()) {
+            SkErrorInternals::SetError(kInvalidOperation_SkError,
+                                       "Unable to rewind the image stream\n");
+            return kUnknown_Format;
+        }
+        if (format != kUnknown_Format) {
+            return format;
+        }
+        curr = curr->next();
+    }
+    return kUnknown_Format;
+}
diff --git a/src/images/SkImageDecoder_astc.cpp b/src/images/SkImageDecoder_astc.cpp
new file mode 100644
index 0000000..30d65f1
--- /dev/null
+++ b/src/images/SkImageDecoder_astc.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkData.h"
+#include "SkEndian.h"
+#include "SkColorPriv.h"
+#include "SkImageDecoder.h"
+#include "SkScaledBitmapSampler.h"
+#include "SkStream.h"
+#include "SkStreamPriv.h"
+#include "SkTypes.h"
+
+#include "SkTextureCompressor.h"
+
+class SkASTCImageDecoder : public SkImageDecoder {
+public:
+    SkASTCImageDecoder() { }
+
+    Format getFormat() const override {
+        return kASTC_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static const uint32_t kASTCMagicNumber = 0x5CA1AB13;
+
+static inline int read_24bit(const uint8_t* buf) {
+    // Assume everything is little endian...
+    return
+        static_cast<int>(buf[0]) |
+        (static_cast<int>(buf[1]) << 8) |
+        (static_cast<int>(buf[2]) << 16);
+}
+
+SkImageDecoder::Result SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    auto data = SkCopyStreamToData(stream);
+    if (!data || !data->size()) {
+        return kFailure;
+    }
+
+    unsigned char* buf = (unsigned char*) data->data();
+
+    // Make sure that the magic header is there...
+    SkASSERT(SkEndian_SwapLE32(*(reinterpret_cast<uint32_t*>(buf))) == kASTCMagicNumber);
+
+    // Advance past the magic header
+    buf += 4;
+
+    const int blockDimX = buf[0];
+    const int blockDimY = buf[1];
+    const int blockDimZ = buf[2];
+
+    if (1 != blockDimZ) {
+        // We don't support decoding 3D
+        return kFailure;
+    }
+
+    // Choose the proper ASTC format
+    SkTextureCompressor::Format astcFormat;
+    if (4 == blockDimX && 4 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_4x4_Format;
+    } else if (5 == blockDimX && 4 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_5x4_Format;
+    } else if (5 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_5x5_Format;
+    } else if (6 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_6x5_Format;
+    } else if (6 == blockDimX && 6 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_6x6_Format;
+    } else if (8 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_8x5_Format;
+    } else if (8 == blockDimX && 6 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_8x6_Format;
+    } else if (8 == blockDimX && 8 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_8x8_Format;
+    } else if (10 == blockDimX && 5 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x5_Format;
+    } else if (10 == blockDimX && 6 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x6_Format;
+    } else if (10 == blockDimX && 8 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x8_Format;
+    } else if (10 == blockDimX && 10 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_10x10_Format;
+    } else if (12 == blockDimX && 10 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_12x10_Format;
+    } else if (12 == blockDimX && 12 == blockDimY) {
+        astcFormat = SkTextureCompressor::kASTC_12x12_Format;
+    } else {
+        // We don't support any other block dimensions..
+        return kFailure;
+    }
+
+    // Advance buf past the block dimensions
+    buf += 3;
+
+    // Read the width/height/depth from the buffer...
+    const int width = read_24bit(buf);
+    const int height = read_24bit(buf + 3);
+    const int depth = read_24bit(buf + 6);
+
+    if (1 != depth) {
+        // We don't support decoding 3D.
+        return kFailure;
+    }
+
+    // Advance the buffer past the image dimensions
+    buf += 9;
+
+    // Setup the sampler...
+    SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
+
+    // Determine the alpha of the bitmap...
+    SkAlphaType alphaType = kOpaque_SkAlphaType;
+    if (this->getRequireUnpremultipliedColors()) {
+        alphaType = kUnpremul_SkAlphaType;
+    } else {
+        alphaType = kPremul_SkAlphaType;
+    }
+
+    // Set the config...
+    bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), alphaType));
+
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    if (!this->allocPixelRef(bm, nullptr)) {
+        return kFailure;
+    }
+
+    // Lock the pixels, since we're about to write to them...
+    SkAutoLockPixels alp(*bm);
+
+    if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, *this)) {
+        return kFailure;
+    }
+
+    // ASTC Data is encoded as RGBA pixels, so we should extract it as such
+    int nPixels = width * height;
+    SkAutoMalloc outRGBAData(nPixels * 4);
+    uint8_t *outRGBADataPtr = reinterpret_cast<uint8_t *>(outRGBAData.get());
+
+    // Decode ASTC
+    if (!SkTextureCompressor::DecompressBufferFromFormat(
+            outRGBADataPtr, width*4, buf, width, height, astcFormat)) {
+        return kFailure;
+    }
+
+    // Set each of the pixels...
+    const int srcRowBytes = width * 4;
+    const int dstHeight = sampler.scaledHeight();
+    const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBADataPtr);
+    srcRow += sampler.srcY0() * srcRowBytes;
+    for (int y = 0; y < dstHeight; ++y) {
+        sampler.next(srcRow);
+        srcRow += sampler.srcDY() * srcRowBytes;
+    }
+
+    return kSuccess;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(ASTCImageDecoder);
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static bool is_astc(SkStreamRewindable* stream) {
+    // Read the ASTC header and make sure it's valid.
+    uint32_t magic;
+    if (stream->read((void*)&magic, 4) != 4) {
+        return false;
+    }
+
+    return kASTCMagicNumber == SkEndian_SwapLE32(magic);
+}
+
+static SkImageDecoder* sk_libastc_dfactory(SkStreamRewindable* stream) {
+    if (is_astc(stream)) {
+        return new SkASTCImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder_DecodeReg gReg(sk_libastc_dfactory);
+
+static SkImageDecoder::Format get_format_astc(SkStreamRewindable* stream) {
+    if (is_astc(stream)) {
+        return SkImageDecoder::kASTC_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_astc);
diff --git a/src/images/SkImageDecoder_ktx.cpp b/src/images/SkImageDecoder_ktx.cpp
index 79f0293..1566745 100644
--- a/src/images/SkImageDecoder_ktx.cpp
+++ b/src/images/SkImageDecoder_ktx.cpp
@@ -6,9 +6,10 @@
  */
 
 #include "SkColorPriv.h"
-#include "SkImageEncoder.h"
+#include "SkImageDecoder.h"
 #include "SkImageGenerator.h"
 #include "SkPixelRef.h"
+#include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
 #include "SkStreamPriv.h"
 #include "SkTypes.h"
@@ -16,14 +17,230 @@
 #include "ktx.h"
 #include "etc1.h"
 
-///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
 
-// KTX Image Encoder
-//
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+// KTX Image decoder
+// ---
 // KTX is a general texture data storage file format ratified by the Khronos Group. As an
 // overview, a KTX file contains all of the appropriate values needed to fully specify a
 // texture in an OpenGL application, including the use of compressed data.
 //
+// This decoder is meant to be used with an SkDiscardablePixelRef so that GPU backends
+// can sniff the data before creating a texture. If they encounter a compressed format
+// that they understand, they can then upload the data directly to the GPU. Otherwise,
+// they will decode the data into a format that Skia supports.
+
+class SkKTXImageDecoder : public SkImageDecoder {
+public:
+    SkKTXImageDecoder() { }
+
+    Format getFormat() const override {
+        return kKTX_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+SkImageDecoder::Result SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    // TODO: Implement SkStream::copyToData() that's cheap for memory and file streams
+    auto data = SkCopyStreamToData(stream);
+    if (nullptr == data) {
+        return kFailure;
+    }
+
+    SkKTXFile ktxFile(data.get());
+    if (!ktxFile.valid()) {
+        return kFailure;
+    }
+
+    const unsigned short width = ktxFile.width();
+    const unsigned short height = ktxFile.height();
+
+    // Set a flag if our source is premultiplied alpha
+    const SkString premulKey("KTXPremultipliedAlpha");
+    const bool bSrcIsPremul = ktxFile.getValueForKey(premulKey) == SkString("True");
+
+    // Setup the sampler...
+    SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
+
+    // Determine the alpha of the bitmap...
+    SkAlphaType alphaType = kOpaque_SkAlphaType;
+    if (ktxFile.isRGBA8()) {
+        if (this->getRequireUnpremultipliedColors()) {
+            alphaType = kUnpremul_SkAlphaType;
+            // If the client wants unpremul colors and we only have
+            // premul, then we cannot honor their wish.
+            if (bSrcIsPremul) {
+                return kFailure;
+            }
+        } else {
+            alphaType = kPremul_SkAlphaType;
+        }
+    }
+
+    // Search through the compressed formats to see if the KTX file is holding
+    // compressed data
+    bool ktxIsCompressed = false;
+    SkTextureCompressor::Format ktxCompressedFormat;
+    for (int i = 0; i < SkTextureCompressor::kFormatCnt; ++i) {
+        SkTextureCompressor::Format fmt = static_cast<SkTextureCompressor::Format>(i);
+        if (ktxFile.isCompressedFormat(fmt)) {
+            ktxIsCompressed = true;
+            ktxCompressedFormat = fmt;
+            break;
+        }
+    }
+
+    // If the compressed format is a grayscale image, then setup the bitmap properly...
+    bool isCompressedAlpha = ktxIsCompressed &&
+        ((SkTextureCompressor::kLATC_Format == ktxCompressedFormat) ||
+         (SkTextureCompressor::kR11_EAC_Format == ktxCompressedFormat));
+
+    // Set the image dimensions and underlying pixel type.
+    if (isCompressedAlpha) {
+        const int w = sampler.scaledWidth();
+        const int h = sampler.scaledHeight();
+        bm->setInfo(SkImageInfo::MakeA8(w, h));
+    } else {
+        const int w = sampler.scaledWidth();
+        const int h = sampler.scaledHeight();
+        bm->setInfo(SkImageInfo::MakeN32(w, h, alphaType));
+    }
+    
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    // If we've made it this far, then we know how to grok the data.
+    if (!this->allocPixelRef(bm, nullptr)) {
+        return kFailure;
+    }
+
+    // Lock the pixels, since we're about to write to them...
+    SkAutoLockPixels alp(*bm);
+
+    if (isCompressedAlpha) {
+        if (!sampler.begin(bm, SkScaledBitmapSampler::kGray, *this)) {
+            return kFailure;
+        }
+
+        // Alpha data is only a single byte per pixel.
+        int nPixels = width * height;
+        SkAutoMalloc outRGBData(nPixels);
+        uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
+
+        // Decode the compressed format
+        const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData());
+        if (!SkTextureCompressor::DecompressBufferFromFormat(
+                outRGBDataPtr, width, buf, width, height, ktxCompressedFormat)) {
+            return kFailure;
+        }
+
+        // Set each of the pixels...
+        const int srcRowBytes = width;
+        const int dstHeight = sampler.scaledHeight();
+        const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr);
+        srcRow += sampler.srcY0() * srcRowBytes;
+        for (int y = 0; y < dstHeight; ++y) {
+            sampler.next(srcRow);
+            srcRow += sampler.srcDY() * srcRowBytes;
+        }
+
+        return kSuccess;
+
+    } else if (ktxFile.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
+        if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
+            return kFailure;
+        }
+
+        // ETC1 Data is encoded as RGB pixels, so we should extract it as such
+        int nPixels = width * height;
+        SkAutoMalloc outRGBData(nPixels * 3);
+        uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
+
+        // Decode ETC1
+        const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData());
+        if (!SkTextureCompressor::DecompressBufferFromFormat(
+                outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) {
+            return kFailure;
+        }
+
+        // Set each of the pixels...
+        const int srcRowBytes = width * 3;
+        const int dstHeight = sampler.scaledHeight();
+        const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr);
+        srcRow += sampler.srcY0() * srcRowBytes;
+        for (int y = 0; y < dstHeight; ++y) {
+            sampler.next(srcRow);
+            srcRow += sampler.srcDY() * srcRowBytes;
+        }
+
+        return kSuccess;
+
+    } else if (ktxFile.isRGB8()) {
+
+        // Uncompressed RGB data (without alpha)
+        if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
+            return kFailure;
+        }
+
+        // Just need to read RGB pixels
+        const int srcRowBytes = width * 3;
+        const int dstHeight = sampler.scaledHeight();
+        const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelData());
+        srcRow += sampler.srcY0() * srcRowBytes;
+        for (int y = 0; y < dstHeight; ++y) {
+            sampler.next(srcRow);
+            srcRow += sampler.srcDY() * srcRowBytes;
+        }
+
+        return kSuccess;
+
+    } else if (ktxFile.isRGBA8()) {
+
+        // Uncompressed RGBA data
+
+        // If we know that the image contains premultiplied alpha, then
+        // we need to turn off the premultiplier
+        SkScaledBitmapSampler::Options opts (*this);
+        if (bSrcIsPremul) {
+            SkASSERT(bm->alphaType() == kPremul_SkAlphaType);
+            SkASSERT(!this->getRequireUnpremultipliedColors());
+
+            opts.fPremultiplyAlpha = false;
+        } 
+
+        if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, opts)) {
+            return kFailure;
+        }
+
+        // Just need to read RGBA pixels
+        const int srcRowBytes = width * 4;
+        const int dstHeight = sampler.scaledHeight();
+        const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelData());
+        srcRow += sampler.srcY0() * srcRowBytes;
+        for (int y = 0; y < dstHeight; ++y) {
+            sampler.next(srcRow);
+            srcRow += sampler.srcDY() * srcRowBytes;
+        }
+
+        return kSuccess;
+    }
+
+    return kFailure;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// KTX Image Encoder
+//
 // This encoder takes a best guess at how to encode the bitmap passed to it. If
 // there is an installed discardable pixel ref with existing PKM data, then we
 // will repurpose the existing ETC1 data into a KTX file. If the data contains
@@ -87,11 +304,28 @@
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(KTXImageDecoder);
 DEFINE_ENCODER_CREATOR(KTXImageEncoder);
 /////////////////////////////////////////////////////////////////////////////////////////
 
+static SkImageDecoder* sk_libktx_dfactory(SkStreamRewindable* stream) {
+    if (SkKTXFile::is_ktx(stream)) {
+        return new SkKTXImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder::Format get_format_ktx(SkStreamRewindable* stream) {
+    if (SkKTXFile::is_ktx(stream)) {
+        return SkImageDecoder::kKTX_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
 SkImageEncoder* sk_libktx_efactory(SkImageEncoder::Type t) {
     return (SkImageEncoder::kKTX_Type == t) ? new SkKTXImageEncoder : nullptr;
 }
 
+static SkImageDecoder_DecodeReg gReg(sk_libktx_dfactory);
+static SkImageDecoder_FormatReg gFormatReg(get_format_ktx);
 static SkImageEncoder_EncodeReg gEReg(sk_libktx_efactory);
diff --git a/src/images/SkImageDecoder_libbmp.cpp b/src/images/SkImageDecoder_libbmp.cpp
new file mode 100644
index 0000000..b9359be
--- /dev/null
+++ b/src/images/SkImageDecoder_libbmp.cpp
@@ -0,0 +1,166 @@
+
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "bmpdecoderhelper.h"
+#include "SkColorPriv.h"
+#include "SkData.h"
+#include "SkImageDecoder.h"
+#include "SkScaledBitmapSampler.h"
+#include "SkStream.h"
+#include "SkStreamPriv.h"
+#include "SkTDArray.h"
+
+class SkBMPImageDecoder : public SkImageDecoder {
+public:
+    SkBMPImageDecoder() {}
+
+    Format getFormat() const override {
+        return kBMP_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(BMPImageDecoder);
+///////////////////////////////////////////////////////////////////////////////
+
+static bool is_bmp(SkStreamRewindable* stream) {
+    static const char kBmpMagic[] = { 'B', 'M' };
+
+
+    char buffer[sizeof(kBmpMagic)];
+
+    return stream->read(buffer, sizeof(kBmpMagic)) == sizeof(kBmpMagic) &&
+        !memcmp(buffer, kBmpMagic, sizeof(kBmpMagic));
+}
+
+static SkImageDecoder* sk_libbmp_dfactory(SkStreamRewindable* stream) {
+    if (is_bmp(stream)) {
+        return new SkBMPImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder_DecodeReg gReg(sk_libbmp_dfactory);
+
+static SkImageDecoder::Format get_format_bmp(SkStreamRewindable* stream) {
+    if (is_bmp(stream)) {
+        return SkImageDecoder::kBMP_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_bmp);
+
+///////////////////////////////////////////////////////////////////////////////
+
+class SkBmpDecoderCallback : public image_codec::BmpDecoderCallback {
+public:
+    // we don't copy the bitmap, just remember the pointer
+    SkBmpDecoderCallback(bool justBounds) : fJustBounds(justBounds) {}
+
+    // override from BmpDecoderCallback
+    virtual uint8* SetSize(int width, int height) {
+        fWidth = width;
+        fHeight = height;
+        if (fJustBounds) {
+            return nullptr;
+        }
+
+        fRGB.setCount(width * height * 3);  // 3 == r, g, b
+        return fRGB.begin();
+    }
+
+    int width() const { return fWidth; }
+    int height() const { return fHeight; }
+    const uint8_t* rgb() const { return fRGB.begin(); }
+
+private:
+    SkTDArray<uint8_t> fRGB;
+    int fWidth;
+    int fHeight;
+    bool fJustBounds;
+};
+
+SkImageDecoder::Result SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    // First read the entire stream, so that all of the data can be passed to
+    // the BmpDecoderHelper.
+
+    auto data = SkCopyStreamToData(stream);
+    if (!data) {
+        return kFailure;
+    }
+
+    // Byte length of all of the data.
+    const size_t length = data->size();
+    if (0 == length) {
+        return kFailure;
+    }
+
+    const bool justBounds = SkImageDecoder::kDecodeBounds_Mode == mode;
+    SkBmpDecoderCallback callback(justBounds);
+
+    // Now decode the BMP into callback's rgb() array [r,g,b, r,g,b, ...]
+    {
+        image_codec::BmpDecoderHelper helper;
+        const int max_pixels = 16383*16383; // max width*height
+        if (!helper.DecodeImage((const char*) data->data(), length,
+                                max_pixels, &callback)) {
+            return kFailure;
+        }
+    }
+
+    // we don't need this anymore, so free it now (before we try to allocate
+    // the bitmap's pixels) rather than waiting for its destructor
+    data.reset(nullptr);
+
+    int width = callback.width();
+    int height = callback.height();
+    SkColorType colorType = this->getPrefColorType(k32Bit_SrcDepth, false);
+
+    // only accept prefConfig if it makes sense for us
+    if (kARGB_4444_SkColorType != colorType && kRGB_565_SkColorType != colorType) {
+        colorType = kN32_SkColorType;
+    }
+
+    SkScaledBitmapSampler sampler(width, height, getSampleSize());
+
+    bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
+                                  colorType, kOpaque_SkAlphaType));
+
+    if (justBounds) {
+        return kSuccess;
+    }
+
+    if (!this->allocPixelRef(bm, nullptr)) {
+        return kFailure;
+    }
+
+    SkAutoLockPixels alp(*bm);
+
+    if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
+        return kFailure;
+    }
+
+    const int srcRowBytes = width * 3;
+    const int dstHeight = sampler.scaledHeight();
+    const uint8_t* srcRow = callback.rgb();
+
+    srcRow += sampler.srcY0() * srcRowBytes;
+    for (int y = 0; y < dstHeight; y++) {
+        sampler.next(srcRow);
+        srcRow += sampler.srcDY() * srcRowBytes;
+    }
+    return kSuccess;
+}
diff --git a/src/images/SkImageDecoder_libgif.cpp b/src/images/SkImageDecoder_libgif.cpp
new file mode 100644
index 0000000..2677b13
--- /dev/null
+++ b/src/images/SkImageDecoder_libgif.cpp
@@ -0,0 +1,541 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkColor.h"
+#include "SkColorPriv.h"
+#include "SkColorTable.h"
+#include "SkImageDecoder.h"
+#include "SkRTConf.h"
+#include "SkScaledBitmapSampler.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include "SkUtils.h"
+
+#include "gif_lib.h"
+
+class SkGIFImageDecoder : public SkImageDecoder {
+public:
+    Format getFormat() const override {
+        return kGIF_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+static const uint8_t gStartingIterlaceYValue[] = {
+    0, 4, 2, 1
+};
+static const uint8_t gDeltaIterlaceYValue[] = {
+    8, 8, 4, 2
+};
+
+SK_CONF_DECLARE(bool, c_suppressGIFImageDecoderWarnings,
+                "images.gif.suppressDecoderWarnings", true,
+                "Suppress GIF warnings and errors when calling image decode "
+                "functions.");
+
+
+/*  Implement the GIF interlace algorithm in an iterator.
+    1) grab every 8th line beginning at 0
+    2) grab every 8th line beginning at 4
+    3) grab every 4th line beginning at 2
+    4) grab every 2nd line beginning at 1
+*/
+class GifInterlaceIter {
+public:
+    GifInterlaceIter(int height) : fHeight(height) {
+        fStartYPtr = gStartingIterlaceYValue;
+        fDeltaYPtr = gDeltaIterlaceYValue;
+
+        fCurrY = *fStartYPtr++;
+        fDeltaY = *fDeltaYPtr++;
+    }
+
+    int currY() const {
+        SkASSERT(fStartYPtr);
+        SkASSERT(fDeltaYPtr);
+        return fCurrY;
+    }
+
+    void next() {
+        SkASSERT(fStartYPtr);
+        SkASSERT(fDeltaYPtr);
+
+        int y = fCurrY + fDeltaY;
+        // We went from an if statement to a while loop so that we iterate
+        // through fStartYPtr until a valid row is found. This is so that images
+        // that are smaller than 5x5 will not trash memory.
+        while (y >= fHeight) {
+            if (gStartingIterlaceYValue +
+                    SK_ARRAY_COUNT(gStartingIterlaceYValue) == fStartYPtr) {
+                // we done
+                SkDEBUGCODE(fStartYPtr = nullptr;)
+                SkDEBUGCODE(fDeltaYPtr = nullptr;)
+                y = 0;
+            } else {
+                y = *fStartYPtr++;
+                fDeltaY = *fDeltaYPtr++;
+            }
+        }
+        fCurrY = y;
+    }
+
+private:
+    const int fHeight;
+    int fCurrY;
+    int fDeltaY;
+    const uint8_t* fStartYPtr;
+    const uint8_t* fDeltaYPtr;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static int DecodeCallBackProc(GifFileType* fileType, GifByteType* out,
+                              int size) {
+    SkStream* stream = (SkStream*) fileType->UserData;
+    return (int) stream->read(out, size);
+}
+
+void CheckFreeExtension(SavedImage* Image) {
+    if (Image->ExtensionBlocks) {
+#if GIFLIB_MAJOR < 5
+        FreeExtension(Image);
+#else
+        GifFreeExtensions(&Image->ExtensionBlockCount, &Image->ExtensionBlocks);
+#endif
+    }
+}
+
+// return nullptr on failure
+static const ColorMapObject* find_colormap(const GifFileType* gif) {
+    const ColorMapObject* cmap = gif->Image.ColorMap;
+    if (nullptr == cmap) {
+        cmap = gif->SColorMap;
+    }
+
+    if (nullptr == cmap) {
+        // no colormap found
+        return nullptr;
+    }
+    // some sanity checks
+    if (cmap && ((unsigned)cmap->ColorCount > 256 ||
+                 cmap->ColorCount != (1 << cmap->BitsPerPixel))) {
+        cmap = nullptr;
+    }
+    return cmap;
+}
+
+// return -1 if not found (i.e. we're completely opaque)
+static int find_transpIndex(const SavedImage& image, int colorCount) {
+    int transpIndex = -1;
+    for (int i = 0; i < image.ExtensionBlockCount; ++i) {
+        const ExtensionBlock* eb = image.ExtensionBlocks + i;
+        if (eb->Function == 0xF9 && eb->ByteCount == 4) {
+            if (eb->Bytes[0] & 1) {
+                transpIndex = (unsigned char)eb->Bytes[3];
+                // check for valid transpIndex
+                if (transpIndex >= colorCount) {
+                    transpIndex = -1;
+                }
+                break;
+            }
+        }
+    }
+    return transpIndex;
+}
+
+static SkImageDecoder::Result error_return(const SkBitmap& bm, const char msg[]) {
+    if (!c_suppressGIFImageDecoderWarnings) {
+        SkDebugf("libgif error [%s] bitmap [%d %d] pixels %p colortable %p\n",
+                 msg, bm.width(), bm.height(), bm.getPixels(),
+                 bm.getColorTable());
+    }
+    return SkImageDecoder::kFailure;
+}
+
+static void gif_warning(const SkBitmap& bm, const char msg[]) {
+    if (!c_suppressGIFImageDecoderWarnings) {
+        SkDebugf("libgif warning [%s] bitmap [%d %d] pixels %p colortable %p\n",
+                 msg, bm.width(), bm.height(), bm.getPixels(),
+                 bm.getColorTable());
+    }
+}
+
+/**
+ *  Skip rows in the source gif image.
+ *  @param gif Source image.
+ *  @param dst Scratch output needed by gif library call. Must be >= width bytes.
+ *  @param width Bytes per row in the source image.
+ *  @param rowsToSkip Number of rows to skip.
+ *  @return True on success, false on GIF_ERROR.
+ */
+static bool skip_src_rows(GifFileType* gif, uint8_t* dst, int width, int rowsToSkip) {
+    for (int i = 0; i < rowsToSkip; i++) {
+        if (DGifGetLine(gif, dst, width) == GIF_ERROR) {
+            return false;
+        }
+    }
+    return true;
+}
+
+/**
+ *  GIFs with fewer then 256 color entries will sometimes index out of
+ *  bounds of the color table (this is malformed, but libgif does not
+ *  check sicne it is rare).  This function checks for this error and
+ *  fixes it.  This makes the output image consistantly deterministic.
+ */
+static void sanitize_indexed_bitmap(SkBitmap* bm) {
+    if ((kIndex_8_SkColorType == bm->colorType()) && !(bm->empty())) {
+        SkAutoLockPixels alp(*bm);
+        if (bm->getPixels()) {
+            SkColorTable* ct = bm->getColorTable();  // Index8 must have it.
+            SkASSERT(ct != nullptr);
+            uint32_t count = ct->count();
+            SkASSERT(count > 0);
+            SkASSERT(count <= 0x100);
+            if (count != 0x100) {  // Full colortables can't go wrong.
+                // Count is a power of 2; asserted elsewhere.
+                uint8_t byteMask = (~(count - 1));
+                bool warning = false;
+                uint8_t* addr = static_cast<uint8_t*>(bm->getPixels());
+                int height = bm->height();
+                int width = bm->width();
+                size_t rowBytes = bm->rowBytes();
+                while (--height >= 0) {
+                    uint8_t* ptr = addr;
+                    int x = width;
+                    while (--x >= 0) {
+                        if (0 != ((*ptr) & byteMask)) {
+                            warning = true;
+                            *ptr = 0;
+                        }
+                        ++ptr;
+                    }
+                    addr += rowBytes;
+                }
+                if (warning) {
+                    gif_warning(*bm, "Index out of bounds.");
+                }
+            }
+        }
+    }
+}
+
+namespace {
+// This function is a template argument, so can't be static.
+int close_gif(GifFileType* gif) {
+#if GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0)
+    return DGifCloseFile(gif);
+#else
+    return DGifCloseFile(gif, nullptr);
+#endif
+}
+}//namespace
+
+SkImageDecoder::Result SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) {
+#if GIFLIB_MAJOR < 5
+    GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc);
+#else
+    GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc, nullptr);
+#endif
+    if (nullptr == gif) {
+        return error_return(*bm, "DGifOpen");
+    }
+
+    SkAutoTCallIProc<GifFileType, close_gif> acp(gif);
+
+    SavedImage temp_save;
+    temp_save.ExtensionBlocks=nullptr;
+    temp_save.ExtensionBlockCount=0;
+    SkAutoTCallVProc<SavedImage, CheckFreeExtension> acp2(&temp_save);
+
+    int width, height;
+    GifRecordType recType;
+    GifByteType *extData;
+#if GIFLIB_MAJOR >= 5
+    int extFunction;
+#endif
+    int transpIndex = -1;   // -1 means we don't have it (yet)
+    int fillIndex = gif->SBackGroundColor;
+
+    do {
+        if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
+            return error_return(*bm, "DGifGetRecordType");
+        }
+
+        switch (recType) {
+        case IMAGE_DESC_RECORD_TYPE: {
+            if (DGifGetImageDesc(gif) == GIF_ERROR) {
+                return error_return(*bm, "IMAGE_DESC_RECORD_TYPE");
+            }
+
+            if (gif->ImageCount < 1) {    // sanity check
+                return error_return(*bm, "ImageCount < 1");
+            }
+
+            width = gif->SWidth;
+            height = gif->SHeight;
+
+            SavedImage* image = &gif->SavedImages[gif->ImageCount-1];
+            const GifImageDesc& desc = image->ImageDesc;
+
+            int imageLeft = desc.Left;
+            int imageTop = desc.Top;
+            const int innerWidth = desc.Width;
+            const int innerHeight = desc.Height;
+            if (innerWidth <= 0 || innerHeight <= 0) {
+                return error_return(*bm, "invalid dimensions");
+            }
+
+            // check for valid descriptor
+            if (innerWidth > width) {
+                gif_warning(*bm, "image too wide, expanding output to size");
+                width = innerWidth;
+                imageLeft = 0;
+            } else if (imageLeft + innerWidth > width) {
+                gif_warning(*bm, "shifting image left to fit");
+                imageLeft = width - innerWidth;
+            } else if (imageLeft < 0) {
+                gif_warning(*bm, "shifting image right to fit");
+                imageLeft = 0;
+            }
+
+
+            if (innerHeight > height) {
+                gif_warning(*bm, "image too tall,  expanding output to size");
+                height = innerHeight;
+                imageTop = 0;
+            } else if (imageTop + innerHeight > height) {
+                gif_warning(*bm, "shifting image up to fit");
+                imageTop = height - innerHeight;
+            } else if (imageTop < 0) {
+                gif_warning(*bm, "shifting image down to fit");
+                imageTop = 0;
+            }
+
+            SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
+
+            bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
+                                          kIndex_8_SkColorType, kPremul_SkAlphaType));
+
+            if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+                return kSuccess;
+            }
+
+
+            // now we decode the colortable
+            int colorCount = 0;
+            {
+                // Declare colorPtr here for scope.
+                SkPMColor colorPtr[256]; // storage for worst-case
+                const ColorMapObject* cmap = find_colormap(gif);
+                if (cmap != nullptr) {
+                    SkASSERT(cmap->ColorCount == (1 << (cmap->BitsPerPixel)));
+                    colorCount = cmap->ColorCount;
+                    if (colorCount > 256) {
+                        colorCount = 256;  // our kIndex8 can't support more
+                    }
+                    for (int index = 0; index < colorCount; index++) {
+                        colorPtr[index] = SkPackARGB32(0xFF,
+                                                       cmap->Colors[index].Red,
+                                                       cmap->Colors[index].Green,
+                                                       cmap->Colors[index].Blue);
+                    }
+                } else {
+                    // find_colormap() returned nullptr.  Some (rare, broken)
+                    // GIFs don't have a color table, so we force one.
+                    gif_warning(*bm, "missing colormap");
+                    colorCount = 256;
+                    sk_memset32(colorPtr, SK_ColorWHITE, colorCount);
+                }
+                transpIndex = find_transpIndex(temp_save, colorCount);
+                if (transpIndex >= 0) {
+                    colorPtr[transpIndex] = SK_ColorTRANSPARENT; // ram in a transparent SkPMColor
+                    fillIndex = transpIndex;
+                } else if (fillIndex >= colorCount) {
+                    // gif->SBackGroundColor should be less than colorCount.
+                    fillIndex = 0;  // If not, fix it.
+                }
+
+                SkAutoTUnref<SkColorTable> ctable(new SkColorTable(colorPtr, colorCount));
+                if (!this->allocPixelRef(bm, ctable)) {
+                    return error_return(*bm, "allocPixelRef");
+                }
+            }
+
+            // abort if either inner dimension is <= 0
+            if (innerWidth <= 0 || innerHeight <= 0) {
+                return error_return(*bm, "non-pos inner width/height");
+            }
+
+            SkAutoLockPixels alp(*bm);
+
+            SkAutoTMalloc<uint8_t> storage(innerWidth);
+            uint8_t* scanline = storage.get();
+
+            // GIF has an option to store the scanlines of an image, plus a larger background,
+            // filled by a fill color. In this case, we will use a subset of the larger bitmap
+            // for sampling.
+            SkBitmap subset;
+            SkBitmap* workingBitmap;
+            // are we only a subset of the total bounds?
+            if ((imageTop | imageLeft) > 0 ||
+                 innerWidth < width || innerHeight < height) {
+                // Fill the background.
+                memset(bm->getPixels(), fillIndex, bm->getSize());
+
+                // Create a subset of the bitmap.
+                SkIRect subsetRect(SkIRect::MakeXYWH(imageLeft / sampler.srcDX(),
+                                                     imageTop / sampler.srcDY(),
+                                                     innerWidth / sampler.srcDX(),
+                                                     innerHeight / sampler.srcDY()));
+                if (!bm->extractSubset(&subset, subsetRect)) {
+                    return error_return(*bm, "Extract failed.");
+                }
+                // Update the sampler. We'll now be only sampling into the subset.
+                sampler = SkScaledBitmapSampler(innerWidth, innerHeight, this->getSampleSize());
+                workingBitmap = &subset;
+            } else {
+                workingBitmap = bm;
+            }
+
+            // bm is already locked, but if we had to take a subset, it must be locked also,
+            // so that getPixels() will point to its pixels.
+            SkAutoLockPixels alpWorking(*workingBitmap);
+
+            if (!sampler.begin(workingBitmap, SkScaledBitmapSampler::kIndex, *this)) {
+                return error_return(*bm, "Sampler failed to begin.");
+            }
+
+            // now decode each scanline
+            if (gif->Image.Interlace) {
+                // Iterate over the height of the source data. The sampler will
+                // take care of skipping unneeded rows.
+                GifInterlaceIter iter(innerHeight);
+                for (int y = 0; y < innerHeight; y++) {
+                    if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) {
+                        gif_warning(*bm, "interlace DGifGetLine");
+                        memset(scanline, fillIndex, innerWidth);
+                        for (; y < innerHeight; y++) {
+                            sampler.sampleInterlaced(scanline, iter.currY());
+                            iter.next();
+                        }
+                        return kPartialSuccess;
+                    }
+                    sampler.sampleInterlaced(scanline, iter.currY());
+                    iter.next();
+                }
+            } else {
+                // easy, non-interlace case
+                const int outHeight = workingBitmap->height();
+                skip_src_rows(gif, scanline, innerWidth, sampler.srcY0());
+                for (int y = 0; y < outHeight; y++) {
+                    if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) {
+                        gif_warning(*bm, "DGifGetLine");
+                        memset(scanline, fillIndex, innerWidth);
+                        for (; y < outHeight; y++) {
+                            sampler.next(scanline);
+                        }
+                        return kPartialSuccess;
+                    }
+                    // scanline now contains the raw data. Sample it.
+                    sampler.next(scanline);
+                    if (y < outHeight - 1) {
+                        skip_src_rows(gif, scanline, innerWidth, sampler.srcDY() - 1);
+                    }
+                }
+                // skip the rest of the rows (if any)
+                int read = (outHeight - 1) * sampler.srcDY() + sampler.srcY0() + 1;
+                SkASSERT(read <= innerHeight);
+                skip_src_rows(gif, scanline, innerWidth, innerHeight - read);
+            }
+            sanitize_indexed_bitmap(bm);
+            return kSuccess;
+            } break;
+
+        case EXTENSION_RECORD_TYPE:
+#if GIFLIB_MAJOR < 5
+            if (DGifGetExtension(gif, &temp_save.Function,
+                                 &extData) == GIF_ERROR) {
+#else
+            if (DGifGetExtension(gif, &extFunction, &extData) == GIF_ERROR) {
+#endif
+                return error_return(*bm, "DGifGetExtension");
+            }
+
+            while (extData != nullptr) {
+                /* Create an extension block with our data */
+#if GIFLIB_MAJOR < 5
+                if (AddExtensionBlock(&temp_save, extData[0],
+                                      &extData[1]) == GIF_ERROR) {
+#else
+                if (GifAddExtensionBlock(&temp_save.ExtensionBlockCount,
+                                         &temp_save.ExtensionBlocks,
+                                         extFunction,
+                                         extData[0],
+                                         &extData[1]) == GIF_ERROR) {
+#endif
+                    return error_return(*bm, "AddExtensionBlock");
+                }
+                if (DGifGetExtensionNext(gif, &extData) == GIF_ERROR) {
+                    return error_return(*bm, "DGifGetExtensionNext");
+                }
+#if GIFLIB_MAJOR < 5
+                temp_save.Function = 0;
+#endif
+            }
+            break;
+
+        case TERMINATE_RECORD_TYPE:
+            break;
+
+        default:    /* Should be trapped by DGifGetRecordType */
+            break;
+        }
+    } while (recType != TERMINATE_RECORD_TYPE);
+
+    sanitize_indexed_bitmap(bm);
+    return kSuccess;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(GIFImageDecoder);
+///////////////////////////////////////////////////////////////////////////////
+
+static bool is_gif(SkStreamRewindable* stream) {
+    char buf[GIF_STAMP_LEN];
+    if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
+        if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
+                memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
+                memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static SkImageDecoder* sk_libgif_dfactory(SkStreamRewindable* stream) {
+    if (is_gif(stream)) {
+        return new SkGIFImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder_DecodeReg gReg(sk_libgif_dfactory);
+
+static SkImageDecoder::Format get_format_gif(SkStreamRewindable* stream) {
+    if (is_gif(stream)) {
+        return SkImageDecoder::kGIF_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_gif);
diff --git a/src/images/SkImageDecoder_libico.cpp b/src/images/SkImageDecoder_libico.cpp
new file mode 100644
index 0000000..ff04d74
--- /dev/null
+++ b/src/images/SkImageDecoder_libico.cpp
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkColorPriv.h"
+#include "SkData.h"
+#include "SkImageDecoder.h"
+#include "SkStream.h"
+#include "SkStreamPriv.h"
+#include "SkTypes.h"
+
+class SkICOImageDecoder : public SkImageDecoder {
+public:
+    SkICOImageDecoder();
+
+    Format getFormat() const override {
+        return kICO_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+//read bytes starting from the begin-th index in the buffer
+//read in Intel order, and return an integer
+
+#define readByte(buffer,begin) buffer[begin]
+#define read2Bytes(buffer,begin) buffer[begin]+SkLeftShift(buffer[begin+1],8)
+#define read4Bytes(buffer,begin) buffer[begin]+SkLeftShift(buffer[begin+1],8)+SkLeftShift(buffer[begin+2],16)+SkLeftShift(buffer[begin+3],24)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+SkICOImageDecoder::SkICOImageDecoder()
+{
+}
+
+//helpers - my function pointer will call one of these, depending on the bitCount, each time through the inner loop
+static void editPixelBit1(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors);
+static void editPixelBit4(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors);
+static void editPixelBit8(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors);
+static void editPixelBit24(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors);
+static void editPixelBit32(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors);
+
+
+static int calculateRowBytesFor8888(int w, int bitCount)
+{
+    //  Default rowBytes is w << 2 for kARGB_8888
+    //  In the case of a 4 bit image with an odd width, we need to add some
+    //  so we can go off the end of the drawn bitmap.
+    //  Add 4 to ensure that it is still a multiple of 4.
+    if (4 == bitCount && (w & 0x1)) {
+        return (w + 1) << 2;
+    }
+    //  Otherwise return 0, which will allow it to be calculated automatically.
+    return 0;
+}
+
+SkImageDecoder::Result SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    auto data = SkCopyStreamToData(stream);
+    if (!data) {
+        return kFailure;
+    }
+
+    const size_t length = data->size();
+    // Check that the buffer is large enough to read the directory header
+    if (length < 6) {
+        return kFailure;
+    }
+
+    unsigned char* buf = (unsigned char*) data->data();
+
+    //these should always be the same - should i use for error checking? - what about files that have some
+    //incorrect values, but still decode properly?
+    int reserved = read2Bytes(buf, 0);    // 0
+    int type = read2Bytes(buf, 2);        // 1
+    if (reserved != 0 || type != 1) {
+        return kFailure;
+    }
+
+    int count = read2Bytes(buf, 4);
+    // Check that there are directory entries
+    if (count < 1) {
+        return kFailure;
+    }
+
+    // Check that buffer is large enough to read directory entries.
+    // We are guaranteed that count is at least 1.  We might as well assume
+    // count is 1 because this deprecated decoder only looks at the first
+    // directory entry.
+    if (length < (size_t)(6 + count*16)) {
+        return kFailure;
+    }
+
+    //skip ahead to the correct header
+    //commented out lines are not used, but if i switch to other read method, need to know how many to skip
+    //otherwise, they could be used for error checking
+    int w = readByte(buf, 6);
+    int h = readByte(buf, 7);
+    SkASSERT(w >= 0 && h >= 0);
+    int colorCount = readByte(buf, 8);
+    //int reservedToo = readByte(buf, 9 + choice*16);   //0
+    //int planes = read2Bytes(buf, 10 + choice*16);       //1 - but often 0
+    //int fakeBitCount = read2Bytes(buf, 12 + choice*16); //should be real - usually 0
+    const size_t size = read4Bytes(buf, 14);           //matters?
+    const size_t offset = read4Bytes(buf, 18);
+    // promote the sum to 64-bits to avoid overflow
+    // Check that buffer is large enough to read image data
+    if (offset > length || size > length || ((uint64_t)offset + size) > length) {
+        return kFailure;
+    }
+
+    // Check to see if this is a PNG image inside the ICO
+    {
+        SkMemoryStream subStream(buf + offset, size, false);
+        SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subStream));
+        if (otherDecoder.get() != nullptr) {
+            // Disallow nesting ICO files within one another
+            // FIXME: Can ICO files contain other formats besides PNG?
+            if (otherDecoder->getFormat() == SkImageDecoder::kICO_Format) {
+                return kFailure;
+            }
+            // Set fields on the other decoder to be the same as this one.
+            this->copyFieldsToOther(otherDecoder.get());
+            const Result result = otherDecoder->decode(&subStream, bm, this->getDefaultPref(),
+                                                       mode);
+            // FIXME: Should we just return result here? Is it possible that data that looked like
+            // a subimage was not, but was actually a valid ICO?
+            if (result != kFailure) {
+                return result;
+            }
+        }
+    }
+
+    //int infoSize = read4Bytes(buf, offset);             //40
+    //int width = read4Bytes(buf, offset+4);              //should == w
+    //int height = read4Bytes(buf, offset+8);             //should == 2*h
+    //int planesToo = read2Bytes(buf, offset+12);         //should == 1 (does it?)
+    
+    // For ico images, only a byte is used to store each dimension
+    // 0 is used to represent 256
+    if (w == 0) {
+        w = 256;
+    }
+    if (h == 0) {
+        h = 256;
+    }
+
+    // Check that buffer is large enough to read the bit depth
+    if (length < offset + 16) {
+        return kFailure;
+    }
+    int bitCount = read2Bytes(buf, offset+14);
+
+    void (*placePixel)(const int pixelNo, const unsigned char* buf,
+        const int xorOffset, int& x, int y, const int w,
+        SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) = nullptr;
+    switch (bitCount)
+    {
+        case 1:
+            placePixel = &editPixelBit1;
+            colorCount = 2;
+            break;
+        case 4:
+            placePixel = &editPixelBit4;
+            colorCount = 16;
+            break;
+        case 8:
+            placePixel = &editPixelBit8;
+            colorCount = 256;
+            break;
+        case 24:
+            placePixel = &editPixelBit24;
+            colorCount = 0;
+            break;
+        case 32:
+            placePixel = &editPixelBit32;
+            colorCount = 0;
+            break;
+        default:
+            SkDEBUGF(("Decoding %ibpp is unimplemented\n", bitCount));
+            return kFailure;
+    }
+
+    //these should all be zero, but perhaps are not - need to check
+    //int compression = read4Bytes(buf, offset+16);       //0
+    //int imageSize = read4Bytes(buf, offset+20);         //0 - sometimes has a value
+    //int xPixels = read4Bytes(buf, offset+24);           //0
+    //int yPixels = read4Bytes(buf, offset+28);           //0
+    //int colorsUsed = read4Bytes(buf, offset+32)         //0 - might have an actual value though
+    //int colorsImportant = read4Bytes(buf, offset+36);   //0
+
+    int begin = SkToInt(offset + 40);
+    // Check that the buffer is large enough to read the color table
+    // For bmp-in-icos, there should be 4 bytes per color
+    if (length < (size_t) (begin + 4*colorCount)) {
+        return kFailure;
+    }
+
+    //this array represents the colortable
+    //if i allow other types of bitmaps, it may actually be used as a part of the bitmap
+    SkPMColor* colors = nullptr;
+    int blue, green, red;
+    if (colorCount)
+    {
+        colors = new SkPMColor[colorCount];
+        for (int j = 0; j < colorCount; j++)
+        {
+            //should this be a function - maybe a #define?
+            blue = readByte(buf, begin + 4*j);
+            green = readByte(buf, begin + 4*j + 1);
+            red = readByte(buf, begin + 4*j + 2);
+            colors[j] = SkPackARGB32(0xFF, red & 0xFF, green & 0xFF, blue & 0xFF);
+        }
+    }
+    int bitWidth = w*bitCount;
+    int test = bitWidth & 0x1F;
+    int mask = -(((test >> 4) | (test >> 3) | (test >> 2) | (test >> 1) | test) & 0x1);    //either 0xFFFFFFFF or 0
+    int lineBitWidth = (bitWidth & 0xFFFFFFE0) + (0x20 & mask);
+    int lineWidth = lineBitWidth/bitCount;
+
+    int xorOffset = begin + colorCount*4;   //beginning of the color bitmap
+                                            //other read method means we will just be here already
+    int andOffset = xorOffset + ((lineWidth*h*bitCount) >> 3);
+
+    /*int */test = w & 0x1F;   //the low 5 bits - we are rounding up to the next 32 (2^5)
+    /*int */mask = -(((test >> 4) | (test >> 3) | (test >> 2) | (test >> 1) | test) & 0x1);    //either 0xFFFFFFFF or 0
+    int andLineWidth = (w & 0xFFFFFFE0) + (0x20 & mask);
+    //if we allow different Configs, everything is the same til here
+    //change the config, and use different address getter, and place index vs color, and add the color table
+    //FIXME: what is the tradeoff in size?
+    //if the andbitmap (mask) is all zeroes, then we can easily do an index bitmap
+    //however, with small images with large colortables, maybe it's better to still do argb_8888
+
+    bm->setInfo(SkImageInfo::MakeN32Premul(w, h), calculateRowBytesFor8888(w, bitCount));
+
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        delete[] colors;
+        return kSuccess;
+    }
+
+    if (!this->allocPixelRef(bm, nullptr))
+    {
+        delete[] colors;
+        return kFailure;
+    }
+
+    // The AND mask is a 1-bit alpha mask for each pixel that comes after the
+    // XOR mask in the bmp.  If we check that the largest AND offset is safe,
+    // it should mean all other buffer accesses will be at smaller indices and
+    // will therefore be safe.
+    size_t maxAndOffset = andOffset + ((andLineWidth*(h-1)+(w-1)) >> 3);
+    if (length <= maxAndOffset) {
+        return kFailure;
+    }
+
+    // Here we assert that all reads from the buffer using the XOR offset are
+    // less than the AND offset.  This should be guaranteed based on the above
+    // calculations.
+#ifdef SK_DEBUG
+    int maxPixelNum = lineWidth*(h-1)+w-1;
+    int maxByte;
+    switch (bitCount) {
+        case 1:
+            maxByte = maxPixelNum >> 3;
+            break;
+        case 4:
+            maxByte = maxPixelNum >> 1;
+            break;
+        case 8:
+            maxByte = maxPixelNum;
+            break;
+        case 24:
+            maxByte = maxPixelNum * 3 + 2;
+            break;
+        case 32:
+            maxByte = maxPixelNum * 4 + 3;
+            break;
+        default:
+            SkASSERT(false);
+            return kFailure;
+    }
+    int maxXOROffset = xorOffset + maxByte;
+    SkASSERT(maxXOROffset < andOffset);
+#endif
+
+    SkAutoLockPixels alp(*bm);
+
+    for (int y = 0; y < h; y++)
+    {
+        for (int x = 0; x < w; x++)
+        {
+            //U32* address = bm->getAddr32(x, y);
+
+            //check the alpha bit first, but pass it along to the function to figure out how to deal with it
+            int andPixelNo = andLineWidth*(h-y-1)+x;
+            //only need to get a new alphaByte when x %8 == 0
+            //but that introduces an if and a mod - probably much slower
+            //that's ok, it's just a read of an array, not a stream
+            int alphaByte = readByte(buf, andOffset + (andPixelNo >> 3));
+            int shift = 7 - (andPixelNo & 0x7);
+            int m = 1 << shift;
+
+            int pixelNo = lineWidth*(h-y-1)+x;
+            placePixel(pixelNo, buf, xorOffset, x, y, w, bm, alphaByte, m, shift, colors);
+
+        }
+    }
+
+    delete [] colors;
+    //ensure we haven't read off the end?
+    //of course this doesn't help us if the andOffset was a lie...
+    //return andOffset + (andLineWidth >> 3) <= length;
+    return kSuccess;
+}   //onDecode
+
+//function to place the pixel, determined by the bitCount
+static void editPixelBit1(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors)
+{
+    // note that this should be the same as/similar to the AND bitmap
+    SkPMColor* address = bm->getAddr32(x,y);
+    int byte = readByte(buf, xorOffset + (pixelNo >> 3));
+    int colorBit;
+    int alphaBit;
+    // Read all of the bits in this byte.
+    int i = x + 8;
+    // Pin to the width so we do not write outside the bounds of
+    // our color table.
+    i = i > w ? w : i;
+    // While loop to check all 8 bits individually.
+    while (x < i)
+    {
+
+        colorBit = (byte & m) >> shift;
+        alphaBit = (alphaByte & m) >> shift;
+        *address = (alphaBit-1)&(colors[colorBit]);
+        x++;
+        // setup for the next pixel
+        address = address + 1;
+        m = m >> 1;
+        shift -= 1;
+    }
+    x--;
+}
+static void editPixelBit4(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors)
+{
+    SkPMColor* address = bm->getAddr32(x, y);
+    int byte = readByte(buf, xorOffset + (pixelNo >> 1));
+    int pixel = (byte >> 4) & 0xF;
+    int alphaBit = (alphaByte & m) >> shift;
+    *address = (alphaBit-1)&(colors[pixel]);
+    x++;
+    //if w is odd, x may be the same as w, which means we are writing to an unused portion of the bitmap
+    //but that's okay, since i've added an extra rowByte for just this purpose
+    address = address + 1;
+    pixel = byte & 0xF;
+    m = m >> 1;
+    alphaBit = (alphaByte & m) >> (shift-1);
+    //speed up trick here
+    *address = (alphaBit-1)&(colors[pixel]);
+}
+
+static void editPixelBit8(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors)
+{
+    SkPMColor* address = bm->getAddr32(x, y);
+    int pixel = readByte(buf, xorOffset + pixelNo);
+    int alphaBit = (alphaByte & m) >> shift;
+    *address = (alphaBit-1)&(colors[pixel]);
+}
+
+static void editPixelBit24(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors)
+{
+    SkPMColor* address = bm->getAddr32(x, y);
+    int blue = readByte(buf, xorOffset + 3*pixelNo);
+    int green = readByte(buf, xorOffset + 3*pixelNo + 1);
+    int red = readByte(buf, xorOffset + 3*pixelNo + 2);
+    int alphaBit = (alphaByte & m) >> shift;
+    //alphaBit == 1 => alpha = 0
+    int alpha = (alphaBit-1) & 0xFF;
+    *address = SkPreMultiplyARGB(alpha, red, green, blue);
+}
+
+static void editPixelBit32(const int pixelNo, const unsigned char* buf,
+            const int xorOffset, int& x, int y, const int w,
+            SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors)
+{
+    SkPMColor* address = bm->getAddr32(x, y);
+    int blue = readByte(buf, xorOffset + 4*pixelNo);
+    int green = readByte(buf, xorOffset + 4*pixelNo + 1);
+    int red = readByte(buf, xorOffset + 4*pixelNo + 2);
+    int alphaBit = (alphaByte & m) >> shift;
+#if 1 // don't trust the alphaBit for 32bit images <mrr>
+    alphaBit = 0;
+#endif
+    int alpha = readByte(buf, xorOffset + 4*pixelNo + 3) & ((alphaBit-1)&0xFF);
+    *address = SkPreMultiplyARGB(alpha, red, green, blue);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(ICOImageDecoder);
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static bool is_ico(SkStreamRewindable* stream) {
+    // Check to see if the first four bytes are 0,0,1,0
+    // FIXME: Is that required and sufficient?
+    char buf[4];
+    if (stream->read((void*)buf, 4) != 4) {
+        return false;
+    }
+    int reserved = read2Bytes(buf, 0);
+    int type = read2Bytes(buf, 2);
+    return 0 == reserved && 1 == type;
+}
+
+static SkImageDecoder* sk_libico_dfactory(SkStreamRewindable* stream) {
+    if (is_ico(stream)) {
+        return new SkICOImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder_DecodeReg gReg(sk_libico_dfactory);
+
+static SkImageDecoder::Format get_format_ico(SkStreamRewindable* stream) {
+    if (is_ico(stream)) {
+        return SkImageDecoder::kICO_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_ico);
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index fd10bdb..89bfefc 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -6,10 +6,13 @@
  */
 
 
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkJpegUtility.h"
 #include "SkColorPriv.h"
 #include "SkDither.h"
+#include "SkMSAN.h"
+#include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
 #include "SkTime.h"
@@ -25,12 +28,730 @@
     #include "jerror.h"
 }
 
-// These enable timing code that report milliseconds for an encoding
+// These enable timing code that report milliseconds for an encoding/decoding
 //#define TIME_ENCODE
+//#define TIME_DECODE
 
 // this enables our rgb->yuv code, which is faster than libjpeg on ARM
 #define WE_CONVERT_TO_YUV
 
+// If ANDROID_RGB is defined by in the jpeg headers it indicates that jpeg offers
+// support for two additional formats (1) JCS_RGBA_8888 and (2) JCS_RGB_565.
+
+#define DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_WARNINGS true
+#define DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_ERRORS true
+SK_CONF_DECLARE(bool, c_suppressJPEGImageDecoderWarnings,
+                "images.jpeg.suppressDecoderWarnings",
+                DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_WARNINGS,
+                "Suppress most JPG warnings when calling decode functions.");
+SK_CONF_DECLARE(bool, c_suppressJPEGImageDecoderErrors,
+                "images.jpeg.suppressDecoderErrors",
+                DEFAULT_FOR_SUPPRESS_JPEG_IMAGE_DECODER_ERRORS,
+                "Suppress most JPG error messages when decode "
+                "function fails.");
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+static void do_nothing_emit_message(jpeg_common_struct*, int) {
+    /* do nothing */
+}
+static void do_nothing_output_message(j_common_ptr) {
+    /* do nothing */
+}
+
+static void initialize_info(jpeg_decompress_struct* cinfo, skjpeg_source_mgr* src_mgr) {
+    SkASSERT(cinfo != nullptr);
+    SkASSERT(src_mgr != nullptr);
+    jpeg_create_decompress(cinfo);
+    cinfo->src = src_mgr;
+    /* To suppress warnings with a SK_DEBUG binary, set the
+     * environment variable "skia_images_jpeg_suppressDecoderWarnings"
+     * to "true".  Inside a program that links to skia:
+     * SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); */
+    if (c_suppressJPEGImageDecoderWarnings) {
+        cinfo->err->emit_message = &do_nothing_emit_message;
+    }
+    /* To suppress error messages with a SK_DEBUG binary, set the
+     * environment variable "skia_images_jpeg_suppressDecoderErrors"
+     * to "true".  Inside a program that links to skia:
+     * SK_CONF_SET("images.jpeg.suppressDecoderErrors", true); */
+    if (c_suppressJPEGImageDecoderErrors) {
+        cinfo->err->output_message = &do_nothing_output_message;
+    }
+}
+
+class SkJPEGImageDecoder : public SkImageDecoder {
+public:
+
+    Format getFormat() const override {
+        return kJPEG_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+    bool onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3],
+                            void* planes[3], size_t rowBytes[3],
+                            SkYUVColorSpace* colorSpace) override;
+
+private:
+
+    /**
+     *  Determine the appropriate bitmap colortype and out_color_space based on
+     *  both the preference of the caller and the jpeg_color_space on the
+     *  jpeg_decompress_struct passed in.
+     *  Must be called after jpeg_read_header.
+     */
+    SkColorType getBitmapColorType(jpeg_decompress_struct*);
+
+    typedef SkImageDecoder INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+/* Automatically clean up after throwing an exception */
+class JPEGAutoClean {
+public:
+    JPEGAutoClean(): cinfo_ptr(nullptr) {}
+    ~JPEGAutoClean() {
+        if (cinfo_ptr) {
+            jpeg_destroy_decompress(cinfo_ptr);
+        }
+    }
+    void set(jpeg_decompress_struct* info) {
+        cinfo_ptr = info;
+    }
+private:
+    jpeg_decompress_struct* cinfo_ptr;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/*  If we need to better match the request, we might examine the image and
+     output dimensions, and determine if the downsampling jpeg provided is
+     not sufficient. If so, we can recompute a modified sampleSize value to
+     make up the difference.
+
+     To skip this additional scaling, just set sampleSize = 1; below.
+ */
+static int recompute_sampleSize(int sampleSize,
+                                const jpeg_decompress_struct& cinfo) {
+    return sampleSize * cinfo.output_width / cinfo.image_width;
+}
+
+static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) {
+    /* These are initialized to 0, so if they have non-zero values, we assume
+       they are "valid" (i.e. have been computed by libjpeg)
+     */
+    return 0 != cinfo.output_width && 0 != cinfo.output_height;
+}
+
+static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count) {
+    for (int i = 0; i < count; i++) {
+        JSAMPLE* rowptr = (JSAMPLE*)buffer;
+        int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1);
+        if (1 != row_count) {
+            return false;
+        }
+    }
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This guy exists just to aid in debugging, as it allows debuggers to just
+// set a break-point in one place to see all error exists.
+static void print_jpeg_decoder_errors(const jpeg_decompress_struct& cinfo,
+                         int width, int height, const char caller[]) {
+    if (!(c_suppressJPEGImageDecoderErrors)) {
+        char buffer[JMSG_LENGTH_MAX];
+        cinfo.err->format_message((const j_common_ptr)&cinfo, buffer);
+        SkDebugf("libjpeg error %d <%s> from %s [%d %d]\n",
+                 cinfo.err->msg_code, buffer, caller, width, height);
+    }
+}
+
+static bool return_false(const jpeg_decompress_struct& cinfo,
+                         const char caller[]) {
+    print_jpeg_decoder_errors(cinfo, 0, 0, caller);
+    return false;
+}
+
+static SkImageDecoder::Result return_failure(const jpeg_decompress_struct& cinfo,
+                                             const SkBitmap& bm, const char caller[]) {
+    print_jpeg_decoder_errors(cinfo, bm.width(), bm.height(), caller);
+    return SkImageDecoder::kFailure;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Convert a scanline of CMYK samples to RGBX in place. Note that this
+// method moves the "scanline" pointer in its processing
+static void convert_CMYK_to_RGB(uint8_t* scanline, unsigned int width) {
+    // At this point we've received CMYK pixels from libjpeg. We
+    // perform a crude conversion to RGB (based on the formulae
+    // from easyrgb.com):
+    //  CMYK -> CMY
+    //    C = ( C * (1 - K) + K )      // for each CMY component
+    //  CMY -> RGB
+    //    R = ( 1 - C ) * 255          // for each RGB component
+    // Unfortunately we are seeing inverted CMYK so all the original terms
+    // are 1-. This yields:
+    //  CMYK -> CMY
+    //    C = ( (1-C) * (1 - (1-K) + (1-K) ) -> C = 1 - C*K
+    // The conversion from CMY->RGB remains the same
+    for (unsigned int x = 0; x < width; ++x, scanline += 4) {
+        scanline[0] = SkMulDiv255Round(scanline[0], scanline[3]);
+        scanline[1] = SkMulDiv255Round(scanline[1], scanline[3]);
+        scanline[2] = SkMulDiv255Round(scanline[2], scanline[3]);
+        scanline[3] = 255;
+    }
+}
+
+/**
+ *  Common code for setting the error manager.
+ */
+static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* errorManager) {
+    SkASSERT(cinfo != nullptr);
+    SkASSERT(errorManager != nullptr);
+    cinfo->err = jpeg_std_error(errorManager);
+    errorManager->error_exit = skjpeg_error_exit;
+}
+
+/**
+ * Common code for setting the dct method.
+ */
+static void set_dct_method(const SkImageDecoder& decoder, jpeg_decompress_struct* cinfo) {
+    SkASSERT(cinfo != nullptr);
+    cinfo->dct_method = JDCT_ISLOW;
+}
+
+SkColorType SkJPEGImageDecoder::getBitmapColorType(jpeg_decompress_struct* cinfo) {
+    SkASSERT(cinfo != nullptr);
+
+    SrcDepth srcDepth = k32Bit_SrcDepth;
+    if (JCS_GRAYSCALE == cinfo->jpeg_color_space) {
+        srcDepth = k8BitGray_SrcDepth;
+    }
+
+    SkColorType colorType = this->getPrefColorType(srcDepth, /*hasAlpha*/ false);
+    switch (colorType) {
+        case kAlpha_8_SkColorType:
+            // Only respect A8 colortype if the original is grayscale,
+            // in which case we will treat the grayscale as alpha
+            // values.
+            if (cinfo->jpeg_color_space != JCS_GRAYSCALE) {
+                colorType = kN32_SkColorType;
+            }
+            break;
+        case kN32_SkColorType:
+            // Fall through.
+        case kARGB_4444_SkColorType:
+            // Fall through.
+        case kRGB_565_SkColorType:
+            // These are acceptable destination colortypes.
+            break;
+        default:
+            // Force all other colortypes to 8888.
+            colorType = kN32_SkColorType;
+            break;
+    }
+
+    switch (cinfo->jpeg_color_space) {
+        case JCS_CMYK:
+            // Fall through.
+        case JCS_YCCK:
+            // libjpeg cannot convert from CMYK or YCCK to RGB - here we set up
+            // so libjpeg will give us CMYK samples back and we will later
+            // manually convert them to RGB
+            cinfo->out_color_space = JCS_CMYK;
+            break;
+        case JCS_GRAYSCALE:
+            if (kAlpha_8_SkColorType == colorType) {
+                cinfo->out_color_space = JCS_GRAYSCALE;
+                break;
+            }
+            // The data is JCS_GRAYSCALE, but the caller wants some sort of RGB
+            // colortype. Fall through to set to the default.
+        default:
+            cinfo->out_color_space = JCS_RGB;
+            break;
+    }
+    return colorType;
+}
+
+/**
+ *  Based on the colortype and dither mode, adjust out_color_space and
+ *  dither_mode of cinfo. Only does work in ANDROID_RGB
+ */
+static void adjust_out_color_space_and_dither(jpeg_decompress_struct* cinfo,
+                                              SkColorType colorType,
+                                              const SkImageDecoder& decoder) {
+    SkASSERT(cinfo != nullptr);
+#ifdef ANDROID_RGB
+    cinfo->dither_mode = JDITHER_NONE;
+    if (JCS_CMYK == cinfo->out_color_space) {
+        return;
+    }
+    switch (colorType) {
+        case kN32_SkColorType:
+            cinfo->out_color_space = JCS_RGBA_8888;
+            break;
+        case kRGB_565_SkColorType:
+            cinfo->out_color_space = JCS_RGB_565;
+            if (decoder.getDitherImage()) {
+                cinfo->dither_mode = JDITHER_ORDERED;
+            }
+            break;
+        default:
+            break;
+    }
+#endif
+}
+
+/**
+   Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y.
+   Used when decoding fails partway through reading scanlines to fill
+   remaining lines. */
+static void fill_below_level(int y, SkBitmap* bitmap) {
+    SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height());
+    SkCanvas canvas(*bitmap);
+    canvas.clipRect(SkRect::Make(rect));
+    canvas.drawColor(SK_ColorWHITE);
+}
+
+/**
+ *  Get the config and bytes per pixel of the source data. Return
+ *  whether the data is supported.
+ */
+static bool get_src_config(const jpeg_decompress_struct& cinfo,
+                           SkScaledBitmapSampler::SrcConfig* sc,
+                           int* srcBytesPerPixel) {
+    SkASSERT(sc != nullptr && srcBytesPerPixel != nullptr);
+    if (JCS_CMYK == cinfo.out_color_space) {
+        // In this case we will manually convert the CMYK values to RGB
+        *sc = SkScaledBitmapSampler::kRGBX;
+        // The CMYK work-around relies on 4 components per pixel here
+        *srcBytesPerPixel = 4;
+    } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_space) {
+        *sc = SkScaledBitmapSampler::kRGB;
+        *srcBytesPerPixel = 3;
+#ifdef ANDROID_RGB
+    } else if (JCS_RGBA_8888 == cinfo.out_color_space) {
+        *sc = SkScaledBitmapSampler::kRGBX;
+        *srcBytesPerPixel = 4;
+    } else if (JCS_RGB_565 == cinfo.out_color_space) {
+        *sc = SkScaledBitmapSampler::kRGB_565;
+        *srcBytesPerPixel = 2;
+#endif
+    } else if (1 == cinfo.out_color_components &&
+               JCS_GRAYSCALE == cinfo.out_color_space) {
+        *sc = SkScaledBitmapSampler::kGray;
+        *srcBytesPerPixel = 1;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+SkImageDecoder::Result SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+#ifdef TIME_DECODE
+    SkAutoTime atm("JPEG Decode");
+#endif
+
+    JPEGAutoClean autoClean;
+
+    jpeg_decompress_struct  cinfo;
+    skjpeg_source_mgr       srcManager(stream, this);
+
+    skjpeg_error_mgr errorManager;
+    set_error_mgr(&cinfo, &errorManager);
+
+    // All objects need to be instantiated before this setjmp call so that
+    // they will be cleaned up properly if an error occurs.
+    if (setjmp(errorManager.fJmpBuf)) {
+        return return_failure(cinfo, *bm, "setjmp");
+    }
+
+    initialize_info(&cinfo, &srcManager);
+    autoClean.set(&cinfo);
+
+    int status = jpeg_read_header(&cinfo, true);
+    if (status != JPEG_HEADER_OK) {
+        return return_failure(cinfo, *bm, "read_header");
+    }
+
+    /*  Try to fulfill the requested sampleSize. Since jpeg can do it (when it
+        can) much faster that we, just use their num/denom api to approximate
+        the size.
+    */
+    int sampleSize = this->getSampleSize();
+
+    set_dct_method(*this, &cinfo);
+
+    SkASSERT(1 == cinfo.scale_num);
+    cinfo.scale_denom = sampleSize;
+
+    const SkColorType colorType = this->getBitmapColorType(&cinfo);
+    const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ?
+                                      kPremul_SkAlphaType : kOpaque_SkAlphaType;
+
+    adjust_out_color_space_and_dither(&cinfo, colorType, *this);
+
+    if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) {
+        // Assume an A8 bitmap is not opaque to avoid the check of each
+        // individual pixel. It is very unlikely to be opaque, since
+        // an opaque A8 bitmap would not be very interesting.
+        // Otherwise, a jpeg image is opaque.
+        bool success = bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.image_height,
+                                                     colorType, alphaType));
+        return success ? kSuccess : kFailure;
+    }
+
+    /*  image_width and image_height are the original dimensions, available
+        after jpeg_read_header(). To see the scaled dimensions, we have to call
+        jpeg_start_decompress(), and then read output_width and output_height.
+    */
+    if (!jpeg_start_decompress(&cinfo)) {
+        /*  If we failed here, we may still have enough information to return
+            to the caller if they just wanted (subsampled bounds). If sampleSize
+            was 1, then we would have already returned. Thus we just check if
+            we're in kDecodeBounds_Mode, and that we have valid output sizes.
+
+            One reason to fail here is that we have insufficient stream data
+            to complete the setup. However, output dimensions seem to get
+            computed very early, which is why this special check can pay off.
+         */
+        if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimensions(cinfo)) {
+            SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height,
+                                       recompute_sampleSize(sampleSize, cinfo));
+            // Assume an A8 bitmap is not opaque to avoid the check of each
+            // individual pixel. It is very unlikely to be opaque, since
+            // an opaque A8 bitmap would not be very interesting.
+            // Otherwise, a jpeg image is opaque.
+            bool success = bm->setInfo(SkImageInfo::Make(smpl.scaledWidth(), smpl.scaledHeight(),
+                                                         colorType, alphaType));
+            return success ? kSuccess : kFailure;
+        } else {
+            return return_failure(cinfo, *bm, "start_decompress");
+        }
+    }
+    sampleSize = recompute_sampleSize(sampleSize, cinfo);
+
+    SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize);
+    // Assume an A8 bitmap is not opaque to avoid the check of each
+    // individual pixel. It is very unlikely to be opaque, since
+    // an opaque A8 bitmap would not be very interesting.
+    // Otherwise, a jpeg image is opaque.
+    bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
+                                  colorType, alphaType));
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+    if (!this->allocPixelRef(bm, nullptr)) {
+        return return_failure(cinfo, *bm, "allocPixelRef");
+    }
+
+    SkAutoLockPixels alp(*bm);
+
+#ifdef ANDROID_RGB
+    /* short-circuit the SkScaledBitmapSampler when possible, as this gives
+       a significant performance boost.
+    */
+    if (sampleSize == 1 &&
+        ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_8888) ||
+         (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_565)))
+    {
+        JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
+        INT32 const bpr =  bm->rowBytes();
+
+        while (cinfo.output_scanline < cinfo.output_height) {
+            int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
+            if (0 == row_count) {
+                // if row_count == 0, then we didn't get a scanline,
+                // so return early.  We will return a partial image.
+                fill_below_level(cinfo.output_scanline, bm);
+                cinfo.output_scanline = cinfo.output_height;
+                jpeg_finish_decompress(&cinfo);
+                return kPartialSuccess;
+            }
+            if (this->shouldCancelDecode()) {
+                return return_failure(cinfo, *bm, "shouldCancelDecode");
+            }
+            rowptr += bpr;
+        }
+        jpeg_finish_decompress(&cinfo);
+        return kSuccess;
+    }
+#endif
+
+    // check for supported formats
+    SkScaledBitmapSampler::SrcConfig sc;
+    int srcBytesPerPixel;
+
+    if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) {
+        return return_failure(cinfo, *bm, "jpeg colorspace");
+    }
+
+    if (!sampler.begin(bm, sc, *this)) {
+        return return_failure(cinfo, *bm, "sampler.begin");
+    }
+
+    SkAutoTMalloc<uint8_t> srcStorage(cinfo.output_width * srcBytesPerPixel);
+    uint8_t* srcRow = srcStorage.get();
+
+    //  Possibly skip initial rows [sampler.srcY0]
+    if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) {
+        return return_failure(cinfo, *bm, "skip rows");
+    }
+
+    // now loop through scanlines until y == bm->height() - 1
+    for (int y = 0;; y++) {
+        JSAMPLE* rowptr = (JSAMPLE*)srcRow;
+        int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1);
+        sk_msan_mark_initialized(srcRow, srcRow + cinfo.output_width * srcBytesPerPixel,
+                                 "skbug.com/4550");
+        if (0 == row_count) {
+            // if row_count == 0, then we didn't get a scanline,
+            // so return early.  We will return a partial image.
+            fill_below_level(y, bm);
+            cinfo.output_scanline = cinfo.output_height;
+            jpeg_finish_decompress(&cinfo);
+            return kPartialSuccess;
+        }
+        if (this->shouldCancelDecode()) {
+            return return_failure(cinfo, *bm, "shouldCancelDecode");
+        }
+
+        if (JCS_CMYK == cinfo.out_color_space) {
+            convert_CMYK_to_RGB(srcRow, cinfo.output_width);
+        }
+
+
+        sampler.next(srcRow);
+        if (bm->height() - 1 == y) {
+            // we're done
+            break;
+        }
+
+        if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) {
+            return return_failure(cinfo, *bm, "skip rows");
+        }
+    }
+
+    // we formally skip the rest, so we don't get a complaint from libjpeg
+    if (!skip_src_rows(&cinfo, srcRow,
+                       cinfo.output_height - cinfo.output_scanline)) {
+        return return_failure(cinfo, *bm, "skip rows");
+    }
+    jpeg_finish_decompress(&cinfo);
+
+    return kSuccess;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+enum SizeType {
+    kSizeForMemoryAllocation_SizeType,
+    kActualSize_SizeType
+};
+
+static SkISize compute_yuv_size(const jpeg_decompress_struct& info, int component,
+                                SizeType sizeType) {
+    if (sizeType == kSizeForMemoryAllocation_SizeType) {
+        return SkISize::Make(info.cur_comp_info[component]->width_in_blocks * DCTSIZE,
+                             info.cur_comp_info[component]->height_in_blocks * DCTSIZE);
+    }
+    return SkISize::Make(info.cur_comp_info[component]->downsampled_width,
+                         info.cur_comp_info[component]->downsampled_height);
+}
+
+static bool appears_to_be_yuv(const jpeg_decompress_struct& info) {
+    return (info.jpeg_color_space == JCS_YCbCr)
+        && (DCTSIZE == 8)
+        && (info.num_components == 3)
+        && (info.comps_in_scan >= info.num_components)
+        && (info.scale_denom <= 8)
+        && (info.cur_comp_info[0])
+        && (info.cur_comp_info[1])
+        && (info.cur_comp_info[2])
+        && (info.cur_comp_info[1]->h_samp_factor == 1)
+        && (info.cur_comp_info[1]->v_samp_factor == 1)
+        && (info.cur_comp_info[2]->h_samp_factor == 1)
+        && (info.cur_comp_info[2]->v_samp_factor == 1);
+}
+
+static void update_components_sizes(const jpeg_decompress_struct& cinfo, SkISize componentSizes[3],
+                                    SizeType sizeType) {
+    SkASSERT(appears_to_be_yuv(cinfo));
+    for (int i = 0; i < 3; ++i) {
+        componentSizes[i] = compute_yuv_size(cinfo, i, sizeType);
+    }
+}
+
+static bool output_raw_data(jpeg_decompress_struct& cinfo, void* planes[3], size_t rowBytes[3]) {
+    SkASSERT(appears_to_be_yuv(cinfo));
+    // U size and V size have to be the same if we're calling output_raw_data()
+    SkISize uvSize = compute_yuv_size(cinfo, 1, kSizeForMemoryAllocation_SizeType);
+    SkASSERT(uvSize == compute_yuv_size(cinfo, 2, kSizeForMemoryAllocation_SizeType));
+
+    JSAMPARRAY bufferraw[3];
+    JSAMPROW bufferraw2[32];
+    bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16)
+    bufferraw[1] = &bufferraw2[16]; // U channel rows (8)
+    bufferraw[2] = &bufferraw2[24]; // V channel rows (8)
+    int yWidth = cinfo.output_width;
+    int yHeight = cinfo.output_height;
+    int yMaxH = yHeight - 1;
+    int v = cinfo.cur_comp_info[0]->v_samp_factor;
+    int uvMaxH = uvSize.height() - 1;
+    JSAMPROW outputY = static_cast<JSAMPROW>(planes[0]);
+    JSAMPROW outputU = static_cast<JSAMPROW>(planes[1]);
+    JSAMPROW outputV = static_cast<JSAMPROW>(planes[2]);
+    size_t rowBytesY = rowBytes[0];
+    size_t rowBytesU = rowBytes[1];
+    size_t rowBytesV = rowBytes[2];
+
+    int yScanlinesToRead = DCTSIZE * v;
+    SkAutoMalloc lastRowStorage(rowBytesY * 4);
+    JSAMPROW yLastRow = (JSAMPROW)lastRowStorage.get();
+    JSAMPROW uLastRow = yLastRow + rowBytesY;
+    JSAMPROW vLastRow = uLastRow + rowBytesY;
+    JSAMPROW dummyRow = vLastRow + rowBytesY;
+
+    while (cinfo.output_scanline < cinfo.output_height) {
+        // Request 8 or 16 scanlines: returns 0 or more scanlines.
+        bool hasYLastRow(false), hasUVLastRow(false);
+        // Assign 8 or 16 rows of memory to read the Y channel.
+        for (int i = 0; i < yScanlinesToRead; ++i) {
+            int scanline = (cinfo.output_scanline + i);
+            if (scanline < yMaxH) {
+                bufferraw2[i] = &outputY[scanline * rowBytesY];
+            } else if (scanline == yMaxH) {
+                bufferraw2[i] = yLastRow;
+                hasYLastRow = true;
+            } else {
+                bufferraw2[i] = dummyRow;
+            }
+        }
+        int scaledScanline = cinfo.output_scanline / v;
+        // Assign 8 rows of memory to read the U and V channels.
+        for (int i = 0; i < 8; ++i) {
+            int scanline = (scaledScanline + i);
+            if (scanline < uvMaxH) {
+                bufferraw2[16 + i] = &outputU[scanline * rowBytesU];
+                bufferraw2[24 + i] = &outputV[scanline * rowBytesV];
+            } else if (scanline == uvMaxH) {
+                bufferraw2[16 + i] = uLastRow;
+                bufferraw2[24 + i] = vLastRow;
+                hasUVLastRow = true;
+            } else {
+                bufferraw2[16 + i] = dummyRow;
+                bufferraw2[24 + i] = dummyRow;
+            }
+        }
+        JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanlinesToRead);
+
+        if (scanlinesRead == 0) {
+            return false;
+        }
+
+        if (hasYLastRow) {
+            memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth);
+        }
+        if (hasUVLastRow) {
+            memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width());
+            memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width());
+        }
+    }
+
+    cinfo.output_scanline = SkMin32(cinfo.output_scanline, cinfo.output_height);
+
+    return true;
+}
+
+bool SkJPEGImageDecoder::onDecodeYUV8Planes(SkStream* stream, SkISize componentSizes[3],
+                                            void* planes[3], size_t rowBytes[3],
+                                            SkYUVColorSpace* colorSpace) {
+#ifdef TIME_DECODE
+    SkAutoTime atm("JPEG YUV8 Decode");
+#endif
+    if (this->getSampleSize() != 1) {
+        return false; // Resizing not supported
+    }
+
+    JPEGAutoClean autoClean;
+
+    jpeg_decompress_struct  cinfo;
+    skjpeg_source_mgr       srcManager(stream, this);
+
+    skjpeg_error_mgr errorManager;
+    set_error_mgr(&cinfo, &errorManager);
+
+    // All objects need to be instantiated before this setjmp call so that
+    // they will be cleaned up properly if an error occurs.
+    if (setjmp(errorManager.fJmpBuf)) {
+        return return_false(cinfo, "setjmp YUV8");
+    }
+
+    initialize_info(&cinfo, &srcManager);
+    autoClean.set(&cinfo);
+
+    int status = jpeg_read_header(&cinfo, true);
+    if (status != JPEG_HEADER_OK) {
+        return return_false(cinfo, "read_header YUV8");
+    }
+
+    if (!appears_to_be_yuv(cinfo)) {
+        // It's not an error to not be encoded in YUV, so no need to use return_false()
+        return false;
+    }
+
+    cinfo.out_color_space = JCS_YCbCr;
+    cinfo.raw_data_out = TRUE;
+
+    if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size only
+        update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_SizeType);
+        return true;
+    }
+
+    set_dct_method(*this, &cinfo);
+
+    SkASSERT(1 == cinfo.scale_num);
+    cinfo.scale_denom = 1;
+
+#ifdef ANDROID_RGB
+    cinfo.dither_mode = JDITHER_NONE;
+#endif
+
+    /*  image_width and image_height are the original dimensions, available
+        after jpeg_read_header(). To see the scaled dimensions, we have to call
+        jpeg_start_decompress(), and then read output_width and output_height.
+    */
+    if (!jpeg_start_decompress(&cinfo)) {
+        return return_false(cinfo, "start_decompress YUV8");
+    }
+
+    // Seems like jpeg_start_decompress is updating our opinion of whether cinfo represents YUV.
+    // Again, not really an error.
+    if (!appears_to_be_yuv(cinfo)) {
+        return false;
+    }
+
+    if (!output_raw_data(cinfo, planes, rowBytes)) {
+        return return_false(cinfo, "output_raw_data");
+    }
+
+    update_components_sizes(cinfo, componentSizes, kActualSize_SizeType);
+    jpeg_finish_decompress(&cinfo);
+
+    if (nullptr != colorSpace) {
+        *colorSpace = kJPEG_SkYUVColorSpace;
+    }
+
+    return true;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkColorPriv.h"
@@ -272,11 +993,45 @@
 };
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(JPEGImageDecoder);
 DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
 ///////////////////////////////////////////////////////////////////////////////
 
+static bool is_jpeg(SkStreamRewindable* stream) {
+    static const unsigned char gHeader[] = { 0xFF, 0xD8, 0xFF };
+    static const size_t HEADER_SIZE = sizeof(gHeader);
+
+    char buffer[HEADER_SIZE];
+    size_t len = stream->read(buffer, HEADER_SIZE);
+
+    if (len != HEADER_SIZE) {
+        return false;   // can't read enough
+    }
+    if (memcmp(buffer, gHeader, HEADER_SIZE)) {
+        return false;
+    }
+    return true;
+}
+
+
+static SkImageDecoder* sk_libjpeg_dfactory(SkStreamRewindable* stream) {
+    if (is_jpeg(stream)) {
+        return new SkJPEGImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder::Format get_format_jpeg(SkStreamRewindable* stream) {
+    if (is_jpeg(stream)) {
+        return SkImageDecoder::kJPEG_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
     return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr;
 }
 
+static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory);
+static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg);
 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index c3df5d1..cd8152a 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -5,12 +5,14 @@
  * found in the LICENSE file.
  */
 
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkColor.h"
 #include "SkColorPriv.h"
 #include "SkDither.h"
 #include "SkMath.h"
 #include "SkRTConf.h"
+#include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
 #include "SkUtils.h"
@@ -42,10 +44,88 @@
                 "Suppress most PNG warnings when calling image decode "
                 "functions.");
 
-///////////////////////////////////////////////////////////////////////////////
+class SkPNGImageIndex {
+public:
+    // Takes ownership of stream.
+    SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop info_ptr)
+        : fStream(stream)
+        , fPng_ptr(png_ptr)
+        , fInfo_ptr(info_ptr)
+        , fColorType(kUnknown_SkColorType) {
+        SkASSERT(stream != nullptr);
+    }
+    ~SkPNGImageIndex() {
+        if (fPng_ptr) {
+            png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL);
+        }
+    }
 
-#include "SkColorPriv.h"
-#include "SkUnPreMultiply.h"
+    SkAutoTDelete<SkStreamRewindable>   fStream;
+    png_structp                         fPng_ptr;
+    png_infop                           fInfo_ptr;
+    SkColorType                         fColorType;
+};
+
+class SkPNGImageDecoder : public SkImageDecoder {
+public:
+    SkPNGImageDecoder() {
+        fImageIndex = nullptr;
+    }
+    Format getFormat() const override {
+        return kPNG_Format;
+    }
+
+    virtual ~SkPNGImageDecoder() { delete fImageIndex; }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    SkPNGImageIndex* fImageIndex;
+
+    bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_ptrp);
+    bool decodePalette(png_structp png_ptr, png_infop info_ptr, int bitDepth,
+                       bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap,
+                       SkColorTable **colorTablep);
+    bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha,
+                            SkPMColor* theTranspColor);
+
+    typedef SkImageDecoder INHERITED;
+};
+
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
+
+#define PNG_BYTES_TO_CHECK 4
+
+/* Automatically clean up after throwing an exception */
+struct PNGAutoClean {
+    PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {}
+    ~PNGAutoClean() {
+        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+    }
+private:
+    png_structp png_ptr;
+    png_infop info_ptr;
+};
+
+static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) {
+    SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr);
+    size_t bytes = sk_stream->read(data, length);
+    if (bytes != length) {
+        png_error(png_ptr, "Read Error!");
+    }
+}
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) {
+    SkPngChunkReader* peeker = (SkPngChunkReader*)png_get_user_chunk_ptr(png_ptr);
+    // readChunk() returning true means continue decoding
+    return peeker->readChunk((const char*)chunk->name, chunk->data, chunk->size) ?
+            1 : -1;
+}
+#endif
 
 static void sk_error_fn(png_structp png_ptr, png_const_charp msg) {
     if (!c_suppressPNGImageDecoderWarnings) {
@@ -54,6 +134,577 @@
     longjmp(png_jmpbuf(png_ptr), 1);
 }
 
+static void skip_src_rows(png_structp png_ptr, uint8_t storage[], int count) {
+    for (int i = 0; i < count; i++) {
+        uint8_t* tmp = storage;
+        png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
+    }
+}
+
+static bool pos_le(int value, int max) {
+    return value > 0 && value <= max;
+}
+
+static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) {
+    SkASSERT(bm->colorType() == kN32_SkColorType);
+
+    bool reallyHasAlpha = false;
+
+    for (int y = bm->height() - 1; y >= 0; --y) {
+        SkPMColor* p = bm->getAddr32(0, y);
+        for (int x = bm->width() - 1; x >= 0; --x) {
+            if (match == *p) {
+                *p = 0;
+                reallyHasAlpha = true;
+            }
+            p += 1;
+        }
+    }
+    return reallyHasAlpha;
+}
+
+static bool canUpscalePaletteToConfig(SkColorType dstColorType, bool srcHasAlpha) {
+    switch (dstColorType) {
+        case kN32_SkColorType:
+        case kARGB_4444_SkColorType:
+            return true;
+        case kRGB_565_SkColorType:
+            // only return true if the src is opaque (since 565 is opaque)
+            return !srcHasAlpha;
+        default:
+            return false;
+    }
+}
+
+// call only if color_type is PALETTE. Returns true if the ctable has alpha
+static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) {
+    png_bytep trans;
+    int num_trans;
+
+    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+        png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, nullptr);
+        return num_trans > 0;
+    }
+    return false;
+}
+
+void do_nothing_warning_fn(png_structp, png_const_charp) {
+    /* do nothing */
+}
+
+bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp,
+                                     png_infop *info_ptrp) {
+    /* Create and initialize the png_struct with the desired error handler
+    * functions.  If you want to use the default stderr and longjump method,
+    * you can supply nullptr for the last three parameters.  We also supply the
+    * the compiler header file version, so that we know if the application
+    * was compiled with a compatible version of the library.  */
+
+    png_error_ptr user_warning_fn =
+        (c_suppressPNGImageDecoderWarnings) ? (&do_nothing_warning_fn) : nullptr;
+    /* nullptr means to leave as default library behavior. */
+    /* c_suppressPNGImageDecoderWarnings default depends on SK_DEBUG. */
+    /* To suppress warnings with a SK_DEBUG binary, set the
+     * environment variable "skia_images_png_suppressDecoderWarnings"
+     * to "true".  Inside a program that links to skia:
+     * SK_CONF_SET("images.png.suppressDecoderWarnings", true); */
+
+    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+        nullptr, sk_error_fn, user_warning_fn);
+    //   png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+    if (png_ptr == nullptr) {
+        return false;
+    }
+
+    *png_ptrp = png_ptr;
+
+    /* Allocate/initialize the memory for image information. */
+    png_infop info_ptr = png_create_info_struct(png_ptr);
+    if (info_ptr == nullptr) {
+        png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
+        return false;
+    }
+    *info_ptrp = info_ptr;
+
+    /* Set error handling if you are using the setjmp/longjmp method (this is
+    * the normal method of doing things with libpng).  REQUIRED unless you
+    * set up your own error handlers in the png_create_read_struct() earlier.
+    */
+    if (setjmp(png_jmpbuf(png_ptr))) {
+        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+        return false;
+    }
+
+    /* If you are using replacement read functions, instead of calling
+    * png_init_io() here you would call:
+    */
+    png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn);
+    /* where user_io_ptr is a structure you want available to the callbacks */
+    /* If we have already read some of the signature */
+//  png_set_sig_bytes(png_ptr, 0 /* sig_read */ );
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+    // hookup our peeker so we can see any user-chunks the caller may be interested in
+    png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0);
+    if (this->getPeeker()) {
+        png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_read_user_chunk);
+    }
+#endif
+    /* The call to png_read_info() gives us all of the information from the
+    * PNG file before the first IDAT (image data chunk). */
+    png_read_info(png_ptr, info_ptr);
+    png_uint_32 origWidth, origHeight;
+    int bitDepth, colorType;
+    png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
+                 &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
+
+    /* tell libpng to strip 16 bit/color files down to 8 bits/color */
+    if (bitDepth == 16) {
+        png_set_strip_16(png_ptr);
+    }
+#ifdef PNG_READ_PACK_SUPPORTED
+    /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+     * byte into separate bytes (useful for paletted and grayscale images). */
+    if (bitDepth < 8) {
+        png_set_packing(png_ptr);
+    }
+#endif
+    /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
+    if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) {
+        png_set_expand_gray_1_2_4_to_8(png_ptr);
+    }
+
+    return true;
+}
+
+SkImageDecoder::Result SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
+                                                   Mode mode) {
+    png_structp png_ptr;
+    png_infop info_ptr;
+
+    if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) {
+        return kFailure;
+    }
+
+    PNGAutoClean autoClean(png_ptr, info_ptr);
+
+    if (setjmp(png_jmpbuf(png_ptr))) {
+        return kFailure;
+    }
+
+    png_uint_32 origWidth, origHeight;
+    int bitDepth, pngColorType, interlaceType;
+    png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
+                 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL);
+
+    SkColorType         colorType;
+    bool                hasAlpha = false;
+    SkPMColor           theTranspColor = 0; // 0 tells us not to try to match
+
+    if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &theTranspColor)) {
+        return kFailure;
+    }
+
+    SkAlphaType alphaType = this->getRequireUnpremultipliedColors() ?
+                                kUnpremul_SkAlphaType : kPremul_SkAlphaType;
+    const int sampleSize = this->getSampleSize();
+    SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
+    decodedBitmap->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
+                                             colorType, alphaType));
+
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    // from here down we are concerned with colortables and pixels
+
+    // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype
+    // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
+    // draw lots faster if we can flag the bitmap has being opaque
+    bool reallyHasAlpha = false;
+    SkColorTable* colorTable = nullptr;
+
+    if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
+        decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, &colorTable);
+    }
+
+    SkAutoUnref aur(colorTable);
+
+    if (!this->allocPixelRef(decodedBitmap,
+                             kIndex_8_SkColorType == colorType ? colorTable : nullptr)) {
+        return kFailure;
+    }
+
+    SkAutoLockPixels alp(*decodedBitmap);
+
+    // Repeat setjmp, otherwise variables declared since the last call (e.g. alp
+    // and aur) won't get their destructors called in case of a failure.
+    if (setjmp(png_jmpbuf(png_ptr))) {
+        return kFailure;
+    }
+
+    /* Turn on interlace handling.  REQUIRED if you are not using
+    *  png_read_image().  To see how to handle interlacing passes,
+    *  see the png_read_row() method below:
+    */
+    const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ?
+                              png_set_interlace_handling(png_ptr) : 1;
+
+    /* Optional call to gamma correct and add the background to the palette
+    *  and update info structure.  REQUIRED if you are expecting libpng to
+    *  update the palette for you (ie you selected such a transform above).
+    */
+    png_read_update_info(png_ptr, info_ptr);
+
+    if ((kAlpha_8_SkColorType == colorType || kIndex_8_SkColorType == colorType) &&
+            1 == sampleSize) {
+        if (kAlpha_8_SkColorType == colorType) {
+            // For an A8 bitmap, we assume there is an alpha for speed. It is
+            // possible the bitmap is opaque, but that is an unlikely use case
+            // since it would not be very interesting.
+            reallyHasAlpha = true;
+            // A8 is only allowed if the original was GRAY.
+            SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
+        }
+        for (int i = 0; i < number_passes; i++) {
+            for (png_uint_32 y = 0; y < origHeight; y++) {
+                uint8_t* bmRow = decodedBitmap->getAddr8(0, y);
+                png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
+            }
+        }
+    } else {
+        SkScaledBitmapSampler::SrcConfig sc;
+        int srcBytesPerPixel = 4;
+
+        if (colorTable != nullptr) {
+            sc = SkScaledBitmapSampler::kIndex;
+            srcBytesPerPixel = 1;
+        } else if (kAlpha_8_SkColorType == colorType) {
+            // A8 is only allowed if the original was GRAY.
+            SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
+            sc = SkScaledBitmapSampler::kGray;
+            srcBytesPerPixel = 1;
+        } else if (hasAlpha) {
+            sc = SkScaledBitmapSampler::kRGBA;
+        } else {
+            sc = SkScaledBitmapSampler::kRGBX;
+        }
+
+        /*  We have to pass the colortable explicitly, since we may have one
+            even if our decodedBitmap doesn't, due to the request that we
+            upscale png's palette to a direct model
+         */
+        const SkPMColor* colors = colorTable ? colorTable->readColors() : nullptr;
+        if (!sampler.begin(decodedBitmap, sc, *this, colors)) {
+            return kFailure;
+        }
+        const int height = decodedBitmap->height();
+
+        if (number_passes > 1) {
+            SkAutoTMalloc<uint8_t> storage(origWidth * origHeight * srcBytesPerPixel);
+            uint8_t* base = storage.get();
+            size_t rowBytes = origWidth * srcBytesPerPixel;
+
+            for (int i = 0; i < number_passes; i++) {
+                uint8_t* row = base;
+                for (png_uint_32 y = 0; y < origHeight; y++) {
+                    uint8_t* bmRow = row;
+                    png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
+                    row += rowBytes;
+                }
+            }
+            // now sample it
+            base += sampler.srcY0() * rowBytes;
+            for (int y = 0; y < height; y++) {
+                reallyHasAlpha |= sampler.next(base);
+                base += sampler.srcDY() * rowBytes;
+            }
+        } else {
+            SkAutoTMalloc<uint8_t> storage(origWidth * srcBytesPerPixel);
+            uint8_t* srcRow = storage.get();
+            skip_src_rows(png_ptr, srcRow, sampler.srcY0());
+
+            for (int y = 0; y < height; y++) {
+                uint8_t* tmp = srcRow;
+                png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
+                reallyHasAlpha |= sampler.next(srcRow);
+                if (y < height - 1) {
+                    skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
+                }
+            }
+
+            // skip the rest of the rows (if any)
+            png_uint_32 read = (height - 1) * sampler.srcDY() +
+                               sampler.srcY0() + 1;
+            SkASSERT(read <= origHeight);
+            skip_src_rows(png_ptr, srcRow, origHeight - read);
+        }
+    }
+
+    /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
+    png_read_end(png_ptr, info_ptr);
+
+    if (0 != theTranspColor) {
+        reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor);
+    }
+    if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) {
+        switch (decodedBitmap->colorType()) {
+            case kIndex_8_SkColorType:
+                // Fall through.
+            case kARGB_4444_SkColorType:
+                // We have chosen not to support unpremul for these colortypes.
+                return kFailure;
+            default: {
+                // Fall through to finish the decode. This colortype either
+                // supports unpremul or it is irrelevant because it has no
+                // alpha (or only alpha).
+                // These brackets prevent a warning.
+            }
+        }
+    }
+
+    if (!reallyHasAlpha) {
+        decodedBitmap->setAlphaType(kOpaque_SkAlphaType);
+    }
+    return kSuccess;
+}
+
+
+
+bool SkPNGImageDecoder::getBitmapColorType(png_structp png_ptr, png_infop info_ptr,
+                                           SkColorType* colorTypep,
+                                           bool* hasAlphap,
+                                           SkPMColor* SK_RESTRICT theTranspColorp) {
+    png_uint_32 origWidth, origHeight;
+    int bitDepth, colorType;
+    png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
+                 &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
+
+#ifdef PNG_sBIT_SUPPORTED
+    // check for sBIT chunk data, in case we should disable dithering because
+    // our data is not truely 8bits per component
+    png_color_8p sig_bit;
+    if (this->getDitherImage() && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) {
+#if 0
+        SkDebugf("----- sBIT %d %d %d %d\n", sig_bit->red, sig_bit->green,
+                 sig_bit->blue, sig_bit->alpha);
+#endif
+        // 0 seems to indicate no information available
+        if (pos_le(sig_bit->red, SK_R16_BITS) &&
+            pos_le(sig_bit->green, SK_G16_BITS) &&
+            pos_le(sig_bit->blue, SK_B16_BITS)) {
+            this->setDitherImage(false);
+        }
+    }
+#endif
+
+    if (colorType == PNG_COLOR_TYPE_PALETTE) {
+        bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr);
+        *colorTypep = this->getPrefColorType(kIndex_SrcDepth, paletteHasAlpha);
+        // now see if we can upscale to their requested colortype
+        if (!canUpscalePaletteToConfig(*colorTypep, paletteHasAlpha)) {
+            *colorTypep = kIndex_8_SkColorType;
+        }
+    } else {
+        png_color_16p transpColor = nullptr;
+        int numTransp = 0;
+
+        png_get_tRNS(png_ptr, info_ptr, nullptr, &numTransp, &transpColor);
+
+        bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
+
+        if (valid && numTransp == 1 && transpColor != nullptr) {
+            /*  Compute our transparent color, which we'll match against later.
+                We don't really handle 16bit components properly here, since we
+                do our compare *after* the values have been knocked down to 8bit
+                which means we will find more matches than we should. The real
+                fix seems to be to see the actual 16bit components, do the
+                compare, and then knock it down to 8bits ourselves.
+            */
+            if (colorType & PNG_COLOR_MASK_COLOR) {
+                if (16 == bitDepth) {
+                    *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8,
+                                                    transpColor->green >> 8,
+                                                    transpColor->blue >> 8);
+                } else {
+                    /* We apply the mask because in a very small
+                       number of corrupt PNGs, (transpColor->red > 255)
+                       and (bitDepth == 8), for certain versions of libpng. */
+                    *theTranspColorp = SkPackARGB32(0xFF,
+                                                    0xFF & (transpColor->red),
+                                                    0xFF & (transpColor->green),
+                                                    0xFF & (transpColor->blue));
+                }
+            } else {    // gray
+                if (16 == bitDepth) {
+                    *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8,
+                                                    transpColor->gray >> 8,
+                                                    transpColor->gray >> 8);
+                } else {
+                    /* We apply the mask because in a very small
+                       number of corrupt PNGs, (transpColor->red >
+                       255) and (bitDepth == 8), for certain versions
+                       of libpng.  For safety we assume the same could
+                       happen with a grayscale PNG.  */
+                    *theTranspColorp = SkPackARGB32(0xFF,
+                                                    0xFF & (transpColor->gray),
+                                                    0xFF & (transpColor->gray),
+                                                    0xFF & (transpColor->gray));
+                }
+            }
+        }
+
+        if (valid ||
+            PNG_COLOR_TYPE_RGB_ALPHA == colorType ||
+            PNG_COLOR_TYPE_GRAY_ALPHA == colorType) {
+            *hasAlphap = true;
+        }
+
+        SrcDepth srcDepth = k32Bit_SrcDepth;
+        if (PNG_COLOR_TYPE_GRAY == colorType) {
+            srcDepth = k8BitGray_SrcDepth;
+            // Remove this assert, which fails on desk_pokemonwiki.skp
+            //SkASSERT(!*hasAlphap);
+        }
+
+        *colorTypep = this->getPrefColorType(srcDepth, *hasAlphap);
+        // now match the request against our capabilities
+        if (*hasAlphap) {
+            if (*colorTypep != kARGB_4444_SkColorType) {
+                *colorTypep = kN32_SkColorType;
+            }
+        } else {
+            if (kAlpha_8_SkColorType == *colorTypep) {
+                if (k8BitGray_SrcDepth != srcDepth) {
+                    // Converting a non grayscale image to A8 is not currently supported.
+                    *colorTypep = kN32_SkColorType;
+                }
+            } else if (*colorTypep != kRGB_565_SkColorType &&
+                       *colorTypep != kARGB_4444_SkColorType) {
+                *colorTypep = kN32_SkColorType;
+            }
+        }
+    }
+
+    // sanity check for size
+    {
+        int64_t size = sk_64_mul(origWidth, origHeight);
+        // now check that if we are 4-bytes per pixel, we also don't overflow
+        if (size < 0 || size > (0x7FFFFFFF >> 2)) {
+            return false;
+        }
+    }
+
+    // If the image has alpha and the decoder wants unpremultiplied
+    // colors, the only supported colortype is 8888.
+    if (this->getRequireUnpremultipliedColors() && *hasAlphap) {
+        *colorTypep = kN32_SkColorType;
+    }
+
+    if (fImageIndex != nullptr) {
+        if (kUnknown_SkColorType == fImageIndex->fColorType) {
+            // This is the first time for this subset decode. From now on,
+            // all decodes must be in the same colortype.
+            fImageIndex->fColorType = *colorTypep;
+        } else if (fImageIndex->fColorType != *colorTypep) {
+            // Requesting a different colortype for a subsequent decode is not
+            // supported. Report failure before we make changes to png_ptr.
+            return false;
+        }
+    }
+
+    bool convertGrayToRGB = PNG_COLOR_TYPE_GRAY == colorType && *colorTypep != kAlpha_8_SkColorType;
+
+    // Unless the user is requesting A8, convert a grayscale image into RGB.
+    // GRAY_ALPHA will always be converted to RGB
+    if (convertGrayToRGB || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
+        png_set_gray_to_rgb(png_ptr);
+    }
+
+    // Add filler (or alpha) byte (after each RGB triplet) if necessary.
+    if (colorType == PNG_COLOR_TYPE_RGB || convertGrayToRGB) {
+        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+    }
+
+    return true;
+}
+
+typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
+
+bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
+                                      int bitDepth, bool *hasAlphap,
+                                      bool *reallyHasAlphap,
+                                      SkColorTable **colorTablep) {
+    int numPalette;
+    png_colorp palette;
+    png_bytep trans;
+    int numTrans;
+
+    png_get_PLTE(png_ptr, info_ptr, &palette, &numPalette);
+
+    SkPMColor colorStorage[256];    // worst-case storage
+    SkPMColor* colorPtr = colorStorage;
+
+    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+        png_get_tRNS(png_ptr, info_ptr, &trans, &numTrans, nullptr);
+        *hasAlphap = (numTrans > 0);
+    } else {
+        numTrans = 0;
+    }
+
+    // check for bad images that might make us crash
+    if (numTrans > numPalette) {
+        numTrans = numPalette;
+    }
+
+    int index = 0;
+    int transLessThanFF = 0;
+
+    // Choose which function to use to create the color table. If the final destination's
+    // colortype is unpremultiplied, the color table will store unpremultiplied colors.
+    PackColorProc proc;
+    if (this->getRequireUnpremultipliedColors()) {
+        proc = &SkPackARGB32NoCheck;
+    } else {
+        proc = &SkPreMultiplyARGB;
+    }
+    for (; index < numTrans; index++) {
+        transLessThanFF |= (int)*trans - 0xFF;
+        *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue);
+        palette++;
+    }
+    bool reallyHasAlpha = (transLessThanFF < 0);
+
+    for (; index < numPalette; index++) {
+        *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->blue);
+        palette++;
+    }
+
+    /*  BUGGY IMAGE WORKAROUND
+
+        Invalid images could contain pixel values that are greater than the number of palette
+        entries. Since we use pixel values as indices into the palette this could result in reading
+        beyond the end of the palette which could leak the contents of uninitialized memory. To
+        ensure this doesn't happen, we grow the colortable to the maximum size that can be
+        addressed by the bitdepth of the image and fill it with the last palette color or black if
+        the palette is empty (really broken image).
+    */
+    int colorCount = SkTMax(numPalette, 1 << SkTMin(bitDepth, 8));
+    SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0);
+    for (; index < colorCount; index++) {
+        *colorPtr++ = lastColor;
+    }
+
+    *colorTablep = new SkColorTable(colorStorage, colorCount);
+    *reallyHasAlphap = reallyHasAlpha;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkColorPriv.h"
+#include "SkUnPreMultiply.h"
+
 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
     SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr);
     if (!sk_stream->write(data, len)) {
@@ -334,11 +985,37 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(PNGImageDecoder);
 DEFINE_ENCODER_CREATOR(PNGImageEncoder);
 ///////////////////////////////////////////////////////////////////////////////
 
+static bool is_png(SkStreamRewindable* stream) {
+    char buf[PNG_BYTES_TO_CHECK];
+    if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK &&
+        !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
+        return true;
+    }
+    return false;
+}
+
+SkImageDecoder* sk_libpng_dfactory(SkStreamRewindable* stream) {
+    if (is_png(stream)) {
+        return new SkPNGImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder::Format get_format_png(SkStreamRewindable* stream) {
+    if (is_png(stream)) {
+        return SkImageDecoder::kPNG_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
     return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr;
 }
 
+static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
+static SkImageDecoder_FormatReg gFormatReg(get_format_png);
 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp
index 116608a..2db08ce 100644
--- a/src/images/SkImageDecoder_libwebp.cpp
+++ b/src/images/SkImageDecoder_libwebp.cpp
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-#include "SkBitmap.h"
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkColorPriv.h"
+#include "SkScaledBitmapSampler.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
 #include "SkUtils.h"
@@ -31,9 +32,299 @@
 extern "C" {
 // If moving libwebp out of skia source tree, path for webp headers must be
 // updated accordingly. Here, we enforce using local copy in webp sub-directory.
+#include "webp/decode.h"
 #include "webp/encode.h"
 }
 
+// this enables timing code to report milliseconds for a decode
+//#define TIME_DECODE
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+// Define VP8 I/O on top of Skia stream
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+static const size_t WEBP_VP8_HEADER_SIZE = 64;
+static const size_t WEBP_IDECODE_BUFFER_SZ = (1 << 16);
+
+// Parse headers of RIFF container, and check for valid Webp (VP8) content.
+static bool webp_parse_header(SkStream* stream, int* width, int* height, int* alpha) {
+    unsigned char buffer[WEBP_VP8_HEADER_SIZE];
+    size_t bytesToRead = WEBP_VP8_HEADER_SIZE;
+    size_t totalBytesRead = 0;
+    do {
+        unsigned char* dst = buffer + totalBytesRead;
+        const size_t bytesRead = stream->read(dst, bytesToRead);
+        if (0 == bytesRead) {
+            SkASSERT(stream->isAtEnd());
+            break;
+        }
+        bytesToRead -= bytesRead;
+        totalBytesRead += bytesRead;
+        SkASSERT(bytesToRead + totalBytesRead == WEBP_VP8_HEADER_SIZE);
+    } while (!stream->isAtEnd() && bytesToRead > 0);
+
+    WebPBitstreamFeatures features;
+    VP8StatusCode status = WebPGetFeatures(buffer, totalBytesRead, &features);
+    if (VP8_STATUS_OK != status) {
+        return false; // Invalid WebP file.
+    }
+    *width = features.width;
+    *height = features.height;
+    *alpha = features.has_alpha;
+
+    // sanity check for image size that's about to be decoded.
+    {
+        int64_t size = sk_64_mul(*width, *height);
+        if (!sk_64_isS32(size)) {
+            return false;
+        }
+        // now check that if we are 4-bytes per pixel, we also don't overflow
+        if (sk_64_asS32(size) > (0x7FFFFFFF >> 2)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+class SkWEBPImageDecoder: public SkImageDecoder {
+public:
+    SkWEBPImageDecoder() {
+        fOrigWidth = 0;
+        fOrigHeight = 0;
+        fHasAlpha = 0;
+    }
+
+    Format getFormat() const override {
+        return kWEBP_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    /**
+     *  Called when determining the output config to request to webp.
+     *  If the image does not have alpha, there is no need to premultiply.
+     *  If the caller wants unpremultiplied colors, that is respected.
+     */
+    bool shouldPremultiply() const {
+        return SkToBool(fHasAlpha) && !this->getRequireUnpremultipliedColors();
+    }
+
+    bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height);
+
+    SkAutoTDelete<SkStream> fInputStream;
+    int fOrigWidth;
+    int fOrigHeight;
+    int fHasAlpha;
+
+    typedef SkImageDecoder INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef TIME_DECODE
+
+#include "SkTime.h"
+
+class AutoTimeMillis {
+public:
+    AutoTimeMillis(const char label[]) :
+        fLabel(label) {
+        if (nullptr == fLabel) {
+            fLabel = "";
+        }
+        fNow = SkTime::GetMSecs();
+    }
+    ~AutoTimeMillis() {
+        SkDebugf("---- Time (ms): %s %d\n", fLabel, SkTime::GetMSecs() - fNow);
+    }
+private:
+    const char* fLabel;
+    SkMSec fNow;
+};
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+// This guy exists just to aid in debugging, as it allows debuggers to just
+// set a break-point in one place to see all error exists.
+static void print_webp_error(const SkBitmap& bm, const char msg[]) {
+    SkDEBUGF(("libwebp error %s [%d %d]", msg, bm.width(), bm.height()));
+}
+
+static SkImageDecoder::Result return_failure(const SkBitmap& bm, const char msg[]) {
+    print_webp_error(bm, msg);
+    return SkImageDecoder::kFailure; // must always return kFailure
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static WEBP_CSP_MODE webp_decode_mode(const SkBitmap* decodedBitmap, bool premultiply) {
+    WEBP_CSP_MODE mode = MODE_LAST;
+    const SkColorType ct = decodedBitmap->colorType();
+
+    if (ct == kN32_SkColorType) {
+        #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
+            mode = premultiply ? MODE_bgrA : MODE_BGRA;
+        #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
+            mode = premultiply ? MODE_rgbA : MODE_RGBA;
+        #else
+            #error "Skia uses BGRA or RGBA byte order"
+        #endif
+    } else if (ct == kARGB_4444_SkColorType) {
+        mode = premultiply ? MODE_rgbA_4444 : MODE_RGBA_4444;
+    } else if (ct == kRGB_565_SkColorType) {
+        mode = MODE_RGB_565;
+    }
+    SkASSERT(MODE_LAST != mode);
+    return mode;
+}
+
+// Incremental WebP image decoding. Reads input buffer of 64K size iteratively
+// and decodes this block to appropriate color-space as per config object.
+static bool webp_idecode(SkStream* stream, WebPDecoderConfig* config) {
+    WebPIDecoder* idec = WebPIDecode(nullptr, 0, config);
+    if (nullptr == idec) {
+        WebPFreeDecBuffer(&config->output);
+        return false;
+    }
+
+    if (!stream->rewind()) {
+        SkDebugf("Failed to rewind webp stream!");
+        return false;
+    }
+    const size_t readBufferSize = stream->hasLength() ?
+            SkTMin(stream->getLength(), WEBP_IDECODE_BUFFER_SZ) : WEBP_IDECODE_BUFFER_SZ;
+    SkAutoTMalloc<unsigned char> srcStorage(readBufferSize);
+    unsigned char* input = srcStorage.get();
+    if (nullptr == input) {
+        WebPIDelete(idec);
+        WebPFreeDecBuffer(&config->output);
+        return false;
+    }
+
+    bool success = true;
+    VP8StatusCode status = VP8_STATUS_SUSPENDED;
+    do {
+        const size_t bytesRead = stream->read(input, readBufferSize);
+        if (0 == bytesRead) {
+            success = false;
+            break;
+        }
+
+        status = WebPIAppend(idec, input, bytesRead);
+        if (VP8_STATUS_OK != status && VP8_STATUS_SUSPENDED != status) {
+            success = false;
+            break;
+        }
+    } while (VP8_STATUS_OK != status);
+    srcStorage.reset();
+    WebPIDelete(idec);
+    WebPFreeDecBuffer(&config->output);
+
+    return success;
+}
+
+static bool webp_get_config_resize(WebPDecoderConfig* config,
+                                   SkBitmap* decodedBitmap,
+                                   int width, int height, bool premultiply) {
+    WEBP_CSP_MODE mode = webp_decode_mode(decodedBitmap, premultiply);
+    if (MODE_LAST == mode) {
+        return false;
+    }
+
+    if (0 == WebPInitDecoderConfig(config)) {
+        return false;
+    }
+
+    config->output.colorspace = mode;
+    config->output.u.RGBA.rgba = (uint8_t*)decodedBitmap->getPixels();
+    config->output.u.RGBA.stride = (int) decodedBitmap->rowBytes();
+    config->output.u.RGBA.size = decodedBitmap->getSize();
+    config->output.is_external_memory = 1;
+
+    if (width != decodedBitmap->width() || height != decodedBitmap->height()) {
+        config->options.use_scaling = 1;
+        config->options.scaled_width = decodedBitmap->width();
+        config->options.scaled_height = decodedBitmap->height();
+    }
+
+    return true;
+}
+
+bool SkWEBPImageDecoder::setDecodeConfig(SkBitmap* decodedBitmap, int width, int height) {
+    SkColorType colorType = this->getPrefColorType(k32Bit_SrcDepth, SkToBool(fHasAlpha));
+
+    // YUV converter supports output in RGB565, RGBA4444 and RGBA8888 formats.
+    if (fHasAlpha) {
+        if (colorType != kARGB_4444_SkColorType) {
+            colorType = kN32_SkColorType;
+        }
+    } else {
+        if (colorType != kRGB_565_SkColorType && colorType != kARGB_4444_SkColorType) {
+            colorType = kN32_SkColorType;
+        }
+    }
+
+    SkAlphaType alphaType = kOpaque_SkAlphaType;
+    if (SkToBool(fHasAlpha)) {
+        if (this->getRequireUnpremultipliedColors()) {
+            alphaType = kUnpremul_SkAlphaType;
+        } else {
+            alphaType = kPremul_SkAlphaType;
+        }
+    }
+    return decodedBitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType));
+}
+
+SkImageDecoder::Result SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
+                                                    Mode mode) {
+#ifdef TIME_DECODE
+    AutoTimeMillis atm("WEBP Decode");
+#endif
+
+    int origWidth, origHeight, hasAlpha;
+    if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) {
+        return kFailure;
+    }
+    this->fHasAlpha = hasAlpha;
+
+    const int sampleSize = this->getSampleSize();
+    SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
+    if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
+                         sampler.scaledHeight())) {
+        return kFailure;
+    }
+
+    // If only bounds are requested, done
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    if (!this->allocPixelRef(decodedBitmap, nullptr)) {
+        return return_failure(*decodedBitmap, "allocPixelRef");
+    }
+
+    SkAutoLockPixels alp(*decodedBitmap);
+
+    WebPDecoderConfig config;
+    if (!webp_get_config_resize(&config, decodedBitmap, origWidth, origHeight,
+                                this->shouldPremultiply())) {
+        return kFailure;
+    }
+
+    // Decode the WebP image data stream using WebP incremental decoding.
+    return webp_idecode(stream, &config) ? kSuccess : kFailure;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 #include "SkUnPreMultiply.h"
 
 typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width,
@@ -237,11 +528,32 @@
 
 
 ///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(WEBPImageDecoder);
 DEFINE_ENCODER_CREATOR(WEBPImageEncoder);
 ///////////////////////////////////////////////////////////////////////////////
 
+static SkImageDecoder* sk_libwebp_dfactory(SkStreamRewindable* stream) {
+    int width, height, hasAlpha;
+    if (!webp_parse_header(stream, &width, &height, &hasAlpha)) {
+        return nullptr;
+    }
+
+    // Magic matches, call decoder
+    return new SkWEBPImageDecoder;
+}
+
+static SkImageDecoder::Format get_format_webp(SkStreamRewindable* stream) {
+    int width, height, hasAlpha;
+    if (webp_parse_header(stream, &width, &height, &hasAlpha)) {
+        return SkImageDecoder::kWEBP_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
 static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) {
     return (SkImageEncoder::kWEBP_Type == t) ? new SkWEBPImageEncoder : nullptr;
 }
 
+static SkImageDecoder_DecodeReg gDReg(sk_libwebp_dfactory);
+static SkImageDecoder_FormatReg gFormatReg(get_format_webp);
 static SkImageEncoder_EncodeReg gEReg(sk_libwebp_efactory);
diff --git a/src/images/SkImageDecoder_pkm.cpp b/src/images/SkImageDecoder_pkm.cpp
new file mode 100644
index 0000000..af68f20
--- /dev/null
+++ b/src/images/SkImageDecoder_pkm.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkColorPriv.h"
+#include "SkData.h"
+#include "SkImageDecoder.h"
+#include "SkScaledBitmapSampler.h"
+#include "SkStream.h"
+#include "SkStreamPriv.h"
+#include "SkTextureCompressor.h"
+#include "SkTypes.h"
+
+#include "etc1.h"
+
+class SkPKMImageDecoder : public SkImageDecoder {
+public:
+    SkPKMImageDecoder() { }
+
+    Format getFormat() const override {
+        return kPKM_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+SkImageDecoder::Result SkPKMImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    sk_sp<SkData> data(SkCopyStreamToData(stream));
+    if (!data || !data->size()) {
+        return kFailure;
+    }
+
+    unsigned char* buf = (unsigned char*) data->data();
+
+    // Make sure original PKM header is there...
+    SkASSERT(etc1_pkm_is_valid(buf));
+
+    const unsigned short width = etc1_pkm_get_width(buf);
+    const unsigned short height = etc1_pkm_get_height(buf);
+
+    // Setup the sampler...
+    SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
+
+    // Set the config...
+    bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(),
+                                     kOpaque_SkAlphaType));
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    if (!this->allocPixelRef(bm, nullptr)) {
+        return kFailure;
+    }
+
+    // Lock the pixels, since we're about to write to them...
+    SkAutoLockPixels alp(*bm);
+
+    if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
+        return kFailure;
+    }
+
+    // Advance buffer past the header
+    buf += ETC_PKM_HEADER_SIZE;
+
+    // ETC1 Data is encoded as RGB pixels, so we should extract it as such
+    int nPixels = width * height;
+    SkAutoMalloc outRGBData(nPixels * 3);
+    uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
+
+    // Decode ETC1
+    if (!SkTextureCompressor::DecompressBufferFromFormat(
+            outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor::kETC1_Format)) {
+        return kFailure;
+    }
+
+    // Set each of the pixels...
+    const int srcRowBytes = width * 3;
+    const int dstHeight = sampler.scaledHeight();
+    const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr);
+    srcRow += sampler.srcY0() * srcRowBytes;
+    for (int y = 0; y < dstHeight; ++y) {
+        sampler.next(srcRow);
+        srcRow += sampler.srcDY() * srcRowBytes;
+    }
+
+    return kSuccess;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(PKMImageDecoder);
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static bool is_pkm(SkStreamRewindable* stream) {
+    // Read the PKM header and make sure it's valid.
+    unsigned char buf[ETC_PKM_HEADER_SIZE];
+    if (stream->read((void*)buf, ETC_PKM_HEADER_SIZE) != ETC_PKM_HEADER_SIZE) {
+        return false;
+    }
+
+    return SkToBool(etc1_pkm_is_valid(buf));
+}
+
+static SkImageDecoder* sk_libpkm_dfactory(SkStreamRewindable* stream) {
+    if (is_pkm(stream)) {
+        return new SkPKMImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder_DecodeReg gReg(sk_libpkm_dfactory);
+
+static SkImageDecoder::Format get_format_pkm(SkStreamRewindable* stream) {
+    if (is_pkm(stream)) {
+        return SkImageDecoder::kPKM_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_pkm);
diff --git a/src/images/SkImageDecoder_wbmp.cpp b/src/images/SkImageDecoder_wbmp.cpp
new file mode 100644
index 0000000..335966b
--- /dev/null
+++ b/src/images/SkImageDecoder_wbmp.cpp
@@ -0,0 +1,173 @@
+
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkImageDecoder.h"
+#include "SkColor.h"
+#include "SkColorPriv.h"
+#include "SkMath.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include "SkUtils.h"
+
+class SkWBMPImageDecoder : public SkImageDecoder {
+public:
+    Format getFormat() const override {
+        return kWBMP_Format;
+    }
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
+
+private:
+    typedef SkImageDecoder INHERITED;
+};
+
+static bool read_byte(SkStream* stream, uint8_t* data)
+{
+    return stream->read(data, 1) == 1;
+}
+
+static bool read_mbf(SkStream* stream, int* value)
+{
+    int n = 0;
+    uint8_t data;
+    do {
+        if (!read_byte(stream, &data)) {
+            return false;
+        }
+        n = (n << 7) | (data & 0x7F);
+    } while (data & 0x80);
+
+    *value = n;
+    return true;
+}
+
+struct wbmp_head {
+    int fWidth;
+    int fHeight;
+
+    bool init(SkStream* stream)
+    {
+        uint8_t data;
+
+        if (!read_byte(stream, &data) || data != 0) { // unknown type
+            return false;
+        }
+        if (!read_byte(stream, &data) || (data & 0x9F)) { // skip fixed header
+            return false;
+        }
+        if (!read_mbf(stream, &fWidth) || (unsigned)fWidth > 0xFFFF) {
+            return false;
+        }
+        if (!read_mbf(stream, &fHeight) || (unsigned)fHeight > 0xFFFF) {
+            return false;
+        }
+        return fWidth != 0 && fHeight != 0;
+    }
+};
+
+static void expand_bits_to_bytes(uint8_t dst[], const uint8_t src[], int bits)
+{
+    int bytes = bits >> 3;
+
+    for (int i = 0; i < bytes; i++) {
+        unsigned mask = *src++;
+        dst[0] = (mask >> 7) & 1;
+        dst[1] = (mask >> 6) & 1;
+        dst[2] = (mask >> 5) & 1;
+        dst[3] = (mask >> 4) & 1;
+        dst[4] = (mask >> 3) & 1;
+        dst[5] = (mask >> 2) & 1;
+        dst[6] = (mask >> 1) & 1;
+        dst[7] = (mask >> 0) & 1;
+        dst += 8;
+    }
+
+    bits &= 7;
+    if (bits > 0) {
+        unsigned mask = *src;
+        do {
+            *dst++ = (mask >> 7) & 1;
+            mask <<= 1;
+        } while (--bits != 0);
+    }
+}
+
+SkImageDecoder::Result SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
+                                                    Mode mode)
+{
+    wbmp_head   head;
+
+    if (!head.init(stream)) {
+        return kFailure;
+    }
+
+    int width = head.fWidth;
+    int height = head.fHeight;
+
+    decodedBitmap->setInfo(SkImageInfo::Make(width, height,
+                                             kIndex_8_SkColorType, kOpaque_SkAlphaType));
+
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
+    SkColorTable* ct = new SkColorTable(colors, 2);
+    SkAutoUnref   aur(ct);
+
+    if (!this->allocPixelRef(decodedBitmap, ct)) {
+        return kFailure;
+    }
+
+    SkAutoLockPixels alp(*decodedBitmap);
+
+    uint8_t* dst = decodedBitmap->getAddr8(0, 0);
+    // store the 1-bit valuess at the end of our pixels, so we won't stomp
+    // on them before we're read them. Just trying to avoid a temp allocation
+    size_t srcRB = SkAlign8(width) >> 3;
+    size_t srcSize = height * srcRB;
+    uint8_t* src = dst + decodedBitmap->getSize() - srcSize;
+    if (stream->read(src, srcSize) != srcSize) {
+        return kFailure;
+    }
+
+    for (int y = 0; y < height; y++)
+    {
+        expand_bits_to_bytes(dst, src, width);
+        dst += decodedBitmap->rowBytes();
+        src += srcRB;
+    }
+
+    return kSuccess;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+DEFINE_DECODER_CREATOR(WBMPImageDecoder);
+///////////////////////////////////////////////////////////////////////////////
+
+static SkImageDecoder* sk_wbmp_dfactory(SkStreamRewindable* stream) {
+    wbmp_head   head;
+
+    if (head.init(stream)) {
+        return new SkWBMPImageDecoder;
+    }
+    return nullptr;
+}
+
+static SkImageDecoder::Format get_format_wbmp(SkStreamRewindable* stream) {
+    wbmp_head head;
+    if (head.init(stream)) {
+        return SkImageDecoder::kWBMP_Format;
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder_DecodeReg gDReg(sk_wbmp_dfactory);
+static SkImageDecoder_FormatReg gFormatReg(get_format_wbmp);
diff --git a/src/images/SkJpegUtility.cpp b/src/images/SkJpegUtility.cpp
index ab8486b..f1a32ca 100644
--- a/src/images/SkJpegUtility.cpp
+++ b/src/images/SkJpegUtility.cpp
@@ -8,6 +8,108 @@
 
 #include "SkJpegUtility.h"
 
+/////////////////////////////////////////////////////////////////////
+static void sk_init_source(j_decompress_ptr cinfo) {
+    skjpeg_source_mgr*  src = (skjpeg_source_mgr*)cinfo->src;
+    src->next_input_byte = (const JOCTET*)src->fBuffer;
+    src->bytes_in_buffer = 0;
+#ifdef SK_JPEG_INDEX_SUPPORTED
+    src->current_offset = 0;
+#endif
+    if (!src->fStream->rewind()) {
+        SkDebugf("xxxxxxxxxxxxxx failure to rewind\n");
+        cinfo->err->error_exit((j_common_ptr)cinfo);
+    }
+}
+
+#ifdef SK_JPEG_INDEX_SUPPORTED
+static boolean sk_seek_input_data(j_decompress_ptr cinfo, long byte_offset) {
+    skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src;
+    size_t bo = (size_t) byte_offset;
+
+    if (bo > src->current_offset) {
+        (void)src->fStream->skip(bo - src->current_offset);
+    } else {
+        if (!src->fStream->rewind()) {
+            SkDebugf("xxxxxxxxxxxxxx failure to rewind\n");
+            cinfo->err->error_exit((j_common_ptr)cinfo);
+            return false;
+        }
+        (void)src->fStream->skip(bo);
+    }
+
+    src->current_offset = bo;
+    src->next_input_byte = (const JOCTET*)src->fBuffer;
+    src->bytes_in_buffer = 0;
+    return true;
+}
+#endif
+
+static boolean sk_fill_input_buffer(j_decompress_ptr cinfo) {
+    skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src;
+    if (src->fDecoder != nullptr && src->fDecoder->shouldCancelDecode()) {
+        return FALSE;
+    }
+    size_t bytes = src->fStream->read(src->fBuffer, skjpeg_source_mgr::kBufferSize);
+    // note that JPEG is happy with less than the full read,
+    // as long as the result is non-zero
+    if (bytes == 0) {
+        return FALSE;
+    }
+
+#ifdef SK_JPEG_INDEX_SUPPORTED
+    src->current_offset += bytes;
+#endif
+    src->next_input_byte = (const JOCTET*)src->fBuffer;
+    src->bytes_in_buffer = bytes;
+    return TRUE;
+}
+
+static void sk_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
+    skjpeg_source_mgr*  src = (skjpeg_source_mgr*)cinfo->src;
+
+    if (num_bytes > (long)src->bytes_in_buffer) {
+        size_t bytesToSkip = num_bytes - src->bytes_in_buffer;
+        while (bytesToSkip > 0) {
+            size_t bytes = src->fStream->skip(bytesToSkip);
+            if (bytes <= 0 || bytes > bytesToSkip) {
+//              SkDebugf("xxxxxxxxxxxxxx failure to skip request %d returned %d\n", bytesToSkip, bytes);
+                cinfo->err->error_exit((j_common_ptr)cinfo);
+                return;
+            }
+#ifdef SK_JPEG_INDEX_SUPPORTED
+            src->current_offset += bytes;
+#endif
+            bytesToSkip -= bytes;
+        }
+        src->next_input_byte = (const JOCTET*)src->fBuffer;
+        src->bytes_in_buffer = 0;
+    } else {
+        src->next_input_byte += num_bytes;
+        src->bytes_in_buffer -= num_bytes;
+    }
+}
+
+static void sk_term_source(j_decompress_ptr /*cinfo*/) {}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder)
+    : fStream(stream)
+    , fDecoder(decoder) {
+
+    init_source = sk_init_source;
+    fill_input_buffer = sk_fill_input_buffer;
+    skip_input_data = sk_skip_input_data;
+    resync_to_restart = jpeg_resync_to_restart;
+    term_source = sk_term_source;
+#ifdef SK_JPEG_INDEX_SUPPORTED
+    seek_input_data = sk_seek_input_data;
+#endif
+//    SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static void sk_init_destination(j_compress_ptr cinfo) {
diff --git a/src/images/SkJpegUtility.h b/src/images/SkJpegUtility.h
index c844652..1a763f8 100644
--- a/src/images/SkJpegUtility.h
+++ b/src/images/SkJpegUtility.h
@@ -10,6 +10,7 @@
 #ifndef SkJpegUtility_DEFINED
 #define SkJpegUtility_DEFINED
 
+#include "SkImageDecoder.h"
 #include "SkStream.h"
 
 extern "C" {
@@ -29,6 +30,23 @@
 
 void skjpeg_error_exit(j_common_ptr cinfo);
 
+///////////////////////////////////////////////////////////////////////////
+/* Our source struct for directing jpeg to our stream object.
+*/
+struct skjpeg_source_mgr : jpeg_source_mgr {
+    skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder);
+
+    // Unowned.
+    SkStream*       fStream;
+    // Unowned pointer to the decoder, used to check if the decoding process
+    // has been cancelled.
+    SkImageDecoder* fDecoder;
+    enum {
+        kBufferSize = 1024
+    };
+    char    fBuffer[kBufferSize];
+};
+
 /////////////////////////////////////////////////////////////////////////////
 /* Our destination struct for directing decompressed pixels to our stream
  * object.
diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp
new file mode 100644
index 0000000..5ffd648
--- /dev/null
+++ b/src/images/SkScaledBitmapSampler.cpp
@@ -0,0 +1,877 @@
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkScaledBitmapSampler.h"
+#include "SkBitmap.h"
+#include "SkColorPriv.h"
+#include "SkDither.h"
+#include "SkTypes.h"
+
+// 8888
+
+static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow,
+                              const uint8_t* SK_RESTRICT src,
+                              int width, int deltaSrc, int, const SkPMColor[]) {
+    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_gray_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Dither, unpremul, and skipZeroes have no effect
+    return Sample_Gray_D8888;
+}
+
+static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow,
+                              const uint8_t* SK_RESTRICT src,
+                              int width, int deltaSrc, int, const SkPMColor[]) {
+    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_RGBx_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Dither, unpremul, and skipZeroes have no effect
+    return Sample_RGBx_D8888;
+}
+
+static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow,
+                              const uint8_t* SK_RESTRICT src,
+                              int width, int deltaSrc, int, const SkPMColor[]) {
+    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
+    unsigned alphaMask = 0xFF;
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow,
+                                       const uint8_t* SK_RESTRICT src,
+                                       int width, int deltaSrc, int,
+                                       const SkPMColor[]) {
+    uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
+    unsigned alphaMask = 0xFF;
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+static bool Sample_RGBA_D8888_SkipZ(void* SK_RESTRICT dstRow,
+                                    const uint8_t* SK_RESTRICT src,
+                                    int width, int deltaSrc, int,
+                                    const SkPMColor[]) {
+    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
+    unsigned alphaMask = 0xFF;
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        if (0 != alpha) {
+            dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
+        }
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_RGBA_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Dither has no effect.
+    if (!opts.fPremultiplyAlpha) {
+        // We could check each component for a zero, at the expense of extra checks.
+        // For now, just return unpremul.
+        return Sample_RGBA_D8888_Unpremul;
+    }
+    // Supply the versions that premultiply the colors
+    if (opts.fSkipZeros) {
+        return Sample_RGBA_D8888_SkipZ;
+    }
+    return Sample_RGBA_D8888;
+}
+
+// 565
+
+static bool Sample_Gray_D565(void* SK_RESTRICT dstRow,
+                             const uint8_t* SK_RESTRICT src,
+                             int width, int deltaSrc, int, const SkPMColor[]) {
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow,
+                               const uint8_t* SK_RESTRICT src,
+                           int width, int deltaSrc, int y, const SkPMColor[]) {
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    DITHER_565_SCAN(y);
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x));
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_gray_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Unpremul and skip zeroes make no difference
+    if (opts.fDither) {
+        return Sample_Gray_D565_D;
+    }
+    return Sample_Gray_D565;
+}
+
+static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow,
+                             const uint8_t* SK_RESTRICT src,
+                             int width, int deltaSrc, int, const SkPMColor[]) {
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow,
+                               const uint8_t* SK_RESTRICT src,
+                               int width, int deltaSrc, int y,
+                               const SkPMColor[]) {
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    DITHER_565_SCAN(y);
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x));
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_RGBx_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Unpremul and skip zeroes make no difference
+    if (opts.fDither) {
+        return Sample_RGBx_D565_D;
+    }
+    return Sample_RGBx_D565;
+}
+
+
+static bool Sample_D565_D565(void* SK_RESTRICT dstRow,
+                             const uint8_t* SK_RESTRICT src,
+                             int width, int deltaSrc, int, const SkPMColor[]) {
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src;
+    for (int x = 0; x < width; x++) {
+        dst[x] = castedSrc[0];
+        castedSrc += deltaSrc >> 1;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_565_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Unpremul, dither, and skip zeroes have no effect
+    return Sample_D565_D565;
+}
+
+// 4444
+
+static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow,
+                              const uint8_t* SK_RESTRICT src,
+                              int width, int deltaSrc, int, const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    for (int x = 0; x < width; x++) {
+        unsigned gray = src[0] >> 4;
+        dst[x] = SkPackARGB4444(0xF, gray, gray, gray);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow,
+                                const uint8_t* SK_RESTRICT src,
+                            int width, int deltaSrc, int y, const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    DITHER_4444_SCAN(y);
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0],
+                                      DITHER_VALUE(x));
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_gray_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Skip zeroes and unpremul make no difference
+    if (opts.fDither) {
+        return Sample_Gray_D4444_D;
+    }
+    return Sample_Gray_D4444;
+}
+
+static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow,
+                              const uint8_t* SK_RESTRICT src,
+                              int width, int deltaSrc, int, const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow,
+                                const uint8_t* SK_RESTRICT src,
+                            int width, int deltaSrc, int y, const SkPMColor[]) {
+    SkPMColor16* dst = (SkPMColor16*)dstRow;
+    DITHER_4444_SCAN(y);
+
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2],
+                                      DITHER_VALUE(x));
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_RGBx_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Skip zeroes and unpremul make no difference
+    if (opts.fDither) {
+        return Sample_RGBx_D4444_D;
+    }
+    return Sample_RGBx_D4444;
+}
+
+static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow,
+                              const uint8_t* SK_RESTRICT src,
+                              int width, int deltaSrc, int, const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    unsigned alphaMask = 0xFF;
+
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
+        dst[x] = SkPixel32ToPixel4444(c);
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+static bool Sample_RGBA_D4444_SkipZ(void* SK_RESTRICT dstRow,
+                                    const uint8_t* SK_RESTRICT src,
+                                    int width, int deltaSrc, int,
+                                    const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    unsigned alphaMask = 0xFF;
+
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        if (alpha != 0) {
+            SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
+            dst[x] = SkPixel32ToPixel4444(c);
+        }
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+
+static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow,
+                                const uint8_t* SK_RESTRICT src,
+                                int width, int deltaSrc, int y,
+                                const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    unsigned alphaMask = 0xFF;
+    DITHER_4444_SCAN(y);
+
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
+        dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+static bool Sample_RGBA_D4444_D_SkipZ(void* SK_RESTRICT dstRow,
+                                      const uint8_t* SK_RESTRICT src,
+                                      int width, int deltaSrc, int y,
+                                      const SkPMColor[]) {
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    unsigned alphaMask = 0xFF;
+    DITHER_4444_SCAN(y);
+
+    for (int x = 0; x < width; x++) {
+        unsigned alpha = src[3];
+        if (alpha != 0) {
+            SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
+            dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
+        }
+        src += deltaSrc;
+        alphaMask &= alpha;
+    }
+    return alphaMask != 0xFF;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_RGBA_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
+    if (!opts.fPremultiplyAlpha) {
+        // Unpremultiplied is not supported for 4444
+        return nullptr;
+    }
+    if (opts.fSkipZeros) {
+        if (opts.fDither) {
+            return Sample_RGBA_D4444_D_SkipZ;
+        }
+        return Sample_RGBA_D4444_SkipZ;
+    }
+    if (opts.fDither) {
+        return Sample_RGBA_D4444_D;
+    }
+    return Sample_RGBA_D4444;
+}
+
+// Index
+
+#define A32_MASK_IN_PLACE   (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
+
+static bool Sample_Index_D8888(void* SK_RESTRICT dstRow,
+                               const uint8_t* SK_RESTRICT src,
+                       int width, int deltaSrc, int, const SkPMColor ctable[]) {
+
+    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
+    SkPMColor cc = A32_MASK_IN_PLACE;
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        cc &= c;
+        dst[x] = c;
+        src += deltaSrc;
+    }
+    return cc != A32_MASK_IN_PLACE;
+}
+
+static bool Sample_Index_D8888_SkipZ(void* SK_RESTRICT dstRow,
+                                     const uint8_t* SK_RESTRICT src,
+                                     int width, int deltaSrc, int,
+                                     const SkPMColor ctable[]) {
+
+    SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
+    SkPMColor cc = A32_MASK_IN_PLACE;
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        cc &= c;
+        if (c != 0) {
+            dst[x] = c;
+        }
+        src += deltaSrc;
+    }
+    return cc != A32_MASK_IN_PLACE;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_index_to_8888_proc(const SkScaledBitmapSampler::Options& opts) {
+    // The caller is expected to have created the source colortable
+    // properly with respect to opts.fPremultiplyAlpha, so premul makes
+    // no difference here.
+    // Dither makes no difference
+    if (opts.fSkipZeros) {
+        return Sample_Index_D8888_SkipZ;
+    }
+    return Sample_Index_D8888;
+}
+
+static bool Sample_Index_D565(void* SK_RESTRICT dstRow,
+                               const uint8_t* SK_RESTRICT src,
+                       int width, int deltaSrc, int, const SkPMColor ctable[]) {
+
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    for (int x = 0; x < width; x++) {
+        dst[x] = SkPixel32ToPixel16(ctable[*src]);
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow,
+                                const uint8_t* SK_RESTRICT src, int width,
+                                int deltaSrc, int y, const SkPMColor ctable[]) {
+
+    uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
+    DITHER_565_SCAN(y);
+
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c),
+                                  SkGetPackedB32(c), DITHER_VALUE(x));
+        src += deltaSrc;
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_index_to_565_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Unpremultiplied and skip zeroes make no difference
+    if (opts.fDither) {
+        return Sample_Index_D565_D;
+    }
+    return Sample_Index_D565;
+}
+
+static bool Sample_Index_D4444(void* SK_RESTRICT dstRow,
+                               const uint8_t* SK_RESTRICT src, int width,
+                               int deltaSrc, int y, const SkPMColor ctable[]) {
+
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    SkPMColor cc = A32_MASK_IN_PLACE;
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        cc &= c;
+        dst[x] = SkPixel32ToPixel4444(c);
+        src += deltaSrc;
+    }
+    return cc != A32_MASK_IN_PLACE;
+}
+
+static bool Sample_Index_D4444_D(void* SK_RESTRICT dstRow,
+                                 const uint8_t* SK_RESTRICT src, int width,
+                                int deltaSrc, int y, const SkPMColor ctable[]) {
+
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    SkPMColor cc = A32_MASK_IN_PLACE;
+    DITHER_4444_SCAN(y);
+
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        cc &= c;
+        dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
+        src += deltaSrc;
+    }
+    return cc != A32_MASK_IN_PLACE;
+}
+
+static bool Sample_Index_D4444_SkipZ(void* SK_RESTRICT dstRow,
+                                     const uint8_t* SK_RESTRICT src, int width,
+                                     int deltaSrc, int y, const SkPMColor ctable[]) {
+
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    SkPMColor cc = A32_MASK_IN_PLACE;
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        cc &= c;
+        if (c != 0) {
+            dst[x] = SkPixel32ToPixel4444(c);
+        }
+        src += deltaSrc;
+    }
+    return cc != A32_MASK_IN_PLACE;
+}
+
+static bool Sample_Index_D4444_D_SkipZ(void* SK_RESTRICT dstRow,
+                                       const uint8_t* SK_RESTRICT src, int width,
+                                       int deltaSrc, int y, const SkPMColor ctable[]) {
+
+    SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow;
+    SkPMColor cc = A32_MASK_IN_PLACE;
+    DITHER_4444_SCAN(y);
+
+    for (int x = 0; x < width; x++) {
+        SkPMColor c = ctable[*src];
+        cc &= c;
+        if (c != 0) {
+            dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x));
+        }
+        src += deltaSrc;
+    }
+    return cc != A32_MASK_IN_PLACE;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_index_to_4444_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Unpremul not allowed
+    if (!opts.fPremultiplyAlpha) {
+        return nullptr;
+    }
+    if (opts.fSkipZeros) {
+        if (opts.fDither) {
+            return Sample_Index_D4444_D_SkipZ;
+        }
+        return Sample_Index_D4444_SkipZ;
+    }
+    if (opts.fDither) {
+        return Sample_Index_D4444_D;
+    }
+    return Sample_Index_D4444;
+}
+
+static bool Sample_Index_DI(void* SK_RESTRICT dstRow,
+                            const uint8_t* SK_RESTRICT src,
+                            int width, int deltaSrc, int, const SkPMColor[]) {
+    if (1 == deltaSrc) {
+        memcpy(dstRow, src, width);
+    } else {
+        uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow;
+        for (int x = 0; x < width; x++) {
+            dst[x] = src[0];
+            src += deltaSrc;
+        }
+    }
+    return false;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_index_to_index_proc(const SkScaledBitmapSampler::Options& opts) {
+    // Unpremul not allowed
+    if (!opts.fPremultiplyAlpha) {
+        return nullptr;
+    }
+    // Ignore dither and skip zeroes
+    return Sample_Index_DI;
+}
+
+// A8
+static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow,
+                            const uint8_t* SK_RESTRICT src,
+                            int width, int deltaSrc, int,
+                            const SkPMColor[]) {
+    // Sampling Gray to A8 uses the same function as Index to Index8,
+    // except we assume that there is alpha for speed, since an A8
+    // bitmap with no alpha is not interesting.
+    (void) Sample_Index_DI(dstRow, src, width, deltaSrc, /* y unused */ 0,
+                           /* ctable unused */ nullptr);
+    return true;
+}
+
+static SkScaledBitmapSampler::RowProc
+get_gray_to_A8_proc(const SkScaledBitmapSampler::Options& opts) {
+    if (!opts.fPremultiplyAlpha) {
+        return nullptr;
+    }
+    // Ignore skip and dither.
+    return Sample_Gray_DA8;
+}
+
+typedef SkScaledBitmapSampler::RowProc (*RowProcChooser)(const SkScaledBitmapSampler::Options&);
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkScaledBitmapSampler.h"
+
+SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height,
+                                             int sampleSize) {
+    fCTable = nullptr;
+    fDstRow = nullptr;
+    fRowProc = nullptr;
+
+    if (width <= 0 || height <= 0) {
+        sk_throw();
+    }
+
+    SkDEBUGCODE(fSampleMode = kUninitialized_SampleMode);
+
+    if (sampleSize <= 1) {
+        fScaledWidth = width;
+        fScaledHeight = height;
+        fX0 = fY0 = 0;
+        fDX = fDY = 1;
+        return;
+    }
+
+    int dx = SkMin32(sampleSize, width);
+    int dy = SkMin32(sampleSize, height);
+
+    fScaledWidth = width / dx;
+    fScaledHeight = height / dy;
+
+    SkASSERT(fScaledWidth > 0);
+    SkASSERT(fScaledHeight > 0);
+
+    fX0 = dx >> 1;
+    fY0 = dy >> 1;
+
+    SkASSERT(fX0 >= 0 && fX0 < width);
+    SkASSERT(fY0 >= 0 && fY0 < height);
+
+    fDX = dx;
+    fDY = dy;
+
+    SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width);
+    SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height);
+}
+
+bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
+                                  const Options& opts,
+                                  const SkPMColor ctable[]) {
+    static const RowProcChooser gProcChoosers[] = {
+        get_gray_to_8888_proc,
+        get_RGBx_to_8888_proc,
+        get_RGBA_to_8888_proc,
+        get_index_to_8888_proc,
+        nullptr, // 565 to 8888
+
+        get_gray_to_565_proc,
+        get_RGBx_to_565_proc,
+        get_RGBx_to_565_proc, // The source alpha will be ignored.
+        get_index_to_565_proc,
+        get_565_to_565_proc,
+
+        get_gray_to_4444_proc,
+        get_RGBx_to_4444_proc,
+        get_RGBA_to_4444_proc,
+        get_index_to_4444_proc,
+        nullptr, // 565 to 4444
+
+        nullptr, // gray to index
+        nullptr, // rgbx to index
+        nullptr, // rgba to index
+        get_index_to_index_proc,
+        nullptr, // 565 to index
+
+        get_gray_to_A8_proc,
+        nullptr, // rgbx to a8
+        nullptr, // rgba to a8
+        nullptr, // index to a8
+        nullptr, // 565 to a8
+    };
+
+    // The jump between dst configs in the table
+    static const int gProcDstConfigSpan = 5;
+    static_assert(SK_ARRAY_COUNT(gProcChoosers) == 5 * gProcDstConfigSpan,
+                  "gProcs_has_the_wrong_number_of_entries");
+
+    fCTable = ctable;
+
+    int index = 0;
+    switch (sc) {
+        case SkScaledBitmapSampler::kGray:
+            fSrcPixelSize = 1;
+            index += 0;
+            break;
+        case SkScaledBitmapSampler::kRGB:
+            fSrcPixelSize = 3;
+            index += 1;
+            break;
+        case SkScaledBitmapSampler::kRGBX:
+            fSrcPixelSize = 4;
+            index += 1;
+            break;
+        case SkScaledBitmapSampler::kRGBA:
+            fSrcPixelSize = 4;
+            index += 2;
+            break;
+        case SkScaledBitmapSampler::kIndex:
+            fSrcPixelSize = 1;
+            index += 3;
+            break;
+        case SkScaledBitmapSampler::kRGB_565:
+            fSrcPixelSize = 2;
+            index += 4;
+            break;
+        default:
+            return false;
+    }
+
+    switch (dst->colorType()) {
+        case kN32_SkColorType:
+            index += 0 * gProcDstConfigSpan;
+            break;
+        case kRGB_565_SkColorType:
+            index += 1 * gProcDstConfigSpan;
+            break;
+        case kARGB_4444_SkColorType:
+            index += 2 * gProcDstConfigSpan;
+            break;
+        case kIndex_8_SkColorType:
+            index += 3 * gProcDstConfigSpan;
+            break;
+        case kAlpha_8_SkColorType:
+            index += 4 * gProcDstConfigSpan;
+            break;
+        default:
+            return false;
+    }
+
+    RowProcChooser chooser = gProcChoosers[index];
+    if (nullptr == chooser) {
+        fRowProc = nullptr;
+    } else {
+        fRowProc = chooser(opts);
+    }
+    fDstRow = (char*)dst->getPixels();
+    fDstRowBytes = dst->rowBytes();
+    fCurrY = 0;
+    return fRowProc != nullptr;
+}
+
+bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc,
+                                  const SkImageDecoder& decoder,
+                                  const SkPMColor ctable[]) {
+    return this->begin(dst, sc, Options(decoder), ctable);
+}
+
+bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) {
+    SkASSERT(kInterlaced_SampleMode != fSampleMode);
+    SkDEBUGCODE(fSampleMode = kConsecutive_SampleMode);
+    SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight);
+
+    bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth,
+                             fDX * fSrcPixelSize, fCurrY, fCTable);
+    fDstRow += fDstRowBytes;
+    fCurrY += 1;
+    return hadAlpha;
+}
+
+bool SkScaledBitmapSampler::sampleInterlaced(const uint8_t* SK_RESTRICT src, int srcY) {
+    SkASSERT(kConsecutive_SampleMode != fSampleMode);
+    SkDEBUGCODE(fSampleMode = kInterlaced_SampleMode);
+    // Any line that should be a part of the destination can be created by the formula:
+    // fY0 + (some multiplier) * fDY
+    // so if srcY - fY0 is not an integer multiple of fDY that srcY will be skipped.
+    const int srcYMinusY0 = srcY - fY0;
+    if (srcYMinusY0 % fDY != 0) {
+        // This line is not part of the output, so return false for alpha, since we have
+        // not added an alpha to the output.
+        return false;
+    }
+    // Unlike in next(), where the data is used sequentially, this function skips around,
+    // so fDstRow and fCurrY are never updated. fDstRow must always be the starting point
+    // of the destination bitmap's pixels, which is used to calculate the destination row
+    // each time this function is called.
+    const int dstY = srcYMinusY0 / fDY;
+    if (dstY >= fScaledHeight) {
+        return false;
+    }
+    char* dstRow = fDstRow + dstY * fDstRowBytes;
+    return fRowProc(dstRow, src + fX0 * fSrcPixelSize, fScaledWidth,
+                    fDX * fSrcPixelSize, dstY, fCTable);
+}
+
+#ifdef SK_DEBUG
+// The following code is for a test to ensure that changing the method to get the right row proc
+// did not change the row proc unintentionally. Tested by ImageDecodingTest.cpp
+
+// friend of SkScaledBitmapSampler solely for the purpose of accessing fRowProc.
+class RowProcTester {
+public:
+    static SkScaledBitmapSampler::RowProc getRowProc(const SkScaledBitmapSampler& sampler) {
+        return sampler.fRowProc;
+    }
+};
+
+
+// Table showing the expected RowProc for each combination of inputs.
+// Table formated as follows:
+// Each group of 5 consecutive rows represents sampling from a single
+// SkScaledBitmapSampler::SrcConfig.
+// Within each set, each row represents a different destination SkBitmap::Config
+// Each column represents a different combination of dither and unpremul.
+// D = dither   ~D = no dither
+// U = unpremul ~U = no unpremul
+//  ~D~U                D~U                     ~DU                         DU
+SkScaledBitmapSampler::RowProc gTestProcs[] = {
+    // Gray
+    Sample_Gray_DA8,    Sample_Gray_DA8,        nullptr,                       nullptr,                       // to A8
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to Index8
+    Sample_Gray_D565,   Sample_Gray_D565_D,     Sample_Gray_D565,           Sample_Gray_D565_D,         // to 565
+    Sample_Gray_D4444,  Sample_Gray_D4444_D,    Sample_Gray_D4444,          Sample_Gray_D4444_D,        // to 4444
+    Sample_Gray_D8888,  Sample_Gray_D8888,      Sample_Gray_D8888,          Sample_Gray_D8888,          // to 8888
+    // Index
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to A8
+    Sample_Index_DI,    Sample_Index_DI,        nullptr,                       nullptr,                       // to Index8
+    Sample_Index_D565,  Sample_Index_D565_D,    Sample_Index_D565,          Sample_Index_D565_D,        // to 565
+    Sample_Index_D4444, Sample_Index_D4444_D,   nullptr,                       nullptr,                       // to 4444
+    Sample_Index_D8888, Sample_Index_D8888,     Sample_Index_D8888,         Sample_Index_D8888,         // to 8888
+    // RGB
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to A8
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to Index8
+    Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Sample_RGBx_D565_D,         // to 565
+    Sample_RGBx_D4444,  Sample_RGBx_D4444_D,    Sample_RGBx_D4444,          Sample_RGBx_D4444_D,        // to 4444
+    Sample_RGBx_D8888,  Sample_RGBx_D8888,      Sample_RGBx_D8888,          Sample_RGBx_D8888,          // to 8888
+    // RGBx is the same as RGB
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to A8
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to Index8
+    Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Sample_RGBx_D565_D,         // to 565
+    Sample_RGBx_D4444,  Sample_RGBx_D4444_D,    Sample_RGBx_D4444,          Sample_RGBx_D4444_D,        // to 4444
+    Sample_RGBx_D8888,  Sample_RGBx_D8888,      Sample_RGBx_D8888,          Sample_RGBx_D8888,          // to 8888
+    // RGBA
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to A8
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to Index8
+    Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Sample_RGBx_D565_D,         // to 565
+    Sample_RGBA_D4444,  Sample_RGBA_D4444_D,    nullptr,                       nullptr,                       // to 4444
+    Sample_RGBA_D8888,  Sample_RGBA_D8888,      Sample_RGBA_D8888_Unpremul, Sample_RGBA_D8888_Unpremul, // to 8888
+    // RGB_565
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to A8
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to Index8
+    Sample_D565_D565,   Sample_D565_D565,       Sample_D565_D565,           Sample_D565_D565,           // to 565
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to 4444
+    nullptr,               nullptr,                   nullptr,                       nullptr,                       // to 8888
+};
+
+// Dummy class that allows instantiation of an ImageDecoder, so begin can query its fields.
+class DummyDecoder : public SkImageDecoder {
+public:
+    DummyDecoder() {}
+protected:
+    Result onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) override {
+        return kFailure;
+    }
+};
+
+void test_row_proc_choice();
+void test_row_proc_choice() {
+    const SkColorType colorTypes[] = {
+        kAlpha_8_SkColorType, kIndex_8_SkColorType, kRGB_565_SkColorType, kARGB_4444_SkColorType,
+        kN32_SkColorType
+    };
+
+    SkBitmap dummyBitmap;
+    DummyDecoder dummyDecoder;
+    size_t procCounter = 0;
+    for (int sc = SkScaledBitmapSampler::kGray; sc <= SkScaledBitmapSampler::kRGB_565; ++sc) {
+        for (size_t c = 0; c < SK_ARRAY_COUNT(colorTypes); ++c) {
+            for (int unpremul = 0; unpremul <= 1; ++unpremul) {
+                for (int dither = 0; dither <= 1; ++dither) {
+                    // Arbitrary width/height/sampleSize to allow SkScaledBitmapSampler to
+                    // be considered valid.
+                    SkScaledBitmapSampler sampler(10, 10, 1);
+                    dummyBitmap.setInfo(SkImageInfo::Make(10, 10,
+                                                          colorTypes[c], kPremul_SkAlphaType));
+                    dummyDecoder.setDitherImage(SkToBool(dither));
+                    dummyDecoder.setRequireUnpremultipliedColors(SkToBool(unpremul));
+                    sampler.begin(&dummyBitmap, (SkScaledBitmapSampler::SrcConfig) sc,
+                                  dummyDecoder);
+                    SkScaledBitmapSampler::RowProc expected = gTestProcs[procCounter];
+                    SkScaledBitmapSampler::RowProc actual = RowProcTester::getRowProc(sampler);
+                    SkASSERT(expected == actual);
+                    procCounter++;
+                }
+            }
+        }
+    }
+    SkASSERT(SK_ARRAY_COUNT(gTestProcs) == procCounter);
+}
+#endif // SK_DEBUG
diff --git a/src/images/SkScaledBitmapSampler.h b/src/images/SkScaledBitmapSampler.h
new file mode 100644
index 0000000..198dc07
--- /dev/null
+++ b/src/images/SkScaledBitmapSampler.h
@@ -0,0 +1,107 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkScaledBitmapSampler_DEFINED
+#define SkScaledBitmapSampler_DEFINED
+
+#include "SkTypes.h"
+#include "SkColor.h"
+#include "SkImageDecoder.h"
+
+class SkBitmap;
+
+class SkScaledBitmapSampler {
+public:
+    SkScaledBitmapSampler(int origWidth, int origHeight, int cellSize);
+
+    int scaledWidth() const { return fScaledWidth; }
+    int scaledHeight() const { return fScaledHeight; }
+
+    int srcY0() const { return fY0; }
+    int srcDX() const { return fDX; }
+    int srcDY() const { return fDY; }
+
+    enum SrcConfig {
+        kGray,  // 1 byte per pixel
+        kIndex, // 1 byte per pixel
+        kRGB,   // 3 bytes per pixel
+        kRGBX,  // 4 byes per pixel (ignore 4th)
+        kRGBA,  // 4 bytes per pixel
+        kRGB_565 // 2 bytes per pixel
+    };
+
+    struct Options {
+        bool fDither;
+        bool fPremultiplyAlpha;
+        bool fSkipZeros;
+        explicit Options(const SkImageDecoder &dec)
+            : fDither(dec.getDitherImage())
+            , fPremultiplyAlpha(!dec.getRequireUnpremultipliedColors())
+            , fSkipZeros(dec.getSkipWritingZeroes())
+            { }
+    };
+
+    // Given a dst bitmap (with pixels already allocated) and a src-config,
+    // prepares iterator to process the src colors and write them into dst.
+    // Returns false if the request cannot be fulfulled.
+    bool begin(SkBitmap* dst, SrcConfig sc, const SkImageDecoder& decoder,
+               const SkPMColor* = nullptr);
+    bool begin(SkBitmap* dst, SrcConfig sc, const Options& opts,
+               const SkPMColor* = nullptr);
+    // call with row of src pixels, for y = 0...scaledHeight-1.
+    // returns true if the row had non-opaque alpha in it
+    bool next(const uint8_t* SK_RESTRICT src);
+
+    // Like next(), but specifies the y value of the source row, so the
+    // rows can come in any order. If the row is not part of the output
+    // sample, it will be skipped. Only sampleInterlaced OR next should
+    // be called for one SkScaledBitmapSampler.
+    bool sampleInterlaced(const uint8_t* SK_RESTRICT src, int srcY);
+
+    typedef bool (*RowProc)(void* SK_RESTRICT dstRow,
+                            const uint8_t* SK_RESTRICT src,
+                            int width, int deltaSrc, int y,
+                            const SkPMColor[]);
+
+private:
+    int fScaledWidth;
+    int fScaledHeight;
+
+    int fX0;    // first X coord to sample
+    int fY0;    // first Y coord (scanline) to sample
+    int fDX;    // step between X samples
+    int fDY;    // step between Y samples
+
+#ifdef SK_DEBUG
+    // Keep track of whether the caller is using next or sampleInterlaced.
+    // Only one can be used per sampler.
+    enum SampleMode {
+        kUninitialized_SampleMode,
+        kConsecutive_SampleMode,
+        kInterlaced_SampleMode,
+    };
+
+    SampleMode fSampleMode;
+#endif
+
+    // setup state
+    char*   fDstRow; // points into bitmap's pixels
+    size_t  fDstRowBytes;
+    int     fCurrY; // used for dithering
+    int     fSrcPixelSize;  // 1, 3, 4
+    RowProc fRowProc;
+
+    // optional reference to the src colors if the src is a palette model
+    const SkPMColor* fCTable;
+
+#ifdef SK_DEBUG
+    // Helper class allowing a test to have access to fRowProc.
+    friend class RowProcTester;
+#endif
+};
+
+#endif
diff --git a/src/images/bmpdecoderhelper.cpp b/src/images/bmpdecoderhelper.cpp
new file mode 100644
index 0000000..9171b5d
--- /dev/null
+++ b/src/images/bmpdecoderhelper.cpp
@@ -0,0 +1,369 @@
+
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Author: cevans@google.com (Chris Evans)
+
+#include "bmpdecoderhelper.h"
+
+namespace image_codec {
+
+static const int kBmpHeaderSize = 14;
+static const int kBmpInfoSize = 40;
+static const int kBmpOS2InfoSize = 12;
+static const int kMaxDim = SHRT_MAX / 2;
+
+bool BmpDecoderHelper::DecodeImage(const char* p,
+                                   size_t len,
+                                   int max_pixels,
+                                   BmpDecoderCallback* callback) {
+  data_ = reinterpret_cast<const uint8*>(p);
+  pos_ = 0;
+  len_ = len;
+  inverted_ = true;
+  // Parse the header structure.
+  if (len < kBmpHeaderSize + 4) {
+    return false;
+  }
+  GetShort();  // Signature.
+  GetInt();  // Size.
+  GetInt();  // Reserved.
+  int offset = GetInt();
+  // Parse the info structure.
+  int infoSize = GetInt();
+  if (infoSize != kBmpOS2InfoSize && infoSize < kBmpInfoSize) {
+    return false;
+  }
+  int cols = 0;
+  int comp = 0;
+  int colLen = 4;
+  if (infoSize >= kBmpInfoSize) {
+    if (len < kBmpHeaderSize + kBmpInfoSize) {
+      return false;
+    }
+    width_ = GetInt();
+    height_ = GetInt();
+    GetShort();  // Planes.
+    bpp_ = GetShort();
+    comp = GetInt();
+    GetInt();  // Size.
+    GetInt();  // XPPM.
+    GetInt();  // YPPM.
+    cols = GetInt();
+    GetInt();  // Important colours.
+  } else {
+    if (len < kBmpHeaderSize + kBmpOS2InfoSize) {
+      return false;
+    }
+    colLen = 3;
+    width_ = GetShort();
+    height_ = GetShort();
+    GetShort();  // Planes.
+    bpp_ = GetShort();
+  }
+  if (height_ < 0) {
+    height_ = -height_;
+    inverted_ = false;
+  }
+  if (width_ <= 0 || width_ > kMaxDim || height_ <= 0 || height_ > kMaxDim) {
+    return false;
+  }
+  if (width_ * height_ > max_pixels) {
+    return false;
+  }
+  if (cols < 0 || cols > 256) {
+    return false;
+  }
+  // Allocate then read in the colour map.
+  if (cols == 0 && bpp_ <= 8) {
+    cols = 1 << bpp_;
+  }
+  if (bpp_ <= 8 || cols > 0) {
+    uint8* colBuf = new uint8[256 * 3];
+    memset(colBuf, '\0', 256 * 3);
+    colTab_.reset(colBuf);
+  }
+  if (cols > 0) {
+    if (pos_ + (cols * colLen) > len_) {
+      return false;
+    }
+    for (int i = 0; i < cols; ++i) {
+      int base = i * 3;
+      colTab_[base + 2] = GetByte();
+      colTab_[base + 1] = GetByte();
+      colTab_[base] = GetByte();
+      if (colLen == 4) {
+        GetByte();
+      }
+    }
+  }
+  // Read in the compression data if necessary.
+  redBits_ = 0x7c00;
+  greenBits_ = 0x03e0;
+  blueBits_ = 0x001f;
+  bool rle = false;
+  if (comp == 1 || comp == 2) {
+    rle = true;
+  } else if (comp == 3) {
+    if (pos_ + 12 > len_) {
+      return false;
+    }
+    redBits_ = GetInt() & 0xffff;
+    greenBits_ = GetInt() & 0xffff;
+    blueBits_ = GetInt() & 0xffff;
+  }
+  redShiftRight_ = CalcShiftRight(redBits_);
+  greenShiftRight_ = CalcShiftRight(greenBits_);
+  blueShiftRight_ = CalcShiftRight(blueBits_);
+  redShiftLeft_ = CalcShiftLeft(redBits_);
+  greenShiftLeft_ = CalcShiftLeft(greenBits_);
+  blueShiftLeft_ = CalcShiftLeft(blueBits_);
+  rowPad_ = 0;
+  pixelPad_ = 0;
+  int rowLen;
+  if (bpp_ == 32) {
+    rowLen = width_ * 4;
+    pixelPad_ = 1;
+  } else if (bpp_ == 24) {
+    rowLen = width_ * 3;
+  } else if (bpp_ == 16) {
+    rowLen = width_ * 2;
+  } else if (bpp_ == 8) {
+    rowLen = width_;
+  } else if (bpp_ == 4) {
+    rowLen = width_ / 2;
+    if (width_ & 1) {
+      rowLen++;
+    }
+  } else if (bpp_ == 1) {
+    rowLen = width_ / 8;
+    if (width_ & 7) {
+      rowLen++;
+    }
+  } else {
+    return false;
+  }
+  // Round the rowLen up to a multiple of 4.
+  if (rowLen % 4 != 0) {
+    rowPad_ = 4 - (rowLen % 4);
+    rowLen += rowPad_;
+  }
+
+  if (offset > 0 && (size_t)offset > pos_ && (size_t)offset < len_) {
+    pos_ = offset;
+  }
+  // Deliberately off-by-one; a load of BMPs seem to have their last byte
+  // missing.
+  if (!rle && (pos_ + (rowLen * height_) > len_ + 1)) {
+    return false;
+  }
+
+  output_ = callback->SetSize(width_, height_);
+  if (nullptr == output_) {
+    return true;  // meaning we succeeded, but they want us to stop now
+  }
+
+  if (rle && (bpp_ == 4 || bpp_ == 8)) {
+    DoRLEDecode();
+  } else {
+    DoStandardDecode();
+  }
+  return true;
+}
+
+void BmpDecoderHelper::DoRLEDecode() {
+  static const uint8 RLE_ESCAPE = 0;
+  static const uint8 RLE_EOL = 0;
+  static const uint8 RLE_EOF = 1;
+  static const uint8 RLE_DELTA = 2;
+  int x = 0;
+  int y = height_ - 1;
+  while (pos_ + 1 < len_) {
+    uint8 cmd = GetByte();
+    if (cmd != RLE_ESCAPE) {
+      uint8 pixels = GetByte();
+      int num = 0;
+      uint8 col = pixels;
+      while (cmd-- && x < width_) {
+        if (bpp_ == 4) {
+          if (num & 1) {
+            col = pixels & 0xf;
+          } else {
+            col = pixels >> 4;
+          }
+        }
+        PutPixel(x++, y, col);
+        num++;
+      }
+    } else {
+      cmd = GetByte();
+      if (cmd == RLE_EOF) {
+        return;
+      } else if (cmd == RLE_EOL) {
+        x = 0;
+        y--;
+        if (y < 0) {
+          return;
+        }
+      } else if (cmd == RLE_DELTA) {
+        if (pos_ + 1 < len_) {
+          uint8 dx = GetByte();
+          uint8 dy = GetByte();
+          x += dx;
+          if (x > width_) {
+            x = width_;
+          }
+          y -= dy;
+          if (y < 0) {
+            return;
+          }
+        }
+      } else {
+        int num = 0;
+        int bytesRead = 0;
+        uint8 val = 0;
+        while (cmd-- && pos_ < len_) {
+          if (bpp_ == 8 || !(num & 1)) {
+            val = GetByte();
+            bytesRead++;
+          }
+          uint8 col = val;
+          if (bpp_ == 4) {
+            if (num & 1) {
+              col = col & 0xf;
+            } else {
+              col >>= 4;
+            }
+          }
+          if (x < width_) {
+            PutPixel(x++, y, col);
+          }
+          num++;
+        }
+        // All pixel runs must be an even number of bytes - skip a byte if we
+        // read an odd number.
+        if ((bytesRead & 1) && pos_ < len_) {
+          GetByte();
+        }
+      }
+    }
+  }
+}
+
+void BmpDecoderHelper::PutPixel(int x, int y, uint8 col) {
+  CHECK(x >= 0 && x < width_);
+  CHECK(y >= 0 && y < height_);
+  if (!inverted_) {
+    y = height_ - (y + 1);
+  }
+
+  int base = ((y * width_) + x) * 3;
+  int colBase = col * 3;
+  output_[base] = colTab_[colBase];
+  output_[base + 1] = colTab_[colBase + 1];
+  output_[base + 2] = colTab_[colBase + 2];
+}
+
+void BmpDecoderHelper::DoStandardDecode() {
+  int row = 0;
+  uint8 currVal = 0;
+  for (int h = height_ - 1; h >= 0; h--, row++) {
+    int realH = h;
+    if (!inverted_) {
+      realH = height_ - (h + 1);
+    }
+    uint8* line = output_ + (3 * width_ * realH);
+    for (int w = 0; w < width_; w++) {
+      if (bpp_ >= 24) {
+        line[2] = GetByte();
+        line[1] = GetByte();
+        line[0] = GetByte();
+      } else if (bpp_ == 16) {
+        uint32 val = GetShort();
+        line[0] = ((val & redBits_) >> redShiftRight_) << redShiftLeft_;
+        line[1] = ((val & greenBits_) >> greenShiftRight_) << greenShiftLeft_;
+        line[2] = ((val & blueBits_) >> blueShiftRight_) << blueShiftLeft_;
+      } else if (bpp_ <= 8) {
+        uint8 col;
+        if (bpp_ == 8) {
+          col = GetByte();
+        } else if (bpp_ == 4) {
+          if ((w % 2) == 0) {
+            currVal = GetByte();
+            col = currVal >> 4;
+          } else {
+            col = currVal & 0xf;
+          }
+        } else {
+          if ((w % 8) == 0) {
+            currVal = GetByte();
+          }
+          int bit = w & 7;
+          col = ((currVal >> (7 - bit)) & 1);
+        }
+        int base = col * 3;
+        line[0] = colTab_[base];
+        line[1] = colTab_[base + 1];
+        line[2] = colTab_[base + 2];
+      }
+      line += 3;
+      for (int i = 0; i < pixelPad_; ++i) {
+        GetByte();
+      }
+    }
+    for (int i = 0; i < rowPad_; ++i) {
+      GetByte();
+    }
+  }
+}
+
+int BmpDecoderHelper::GetInt() {
+  uint8 b1 = GetByte();
+  uint8 b2 = GetByte();
+  uint8 b3 = GetByte();
+  uint8 b4 = GetByte();
+  return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
+}
+
+int BmpDecoderHelper::GetShort() {
+  uint8 b1 = GetByte();
+  uint8 b2 = GetByte();
+  return b1 | (b2 << 8);
+}
+
+uint8 BmpDecoderHelper::GetByte() {
+  CHECK(pos_ <= len_);
+  // We deliberately allow this off-by-one access to cater for BMPs with their
+  // last byte missing.
+  if (pos_ == len_) {
+    return 0;
+  }
+  return data_[pos_++];
+}
+
+int BmpDecoderHelper::CalcShiftRight(uint32 mask) {
+  int ret = 0;
+  while (mask != 0 && !(mask & 1)) {
+    mask >>= 1;
+    ret++;
+  }
+  return ret;
+}
+
+int BmpDecoderHelper::CalcShiftLeft(uint32 mask) {
+  int ret = 0;
+  while (mask != 0 && !(mask & 1)) {
+    mask >>= 1;
+  }
+  while (mask != 0 && !(mask & 0x80)) {
+    mask <<= 1;
+    ret++;
+  }
+  return ret;
+}
+
+}  // namespace image_codec
diff --git a/src/images/bmpdecoderhelper.h b/src/images/bmpdecoderhelper.h
new file mode 100644
index 0000000..b448734
--- /dev/null
+++ b/src/images/bmpdecoderhelper.h
@@ -0,0 +1,116 @@
+
+/*
+ * Copyright 2007 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef IMAGE_CODEC_BMPDECODERHELPER_H__
+#define IMAGE_CODEC_BMPDECODERHELPER_H__
+
+///////////////////////////////////////////////////////////////////////////////
+// this section is my current "glue" between google3 code and android.
+// will be fixed soon
+
+#include "SkTypes.h"
+#include <limits.h>
+#define DISALLOW_EVIL_CONSTRUCTORS(name)
+#define CHECK(predicate)  SkASSERT(predicate)
+typedef uint8_t uint8;
+typedef uint32_t uint32;
+
+template <typename T> class scoped_array {
+private:
+  T* ptr_;
+  scoped_array(scoped_array const&);
+  scoped_array& operator=(const scoped_array&);
+
+public:
+  explicit scoped_array(T* p = 0) : ptr_(p) {}
+  ~scoped_array() {
+    delete[] ptr_;
+  }
+
+  void reset(T* p = 0) {
+    if (p != ptr_) {
+      delete[] ptr_;
+      ptr_ = p;
+    }
+  }
+
+  T& operator[](int i) const {
+    return ptr_[i];
+  }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace image_codec {
+
+class BmpDecoderCallback {
+ public:
+  BmpDecoderCallback() { }
+  virtual ~BmpDecoderCallback() {}
+
+  /**
+   * This is called once for an image. It is passed the width and height and
+   * should return the address of a buffer that is large enough to store
+   * all of the resulting pixels (widht * height * 3 bytes). If it returns nullptr,
+   * then the decoder will abort, but return true, as the caller has received
+   * valid dimensions.
+   */
+  virtual uint8* SetSize(int width, int height) = 0;
+
+ private:
+  DISALLOW_EVIL_CONSTRUCTORS(BmpDecoderCallback);
+};
+
+class BmpDecoderHelper {
+ public:
+  BmpDecoderHelper() { }
+  ~BmpDecoderHelper() { }
+  bool DecodeImage(const char* data,
+                   size_t len,
+                   int max_pixels,
+                   BmpDecoderCallback* callback);
+
+ private:
+  DISALLOW_EVIL_CONSTRUCTORS(BmpDecoderHelper);
+
+  void DoRLEDecode();
+  void DoStandardDecode();
+  void PutPixel(int x, int y, uint8 col);
+
+  int GetInt();
+  int GetShort();
+  uint8 GetByte();
+  int CalcShiftRight(uint32 mask);
+  int CalcShiftLeft(uint32 mask);
+
+  const uint8* data_;
+  size_t pos_;
+  size_t len_;
+  int width_;
+  int height_;
+  int bpp_;
+  int pixelPad_;
+  int rowPad_;
+  scoped_array<uint8> colTab_;
+  uint32 redBits_;
+  uint32 greenBits_;
+  uint32 blueBits_;
+  int redShiftRight_;
+  int greenShiftRight_;
+  int blueShiftRight_;
+  int redShiftLeft_;
+  int greenShiftLeft_;
+  int blueShiftLeft_;
+  uint8* output_;
+  bool inverted_;
+};
+
+} // namespace
+
+#endif
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp
index ead0ed6..c4446ae 100644
--- a/src/ports/SkImageDecoder_CG.cpp
+++ b/src/ports/SkImageDecoder_CG.cpp
@@ -11,6 +11,7 @@
 #include "SkCGUtils.h"
 #include "SkColorPriv.h"
 #include "SkData.h"
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkMovie.h"
 #include "SkStream.h"
@@ -28,6 +29,210 @@
 #include <MobileCoreServices/MobileCoreServices.h>
 #endif
 
+static void data_unref_proc(void* skdata, const void*, size_t) {
+    SkASSERT(skdata);
+    static_cast<SkData*>(skdata)->unref();
+}
+
+static CGDataProviderRef SkStreamToDataProvider(SkStream* stream) {
+    // TODO: use callbacks, so we don't have to load all the data into RAM
+    SkData* skdata = SkCopyStreamToData(stream).release();
+    if (!skdata) {
+        return nullptr;
+    }
+
+    return CGDataProviderCreateWithData(skdata, skdata->data(), skdata->size(), data_unref_proc);
+}
+
+static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) {
+    CGDataProviderRef data = SkStreamToDataProvider(stream);
+    if (!data) {
+        return nullptr;
+    }
+    CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0);
+    CGDataProviderRelease(data);
+    return imageSrc;
+}
+
+class SkImageDecoder_CG : public SkImageDecoder {
+protected:
+    virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode);
+};
+
+static void argb_4444_force_opaque(void* row, int count) {
+    uint16_t* row16 = (uint16_t*)row;
+    for (int i = 0; i < count; ++i) {
+        row16[i] |= 0xF000;
+    }
+}
+
+static void argb_8888_force_opaque(void* row, int count) {
+    // can use RGBA or BGRA, they have the same shift for alpha
+    const uint32_t alphaMask = 0xFF << SK_RGBA_A32_SHIFT;
+    uint32_t* row32 = (uint32_t*)row;
+    for (int i = 0; i < count; ++i) {
+        row32[i] |= alphaMask;
+    }
+}
+
+static void alpha_8_force_opaque(void* row, int count) {
+    memset(row, 0xFF, count);
+}
+
+static void force_opaque(SkBitmap* bm) {
+    SkAutoLockPixels alp(*bm);
+    if (!bm->getPixels()) {
+        return;
+    }
+
+    void (*proc)(void*, int);
+    switch (bm->colorType()) {
+        case kARGB_4444_SkColorType:
+            proc = argb_4444_force_opaque;
+            break;
+        case kRGBA_8888_SkColorType:
+        case kBGRA_8888_SkColorType:
+            proc = argb_8888_force_opaque;
+            break;
+        case kAlpha_8_SkColorType:
+            proc = alpha_8_force_opaque;
+            break;
+        default:
+            return;
+    }
+
+    char* row = (char*)bm->getPixels();
+    for (int y = 0; y < bm->height(); ++y) {
+        proc(row, bm->width());
+        row += bm->rowBytes();
+    }
+    bm->setAlphaType(kOpaque_SkAlphaType);
+}
+
+#define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast)
+
+class AutoCFDataRelease {
+    CFDataRef fDR;
+public:
+    AutoCFDataRelease(CFDataRef dr) : fDR(dr) {}
+    ~AutoCFDataRelease() { if (fDR) { CFRelease(fDR); } }
+
+    operator CFDataRef () { return fDR; }
+};
+
+static bool colorspace_is_sRGB(CGColorSpaceRef cs) {
+#ifdef SK_BUILD_FOR_IOS
+    return true;    // iOS seems to define itself to always return sRGB <reed>
+#else
+    AutoCFDataRelease data(CGColorSpaceCopyICCProfile(cs));
+    if (data) {
+        // found by inspection -- need a cleaner way to sniff a profile
+        const CFIndex ICC_PROFILE_OFFSET_TO_SRGB_TAG = 52;
+
+        if (CFDataGetLength(data) >= ICC_PROFILE_OFFSET_TO_SRGB_TAG + 4) {
+            return !memcmp(CFDataGetBytePtr(data) + ICC_PROFILE_OFFSET_TO_SRGB_TAG, "sRGB", 4);
+        }
+    }
+    return false;
+#endif
+}
+
+SkImageDecoder::Result SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream);
+
+    if (nullptr == imageSrc) {
+        return kFailure;
+    }
+    SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc);
+
+    CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, nullptr);
+    if (nullptr == image) {
+        return kFailure;
+    }
+    SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image);
+
+    const int width = SkToInt(CGImageGetWidth(image));
+    const int height = SkToInt(CGImageGetHeight(image));
+    SkColorProfileType cpType = kLinear_SkColorProfileType;
+
+    CGColorSpaceRef cs = CGImageGetColorSpace(image);
+    if (cs) {
+        CGColorSpaceModel m = CGColorSpaceGetModel(cs);
+        if (kCGColorSpaceModelRGB == m && colorspace_is_sRGB(cs)) {
+            cpType = kSRGB_SkColorProfileType;
+        }
+    }
+
+    SkAlphaType at = kPremul_SkAlphaType;
+    switch (CGImageGetAlphaInfo(image)) {
+        case kCGImageAlphaNone:
+        case kCGImageAlphaNoneSkipLast:
+        case kCGImageAlphaNoneSkipFirst:
+            at = kOpaque_SkAlphaType;
+            break;
+        default:
+            break;
+    }
+
+    bm->setInfo(SkImageInfo::Make(width, height, kN32_SkColorType, at, cpType));
+    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+        return kSuccess;
+    }
+
+    if (!this->allocPixelRef(bm, nullptr)) {
+        return kFailure;
+    }
+
+    SkAutoLockPixels alp(*bm);
+
+    if (!SkCopyPixelsFromCGImage(bm->info(), bm->rowBytes(), bm->getPixels(), image)) {
+        return kFailure;
+    }
+
+    CGImageAlphaInfo info = CGImageGetAlphaInfo(image);
+    switch (info) {
+        case kCGImageAlphaNone:
+        case kCGImageAlphaNoneSkipLast:
+        case kCGImageAlphaNoneSkipFirst:
+            // We're opaque, but we can't rely on the data always having 0xFF
+            // in the alpha slot (which Skia wants), so we have to ram it in
+            // ourselves.
+            force_opaque(bm);
+            break;
+        default:
+            // we don't know if we're opaque or not, so compute it.
+            if (SkBitmap::ComputeIsOpaque(*bm)) {
+                bm->setAlphaType(kOpaque_SkAlphaType);
+            }
+    }
+    if (!bm->isOpaque() && this->getRequireUnpremultipliedColors()) {
+        // CGBitmapContext does not support unpremultiplied, so the image has been premultiplied.
+        // Convert to unpremultiplied.
+        for (int i = 0; i < width; ++i) {
+            for (int j = 0; j < height; ++j) {
+                uint32_t* addr = bm->getAddr32(i, j);
+                *addr = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(*addr);
+            }
+        }
+        bm->setAlphaType(kUnpremul_SkAlphaType);
+    }
+    return kSuccess;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+extern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*);
+
+SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) {
+    SkImageDecoder* decoder = image_decoder_from_stream(stream);
+    if (nullptr == decoder) {
+        // If no image decoder specific to the stream exists, use SkImageDecoder_CG.
+        return new SkImageDecoder_CG;
+    } else {
+        return decoder;
+    }
+}
+
 /////////////////////////////////////////////////////////////////////////
 
 SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) {
@@ -150,13 +355,57 @@
 
 static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_cg_factory);
 
-class SkPNGImageEncoder_CG : public SkImageEncoder_CG {
+#ifdef SK_BUILD_FOR_IOS
+class SkPNGImageEncoder_IOS : public SkImageEncoder_CG {
 public:
-    SkPNGImageEncoder_CG()
+    SkPNGImageEncoder_IOS()
         : SkImageEncoder_CG(kPNG_Type) {
     }
 };
 
-DEFINE_ENCODER_CREATOR(PNGImageEncoder_CG);
+DEFINE_ENCODER_CREATOR(PNGImageEncoder_IOS);
+#endif
+
+struct FormatConversion {
+    CFStringRef             fUTType;
+    SkImageDecoder::Format  fFormat;
+};
+
+// Array of the types supported by the decoder.
+static const FormatConversion gFormatConversions[] = {
+    { kUTTypeBMP, SkImageDecoder::kBMP_Format },
+    { kUTTypeGIF, SkImageDecoder::kGIF_Format },
+    { kUTTypeICO, SkImageDecoder::kICO_Format },
+    { kUTTypeJPEG, SkImageDecoder::kJPEG_Format },
+    // Also include JPEG2000
+    { kUTTypeJPEG2000, SkImageDecoder::kJPEG_Format },
+    { kUTTypePNG, SkImageDecoder::kPNG_Format },
+};
+
+static SkImageDecoder::Format UTType_to_Format(const CFStringRef uttype) {
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) {
+        if (CFStringCompare(uttype, gFormatConversions[i].fUTType, 0) == kCFCompareEqualTo) {
+            return gFormatConversions[i].fFormat;
+        }
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+static SkImageDecoder::Format get_format_cg(SkStreamRewindable* stream) {
+    CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream);
+
+    if (nullptr == imageSrc) {
+        return SkImageDecoder::kUnknown_Format;
+    }
+
+    SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc);
+    const CFStringRef name = CGImageSourceGetType(imageSrc);
+    if (nullptr == name) {
+        return SkImageDecoder::kUnknown_Format;
+    }
+    return UTType_to_Format(name);
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_cg);
 
 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
diff --git a/src/ports/SkImageDecoder_WIC.cpp b/src/ports/SkImageDecoder_WIC.cpp
index 43068fc..5febd85 100644
--- a/src/ports/SkImageDecoder_WIC.cpp
+++ b/src/ports/SkImageDecoder_WIC.cpp
@@ -31,6 +31,7 @@
 
 #include <wincodec.h>
 #include "SkAutoCoInitialize.h"
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkIStream.h"
 #include "SkMovie.h"
@@ -47,6 +48,222 @@
 #undef CLSID_WICImagingFactory
 #endif
 
+class SkImageDecoder_WIC : public SkImageDecoder {
+public:
+    // Decoding modes corresponding to SkImageDecoder::Mode, plus an extra mode for decoding
+    // only the format.
+    enum WICModes {
+        kDecodeFormat_WICMode,
+        kDecodeBounds_WICMode,
+        kDecodePixels_WICMode,
+    };
+
+    /**
+     *  Helper function to decode an SkStream.
+     *  @param stream SkStream to decode. Must be at the beginning.
+     *  @param bm   SkBitmap to decode into. Only used if wicMode is kDecodeBounds_WICMode or
+     *      kDecodePixels_WICMode, in which case it must not be nullptr.
+     *  @param format Out parameter for the SkImageDecoder::Format of the SkStream. Only used if
+     *      wicMode is kDecodeFormat_WICMode.
+     */
+    bool decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode, Format* format) const;
+
+protected:
+    Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) override;
+};
+
+struct FormatConversion {
+    GUID                    fGuidFormat;
+    SkImageDecoder::Format  fFormat;
+};
+
+static const FormatConversion gFormatConversions[] = {
+    { GUID_ContainerFormatBmp, SkImageDecoder::kBMP_Format },
+    { GUID_ContainerFormatGif, SkImageDecoder::kGIF_Format },
+    { GUID_ContainerFormatIco, SkImageDecoder::kICO_Format },
+    { GUID_ContainerFormatJpeg, SkImageDecoder::kJPEG_Format },
+    { GUID_ContainerFormatPng, SkImageDecoder::kPNG_Format },
+};
+
+static SkImageDecoder::Format GuidContainerFormat_to_Format(REFGUID guid) {
+    for (size_t i = 0; i < SK_ARRAY_COUNT(gFormatConversions); i++) {
+        if (IsEqualGUID(guid, gFormatConversions[i].fGuidFormat)) {
+            return gFormatConversions[i].fFormat;
+        }
+    }
+    return SkImageDecoder::kUnknown_Format;
+}
+
+SkImageDecoder::Result SkImageDecoder_WIC::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
+    WICModes wicMode;
+    switch (mode) {
+        case SkImageDecoder::kDecodeBounds_Mode:
+            wicMode = kDecodeBounds_WICMode;
+            break;
+        case SkImageDecoder::kDecodePixels_Mode:
+            wicMode = kDecodePixels_WICMode;
+            break;
+    }
+    return this->decodeStream(stream, bm, wicMode, nullptr) ? kSuccess : kFailure;
+}
+
+bool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes wicMode,
+                                      Format* format) const {
+    //Initialize COM.
+    SkAutoCoInitialize scopedCo;
+    if (!scopedCo.succeeded()) {
+        return false;
+    }
+
+    HRESULT hr = S_OK;
+
+    //Create Windows Imaging Component ImagingFactory.
+    SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
+    if (SUCCEEDED(hr)) {
+        hr = CoCreateInstance(
+            CLSID_WICImagingFactory
+            , nullptr
+            , CLSCTX_INPROC_SERVER
+            , IID_PPV_ARGS(&piImagingFactory)
+        );
+    }
+
+    //Convert SkStream to IStream.
+    SkTScopedComPtr<IStream> piStream;
+    if (SUCCEEDED(hr)) {
+        hr = SkIStream::CreateFromSkStream(stream, false, &piStream);
+    }
+
+    //Make sure we're at the beginning of the stream.
+    if (SUCCEEDED(hr)) {
+        LARGE_INTEGER liBeginning = { 0 };
+        hr = piStream->Seek(liBeginning, STREAM_SEEK_SET, nullptr);
+    }
+
+    //Create the decoder from the stream content.
+    SkTScopedComPtr<IWICBitmapDecoder> piBitmapDecoder;
+    if (SUCCEEDED(hr)) {
+        hr = piImagingFactory->CreateDecoderFromStream(
+            piStream.get()                    //Image to be decoded
+            , nullptr                            //No particular vendor
+            , WICDecodeMetadataCacheOnDemand  //Cache metadata when needed
+            , &piBitmapDecoder                //Pointer to the decoder
+        );
+    }
+
+    if (kDecodeFormat_WICMode == wicMode) {
+        SkASSERT(format != nullptr);
+        //Get the format
+        if (SUCCEEDED(hr)) {
+            GUID guidFormat;
+            hr = piBitmapDecoder->GetContainerFormat(&guidFormat);
+            if (SUCCEEDED(hr)) {
+                *format = GuidContainerFormat_to_Format(guidFormat);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    //Get the first frame from the decoder.
+    SkTScopedComPtr<IWICBitmapFrameDecode> piBitmapFrameDecode;
+    if (SUCCEEDED(hr)) {
+        hr = piBitmapDecoder->GetFrame(0, &piBitmapFrameDecode);
+    }
+
+    //Get the BitmapSource interface of the frame.
+    SkTScopedComPtr<IWICBitmapSource> piBitmapSourceOriginal;
+    if (SUCCEEDED(hr)) {
+        hr = piBitmapFrameDecode->QueryInterface(
+            IID_PPV_ARGS(&piBitmapSourceOriginal)
+        );
+    }
+
+    //Get the size of the bitmap.
+    UINT width;
+    UINT height;
+    if (SUCCEEDED(hr)) {
+        hr = piBitmapSourceOriginal->GetSize(&width, &height);
+    }
+
+    //Exit early if we're only looking for the bitmap bounds.
+    if (SUCCEEDED(hr)) {
+        bm->setInfo(SkImageInfo::MakeN32Premul(width, height));
+        if (kDecodeBounds_WICMode == wicMode) {
+            return true;
+        }
+        if (!this->allocPixelRef(bm, nullptr)) {
+            return false;
+        }
+    }
+
+    //Create a format converter.
+    SkTScopedComPtr<IWICFormatConverter> piFormatConverter;
+    if (SUCCEEDED(hr)) {
+        hr = piImagingFactory->CreateFormatConverter(&piFormatConverter);
+    }
+
+    GUID destinationPixelFormat;
+    if (this->getRequireUnpremultipliedColors()) {
+        destinationPixelFormat = GUID_WICPixelFormat32bppBGRA;
+    } else {
+        destinationPixelFormat = GUID_WICPixelFormat32bppPBGRA;
+    }
+
+    if (SUCCEEDED(hr)) {
+        hr = piFormatConverter->Initialize(
+            piBitmapSourceOriginal.get()      //Input bitmap to convert
+            , destinationPixelFormat          //Destination pixel format
+            , WICBitmapDitherTypeNone         //Specified dither patterm
+            , nullptr                            //Specify a particular palette
+            , 0.f                             //Alpha threshold
+            , WICBitmapPaletteTypeCustom      //Palette translation type
+        );
+    }
+
+    //Get the BitmapSource interface of the format converter.
+    SkTScopedComPtr<IWICBitmapSource> piBitmapSourceConverted;
+    if (SUCCEEDED(hr)) {
+        hr = piFormatConverter->QueryInterface(
+            IID_PPV_ARGS(&piBitmapSourceConverted)
+        );
+    }
+
+    //Copy the pixels into the bitmap.
+    if (SUCCEEDED(hr)) {
+        SkAutoLockPixels alp(*bm);
+        bm->eraseColor(SK_ColorTRANSPARENT);
+        const UINT stride = (UINT) bm->rowBytes();
+        hr = piBitmapSourceConverted->CopyPixels(
+            nullptr,                             //Get all the pixels
+            stride,
+            stride * height,
+            reinterpret_cast<BYTE *>(bm->getPixels())
+        );
+
+        // Note: we don't need to premultiply here since we specified PBGRA
+        if (SkBitmap::ComputeIsOpaque(*bm)) {
+            bm->setAlphaType(kOpaque_SkAlphaType);
+        }
+    }
+
+    return SUCCEEDED(hr);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+extern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*);
+
+SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) {
+    SkImageDecoder* decoder = image_decoder_from_stream(stream);
+    if (nullptr == decoder) {
+        // If no image decoder specific to the stream exists, use SkImageDecoder_WIC.
+        return new SkImageDecoder_WIC;
+    } else {
+        return decoder;
+    }
+}
+
 /////////////////////////////////////////////////////////////////////////
 
 SkMovie* SkMovie::DecodeStream(SkStreamRewindable* stream) {
@@ -58,10 +275,6 @@
 class SkImageEncoder_WIC : public SkImageEncoder {
 public:
     SkImageEncoder_WIC(Type t) : fType(t) {}
-    
-    // DO NOT USE this constructor.  This exists only so SkForceLinking can
-    // link the WIC image encoder.
-    SkImageEncoder_WIC() {}
 
 protected:
     virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality);
@@ -241,6 +454,15 @@
 
 static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory);
 
-DEFINE_ENCODER_CREATOR(ImageEncoder_WIC);
+static SkImageDecoder::Format get_format_wic(SkStreamRewindable* stream) {
+    SkImageDecoder::Format format;
+    SkImageDecoder_WIC codec;
+    if (!codec.decodeStream(stream, nullptr, SkImageDecoder_WIC::kDecodeFormat_WICMode, &format)) {
+        format = SkImageDecoder::kUnknown_Format;
+    }
+    return format;
+}
+
+static SkImageDecoder_FormatReg gFormatReg(get_format_wic);
 
 #endif // defined(SK_BUILD_FOR_WIN32)
diff --git a/src/ports/SkImageDecoder_empty.cpp b/src/ports/SkImageDecoder_empty.cpp
index 33e07ac..f52dada 100644
--- a/src/ports/SkImageDecoder_empty.cpp
+++ b/src/ports/SkImageDecoder_empty.cpp
@@ -8,11 +8,74 @@
 
 #include "SkBitmap.h"
 #include "SkImage.h"
+#include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkMovie.h"
 #include "SkPixelSerializer.h"
 #include "SkStream.h"
 
+class SkColorTable;
+class SkPngChunkReader;
+
+// Empty implementations for SkImageDecoder.
+
+SkImageDecoder::SkImageDecoder() {}
+
+SkImageDecoder::~SkImageDecoder() {}
+
+SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable*) {
+    return nullptr;
+}
+
+void SkImageDecoder::copyFieldsToOther(SkImageDecoder* ) {}
+
+bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkColorType, Mode, Format*) {
+    return false;
+}
+
+SkImageDecoder::Result SkImageDecoder::decode(SkStream*, SkBitmap*, SkColorType, Mode) {
+    return kFailure;
+}
+
+bool SkImageDecoder::DecodeStream(SkStreamRewindable*, SkBitmap*, SkColorType, Mode, Format*) {
+    return false;
+}
+
+bool SkImageDecoder::DecodeMemory(const void*, size_t, SkBitmap*, SkColorType, Mode, Format*) {
+    return false;
+}
+
+bool SkImageDecoder::decodeYUV8Planes(SkStream*, SkISize[3], void*[3],
+                                      size_t[3], SkYUVColorSpace*) {
+    return false;
+}
+
+SkImageDecoder::Format SkImageDecoder::getFormat() const {
+    return kUnknown_Format;
+}
+
+SkImageDecoder::Format SkImageDecoder::GetStreamFormat(SkStreamRewindable*) {
+    return kUnknown_Format;
+}
+
+const char* SkImageDecoder::GetFormatName(Format) {
+    return nullptr;
+}
+
+SkPngChunkReader* SkImageDecoder::setPeeker(SkPngChunkReader*) {
+    return nullptr;
+}
+
+SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator*) {
+    return nullptr;
+}
+
+void SkImageDecoder::setSampleSize(int) {}
+
+bool SkImageDecoder::allocPixelRef(SkBitmap*, SkColorTable*) const {
+    return false;
+}
+
 /////////////////////////////////////////////////////////////////////////
 
 // Empty implementation for SkMovie.
