diff --git a/app/src/main/java/com/hippo/ehviewer/ImageBitmapHelper.java b/app/src/main/java/com/hippo/ehviewer/ImageBitmapHelper.java index 5e4aefed2..9c658b78b 100644 --- a/app/src/main/java/com/hippo/ehviewer/ImageBitmapHelper.java +++ b/app/src/main/java/com/hippo/ehviewer/ImageBitmapHelper.java @@ -16,6 +16,8 @@ package com.hippo.ehviewer; +import android.os.ParcelFileDescriptor; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -23,7 +25,9 @@ import com.hippo.conaco.ValueHelper; import com.hippo.image.ImageBitmap; import com.hippo.streampipe.InputStreamPipe; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; public class ImageBitmapHelper implements ValueHelper { @@ -34,7 +38,8 @@ public class ImageBitmapHelper implements ValueHelper { public ImageBitmap decode(@NonNull InputStreamPipe isPipe) { try { isPipe.obtain(); - return ImageBitmap.decode(isPipe.open()); + FileInputStream is = (FileInputStream) isPipe.open(); + return ImageBitmap.decode(is.getFD()); } catch (OutOfMemoryError | IOException e) { return null; } finally { diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java index d0025378a..ef0aa77ae 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/ArchiveGalleryProvider.java @@ -34,6 +34,9 @@ import com.hippo.unifile.UniFile; import com.hippo.yorozuya.thread.PVLock; import com.hippo.yorozuya.thread.PriorityThread; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.LinkedHashMap; @@ -50,7 +53,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 { private final UriArchiveAccessor archiveAccessor; private final Stack requests = new Stack<>(); private final AtomicInteger extractingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); - private final LinkedHashMap streams = new LinkedHashMap<>(); + private final LinkedHashMap streams = new LinkedHashMap<>(); private final AtomicInteger decodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); private Thread archiveThread; private Thread decodeThread; @@ -256,7 +259,11 @@ public class ArchiveGalleryProvider extends GalleryProvider2 { if (streams.get(index) != null) { continue; } - streams.put(index, pipe.getInputStream()); + try { + streams.put(index, ((FileInputStream)pipe.getInputStream()).getFD()); + } catch (IOException e) { + e.printStackTrace(); + } streams.notify(); } @@ -271,7 +278,7 @@ public class ArchiveGalleryProvider extends GalleryProvider2 { public void run() { while (!Thread.currentThread().isInterrupted()) { int index; - Integer fd; + FileDescriptor fd; synchronized (streams) { if (streams.isEmpty()) { try { @@ -283,8 +290,8 @@ public class ArchiveGalleryProvider extends GalleryProvider2 { continue; } - Iterator> iterator = streams.entrySet().iterator(); - Map.Entry entry = iterator.next(); + Iterator> iterator = streams.entrySet().iterator(); + Map.Entry entry = iterator.next(); iterator.remove(); index = entry.getKey(); fd = entry.getValue(); diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java index 533184ec0..416aa024b 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java @@ -34,6 +34,7 @@ import com.hippo.yorozuya.IOUtils; import com.hippo.yorozuya.StringUtils; import com.hippo.yorozuya.thread.PriorityThread; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -258,7 +259,7 @@ public class DirGalleryProvider extends GalleryProvider2 implements Runnable { InputStream is = null; try { is = files[index].openInputStream(); - Image image = Image.decode(is, true); + Image image = Image.decode(((FileInputStream)is).getFD(), true); mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); if (image != null) { notifyPageSucceed(index, image); diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java index e531842a6..1b5f949a7 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java @@ -66,6 +66,7 @@ import com.hippo.yorozuya.thread.PriorityThread; import com.hippo.yorozuya.thread.PriorityThreadFactory; import java.io.BufferedInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -1703,7 +1704,12 @@ public final class SpiderQueen implements Runnable { } if (is != null) { - image = Image.decode(is, true); + try { + image = Image.decode(((FileInputStream)is).getFD(), true); + } catch (IOException e) { + e.printStackTrace(); + image = null; + } if (image == null) { error = GetText.getString(R.string.error_decoding_failed); } diff --git a/native/src/main/java/com/hippo/image/Image.java b/native/src/main/java/com/hippo/image/Image.java index a3a715c00..09e5d7370 100644 --- a/native/src/main/java/com/hippo/image/Image.java +++ b/native/src/main/java/com/hippo/image/Image.java @@ -21,6 +21,7 @@ import android.graphics.Bitmap; import androidx.annotation.Nullable; import java.io.BufferedInputStream; +import java.io.FileDescriptor; import java.io.InputStream; import java.util.concurrent.atomic.AtomicInteger; @@ -52,7 +53,7 @@ public final class Image { * Decode image from {@code InputStream} */ @Nullable - public static Image decode(Integer fd, boolean partially) { + public static Image decode(FileDescriptor fd, boolean partially) { return nativeDecode(fd, partially); } @@ -72,7 +73,7 @@ public final class Image { return sImageCount.get(); } - private static native Image nativeDecode(int fd, boolean partially); + private static native Image nativeDecode(FileDescriptor fd, boolean partially); private static native Image nativeCreate(Bitmap bitmap); diff --git a/native/src/main/java/com/hippo/image/ImageBitmap.java b/native/src/main/java/com/hippo/image/ImageBitmap.java index 9639975cb..509807b1d 100644 --- a/native/src/main/java/com/hippo/image/ImageBitmap.java +++ b/native/src/main/java/com/hippo/image/ImageBitmap.java @@ -28,6 +28,7 @@ import android.os.Looper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import java.io.FileDescriptor; import java.io.InputStream; import java.lang.ref.WeakReference; import java.util.Iterator; @@ -84,7 +85,7 @@ public final class ImageBitmap implements Animatable, Runnable { * Decode {@code InputStream}, then create image. */ @Nullable - public static ImageBitmap decode(@NonNull Integer fd) { + public static ImageBitmap decode(@NonNull FileDescriptor fd) { Image image = Image.decode(fd, false); if (image != null) { return create(image); diff --git a/native/src/main/jni/image/java_wrapper.c b/native/src/main/jni/image/java_wrapper.c index b10992e1d..f226edb26 100644 --- a/native/src/main/jni/image/java_wrapper.c +++ b/native/src/main/jni/image/java_wrapper.c @@ -30,6 +30,20 @@ static JavaVM* jvm; static void* tile_buffer; +static int jniGetFDFromFileDescriptor(JNIEnv * env, jobject fileDescriptor) { + jint fd = -1; + jclass fdClass = (*env)->FindClass(env, "java/io/FileDescriptor"); + + if (fdClass != NULL) { + jfieldID fdClassDescriptorFieldID = (*env)->GetFieldID(env, fdClass, "descriptor", "I"); + if (fdClassDescriptorFieldID != NULL && fileDescriptor != NULL) { + fd = (*env)->GetIntField(env, fileDescriptor, fdClassDescriptorFieldID); + } + } + + return fd; +} + JNIEnv *obtain_env(bool *attach) { JNIEnv *env; @@ -73,13 +87,13 @@ jobject create_image_object(JNIEnv* env, void* ptr, int format, int width, int h JNIEXPORT jobject JNICALL Java_com_hippo_image_Image_nativeDecode(JNIEnv* env, - jclass clazz, jint fd, jboolean partially) + jclass clazz, jobject fd, jboolean partially) { int format; void* image; jobject image_object; - image = decode(env, fd, partially, &format); + image = decode(env, jniGetFDFromFileDescriptor(env, fd), partially, &format); if (image == NULL) { return NULL; }