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);