Implement AImageDecoder _advanceFrame and _rewind

Bug: 160984428
Test: Iae7d274b69999c471fd5610c6ef4d148cca81bec

Disallow AImageDecoder_set* methods after the first frame, since
changing the settings would interfere with blending and caching for
kRestorePrevious frames.

Add a cache (and a state machine) for handling kRestorePrevious frames.

Follow-on to Ib93b0ced09fa3cca4a6681745406355c48158fae - support using
a matrix for unpremul + orientation (the orientation was previously
handled by a matrix internally in SkAndroidCodec).

Change-Id: I7c32ede013fa83f1fe95c35778c33278ca6fe6a3
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index 4aeebe4..971ba37 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -173,7 +173,13 @@
             || format > ANDROID_BITMAP_FORMAT_RGBA_F16) {
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
-    return toDecoder(decoder)->setOutColorType(getColorType((AndroidBitmapFormat) format))
+
+    auto* imageDecoder = toDecoder(decoder);
+    if (imageDecoder->currentFrame() != 0) {
+        return ANDROID_IMAGE_DECODER_INVALID_STATE;
+    }
+
+    return imageDecoder->setOutColorType(getColorType((AndroidBitmapFormat) format))
             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
 }
 
@@ -185,6 +191,10 @@
     }
 
     ImageDecoder* imageDecoder = toDecoder(decoder);
+    if (imageDecoder->currentFrame() != 0) {
+        return ANDROID_IMAGE_DECODER_INVALID_STATE;
+    }
+
     imageDecoder->setOutColorSpace(std::move(cs));
     return ANDROID_IMAGE_DECODER_SUCCESS;
 }
@@ -279,7 +289,12 @@
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
 
-    return toDecoder(decoder)->setUnpremultipliedRequired(required)
+    auto* imageDecoder = toDecoder(decoder);
+    if (imageDecoder->currentFrame() != 0) {
+        return ANDROID_IMAGE_DECODER_INVALID_STATE;
+    }
+
+    return imageDecoder->setUnpremultipliedRequired(required)
             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
 }
 
@@ -288,7 +303,12 @@
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
 
-    return toDecoder(decoder)->setTargetSize(width, height)
+    auto* imageDecoder = toDecoder(decoder);
+    if (imageDecoder->currentFrame() != 0) {
+        return ANDROID_IMAGE_DECODER_INVALID_STATE;
+    }
+
+    return imageDecoder->setTargetSize(width, height)
             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_SCALE;
 }
 
@@ -309,10 +329,15 @@
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
 
+    auto* imageDecoder = toDecoder(decoder);
+    if (imageDecoder->currentFrame() != 0) {
+        return ANDROID_IMAGE_DECODER_INVALID_STATE;
+    }
+
     SkIRect cropIRect;
     cropIRect.setLTRB(crop.left, crop.top, crop.right, crop.bottom);
     SkIRect* cropPtr = cropIRect == SkIRect::MakeEmpty() ? nullptr : &cropIRect;
-    return toDecoder(decoder)->setCropRect(cropPtr)
+    return imageDecoder->setCropRect(cropPtr)
             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_BAD_PARAMETER;
 }
 
@@ -341,6 +366,10 @@
         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
     }
 
+    if (imageDecoder->finished()) {
+        return ANDROID_IMAGE_DECODER_FINISHED;
+    }
+
     return ResultToErrorCode(imageDecoder->decode(pixels, stride));
 }
 
@@ -352,7 +381,7 @@
     if (!decoder) return false;
 
     ImageDecoder* imageDecoder = toDecoder(decoder);
-    return imageDecoder->mCodec->codec()->getFrameCount() > 1;
+    return imageDecoder->isAnimated();
 }
 
 int32_t AImageDecoder_getRepeatCount(AImageDecoder* decoder) {
@@ -369,3 +398,34 @@
     }
     return count;
 }
+
+int AImageDecoder_advanceFrame(AImageDecoder* decoder) {
+    if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
+
+    ImageDecoder* imageDecoder = toDecoder(decoder);
+    if (!imageDecoder->isAnimated()) {
+        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
+    }
+
+    if (imageDecoder->advanceFrame()) {
+        return ANDROID_IMAGE_DECODER_SUCCESS;
+    }
+
+    if (imageDecoder->finished()) {
+        return ANDROID_IMAGE_DECODER_FINISHED;
+    }
+
+    return ANDROID_IMAGE_DECODER_INCOMPLETE;
+}
+
+int AImageDecoder_rewind(AImageDecoder* decoder) {
+    if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
+
+    ImageDecoder* imageDecoder = toDecoder(decoder);
+    if (!imageDecoder->isAnimated()) {
+        return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
+    }
+
+    return imageDecoder->rewind() ? ANDROID_IMAGE_DECODER_SUCCESS
+                                  : ANDROID_IMAGE_DECODER_SEEK_ERROR;
+}