android_jni: Expose avifResultToString in the JNI API

GOOGLE_INTERNAL_CL: 525828164
diff --git a/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/AnimatedImageTest.java b/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/AnimatedImageTest.java
index 8fac08a..20e1c23 100644
--- a/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/AnimatedImageTest.java
+++ b/android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/AnimatedImageTest.java
@@ -130,6 +130,12 @@
     decoder.release();
   }
 
+  @Test
+  public void testResultToString() throws IOException {
+    // Test the avifResult value whose value and string representations are least likely to change.
+    assertThat(AvifDecoder.resultToString(AVIF_RESULT_OK)).isEqualTo("OK");
+  }
+
   private ByteBuffer getBuffer() throws IOException {
     Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
     String assetPath = Paths.get(ASSET_DIRECTORY, image.filename).toString();
diff --git a/android_jni/avifandroidjni/src/main/java/org/aomedia/avif/android/AvifDecoder.java b/android_jni/avifandroidjni/src/main/java/org/aomedia/avif/android/AvifDecoder.java
index db8eee5..09caebf 100644
--- a/android_jni/avifandroidjni/src/main/java/org/aomedia/avif/android/AvifDecoder.java
+++ b/android_jni/avifandroidjni/src/main/java/org/aomedia/avif/android/AvifDecoder.java
@@ -196,7 +196,9 @@
    *
    * @param bitmap The decoded pixels will be copied into the bitmap.
    * @return 0 (AVIF_RESULT_OK) on success and some other avifStatus on failure. For a list of all
-   *     possible status codes, see the avifResult enum on avif.h in libavif's C source code.
+   *     possible status codes, see the avifResult enum on avif.h in libavif's C source code. A
+   *     String describing the return value can be obtained by calling {@link resultToString} with
+   *     the return value of this function.
    */
   public int nextFrame(Bitmap bitmap) {
     return nextFrame(decoder, bitmap);
@@ -224,7 +226,9 @@
    * @param bitmap The decoded pixels will be copied into the bitmap.
    * @param n The zero-based index of the frame to be decoded.
    * @return 0 (AVIF_RESULT_OK) on success and some other avifStatus on failure. For a list of all
-   *     possible status codes, see the avifResult enum on avif.h in libavif's C source code.
+   *     possible status codes, see the avifResult enum on avif.h in libavif's C source code. A
+   *     String describing the return value can be obtained by calling {@link resultToString} with
+   *     the return value of this function.
    */
   public int nthFrame(int n, Bitmap bitmap) {
     return nthFrame(decoder, n, bitmap);
@@ -232,6 +236,15 @@
 
   private native int nthFrame(long decoder, int n, Bitmap bitmap);
 
+  /**
+   * Returns a String describing an avifResult enum value.
+   *
+   * @param result The avifResult value. Typically this is the return value of {@link nextFrame} or
+   *     {@link nthFrame}.
+   * @return A String containing the description of the avifResult.
+   */
+  public static native String resultToString(int result);
+
   private native long createDecoder(ByteBuffer encoded, int length, int threads);
 
   private native void destroyDecoder(long decoder);
diff --git a/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc b/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
index f6901b2..bbbffc6 100644
--- a/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
+++ b/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
@@ -291,6 +291,10 @@
   return DecodeNthImage(env, decoder, n, bitmap);
 }
 
+FUNC(jstring, resultToString, jint result) {
+  return env->NewStringUTF(avifResultToString(static_cast<avifResult>(result)));
+}
+
 FUNC(void, destroyDecoder, jlong jdecoder) {
   AvifDecoderWrapper* const decoder =
       reinterpret_cast<AvifDecoderWrapper*>(jdecoder);