diff --git a/native/src/main/jni/image/image.c b/native/src/main/jni/image/image.c index fdebabb49..d9899d4d9 100644 --- a/native/src/main/jni/image/image.c +++ b/native/src/main/jni/image/image.c @@ -1,17 +1,20 @@ /* - * Copyright 2015 Hippo Seven + * Copyright 2022 Tarsin Norbin * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This file is part of EhViewer * - * http://www.apache.org/licenses/LICENSE-2.0 + * EhViewer is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * EhViewer is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * EhViewer. If not, see . */ #include @@ -33,12 +36,14 @@ void decodeCommon(IMAGE *image, SOURCE *src) { image->alpha = AImageDecoderHeaderInfo_getAlphaFlags(headerInfo) == ANDROID_BITMAP_FLAGS_ALPHA_PREMUL; src->stride = AImageDecoder_getMinimumStride(decoder); - image->bufferLen = image->height * src->stride; + image->bufferLen = (int) (image->height * src->stride); image->buffer = malloc(image->bufferLen); if (image->isAnimated) { AImageDecoder_setInternallyHandleDisposePrevious(decoder, false); - src->frameInfo = AImageDecoderFrameInfo_create(); - AImageDecoder_getFrameInfo(decoder, src->frameInfo); + AImageDecoderFrameInfo *frameInfo = AImageDecoderFrameInfo_create(); + AImageDecoder_getFrameInfo(decoder, frameInfo); + image->delay = (int) AImageDecoderFrameInfo_getDuration(frameInfo) / 1000000; + AImageDecoderFrameInfo_delete(frameInfo); } AImageDecoder_decodeImage(decoder, image->buffer, src->stride, image->bufferLen); if (!image->isAnimated) { @@ -47,7 +52,7 @@ void decodeCommon(IMAGE *image, SOURCE *src) { } } -IMAGE *createFromFd(JNIEnv *env, int fd) { +IMAGE *createFromFd(int fd) { AImageDecoder *decoder; AImageDecoder_createFromFd(fd, &decoder); IMAGE *image = calloc(1, sizeof(IMAGE)); @@ -58,7 +63,7 @@ IMAGE *createFromFd(JNIEnv *env, int fd) { return image; } -IMAGE *createFromAddr(JNIEnv *env, void *addr, long size) { +IMAGE *createFromAddr(void *addr, long size) { AImageDecoder *decoder; AImageDecoder_createFromBuffer((const void *) addr, size, &decoder); IMAGE *image = calloc(1, sizeof(IMAGE)); @@ -80,7 +85,7 @@ IMAGE *create(int32_t width, int32_t height, const void *data) { plain->width = width; plain->height = height; plain->buffer = buffer; - plain->bufferLen = length; + plain->bufferLen = (int) length; return plain; } @@ -103,9 +108,3 @@ void advance(IMAGE *image) { } } } - -int get_delay(IMAGE *image) { - if (image->isAnimated) - return (int) AImageDecoderFrameInfo_getDuration(image->src->frameInfo) / 1000000; - return 0; -} diff --git a/native/src/main/jni/image/image.h b/native/src/main/jni/image/image.h index ef3328e8f..17258e360 100644 --- a/native/src/main/jni/image/image.h +++ b/native/src/main/jni/image/image.h @@ -1,17 +1,20 @@ /* - * Copyright 2015 Hippo Seven + * Copyright 2022 Tarsin Norbin * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This file is part of EhViewer * - * http://www.apache.org/licenses/LICENSE-2.0 + * EhViewer is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * EhViewer is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * EhViewer. If not, see . */ #ifndef IMAGE_IMAGE_H @@ -19,15 +22,11 @@ #include #include -#include - -#include "log.h" typedef struct { AImageDecoder *decoder; void *srcBuffer; size_t stride; - AImageDecoderFrameInfo *frameInfo; int fd; } SOURCE; @@ -38,13 +37,13 @@ typedef struct { int bufferLen; bool isAnimated; bool alpha; + int delay; SOURCE *src; } IMAGE; static void recycleSource(SOURCE *src) { if (!src) return; - AImageDecoderFrameInfo_delete(src->frameInfo); AImageDecoder_delete(src->decoder); free(src->srcBuffer); free(src); @@ -58,9 +57,9 @@ static void recycle(IMAGE *image) { free(image); } -IMAGE *createFromFd(JNIEnv *env, int fd); +IMAGE *createFromFd(int fd); -IMAGE *createFromAddr(JNIEnv *env, void *addr, long size); +IMAGE *createFromAddr(void *addr, long size); IMAGE *create(int32_t width, int32_t height, const void *data); @@ -70,6 +69,4 @@ void render(IMAGE *image, int src_x, int src_y, void advance(IMAGE *image); -int get_delay(IMAGE *image); - -#endif //IMAGE_IMAGE_H +#endif /* IMAGE_IMAGE_H */ diff --git a/native/src/main/jni/image/image_utils.h b/native/src/main/jni/image/image_utils.h index 391d2e27b..fe4f6df76 100644 --- a/native/src/main/jni/image/image_utils.h +++ b/native/src/main/jni/image/image_utils.h @@ -26,10 +26,4 @@ bool copy_pixels(const void *src, int src_w, int src_h, int src_x, int src_y, void *dst, int dst_w, int dst_h, int dst_x, int dst_y, int width, int height); -#define STRINGIZE(L) #L -#define MAKESTRING(M, L) M(L) - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -#endif //IMAGE_IMAGE_UTILS_H +#endif /* IMAGE_IMAGE_UTILS_H */ diff --git a/native/src/main/jni/image/java_wrapper.c b/native/src/main/jni/image/java_wrapper.c index de8d28087..20321d57c 100644 --- a/native/src/main/jni/image/java_wrapper.c +++ b/native/src/main/jni/image/java_wrapper.c @@ -17,15 +17,13 @@ #include #include #include +#include #include "java_wrapper.h" #include "image.h" -#include "image_utils.h" #include "log.h" -static JavaVM *jvm; - -static void *tile_buffer; +static void *tile_buffer = NULL; static int jniGetFDFromFileDescriptor(JNIEnv *env, jobject fileDescriptor) { jint fd = -1; @@ -41,54 +39,20 @@ static int jniGetFDFromFileDescriptor(JNIEnv *env, jobject fileDescriptor) { return fd; } -JNIEnv *obtain_env(bool *attach) { - JNIEnv *env; - switch ((*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_6)) { - case JNI_EDETACHED: - if ((*jvm)->AttachCurrentThread(jvm, &env, NULL) == JNI_OK) { - *attach = true; - return env; - } else { - return NULL; - } - case JNI_OK: - *attach = false; - return env; - default: - case JNI_EVERSION: - return NULL; - } -} - -void release_env() { - (*jvm)->DetachCurrentThread(jvm); -} - 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"); - if (constructor == 0) { - LOGE(MSG("Can't find Image object constructor")); - return NULL; - } else { - return (*env)->NewObject(env, image_clazz, constructor, - (jlong) (uintptr_t) ptr, (jint) format, (jint) width, - (jint) height); - } + return (*env)->NewObject(env, image_clazz, constructor, + (jlong) (uintptr_t) ptr, (jint) format, (jint) width, + (jint) height); } JNIEXPORT jobject JNICALL Java_com_hippo_image_Image_nativeDecodeFdInt(JNIEnv *env, jclass clazz, jint fd) { - IMAGE *image; - - image = createFromFd(env, fd); - if (image == NULL) { - return NULL; - } - + IMAGE *image = createFromFd(fd); return create_image_object(env, image, image->isAnimated, image->width, image->height); } @@ -106,10 +70,6 @@ Java_com_hippo_image_Image_nativeCreate(JNIEnv *env, jclass clazz, jobject bitma AndroidBitmap_getInfo(env, bitmap, &info); AndroidBitmap_lockPixels(env, bitmap, &pixels); - if (pixels == NULL) { - LOGE(MSG("Can't lock bitmap pixels")); - return NULL; - } image = create(info.width, info.height, pixels); AndroidBitmap_unlockPixels(env, bitmap); @@ -125,10 +85,6 @@ Java_com_hippo_image_Image_nativeRender(JNIEnv *env, jclass clazz, jlong ptr, ji AndroidBitmap_getInfo(env, dst, &info); AndroidBitmap_lockPixels(env, dst, &pixels); - if (pixels == NULL) { - LOGE(MSG("Can't lock bitmap pixels")); - return; - } render((IMAGE *) ptr, src_x, src_y, pixels, info.width, info.height, dst_x, dst_y, width, height); @@ -160,7 +116,7 @@ Java_com_hippo_image_Image_nativeAdvance(JNIEnv *env, jclass clazz, jlong ptr) { JNIEXPORT jint JNICALL Java_com_hippo_image_Image_nativeGetDelay(JNIEnv *env, jclass clazz, jlong ptr) { - return get_delay((IMAGE *) ptr); + return ((IMAGE *) ptr)->delay; } JNIEXPORT jboolean JNICALL @@ -173,14 +129,12 @@ Java_com_hippo_image_Image_nativeRecycle(JNIEnv *env, jclass clazz, jlong ptr) { recycle((IMAGE *) ptr); } -bool image_onLoad(JavaVM *vm) { - jvm = vm; +bool image_onLoad() { tile_buffer = malloc(IMAGE_TILE_MAX_SIZE * 4); - return true; + return tile_buffer != NULL; } -JNIEXPORT void JNICALL -JNI_OnUnload(JavaVM *vm, void *reserved) { +void image_onUnload() { free(tile_buffer); tile_buffer = NULL; } @@ -188,7 +142,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved) { JNIEXPORT jobject JNICALL Java_com_hippo_image_Image_nativeDecodeAddr(JNIEnv *env, jclass clazz, jlong addr) { Memarea *memarea = (Memarea *) addr; - IMAGE *image = createFromAddr(env, memarea->buffer, memarea->size); + IMAGE *image = createFromAddr(memarea->buffer, memarea->size); free(memarea); return create_image_object(env, image, image->isAnimated, image->width, image->height); } diff --git a/native/src/main/jni/image/java_wrapper.h b/native/src/main/jni/image/java_wrapper.h index b2a5aabbd..a8b7a267f 100644 --- a/native/src/main/jni/image/java_wrapper.h +++ b/native/src/main/jni/image/java_wrapper.h @@ -20,7 +20,6 @@ #ifndef IMAGE_JAVA_WRAPPER_H #define IMAGE_JAVA_WRAPPER_H -#include #include #define IMAGE_TILE_MAX_SIZE (512 * 512) @@ -30,10 +29,8 @@ typedef struct Memarea { long size; } Memarea; -bool image_onLoad(JavaVM *vm); +bool image_onLoad(); -JNIEnv *obtain_env(bool *attach); +void image_onUnload(); -void release_env(); - -#endif // IMAGE_JAVA_WRAPPER_H +#endif /* IMAGE_JAVA_WRAPPER_H */ diff --git a/native/src/main/jni/image/log.h b/native/src/main/jni/image/log.h index 51e94c439..0f52e28bb 100644 --- a/native/src/main/jni/image/log.h +++ b/native/src/main/jni/image/log.h @@ -27,11 +27,4 @@ #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG ,__VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, TAG ,__VA_ARGS__) -#define FILE_LINE MAKESTRING(STRINGIZE, __LINE__ ) -#define MSG(msg) __FILE__ "(" FILE_LINE "): "msg - -#define OUT_OF_MEMORY "Out of memory" - -#define WTF_OM LOGE(MSG(OUT_OF_MEMORY)) - -#endif //LOG_H +#endif /* LOG_H */ diff --git a/native/src/main/jni/main.c b/native/src/main/jni/main.c index 6db6baa92..b8124f906 100644 --- a/native/src/main/jni/main.c +++ b/native/src/main/jni/main.c @@ -39,6 +39,11 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_VERSION_1_6; } +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved) { + image_onUnload(); +} + JNIEXPORT jstring JNICALL Java_com_hippo_Native_getlibarchiveVersion(JNIEnv *env, jclass clazz) { return (*env)->NewStringUTF(env, ARCHIVE_VERSION_STRING);