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

Unified Diff: src/codec/SkCodec.cpp

Issue 1395183003: Add scaled subset API to SkCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@split0
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 56f6a8de9e4c6f6d9c72abef44d1402d5586828c..00fcb9656e75fd273632fcefc146307714681de3 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -111,6 +111,94 @@ bool SkCodec::rewindIfNeeded() {
return this->onRewind();
}
+bool SkCodec::getScaledSubsetDimensions(float desiredScale, const 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 (!options.fSubset || !options.fScaledDimensions || !options.fScaledSubset) {
+ return false;
+ }
+
+ if (!is_valid_subset(*options.fSubset, this->getInfo().dimensions())) {
+ return false;
+ }
+
+ return this->onGetScaledSubsetDimensions(desiredScale, options);
+}
+
+bool SkCodec::subsetSupported(const SkIRect& subset, bool isScanlineDecode) {
+ if (!is_valid_subset(subset, this->getInfo().dimensions())) {
scroggo 2015/10/12 20:47:07 nit: fInfo.dimensions() No need to call the acces
+ return false;
+ }
+
+ return this->onSubsetSupported(subset, isScanlineDecode);
+}
+
+bool SkCodec::onSubsetSupported(const SkIRect& subset, bool isScanlineDecode) {
+ if (!isScanlineDecode) {
+ return false;
+ }
+
+ // We support subsetting in the x-dimension for the scanline decoder.
+ // Subsetting in the y-dimension can be accomplished using skipScanlines().
+ return subset.top() == 0 && subset.height() == this->getInfo().height();
+}
+
+bool SkCodec::scaledSubsetSupported(const SkISize& dstSize, const Options& options,
+ bool isScanlineDecode) {
+ SkIRect* subset = options.fSubset;
+
+ // If there is no subsetting, we simply check if we can scale to dstSize
+ if (!subset) {
+ return this->dimensionsSupported(dstSize);
+ }
+
+ SkISize* scaledDimensions = options.fScaledDimensions;
+ SkIRect* scaledSubset = options.fScaledSubset;
+ if (!scaledDimensions && !scaledSubset) {
+ // If there is no scaling, check if we support the subset requested
+ return this->subsetSupported(*subset, isScanlineDecode);
+ }
+
+ if (!scaledDimensions || !scaledSubset) {
+ // Both scaledDimensions and scaledSubset must be non-NULL to perform
+ // a scaled subset decode.
+ return false;
+ }
+
+ if (!is_valid_subset(*scaledSubset, *scaledDimensions)) {
+ return false;
+ }
+
+ return this->onScaledSubsetSupported(options, isScanlineDecode);
+}
+
+bool SkCodec::onScaledSubsetSupported(const Options& options, bool isScanlineDecode) {
+ if (!isScanlineDecode) {
+ return false;
+ }
+
+ if (!this->dimensionsSupported(*options.fScaledDimensions)) {
+ return false;
+ }
+
+ // We support subsetting in the x-dimension for the scanline decoder.
+ // Subsetting in the y-dimension can be accomplished using skipScanlines().
+ return options.fSubset->top() == 0 &&
+ options.fSubset->height() == options.fScaledDimensions->height();
+}
+
SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
const Options* options, SkPMColor ctable[], int* ctableCount) {
if (kUnknown_SkColorType == info.colorType()) {
@@ -152,18 +240,9 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
Options optsStorage;
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;
- }
}
- // FIXME: Support subsets somehow? Note that this works for SkWebpCodec
- // because it supports arbitrary scaling/subset combinations.
- if (!this->dimensionsSupported(info.dimensions())) {
+ if (!this->scaledSubsetSupported(info.dimensions(), *options, false)) {
return kInvalidScale;
}
@@ -219,21 +298,9 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo,
Options optsStorage;
if (nullptr == options) {
options = &optsStorage;
- } else if (options->fSubset) {
- 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;
- }
}
- // FIXME: Support subsets somehow?
- if (!this->dimensionsSupported(dstInfo.dimensions())) {
+ if (!this->scaledSubsetSupported(dstInfo.dimensions(), *options, true)) {
return kInvalidScale;
}

Powered by Google App Engine
This is Rietveld 408576698