Skip to content

Commit

Permalink
Add Image scale
Browse files Browse the repository at this point in the history
  • Loading branch information
WizzXu committed Oct 9, 2023
1 parent 663e45b commit bed76d9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public static boolean isAvifImage(ByteBuffer buffer) {
* was not valid AVIF. 2) Bitmap was not large enough to store the decoded image.
*/
public static boolean decode(ByteBuffer encoded, int length, Bitmap bitmap) {
return decode(encoded, length, bitmap, 0);
return decode(encoded, length, bitmap, 0, false);
}

/**
Expand All @@ -110,11 +110,12 @@ public static boolean decode(ByteBuffer encoded, int length, Bitmap bitmap) {
* cores as the thread count. Negative values are invalid. When this value is > 0, it is
* simply mapped to the maxThreads parameter in libavif. For more details, see the
* documentation for maxThreads variable in avif.h.
* @param isScale
* @return true on success and false on failure. A few possible reasons for failure are: 1) Input
* was not valid AVIF. 2) Bitmap was not large enough to store the decoded image. 3) Negative
* value was passed for the threads parameter.
*/
public static native boolean decode(ByteBuffer encoded, int length, Bitmap bitmap, int threads);
public static native boolean decode(ByteBuffer encoded, int length, Bitmap bitmap, int threads, boolean isScale);

/** Get the width of the image. */
public int getWidth() {
Expand Down
32 changes: 25 additions & 7 deletions android_jni/avifandroidjni/src/main/jni/libavif_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ bool CreateDecoderAndParse(AvifDecoderWrapper* const decoder,

avifResult AvifImageToBitmap(JNIEnv* const env,
AvifDecoderWrapper* const decoder,
jobject bitmap) {
jobject bitmap, jboolean isScale) {
AndroidBitmapInfo bitmap_info;
if (AndroidBitmap_getInfo(env, bitmap, &bitmap_info) < 0) {
LOGE("AndroidBitmap_getInfo failed.");
return AVIF_RESULT_UNKNOWN_ERROR;
}
// Ensure that the bitmap is large enough to store the decoded image.
if (bitmap_info.width < decoder->crop.width ||
bitmap_info.height < decoder->crop.height) {
if (!isScale && (bitmap_info.width < decoder->crop.width ||
bitmap_info.height < decoder->crop.height)) {
LOGE(
"Bitmap is not large enough to fit the image. Bitmap %dx%d Image "
"%dx%d.",
Expand Down Expand Up @@ -146,6 +146,14 @@ avifResult AvifImageToBitmap(JNIEnv* const env,
}
image = cropped_image.get();
}
if (isScale) {
res = avifImageScale(image, bitmap_info.width, bitmap_info.height, &decoder->decoder->diag);
if (res != AVIF_RESULT_OK) {
LOGE("Failed to scale image. Status: %d", res);
return res;
}
}

avifRGBImage rgb_image;
avifRGBImageSetDefaults(&rgb_image, image);
if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGBA_F16) {
Expand Down Expand Up @@ -179,7 +187,17 @@ avifResult DecodeNextImage(JNIEnv* const env, AvifDecoderWrapper* const decoder,
LOGE("Failed to decode AVIF image. Status: %d", res);
return res;
}
return AvifImageToBitmap(env, decoder, bitmap);
return AvifImageToBitmap(env, decoder, bitmap, false);
}

avifResult DecodeNextImage(JNIEnv* const env, AvifDecoderWrapper* const decoder,
jobject bitmap, jboolean isScale) {
avifResult res = avifDecoderNextImage(decoder->decoder);
if (res != AVIF_RESULT_OK) {
LOGE("Failed to decode AVIF image. Status: %d", res);
return res;
}
return AvifImageToBitmap(env, decoder, bitmap, isScale);
}

avifResult DecodeNthImage(JNIEnv* const env, AvifDecoderWrapper* const decoder,
Expand All @@ -189,7 +207,7 @@ avifResult DecodeNthImage(JNIEnv* const env, AvifDecoderWrapper* const decoder,
LOGE("Failed to decode AVIF image. Status: %d", res);
return res;
}
return AvifImageToBitmap(env, decoder, bitmap);
return AvifImageToBitmap(env, decoder, bitmap, false);
}

int getThreadCount(int threads) {
Expand Down Expand Up @@ -265,7 +283,7 @@ FUNC(jboolean, getInfo, jobject encoded, int length, jobject info) {
}

FUNC(jboolean, decode, jobject encoded, int length, jobject bitmap,
jint threads) {
jint threads, jboolean isScale) {
if (threads < 0) {
LOGE("Invalid value for threads (%d).", threads);
return false;
Expand All @@ -277,7 +295,7 @@ FUNC(jboolean, decode, jobject encoded, int length, jobject bitmap,
getThreadCount(threads))) {
return false;
}
return DecodeNextImage(env, &decoder, bitmap) == AVIF_RESULT_OK;
return DecodeNextImage(env, &decoder, bitmap, isScale) == AVIF_RESULT_OK;
}

FUNC(jlong, createDecoder, jobject encoded, jint length, jint threads) {
Expand Down

0 comments on commit bed76d9

Please sign in to comment.