diff --git a/app/src/main/cpp/archive.c b/app/src/main/cpp/archive.c
index a1fa6f026..b9072a878 100644
--- a/app/src/main/cpp/archive.c
+++ b/app/src/main/cpp/archive.c
@@ -279,7 +279,8 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
}
JNIEXPORT jint JNICALL
-Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd, jlong size) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_openArchive(JNIEnv *env, jclass thiz, jint fd,
+ jlong size) {
EH_UNUSED(env);
EH_UNUSED(thiz);
archive_ctx *ctx = NULL;
@@ -359,7 +360,8 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd
#pragma ide diagnostic ignored "UnreachableCode"
JNIEXPORT jobject JNICALL
-Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz, jint index) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_extractToByteBuffer(JNIEnv *env, jclass thiz,
+ jint index) {
EH_UNUSED(env);
EH_UNUSED(thiz);
void *addr = MEMPOOL_ADDR_BY_SORTED_IDX(index);
@@ -388,7 +390,7 @@ Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz,
#pragma clang diagnostic pop
JNIEXPORT void JNICALL
-Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_closeArchive(JNIEnv *env, jclass thiz) {
EH_UNUSED(env);
EH_UNUSED(thiz);
for (int i = 0; i < CTX_POOL_SIZE; i++)
@@ -408,14 +410,15 @@ Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) {
}
JNIEXPORT jboolean JNICALL
-Java_com_hippo_UriArchiveAccessor_needPassword(JNIEnv *env, jobject thiz) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_needPassword(JNIEnv *env, jclass thiz) {
EH_UNUSED(env);
EH_UNUSED(thiz);
return need_encrypt;
}
JNIEXPORT jboolean JNICALL
-Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jstring str) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_providePassword(JNIEnv *env, jclass thiz,
+ jstring str) {
EH_UNUSED(thiz);
struct archive_entry *entry;
archive_ctx *ctx;
@@ -445,7 +448,8 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jst
}
JNIEXPORT jstring JNICALL
-Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint index) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_getFilename(JNIEnv *env, jclass thiz,
+ jint index) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
@@ -460,7 +464,8 @@ Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint in
}
JNIEXPORT void JNICALL
-Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint index, jint fd) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_extractToFd(JNIEnv *env, jclass thiz,
+ jint index, jint fd) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
@@ -474,7 +479,8 @@ Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint in
}
JNIEXPORT void JNICALL
-Java_com_hippo_UriArchiveAccessor_releaseByteBuffer(JNIEnv *env, jobject thiz, jobject buffer) {
+Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_releaseByteBuffer(JNIEnv *env, jclass thiz,
+ jobject buffer) {
EH_UNUSED(thiz);
void *addr = (*env)->GetDirectBufferAddress(env, buffer);
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
diff --git a/app/src/main/cpp/gifutils.c b/app/src/main/cpp/gifutils.c
index 37e194b62..cf8177497 100644
--- a/app/src/main/cpp/gifutils.c
+++ b/app/src/main/cpp/gifutils.c
@@ -43,14 +43,14 @@ static void doRewrite(byte *addr, size_t size) {
}
JNIEXPORT void JNICALL
-Java_com_hippo_image_Image_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) {
+Java_com_hippo_image_ImageKt_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) {
byte *addr = (*env)->GetDirectBufferAddress(env, buffer);
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
doRewrite(addr, size);
}
JNIEXPORT void JNICALL
-Java_com_hippo_image_Image_rewriteGifSource2(JNIEnv *env, jclass clazz, jint fd) {
+Java_com_hippo_image_ImageKt_rewriteGifSource2(JNIEnv *env, jclass clazz, jint fd) {
struct stat64 st;
fstat64(fd, &st);
size_t size = st.st_size;
diff --git a/app/src/main/java/com/hippo/Native.kt b/app/src/main/java/com/hippo/Native.kt
deleted file mode 100644
index 3385a3679..000000000
--- a/app/src/main/java/com/hippo/Native.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2022 Tarsin Norbin
- *
- * This file is part of EhViewer
- *
- * 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.
- *
- * 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 .
- */
-package com.hippo
-
-import android.os.ParcelFileDescriptor
-import android.system.Int64Ref
-import android.system.Os
-import java.io.FileDescriptor
-
-private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor) {
- Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE)
-}
-
-infix fun ParcelFileDescriptor.sendTo(fd: FileDescriptor) {
- sendFileTotally(fileDescriptor, fd)
-}
-
-infix fun ParcelFileDescriptor.sendTo(fd: ParcelFileDescriptor) {
- sendFileTotally(fileDescriptor, fd.fileDescriptor)
-}
diff --git a/app/src/main/java/com/hippo/UriArchiveAccessor.kt b/app/src/main/java/com/hippo/UriArchiveAccessor.kt
deleted file mode 100644
index 3aa0edc99..000000000
--- a/app/src/main/java/com/hippo/UriArchiveAccessor.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2022 Tarsin Norbin
- *
- * This file is part of EhViewer
- *
- * 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.
- *
- * 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 .
- */
-package com.hippo
-
-import android.content.Context
-import android.graphics.ImageDecoder
-import android.net.Uri
-import android.util.Log
-import com.hippo.image.Image
-import java.io.FileDescriptor
-import java.nio.ByteBuffer
-
-class UriArchiveAccessor(ctx: Context, private val uri: Uri) {
- val pfd by lazy { ctx.contentResolver.openFileDescriptor(uri, "r")!! }
- fun open(): Int {
- Log.d(DEBUG_TAG, "Open archive $uri")
- return openArchive(pfd.fd, pfd.statSize)
- }
-
- private external fun openArchive(fd: Int, size: Long): Int
- private external fun extractToByteBuffer(index: Int): ByteBuffer?
- external fun extractToFd(index: Int, fd: Int)
- external fun getFilename(index: Int): String
- external fun needPassword(): Boolean
- external fun providePassword(str: String): Boolean
- private external fun closeArchive()
- fun close() {
- closeArchive()
- pfd.close()
- Log.d(DEBUG_TAG, "Close archive $uri successfully!")
- }
-
- fun getImageSource(index: Int): Image.CloseableSource? {
- val buffer = extractToByteBuffer(index)
- buffer ?: return null
- check(buffer.isDirect)
- Image.rewriteGifSource(buffer)
- val source = ImageDecoder.createSource(buffer)
- return object : Image.CloseableSource {
- override val source: ImageDecoder.Source
- get() = source
-
- override fun close() {
- releaseByteBuffer(buffer)
- }
- }
- }
-
- companion object {
- @JvmStatic
- private external fun releaseByteBuffer(buffer: ByteBuffer)
- }
-}
-
-private const val DEBUG_TAG = "UriArchiveAccessor"
diff --git a/app/src/main/java/com/hippo/ehviewer/EhDB.kt b/app/src/main/java/com/hippo/ehviewer/EhDB.kt
index 7dcc3d8b5..2eafda973 100644
--- a/app/src/main/java/com/hippo/ehviewer/EhDB.kt
+++ b/app/src/main/java/com/hippo/ehviewer/EhDB.kt
@@ -33,7 +33,7 @@ import com.hippo.ehviewer.dao.HistoryInfo
import com.hippo.ehviewer.dao.LocalFavoriteInfo
import com.hippo.ehviewer.dao.QuickSearch
import com.hippo.ehviewer.download.DownloadManager
-import com.hippo.sendTo
+import com.hippo.util.sendTo
object EhDB {
private const val CUR_DB_VER = 4
diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt b/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt
index 6ad4f4ef4..6aad70c0c 100644
--- a/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt
+++ b/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt
@@ -16,10 +16,13 @@
package com.hippo.ehviewer.gallery
import android.content.Context
+import android.graphics.ImageDecoder
import android.net.Uri
-import com.hippo.UriArchiveAccessor
+import android.os.ParcelFileDescriptor
+import android.util.Log
import com.hippo.ehviewer.Settings
import com.hippo.image.Image
+import com.hippo.image.rewriteGifSource
import com.hippo.unifile.UniFile
import com.hippo.yorozuya.FileUtils
import kotlinx.coroutines.CoroutineScope
@@ -35,26 +38,26 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.sync.withPermit
+import java.nio.ByteBuffer
-class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) : PageLoader2(),
- CoroutineScope {
+class ArchivePageLoader(context: Context, private val uri: Uri, passwdFlow: Flow) : PageLoader2(), CoroutineScope {
override val coroutineContext = Dispatchers.IO + Job()
- private val archiveAccessor by lazy { UriArchiveAccessor(context, uri) }
+ private lateinit var pfd: ParcelFileDescriptor
private val hostJob = launch(start = CoroutineStart.LAZY) {
- size = archiveAccessor.open()
+ Log.d(DEBUG_TAG, "Open archive $uri")
+ pfd = context.contentResolver.openFileDescriptor(uri, "r")!!
+ size = openArchive(pfd.fd, pfd.statSize)
if (size == 0) {
return@launch
}
- archiveAccessor.run {
- if (needPassword()) {
- Settings.archivePasswds?.forEach {
- if (providePassword(it)) return@launch
- }
- passwdFlow.collect {
- if (providePassword(it)) {
- Settings.putPasswdToArchivePasswds(it)
- currentCoroutineContext().cancel()
- }
+ if (needPassword()) {
+ Settings.archivePasswds?.forEach {
+ if (providePassword(it)) return@launch
+ }
+ passwdFlow.collect {
+ if (providePassword(it)) {
+ Settings.putPasswdToArchivePasswds(it)
+ currentCoroutineContext().cancel()
}
}
}
@@ -69,7 +72,9 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) :
override fun stop() {
cancel()
- archiveAccessor.close()
+ closeArchive()
+ pfd.close()
+ Log.d(DEBUG_TAG, "Close archive $uri successfully!")
super.stop()
}
@@ -93,7 +98,19 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) :
}
private suspend fun doRealWork(index: Int) {
- val src = archiveAccessor.getImageSource(index) ?: return
+ val buffer = extractToByteBuffer(index)
+ buffer ?: return
+ check(buffer.isDirect)
+ rewriteGifSource(buffer)
+ val source = ImageDecoder.createSource(buffer)
+ val src = object : Image.CloseableSource {
+ override val source: ImageDecoder.Source
+ get() = source
+
+ override fun close() {
+ releaseByteBuffer(buffer)
+ }
+ }
runCatching {
currentCoroutineContext().ensureActive()
}.onFailure {
@@ -131,13 +148,13 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) :
}
override fun getImageFilenameWithExtension(index: Int): String {
- return FileUtils.sanitizeFilename(archiveAccessor.getFilename(index))
+ return FileUtils.sanitizeFilename(getFilename(index))
}
override fun save(index: Int, file: UniFile): Boolean {
runCatching {
file.openFileDescriptor("w").use {
- archiveAccessor.extractToFd(index, it.fd)
+ extractToFd(index, it.fd)
}
}.onFailure {
it.printStackTrace()
@@ -154,4 +171,15 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) :
}
override fun preloadPages(pages: List, pair: Pair) {}
-}
\ No newline at end of file
+}
+
+private const val DEBUG_TAG = "ArchivePageLoader"
+
+private external fun releaseByteBuffer(buffer: ByteBuffer)
+private external fun openArchive(fd: Int, size: Long): Int
+private external fun extractToByteBuffer(index: Int): ByteBuffer?
+private external fun extractToFd(index: Int, fd: Int)
+private external fun getFilename(index: Int): String
+private external fun needPassword(): Boolean
+private external fun providePassword(str: String): Boolean
+private external fun closeArchive()
diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt b/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt
index fb498ed74..d067b3389 100644
--- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt
+++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt
@@ -28,9 +28,9 @@ import com.hippo.ehviewer.client.referer
import com.hippo.ehviewer.coil.edit
import com.hippo.ehviewer.coil.read
import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS
-import com.hippo.image.Image
import com.hippo.image.Image.CloseableSource
-import com.hippo.sendTo
+import com.hippo.image.rewriteGifSource2
+import com.hippo.util.sendTo
import com.hippo.unifile.UniFile
import com.hippo.unifile.openOutputStream
import com.hippo.yorozuya.FileUtils
@@ -163,7 +163,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
}
if (contentType == ContentType.Image.GIF)
outFile.openFileDescriptor("rw").use {
- Image.rewriteGifSource2(it.fd)
+ rewriteGifSource2(it.fd)
}
return ret
}
diff --git a/app/src/main/java/com/hippo/image/Image.kt b/app/src/main/java/com/hippo/image/Image.kt
index e9d8c967a..3e5a93da9 100644
--- a/app/src/main/java/com/hippo/image/Image.kt
+++ b/app/src/main/java/com/hippo/image/Image.kt
@@ -95,15 +95,12 @@ class Image private constructor(private val src: CloseableSource) {
it.printStackTrace()
}.getOrNull()
}
-
- @JvmStatic
- external fun rewriteGifSource(buffer: ByteBuffer)
-
- @JvmStatic
- external fun rewriteGifSource2(fd: Int)
}
interface CloseableSource : AutoCloseable {
val source: Source
}
}
+
+external fun rewriteGifSource(buffer: ByteBuffer)
+external fun rewriteGifSource2(fd: Int)
diff --git a/app/src/main/java/com/hippo/util/FDUtils.kt b/app/src/main/java/com/hippo/util/FDUtils.kt
new file mode 100644
index 000000000..690f90e8a
--- /dev/null
+++ b/app/src/main/java/com/hippo/util/FDUtils.kt
@@ -0,0 +1,18 @@
+package com.hippo.util
+
+import android.os.ParcelFileDescriptor
+import android.system.Int64Ref
+import android.system.Os
+import java.io.FileDescriptor
+
+private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor) {
+ Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE)
+}
+
+infix fun ParcelFileDescriptor.sendTo(fd: FileDescriptor) {
+ sendFileTotally(fileDescriptor, fd)
+}
+
+infix fun ParcelFileDescriptor.sendTo(fd: ParcelFileDescriptor) {
+ sendFileTotally(fileDescriptor, fd.fileDescriptor)
+}
\ No newline at end of file
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
index 41e4c477c..d9ddbbc00 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
@@ -73,7 +73,7 @@ import com.hippo.ehviewer.gallery.EhPageLoader
import com.hippo.ehviewer.gallery.PageLoader2
import com.hippo.ehviewer.ui.EhActivity
import com.hippo.image.Image
-import com.hippo.sendTo
+import com.hippo.util.sendTo
import com.hippo.unifile.UniFile
import com.hippo.util.ExceptionUtils
import com.hippo.util.getParcelableCompat