#443 Info: improved NS prefix handling
This commit is contained in:
parent
a6b5398962
commit
86c6e7ce93
14 changed files with 132 additions and 98 deletions
|
@ -12,7 +12,7 @@ import com.drew.metadata.xmp.XmpDirectory
|
|||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
||||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
|
||||
import deckers.thibault.aves.metadata.*
|
||||
import deckers.thibault.aves.metadata.XMP.doesPropExist
|
||||
import deckers.thibault.aves.metadata.XMP.doesPropPathExist
|
||||
import deckers.thibault.aves.metadata.XMP.getSafeStructField
|
||||
import deckers.thibault.aves.metadata.metadataextractor.Helper
|
||||
import deckers.thibault.aves.model.FieldMap
|
||||
|
@ -104,7 +104,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
|
|||
try {
|
||||
container = xmpDirs.firstNotNullOfOrNull {
|
||||
val xmpMeta = it.xmpMeta
|
||||
if (xmpMeta.doesPropExist(XMP.GDEVICE_DIRECTORY_PROP_NAME)) {
|
||||
if (xmpMeta.doesPropPathExist(listOf(XMP.GDEVICE_CONTAINER_PROP_NAME, XMP.GDEVICE_CONTAINER_DIRECTORY_PROP_NAME))) {
|
||||
GoogleDeviceContainer().apply { findItems(xmpMeta) }
|
||||
} else {
|
||||
null
|
||||
|
|
|
@ -3,7 +3,7 @@ package deckers.thibault.aves.metadata
|
|||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import com.adobe.internal.xmp.XMPMeta
|
||||
import deckers.thibault.aves.metadata.XMP.countPropArrayItems
|
||||
import deckers.thibault.aves.metadata.XMP.countPropPathArrayItems
|
||||
import deckers.thibault.aves.metadata.XMP.getSafeStructField
|
||||
import deckers.thibault.aves.utils.indexOfBytes
|
||||
import java.io.DataInputStream
|
||||
|
@ -15,11 +15,12 @@ class GoogleDeviceContainer {
|
|||
private val offsets: MutableList<Int> = ArrayList()
|
||||
|
||||
fun findItems(xmpMeta: XMPMeta) {
|
||||
val count = xmpMeta.countPropArrayItems(XMP.GDEVICE_DIRECTORY_PROP_NAME)
|
||||
val containerDirectoryPath = listOf(XMP.GDEVICE_CONTAINER_PROP_NAME, XMP.GDEVICE_CONTAINER_DIRECTORY_PROP_NAME)
|
||||
val count = xmpMeta.countPropPathArrayItems(containerDirectoryPath)
|
||||
for (i in 1 until count + 1) {
|
||||
val mimeType = xmpMeta.getSafeStructField(listOf(XMP.GDEVICE_DIRECTORY_PROP_NAME, i, XMP.GDEVICE_CONTAINER_ITEM_MIME_PROP_NAME))?.value
|
||||
val length = xmpMeta.getSafeStructField(listOf(XMP.GDEVICE_DIRECTORY_PROP_NAME, i, XMP.GDEVICE_CONTAINER_ITEM_LENGTH_PROP_NAME))?.value?.toLongOrNull()
|
||||
val dataUri = xmpMeta.getSafeStructField(listOf(XMP.GDEVICE_DIRECTORY_PROP_NAME, i, XMP.GDEVICE_CONTAINER_ITEM_DATA_URI_PROP_NAME))?.value
|
||||
val mimeType = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, XMP.GDEVICE_CONTAINER_ITEM_MIME_PROP_NAME))?.value
|
||||
val length = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, XMP.GDEVICE_CONTAINER_ITEM_LENGTH_PROP_NAME))?.value?.toLongOrNull()
|
||||
val dataUri = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, XMP.GDEVICE_CONTAINER_ITEM_DATA_URI_PROP_NAME))?.value
|
||||
if (mimeType != null && length != null && dataUri != null) {
|
||||
items.add(
|
||||
GoogleDeviceContainerItem(
|
||||
|
|
|
@ -49,6 +49,7 @@ object XMP {
|
|||
private const val GCONTAINER_ITEM_NS_URI = "http://ns.google.com/photos/1.0/container/item/"
|
||||
private const val GDEPTH_NS_URI = "http://ns.google.com/photos/1.0/depthmap/"
|
||||
private const val GDEVICE_NS_URI = "http://ns.google.com/photos/dd/1.0/device/"
|
||||
private const val GDEVICE_CONTAINER_NS_URI = "http://ns.google.com/photos/dd/1.0/container/"
|
||||
private const val GDEVICE_ITEM_NS_URI = "http://ns.google.com/photos/dd/1.0/item/"
|
||||
private const val GIMAGE_NS_URI = "http://ns.google.com/photos/1.0/image/"
|
||||
private const val GPANO_NS_URI = "http://ns.google.com/photos/1.0/panorama/"
|
||||
|
@ -79,7 +80,8 @@ object XMP {
|
|||
|
||||
// google portrait
|
||||
|
||||
val GDEVICE_DIRECTORY_PROP_NAME = XMPPropName(GDEVICE_NS_URI, "Container/Container:Directory")
|
||||
val GDEVICE_CONTAINER_PROP_NAME = XMPPropName(GDEVICE_NS_URI, "Container")
|
||||
val GDEVICE_CONTAINER_DIRECTORY_PROP_NAME = XMPPropName(GDEVICE_CONTAINER_NS_URI, "Directory")
|
||||
val GDEVICE_CONTAINER_ITEM_DATA_URI_PROP_NAME = XMPPropName(GDEVICE_ITEM_NS_URI, "DataURI")
|
||||
val GDEVICE_CONTAINER_ITEM_LENGTH_PROP_NAME = XMPPropName(GDEVICE_ITEM_NS_URI, "Length")
|
||||
val GDEVICE_CONTAINER_ITEM_MIME_PROP_NAME = XMPPropName(GDEVICE_ITEM_NS_URI, "Mime")
|
||||
|
@ -254,10 +256,18 @@ object XMP {
|
|||
return doesPropertyExist(prop.nsUri, prop.toString())
|
||||
}
|
||||
|
||||
fun XMPMeta.doesPropPathExist(props: List<XMPPropName>): Boolean {
|
||||
return doesPropertyExist(props.first().nsUri, props.joinToString("/"))
|
||||
}
|
||||
|
||||
fun XMPMeta.countPropArrayItems(prop: XMPPropName): Int {
|
||||
return countArrayItems(prop.nsUri, prop.toString())
|
||||
}
|
||||
|
||||
fun XMPMeta.countPropPathArrayItems(props: List<XMPPropName>): Int {
|
||||
return countArrayItems(props.first().nsUri, props.joinToString("/"))
|
||||
}
|
||||
|
||||
fun XMPMeta.getPropArrayItemValues(prop: XMPPropName): List<String> {
|
||||
val schema = prop.nsUri
|
||||
val propName = prop.toString()
|
||||
|
|
|
@ -463,7 +463,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
|
|||
modified |= XMP.removeElements(
|
||||
descriptions,
|
||||
XMP.containerDirectory,
|
||||
Namespaces.container,
|
||||
Namespaces.gContainer,
|
||||
);
|
||||
|
||||
modified |= [
|
||||
|
|
|
@ -7,7 +7,6 @@ class Namespaces {
|
|||
static const avm = 'http://www.communicatingastronomy.org/avm/1.0/';
|
||||
static const camera = 'http://pix4d.com/camera/1.0/';
|
||||
static const cc = 'http://creativecommons.org/ns#';
|
||||
static const container = 'http://ns.google.com/photos/1.0/container/';
|
||||
static const creatorAtom = 'http://ns.adobe.com/creatorAtom/1.0/';
|
||||
static const crd = 'http://ns.adobe.com/camera-raw-defaults/1.0/';
|
||||
static const crlcp = 'http://ns.adobe.com/camera-raw-embedded-lens-profile/1.0/';
|
||||
|
@ -26,9 +25,13 @@ class Namespaces {
|
|||
static const exifEx = 'http://cipa.jp/exif/1.0/';
|
||||
static const gAudio = 'http://ns.google.com/photos/1.0/audio/';
|
||||
static const gCamera = 'http://ns.google.com/photos/1.0/camera/';
|
||||
static const gContainer = 'http://ns.google.com/photos/1.0/container/';
|
||||
static const gCreations = 'http://ns.google.com/photos/1.0/creations/';
|
||||
static const gDepth = 'http://ns.google.com/photos/1.0/depthmap/';
|
||||
static const gDevice = 'http://ns.google.com/photos/dd/1.0/device/';
|
||||
static const gDeviceCamera = 'http://ns.google.com/photos/dd/1.0/camera/';
|
||||
static const gDeviceContainer = 'http://ns.google.com/photos/dd/1.0/container/';
|
||||
static const gDeviceItem = 'http://ns.google.com/photos/dd/1.0/item/';
|
||||
static const gFocus = 'http://ns.google.com/photos/1.0/focus/';
|
||||
static const gImage = 'http://ns.google.com/photos/1.0/image/';
|
||||
static const gPano = 'http://ns.google.com/photos/1.0/panorama/';
|
||||
|
@ -83,7 +86,6 @@ class Namespaces {
|
|||
avm: 'Astronomy Visualization',
|
||||
camera: 'Pix4D Camera',
|
||||
cc: 'Creative Commons',
|
||||
container: 'Container',
|
||||
crd: 'Camera Raw Defaults',
|
||||
creatorAtom: 'After Effects',
|
||||
crs: 'Camera Raw Settings',
|
||||
|
@ -97,6 +99,7 @@ class Namespaces {
|
|||
exifEx: 'Exif Ex',
|
||||
gAudio: 'Google Audio',
|
||||
gCamera: 'Google Camera',
|
||||
gContainer: 'Google Container',
|
||||
gCreations: 'Google Creations',
|
||||
gDepth: 'Google Depth',
|
||||
gDevice: 'Google Device',
|
||||
|
@ -138,7 +141,7 @@ class Namespaces {
|
|||
};
|
||||
|
||||
static final defaultPrefixes = {
|
||||
container: 'Container',
|
||||
gContainer: 'Container',
|
||||
dc: 'dc',
|
||||
gCamera: 'GCamera',
|
||||
microsoftPhoto: 'MicrosoftPhoto',
|
||||
|
|
|
@ -22,56 +22,62 @@ import 'package:tuple/tuple.dart';
|
|||
|
||||
@immutable
|
||||
class XmpNamespace extends Equatable {
|
||||
final Map<String, String> schemaRegistryPrefixes;
|
||||
final String nsUri, nsPrefix;
|
||||
final Map<String, String> rawProps;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nsUri, nsPrefix];
|
||||
|
||||
const XmpNamespace(this.nsUri, this.nsPrefix, this.rawProps);
|
||||
XmpNamespace({
|
||||
required this.nsUri,
|
||||
required this.schemaRegistryPrefixes,
|
||||
required this.rawProps,
|
||||
}) : nsPrefix = prefixForUri(schemaRegistryPrefixes, nsUri);
|
||||
|
||||
factory XmpNamespace.create(String nsUri, String nsPrefix, Map<String, String> rawProps) {
|
||||
factory XmpNamespace.create(Map<String, String> schemaRegistryPrefixes, String nsPrefix, Map<String, String> rawProps) {
|
||||
final nsUri = schemaRegistryPrefixes[nsPrefix] ?? '';
|
||||
switch (nsUri) {
|
||||
case Namespaces.container:
|
||||
return XmpContainer(nsPrefix, rawProps);
|
||||
case Namespaces.creatorAtom:
|
||||
return XmpCreatorAtom(nsPrefix, rawProps);
|
||||
return XmpCreatorAtom(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.crs:
|
||||
return XmpCrsNamespace(nsPrefix, rawProps);
|
||||
return XmpCrsNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.darktable:
|
||||
return XmpDarktableNamespace(nsPrefix, rawProps);
|
||||
return XmpDarktableNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.dwc:
|
||||
return XmpDwcNamespace(nsPrefix, rawProps);
|
||||
return XmpDwcNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.exif:
|
||||
return XmpExifNamespace(nsPrefix, rawProps);
|
||||
return XmpExifNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.gAudio:
|
||||
return XmpGAudioNamespace(nsPrefix, rawProps);
|
||||
return XmpGAudioNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.gContainer:
|
||||
return XmpGContainer(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.gDepth:
|
||||
return XmpGDepthNamespace(nsPrefix, rawProps);
|
||||
return XmpGDepthNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.gDevice:
|
||||
return XmpGDeviceNamespace(nsPrefix, rawProps);
|
||||
return XmpGDeviceNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.gImage:
|
||||
return XmpGImageNamespace(nsPrefix, rawProps);
|
||||
return XmpGImageNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.iptc4xmpCore:
|
||||
return XmpIptcCoreNamespace(nsPrefix, rawProps);
|
||||
return XmpIptcCoreNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.iptc4xmpExt:
|
||||
return XmpIptc4xmpExtNamespace(nsPrefix, rawProps);
|
||||
return XmpIptc4xmpExtNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.mwgrs:
|
||||
return XmpMgwRegionsNamespace(nsPrefix, rawProps);
|
||||
return XmpMgwRegionsNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.mp:
|
||||
return XmpMPNamespace(nsPrefix, rawProps);
|
||||
return XmpMPNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.photoshop:
|
||||
return XmpPhotoshopNamespace(nsPrefix, rawProps);
|
||||
return XmpPhotoshopNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.plus:
|
||||
return XmpPlusNamespace(nsPrefix, rawProps);
|
||||
return XmpPlusNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.tiff:
|
||||
return XmpTiffNamespace(nsPrefix, rawProps);
|
||||
return XmpTiffNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.xmp:
|
||||
return XmpBasicNamespace(nsPrefix, rawProps);
|
||||
return XmpBasicNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
case Namespaces.xmpMM:
|
||||
return XmpMMNamespace(nsPrefix, rawProps);
|
||||
return XmpMMNamespace(schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
default:
|
||||
return XmpNamespace(nsUri, nsPrefix, rawProps);
|
||||
return XmpNamespace(nsUri: nsUri, schemaRegistryPrefixes: schemaRegistryPrefixes, rawProps: rawProps);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +136,8 @@ class XmpNamespace extends Equatable {
|
|||
String formatValue(XmpProp prop) => prop.value;
|
||||
|
||||
Map<String, InfoValueSpanBuilder> linkifyValues(List<XmpProp> props) => {};
|
||||
|
||||
static String prefixForUri(Map<String, String> schemaRegistryPrefixes, String nsUri) => schemaRegistryPrefixes.entries.firstWhereOrNull((kv) => kv.value == nsUri)?.key ?? '';
|
||||
}
|
||||
|
||||
class XmpProp implements Comparable<XmpProp> {
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:aves/utils/xmp_utils.dart';
|
|||
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
|
||||
|
||||
class XmpCrsNamespace extends XmpNamespace {
|
||||
XmpCrsNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.crs, nsPrefix, rawProps);
|
||||
XmpCrsNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.crs);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
|
|
@ -4,68 +4,69 @@ import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
|
|||
|
||||
// cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/exif.md
|
||||
class XmpExifNamespace extends XmpNamespace {
|
||||
const XmpExifNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.exif, nsPrefix, rawProps);
|
||||
XmpExifNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.exif);
|
||||
|
||||
@override
|
||||
String formatValue(XmpProp prop) {
|
||||
final v = prop.value;
|
||||
switch (prop.path) {
|
||||
case 'exif:ColorSpace':
|
||||
final field = prop.path.replaceAll(nsPrefix, '');
|
||||
switch (field) {
|
||||
case 'ColorSpace':
|
||||
return Exif.getColorSpaceDescription(v);
|
||||
case 'exif:Contrast':
|
||||
case 'Contrast':
|
||||
return Exif.getContrastDescription(v);
|
||||
case 'exif:CustomRendered':
|
||||
case 'CustomRendered':
|
||||
return Exif.getCustomRenderedDescription(v);
|
||||
case 'exif:ExifVersion':
|
||||
case 'exif:FlashpixVersion':
|
||||
case 'ExifVersion':
|
||||
case 'FlashpixVersion':
|
||||
return Exif.getExifVersionDescription(v);
|
||||
case 'exif:ExposureMode':
|
||||
case 'ExposureMode':
|
||||
return Exif.getExposureModeDescription(v);
|
||||
case 'exif:ExposureProgram':
|
||||
case 'ExposureProgram':
|
||||
return Exif.getExposureProgramDescription(v);
|
||||
case 'exif:FileSource':
|
||||
case 'FileSource':
|
||||
return Exif.getFileSourceDescription(v);
|
||||
case 'exif:Flash/exif:Mode':
|
||||
case 'Flash/Mode':
|
||||
return Exif.getFlashModeDescription(v);
|
||||
case 'exif:Flash/exif:Return':
|
||||
case 'Flash/Return':
|
||||
return Exif.getFlashReturnDescription(v);
|
||||
case 'exif:FocalPlaneResolutionUnit':
|
||||
case 'FocalPlaneResolutionUnit':
|
||||
return Exif.getResolutionUnitDescription(v);
|
||||
case 'exif:GainControl':
|
||||
case 'GainControl':
|
||||
return Exif.getGainControlDescription(v);
|
||||
case 'exif:LightSource':
|
||||
case 'LightSource':
|
||||
return Exif.getLightSourceDescription(v);
|
||||
case 'exif:MeteringMode':
|
||||
case 'MeteringMode':
|
||||
return Exif.getMeteringModeDescription(v);
|
||||
case 'exif:Saturation':
|
||||
case 'Saturation':
|
||||
return Exif.getSaturationDescription(v);
|
||||
case 'exif:SceneCaptureType':
|
||||
case 'SceneCaptureType':
|
||||
return Exif.getSceneCaptureTypeDescription(v);
|
||||
case 'exif:SceneType':
|
||||
case 'SceneType':
|
||||
return Exif.getSceneTypeDescription(v);
|
||||
case 'exif:SensingMethod':
|
||||
case 'SensingMethod':
|
||||
return Exif.getSensingMethodDescription(v);
|
||||
case 'exif:Sharpness':
|
||||
case 'Sharpness':
|
||||
return Exif.getSharpnessDescription(v);
|
||||
case 'exif:SubjectDistanceRange':
|
||||
case 'SubjectDistanceRange':
|
||||
return Exif.getSubjectDistanceRangeDescription(v);
|
||||
case 'exif:WhiteBalance':
|
||||
case 'WhiteBalance':
|
||||
return Exif.getWhiteBalanceDescription(v);
|
||||
case 'exif:GPSAltitudeRef':
|
||||
case 'GPSAltitudeRef':
|
||||
return Exif.getGPSAltitudeRefDescription(v);
|
||||
case 'exif:GPSDestBearingRef':
|
||||
case 'exif:GPSImgDirectionRef':
|
||||
case 'exif:GPSTrackRef':
|
||||
case 'GPSDestBearingRef':
|
||||
case 'GPSImgDirectionRef':
|
||||
case 'GPSTrackRef':
|
||||
return Exif.getGPSDirectionRefDescription(v);
|
||||
case 'exif:GPSDestDistanceRef':
|
||||
case 'GPSDestDistanceRef':
|
||||
return Exif.getGPSDestDistanceRefDescription(v);
|
||||
case 'exif:GPSDifferential':
|
||||
case 'GPSDifferential':
|
||||
return Exif.getGPSDifferentialDescription(v);
|
||||
case 'exif:GPSMeasureMode':
|
||||
case 'GPSMeasureMode':
|
||||
return Exif.getGPSMeasureModeDescription(v);
|
||||
case 'exif:GPSSpeedRef':
|
||||
case 'GPSSpeedRef':
|
||||
return Exif.getGPSSpeedRefDescription(v);
|
||||
case 'exif:GPSStatus':
|
||||
case 'GPSStatus':
|
||||
return Exif.getGPSStatusDescription(v);
|
||||
default:
|
||||
return v;
|
||||
|
|
|
@ -7,7 +7,11 @@ import 'package:collection/collection.dart';
|
|||
import 'package:tuple/tuple.dart';
|
||||
|
||||
abstract class XmpGoogleNamespace extends XmpNamespace {
|
||||
const XmpGoogleNamespace(String nsUri, String nsPrefix, Map<String, String> rawProps) : super(nsUri, nsPrefix, rawProps);
|
||||
XmpGoogleNamespace({
|
||||
required super.nsUri,
|
||||
required super.schemaRegistryPrefixes,
|
||||
required super.rawProps,
|
||||
});
|
||||
|
||||
List<Tuple2<String, String>> get dataProps;
|
||||
|
||||
|
@ -53,14 +57,14 @@ abstract class XmpGoogleNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpGAudioNamespace extends XmpGoogleNamespace {
|
||||
const XmpGAudioNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.gAudio, nsPrefix, rawProps);
|
||||
XmpGAudioNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.gAudio);
|
||||
|
||||
@override
|
||||
List<Tuple2<String, String>> get dataProps => [Tuple2('${nsPrefix}Data', '${nsPrefix}Mime')];
|
||||
}
|
||||
|
||||
class XmpGDepthNamespace extends XmpGoogleNamespace {
|
||||
const XmpGDepthNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.gDepth, nsPrefix, rawProps);
|
||||
XmpGDepthNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.gDepth);
|
||||
|
||||
@override
|
||||
List<Tuple2<String, String>> get dataProps => [
|
||||
|
@ -70,8 +74,16 @@ class XmpGDepthNamespace extends XmpGoogleNamespace {
|
|||
}
|
||||
|
||||
class XmpGDeviceNamespace extends XmpNamespace {
|
||||
XmpGDeviceNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.gDevice, nsPrefix, rawProps) {
|
||||
final mimePattern = RegExp(nsPrefix + r'Container/Container:Directory\[(\d+)\]/Item:Mime');
|
||||
late final String _cameraNsPrefix;
|
||||
late final String _containerNsPrefix;
|
||||
late final String _itemNsPrefix;
|
||||
|
||||
XmpGDeviceNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.gDevice) {
|
||||
_cameraNsPrefix = XmpNamespace.prefixForUri(schemaRegistryPrefixes, Namespaces.gDeviceCamera);
|
||||
_containerNsPrefix = XmpNamespace.prefixForUri(schemaRegistryPrefixes, Namespaces.gDeviceContainer);
|
||||
_itemNsPrefix = XmpNamespace.prefixForUri(schemaRegistryPrefixes, Namespaces.gDeviceItem);
|
||||
|
||||
final mimePattern = RegExp(nsPrefix + r'Container/' + _containerNsPrefix + r'Directory\[(\d+)\]/' + _itemNsPrefix + r'Mime');
|
||||
final originalProps = rawProps.entries.toList();
|
||||
originalProps.forEach((kv) {
|
||||
final path = kv.key;
|
||||
|
@ -81,7 +93,7 @@ class XmpGDeviceNamespace extends XmpNamespace {
|
|||
if (indexString != null) {
|
||||
final index = int.tryParse(indexString);
|
||||
if (index != null) {
|
||||
final dataPath = '${nsPrefix}Container/Container:Directory[$index]/Item:Data';
|
||||
final dataPath = '${nsPrefix}Container/${_containerNsPrefix}Directory[$index]/${_itemNsPrefix}Data';
|
||||
rawProps[dataPath] = '[skipped]';
|
||||
}
|
||||
}
|
||||
|
@ -94,16 +106,16 @@ class XmpGDeviceNamespace extends XmpNamespace {
|
|||
XmpCardData(
|
||||
RegExp(nsPrefix + r'Cameras\[(\d+)\]/(.*)'),
|
||||
cards: [
|
||||
XmpCardData(RegExp(r'Camera:DepthMap/(.*)')),
|
||||
XmpCardData(RegExp(r'Camera:Image/(.*)')),
|
||||
XmpCardData(RegExp(r'Camera:ImagingModel/(.*)')),
|
||||
XmpCardData(RegExp(_cameraNsPrefix + r'DepthMap/(.*)')),
|
||||
XmpCardData(RegExp(_cameraNsPrefix + r'Image/(.*)')),
|
||||
XmpCardData(RegExp(_cameraNsPrefix + r'ImagingModel/(.*)')),
|
||||
],
|
||||
),
|
||||
XmpCardData(
|
||||
RegExp(nsPrefix + r'Container/Container:Directory\[(\d+)\]/(.*)'),
|
||||
RegExp(nsPrefix + r'Container/' + _containerNsPrefix + r'Directory\[(\d+)\]/(.*)'),
|
||||
spanBuilders: (index, struct) {
|
||||
if (struct.containsKey('Item:Data') && struct.containsKey('Item:DataURI')) {
|
||||
final dataUriProp = struct['Item:DataURI'];
|
||||
if (struct.containsKey('${_itemNsPrefix}Data') && struct.containsKey('${_itemNsPrefix}DataURI')) {
|
||||
final dataUriProp = struct['${_itemNsPrefix}DataURI'];
|
||||
if (dataUriProp != null) {
|
||||
return {
|
||||
'Data': InfoRowGroup.linkSpanBuilder(
|
||||
|
@ -121,17 +133,17 @@ class XmpGDeviceNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpGImageNamespace extends XmpGoogleNamespace {
|
||||
const XmpGImageNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.gImage, nsPrefix, rawProps);
|
||||
XmpGImageNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.gImage);
|
||||
|
||||
@override
|
||||
List<Tuple2<String, String>> get dataProps => [Tuple2('${nsPrefix}Data', '${nsPrefix}Mime')];
|
||||
}
|
||||
|
||||
class XmpContainer extends XmpNamespace {
|
||||
XmpContainer(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.container, nsPrefix, rawProps);
|
||||
class XmpGContainer extends XmpNamespace {
|
||||
XmpGContainer({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.gContainer);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
XmpCardData(RegExp('${nsPrefix}Directory\\[(\\d+)\\]/${nsPrefix}Item/(.*)'), title: 'Directory Item'),
|
||||
XmpCardData(RegExp(nsPrefix + r'Directory\[(\d+)\]/' + nsPrefix + r'Item/(.*)'), title: 'Directory Item'),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:aves/utils/xmp_utils.dart';
|
|||
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
|
||||
|
||||
class XmpCreatorAtom extends XmpNamespace {
|
||||
XmpCreatorAtom(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.creatorAtom, nsPrefix, rawProps);
|
||||
XmpCreatorAtom({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.creatorAtom);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -11,7 +11,7 @@ class XmpCreatorAtom extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpDarktableNamespace extends XmpNamespace {
|
||||
XmpDarktableNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.darktable, nsPrefix, rawProps);
|
||||
XmpDarktableNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.darktable);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -20,7 +20,7 @@ class XmpDarktableNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpDwcNamespace extends XmpNamespace {
|
||||
XmpDwcNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.dwc, nsPrefix, rawProps);
|
||||
XmpDwcNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.dwc);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -37,7 +37,7 @@ class XmpDwcNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpIptcCoreNamespace extends XmpNamespace {
|
||||
XmpIptcCoreNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.iptc4xmpCore, nsPrefix, rawProps);
|
||||
XmpIptcCoreNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.iptc4xmpCore);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -46,7 +46,7 @@ class XmpIptcCoreNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpIptc4xmpExtNamespace extends XmpNamespace {
|
||||
XmpIptc4xmpExtNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.iptc4xmpExt, nsPrefix, rawProps);
|
||||
XmpIptc4xmpExtNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.iptc4xmpExt);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -55,7 +55,7 @@ class XmpIptc4xmpExtNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpMPNamespace extends XmpNamespace {
|
||||
XmpMPNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.mp, nsPrefix, rawProps);
|
||||
XmpMPNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.mp);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -65,7 +65,7 @@ class XmpMPNamespace extends XmpNamespace {
|
|||
|
||||
// cf www.metadataworkinggroup.org/pdf/mwg_guidance.pdf (down, as of 2021/02/15)
|
||||
class XmpMgwRegionsNamespace extends XmpNamespace {
|
||||
XmpMgwRegionsNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.mwgrs, nsPrefix, rawProps);
|
||||
XmpMgwRegionsNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.mwgrs);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -75,7 +75,7 @@ class XmpMgwRegionsNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpPlusNamespace extends XmpNamespace {
|
||||
XmpPlusNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.plus, nsPrefix, rawProps);
|
||||
XmpPlusNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.plus);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
@ -86,7 +86,7 @@ class XmpPlusNamespace extends XmpNamespace {
|
|||
}
|
||||
|
||||
class XmpMMNamespace extends XmpNamespace {
|
||||
XmpMMNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.xmpMM, nsPrefix, rawProps);
|
||||
XmpMMNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.xmpMM);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
|
|||
|
||||
// cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/photoshop.md
|
||||
class XmpPhotoshopNamespace extends XmpNamespace {
|
||||
XmpPhotoshopNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.photoshop, nsPrefix, rawProps);
|
||||
XmpPhotoshopNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.photoshop);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
|
|||
|
||||
// cf https://github.com/adobe/xmp-docs/blob/master/XMPNamespaces/tiff.md
|
||||
class XmpTiffNamespace extends XmpNamespace {
|
||||
const XmpTiffNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.tiff, nsPrefix, rawProps);
|
||||
XmpTiffNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.tiff);
|
||||
|
||||
@override
|
||||
String formatValue(XmpProp prop) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:aves/widgets/viewer/info/common.dart';
|
|||
import 'package:aves/widgets/viewer/info/metadata/xmp_namespaces.dart';
|
||||
|
||||
class XmpBasicNamespace extends XmpNamespace {
|
||||
XmpBasicNamespace(String nsPrefix, Map<String, String> rawProps) : super(Namespaces.xmp, nsPrefix, rawProps);
|
||||
XmpBasicNamespace({required super.schemaRegistryPrefixes, required super.rawProps}) : super(nsUri: Namespaces.xmp);
|
||||
|
||||
@override
|
||||
late final List<XmpCardData> cards = [
|
||||
|
|
|
@ -56,9 +56,8 @@ class _XmpDirTileState extends State<XmpDirTile> {
|
|||
return nsPrefix;
|
||||
}).entries.map((kv) {
|
||||
final nsPrefix = kv.key;
|
||||
final nsUri = _schemaRegistryPrefixes[nsPrefix] ?? '';
|
||||
final rawProps = Map.fromEntries(kv.value);
|
||||
return XmpNamespace.create(nsUri, nsPrefix, rawProps);
|
||||
return XmpNamespace.create(_schemaRegistryPrefixes, nsPrefix, rawProps);
|
||||
}).toList()
|
||||
..sort((a, b) => compareAsciiUpperCase(a.displayTitle, b.displayTitle));
|
||||
return AvesExpansionTile(
|
||||
|
|
Loading…
Reference in a new issue