diff options
author | Leon Scroggins III <scroggo@google.com> | 2018-05-08 09:35:32 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-08 20:41:04 +0000 |
commit | 8a8a1449526cce423d2e76fb69a8151f49135a5a (patch) | |
tree | f56195638549c0f21ba0330008726acd29bbc3c3 /src/core/SkStream.cpp | |
parent | 71a6995084bd493622f4c701db1bf82edb15e062 (diff) |
Treat SkFILEStream's fOriginalOffset as the start
Bug: b/78866720
::rewind() rewinds to fOriginalOffset
::seek(position) seeks to position + fOriginalOffset
::move(offset) will not move < fOriginalOffset
::getPosition() returns position relative to fOriginalOffset
::getLength() returns full size minus fOriginalOffset
::duplicate() and ::fork() pass on fOriginalOffset
Android may create an SkFILEStream using a file descriptor whose offset
is at the beginning of the data that Android cares about. Treat all
positions in SkFILEStream as relative to that original offset.
This allows AnimatedImageDrawable to read directly from the
SkFILEStream, rather than using an SkFrontBufferedStream and forcing
SkGifCodec to cache data for later use.
This fixes a TODO that was introduced in
https://skia-review.googlesource.com/c/skia/+/9498 and takes it a step
further. In that CL, bungeman@ and I discussed the change and decided to
"leave this alone for now to avoid changing behavior". Doing a code
search today, the only two callers want the new behavior.
Change-Id: I9211394d5b730adf528fac0df0af7a664b1295be
Reviewed-on: https://skia-review.googlesource.com/126511
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
Diffstat (limited to 'src/core/SkStream.cpp')
-rw-r--r-- | src/core/SkStream.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp index fef5aa8794..dfdc257ff6 100644 --- a/src/core/SkStream.cpp +++ b/src/core/SkStream.cpp @@ -10,9 +10,13 @@ #include "SkData.h" #include "SkFixed.h" #include "SkMakeUnique.h" +#include "SkSafeMath.h" #include "SkString.h" #include "SkOSFile.h" #include "SkTypes.h" +#include "SkTFitsIn.h" + +#include <limits> /////////////////////////////////////////////////////////////////////////////// @@ -209,27 +213,41 @@ bool SkFILEStream::isAtEnd() const { } bool SkFILEStream::rewind() { - // TODO: fOriginalOffset instead of 0. - fOffset = 0; + fOffset = fOriginalOffset; return true; } SkStreamAsset* SkFILEStream::onDuplicate() const { - // TODO: fOriginalOffset instead of 0. - return new SkFILEStream(fFILE, fSize, 0, fOriginalOffset); + return new SkFILEStream(fFILE, fSize, fOriginalOffset, fOriginalOffset); } size_t SkFILEStream::getPosition() const { - return fOffset; + SkASSERT(fOffset >= fOriginalOffset); + return fOffset - fOriginalOffset; } bool SkFILEStream::seek(size_t position) { - fOffset = position > fSize ? fSize : position; + fOffset = SkTMin(SkSafeMath::Add(position, fOriginalOffset), fSize); return true; } bool SkFILEStream::move(long offset) { - return this->seek(fOffset + offset); + if (offset < 0) { + if (offset == std::numeric_limits<long>::min() + || !SkTFitsIn<size_t>(-offset) + || (size_t) (-offset) >= this->getPosition()) { + fOffset = fOriginalOffset; + } else { + fOffset += offset; + } + } else if (!SkTFitsIn<size_t>(offset)) { + fOffset = fSize; + } else { + fOffset = SkTMin(SkSafeMath::Add(fOffset, (size_t) offset), fSize); + } + + SkASSERT(fOffset >= fOriginalOffset && fOffset <= fSize); + return true; } SkStreamAsset* SkFILEStream::onFork() const { @@ -237,7 +255,7 @@ SkStreamAsset* SkFILEStream::onFork() const { } size_t SkFILEStream::getLength() const { - return fSize; + return fSize - fOriginalOffset; } /////////////////////////////////////////////////////////////////////////////// |