diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..139810c
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,109 @@
+MPL-1.1 / GPL-2.0 / LGPL-2.1
+============================
+
+SkGifImageReader.cpp and SkGifImageReader.h:
+
+    ***** BEGIN LICENSE BLOCK *****
+    Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+    The contents of this file are subject to the Mozilla Public License Version
+    1.1 (the "License"); you may not use this file except in compliance with
+    the License. You may obtain a copy of the License at
+    http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS IS" basis,
+    WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+    for the specific language governing rights and limitations under the
+    License.
+
+    The Original Code is mozilla.org code.
+
+    The Initial Developer of the Original Code is
+    Netscape Communications Corporation.
+    Portions created by the Initial Developer are Copyright (C) 1998
+    the Initial Developer. All Rights Reserved.
+
+    Contributor(s):
+      Chris Saari <saari@netscape.com>
+      Apple Computer
+
+    Alternatively, the contents of this file may be used under the terms of
+    either the GNU General Public License Version 2 or later (the "GPL"), or
+    the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+    in which case the provisions of the GPL or the LGPL are applicable instead
+    of those above. If you wish to allow use of your version of this file only
+    under the terms of either the GPL or the LGPL, and not to allow others to
+    use your version of this file under the terms of the MPL, indicate your
+    decision by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL or the LGPL. If you do not delete
+    the provisions above, a recipient may use your version of this file under
+    the terms of any one of the MPL, the GPL or the LGPL.
+
+    ***** END LICENSE BLOCK ***** */
+
+
+BSD-3-Clause
+============
+
+libgifcodec.gni, SkGifCodec.h, SkLibGifCodec.cpp, SkLibGifCodec.h:
+
+    Copyright (c) 2011 Google Inc. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are
+    met:
+
+      * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+      * Redistributions in binary form must reproduce the above
+        copyright notice, this list of conditions and the following
+        disclaimer in the documentation and/or other materials provided
+        with the distribution.
+
+      * Neither the name of Google Inc. nor the names of its
+        contributors may be used to endorse or promote products derived
+        from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+BSD-2-Clause
+============
+
+SkLibGifCodec.cpp:
+
+    Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+    OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0acefc6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+LIBGIF CODEC FOR SKIA
+=====================
+
+libgifcodec is based on a fork of libgif made by Chromium.  It was copied into
+Skia with <https://codereview.chromium.org/2045293002>, as
+<https://skia.googlesource.com/skia/+/19b91531e912283d237435d94516575b28713cba>.
+
+The header file `SkGifCodec.h` exposes two functions:
+
+  * `bool SkGifCodec::IsGif(const void*, size_t);`
+
+  * `std::unique_ptr<SkCodec> SkGifCodec::MakeFromStream(std::unique_ptr<SkStream>, SkCodec::Result*);`
+
+Which can be used by Skia's `SkCodec::MakeFromStream` to implement GIF Decoding.
+
+See [`LICENSE.md`](LICENSE.md) for the license information.
diff --git a/SkGifCodec.h b/SkGifCodec.h
new file mode 100644
index 0000000..532e7b1
--- /dev/null
+++ b/SkGifCodec.h
@@ -0,0 +1,20 @@
+// Copyright 2019 Google LLC.
+// Use of this source code is governed by the BSD-3-Clause license that can be
+// found in the LICENSE.md file.
+
+#ifndef SkGifCodec_DEFINED
+#define SkGifCodec_DEFINED
+
+#include "include/codec/SkCodec.h"
+
+namespace SkGifCodec {
+
+// Returns true if the span of bytes appears to be GIF encoded data.
+bool IsGif(const void*, size_t);
+
+// Assumes IsGif was called and returned true.
+// Reads enough of the stream to determine the image format.
+std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, SkCodec::Result*);
+
+}  // namespace SkGifCodec
+#endif  // SkGifCodec_DEFINED
diff --git a/SkGifImageReader.cpp b/SkGifImageReader.cpp
new file mode 100644
index 0000000..da9119a
--- /dev/null
+++ b/SkGifImageReader.cpp
@@ -0,0 +1,958 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Saari <saari@netscape.com>
+ *   Apple Computer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+The Graphics Interchange Format(c) is the copyright property of CompuServe
+Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
+enhance, alter, modify or change in any way the definition of the format.
+
+CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
+license for the use of the Graphics Interchange Format(sm) in computer
+software; computer software utilizing GIF(sm) must acknowledge ownership of the
+Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
+User and Technical Documentation. Computer software utilizing GIF, which is
+distributed or may be distributed without User or Technical Documentation must
+display to the screen or printer a message acknowledging ownership of the
+Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
+this case, the acknowledgement may be displayed in an opening screen or leading
+banner, or a closing screen or trailing banner. A message such as the following
+may be used:
+
+    "The Graphics Interchange Format(c) is the Copyright property of
+    CompuServe Incorporated. GIF(sm) is a Service Mark property of
+    CompuServe Incorporated."
+
+For further information, please contact :
+
+    CompuServe Incorporated
+    Graphics Technology Department
+    5000 Arlington Center Boulevard
+    Columbus, Ohio  43220
+    U. S. A.
+
+CompuServe Incorporated maintains a mailing list with all those individuals and
+organizations who wish to receive copies of this document when it is corrected
+or revised. This service is offered free of charge; please provide us with your
+mailing address.
+*/
+
+#include "SkGifImageReader.h"
+#include "SkLibGifCodec.h"
+
+#include "include/core/SkColorPriv.h"
+
+#include <algorithm>
+#include <string.h>
+
+
+// GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's'.
+//
+// Note, the hold will never need to be bigger than 256 bytes to gather up in the hold,
+// as each GIF block (except colormaps) can never be bigger than 256 bytes.
+// Colormaps are directly copied in the resp. global_colormap or dynamically allocated local_colormap.
+// So a fixed buffer in SkGifImageReader is good enough.
+// This buffer is only needed to copy left-over data from one GifWrite call to the next
+#define GETN(n, s) \
+    do { \
+        m_bytesToConsume = (n); \
+        m_state = (s); \
+    } while (0)
+
+// 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)
+{
+    int drowStart = irow;
+    int drowEnd = irow;
+
+    // Haeberli-inspired hack for interlaced GIFs: Replicate lines while
+    // displaying to diminish the "venetian-blind" effect as the image is
+    // loaded. Adjust pixel vertical positions to avoid the appearance of the
+    // image crawling up the screen as successive passes are drawn.
+    if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass < 4) {
+        unsigned rowDup = 0;
+        unsigned rowShift = 0;
+
+        switch (ipass) {
+        case 1:
+            rowDup = 7;
+            rowShift = 3;
+            break;
+        case 2:
+            rowDup = 3;
+            rowShift = 1;
+            break;
+        case 3:
+            rowDup = 1;
+            rowShift = 0;
+            break;
+        default:
+            break;
+        }
+
+        drowStart -= rowShift;
+        drowEnd = drowStart + rowDup;
+
+        // Extend if bottom edge isn't covered because of the shift upward.
+        if ((unsigned)((m_frameContext->height() - 1) - drowEnd) <= rowShift)
+            drowEnd = m_frameContext->height() - 1;
+
+        // Clamp first and last rows to upper and lower edge of image.
+        if (drowStart < 0)
+            drowStart = 0;
+
+        if (drowEnd >= m_frameContext->height())
+            drowEnd = m_frameContext->height() - 1;
+    }
+
+    // Protect against too much image data.
+    if (drowStart >= m_frameContext->height())
+        return;
+
+    // CALLBACK: Let the client know we have decoded a row.
+    const bool writeTransparentPixels =
+            SkCodec::kNoFrame == m_frameContext->getRequiredFrame();
+    m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin,
+            drowStart, drowEnd - drowStart + 1, writeTransparentPixels);
+
+    if (!m_frameContext->interlaced())
+        irow++;
+    else {
+        do {
+            switch (ipass) {
+            case 1:
+                irow += 8;
+                if (irow >= (unsigned) m_frameContext->height()) {
+                    ipass++;
+                    irow = 4;
+                }
+                break;
+
+            case 2:
+                irow += 8;
+                if (irow >= (unsigned) m_frameContext->height()) {
+                    ipass++;
+                    irow = 2;
+                }
+                break;
+
+            case 3:
+                irow += 4;
+                if (irow >= (unsigned) m_frameContext->height()) {
+                    ipass++;
+                    irow = 1;
+                }
+                break;
+
+            case 4:
+                irow += 2;
+                if (irow >= (unsigned) m_frameContext->height()) {
+                    ipass++;
+                    irow = 0;
+                }
+                break;
+
+            default:
+                break;
+            }
+        } while (irow > (unsigned) (m_frameContext->height() - 1));
+    }
+}
+
+// Perform Lempel-Ziv-Welch decoding.
+// Returns true if decoding was successful. In this case the block will have been completely consumed and/or rowsRemaining will be 0.
+// Otherwise, decoding failed; returns false in this case, which will always cause the SkGifImageReader to set the "decode failed" flag.
+bool SkGIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
+{
+    if (rowIter == rowBuffer.end())
+        return true;
+    const int width = m_frameContext->width();
+
+    for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) {
+        // Feed the next byte into the decoder's 32-bit input buffer.
+        datum += ((int) *ch) << bits;
+        bits += 8;
+
+        // Check for underflow of decoder's 32-bit input buffer.
+        while (bits >= codesize) {
+            // Get the leading variable-length symbol from the data stream.
+            int code = datum & codemask;
+            datum >>= codesize;
+            bits -= codesize;
+
+            // Reset the dictionary to its original state, if requested.
+            if (code == clearCode) {
+                codesize = m_frameContext->dataSize() + 1;
+                codemask = (1 << codesize) - 1;
+                avail = clearCode + 2;
+                oldcode = -1;
+                continue;
+            }
+
+            // Check for explicit end-of-stream code.
+            if (code == (clearCode + 1)) {
+                // end-of-stream should only appear after all image data.
+                if (!rowsRemaining)
+                    return true;
+                return false;
+            }
+
+            const int tempCode = code;
+            if (code > avail) {
+                // This is an invalid code. The dictionary is just initialized
+                // and the code is incomplete. We don't know how to handle
+                // this case.
+                return false;
+            }
+
+            if (code == avail) {
+                if (oldcode != -1) {
+                    // This is a new code just being added to the dictionary.
+                    // It must encode the contents of the previous code, plus
+                    // the first character of the previous code again.
+                    // Now we know avail is the new code we can use oldcode
+                    // value to get the code related to that.
+                    code = oldcode;
+                } else {
+                    // This is an invalid code. The dictionary is just initialized
+                    // and the code is incomplete. We don't know how to handle
+                    // this case.
+                    return false;
+                }
+            }
+
+            // code length of the oldcode for new code which is
+            // avail = oldcode + firstchar of the oldcode
+            int remaining = suffixLength[code];
+
+            // Round remaining up to multiple of SK_DICTIONARY_WORD_SIZE, because that's
+            // the granularity of the chunks we copy.  The last chunk may contain
+            // some garbage but it'll be overwritten by the next code or left unused.
+            // The working buffer is padded to account for this.
+            remaining += -remaining & (SK_DICTIONARY_WORD_SIZE - 1) ;
+            unsigned char* p = rowIter + remaining;
+
+            // Place rowIter so that after writing pixels rowIter can be set to firstchar, thereby
+            // completing the code.
+            rowIter += suffixLength[code];
+
+            while (remaining > 0) {
+                p -= SK_DICTIONARY_WORD_SIZE;
+                std::copy_n(suffix[code].begin(), SK_DICTIONARY_WORD_SIZE, p);
+                code = prefix[code];
+                remaining -= SK_DICTIONARY_WORD_SIZE;
+            }
+            const int firstchar = static_cast<unsigned char>(code);  // (strictly `suffix[code][0]`)
+
+            // This completes the new code avail and writing the corresponding
+            // pixels on target.
+            if (tempCode == avail) {
+                *rowIter++ = firstchar;
+            }
+
+            // Define a new codeword in the dictionary as long as we've read
+            // more than one value from the stream.
+            if (avail < SK_MAX_DICTIONARY_ENTRIES && oldcode != -1) {
+                // now add avail to the dictionary for future reference
+                unsigned short codeLength = suffixLength[oldcode] + 1;
+                int l = (codeLength - 1) & (SK_DICTIONARY_WORD_SIZE - 1);
+                // If the suffix buffer is full (l == 0) then oldcode becomes the new
+                // prefix, otherwise copy and extend oldcode's buffer and use the same
+                // prefix as oldcode used.
+                prefix[avail] = (l == 0) ? oldcode : prefix[oldcode];
+                suffix[avail] = suffix[oldcode];
+                suffix[avail][l] = firstchar;
+                suffixLength[avail] = codeLength;
+                ++avail;
+
+                // If we've used up all the codewords of a given length
+                // increase the length of codewords by one bit, but don't
+                // exceed the specified maximum codeword size.
+                if (!(avail & codemask) && avail < SK_MAX_DICTIONARY_ENTRIES) {
+                    ++codesize;
+                    codemask += avail;
+                }
+            }
+            oldcode = tempCode;
+
+            // Output as many rows as possible.
+            unsigned char* rowBegin = rowBuffer.begin();
+            for (; rowBegin + width <= rowIter; rowBegin += width) {
+                outputRow(rowBegin);
+                rowsRemaining--;
+                if (!rowsRemaining)
+                    return true;
+            }
+
+            if (rowBegin != rowBuffer.begin()) {
+                // Move the remaining bytes to the beginning of the buffer.
+                const size_t bytesToCopy = rowIter - rowBegin;
+                memcpy(&rowBuffer.front(), rowBegin, bytesToCopy);
+                rowIter = rowBuffer.begin() + bytesToCopy;
+            }
+        }
+    }
+    return true;
+}
+
+sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkColorType colorType,
+                                              int transparentPixel) const
+{
+    if (!m_isDefined)
+        return nullptr;
+
+    const PackColorProc proc = choose_pack_color_proc(false, colorType);
+    if (m_table && proc == m_packColorProc && m_transPixel == transparentPixel) {
+        SkASSERT(transparentPixel == kNotFound || transparentPixel > m_table->count()
+                || m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT);
+        // This SkColorTable has already been built with the same transparent color and
+        // packing proc. Reuse it.
+        return m_table;
+    }
+    m_packColorProc = proc;
+    m_transPixel = transparentPixel;
+
+    const size_t bytes = m_colors * SK_BYTES_PER_COLORMAP_ENTRY;
+    sk_sp<SkData> rawData(streamBuffer->getDataAtPosition(m_position, bytes));
+    if (!rawData) {
+        return nullptr;
+    }
+
+    SkASSERT(m_colors <= SK_MAX_COLORS);
+    const uint8_t* srcColormap = rawData->bytes();
+    SkPMColor colorStorage[SK_MAX_COLORS];
+    for (int i = 0; i < m_colors; i++) {
+        if (i == transparentPixel) {
+            colorStorage[i] = SK_ColorTRANSPARENT;
+        } else {
+            colorStorage[i] = proc(255, srcColormap[0], srcColormap[1], srcColormap[2]);
+        }
+        srcColormap += SK_BYTES_PER_COLORMAP_ENTRY;
+    }
+    for (int i = m_colors; i < SK_MAX_COLORS; i++) {
+        colorStorage[i] = SK_ColorTRANSPARENT;
+    }
+    m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, SK_MAX_COLORS));
+    return m_table;
+}
+
+sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, int index) {
+    if (index < 0 || index >= m_frames.count()) {
+        return nullptr;
+    }
+
+    const SkGIFFrameContext* frameContext = m_frames[index].get();
+    const SkGIFColorMap& localColorMap = frameContext->localColorMap();
+    const int transPix = frameContext->transparentPixel();
+    if (localColorMap.isDefined()) {
+        return localColorMap.buildTable(&m_streamBuffer, colorType, transPix);
+    }
+    if (m_globalColorMap.isDefined()) {
+        return m_globalColorMap.buildTable(&m_streamBuffer, colorType, transPix);
+    }
+    return nullptr;
+}
+
+// Perform decoding for this frame. frameComplete will be true if the entire frame is decoded.
+// Returns false if a decoding error occurred. This is a fatal error and causes the SkGifImageReader to set the "decode failed" flag.
+// Otherwise, either not enough data is available to decode further than before, or the new data has been decoded successfully; returns true in this case.
+bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkLibGifCodec* client,
+                               bool* frameComplete)
+{
+    *frameComplete = false;
+    if (!m_lzwContext) {
+        // Wait for more data to properly initialize SkGIFLZWContext.
+        if (!isDataSizeDefined() || !isHeaderDefined())
+            return true;
+
+        m_lzwContext.reset(new SkGIFLZWContext(client, this));
+        if (!m_lzwContext->prepareToDecode()) {
+            m_lzwContext.reset();
+            return false;
+        }
+
+        m_currentLzwBlock = 0;
+    }
+
+    // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
+    while (m_currentLzwBlock < m_lzwBlocks.count() && m_lzwContext->hasRemainingRows()) {
+        const auto& block = m_lzwBlocks[m_currentLzwBlock];
+        const size_t len = block.blockSize;
+
+        sk_sp<SkData> data(streamBuffer->getDataAtPosition(block.blockPosition, len));
+        if (!data) {
+            return false;
+        }
+        if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(data->data()), len)) {
+            return false;
+        }
+        ++m_currentLzwBlock;
+    }
+
+    // If this frame is data complete then the previous loop must have completely decoded all LZW blocks.
+    // There will be no more decoding for this frame so it's time to cleanup.
+    if (isComplete()) {
+        *frameComplete = true;
+        m_lzwContext.reset();
+    }
+    return true;
+}
+
+// Decode a frame.
+// This method uses SkGIFFrameContext:decode() to decode the frame; decoding error is reported to client as a critical failure.
+// Return true if decoding has progressed. Return false if an error has occurred.
+bool SkGifImageReader::decode(int frameIndex, bool* frameComplete)
+{
+    SkGIFFrameContext* currentFrame = m_frames[frameIndex].get();
+
+    return currentFrame->decode(&m_streamBuffer, m_client, frameComplete);
+}
+
+// Parse incoming GIF data stream into internal data structures.
+SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
+{
+    if (m_parseCompleted) {
+        return SkCodec::kSuccess;
+    }
+
+    if (SkGIFLoopCountQuery == query && m_loopCount != cLoopCountNotSeen) {
+        // Loop count has already been parsed.
+        return SkCodec::kSuccess;
+    }
+
+    // SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only meaningful when >= 0.
+    const int lastFrameToParse = (int) query;
+    if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse
+                && m_frames[lastFrameToParse]->isComplete()) {
+        // We have already parsed this frame.
+        return SkCodec::kSuccess;
+    }
+
+    while (true) {
+        if (!m_streamBuffer.buffer(m_bytesToConsume)) {
+            // The stream does not yet have enough data.
+            return SkCodec::kIncompleteInput;
+        }
+
+        switch (m_state) {
+        case SkGIFLZW: {
+            SkASSERT(!m_frames.empty());
+            auto* frame = m_frames.back().get();
+            frame->addLzwBlock(m_streamBuffer.markPosition(), m_bytesToConsume);
+            GETN(1, SkGIFSubBlock);
+            break;
+        }
+        case SkGIFLZWStart: {
+            SkASSERT(!m_frames.empty());
+            auto* currentFrame = m_frames.back().get();
+
+            currentFrame->setDataSize(this->getOneByte());
+            GETN(1, SkGIFSubBlock);
+            break;
+        }
+
+        case SkGIFType: {
+            const char* currentComponent = m_streamBuffer.get();
+
+            // All GIF files begin with "GIF87a" or "GIF89a".
+            if (!memcmp(currentComponent, "GIF89a", 6))
+                m_version = 89;
+            else if (!memcmp(currentComponent, "GIF87a", 6))
+                m_version = 87;
+            else {
+                // This prevents attempting to continue reading this invalid stream.
+                GETN(0, SkGIFDone);
+                return SkCodec::kInvalidInput;
+            }
+            GETN(7, SkGIFGlobalHeader);
+            break;
+        }
+
+        case SkGIFGlobalHeader: {
+            const unsigned char* currentComponent =
+                reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
+
+            // 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 we don't inform the client of the size yet, as it might
+            // change after we read the first frame's image header.
+            fScreenWidth = GETINT16(currentComponent);
+            fScreenHeight = GETINT16(currentComponent + 2);
+
+            const int globalColorMapColors = 2 << (currentComponent[4] & 0x07);
+
+            if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* global map */
+                m_globalColorMap.setNumColors(globalColorMapColors);
+                GETN(SK_BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, SkGIFGlobalColormap);
+                break;
+            }
+
+            GETN(1, SkGIFImageStart);
+            break;
+        }
+
+        case SkGIFGlobalColormap: {
+            m_globalColorMap.setTablePosition(m_streamBuffer.markPosition());
+            GETN(1, SkGIFImageStart);
+            break;
+        }
+
+        case SkGIFImageStart: {
+            const char currentComponent = m_streamBuffer.get()[0];
+
+            if (currentComponent == '!') { // extension.
+                GETN(2, SkGIFExtension);
+                break;
+            }
+
+            if (currentComponent == ',') { // image separator.
+                GETN(9, SkGIFImageHeader);
+                break;
+            }
+
+            // If we get anything other than ',' (image separator), '!'
+            // (extension), or ';' (trailer), there is extraneous data
+            // between blocks. The GIF87a spec tells us to keep reading
+            // until we find an image separator, but GIF89a says such
+            // a file is corrupt. We follow Mozilla's implementation and
+            // proceed as if the file were correctly terminated, so the
+            // GIF will display.
+            GETN(0, SkGIFDone);
+            break;
+        }
+
+        case SkGIFExtension: {
+            const unsigned char* currentComponent =
+                reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
+
+            size_t bytesInBlock = currentComponent[1];
+            SkGIFState exceptionState = SkGIFSkipBlock;
+
+            switch (*currentComponent) {
+            case 0xf9:
+                // The GIF spec mandates that the GIFControlExtension header block length is 4 bytes,
+                exceptionState = SkGIFControlExtension;
+                // and the parser for this block reads 4 bytes, so we must enforce that the buffer
+                // contains at least this many bytes. If the GIF specifies a different length, we
+                // allow that, so long as it's larger; the additional data will simply be ignored.
+                bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
+                break;
+
+            // The GIF spec also specifies the lengths of the following two extensions' headers
+            // (as 12 and 11 bytes, respectively). Because we ignore the plain text extension entirely
+            // and sanity-check the actual length of the application extension header before reading it,
+            // we allow GIFs to deviate from these values in either direction. This is important for
+            // real-world compatibility, as GIFs in the wild exist with application extension headers
+            // that are both shorter and longer than 11 bytes.
+            case 0x01:
+                // ignoring plain text extension
+                break;
+
+            case 0xff:
+                exceptionState = SkGIFApplicationExtension;
+                break;
+
+            case 0xfe:
+                exceptionState = SkGIFConsumeComment;
+                break;
+            }
+
+            if (bytesInBlock)
+                GETN(bytesInBlock, exceptionState);
+            else
+                GETN(1, SkGIFImageStart);
+            break;
+        }
+
+        case SkGIFConsumeBlock: {
+            const unsigned char currentComponent = this->getOneByte();
+            if (!currentComponent)
+                GETN(1, SkGIFImageStart);
+            else
+                GETN(currentComponent, SkGIFSkipBlock);
+            break;
+        }
+
+        case SkGIFSkipBlock: {
+            GETN(1, SkGIFConsumeBlock);
+            break;
+        }
+
+        case SkGIFControlExtension: {
+            const unsigned char* currentComponent =
+                reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
+
+            addFrameIfNecessary();
+            SkGIFFrameContext* currentFrame = m_frames.back().get();
+            if (*currentComponent & 0x1)
+                currentFrame->setTransparentPixel(currentComponent[3]);
+
+            // We ignore the "user input" bit.
+
+            // NOTE: This relies on the values in the FrameDisposalMethod enum
+            // matching those in the GIF spec!
+            int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7;
+            switch (rawDisposalMethod) {
+            case 1:
+            case 2:
+            case 3:
+                currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMethod) rawDisposalMethod);
+                break;
+            case 4:
+                // Some specs say that disposal method 3 is "overwrite previous", others that setting
+                // the third bit of the field (i.e. method 4) is. We map both to the same value.
+                currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kRestorePrevious);
+                break;
+            default:
+                // Other values use the default.
+                currentFrame->setDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep);
+                break;
+            }
+            currentFrame->setDuration(GETINT16(currentComponent + 1) * 10);
+            GETN(1, SkGIFConsumeBlock);
+            break;
+        }
+
+        case SkGIFCommentExtension: {
+            const unsigned char currentComponent = this->getOneByte();
+            if (currentComponent)
+                GETN(currentComponent, SkGIFConsumeComment);
+            else
+                GETN(1, SkGIFImageStart);
+            break;
+        }
+
+        case SkGIFConsumeComment: {
+            GETN(1, SkGIFCommentExtension);
+            break;
+        }
+
+        case SkGIFApplicationExtension: {
+            // Check for netscape application extension.
+            if (m_bytesToConsume == 11) {
+                const unsigned char* currentComponent =
+                    reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
+
+                if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(currentComponent, "ANIMEXTS1.0", 11))
+                    GETN(1, SkGIFNetscapeExtensionBlock);
+            }
+
+            if (m_state != SkGIFNetscapeExtensionBlock)
+                GETN(1, SkGIFConsumeBlock);
+            break;
+        }
+
+        // Netscape-specific GIF extension: animation looping.
+        case SkGIFNetscapeExtensionBlock: {
+            const int currentComponent = this->getOneByte();
+            // SkGIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount.
+            if (currentComponent)
+                GETN(std::max(3, currentComponent), SkGIFConsumeNetscapeExtension);
+            else
+                GETN(1, SkGIFImageStart);
+            break;
+        }
+
+        // Parse netscape-specific application extensions
+        case SkGIFConsumeNetscapeExtension: {
+            const unsigned char* currentComponent =
+                reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
+
+            int netscapeExtension = currentComponent[0] & 7;
+
+            // Loop entire animation specified # of times. Only read the loop count during the first iteration.
+            if (netscapeExtension == 1) {
+                m_loopCount = GETINT16(currentComponent + 1);
+
+                // Zero loop count is infinite animation loop request.
+                if (!m_loopCount)
+                    m_loopCount = SkCodec::kRepetitionCountInfinite;
+
+                GETN(1, SkGIFNetscapeExtensionBlock);
+
+                if (SkGIFLoopCountQuery == query) {
+                    m_streamBuffer.flush();
+                    return SkCodec::kSuccess;
+                }
+            } else if (netscapeExtension == 2) {
+                // Wait for specified # of bytes to enter buffer.
+
+                // Don't do this, this extension doesn't exist (isn't used at all)
+                // and doesn't do anything, as our streaming/buffering takes care of it all...
+                // See: http://semmix.pl/color/exgraf/eeg24.htm
+                GETN(1, SkGIFNetscapeExtensionBlock);
+            } else {
+                // 0,3-7 are yet to be defined netscape extension codes
+                // This prevents attempting to continue reading this invalid stream.
+                GETN(0, SkGIFDone);
+                return SkCodec::kInvalidInput;
+            }
+            break;
+        }
+
+        case SkGIFImageHeader: {
+            int height, width, xOffset, yOffset;
+            const unsigned char* currentComponent =
+                reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
+
+            /* Get image offsets, with respect to the screen origin */
+            xOffset = GETINT16(currentComponent);
+            yOffset = GETINT16(currentComponent + 2);
+
+            /* Get image width and height. */
+            width  = GETINT16(currentComponent + 4);
+            height = GETINT16(currentComponent + 6);
+
+            // Some GIF files have frames that don't fit in the specified
+            // overall image size. For the first frame, we can simply enlarge
+            // the image size to allow the frame to be visible.  We can't do
+            // this on subsequent frames because the rest of the decoding
+            // infrastructure assumes the image size won't change as we
+            // continue decoding, so any subsequent frames that are even
+            // larger will be cropped.
+            // Luckily, handling just the first frame is sufficient to deal
+            // with most cases, e.g. ones where the image size is erroneously
+            // set to zero, since usually the first frame completely fills
+            // the image.
+            if (currentFrameIsFirstFrame()) {
+                fScreenHeight = std::max(fScreenHeight, yOffset + height);
+                fScreenWidth = std::max(fScreenWidth, xOffset + width);
+            }
+
+            // NOTE: Chromium placed this block after setHeaderDefined, down
+            // below we returned true when asked for the size. So Chromium
+            // created an image which would fail. Is this the correct behavior?
+            // We choose to return false early, so we will not create an
+            // SkCodec.
+
+            // Work around more broken GIF files that have zero image width or
+            // height.
+            if (!height || !width) {
+                height = fScreenHeight;
+                width = fScreenWidth;
+                if (!height || !width) {
+                    // This prevents attempting to continue reading this invalid stream.
+                    GETN(0, SkGIFDone);
+                    return SkCodec::kInvalidInput;
+                }
+            }
+
+            const bool isLocalColormapDefined = SkToBool(currentComponent[8] & 0x80);
+            // The three low-order bits of currentComponent[8] specify the bits per pixel.
+            const int numColors = 2 << (currentComponent[8] & 0x7);
+            if (currentFrameIsFirstFrame()) {
+                const int transPix = m_frames.empty() ? SkGIFColorMap::kNotFound
+                                                      : m_frames[0]->transparentPixel();
+                if (is_palette_index_valid(transPix)) {
+                    m_firstFrameHasAlpha = true;
+                } else {
+                    const bool frameIsSubset = xOffset > 0 || yOffset > 0
+                            || width < fScreenWidth
+                            || height < fScreenHeight;
+                    m_firstFrameHasAlpha = frameIsSubset;
+                }
+            }
+
+            addFrameIfNecessary();
+            SkGIFFrameContext* currentFrame = m_frames.back().get();
+            currentFrame->setHeaderDefined();
+
+            if (query == SkGIFSizeQuery) {
+                // The decoder needs to stop, so we return here, before
+                // flushing the buffer. Next time through, we'll be in the same
+                // state, requiring the same amount in the buffer.
+                return SkCodec::kSuccess;
+            }
+
+
+            currentFrame->setXYWH(xOffset, yOffset, width, height);
+            currentFrame->setInterlaced(SkToBool(currentComponent[8] & 0x40));
+
+            // Overlaying interlaced, transparent GIFs over
+            // existing image data using the Haeberli display hack
+            // requires saving the underlying image in order to
+            // avoid jaggies at the transparency edges. We are
+            // unprepared to deal with that, so don't display such
+            // images progressively. Which means only the first
+            // frame can be progressively displayed.
+            // FIXME: It is possible that a non-transparent frame
+            // can be interlaced and progressively displayed.
+            currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
+
+            if (isLocalColormapDefined) {
+                currentFrame->localColorMap().setNumColors(numColors);
+                GETN(SK_BYTES_PER_COLORMAP_ENTRY * numColors, SkGIFImageColormap);
+                break;
+            }
+
+            setAlphaAndRequiredFrame(currentFrame);
+            GETN(1, SkGIFLZWStart);
+            break;
+        }
+
+        case SkGIFImageColormap: {
+            SkASSERT(!m_frames.empty());
+            auto* currentFrame = m_frames.back().get();
+            auto& cmap = currentFrame->localColorMap();
+            cmap.setTablePosition(m_streamBuffer.markPosition());
+            setAlphaAndRequiredFrame(currentFrame);
+            GETN(1, SkGIFLZWStart);
+            break;
+        }
+
+        case SkGIFSubBlock: {
+            const size_t bytesInBlock = this->getOneByte();
+            if (bytesInBlock)
+                GETN(bytesInBlock, SkGIFLZW);
+            else {
+                // Finished parsing one frame; Process next frame.
+                SkASSERT(!m_frames.empty());
+                // Note that some broken GIF files do not have enough LZW blocks to fully
+                // decode all rows but we treat it as frame complete.
+                m_frames.back()->setComplete();
+                GETN(1, SkGIFImageStart);
+                if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse) {
+                    m_streamBuffer.flush();
+                    return SkCodec::kSuccess;
+                }
+            }
+            break;
+        }
+
+        case SkGIFDone: {
+            m_parseCompleted = true;
+            return SkCodec::kSuccess;
+        }
+
+        default:
+            // We shouldn't ever get here.
+            // This prevents attempting to continue reading this invalid stream.
+            GETN(0, SkGIFDone);
+            return SkCodec::kInvalidInput;
+            break;
+        }   // switch
+        m_streamBuffer.flush();
+    }
+}
+
+void SkGifImageReader::addFrameIfNecessary()
+{
+    if (m_frames.empty() || m_frames.back()->isComplete()) {
+        const int i = m_frames.count();
+        m_frames.emplace_back(new SkGIFFrameContext(i));
+    }
+}
+
+SkEncodedInfo::Alpha SkGIFFrameContext::onReportedAlpha() 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 is_palette_index_valid(this->transparentPixel()) ? SkEncodedInfo::kBinary_Alpha
+                                                            : SkEncodedInfo::kOpaque_Alpha;
+}
+
+// FIXME: Move this method to close to doLZW().
+bool SkGIFLZWContext::prepareToDecode()
+{
+    SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefined());
+
+    // Since we use a codesize of 1 more than the datasize, we need to ensure
+    // that our datasize is strictly less than the SK_MAX_DICTIONARY_ENTRY_BITS.
+    if (m_frameContext->dataSize() >= SK_MAX_DICTIONARY_ENTRY_BITS)
+        return false;
+    clearCode = 1 << m_frameContext->dataSize();
+    avail = clearCode + 2;
+    oldcode = -1;
+    codesize = m_frameContext->dataSize() + 1;
+    codemask = (1 << codesize) - 1;
+    datum = bits = 0;
+    ipass = m_frameContext->interlaced() ? 1 : 0;
+    irow = 0;
+
+    // We want to know the longest sequence encodable by a dictionary with
+    // SK_MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base
+    // values themselves at the beginning of the dictionary, as well as the need
+    // for a clear code or a termination code, we could use every entry to
+    // encode a series of multiple values. If the input value stream looked
+    // like "AAAAA..." (a long string of just one value), the first dictionary
+    // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
+    // the longest sequence would be SK_MAX_DICTIONARY_ENTRIES + 1 values.
+    //
+    // However, we have to account for reserved entries. The first |datasize|
+    // bits are reserved for the base values, and the next two entries are
+    // reserved for the clear code and termination code. In theory a GIF can
+    // set the datasize to 0, meaning we have just two reserved entries, making
+    // the longest sequence (SK_MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since
+    // each value is a byte, this is also the number of bytes in the longest
+    // encodable sequence.
+    constexpr size_t kMaxSequence = SK_MAX_DICTIONARY_ENTRIES - 1;
+    constexpr size_t kMaxBytes = (kMaxSequence + SK_DICTIONARY_WORD_SIZE - 1)
+                         & ~(SK_DICTIONARY_WORD_SIZE - 1);
+
+    // Now allocate the output buffer. We decode directly into this buffer
+    // until we have at least one row worth of data, then call outputRow().
+    // This means worst case we may have (row width - 1) bytes in the buffer
+    // and then decode a sequence |kMaxBytes| long to append.
+    rowBuffer.reset(m_frameContext->width() - 1 + kMaxBytes);
+    rowIter = rowBuffer.begin();
+    rowsRemaining = m_frameContext->height();
+
+    // Clearing the whole suffix table lets us be more tolerant of bad data.
+    for (int i = 0; i < clearCode; ++i) {
+        std::fill_n(suffix[i].begin(), SK_DICTIONARY_WORD_SIZE, 0);
+        suffix[i][0] = i;
+        suffixLength[i] = 1;
+        prefix[i] = i;  // ensure that we have a place to find firstchar
+    }
+    return true;
+}
diff --git a/SkGifImageReader.h b/SkGifImageReader.h
new file mode 100644
index 0000000..9b02255
--- /dev/null
+++ b/SkGifImageReader.h
@@ -0,0 +1,398 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef SkGifImageReader_h
+#define SkGifImageReader_h
+
+// Define ourselves as the clientPtr.  Mozilla just hacked their C++ callback class into this old C decoder,
+// so we will too.
+class SkLibGifCodec;
+
+#include "include/codec/SkCodec.h"
+#include "include/codec/SkCodecAnimation.h"
+#include "include/core/SkData.h"
+#include "include/core/SkImageInfo.h"
+#include "include/private/SkTArray.h"
+#include "src/codec/SkCodecPriv.h"
+#include "src/codec/SkColorTable.h"
+#include "src/codec/SkFrameHolder.h"
+#include "src/codec/SkStreamBuffer.h"
+
+#include <array>
+#include <memory>
+
+typedef SkTArray<unsigned char, true> SkGIFRow;
+
+
+#define SK_MAX_DICTIONARY_ENTRY_BITS 12
+#define SK_MAX_DICTIONARY_ENTRIES    4096 // 2^SK_MAX_DICTIONARY_ENTRY_BITS
+#define SK_MAX_COLORS                256
+#define SK_BYTES_PER_COLORMAP_ENTRY  3
+#define SK_DICTIONARY_WORD_SIZE      8
+
+// List of possible parsing states.
+enum SkGIFState {
+    SkGIFType,
+    SkGIFGlobalHeader,
+    SkGIFGlobalColormap,
+    SkGIFImageStart,
+    SkGIFImageHeader,
+    SkGIFImageColormap,
+    SkGIFImageBody,
+    SkGIFLZWStart,
+    SkGIFLZW,
+    SkGIFSubBlock,
+    SkGIFExtension,
+    SkGIFControlExtension,
+    SkGIFConsumeBlock,
+    SkGIFSkipBlock,
+    SkGIFDone,
+    SkGIFCommentExtension,
+    SkGIFApplicationExtension,
+    SkGIFNetscapeExtensionBlock,
+    SkGIFConsumeNetscapeExtension,
+    SkGIFConsumeComment
+};
+
+class SkGIFFrameContext;
+class SkGIFColorMap;
+
+// LZW decoder state machine.
+class SkGIFLZWContext final : public SkNoncopyable {
+public:
+    SkGIFLZWContext(SkLibGifCodec* client, const SkGIFFrameContext* frameContext)
+        : codesize(0)
+        , codemask(0)
+        , clearCode(0)
+        , avail(0)
+        , oldcode(0)
+        , bits(0)
+        , datum(0)
+        , ipass(0)
+        , irow(0)
+        , rowsRemaining(0)
+        , rowIter(nullptr)
+        , m_client(client)
+        , m_frameContext(frameContext)
+    { }
+
+    bool prepareToDecode();
+    void outputRow(const unsigned char* rowBegin);
+    bool doLZW(const unsigned char* block, size_t bytesInBlock);
+    bool hasRemainingRows() { return SkToBool(rowsRemaining); }
+
+private:
+    // LZW decoding states and output states.
+    int codesize;
+    int codemask;
+    int clearCode; // Codeword used to trigger dictionary reset.
+    int avail; // Index of next available slot in dictionary.
+    int oldcode;
+    int bits; // Number of unread bits in "datum".
+    int datum; // 32-bit input buffer.
+    int ipass; // Interlace pass; Ranges 1-4 if interlaced.
+    size_t irow; // Current output row, starting at zero.
+    size_t rowsRemaining; // Rows remaining to be output.
+
+    unsigned short prefix[SK_MAX_DICTIONARY_ENTRIES];
+    std::array<std::array<unsigned char, SK_DICTIONARY_WORD_SIZE>,
+                SK_MAX_DICTIONARY_ENTRIES> suffix;
+    unsigned short suffixLength[SK_MAX_DICTIONARY_ENTRIES];
+    SkGIFRow rowBuffer; // Single scanline temporary buffer.
+    unsigned char* rowIter;
+
+    SkLibGifCodec* const m_client;
+    const SkGIFFrameContext* m_frameContext;
+};
+
+struct SkGIFLZWBlock {
+ public:
+  SkGIFLZWBlock(size_t position, size_t size)
+      : blockPosition(position), blockSize(size) {}
+
+  size_t blockPosition;
+  size_t blockSize;
+};
+
+class SkGIFColorMap final {
+public:
+    static constexpr int kNotFound = -1;
+
+    SkGIFColorMap()
+        : m_isDefined(false)
+        , m_position(0)
+        , m_colors(0)
+        , m_transPixel(kNotFound)
+        , m_packColorProc(nullptr)
+    {
+    }
+
+    void setNumColors(int colors) {
+        SkASSERT(!m_colors);
+        SkASSERT(!m_position);
+
+        m_colors = colors;
+    }
+
+    void setTablePosition(size_t position) {
+        SkASSERT(!m_isDefined);
+
+        m_position = position;
+        m_isDefined = true;
+    }
+
+    int numColors() const { return m_colors; }
+
+    bool isDefined() const { return m_isDefined; }
+
+    // Build RGBA table using the data stream.
+    sk_sp<SkColorTable> buildTable(SkStreamBuffer*, SkColorType dstColorType,
+                                   int transparentPixel) const;
+
+private:
+    bool m_isDefined;
+    size_t m_position;
+    int m_colors;
+    // Cached values. If these match on a new request, we can reuse m_table.
+    mutable int m_transPixel;
+    mutable PackColorProc m_packColorProc;
+    mutable sk_sp<SkColorTable> m_table;
+};
+
+class SkGifImageReader;
+
+// LocalFrame output state machine.
+class SkGIFFrameContext : public SkFrame {
+public:
+    SkGIFFrameContext(int id)
+        : INHERITED(id)
+        , m_transparentPixel(SkGIFColorMap::kNotFound)
+        , m_dataSize(0)
+        , m_progressiveDisplay(false)
+        , m_interlaced(false)
+        , m_currentLzwBlock(0)
+        , m_isComplete(false)
+        , m_isHeaderDefined(false)
+        , m_isDataSizeDefined(false)
+    {
+    }
+
+    ~SkGIFFrameContext() override
+    {
+    }
+
+    void addLzwBlock(size_t position, size_t size)
+    {
+        m_lzwBlocks.emplace_back(position, size);
+    }
+
+    bool decode(SkStreamBuffer*, SkLibGifCodec* client, bool* frameDecoded);
+
+    int transparentPixel() const { return m_transparentPixel; }
+    void setTransparentPixel(int pixel) { m_transparentPixel = pixel; }
+
+    bool isComplete() const { return m_isComplete; }
+    void setComplete() { m_isComplete = true; }
+    bool isHeaderDefined() const { return m_isHeaderDefined; }
+    void setHeaderDefined() { m_isHeaderDefined = true; }
+    bool isDataSizeDefined() const { return m_isDataSizeDefined; }
+    int dataSize() const { return m_dataSize; }
+    void setDataSize(int size)
+    {
+        m_dataSize = size;
+        m_isDataSizeDefined = true;
+    }
+    bool progressiveDisplay() const { return m_progressiveDisplay; }
+    void setProgressiveDisplay(bool progressiveDisplay) { m_progressiveDisplay = progressiveDisplay; }
+    bool interlaced() const { return m_interlaced; }
+    void setInterlaced(bool interlaced) { m_interlaced = interlaced; }
+
+    void clearDecodeState() { m_lzwContext.reset(); }
+    const SkGIFColorMap& localColorMap() const { return m_localColorMap; }
+    SkGIFColorMap& localColorMap() { return m_localColorMap; }
+
+protected:
+    SkEncodedInfo::Alpha onReportedAlpha() const override;
+
+private:
+    int m_transparentPixel; // Index of transparent pixel. Value is kNotFound if there is no transparent pixel.
+    int m_dataSize;
+
+    bool m_progressiveDisplay; // If true, do Haeberli interlace hack.
+    bool m_interlaced; // True, if scanlines arrive interlaced order.
+
+    std::unique_ptr<SkGIFLZWContext> m_lzwContext;
+    // LZW blocks for this frame.
+    SkTArray<SkGIFLZWBlock> m_lzwBlocks;
+
+    SkGIFColorMap m_localColorMap;
+
+    int m_currentLzwBlock;
+    bool m_isComplete;
+    bool m_isHeaderDefined;
+    bool m_isDataSizeDefined;
+
+    typedef SkFrame INHERITED;
+};
+
+class SkGifImageReader final : public SkFrameHolder {
+public:
+    // This takes ownership of stream.
+    SkGifImageReader(std::unique_ptr<SkStream> stream)
+        : m_client(nullptr)
+        , m_state(SkGIFType)
+        , m_bytesToConsume(6) // Number of bytes for GIF type, either "GIF87a" or "GIF89a".
+        , m_version(0)
+        , m_loopCount(cLoopCountNotSeen)
+        , m_streamBuffer(std::move(stream))
+        , m_parseCompleted(false)
+        , m_firstFrameHasAlpha(false)
+    {
+    }
+
+    ~SkGifImageReader() override
+    {
+    }
+
+    void setClient(SkLibGifCodec* client) { m_client = client; }
+
+    // Option to pass to parse(). All enums are negative, because a non-negative value is used to
+    // indicate that the Reader should parse up to and including the frame indicated.
+    enum SkGIFParseQuery {
+        // Parse enough to determine the size. Note that this parses the first frame's header,
+        // since we may decide to expand based on the frame's dimensions.
+        SkGIFSizeQuery        = -1,
+        // Parse to the end, so we know about all frames.
+        SkGIFFrameCountQuery  = -2,
+        // Parse until we see the loop count.
+        SkGIFLoopCountQuery   = -3,
+    };
+
+    // Parse incoming GIF data stream into internal data structures.
+    // Non-negative values are used to indicate to parse through that frame.
+    SkCodec::Result parse(SkGIFParseQuery);
+
+    // Decode the frame indicated by frameIndex.
+    // frameComplete will be set to true if the frame is completely decoded.
+    // The method returns false if there is an error.
+    bool decode(int frameIndex, bool* frameComplete);
+
+    int imagesCount() const
+    {
+        const int frames = m_frames.count();
+        if (!frames) {
+            return 0;
+        }
+
+        // This avoids counting an empty frame when the file is truncated (or
+        // simply not yet complete) after receiving SkGIFControlExtension (and
+        // possibly SkGIFImageHeader) but before reading the color table. This
+        // ensures that we do not count a frame before we know its required
+        // frame.
+        return m_frames.back()->reachedStartOfData() ? frames : frames - 1;
+    }
+    int loopCount() const {
+        if (cLoopCountNotSeen == m_loopCount) {
+            return 0;
+        }
+        return m_loopCount;
+    }
+
+    const SkGIFColorMap& globalColorMap() const
+    {
+        return m_globalColorMap;
+    }
+
+    const SkGIFFrameContext* frameContext(int index) const
+    {
+        return index >= 0 && index < m_frames.count()
+                ? m_frames[index].get() : nullptr;
+    }
+
+    void clearDecodeState() {
+        for (int index = 0; index < m_frames.count(); index++) {
+            m_frames[index]->clearDecodeState();
+        }
+    }
+
+    // Return the color table for frame index (which may be the global color table).
+    sk_sp<SkColorTable> getColorTable(SkColorType dstColorType, int index);
+
+    bool firstFrameHasAlpha() const { return m_firstFrameHasAlpha; }
+
+protected:
+    const SkFrame* onGetFrame(int i) const override {
+        return static_cast<const SkFrame*>(this->frameContext(i));
+    }
+
+private:
+    // Requires that one byte has been buffered into m_streamBuffer.
+    unsigned char getOneByte() const {
+        return reinterpret_cast<const unsigned char*>(m_streamBuffer.get())[0];
+    }
+
+    void addFrameIfNecessary();
+    bool currentFrameIsFirstFrame() const
+    {
+        return m_frames.empty() || (m_frames.count() == 1 && !m_frames[0]->isComplete());
+    }
+
+    // Unowned pointer
+    SkLibGifCodec* m_client;
+
+    // Parsing state machine.
+    SkGIFState m_state; // Current decoder master state.
+    size_t m_bytesToConsume; // Number of bytes to consume for next stage of parsing.
+
+    // Global (multi-image) state.
+    int m_version; // Either 89 for GIF89 or 87 for GIF87.
+    SkGIFColorMap m_globalColorMap;
+
+    static constexpr int cLoopCountNotSeen = -2;
+    int m_loopCount; // Netscape specific extension block to control the number of animation loops a GIF renders.
+
+    SkTArray<std::unique_ptr<SkGIFFrameContext>> m_frames;
+
+    SkStreamBuffer m_streamBuffer;
+    bool m_parseCompleted;
+
+    // This value can be computed before we create a SkGIFFrameContext, so we
+    // store it here instead of on m_frames[0].
+    bool m_firstFrameHasAlpha;
+};
+
+#endif
diff --git a/SkLibGifCodec.cpp b/SkLibGifCodec.cpp
new file mode 100644
index 0000000..d4f8790
--- /dev/null
+++ b/SkLibGifCodec.cpp
@@ -0,0 +1,532 @@
+// Copyright 2015 Google Inc.
+// Use of this source code is governed by the BSD-3-Clause license that can be
+// found in the LICENSE.md file.
+
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "SkGifCodec.h"
+#include "SkLibGifCodec.h"
+
+#include "include/codec/SkCodecAnimation.h"
+#include "include/core/SkStream.h"
+#include "include/private/SkColorData.h"
+#include "src/codec/SkCodecPriv.h"
+#include "src/codec/SkColorTable.h"
+#include "src/codec/SkSwizzler.h"
+#include "src/core/SkMakeUnique.h"
+
+#include <algorithm>
+
+#define GIF87_STAMP "GIF87a"
+#define GIF89_STAMP "GIF89a"
+#define GIF_STAMP_LEN 6
+
+/*
+ * Checks the start of the stream to see if the image is a gif
+ */
+bool SkGifCodec::IsGif(const void* buf, size_t bytesRead) {
+    if (bytesRead >= GIF_STAMP_LEN) {
+        if (memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
+            memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+/*
+ * Error function
+ */
+static SkCodec::Result gif_error(const char* msg, SkCodec::Result result = SkCodec::kInvalidInput) {
+    SkCodecPrintf("Gif Error: %s\n", msg);
+    return result;
+}
+
+std::unique_ptr<SkCodec> SkGifCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
+                                                    SkCodec::Result* result) {
+    std::unique_ptr<SkGifImageReader> reader(new SkGifImageReader(std::move(stream)));
+    *result = reader->parse(SkGifImageReader::SkGIFSizeQuery);
+    if (*result != SkCodec::kSuccess) {
+        return nullptr;
+    }
+
+    // If no images are in the data, or the first header is not yet defined, we cannot
+    // create a codec. In either case, the width and height are not yet known.
+    auto* frame = reader->frameContext(0);
+    if (!frame || !frame->isHeaderDefined()) {
+        *result = SkCodec::kInvalidInput;
+        return nullptr;
+    }
+
+    // isHeaderDefined() will not return true if the screen size is empty.
+    SkASSERT(reader->screenHeight() > 0 && reader->screenWidth() > 0);
+
+    const auto alpha = reader->firstFrameHasAlpha() ? SkEncodedInfo::kBinary_Alpha
+                                                    : SkEncodedInfo::kOpaque_Alpha;
+    // Use kPalette since Gifs are encoded with a color table.
+    // FIXME: Gifs can actually be encoded with 4-bits per pixel. Using 8 works, but we could skip
+    //        expanding to 8 bits and take advantage of the SkSwizzler to work from 4.
+    auto encodedInfo = SkEncodedInfo::Make(reader->screenWidth(), reader->screenHeight(),
+                                           SkEncodedInfo::kPalette_Color, alpha, 8);
+    return std::unique_ptr<SkCodec>(new SkLibGifCodec(std::move(encodedInfo), reader.release()));
+}
+
+bool SkLibGifCodec::onRewind() {
+    fReader->clearDecodeState();
+    return true;
+}
+
+SkLibGifCodec::SkLibGifCodec(SkEncodedInfo&& encodedInfo, SkGifImageReader* reader)
+    : INHERITED(std::move(encodedInfo), skcms_PixelFormat_RGBA_8888, nullptr)
+    , fReader(reader)
+    , fTmpBuffer(nullptr)
+    , fSwizzler(nullptr)
+    , fCurrColorTable(nullptr)
+    , fCurrColorTableIsReal(false)
+    , fFilledBackground(false)
+    , fFirstCallToIncrementalDecode(false)
+    , fDst(nullptr)
+    , fDstRowBytes(0)
+    , fRowsDecoded(0)
+{
+    reader->setClient(this);
+}
+
+int SkLibGifCodec::onGetFrameCount() {
+    fReader->parse(SkGifImageReader::SkGIFFrameCountQuery);
+    return fReader->imagesCount();
+}
+
+bool SkLibGifCodec::onGetFrameInfo(int i, SkCodec::FrameInfo* frameInfo) const {
+    if (i >= fReader->imagesCount()) {
+        return false;
+    }
+
+    const SkGIFFrameContext* frameContext = fReader->frameContext(i);
+    SkASSERT(frameContext->reachedStartOfData());
+
+    if (frameInfo) {
+        frameInfo->fDuration = frameContext->getDuration();
+        frameInfo->fRequiredFrame = frameContext->getRequiredFrame();
+        frameInfo->fFullyReceived = frameContext->isComplete();
+        frameInfo->fAlphaType = frameContext->hasAlpha() ? kUnpremul_SkAlphaType
+                                                         : kOpaque_SkAlphaType;
+        frameInfo->fDisposalMethod = frameContext->getDisposalMethod();
+    }
+    return true;
+}
+
+int SkLibGifCodec::onGetRepetitionCount() {
+    fReader->parse(SkGifImageReader::SkGIFLoopCountQuery);
+    return fReader->loopCount();
+}
+
+static constexpr SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
+
+void SkLibGifCodec::initializeColorTable(const SkImageInfo& dstInfo, int frameIndex) {
+    SkColorType colorTableColorType = dstInfo.colorType();
+    if (this->colorXform()) {
+        colorTableColorType = kXformSrcColorType;
+    }
+
+    sk_sp<SkColorTable> currColorTable = fReader->getColorTable(colorTableColorType, frameIndex);
+    fCurrColorTableIsReal = static_cast<bool>(currColorTable);
+    if (!fCurrColorTableIsReal) {
+        // This is possible for an empty frame. Create a dummy with one value (transparent).
+        SkPMColor color = SK_ColorTRANSPARENT;
+        fCurrColorTable.reset(new SkColorTable(&color, 1));
+    } else if (this->colorXform() && !this->xformOnDecode()) {
+        SkPMColor dstColors[256];
+        this->applyColorXform(dstColors, currColorTable->readColors(),
+                              currColorTable->count());
+        fCurrColorTable.reset(new SkColorTable(dstColors, currColorTable->count()));
+    } else {
+        fCurrColorTable = std::move(currColorTable);
+    }
+}
+
+
+SkCodec::Result SkLibGifCodec::prepareToDecode(const SkImageInfo& dstInfo, const Options& opts) {
+    if (opts.fSubset) {
+        return gif_error("Subsets not supported.\n", kUnimplemented);
+    }
+
+    const int frameIndex = opts.fFrameIndex;
+    if (frameIndex > 0 && kRGB_565_SkColorType == dstInfo.colorType()) {
+        // FIXME: In theory, we might be able to support this, but it's not clear that it
+        // is necessary (Chromium does not decode to 565, and Android does not decode
+        // frames beyond the first). Disabling it because it is somewhat difficult:
+        // - If there is a transparent pixel, and this frame draws on top of another frame
+        //   (if the frame is independent with a transparent pixel, we should not decode to
+        //   565 anyway, since it is not opaque), we need to skip drawing the transparent
+        //   pixels (see writeTransparentPixels in haveDecodedRow). We currently do this by
+        //   first swizzling into temporary memory, then copying into the destination. (We
+        //   let the swizzler handle it first because it may need to sample.) After
+        //   swizzling to 565, we do not know which pixels in our temporary memory
+        //   correspond to the transparent pixel, so we do not know what to skip. We could
+        //   special case the non-sampled case (no need to swizzle), but as this is
+        //   currently unused we can just not support it.
+        return gif_error("Cannot decode multiframe gif (except frame 0) as 565.\n",
+                         kInvalidConversion);
+    }
+
+    const auto* frame = fReader->frameContext(frameIndex);
+    SkASSERT(frame);
+    if (0 == frameIndex) {
+        // SkCodec does not have a way to just parse through frame 0, so we
+        // have to do so manually, here.
+        fReader->parse((SkGifImageReader::SkGIFParseQuery) 0);
+        if (!frame->reachedStartOfData()) {
+            // We have parsed enough to know that there is a color map, but cannot
+            // parse the map itself yet. Exit now, so we do not build an incorrect
+            // table.
+            return gif_error("color map not available yet\n", kIncompleteInput);
+        }
+    } else {
+        // Parsing happened in SkCodec::getPixels.
+        SkASSERT(frameIndex < fReader->imagesCount());
+        SkASSERT(frame->reachedStartOfData());
+    }
+
+    if (this->xformOnDecode()) {
+        fXformBuffer.reset(new uint32_t[dstInfo.width()]);
+        sk_bzero(fXformBuffer.get(), dstInfo.width() * sizeof(uint32_t));
+    }
+
+    fTmpBuffer.reset(new uint8_t[dstInfo.minRowBytes()]);
+
+    this->initializeColorTable(dstInfo, frameIndex);
+    this->initializeSwizzler(dstInfo, frameIndex);
+
+    SkASSERT(fCurrColorTable);
+    return kSuccess;
+}
+
+void SkLibGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex) {
+    const SkGIFFrameContext* frame = fReader->frameContext(frameIndex);
+    // This is only called by prepareToDecode, which ensures frameIndex is in range.
+    SkASSERT(frame);
+
+    const int xBegin = frame->xOffset();
+    const int xEnd = std::min(frame->frameRect().right(), fReader->screenWidth());
+
+    // CreateSwizzler only reads left and right of the frame. We cannot use the frame's raw
+    // frameRect, since it might extend beyond the edge of the frame.
+    SkIRect swizzleRect = SkIRect::MakeLTRB(xBegin, 0, xEnd, 0);
+
+    SkImageInfo swizzlerInfo = dstInfo;
+    if (this->colorXform()) {
+        swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
+        if (kPremul_SkAlphaType == dstInfo.alphaType()) {
+            swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
+        }
+    }
+
+    // The default Options should be fine:
+    // - we'll ignore if the memory is zero initialized - unless we're the first frame, this won't
+    //   matter anyway.
+    // - subsets are not supported for gif
+    // - the swizzler does not need to know about the frame.
+    // We may not be able to use the real Options anyway, since getPixels does not store it (due to
+    // a bug).
+    fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), fCurrColorTable->readColors(),
+                                 swizzlerInfo, Options(), &swizzleRect);
+    SkASSERT(fSwizzler.get());
+}
+
+/*
+ * Initiates the gif decode
+ */
+SkCodec::Result SkLibGifCodec::onGetPixels(const SkImageInfo& dstInfo,
+                                        void* pixels, size_t dstRowBytes,
+                                        const Options& opts,
+                                        int* rowsDecoded) {
+    Result result = this->prepareToDecode(dstInfo, opts);
+    switch (result) {
+        case kSuccess:
+            break;
+        case kIncompleteInput:
+            // onStartIncrementalDecode treats this as incomplete, since it may
+            // provide more data later, but in this case, no more data will be
+            // provided, and there is nothing to draw. We also cannot return
+            // kIncompleteInput, which will make SkCodec attempt to fill
+            // remaining rows, but that requires an SkSwizzler, which we have
+            // not created.
+            return kInvalidInput;
+        default:
+            return result;
+    }
+
+    if (dstInfo.dimensions() != this->dimensions()) {
+        return gif_error("Scaling not supported.\n", kInvalidScale);
+    }
+
+    fDst = pixels;
+    fDstRowBytes = dstRowBytes;
+
+    return this->decodeFrame(true, opts, rowsDecoded);
+}
+
+SkCodec::Result SkLibGifCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
+                                                     void* pixels, size_t dstRowBytes,
+                                                     const SkCodec::Options& opts) {
+    Result result = this->prepareToDecode(dstInfo, opts);
+    if (result != kSuccess) {
+        return result;
+    }
+
+    fDst = pixels;
+    fDstRowBytes = dstRowBytes;
+
+    fFirstCallToIncrementalDecode = true;
+
+    return kSuccess;
+}
+
+SkCodec::Result SkLibGifCodec::onIncrementalDecode(int* rowsDecoded) {
+    // It is possible the client has appended more data. Parse, if needed.
+    const auto& options = this->options();
+    const int frameIndex = options.fFrameIndex;
+    fReader->parse((SkGifImageReader::SkGIFParseQuery) frameIndex);
+
+    const bool firstCallToIncrementalDecode = fFirstCallToIncrementalDecode;
+    fFirstCallToIncrementalDecode = false;
+    return this->decodeFrame(firstCallToIncrementalDecode, options, rowsDecoded);
+}
+
+SkCodec::Result SkLibGifCodec::decodeFrame(bool firstAttempt, const Options& opts, int* rowsDecoded) {
+    const SkImageInfo& dstInfo = this->dstInfo();
+    const int scaledHeight = get_scaled_dimension(dstInfo.height(), fSwizzler->sampleY());
+
+    const int frameIndex = opts.fFrameIndex;
+    SkASSERT(frameIndex < fReader->imagesCount());
+    const SkGIFFrameContext* frameContext = fReader->frameContext(frameIndex);
+    if (firstAttempt) {
+        // rowsDecoded reports how many rows have been initialized, so a layer above
+        // can fill the rest. In some cases, we fill the background before decoding
+        // (or it is already filled for us), so we report rowsDecoded to be the full
+        // height.
+        bool filledBackground = false;
+        if (frameContext->getRequiredFrame() == kNoFrame) {
+            // We may need to clear to transparent for one of the following reasons:
+            // - The frameRect does not cover the full bounds. haveDecodedRow will
+            //   only draw inside the frameRect, so we need to clear the rest.
+            // - The frame is interlaced. There is no obvious way to fill
+            //   afterwards for an incomplete image. (FIXME: Does the first pass
+            //   cover all rows? If so, we do not have to fill here.)
+            // - There is no color table for this frame. In that case will not
+            //   draw anything, so we need to fill.
+            if (frameContext->frameRect() != this->bounds()
+                    || frameContext->interlaced() || !fCurrColorTableIsReal) {
+                auto fillInfo = dstInfo.makeWH(fSwizzler->fillWidth(), scaledHeight);
+                SkSampler::Fill(fillInfo, fDst, fDstRowBytes, opts.fZeroInitialized);
+                filledBackground = true;
+            }
+        } else {
+            // Not independent.
+            // SkCodec ensured that the prior frame has been decoded.
+            filledBackground = true;
+        }
+
+        fFilledBackground = filledBackground;
+        if (filledBackground) {
+            // Report the full (scaled) height, since the client will never need to fill.
+            fRowsDecoded = scaledHeight;
+        } else {
+            // This will be updated by haveDecodedRow.
+            fRowsDecoded = 0;
+        }
+    }
+
+    if (!fCurrColorTableIsReal) {
+        // Nothing to draw this frame.
+        return kSuccess;
+    }
+
+    bool frameDecoded = false;
+    const bool fatalError = !fReader->decode(frameIndex, &frameDecoded);
+    if (fatalError || !frameDecoded || fRowsDecoded != scaledHeight) {
+        if (rowsDecoded) {
+            *rowsDecoded = fRowsDecoded;
+        }
+        if (fatalError) {
+            return kErrorInInput;
+        }
+        return kIncompleteInput;
+    }
+
+    return kSuccess;
+}
+
+void SkLibGifCodec::applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint8_t* src) const {
+    if (this->xformOnDecode()) {
+        SkASSERT(this->colorXform());
+        fSwizzler->swizzle(fXformBuffer.get(), src);
+
+        const int xformWidth = get_scaled_dimension(dstInfo.width(), fSwizzler->sampleX());
+        this->applyColorXform(dst, fXformBuffer.get(), xformWidth);
+    } else {
+        fSwizzler->swizzle(dst, src);
+    }
+}
+
+template <typename T>
+static void blend_line(void* dstAsVoid, const void* srcAsVoid, int width) {
+    T*       dst = reinterpret_cast<T*>(dstAsVoid);
+    const T* src = reinterpret_cast<const T*>(srcAsVoid);
+    while (width --> 0) {
+        if (*src != 0) {   // GIF pixels are either transparent (== 0) or opaque (!= 0).
+            *dst = *src;
+        }
+        src++;
+        dst++;
+    }
+}
+
+void SkLibGifCodec::haveDecodedRow(int frameIndex, const unsigned char* rowBegin,
+                                int rowNumber, int repeatCount, bool writeTransparentPixels)
+{
+    const SkGIFFrameContext* frameContext = fReader->frameContext(frameIndex);
+    // The pixel data and coordinates supplied to us are relative to the frame's
+    // origin within the entire image size, i.e.
+    // (frameContext->xOffset, frameContext->yOffset). There is no guarantee
+    // that width == (size().width() - frameContext->xOffset), so
+    // we must ensure we don't run off the end of either the source data or the
+    // row's X-coordinates.
+    const int width = frameContext->width();
+    const int xBegin = frameContext->xOffset();
+    const int yBegin = frameContext->yOffset() + rowNumber;
+    const int xEnd = std::min(xBegin + width, this->dimensions().width());
+    const int yEnd = std::min(yBegin + rowNumber + repeatCount, this->dimensions().height());
+    // FIXME: No need to make the checks on width/xBegin/xEnd for every row. We could instead do
+    // this once in prepareToDecode.
+    if (!width || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
+        return;
+
+    // yBegin is the first row in the non-sampled image. dstRow will be the row in the output,
+    // after potentially scaling it.
+    int dstRow = yBegin;
+
+    const int sampleY = fSwizzler->sampleY();
+    if (sampleY > 1) {
+        // Check to see whether this row or one that falls in the repeatCount is needed in the
+        // output.
+        bool foundNecessaryRow = false;
+        for (int i = 0; i < repeatCount; i++) {
+            const int potentialRow = yBegin + i;
+            if (fSwizzler->rowNeeded(potentialRow)) {
+                dstRow = potentialRow / sampleY;
+                const int scaledHeight = get_scaled_dimension(this->dstInfo().height(), sampleY);
+                if (dstRow >= scaledHeight) {
+                    return;
+                }
+
+                foundNecessaryRow = true;
+                repeatCount -= i;
+
+                repeatCount = (repeatCount - 1) / sampleY + 1;
+
+                // Make sure the repeatCount does not take us beyond the end of the dst
+                if (dstRow + repeatCount > scaledHeight) {
+                    repeatCount = scaledHeight - dstRow;
+                    SkASSERT(repeatCount >= 1);
+                }
+                break;
+            }
+        }
+
+        if (!foundNecessaryRow) {
+            return;
+        }
+    } else {
+        // Make sure the repeatCount does not take us beyond the end of the dst
+        SkASSERT(this->dstInfo().height() >= yBegin);
+        repeatCount = SkTMin(repeatCount, this->dstInfo().height() - yBegin);
+    }
+
+    if (!fFilledBackground) {
+        // At this point, we are definitely going to write the row, so count it towards the number
+        // of rows decoded.
+        // We do not consider the repeatCount, which only happens for interlaced, in which case we
+        // have already set fRowsDecoded to the proper value (reflecting that we have filled the
+        // background).
+        fRowsDecoded++;
+    }
+
+    // decodeFrame will early exit if this is false, so this method will not be
+    // called.
+    SkASSERT(fCurrColorTableIsReal);
+
+    // The swizzler takes care of offsetting into the dst width-wise.
+    void* dstLine = SkTAddOffset<void>(fDst, dstRow * fDstRowBytes);
+
+    // We may or may not need to write transparent pixels to the buffer.
+    // If we're compositing against a previous image, it's wrong, but if
+    // we're decoding an interlaced gif and displaying it "Haeberli"-style,
+    // we must write these for passes beyond the first, or the initial passes
+    // will "show through" the later ones.
+    const auto dstInfo = this->dstInfo();
+    if (writeTransparentPixels) {
+        this->applyXformRow(dstInfo, dstLine, rowBegin);
+    } else {
+        this->applyXformRow(dstInfo, fTmpBuffer.get(), rowBegin);
+
+        size_t offsetBytes = fSwizzler->swizzleOffsetBytes();
+        if (dstInfo.colorType() == kRGBA_F16_SkColorType) {
+            // Account for the fact that post-swizzling we converted to F16,
+            // which is twice as wide.
+            offsetBytes *= 2;
+        }
+        const void* src = SkTAddOffset<void>(fTmpBuffer.get(), offsetBytes);
+        void*       dst = SkTAddOffset<void>(dstLine, offsetBytes);
+
+        switch (dstInfo.colorType()) {
+            case kBGRA_8888_SkColorType:
+            case kRGBA_8888_SkColorType:
+                blend_line<uint32_t>(dst, src, fSwizzler->swizzleWidth());
+                break;
+            case kRGBA_F16_SkColorType:
+                blend_line<uint64_t>(dst, src, fSwizzler->swizzleWidth());
+                break;
+            default:
+                SkASSERT(false);
+                return;
+        }
+    }
+
+    // Tell the frame to copy the row data if need be.
+    if (repeatCount > 1) {
+        const size_t bytesPerPixel = this->dstInfo().bytesPerPixel();
+        const size_t bytesToCopy = fSwizzler->swizzleWidth() * bytesPerPixel;
+        void* copiedLine = SkTAddOffset<void>(dstLine, fSwizzler->swizzleOffsetBytes());
+        void* dst = copiedLine;
+        for (int i = 1; i < repeatCount; i++) {
+            dst = SkTAddOffset<void>(dst, fDstRowBytes);
+            memcpy(dst, copiedLine, bytesToCopy);
+        }
+    }
+}
diff --git a/SkLibGifCodec.h b/SkLibGifCodec.h
new file mode 100644
index 0000000..014df5f
--- /dev/null
+++ b/SkLibGifCodec.h
@@ -0,0 +1,153 @@
+// Copyright 2015 Google Inc.
+// Use of this source code is governed by the BSD-3-Clause license that can be
+// found in the LICENSE.md file.
+#ifndef SkLibGifCodec_DEFINED
+#define SkLibGifCodec_DEFINED
+
+#include "SkGifImageReader.h"
+
+#include "include/codec/SkCodec.h"
+#include "include/codec/SkCodecAnimation.h"
+#include "include/core/SkColorSpace.h"
+#include "include/core/SkImageInfo.h"
+#include "src/codec/SkColorTable.h"
+#include "src/codec/SkSwizzler.h"
+
+/*
+ *
+ * This class implements the decoding for gif images
+ *
+ */
+class SkLibGifCodec : public SkCodec {
+public:
+    static bool IsGif(const void*, size_t);
+
+    /*
+     * Assumes IsGif was called and returned true
+     * Reads enough of the stream to determine the image format
+     */
+    static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
+
+    // Callback for SkGifImageReader when a row is available.
+    void haveDecodedRow(int frameIndex, const unsigned char* rowBegin,
+                        int rowNumber, int repeatCount, bool writeTransparentPixels);
+    /*
+     * Creates an instance of the decoder
+     * Called only by NewFromStream
+     * Takes ownership of the SkGifImageReader
+     */
+    SkLibGifCodec(SkEncodedInfo&&, SkGifImageReader*);
+
+protected:
+    /*
+     * Performs the full gif decode
+     */
+    Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&,
+            int*) override;
+
+    SkEncodedImageFormat onGetEncodedFormat() const override {
+        return SkEncodedImageFormat::kGIF;
+    }
+
+    bool onRewind() override;
+
+    int onGetFrameCount() override;
+    bool onGetFrameInfo(int, FrameInfo*) const override;
+    int onGetRepetitionCount() override;
+
+    Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
+            const SkCodec::Options&) override;
+
+    Result onIncrementalDecode(int*) override;
+
+    const SkFrameHolder* getFrameHolder() const override {
+        return fReader.get();
+    }
+
+private:
+
+    /*
+     * Initializes the color table that we will use for decoding.
+     *
+     * @param dstInfo         Contains the requested dst color type.
+     * @param frameIndex      Frame whose color table to use.
+     */
+    void initializeColorTable(const SkImageInfo& dstInfo, int frameIndex);
+
+   /*
+    * Does necessary setup, including setting up the color table and swizzler.
+    */
+    Result prepareToDecode(const SkImageInfo& dstInfo, const Options& opts);
+
+    /*
+     * Initializes the swizzler.
+     *
+     * @param dstInfo    Output image information.  Dimensions may have been
+     *                   adjusted if the image frame size does not match the size
+     *                   indicated in the header.
+     * @param frameIndex Which frame we are decoding. This determines the frameRect
+     *                   to use.
+     */
+    void initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex);
+
+    SkSampler* getSampler(bool createIfNecessary) override {
+        SkASSERT(fSwizzler);
+        return fSwizzler.get();
+    }
+
+    /*
+     * Recursive function to decode a frame.
+     *
+     * @param firstAttempt Whether this is the first call to decodeFrame since
+     *                     starting. e.g. true in onGetPixels, and true in the
+     *                     first call to onIncrementalDecode after calling
+     *                     onStartIncrementalDecode.
+     *                     When true, this method may have to initialize the
+     *                     frame, for example by filling or decoding the prior
+     *                     frame.
+     * @param opts         Options for decoding. May be different from
+     *                     this->options() for decoding prior frames. Specifies
+     *                     the frame to decode and whether the prior frame has
+     *                     already been decoded to fDst. If not, and the frame
+     *                     is not independent, this method will recursively
+     *                     decode the frame it depends on.
+     * @param rowsDecoded  Out-parameter to report the total number of rows
+     *                     that have been decoded (or at least written to, if
+     *                     it had to fill), including rows decoded by prior
+     *                     calls to onIncrementalDecode.
+     * @return             kSuccess if the frame is complete, kIncompleteInput
+     *                     otherwise.
+     */
+    Result decodeFrame(bool firstAttempt, const Options& opts, int* rowsDecoded);
+
+    /*
+     *  Swizzles and color xforms (if necessary) into dst.
+     */
+    void applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint8_t* src) const;
+
+    std::unique_ptr<SkGifImageReader>   fReader;
+    std::unique_ptr<uint8_t[]>          fTmpBuffer;
+    std::unique_ptr<SkSwizzler>         fSwizzler;
+    sk_sp<SkColorTable>                 fCurrColorTable;
+    // We may create a dummy table if there is not a Map in the input data. In
+    // that case, we set this value to false, and we can skip a lot of decoding
+    // work (which would not be meaningful anyway). We create a "fake"/"dummy"
+    // one in that case, so the client and the swizzler have something to draw.
+    bool                                fCurrColorTableIsReal;
+    // Whether the background was filled.
+    bool                                fFilledBackground;
+    // True on the first call to onIncrementalDecode. This value is passed to
+    // decodeFrame.
+    bool                                fFirstCallToIncrementalDecode;
+
+    void*                               fDst;
+    size_t                              fDstRowBytes;
+
+    // Updated inside haveDecodedRow when rows are decoded, unless we filled
+    // the background, in which case it is set once and left alone.
+    int                                 fRowsDecoded;
+    std::unique_ptr<uint32_t[]>         fXformBuffer;
+
+    typedef SkCodec INHERITED;
+};
+#endif  // SkLibGifCodec_DEFINED
diff --git a/libgifcodec.gni b/libgifcodec.gni
new file mode 100644
index 0000000..aa94603
--- /dev/null
+++ b/libgifcodec.gni
@@ -0,0 +1,14 @@
+# Copyright 2019 Google LLC.
+# Use of this source code is governed by the BSD-3-Clause license that can be
+# found in the LICENSE.md file.
+
+libgifcodec_sources = [
+  "SkGifImageReader.cpp",
+  "SkGifImageReader.h",
+  "SkLibGifCodec.cpp",
+  "SkLibGifCodec.h",
+]
+
+libgifcodec_public = [
+  "SkGifCodec.h",
+]
