#1203 keep full file to fetch metadata from large PNG

This commit is contained in:
Thibault Deckers 2024-10-07 17:09:12 +02:00
parent 8f431a5426
commit 0f5d0a42a3
2 changed files with 36 additions and 19 deletions

View file

@ -2,8 +2,9 @@ package deckers.thibault.aves.metadata
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface import android.util.Log
import deckers.thibault.aves.utils.FileUtils.transferFrom import deckers.thibault.aves.utils.FileUtils.transferFrom
import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes
import deckers.thibault.aves.utils.StorageUtils import deckers.thibault.aves.utils.StorageUtils
import java.io.File import java.io.File
@ -14,8 +15,11 @@ import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.TimeZone import java.util.TimeZone
import java.util.regex.Pattern import java.util.regex.Pattern
import androidx.exifinterface.media.ExifInterfaceFork as ExifInterface
object Metadata { object Metadata {
private val LOG_TAG = LogUtils.createTag<Metadata>()
const val IPTC_MARKER_BYTE: Byte = 0x1c const val IPTC_MARKER_BYTE: Byte = 0x1c
// Pattern to extract latitude & longitude from a video location tag (cf ISO 6709) // Pattern to extract latitude & longitude from a video location tag (cf ISO 6709)
@ -135,29 +139,42 @@ object Metadata {
private fun getSafeUri(context: Context, uri: Uri, mimeType: String, sizeBytes: Long?): Uri { private fun getSafeUri(context: Context, uri: Uri, mimeType: String, sizeBytes: Long?): Uri {
// formats known to yield OOM for large files // formats known to yield OOM for large files
return if ((MimeTypes.isImage(mimeType) || mimeType == MimeTypes.MP4)) { return when (mimeType) {
if (isDangerouslyLarge(sizeBytes)) { // formats known to yield OOM for large files
// make a preview from the beginning of the file, MimeTypes.DNG,
// hoping the metadata is accessible in the copied chunk MimeTypes.DNG_ADOBE,
var previewFile = previewFiles[uri] MimeTypes.HEIC,
if (previewFile == null) { MimeTypes.HEIF,
previewFile = createPreviewFile(context, uri) MimeTypes.MP4,
previewFiles[uri] = previewFile MimeTypes.PSD_VND,
MimeTypes.PSD_X,
MimeTypes.TIFF ->
if (isDangerouslyLarge(sizeBytes)) {
Log.d(LOG_TAG, "Dangerously large file with uri=$uri, mimeType=$mimeType, size=$sizeBytes")
// make a preview from the beginning of the file,
// hoping the metadata is accessible in the copied chunk
var previewFile = previewFiles[uri]
if (previewFile == null) {
previewFile = createPreviewFile(context, uri)
previewFiles[uri] = previewFile
}
Uri.fromFile(previewFile)
} else {
// small enough to be safe as it is
uri
} }
Uri.fromFile(previewFile)
} else { else ->
// small enough to be safe as it is // *probably* safe
uri uri
}
} else {
// *probably* safe
uri
} }
} }
fun createPreviewFile(context: Context, uri: Uri): File { fun createPreviewFile(context: Context, uri: Uri): File {
val size = PREVIEW_SIZE
Log.d(LOG_TAG, "create preview of size=$size for uri=$uri")
return StorageUtils.createTempFile(context).apply { return StorageUtils.createTempFile(context).apply {
transferFrom(StorageUtils.openInputStream(context, uri), PREVIEW_SIZE) transferFrom(StorageUtils.openInputStream(context, uri), size)
} }
} }

View file

@ -17,8 +17,8 @@ object MimeTypes {
private const val ICO = "image/x-icon" private const val ICO = "image/x-icon"
const val JPEG = "image/jpeg" const val JPEG = "image/jpeg"
const val PNG = "image/png" const val PNG = "image/png"
private const val PSD_VND = "image/vnd.adobe.photoshop" const val PSD_VND = "image/vnd.adobe.photoshop"
private const val PSD_X = "image/x-photoshop" const val PSD_X = "image/x-photoshop"
const val TIFF = "image/tiff" const val TIFF = "image/tiff"
private const val WBMP = "image/vnd.wap.wbmp" private const val WBMP = "image/vnd.wap.wbmp"
const val WEBP = "image/webp" const val WEBP = "image/webp"