Bläddra i källkod

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

inorichi 3 år sedan
förälder
incheckning
8c18a14dfd

+ 4 - 1
app/build.gradle.kts

@@ -205,7 +205,10 @@ dependencies {
     implementation("io.coil-kt:coil:$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
     implementation("com.jakewharton.timber:timber:4.7.1")

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt

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

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt

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

+ 31 - 0
app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt

@@ -10,11 +10,14 @@ import android.graphics.Rect
 import android.graphics.drawable.ColorDrawable
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
+import android.os.Build
 import androidx.core.graphics.alpha
 import androidx.core.graphics.blue
 import androidx.core.graphics.createBitmap
 import androidx.core.graphics.green
 import androidx.core.graphics.red
+import tachiyomi.decoder.Format
+import tachiyomi.decoder.ImageDecoder
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.io.InputStream
@@ -68,6 +71,34 @@ object ImageUtil {
         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 {
         return magic.indices.none { this[it] != magic[it] }
     }