Implement SkGifCodec::onSkipScanlines()

This should give a performance improvment because we are able to skip
swizzling pixels.

This should also fix valgrind failures caused by color table lookups
with uninitialized memory.

BUG=skia:4270

Review URL: https://codereview.chromium.org/1460073002
diff --git a/src/codec/SkCodec_libgif.cpp b/src/codec/SkCodec_libgif.cpp
index 6550355..8021af9 100644
--- a/src/codec/SkCodec_libgif.cpp
+++ b/src/codec/SkCodec_libgif.cpp
@@ -506,10 +506,36 @@
     return this->prepareToDecode(dstInfo, inputColorPtr, inputColorCount, this->options());
 }
 
+void SkGifCodec::handleScanlineFrame(int count, int* rowsBeforeFrame, int* rowsInFrame) {
+    if (fFrameIsSubset) {
+        const int currRow = this->INHERITED::nextScanline();
+
+        // The number of rows that remain to be skipped before reaching rows that we
+        // actually must decode into.
+        // This must be at least zero.  We also make sure that it is less than or
+        // equal to count, since we will skip at most count rows.
+        *rowsBeforeFrame = SkTMin(count, SkTMax(0, fFrameRect.top() - currRow));
+
+        // Rows left to decode once we reach the start of the frame.
+        const int rowsLeft = count - *rowsBeforeFrame;
+
+        // Count the number of that extend beyond the bottom of the frame.  We do not
+        // need to decode into these rows.
+        const int rowsAfterFrame = SkTMax(0, currRow + rowsLeft - fFrameRect.bottom());
+
+        // Set the actual number of source rows that we need to decode.
+        *rowsInFrame = rowsLeft - rowsAfterFrame;
+    } else {
+        *rowsBeforeFrame = 0;
+        *rowsInFrame = count;
+    }
+}
+
 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
-    int rowsBeforeFrame = 0;
-    int rowsAfterFrame = 0;
-    int rowsInFrame = count;
+    int rowsBeforeFrame;
+    int rowsInFrame;
+    this->handleScanlineFrame(count, &rowsBeforeFrame, &rowsInFrame);
+
     if (fFrameIsSubset) {
         // Fill the requested rows
         SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
@@ -517,15 +543,8 @@
                 this->dstInfo().alphaType());
         fSwizzler->fill(fillInfo, dst, rowBytes, fillValue, this->options().fZeroInitialized);
 
-        // Do nothing for rows before the image frame
-        rowsBeforeFrame = SkTMax(0, fFrameRect.top() - this->INHERITED::nextScanline());
-        rowsInFrame = SkTMax(0, rowsInFrame - rowsBeforeFrame);
+        // Start to write pixels at the start of the image frame
         dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame);
-
-        // Do nothing for rows after the image frame
-        rowsAfterFrame = SkTMax(0,
-                this->INHERITED::nextScanline() + rowsInFrame - fFrameRect.bottom());
-        rowsInFrame = SkTMax(0, rowsInFrame - rowsAfterFrame);
     }
 
     for (int i = 0; i < rowsInFrame; i++) {
@@ -539,6 +558,20 @@
     return count;
 }
 
+bool SkGifCodec::onSkipScanlines(int count) {
+    int rowsBeforeFrame;
+    int rowsInFrame;
+    this->handleScanlineFrame(count, &rowsBeforeFrame, &rowsInFrame);
+
+    for (int i = 0; i < rowsInFrame; i++) {
+        if (!this->readRow()) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const {
     if (fGif->Image.Interlace) {
         return kOutOfOrder_SkScanlineOrder;
diff --git a/src/codec/SkCodec_libgif.h b/src/codec/SkCodec_libgif.h
index 31e0139..200f176 100644
--- a/src/codec/SkCodec_libgif.h
+++ b/src/codec/SkCodec_libgif.h
@@ -150,6 +150,22 @@
 
     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
 
+    bool onSkipScanlines(int count) override;
+
+    /*
+     * For a scanline decode of "count" lines, this function indicates how
+     * many of the "count" lines should be skipped until we reach the top of
+     * the image frame and how many of the "count" lines are actually inside
+     * the image frame.
+     *
+     * @param count           The number of scanlines requested.
+     * @param rowsBeforeFrame Output variable.  The number of lines before
+     *                        we reach the top of the image frame.
+     * @param rowsInFrame     Output variable.  The number of lines to decode
+     *                        inside the image frame.
+     */
+    void handleScanlineFrame(int count, int* rowsBeforeFrame, int* rowsInFrame);
+
     SkScanlineOrder onGetScanlineOrder() const override;
 
     /*