#976 identify Apple variant of HDR images
This commit is contained in:
parent
e9d2e3c42e
commit
ce27d47342
3 changed files with 38 additions and 0 deletions
|
@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## <a id="unreleased"></a>[Unreleased]
|
## <a id="unreleased"></a>[Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Cataloguing: identify Apple variant of HDR images
|
||||||
|
|
||||||
## <a id="v1.10.9"></a>[v1.10.9] - 2024-04-14
|
## <a id="v1.10.9"></a>[v1.10.9] - 2024-04-14
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.drew.metadata.exif.ExifDirectoryBase
|
||||||
import com.drew.metadata.exif.ExifIFD0Directory
|
import com.drew.metadata.exif.ExifIFD0Directory
|
||||||
import com.drew.metadata.exif.ExifSubIFDDirectory
|
import com.drew.metadata.exif.ExifSubIFDDirectory
|
||||||
import com.drew.metadata.exif.GpsDirectory
|
import com.drew.metadata.exif.GpsDirectory
|
||||||
|
import com.drew.metadata.exif.makernotes.AppleMakernoteDirectory
|
||||||
import com.drew.metadata.file.FileTypeDirectory
|
import com.drew.metadata.file.FileTypeDirectory
|
||||||
import com.drew.metadata.gif.GifAnimationDirectory
|
import com.drew.metadata.gif.GifAnimationDirectory
|
||||||
import com.drew.metadata.iptc.IptcDirectory
|
import com.drew.metadata.iptc.IptcDirectory
|
||||||
|
@ -69,6 +70,7 @@ import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeRational
|
||||||
import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeString
|
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.MpEntry
|
||||||
import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory
|
import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory
|
||||||
import deckers.thibault.aves.metadata.xmp.GoogleXMP
|
import deckers.thibault.aves.metadata.xmp.GoogleXMP
|
||||||
import deckers.thibault.aves.metadata.xmp.XMP
|
import deckers.thibault.aves.metadata.xmp.XMP
|
||||||
|
@ -639,6 +641,10 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
||||||
// JPEG Multi-Picture Format
|
// JPEG Multi-Picture Format
|
||||||
if (metadata.getDirectoriesOfType(MpEntryDirectory::class.java).count { !it.entry.isThumbnail } > 1) {
|
if (metadata.getDirectoriesOfType(MpEntryDirectory::class.java).count { !it.entry.isThumbnail } > 1) {
|
||||||
flags = flags or MASK_IS_MULTIPAGE
|
flags = flags or MASK_IS_MULTIPAGE
|
||||||
|
|
||||||
|
if (hasAppleHdrGainMap(uri, sizeBytes, metadata)) {
|
||||||
|
flags = flags or MASK_IS_HDR
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XMP
|
// XMP
|
||||||
|
@ -765,6 +771,29 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
||||||
metadataMap[KEY_FLAGS] = flags
|
metadataMap[KEY_FLAGS] = flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hasAppleHdrGainMap(uri: Uri, sizeBytes: Long?, primaryMetadata: com.drew.metadata.Metadata): Boolean {
|
||||||
|
if (!primaryMetadata.containsDirectoryOfType(AppleMakernoteDirectory::class.java)) return false
|
||||||
|
|
||||||
|
val mpEntries = MultiPage.getJpegMpfEntries(context, uri, sizeBytes) ?: return false
|
||||||
|
mpEntries.filter { it.type == MpEntry.TYPE_UNDEFINED }.forEach { mpEntry ->
|
||||||
|
var dataOffset = mpEntry.dataOffset
|
||||||
|
if (dataOffset > 0) {
|
||||||
|
val baseOffset = MultiPage.getJpegMpfBaseOffset(context, uri, sizeBytes)
|
||||||
|
if (baseOffset != null) {
|
||||||
|
dataOffset += baseOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StorageUtils.openInputStream(context, uri)?.let { input ->
|
||||||
|
input.skip(dataOffset)
|
||||||
|
val pageMetadata = Helper.safeRead(input)
|
||||||
|
if (pageMetadata.getDirectoriesOfType(XmpDirectory::class.java).any { it.xmpMeta.hasHdrGainMap() }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private fun getMultimediaCatalogMetadataByMediaMetadataRetriever(
|
private fun getMultimediaCatalogMetadataByMediaMetadataRetriever(
|
||||||
mimeType: String,
|
mimeType: String,
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
|
|
|
@ -40,6 +40,7 @@ object XMP {
|
||||||
private const val XMP_NS_URI = "http://ns.adobe.com/xap/1.0/"
|
private const val XMP_NS_URI = "http://ns.adobe.com/xap/1.0/"
|
||||||
|
|
||||||
// other namespaces
|
// other namespaces
|
||||||
|
private const val APPLE_HDRGM_NS_URI = "http://ns.apple.com/HDRGainMap/1.0/"
|
||||||
private const val HDRGM_NS_URI = "http://ns.adobe.com/hdr-gain-map/1.0/"
|
private const val HDRGM_NS_URI = "http://ns.adobe.com/hdr-gain-map/1.0/"
|
||||||
private const val PMTM_NS_URI = "http://www.hdrsoft.com/photomatix_settings01"
|
private const val PMTM_NS_URI = "http://www.hdrsoft.com/photomatix_settings01"
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ object XMP {
|
||||||
// HDR gain map
|
// HDR gain map
|
||||||
|
|
||||||
private val HDRGM_VERSION_PROP_NAME = XMPPropName(HDRGM_NS_URI, "Version")
|
private val HDRGM_VERSION_PROP_NAME = XMPPropName(HDRGM_NS_URI, "Version")
|
||||||
|
private val APPLE_HDRGM_VERSION_PROP_NAME = XMPPropName(APPLE_HDRGM_NS_URI, "HDRGainMapVersion")
|
||||||
|
|
||||||
// panorama
|
// panorama
|
||||||
|
|
||||||
|
@ -137,6 +139,9 @@ object XMP {
|
||||||
// `Ultra HDR`
|
// `Ultra HDR`
|
||||||
if (GoogleXMP.isUltraHdPhoto(this)) return true
|
if (GoogleXMP.isUltraHdPhoto(this)) return true
|
||||||
|
|
||||||
|
// Apple HDR gain map
|
||||||
|
if (doesPropExist(APPLE_HDRGM_VERSION_PROP_NAME)) return true
|
||||||
|
|
||||||
return false
|
return false
|
||||||
} catch (e: XMPException) {
|
} catch (e: XMPException) {
|
||||||
if (e.errorCode != XMPError.BADSCHEMA) {
|
if (e.errorCode != XMPError.BADSCHEMA) {
|
||||||
|
|
Loading…
Reference in a new issue