Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1288)

Unified Diff: Source/platform/image-decoders/gif/GIFImageReader.cpp

Issue 813943003: Fix handling of broken GIFs with weird frame sizes (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: nits Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/platform/image-decoders/gif/GIFImageReader.cpp
diff --git a/Source/platform/image-decoders/gif/GIFImageReader.cpp b/Source/platform/image-decoders/gif/GIFImageReader.cpp
index 42db80edb56dab57fb92fcea2f215a966c84b03b..a88ef58bbfd729168169a4fa3d3e3a121b67e852 100644
--- a/Source/platform/image-decoders/gif/GIFImageReader.cpp
+++ b/Source/platform/image-decoders/gif/GIFImageReader.cpp
@@ -437,14 +437,10 @@ bool GIFImageReader::parseData(size_t dataPosition, size_t len, GIFImageDecoder:
// This is the height and width of the "screen" or frame into which images are rendered. The
// individual images can be smaller than the screen size and located with an origin anywhere
// within the screen.
+ // Note that size is final only when the first frame is encountered.
m_screenWidth = GETINT16(currentComponent);
m_screenHeight = GETINT16(currentComponent + 2);
- // CALLBACK: Inform the decoderplugin of our size.
- // Note: A subsequent frame might have dimensions larger than the "screen" dimensions.
- if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight))
- return false;
-
const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07);
if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
@@ -632,29 +628,18 @@ bool GIFImageReader::parseData(size_t dataPosition, size_t len, GIFImageDecoder:
width = GETINT16(currentComponent + 4);
height = GETINT16(currentComponent + 6);
- /* Work around broken GIF files where the logical screen
- * size has weird width or height. We assume that GIF87a
- * files don't contain animations.
- */
+ // Work around broken GIF file where the first frame has size greater than the
Peter Kasting 2015/01/08 06:56:18 Nit: files I also wouldn't mind wrapping the comm
Alpha Left Google 2015/01/12 22:12:49 Done.
+ // "screen size".
Peter Kasting 2015/01/08 06:56:18 What about when subsequent frames have larger size
Alpha Left Google 2015/01/12 22:12:49 I added the std::max() code in 672 and 673 in the
if (currentFrameIsFirstFrame()
- && ((m_screenHeight < height) || (m_screenWidth < width) || (m_version == 87))) {
- m_screenHeight = height;
- m_screenWidth = width;
- xOffset = 0;
- yOffset = 0;
-
- // CALLBACK: Inform the decoderplugin of our size.
- if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight))
- return false;
+ && (m_screenHeight < yOffset + height || m_screenWidth < xOffset + width)) {
+ m_screenHeight = std::max(m_screenHeight, yOffset + height);
+ m_screenWidth = std::max(m_screenWidth, xOffset + width);
Peter Kasting 2015/01/08 06:56:18 This is a behavior change from the previous code i
Alpha Left Google 2015/01/12 22:12:49 The behavior changes unless the image is GIF87 and
}
- // Work around more broken GIF files that have zero image width or height
- if (!height || !width) {
- height = m_screenHeight;
- width = m_screenWidth;
- if (!height || !width)
- return false;
- }
+ // Inform the client of the final size.
+ if (!m_sizeFinal && m_client && !m_client->setSize(m_screenWidth, m_screenHeight))
Peter Kasting 2015/01/08 06:56:18 Is it possible to have m_client null here but have
Alpha Left Google 2015/01/12 22:12:49 m_client is always non null. We shouldn't need to
+ return false;
+ m_sizeFinal = true;
if (query == GIFImageDecoder::GIFSizeQuery) {
// The decoder needs to stop. Hand back the number of bytes we consumed from
@@ -668,9 +653,15 @@ bool GIFImageReader::parseData(size_t dataPosition, size_t len, GIFImageDecoder:
GIFFrameContext* currentFrame = m_frames.last().get();
currentFrame->setHeaderDefined();
+
+ // Work around more broken GIF files that have zero image width or height.
+ if (!height || !width) {
+ height = m_screenHeight;
+ width = m_screenWidth;
+ if (!height || !width)
+ return false;
+ }
currentFrame->setRect(xOffset, yOffset, width, height);
- m_screenWidth = std::max(m_screenWidth, width);
- m_screenHeight = std::max(m_screenHeight, height);
currentFrame->setInterlaced(currentComponent[8] & 0x40);
// Overlaying interlaced, transparent GIFs over

Powered by Google App Engine
This is Rietveld 408576698