Delete SkBitmapRegionCanvas

This was an approach we considered for implementing Android's
BitmapRegionDecoder.

It was useful for testing and comparison, but now is no longer worth
maintaining and testing.

The approach to subset/scaled decodes (clipped decode, then scale)
may be worth reconsidering at some point.

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

Review-Url: https://codereview.chromium.org/1990543002
diff --git a/bench/BitmapRegionDecoderBench.cpp b/bench/BitmapRegionDecoderBench.cpp
index 125c4a8..dd60b18 100644
--- a/bench/BitmapRegionDecoderBench.cpp
+++ b/bench/BitmapRegionDecoderBench.cpp
@@ -11,34 +11,17 @@
 #include "SkOSFile.h"
 
 BitmapRegionDecoderBench::BitmapRegionDecoderBench(const char* baseName, SkData* encoded,
-        SkBitmapRegionDecoder::Strategy strategy, SkColorType colorType,
-        uint32_t sampleSize, const SkIRect& subset)
+        SkColorType colorType, uint32_t sampleSize, const SkIRect& subset)
     : fBRD(nullptr)
     , fData(SkRef(encoded))
-    , fStrategy(strategy)
     , fColorType(colorType)
     , fSampleSize(sampleSize)
     , fSubset(subset)
 {
-    // Choose a useful name for the region decoding strategy
-    const char* strategyName;
-    switch (strategy) {
-        case SkBitmapRegionDecoder::kCanvas_Strategy:
-            strategyName = "Canvas";
-            break;
-        case SkBitmapRegionDecoder::kAndroidCodec_Strategy:
-            strategyName = "AndroidCodec";
-            break;
-        default:
-            SkASSERT(false);
-            strategyName = "";
-            break;
-    }
-
     // Choose a useful name for the color type
     const char* colorName = color_type_to_str(colorType);
 
-    fName.printf("BRD_%s_%s_%s", baseName, strategyName, colorName);
+    fName.printf("BRD_%s_%s", baseName, colorName);
     if (1 != sampleSize) {
         fName.appendf("_%.3f", 1.0f / (float) sampleSize);
     }
@@ -53,7 +36,7 @@
 }
 
 void BitmapRegionDecoderBench::onDelayedSetup() {
-    fBRD.reset(SkBitmapRegionDecoder::Create(fData, fStrategy));
+    fBRD.reset(SkBitmapRegionDecoder::Create(fData, SkBitmapRegionDecoder::kAndroidCodec_Strategy));
 }
 
 void BitmapRegionDecoderBench::onDraw(int n, SkCanvas* canvas) {
diff --git a/bench/BitmapRegionDecoderBench.h b/bench/BitmapRegionDecoderBench.h
index 7c331ae..69588b2 100644
--- a/bench/BitmapRegionDecoderBench.h
+++ b/bench/BitmapRegionDecoderBench.h
@@ -18,16 +18,13 @@
 /**
  *  Benchmark Android's BitmapRegionDecoder for a particular colorType, sampleSize, and subset.
  *
- *  fStrategy determines which of various implementations is to be used.
- *
  *  nanobench.cpp handles creating benchmarks for interesting scaled subsets.  We strive to test
  *  on real use cases.
  */
 class BitmapRegionDecoderBench : public Benchmark {
 public:
     // Calls encoded->ref()
-    BitmapRegionDecoderBench(const char* basename, SkData* encoded,
-            SkBitmapRegionDecoder::Strategy strategy, SkColorType colorType,
+    BitmapRegionDecoderBench(const char* basename, SkData* encoded, SkColorType colorType,
             uint32_t sampleSize, const SkIRect& subset);
 
 protected:
@@ -40,7 +37,6 @@
     SkString                                       fName;
     SkAutoTDelete<SkBitmapRegionDecoder>           fBRD;
     SkAutoTUnref<SkData>                           fData;
-    const SkBitmapRegionDecoder::Strategy          fStrategy;
     const SkColorType                              fColorType;
     const uint32_t                                 fSampleSize;
     const SkIRect                                  fSubset;
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 8bc40cc..4fb1ed2 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -513,22 +513,15 @@
     return target;
 }
 
-static bool valid_brd_bench(SkData* encoded, SkBitmapRegionDecoder::Strategy strategy,
-        SkColorType colorType, uint32_t sampleSize, uint32_t minOutputSize, int* width,
-        int* height) {
+static bool valid_brd_bench(SkData* encoded, SkColorType colorType, uint32_t sampleSize,
+        uint32_t minOutputSize, int* width, int* height) {
     SkAutoTDelete<SkBitmapRegionDecoder> brd(
-            SkBitmapRegionDecoder::Create(encoded, strategy));
+            SkBitmapRegionDecoder::Create(encoded, SkBitmapRegionDecoder::kAndroidCodec_Strategy));
     if (nullptr == brd.get()) {
         // This is indicates that subset decoding is not supported for a particular image format.
         return false;
     }
 
-    SkBitmap bitmap;
-    if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, brd->width(), brd->height()),
-            1, colorType, false)) {
-        return false;
-    }
-
     if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * minOutputSize >
             (uint32_t) brd->height()) {
         // This indicates that the image is not large enough to decode a
@@ -568,7 +561,6 @@
                       , fCurrentColorType(0)
                       , fCurrentAlphaType(0)
                       , fCurrentSubsetType(0)
-                      , fCurrentBRDStrategy(0)
                       , fCurrentSampleSize(0)
                       , fCurrentAnimSKP(0) {
         for (int i = 0; i < FLAGS_skps.count(); i++) {
@@ -842,15 +834,6 @@
         }
 
         // Run the BRDBenches
-        // We will benchmark multiple BRD strategies.
-        static const struct {
-            SkBitmapRegionDecoder::Strategy    fStrategy;
-            const char*                        fName;
-        } strategies[] = {
-            { SkBitmapRegionDecoder::kCanvas_Strategy,       "BRD_canvas" },
-            { SkBitmapRegionDecoder::kAndroidCodec_Strategy, "BRD_android_codec" },
-        };
-
         // We intend to create benchmarks that model the use cases in
         // android/libraries/social/tiledimage.  In this library, an image is decoded in 512x512
         // tiles.  The image can be translated freely, so the location of a tile may be anywhere in
@@ -866,78 +849,72 @@
         const uint32_t brdSampleSizes[] = { 1, 2, 4, 8, 16 };
         const uint32_t minOutputSize = 512;
         for (; fCurrentBRDImage < fImages.count(); fCurrentBRDImage++) {
+            fSourceType = "image";
+            fBenchType = "BRD";
+
             const SkString& path = fImages[fCurrentBRDImage];
             if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) {
                 continue;
             }
-            while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) {
-                fSourceType = "image";
-                fBenchType = strategies[fCurrentBRDStrategy].fName;
 
-                const SkBitmapRegionDecoder::Strategy strategy =
-                        strategies[fCurrentBRDStrategy].fStrategy;
+            while (fCurrentColorType < fColorTypes.count()) {
+                while (fCurrentSampleSize < (int) SK_ARRAY_COUNT(brdSampleSizes)) {
+                    while (fCurrentSubsetType <= kLastSingle_SubsetType) {
 
-                while (fCurrentColorType < fColorTypes.count()) {
-                    while (fCurrentSampleSize < (int) SK_ARRAY_COUNT(brdSampleSizes)) {
-                        while (fCurrentSubsetType <= kLastSingle_SubsetType) {
+                        SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
+                        const SkColorType colorType = fColorTypes[fCurrentColorType];
+                        uint32_t sampleSize = brdSampleSizes[fCurrentSampleSize];
+                        int currentSubsetType = fCurrentSubsetType++;
 
-                            SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
-                            const SkColorType colorType = fColorTypes[fCurrentColorType];
-                            uint32_t sampleSize = brdSampleSizes[fCurrentSampleSize];
-                            int currentSubsetType = fCurrentSubsetType++;
-
-                            int width = 0;
-                            int height = 0;
-                            if (!valid_brd_bench(encoded.get(), strategy, colorType, sampleSize,
-                                    minOutputSize, &width, &height)) {
-                                break;
-                            }
-
-                            SkString basename = SkOSPath::Basename(path.c_str());
-                            SkIRect subset;
-                            const uint32_t subsetSize = sampleSize * minOutputSize;
-                            switch (currentSubsetType) {
-                                case kTopLeft_SubsetType:
-                                    basename.append("_TopLeft");
-                                    subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize);
-                                    break;
-                                case kTopRight_SubsetType:
-                                    basename.append("_TopRight");
-                                    subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize,
-                                            subsetSize);
-                                    break;
-                                case kMiddle_SubsetType:
-                                    basename.append("_Middle");
-                                    subset = SkIRect::MakeXYWH((width - subsetSize) / 2,
-                                            (height - subsetSize) / 2, subsetSize, subsetSize);
-                                    break;
-                                case kBottomLeft_SubsetType:
-                                    basename.append("_BottomLeft");
-                                    subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize,
-                                            subsetSize);
-                                    break;
-                                case kBottomRight_SubsetType:
-                                    basename.append("_BottomRight");
-                                    subset = SkIRect::MakeXYWH(width - subsetSize,
-                                            height - subsetSize, subsetSize, subsetSize);
-                                    break;
-                                default:
-                                    SkASSERT(false);
-                            }
-
-                            return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(),
-                                    strategy, colorType, sampleSize, subset);
+                        int width = 0;
+                        int height = 0;
+                        if (!valid_brd_bench(encoded.get(), colorType, sampleSize, minOutputSize,
+                                &width, &height)) {
+                            break;
                         }
-                        fCurrentSubsetType = 0;
-                        fCurrentSampleSize++;
+
+                        SkString basename = SkOSPath::Basename(path.c_str());
+                        SkIRect subset;
+                        const uint32_t subsetSize = sampleSize * minOutputSize;
+                        switch (currentSubsetType) {
+                            case kTopLeft_SubsetType:
+                                basename.append("_TopLeft");
+                                subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize);
+                                break;
+                            case kTopRight_SubsetType:
+                                basename.append("_TopRight");
+                                subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize,
+                                        subsetSize);
+                                break;
+                            case kMiddle_SubsetType:
+                                basename.append("_Middle");
+                                subset = SkIRect::MakeXYWH((width - subsetSize) / 2,
+                                        (height - subsetSize) / 2, subsetSize, subsetSize);
+                                break;
+                            case kBottomLeft_SubsetType:
+                                basename.append("_BottomLeft");
+                                subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize,
+                                        subsetSize);
+                                break;
+                            case kBottomRight_SubsetType:
+                                basename.append("_BottomRight");
+                                subset = SkIRect::MakeXYWH(width - subsetSize,
+                                        height - subsetSize, subsetSize, subsetSize);
+                                break;
+                            default:
+                                SkASSERT(false);
+                        }
+
+                        return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(),
+                                colorType, sampleSize, subset);
                     }
-                    fCurrentSampleSize = 0;
-                    fCurrentColorType++;
+                    fCurrentSubsetType = 0;
+                    fCurrentSampleSize++;
                 }
-                fCurrentColorType = 0;
-                fCurrentBRDStrategy++;
+                fCurrentSampleSize = 0;
+                fCurrentColorType++;
             }
-            fCurrentBRDStrategy = 0;
+            fCurrentColorType = 0;
         }
 
         return nullptr;
@@ -1001,7 +978,6 @@
     int fCurrentColorType;
     int fCurrentAlphaType;
     int fCurrentSubsetType;
-    int fCurrentBRDStrategy;
     int fCurrentSampleSize;
     int fCurrentAnimSKP;
 };
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 4f03bef..8685ec5 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -609,44 +609,9 @@
     }
 }
 
-static bool brd_color_type_supported(SkBitmapRegionDecoder::Strategy strategy,
-        CodecSrc::DstColorType dstColorType) {
-    switch (strategy) {
-        case SkBitmapRegionDecoder::kCanvas_Strategy:
-            if (CodecSrc::kGetFromCanvas_DstColorType == dstColorType) {
-                return true;
-            }
-            return false;
-        case SkBitmapRegionDecoder::kAndroidCodec_Strategy:
-            switch (dstColorType) {
-                case CodecSrc::kGetFromCanvas_DstColorType:
-                case CodecSrc::kIndex8_Always_DstColorType:
-                case CodecSrc::kGrayscale_Always_DstColorType:
-                    return true;
-                default:
-                    return false;
-            }
-        default:
-            SkASSERT(false);
-            return false;
-    }
-}
-
-static void push_brd_src(Path path, SkBitmapRegionDecoder::Strategy strategy,
-        CodecSrc::DstColorType dstColorType, BRDSrc::Mode mode, uint32_t sampleSize) {
-    SkString folder;
-    switch (strategy) {
-        case SkBitmapRegionDecoder::kCanvas_Strategy:
-            folder.append("brd_canvas");
-            break;
-        case SkBitmapRegionDecoder::kAndroidCodec_Strategy:
-            folder.append("brd_android_codec");
-            break;
-        default:
-            SkASSERT(false);
-            return;
-    }
-
+static void push_brd_src(Path path, CodecSrc::DstColorType dstColorType, BRDSrc::Mode mode,
+        uint32_t sampleSize) {
+    SkString folder("brd_android_codec");
     switch (mode) {
         case BRDSrc::kFullImage_Mode:
             break;
@@ -676,17 +641,11 @@
         folder.appendf("_%.3f", 1.0f / (float) sampleSize);
     }
 
-    BRDSrc* src = new BRDSrc(path, strategy, mode, dstColorType, sampleSize);
+    BRDSrc* src = new BRDSrc(path, mode, dstColorType, sampleSize);
     push_src("image", folder, src);
 }
 
 static void push_brd_srcs(Path path) {
-
-    const SkBitmapRegionDecoder::Strategy strategies[] = {
-            SkBitmapRegionDecoder::kCanvas_Strategy,
-            SkBitmapRegionDecoder::kAndroidCodec_Strategy,
-    };
-
     // Test on a variety of sampleSizes, making sure to include:
     // - 2, 4, and 8, which are natively supported by jpeg
     // - multiples of 2 which are not divisible by 4 (analogous for 4)
@@ -707,14 +666,10 @@
             BRDSrc::kDivisor_Mode,
     };
 
-    for (SkBitmapRegionDecoder::Strategy strategy : strategies) {
-        for (uint32_t sampleSize : sampleSizes) {
-            for (CodecSrc::DstColorType dstColorType : dstColorTypes) {
-                if (brd_color_type_supported(strategy, dstColorType)) {
-                    for (BRDSrc::Mode mode : modes) {
-                        push_brd_src(path, strategy, dstColorType, mode, sampleSize);
-                    }
-                }
+    for (uint32_t sampleSize : sampleSizes) {
+        for (CodecSrc::DstColorType dstColorType : dstColorTypes) {
+            for (BRDSrc::Mode mode : modes) {
+                push_brd_src(path, dstColorType, mode, sampleSize);
             }
         }
     }
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 1155395..028dff8 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -71,10 +71,8 @@
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
-BRDSrc::BRDSrc(Path path, SkBitmapRegionDecoder::Strategy strategy, Mode mode,
-        CodecSrc::DstColorType dstColorType, uint32_t sampleSize)
+BRDSrc::BRDSrc(Path path, Mode mode, CodecSrc::DstColorType dstColorType, uint32_t sampleSize)
     : fPath(path)
-    , fStrategy(strategy)
     , fMode(mode)
     , fDstColorType(dstColorType)
     , fSampleSize(sampleSize)
@@ -86,13 +84,12 @@
         || flags.approach != SinkFlags::kDirect;
 }
 
-static SkBitmapRegionDecoder* create_brd(Path path,
-        SkBitmapRegionDecoder::Strategy strategy) {
+static SkBitmapRegionDecoder* create_brd(Path path) {
     SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
     if (!encoded) {
         return NULL;
     }
-    return SkBitmapRegionDecoder::Create(encoded, strategy);
+    return SkBitmapRegionDecoder::Create(encoded, SkBitmapRegionDecoder::kAndroidCodec_Strategy);
 }
 
 Error BRDSrc::draw(SkCanvas* canvas) const {
@@ -115,7 +112,7 @@
             break;
     }
 
-    SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy));
+    SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath));
     if (nullptr == brd.get()) {
         return Error::Nonfatal(SkStringPrintf("Could not create brd for %s.", fPath.c_str()));
     }
@@ -217,7 +214,7 @@
 }
 
 SkISize BRDSrc::size() const {
-    SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy));
+    SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath));
     if (brd) {
         return SkISize::Make(SkTMax(1, brd->width() / (int) fSampleSize),
                 SkTMax(1, brd->height() / (int) fSampleSize));
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index b486642..b0f67db 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -165,7 +165,7 @@
         kDivisor_Mode,
     };
 
-    BRDSrc(Path, SkBitmapRegionDecoder::Strategy, Mode, CodecSrc::DstColorType, uint32_t);
+    BRDSrc(Path, Mode, CodecSrc::DstColorType, uint32_t);
 
     Error draw(SkCanvas*) const override;
     SkISize size() const override;
@@ -173,7 +173,6 @@
     bool veto(SinkFlags) const override;
 private:
     Path                                     fPath;
-    SkBitmapRegionDecoder::Strategy          fStrategy;
     Mode                                     fMode;
     CodecSrc::DstColorType                   fDstColorType;
     uint32_t                                 fSampleSize;
diff --git a/gyp/codec_android.gyp b/gyp/codec_android.gyp
index ca9c7a3..833d430 100644
--- a/gyp/codec_android.gyp
+++ b/gyp/codec_android.gyp
@@ -27,7 +27,6 @@
         '../src/codec',
       ],
       'sources': [
-        '../src/android/SkBitmapRegionCanvas.cpp',
         '../src/android/SkBitmapRegionCodec.cpp',
         '../src/android/SkBitmapRegionDecoder.cpp',
       ],
diff --git a/include/android/SkBitmapRegionDecoder.h b/include/android/SkBitmapRegionDecoder.h
index 575ad9d..913f947 100644
--- a/include/android/SkBitmapRegionDecoder.h
+++ b/include/android/SkBitmapRegionDecoder.h
@@ -21,7 +21,6 @@
 public:
 
     enum Strategy {
-        kCanvas_Strategy,       // Draw to the canvas, uses SkCodec
         kAndroidCodec_Strategy, // Uses SkAndroidCodec for scaling and subsetting
     };
 
diff --git a/src/android/SkBitmapRegionCanvas.cpp b/src/android/SkBitmapRegionCanvas.cpp
deleted file mode 100644
index c7c42bd..0000000
--- a/src/android/SkBitmapRegionCanvas.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkBitmapRegionCanvas.h"
-#include "SkBitmapRegionDecoderPriv.h"
-#include "SkCanvas.h"
-#include "SkCodecPriv.h"
-
-SkBitmapRegionCanvas::SkBitmapRegionCanvas(SkCodec* decoder)
-    : INHERITED(decoder->getInfo().width(), decoder->getInfo().height())
-    , fDecoder(decoder)
-{}
-
-bool SkBitmapRegionCanvas::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
-        const SkIRect& desiredSubset, int sampleSize, SkColorType dstColorType,
-        bool requireUnpremul) {
-
-    // Reject color types not supported by this method
-    if (kIndex_8_SkColorType == dstColorType || kGray_8_SkColorType == dstColorType) {
-        SkCodecPrintf("Error: Color type not supported.\n");
-        return false;
-    }
-
-    // Reject requests for unpremultiplied alpha
-    if (requireUnpremul) {
-        SkCodecPrintf("Error: Alpha type not supported.\n");
-        return false;
-    }
-    SkAlphaType dstAlphaType = fDecoder->getInfo().alphaType();
-    if (kUnpremul_SkAlphaType == dstAlphaType) {
-        dstAlphaType = kPremul_SkAlphaType;
-    }
-
-    // Fix the input sampleSize if necessary.
-    if (sampleSize < 1) {
-        sampleSize = 1;
-    }
-
-    // The size of the output bitmap is determined by the size of the
-    // requested subset, not by the size of the intersection of the subset
-    // and the image dimensions.
-    // If inputX is negative, we will need to place decoded pixels into the
-    // output bitmap starting at a left offset.  Call this outX.
-    // If outX is non-zero, subsetX must be zero.
-    // If inputY is negative, we will need to place decoded pixels into the
-    // output bitmap starting at a top offset.  Call this outY.
-    // If outY is non-zero, subsetY must be zero.
-    int outX;
-    int outY;
-    SkIRect subset = desiredSubset;
-    SubsetType type = adjust_subset_rect(fDecoder->getInfo().dimensions(), &subset, &outX, &outY);
-    if (SubsetType::kOutside_SubsetType == type) {
-        return false;
-    }
-
-    // Create the image info for the decode
-    SkImageInfo decodeInfo = SkImageInfo::Make(this->width(), this->height(),
-            dstColorType, dstAlphaType);
-
-    // Start the scanline decoder
-    SkCodec::Result r = fDecoder->startScanlineDecode(decodeInfo);
-    if (SkCodec::kSuccess != r) {
-        SkCodecPrintf("Error: Could not start scanline decoder.\n");
-        return false;
-    }
-
-    // Allocate a bitmap for the unscaled decode
-    SkBitmap tmp;
-    SkImageInfo tmpInfo = decodeInfo.makeWH(this->width(), subset.height());
-    if (!tmp.tryAllocPixels(tmpInfo)) {
-        SkCodecPrintf("Error: Could not allocate pixels.\n");
-        return false;
-    }
-
-    // Skip the unneeded rows
-    if (!fDecoder->skipScanlines(subset.y())) {
-        SkCodecPrintf("Error: Failed to skip scanlines.\n");
-        return false;
-    }
-
-    // Decode the necessary rows
-    fDecoder->getScanlines(tmp.getAddr(0, 0), subset.height(), tmp.rowBytes());
-
-    // Calculate the size of the output
-    const int outWidth = get_scaled_dimension(desiredSubset.width(), sampleSize);
-    const int outHeight = get_scaled_dimension(desiredSubset.height(), sampleSize);
-
-    // Initialize the destination bitmap
-    SkImageInfo dstInfo = decodeInfo.makeWH(outWidth, outHeight);
-    bitmap->setInfo(dstInfo, dstInfo.minRowBytes());
-    if (!bitmap->tryAllocPixels(allocator, nullptr)) {
-        SkCodecPrintf("Error: Could not allocate pixels.\n");
-        return false;
-    }
-
-    // Zero the bitmap if the region is not completely within the image.
-    // TODO (msarett): Can we make this faster by implementing it to only
-    //                 zero parts of the image that we won't overwrite with
-    //                 pixels?
-    if (SubsetType::kPartiallyInside_SubsetType == type) {
-        SkCodec::ZeroInitialized zeroInit = allocator ? allocator->zeroInit() :
-                    SkCodec::kNo_ZeroInitialized;
-        if (SkCodec::kNo_ZeroInitialized == zeroInit) {
-            bitmap->eraseColor(0);
-        }
-    }
-
-    // Use a canvas to crop and scale to the destination bitmap
-    SkCanvas canvas(*bitmap);
-    // TODO (msarett): Maybe we can take advantage of the fact that SkRect uses floats?
-    SkRect src = SkRect::MakeXYWH((SkScalar) subset.x(), (SkScalar) 0,
-            (SkScalar) subset.width(), (SkScalar) subset.height());
-    SkRect dst = SkRect::MakeXYWH((SkScalar) (outX / sampleSize), (SkScalar) (outY / sampleSize),
-            (SkScalar) get_scaled_dimension(subset.width(), sampleSize),
-            (SkScalar) get_scaled_dimension(subset.height(), sampleSize));
-    SkPaint paint;
-    // Overwrite the dst with the src pixels
-    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
-    // TODO (msarett): Test multiple filter qualities.  kNone is the default.
-    canvas.drawBitmapRect(tmp, src, dst, &paint);
-
-    return true;
-}
-
-bool SkBitmapRegionCanvas::conversionSupported(SkColorType colorType) {
-    // SkCanvas does not draw to these color types.
-    if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorType) {
-        return false;
-    }
-
-    // FIXME: Call virtual function when it lands.
-    SkImageInfo info = SkImageInfo::Make(0, 0, colorType, fDecoder->getInfo().alphaType(),
-            fDecoder->getInfo().profileType());
-    return conversion_possible(info, fDecoder->getInfo());
-}
diff --git a/src/android/SkBitmapRegionCanvas.h b/src/android/SkBitmapRegionCanvas.h
deleted file mode 100644
index c01f96b..0000000
--- a/src/android/SkBitmapRegionCanvas.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkBitmap.h"
-#include "SkBitmapRegionDecoder.h"
-#include "SkCodec.h"
-
-/*
- * This class implements SkBitmapRegionDecoder using an SkCodec and
- * an SkCanvas.  It uses the scanline decoder to subset the height.  It then
- * will subset the width and scale by drawing to an SkCanvas.
- */
-// FIXME: This class works well as a performance/quality comparison for
-//        SkBitmapRegionCodec, but it lacks several capabilities that are
-//        required by BitmapRegionDecoder in Android.
-//        (1) WEBP decodes - because SkWebpCodec does not have a scanline
-//            decoder.
-//        (2) Decodes to kGray8 and kIndex8.
-//        (3) Decodes to kUnpremul.
-//        (4) Correcting an invalid dstColorType.  For example, if the
-//            client requests kRGB_565 for a non-opaque image, rather than
-//            fail, we need to go ahead and decode to kN32.
-class SkBitmapRegionCanvas : public SkBitmapRegionDecoder {
-public:
-
-    /*
-     * Takes ownership of pointer to decoder
-     */
-    SkBitmapRegionCanvas(SkCodec* decoder);
-
-    bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
-                      const SkIRect& desiredSubset, int sampleSize,
-                      SkColorType colorType, bool requireUnpremul) override;
-
-    bool conversionSupported(SkColorType colorType) override;
-
-    SkEncodedFormat getEncodedFormat() override { return fDecoder->getEncodedFormat(); }
-
-private:
-
-    SkAutoTDelete<SkCodec> fDecoder;
-
-    typedef SkBitmapRegionDecoder INHERITED;
-
-};
diff --git a/src/android/SkBitmapRegionDecoder.cpp b/src/android/SkBitmapRegionDecoder.cpp
index 101efbd..324d1be 100644
--- a/src/android/SkBitmapRegionDecoder.cpp
+++ b/src/android/SkBitmapRegionDecoder.cpp
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkBitmapRegionCanvas.h"
 #include "SkBitmapRegionCodec.h"
 #include "SkBitmapRegionDecoder.h"
 #include "SkAndroidCodec.h"
@@ -22,32 +21,6 @@
         SkStreamRewindable* stream, Strategy strategy) {
     SkAutoTDelete<SkStreamRewindable> streamDeleter(stream);
     switch (strategy) {
-        case kCanvas_Strategy: {
-            SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(streamDeleter.release()));
-            if (nullptr == codec) {
-                SkCodecPrintf("Error: Failed to create decoder.\n");
-                return nullptr;
-            }
-
-            SkEncodedFormat format = codec->getEncodedFormat();
-            switch (format) {
-                case SkEncodedFormat::kJPEG_SkEncodedFormat:
-                case SkEncodedFormat::kPNG_SkEncodedFormat:
-                    break;
-                default:
-                    // FIXME: Support webp using a special case.  Webp does not support
-                    //        scanline decoding.
-                    return nullptr;
-            }
-
-            // If the image is a jpeg or a png, the scanline ordering should always be
-            // kTopDown or kNone.  It is relevant to check because this implementation
-            // only supports these two scanline orderings.
-            SkASSERT(SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder() ||
-                    SkCodec::kNone_SkScanlineOrder == codec->getScanlineOrder());
-
-            return new SkBitmapRegionCanvas(codec.release());
-        }
         case kAndroidCodec_Strategy: {
             SkAutoTDelete<SkAndroidCodec> codec =
                     SkAndroidCodec::NewFromStream(streamDeleter.release());