File Coverage

blib/lib/Image/ExifTool/XMP2.pl
Criterion Covered Total %
statement 16 16 100.0
branch 1 2 50.0
condition n/a
subroutine 4 4 100.0
pod 0 1 0.0
total 21 23 91.3


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