1#------------------------------------------------------------------------------
2# File:         XMP2.pl
3#
4# Description:  Additional XMP namespace definitions
5#
6# Revisions:    10/12/2008 - P. Harvey Created
7#
8# References:   1) PLUS - http://ns.useplus.org/
9#               2) PRISM - http://www.prismstandard.org/
10#               3) http://www.portfoliofaq.com/pfaq/v7mappings.htm
11#               4) http://www.iptc.org/IPTC4XMP/
12#               5) http://creativecommons.org/technology/xmp
13#                  --> changed to http://wiki.creativecommons.org/Companion_File_metadata_specification (2007/12/21)
14#               6) http://www.optimasc.com/products/fileid/xmp-extensions.pdf
15#               9) http://www.w3.org/TR/SVG11/
16#               11) http://www.extensis.com/en/support/kb_article.jsp?articleNumber=6102211
17#               12) XMPSpecificationPart3_May2013, page 58
18#               13) https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf
19#------------------------------------------------------------------------------
20
21package Image::ExifTool::XMP;
22
23use strict;
24use Image::ExifTool qw(:Utils);
25use Image::ExifTool::XMP;
26
27sub Init_crd($);
28
29#------------------------------------------------------------------------------
30
31# xmpDM structure definitions
32my %sCuePointParam = (
33    STRUCT_NAME => 'CuePointParam',
34    NAMESPACE   => 'xmpDM',
35    key         => { },
36    value       => { },
37);
38my %sMarker = (
39    STRUCT_NAME => 'Marker',
40    NAMESPACE   => 'xmpDM',
41    comment     => { },
42    duration    => { },
43    location    => { },
44    name        => { },
45    startTime   => { },
46    target      => { },
47    type        => { },
48    # added Oct 2008
49    cuePointParams => { Struct => \%sCuePointParam, List => 'Seq' },
50    cuePointType=> { },
51    probability => { Writable => 'real' },
52    speaker     => { },
53);
54my %sTime = (
55    STRUCT_NAME => 'Time',
56    NAMESPACE   => 'xmpDM',
57    scale       => { Writable => 'rational' },
58    value       => { Writable => 'integer' },
59);
60my %sTimecode = (
61    STRUCT_NAME => 'Timecode',
62    NAMESPACE   => 'xmpDM',
63    timeFormat  => {
64        PrintConv => {
65            '24Timecode' => '24 fps',
66            '25Timecode' => '25 fps',
67            '2997DropTimecode' => '29.97 fps (drop)',
68            '2997NonDropTimecode' => '29.97 fps (non-drop)',
69            '30Timecode' => '30 fps',
70            '50Timecode' => '50 fps',
71            '5994DropTimecode' => '59.94 fps (drop)',
72            '5994NonDropTimecode' => '59.94 fps (non-drop)',
73            '60Timecode' => '60 fps',
74            '23976Timecode' => '23.976 fps',
75        },
76    },
77    timeValue   => { },
78    value       => { Writable => 'integer', Notes => 'only in XMP 2008 spec; an error?' },
79);
80my %sPose = (
81    STRUCT_NAME => 'Pose',
82    NAMESPACE => { Pose => 'http://ns.google.com/photos/dd/1.0/pose/' },
83    PositionX => { Writable => 'real', Groups => { 2 => 'Location' } },
84    PositionY => { Writable => 'real', Groups => { 2 => 'Location' } },
85    PositionZ => { Writable => 'real', Groups => { 2 => 'Location' } },
86    RotationX => { Writable => 'real', Groups => { 2 => 'Location' } },
87    RotationY => { Writable => 'real', Groups => { 2 => 'Location' } },
88    RotationZ => { Writable => 'real', Groups => { 2 => 'Location' } },
89    RotationW => { Writable => 'real', Groups => { 2 => 'Location' } },
90    Timestamp => {
91        Writable => 'integer',
92        Shift => 'Time',
93        Groups => { 2 => 'Time' },
94        ValueConv => 'ConvertUnixTime($val / 1000, 1, 3)',
95        ValueConvInv => 'int(GetUnixTime($val, 1) * 1000)',
96        PrintConv => '$self->ConvertDateTime($val)',
97        PrintConvInv => '$self->InverseDateTime($val,undef,1)',
98    },
99);
100my %sEarthPose = (
101    STRUCT_NAME => 'EarthPose',
102    NAMESPACE => { EarthPose => 'http://ns.google.com/photos/dd/1.0/earthpose/' },
103    Latitude  => { Writable => 'real', Groups => { 2 => 'Location' }, %latConv },
104    Longitude => { Writable => 'real', Groups => { 2 => 'Location' }, %longConv },
105    Altitude  => {
106        Writable => 'real',
107        Groups => { 2 => 'Location' },
108        PrintConv => '"$val m"',
109        PrintConvInv => '$val=~s/\s*m$//;$val',
110    },
111    RotationX => { Writable => 'real', Groups => { 2 => 'Location' } },
112    RotationY => { Writable => 'real', Groups => { 2 => 'Location' } },
113    RotationZ => { Writable => 'real', Groups => { 2 => 'Location' } },
114    RotationW => { Writable => 'real', Groups => { 2 => 'Location' } },
115    Timestamp => {
116        Writable => 'integer',
117        Shift => 'Time',
118        Groups => { 2 => 'Time' },
119        ValueConv => 'ConvertUnixTime($val / 1000, 1, 3)',
120        ValueConvInv => 'int(GetUnixTime($val, 1) * 1000)',
121        PrintConv => '$self->ConvertDateTime($val)',
122        PrintConvInv => '$self->InverseDateTime($val,undef,1)',
123    },
124);
125my %sVendorInfo = (
126    STRUCT_NAME => 'VendorInfo',
127    NAMESPACE   => { VendorInfo => 'http://ns.google.com/photos/dd/1.0/vendorinfo/' },
128    Model => { },
129    Manufacturer => { },
130    Notes => { },
131);
132my %sAppInfo = (
133    STRUCT_NAME => 'AppInfo',
134    NAMESPACE   => { AppInfo => 'http://ns.google.com/photos/dd/1.0/appinfo/' },
135    Application => { },
136    Version => { },
137    ItemURI => { },
138);
139
140# camera-raw defaults
141%Image::ExifTool::XMP::crd = (
142    %xmpTableDefaults,
143    INIT_TABLE => \&Init_crd,
144    GROUPS => { 1 => 'XMP-crd', 2 => 'Image' },
145    NAMESPACE   => 'crd',
146    AVOID => 1,
147    TABLE_DESC => 'Photoshop Camera Defaults namespace',
148    NOTES => 'Adobe Camera Raw Defaults tags.',
149    # (tags added dynamically when WRITE_PROC is called)
150);
151
152# XMP Dynamic Media namespace properties (xmpDM)
153%Image::ExifTool::XMP::xmpDM = (
154    %xmpTableDefaults,
155    GROUPS => { 1 => 'XMP-xmpDM', 2 => 'Image' },
156    NAMESPACE => 'xmpDM',
157    NOTES => 'XMP Dynamic Media namespace tags.',
158    absPeakAudioFilePath=> { },
159    album               => { },
160    altTapeName         => { },
161    altTimecode         => { Struct => \%sTimecode },
162    artist              => { Avoid => 1, Groups => { 2 => 'Author' } },
163    audioModDate        => { Groups => { 2 => 'Time' }, %dateTimeInfo },
164    audioSampleRate     => { Writable => 'integer' },
165    audioSampleType => {
166        PrintConv => {
167            '8Int' => '8-bit integer',
168            '16Int' => '16-bit integer',
169            '24Int' => '24-bit integer',
170            '32Int' => '32-bit integer',
171            '32Float' => '32-bit float',
172            'Compressed' => 'Compressed',
173            'Packed' => 'Packed',
174            'Other' => 'Other',
175        },
176    },
177    audioChannelType => {
178        PrintConv => {
179            'Mono' => 'Mono',
180            'Stereo' => 'Stereo',
181            '5.1' => '5.1',
182            '7.1' => '7.1',
183            '16 Channel' => '16 Channel',
184            'Other' => 'Other',
185        },
186    },
187    audioCompressor     => { },
188    beatSpliceParams => {
189        Struct => {
190            STRUCT_NAME => 'BeatSpliceStretch',
191            NAMESPACE   => 'xmpDM',
192            riseInDecibel       => { Writable => 'real' },
193            riseInTimeDuration  => { Struct => \%sTime },
194            useFileBeatsMarker  => { Writable => 'boolean' },
195        },
196    },
197    cameraAngle         => { },
198    cameraLabel         => { },
199    cameraModel         => { },
200    cameraMove          => { },
201    client              => { },
202    comment             => { Name => 'DMComment' },
203    composer            => { Groups => { 2 => 'Author' } },
204    contributedMedia => {
205        Struct => {
206            STRUCT_NAME => 'Media',
207            NAMESPACE   => 'xmpDM',
208            duration    => { Struct => \%sTime },
209            managed     => { Writable => 'boolean' },
210            path        => { },
211            startTime   => { Struct => \%sTime },
212            track       => { },
213            webStatement=> { },
214        },
215        List => 'Bag',
216    },
217    copyright       => { Avoid => 1, Groups => { 2 => 'Author' } }, # (deprecated)
218    director        => { },
219    directorPhotography => { },
220    discNumber      => { }, #12
221    duration        => { Struct => \%sTime },
222    engineer        => { },
223    fileDataRate    => { Writable => 'rational' },
224    genre           => { },
225    good            => { Writable => 'boolean' },
226    instrument      => { },
227    introTime       => { Struct => \%sTime },
228    key => {
229        PrintConvColumns => 3,
230        PrintConv => {
231            'C'  => 'C',  'C#' => 'C#', 'D'  => 'D',  'D#' => 'D#',
232            'E'  => 'E',  'F'  => 'F',  'F#' => 'F#', 'G'  => 'G',
233            'G#' => 'G#', 'A'  => 'A',  'A#' => 'A#', 'B'  => 'B',
234        },
235    },
236    logComment      => { },
237    loop            => { Writable => 'boolean' },
238    lyrics          => { }, #12
239    numberOfBeats   => { Writable => 'real' },
240    markers         => { Struct => \%sMarker, List => 'Seq' },
241    metadataModDate => { Groups => { 2 => 'Time' }, %dateTimeInfo },
242    outCue          => { Struct => \%sTime },
243    partOfCompilation=>{ Writable => 'boolean' }, #12
244    projectName     => { },
245    projectRef => {
246        Struct => {
247            STRUCT_NAME => 'ProjectLink',
248            NAMESPACE   => 'xmpDM',
249            path        => { },
250            type        => {
251                PrintConv => {
252                    movie => 'Movie',
253                    still => 'Still Image',
254                    audio => 'Audio',
255                    custom => 'Custom',
256                },
257            },
258        },
259    },
260    pullDown => {
261        PrintConvColumns => 2,
262        PrintConv => {
263            'WSSWW' => 'WSSWW',  'SSWWW' => 'SSWWW',
264            'SWWWS' => 'SWWWS',  'WWWSS' => 'WWWSS',
265            'WWSSW' => 'WWSSW',  'WWWSW' => 'WWWSW',
266            'WWSWW' => 'WWSWW',  'WSWWW' => 'WSWWW',
267            'SWWWW' => 'SWWWW',  'WWWWS' => 'WWWWS',
268        },
269    },
270    relativePeakAudioFilePath => { },
271    relativeTimestamp   => { Struct => \%sTime },
272    releaseDate         => { Groups => { 2 => 'Time' }, %dateTimeInfo },
273    resampleParams => {
274        Struct => {
275            STRUCT_NAME => 'ResampleStretch',
276            NAMESPACE   => 'xmpDM',
277            quality     => { PrintConv => { Low => 'Low', Medium => 'Medium', High => 'High' } },
278        },
279    },
280    scaleType => {
281        PrintConv => {
282            Major => 'Major',
283            Minor => 'Minor',
284            Both => 'Both',
285            Neither => 'Neither',
286        },
287    },
288    scene           => { Avoid => 1 },
289    shotDate        => { Groups => { 2 => 'Time' }, %dateTimeInfo },
290    shotDay         => { },
291    shotLocation    => { },
292    shotName        => { },
293    shotNumber      => { },
294    shotSize        => { },
295    speakerPlacement=> { },
296    startTimecode   => { Struct => \%sTimecode },
297    startTimeSampleSize => { Writable => 'integer' }, #PH
298    startTimeScale  => { }, #PH (real?)
299    stretchMode     => {
300        PrintConv => {
301            'Fixed length' => 'Fixed length',
302            'Time-Scale' => 'Time-Scale',
303            'Resample' => 'Resample',
304            'Beat Splice' => 'Beat Splice',
305            'Hybrid' => 'Hybrid',
306        },
307    },
308    takeNumber      => { Writable => 'integer' },
309    tapeName        => { },
310    tempo           => { Writable => 'real' },
311    timeScaleParams => {
312        Struct => {
313            STRUCT_NAME => 'TimeScaleStretch',
314            NAMESPACE   => 'xmpDM',
315            frameOverlappingPercentage => { Writable => 'real' },
316            frameSize   => { Writable => 'real' },
317            quality     => { PrintConv => { Low => 'Low', Medium => 'Medium', High => 'High' } },
318        },
319    },
320    timeSignature   => {
321        PrintConvColumns => 3,
322        PrintConv => {
323            '2/4' => '2/4',  '3/4' => '3/4',  '4/4' => '4/4',
324            '5/4' => '5/4',  '7/4' => '7/4',  '6/8' => '6/8',
325            '9/8' => '9/8',  '12/8'=> '12/8', 'other' => 'other',
326        },
327    },
328    trackNumber     => { Writable => 'integer' },
329    Tracks => {
330        Struct => {
331            STRUCT_NAME => 'Track',
332            NAMESPACE   => 'xmpDM',
333            frameRate => { },
334            markers   => { Struct => \%sMarker, List => 'Seq' },
335            trackName => { },
336            trackType => { },
337        },
338        List => 'Bag',
339    },
340    videoAlphaMode => {
341        PrintConv => {
342            'straight' => 'Straight',
343            'pre-multiplied', => 'Pre-multiplied',
344            'none' => 'None',
345        },
346    },
347    videoAlphaPremultipleColor   => { Struct => \%sColorant },
348    videoAlphaUnityIsTransparent => { Writable => 'boolean' },
349    videoColorSpace     => {
350        PrintConv => {
351            'sRGB' => 'sRGB',
352            'CCIR-601' => 'CCIR-601',
353            'CCIR-709' => 'CCIR-709',
354        },
355    },
356    videoCompressor => { },
357    videoFieldOrder => {
358        PrintConv => {
359            Upper => 'Upper',
360            Lower => 'Lower',
361            Progressive => 'Progressive',
362        },
363    },
364    videoFrameRate  => { Writable => 'real' },
365    videoFrameSize  => { Struct => \%sDimensions },
366    videoModDate    => { Groups => { 2 => 'Time' }, %dateTimeInfo },
367    videoPixelAspectRatio => { Writable => 'rational' },
368    videoPixelDepth => {
369        PrintConv => {
370            '8Int' => '8-bit integer',
371            '16Int' => '16-bit integer',
372            '24Int' => '24-bit integer',
373            '32Int' => '32-bit integer',
374            '32Float' => '32-bit float',
375            'Other' => 'Other',
376        },
377    },
378);
379
380#------------------------------------------------------------------------------
381# IPTC Extensions version 1.3 (+ proposed video extensions)
382
383# IPTC Extension 1.0 structures
384my %sLocationDetails = (
385    STRUCT_NAME => 'LocationDetails',
386    NAMESPACE   => 'Iptc4xmpExt',
387    GROUPS      => { 2 => 'Location' },
388    Identifier  => { List => 'Bag', Namespace => 'xmp' },
389    City        => { },
390    CountryCode => { },
391    CountryName => { },
392    ProvinceState => { },
393    Sublocation => { },
394    WorldRegion => { },
395    LocationId  => { List => 'Bag' },
396    LocationName => { Writable => 'lang-alt' },
397    GPSLatitude  => { Namespace => 'exif', %latConv },
398    GPSLongitude => { Namespace => 'exif', %longConv },
399    GPSAltitude => {
400        Namespace => 'exif',
401        Writable => 'rational',
402        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
403        PrintConvInv => '$val=~s/\s*m$//;$val',
404    },
405);
406my %sCVTermDetails = (
407    STRUCT_NAME => 'CVTermDetails',
408    NAMESPACE   => 'Iptc4xmpExt',
409    CvTermId    => { },
410    CvTermName  => { Writable => 'lang-alt' },
411    CvId        => { },
412    CvTermRefinedAbout => { },
413);
414
415# IPTC video extensions
416my %sPublicationEvent = (
417    STRUCT_NAME => 'PublicationEvent',
418    NAMESPACE   => 'Iptc4xmpExt',
419    Date        => { Groups => { 2 => 'Time' }, %dateTimeInfo },
420    Name        => { },
421    Identifier  => { },
422);
423my %sEntity = (
424    STRUCT_NAME => 'Entity',
425    NAMESPACE   => 'Iptc4xmpExt',
426    Identifier  => { List => 'Bag', Namespace => 'xmp' },
427    Name        => { Writable => 'lang-alt' },
428);
429my %sEntityWithRole = (
430    STRUCT_NAME => 'EntityWithRole',
431    NAMESPACE   => 'Iptc4xmpExt',
432    Identifier  => { List => 'Bag', Namespace => 'xmp' },
433    Name        => { Writable => 'lang-alt' },
434    Role        => { List => 'Bag' },
435);
436# (no longer used)
437#my %sFrameSize = (
438#    STRUCT_NAME => 'FrameSize',
439#    NAMESPACE   => 'Iptc4xmpExt',
440#    WidthPixels  => { Writable => 'integer' },
441#    HeightPixels => { Writable => 'integer' },
442#);
443my %sRating = (
444    STRUCT_NAME => 'Rating',
445    NAMESPACE   => 'Iptc4xmpExt',
446    RatingValue         => { FlatName => 'Value' },
447    RatingSourceLink    => { FlatName => 'SourceLink' },
448    RatingScaleMinValue => { FlatName => 'ScaleMinValue' },
449    RatingScaleMaxValue => { FlatName => 'ScaleMaxValue' },
450    RatingValueLogoLink => { FlatName => 'ValueLogoLink' },
451    RatingRegion => {
452        FlatName => 'Region',
453        Struct => \%sLocationDetails,
454        List => 'Bag',
455    },
456);
457my %sEpisode = (
458    STRUCT_NAME => 'EpisodeOrSeason',
459    NAMESPACE   => 'Iptc4xmpExt',
460    Name        => { },
461    Number      => { },
462    Identifier  => { },
463);
464my %sSeries = (
465    STRUCT_NAME => 'Series',
466    NAMESPACE   => 'Iptc4xmpExt',
467    Name        => { },
468    Identifier  => { },
469);
470my %sTemporalCoverage = (
471    STRUCT_NAME => 'TemporalCoverage',
472    NAMESPACE   => 'Iptc4xmpExt',
473    tempCoverageFrom => { FlatName => 'From', %dateTimeInfo, Groups => { 2 => 'Time' } },
474    tempCoverageTo   => { FlatName => 'To',   %dateTimeInfo, Groups => { 2 => 'Time' } },
475);
476my %sQualifiedLink = (
477    STRUCT_NAME => 'QualifiedLink',
478    NAMESPACE   => 'Iptc4xmpExt',
479    Link        => { },
480    LinkQualifier => { },
481);
482my %sTextRegion = (
483    STRUCT_NAME => 'TextRegion',
484    NAMESPACE   => 'Iptc4xmpExt',
485    RegionText  => { },
486    Region      => { Struct => \%Image::ExifTool::XMP::sArea },
487);
488my %sLinkedImage = (
489    STRUCT_NAME => 'LinkedImage',
490    NAMESPACE   => 'Iptc4xmpExt',
491    Link        => { },
492    LinkQualifier => { List => 'Bag' },
493    ImageRole   => { },
494   'format'     => { Namespace => 'dc' },
495    WidthPixels => { Writable => 'integer' },
496    HeightPixels=> { Writable => 'integer' },
497    UsedVideoFrame => { Struct => \%sTimecode },
498);
499my %sBoundaryPoint = ( # new in 1.5
500    STRUCT_NAME => 'BoundaryPoint',
501    NAMESPACE   => 'Iptc4xmpExt',
502    rbX => { FlatName => 'X', Writable => 'real' },
503    rbY => { FlatName => 'Y', Writable => 'real' },
504);
505my %sRegionBoundary = ( # new in 1.5
506    STRUCT_NAME => 'RegionBoundary',
507    NAMESPACE   => 'Iptc4xmpExt',
508    rbShape => { FlatName => 'Shape', PrintConv => { rectangle => 'Rectangle', circle => 'Circle', polygon => 'Polygon' } },
509    rbUnit  => { FlatName => 'Unit',  PrintConv => { pixel => 'Pixel', relative => 'Relative' } },
510    rbX => { FlatName => 'X', Writable => 'real' },
511    rbY => { FlatName => 'Y', Writable => 'real' },
512    rbW => { FlatName => 'W', Writable => 'real' },
513    rbH => { FlatName => 'H', Writable => 'real' },
514    rbRx => { FlatName => 'Rx', Writable => 'real' },
515    rbVertices => { FlatName => 'Vertices', List => 'Seq', Struct => \%sBoundaryPoint },
516);
517my %sImageRegion = ( # new in 1.5
518    STRUCT_NAME => 'ImageRegion',
519    NAMESPACE   => undef,   # undefined to allow variable-namespace extensions
520    NOTES => q{
521        This structure is new in the IPTC Extension version 1.5 specification.  As
522        well as the fields defined below, this structure may contain any top-level
523        XMP tags, but since they aren't pre-defined the only way to add these tags
524        is to write ImageRegion as a structure with these tags as new fields.
525    },
526    RegionBoundary => { Namespace => 'Iptc4xmpExt', FlatName => 'Boundary', Struct => \%sRegionBoundary },
527    rId    => { Namespace => 'Iptc4xmpExt', FlatName => 'ID' },
528    Name   => { Namespace => 'Iptc4xmpExt', Writable => 'lang-alt' },
529    rCtype => { Namespace => 'Iptc4xmpExt', FlatName => 'Ctype', List => 'Bag', Struct => \%sEntity },
530    rRole  => { Namespace => 'Iptc4xmpExt', FlatName => 'Role',  List => 'Bag', Struct => \%sEntity },
531);
532
533# IPTC Extension namespace properties (Iptc4xmpExt) (ref 4)
534%Image::ExifTool::XMP::iptcExt = (
535    %xmpTableDefaults,
536    GROUPS => { 1 => 'XMP-iptcExt', 2 => 'Author' },
537    NAMESPACE   => 'Iptc4xmpExt',
538    TABLE_DESC => 'XMP IPTC Extension',
539    NOTES => q{
540        This table contains tags defined by the IPTC Extension schema version 1.5.
541        The actual namespace prefix is "Iptc4xmpExt", but ExifTool shortens this for
542        the family 1 group name. (see
543        L<http://www.iptc.org/standards/photo-metadata/iptc-standard/>)
544    },
545    AboutCvTerm => {
546        Struct => \%sCVTermDetails,
547        List => 'Bag',
548    },
549    AboutCvTermCvId                 => { Flat => 1, Name => 'AboutCvTermCvId' },
550    AboutCvTermCvTermId             => { Flat => 1, Name => 'AboutCvTermId' },
551    AboutCvTermCvTermName           => { Flat => 1, Name => 'AboutCvTermName' },
552    AboutCvTermCvTermRefinedAbout   => { Flat => 1, Name => 'AboutCvTermRefinedAbout' },
553    AddlModelInfo   => { Name => 'AdditionalModelInformation' },
554    ArtworkOrObject => {
555        Struct => {
556            STRUCT_NAME => 'ArtworkOrObjectDetails',
557            NAMESPACE   => 'Iptc4xmpExt',
558            AOCopyrightNotice => { },
559            AOCreator    => { List => 'Seq' },
560            AODateCreated=> { Groups => { 2 => 'Time' }, %dateTimeInfo },
561            AOSource     => { },
562            AOSourceInvNo=> { },
563            AOTitle      => { Writable => 'lang-alt' },
564            AOCurrentCopyrightOwnerName => { },
565            AOCurrentCopyrightOwnerId   => { },
566            AOCurrentLicensorName       => { },
567            AOCurrentLicensorId         => { },
568            AOCreatorId                 => { List => 'Seq' },
569            AOCircaDateCreated          => { Groups => { 2 => 'Time' }, Protected => 1 },
570            AOStylePeriod               => { List => 'Bag' },
571            AOSourceInvURL              => { },
572            AOContentDescription        => { Writable => 'lang-alt' },
573            AOContributionDescription   => { Writable => 'lang-alt' },
574            AOPhysicalDescription       => { Writable => 'lang-alt' },
575        },
576        List => 'Bag',
577    },
578    ArtworkOrObjectAOCopyrightNotice           => { Flat => 1, Name => 'ArtworkCopyrightNotice' },
579    ArtworkOrObjectAOCreator                   => { Flat => 1, Name => 'ArtworkCreator' },
580    ArtworkOrObjectAODateCreated               => { Flat => 1, Name => 'ArtworkDateCreated' },
581    ArtworkOrObjectAOSource                    => { Flat => 1, Name => 'ArtworkSource' },
582    ArtworkOrObjectAOSourceInvNo               => { Flat => 1, Name => 'ArtworkSourceInventoryNo' },
583    ArtworkOrObjectAOTitle                     => { Flat => 1, Name => 'ArtworkTitle' },
584    ArtworkOrObjectAOCurrentCopyrightOwnerName => { Flat => 1, Name => 'ArtworkCopyrightOwnerName' },
585    ArtworkOrObjectAOCurrentCopyrightOwnerId   => { Flat => 1, Name => 'ArtworkCopyrightOwnerID' },
586    ArtworkOrObjectAOCurrentLicensorName       => { Flat => 1, Name => 'ArtworkLicensorName' },
587    ArtworkOrObjectAOCurrentLicensorId         => { Flat => 1, Name => 'ArtworkLicensorID' },
588    ArtworkOrObjectAOCreatorId                 => { Flat => 1, Name => 'ArtworkCreatorID' },
589    ArtworkOrObjectAOCircaDateCreated          => { Flat => 1, Name => 'ArtworkCircaDateCreated' },
590    ArtworkOrObjectAOStylePeriod               => { Flat => 1, Name => 'ArtworkStylePeriod' },
591    ArtworkOrObjectAOSourceInvURL              => { Flat => 1, Name => 'ArtworkSourceInvURL' },
592    ArtworkOrObjectAOContentDescription        => { Flat => 1, Name => 'ArtworkContentDescription' },
593    ArtworkOrObjectAOContributionDescription   => { Flat => 1, Name => 'ArtworkContributionDescription' },
594    ArtworkOrObjectAOPhysicalDescription       => { Flat => 1, Name => 'ArtworkPhysicalDescription' },
595    CVterm => {
596        Name => 'ControlledVocabularyTerm',
597        List => 'Bag',
598        Notes => 'deprecated by version 1.2',
599    },
600    DigImageGUID            => { Groups => { 2 => 'Image' }, Name => 'DigitalImageGUID' },
601    DigitalSourcefileType   => {
602        Name => 'DigitalSourceFileType',
603        Notes => 'now deprecated -- replaced by DigitalSourceType',
604        Groups => { 2 => 'Image' },
605    },
606    DigitalSourceType       => { Name => 'DigitalSourceType', Groups => { 2 => 'Image' } },
607    EmbdEncRightsExpr => {
608        Struct => {
609            STRUCT_NAME => 'EEREDetails',
610            NAMESPACE   => 'Iptc4xmpExt',
611            EncRightsExpr       => { },
612            RightsExprEncType   => { },
613            RightsExprLangId    => { },
614        },
615        List => 'Bag',
616    },
617    EmbdEncRightsExprEncRightsExpr      => { Flat => 1, Name => 'EmbeddedEncodedRightsExpr' },
618    EmbdEncRightsExprRightsExprEncType  => { Flat => 1, Name => 'EmbeddedEncodedRightsExprType' },
619    EmbdEncRightsExprRightsExprLangId   => { Flat => 1, Name => 'EmbeddedEncodedRightsExprLangID' },
620    Event       => { Writable => 'lang-alt' },
621    IptcLastEdited => {
622        Name => 'IPTCLastEdited',
623        Groups => { 2 => 'Time' },
624        %dateTimeInfo,
625    },
626    LinkedEncRightsExpr => {
627        Struct => {
628            STRUCT_NAME => 'LEREDetails',
629            NAMESPACE   => 'Iptc4xmpExt',
630            LinkedRightsExpr    => { },
631            RightsExprEncType   => { },
632            RightsExprLangId    => { },
633        },
634        List => 'Bag',
635    },
636    LinkedEncRightsExprLinkedRightsExpr  => { Flat => 1, Name => 'LinkedEncodedRightsExpr' },
637    LinkedEncRightsExprRightsExprEncType => { Flat => 1, Name => 'LinkedEncodedRightsExprType' },
638    LinkedEncRightsExprRightsExprLangId  => { Flat => 1, Name => 'LinkedEncodedRightsExprLangID' },
639    LocationCreated => {
640        Struct => \%sLocationDetails,
641        Groups => { 2 => 'Location' },
642        List => 'Bag',
643    },
644    LocationShown => {
645        Struct => \%sLocationDetails,
646        Groups => { 2 => 'Location' },
647        List => 'Bag',
648    },
649    MaxAvailHeight          => { Groups => { 2 => 'Image' }, Writable => 'integer' },
650    MaxAvailWidth           => { Groups => { 2 => 'Image' }, Writable => 'integer' },
651    ModelAge                => { List => 'Bag', Writable => 'integer' },
652    OrganisationInImageCode => { List => 'Bag' },
653    OrganisationInImageName => { List => 'Bag' },
654    PersonInImage           => { List => 'Bag' },
655    PersonInImageWDetails => {
656        Struct => {
657            STRUCT_NAME => 'PersonDetails',
658            NAMESPACE   => 'Iptc4xmpExt',
659            PersonId    => { List => 'Bag' },
660            PersonName  => { Writable => 'lang-alt' },
661            PersonCharacteristic => {
662                Struct  => \%sCVTermDetails,
663                List    => 'Bag',
664            },
665            PersonDescription => { Writable => 'lang-alt' },
666        },
667        List => 'Bag',
668    },
669    PersonInImageWDetailsPersonId                               => { Flat => 1, Name => 'PersonInImageId' },
670    PersonInImageWDetailsPersonName                             => { Flat => 1, Name => 'PersonInImageName' },
671    PersonInImageWDetailsPersonCharacteristic                   => { Flat => 1, Name => 'PersonInImageCharacteristic' },
672    PersonInImageWDetailsPersonCharacteristicCvId               => { Flat => 1, Name => 'PersonInImageCvTermCvId' },
673    PersonInImageWDetailsPersonCharacteristicCvTermId           => { Flat => 1, Name => 'PersonInImageCvTermId' },
674    PersonInImageWDetailsPersonCharacteristicCvTermName         => { Flat => 1, Name => 'PersonInImageCvTermName' },
675    PersonInImageWDetailsPersonCharacteristicCvTermRefinedAbout => { Flat => 1, Name => 'PersonInImageCvTermRefinedAbout' },
676    PersonInImageWDetailsPersonDescription                      => { Flat => 1, Name => 'PersonInImageDescription' },
677    ProductInImage => {
678        Struct => {
679            STRUCT_NAME => 'ProductDetails',
680            NAMESPACE   => 'Iptc4xmpExt',
681            ProductName => { Writable => 'lang-alt' },
682            ProductGTIN => { },
683            ProductDescription => { Writable => 'lang-alt' },
684        },
685        List => 'Bag',
686    },
687    ProductInImageProductName        => { Flat => 1, Name => 'ProductInImageName' },
688    ProductInImageProductGTIN        => { Flat => 1, Name => 'ProductInImageGTIN' },
689    ProductInImageProductDescription => { Flat => 1, Name => 'ProductInImageDescription' },
690    RegistryId => {
691        Name => 'RegistryID',
692        Struct => {
693            STRUCT_NAME => 'RegistryEntryDetails',
694            NAMESPACE   => 'Iptc4xmpExt',
695            RegItemId   => { },
696            RegOrgId    => { },
697            RegEntryRole=> { }, # (new in 1.3)
698        },
699        List => 'Bag',
700    },
701    RegistryIdRegItemId => { Flat => 1, Name => 'RegistryItemID' },
702    RegistryIdRegOrgId  => { Flat => 1, Name => 'RegistryOrganisationID' },
703    RegistryIdRegEntryRole => { Flat => 1, Name => 'RegistryEntryRole' },
704
705    # new Extension 1.3 properties
706    Genre           => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sCVTermDetails },
707
708    # new video properties (Oct 2016, ref Michael Steidl)
709    # (see http://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.0.html)
710    CircaDateCreated=> { Groups => { 2 => 'Time' } },
711    Episode         => { Groups => { 2 => 'Video' }, Struct => \%sEpisode },
712    ExternalMetadataLink => { Groups => { 2 => 'Other' }, List => 'Bag' },
713    FeedIdentifier  => { Groups => { 2 => 'Video' } },
714    PublicationEvent=> { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sPublicationEvent },
715    Rating          => {
716        Groups => { 2 => 'Other' },
717        Struct  => \%sRating,
718        List    => 'Bag',
719    },
720    ReleaseReady    => { Groups => { 2 => 'Other' }, Writable => 'boolean' },
721    Season          => { Groups => { 2 => 'Video' }, Struct => \%sEpisode },
722    Series          => { Groups => { 2 => 'Video' }, Struct => \%sSeries },
723    StorylineIdentifier => { Groups => { 2 => 'Video' }, List => 'Bag' },
724    StylePeriod     => { Groups => { 2 => 'Video' } },
725    TemporalCoverage=> { Groups => { 2 => 'Video' }, Struct => \%sTemporalCoverage },
726    WorkflowTag     => { Groups => { 2 => 'Video' }, Struct => \%sCVTermDetails },
727    DataOnScreen    => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sTextRegion },
728    Dopesheet       => { Groups => { 2 => 'Video' }, Writable => 'lang-alt' },
729    DopesheetLink   => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sQualifiedLink },
730    Headline        => { Groups => { 2 => 'Video' }, Writable => 'lang-alt', Avoid => 1 },
731    PersonHeard     => { Groups => { 2 => 'Audio' }, List => 'Bag', Struct => \%sEntity },
732    VideoShotType   => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sEntity },
733    EventExt        => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sEntity, Name => 'ShownEvent' },
734    Transcript      => { Groups => { 2 => 'Video' }, Writable => 'lang-alt' },
735    TranscriptLink  => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sQualifiedLink },
736    VisualColour    => {
737        Name => 'VisualColor',
738        Groups => { 2 => 'Video' },
739        PrintConv => {
740            'bw-monochrome' => 'Monochrome',
741            'colour'        => 'Color',
742        },
743    },
744    Contributor     => { List => 'Bag', Struct => \%sEntityWithRole },
745    CopyrightYear   => { Groups => { 2 => 'Time' },  Writable => 'integer' },
746    Creator         => { List => 'Bag', Struct => \%sEntityWithRole },
747    SupplyChainSource => { Groups => { 2 => 'Other' }, List => 'Bag', Struct => \%sEntity },
748    audioBitRate    => { Groups => { 2 => 'Audio' }, Writable => 'integer', Name => 'AudioBitrate' },
749    audioBitRateMode=> {
750        Name => 'AudioBitrateMode',
751        Groups => { 2 => 'Audio' },
752        PrintConv => {
753            fixed => 'Fixed',
754            variable => 'Variable',
755        },
756    },
757    audioChannelCount       => { Groups => { 2 => 'Audio' }, Writable => 'integer' },
758    videoDisplayAspectRatio => { Groups => { 2 => 'Audio' }, Writable => 'rational' },
759    ContainerFormat         => { Groups => { 2 => 'Video' }, Struct => \%sEntity },
760    StreamReady => {
761        Groups => { 2 => 'Video' },
762        PrintConv => {
763            true => 'True',
764            false => 'False',
765            unknown => 'Unknown',
766        },
767    },
768    videoBitRate     => { Groups => { 2 => 'Video' }, Writable => 'integer', Name => 'VideoBitrate' },
769    videoBitRateMode => {
770        Name => 'VideoBitrateMode',
771        Groups => { 2 => 'Video' },
772        PrintConv => {
773            fixed => 'Fixed',
774            variable => 'Variable',
775        },
776    },
777    videoEncodingProfile => { Groups => { 2 => 'Video' } },
778    videoStreamsCount    => { Groups => { 2 => 'Video' }, Writable => 'integer' },
779    # new IPTC video metadata 1.1 properties
780    # (ref https://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.1.html)
781    SnapshotLink => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sLinkedImage, Name => 'Snapshot' },
782    # new IPTC video metadata 1.2 properties
783    # (ref http://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.2.html)
784    RecDevice => {
785        Groups => { 2 => 'Device' },
786        Struct => {
787            STRUCT_NAME => 'Device',
788            NAMESPACE   => 'Iptc4xmpExt',
789            Manufacturer        => { },
790            ModelName           => { },
791            SerialNumber        => { },
792            AttLensDescription  => { },
793            OwnersDeviceId      => { },
794        },
795    },
796    PlanningRef         => { List => 'Bag', Struct => \%sEntityWithRole },
797    audioBitsPerSample  => { Groups => { 2 => 'Audio' }, Writable => 'integer' },
798    # new IPTC Extension schema 1.5 property
799    ImageRegion => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sImageRegion },
800);
801
802#------------------------------------------------------------------------------
803# PRISM
804#
805# NOTE: The "Avoid" flag is set for all PRISM tags (via tag table AVOID flag)
806
807# my %obsolete = (
808#     Notes => 'obsolete in 2.0',
809#     ValueConvInv => sub {
810#         my ($val, $self) = @_;
811#         unless ($self->Options('IgnoreMinorErrors')) {
812#             warn "Warning: [minor] Attempt to write obsolete tag\n";
813#             return undef;
814#         }
815#         return $val;
816#     }
817# );
818
819# PRISM structure definitions
820my %prismPublicationDate = (
821    STRUCT_NAME => 'prismPublicationDate',
822    NAMESPACE   => 'prism',
823    date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
824    'a-platform'=> { },
825);
826
827# Publishing Requirements for Industry Standard Metadata (prism) (ref 2)
828%Image::ExifTool::XMP::prism = (
829    %xmpTableDefaults,
830    GROUPS => { 0 => 'XMP', 1 => 'XMP-prism', 2 => 'Document' },
831    NAMESPACE => 'prism',
832    AVOID => 1,
833    NOTES => q{
834        Publishing Requirements for Industry Standard Metadata 3.0 namespace
835        tags.  (see L<http://www.prismstandard.org/>)
836    },
837    academicField   => { }, # (3.0)
838    aggregateIssueNumber => { Writable => 'integer' }, # (3.0)
839    aggregationType => { List => 'Bag' },
840    alternateTitle  => {
841        List => 'Bag',
842        Struct => { # (becomes a structure in 3.0)
843            STRUCT_NAME => 'prismAlternateTitle',
844            NAMESPACE   => 'prism',
845            text        => { },
846            'a-platform'=> { },
847            'a-lang'    => { },
848        },
849    },
850    blogTitle       => { }, # (3.0)
851    blogURL         => { }, # (3.0)
852    bookEdition     => { }, # (3.0)
853    byteCount       => { Writable => 'integer' },
854    channel         => {
855        List => 'Bag',
856        Struct => { # (becomes a structure in 3.0)
857            STRUCT_NAME => 'prismChannel',
858            NAMESPACE   => 'prism',
859            channel     => { },
860            subchannel1 => { },
861            subchannel2 => { },
862            subchannel3 => { },
863            subchannel4 => { },
864            'a-lang'    => { },
865        },
866    },
867    complianceProfile=>{ PrintConv => { three => 'Three' } },
868    contentType     => { }, # (3.0)
869    copyrightYear   => { }, # (3.0)
870    # copyright       => { Groups => { 2 => 'Author' } }, # (deprecated in 3.0)
871    corporateEntity => { List => 'Bag' },
872    coverDate       => { %dateTimeInfo, Groups => { 2 => 'Time'} },
873    coverDisplayDate=> { },
874    creationDate    => { %dateTimeInfo, Groups => { 2 => 'Time'} },
875    dateRecieved    => { %dateTimeInfo, Groups => { 2 => 'Time'} },
876    device          => { }, # (3.0)
877    distributor     => { },
878    doi             => { Name => 'DOI', Description => 'Digital Object Identifier' },
879    edition         => { },
880    eIssn           => { },
881    #embargoDate     => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, # (deprecated in 3.0)
882    endingPage      => { },
883    event           => { List => 'Bag' },
884    #expirationDate  => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, # (deprecated in 3.0)
885    genre           => { List => 'Bag' },
886    hasAlternative  => { List => 'Bag' },
887    hasCorrection   => {
888        Struct => { # (becomes a structure in 3.0)
889            STRUCT_NAME => 'prismHasCorrection',
890            NAMESPACE   => 'prism',
891            text        => { },
892            'a-platform'=> { },
893            'a-lang'    => { },
894        },
895    },
896    # hasPreviousVersion => { }, # (not in 3.0)
897    hasTranslation  => { List => 'Bag' },
898    industry        => { List => 'Bag' },
899    isAlternativeOf => { List => 'Bag' }, # (3.0)
900    isbn            => { Name => 'ISBN', List => 'Bag' }, # 2.1 (becomes a list in 3.0)
901    isCorrectionOf  => { List => 'Bag' },
902    issn            => { Name => 'ISSN' },
903    issueIdentifier => { },
904    issueName       => { },
905    issueTeaser     => { }, # (3.0)
906    issueType       => { }, # (3.0)
907    isTranslationOf => { },
908    keyword         => { List => 'Bag' },
909    killDate        => {
910        Struct => { # (becomes a structure in 3.0)
911            STRUCT_NAME => 'prismKillDate',
912            NAMESPACE   => 'prism',
913            date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
914            'a-platform'=> { }, #PH (missed in spec?)
915        },
916    },
917   'link'           => { List => 'Bag' }, # (3.0)
918    location        => { List => 'Bag' },
919    # metadataContainer => { }, (not valid for PRISM XMP)
920    modificationDate=> { %dateTimeInfo, Groups => { 2 => 'Time'} },
921    nationalCatalogNumber => { }, # (3.0)
922    number          => { },
923    object          => { List => 'Bag' },
924    onSaleDate => { # (3.0)
925        List => 'Bag',
926        Struct => {
927            STRUCT_NAME => 'prismOnSaleDate',
928            NAMESPACE   => 'prism',
929            date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
930            'a-platform'=> { },
931        },
932    },
933    onSaleDay => { # (3.0)
934        List => 'Bag',
935        Struct => {
936            STRUCT_NAME => 'prismOnSaleDay',
937            NAMESPACE   => 'prism',
938            day         => { }, #PH (not named in spec)
939            'a-platform'=> { },
940        },
941    },
942    offSaleDate => { # (3.0)
943        List => 'Bag',
944        Struct => {
945            STRUCT_NAME => 'prismOffSaleDate',
946            NAMESPACE   => 'prism',
947            date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
948            'a-platform'=> { },
949        },
950    },
951    organization    => { List => 'Bag' },
952    originPlatform  => {
953        List => 'Bag',
954        PrintConv => {
955            email       => 'E-Mail',
956            mobile      => 'Mobile',
957            broadcast   => 'Broadcast',
958            web         => 'Web',
959           'print'      => 'Print',
960            recordableMedia => 'Recordable Media',
961            other       => 'Other',
962        },
963    },
964    pageCount       => { Writable => 'integer' }, # (3.0)
965    pageProgressionDirection => { # (3.0)
966        PrintConv => { LTR => 'Left to Right', RTL => 'Right to Left' },
967    },
968    pageRange       => { List => 'Bag' },
969    person          => { },
970    platform        => { }, # (3.0)
971    productCode     => { }, # (3.0)
972    profession      => { }, # (3.0)
973    publicationDate => {
974        List => 'Bag',
975        Struct => \%prismPublicationDate, # (becomes a structure in 3.0)
976    },
977    publicationDisplayDate => { # (3.0)
978        List => 'Bag',
979        Struct => \%prismPublicationDate,
980    },
981    publicationName => { },
982    publishingFrequency => { }, # (3.0)
983    rating          => { },
984    # rightsAgent     => { }, # (deprecated in 3.0)
985    samplePageRange => { }, # (3.0)
986    section         => { },
987    sellingAgency   => { }, # (3.0)
988    seriesNumber    => { Writable => 'integer' }, # (3.0)
989    seriesTitle     => { }, # (3.0)
990    sport           => { }, # (3.0)
991    startingPage    => { },
992    subsection1     => { },
993    subsection2     => { },
994    subsection3     => { },
995    subsection4     => { },
996    subtitle        => { }, # (3.0)
997    supplementDisplayID => { }, # (3.0)
998    supplementStartingPage => { }, # (3.0)
999    supplementTitle => { }, # (3.0)
1000    teaser          => { List => 'Bag' },
1001    ticker          => { List => 'Bag' },
1002    timePeriod      => { },
1003    url             => {
1004        Name => 'URL',
1005        List => 'Bag',
1006        Struct => { # (becomes a structure in 3.0)
1007            STRUCT_NAME => 'prismUrl',
1008            NAMESPACE   => 'prism',
1009            url         => { },
1010            'a-platform'=> { },
1011        },
1012    },
1013    uspsNumber      => { }, # (3.0)
1014    versionIdentifier => { },
1015    volume          => { },
1016    wordCount       => { Writable => 'integer' },
1017# tags that existed in version 1.3
1018#    category        => { %obsolete, List => 'Bag' },
1019#    hasFormat       => { %obsolete, List => 'Bag' },
1020#    hasPart         => { %obsolete, List => 'Bag' },
1021#    isFormatOf      => { %obsolete, List => 'Bag' },
1022#    isPartOf        => { %obsolete },
1023#    isReferencedBy  => { %obsolete, List => 'Bag' },
1024#    isRequiredBy    => { %obsolete, List => 'Bag' },
1025#    isVersionOf     => { %obsolete },
1026#    objectTitle     => { %obsolete, List => 'Bag' },
1027#    receptionDate   => { %obsolete },
1028#    references      => { %obsolete, List => 'Bag' },
1029#    requires        => { %obsolete, List => 'Bag' },
1030# tags in older versions
1031#    page
1032#    contentLength
1033#    creationTime
1034#    expirationTime
1035#    hasVersion
1036#    isAlternativeFor
1037#    isBasedOn
1038#    isBasisFor
1039#    modificationTime
1040#    publicationTime
1041#    receptionTime
1042#    releaseTime
1043);
1044
1045# PRISM Rights Language namespace (prl) (ref 2)
1046%Image::ExifTool::XMP::prl = (
1047    %xmpTableDefaults,
1048    GROUPS => { 0 => 'XMP', 1 => 'XMP-prl', 2 => 'Document' },
1049    NAMESPACE => 'prl',
1050    AVOID => 1,
1051    NOTES => q{
1052        PRISM Rights Language 2.1 namespace tags.  These tags have been deprecated
1053        since the release of the PRISM Usage Rights 3.0. (see
1054        L<http://www.prismstandard.org/>)
1055    },
1056    geography       => { List => 'Bag' },
1057    industry        => { List => 'Bag' },
1058    usage           => { List => 'Bag' },
1059);
1060
1061# PRISM Usage Rights namespace (prismusagerights) (ref 2)
1062%Image::ExifTool::XMP::pur = (
1063    %xmpTableDefaults,
1064    GROUPS => { 0 => 'XMP', 1 => 'XMP-pur', 2 => 'Document' },
1065    NAMESPACE => 'pur',
1066    AVOID => 1,
1067    NOTES => q{
1068        PRISM Usage Rights 3.0 namespace tags.  (see
1069        L<http://www.prismstandard.org/>)
1070    },
1071    adultContentWarning => { List => 'Bag' },
1072    agreement           => { List => 'Bag' },
1073    copyright           => {
1074        # (not clear in 3.0 spec, which lists only "bag Text", and called
1075        #  "copyrightDate" instead of "copyright" the PRISM basic 3.0 spec)
1076        Writable => 'lang-alt',
1077        Groups => { 2 => 'Author' },
1078    },
1079    creditLine          => { List => 'Bag' },
1080    embargoDate         => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1081    exclusivityEndDate  => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1082    expirationDate      => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1083    imageSizeRestriction=> { },
1084    optionEndDate       => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1085    permissions         => { List => 'Bag' },
1086    restrictions        => { List => 'Bag' },
1087    reuseProhibited     => { Writable => 'boolean' },
1088    rightsAgent         => { },
1089    rightsOwner         => { },
1090    # usageFee            => { List => 'Bag' }, # (not in 3.0)
1091);
1092
1093# PRISM Metadata for Images namespace (pmi) (ref 2)
1094%Image::ExifTool::XMP::pmi = (
1095    %xmpTableDefaults,
1096    GROUPS => { 0 => 'XMP', 1 => 'XMP-pmi', 2 => 'Image' },
1097    NAMESPACE => 'pmi',
1098    AVOID => 1,
1099    NOTES => q{
1100        PRISM Metadata for Images 3.0 namespace tags.  (see
1101        L<http://www.prismstandard.org/>)
1102    },
1103    color => {
1104        PrintConv => {
1105            bw => 'BW',
1106            color => 'Color',
1107            sepia => 'Sepia',
1108            duotone => 'Duotone',
1109            tritone => 'Tritone',
1110            quadtone => 'Quadtone',
1111        },
1112    },
1113    contactInfo     => { },
1114    displayName     => { },
1115    distributorProductID => { },
1116    eventAlias      => { },
1117    eventEnd        => { },
1118    eventStart      => { },
1119    eventSubtype    => { },
1120    eventType       => { },
1121    field           => { },
1122    framing         => { },
1123    location        => { },
1124    make            => { },
1125    manufacturer    => { },
1126    model           => { },
1127    modelYear       => { },
1128    objectDescription=>{ },
1129    objectSubtype   => { },
1130    objectType      => { },
1131    orientation => {
1132        PrintConv => {
1133            horizontal => 'Horizontal',
1134            vertical => 'Vertical',
1135        }
1136    },
1137    positionDescriptor => { },
1138    productID       => { },
1139    productIDType   => { },
1140    season => {
1141        PrintConv => {
1142            spring => 'Spring',
1143            summer => 'Summer',
1144            fall => 'Fall',
1145            winter => 'Winter',
1146        },
1147    },
1148    sequenceName    => { },
1149    sequenceNumber  => { },
1150    sequenceTotalNumber => { },
1151    setting         => { },
1152    shootID         => { },
1153    slideshowName   => { },
1154    slideshowNumber => { Writable => 'integer' },
1155    slideshowTotalNumber => { Writable => 'integer' },
1156    viewpoint       => { },
1157    visualTechnique => { },
1158);
1159
1160# PRISM Recipe Metadata (prm) (ref 2)
1161%Image::ExifTool::XMP::prm = (
1162    %xmpTableDefaults,
1163    GROUPS => { 0 => 'XMP', 1 => 'XMP-prm', 2 => 'Document' },
1164    NAMESPACE => 'prm',
1165    AVOID => 1,
1166    NOTES => q{
1167        PRISM Recipe Metadata 3.0 namespace tags.  (see
1168        L<http://www.prismstandard.org/>)
1169    },
1170    cookingEquipment    => { },
1171    cookingMethod       => { },
1172    course              => { },
1173    cuisine             => { },
1174    dietaryNeeds        => { },
1175    dishType            => { },
1176    duration            => { },
1177    ingredientExclusion => { },
1178    mainIngredient      => { },
1179    meal                => { },
1180    recipeEndingPage    => { },
1181    recipePageRange     => { },
1182    recipeSource        => { },
1183    recipeStartingPage  => { },
1184    recipeTitle         => { },
1185    servingSize         => { },
1186    skillLevel          => { },
1187    specialOccasion     => { },
1188    yield               => { },
1189);
1190
1191#------------------------------------------------------------------------------
1192
1193# DICOM namespace properties (DICOM) (ref PH, written by CS3)
1194%Image::ExifTool::XMP::DICOM = (
1195    %xmpTableDefaults,
1196    GROUPS => { 1 => 'XMP-DICOM', 2 => 'Image' },
1197    NAMESPACE => 'DICOM',
1198    NOTES => q{
1199        DICOM namespace tags.  These XMP tags allow some DICOM information to be
1200        stored in files of other than DICOM format.  See the
1201        L<DICOM Tags documentation|Image::ExifTool::TagNames/DICOM Tags> for a list
1202        of tags available in DICOM-format files.
1203    },
1204    # change some tag names to correspond with DICOM tags
1205    PatientName             => { },
1206    PatientID               => { },
1207    PatientSex              => { },
1208    PatientDOB => {
1209        Name => 'PatientBirthDate',
1210        Groups => { 2 => 'Time' },
1211        %dateTimeInfo,
1212    },
1213    StudyID                 => { },
1214    StudyPhysician          => { },
1215    StudyDateTime           => { Groups => { 2 => 'Time' }, %dateTimeInfo },
1216    StudyDescription        => { },
1217    SeriesNumber            => { },
1218    SeriesModality          => { },
1219    SeriesDateTime          => { Groups => { 2 => 'Time' }, %dateTimeInfo },
1220    SeriesDescription       => { },
1221    EquipmentInstitution    => { },
1222    EquipmentManufacturer   => { },
1223);
1224
1225# PixelLive namespace properties (PixelLive) (ref 3)
1226%Image::ExifTool::XMP::PixelLive = (
1227    GROUPS => { 1 => 'XMP-PixelLive', 2 => 'Image' },
1228    NAMESPACE => 'PixelLive',
1229    AVOID => 1,
1230    NOTES => q{
1231        PixelLive namespace tags.  These tags are not writable because they are very
1232        uncommon and I haven't been able to locate a reference which gives the
1233        namespace URI.
1234    },
1235    AUTHOR    => { Name => 'Author',    Groups => { 2 => 'Author' } },
1236    COMMENTS  => { Name => 'Comments' },
1237    COPYRIGHT => { Name => 'Copyright', Groups => { 2 => 'Author' } },
1238    DATE      => { Name => 'Date',      Groups => { 2 => 'Time' } },
1239    GENRE     => { Name => 'Genre' },
1240    TITLE     => { Name => 'Title' },
1241);
1242
1243# Extensis Portfolio tags (extensis) (ref 11)
1244%Image::ExifTool::XMP::extensis = (
1245    %xmpTableDefaults,
1246    GROUPS => { 1 => 'XMP-extensis', 2 => 'Image' },
1247    NAMESPACE => 'extensis',
1248    NOTES => 'Tags used by Extensis Portfolio.',
1249    Approved     => { Writable => 'boolean' },
1250    ApprovedBy   => { },
1251    ClientName   => { },
1252    JobName      => { },
1253    JobStatus    => { },
1254    RoutedTo     => { },
1255    RoutingNotes => { },
1256    WorkToDo     => { },
1257);
1258
1259# IDimager structures (ref PH)
1260my %sTagStruct;
1261%sTagStruct = (
1262    STRUCT_NAME => 'TagStructure',
1263    NAMESPACE => 'ics',
1264    LabelName => { },
1265    Reference => { },
1266    ParentReference => { },
1267    SubLabels => { Struct => \%sTagStruct, List => 'Bag' },
1268);
1269my %sSubVersion = (
1270    STRUCT_NAME => 'SubVersion',
1271    NAMESPACE => 'ics',
1272    VersRef => { },
1273    FileName => { },
1274);
1275
1276# IDimager namespace (ics) (ref PH)
1277%Image::ExifTool::XMP::ics = (
1278    %xmpTableDefaults,
1279    GROUPS => { 0 => 'XMP', 1 => 'XMP-ics', 2 => 'Image' },
1280    NAMESPACE => 'ics',
1281    NOTES => q{
1282        Tags used by IDimager.  Nested TagStructure structures are unrolled to an
1283        arbitrary depth of 6 to avoid infinite recursion.
1284    },
1285    ImageRef => { },
1286    TagStructure => { Struct => \%sTagStruct, List => 'Bag' },
1287    TagStructureLabelName => { Name => 'LabelName1', Flat => 1 },
1288    TagStructureReference => { Name => 'Reference1', Flat => 1 },
1289    TagStructureSubLabels => { Name => 'SubLabels1', Flat => 1 },
1290    TagStructureParentReference => { Name => 'ParentReference1', Flat => 1 },
1291    TagStructureSubLabelsLabelName => { Name => 'LabelName2', Flat => 1 },
1292    TagStructureSubLabelsReference => { Name => 'Reference2', Flat => 1 },
1293    TagStructureSubLabelsSubLabels => { Name => 'SubLabels2', Flat => 1 },
1294    TagStructureSubLabelsParentReference => { Name => 'ParentReference2', Flat => 1 },
1295    TagStructureSubLabelsSubLabelsLabelName => { Name => 'LabelName3', Flat => 1 },
1296    TagStructureSubLabelsSubLabelsReference => { Name => 'Reference3', Flat => 1 },
1297    TagStructureSubLabelsSubLabelsSubLabels => { Name => 'SubLabels3', Flat => 1 },
1298    TagStructureSubLabelsSubLabelsParentReference => { Name => 'ParentReference3', Flat => 1 },
1299    TagStructureSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName4', Flat => 1 },
1300    TagStructureSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference4', Flat => 1 },
1301    TagStructureSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels4', Flat => 1 },
1302    TagStructureSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference4', Flat => 1 },
1303    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName5', Flat => 1 },
1304    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference5', Flat => 1 },
1305    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels5', Flat => 1, NoSubStruct => 1 }, # break infinite recursion
1306    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference5', Flat => 1 },
1307    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName6', Flat => 1 },
1308    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference6', Flat => 1 },
1309    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference6', Flat => 1 },
1310    SubVersions => { Struct => \%sSubVersion, List => 'Bag' },
1311    SubVersionsVersRef => { Name => 'SubVersionReference', Flat => 1 },
1312    SubVersionsFileName => { Name => 'SubVersionFileName', Flat => 1 },
1313    TimeStamp  => { Avoid => 1, Groups => { 2 => 'Time' }, %dateTimeInfo },
1314    AppVersion => { Avoid => 1 },
1315);
1316
1317# ACDSee namespace (acdsee) (ref PH)
1318%Image::ExifTool::XMP::acdsee = (
1319    %xmpTableDefaults,
1320    GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee', 2 => 'Image' },
1321    NAMESPACE => 'acdsee',
1322    AVOID => 1,
1323    NOTES => q{
1324        ACD Systems ACDSee namespace tags.
1325
1326        (A note to software developers: Re-inventing your own private tags instead
1327        of using the equivalent tags in standard XMP namespaces defeats one of the
1328        most valuable features of metadata: interoperability.  Your applications
1329        mumble to themselves instead of speaking out for the rest of the world to
1330        hear.)
1331    },
1332    author     => { Groups => { 2 => 'Author' } },
1333    caption    => { },
1334    categories => { },
1335    collections=> { },
1336    datetime   => { Name => 'DateTime', Groups => { 2 => 'Time' }, %dateTimeInfo },
1337    keywords   => { List => 'Bag' },
1338    notes      => { },
1339    rating     => { Writable => 'real' }, # integer?
1340    tagged     => { Writable => 'boolean' },
1341    rawrppused => { Writable => 'boolean' },
1342    rpp => {
1343        Name => 'RPP',
1344        Writable => 'lang-alt',
1345        Notes => 'raw processing settings in XML format',
1346        Binary => 1,
1347    },
1348    dpp => {
1349        Name => 'DPP',
1350        Writable => 'lang-alt',
1351        Notes => 'newer version of XML raw processing settings',
1352        Binary => 1,
1353    },
1354    # more tags (ref forum6840)
1355    FixtureIdentifier   => { },
1356    EditStatus          => { },
1357    ReleaseDate         => { },
1358    ReleaseTime         => { },
1359    OriginatingProgram  => { },
1360    ObjectCycle         => { },
1361    Snapshots           => { List => 'Bag', Binary => 1 },
1362);
1363
1364# Picture Licensing Universal System namespace properties (xmpPLUS)
1365%Image::ExifTool::XMP::xmpPLUS = (
1366    %xmpTableDefaults,
1367    GROUPS => { 1 => 'XMP-xmpPLUS', 2 => 'Author' },
1368    NAMESPACE => 'xmpPLUS',
1369    AVOID => 1,
1370    NOTES => q{
1371        XMP Picture Licensing Universal System (PLUS) tags as written by some older
1372        Adobe applications.  See L<PLUS XMP Tags|Image::ExifTool::TagNames/PLUS XMP Tags>
1373        for the current PLUS tags.
1374    },
1375    CreditLineReq   => { Writable => 'boolean' },
1376    ReuseAllowed    => { Writable => 'boolean' },
1377);
1378
1379# Creative Commons namespace properties (cc) (ref 5)
1380%Image::ExifTool::XMP::cc = (
1381    %xmpTableDefaults,
1382    GROUPS => { 1 => 'XMP-cc', 2 => 'Author' },
1383    NAMESPACE => 'cc',
1384    NOTES => q{
1385        Creative Commons namespace tags.  Note that the CC specification for XMP is
1386        non-existent, so ExifTool must make some assumptions about the format of the
1387        specific properties in XMP (see L<http://creativecommons.org/ns>).
1388    },
1389    # Work properties
1390    license         => { Resource => 1 },
1391    attributionName => { },
1392    attributionURL  => { Resource => 1 },
1393    morePermissions => { Resource => 1 },
1394    useGuidelines   => { Resource => 1 },
1395    # License properties
1396    permits => {
1397        List => 'Bag',
1398        Resource => 1,
1399        PrintConv => {
1400            'cc:Sharing' => 'Sharing',
1401            'cc:DerivativeWorks' => 'Derivative Works',
1402            'cc:Reproduction' => 'Reproduction',
1403            'cc:Distribution' => 'Distribution',
1404        },
1405    },
1406    requires => {
1407        List => 'Bag',
1408        Resource => 1,
1409        PrintConv => {
1410            'cc:Copyleft' => 'Copyleft',
1411            'cc:LesserCopyleft' => 'Lesser Copyleft',
1412            'cc:SourceCode' => 'Source Code',
1413            'cc:ShareAlike' => 'Share Alike',
1414            'cc:Notice' => 'Notice',
1415            'cc:Attribution' => 'Attribution',
1416        },
1417    },
1418    prohibits => {
1419        List => 'Bag',
1420        Resource => 1,
1421        PrintConv => {
1422            'cc:HighIncomeNationUse' => 'High Income Nation Use',
1423            'cc:CommercialUse' => 'Commercial Use',
1424        },
1425    },
1426    jurisdiction    => { Resource => 1 },
1427    legalcode       => { Name => 'LegalCode', Resource => 1 },
1428    deprecatedOn    => { %dateTimeInfo, Groups => { 2 => 'Time' } },
1429);
1430
1431# Description Explorer namespace properties (dex) (ref 6)
1432%Image::ExifTool::XMP::dex = (
1433    %xmpTableDefaults,
1434    GROUPS => { 1 => 'XMP-dex', 2 => 'Image' },
1435    NAMESPACE => 'dex',
1436    NOTES => q{
1437        Description Explorer namespace tags.  These tags are not very common.  The
1438        Source and Rating tags are avoided when writing due to name conflicts with
1439        other XMP tags.  (see L<http://www.optimasc.com/products/fileid/>)
1440    },
1441    crc32       => { Name => 'CRC32', Writable => 'integer' },
1442    source      => { Avoid => 1 },
1443    shortdescription => {
1444        Name => 'ShortDescription',
1445        Writable => 'lang-alt',
1446    },
1447    licensetype => {
1448        Name => 'LicenseType',
1449        PrintConv => {
1450            unknown        => 'Unknown',
1451            shareware      => 'Shareware',
1452            freeware       => 'Freeware',
1453            adware         => 'Adware',
1454            demo           => 'Demo',
1455            commercial     => 'Commercial',
1456           'public domain' => 'Public Domain',
1457           'open source'   => 'Open Source',
1458        },
1459    },
1460    revision    => { },
1461    rating      => { Avoid => 1 },
1462    os          => { Name => 'OS', Writable => 'integer' },
1463    ffid        => { Name => 'FFID' },
1464);
1465
1466# iView MediaPro namespace properties (mediapro) (ref PH)
1467%Image::ExifTool::XMP::MediaPro = (
1468    %xmpTableDefaults,
1469    GROUPS => { 1 => 'XMP-mediapro', 2 => 'Image' },
1470    NAMESPACE => 'mediapro',
1471    NOTES => 'iView MediaPro namespace tags.',
1472    Event       => {
1473        Avoid => 1,
1474        Notes => 'avoided due to conflict with XMP-iptcExt:Event',
1475    },
1476    Location    => {
1477        Avoid => 1,
1478        Groups => { 2 => 'Location' },
1479        Notes => 'avoided due to conflict with XMP-iptcCore:Location',
1480    },
1481    Status      => { },
1482    People      => { List => 'Bag' },
1483    UserFields  => { List => 'Bag' },
1484    CatalogSets => { List => 'Bag' },
1485);
1486
1487# Microsoft ExpressionMedia namespace properties (expressionmedia)
1488# (ref https://exiftool.org/forum/index.php/topic,4235.0.html)
1489%Image::ExifTool::XMP::ExpressionMedia = (
1490    %xmpTableDefaults,
1491    GROUPS => { 1 => 'XMP-expressionmedia', 2 => 'Image' },
1492    NAMESPACE => 'expressionmedia',
1493    AVOID => 1,
1494    NOTES => q{
1495        Microsoft Expression Media namespace tags.  These tags are avoided when
1496        writing due to name conflicts with tags in other schemas.
1497    },
1498    Event       => { },
1499    Status      => { },
1500    People      => { List => 'Bag' },
1501    CatalogSets => { List => 'Bag' },
1502);
1503
1504# DigiKam namespace tags (ref PH)
1505%Image::ExifTool::XMP::digiKam = (
1506    %xmpTableDefaults,
1507    GROUPS => { 1 => 'XMP-digiKam', 2 => 'Image' },
1508    NAMESPACE => 'digiKam',
1509    NOTES => 'DigiKam namespace tags.',
1510    CaptionsAuthorNames    => { Writable => 'lang-alt' },
1511    CaptionsDateTimeStamps => { Writable => 'lang-alt', Groups => { 2 => 'Time' } },
1512    TagsList               => { List => 'Seq' },
1513    ColorLabel             => { },
1514    PickLabel              => { },
1515    ImageHistory           => { Avoid => 1, Notes => 'different format from EXIF:ImageHistory' },
1516    LensCorrectionSettings => { },
1517    ImageUniqueID          => { Avoid => 1 },
1518);
1519
1520# SWF namespace tags (ref PH)
1521%Image::ExifTool::XMP::swf = (
1522    %xmpTableDefaults,
1523    GROUPS => { 1 => 'XMP-swf', 2 => 'Image' },
1524    NAMESPACE => 'swf',
1525    NOTES => 'Adobe SWF namespace tags.',
1526    type         => { Avoid => 1 },
1527    bgalpha      => { Name => 'BackgroundAlpha', Writable => 'integer' },
1528    forwardlock  => { Name => 'ForwardLock',     Writable => 'boolean' },
1529    maxstorage   => { Name => 'MaxStorage',      Writable => 'integer' }, # (CS5)
1530);
1531
1532# Sony Ericsson cell phone location tags
1533# refs: http://www.opencellid.org/api
1534# http://zonetag.research.yahoo.com/faq_location.php
1535# http://www.cs.columbia.edu/sip/drafts/LIF%20TS%20101%20v2.0.0.pdf
1536%Image::ExifTool::XMP::cell = (
1537    %xmpTableDefaults,
1538    GROUPS => { 1 => 'XMP-cell', 2 => 'Location' },
1539    NAMESPACE => 'cell',
1540    NOTES => 'Location tags written by some Sony Ericsson phones.',
1541    mcc     => { Name => 'MobileCountryCode' },
1542    mnc     => { Name => 'MobileNetworkCode' },
1543    lac     => { Name => 'LocationAreaCode' },
1544    cellid  => { Name => 'CellTowerID' },
1545    cgi     => { Name => 'CellGlobalID' },
1546    r       => { Name => 'CellR' }, # (what is this? Radius?)
1547);
1548
1549# Apple adjustment settings (ref PH)
1550%Image::ExifTool::XMP::aas = (
1551    %xmpTableDefaults,
1552    GROUPS => { 1 => 'XMP-aas', 2 => 'Image' },
1553    NAMESPACE => 'aas',
1554    NOTES => 'Apple Adjustment Settings used by iPhone/iPad.',
1555    CropX      => { Writable => 'integer', Avoid => 1 },
1556    CropY      => { Writable => 'integer', Avoid => 1 },
1557    CropW      => { Writable => 'integer', Avoid => 1 },
1558    CropH      => { Writable => 'integer', Avoid => 1 },
1559    AffineA    => { Writable => 'real' },
1560    AffineB    => { Writable => 'real' },
1561    AffineC    => { Writable => 'real' },
1562    AffineD    => { Writable => 'real' },
1563    AffineX    => { Writable => 'real' },
1564    AffineY    => { Writable => 'real' },
1565    Vibrance   => { Writable => 'real', Avoid => 1 },
1566    Curve0x    => { Writable => 'real' },
1567    Curve0y    => { Writable => 'real' },
1568    Curve1x    => { Writable => 'real' },
1569    Curve1y    => { Writable => 'real' },
1570    Curve2x    => { Writable => 'real' },
1571    Curve2y    => { Writable => 'real' },
1572    Curve3x    => { Writable => 'real' },
1573    Curve3y    => { Writable => 'real' },
1574    Curve4x    => { Writable => 'real' },
1575    Curve4y    => { Writable => 'real' },
1576    Shadows    => { Writable => 'real', Avoid => 1 },
1577    Highlights => { Writable => 'real', Avoid => 1 },
1578    # the following from StarGeek
1579    FaceBalanceOrigI    => { Writable => 'real' },
1580    FaceBalanceOrigQ    => { Writable => 'real' },
1581    FaceBalanceStrength => { Writable => 'real' },
1582    FaceBalanceWarmth   => { Writable => 'real' },
1583);
1584
1585# Adobe creatorAtom properties (ref PH)
1586%Image::ExifTool::XMP::creatorAtom = (
1587    %xmpTableDefaults,
1588    GROUPS => { 1 => 'XMP-creatorAtom', 2 => 'Image' },
1589    NAMESPACE => 'creatorAtom',
1590    NOTES => 'Adobe creatorAtom tags, written by After Effects.',
1591    macAtom => {
1592        Struct => {
1593            STRUCT_NAME => 'MacAtom',
1594            NAMESPACE   => 'creatorAtom',
1595            applicationCode      => { },
1596            invocationAppleEvent => { },
1597            posixProjectPath     => { },
1598        },
1599    },
1600    windowsAtom => {
1601        Struct => {
1602            STRUCT_NAME => 'WindowsAtom',
1603            NAMESPACE   => 'creatorAtom',
1604            extension       => { },
1605            invocationFlags => { },
1606            uncProjectPath  => { },
1607        },
1608    },
1609    aeProjectLink => { # (After Effects Project Link)
1610        Struct => {
1611            STRUCT_NAME => 'AEProjectLink',
1612            NAMESPACE   => 'creatorAtom',
1613            renderTimeStamp         => { Writable => 'integer' },
1614            compositionID           => { },
1615            renderQueueItemID       => { },
1616            renderOutputModuleIndex => { },
1617            fullPath                => { },
1618        },
1619    },
1620);
1621
1622# FastPictureViewer namespace properties (http://www.fastpictureviewer.com/help/#rtfcomments)
1623%Image::ExifTool::XMP::fpv = (
1624    %xmpTableDefaults,
1625    GROUPS => { 1 => 'XMP-fpv', 2 => 'Image' },
1626    NAMESPACE => 'fpv',
1627    NOTES => q{
1628        Fast Picture Viewer tags (see
1629        L<http://www.fastpictureviewer.com/help/#rtfcomments>).
1630    },
1631    RichTextComment => { },
1632);
1633
1634# Apple FaceInfo namespace properties (ref PH)
1635%Image::ExifTool::XMP::apple_fi = (
1636    %xmpTableDefaults,
1637    GROUPS => { 1 => 'XMP-apple-fi', 2 => 'Image' },
1638    NAMESPACE => 'apple-fi',
1639    NOTES => q{
1640        Face information tags written by the Apple iPhone 5 inside the mwg-rs
1641        RegionExtensions.
1642    },
1643    Timestamp => {
1644        Name => 'TimeStamp',
1645        Writable => 'integer',
1646        # (don't know how to convert this)
1647    },
1648    FaceID          => { Writable => 'integer' },
1649    AngleInfoRoll   => { Writable => 'integer' },
1650    AngleInfoYaw    => { Writable => 'integer' },
1651    ConfidenceLevel => { Writable => 'integer' },
1652);
1653
1654# Google audio namespace
1655%Image::ExifTool::XMP::GAudio = (
1656    %xmpTableDefaults,
1657    GROUPS => { 1 => 'XMP-GAudio', 2 => 'Audio' },
1658    NAMESPACE => 'GAudio',
1659    Data => {
1660        Name => 'AudioData',
1661        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1662        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1663    },
1664    Mime => { Name => 'AudioMimeType' },
1665);
1666
1667# Google image namespace
1668%Image::ExifTool::XMP::GImage = (
1669    %xmpTableDefaults,
1670    GROUPS => { 1 => 'XMP-GImage', 2 => 'Image' },
1671    NAMESPACE => 'GImage',
1672    Data => {
1673        Name => 'ImageData',
1674        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1675        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1676    },
1677    Mime => { Name => 'ImageMimeType' },
1678);
1679
1680# Google panorama namespace properties
1681# (ref https://exiftool.org/forum/index.php/topic,4569.0.html)
1682%Image::ExifTool::XMP::GPano = (
1683    %xmpTableDefaults,
1684    GROUPS => { 1 => 'XMP-GPano', 2 => 'Image' },
1685    NAMESPACE => 'GPano',
1686    NOTES => q{
1687        Panorama tags written by Google Photosphere. See
1688        L<https://developers.google.com/panorama/metadata/> for the specification.
1689    },
1690    UsePanoramaViewer               => { Writable => 'boolean' },
1691    CaptureSoftware                 => { },
1692    StitchingSoftware               => { },
1693    ProjectionType                  => { },
1694    PoseHeadingDegrees              => { Writable => 'real' },
1695    PosePitchDegrees                => { Writable => 'real' },
1696    PoseRollDegrees                 => { Writable => 'real' },
1697    InitialViewHeadingDegrees       => { Writable => 'real' },
1698    InitialViewPitchDegrees         => { Writable => 'real' },
1699    InitialViewRollDegrees          => { Writable => 'real' },
1700    InitialHorizontalFOVDegrees     => { Writable => 'real' },
1701    InitialVerticalFOVDegrees       => { Writable => 'real' },
1702    FirstPhotoDate                  => { %dateTimeInfo, Groups => { 2 => 'Time' } },
1703    LastPhotoDate                   => { %dateTimeInfo, Groups => { 2 => 'Time' } },
1704    SourcePhotosCount               => { Writable => 'integer' },
1705    ExposureLockUsed                => { Writable => 'boolean' },
1706    CroppedAreaImageWidthPixels     => { Writable => 'real' },
1707    CroppedAreaImageHeightPixels    => { Writable => 'real' },
1708    FullPanoWidthPixels             => { Writable => 'real' },
1709    FullPanoHeightPixels            => { Writable => 'real' },
1710    CroppedAreaLeftPixels           => { Writable => 'real' },
1711    CroppedAreaTopPixels            => { Writable => 'real' },
1712    InitialCameraDolly              => { Writable => 'real' },
1713    # (the following have been observed, but are not in the specification)
1714    LargestValidInteriorRectLeft    => { Writable => 'real' },
1715    LargestValidInteriorRectTop     => { Writable => 'real' },
1716    LargestValidInteriorRectWidth   => { Writable => 'real' },
1717    LargestValidInteriorRectHeight  => { Writable => 'real' },
1718);
1719
1720# Google Spherical Images namespace (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md)
1721%Image::ExifTool::XMP::GSpherical = (
1722    %xmpTableDefaults,
1723    GROUPS => { 1 => 'XMP-GSpherical', 2 => 'Image' },
1724    WRITE_GROUP => 'GSpherical', # write in special location for video files
1725    NAMESPACE => 'GSpherical',
1726    AVOID => 1,
1727    NOTES => q{
1728        Not actually XMP.  These RDF/XML tags are used in Google spherical MP4
1729        videos.  These tags are written into the video track of MOV/MP4 files, and
1730        not at the top level like other XMP tags.  See
1731        L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md>
1732        for the specification.
1733    },
1734    # (avoid due to conflicts with XMP-GPano tags)
1735    Spherical                   => { Writable => 'boolean' },
1736    Stitched                    => { Writable => 'boolean' },
1737    StitchingSoftware           => { },
1738    ProjectionType              => { },
1739    StereoMode                  => { },
1740    SourceCount                 => { Writable => 'integer' },
1741    InitialViewHeadingDegrees   => { Writable => 'real' },
1742    InitialViewPitchDegrees     => { Writable => 'real' },
1743    InitialViewRollDegrees      => { Writable => 'real' },
1744    Timestamp                   => {
1745        Name => 'TimeStamp',
1746        Groups => { 2 => 'Time' },
1747        Writable => 'integer',
1748        Shift => 'Time',
1749        ValueConv => 'ConvertUnixTime($val)', #(NC)
1750        ValueConvInv => 'GetUnixTime($val)',
1751        PrintConv => '$self->ConvertDateTime($val)',
1752        PrintConvInv => '$self->InverseDateTime($val)',
1753    },
1754    FullPanoWidthPixels         => { Writable => 'integer' },
1755    FullPanoHeightPixels        => { Writable => 'integer' },
1756    CroppedAreaImageWidthPixels => { Writable => 'integer' },
1757    CroppedAreaImageHeightPixels=> { Writable => 'integer' },
1758    CroppedAreaLeftPixels       => { Writable => 'integer' },
1759    CroppedAreaTopPixels        => { Writable => 'integer' },
1760);
1761
1762# Google depthmap information (ref https://developers.google.com/depthmap-metadata/reference)
1763%Image::ExifTool::XMP::GDepth = (
1764    GROUPS      => { 0 => 'XMP', 1 => 'XMP-GDepth', 2 => 'Image' },
1765    NAMESPACE   => 'GDepth',
1766    AVOID       => 1, # (too many potential tag name conflicts)
1767    NOTES       => q{
1768        Google depthmap information. See
1769        L<https://developers.google.com/depthmap-metadata/> for the specification.
1770    },
1771    WRITABLE    => 'string', # (default to string-type tags)
1772    PRIORITY    => 0,
1773    Format => {
1774        PrintConv => {
1775            RangeInverse => 'RangeInverse',
1776            RangeLinear  => 'RangeLinear',
1777        },
1778    },
1779    Near        => { Writable => 'real' },
1780    Far         => { Writable => 'real' },
1781    Mime        => { },
1782    Data => {
1783        Name => 'DepthImage',
1784        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1785        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1786    },
1787    Units       => { },
1788    MeasureType => {
1789        PrintConv => {
1790            OpticalAxis => 'OpticalAxis',
1791            OpticalRay  => 'OpticalRay',
1792        },
1793    },
1794    ConfidenceMime  => { },
1795    Confidence => {
1796        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1797        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1798    },
1799    Manufacturer=> { },
1800    Model       => { },
1801    Software    => { },
1802    ImageWidth  => { Writable => 'real' },
1803    ImageHeight => { Writable => 'real' },
1804);
1805
1806# Google focus namespace
1807%Image::ExifTool::XMP::GFocus = (
1808    %xmpTableDefaults,
1809    GROUPS => { 1 => 'XMP-GFocus', 2 => 'Image' },
1810    NAMESPACE => 'GFocus',
1811    NOTES => 'Focus information found in Google depthmap images.',
1812    BlurAtInfinity  => { Writable => 'real' },
1813    FocalDistance   => { Writable => 'real' },
1814    FocalPointX     => { Writable => 'real' },
1815    FocalPointY     => { Writable => 'real' },
1816);
1817
1818# Google camera namespace (ref PH)
1819%Image::ExifTool::XMP::GCamera = (
1820    %xmpTableDefaults,
1821    GROUPS => { 1 => 'XMP-GCamera', 2 => 'Camera' },
1822    NAMESPACE => 'GCamera',
1823    NOTES => 'Camera information found in Google panorama images.',
1824    BurstID         => { },
1825    BurstPrimary    => { },
1826    PortraitNote    => { },
1827    PortraitRequest => {
1828        Notes => 'High Definition Render Pipeline (HDRP) data', #PH (guess)
1829        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1830        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1831    },
1832    PortraitVersion => { },
1833    SpecialTypeID   => { List => 'Bag' },
1834    PortraitNote    => { },
1835    DisableAutoCreation => { List => 'Bag' },
1836    hdrp_makernote => {
1837        Name => 'HDRPMakerNote',
1838        # decoded data starts with the following bytes, but nothing yet is known about its contents:
1839        # 48 44 52 50 02 ef 64 35 6d 5e 70 1e 2c ea e3 4c [HDRP..d5m^p.,..L]
1840        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1841        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1842    },
1843    MicroVideo          => { Writable => 'integer' },
1844    MicroVideoVersion   => { Writable => 'integer' },
1845    MicroVideoOffset    => { Writable => 'integer' },
1846    MicroVideoPresentationTimestampUs => { Writable => 'integer' },
1847);
1848
1849# Google creations namespace (ref PH)
1850%Image::ExifTool::XMP::GCreations = (
1851    %xmpTableDefaults,
1852    GROUPS => { 1 => 'XMP-GCreations', 2 => 'Camera' },
1853    NAMESPACE => 'GCreations',
1854    NOTES => 'Google creations tags.',
1855    CameraBurstID  => { },
1856);
1857
1858# Google depth-map Device namespace (ref 13)
1859%Image::ExifTool::XMP::Device = (
1860    %xmpTableDefaults,
1861    GROUPS => { 1 => 'XMP-Device', 2 => 'Camera' },
1862    NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1863    NOTES => q{
1864        Google depth-map Device tags.  See
1865        L<https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf> for
1866        the specification.
1867    },
1868    Container => {
1869        Struct => {
1870            STRUCT_NAME => 'DeviceContainer',
1871            NAMESPACE   => { Container => 'http://ns.google.com/photos/dd/1.0/container/' },
1872            Directory => {
1873                List => 'Seq',
1874                Struct => {
1875                    STRUCT_NAME => 'DeviceDirectory',
1876                    NAMESPACE   => { Container => 'http://ns.google.com/photos/dd/1.0/container/' },
1877                    Item => {
1878                        Struct => {
1879                            STRUCT_NAME => 'DeviceItem',
1880                            NAMESPACE => { Item => 'http://ns.google.com/photos/dd/1.0/item/' },
1881                            Mime    => { },
1882                            Length  => { Writable => 'integer' },
1883                            Padding => { Writable => 'integer' },
1884                            DataURI => { },
1885                        },
1886                    },
1887                },
1888            }
1889        },
1890    },
1891    Profiles => {
1892        List => 'Seq',
1893        FlatName => '',
1894        Struct => {
1895            STRUCT_NAME => 'DeviceProfiles',
1896            NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1897            Profile => {
1898                Struct => {
1899                    STRUCT_NAME => 'DeviceProfile',
1900                    NAMESPACE => { Profile => 'http://ns.google.com/photos/dd/1.0/profile/' },
1901                    CameraIndices => { List => 'Seq', Writable => 'integer' },
1902                    Type => { },
1903                },
1904            },
1905        },
1906    },
1907    Cameras => {
1908        List => 'Seq',
1909        FlatName => '',
1910        Struct => {
1911            STRUCT_NAME => 'DeviceCameras',
1912            NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1913            Camera => {
1914                Struct => {
1915                    STRUCT_NAME => 'DeviceCamera',
1916                    NAMESPACE => { Camera => 'http://ns.google.com/photos/dd/1.0/camera/' },
1917                    DepthMap => {
1918                        Struct => {
1919                            STRUCT_NAME => 'DeviceDepthMap',
1920                            NAMESPACE => { DepthMap => 'http://ns.google.com/photos/dd/1.0/depthmap/' },
1921                            ConfidenceURI => { },
1922                            DepthURI    => { },
1923                            Far         => { Writable => 'real' },
1924                            Format      => { },
1925                            ItemSemantic=> { },
1926                            MeasureType => { },
1927                            Near        => { Writable => 'real' },
1928                            Units       => { },
1929                            Software    => { },
1930                            FocalTableEntryCount => { Writable => 'integer' },
1931                            FocalTable  => { }, # (base64)
1932                        },
1933                    },
1934                    Image => {
1935                        Struct => {
1936                            STRUCT_NAME => 'DeviceImage',
1937                            NAMESPACE => { Image => 'http://ns.google.com/photos/dd/1.0/image/' },
1938                            ItemSemantic=> { },
1939                            ItemURI     => { },
1940                        },
1941                    },
1942                    ImagingModel => {
1943                        Struct => {
1944                            STRUCT_NAME => 'DeviceImagingModel',
1945                            NAMESPACE => { ImagingModel => 'http://ns.google.com/photos/dd/1.0/imagingmodel/' },
1946                            Distortion      => { }, # (base64)
1947                            DistortionCount => { Writable => 'integer' },
1948                            FocalLengthX    => { Writable => 'real' },
1949                            FocalLengthY    => { Writable => 'real' },
1950                            ImageHeight     => { Writable => 'integer' },
1951                            ImageWidth      => { Writable => 'integer' },
1952                            PixelAspectRatio=> { Writable => 'real' },
1953                            PrincipalPointX => { Writable => 'real' },
1954                            PrincipalPointY => { Writable => 'real' },
1955                            Skew            => { Writable => 'real' },
1956                        },
1957                    },
1958                    PointCloud => {
1959                        Struct => {
1960                            STRUCT_NAME => 'DevicePointCloud',
1961                            NAMESPACE => { PointCloud => 'http://ns.google.com/photos/dd/1.0/pointcloud/' },
1962                            PointCloud  => { Writable => 'integer' },
1963                            Points      => { },
1964                            Metric      => { Writable => 'boolean' },
1965                        },
1966                    },
1967                    Pose => { Struct => \%sPose },
1968                    LightEstimate => {
1969                        Struct => {
1970                            STRUCT_NAME => 'DeviceLightEstimate',
1971                            NAMESPACE => { LightEstimate => 'http://ns.google.com/photos/dd/1.0/lightestimate/' },
1972                            ColorCorrectionR => { Writable => 'real' },
1973                            ColorCorrectionG => { Writable => 'real' },
1974                            ColorCorrectionB => { Writable => 'real' },
1975                            PixelIntensity   => { Writable => 'real' },
1976                        },
1977                    },
1978                    VendorInfo => { Struct => \%sVendorInfo },
1979                    AppInfo    => { Struct => \%sAppInfo },
1980                    Trait => { },
1981                },
1982            },
1983        },
1984    },
1985    VendorInfo  => { Struct => \%sVendorInfo },
1986    AppInfo     => { Struct => \%sAppInfo },
1987    EarthPos    => { Struct => \%sEarthPose },
1988    Pose        => { Struct => \%sPose },
1989    Planes => {
1990        List => 'Seq',
1991        FlatName => '',
1992        Struct => {
1993            STRUCT_NAME => 'DevicePlanes',
1994            NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1995            Plane => {
1996                Struct => {
1997                    STRUCT_NAME => 'DevicePlane',
1998                    NAMESPACE => { Plane => 'http://ns.google.com/photos/dd/1.0/plane/' },
1999                    Pose    => { Struct => \%sPose },
2000                    ExtentX => { Writable => 'real' },
2001                    ExtentZ => { Writable => 'real' },
2002                    BoundaryVertexCount => { Writable => 'integer' },
2003                    Boundary => { },
2004                },
2005            },
2006        },
2007    },
2008);
2009
2010# Getty Images namespace (ref PH)
2011%Image::ExifTool::XMP::GettyImages = (
2012    %xmpTableDefaults,
2013    GROUPS => { 1 => 'XMP-getty', 2 => 'Image' },
2014    NAMESPACE => 'GettyImagesGIFT',
2015    NOTES => q{
2016        The actual Getty Images namespace prefix is "GettyImagesGIFT", which is the
2017        prefix recorded in the file, but ExifTool shortens this for the family 1
2018        group name.
2019    },
2020    Personality         => { List => 'Bag' },
2021    OriginalFilename    => { Name => 'OriginalFileName' },
2022    ParentMEID          => { },
2023    # the following from StarGeek
2024    AssetID             => { },
2025    CallForImage        => { },
2026    CameraFilename      => { },
2027    CameraMakeModel     => { Avoid => 1 },
2028    Composition         => { },
2029    CameraSerialNumber  => { Avoid => 1 },
2030    ExclusiveCoverage   => { },
2031    GIFTFtpPriority     => { },
2032    ImageRank           => { },
2033    MediaEventIdDate    => { },
2034    OriginalCreateDateTime => { %dateTimeInfo, Groups => { 2 => 'Time' }, Avoid => 1 },
2035    ParentMediaEventID  => { },
2036    PrimaryFTP          => { List => 'Bag' },
2037    RoutingDestinations => { List => 'Bag' },
2038    RoutingExclusions   => { List => 'Bag' },
2039    SecondaryFTP        => { List => 'Bag' },
2040    TimeShot            => { },
2041);
2042
2043# RED smartphone images (ref PH)
2044%Image::ExifTool::XMP::LImage = (
2045    %xmpTableDefaults,
2046    GROUPS => { 1 => 'XMP-LImage', 2 => 'Image' },
2047    NAMESPACE => 'LImage',
2048    NOTES => 'Tags written by RED smartphones.',
2049    MajorVersion => { },
2050    MinorVersion => { },
2051    RightAlbedo => {
2052        Notes => 'Right stereoscopic image',
2053        Groups => { 2 => 'Preview' },
2054        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
2055        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
2056    },
2057);
2058
2059# SVG namespace properties (ref 9)
2060%Image::ExifTool::XMP::SVG = (
2061    GROUPS => { 0 => 'SVG', 1 => 'SVG', 2 => 'Image' },
2062    NAMESPACE => 'svg',
2063    LANG_INFO => \&GetLangInfo,
2064    NOTES => q{
2065        SVG (Scalable Vector Graphics) image tags.  By default, only the top-level
2066        SVG and Metadata tags are extracted from these images, but all graphics tags
2067        may be extracted by setting the Unknown option to 2 (-U on the command
2068        line).  The SVG tags are not part of XMP as such, but are included with the
2069        XMP module for convenience.  (see L<http://www.w3.org/TR/SVG11/>)
2070    },
2071    version    => 'SVGVersion',
2072    id         => 'ID',
2073    metadataId => 'MetadataID',
2074    width      => {
2075        Name => 'ImageWidth',
2076        ValueConv => '$val =~ s/px$//; $val',
2077    },
2078    height     => {
2079        Name => 'ImageHeight',
2080        ValueConv => '$val =~ s/px$//; $val',
2081    },
2082);
2083
2084# table to add tags in other namespaces
2085%Image::ExifTool::XMP::otherSVG = (
2086    GROUPS => { 0 => 'SVG', 2 => 'Unknown' },
2087    LANG_INFO => \&GetLangInfo,
2088    NAMESPACE => undef, # variable namespace
2089);
2090
2091#------------------------------------------------------------------------------
2092# Generate crd tags
2093# Inputs: 0) tag table ref
2094sub Init_crd($)
2095{
2096    my $tagTablePtr = shift;
2097    # import tags from CRS namespace
2098    my $crsTable = GetTagTable('Image::ExifTool::XMP::crs');
2099    my $tag;
2100    foreach $tag (Image::ExifTool::TagTableKeys($crsTable)) {
2101        my $crsInfo = $$crsTable{$tag};
2102        my $tagInfo = $$tagTablePtr{$tag} = { %$crsInfo };
2103        $$tagInfo{Groups} = { 0 => 'XMP', 1 => 'XMP-crd' , 2 => $$crsInfo{Groups}{2} } if $$crsInfo{Groups};
2104    }
2105}
2106
2107
21081;  #end
2109
2110__END__
2111
2112=head1 NAME
2113
2114Image::ExifTool::XMP2.pl - Additional XMP namespace definitions
2115
2116=head1 SYNOPSIS
2117
2118This module is loaded automatically by Image::ExifTool when required.
2119
2120=head1 DESCRIPTION
2121
2122This file contains definitions for less common XMP namespaces.
2123
2124=head1 AUTHOR
2125
2126Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
2127
2128This library is free software; you can redistribute it and/or modify it
2129under the same terms as Perl itself.
2130
2131=head1 REFERENCES
2132
2133=over 4
2134
2135=item L<http://ns.useplus.org/>
2136
2137=item L<http://www.prismstandard.org/>
2138
2139=item L<http://www.portfoliofaq.com/pfaq/v7mappings.htm>
2140
2141=item L<http://www.iptc.org/IPTC4XMP/>
2142
2143=item L<http://creativecommons.org/technology/xmp>
2144
2145=item L<http://www.optimasc.com/products/fileid/xmp-extensions.pdf>
2146
2147=item L<http://www.w3.org/TR/SVG11/>
2148
2149=back
2150
2151=head1 SEE ALSO
2152
2153L<Image::ExifTool::TagNames/XMP Tags>,
2154L<Image::ExifTool(3pm)|Image::ExifTool>
2155
2156=cut
2157