Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
7d95766812
3 changed files with 38 additions and 1 deletions
|
@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
- Info: show matching dynamic albums
|
- Info: show matching dynamic albums
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- crash when decoding some large thumbnails
|
||||||
|
|
||||||
## <a id="v1.13.2"></a>[v1.13.2] - 2025-06-02
|
## <a id="v1.13.2"></a>[v1.13.2] - 2025-06-02
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -5,8 +5,10 @@ import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
|
import android.util.Log
|
||||||
import android.util.Size
|
import android.util.Size
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.graphics.scale
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.DecodeFormat
|
import com.bumptech.glide.load.DecodeFormat
|
||||||
|
@ -17,6 +19,7 @@ import deckers.thibault.aves.decoder.AvesAppGlideModule
|
||||||
import deckers.thibault.aves.decoder.MultiPageImage
|
import deckers.thibault.aves.decoder.MultiPageImage
|
||||||
import deckers.thibault.aves.utils.BitmapUtils
|
import deckers.thibault.aves.utils.BitmapUtils
|
||||||
import deckers.thibault.aves.utils.BitmapUtils.applyExifOrientation
|
import deckers.thibault.aves.utils.BitmapUtils.applyExifOrientation
|
||||||
|
import deckers.thibault.aves.utils.LogUtils
|
||||||
import deckers.thibault.aves.utils.MimeTypes
|
import deckers.thibault.aves.utils.MimeTypes
|
||||||
import deckers.thibault.aves.utils.MimeTypes.SVG
|
import deckers.thibault.aves.utils.MimeTypes.SVG
|
||||||
import deckers.thibault.aves.utils.MimeTypes.isVideo
|
import deckers.thibault.aves.utils.MimeTypes.isVideo
|
||||||
|
@ -25,6 +28,8 @@ import deckers.thibault.aves.utils.MimeTypes.needRotationAfterGlide
|
||||||
import deckers.thibault.aves.utils.StorageUtils
|
import deckers.thibault.aves.utils.StorageUtils
|
||||||
import deckers.thibault.aves.utils.UriUtils.tryParseId
|
import deckers.thibault.aves.utils.UriUtils.tryParseId
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
import kotlin.math.min
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class ThumbnailFetcher internal constructor(
|
class ThumbnailFetcher internal constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
|
@ -77,6 +82,29 @@ class ThumbnailFetcher internal constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bitmap != null) {
|
||||||
|
if (bitmap.width > width && bitmap.height > height) {
|
||||||
|
val scalingFactor: Double = min(bitmap.width.toDouble() / width, bitmap.height.toDouble() / height)
|
||||||
|
val dstWidth = (bitmap.width / scalingFactor).roundToInt()
|
||||||
|
val dstHeight = (bitmap.height / scalingFactor).roundToInt()
|
||||||
|
Log.d(
|
||||||
|
LOG_TAG, "rescale thumbnail for mimeType=$mimeType uri=$uri width=$width height=$height" +
|
||||||
|
", with bitmap byteCount=${bitmap.byteCount} size=${bitmap.width}x${bitmap.height}" +
|
||||||
|
", to target=${dstWidth}x${dstHeight}"
|
||||||
|
)
|
||||||
|
bitmap = bitmap.scale(dstWidth, dstHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitmap.byteCount > BITMAP_SIZE_DANGER_THRESHOLD) {
|
||||||
|
result.error(
|
||||||
|
"getThumbnail-large", "thumbnail bitmap dangerously large" +
|
||||||
|
" for mimeType=$mimeType uri=$uri pageId=$pageId width=$width height=$height" +
|
||||||
|
", with bitmap byteCount=${bitmap.byteCount} size=${bitmap.width}x${bitmap.height} config=${bitmap.config?.name}", null
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// do not recycle bitmaps fetched from `ContentResolver` or Glide as their lifecycle is unknown
|
// do not recycle bitmaps fetched from `ContentResolver` or Glide as their lifecycle is unknown
|
||||||
val recycle = false
|
val recycle = false
|
||||||
val bytes = BitmapUtils.getRawBytes(bitmap, recycle = recycle)
|
val bytes = BitmapUtils.getRawBytes(bitmap, recycle = recycle)
|
||||||
|
@ -144,4 +172,9 @@ class ThumbnailFetcher internal constructor(
|
||||||
Glide.with(context).clear(target)
|
Glide.with(context).clear(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOG_TAG = LogUtils.createTag<ThumbnailFetcher>()
|
||||||
|
private const val BITMAP_SIZE_DANGER_THRESHOLD = 20 * (1 shl 20) // MB
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -247,7 +247,7 @@ class PlatformMediaFetchService implements MediaFetchService {
|
||||||
return InteropDecoding.bytesToCodec(bytes);
|
return InteropDecoding.bytesToCodec(bytes);
|
||||||
}
|
}
|
||||||
} on PlatformException catch (e, stack) {
|
} on PlatformException catch (e, stack) {
|
||||||
if (_isUnknownVisual(mimeType)) {
|
if (_isUnknownVisual(mimeType) || e.code == 'getThumbnail-large') {
|
||||||
await reportService.recordError(e, stack);
|
await reportService.recordError(e, stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue