Merge branch 'master' into devel
This commit is contained in:
@@ -3,5 +3,5 @@ package org.koitharu.kotatsu.core.exceptions
|
|||||||
import okio.IOException
|
import okio.IOException
|
||||||
|
|
||||||
class NoDataReceivedException(
|
class NoDataReceivedException(
|
||||||
url: String,
|
val url: String,
|
||||||
) : IOException("No data has been received from $url")
|
) : IOException("No data has been received from $url")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.graphics.BitmapFactory
|
|||||||
import android.graphics.ImageDecoder
|
import android.graphics.ImageDecoder
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException
|
import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException
|
||||||
import okhttp3.MediaType
|
import okhttp3.MediaType
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
@@ -32,19 +33,21 @@ object BitmapDecoderCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Blocking
|
@Blocking
|
||||||
fun decode(stream: InputStream, type: MediaType?): Bitmap {
|
fun decode(stream: InputStream, type: MediaType?, isMutable: Boolean = false): Bitmap {
|
||||||
val format = type?.subtype
|
val format = type?.subtype
|
||||||
if (format == FORMAT_AVIF) {
|
if (format == FORMAT_AVIF) {
|
||||||
return decodeAvif(stream.toByteBuffer())
|
return decodeAvif(stream.toByteBuffer())
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
||||||
return checkBitmapNotNull(BitmapFactory.decodeStream(stream), format)
|
val opts = BitmapFactory.Options()
|
||||||
|
opts.inMutable = isMutable
|
||||||
|
return checkBitmapNotNull(BitmapFactory.decodeStream(stream, null, opts), format)
|
||||||
}
|
}
|
||||||
val byteBuffer = stream.toByteBuffer()
|
val byteBuffer = stream.toByteBuffer()
|
||||||
return if (AvifDecoder.isAvifImage(byteBuffer)) {
|
return if (AvifDecoder.isAvifImage(byteBuffer)) {
|
||||||
decodeAvif(byteBuffer)
|
decodeAvif(byteBuffer)
|
||||||
} else {
|
} else {
|
||||||
ImageDecoder.decodeBitmap(ImageDecoder.createSource(byteBuffer))
|
ImageDecoder.decodeBitmap(ImageDecoder.createSource(byteBuffer), DecoderConfigListener(isMutable))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,4 +77,18 @@ object BitmapDecoderCompat {
|
|||||||
}
|
}
|
||||||
return bitmap
|
return bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.P)
|
||||||
|
private class DecoderConfigListener(
|
||||||
|
private val isMutable: Boolean,
|
||||||
|
) : ImageDecoder.OnHeaderDecodedListener {
|
||||||
|
|
||||||
|
override fun onHeaderDecoded(
|
||||||
|
decoder: ImageDecoder,
|
||||||
|
info: ImageDecoder.ImageInfo,
|
||||||
|
source: ImageDecoder.Source
|
||||||
|
) {
|
||||||
|
decoder.isMutableRequired = isMutable
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package org.koitharu.kotatsu.core.parser
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import androidx.annotation.MainThread
|
import androidx.annotation.MainThread
|
||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException
|
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
@@ -17,6 +15,7 @@ import okhttp3.OkHttpClient
|
|||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okhttp3.ResponseBody.Companion.asResponseBody
|
import okhttp3.ResponseBody.Companion.asResponseBody
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
|
import org.koitharu.kotatsu.core.image.BitmapDecoderCompat
|
||||||
import org.koitharu.kotatsu.core.network.MangaHttpClient
|
import org.koitharu.kotatsu.core.network.MangaHttpClient
|
||||||
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
||||||
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
||||||
@@ -31,7 +30,6 @@ import org.koitharu.kotatsu.parsers.config.MangaSourceConfig
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
import org.koitharu.kotatsu.parsers.network.UserAgents
|
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||||
import org.koitharu.kotatsu.parsers.util.map
|
import org.koitharu.kotatsu.parsers.util.map
|
||||||
import org.koitharu.kotatsu.parsers.util.mimeType
|
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -80,15 +78,13 @@ class MangaLoaderContextImpl @Inject constructor(
|
|||||||
|
|
||||||
override fun redrawImageResponse(response: Response, redraw: (image: Bitmap) -> Bitmap): Response {
|
override fun redrawImageResponse(response: Response, redraw: (image: Bitmap) -> Bitmap): Response {
|
||||||
return response.map { body ->
|
return response.map { body ->
|
||||||
val opts = BitmapFactory.Options()
|
BitmapDecoderCompat.decode(body.byteStream(), body.contentType(), isMutable = true).use { bitmap ->
|
||||||
opts.inMutable = true
|
|
||||||
BitmapFactory.decodeStream(body.byteStream(), null, opts)?.use { bitmap ->
|
|
||||||
(redraw(BitmapWrapper.create(bitmap)) as BitmapWrapper).use { result ->
|
(redraw(BitmapWrapper.create(bitmap)) as BitmapWrapper).use { result ->
|
||||||
Buffer().also {
|
Buffer().also {
|
||||||
result.compressTo(it.outputStream())
|
result.compressTo(it.outputStream())
|
||||||
}.asResponseBody("image/jpeg".toMediaType())
|
}.asResponseBody("image/jpeg".toMediaType())
|
||||||
}
|
}
|
||||||
} ?: throw ImageDecodeException(response.request.url.toString(), response.mimeType)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ fun Throwable.getCauseUrl(): String? = when (this) {
|
|||||||
is NotFoundException -> url
|
is NotFoundException -> url
|
||||||
is TooManyRequestExceptions -> url
|
is TooManyRequestExceptions -> url
|
||||||
is CaughtException -> cause?.getCauseUrl()
|
is CaughtException -> cause?.getCauseUrl()
|
||||||
|
is NoDataReceivedException -> url
|
||||||
is CloudFlareBlockedException -> url
|
is CloudFlareBlockedException -> url
|
||||||
is CloudFlareProtectedException -> url
|
is CloudFlareProtectedException -> url
|
||||||
is HttpStatusException -> url
|
is HttpStatusException -> url
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ material = "1.13.0-alpha08"
|
|||||||
moshi = "1.15.2"
|
moshi = "1.15.2"
|
||||||
okhttp = "4.12.0"
|
okhttp = "4.12.0"
|
||||||
okio = "3.9.1"
|
okio = "3.9.1"
|
||||||
parsers = "f86d31f811"
|
parsers = "2550b9cac1"
|
||||||
preference = "1.2.1"
|
preference = "1.2.1"
|
||||||
recyclerview = "1.3.2"
|
recyclerview = "1.3.2"
|
||||||
room = "2.6.1"
|
room = "2.6.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user