From 2e483c130bc3db530caa4b7c4f25b9232464d592 Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Thu, 13 May 2010 15:31:02 -0400 Subject: don't use animated gifs if gifs only have one frame Gifs use a different decoding mechanism from other images. The default webkit implementation allocates a bitmap for the gif, which is serialized when the picture is flattened. A page with a 25K display list may flatten into a 20M file if GIFs are included as bitmaps. GIFs can be written like other image types, as streams; then the display list flattens to a 140K file. Currently, the Skia-based images only can handle non-animated types. When animated gifs was recently enabled, the flattened file size grew. All gifs were treated as if they could be animated, and all were decoded into bitmaps with straight memory allocations. This change uses the stream-allocation mechanism if the GIF has only one frame, and is therefore not animating. Change-Id: Ie2360bb6f20515b81bd62761ca97242f33ffb43b http://b/2650945 --- .../graphics/android/ImageSourceAndroid.cpp | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'WebCore') diff --git a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp index 06455d2..914a9d6 100644 --- a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp +++ b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp @@ -228,10 +228,15 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived) { #ifdef ANDROID_ANIMATED_GIF // This is only necessary if we allow ourselves to partially decode GIF + bool disabledAnimatedGif = false; if (m_decoder.m_gifDecoder && !m_decoder.m_gifDecoder->failed()) { m_decoder.m_gifDecoder->setData(data, allDataReceived); - return; + if (!allDataReceived || m_decoder.m_gifDecoder->frameCount() != 1) + return; + disabledAnimatedGif = true; + delete m_decoder.m_gifDecoder; + m_decoder.m_gifDecoder = 0; } #endif if (NULL == m_decoder.m_image @@ -258,17 +263,26 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived) // First, check to see if this is an animated GIF const Vector& buffer = data->buffer(); const char* contents = buffer.data(); - if (buffer.size() > 3 && strncmp(contents, "GIF8", 4) == 0 && - should_use_animated_gif(origW, origH)) { + if (buffer.size() > 3 && strncmp(contents, "GIF8", 4) == 0 + && should_use_animated_gif(origW, origH) + && !disabledAnimatedGif) { // This means we are looking at a GIF, so create special // GIF Decoder // Need to wait for all data received if we are assigning an // allocator (which we are not at the moment). if (!m_decoder.m_gifDecoder /*&& allDataReceived*/) m_decoder.m_gifDecoder = new GIFImageDecoder(); - if (!m_decoder.m_gifDecoder->failed()) + int frameCount = 0; + if (!m_decoder.m_gifDecoder->failed()) { m_decoder.m_gifDecoder->setData(data, allDataReceived); - return; + if (!allDataReceived) + return; + frameCount = m_decoder.m_gifDecoder->frameCount(); + } + if (frameCount != 1) + return; + delete m_decoder.m_gifDecoder; + m_decoder.m_gifDecoder = 0; } #endif -- cgit v1.1