diff --git a/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java b/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java index 426ad7233..86bbbc64f 100644 --- a/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java +++ b/app/src/main/java/com/hippo/gl/glrenderer/ImageTexture.java @@ -59,10 +59,10 @@ public class ImageTexture implements Texture { // In this 16ms, we use about 4~8 ms to upload tiles. private static final long UPLOAD_TILE_LIMIT = 4; // ms - private static Bitmap sSmallUploadBitmap; - private static Bitmap sLargeUploadBitmap; - private static InfiniteThreadExecutor sThreadExecutor; - private static PVLock sPVLock; + private static final Bitmap sSmallUploadBitmap; + private static final Bitmap sLargeUploadBitmap; + private static final InfiniteThreadExecutor sThreadExecutor; + private static final PVLock sPVLock; private static Tile sSmallFreeTileHead = null; private static Tile sLargeFreeTileHead = null; @@ -75,6 +75,7 @@ public class ImageTexture implements Texture { private final int mWidth; private final int mHeight; + private final boolean mOpaque; private final RectF mSrcRect = new RectF(); private final RectF mDestRect = new RectF(); @@ -293,6 +294,7 @@ public class ImageTexture implements Texture { mImage = image; int width = mWidth = image.getWidth(); int height = mHeight = image.getHeight(); + boolean opaque = mOpaque = image.isOpaque(); ArrayList list = new ArrayList<>(); for (int x = 0; x < width; x += LARGE_CONTENT_SIZE) { @@ -306,6 +308,7 @@ public class ImageTexture implements Texture { tile.offsetY = y; tile.image = image; tile.setSize(TILE_SMALL, w, Math.min(SMALL_CONTENT_SIZE, h)); + tile.setOpaque(opaque); list.add(tile); int nextHeight = h - SMALL_CONTENT_SIZE; @@ -315,6 +318,7 @@ public class ImageTexture implements Texture { nextTile.offsetY = y + SMALL_CONTENT_SIZE; nextTile.image = image; nextTile.setSize(TILE_SMALL, w, nextHeight); + nextTile.setOpaque(opaque); list.add(nextTile); } } else if (h <= SMALL_CONTENT_SIZE) { @@ -323,6 +327,7 @@ public class ImageTexture implements Texture { tile.offsetY = y; tile.image = image; tile.setSize(TILE_SMALL, Math.min(SMALL_CONTENT_SIZE, w), h); + tile.setOpaque(opaque); list.add(tile); int nextWidth = w - SMALL_CONTENT_SIZE; @@ -332,6 +337,7 @@ public class ImageTexture implements Texture { nextTile.offsetY = y; nextTile.image = image; nextTile.setSize(TILE_SMALL, nextWidth, h); + nextTile.setOpaque(opaque); list.add(nextTile); } } else { @@ -340,6 +346,7 @@ public class ImageTexture implements Texture { tile.offsetY = y; tile.image = image; tile.setSize(TILE_LARGE, w, h); + tile.setOpaque(opaque); list.add(tile); } } @@ -530,7 +537,7 @@ public class ImageTexture implements Texture { @Override public boolean isOpaque() { - return false; + return mOpaque; } public boolean isReady() { diff --git a/app/src/main/java/com/hippo/image/Image.java b/app/src/main/java/com/hippo/image/Image.java index 1a48e6823..24190adc7 100644 --- a/app/src/main/java/com/hippo/image/Image.java +++ b/app/src/main/java/com/hippo/image/Image.java @@ -27,9 +27,9 @@ public class Image { public static final int FORMAT_GIF = 0x02; private long mNativePtr; - private int mFormat; - private int mWidth; - private int mHeight; + private final int mFormat; + private final int mWidth; + private final int mHeight; private Image(long nativePtr, int format, int width, int height) { mNativePtr = nativePtr; @@ -88,6 +88,11 @@ public class Image { return nativeFrameCount(mNativePtr, mFormat); } + public boolean isOpaque() { + checkRecycled(); + return nativeIsOpaque(mNativePtr, mFormat); + } + public void recycle() { if (mNativePtr != 0) { nativeRecycle(mNativePtr, mFormat); @@ -104,9 +109,6 @@ public class Image { } static { - System.loadLibrary("stream"); - System.loadLibrary("jpeg-turbo"); - System.loadLibrary("gif"); System.loadLibrary("image"); } @@ -126,5 +128,7 @@ public class Image { private static native int nativeFrameCount(long nativePtr, int format); + private static native boolean nativeIsOpaque(long nativePtr, int format); + private static native void nativeRecycle(long nativePtr, int format); } diff --git a/app/src/main/jni/giflib/Android.mk b/app/src/main/jni/giflib/Android.mk index 9fd2d998d..666ccd827 100644 --- a/app/src/main/jni/giflib/Android.mk +++ b/app/src/main/jni/giflib/Android.mk @@ -24,4 +24,4 @@ gif_hash.c \ gifalloc.c \ openbsd-reallocarray.c -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_STATIC_LIBRARY) diff --git a/app/src/main/jni/image/Android.mk b/app/src/main/jni/image/Android.mk index cabecfe88..e19763ac8 100644 --- a/app/src/main/jni/image/Android.mk +++ b/app/src/main/jni/image/Android.mk @@ -26,7 +26,6 @@ image_gif.c \ image_utils.c \ java_wrapper.c LOCAL_LDLIBS := -llog -ljnigraphics -LOCAL_STATIC_LIBRARIES := png -LOCAL_SHARED_LIBRARIES := jpeg-turbo png gif stream +LOCAL_STATIC_LIBRARIES := jpeg-turbo png gif stream include $(BUILD_SHARED_LIBRARY) diff --git a/app/src/main/jni/image/image.c b/app/src/main/jni/image/image.c index f8b2674e3..eb2f33ce0 100644 --- a/app/src/main/jni/image/image.c +++ b/app/src/main/jni/image/image.c @@ -289,6 +289,27 @@ int get_frame_count(void* image, int format) } } +bool is_opaque(void* image, int format) +{ + switch (format) { +#ifdef IMAGE_SUPPORT_JPEG + case IMAGE_FORMAT_JPEG: + return JPEG_is_opaque((JPEG*) image); +#endif +#ifdef IMAGE_SUPPORT_PNG + case IMAGE_FORMAT_PNG: + return PNG_is_opaque((PNG*) image); +#endif +#ifdef IMAGE_SUPPORT_GIF + case IMAGE_FORMAT_GIF: + return GIF_is_opaque((GIF*) image); +#endif + default: + LOGE(EMSG("Can't detect format %d"), format); + return false; + } +} + void recycle(void* image, int format) { switch (format) { diff --git a/app/src/main/jni/image/image.h b/app/src/main/jni/image/image.h index fcda16438..e98e3da75 100644 --- a/app/src/main/jni/image/image.h +++ b/app/src/main/jni/image/image.h @@ -48,6 +48,7 @@ bool render(void* image, int format, int src_x, int src_y, void advance(void* image, int format); int get_delay(void* image, int format); int get_frame_count(void* image, int format); +bool is_opaque(void* image, int format); void recycle(void* image, int format); #endif //IMAGE_IMAGE_H diff --git a/app/src/main/jni/image/image_gif.c b/app/src/main/jni/image/image_gif.c index 8f5e47aec..c32ac12b6 100644 --- a/app/src/main/jni/image/image_gif.c +++ b/app/src/main/jni/image/image_gif.c @@ -471,6 +471,11 @@ int GIF_get_frame_count(GIF* gif) return gif->gif_file->ImageCount; } +bool GIF_is_opaque(GIF* gif) +{ + return gif->frame_info_array->tran < 0; +} + void GIF_recycle(GIF* gif) { DGifCloseFile(gif->gif_file, &error_code); diff --git a/app/src/main/jni/image/image_gif.h b/app/src/main/jni/image/image_gif.h index 56847d9b5..3cb621087 100644 --- a/app/src/main/jni/image/image_gif.h +++ b/app/src/main/jni/image/image_gif.h @@ -67,6 +67,7 @@ bool GIF_render(GIF* gif, int src_x, int src_y, void GIF_advance(GIF* gif); int GIF_get_delay(GIF* gif); int GIF_get_frame_count(GIF* gif); +bool GIF_is_opaque(GIF* gif); void GIF_recycle(GIF* gif); #endif // IMAGE_SUPPORT_GIF diff --git a/app/src/main/jni/image/image_jpeg.c b/app/src/main/jni/image/image_jpeg.c index ea0d5f626..2d1655aac 100644 --- a/app/src/main/jni/image/image_jpeg.c +++ b/app/src/main/jni/image/image_jpeg.c @@ -176,6 +176,11 @@ int JPEG_get_frame_count(JPEG* jpeg) return 1; } +bool JPEG_is_opaque(JPEG* jpeg) +{ + return true; +} + void JPEG_recycle(JPEG* jpeg) { free(jpeg->buffer); diff --git a/app/src/main/jni/image/image_jpeg.h b/app/src/main/jni/image/image_jpeg.h index f889d4d3e..197cbb151 100644 --- a/app/src/main/jni/image/image_jpeg.h +++ b/app/src/main/jni/image/image_jpeg.h @@ -49,6 +49,7 @@ bool JPEG_render(JPEG* jpeg, int src_x, int src_y, void JPEG_advance(JPEG* jpeg); int JPEG_get_delay(JPEG* jpeg); int JPEG_get_frame_count(JPEG* jpeg); +bool JPEG_is_opaque(JPEG* jpeg); void JPEG_recycle(JPEG* jpeg); #endif // IMAGE_SUPPORT_JPEG diff --git a/app/src/main/jni/image/image_png.c b/app/src/main/jni/image/image_png.c index 823d45651..b36e88ed1 100644 --- a/app/src/main/jni/image/image_png.c +++ b/app/src/main/jni/image/image_png.c @@ -160,6 +160,7 @@ void* PNG_decode(JNIEnv* env, PatchHeadInputStream* patch_head_input_stream, boo unsigned int height; int color_type; int bit_depth; + bool is_opaque; unsigned char* buffer = NULL; unsigned int frame_count = 0; bool hide_first_frame = false; @@ -271,7 +272,10 @@ void* PNG_decode(JNIEnv* env, PatchHeadInputStream* patch_head_input_stream, boo png_set_gray_to_rgb(png_ptr); } if (!(color_type & PNG_COLOR_MASK_ALPHA)) { + is_opaque = true; png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); + } else { + is_opaque = false; } if (apng) { @@ -316,6 +320,7 @@ void* PNG_decode(JNIEnv* env, PatchHeadInputStream* patch_head_input_stream, boo // Fill PNG png->width = width; png->height = height; + png->is_opaque = is_opaque; png->buffer = buffer; png->apng = true; png->buffer_index = -1; @@ -560,6 +565,11 @@ int PNG_get_frame_count(PNG* png) } } +bool PNG_is_opaque(PNG* png) +{ + return png->is_opaque; +} + void PNG_recycle(PNG* png) { if (png == NULL) { diff --git a/app/src/main/jni/image/image_png.h b/app/src/main/jni/image/image_png.h index 9deb9bfef..da42b006b 100644 --- a/app/src/main/jni/image/image_png.h +++ b/app/src/main/jni/image/image_png.h @@ -53,6 +53,7 @@ typedef struct { unsigned int width; unsigned int height; + bool is_opaque; unsigned char* buffer; bool apng; int buffer_index; @@ -76,6 +77,7 @@ bool PNG_render(PNG* png, int src_x, int src_y, void PNG_advance(PNG* png); int PNG_get_delay(PNG* png); int PNG_get_frame_count(PNG* png); +bool PNG_is_opaque(PNG* png); void PNG_recycle(PNG* png); #endif // IMAGE_SUPPORT_PNG diff --git a/app/src/main/jni/image/java_wrapper.c b/app/src/main/jni/image/java_wrapper.c index 49cc320b6..e4cd62d12 100644 --- a/app/src/main/jni/image/java_wrapper.c +++ b/app/src/main/jni/image/java_wrapper.c @@ -145,6 +145,13 @@ Java_com_hippo_image_Image_nativeFrameCount(JNIEnv* env, return (jint) get_frame_count((void*) (intptr_t) ptr, format); } +JNIEXPORT jboolean JNICALL +Java_com_hippo_image_Image_nativeIsOpaque(JNIEnv* env, + jclass clazz, jlong ptr, jint format) +{ + return (jboolean) is_opaque((void*) (intptr_t) ptr, format); +} + JNIEXPORT void JNICALL Java_com_hippo_image_Image_nativeRecycle(JNIEnv* env, jclass clazz, jlong ptr, jint format) diff --git a/app/src/main/jni/libjpeg-turbo/Android.mk b/app/src/main/jni/libjpeg-turbo/Android.mk index c1b5d7443..712d7f8eb 100644 --- a/app/src/main/jni/libjpeg-turbo/Android.mk +++ b/app/src/main/jni/libjpeg-turbo/Android.mk @@ -124,4 +124,4 @@ else LOCAL_SRC_FILES += jsimd_none.c endif -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_STATIC_LIBRARY) diff --git a/app/src/main/jni/log.h b/app/src/main/jni/log.h index e31747389..9853f7153 100644 --- a/app/src/main/jni/log.h +++ b/app/src/main/jni/log.h @@ -23,7 +23,7 @@ #include -#define TAG "nimingban" +#define TAG "EhViewer" #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG ,__VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG ,__VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG ,__VA_ARGS__) diff --git a/app/src/main/jni/stream/Android.mk b/app/src/main/jni/stream/Android.mk index 3b968060b..0bc2f2a44 100644 --- a/app/src/main/jni/stream/Android.mk +++ b/app/src/main/jni/stream/Android.mk @@ -23,6 +23,5 @@ input_stream_pipe.c \ output_stream.c \ output_stream_pipe.c \ patch_head_input_stream.c -LOCAL_LDLIBS := -llog -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_STATIC_LIBRARY)