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

Unified Diff: src/codec/SkWebpCodec.cpp

Issue 1240143002: Add the ability to decode a subset to SkCodec. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix some conversion warning/errors. Created 5 years, 5 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
« no previous file with comments | « src/codec/SkWebpCodec.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codec/SkWebpCodec.cpp
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index 32a8b78b14f2487e69305c6d90c89533319435bb..fea557d21ed9ddb8e9a86ff475a2c996a8fa749d 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -125,8 +125,26 @@ static WEBP_CSP_MODE webp_decode_mode(SkColorType ct, bool premultiply) {
// is arbitrary.
static const size_t BUFFER_SIZE = 4096;
+bool SkWebpCodec::onGetValidSubset(SkIRect* desiredSubset) const {
+ if (!desiredSubset) {
+ return false;
+ }
+
+ SkIRect bounds = SkIRect::MakeSize(this->getInfo().dimensions());
+ if (!desiredSubset->intersect(bounds)) {
+ return false;
+ }
+
+ // As stated below, libwebp snaps to even left and top. Make sure top and left are even, so we
+ // decode this exact subset.
+ // Leave right and bottom unmodified, so we suggest a slightly larger subset than requested.
+ desiredSubset->fLeft = (desiredSubset->fLeft >> 1) << 1;
+ desiredSubset->fTop = (desiredSubset->fTop >> 1) << 1;
+ return true;
+}
+
SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
- const Options&, SkPMColor*, int*) {
+ const Options& options, SkPMColor*, int*) {
switch (this->rewindIfNeeded()) {
case kCouldNotRewind_RewindState:
return kCouldNotRewind;
@@ -153,12 +171,48 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
// Free any memory associated with the buffer. Must be called last, so we declare it first.
SkAutoTCallVProc<WebPDecBuffer, WebPFreeDecBuffer> autoFree(&(config.output));
- SkISize dimensions = dstInfo.dimensions();
- if (this->getInfo().dimensions() != dimensions) {
+ SkIRect bounds = SkIRect::MakeSize(this->getInfo().dimensions());
+ if (options.fSubset) {
+ // Caller is requesting a subset.
+ if (!bounds.contains(*options.fSubset)) {
+ // The subset is out of bounds.
+ return kInvalidParameters;
+ }
+
+ bounds = *options.fSubset;
+
+ // This is tricky. libwebp snaps the top and left to even values. We could let libwebp
+ // do the snap, and return a subset which is a different one than requested. The problem
+ // with that approach is that the caller may try to stitch subsets together, and if we
+ // returned different subsets than requested, there would be artifacts at the boundaries.
+ // Instead, we report that we cannot support odd values for top and left..
+ if (!SkIsAlign2(bounds.fLeft) || !SkIsAlign2(bounds.fTop)) {
+ return kInvalidParameters;
+ }
+
+#ifdef SK_DEBUG
+ {
+ // Make a copy, since getValidSubset can change its input.
+ SkIRect subset(bounds);
+ // That said, getValidSubset should *not* change its input, in this case; otherwise
+ // getValidSubset does not match the actual subsets we can do.
+ SkASSERT(this->getValidSubset(&subset) && subset == bounds);
+ }
+#endif
+
+ config.options.use_cropping = 1;
+ config.options.crop_left = bounds.fLeft;
+ config.options.crop_top = bounds.fTop;
+ config.options.crop_width = bounds.width();
+ config.options.crop_height = bounds.height();
+ }
+
+ SkISize dstDimensions = dstInfo.dimensions();
+ if (bounds.size() != dstDimensions) {
// Caller is requesting scaling.
config.options.use_scaling = 1;
- config.options.scaled_width = dimensions.width();
- config.options.scaled_height = dimensions.height();
+ config.options.scaled_width = dstDimensions.width();
+ config.options.scaled_height = dstDimensions.height();
}
config.output.colorspace = webp_decode_mode(dstInfo.colorType(),
« no previous file with comments | « src/codec/SkWebpCodec.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698