diff --git a/app/build.gradle b/app/build.gradle
index c64ac0512..760c4440c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -16,8 +16,8 @@ android {
applicationId 'org.koitharu.kotatsu'
minSdk = 21
targetSdk = 35
- versionCode = 672
- versionName = '7.6-b1'
+ versionCode = 673
+ versionName = '7.6'
generatedDensities = []
testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner'
ksp {
@@ -83,7 +83,7 @@ afterEvaluate {
}
dependencies {
//noinspection GradleDependency
- implementation('com.github.KotatsuApp:kotatsu-parsers:cc62981f12') {
+ implementation('com.github.KotatsuApp:kotatsu-parsers:3cdd391410') {
exclude group: 'org.json', module: 'json'
}
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/MangaSource.kt
index 9c8ff510d..ce77eed36 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/model/MangaSource.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/model/MangaSource.kt
@@ -62,6 +62,10 @@ val ContentType.titleResId
ContentType.MANHUA -> R.string.content_type_manhua
ContentType.NOVEL -> R.string.content_type_novel
ContentType.ONE_SHOT -> R.string.content_type_one_shot
+ ContentType.DOUJINSHI -> R.string.content_type_doujinshi
+ ContentType.IMAGE_SET -> R.string.content_type_image_set
+ ContentType.ARTIST_CG -> R.string.content_type_artist_cg
+ ContentType.GAME_CG -> R.string.content_type_game_cg
}
tailrec fun MangaSource.unwrap(): MangaSource = if (this is MangaSourceInfo) {
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/BitmapWrapper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/BitmapWrapper.kt
index 13d429091..09d2d6ec8 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/BitmapWrapper.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/BitmapWrapper.kt
@@ -9,7 +9,7 @@ import android.graphics.Rect as AndroidRect
class BitmapWrapper private constructor(
private val androidBitmap: AndroidBitmap,
-) : Bitmap {
+) : Bitmap, AutoCloseable {
private val canvas by lazy { Canvas(androidBitmap) } // is not always used, so initialized lazily
@@ -24,17 +24,21 @@ class BitmapWrapper private constructor(
canvas.drawBitmap(androidSourceBitmap, src.toAndroidRect(), dst.toAndroidRect(), null)
}
+ override fun close() {
+ androidBitmap.recycle()
+ }
+
fun compressTo(output: OutputStream) {
androidBitmap.compress(AndroidBitmap.CompressFormat.PNG, 100, output)
}
companion object {
- fun create(width: Int, height: Int): Bitmap = BitmapWrapper(
+ fun create(width: Int, height: Int) = BitmapWrapper(
AndroidBitmap.createBitmap(width, height, AndroidBitmap.Config.ARGB_8888),
)
- fun create(bitmap: AndroidBitmap): Bitmap = BitmapWrapper(
+ fun create(bitmap: AndroidBitmap) = BitmapWrapper(
if (bitmap.isMutable) bitmap else bitmap.copy(AndroidBitmap.Config.ARGB_8888, true),
)
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt
index a4fe4fa25..b6fb9f9f3 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt
@@ -21,14 +21,15 @@ import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
import org.koitharu.kotatsu.core.prefs.SourceSettings
import org.koitharu.kotatsu.core.util.ext.configureForParser
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
-import org.koitharu.kotatsu.core.util.ext.requireBody
import org.koitharu.kotatsu.core.util.ext.sanitizeHeaderValue
import org.koitharu.kotatsu.core.util.ext.toList
+import org.koitharu.kotatsu.core.util.ext.use
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.bitmap.Bitmap
import org.koitharu.kotatsu.parsers.config.MangaSourceConfig
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.network.UserAgents
+import org.koitharu.kotatsu.parsers.util.map
import java.lang.ref.WeakReference
import java.util.Locale
import javax.inject.Inject
@@ -76,32 +77,25 @@ class MangaLoaderContextImpl @Inject constructor(
}
override fun redrawImageResponse(response: Response, redraw: (image: Bitmap) -> Bitmap): Response {
- val image = response.requireBody().byteStream()
-
- val opts = BitmapFactory.Options()
- opts.inMutable = true
- val bitmap = BitmapFactory.decodeStream(image, null, opts) ?: error("Cannot decode bitmap")
- val result = redraw(BitmapWrapper.create(bitmap)) as BitmapWrapper
-
- val body = Buffer().also {
- result.compressTo(it.outputStream())
- }.asResponseBody("image/jpeg".toMediaType())
-
- return response.newBuilder()
- .body(body)
- .build()
+ return response.map { body ->
+ val opts = BitmapFactory.Options()
+ opts.inMutable = true
+ BitmapFactory.decodeStream(body.byteStream(), null, opts)?.use { bitmap ->
+ (redraw(BitmapWrapper.create(bitmap)) as BitmapWrapper).use { result ->
+ Buffer().also {
+ result.compressTo(it.outputStream())
+ }.asResponseBody("image/jpeg".toMediaType())
+ }
+ } ?: error("Cannot decode bitmap")
+ }
}
- override fun createBitmap(width: Int, height: Int): Bitmap {
- return BitmapWrapper.create(width, height)
- }
+ override fun createBitmap(width: Int, height: Int): Bitmap = BitmapWrapper.create(width, height)
@MainThread
- private fun obtainWebView(): WebView {
- return webViewCached?.get() ?: WebView(androidContext).also {
- it.configureForParser(null)
- webViewCached = WeakReference(it)
- }
+ private fun obtainWebView(): WebView = webViewCached?.get() ?: WebView(androidContext).also {
+ it.configureForParser(null)
+ webViewCached = WeakReference(it)
}
private fun obtainWebViewUserAgent(): String {
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt
index 035e14c9e..1d28509c7 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/favicon/FaviconFetcher.kt
@@ -37,12 +37,12 @@ import org.koitharu.kotatsu.core.parser.EmptyMangaRepository
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.ParserMangaRepository
import org.koitharu.kotatsu.core.parser.external.ExternalMangaRepository
-import org.koitharu.kotatsu.core.util.ext.requireBody
import org.koitharu.kotatsu.core.util.ext.writeAllCancellable
import org.koitharu.kotatsu.local.data.CacheDir
import org.koitharu.kotatsu.local.data.util.withExtraCloseable
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.util.await
+import org.koitharu.kotatsu.parsers.util.requireBody
import java.net.HttpURLConnection
import kotlin.coroutines.coroutineContext
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Http.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Http.kt
index 018d594e1..5d384ba88 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Http.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/Http.kt
@@ -5,7 +5,6 @@ import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
-import okhttp3.ResponseBody
import okhttp3.internal.closeQuietly
import okio.IOException
import org.json.JSONObject
@@ -41,8 +40,6 @@ fun Response.ensureSuccess() = apply {
}
}
-fun Response.requireBody(): ResponseBody = checkNotNull(body) { "Response body is null" }
-
fun Cookie.newBuilder(): Cookie.Builder = Cookie.Builder().also { c ->
c.name(name)
c.value(value)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2076ad1f7..2648670ac 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -729,4 +729,8 @@
This source does not support search with filters. Your filters have been cleared
Kodomo
One shot
+ Doujinshi
+ Image set
+ Artist CG
+ Game CG