diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01ef0cb47..92375ca0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
- Cataloguing: identify Apple variant of HDR images
+### Fixed
+
+- rendering of SVG with large header
+
## [v1.10.9] - 2024-04-14
### Fixed
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/SvgRegionFetcher.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/SvgRegionFetcher.kt
index 32eaf7e25..6b3d7f9aa 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/SvgRegionFetcher.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/SvgRegionFetcher.kt
@@ -10,6 +10,7 @@ import com.caverock.androidsvg.PreserveAspectRatio
import com.caverock.androidsvg.RenderOptions
import com.caverock.androidsvg.SVG
import com.caverock.androidsvg.SVGParseException
+import deckers.thibault.aves.metadata.SVGParserBufferedInputStream
import deckers.thibault.aves.metadata.SvgHelper.normalizeSize
import deckers.thibault.aves.utils.BitmapUtils.ARGB_8888_BYTE_SIZE
import deckers.thibault.aves.utils.BitmapUtils.getBytes
@@ -47,7 +48,7 @@ class SvgRegionFetcher internal constructor(
if (currentSvgRef == null) {
val newSvg = StorageUtils.openInputStream(context, uri)?.use { input ->
try {
- SVG.getFromInputStream(input)
+ SVG.getFromInputStream(SVGParserBufferedInputStream(input))
} catch (ex: SVGParseException) {
result.error("fetch-parse", "failed to parse SVG for uri=$uri regionRect=$regionRect", null)
return
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt
index 9fd0d45a0..7d442e98b 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ActivityResultStreamHandler.kt
@@ -279,6 +279,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
companion object {
private val LOG_TAG = LogUtils.createTag()
const val CHANNEL = "deckers.thibault/aves/activity_result_stream"
- private const val BUFFER_SIZE = 2 shl 17 // 256kB
+ private const val BUFFER_SIZE = 1 shl 18 // 256kB
}
}
\ No newline at end of file
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/decoder/SvgGlideModule.kt b/android/app/src/main/kotlin/deckers/thibault/aves/decoder/SvgGlideModule.kt
index d544ba203..bf4e3b6d0 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/decoder/SvgGlideModule.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/decoder/SvgGlideModule.kt
@@ -18,6 +18,7 @@ import com.bumptech.glide.module.LibraryGlideModule
import com.bumptech.glide.signature.ObjectKey
import com.caverock.androidsvg.SVG
import com.caverock.androidsvg.SVGParseException
+import deckers.thibault.aves.metadata.SVGParserBufferedInputStream
import deckers.thibault.aves.metadata.SvgHelper.normalizeSize
import deckers.thibault.aves.utils.StorageUtils
import kotlin.math.ceil
@@ -52,7 +53,7 @@ internal class SvgFetcher(val model: SvgImage, val width: Int, val height: Int)
val bitmap: Bitmap? = StorageUtils.openInputStream(context, uri)?.use { input ->
try {
- SVG.getFromInputStream(input)?.let { svg ->
+ SVG.getFromInputStream(SVGParserBufferedInputStream(input))?.let { svg ->
svg.normalizeSize()
val viewBox = svg.documentViewBox
val svgWidth = viewBox.width()
diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/SvgHelper.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/SvgHelper.kt
index 08efc7bb5..da90f0c0e 100644
--- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/SvgHelper.kt
+++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/SvgHelper.kt
@@ -1,6 +1,9 @@
package deckers.thibault.aves.metadata
import com.caverock.androidsvg.SVG
+import java.io.BufferedInputStream
+import java.io.InputStream
+import kotlin.math.max
object SvgHelper {
fun SVG.normalizeSize() {
@@ -10,4 +13,19 @@ object SvgHelper {
setDocumentWidth("100%")
setDocumentHeight("100%")
}
-}
\ No newline at end of file
+}
+
+// As of AndroidSVG v1.4, SVGParser.ENTITY_WATCH_BUFFER_SIZE is set at 4096.
+// This constant is not configurable and used for the internal buffer mark read limit.
+// Parsing will fail if the SVG header is larger than this value.
+// So we define and apply a minimum read limit.
+class SVGParserBufferedInputStream(input: InputStream) : BufferedInputStream(input) {
+ @Synchronized
+ override fun mark(readlimit: Int) {
+ super.mark(max(MINIMUM_READ_LIMIT, readlimit))
+ }
+
+ companion object {
+ private const val MINIMUM_READ_LIMIT = 1 shl 14 // 16kB
+ }
+}