Add animation support to SkWebpCodec

TBR=reed@google.com
(No change to the public API, but changed a header file)

SkWebpCodec:
- Implement onGetFrameCount, onGetFrameInfo, and onGetRepetitionCount
- Respect the alpha reported by libwebp. Although the spec states that
  it is only a hint, the libwebp encoder uses it properly. Respecting
  allows us to draw opaque images faster and decode them to 565. This
  also matches other SkCodecs (and Chromium).
- onGetPixels:
  - Decode the frame requested, recursively decoding required frame if
    necessary
  - When blending with a prior frame, use SkRasterPipeline

SkCodec:
- Move check for negative index to getFrameInfo
- Reset the colorXform if one is not needed

SkCodecAnimation:
- Add new blend enum, for WebP's (and APNG's) non-blending option

SkFrameHolder:
- New base classes for frames and the owner of the frames, allowing
  code sharing between SkWebpCodec and SkGifCodec (particularly for
  determining whether a frame has alpha and what frame it depends on)
- When moving items from SkGIFFrameContext, use Skia conventions (i.e.
  int instead of unsigned)
- Rename "delay time" to "duration", to match e.g. SkFrameInfo::
  fDuration

SkGifImageReader:
- Move pieces to SkFrameHolder, and adapt to changes made in the
  process
- Make setAlphaAndRequiredFrame (now on the base class SkFrameHolder)
  more general to support webp, and add support for frames that do not
  blend
- Change SkGIFFrameContext from a struct to a class, to match how we
  use the distinction elsewhere (i.e. struct is a small object with
  public fields)
- Rework hasTransparentPixel (now hasTransparency, since it returns true
  in some cases where there is not a transparent pixel) to better fit
  with the modified setAlphaAndRequiredFrame. Also be more consistent
  when there is no transparent pixel but no color map.
- Simplify an if condition that was previously simplified in 2d61e717
  but accidentally got reverted in a4db9be6

CodecAnimTest:
- Test new animated webp files
- Rearrange the test to more cleanly print alpha type mismatches for
  the first frame

resources:
- webp-animated.webp
  - animated webp from Chromium
- blendBG.webp
  - new webp file using bits of webp-animated-semitransparent4.webp
    from Chromium
  - tests required frame and alpha when using the non-blending mode
  - frames have the following properties:
    - Frame 0: no alpha, fills screen
    - Frame 1: alpha, fills screen
    - Frame 2: no alpha, fills screen
    - Frame 3: alpha, fills screen, blendBG
    - Frame 4: no alpha, fills screen, blendBG
    - Frame 5: alpha, blendBG
    - Frame 6: covers 4, has alpha, blendBG
  - also used to test decoding to 565 if the new frame data has alpha
    but blends onto an opaque frame

DM.cpp:
- Test animated images to non-native 8888 and unpremul

DMSrcSink.cpp:
- Do not test non-native 8888 decodes to f16 dst
- Test unpremul decodes to f16
- Copy a frame of an animated image prior to drawing, since in unpremul
  mode, the DM code will premultiply first.

Bug: skia: 3315
Change-Id: I4e55ae2ee5bc095b37a743bdcfac644be603b980
Reviewed-on: https://skia-review.googlesource.com/16707
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
diff --git a/tests/CodecAnimTest.cpp b/tests/CodecAnimTest.cpp
index 24b9c13..087f5d8 100644
--- a/tests/CodecAnimTest.cpp
+++ b/tests/CodecAnimTest.cpp
@@ -34,11 +34,37 @@
 
 DEF_TEST(Codec_trunc, r) {
     sk_sp<SkData> data(GetResourceAsData("box.gif"));
+    if (!data) {
+        return;
+    }
     data = SkData::MakeSubset(data.get(), 0, 23);
     std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(data));
     codec->getFrameInfo();
 }
 
+// 565 does not support alpha, but there is no reason for it not to support an
+// animated image with a frame that has alpha but then blends onto an opaque
+// frame making the result opaque. Test that we can decode such a frame.
+DEF_TEST(Codec_565, r) {
+    sk_sp<SkData> data(GetResourceAsData("blendBG.webp"));
+    if (!data) {
+        return;
+    }
+    std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(std::move(data)));
+    auto info = codec->getInfo().makeColorType(kRGB_565_SkColorType);
+    SkBitmap bm;
+    bm.allocPixels(info);
+
+    SkCodec::Options options;
+    options.fFrameIndex = 1;
+    options.fHasPriorFrame = false;
+
+    const auto result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(),
+                                         &options, nullptr, nullptr);
+    REPORTER_ASSERT(r, result == SkCodec::kSuccess);
+}
+
+
 DEF_TEST(Codec_frames, r) {
     #define kOpaque     kOpaque_SkAlphaType
     #define kUnpremul   kUnpremul_SkAlphaType
@@ -97,6 +123,12 @@
         { "mandrill.wbmp", 1, {}, {}, {}, 0 },
         { "randPixels.bmp", 1, {}, {}, {}, 0 },
         { "yellow_rose.webp", 1, {}, {}, {}, 0 },
+        { "webp-animated.webp", 3, { 0, 1 }, { kOpaque, kOpaque, kOpaque },
+            { 1000, 500, 1000 }, SkCodec::kRepetitionCountInfinite },
+        { "blendBG.webp", 7, { 0, SkCodec::kNone, SkCodec::kNone, SkCodec::kNone,
+                               3, 3 },
+            { kOpaque, kOpaque, kUnpremul, kOpaque, kUnpremul, kUnpremul },
+            { 525, 500, 525, 437, 609, 729, 444 }, 7 },
     };
     #undef kOpaque
     #undef kUnpremul
@@ -190,17 +222,6 @@
                            rec.fName, i, rec.fDurations[i], frameInfo.fDuration);
                 }
 
-                if (0 == i) {
-                    REPORTER_ASSERT(r, frameInfo.fRequiredFrame == SkCodec::kNone);
-                    REPORTER_ASSERT(r, frameInfo.fAlphaType == codec->getInfo().alphaType());
-                    continue;
-                }
-
-                if (rec.fRequiredFrames[i-1] != frameInfo.fRequiredFrame) {
-                    ERRORF(r, "%s's frame %i has wrong dependency! expected: %i\tactual: %i",
-                           rec.fName, i, rec.fRequiredFrames[i-1], frameInfo.fRequiredFrame);
-                }
-
                 auto to_string = [](SkAlphaType type) {
                     switch (type) {
                         case kUnpremul_SkAlphaType:
@@ -212,12 +233,19 @@
                     }
                 };
 
-                auto expectedAlpha = rec.fAlphaTypes[i-1];
+                auto expectedAlpha = 0 == i ? codec->getInfo().alphaType() : rec.fAlphaTypes[i-1];
                 auto alpha = frameInfo.fAlphaType;
                 if (expectedAlpha != alpha) {
                     ERRORF(r, "%s's frame %i has wrong alpha type! expected: %s\tactual: %s",
                            rec.fName, i, to_string(expectedAlpha), to_string(alpha));
                 }
+
+                if (0 == i) {
+                    REPORTER_ASSERT(r, frameInfo.fRequiredFrame == SkCodec::kNone);
+                } else if (rec.fRequiredFrames[i-1] != frameInfo.fRequiredFrame) {
+                    ERRORF(r, "%s's frame %i has wrong dependency! expected: %i\tactual: %i",
+                           rec.fName, i, rec.fRequiredFrames[i-1], frameInfo.fRequiredFrame);
+                }
             }
 
             if (TestMode::kIndividual == mode) {