MPF: exclude thumbnails to detect multipage JPEG

This commit is contained in:
Thibault Deckers 2023-12-20 19:33:48 +01:00
parent e5b4f648a1
commit 8c5cfc4a87
5 changed files with 49 additions and 37 deletions

View file

@ -19,7 +19,6 @@ import deckers.thibault.aves.metadata.XMP.doesPropPathExist
import deckers.thibault.aves.metadata.XMP.getSafeStructField import deckers.thibault.aves.metadata.XMP.getSafeStructField
import deckers.thibault.aves.metadata.XMPPropName import deckers.thibault.aves.metadata.XMPPropName
import deckers.thibault.aves.metadata.metadataextractor.Helper 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.FieldMap
import deckers.thibault.aves.model.provider.ContentImageProvider import deckers.thibault.aves.model.provider.ContentImageProvider
import deckers.thibault.aves.model.provider.ImageProvider import deckers.thibault.aves.model.provider.ImageProvider
@ -165,7 +164,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
val mpEntries = MultiPage.getJpegMpfEntries(context, uri) val mpEntries = MultiPage.getJpegMpfEntries(context, uri)
if (mpEntries != null && pageIndex < mpEntries.size) { if (mpEntries != null && pageIndex < mpEntries.size) {
val mpEntry = mpEntries[pageIndex] val mpEntry = mpEntries[pageIndex]
MpEntry.getMimeType(mpEntry.format)?.let { embedMimeType -> mpEntry.mimeType?.let { embedMimeType ->
var dataOffset = mpEntry.dataOffset var dataOffset = mpEntry.dataOffset
if (dataOffset > 0) { if (dataOffset > 0) {
val baseOffset = MultiPage.getJpegMpfBaseOffset(context, uri) val baseOffset = MultiPage.getJpegMpfBaseOffset(context, uri)

View file

@ -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.Helper.isPngTextDir
import deckers.thibault.aves.metadata.metadataextractor.PngActlDirectory import deckers.thibault.aves.metadata.metadataextractor.PngActlDirectory
import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory 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.model.FieldMap
import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue
import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.LogUtils
@ -636,11 +635,8 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
} }
// JPEG Multi-Picture Format // JPEG Multi-Picture Format
for (dir in metadata.getDirectoriesOfType(MpfDirectory::class.java)) { if (metadata.getDirectoriesOfType(MpEntryDirectory::class.java).count { !it.entry.isThumbnail } > 1) {
val imageCount = dir.getNumberOfImages() flags = flags or MASK_IS_MULTIPAGE
if (imageCount > 1) {
flags = flags or MASK_IS_MULTIPAGE
}
} }
// XMP // XMP

View file

@ -137,7 +137,7 @@ object MultiPage {
val mpEntries = getJpegMpfEntries(context, uri) val mpEntries = getJpegMpfEntries(context, uri)
if (mpEntries != null && baseOffset != null) { if (mpEntries != null && baseOffset != null) {
for ((pageIndex, mpEntry) in mpEntries.withIndex()) { for ((pageIndex, mpEntry) in mpEntries.withIndex()) {
MpEntry.getMimeType(mpEntry.format)?.let { embedMimeType -> mpEntry.mimeType?.let { embedMimeType ->
val page = hashMapOf<String, Any?>( val page = hashMapOf<String, Any?>(
KEY_PAGE to pageIndex, KEY_PAGE to pageIndex,
KEY_MIME_TYPE to embedMimeType, KEY_MIME_TYPE to embedMimeType,

View file

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

View file

@ -2,7 +2,6 @@ package deckers.thibault.aves.metadata.metadataextractor.mpf
import com.drew.metadata.Directory import com.drew.metadata.Directory
import com.drew.metadata.TagDescriptor import com.drew.metadata.TagDescriptor
import deckers.thibault.aves.utils.MimeTypes
class MpEntryDirectory(val id: Int, val entry: MpEntry) : Directory() { class MpEntryDirectory(val id: Int, val entry: MpEntry) : Directory() {
private val descriptor = MpEntryDescriptor(this) private val descriptor = MpEntryDescriptor(this)
@ -39,9 +38,9 @@ class MpEntryDirectory(val id: Int, val entry: MpEntry) : Directory() {
class MpEntryDescriptor(directory: MpEntryDirectory?) : TagDescriptor<MpEntryDirectory>(directory) { class MpEntryDescriptor(directory: MpEntryDirectory?) : TagDescriptor<MpEntryDirectory>(directory) {
fun getFlagsDescription(flags: Int): String { fun getFlagsDescription(flags: Int): String {
val flagStrings = ArrayList<String>().apply { val flagStrings = ArrayList<String>().apply {
if (flags and FLAG_REPRESENTATIVE != 0) add("representative image") if (flags and MpEntry.FLAG_REPRESENTATIVE != 0) add("representative image")
if (flags and FLAG_DEPENDENT_CHILD != 0) add("dependent child image") if (flags and MpEntry.FLAG_DEPENDENT_CHILD != 0) add("dependent child image")
if (flags and FLAG_DEPENDENT_PARENT != 0) add("dependent parent image") if (flags and MpEntry.FLAG_DEPENDENT_PARENT != 0) add("dependent parent image")
} }
return if (flagStrings.isEmpty()) "none" else flagStrings.joinToString(", ") return if (flagStrings.isEmpty()) "none" else flagStrings.joinToString(", ")
} }
@ -52,31 +51,14 @@ class MpEntryDescriptor(directory: MpEntryDirectory?) : TagDescriptor<MpEntryDir
fun getTypeDescription(type: Int): String { fun getTypeDescription(type: Int): String {
return when (type) { return when (type) {
0x030000 -> "Baseline MP Primary Image" MpEntry.TYPE_PRIMARY -> "Baseline MP Primary Image"
0x010001 -> "Large Thumbnail (VGA equivalent)" MpEntry.TYPE_THUMBNAIL_VGA -> "Large Thumbnail (VGA equivalent)"
0x010002 -> "Large Thumbnail (full HD equivalent)" MpEntry.TYPE_THUMBNAIL_FULL_HD -> "Large Thumbnail (full HD equivalent)"
0x020001 -> "Multi-frame Panorama" MpEntry.TYPE_PANORAMA -> "Multi-frame Panorama"
0x020002 -> "Multi-frame Disparity" MpEntry.TYPE_DISPARITY -> "Multi-frame Disparity"
0x020003 -> "Multi-angle" MpEntry.TYPE_MULTI_ANGLE -> "Multi-angle"
0x000000 -> "Undefined" MpEntry.TYPE_UNDEFINED -> "Undefined"
else -> "Unknown ($type)" 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
}
}
}
} }