CoilPreviewDecoder.kt (2513B) - raw


      1 package me.rhunk.snapenhance.ui.util.coil
      2 
      3 import android.content.res.Resources
      4 import android.graphics.Bitmap
      5 import android.graphics.drawable.BitmapDrawable
      6 import coil.decode.DecodeResult
      7 import coil.decode.Decoder
      8 import coil.fetch.SourceResult
      9 import me.rhunk.snapenhance.common.data.FileType
     10 import me.rhunk.snapenhance.common.data.download.MediaEncryptionKeyPair
     11 import me.rhunk.snapenhance.common.data.download.SplitMediaAssetType
     12 import me.rhunk.snapenhance.common.logger.AbstractLogger
     13 import me.rhunk.snapenhance.common.util.snap.MediaDownloaderHelper
     14 import me.rhunk.snapenhance.core.util.media.PreviewUtils
     15 
     16 class CoilPreviewDecoder(
     17     private val resources: Resources,
     18     private val sourceResult: SourceResult,
     19     private val encryptionKeyPair: MediaEncryptionKeyPair? = null,
     20     private val mergeOverlay: Boolean = false
     21 ): Decoder {
     22     override suspend fun decode(): DecodeResult {
     23         return sourceResult.source.file().toFile().inputStream().use { fileInputStream ->
     24             val cipherInputStream = encryptionKeyPair?.decryptInputStream(fileInputStream) ?: fileInputStream
     25 
     26             var bitmap: Bitmap? = null
     27             var overlayBitmap: Bitmap? = null
     28 
     29             MediaDownloaderHelper.getSplitElements(cipherInputStream) { type, inputStream ->
     30                 if (inputStream.available() > 50 * 1024 * 1024) {
     31                     return@getSplitElements
     32                 }
     33                 if (type == SplitMediaAssetType.ORIGINAL || (mergeOverlay && type == SplitMediaAssetType.OVERLAY)) {
     34                     runCatching {
     35                         val bytes = inputStream.readBytes()
     36                         PreviewUtils.createPreview(bytes, isVideo = FileType.fromByteArray(bytes).isVideo)?.let {
     37                             if (type == SplitMediaAssetType.ORIGINAL) {
     38                                 bitmap = it
     39                             } else {
     40                                 overlayBitmap = it
     41                             }
     42                         }
     43                     }.onFailure {
     44                         AbstractLogger.directError("CoilPreviewDecoder", it)
     45                     }
     46                 }
     47             }
     48 
     49             if (mergeOverlay && overlayBitmap != null) {
     50                 bitmap = PreviewUtils.mergeBitmapOverlay(bitmap!!, overlayBitmap!!)
     51             }
     52 
     53             cipherInputStream.close()
     54 
     55             DecodeResult(
     56                 drawable = BitmapDrawable(resources, bitmap!!),
     57                 isSampled = true
     58             )
     59         }
     60     }
     61 }