Make comic book archive caching optional instead of rolling it back completely (#883)

* Make comic book archive caching optional and fix cbz archives not opening for some users

* corrected placement of // SY <--
This commit is contained in:
Shamicen
2023-05-13 04:52:17 +02:00
committed by GitHub
parent be6bbb8e9b
commit 6071acd3df
10 changed files with 278 additions and 36 deletions
@@ -26,6 +26,8 @@ import androidx.core.graphics.red
import androidx.exifinterface.media.ExifInterface
import com.hippo.unifile.UniFile
import logcat.LogPriority
import net.lingala.zip4j.ZipFile
import net.lingala.zip4j.model.FileHeader
import tachiyomi.decoder.Format
import tachiyomi.decoder.ImageDecoder
import java.io.BufferedInputStream
@@ -129,9 +131,19 @@ object ImageUtil {
*
* @return true if the width is greater than the height
*/
fun isWideImage(imageStream: BufferedInputStream): Boolean {
fun isWideImage(
imageStream: BufferedInputStream,
// SY -->
zip4jFile: ZipFile?,
zip4jEntry: FileHeader?,
// SY <--
): Boolean {
val options = extractImageOptions(
imageStream,
// SY -->
zip4jFile,
zip4jEntry,
// SY <--
)
return options.outWidth > options.outHeight
}
@@ -257,9 +269,19 @@ object ImageUtil {
*
* @return true if the height:width ratio is greater than 3.
*/
private fun isTallImage(imageStream: InputStream): Boolean {
private fun isTallImage(
imageStream: InputStream,
// SY -->
zip4jFile: ZipFile?,
zip4jEntry: FileHeader?,
// SY <--
): Boolean {
val options = extractImageOptions(
imageStream,
// SY -->
zip4jFile,
zip4jEntry,
// SY <--
resetAfterExtraction = false,
)
@@ -269,8 +291,23 @@ object ImageUtil {
/**
* Splits tall images to improve performance of reader
*/
fun splitTallImage(tmpDir: UniFile, imageFile: UniFile, filenamePrefix: String): Boolean {
if (isAnimatedAndSupported(imageFile.openInputStream()) || !isTallImage(imageFile.openInputStream())) {
fun splitTallImage(
tmpDir: UniFile,
imageFile: UniFile,
filenamePrefix: String,
// SY -->
zip4jFile: ZipFile?,
zip4jEntry: FileHeader?,
// SY <--
): Boolean {
if (isAnimatedAndSupported(imageFile.openInputStream()) || !isTallImage(
imageFile.openInputStream(),
// SY -->
zip4jFile,
zip4jEntry,
// SY <--
)
) {
return true
}
@@ -280,7 +317,14 @@ object ImageUtil {
return false
}
val options = extractImageOptions(imageFile.openInputStream(), resetAfterExtraction = false).apply {
val options = extractImageOptions(
imageFile.openInputStream(),
// SY -->
zip4jFile,
zip4jEntry,
// SY <--
resetAfterExtraction = false,
).apply {
inJustDecodeBounds = false
}
@@ -326,10 +370,22 @@ object ImageUtil {
* Check whether the image is a long Strip that needs splitting
* @return true if the image is not animated and it's height is greater than image width and screen height
*/
fun isStripSplitNeeded(imageStream: BufferedInputStream): Boolean {
fun isStripSplitNeeded(
imageStream: BufferedInputStream,
// SY -->
zip4jFile: ZipFile?,
zip4jEntry: FileHeader?,
// SY <--
): Boolean {
if (isAnimatedAndSupported(imageStream)) return false
val options = extractImageOptions(imageStream)
val options = extractImageOptions(
imageStream,
// SY -->
zip4jFile,
zip4jEntry,
// SY <--
)
val imageHeightIsBiggerThanWidth = options.outHeight > options.outWidth
val imageHeightBiggerThanScreenHeight = options.outHeight > optimalImageHeight
return imageHeightIsBiggerThanWidth && imageHeightBiggerThanScreenHeight
@@ -361,8 +417,20 @@ object ImageUtil {
}
}
fun getSplitDataForStream(imageStream: InputStream): List<SplitData> {
return extractImageOptions(imageStream).splitData
fun getSplitDataForStream(
imageStream: InputStream,
// SY -->
zip4jFile: ZipFile?,
zip4jEntry: FileHeader?,
// SY <--
): List<SplitData> {
return extractImageOptions(
imageStream,
// SY -->
zip4jFile,
zip4jEntry,
// SY <--
).splitData
}
private val BitmapFactory.Options.splitData
@@ -627,8 +695,17 @@ object ImageUtil {
*/
private fun extractImageOptions(
imageStream: InputStream,
// SY -->
zip4jFile: ZipFile?,
zip4jEntry: FileHeader?,
// SY <--
resetAfterExtraction: Boolean = true,
): BitmapFactory.Options {
// SY -->
// zip4j does currently not support mark() and reset()
if (zip4jFile != null && zip4jEntry != null) return extractImageOptionsZip4j(zip4jFile, zip4jEntry)
// SY <--
imageStream.mark(imageStream.available() + 1)
val imageBytes = imageStream.readBytes()
@@ -639,6 +716,15 @@ object ImageUtil {
}
// SY -->
private fun extractImageOptionsZip4j(zip4jFile: ZipFile?, zip4jEntry: FileHeader?): BitmapFactory.Options {
zip4jFile?.getInputStream(zip4jEntry).use { imageStream ->
val imageBytes = imageStream?.readBytes()
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
imageBytes?.size?.let { BitmapFactory.decodeByteArray(imageBytes, 0, it, options) }
return options
}
}
/**
* Creates random exif metadata used as padding to make
* the size of files inside CBZ archives unique