Display animated webp whenever possible, otherwise fallback to static image. Fixes #5139

(cherry picked from commit 8c18a14dfd4ed51001b135a469434fe6f8103929)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt
This commit is contained in:
inorichi 2021-05-25 19:42:48 +02:00 committed by Jobobby04
parent fba4bd163b
commit 2eb5436b25
4 changed files with 37 additions and 3 deletions

View File

@ -207,7 +207,10 @@ dependencies {
implementation("io.coil-kt:coil:$coilVersion") implementation("io.coil-kt:coil:$coilVersion")
implementation("io.coil-kt:coil-gif:$coilVersion") implementation("io.coil-kt:coil-gif:$coilVersion")
implementation("com.github.tachiyomiorg:subsampling-scale-image-view:846abe0") implementation("com.github.tachiyomiorg:subsampling-scale-image-view:846abe0") {
exclude(module = "image-decoder")
}
implementation("com.github.tachiyomiorg:image-decoder:e6d680f")
// Logging // Logging
implementation("com.jakewharton.timber:timber:4.7.1") implementation("com.jakewharton.timber:timber:4.7.1")

View File

@ -331,7 +331,7 @@ class PagerPageHolder(
} }
// SY <-- // SY <--
ImageUtil.findImageType(stream) == ImageUtil.ImageType.GIF ImageUtil.isAnimatedAndSupported(stream)
} }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())

View File

@ -279,7 +279,7 @@ class WebtoonPageHolder(
val stream = streamFn().buffered(16) val stream = streamFn().buffered(16)
openStream = process(stream) openStream = process(stream)
ImageUtil.findImageType(stream) == ImageUtil.ImageType.GIF ImageUtil.isAnimatedAndSupported(stream)
} }
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())

View File

@ -10,12 +10,15 @@ import android.graphics.Rect
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.os.Build
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.core.graphics.alpha import androidx.core.graphics.alpha
import androidx.core.graphics.blue import androidx.core.graphics.blue
import androidx.core.graphics.createBitmap import androidx.core.graphics.createBitmap
import androidx.core.graphics.green import androidx.core.graphics.green
import androidx.core.graphics.red import androidx.core.graphics.red
import tachiyomi.decoder.Format
import tachiyomi.decoder.ImageDecoder
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.InputStream import java.io.InputStream
@ -70,6 +73,34 @@ object ImageUtil {
return null return null
} }
fun isAnimatedAndSupported(stream: InputStream): Boolean {
try {
val bytes = ByteArray(32)
val length = if (stream.markSupported()) {
stream.mark(bytes.size)
stream.read(bytes, 0, bytes.size).also { stream.reset() }
} else {
stream.read(bytes, 0, bytes.size)
}
if (length == -1) {
return false
}
val type = ImageDecoder.findType(bytes) ?: return false
return when (type.format) {
Format.Gif -> true
// Coil supports animated WebP on Android 9.0+
// https://coil-kt.github.io/coil/getting_started/#supported-image-formats
Format.Webp -> type.isAnimated && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
else -> false
}
} catch (e: Exception) {
}
return false
}
private fun ByteArray.compareWith(magic: ByteArray): Boolean { private fun ByteArray.compareWith(magic: ByteArray): Boolean {
return magic.indices.none { this[it] != magic[it] } return magic.indices.none { this[it] != magic[it] }
} }