diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 7c19ecae2..405eeff53 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -34,4 +34,3 @@ -dontwarn org.openjsse.net.ssl.OpenJSSE -keepclasseswithmembernames class * { native ;} --keepclassmembers class com.hippo.image.Image {private (long, int, int, int);} diff --git a/app/src/main/cpp/image/image.c b/app/src/main/cpp/image/image.c index 266ad38eb..219560b46 100644 --- a/app/src/main/cpp/image/image.c +++ b/app/src/main/cpp/image/image.c @@ -83,6 +83,7 @@ IMAGE *create(int32_t width, int32_t height, const void *data) { buffer = malloc(length); memcpy(buffer, data, length); + // plain->isAnimated = false; this is unnecessary since we use calloc plain->width = width; plain->height = height; plain->buffer = buffer; diff --git a/app/src/main/cpp/image/java_wrapper.c b/app/src/main/cpp/image/java_wrapper.c index 38cc4c1e0..61010dce6 100644 --- a/app/src/main/cpp/image/java_wrapper.c +++ b/app/src/main/cpp/image/java_wrapper.c @@ -39,32 +39,19 @@ static int jniGetFDFromFileDescriptor(JNIEnv *env, jobject fileDescriptor) { return fd; } -jobject create_image_object(JNIEnv *env, void *ptr, int format, int width, int height) { - jclass image_clazz; - jmethodID constructor; - - image_clazz = (*env)->FindClass(env, "com/hippo/image/Image"); - constructor = (*env)->GetMethodID(env, image_clazz, "", "(JIII)V"); - return (*env)->NewObject(env, image_clazz, constructor, - (jlong) (uintptr_t) ptr, (jint) format, (jint) width, - (jint) height); -} - -JNIEXPORT jobject JNICALL +JNIEXPORT jlong JNICALL Java_com_hippo_image_Image_nativeDecodeFdInt(JNIEnv *env, jclass clazz, jint fd) { IMAGE *image = createFromFd(fd); - if (!image) - return NULL; - return create_image_object(env, image, image->isAnimated, image->width, image->height); + return (jlong) image; } -JNIEXPORT jobject JNICALL +JNIEXPORT jlong JNICALL Java_com_hippo_image_Image_nativeDecode(JNIEnv *env, jclass clazz, jobject fd) { return Java_com_hippo_image_Image_nativeDecodeFdInt(env, clazz, jniGetFDFromFileDescriptor(env, fd)); } -JNIEXPORT jobject JNICALL +JNIEXPORT jlong JNICALL Java_com_hippo_image_Image_nativeCreate(JNIEnv *env, jclass clazz, jobject bitmap) { AndroidBitmapInfo info; void *pixels = NULL; @@ -75,7 +62,7 @@ Java_com_hippo_image_Image_nativeCreate(JNIEnv *env, jclass clazz, jobject bitma image = create(info.width, info.height, pixels); AndroidBitmap_unlockPixels(env, bitmap); - return create_image_object(env, image, 0, info.width, info.height); + return (jlong) image; } JNIEXPORT void JNICALL @@ -141,10 +128,25 @@ void image_onUnload() { tile_buffer = NULL; } -JNIEXPORT jobject JNICALL +JNIEXPORT jlong JNICALL Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr) { Memarea *memarea = (Memarea *) addr; IMAGE *image = createFromAddr(memarea->buffer, memarea->size); free(memarea); - return create_image_object(env, image, image->isAnimated, image->width, image->height); + return (jlong) image; +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetFormat(JNIEnv *env, jclass clazz, jlong native_ptr) { + return ((IMAGE *) native_ptr)->isAnimated; +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetWidth(JNIEnv *env, jclass clazz, jlong native_ptr) { + return ((IMAGE *) native_ptr)->width; +} + +JNIEXPORT jint JNICALL +Java_com_hippo_image_Image_nativeGetHeight(JNIEnv *env, jclass clazz, jlong native_ptr) { + return ((IMAGE *) native_ptr)->height; } diff --git a/app/src/main/java/com/hippo/image/Image.java b/app/src/main/java/com/hippo/image/Image.java index f962a0dc4..772ef2f4f 100644 --- a/app/src/main/java/com/hippo/image/Image.java +++ b/app/src/main/java/com/hippo/image/Image.java @@ -28,29 +28,24 @@ import java.util.ArrayList; */ public final class Image { public static final int FORMAT_NORMAL = 0; - public static final int FORMAT_ANIMATED = 1; - private static final ArrayList imageList = new ArrayList<>(); private static boolean needEvictAll = false; - - private final int mFormat; - private final int mWidth; - private final int mHeight; private long mNativePtr; - private Image(long nativePtr, int format, int width, int height) { + private Image(long nativePtr) { if (needEvictAll) evictAll(); - mNativePtr = nativePtr; - mFormat = format; - mWidth = width; - mHeight = height; - imageList.add(this); } + private static Image newFromAddr(long addr) { + if (addr == 0) + return null; + return new Image(addr); + } + public static void lazyEvictAll() { needEvictAll = true; } @@ -65,7 +60,7 @@ public final class Image { */ @Nullable public static Image decode(FileDescriptor fd, boolean partially) { - return nativeDecode(fd); + return newFromAddr(nativeDecode(fd)); } /** @@ -73,7 +68,7 @@ public final class Image { */ @Nullable public static Image decode(Integer fd, boolean partially) { - return nativeDecodeFdInt(fd); + return newFromAddr(nativeDecodeFdInt(fd)); } /** @@ -81,7 +76,7 @@ public final class Image { */ @Nullable public static Image decodeAddr(Long addr, boolean partially) { - return nativeDecodeAddr(addr); + return newFromAddr(nativeDecodeAddr(addr)); } /** @@ -89,7 +84,7 @@ public final class Image { */ @Nullable public static Image create(Bitmap bitmap) { - return nativeCreate(bitmap); + return newFromAddr(nativeCreate(bitmap)); } /** @@ -100,13 +95,13 @@ public final class Image { return imageList.size(); } - private static native Image nativeDecode(FileDescriptor fd); + private static native long nativeDecode(FileDescriptor fd); - private static native Image nativeDecodeFdInt(int fd); + private static native long nativeDecodeFdInt(int fd); - private static native Image nativeDecodeAddr(long addr); + private static native long nativeDecodeAddr(long addr); - private static native Image nativeCreate(Bitmap bitmap); + private static native long nativeCreate(Bitmap bitmap); private static native void nativeRender(long nativePtr, int srcX, int srcY, Bitmap dst, int dstX, int dstY, @@ -122,25 +117,34 @@ public final class Image { private static native void nativeRecycle(long nativePtr); + private static native int nativeGetFormat(long nativePtr); + + private static native int nativeGetWidth(long nativePtr); + + private static native int nativeGetHeight(long nativePtr); + /** * Return the format of the image */ public int getFormat() { - return mFormat; + checkRecycled(); + return nativeGetFormat(mNativePtr); } /** * Return the width of the image */ public int getWidth() { - return mWidth; + checkRecycled(); + return nativeGetWidth(mNativePtr); } /** * Return the height of the image */ public int getHeight() { - return mHeight; + checkRecycled(); + return nativeGetHeight(mNativePtr); } private void checkRecycled() {