From f01dcbd9923a2420ddd2983ced0fdb6dafe18d51 Mon Sep 17 00:00:00 2001 From: w Date: Sat, 9 Mar 2024 20:54:09 -0800 Subject: [PATCH] Update image-decoder, color management --- .../settings/screen/SettingsReaderScreen.kt | 26 ++++++++++++++++--- .../data/coil/TachiyomiImageDecoder.kt | 2 +- .../tachiyomi/ui/reader/ReaderActivity.kt | 24 +++++++++++------ .../ui/reader/setting/ReaderPreferences.kt | 3 +-- .../ui/reader/viewer/ViewerConfig.kt | 8 +++--- gradle/libs.versions.toml | 4 +-- .../commonMain/resources/MR/base/strings.xml | 2 ++ 7 files changed, 48 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt index a0a2e8f97..ffa77e5af 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsReaderScreen.kt @@ -1,10 +1,14 @@ package eu.kanade.presentation.more.settings.screen +import android.content.Intent import android.os.Build +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.runtime.Composable import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView import eu.kanade.presentation.more.settings.Preference import eu.kanade.tachiyomi.ui.reader.setting.ReaderOrientation @@ -29,6 +33,18 @@ object SettingsReaderScreen : SearchableSettings { @Composable override fun getPreferences(): List { val readerPref = remember { Injekt.get() } + val context = LocalContext.current + + val chooseColorProfile = rememberLauncherForActivityResult( + contract = ActivityResultContracts.OpenDocument(), + ) { uri -> + uri?.let { + val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION + context.contentResolver.takePersistableUriPermission(uri, flags) + readerPref.displayProfile().set(uri.toString()) + } + } + return listOf( Preference.PreferenceItem.ListPreference( pref = readerPref.defaultReadingMode(), @@ -56,10 +72,12 @@ object SettingsReaderScreen : SearchableSettings { title = stringResource(MR.strings.pref_show_navigation_mode), subtitle = stringResource(MR.strings.pref_show_navigation_mode_summary), ), - Preference.PreferenceItem.SwitchPreference( - pref = readerPref.trueColor(), - title = stringResource(MR.strings.pref_true_color), - subtitle = stringResource(MR.strings.pref_true_color_summary), + Preference.PreferenceItem.TextPreference( + title = stringResource(MR.strings.pref_display_profile), + subtitle = readerPref.displayProfile().get(), + onClick = { + chooseColorProfile.launch(arrayOf("*/*")) + }, ), Preference.PreferenceItem.SwitchPreference( pref = readerPref.pageTransitions(), diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt b/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt index 3f6c13906..8105192ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/coil/TachiyomiImageDecoder.kt @@ -24,7 +24,7 @@ class TachiyomiImageDecoder(private val resources: ImageSource, private val opti check(decoder != null && decoder.width > 0 && decoder.height > 0) { "Failed to initialize decoder" } - val bitmap = decoder.decode(rgb565 = options.allowRgb565) + val bitmap = decoder.decode() decoder.recycle() check(bitmap != null) { "Failed to decode image" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index e21fa11c6..25607d471 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -39,6 +39,7 @@ import androidx.lifecycle.lifecycleScope import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.google.android.material.elevation.SurfaceColors import com.google.android.material.transition.platform.MaterialContainerTransform +import com.hippo.unifile.UniFile import dev.chrisbanes.insetter.applyInsetter import eu.kanade.domain.base.BasePreferences import eu.kanade.presentation.reader.DisplayRefreshHost @@ -93,6 +94,7 @@ import tachiyomi.i18n.MR import tachiyomi.presentation.core.util.collectAsState import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import java.io.ByteArrayOutputStream class ReaderActivity : BaseActivity() { @@ -814,8 +816,8 @@ class ReaderActivity : BaseActivity() { } .launchIn(lifecycleScope) - readerPreferences.trueColor().changes() - .onEach(::setTrueColor) + readerPreferences.displayProfile().changes() + .onEach { setDisplayProfile(it) } .launchIn(lifecycleScope) readerPreferences.cutoutShort().changes() @@ -854,13 +856,19 @@ class ReaderActivity : BaseActivity() { } /** - * Sets the 32-bit color mode according to [enabled]. + * Sets the display profile to [path]. */ - private fun setTrueColor(enabled: Boolean) { - if (enabled) { - SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.ARGB_8888) - } else { - SubsamplingScaleImageView.setPreferredBitmapConfig(Bitmap.Config.RGB_565) + private fun setDisplayProfile(path: String) { + val file = UniFile.fromUri(baseContext, path.toUri()) + if (file != null && file.exists()) { + val inputStream = file.openInputStream() + val outputStream = ByteArrayOutputStream() + inputStream.use { input -> + outputStream.use { output -> + input.copyTo(output) + } + } + SubsamplingScaleImageView.setDisplayProfile(outputStream.toByteArray()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt index 53e342e76..a71aec302 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt @@ -23,8 +23,7 @@ class ReaderPreferences( fun showReadingMode() = preferenceStore.getBoolean("pref_show_reading_mode", true) - // TODO: default this to true if reader long strip ever goes stable - fun trueColor() = preferenceStore.getBoolean("pref_true_color_key", false) + fun displayProfile() = preferenceStore.getString("pref_display_profile_key", "") fun fullscreen() = preferenceStore.getBoolean("fullscreen", true) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt index 0d973d239..69ea9ba6f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ViewerConfig.kt @@ -22,7 +22,7 @@ abstract class ViewerConfig(readerPreferences: ReaderPreferences, private val sc var doubleTapAnimDuration = 500 var volumeKeysEnabled = false var volumeKeysInverted = false - var trueColor = false + var displayProfile = "" var alwaysShowChapterTransition = true var navigationMode = 0 protected set @@ -62,12 +62,12 @@ abstract class ViewerConfig(readerPreferences: ReaderPreferences, private val sc readerPreferences.readWithVolumeKeysInverted() .register({ volumeKeysInverted = it }) - readerPreferences.trueColor() - .register({ trueColor = it }, { imagePropertyChangedListener?.invoke() }) - readerPreferences.alwaysShowChapterTransition() .register({ alwaysShowChapterTransition = it }) + readerPreferences.displayProfile() + .register({ displayProfile = it }, { imagePropertyChangedListener?.invoke() }) + forceNavigationOverlay = readerPreferences.showNavigationOverlayNewUser().get() if (forceNavigationOverlay) { readerPreferences.showNavigationOverlayNewUser().set(false) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d55c51452..0971247d9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -49,8 +49,8 @@ coil-gif = { module = "io.coil-kt.coil3:coil-gif" } coil-compose = { module = "io.coil-kt.coil3:coil-compose" } coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp" } -subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:7e57335" -image-decoder = "com.github.tachiyomiorg:image-decoder:398d3c074f" +subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:aeaa170036" +image-decoder = "com.github.tachiyomiorg:image-decoder:e08e9be535" natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1" diff --git a/i18n/src/commonMain/resources/MR/base/strings.xml b/i18n/src/commonMain/resources/MR/base/strings.xml index 6c6e1681a..9ca71a2f7 100644 --- a/i18n/src/commonMain/resources/MR/base/strings.xml +++ b/i18n/src/commonMain/resources/MR/base/strings.xml @@ -366,6 +366,8 @@ Briefly show current mode when reader is opened 32-bit color Reduces banding, but may impact performance + Display profile + Select ICC profile Crop borders Custom brightness Grayscale