mihon/app/src/main/java/eu/kanade/tachiyomi/util/ImageUtil.kt

75 lines
2.1 KiB
Kotlin
Raw Normal View History

package eu.kanade.tachiyomi.util
import java.io.InputStream
import java.net.URLConnection
object ImageUtil {
fun isImage(name: String, openStream: (() -> InputStream)? = null): Boolean {
2018-09-08 12:44:35 +02:00
val contentType = try {
URLConnection.guessContentTypeFromName(name)
} catch (e: Exception) {
2018-09-08 12:44:35 +02:00
null
} ?: openStream?.let { findImageType(it)?.mime }
return contentType?.startsWith("image/") ?: false
}
fun findImageType(openStream: () -> InputStream): ImageType? {
return openStream().use { findImageType(it) }
}
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
}
} catch(e: Exception) {
}
return null
}
private fun ByteArray.compareWith(magic: ByteArray): Boolean {
for (i in 0 until magic.size) {
if (this[i] != magic[i]) return false
}
return true
}
private fun charByteArrayOf(vararg bytes: Int): ByteArray {
return ByteArray(bytes.size).apply {
for (i in 0 until bytes.size) {
set(i, bytes[i].toByte())
}
}
}
enum class ImageType(val mime: String, val extension: String) {
JPG("image/jpeg", "jpg"),
PNG("image/png", "png"),
GIF("image/gif", "gif"),
WEBP("image/webp", "webp")
}
}