aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/gif/SkGifImageReader.cpp
diff options
context:
space:
mode:
authorGravatar Chris Blume <cblume@google.com>2017-09-27 13:23:41 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-27 21:03:41 +0000
commit0b5e7d16c20f4c5b75377f6722fc1bb57e63e9f3 (patch)
treefd01f46315a9f1c8e6e89e5fc4bf137f096a8946 /third_party/gif/SkGifImageReader.cpp
parente56774602c115567d9a330c5918b7dcac9a10ae1 (diff)
Treat invalid indices as transparent in gifs
Other browsers (including old Chrome) treat invalid palette indices as transparent for gifs. And there are gifs in the wild which rely on this. As an example, if the palette only has 64 entries (0-63) then index 64 is treated as transparent. BUG=skia:7069 Change-Id: I15e8919a953387506c9ac5945c3ae6a2b90189ab Reviewed-on: https://skia-review.googlesource.com/51100 Reviewed-by: Leon Scroggins <scroggo@google.com> Commit-Queue: Chris Blume <cblume@google.com>
Diffstat (limited to 'third_party/gif/SkGifImageReader.cpp')
-rw-r--r--third_party/gif/SkGifImageReader.cpp41
1 files changed, 12 insertions, 29 deletions
diff --git a/third_party/gif/SkGifImageReader.cpp b/third_party/gif/SkGifImageReader.cpp
index 990da5618b..658e08348f 100644
--- a/third_party/gif/SkGifImageReader.cpp
+++ b/third_party/gif/SkGifImageReader.cpp
@@ -96,6 +96,16 @@ mailing address.
// Get a 16-bit value stored in little-endian format.
#define GETINT16(p) ((p)[1]<<8|(p)[0])
+namespace {
+ bool is_palette_index_valid(int transparentIndex) {
+ // -1 is a signal that there is no transparent index.
+ // Otherwise, it is encoded in 8 bits, and all 256 values are considered
+ // valid since a GIF may use an index outside of the palette to be
+ // transparent.
+ return transparentIndex >= 0;
+ }
+} // anonymous namespace
+
// Send the data to the display front-end.
void SkGIFLZWContext::outputRow(const unsigned char* rowBegin)
{
@@ -752,9 +762,7 @@ SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
if (currentFrameIsFirstFrame()) {
const int transPix = m_frames.empty() ? SkGIFColorMap::kNotFound
: m_frames[0]->transparentPixel();
- if (this->hasTransparency(transPix,
- isLocalColormapDefined, numColors))
- {
+ if (is_palette_index_valid(transPix)) {
m_firstFrameHasAlpha = true;
} else {
const bool frameIsSubset = xOffset > 0 || yOffset > 0
@@ -846,30 +854,6 @@ SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
}
}
-bool SkGifImageReader::hasTransparency(int transparentPixel, bool isLocalColormapDefined,
- int localColors) const {
- const int globalColors = m_globalColorMap.numColors();
- if (!isLocalColormapDefined && globalColors == 0) {
- // No color table for this frame, so it is completely transparent.
- return true;
- }
-
- if (transparentPixel < 0) {
- SkASSERT(SkGIFColorMap::kNotFound == transparentPixel);
- return false;
- }
-
- if (isLocalColormapDefined) {
- return transparentPixel < localColors;
- }
-
- // If there is a global color table, it will be parsed before reaching
- // here. If its numColors is set, it will be defined.
- SkASSERT(globalColors > 0);
- SkASSERT(m_globalColorMap.isDefined());
- return transparentPixel < globalColors;
-}
-
void SkGifImageReader::addFrameIfNecessary()
{
if (m_frames.empty() || m_frames.back()->isComplete()) {
@@ -899,8 +883,7 @@ bool SkGIFFrameContext::onReportsAlpha() const {
// Note: We could correct these after decoding - i.e. some frames may turn out to be
// independent and opaque if they do not use the transparent pixel, but that would require
// checking whether each pixel used the transparent index.
- return m_owner->hasTransparency(this->transparentPixel(),
- m_localColorMap.isDefined(), m_localColorMap.numColors());
+ return is_palette_index_valid(this->transparentPixel());
}
void SkFrameHolder::setAlphaAndRequiredFrame(SkFrame* frame) {