aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/SkCodec.cpp63
1 files changed, 34 insertions, 29 deletions
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index bf12ad2625..d9992c0cd9 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -208,16 +208,37 @@ bool SkCodec::rewindIfNeeded() {
return this->onRewind();
}
-static void zero_rect(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
- SkIRect frameRect) {
- if (!frameRect.intersect(dstInfo.bounds())) {
- return;
+bool zero_rect(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
+ SkISize srcDimensions, SkIRect prevRect) {
+ const auto dimensions = dstInfo.dimensions();
+ if (dimensions != srcDimensions) {
+ SkRect src = SkRect::Make(srcDimensions);
+ SkRect dst = SkRect::Make(dimensions);
+ SkMatrix map = SkMatrix::MakeRectToRect(src, dst, SkMatrix::kCenter_ScaleToFit);
+ SkRect asRect = SkRect::Make(prevRect);
+ if (!map.mapRect(&asRect)) {
+ return false;
+ }
+ asRect.roundIn(&prevRect);
+ if (prevRect.isEmpty()) {
+ // Down-scaling shrank the empty portion to nothing,
+ // so nothing to zero.
+ return true;
+ }
}
- const auto info = dstInfo.makeWH(frameRect.width(), frameRect.height());
+
+ if (!prevRect.intersect(dstInfo.bounds())) {
+ SkCodecPrintf("rectangles do not intersect!");
+ SkASSERT(false);
+ return true;
+ }
+
+ const SkImageInfo info = dstInfo.makeWH(prevRect.width(), prevRect.height());
const size_t bpp = dstInfo.bytesPerPixel();
- const size_t offset = frameRect.x() * bpp + frameRect.y() * rowBytes;
- auto* eraseDst = SkTAddOffset<void>(pixels, offset);
+ const size_t offset = prevRect.x() * bpp + prevRect.y() * rowBytes;
+ void* eraseDst = SkTAddOffset<void>(pixels, offset);
SkSampler::Fill(info, eraseDst, rowBytes, 0, SkCodec::kNo_ZeroInitialized);
+ return true;
}
SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels, size_t rowBytes,
@@ -276,28 +297,9 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
// need to clear, since it must be covered by the desired frame.
if (options.fPriorFrame == requiredFrame) {
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;
- }
+ if (!zero_rect(info, pixels, rowBytes, fSrcInfo.dimensions(), prevRect)) {
+ return kInternalError;
}
- zero_rect(info, pixels, rowBytes, prevRect);
}
break;
default:
@@ -314,7 +316,10 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
const auto* prevFrame = frameHolder->getFrame(requiredFrame);
const auto disposalMethod = prevFrame->getDisposalMethod();
if (disposalMethod == SkCodecAnimation::DisposalMethod::kRestoreBGColor) {
- zero_rect(info, pixels, rowBytes, prevFrame->frameRect());
+ auto prevRect = prevFrame->frameRect();
+ if (!zero_rect(info, pixels, rowBytes, fSrcInfo.dimensions(), prevRect)) {
+ return kInternalError;
+ }
}
}
}