fixed crash when loading TIFF on Android 11
This commit is contained in:
parent
7281eaff06
commit
276743bc64
5 changed files with 88 additions and 74 deletions
|
@ -240,27 +240,30 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val metadataMap = HashMap<String, FieldMap>()
|
val metadataMap = HashMap<String, FieldMap>()
|
||||||
var dirCount: Int? = null
|
var fd = context.contentResolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
context.contentResolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
if (fd == null) {
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
result.error("getTiffStructure-fd", "failed to get file descriptor", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var options = TiffBitmapFactory.Options().apply {
|
||||||
inJustDecodeBounds = true
|
inJustDecodeBounds = true
|
||||||
}
|
}
|
||||||
TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
metadataMap["0"] = tiffOptionsToMap(options)
|
metadataMap["0"] = tiffOptionsToMap(options)
|
||||||
dirCount = options.outDirectoryCount
|
val dirCount = options.outDirectoryCount
|
||||||
|
for (i in 1 until dirCount) {
|
||||||
|
fd = context.contentResolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
|
if (fd == null) {
|
||||||
|
result.error("getTiffStructure-fd", "failed to get file descriptor", null)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (dirCount != null) {
|
options = TiffBitmapFactory.Options().apply {
|
||||||
for (i in 1 until dirCount!!) {
|
|
||||||
context.contentResolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
|
||||||
inJustDecodeBounds = true
|
inJustDecodeBounds = true
|
||||||
inDirectoryNumber = i
|
inDirectoryNumber = i
|
||||||
}
|
}
|
||||||
TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
metadataMap["$i"] = tiffOptionsToMap(options)
|
metadataMap["$i"] = tiffOptionsToMap(options)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
result.success(metadataMap)
|
result.success(metadataMap)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
result.error("getTiffStructure-read", "failed to read tiff", e.message)
|
result.error("getTiffStructure-read", "failed to read tiff", e.message)
|
||||||
|
|
|
@ -18,21 +18,23 @@ class TiffRegionFetcher internal constructor(
|
||||||
page: Int = 0,
|
page: Int = 0,
|
||||||
result: MethodChannel.Result,
|
result: MethodChannel.Result,
|
||||||
) {
|
) {
|
||||||
val resolver = context.contentResolver
|
|
||||||
try {
|
try {
|
||||||
resolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
val fd = context.contentResolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
|
if (fd == null) {
|
||||||
|
result.error("getRegion-tiff-fd", "failed to get file descriptor for uri=$uri", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
val options = TiffBitmapFactory.Options().apply {
|
||||||
inDirectoryNumber = page
|
inDirectoryNumber = page
|
||||||
inSampleSize = sampleSize
|
inSampleSize = sampleSize
|
||||||
inDecodeArea = DecodeArea(regionRect.left, regionRect.top, regionRect.width(), regionRect.height())
|
inDecodeArea = DecodeArea(regionRect.left, regionRect.top, regionRect.width(), regionRect.height())
|
||||||
}
|
}
|
||||||
val bitmap = TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
val bitmap = TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
result.success(bitmap.getBytes(canHaveAlpha = true, recycle = true))
|
result.success(bitmap.getBytes(canHaveAlpha = true, recycle = true))
|
||||||
} else {
|
} else {
|
||||||
result.error("getRegion-tiff-null", "failed to decode region for uri=$uri page=$page regionRect=$regionRect", null)
|
result.error("getRegion-tiff-null", "failed to decode region for uri=$uri page=$page regionRect=$regionRect", null)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
result.error("getRegion-tiff-read-exception", "failed to read from uri=$uri page=$page regionRect=$regionRect", e.message)
|
result.error("getRegion-tiff-read-exception", "failed to read from uri=$uri page=$page regionRect=$regionRect", e.message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,30 +139,35 @@ class ImageByteStreamHandler(private val activity: Activity, private val argumen
|
||||||
private fun streamTiffImage(uri: Uri, page: Int = 0) {
|
private fun streamTiffImage(uri: Uri, page: Int = 0) {
|
||||||
val resolver = activity.contentResolver
|
val resolver = activity.contentResolver
|
||||||
try {
|
try {
|
||||||
var dirCount = 0
|
var fd = resolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
resolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
if (fd == null) {
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
error("streamImage-tiff-fd", "failed to get file descriptor for uri=$uri", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var options = TiffBitmapFactory.Options().apply {
|
||||||
inJustDecodeBounds = true
|
inJustDecodeBounds = true
|
||||||
}
|
}
|
||||||
TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
dirCount = options.outDirectoryCount
|
val dirCount = options.outDirectoryCount
|
||||||
}
|
|
||||||
|
|
||||||
// TODO TLAD handle multipage TIFF
|
// TODO TLAD handle multipage TIFF
|
||||||
if (dirCount > page) {
|
if (dirCount > page) {
|
||||||
resolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
fd = resolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
if (fd == null) {
|
||||||
|
error("streamImage-tiff-fd", "failed to get file descriptor for uri=$uri", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
options = TiffBitmapFactory.Options().apply {
|
||||||
inJustDecodeBounds = false
|
inJustDecodeBounds = false
|
||||||
inDirectoryNumber = page
|
inDirectoryNumber = page
|
||||||
}
|
}
|
||||||
val bitmap = TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
val bitmap = TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
if (bitmap != null) {
|
if (bitmap != null) {
|
||||||
success(bitmap.getBytes(canHaveAlpha = true, recycle = true))
|
success(bitmap.getBytes(canHaveAlpha = true, recycle = true))
|
||||||
} else {
|
} else {
|
||||||
error("streamImage-tiff-null", "failed to get tiff image (dir=$page) from uri=$uri", null)
|
error("streamImage-tiff-null", "failed to get tiff image (dir=$page) from uri=$uri", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
error("streamImage-tiff-exception", "failed to get image from uri=$uri", toErrorDetails(e))
|
error("streamImage-tiff-exception", "failed to get image from uri=$uri", toErrorDetails(e))
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,12 +48,16 @@ internal class TiffThumbnailFetcher(val model: TiffThumbnail, val width: Int, va
|
||||||
val uri = model.uri
|
val uri = model.uri
|
||||||
|
|
||||||
// determine sample size
|
// determine sample size
|
||||||
|
var fd = context.contentResolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
|
if (fd == null) {
|
||||||
|
callback.onLoadFailed(Exception("null file descriptor"))
|
||||||
|
return
|
||||||
|
}
|
||||||
var sampleSize = 1
|
var sampleSize = 1
|
||||||
context.contentResolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
var options = TiffBitmapFactory.Options().apply {
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
|
||||||
inJustDecodeBounds = true
|
inJustDecodeBounds = true
|
||||||
}
|
}
|
||||||
TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
val imageWidth = options.outWidth
|
val imageWidth = options.outWidth
|
||||||
val imageHeight = options.outHeight
|
val imageHeight = options.outHeight
|
||||||
if (imageHeight > height || imageWidth > width) {
|
if (imageHeight > height || imageWidth > width) {
|
||||||
|
@ -61,17 +65,18 @@ internal class TiffThumbnailFetcher(val model: TiffThumbnail, val width: Int, va
|
||||||
sampleSize *= 2
|
sampleSize *= 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// decode
|
// decode
|
||||||
val bitmap = context.contentResolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
fd = context.contentResolver.openFileDescriptor(uri, "r")?.detachFd()
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
if (fd == null) {
|
||||||
|
callback.onLoadFailed(Exception("null file descriptor"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
options = TiffBitmapFactory.Options().apply {
|
||||||
inJustDecodeBounds = false
|
inJustDecodeBounds = false
|
||||||
inSampleSize = sampleSize
|
inSampleSize = sampleSize
|
||||||
}
|
}
|
||||||
TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
val bitmap = TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
}
|
|
||||||
|
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
callback.onLoadFailed(Exception("null bitmap"))
|
callback.onLoadFailed(Exception("null bitmap"))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -249,14 +249,13 @@ class SourceImageEntry {
|
||||||
|
|
||||||
private fun fillByTiffDecode(context: Context) {
|
private fun fillByTiffDecode(context: Context) {
|
||||||
try {
|
try {
|
||||||
context.contentResolver.openFileDescriptor(uri, "r")?.use { descriptor ->
|
val fd = context.contentResolver.openFileDescriptor(uri, "r")?.detachFd() ?: return
|
||||||
val options = TiffBitmapFactory.Options().apply {
|
val options = TiffBitmapFactory.Options().apply {
|
||||||
inJustDecodeBounds = true
|
inJustDecodeBounds = true
|
||||||
}
|
}
|
||||||
TiffBitmapFactory.decodeFileDescriptor(descriptor.fd, options)
|
TiffBitmapFactory.decodeFileDescriptor(fd, options)
|
||||||
width = options.outWidth
|
width = options.outWidth
|
||||||
height = options.outHeight
|
height = options.outHeight
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue