Reland "SkAnimatedImage: Use fSampleSize"

This is a reland of 4fdf9f9ce5209cb33bf75eb21023dd014364d57b

No change from the original, which was just reverted to be able to
cleanly revert its parent, which has now been relanded with a fix.

Original change's description:
> SkAnimatedImage: Use fSampleSize
>
> Bug: b/163595585
>
> This will allow using less memory when decoding an animated GIF by
> sampling at decode time. This is tested by the animated_image GMs.
>
> Change-Id: I748b2180827623e4ca1fc0fd4d6dd02733b3b5f2
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/333226
> Commit-Queue: Leon Scroggins <scroggo@google.com>
> Reviewed-by: Derek Sollenberger <djsollen@google.com>

Bug: b/163595585
Change-Id: I3249bd04b64750a50a4c5c787db3e80ac4d85e67
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335279
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
diff --git a/src/android/SkAnimatedImage.cpp b/src/android/SkAnimatedImage.cpp
index 5c35db8..60015ea 100644
--- a/src/android/SkAnimatedImage.cpp
+++ b/src/android/SkAnimatedImage.cpp
@@ -29,18 +29,8 @@
         return nullptr;
     }
 
-    auto scaledSize = requestedInfo.dimensions();
-    auto decodeInfo = requestedInfo;
-    if (codec->getEncodedFormat() != SkEncodedImageFormat::kWEBP
-            || scaledSize.width()  >= decodeInfo.width()
-            || scaledSize.height() >= decodeInfo.height()) {
-        // Only libwebp can decode to arbitrary smaller sizes.
-        auto dims = codec->getInfo().dimensions();
-        decodeInfo = decodeInfo.makeDimensions(dims);
-    }
-
-    auto image = sk_sp<SkAnimatedImage>(new SkAnimatedImage(std::move(codec), scaledSize,
-                decodeInfo, cropRect, std::move(postProcess)));
+    auto image = sk_sp<SkAnimatedImage>(new SkAnimatedImage(std::move(codec), requestedInfo,
+                cropRect, std::move(postProcess)));
     if (!image->fDisplayFrame.fBitmap.getPixels()) {
         // tryAllocPixels failed.
         return nullptr;
@@ -54,32 +44,28 @@
         return nullptr;
     }
 
-    const auto decodeInfo = codec->getInfo();
-    const auto scaledSize = decodeInfo.dimensions();
-    const auto cropRect   = SkIRect::MakeSize(scaledSize);
-    auto image = sk_sp<SkAnimatedImage>(new SkAnimatedImage(std::move(codec), scaledSize,
-                decodeInfo, cropRect, nullptr));
+    const auto& decodeInfo = codec->getInfo();
+    const auto  cropRect   = SkIRect::MakeSize(decodeInfo.dimensions());
+    auto image = Make(std::move(codec), decodeInfo, cropRect, nullptr);
 
-    if (!image->fDisplayFrame.fBitmap.getPixels()) {
-        // tryAllocPixels failed.
-        return nullptr;
-    }
-
-    SkASSERT(image->simple());
+    SkASSERT(!image || image->simple());
     return image;
 }
 
-SkAnimatedImage::SkAnimatedImage(std::unique_ptr<SkAndroidCodec> codec, SkISize scaledSize,
-        SkImageInfo decodeInfo, SkIRect cropRect, sk_sp<SkPicture> postProcess)
+SkAnimatedImage::SkAnimatedImage(std::unique_ptr<SkAndroidCodec> codec,
+        const SkImageInfo& requestedInfo, SkIRect cropRect, sk_sp<SkPicture> postProcess)
     : fCodec(std::move(codec))
-    , fDecodeInfo(decodeInfo)
+    , fDecodeInfo(requestedInfo)
     , fCropRect(cropRect)
     , fPostProcess(std::move(postProcess))
     , fFrameCount(fCodec->codec()->getFrameCount())
+    , fSampleSize(1)
     , fFinished(false)
     , fRepetitionCount(fCodec->codec()->getRepetitionCount())
     , fRepetitionsCompleted(0)
 {
+    auto scaledSize = requestedInfo.dimensions();
+
     // For simplicity in decoding and compositing frames, decode directly to a size and
     // orientation that fCodec can do directly, and then use fMatrix to handle crop (along with a
     // clip), orientation, and scaling outside of fCodec. The matrices are computed individually
@@ -100,6 +86,11 @@
             scaledSize = { scaledSize.height(), scaledSize.width() };
         }
     }
+
+    auto decodeSize = scaledSize;
+    fSampleSize = fCodec->computeSampleSize(&decodeSize);
+    fDecodeInfo = fDecodeInfo.makeDimensions(decodeSize);
+
     if (!fDecodingFrame.fBitmap.tryAllocPixels(fDecodeInfo)) {
         return;
     }
@@ -255,7 +246,8 @@
     // for frame |i+1|.
     // We could be even smarter about which frames to save by looking at the
     // entire dependency chain.
-    SkCodec::Options options;
+    SkAndroidCodec::AndroidOptions options;
+    options.fSampleSize = fSampleSize;
     options.fFrameIndex = frameToDecode;
     if (frameInfo.fRequiredFrame == SkCodec::kNoFrame) {
         if (is_restore_previous(frameInfo.fDisposalMethod)) {
@@ -310,8 +302,8 @@
         return this->finish();
     }
 
-    auto result = fCodec->codec()->getPixels(dst->info(), dst->getPixels(), dst->rowBytes(),
-                                             &options);
+    auto result = fCodec->getAndroidPixels(dst->info(), dst->getPixels(), dst->rowBytes(),
+                                           &options);
     if (result != SkCodec::kSuccess) {
         SkCodecPrintf("error %i, frame %i of %i\n", result, frameToDecode, fFrameCount);
         return this->finish();