diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 45a994ad28..6d3d32e11f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -37,6 +37,7 @@ import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers +import java.io.ByteArrayInputStream import java.io.InputStream import java.nio.ByteBuffer import java.util.concurrent.TimeUnit @@ -258,31 +259,40 @@ class PagerPageHolder( unsubscribeReadImageHeader() val streamFn = page.stream ?: return - var openStream: InputStream? = null readImageHeaderSubscription = Observable .fromCallable { val stream = streamFn().buffered(16) - openStream = process(item, stream) - - ImageUtil.isAnimatedAndSupported(stream) + val itemStream = process(item, stream) + try { + val streamBytes = itemStream.readBytes() + val isAnimated = ImageUtil.isAnimatedAndSupported(stream) + val background = if (!isAnimated && viewer.config.automaticBackground) { + ByteArrayInputStream(streamBytes).use { bais -> + ImageUtil.chooseBackground(context, bais) + } + } else { + null + } + Triple(streamBytes, isAnimated, background) + } finally { + stream.close() + itemStream.close() + } } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .doOnNext { isAnimated -> - if (!isAnimated) { - initSubsamplingImageView().apply { - if (viewer.config.automaticBackground) { - background = ImageUtil.chooseBackground(context, openStream!!) + .doOnNext { (streamBytes, isAnimated, background) -> + ByteArrayInputStream(streamBytes).use { bais -> + if (!isAnimated) { + this.background = background + initSubsamplingImageView().apply { + setImage(ImageSource.inputStream(bais)) } - setImage(ImageSource.inputStream(openStream!!)) + } else { + initImageView().setImage(bais) } - } else { - initImageView().setImage(openStream!!) } } - // Keep the Rx stream alive to close the input stream only when unsubscribed - .flatMap { Observable.never() } - .doOnUnsubscribe { openStream?.close() } .subscribe({}, {}) } 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 998d1f71b2..3c4a564540 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 @@ -18,7 +18,6 @@ import androidx.core.graphics.green import androidx.core.graphics.red import tachiyomi.decoder.Format import tachiyomi.decoder.ImageDecoder -import tachiyomi.decoder.ImageType import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.InputStream @@ -181,11 +180,9 @@ object ImageUtil { * Algorithm for determining what background to accompany a comic/manga page */ fun chooseBackground(context: Context, imageStream: InputStream): Drawable { - imageStream.mark(imageStream.available() + 1) - - val image = BitmapFactory.decodeStream(imageStream) - - imageStream.reset() + val decoder = ImageDecoder.newInstance(imageStream) + val image = decoder?.decode() + decoder?.recycle() val whiteColor = Color.WHITE if (image == null) return ColorDrawable(whiteColor)