aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Leon Scroggins III <scroggo@google.com>2018-01-14 14:46:51 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-16 20:36:09 +0000
commit42ee2845673c38f6d70f0d8ddf7e26dce8aa61d3 (patch)
tree623988f152fca794623e25458bf55212fe5b670d /src
parent23e0cf29639459fb8695bf8174d82ae47fd0d0bb (diff)
Use SkAndroidCodec in SkAnimatedImage
Bug: b/63909536 Bug: b/63908092 SkAnimatedImage is designed around a specific Android use case, so move it into the android folders. Make SkAnimatedImage hold an SkAndroidCodec (instead of an SkCodec). Expose fCodec so that SkAnimatedImage can animate by using the internal SkCodec. Update the sample to use SkAndroidCodec. Allow webp to decode a scaled down animation. For RestoreBG frames, adjust the frameRect (which is erased) to account for the scaling. Add a test to verify that we decode a webp with a RestoreBG frame successfully. Disable scaling for later frames in other formats (GIF, for now), since the code for erasing a RestoreBG frame is currently unaware of the sampling. Change-Id: I5dd2b86138f2c7f6adcd08dce1bd49040f7dc224 Reviewed-on: https://skia-review.googlesource.com/94621 Commit-Queue: Leon Scroggins <scroggo@google.com> Reviewed-by: Derek Sollenberger <djsollen@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/android/SkAnimatedImage.cpp (renamed from src/codec/SkAnimatedImage.cpp)16
-rw-r--r--src/codec/SkCodec.cpp28
-rw-r--r--src/codec/SkWebpCodec.cpp2
3 files changed, 35 insertions, 11 deletions
diff --git a/src/codec/SkAnimatedImage.cpp b/src/android/SkAnimatedImage.cpp
index dcb4bb93bf..25c020fde8 100644
--- a/src/codec/SkAnimatedImage.cpp
+++ b/src/android/SkAnimatedImage.cpp
@@ -5,12 +5,13 @@
* found in the LICENSE file.
*/
+#include "SkAndroidCodec.h"
#include "SkAnimatedImage.h"
#include "SkCanvas.h"
#include "SkCodec.h"
#include "SkCodecPriv.h"
-sk_sp<SkAnimatedImage> SkAnimatedImage::MakeFromCodec(std::unique_ptr<SkCodec> codec) {
+sk_sp<SkAnimatedImage> SkAnimatedImage::Make(std::unique_ptr<SkAndroidCodec> codec) {
if (!codec) {
return nullptr;
}
@@ -27,7 +28,7 @@ sk_sp<SkAnimatedImage> SkAnimatedImage::MakeFromCodec(std::unique_ptr<SkCodec> c
// Sentinel value for starting at the beginning.
static constexpr double kInit = -1.0;
-SkAnimatedImage::SkAnimatedImage(std::unique_ptr<SkCodec> codec)
+SkAnimatedImage::SkAnimatedImage(std::unique_ptr<SkAndroidCodec> codec)
: fCodec(std::move(codec))
, fFinished(false)
, fRunning(false)
@@ -93,7 +94,7 @@ double SkAnimatedImage::update(double msecs) {
fNowMS = msecs;
const double msSinceLastUpdate = fNowMS - lastUpdateMS;
- const int frameCount = fCodec->getFrameCount();
+ const int frameCount = fCodec->codec()->getFrameCount();
int frameToDecode = SkCodec::kNone;
if (kInit == msecs) {
frameToDecode = 0;
@@ -110,7 +111,7 @@ double SkAnimatedImage::update(double msecs) {
}
SkCodec::FrameInfo frameInfo;
- if (fCodec->getFrameInfo(frameToDecode, &frameInfo)) {
+ if (fCodec->codec()->getFrameInfo(frameToDecode, &frameInfo)) {
if (!frameInfo.fFullyReceived) {
SkCodecPrintf("Frame %i not fully received\n", frameToDecode);
fFinished = true;
@@ -126,7 +127,7 @@ double SkAnimatedImage::update(double msecs) {
SkCodecPrintf("Skipping frame %i\n", frameToDecode);
pastUpdate -= frameInfo.fDuration;
frameToDecode = (frameToDecode + 1) % frameCount;
- if (!fCodec->getFrameInfo(frameToDecode, &frameInfo)) {
+ if (!fCodec->codec()->getFrameInfo(frameToDecode, &frameInfo)) {
SkCodecPrintf("Could not getFrameInfo for frame %i",
frameToDecode);
// Prior call to getFrameInfo succeeded, so use that one.
@@ -222,9 +223,10 @@ double SkAnimatedImage::update(double msecs) {
}
}
- auto result = fCodec->getPixels(dst->info(), dst->getPixels(), dst->rowBytes(), &options);
+ auto result = fCodec->codec()->getPixels(dst->info(), dst->getPixels(), dst->rowBytes(),
+ &options);
if (result != SkCodec::kSuccess) {
- SkCodecPrintf("error %i, frame %i of %i\n", result, frameToDecode, fCodec->getFrameCount());
+ SkCodecPrintf("error %i, frame %i of %i\n", result, frameToDecode, frameCount);
// Reset to the beginning.
fActiveFrame.fIndex = SkCodec::kNone;
return 0.0;
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index d0fb43a053..b2902ca75f 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -237,8 +237,8 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
return kInvalidParameters;
}
- if (options.fSubset || info.dimensions() != fSrcInfo.dimensions()) {
- // If we add support for these, we need to update the code that zeroes
+ if (options.fSubset) {
+ // If we add support for this, we need to update the code that zeroes
// a kRestoreBGColor frame.
return kInvalidParameters;
}
@@ -275,7 +275,29 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
// If a frame after the required frame is provided, there is no
// need to clear, since it must be covered by the desired frame.
if (options.fPriorFrame == requiredFrame) {
- zero_rect(info, pixels, rowBytes, prevFrame->frameRect());
+ SkIRect prevRect = prevFrame->frameRect();
+ if (info.dimensions() != fSrcInfo.dimensions()) {
+ auto src = SkRect::Make(fSrcInfo.dimensions());
+ auto dst = SkRect::Make(info.dimensions());
+ SkMatrix map = SkMatrix::MakeRectToRect(src, dst,
+ SkMatrix::kCenter_ScaleToFit);
+ SkRect asRect = SkRect::Make(prevRect);
+ if (!map.mapRect(&asRect)) {
+ return kInternalError;
+ }
+ asRect.roundIn(&prevRect);
+ if (prevRect.isEmpty()) {
+ // Down-scaling shrank the empty portion to nothing,
+ // so nothing to zero.
+ break;
+ }
+ if (!prevRect.intersect(SkIRect::MakeSize(info.dimensions()))) {
+ SkCodecPrintf("rectangles do not intersect!");
+ SkASSERT(false);
+ break;
+ }
+ }
+ zero_rect(info, pixels, rowBytes, prevRect);
}
break;
default:
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index ca63349c0e..aa3547dca5 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -402,7 +402,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
SkASSERT(0 == index || index < fFrameHolder.size());
const auto& srcInfo = this->getInfo();
- SkASSERT(0 == index || (!options.fSubset && dstInfo.dimensions() == srcInfo.dimensions()));
+ SkASSERT(0 == index || !options.fSubset);
WebPDecoderConfig config;
if (0 == WebPInitDecoderConfig(&config)) {