aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/subset/SubsetSingleBench.cpp53
-rw-r--r--bench/subset/SubsetTranslateBench.cpp62
-rw-r--r--bench/subset/SubsetZoomBench.cpp64
-rw-r--r--dm/DMSrcSink.cpp28
-rw-r--r--include/codec/SkCodec.h15
-rw-r--r--src/codec/SkBmpCodec.cpp4
-rw-r--r--src/codec/SkBmpMaskCodec.cpp8
-rw-r--r--src/codec/SkBmpMaskCodec.h2
-rw-r--r--src/codec/SkBmpRLECodec.cpp6
-rw-r--r--src/codec/SkBmpStandardCodec.cpp6
-rw-r--r--src/codec/SkCodec.cpp14
-rw-r--r--src/codec/SkCodec_libgif.cpp18
-rw-r--r--src/codec/SkCodec_libgif.h6
-rw-r--r--src/codec/SkCodec_libpng.cpp15
-rw-r--r--src/codec/SkCodec_libpng.h3
-rw-r--r--src/codec/SkCodec_wbmp.cpp10
-rw-r--r--src/codec/SkJpegCodec.cpp47
-rw-r--r--src/codec/SkJpegCodec.h3
-rw-r--r--src/codec/SkMaskSwizzler.cpp26
-rw-r--r--src/codec/SkMaskSwizzler.h12
-rw-r--r--src/codec/SkSwizzler.cpp35
-rw-r--r--src/codec/SkSwizzler.h20
-rw-r--r--src/codec/SkWebpCodec.cpp4
23 files changed, 194 insertions, 267 deletions
diff --git a/bench/subset/SubsetSingleBench.cpp b/bench/subset/SubsetSingleBench.cpp
index b4e92e4e22..47a897fd83 100644
--- a/bench/subset/SubsetSingleBench.cpp
+++ b/bench/subset/SubsetSingleBench.cpp
@@ -65,56 +65,29 @@ void SubsetSingleBench::onDraw(int n, SkCanvas* canvas) {
if (fUseCodec) {
for (int count = 0; count < n; count++) {
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate()));
+ SkASSERT(SkCodec::kOutOfOrder_SkScanlineOrder != codec->getScanlineOrder());
const SkImageInfo info = codec->getInfo().makeColorType(fColorType);
+ // The scanline decoder will handle subsetting in the x-dimension.
+ SkIRect subset = SkIRect::MakeXYWH(fOffsetLeft, 0, fSubsetWidth,
+ codec->getInfo().height());
+ SkCodec::Options options;
+ options.fSubset = &subset;
+
SkDEBUGCODE(SkCodec::Result result =)
- codec->startScanlineDecode(info, nullptr, colors, &colorCount);
+ codec->startScanlineDecode(info, &options, colors, &colorCount);
SkASSERT(result == SkCodec::kSuccess);
SkBitmap bitmap;
SkImageInfo subsetInfo = info.makeWH(fSubsetWidth, fSubsetHeight);
alloc_pixels(&bitmap, subsetInfo, colors, colorCount);
- SkDEBUGCODE(int lines = ) codec->skipScanlines(fOffsetTop);
- SkASSERT((uint32_t) lines == fOffsetTop);
-
- const uint32_t bpp = info.bytesPerPixel();
-
- switch (codec->getScanlineOrder()) {
- case SkCodec::kTopDown_SkScanlineOrder: {
- SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]);
- for (uint32_t y = 0; y < fSubsetHeight; y++) {
- SkDEBUGCODE(lines = ) codec->getScanlines(row.get(), 1, 0);
- SkASSERT(lines == 1);
-
- memcpy(bitmap.getAddr(0, y), row.get() + fOffsetLeft * bpp,
- fSubsetWidth * bpp);
- }
- break;
- }
- case SkCodec::kNone_SkScanlineOrder: {
- // decode all scanlines that intersect the subset, and copy the subset
- // into the output.
- SkImageInfo stripeInfo = info.makeWH(info.width(), fSubsetHeight);
- SkBitmap stripeBm;
- alloc_pixels(&stripeBm, stripeInfo, colors, colorCount);
-
- SkDEBUGCODE(lines = ) codec->getScanlines(stripeBm.getPixels(), fSubsetHeight,
- stripeBm.rowBytes());
- SkASSERT((uint32_t) lines == fSubsetHeight);
-
- for (uint32_t y = 0; y < fSubsetHeight; y++) {
- memcpy(bitmap.getAddr(0, y), stripeBm.getAddr(fOffsetLeft, y),
- fSubsetWidth * bpp);
- }
- break;
- }
- default:
- // We currently are only testing kTopDown and kNone, which are the only
- // two used by the subsets we care about. skbug.com/4428
- SkASSERT(false);
+ SkDEBUGCODE(bool success = ) codec->skipScanlines(fOffsetTop);
+ SkASSERT(success);
- }
+ SkDEBUGCODE(uint32_t lines = ) codec->getScanlines(bitmap.getPixels(), fSubsetHeight,
+ bitmap.rowBytes());
+ SkASSERT(lines == fSubsetHeight);
}
} else {
for (int count = 0; count < n; count++) {
diff --git a/bench/subset/SubsetTranslateBench.cpp b/bench/subset/SubsetTranslateBench.cpp
index 27c628edde..d8da6db566 100644
--- a/bench/subset/SubsetTranslateBench.cpp
+++ b/bench/subset/SubsetTranslateBench.cpp
@@ -71,11 +71,8 @@ void SubsetTranslateBench::onDraw(int n, SkCanvas* canvas) {
if (fUseCodec) {
for (int count = 0; count < n; count++) {
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate()));
+ SkASSERT(SkCodec::kOutOfOrder_SkScanlineOrder != codec->getScanlineOrder());
const SkImageInfo info = codec->getInfo().makeColorType(fColorType);
- SkAutoTDeleteArray<uint8_t> row(nullptr);
- if (codec->getScanlineOrder() == SkCodec::kTopDown_SkScanlineOrder) {
- row.reset(new uint8_t[info.minRowBytes()]);
- }
SkBitmap bitmap;
// Note that we use the same bitmap for all of the subsets.
@@ -83,17 +80,8 @@ void SubsetTranslateBench::onDraw(int n, SkCanvas* canvas) {
SkImageInfo subsetInfo = info.makeWH(fSubsetWidth, fSubsetHeight);
alloc_pixels(&bitmap, subsetInfo, colors, colorCount);
- const uint32_t bpp = info.bytesPerPixel();
-
for (int x = 0; x < info.width(); x += fSubsetWidth) {
for (int y = 0; y < info.height(); y += fSubsetHeight) {
- SkDEBUGCODE(SkCodec::Result result =)
- codec->startScanlineDecode(info, nullptr, get_colors(&bitmap), &colorCount);
- SkASSERT(SkCodec::kSuccess == result);
-
- SkDEBUGCODE(int lines =) codec->skipScanlines(y);
- SkASSERT(y == lines);
-
const uint32_t currSubsetWidth =
x + (int) fSubsetWidth > info.width() ?
info.width() - x : fSubsetWidth;
@@ -101,38 +89,22 @@ void SubsetTranslateBench::onDraw(int n, SkCanvas* canvas) {
y + (int) fSubsetHeight > info.height() ?
info.height() - y : fSubsetHeight;
- switch (codec->getScanlineOrder()) {
- case SkCodec::kTopDown_SkScanlineOrder:
- for (uint32_t y = 0; y < currSubsetHeight; y++) {
- SkDEBUGCODE(lines =) codec->getScanlines(row.get(), 1, 0);
- SkASSERT(1 == lines);
-
- memcpy(bitmap.getAddr(0, y), row.get() + x * bpp,
- currSubsetWidth * bpp);
- }
- break;
- case SkCodec::kNone_SkScanlineOrder: {
- // decode all scanlines that intersect the subset, and copy the subset
- // into the output.
- SkImageInfo stripeInfo = info.makeWH(info.width(), currSubsetHeight);
- SkBitmap stripeBm;
- alloc_pixels(&stripeBm, stripeInfo, colors, colorCount);
-
- SkDEBUGCODE(lines =) codec->getScanlines(stripeBm.getPixels(),
- currSubsetHeight, stripeBm.rowBytes());
- SkASSERT(currSubsetHeight == (uint32_t) lines);
-
- for (uint32_t subsetY = 0; subsetY < currSubsetHeight; subsetY++) {
- memcpy(bitmap.getAddr(0, subsetY), stripeBm.getAddr(x, subsetY),
- currSubsetWidth * bpp);
- }
- break;
- }
- default:
- // We currently are only testing kTopDown and kNone, which are the only
- // two used by the subsets we care about. skbug.com/4428
- SkASSERT(false);
- }
+ // The scanline decoder will handle subsetting in the x-dimension.
+ SkIRect subset = SkIRect::MakeXYWH(x, 0, currSubsetWidth,
+ codec->getInfo().height());
+ SkCodec::Options options;
+ options.fSubset = &subset;
+
+ SkDEBUGCODE(SkCodec::Result result =)
+ codec->startScanlineDecode(info, &options, get_colors(&bitmap), &colorCount);
+ SkASSERT(SkCodec::kSuccess == result);
+
+ SkDEBUGCODE(bool success =) codec->skipScanlines(y);
+ SkASSERT(success);
+
+ SkDEBUGCODE(uint32_t lines =) codec->getScanlines(bitmap.getPixels(),
+ currSubsetHeight, bitmap.rowBytes());
+ SkASSERT(currSubsetHeight == lines);
}
}
}
diff --git a/bench/subset/SubsetZoomBench.cpp b/bench/subset/SubsetZoomBench.cpp
index 3edc17f1cb..f17a97c26b 100644
--- a/bench/subset/SubsetZoomBench.cpp
+++ b/bench/subset/SubsetZoomBench.cpp
@@ -61,69 +61,41 @@ void SubsetZoomBench::onDraw(int n, SkCanvas* canvas) {
if (fUseCodec) {
for (int count = 0; count < n; count++) {
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate()));
+ SkASSERT(SkCodec::kOutOfOrder_SkScanlineOrder != codec->getScanlineOrder());
const SkImageInfo info = codec->getInfo().makeColorType(fColorType);
- SkAutoTDeleteArray<uint8_t> row(nullptr);
- if (codec->getScanlineOrder() == SkCodec::kTopDown_SkScanlineOrder) {
- row.reset(new uint8_t[info.minRowBytes()]);
- }
const int centerX = info.width() / 2;
const int centerY = info.height() / 2;
int w = fSubsetWidth;
int h = fSubsetHeight;
do {
- SkDEBUGCODE(SkCodec::Result result = )
- codec->startScanlineDecode(info, nullptr, colors, &colorCount);
- SkASSERT(SkCodec::kSuccess == result);
-
const int subsetStartX = SkTMax(0, centerX - w / 2);
const int subsetStartY = SkTMax(0, centerY - h / 2);
const int subsetWidth = SkTMin(w, info.width() - subsetStartX);
const int subsetHeight = SkTMin(h, info.height() - subsetStartY);
+
+ // The scanline decoder will handle subsetting in the x-dimension.
+ SkIRect subset = SkIRect::MakeXYWH(subsetStartX, 0, subsetWidth,
+ codec->getInfo().height());
+ SkCodec::Options options;
+ options.fSubset = &subset;
+
+ SkDEBUGCODE(SkCodec::Result result = )
+ codec->startScanlineDecode(info, &options, colors, &colorCount);
+ SkASSERT(SkCodec::kSuccess == result);
+
// Note that if we subsetted and scaled in a single step, we could use the
// same bitmap - as is often done in actual use cases.
SkBitmap bitmap;
SkImageInfo subsetInfo = info.makeWH(subsetWidth, subsetHeight);
alloc_pixels(&bitmap, subsetInfo, colors, colorCount);
- uint32_t bpp = info.bytesPerPixel();
-
- SkDEBUGCODE(int lines = ) codec->skipScanlines(subsetStartY);
- SkASSERT(subsetStartY == lines);
-
- switch (codec->getScanlineOrder()) {
- case SkCodec::kTopDown_SkScanlineOrder:
- for (int y = 0; y < subsetHeight; y++) {
- SkDEBUGCODE(lines = ) codec->getScanlines(row.get(), 1, 0);
- SkASSERT(1 == lines);
-
- memcpy(bitmap.getAddr(0, y), row.get() + subsetStartX * bpp,
- subsetWidth * bpp);
- }
- break;
- case SkCodec::kNone_SkScanlineOrder: {
- // decode all scanlines that intersect the subset, and copy the subset
- // into the output.
- SkImageInfo stripeInfo = info.makeWH(info.width(), subsetHeight);
- SkBitmap stripeBm;
- alloc_pixels(&stripeBm, stripeInfo, colors, colorCount);
-
- SkDEBUGCODE(lines = ) codec->getScanlines(stripeBm.getPixels(),
- subsetHeight, stripeBm.rowBytes());
- SkASSERT(subsetHeight == lines);
-
- for (int y = 0; y < subsetHeight; y++) {
- memcpy(bitmap.getAddr(0, y),
- stripeBm.getAddr(subsetStartX, y),
- subsetWidth * bpp);
- }
- break;
- }
- default:
- // We currently are only testing kTopDown and kNone, which are the only
- // two used by the subsets we care about. skbug.com/4428
- SkASSERT(false);
- }
+ SkDEBUGCODE(bool success = ) codec->skipScanlines(subsetStartY);
+ SkASSERT(success);
+
+ SkDEBUGCODE(int lines = ) codec->getScanlines(bitmap.getPixels(),
+ subsetHeight, bitmap.rowBytes());
+ SkASSERT(subsetHeight == lines);
w <<= 1;
h <<= 1;
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index c7b389d36d..4137154e99 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -404,9 +404,6 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(),
largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo.height());
}
- const size_t rowBytes = decodeInfo.minRowBytes();
- char* buffer = new char[largestSubsetDecodeInfo.height() * rowBytes];
- SkAutoTDeleteArray<char> lineDeleter(buffer);
for (int col = 0; col < divisor; col++) {
//currentSubsetWidth may be larger than subsetWidth for rightmost subsets
const int currentSubsetWidth = (col + 1 == divisor) ?
@@ -418,10 +415,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
subsetHeight + extraY : subsetHeight;
const int y = row * subsetHeight;
//create scanline decoder for each subset
- if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
- colorCountPtr)
- // TODO (msarett): Support this mode for all scanline orderings.
- || SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOrder()) {
+ SkCodec::Options options;
+ SkIRect subset = SkIRect::MakeXYWH(x, 0, currentSubsetWidth, h);
+ options.fSubset = &subset;
+ // TODO (msarett): Support this mode for all scanline orderings.
+ if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options,
+ colorPtr, colorCountPtr) ||
+ SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOrder()) {
if (x == 0 && y == 0) {
//first try, image may not be compatible
return Error::Nonfatal("Could not start top-down scanline decoder");
@@ -440,17 +440,9 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
SkBitmap subsetBm;
SkIRect bounds = SkIRect::MakeWH(currentSubsetWidth, currentSubsetHeight);
SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, bounds));
- SkAutoLockPixels autlockSubsetBm(subsetBm, true);
- codec->getScanlines(buffer, currentSubsetHeight, rowBytes);
-
- const size_t bpp = decodeInfo.bytesPerPixel();
- char* bufferRow = buffer;
- for (int subsetY = 0; subsetY < currentSubsetHeight; ++subsetY) {
- memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp,
- currentSubsetWidth*bpp);
- bufferRow += rowBytes;
- }
-
+ SkAutoLockPixels autolock(subsetBm, true);
+ codec->getScanlines(subsetBm.getAddr(0, 0), currentSubsetHeight,
+ subsetBm.rowBytes());
subsetBm.notifyPixelsChanged();
canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar(y));
}
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h
index 1b9cb0f5d7..8b6e210167 100644
--- a/include/codec/SkCodec.h
+++ b/include/codec/SkCodec.h
@@ -168,11 +168,20 @@ public:
ZeroInitialized fZeroInitialized;
/**
* If not NULL, represents a subset of the original image to decode.
- *
* Must be within the bounds returned by getInfo().
- *
* If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which
* currently supports subsets), the top and left values must be even.
+ *
+ * In getPixels, we will attempt to decode the exact rectangular
+ * subset specified by fSubset.
+ *
+ * In a scanline decode, it does not make sense to specify a subset
+ * top or subset height, since the client already controls which rows
+ * to get and which rows to skip. During scanline decodes, we will
+ * require that the subset top be zero and the subset height be equal
+ * to the full height. We will, however, use the values of
+ * subset left and subset width to decode partial scanlines on calls
+ * to getScanlines().
*/
SkIRect* fSubset;
};
@@ -259,7 +268,7 @@ public:
* @return Enum representing success or reason for failure.
*/
Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options,
- SkPMColor ctable[], int* ctableCount);
+ SkPMColor ctable[], int* ctableCount);
/**
* Simplified version of startScanlineDecode() that asserts that info is NOT
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index 1aa43f583c..0222c8ce9f 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -564,10 +564,6 @@ uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) {
SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
- if (options.fSubset) {
- // Subsets are not supported.
- return kUnimplemented;
- }
if (!conversion_possible(dstInfo, this->getInfo())) {
SkCodecPrintf("Error: cannot convert input type to output type.\n");
return kInvalidConversion;
diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp
index 336698d319..2bc47b5126 100644
--- a/src/codec/SkBmpMaskCodec.cpp
+++ b/src/codec/SkBmpMaskCodec.cpp
@@ -58,10 +58,10 @@ SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
return kSuccess;
}
-bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo) {
+bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
// Create the swizzler
- fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(
- dstInfo, this->getInfo(), fMasks, this->bitsPerPixel()));
+ fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(dstInfo, this->getInfo(), fMasks,
+ this->bitsPerPixel(), options));
if (nullptr == fMaskSwizzler.get()) {
return false;
@@ -73,7 +73,7 @@ bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo) {
SkCodec::Result SkBmpMaskCodec::prepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
// Initialize a the mask swizzler
- if (!this->initializeSwizzler(dstInfo)) {
+ if (!this->initializeSwizzler(dstInfo, options)) {
SkCodecPrintf("Error: cannot initialize swizzler.\n");
return SkCodec::kInvalidConversion;
}
diff --git a/src/codec/SkBmpMaskCodec.h b/src/codec/SkBmpMaskCodec.h
index 1c1d1d8c11..4ec868db0e 100644
--- a/src/codec/SkBmpMaskCodec.h
+++ b/src/codec/SkBmpMaskCodec.h
@@ -44,7 +44,7 @@ protected:
private:
- bool initializeSwizzler(const SkImageInfo& dstInfo);
+ bool initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
SkSampler* getSampler(bool createIfNecessary) override {
SkASSERT(fMaskSwizzler);
return fMaskSwizzler;
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
index 37af47600b..e215095266 100644
--- a/src/codec/SkBmpRLECodec.cpp
+++ b/src/codec/SkBmpRLECodec.cpp
@@ -259,6 +259,12 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
+ // FIXME: Support subsets for scanline decodes.
+ if (options.fSubset) {
+ // Subsets are not supported.
+ return kUnimplemented;
+ }
+
// Reset fSampleX. If it needs to be a value other than 1, it will get modified by
// the sampler.
fSampleX = 1;
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 938fe8c788..9557609360 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -161,8 +161,7 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
return true;
}
-bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo,
- const Options& opts) {
+bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) {
// Get swizzler configuration
SkSwizzler::SrcConfig config;
switch (this->bitsPerPixel()) {
@@ -197,8 +196,7 @@ bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo,
const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
// Create swizzler
- fSwizzler.reset(SkSwizzler::CreateSwizzler(config,
- colorPtr, dstInfo, opts.fZeroInitialized));
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(config, colorPtr, dstInfo, opts));
if (nullptr == fSwizzler.get()) {
return false;
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index 0047d599ac..56f6a8de9e 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -220,11 +220,15 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
if (nullptr == options) {
options = &optsStorage;
} else if (options->fSubset) {
- SkIRect subset(*options->fSubset);
- if (!this->onGetValidSubset(&subset) || subset != *options->fSubset) {
- // FIXME: How to differentiate between not supporting subset at all
- // and not supporting this particular subset?
- return kUnimplemented;
+ SkIRect size = SkIRect::MakeSize(dstInfo.dimensions());
+ if (!size.contains(*options->fSubset)) {
+ return kInvalidInput;
+ }
+
+ // We only support subsetting in the x-dimension for scanline decoder.
+ // Subsetting in the y-dimension can be accomplished using skipScanlines().
+ if (options->fSubset->top() != 0 || options->fSubset->height() != dstInfo.height()) {
+ return kInvalidInput;
}
}
diff --git a/src/codec/SkCodec_libgif.cpp b/src/codec/SkCodec_libgif.cpp
index 856f69ba3c..0187891558 100644
--- a/src/codec/SkCodec_libgif.cpp
+++ b/src/codec/SkCodec_libgif.cpp
@@ -435,10 +435,6 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, SkPMColor* inp
SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr,
int* inputColorCount, const Options& opts) {
// Check for valid input parameters
- if (opts.fSubset) {
- // Subsets are not supported.
- return kUnimplemented;
- }
if (!conversion_possible(dstInfo, this->getInfo())) {
return gif_error("Cannot convert input type to output type.\n",
kInvalidConversion);
@@ -449,11 +445,9 @@ SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
return kSuccess;
}
-SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo,
- ZeroInitialized zeroInit) {
+SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) {
const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
- fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex,
- colorPtr, dstInfo, zeroInit));
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dstInfo, opts));
if (nullptr != fSwizzler.get()) {
return kSuccess;
}
@@ -485,7 +479,7 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
// Initialize the swizzler
if (fFrameIsSubset) {
const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFrameRect.height());
- if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitialized)) {
+ if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) {
return gif_error("Could not initialize swizzler.\n", kUnimplemented);
}
@@ -499,7 +493,7 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
dst = SkTAddOffset<void*>(dst, dstRowBytes * fFrameRect.top() +
dstBytesPerPixel * fFrameRect.left());
} else {
- if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)) {
+ if (kSuccess != this->initializeSwizzler(dstInfo, opts)) {
return gif_error("Could not initialize swizzler.\n", kUnimplemented);
}
}
@@ -535,11 +529,11 @@ SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
// Initialize the swizzler
if (fFrameIsSubset) {
const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFrameRect.height());
- if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitialized)) {
+ if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) {
return gif_error("Could not initialize swizzler.\n", kUnimplemented);
}
} else {
- if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)) {
+ if (kSuccess != this->initializeSwizzler(dstInfo, opts)) {
return gif_error("Could not initialize swizzler.\n", kUnimplemented);
}
}
diff --git a/src/codec/SkCodec_libgif.h b/src/codec/SkCodec_libgif.h
index 10fdac97f9..2e0c5a4a1d 100644
--- a/src/codec/SkCodec_libgif.h
+++ b/src/codec/SkCodec_libgif.h
@@ -129,9 +129,11 @@ private:
* @param dstInfo Output image information. Dimensions may have been
* adjusted if the image frame size does not match the size
* indicated in the header.
- * @param zeroInit Indicates if destination memory is zero initialized.
+ * @param options Informs the swizzler if destination memory is zero initialized.
+ * Contains subset information.
*/
- Result initializeSwizzler(const SkImageInfo& dstInfo, ZeroInitialized zeroInit);
+ Result initializeSwizzler(const SkImageInfo& dstInfo,
+ const Options& options);
SkSampler* getSampler(bool createIfNecessary) override {
SkASSERT(fSwizzler);
diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp
index e828e24999..7d41623a88 100644
--- a/src/codec/SkCodec_libpng.cpp
+++ b/src/codec/SkCodec_libpng.cpp
@@ -435,8 +435,7 @@ SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo,
// Create the swizzler. SkPngCodec retains ownership of the color table.
const SkPMColor* colors = get_color_ptr(fColorTable.get());
- fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo,
- options.fZeroInitialized));
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo, options));
if (!fSwizzler) {
// FIXME: CreateSwizzler could fail for another reason.
return kUnimplemented;
@@ -477,8 +476,7 @@ SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
}
// Note that ctable and ctableCount may be modified if there is a color table
- const Result result = this->initializeSwizzler(requestedInfo, options,
- ctable, ctableCount);
+ const Result result = this->initializeSwizzler(requestedInfo, options, ctable, ctableCount);
if (result != kSuccess) {
return result;
}
@@ -699,15 +697,14 @@ public:
}
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
- SkPMColor ctable[], int* ctableCount) override
- {
+ SkPMColor ctable[], int* ctableCount) override {
if (!conversion_possible(dstInfo, this->getInfo())) {
return kInvalidConversion;
}
- const SkCodec::Result result = this->initializeSwizzler(dstInfo, options, ctable,
- ctableCount);
- if (result != SkCodec::kSuccess) {
+ const Result result = this->initializeSwizzler(dstInfo, options, ctable,
+ ctableCount);
+ if (result != kSuccess) {
return result;
}
diff --git a/src/codec/SkCodec_libpng.h b/src/codec/SkCodec_libpng.h
index 6bdf58065b..f003cbd4e0 100644
--- a/src/codec/SkCodec_libpng.h
+++ b/src/codec/SkCodec_libpng.h
@@ -18,7 +18,6 @@
#endif
#include "png.h"
-class SkScanlineDecoder;
class SkStream;
class SkPngCodec : public SkCodec {
@@ -27,7 +26,6 @@ public:
// Assume IsPng was called and returned true.
static SkCodec* NewFromStream(SkStream*);
- static SkScanlineDecoder* NewSDFromStream(SkStream*);
virtual ~SkPngCodec();
@@ -78,7 +76,6 @@ private:
SkSwizzler::SrcConfig fSrcConfig;
const int fNumberPasses;
int fBitDepth;
-
AlphaState fAlphaState;
bool decodePalette(bool premultiply, int* ctableCount);
diff --git a/src/codec/SkCodec_wbmp.cpp b/src/codec/SkCodec_wbmp.cpp
index 14b720988f..19ae4eaf0e 100644
--- a/src/codec/SkCodec_wbmp.cpp
+++ b/src/codec/SkCodec_wbmp.cpp
@@ -70,8 +70,8 @@ bool SkWbmpCodec::onRewind() {
return read_header(this->stream(), nullptr);
}
-SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info,
- const SkPMColor* ctable, const Options& opts) {
+SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable,
+ const Options& opts) {
// Create the swizzler based on the desired color type
switch (info.colorType()) {
case kIndex_8_SkColorType:
@@ -82,8 +82,7 @@ SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info,
default:
return nullptr;
}
- return SkSwizzler::CreateSwizzler(SkSwizzler::kBit, ctable, info,
- opts.fZeroInitialized);
+ return SkSwizzler::CreateSwizzler(SkSwizzler::kBit, ctable, info, opts);
}
bool SkWbmpCodec::readRow(uint8_t* row) {
@@ -188,8 +187,7 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
}
// Initialize the swizzler
- fSwizzler.reset(this->initializeSwizzler(dstInfo,
- get_color_ptr(fColorTable.get()), options));
+ fSwizzler.reset(this->initializeSwizzler(dstInfo, get_color_ptr(fColorTable.get()), options));
if (nullptr == fSwizzler.get()) {
return kInvalidConversion;
}
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 196543b682..d0d11b1a08 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -177,19 +177,19 @@ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
// support these as well
unsigned int num;
unsigned int denom = 8;
- if (desiredScale > 0.875f) {
+ if (desiredScale >= 0.9375) {
num = 8;
- } else if (desiredScale > 0.75f) {
+ } else if (desiredScale >= 0.8125) {
num = 7;
- } else if (desiredScale > 0.625f) {
+ } else if (desiredScale >= 0.6875f) {
num = 6;
- } else if (desiredScale > 0.5f) {
+ } else if (desiredScale >= 0.5625f) {
num = 5;
- } else if (desiredScale > 0.375f) {
+ } else if (desiredScale >= 0.4375f) {
num = 4;
- } else if (desiredScale > 0.25f) {
+ } else if (desiredScale >= 0.3125f) {
num = 3;
- } else if (desiredScale > 0.125f) {
+ } else if (desiredScale >= 0.1875f) {
num = 2;
} else {
num = 1;
@@ -380,15 +380,9 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
return kSuccess;
}
-SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
- if (!createIfNecessary || fSwizzler) {
- SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get()) == fSrcRow));
- return fSwizzler;
- }
-
- const SkImageInfo& info = this->dstInfo();
+void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
SkSwizzler::SrcConfig srcConfig;
- switch (info.colorType()) {
+ switch (dstInfo.colorType()) {
case kGray_8_SkColorType:
srcConfig = SkSwizzler::kGray;
break;
@@ -406,14 +400,18 @@ SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
SkASSERT(false);
}
- fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info,
- this->options().fZeroInitialized));
- if (!fSwizzler) {
- return nullptr;
- }
-
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, options));
fStorage.reset(get_row_bytes(fDecoderMgr->dinfo()));
fSrcRow = static_cast<uint8_t*>(fStorage.get());
+}
+
+SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
+ if (!createIfNecessary || fSwizzler) {
+ SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get()) == fSrcRow));
+ return fSwizzler;
+ }
+
+ this->initializeSwizzler(this->dstInfo(), this->options());
return fSwizzler;
}
@@ -441,6 +439,11 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
return kInvalidInput;
}
+ // We will need a swizzler if we are performing a subset decode
+ if (options.fSubset) {
+ this->initializeSwizzler(dstInfo, options);
+ }
+
return kSuccess;
}
@@ -452,7 +455,7 @@ int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
// Read rows one at a time
JSAMPLE* dstRow;
if (fSwizzler) {
- // write data to storage row, then sample using swizzler
+ // write data to storage row, then sample using swizzler
dstRow = fSrcRow;
} else {
// write data directly to dst
diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h
index 67680d66e8..687cf4b4b8 100644
--- a/src/codec/SkJpegCodec.h
+++ b/src/codec/SkJpegCodec.h
@@ -103,9 +103,10 @@ private:
bool setOutputColorSpace(const SkImageInfo& dst);
// scanline decoding
+ void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
SkSampler* getSampler(bool createIfNecessary) override;
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
- SkPMColor ctable[], int* ctableCount) override;
+ SkPMColor ctable[], int* ctableCount) override;
int onGetScanlines(void* dst, int count, size_t rowBytes) override;
bool onSkipScanlines(int count) override;
diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp
index 9772d87e38..72dca28057 100644
--- a/src/codec/SkMaskSwizzler.cpp
+++ b/src/codec/SkMaskSwizzler.cpp
@@ -250,9 +250,9 @@ static SkSwizzler::ResultAlpha swizzle_mask32_to_565(
* Create a new mask swizzler
*
*/
-SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
- const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, SkMasks* masks,
- uint32_t bitsPerPixel) {
+SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
+ const SkImageInfo& srcInfo, SkMasks* masks, uint32_t bitsPerPixel,
+ const SkCodec::Options& options) {
// Choose the appropriate row procedure
RowProc proc = nullptr;
@@ -352,7 +352,14 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
return nullptr;
}
- return new SkMaskSwizzler(dstInfo.width(), masks, proc);
+ int srcOffset = 0;
+ int srcWidth = dstInfo.width();
+ if (options.fSubset) {
+ srcOffset = options.fSubset->left();
+ srcWidth = options.fSubset->width();
+ }
+
+ return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth);
}
/*
@@ -360,13 +367,14 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(
* Constructor for mask swizzler
*
*/
-SkMaskSwizzler::SkMaskSwizzler(int width, SkMasks* masks, RowProc proc)
+SkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int srcWidth)
: fMasks(masks)
, fRowProc(proc)
- , fSrcWidth(width)
- , fDstWidth(width)
+ , fSrcWidth(srcWidth)
+ , fDstWidth(srcWidth)
, fSampleX(1)
- , fX0(0)
+ , fSrcOffset(srcOffset)
+ , fX0(srcOffset)
{}
int SkMaskSwizzler::onSetSampleX(int sampleX) {
@@ -374,7 +382,7 @@ int SkMaskSwizzler::onSetSampleX(int sampleX) {
SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
// way to report failure?
fSampleX = sampleX;
- fX0 = get_start_coord(sampleX);
+ fX0 = get_start_coord(sampleX) + fSrcOffset;
fDstWidth = get_scaled_dimension(fSrcWidth, sampleX);
// check that fX0 is less than original width
diff --git a/src/codec/SkMaskSwizzler.h b/src/codec/SkMaskSwizzler.h
index 0513d838c7..9aea5d8d70 100644
--- a/src/codec/SkMaskSwizzler.h
+++ b/src/codec/SkMaskSwizzler.h
@@ -28,7 +28,8 @@ public:
static SkMaskSwizzler* CreateMaskSwizzler(const SkImageInfo& dstInfo,
const SkImageInfo& srcInfo,
SkMasks* masks,
- uint32_t bitsPerPixel);
+ uint32_t bitsPerPixel,
+ const SkCodec::Options& options);
/*
* Swizzle a row
@@ -49,14 +50,10 @@ private:
/*
* Row procedure used for swizzle
*/
- typedef SkSwizzler::ResultAlpha (*RowProc)(
- void* dstRow, const uint8_t* srcRow, int width,
+ typedef SkSwizzler::ResultAlpha (*RowProc)(void* dstRow, const uint8_t* srcRow, int width,
SkMasks* masks, uint32_t startX, uint32_t sampleX);
- /*
- * Constructor for mask swizzler
- */
- SkMaskSwizzler(int width, SkMasks* masks, RowProc proc);
+ SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcWidth, int srcOffset);
int onSetSampleX(int) override;
@@ -67,6 +64,7 @@ private:
const int fSrcWidth; // Width of the source - i.e. before any sampling.
int fDstWidth; // Width of dst, which may differ with sampling.
int fSampleX;
+ int fSrcOffset;
int fX0;
};
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
index 8d13e56bd2..95ed1d7b96 100644
--- a/src/codec/SkSwizzler.cpp
+++ b/src/codec/SkSwizzler.cpp
@@ -230,9 +230,6 @@ static SkSwizzler::ResultAlpha swizzle_index_to_index(
// SkScaledBitmap sampler just guesses that it is opaque. This is dangerous
// and probably wrong since gif and bmp (rarely) may have alpha.
if (1 == deltaSrc) {
- // A non-zero offset is only used when sampling, meaning that deltaSrc will be
- // greater than 1. The below loop relies on the fact that src remains unchanged.
- SkASSERT(0 == offset);
memcpy(dst, src, dstWidth);
for (int x = 0; x < dstWidth; x++) {
UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT);
@@ -514,8 +511,8 @@ static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
const SkPMColor* ctable,
- const SkImageInfo& dstInfo,
- SkCodec::ZeroInitialized zeroInit) {
+ const SkImageInfo& dstInfo,
+ const SkCodec::Options& options) {
if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
return nullptr;
}
@@ -524,7 +521,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
return nullptr;
}
RowProc proc = nullptr;
-
+ SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized;
switch (sc) {
case kBit:
switch (dstInfo.colorType()) {
@@ -683,28 +680,35 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
return nullptr;
}
- // Store deltaSrc in bytes if it is an even multiple, otherwise use bits
- int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
+ // Store bpp in bytes if it is an even multiple, otherwise use bits
+ int bpp = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
+
+ int srcOffset = 0;
+ int srcWidth = dstInfo.width();
+ if (options.fSubset) {
+ srcOffset = options.fSubset->left();
+ srcWidth = options.fSubset->width();
+ }
- return new SkSwizzler(proc, ctable, deltaSrc, dstInfo.width());
+ return new SkSwizzler(proc, ctable, srcOffset, srcWidth, bpp);
}
-SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
- int deltaSrc, int srcWidth)
+SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, int bpp)
: fRowProc(proc)
, fColorTable(ctable)
- , fDeltaSrc(deltaSrc)
+ , fSrcOffset(srcOffset)
+ , fX0(srcOffset)
, fSrcWidth(srcWidth)
, fDstWidth(srcWidth)
+ , fBPP(bpp)
, fSampleX(1)
- , fX0(0)
{}
int SkSwizzler::onSetSampleX(int sampleX) {
SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
// way to report failure?
fSampleX = sampleX;
- fX0 = get_start_coord(sampleX);
+ fX0 = get_start_coord(sampleX) + fSrcOffset;
fDstWidth = get_scaled_dimension(fSrcWidth, sampleX);
// check that fX0 is less than original width
@@ -714,6 +718,5 @@ int SkSwizzler::onSetSampleX(int sampleX) {
SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
SkASSERT(nullptr != dst && nullptr != src);
- return fRowProc(dst, src, fDstWidth, fDeltaSrc, fSampleX * fDeltaSrc,
- fX0 * fDeltaSrc, fColorTable);
+ return fRowProc(dst, src, fDstWidth, fBPP, fSampleX * fBPP, fX0 * fBPP, fColorTable);
}
diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h
index d7f6337553..058044e420 100644
--- a/src/codec/SkSwizzler.h
+++ b/src/codec/SkSwizzler.h
@@ -121,13 +121,14 @@ public:
* @param ctable Unowned pointer to an array of up to 256 colors for an
* index source.
* @param dstInfo Describes the destination.
- * @param ZeroInitialized Whether dst is zero-initialized. The
+ * @param options Indicates if dst is zero-initialized. The
* implementation may choose to skip writing zeroes
* if set to kYes_ZeroInitialized.
+ * Contains subset information.
* @return A new SkSwizzler or nullptr on failure.
*/
static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
- const SkImageInfo& dstInfo, SkCodec::ZeroInitialized);
+ const SkImageInfo& dstInfo, const SkCodec::Options&);
/**
* Swizzle a line. Generally this will be called height times, once
@@ -173,16 +174,19 @@ private:
const RowProc fRowProc;
const SkPMColor* fColorTable; // Unowned pointer
- const int fDeltaSrc; // if bitsPerPixel % 8 == 0
- // deltaSrc is bytesPerPixel
- // else
- // deltaSrc is bitsPerPixel
+ const int fSrcOffset; // Offset of the src in pixels, allows for partial
+ // scanline decodes.
+ int fX0; // Start coordinate for the src, may be different than
+ // fSrcOffset if we are sampling.
const int fSrcWidth; // Width of the source - i.e. before any sampling.
int fDstWidth; // Width of dst, which may differ with sampling.
- int fX0; // first X coord to sample
int fSampleX; // step between X samples
+ const int fBPP; // if bitsPerPixel % 8 == 0
+ // fBPP is bytesPerPixel
+ // else
+ // fBPP is bitsPerPixel
- SkSwizzler(RowProc proc, const SkPMColor* ctable, int deltaSrc, int srcWidth);
+ SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, int bpp);
int onSetSampleX(int) override;
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index a0fab0a153..3c61b93762 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -144,8 +144,8 @@ bool SkWebpCodec::onGetValidSubset(SkIRect* desiredSubset) const {
return false;
}
- SkIRect bounds = SkIRect::MakeSize(this->getInfo().dimensions());
- if (!desiredSubset->intersect(bounds)) {
+ SkIRect dimensions = SkIRect::MakeSize(this->getInfo().dimensions());
+ if (!dimensions.contains(*desiredSubset)) {
return false;
}