aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/gif/SkGifImageReader.h
diff options
context:
space:
mode:
authorGravatar Leon Scroggins III <scroggo@google.com>2016-12-16 11:39:51 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-19 15:25:13 +0000
commit932efed7c89c69616e283fdfef65e86b9d9da381 (patch)
treea757be369987a936d2163f5c746a8e1ff0e102fc /third_party/gif/SkGifImageReader.h
parent8e04286fa62d04767d39d820439fa4caf6223a46 (diff)
GIF: Avoid copying/storing data when possible
If the input SkStream has a length and position, do not copy and store LZW blocks or ColorMaps. Instead, mark the position and size, and read from the stream when necessary. This will save memory in Chromium's use case, which has already buffered all of its data. In the case where we *do* need to copy, store it on the SkStreamBuffer. This allows SkGifImageReader to have simpler code. Add tests. Change-Id: Ic65fa766328ae2e5974b2084bc2099e19aced731 Reviewed-on: https://skia-review.googlesource.com/6157 Reviewed-by: Matt Sarett <msarett@google.com> Commit-Queue: Leon Scroggins <scroggo@google.com>
Diffstat (limited to 'third_party/gif/SkGifImageReader.h')
-rw-r--r--third_party/gif/SkGifImageReader.h42
1 files changed, 29 insertions, 13 deletions
diff --git a/third_party/gif/SkGifImageReader.h b/third_party/gif/SkGifImageReader.h
index 2843a3538f..0481ba2908 100644
--- a/third_party/gif/SkGifImageReader.h
+++ b/third_party/gif/SkGifImageReader.h
@@ -137,37 +137,51 @@ private:
const SkGIFFrameContext* m_frameContext;
};
+struct SkGIFLZWBlock {
+ public:
+ SkGIFLZWBlock(size_t position, size_t size)
+ : blockPosition(position), blockSize(size) {}
+
+ const size_t blockPosition;
+ const size_t blockSize;
+};
+
class SkGIFColorMap final {
public:
SkGIFColorMap()
: m_isDefined(false)
+ , m_position(0)
, m_colors(0)
, m_packColorProc(nullptr)
{
}
void setNumColors(size_t colors) {
+ SkASSERT(!m_colors);
+ SkASSERT(!m_position);
+
m_colors = colors;
}
- size_t numColors() const { return m_colors; }
+ void setTablePosition(size_t position) {
+ SkASSERT(!m_isDefined);
- void setRawData(const char* data, size_t size)
- {
- // FIXME: Can we avoid this copy?
- m_rawData = SkData::MakeWithCopy(data, size);
- SkASSERT(m_colors * SK_BYTES_PER_COLORMAP_ENTRY == size);
+ m_position = position;
m_isDefined = true;
}
+
+ size_t numColors() const { return m_colors; }
+
bool isDefined() const { return m_isDefined; }
// Build RGBA table using the data stream.
- sk_sp<SkColorTable> buildTable(SkColorType dstColorType, size_t transparentPixel) const;
+ sk_sp<SkColorTable> buildTable(SkStreamBuffer*, SkColorType dstColorType,
+ size_t transparentPixel) const;
private:
bool m_isDefined;
+ size_t m_position;
size_t m_colors;
- sk_sp<SkData> m_rawData;
mutable PackColorProc m_packColorProc;
mutable sk_sp<SkColorTable> m_table;
};
@@ -201,12 +215,12 @@ public:
{
}
- void addLzwBlock(const void* data, size_t size)
+ void addLzwBlock(size_t position, size_t size)
{
- m_lzwBlocks.push_back(SkData::MakeWithCopy(data, size));
+ m_lzwBlocks.push_back(SkGIFLZWBlock(position, size));
}
- bool decode(SkGifCodec* client, bool* frameDecoded);
+ bool decode(SkStreamBuffer*, SkGifCodec* client, bool* frameDecoded);
int frameId() const { return m_frameId; }
void setRect(unsigned x, unsigned y, unsigned width, unsigned height)
@@ -266,7 +280,9 @@ private:
unsigned m_delayTime; // Display time, in milliseconds, for this image in a multi-image GIF.
std::unique_ptr<SkGIFLZWContext> m_lzwContext;
- std::vector<sk_sp<SkData>> m_lzwBlocks; // LZW blocks for this frame.
+ // LZW blocks for this frame.
+ std::vector<SkGIFLZWBlock> m_lzwBlocks;
+
SkGIFColorMap m_localColorMap;
size_t m_currentLzwBlock;
@@ -359,7 +375,7 @@ public:
}
// Return the color table for frame index (which may be the global color table).
- sk_sp<SkColorTable> getColorTable(SkColorType dstColorType, size_t index) const;
+ sk_sp<SkColorTable> getColorTable(SkColorType dstColorType, size_t index);
bool firstFrameHasAlpha() const { return m_firstFrameHasAlpha; }