From d1227a7417922ce26252d55815d0d1e98f0eb070 Mon Sep 17 00:00:00 2001 From: msarett Date: Wed, 18 May 2016 06:23:57 -0700 Subject: 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 --- src/android/SkBitmapRegionCanvas.cpp | 139 ---------------------------------- src/android/SkBitmapRegionCanvas.h | 49 ------------ src/android/SkBitmapRegionDecoder.cpp | 27 ------- 3 files changed, 215 deletions(-) delete mode 100644 src/android/SkBitmapRegionCanvas.cpp delete mode 100644 src/android/SkBitmapRegionCanvas.h (limited to 'src/android') diff --git a/src/android/SkBitmapRegionCanvas.cpp b/src/android/SkBitmapRegionCanvas.cpp deleted file mode 100644 index c7c42bd9a2..0000000000 --- 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 c01f96be3c..0000000000 --- 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 fDecoder; - - typedef SkBitmapRegionDecoder INHERITED; - -}; diff --git a/src/android/SkBitmapRegionDecoder.cpp b/src/android/SkBitmapRegionDecoder.cpp index 101efbda45..324d1be4a4 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 @@ SkBitmapRegionDecoder* SkBitmapRegionDecoder::Create( SkStreamRewindable* stream, Strategy strategy) { SkAutoTDelete streamDeleter(stream); switch (strategy) { - case kCanvas_Strategy: { - SkAutoTDelete 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 codec = SkAndroidCodec::NewFromStream(streamDeleter.release()); -- cgit v1.2.3