android_jni: Support RGBA_F16 Bitmaps
libavif now supports conversion of RGBA pixels into F16 formats
for AVIF images with depths 10 and 12. Make use of that feature to
support RGBA_F16 bitmaps on the android JNI wrapper.
Note that apps can still pass an ARGB_8888 Bitmap for 10/12 bit
images and the wrapper will merely downscale them to 8 bits in that
case (existing behavior). Also as an added behavior, apps can now
pass RGBA_F16 bitmap for 8-bit images as well since libavif supports
converting 8-bit RGBA pixels to 16-bit half floats.
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 bed181a..5baede3 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
@@ -20,10 +20,11 @@
// This is a utility class and cannot be instantiated.
private AvifDecoder() {}
- /** Contains information about the AVIF Image dimensions. */
+ /** Contains information about the AVIF Image. */
public static class Info {
public int width;
public int height;
+ public int depth;
}
/**
diff --git a/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc b/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
index 24a5fc0..2ad5284 100644
--- a/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
+++ b/android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
@@ -23,6 +23,7 @@
jfieldID global_info_width;
jfieldID global_info_height;
+jfieldID global_info_depth;
// RAII wrapper class that properly frees the decoder related objects on
// destruction.
@@ -75,6 +76,7 @@
env->FindClass("org/aomedia/avif/android/AvifDecoder$Info");
global_info_width = env->GetFieldID(info_class, "width", "I");
global_info_height = env->GetFieldID(info_class, "height", "I");
+ global_info_depth = env->GetFieldID(info_class, "depth", "I");
return JNI_VERSION_1_6;
}
@@ -94,6 +96,7 @@
}
env->SetIntField(info, global_info_width, decoder.decoder->image->width);
env->SetIntField(info, global_info_height, decoder.decoder->image->height);
+ env->SetIntField(info, global_info_depth, decoder.decoder->image->depth);
return true;
}
@@ -124,8 +127,9 @@
decoder.decoder->image->height);
return false;
}
- // Ensure that the bitmap format is RGBA_8888. For now, we only support that.
- if (bitmap_info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
+ // Ensure that the bitmap format is either RGBA_8888 or RGBA_F16.
+ if (bitmap_info.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
+ bitmap_info.format != ANDROID_BITMAP_FORMAT_RGBA_F16) {
LOGE("Bitmap format (%d) is not supported.", bitmap_info.format);
return false;
}
@@ -137,8 +141,12 @@
}
avifRGBImage rgb_image;
avifRGBImageSetDefaults(&rgb_image, decoder.decoder->image);
- // For now, we only support 8 bit RGBA output.
- rgb_image.depth = 8;
+ if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGBA_F16) {
+ rgb_image.depth = 16;
+ rgb_image.isFloat = AVIF_TRUE;
+ } else {
+ rgb_image.depth = 8;
+ }
rgb_image.pixels = static_cast<uint8_t*>(bitmap_pixels);
rgb_image.rowBytes = bitmap_info.stride;
res = avifImageYUVToRGB(decoder.decoder->image, &rgb_image);