Browse Source

Handle HEIF images (partly addresses #4756)

arkon 3 years ago
parent
commit
74381ef59e
1 changed files with 28 additions and 49 deletions
  1. 28 49
      app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt

+ 28 - 49
app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt

@@ -18,6 +18,7 @@ import androidx.core.graphics.green
 import androidx.core.graphics.red
 import tachiyomi.decoder.Format
 import tachiyomi.decoder.ImageDecoder
+import tachiyomi.decoder.ImageType
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.io.InputStream
@@ -41,30 +42,14 @@ object ImageUtil {
 
     fun findImageType(stream: InputStream): ImageType? {
         try {
-            val bytes = ByteArray(8)
-
-            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 null
-            }
-
-            if (bytes.compareWith(charByteArrayOf(0xFF, 0xD8, 0xFF))) {
-                return ImageType.JPG
-            }
-            if (bytes.compareWith(charByteArrayOf(0x89, 0x50, 0x4E, 0x47))) {
-                return ImageType.PNG
-            }
-            if (bytes.compareWith("GIF8".toByteArray())) {
-                return ImageType.GIF
-            }
-            if (bytes.compareWith("RIFF".toByteArray())) {
-                return ImageType.WEBP
+            return when (getImageType(stream)?.format) {
+                // TODO: image-decoder library currently doesn't detect this
+                // Format.Avif -> ImageType.AVIF
+                Format.Gif -> ImageType.GIF
+                Format.Heif -> ImageType.HEIF
+                Format.Jpeg -> ImageType.JPEG
+                Format.Png -> ImageType.PNG
+                Format.Webp -> ImageType.WEBP
             }
         } catch (e: Exception) {
         }
@@ -73,20 +58,7 @@ object ImageUtil {
 
     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
+            val type = getImageType(stream) ?: return false
             return when (type.format) {
                 Format.Gif -> true
                 // Coil supports animated WebP on Android 9.0+
@@ -99,23 +71,30 @@ object ImageUtil {
         return false
     }
 
-    private fun ByteArray.compareWith(magic: ByteArray): Boolean {
-        return magic.indices.none { this[it] != magic[it] }
-    }
+    private fun getImageType(stream: InputStream): tachiyomi.decoder.ImageType? {
+        val bytes = ByteArray(32)
 
-    private fun charByteArrayOf(vararg bytes: Int): ByteArray {
-        return ByteArray(bytes.size).apply {
-            for (i in bytes.indices) {
-                set(i, bytes[i].toByte())
-            }
+        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 null
+        }
+
+        return ImageDecoder.findType(bytes)
     }
 
     enum class ImageType(val mime: String, val extension: String) {
-        JPG("image/jpeg", "jpg"),
-        PNG("image/png", "png"),
+        // AVIF("image/avif", "avif"),
         GIF("image/gif", "gif"),
-        WEBP("image/webp", "webp")
+        HEIF("image/heif", "heif"),
+        JPEG("image/jpeg", "jpg"),
+        PNG("image/png", "png"),
+        WEBP("image/webp", "webp"),
     }
 
     /**