From d07d5cbfde43040381b60c4be19e24aa1182ff97 Mon Sep 17 00:00:00 2001 From: panpf Date: Thu, 15 Aug 2024 14:45:04 +0800 Subject: [PATCH] improve: Improve the accuracy of animation-related Decoder in determining the image type. No longer rely on the mimeType attribute of FetchResult because it may be inaccurate. --- CHANGELOG.md | 2 ++ CHANGELOG_zh.md | 2 ++ .../test/decode/GifDrawableDecoderTest.kt | 14 ++++++++++++++ .../panpf/sketch/decode/GifDrawableDecoder.kt | 17 ++++++++--------- .../test/decode/GifAnimatedDecoderTest.kt | 12 ++++++++++++ .../test/decode/GifMovieDecoderTest.kt | 12 ++++++++++++ .../test/decode/HeifAnimatedDecoderTest.kt | 12 ++++++++++++ .../test/decode/WebpAnimatedDecoderTest.kt | 12 ++++++++++++ .../panpf/sketch/decode/GifAnimatedDecoder.kt | 10 +++------- .../panpf/sketch/decode/GifMovieDecoder.kt | 19 +++++++++---------- .../sketch/decode/HeifAnimatedDecoder.kt | 11 +++-------- .../sketch/decode/WebpAnimatedDecoder.kt | 9 +++------ .../sketch/decode/GifSkiaAnimatedDecoder.kt | 14 ++++++-------- .../sketch/decode/WebpSkiaAnimatedDecoder.kt | 15 ++++++--------- .../github/panpf/sketch/fetch/FetchResult.kt | 3 +++ .../github/panpf/sketch/decode/SvgDecoder.kt | 5 +---- .../sketch/svg/test/decode/SvgDecoderTest.kt | 9 +++++++++ 17 files changed, 117 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d8e77e9e..302e8918a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ Translations: [简体中文](CHANGELOG_zh.md) * fix: Fixed a bug where SkiaAnimatedImagePainter crashed when encountering disguised gif images. [#205](https://github.com/panpf/sketch/issues/205) +* improve: Improve the accuracy of animation-related Decoder in determining the image type. No + longer rely on the mimeType attribute of FetchResult because it may be inaccurate. # 4.0.0-alpha05 diff --git a/CHANGELOG_zh.md b/CHANGELOG_zh.md index 2bd0c26776..23ab183a41 100644 --- a/CHANGELOG_zh.md +++ b/CHANGELOG_zh.md @@ -10,6 +10,8 @@ * fix: 修复 SkiaAnimatedImagePainter 在遇到伪装的 gif 图片时崩溃的 bug。[#205](https://github.com/panpf/sketch/issues/205) +* improve: 改进动图相关 Decoder 在判断图片类型时的准确性,不再依赖 FetchResult 的 mimeType + 属性,因为它可能不准确 # 4.0.0-alpha05 diff --git a/sketch-animated-koralgif/src/androidTest/kotlin/com/github/panpf/sketch/animated/koralgif/test/decode/GifDrawableDecoderTest.kt b/sketch-animated-koralgif/src/androidTest/kotlin/com/github/panpf/sketch/animated/koralgif/test/decode/GifDrawableDecoderTest.kt index 937295cfba..f3ca388484 100644 --- a/sketch-animated-koralgif/src/androidTest/kotlin/com/github/panpf/sketch/animated/koralgif/test/decode/GifDrawableDecoderTest.kt +++ b/sketch-animated-koralgif/src/androidTest/kotlin/com/github/panpf/sketch/animated/koralgif/test/decode/GifDrawableDecoderTest.kt @@ -25,6 +25,7 @@ import com.github.panpf.sketch.decode.internal.createInSampledTransformed import com.github.panpf.sketch.decode.supportKoralGif import com.github.panpf.sketch.drawable.AnimatableDrawable import com.github.panpf.sketch.drawable.GifDrawableWrapperDrawable +import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.fetch.copy import com.github.panpf.sketch.getDrawableOrThrow import com.github.panpf.sketch.images.ResourceImages @@ -33,6 +34,7 @@ import com.github.panpf.sketch.request.animatedTransformation import com.github.panpf.sketch.request.onAnimationEnd import com.github.panpf.sketch.request.onAnimationStart import com.github.panpf.sketch.request.repeatCount +import com.github.panpf.sketch.source.AssetDataSource import com.github.panpf.sketch.source.DataFrom.LOCAL import com.github.panpf.sketch.test.singleton.sketch import com.github.panpf.sketch.test.utils.decode @@ -140,6 +142,18 @@ class GifDrawableDecoderTest { }.apply { Assert.assertNull(this) } + + // Disguised, mimeType; data error + ImageRequest(context, ResourceImages.png.uri).let { + val fetchResult = + FetchResult( + AssetDataSource(sketch, it, ResourceImages.png.resourceName), + "image/gif" + ) + factory.create(it.toRequestContext(sketch), fetchResult) + }.apply { + Assert.assertNull(this) + } } @Test diff --git a/sketch-animated-koralgif/src/main/kotlin/com/github/panpf/sketch/decode/GifDrawableDecoder.kt b/sketch-animated-koralgif/src/main/kotlin/com/github/panpf/sketch/decode/GifDrawableDecoder.kt index d4c1d82e54..2ed5dcba07 100644 --- a/sketch-animated-koralgif/src/main/kotlin/com/github/panpf/sketch/decode/GifDrawableDecoder.kt +++ b/sketch-animated-koralgif/src/main/kotlin/com/github/panpf/sketch/decode/GifDrawableDecoder.kt @@ -22,14 +22,13 @@ import android.graphics.Rect import androidx.annotation.WorkerThread import com.github.panpf.sketch.ComponentRegistry import com.github.panpf.sketch.asSketchImage -import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.calculateSampleSize import com.github.panpf.sketch.decode.internal.createInSampledTransformed import com.github.panpf.sketch.decode.internal.isGif import com.github.panpf.sketch.decode.internal.isSmallerSizeMode -import com.github.panpf.sketch.drawable.GifDrawableWrapperDrawable import com.github.panpf.sketch.drawable.AnimatableDrawable +import com.github.panpf.sketch.drawable.GifDrawableWrapperDrawable import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.ANIMATION_REPEAT_INFINITE import com.github.panpf.sketch.request.animatable2CompatCallbackOf @@ -38,6 +37,7 @@ import com.github.panpf.sketch.request.animationEndCallback import com.github.panpf.sketch.request.animationStartCallback import com.github.panpf.sketch.request.internal.RequestContext import com.github.panpf.sketch.request.repeatCount +import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.util.Size import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -85,7 +85,7 @@ class GifDrawableDecoder( height = imageHeight, mimeType = ImageFormat.GIF.mimeType, ) - val resize= requestContext.computeResize(imageInfo.size) + val resize = requestContext.computeResize(imageInfo.size) val inSampleSize = calculateSampleSize( imageSize = imageSize, targetSize = size, @@ -144,12 +144,11 @@ class GifDrawableDecoder( requestContext: RequestContext, fetchResult: FetchResult ): Decoder? { - if (!requestContext.request.disallowAnimatedImage) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - val isGif = imageFormat == ImageFormat.GIF || fetchResult.headerBytes.isGif() - if (isGif) { - return GifDrawableDecoder(requestContext, fetchResult.dataSource) - } + if ( + !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isGif() + ) { + return GifDrawableDecoder(requestContext, fetchResult.dataSource) } return null } diff --git a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifAnimatedDecoderTest.kt b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifAnimatedDecoderTest.kt index 47c30467dc..05be148f1d 100644 --- a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifAnimatedDecoderTest.kt +++ b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifAnimatedDecoderTest.kt @@ -151,6 +151,18 @@ class GifAnimatedDecoderTest { }.apply { Assert.assertNull(this) } + + // Disguised, mimeType; data error + ImageRequest(context, ResourceImages.png.uri).let { + val fetchResult = + FetchResult( + AssetDataSource(sketch, it, ResourceImages.png.resourceName), + "image/gif" + ) + factory.create(it.toRequestContext(sketch), fetchResult) + }.apply { + Assert.assertNull(this) + } } @Test diff --git a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifMovieDecoderTest.kt b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifMovieDecoderTest.kt index a7bb921314..1f07125771 100644 --- a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifMovieDecoderTest.kt +++ b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/GifMovieDecoderTest.kt @@ -149,6 +149,18 @@ class GifMovieDecoderTest { }.apply { Assert.assertNull(this) } + + // Disguised, mimeType; data error + ImageRequest(context, ResourceImages.png.uri).let { + val fetchResult = + FetchResult( + AssetDataSource(sketch, it, ResourceImages.png.resourceName), + "image/gif" + ) + factory.create(it.toRequestContext(sketch), fetchResult) + }.apply { + Assert.assertNull(this) + } } @Test diff --git a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/HeifAnimatedDecoderTest.kt b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/HeifAnimatedDecoderTest.kt index 19a03fbf9d..64515ab71e 100644 --- a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/HeifAnimatedDecoderTest.kt +++ b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/HeifAnimatedDecoderTest.kt @@ -158,6 +158,18 @@ class HeifAnimatedDecoderTest { "image/jpeg", ) factory.create(it.toRequestContext(sketch), fetchResult) + }.apply { + Assert.assertNotNull(this) + } + + // Disguised, mimeType; data error + ImageRequest(context, ResourceImages.png.uri).let { + val fetchResult = + FetchResult( + AssetDataSource(sketch, it, ResourceImages.png.resourceName), + "image/heif" + ) + factory.create(it.toRequestContext(sketch), fetchResult) }.apply { Assert.assertNull(this) } diff --git a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/WebpAnimatedDecoderTest.kt b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/WebpAnimatedDecoderTest.kt index 002294a6a1..f8a3bca9e6 100644 --- a/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/WebpAnimatedDecoderTest.kt +++ b/sketch-animated/src/androidInstrumentedTest/kotlin/com/github/panpf/sketch/animated/android/test/decode/WebpAnimatedDecoderTest.kt @@ -158,6 +158,18 @@ class WebpAnimatedDecoderTest { "image/jpeg", ) factory.create(it.toRequestContext(sketch), fetchResult) + }.apply { + Assert.assertNotNull(this) + } + + // Disguised, mimeType; data error + ImageRequest(context, ResourceImages.png.uri).let { + val fetchResult = + FetchResult( + AssetDataSource(sketch, it, ResourceImages.png.resourceName), + "image/webp" + ) + factory.create(it.toRequestContext(sketch), fetchResult) }.apply { Assert.assertNull(this) } diff --git a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifAnimatedDecoder.kt b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifAnimatedDecoder.kt index 6a5f126442..0c86aaa5cd 100644 --- a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifAnimatedDecoder.kt +++ b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifAnimatedDecoder.kt @@ -18,12 +18,11 @@ package com.github.panpf.sketch.decode import android.os.Build import androidx.annotation.RequiresApi import com.github.panpf.sketch.ComponentRegistry -import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.decode.internal.ImageDecoderAnimatedDecoder -import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.isGif import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.internal.RequestContext +import com.github.panpf.sketch.source.DataSource /** * Adds gif support by AnimatedImageDrawable @@ -62,12 +61,9 @@ class GifAnimatedDecoder( if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isGif() ) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - val isGif = imageFormat == ImageFormat.GIF || fetchResult.headerBytes.isGif() - if (isGif) { - return GifAnimatedDecoder(requestContext, dataSource) - } + return GifAnimatedDecoder(requestContext, dataSource) } return null } diff --git a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifMovieDecoder.kt b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifMovieDecoder.kt index d6b504461d..e3ffb92591 100644 --- a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifMovieDecoder.kt +++ b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/GifMovieDecoder.kt @@ -22,21 +22,21 @@ import android.os.Build import androidx.annotation.RequiresApi import androidx.annotation.WorkerThread import com.github.panpf.sketch.ComponentRegistry -import com.github.panpf.sketch.source.DataSource +import com.github.panpf.sketch.asSketchImage import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.isGif -import com.github.panpf.sketch.drawable.MovieDrawable import com.github.panpf.sketch.drawable.AnimatableDrawable +import com.github.panpf.sketch.drawable.MovieDrawable import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.ANIMATION_REPEAT_INFINITE import com.github.panpf.sketch.request.animatable2CompatCallbackOf import com.github.panpf.sketch.request.animatedTransformation import com.github.panpf.sketch.request.animationEndCallback import com.github.panpf.sketch.request.animationStartCallback -import com.github.panpf.sketch.asSketchImage import com.github.panpf.sketch.request.bitmapConfig import com.github.panpf.sketch.request.internal.RequestContext import com.github.panpf.sketch.request.repeatCount +import com.github.panpf.sketch.source.DataSource import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okio.buffer @@ -68,7 +68,8 @@ class GifMovieDecoder( @WorkerThread override suspend fun decode(): Result = kotlin.runCatching { val request = requestContext.request - val movie: Movie? = dataSource.openSource().buffer().inputStream().use { Movie.decodeStream(it) } + val movie: Movie? = + dataSource.openSource().buffer().inputStream().use { Movie.decodeStream(it) } val width = movie?.width() ?: 0 val height = movie?.height() ?: 0 @@ -123,14 +124,12 @@ class GifMovieDecoder( fetchResult: FetchResult ): Decoder? { val dataSource = fetchResult.dataSource - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT + if ( + Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isGif() ) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - val isGif = imageFormat == ImageFormat.GIF || fetchResult.headerBytes.isGif() - if (isGif) { - return GifMovieDecoder(requestContext, dataSource) - } + return GifMovieDecoder(requestContext, dataSource) } return null } diff --git a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/HeifAnimatedDecoder.kt b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/HeifAnimatedDecoder.kt index 09be8b1be9..5450675044 100644 --- a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/HeifAnimatedDecoder.kt +++ b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/HeifAnimatedDecoder.kt @@ -18,12 +18,11 @@ package com.github.panpf.sketch.decode import android.os.Build import androidx.annotation.RequiresApi import com.github.panpf.sketch.ComponentRegistry -import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.decode.internal.ImageDecoderAnimatedDecoder -import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.isAnimatedHeif import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.internal.RequestContext +import com.github.panpf.sketch.source.DataSource /** * Adds animation heif support by AnimatedImageDrawable @@ -62,13 +61,9 @@ class HeifAnimatedDecoder( if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isAnimatedHeif() ) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - if ((imageFormat == null || imageFormat == ImageFormat.HEIC || imageFormat == ImageFormat.HEIF) - && fetchResult.headerBytes.isAnimatedHeif() - ) { - return HeifAnimatedDecoder(requestContext, dataSource) - } + return HeifAnimatedDecoder(requestContext, dataSource) } return null } diff --git a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/WebpAnimatedDecoder.kt b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/WebpAnimatedDecoder.kt index fe6ef6541e..5e0a3d33d9 100644 --- a/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/WebpAnimatedDecoder.kt +++ b/sketch-animated/src/androidMain/kotlin/com/github/panpf/sketch/decode/WebpAnimatedDecoder.kt @@ -18,12 +18,11 @@ package com.github.panpf.sketch.decode import android.os.Build import androidx.annotation.RequiresApi import com.github.panpf.sketch.ComponentRegistry -import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.decode.internal.ImageDecoderAnimatedDecoder -import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.isAnimatedWebP import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.internal.RequestContext +import com.github.panpf.sketch.source.DataSource /** * Adds animation webp support by AnimatedImageDrawable @@ -62,11 +61,9 @@ class WebpAnimatedDecoder( if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isAnimatedWebP() ) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - if ((imageFormat == null || imageFormat == ImageFormat.WEBP) && fetchResult.headerBytes.isAnimatedWebP()) { - return WebpAnimatedDecoder(requestContext, dataSource) - } + return WebpAnimatedDecoder(requestContext, dataSource) } return null } diff --git a/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/GifSkiaAnimatedDecoder.kt b/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/GifSkiaAnimatedDecoder.kt index c5ffff9be9..acb3a1a093 100644 --- a/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/GifSkiaAnimatedDecoder.kt +++ b/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/GifSkiaAnimatedDecoder.kt @@ -1,12 +1,11 @@ package com.github.panpf.sketch.decode import com.github.panpf.sketch.ComponentRegistry -import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.decode.internal.SkiaAnimatedDecoder -import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.isGif import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.internal.RequestContext +import com.github.panpf.sketch.source.DataSource /** * Adds gif support by Skia @@ -25,12 +24,11 @@ class GifSkiaAnimatedDecoder( override val key: String = "GifSkiaAnimatedDecoder" override fun create(requestContext: RequestContext, fetchResult: FetchResult): Decoder? { - if (!requestContext.request.disallowAnimatedImage) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - val isGif = imageFormat == ImageFormat.GIF || fetchResult.headerBytes.isGif() - if (isGif) { - return GifSkiaAnimatedDecoder(requestContext, fetchResult.dataSource) - } + if ( + !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isGif() + ) { + return GifSkiaAnimatedDecoder(requestContext, fetchResult.dataSource) } return null } diff --git a/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/WebpSkiaAnimatedDecoder.kt b/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/WebpSkiaAnimatedDecoder.kt index 637916f6ed..d06f91eac3 100644 --- a/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/WebpSkiaAnimatedDecoder.kt +++ b/sketch-animated/src/nonAndroidMain/kotlin/com/github/panpf/sketch/decode/WebpSkiaAnimatedDecoder.kt @@ -1,12 +1,11 @@ package com.github.panpf.sketch.decode import com.github.panpf.sketch.ComponentRegistry -import com.github.panpf.sketch.source.DataSource import com.github.panpf.sketch.decode.internal.SkiaAnimatedDecoder -import com.github.panpf.sketch.decode.internal.ImageFormat import com.github.panpf.sketch.decode.internal.isAnimatedWebP import com.github.panpf.sketch.fetch.FetchResult import com.github.panpf.sketch.request.internal.RequestContext +import com.github.panpf.sketch.source.DataSource /** * Adds animation webp support by Skia @@ -25,13 +24,11 @@ class WebpSkiaAnimatedDecoder( override val key: String = "WebpSkiaAnimatedDecoder" override fun create(requestContext: RequestContext, fetchResult: FetchResult): Decoder? { - if (!requestContext.request.disallowAnimatedImage) { - val imageFormat = ImageFormat.parseMimeType(fetchResult.mimeType) - val isAnimatedWebp = - (imageFormat == null || imageFormat == ImageFormat.WEBP) && fetchResult.headerBytes.isAnimatedWebP() - if (isAnimatedWebp) { - return WebpSkiaAnimatedDecoder(requestContext, fetchResult.dataSource) - } + if ( + !requestContext.request.disallowAnimatedImage + && fetchResult.headerBytes.isAnimatedWebP() + ) { + return WebpSkiaAnimatedDecoder(requestContext, fetchResult.dataSource) } return null } diff --git a/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/fetch/FetchResult.kt b/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/fetch/FetchResult.kt index 2e11c4bcd5..afe5741a4d 100644 --- a/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/fetch/FetchResult.kt +++ b/sketch-core/src/commonMain/kotlin/com/github/panpf/sketch/fetch/FetchResult.kt @@ -35,6 +35,9 @@ interface FetchResult { val dataSource: DataSource + /** + * This mimeType is extracted from the uri and may not be accurate + */ val mimeType: String? val dataFrom: DataFrom diff --git a/sketch-svg/src/commonMain/kotlin/com/github/panpf/sketch/decode/SvgDecoder.kt b/sketch-svg/src/commonMain/kotlin/com/github/panpf/sketch/decode/SvgDecoder.kt index 53651b40b5..2f2c3c0ab4 100644 --- a/sketch-svg/src/commonMain/kotlin/com/github/panpf/sketch/decode/SvgDecoder.kt +++ b/sketch-svg/src/commonMain/kotlin/com/github/panpf/sketch/decode/SvgDecoder.kt @@ -67,10 +67,7 @@ class SvgDecoder( fetchResult: FetchResult ): SvgDecoder? { val dataSource = fetchResult.dataSource - return if ( - MIME_TYPE.equals(fetchResult.mimeType, ignoreCase = true) - || fetchResult.headerBytes.isSvg() - ) { + return if (fetchResult.headerBytes.isSvg()) { SvgDecoder( requestContext = requestContext, dataSource = dataSource, diff --git a/sketch-svg/src/commonTest/kotlin/com/github/panpf/sketch/svg/test/decode/SvgDecoderTest.kt b/sketch-svg/src/commonTest/kotlin/com/github/panpf/sketch/svg/test/decode/SvgDecoderTest.kt index 534c07706a..9f1902f9f1 100644 --- a/sketch-svg/src/commonTest/kotlin/com/github/panpf/sketch/svg/test/decode/SvgDecoderTest.kt +++ b/sketch-svg/src/commonTest/kotlin/com/github/panpf/sketch/svg/test/decode/SvgDecoderTest.kt @@ -130,6 +130,15 @@ class SvgDecoderTest { }.apply { assertNotNull(this) } + + // Disguised, mimeType; data error + ImageRequest(context, ResourceImages.png.uri).let { + val fetchResult = sketch.components.newFetcherOrThrow(it).fetch().getOrThrow() + .copy(mimeType = "image/svg+xml") + factory.create(it.toRequestContext(sketch), fetchResult) + }.apply { + assertNull(this) + } } @Test