Reland "SkAndroidCodec: Support decoding all frames"

This is a reland of fc4fdc5b25f448dd9c2cd4e445561a840ce8514b

Original change's description:
> SkAndroidCodec: Support decoding all frames
>
> Bug: b/160984428
> Bug: b/163595585
>
> Add support to SkAndroidCodec for decoding all frames with an
> fSampleSize, so that an entire animation can be decoded to a smaller
> size.
>
> dm/:
> - Test scaled + animated decodes
>
> SkAndroidCodec:
> - Make AndroidOptions inherit from SkCodec::Options. This allows
>   SkAndroidCodec to use fFrameIndex. (It also combines the two versions
>   of fSubset, which is now const for both.)
> - Respect fFrameIndex, and call SkCodec::handleFrameIndex to decode
>   the required frame.
> - Disallow decoding with kRespect + fFrameIndex > 0 if there is a
>   non-default orientation. As currently written (except without
>   disabling this combination), SkPixmapPriv::Orient would draw the new
>   portion of the frame on top of uninitialized pixels, instead of the
>   prior frame. This could be fixed by
>   - If SkAndroidCodec needs to decode the required frame, it could do so
>     without applying the orientation, then decode fFrameIndex, and then
>     apply the orientation.
>   - If the client provided the required frame, SkAndroidCodec would need
>     to un-apply the orientation to get the proper starting state, then
>     decode and apply.
>   I think it is simpler to force the client to handle the orientation
>   externally.
>
> SkCodec:
> - Allow SkAndroidCodec to call its private method handleFrameIndex. This
>   method handles decoding a required frame, if necessary. When called by
>   SkAndroidCodec, it now uses the SkAndroidCodec to check for/decode the
>   required frame, so that it will scale properly.
> - Call rewindIfNeeded inside handleFrameIndex. handleFrameIndex calls a
>   virtual method which may set some state (e.g. in SkJpegCodec). Without
>   this change, that state would be reset by rewindIfNeeded.
> - Simplify handling a kRestoreBGColor frame. Whether provided or not,
>   take the same path to calling zero_rect.
> - Updates to zero_rect:
>   - Intersect after scaling, which will also check for empty.
>   - Round out instead of in - this ensures we don't under-erase
>   - Use kFill_ScaleToFit, which better matches the intent.
>
> Change-Id: Ibe1951980a0dca8f5b7b1f20192432d395681683
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/333225
> Commit-Queue: Leon Scroggins <scroggo@google.com>
> Reviewed-by: Derek Sollenberger <djsollen@google.com>

Bug: b/160984428
Bug: b/163595585
Change-Id: I7c1e79e0f92c75b4840eef65c8fc2b8497189e81
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/334842
Auto-Submit: Leon Scroggins <scroggo@google.com>
Commit-Queue: Derek Sollenberger <djsollen@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp
index b7878df..f995c2e 100644
--- a/src/codec/SkAndroidCodec.cpp
+++ b/src/codec/SkAndroidCodec.cpp
@@ -372,21 +372,35 @@
     AndroidOptions defaultOptions;
     if (!options) {
         options = &defaultOptions;
-    } else if (options->fSubset) {
-        if (!is_valid_subset(*options->fSubset, adjustedInfo.dimensions())) {
-            return SkCodec::kInvalidParameters;
+    } else {
+        if (options->fSubset) {
+            if (!is_valid_subset(*options->fSubset, adjustedInfo.dimensions())) {
+                return SkCodec::kInvalidParameters;
+            }
+
+            if (SkIRect::MakeSize(adjustedInfo.dimensions()) == *options->fSubset) {
+                // The caller wants the whole thing, rather than a subset. Modify
+                // the AndroidOptions passed to onGetAndroidPixels to not specify
+                // a subset.
+                defaultOptions = *options;
+                defaultOptions.fSubset = nullptr;
+                options = &defaultOptions;
+            }
         }
 
-        if (SkIRect::MakeSize(adjustedInfo.dimensions()) == *options->fSubset) {
-            // The caller wants the whole thing, rather than a subset. Modify
-            // the AndroidOptions passed to onGetAndroidPixels to not specify
-            // a subset.
-            defaultOptions = *options;
-            defaultOptions.fSubset = nullptr;
-            options = &defaultOptions;
+        // To simplify frame compositing, force the client to use kIgnore and
+        // handle orientation themselves.
+        if (options->fFrameIndex != 0 && fOrientationBehavior == ExifOrientationBehavior::kRespect
+                && fCodec->getOrigin() != kDefault_SkEncodedOrigin) {
+            return SkCodec::kInvalidParameters;
         }
     }
 
+    if (auto result = fCodec->handleFrameIndex(requestInfo, requestPixels, requestRowBytes,
+            *options, this); result != SkCodec::kSuccess) {
+        return result;
+    }
+
     if (ExifOrientationBehavior::kIgnore == fOrientationBehavior) {
         return this->onGetAndroidPixels(requestInfo, requestPixels, requestRowBytes, *options);
     }