From 8c5cfc4a875980e7f96e1a72223bbcedbea1f22e Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Wed, 20 Dec 2023 19:33:48 +0100 Subject: [PATCH] MPF: exclude thumbnails to detect multipage JPEG --- .../aves/channel/calls/EmbeddedDataHandler.kt | 3 +- .../channel/calls/MetadataFetchHandler.kt | 8 +--- .../thibault/aves/metadata/MultiPage.kt | 2 +- .../metadata/metadataextractor/mpf/MpEntry.kt | 35 +++++++++++++++++ .../metadataextractor/mpf/MpEntryDirectory.kt | 38 +++++-------------- 5 files changed, 49 insertions(+), 37 deletions(-) create mode 100644 android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt index 1515fea65..9b47d0512 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt @@ -19,7 +19,6 @@ import deckers.thibault.aves.metadata.XMP.doesPropPathExist import deckers.thibault.aves.metadata.XMP.getSafeStructField import deckers.thibault.aves.metadata.XMPPropName import deckers.thibault.aves.metadata.metadataextractor.Helper -import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntry import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.model.provider.ContentImageProvider import deckers.thibault.aves.model.provider.ImageProvider @@ -165,7 +164,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { val mpEntries = MultiPage.getJpegMpfEntries(context, uri) if (mpEntries != null && pageIndex < mpEntries.size) { val mpEntry = mpEntries[pageIndex] - MpEntry.getMimeType(mpEntry.format)?.let { embedMimeType -> + mpEntry.mimeType?.let { embedMimeType -> var dataOffset = mpEntry.dataOffset if (dataOffset > 0) { val baseOffset = MultiPage.getJpegMpfBaseOffset(context, uri) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt index 49c2fdb8f..b86b2d636 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt @@ -78,7 +78,6 @@ import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeString import deckers.thibault.aves.metadata.metadataextractor.Helper.isPngTextDir import deckers.thibault.aves.metadata.metadataextractor.PngActlDirectory import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory -import deckers.thibault.aves.metadata.metadataextractor.mpf.MpfDirectory import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue import deckers.thibault.aves.utils.LogUtils @@ -636,11 +635,8 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { } // JPEG Multi-Picture Format - for (dir in metadata.getDirectoriesOfType(MpfDirectory::class.java)) { - val imageCount = dir.getNumberOfImages() - if (imageCount > 1) { - flags = flags or MASK_IS_MULTIPAGE - } + if (metadata.getDirectoriesOfType(MpEntryDirectory::class.java).count { !it.entry.isThumbnail } > 1) { + flags = flags or MASK_IS_MULTIPAGE } // XMP diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt index f6aa79c6d..eab4b5954 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt @@ -137,7 +137,7 @@ object MultiPage { val mpEntries = getJpegMpfEntries(context, uri) if (mpEntries != null && baseOffset != null) { for ((pageIndex, mpEntry) in mpEntries.withIndex()) { - MpEntry.getMimeType(mpEntry.format)?.let { embedMimeType -> + mpEntry.mimeType?.let { embedMimeType -> val page = hashMapOf( KEY_PAGE to pageIndex, KEY_MIME_TYPE to embedMimeType, diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt new file mode 100644 index 000000000..3e81171f3 --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt @@ -0,0 +1,35 @@ +package deckers.thibault.aves.metadata.metadataextractor.mpf + +import deckers.thibault.aves.utils.MimeTypes + +class MpEntry(val flags: Int, val format: Int, val type: Int, val size: Long, val dataOffset: Long, val dep1: Short, val dep2: Short) { + val mimeType: String? + get() = getMimeType(format) + + val isThumbnail: Boolean + get() = when (type) { + TYPE_THUMBNAIL_VGA, TYPE_THUMBNAIL_FULL_HD -> true + else -> false + } + + companion object { + const val FLAG_REPRESENTATIVE = 1 shl 2 + const val FLAG_DEPENDENT_CHILD = 1 shl 3 + const val FLAG_DEPENDENT_PARENT = 1 shl 4 + + const val TYPE_PRIMARY = 0x030000 + const val TYPE_THUMBNAIL_VGA = 0x010001 + const val TYPE_THUMBNAIL_FULL_HD = 0x010002 + const val TYPE_PANORAMA = 0x020001 + const val TYPE_DISPARITY = 0x020002 + const val TYPE_MULTI_ANGLE = 0x020003 + const val TYPE_UNDEFINED = 0x000000 + + fun getMimeType(format: Int): String? { + return when (format) { + 0 -> MimeTypes.JPEG + else -> null + } + } + } +} diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt index b1f217a10..7dba5520f 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt @@ -2,7 +2,6 @@ package deckers.thibault.aves.metadata.metadataextractor.mpf import com.drew.metadata.Directory import com.drew.metadata.TagDescriptor -import deckers.thibault.aves.utils.MimeTypes class MpEntryDirectory(val id: Int, val entry: MpEntry) : Directory() { private val descriptor = MpEntryDescriptor(this) @@ -39,9 +38,9 @@ class MpEntryDirectory(val id: Int, val entry: MpEntry) : Directory() { class MpEntryDescriptor(directory: MpEntryDirectory?) : TagDescriptor(directory) { fun getFlagsDescription(flags: Int): String { val flagStrings = ArrayList().apply { - if (flags and FLAG_REPRESENTATIVE != 0) add("representative image") - if (flags and FLAG_DEPENDENT_CHILD != 0) add("dependent child image") - if (flags and FLAG_DEPENDENT_PARENT != 0) add("dependent parent image") + if (flags and MpEntry.FLAG_REPRESENTATIVE != 0) add("representative image") + if (flags and MpEntry.FLAG_DEPENDENT_CHILD != 0) add("dependent child image") + if (flags and MpEntry.FLAG_DEPENDENT_PARENT != 0) add("dependent parent image") } return if (flagStrings.isEmpty()) "none" else flagStrings.joinToString(", ") } @@ -52,31 +51,14 @@ class MpEntryDescriptor(directory: MpEntryDirectory?) : TagDescriptor "Baseline MP Primary Image" - 0x010001 -> "Large Thumbnail (VGA equivalent)" - 0x010002 -> "Large Thumbnail (full HD equivalent)" - 0x020001 -> "Multi-frame Panorama" - 0x020002 -> "Multi-frame Disparity" - 0x020003 -> "Multi-angle" - 0x000000 -> "Undefined" + MpEntry.TYPE_PRIMARY -> "Baseline MP Primary Image" + MpEntry.TYPE_THUMBNAIL_VGA -> "Large Thumbnail (VGA equivalent)" + MpEntry.TYPE_THUMBNAIL_FULL_HD -> "Large Thumbnail (full HD equivalent)" + MpEntry.TYPE_PANORAMA -> "Multi-frame Panorama" + MpEntry.TYPE_DISPARITY -> "Multi-frame Disparity" + MpEntry.TYPE_MULTI_ANGLE -> "Multi-angle" + MpEntry.TYPE_UNDEFINED -> "Undefined" else -> "Unknown ($type)" } } - - companion object { - private const val FLAG_REPRESENTATIVE = 1 shl 2 - private const val FLAG_DEPENDENT_CHILD = 1 shl 3 - private const val FLAG_DEPENDENT_PARENT = 1 shl 4 - } -} - -class MpEntry(val flags: Int, val format: Int, val type: Int, val size: Long, val dataOffset: Long, val dep1: Short, val dep2: Short) { - companion object { - fun getMimeType(format: Int): String? { - return when (format) { - 0 -> MimeTypes.JPEG - else -> null - } - } - } }