#984 rendering of SVG with large header

This commit is contained in:
Thibault Deckers 2024-04-18 00:12:52 +02:00
parent ce27d47342
commit 342397fb85
5 changed files with 28 additions and 4 deletions

View file

@ -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
## <a id="v1.10.9"></a>[v1.10.9] - 2024-04-14
### Fixed

View file

@ -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

View file

@ -279,6 +279,6 @@ class ActivityResultStreamHandler(private val activity: Activity, arguments: Any
companion object {
private val LOG_TAG = LogUtils.createTag<ActivityResultStreamHandler>()
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
}
}

View file

@ -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()

View file

@ -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%")
}
}
}
// 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
}
}