Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Unified Diff: src/codec/SkCodec.cpp

Issue 1321433002: Add subsetting to SkScaledCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@gif-scan
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/codec/SkCodec.cpp
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index 1171bb0bd0324109acf54a247614d34a25b221d8..9bed4bf7d093942dade4f19fb59c047d320245ca 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -82,6 +82,7 @@ SkCodec::SkCodec(const SkImageInfo& info, SkStream* stream)
, fDstInfo()
, fOptions()
, fCurrScanline(-1)
+ , fSubsetWidth(0)
{}
SkCodec::~SkCodec() {}
@@ -103,6 +104,7 @@ bool SkCodec::rewindIfNeeded() {
// startScanlineDecode will need to be called before decoding scanlines.
fCurrScanline = -1;
+ fSubsetWidth = 0;
if (!fStream->rewind()) {
return false;
@@ -111,6 +113,59 @@ bool SkCodec::rewindIfNeeded() {
return this->onRewind();
}
+SkISize SkCodec::getScaledDimensions(float desiredScale) const {
+ // Negative and zero scales are errors.
+ SkASSERT(desiredScale > 0.0f);
+ if (desiredScale <= 0.0f) {
+ return SkISize::Make(0, 0);
+ }
+
+ // Upscaling is not supported. Return the original size if the client
+ // requests an upscale.
+ if (desiredScale >= 1.0f) {
+ return this->getInfo().dimensions();
+ }
+ return this->onGetScaledDimensions(desiredScale);
+}
+
+bool SkCodec::getValidSubset(SkIRect* desiredSubset) const {
+ if (!desiredSubset) {
+ return false;
+ }
+
+ if (!is_valid_subset(desiredSubset, this->getInfo().dimensions())) {
+ return false;
+ }
+
+ return this->onGetValidSubset(desiredSubset);
+}
+
+bool SkCodec::getScaledSubsetDimensions(float desiredScale, Options* options) const {
+ // Negative and zero scales are errors.
+ SkASSERT(desiredScale > 0.0f);
+ if (desiredScale <= 0.0f) {
+ return false;
+ }
+
+ // Upscaling is not supported. We will suggest a full decode if
+ // upscaling is requested.
+ if (desiredScale >= 1.0f) {
+ desiredScale = 1.0f;
+ }
+
+ // If the client is not requesting a subset decode,
+ // getScaledDimensions() should be used.
+ if (nullptr == options->fSubset) {
+ return false;
+ }
+
+ if (!is_valid_subset(options->fSubset, this->getInfo().dimensions())) {
+ return false;
+ }
+
+ return this->onGetScaledSubsetDimensions(desiredScale, options);
+}
+
SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
const Options* options, SkPMColor ctable[], int* ctableCount) {
if (kUnknown_SkColorType == info.colorType()) {
@@ -182,9 +237,17 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
}
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
- const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) {
+ const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount, int subsetLeft,
+ int subsetWidth) {
// Reset fCurrScanline in case of failure.
fCurrScanline = -1;
+
+ // Ensure that the subset parameters are valid
+ if (0 > subsetLeft || subsetLeft >= dstInfo.width() || 0 > subsetWidth ||
scroggo 2015/10/02 18:27:03 nit: I would lean towards separating these out log
+ subsetLeft + subsetWidth > dstInfo.width()) {
+ return kInvalidParameters;
+ }
+
// Ensure that valid color ptrs are passed in for kIndex8 color type
if (kIndex_8_SkColorType == dstInfo.colorType()) {
if (nullptr == ctable || nullptr == ctableCount) {
@@ -208,7 +271,8 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
options = &optsStorage;
}
- const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable, ctableCount);
+ const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable, ctableCount,
+ subsetLeft, subsetWidth);
if (result != SkCodec::kSuccess) {
return result;
}
@@ -216,11 +280,17 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
fCurrScanline = 0;
fDstInfo = dstInfo;
fOptions = *options;
+ fSubsetWidth = subsetWidth;
return kSuccess;
}
+SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
+ const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) {
+ return this->startScanlineDecode(dstInfo, options, ctable, ctableCount, 0, dstInfo.width());
+}
+
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo) {
- return this->startScanlineDecode(dstInfo, nullptr, nullptr, nullptr);
+ return this->startScanlineDecode(dstInfo, nullptr, nullptr, nullptr, 0, dstInfo.width());
}
int SkCodec::getScanlines(void* dst, int countLines, size_t rowBytes) {
@@ -229,8 +299,7 @@ int SkCodec::getScanlines(void* dst, int countLines, size_t rowBytes) {
}
SkASSERT(!fDstInfo.isEmpty());
- if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
- || fCurrScanline + countLines > fDstInfo.height()) {
+ if (countLines <= 0 || fCurrScanline + countLines > fDstInfo.height()) {
return 0;
}
@@ -282,21 +351,22 @@ void SkCodec::fillIncompleteImage(const SkImageInfo& info, void* dst, size_t row
SkImageInfo fillInfo;
const uint32_t fillValue = this->getFillValue(info.colorType(), info.alphaType());
const int linesRemaining = linesRequested - linesDecoded;
+ const int fillWidth = fSubsetWidth ? fSubsetWidth : info.width();
switch (this->getScanlineOrder()) {
case kTopDown_SkScanlineOrder:
case kNone_SkScanlineOrder:
fillDst = SkTAddOffset<void>(dst, linesDecoded * rowBytes);
- fillInfo = info.makeWH(info.width(), linesRemaining);
+ fillInfo = info.makeWH(fillWidth, linesRemaining);
SkSwizzler::Fill(fillDst, fillInfo, rowBytes, fillValue, zeroInit);
break;
case kBottomUp_SkScanlineOrder:
fillDst = dst;
- fillInfo = info.makeWH(info.width(), linesRemaining);
+ fillInfo = info.makeWH(fillWidth, linesRemaining);
SkSwizzler::Fill(fillDst, fillInfo, rowBytes, fillValue, zeroInit);
break;
case kOutOfOrder_SkScanlineOrder:
SkASSERT(1 == linesRequested || this->getInfo().height() == linesRequested);
- fillInfo = info.makeWH(info.width(), 1);
+ fillInfo = info.makeWH(fillWidth, 1);
for (int srcY = linesDecoded; srcY < linesRequested; srcY++) {
fillDst = SkTAddOffset<void>(dst, this->outputScanline(srcY) * rowBytes);
SkSwizzler::Fill(fillDst, fillInfo, rowBytes, fillValue, zeroInit);

Powered by Google App Engine
This is Rietveld 408576698