Automated import from //branches/master/...@142337,142337
diff --git a/Android.mk b/Android.mk
index cc2b51f..ef65a62 100644
--- a/Android.mk
+++ b/Android.mk
@@ -121,6 +121,7 @@
 	$(LOCAL_PATH)/WebCore/platform/graphics \
 	$(LOCAL_PATH)/WebCore/platform/graphics/android \
 	$(LOCAL_PATH)/WebCore/platform/graphics/network \
+	$(LOCAL_PATH)/WebCore/platform/graphics/skia \
 	$(LOCAL_PATH)/WebCore/platform/graphics/transforms \
 	$(LOCAL_PATH)/WebCore/platform/image-decoders \
 	$(LOCAL_PATH)/WebCore/platform/network \
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index 5b0880e..7b909e3 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -651,6 +651,8 @@
 	\
 	platform/graphics/WidthIterator.cpp \
 	\
+	platform/graphics/skia/NativeImageSkia.cpp \
+	\
 	platform/graphics/transforms/MatrixTransformOperation.cpp \
 	platform/graphics/transforms/RotateTransformOperation.cpp \
 	platform/graphics/transforms/ScaleTransformOperation.cpp \
@@ -658,6 +660,10 @@
 	platform/graphics/transforms/TransformOperations.cpp \
 	platform/graphics/transforms/TransformationMatrix.cpp \
 	platform/graphics/transforms/TranslateTransformOperation.cpp \
+	\
+	platform/image-decoders/skia/GIFImageDecoder.cpp \
+	platform/image-decoders/skia/GIFImageReader.cpp \
+	\
 	platform/network/AuthenticationChallengeBase.cpp \
 	platform/network/Credential.cpp \
 	platform/network/FormData.cpp \
diff --git a/WebCore/WebCorePrefixAndroid.h b/WebCore/WebCorePrefixAndroid.h
index d69c122..e1f0650 100644
--- a/WebCore/WebCorePrefixAndroid.h
+++ b/WebCore/WebCorePrefixAndroid.h
@@ -162,3 +162,6 @@
 // needs additional flavor or parameter to know that it can't be ignored,
 // and/or script engine must keep whether event was user initiated.
 #define ANDROID_SCROLL_ON_GOTO_ANCHOR
+
+// Animated GIF support.
+#define ANDROID_ANIMATED_GIF
diff --git a/WebCore/platform/graphics/BitmapImage.cpp b/WebCore/platform/graphics/BitmapImage.cpp
index 45b32ab..68863df 100644
--- a/WebCore/platform/graphics/BitmapImage.cpp
+++ b/WebCore/platform/graphics/BitmapImage.cpp
@@ -262,6 +262,10 @@
 
 void BitmapImage::startAnimation(bool catchUpIfNecessary)
 {
+#ifdef ANDROID_ANIMATED_GIF
+    // We can't ever seem to keep up, so always let us just show the next frame
+    catchUpIfNecessary = false;
+#endif
     if (m_frameTimer || !shouldAnimate() || frameCount() <= 1)
         return;
 
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index 55e0c5a..07cc2c2 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -71,9 +71,15 @@
 typedef QPixmap* NativeImagePtr;
 #elif PLATFORM(SGL)
 class String;
+#ifdef ANDROID_ANIMATED_GIF
+class ImageDecoder;
+#endif
 struct NativeImageSourcePtr {
     SkString m_url; 
     PrivateAndroidImageSourceRec* m_image;
+#ifdef ANDROID_ANIMATED_GIF
+    ImageDecoder* m_gifDecoder;
+#endif
 };
 typedef const Vector<char>* NativeBytePtr;
 typedef SkBitmapRef* NativeImagePtr;
diff --git a/WebCore/platform/graphics/android/ImageAndroid.cpp b/WebCore/platform/graphics/android/ImageAndroid.cpp
index da52d67..3a3312f 100644
--- a/WebCore/platform/graphics/android/ImageAndroid.cpp
+++ b/WebCore/platform/graphics/android/ImageAndroid.cpp
@@ -67,8 +67,6 @@
     if (m_frame) {
         m_frame->unref();
         m_frame = 0;
-        m_duration = 0.;
-        m_hasAlpha = true;
         return true;
     }
     return false;
@@ -157,11 +155,16 @@
 void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
                        const FloatRect& srcRect, CompositeOperator compositeOp)
 {
+    if (!m_source.initialized())
+        return;
+
+    startAnimation();
+
     SkBitmapRef* image = this->nativeImageForCurrentFrame();
     if (!image) { // If it's too early we won't have an image yet.
         return;
     }
-    
+
     // in case we get called with an incomplete bitmap
     const SkBitmap& bitmap = image->bitmap();
     if (bitmap.getPixels() == NULL && bitmap.pixelRef() == NULL) {
@@ -172,12 +175,12 @@
 #endif
         return;
     }
-    
+
     SkIRect srcR;
     SkRect  dstR;    
     float invScaleX = (float)bitmap.width() / image->origWidth();
     float invScaleY = (float)bitmap.height() / image->origHeight();
-    
+
     android_setrect(&dstR, dstRect);
     android_setrect_scaled(&srcR, srcRect, invScaleX, invScaleY);
     if (srcR.isEmpty() || dstR.isEmpty()) {
@@ -188,16 +191,14 @@
 #endif
         return;
     }
-    
+
     SkCanvas*   canvas = ctxt->platformContext()->mCanvas;
     SkPaint     paint;
-    
+
     paint.setFilterBitmap(true);
     paint.setPorterDuffXfermode(android_convert_compositeOp(compositeOp));
     canvas->drawBitmapRect(bitmap, &srcR, dstR, &paint);
-    
-    startAnimation();
-    
+
 #ifdef TRACE_SUBSAMPLED_BITMAPS
     if (bitmap.width() != image->origWidth() ||
         bitmap.height() != image->origHeight()) {
diff --git a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
index 4bf8f8e..4c6a246 100644
--- a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
+++ b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
@@ -25,7 +25,6 @@
 
 #include "config.h"
 #include "BitmapAllocatorAndroid.h"
-#include "ImageDecoder.h"
 #include "ImageSource.h"
 #include "IntSize.h"
 #include "NotImplemented.h"
@@ -33,11 +32,18 @@
 #include "PlatformString.h"
 
 #include "SkBitmapRef.h"
-#include "SkImageRef.h"
 #include "SkImageDecoder.h"
+#include "SkImageRef.h"
 #include "SkStream.h"
 #include "SkTemplates.h"
 
+#ifdef ANDROID_ANIMATED_GIF
+    #include "EmojiFont.h"
+    #include "skia/GIFImageDecoder.h"
+
+    using namespace android;
+#endif
+
 SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src);
 
 //#define TRACE_SUBSAMPLE_BITMAPS
@@ -95,14 +101,24 @@
 
 ImageSource::ImageSource() {
     m_decoder.m_image = NULL;
+#ifdef ANDROID_ANIMATED_GIF
+    m_decoder.m_gifDecoder = 0;
+#endif
 }
 
 ImageSource::~ImageSource() {
     delete m_decoder.m_image;
+#ifdef ANDROID_ANIMATED_GIF
+    delete m_decoder.m_gifDecoder;
+#endif
 }
 
 bool ImageSource::initialized() const {
-    return m_decoder.m_image != NULL;
+    return
+#ifdef ANDROID_ANIMATED_GIF
+        m_decoder.m_gifDecoder ||
+#endif
+        m_decoder.m_image != NULL;
 }
 
 static int computeSampleSize(const SkBitmap& bitmap) {
@@ -164,11 +180,32 @@
     }
 }
 
+#ifdef ANDROID_ANIMATED_GIF
+// we only animate small GIFs for now, to save memory
+// also, we only support this in Japan, hence the Emoji check
+static bool should_use_animated_gif(int width, int height) {
+    return EmojiFont::IsAvailable() &&
+           width <= 32 && height <= 32;
+}
+#endif
+
 void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
 {
-    if (NULL == m_decoder.m_image) {
+#ifdef ANDROID_ANIMATED_GIF
+    // This is only necessary if we allow ourselves to partially decode GIF
+    if (m_decoder.m_gifDecoder
+            && !m_decoder.m_gifDecoder->failed()) {
+        m_decoder.m_gifDecoder->setData(data, allDataReceived);
+        return;
+    }
+#endif
+    if (NULL == m_decoder.m_image
+#ifdef ANDROID_ANIMATED_GIF
+          && !m_decoder.m_gifDecoder
+#endif
+                                            ) {
         SkBitmap tmp;
-        
+
         SkMemoryStream stream(data->data(), data->size(), false);
         SkImageDecoder* codec = SkImageDecoder::Factory(&stream);
         SkAutoTDelete<SkImageDecoder> ad(codec);
@@ -180,6 +217,25 @@
 
         int origW = tmp.width();
         int origH = tmp.height();
+
+#ifdef ANDROID_ANIMATED_GIF
+        // First, check to see if this is an animated GIF
+        const Vector<char>& buffer = data->buffer();
+        const char* contents = buffer.data();
+        if (buffer.size() > 3 && strncmp(contents, "GIF8", 4) == 0 &&
+                should_use_animated_gif(origW, origH)) {
+            // 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())
+                m_decoder.m_gifDecoder->setData(data, allDataReceived);
+            return;
+        }
+#endif
+        
         int sampleSize = computeSampleSize(tmp);
         if (sampleSize > 1) {
             codec->setSampleSize(sampleSize);
@@ -222,11 +278,20 @@
 
 bool ImageSource::isSizeAvailable()
 {
-    return m_decoder.m_image != NULL;
+    return
+#ifdef ANDROID_ANIMATED_GIF
+            (m_decoder.m_gifDecoder
+                    && m_decoder.m_gifDecoder->isSizeAvailable()) ||
+#endif
+            m_decoder.m_image != NULL;
 }
 
 IntSize ImageSource::size() const
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder)
+        return m_decoder.m_gifDecoder->size();
+#endif
     if (m_decoder.m_image) {
         return IntSize(m_decoder.m_image->origWidth(), m_decoder.m_image->origHeight());
     }
@@ -235,19 +300,40 @@
 
 int ImageSource::repetitionCount()
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder)
+        return m_decoder.m_gifDecoder->repetitionCount();
+    if (!m_decoder.m_image) return 0;
+#endif
     return 1;
     // A property with value 0 means loop forever.
 }
 
 size_t ImageSource::frameCount() const
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder) {
+        return m_decoder.m_gifDecoder->failed() ? 0
+                : m_decoder.m_gifDecoder->frameCount();
+    }
+#endif
     // i.e. 0 frames if we're not decoded, or 1 frame if we are
     return m_decoder.m_image != NULL;
 }
 
 SkBitmapRef* ImageSource::createFrameAtIndex(size_t index)
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder) {
+        RGBA32Buffer* buffer =
+                m_decoder.m_gifDecoder->frameBufferAtIndex(index);
+        if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
+            return 0;
+        return new SkBitmapRef(buffer->bitmap());
+    }
+#else
     SkASSERT(index == 0);
+#endif
     SkASSERT(m_decoder.m_image != NULL);
     m_decoder.m_image->ref();
     return m_decoder.m_image;
@@ -255,8 +341,18 @@
 
 float ImageSource::frameDurationAtIndex(size_t index)
 {
-    SkASSERT(index == 0);
     float duration = 0;
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder) {
+        RGBA32Buffer* buffer
+                = m_decoder.m_gifDecoder->frameBufferAtIndex(index);
+        if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
+            return 0;
+        duration = buffer->duration() / 1000.0f;
+    }
+#else
+    SkASSERT(index == 0);
+#endif
 
     // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
     // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
@@ -268,7 +364,21 @@
 
 bool ImageSource::frameHasAlphaAtIndex(size_t index)
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder) {
+        if (!m_decoder.m_gifDecoder->supportsAlpha())
+            return false;
+
+        RGBA32Buffer* buffer =
+                m_decoder.m_gifDecoder->frameBufferAtIndex(index);
+        if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
+            return false;
+
+        return buffer->hasAlpha();
+    }
+#else
     SkASSERT(0 == index);
+#endif
 
     if (NULL == m_decoder.m_image)
         return true;    // if we're not sure, assume the worse-case
@@ -285,12 +395,32 @@
 
 bool ImageSource::frameIsCompleteAtIndex(size_t index)
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder) {
+        RGBA32Buffer* buffer =
+                m_decoder.m_gifDecoder->frameBufferAtIndex(index);
+        return buffer && buffer->status() == RGBA32Buffer::FrameComplete;
+    }
+#else
     SkASSERT(0 == index);
+#endif
 	return m_decoder.m_image && m_decoder.m_image->fAllDataReceived;
 }
 
 void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
 {
+#ifdef ANDROID_ANIMATED_GIF
+    if (!destroyAll) {
+        if (m_decoder.m_gifDecoder)
+            m_decoder.m_gifDecoder->clearFrameBufferCache(clearBeforeFrame);
+        return;
+    }
+    
+    delete m_decoder.m_gifDecoder;
+    m_decoder.m_gifDecoder = 0;
+    if (data)
+        setData(data, allDataReceived);
+#endif
     // do nothing, since the cache is managed elsewhere
 }
 
@@ -303,6 +433,10 @@
 String ImageSource::filenameExtension() const
 {
     // FIXME: need to add virtual to our decoders to return "jpg/png/gif/..."
+#ifdef ANDROID_ANIMATED_GIF
+    if (m_decoder.m_gifDecoder)
+        return m_decoder.m_gifDecoder->filenameExtension();
+#endif
     return String();
 }
 
diff --git a/WebCore/platform/graphics/skia/NativeImageSkia.cpp b/WebCore/platform/graphics/skia/NativeImageSkia.cpp
index e59d1e2..477be05 100644
--- a/WebCore/platform/graphics/skia/NativeImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/NativeImageSkia.cpp
@@ -30,7 +30,9 @@
 
 #include "config.h"
 
+#if PLATFORM(SKIA)
 #include "skia/ext/image_operations.h"
+#endif
 
 #include "NativeImageSkia.h"
 #include "SkiaUtils.h"
@@ -63,9 +65,10 @@
 
 SkBitmap NativeImageSkia::resizedBitmap(int w, int h) const
 {
+#if PLATFORM(SKIA)
     if (m_resizedImage.width() != w || m_resizedImage.height() != h)
         m_resizedImage = skia::ImageOperations::Resize(*this, skia::ImageOperations::RESIZE_LANCZOS3, w, h);
-
+#endif
     return m_resizedImage;
 }
 
diff --git a/WebCore/platform/image-decoders/skia/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/skia/GIFImageDecoder.cpp
index 38bfa97..2d77943 100644
--- a/WebCore/platform/image-decoders/skia/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/skia/GIFImageDecoder.cpp
@@ -193,6 +193,7 @@
     // can be asked to clear more frames than we currently have.
     if (m_frameBufferCache.isEmpty())
         return; // Nothing to do.
+
     // The "-1" here is tricky.  It does not mean that |clearBeforeFrame| is the
     // last frame we wish to preserve, but rather that we never want to clear
     // the very last frame in the cache: it's empty (so clearing it is
@@ -203,21 +204,36 @@
     // this case.
     clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1);
     const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);
-    for (Vector<RGBA32Buffer>::iterator i(m_frameBufferCache.begin()); i != end; ++i) {
-        if (i->status() == RGBA32Buffer::FrameEmpty)
-            continue; // Nothing to do.
 
-        // The layout of frames is:
-        // [empty frames][complete frames][partial frame][empty frames]
-        // ...where each of these groups may be empty.  We should not clear a
-        // partial frame since that's what's being decoded right now, and we
-        // also should not clear the last complete frame, since it may be needed
-        // when constructing the next frame.  Note that "i + 1" is safe since
-        // i < end < m_frameBufferCache.end().
-        if ((i->status() == RGBA32Buffer::FramePartial) || ((i + 1)->status() != RGBA32Buffer::FrameComplete))
-            break;
+    // We need to preserve frames such that:
+    //   * We don't clear |end|
+    //   * We don't clear the frame we're currently decoding
+    //   * We don't clear any frame from which a future initFrameBuffer() call
+    //     will copy bitmap data
+    // All other frames can be cleared.  Because of the constraints on when
+    // ImageSource::clear() can be called (see ImageSource.h), we're guaranteed
+    // not to have non-empty frames after the frame we're currently decoding.
+    // So, scan backwards from |end| as follows:
+    //   * If the frame is empty, we're still past any frames we care about.
+    //   * If the frame is complete, but is DisposeOverwritePrevious, we'll
+    //     skip over it in future initFrameBuffer() calls.  We can clear it
+    //     unless it's |end|, and keep scanning.  For any other disposal method,
+    //     stop scanning, as we've found the frame initFrameBuffer() will need
+    //     next.
+    //   * If the frame is partial, we're decoding it, so don't clear it; if it
+    //     has a disposal method other than DisposeOverwritePrevious, stop
+    //     scanning, as we'll only need this frame when decoding the next one.
+    Vector<RGBA32Buffer>::iterator i(end);
+    for (; (i != m_frameBufferCache.begin()) && ((i->status() == RGBA32Buffer::FrameEmpty) || (i->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) {
+        if ((i->status() == RGBA32Buffer::FrameComplete) && (i != end))
+            i->clear();
+    }
 
-        i->clear();
+    // Now |i| holds the last frame we need to preserve; clear prior frames.
+    for (Vector<RGBA32Buffer>::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
+        ASSERT(j->status() != RGBA32Buffer::FramePartial);
+        if (j->status() != RGBA32Buffer::FrameEmpty)
+            j->clear();
     }
 }
 
@@ -278,7 +294,6 @@
         // first frame specifies this method, it will get treated like
         // DisposeOverwriteBgcolor below and reset to a completely empty image.)
         const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
-        ASSERT(prevBuffer->status() == RGBA32Buffer::FrameComplete);
         RGBA32Buffer::FrameDisposalMethod prevMethod =
             prevBuffer->disposalMethod();
         while ((frameIndex > 0)
@@ -286,6 +301,7 @@
             prevBuffer = &m_frameBufferCache[--frameIndex];
             prevMethod = prevBuffer->disposalMethod();
         }
+        ASSERT(prevBuffer->status() == RGBA32Buffer::FrameComplete);
 
         if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) ||
                 (prevMethod == RGBA32Buffer::DisposeKeep)) {
@@ -310,6 +326,9 @@
               // Unnecessary (but safe); see comments on the similar call above.
               buffer->setHasAlpha(prevBuffer->hasAlpha());
               SkBitmap& bitmap = buffer->bitmap();
+#ifdef ANDROID_ANIMATED_GIF
+              SkAutoLockPixels alp(bitmap);
+#endif
               for (int y = prevRect.y(); y < prevRect.bottom(); ++y) {
                   for (int x = prevRect.x(); x < prevRect.right(); ++x)
                       buffer->setRGBA(bitmap.getAddr32(x, y), 0, 0, 0, 0);
@@ -361,6 +380,10 @@
     if (!colorMap)
         return;
 
+#ifdef ANDROID_ANIMATED_GIF
+    // Lock the pixels properly.  Should be submitted back to webkit.
+    SkAutoLockPixels alp(buffer.bitmap());
+#endif
     // The buffers that we draw are the entire image's width and height, so a final output frame is
     // width * height RGBA32 values in size.
     //
diff --git a/WebCore/platform/image-decoders/skia/ImageDecoder.h b/WebCore/platform/image-decoders/skia/ImageDecoder.h
index 9988a3e..b983315 100644
--- a/WebCore/platform/image-decoders/skia/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/skia/ImageDecoder.h
@@ -39,6 +39,9 @@
 #include <wtf/Vector.h>
 
 #include "SkBitmap.h"
+#ifdef ANDROID_ANIMATED_GIF
+#include "SkColor.h"
+#endif
 
 namespace WebCore {
 
@@ -169,7 +172,7 @@
             bmp.setConfig(SkBitmap::kARGB_8888_Config, width, height);
             if (!bmp.allocPixels())
                 return false;  // Allocation failure, maybe the bitmap was too big.
-
+                
             // Clear the image.
             bmp.eraseARGB(0, 0, 0, 0);
 
@@ -199,6 +202,10 @@
         static void setRGBA(uint32_t* dest, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
         {
             // We store this data pre-multiplied.
+#ifdef ANDROID_ANIMATED_GIF
+            // Chrome should take this change as well.
+            *dest = SkPreMultiplyARGB(a, r, g, b);
+#else
             if (a == 0)
                 *dest = 0;
             else {
@@ -210,6 +217,7 @@
                 }
                 *dest = (a << 24 | r << 16 | g << 8 | b);
             }
+#endif
         }
 
         void setRGBA(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a)