2018-09-01 11:12:59 -04:00
|
|
|
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 06:44:35 -04:00
|
|
|
val contentType = try {
|
|
|
|
URLConnection.guessContentTypeFromName(name)
|
2018-09-01 11:12:59 -04:00
|
|
|
} catch (e: Exception) {
|
2018-09-08 06:44:35 -04:00
|
|
|
null
|
|
|
|
} ?: openStream?.let { findImageType(it)?.mime }
|
|
|
|
return contentType?.startsWith("image/") ?: false
|
2018-09-01 11:12:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|