diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index fc18b9f27..f8ebc535d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -392,7 +392,10 @@ class Downloader( return pageObservable // When the page is ready, set page path, progress (just in case) and status .doOnNext { file -> - splitTallImageIfNeeded(page, tmpDir) + val success = splitTallImageIfNeeded(page, tmpDir) + if (success.not()) { + notifier.onError(context.getString(R.string.download_notifier_split_failed), download.chapter.name, download.manga.title) + } page.uri = file.uri page.progress = 100 download.downloadedImages++ @@ -477,8 +480,8 @@ class Downloader( return MimeTypeMap.getSingleton().getExtensionFromMimeType(mime) ?: "jpg" } - private fun splitTallImageIfNeeded(page: Page, tmpDir: UniFile) { - if (!preferences.splitTallImages().get()) return + private fun splitTallImageIfNeeded(page: Page, tmpDir: UniFile): Boolean { + if (!preferences.splitTallImages().get()) return true val filename = String.format("%03d", page.number) val imageFile = tmpDir.listFiles()?.find { it.name!!.startsWith(filename) } @@ -487,8 +490,9 @@ class Downloader( ?: throw Error(context.getString(R.string.download_notifier_split_page_path_not_found, page.number)) // check if the original page was previously splitted before then skip. - if (imageFile.name!!.contains("__")) return - ImageUtil.splitTallImage(imageFile, imageFilePath) + if (imageFile.name!!.contains("__")) return true + + return ImageUtil.splitTallImage(imageFile, imageFilePath) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterPresenter.kt index dfe1b26f4..e4bec0995 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceFilterPresenter.kt @@ -33,15 +33,12 @@ class SourceFilterPresenter( .catch { exception -> _state.value = SourceFilterState.Error(exception) } - .collectLatest { sourceLangMap -> - val uiModels = sourceLangMap.toFilterUiModels() - _state.value = SourceFilterState.Success(uiModels) - } + .collectLatest(::collectLatestSourceLangMap) } } - private fun Map>.toFilterUiModels(): List { - return this.flatMap { + private fun collectLatestSourceLangMap(sourceLangMap: Map>) { + val uiModels = sourceLangMap.flatMap { val isLangEnabled = it.key in preferences.enabledLanguages().get() val header = listOf(FilterUiModel.Header(it.key, isLangEnabled)) @@ -53,6 +50,7 @@ class SourceFilterPresenter( ) } } + _state.value = SourceFilterState.Success(uiModels) } fun toggleSource(source: Source) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt index c3d91e25f..184447512 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/ImageUtil.kt @@ -19,6 +19,7 @@ import androidx.core.graphics.createBitmap import androidx.core.graphics.green import androidx.core.graphics.red import com.hippo.unifile.UniFile +import logcat.LogPriority import tachiyomi.decoder.Format import tachiyomi.decoder.ImageDecoder import java.io.BufferedInputStream @@ -182,7 +183,7 @@ object ImageUtil { * * @return true if the height:width ratio is greater than 3. */ - fun isTallImage(imageStream: InputStream): Boolean { + private fun isTallImage(imageStream: InputStream): Boolean { val options = extractImageOptions(imageStream, false) return (options.outHeight / options.outWidth) > 3 } @@ -190,9 +191,9 @@ object ImageUtil { /** * Splits tall images to improve performance of reader */ - fun splitTallImage(imageFile: UniFile, imageFilePath: String) { + fun splitTallImage(imageFile: UniFile, imageFilePath: String): Boolean { if (isAnimatedAndSupported(imageFile.openInputStream()) || !isTallImage(imageFile.openInputStream())) { - return + return true } val options = extractImageOptions(imageFile.openInputStream(), false).apply { inJustDecodeBounds = false } @@ -213,6 +214,11 @@ object ImageUtil { BitmapRegionDecoder.newInstance(imageFile.openInputStream(), false) } + if (bitmapRegionDecoder == null) { + logcat { "Failed to create new instance of BitmapRegionDecoder" } + return false + } + try { (0 until partCount).forEach { splitIndex -> val splitPath = imageFilePath.substringBeforeLast(".") + "__${"%03d".format(splitIndex + 1)}.jpg" @@ -225,19 +231,21 @@ object ImageUtil { val region = Rect(0, topOffset, imageWidth, bottomOffset) FileOutputStream(splitPath).use { outputStream -> - val splitBitmap = bitmapRegionDecoder!!.decodeRegion(region, options) + val splitBitmap = bitmapRegionDecoder.decodeRegion(region, options) splitBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream) } } imageFile.delete() + return true } catch (e: Exception) { // Image splits were not successfully saved so delete them and keep the original image (0 until partCount) - .map { imageFile.filePath!!.substringBeforeLast(".") + "__${"%03d".format(it + 1)}.jpg" } + .map { imageFilePath.substringBeforeLast(".") + "__${"%03d".format(it + 1)}.jpg" } .forEach { File(it).delete() } - throw e + logcat(LogPriority.ERROR, e) + return false } finally { - bitmapRegionDecoder?.recycle() + bitmapRegionDecoder.recycle() } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0c1bbed88..ef43e434f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -820,6 +820,7 @@ Download completed Page %d not found while splitting Couldn\'t find file path of page %d + Couldn\'t split downloaded image Common