PeachScans: Bump ImageDecoder and fix for new signature (#2078)

* Bump ImageDecoder and fix for new signature

* fix for empty svg files
This commit is contained in:
AwkwardPeak7 2024-03-25 17:38:56 +05:00 committed by Draff
parent 78f2c9c650
commit 8fd440d838
3 changed files with 77 additions and 19 deletions

View File

@ -2,8 +2,8 @@ plugins {
id("lib-multisrc") id("lib-multisrc")
} }
baseVersionCode = 3 baseVersionCode = 4
dependencies { dependencies {
compileOnly("com.github.tachiyomiorg:image-decoder:398d3c074f") compileOnly("com.github.tachiyomiorg:image-decoder:e08e9be535")
} }

View File

@ -32,7 +32,6 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.TimeZone import java.util.TimeZone
@ -183,7 +182,7 @@ abstract class PeachScan(
val zis = ZipInputStream(response.body.byteStream()) val zis = ZipInputStream(response.body.byteStream())
val images = generateSequence { zis.nextEntry } val images = generateSequence { zis.nextEntry }
.map { .mapNotNull {
val entryName = it.name val entryName = it.name
val splitEntryName = entryName.split('.') val splitEntryName = entryName.split('.')
val entryIndex = splitEntryName.first().toInt() val entryIndex = splitEntryName.first().toInt()
@ -195,7 +194,7 @@ abstract class PeachScan(
val svgBytes = zis.readBytes() val svgBytes = zis.readBytes()
val svgContent = svgBytes.toString(Charsets.UTF_8) val svgContent = svgBytes.toString(Charsets.UTF_8)
val b64 = dataUriRegex.find(svgContent)?.groupValues?.get(1) val b64 = dataUriRegex.find(svgContent)?.groupValues?.get(1)
?: throw IOException("Não foi possível corresponder a imagem no conteúdo SVG") ?: return@mapNotNull null
Base64.decode(b64, Base64.DEFAULT) Base64.decode(b64, Base64.DEFAULT)
} }

View File

@ -5,6 +5,7 @@ import android.graphics.Rect
import tachiyomi.decoder.ImageDecoder import tachiyomi.decoder.ImageDecoder
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream
import java.lang.reflect.Method import java.lang.reflect.Method
/** /**
@ -18,40 +19,98 @@ import java.lang.reflect.Method
*/ */
object PeachScanUtils { object PeachScanUtils {
private var decodeMethod: Method private var decodeMethod: Method
private var newInstanceMethod: Method
private var isNewDecodeMethod = false private var classSignature = ClassSignature.Newest
private enum class ClassSignature {
Old, New, Newest
}
init { init {
val rectClass = Rect::class.java val rectClass = Rect::class.java
val booleanClass = Boolean::class.java val booleanClass = Boolean::class.java
val intClass = Int::class.java val intClass = Int::class.java
val byteArrayClass = ByteArray::class.java val byteArrayClass = ByteArray::class.java
val inputStreamClass = InputStream::class.java
decodeMethod = try { try {
isNewDecodeMethod = true // Mihon Preview r6595+
classSignature = ClassSignature.Newest
// decode(region, rgb565, sampleSize, applyColorManagement, displayProfile) // decode(region, sampleSize)
ImageDecoder::class.java.getMethod("decode", rectClass, booleanClass, intClass, booleanClass, byteArrayClass) decodeMethod = ImageDecoder::class.java.getMethod(
} catch (e: NoSuchMethodException) { "decode",
isNewDecodeMethod = false rectClass,
intClass,
)
// decode(region, rgb565, sampleSize) // newInstance(stream, cropBorders, displayProfile)
ImageDecoder::class.java.getMethod("decode", rectClass, booleanClass, intClass) newInstanceMethod = ImageDecoder.Companion::class.java.getMethod(
"newInstance",
inputStreamClass,
booleanClass,
byteArrayClass,
)
} catch (_: NoSuchMethodException) {
try {
// Mihon Stable & forks
classSignature = ClassSignature.New
// decode(region, rgb565, sampleSize, applyColorManagement, displayProfile)
decodeMethod = ImageDecoder::class.java.getMethod(
"decode",
rectClass,
booleanClass,
intClass,
booleanClass,
byteArrayClass,
)
// newInstance(stream, cropBorders)
newInstanceMethod = ImageDecoder.Companion::class.java.getMethod(
"newInstance",
inputStreamClass,
booleanClass,
)
} catch (_: NoSuchMethodException) {
// Tachiyomi J2k
classSignature = ClassSignature.Old
// decode(region, rgb565, sampleSize)
decodeMethod =
ImageDecoder::class.java.getMethod(
"decode",
rectClass,
booleanClass,
intClass,
)
// newInstance(stream, cropBorders)
newInstanceMethod = ImageDecoder.Companion::class.java.getMethod(
"newInstance",
inputStreamClass,
booleanClass,
)
}
} }
} }
fun decodeImage(data: ByteArray, rgb565: Boolean, filename: String, entryName: String): Bitmap { fun decodeImage(data: ByteArray, rgb565: Boolean, filename: String, entryName: String): Bitmap {
val decoder = ImageDecoder.newInstance(ByteArrayInputStream(data)) val decoder = when (classSignature) {
ClassSignature.Newest -> newInstanceMethod.invoke(ImageDecoder.Companion, ByteArrayInputStream(data), false, null)
else -> newInstanceMethod.invoke(ImageDecoder.Companion, ByteArrayInputStream(data), false)
} as ImageDecoder?
if (decoder == null || decoder.width <= 0 || decoder.height <= 0) { if (decoder == null || decoder.width <= 0 || decoder.height <= 0) {
throw IOException("Falha ao inicializar o decodificador de imagem") throw IOException("Falha ao inicializar o decodificador de imagem")
} }
val rect = Rect(0, 0, decoder.width, decoder.height) val rect = Rect(0, 0, decoder.width, decoder.height)
val bitmap = if (isNewDecodeMethod) { val bitmap = when (classSignature) {
decodeMethod.invoke(decoder, rect, rgb565, 1, false, null) ClassSignature.Newest -> decodeMethod.invoke(decoder, rect, 1)
} else { ClassSignature.New -> decodeMethod.invoke(decoder, rect, rgb565, 1, false, null)
decodeMethod.invoke(decoder, rect, rgb565, 1) else -> decodeMethod.invoke(decoder, rect, rgb565, 1)
} as Bitmap? } as Bitmap?
decoder.recycle() decoder.recycle()