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   190 use strict;
  28         57  
  28         987  
25 28     28   144 use Image::ExifTool qw(:Utils);
  28         75  
  28         3176  
26 28     28   173 use Image::ExifTool::XMP;
  28         59  
  28         121614  
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.6.
542             The actual namespace prefix is "Iptc4xmpExt", but ExifTool shortens this for
543             the family 1 group name. (see
544             L)
545             },
546             AboutCvTerm => {
547             Struct => \%sCVTermDetails,
548             List => 'Bag',
549             },
550             AboutCvTermCvId => { Flat => 1, Name => 'AboutCvTermCvId' },
551             AboutCvTermCvTermId => { Flat => 1, Name => 'AboutCvTermId' },
552             AboutCvTermCvTermName => { Flat => 1, Name => 'AboutCvTermName' },
553             AboutCvTermCvTermRefinedAbout => { Flat => 1, Name => 'AboutCvTermRefinedAbout' },
554             AddlModelInfo => { Name => 'AdditionalModelInformation' },
555             ArtworkOrObject => {
556             Struct => {
557             STRUCT_NAME => 'ArtworkOrObjectDetails',
558             NAMESPACE => 'Iptc4xmpExt',
559             AOCopyrightNotice => { },
560             AOCreator => { List => 'Seq' },
561             AODateCreated=> { Groups => { 2 => 'Time' }, %dateTimeInfo },
562             AOSource => { },
563             AOSourceInvNo=> { },
564             AOTitle => { Writable => 'lang-alt' },
565             AOCurrentCopyrightOwnerName => { },
566             AOCurrentCopyrightOwnerId => { },
567             AOCurrentLicensorName => { },
568             AOCurrentLicensorId => { },
569             AOCreatorId => { List => 'Seq' },
570             AOCircaDateCreated => { Groups => { 2 => 'Time' }, Protected => 1 },
571             AOStylePeriod => { List => 'Bag' },
572             AOSourceInvURL => { },
573             AOContentDescription => { Writable => 'lang-alt' },
574             AOContributionDescription => { Writable => 'lang-alt' },
575             AOPhysicalDescription => { Writable => 'lang-alt' },
576             },
577             List => 'Bag',
578             },
579             ArtworkOrObjectAOCopyrightNotice => { Flat => 1, Name => 'ArtworkCopyrightNotice' },
580             ArtworkOrObjectAOCreator => { Flat => 1, Name => 'ArtworkCreator' },
581             ArtworkOrObjectAODateCreated => { Flat => 1, Name => 'ArtworkDateCreated' },
582             ArtworkOrObjectAOSource => { Flat => 1, Name => 'ArtworkSource' },
583             ArtworkOrObjectAOSourceInvNo => { Flat => 1, Name => 'ArtworkSourceInventoryNo' },
584             ArtworkOrObjectAOTitle => { Flat => 1, Name => 'ArtworkTitle' },
585             ArtworkOrObjectAOCurrentCopyrightOwnerName => { Flat => 1, Name => 'ArtworkCopyrightOwnerName' },
586             ArtworkOrObjectAOCurrentCopyrightOwnerId => { Flat => 1, Name => 'ArtworkCopyrightOwnerID' },
587             ArtworkOrObjectAOCurrentLicensorName => { Flat => 1, Name => 'ArtworkLicensorName' },
588             ArtworkOrObjectAOCurrentLicensorId => { Flat => 1, Name => 'ArtworkLicensorID' },
589             ArtworkOrObjectAOCreatorId => { Flat => 1, Name => 'ArtworkCreatorID' },
590             ArtworkOrObjectAOCircaDateCreated => { Flat => 1, Name => 'ArtworkCircaDateCreated' },
591             ArtworkOrObjectAOStylePeriod => { Flat => 1, Name => 'ArtworkStylePeriod' },
592             ArtworkOrObjectAOSourceInvURL => { Flat => 1, Name => 'ArtworkSourceInvURL' },
593             ArtworkOrObjectAOContentDescription => { Flat => 1, Name => 'ArtworkContentDescription' },
594             ArtworkOrObjectAOContributionDescription => { Flat => 1, Name => 'ArtworkContributionDescription' },
595             ArtworkOrObjectAOPhysicalDescription => { Flat => 1, Name => 'ArtworkPhysicalDescription' },
596             CVterm => {
597             Name => 'ControlledVocabularyTerm',
598             List => 'Bag',
599             Notes => 'deprecated by version 1.2',
600             },
601             DigImageGUID => { Groups => { 2 => 'Image' }, Name => 'DigitalImageGUID' },
602             DigitalSourcefileType => {
603             Name => 'DigitalSourceFileType',
604             Notes => 'now deprecated -- replaced by DigitalSourceType',
605             Groups => { 2 => 'Image' },
606             },
607             DigitalSourceType => { Name => 'DigitalSourceType', Groups => { 2 => 'Image' } },
608             EmbdEncRightsExpr => {
609             Struct => {
610             STRUCT_NAME => 'EEREDetails',
611             NAMESPACE => 'Iptc4xmpExt',
612             EncRightsExpr => { },
613             RightsExprEncType => { },
614             RightsExprLangId => { },
615             },
616             List => 'Bag',
617             },
618             EmbdEncRightsExprEncRightsExpr => { Flat => 1, Name => 'EmbeddedEncodedRightsExpr' },
619             EmbdEncRightsExprRightsExprEncType => { Flat => 1, Name => 'EmbeddedEncodedRightsExprType' },
620             EmbdEncRightsExprRightsExprLangId => { Flat => 1, Name => 'EmbeddedEncodedRightsExprLangID' },
621             Event => { Writable => 'lang-alt' },
622             IptcLastEdited => {
623             Name => 'IPTCLastEdited',
624             Groups => { 2 => 'Time' },
625             %dateTimeInfo,
626             },
627             LinkedEncRightsExpr => {
628             Struct => {
629             STRUCT_NAME => 'LEREDetails',
630             NAMESPACE => 'Iptc4xmpExt',
631             LinkedRightsExpr => { },
632             RightsExprEncType => { },
633             RightsExprLangId => { },
634             },
635             List => 'Bag',
636             },
637             LinkedEncRightsExprLinkedRightsExpr => { Flat => 1, Name => 'LinkedEncodedRightsExpr' },
638             LinkedEncRightsExprRightsExprEncType => { Flat => 1, Name => 'LinkedEncodedRightsExprType' },
639             LinkedEncRightsExprRightsExprLangId => { Flat => 1, Name => 'LinkedEncodedRightsExprLangID' },
640             LocationCreated => {
641             Struct => \%sLocationDetails,
642             Groups => { 2 => 'Location' },
643             List => 'Bag',
644             },
645             LocationShown => {
646             Struct => \%sLocationDetails,
647             Groups => { 2 => 'Location' },
648             List => 'Bag',
649             },
650             MaxAvailHeight => { Groups => { 2 => 'Image' }, Writable => 'integer' },
651             MaxAvailWidth => { Groups => { 2 => 'Image' }, Writable => 'integer' },
652             ModelAge => { List => 'Bag', Writable => 'integer' },
653             OrganisationInImageCode => { List => 'Bag' },
654             OrganisationInImageName => { List => 'Bag' },
655             PersonInImage => { List => 'Bag' },
656             PersonInImageWDetails => {
657             Struct => {
658             STRUCT_NAME => 'PersonDetails',
659             NAMESPACE => 'Iptc4xmpExt',
660             PersonId => { List => 'Bag' },
661             PersonName => { Writable => 'lang-alt' },
662             PersonCharacteristic => {
663             Struct => \%sCVTermDetails,
664             List => 'Bag',
665             },
666             PersonDescription => { Writable => 'lang-alt' },
667             },
668             List => 'Bag',
669             },
670             PersonInImageWDetailsPersonId => { Flat => 1, Name => 'PersonInImageId' },
671             PersonInImageWDetailsPersonName => { Flat => 1, Name => 'PersonInImageName' },
672             PersonInImageWDetailsPersonCharacteristic => { Flat => 1, Name => 'PersonInImageCharacteristic' },
673             PersonInImageWDetailsPersonCharacteristicCvId => { Flat => 1, Name => 'PersonInImageCvTermCvId' },
674             PersonInImageWDetailsPersonCharacteristicCvTermId => { Flat => 1, Name => 'PersonInImageCvTermId' },
675             PersonInImageWDetailsPersonCharacteristicCvTermName => { Flat => 1, Name => 'PersonInImageCvTermName' },
676             PersonInImageWDetailsPersonCharacteristicCvTermRefinedAbout => { Flat => 1, Name => 'PersonInImageCvTermRefinedAbout' },
677             PersonInImageWDetailsPersonDescription => { Flat => 1, Name => 'PersonInImageDescription' },
678             ProductInImage => {
679             Struct => {
680             STRUCT_NAME => 'ProductDetails',
681             NAMESPACE => 'Iptc4xmpExt',
682             ProductName => { Writable => 'lang-alt' },
683             ProductGTIN => { },
684             ProductDescription => { Writable => 'lang-alt' },
685             },
686             List => 'Bag',
687             },
688             ProductInImageProductName => { Flat => 1, Name => 'ProductInImageName' },
689             ProductInImageProductGTIN => { Flat => 1, Name => 'ProductInImageGTIN' },
690             ProductInImageProductDescription => { Flat => 1, Name => 'ProductInImageDescription' },
691             RegistryId => {
692             Name => 'RegistryID',
693             Struct => {
694             STRUCT_NAME => 'RegistryEntryDetails',
695             NAMESPACE => 'Iptc4xmpExt',
696             RegItemId => { },
697             RegOrgId => { },
698             RegEntryRole=> { }, # (new in 1.3)
699             },
700             List => 'Bag',
701             },
702             RegistryIdRegItemId => { Flat => 1, Name => 'RegistryItemID' },
703             RegistryIdRegOrgId => { Flat => 1, Name => 'RegistryOrganisationID' },
704             RegistryIdRegEntryRole => { Flat => 1, Name => 'RegistryEntryRole' },
705              
706             # new Extension 1.3 properties
707             Genre => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sCVTermDetails },
708              
709             # new video properties (Oct 2016, ref Michael Steidl)
710             # (see http://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.0.html)
711             CircaDateCreated=> { Groups => { 2 => 'Time' } },
712             Episode => { Groups => { 2 => 'Video' }, Struct => \%sEpisode },
713             ExternalMetadataLink => { Groups => { 2 => 'Other' }, List => 'Bag' },
714             FeedIdentifier => { Groups => { 2 => 'Video' } },
715             PublicationEvent=> { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sPublicationEvent },
716             Rating => {
717             Groups => { 2 => 'Other' },
718             Struct => \%sRating,
719             List => 'Bag',
720             },
721             ReleaseReady => { Groups => { 2 => 'Other' }, Writable => 'boolean' },
722             Season => { Groups => { 2 => 'Video' }, Struct => \%sEpisode },
723             Series => { Groups => { 2 => 'Video' }, Struct => \%sSeries },
724             StorylineIdentifier => { Groups => { 2 => 'Video' }, List => 'Bag' },
725             StylePeriod => { Groups => { 2 => 'Video' } },
726             TemporalCoverage=> { Groups => { 2 => 'Video' }, Struct => \%sTemporalCoverage },
727             WorkflowTag => { Groups => { 2 => 'Video' }, Struct => \%sCVTermDetails },
728             DataOnScreen => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sTextRegion },
729             Dopesheet => { Groups => { 2 => 'Video' }, Writable => 'lang-alt' },
730             DopesheetLink => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sQualifiedLink },
731             Headline => { Groups => { 2 => 'Video' }, Writable => 'lang-alt', Avoid => 1 },
732             PersonHeard => { Groups => { 2 => 'Audio' }, List => 'Bag', Struct => \%sEntity },
733             VideoShotType => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sEntity },
734             EventExt => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sEntity, Name => 'ShownEvent' },
735             Transcript => { Groups => { 2 => 'Video' }, Writable => 'lang-alt' },
736             TranscriptLink => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sQualifiedLink },
737             VisualColour => {
738             Name => 'VisualColor',
739             Groups => { 2 => 'Video' },
740             PrintConv => {
741             'bw-monochrome' => 'Monochrome',
742             'colour' => 'Color',
743             },
744             },
745             Contributor => { List => 'Bag', Struct => \%sEntityWithRole },
746             CopyrightYear => { Groups => { 2 => 'Time' }, Writable => 'integer' },
747             Creator => { List => 'Bag', Struct => \%sEntityWithRole },
748             SupplyChainSource => { Groups => { 2 => 'Other' }, List => 'Bag', Struct => \%sEntity },
749             audioBitRate => { Groups => { 2 => 'Audio' }, Writable => 'integer', Name => 'AudioBitrate' },
750             audioBitRateMode=> {
751             Name => 'AudioBitrateMode',
752             Groups => { 2 => 'Audio' },
753             PrintConv => {
754             fixed => 'Fixed',
755             variable => 'Variable',
756             },
757             },
758             audioChannelCount => { Groups => { 2 => 'Audio' }, Writable => 'integer' },
759             videoDisplayAspectRatio => { Groups => { 2 => 'Audio' }, Writable => 'rational' },
760             ContainerFormat => { Groups => { 2 => 'Video' }, Struct => \%sEntity },
761             StreamReady => {
762             Groups => { 2 => 'Video' },
763             PrintConv => {
764             true => 'True',
765             false => 'False',
766             unknown => 'Unknown',
767             },
768             },
769             videoBitRate => { Groups => { 2 => 'Video' }, Writable => 'integer', Name => 'VideoBitrate' },
770             videoBitRateMode => {
771             Name => 'VideoBitrateMode',
772             Groups => { 2 => 'Video' },
773             PrintConv => {
774             fixed => 'Fixed',
775             variable => 'Variable',
776             },
777             },
778             videoEncodingProfile => { Groups => { 2 => 'Video' } },
779             videoStreamsCount => { Groups => { 2 => 'Video' }, Writable => 'integer' },
780             # new IPTC video metadata 1.1 properties
781             # (ref https://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.1.html)
782             SnapshotLink => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sLinkedImage, Name => 'Snapshot' },
783             # new IPTC video metadata 1.2 properties
784             # (ref http://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.2.html)
785             RecDevice => {
786             Groups => { 2 => 'Device' },
787             Struct => {
788             STRUCT_NAME => 'Device',
789             NAMESPACE => 'Iptc4xmpExt',
790             Manufacturer => { },
791             ModelName => { },
792             SerialNumber => { },
793             AttLensDescription => { },
794             OwnersDeviceId => { },
795             },
796             },
797             PlanningRef => { List => 'Bag', Struct => \%sEntityWithRole },
798             audioBitsPerSample => { Groups => { 2 => 'Audio' }, Writable => 'integer' },
799             # new IPTC Extension schema 1.5 property
800             ImageRegion => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sImageRegion },
801             # new Extension 1.6 property
802             EventId => { Name => 'EventID', List => 'Bag' },
803             );
804              
805             #------------------------------------------------------------------------------
806             # PRISM
807             #
808             # NOTE: The "Avoid" flag is set for all PRISM tags (via tag table AVOID flag)
809              
810             # my %obsolete = (
811             # Notes => 'obsolete in 2.0',
812             # ValueConvInv => sub {
813             # my ($val, $self) = @_;
814             # unless ($self->Options('IgnoreMinorErrors')) {
815             # warn "Warning: [minor] Attempt to write obsolete tag\n";
816             # return undef;
817             # }
818             # return $val;
819             # }
820             # );
821              
822             # PRISM structure definitions
823             my %prismPublicationDate = (
824             STRUCT_NAME => 'prismPublicationDate',
825             NAMESPACE => 'prism',
826             date => { %dateTimeInfo, Groups => { 2 => 'Time'} },
827             'a-platform'=> { },
828             );
829              
830             # Publishing Requirements for Industry Standard Metadata (prism) (ref 2)
831             %Image::ExifTool::XMP::prism = (
832             %xmpTableDefaults,
833             GROUPS => { 0 => 'XMP', 1 => 'XMP-prism', 2 => 'Document' },
834             NAMESPACE => 'prism',
835             AVOID => 1,
836             NOTES => q{
837             Publishing Requirements for Industry Standard Metadata 3.0 namespace
838             tags. (see L)
839             },
840             academicField => { }, # (3.0)
841             aggregateIssueNumber => { Writable => 'integer' }, # (3.0)
842             aggregationType => { List => 'Bag' },
843             alternateTitle => {
844             List => 'Bag',
845             Struct => { # (becomes a structure in 3.0)
846             STRUCT_NAME => 'prismAlternateTitle',
847             NAMESPACE => 'prism',
848             text => { },
849             'a-platform'=> { },
850             'a-lang' => { },
851             },
852             },
853             blogTitle => { }, # (3.0)
854             blogURL => { }, # (3.0)
855             bookEdition => { }, # (3.0)
856             byteCount => { Writable => 'integer' },
857             channel => {
858             List => 'Bag',
859             Struct => { # (becomes a structure in 3.0)
860             STRUCT_NAME => 'prismChannel',
861             NAMESPACE => 'prism',
862             channel => { },
863             subchannel1 => { },
864             subchannel2 => { },
865             subchannel3 => { },
866             subchannel4 => { },
867             'a-lang' => { },
868             },
869             },
870             complianceProfile=>{ PrintConv => { three => 'Three' } },
871             contentType => { }, # (3.0)
872             copyrightYear => { }, # (3.0)
873             # copyright => { Groups => { 2 => 'Author' } }, # (deprecated in 3.0)
874             corporateEntity => { List => 'Bag' },
875             coverDate => { %dateTimeInfo, Groups => { 2 => 'Time'} },
876             coverDisplayDate=> { },
877             creationDate => { %dateTimeInfo, Groups => { 2 => 'Time'} },
878             dateRecieved => { %dateTimeInfo, Groups => { 2 => 'Time'} },
879             device => { }, # (3.0)
880             distributor => { },
881             doi => { Name => 'DOI', Description => 'Digital Object Identifier' },
882             edition => { },
883             eIssn => { },
884             #embargoDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, # (deprecated in 3.0)
885             endingPage => { },
886             event => { List => 'Bag' },
887             #expirationDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, # (deprecated in 3.0)
888             genre => { List => 'Bag' },
889             hasAlternative => { List => 'Bag' },
890             hasCorrection => {
891             Struct => { # (becomes a structure in 3.0)
892             STRUCT_NAME => 'prismHasCorrection',
893             NAMESPACE => 'prism',
894             text => { },
895             'a-platform'=> { },
896             'a-lang' => { },
897             },
898             },
899             # hasPreviousVersion => { }, # (not in 3.0)
900             hasTranslation => { List => 'Bag' },
901             industry => { List => 'Bag' },
902             isAlternativeOf => { List => 'Bag' }, # (3.0)
903             isbn => { Name => 'ISBN', List => 'Bag' }, # 2.1 (becomes a list in 3.0)
904             isCorrectionOf => { List => 'Bag' },
905             issn => { Name => 'ISSN' },
906             issueIdentifier => { },
907             issueName => { },
908             issueTeaser => { }, # (3.0)
909             issueType => { }, # (3.0)
910             isTranslationOf => { },
911             keyword => { List => 'Bag' },
912             killDate => {
913             Struct => { # (becomes a structure in 3.0)
914             STRUCT_NAME => 'prismKillDate',
915             NAMESPACE => 'prism',
916             date => { %dateTimeInfo, Groups => { 2 => 'Time'} },
917             'a-platform'=> { }, #PH (missed in spec?)
918             },
919             },
920             'link' => { List => 'Bag' }, # (3.0)
921             location => { List => 'Bag' },
922             # metadataContainer => { }, (not valid for PRISM XMP)
923             modificationDate=> { %dateTimeInfo, Groups => { 2 => 'Time'} },
924             nationalCatalogNumber => { }, # (3.0)
925             number => { },
926             object => { List => 'Bag' },
927             onSaleDate => { # (3.0)
928             List => 'Bag',
929             Struct => {
930             STRUCT_NAME => 'prismOnSaleDate',
931             NAMESPACE => 'prism',
932             date => { %dateTimeInfo, Groups => { 2 => 'Time'} },
933             'a-platform'=> { },
934             },
935             },
936             onSaleDay => { # (3.0)
937             List => 'Bag',
938             Struct => {
939             STRUCT_NAME => 'prismOnSaleDay',
940             NAMESPACE => 'prism',
941             day => { }, #PH (not named in spec)
942             'a-platform'=> { },
943             },
944             },
945             offSaleDate => { # (3.0)
946             List => 'Bag',
947             Struct => {
948             STRUCT_NAME => 'prismOffSaleDate',
949             NAMESPACE => 'prism',
950             date => { %dateTimeInfo, Groups => { 2 => 'Time'} },
951             'a-platform'=> { },
952             },
953             },
954             organization => { List => 'Bag' },
955             originPlatform => {
956             List => 'Bag',
957             PrintConv => {
958             email => 'E-Mail',
959             mobile => 'Mobile',
960             broadcast => 'Broadcast',
961             web => 'Web',
962             'print' => 'Print',
963             recordableMedia => 'Recordable Media',
964             other => 'Other',
965             },
966             },
967             pageCount => { Writable => 'integer' }, # (3.0)
968             pageProgressionDirection => { # (3.0)
969             PrintConv => { LTR => 'Left to Right', RTL => 'Right to Left' },
970             },
971             pageRange => { List => 'Bag' },
972             person => { },
973             platform => { }, # (3.0)
974             productCode => { }, # (3.0)
975             profession => { }, # (3.0)
976             publicationDate => {
977             List => 'Bag',
978             Struct => \%prismPublicationDate, # (becomes a structure in 3.0)
979             },
980             publicationDisplayDate => { # (3.0)
981             List => 'Bag',
982             Struct => \%prismPublicationDate,
983             },
984             publicationName => { },
985             publishingFrequency => { }, # (3.0)
986             rating => { },
987             # rightsAgent => { }, # (deprecated in 3.0)
988             samplePageRange => { }, # (3.0)
989             section => { },
990             sellingAgency => { }, # (3.0)
991             seriesNumber => { Writable => 'integer' }, # (3.0)
992             seriesTitle => { }, # (3.0)
993             sport => { }, # (3.0)
994             startingPage => { },
995             subsection1 => { },
996             subsection2 => { },
997             subsection3 => { },
998             subsection4 => { },
999             subtitle => { }, # (3.0)
1000             supplementDisplayID => { }, # (3.0)
1001             supplementStartingPage => { }, # (3.0)
1002             supplementTitle => { }, # (3.0)
1003             teaser => { List => 'Bag' },
1004             ticker => { List => 'Bag' },
1005             timePeriod => { },
1006             url => {
1007             Name => 'URL',
1008             List => 'Bag',
1009             Struct => { # (becomes a structure in 3.0)
1010             STRUCT_NAME => 'prismUrl',
1011             NAMESPACE => 'prism',
1012             url => { },
1013             'a-platform'=> { },
1014             },
1015             },
1016             uspsNumber => { }, # (3.0)
1017             versionIdentifier => { },
1018             volume => { },
1019             wordCount => { Writable => 'integer' },
1020             # tags that existed in version 1.3
1021             # category => { %obsolete, List => 'Bag' },
1022             # hasFormat => { %obsolete, List => 'Bag' },
1023             # hasPart => { %obsolete, List => 'Bag' },
1024             # isFormatOf => { %obsolete, List => 'Bag' },
1025             # isPartOf => { %obsolete },
1026             # isReferencedBy => { %obsolete, List => 'Bag' },
1027             # isRequiredBy => { %obsolete, List => 'Bag' },
1028             # isVersionOf => { %obsolete },
1029             # objectTitle => { %obsolete, List => 'Bag' },
1030             # receptionDate => { %obsolete },
1031             # references => { %obsolete, List => 'Bag' },
1032             # requires => { %obsolete, List => 'Bag' },
1033             # tags in older versions
1034             # page
1035             # contentLength
1036             # creationTime
1037             # expirationTime
1038             # hasVersion
1039             # isAlternativeFor
1040             # isBasedOn
1041             # isBasisFor
1042             # modificationTime
1043             # publicationTime
1044             # receptionTime
1045             # releaseTime
1046             );
1047              
1048             # PRISM Rights Language namespace (prl) (ref 2)
1049             %Image::ExifTool::XMP::prl = (
1050             %xmpTableDefaults,
1051             GROUPS => { 0 => 'XMP', 1 => 'XMP-prl', 2 => 'Document' },
1052             NAMESPACE => 'prl',
1053             AVOID => 1,
1054             NOTES => q{
1055             PRISM Rights Language 2.1 namespace tags. These tags have been deprecated
1056             since the release of the PRISM Usage Rights 3.0. (see
1057             L)
1058             },
1059             geography => { List => 'Bag' },
1060             industry => { List => 'Bag' },
1061             usage => { List => 'Bag' },
1062             );
1063              
1064             # PRISM Usage Rights namespace (prismusagerights) (ref 2)
1065             %Image::ExifTool::XMP::pur = (
1066             %xmpTableDefaults,
1067             GROUPS => { 0 => 'XMP', 1 => 'XMP-pur', 2 => 'Document' },
1068             NAMESPACE => 'pur',
1069             AVOID => 1,
1070             NOTES => q{
1071             PRISM Usage Rights 3.0 namespace tags. (see
1072             L)
1073             },
1074             adultContentWarning => { List => 'Bag' },
1075             agreement => { List => 'Bag' },
1076             copyright => {
1077             # (not clear in 3.0 spec, which lists only "bag Text", and called
1078             # "copyrightDate" instead of "copyright" the PRISM basic 3.0 spec)
1079             Writable => 'lang-alt',
1080             Groups => { 2 => 'Author' },
1081             },
1082             creditLine => { List => 'Bag' },
1083             embargoDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1084             exclusivityEndDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1085             expirationDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1086             imageSizeRestriction=> { },
1087             optionEndDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
1088             permissions => { List => 'Bag' },
1089             restrictions => { List => 'Bag' },
1090             reuseProhibited => { Writable => 'boolean' },
1091             rightsAgent => { },
1092             rightsOwner => { },
1093             # usageFee => { List => 'Bag' }, # (not in 3.0)
1094             );
1095              
1096             # PRISM Metadata for Images namespace (pmi) (ref 2)
1097             %Image::ExifTool::XMP::pmi = (
1098             %xmpTableDefaults,
1099             GROUPS => { 0 => 'XMP', 1 => 'XMP-pmi', 2 => 'Image' },
1100             NAMESPACE => 'pmi',
1101             AVOID => 1,
1102             NOTES => q{
1103             PRISM Metadata for Images 3.0 namespace tags. (see
1104             L)
1105             },
1106             color => {
1107             PrintConv => {
1108             bw => 'BW',
1109             color => 'Color',
1110             sepia => 'Sepia',
1111             duotone => 'Duotone',
1112             tritone => 'Tritone',
1113             quadtone => 'Quadtone',
1114             },
1115             },
1116             contactInfo => { },
1117             displayName => { },
1118             distributorProductID => { },
1119             eventAlias => { },
1120             eventEnd => { },
1121             eventStart => { },
1122             eventSubtype => { },
1123             eventType => { },
1124             field => { },
1125             framing => { },
1126             location => { },
1127             make => { },
1128             manufacturer => { },
1129             model => { },
1130             modelYear => { },
1131             objectDescription=>{ },
1132             objectSubtype => { },
1133             objectType => { },
1134             orientation => {
1135             PrintConv => {
1136             horizontal => 'Horizontal',
1137             vertical => 'Vertical',
1138             }
1139             },
1140             positionDescriptor => { },
1141             productID => { },
1142             productIDType => { },
1143             season => {
1144             PrintConv => {
1145             spring => 'Spring',
1146             summer => 'Summer',
1147             fall => 'Fall',
1148             winter => 'Winter',
1149             },
1150             },
1151             sequenceName => { },
1152             sequenceNumber => { },
1153             sequenceTotalNumber => { },
1154             setting => { },
1155             shootID => { },
1156             slideshowName => { },
1157             slideshowNumber => { Writable => 'integer' },
1158             slideshowTotalNumber => { Writable => 'integer' },
1159             viewpoint => { },
1160             visualTechnique => { },
1161             );
1162              
1163             # PRISM Recipe Metadata (prm) (ref 2)
1164             %Image::ExifTool::XMP::prm = (
1165             %xmpTableDefaults,
1166             GROUPS => { 0 => 'XMP', 1 => 'XMP-prm', 2 => 'Document' },
1167             NAMESPACE => 'prm',
1168             AVOID => 1,
1169             NOTES => q{
1170             PRISM Recipe Metadata 3.0 namespace tags. (see
1171             L)
1172             },
1173             cookingEquipment => { },
1174             cookingMethod => { },
1175             course => { },
1176             cuisine => { },
1177             dietaryNeeds => { },
1178             dishType => { },
1179             duration => { },
1180             ingredientExclusion => { },
1181             mainIngredient => { },
1182             meal => { },
1183             recipeEndingPage => { },
1184             recipePageRange => { },
1185             recipeSource => { },
1186             recipeStartingPage => { },
1187             recipeTitle => { },
1188             servingSize => { },
1189             skillLevel => { },
1190             specialOccasion => { },
1191             yield => { },
1192             );
1193              
1194             #------------------------------------------------------------------------------
1195              
1196             # DICOM namespace properties (DICOM) (ref PH, written by CS3)
1197             %Image::ExifTool::XMP::DICOM = (
1198             %xmpTableDefaults,
1199             GROUPS => { 1 => 'XMP-DICOM', 2 => 'Image' },
1200             NAMESPACE => 'DICOM',
1201             NOTES => q{
1202             DICOM namespace tags. These XMP tags allow some DICOM information to be
1203             stored in files of other than DICOM format. See the
1204             L for a list
1205             of tags available in DICOM-format files.
1206             },
1207             # change some tag names to correspond with DICOM tags
1208             PatientName => { },
1209             PatientID => { },
1210             PatientSex => { },
1211             PatientDOB => {
1212             Name => 'PatientBirthDate',
1213             Groups => { 2 => 'Time' },
1214             %dateTimeInfo,
1215             },
1216             StudyID => { },
1217             StudyPhysician => { },
1218             StudyDateTime => { Groups => { 2 => 'Time' }, %dateTimeInfo },
1219             StudyDescription => { },
1220             SeriesNumber => { },
1221             SeriesModality => { },
1222             SeriesDateTime => { Groups => { 2 => 'Time' }, %dateTimeInfo },
1223             SeriesDescription => { },
1224             EquipmentInstitution => { },
1225             EquipmentManufacturer => { },
1226             );
1227              
1228             # PixelLive namespace properties (PixelLive) (ref 3)
1229             %Image::ExifTool::XMP::PixelLive = (
1230             GROUPS => { 1 => 'XMP-PixelLive', 2 => 'Image' },
1231             NAMESPACE => 'PixelLive',
1232             AVOID => 1,
1233             NOTES => q{
1234             PixelLive namespace tags. These tags are not writable because they are very
1235             uncommon and I haven't been able to locate a reference which gives the
1236             namespace URI.
1237             },
1238             AUTHOR => { Name => 'Author', Groups => { 2 => 'Author' } },
1239             COMMENTS => { Name => 'Comments' },
1240             COPYRIGHT => { Name => 'Copyright', Groups => { 2 => 'Author' } },
1241             DATE => { Name => 'Date', Groups => { 2 => 'Time' } },
1242             GENRE => { Name => 'Genre' },
1243             TITLE => { Name => 'Title' },
1244             );
1245              
1246             # Extensis Portfolio tags (extensis) (ref 11)
1247             %Image::ExifTool::XMP::extensis = (
1248             %xmpTableDefaults,
1249             GROUPS => { 1 => 'XMP-extensis', 2 => 'Image' },
1250             NAMESPACE => 'extensis',
1251             NOTES => 'Tags used by Extensis Portfolio.',
1252             Approved => { Writable => 'boolean' },
1253             ApprovedBy => { },
1254             ClientName => { },
1255             JobName => { },
1256             JobStatus => { },
1257             RoutedTo => { },
1258             RoutingNotes => { },
1259             WorkToDo => { },
1260             );
1261              
1262             # IDimager structures (ref PH)
1263             my %sTagStruct;
1264             %sTagStruct = (
1265             STRUCT_NAME => 'TagStructure',
1266             NAMESPACE => 'ics',
1267             LabelName => { },
1268             Reference => { },
1269             ParentReference => { },
1270             SubLabels => { Struct => \%sTagStruct, List => 'Bag' },
1271             );
1272             my %sSubVersion = (
1273             STRUCT_NAME => 'SubVersion',
1274             NAMESPACE => 'ics',
1275             VersRef => { },
1276             FileName => { },
1277             );
1278              
1279             # IDimager namespace (ics) (ref PH)
1280             %Image::ExifTool::XMP::ics = (
1281             %xmpTableDefaults,
1282             GROUPS => { 0 => 'XMP', 1 => 'XMP-ics', 2 => 'Image' },
1283             NAMESPACE => 'ics',
1284             NOTES => q{
1285             Tags used by IDimager. Nested TagStructure structures are unrolled to an
1286             arbitrary depth of 6 to avoid infinite recursion.
1287             },
1288             ImageRef => { },
1289             TagStructure => { Struct => \%sTagStruct, List => 'Bag' },
1290             TagStructureLabelName => { Name => 'LabelName1', Flat => 1 },
1291             TagStructureReference => { Name => 'Reference1', Flat => 1 },
1292             TagStructureSubLabels => { Name => 'SubLabels1', Flat => 1 },
1293             TagStructureParentReference => { Name => 'ParentReference1', Flat => 1 },
1294             TagStructureSubLabelsLabelName => { Name => 'LabelName2', Flat => 1 },
1295             TagStructureSubLabelsReference => { Name => 'Reference2', Flat => 1 },
1296             TagStructureSubLabelsSubLabels => { Name => 'SubLabels2', Flat => 1 },
1297             TagStructureSubLabelsParentReference => { Name => 'ParentReference2', Flat => 1 },
1298             TagStructureSubLabelsSubLabelsLabelName => { Name => 'LabelName3', Flat => 1 },
1299             TagStructureSubLabelsSubLabelsReference => { Name => 'Reference3', Flat => 1 },
1300             TagStructureSubLabelsSubLabelsSubLabels => { Name => 'SubLabels3', Flat => 1 },
1301             TagStructureSubLabelsSubLabelsParentReference => { Name => 'ParentReference3', Flat => 1 },
1302             TagStructureSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName4', Flat => 1 },
1303             TagStructureSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference4', Flat => 1 },
1304             TagStructureSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels4', Flat => 1 },
1305             TagStructureSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference4', Flat => 1 },
1306             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName5', Flat => 1 },
1307             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference5', Flat => 1 },
1308             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels5', Flat => 1, NoSubStruct => 1 }, # break infinite recursion
1309             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference5', Flat => 1 },
1310             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName6', Flat => 1 },
1311             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference6', Flat => 1 },
1312             TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference6', Flat => 1 },
1313             SubVersions => { Struct => \%sSubVersion, List => 'Bag' },
1314             SubVersionsVersRef => { Name => 'SubVersionReference', Flat => 1 },
1315             SubVersionsFileName => { Name => 'SubVersionFileName', Flat => 1 },
1316             TimeStamp => { Avoid => 1, Groups => { 2 => 'Time' }, %dateTimeInfo },
1317             AppVersion => { Avoid => 1 },
1318             );
1319              
1320             # ACDSee namespace (acdsee) (ref PH)
1321             %Image::ExifTool::XMP::acdsee = (
1322             %xmpTableDefaults,
1323             GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee', 2 => 'Image' },
1324             NAMESPACE => 'acdsee',
1325             AVOID => 1,
1326             NOTES => q{
1327             ACD Systems ACDSee namespace tags.
1328              
1329             (A note to software developers: Re-inventing your own private tags instead
1330             of using the equivalent tags in standard XMP namespaces defeats one of the
1331             most valuable features of metadata: interoperability. Your applications
1332             mumble to themselves instead of speaking out for the rest of the world to
1333             hear.)
1334             },
1335             author => { Groups => { 2 => 'Author' } },
1336             caption => { },
1337             categories => { },
1338             collections=> { },
1339             datetime => { Name => 'DateTime', Groups => { 2 => 'Time' }, %dateTimeInfo },
1340             keywords => { List => 'Bag' },
1341             notes => { },
1342             rating => { Writable => 'real' }, # integer?
1343             tagged => { Writable => 'boolean' },
1344             rawrppused => { Writable => 'boolean' },
1345             rpp => {
1346             Name => 'RPP',
1347             Writable => 'lang-alt',
1348             Notes => 'raw processing settings in XML format',
1349             Binary => 1,
1350             },
1351             dpp => {
1352             Name => 'DPP',
1353             Writable => 'lang-alt',
1354             Notes => 'newer version of XML raw processing settings',
1355             Binary => 1,
1356             },
1357             # more tags (ref forum6840)
1358             FixtureIdentifier => { },
1359             EditStatus => { },
1360             ReleaseDate => { },
1361             ReleaseTime => { },
1362             OriginatingProgram => { },
1363             ObjectCycle => { },
1364             Snapshots => { List => 'Bag', Binary => 1 },
1365             );
1366              
1367             # Picture Licensing Universal System namespace properties (xmpPLUS)
1368             %Image::ExifTool::XMP::xmpPLUS = (
1369             %xmpTableDefaults,
1370             GROUPS => { 1 => 'XMP-xmpPLUS', 2 => 'Author' },
1371             NAMESPACE => 'xmpPLUS',
1372             AVOID => 1,
1373             NOTES => q{
1374             XMP Picture Licensing Universal System (PLUS) tags as written by some older
1375             Adobe applications. See L
1376             for the current PLUS tags.
1377             },
1378             CreditLineReq => { Writable => 'boolean' },
1379             ReuseAllowed => { Writable => 'boolean' },
1380             );
1381              
1382             # Creative Commons namespace properties (cc) (ref 5)
1383             %Image::ExifTool::XMP::cc = (
1384             %xmpTableDefaults,
1385             GROUPS => { 1 => 'XMP-cc', 2 => 'Author' },
1386             NAMESPACE => 'cc',
1387             NOTES => q{
1388             Creative Commons namespace tags. Note that the CC specification for XMP is
1389             non-existent, so ExifTool must make some assumptions about the format of the
1390             specific properties in XMP (see L).
1391             },
1392             # Work properties
1393             license => { Resource => 1 },
1394             attributionName => { },
1395             attributionURL => { Resource => 1 },
1396             morePermissions => { Resource => 1 },
1397             useGuidelines => { Resource => 1 },
1398             # License properties
1399             permits => {
1400             List => 'Bag',
1401             Resource => 1,
1402             PrintConv => {
1403             'cc:Sharing' => 'Sharing',
1404             'cc:DerivativeWorks' => 'Derivative Works',
1405             'cc:Reproduction' => 'Reproduction',
1406             'cc:Distribution' => 'Distribution',
1407             },
1408             },
1409             requires => {
1410             List => 'Bag',
1411             Resource => 1,
1412             PrintConv => {
1413             'cc:Copyleft' => 'Copyleft',
1414             'cc:LesserCopyleft' => 'Lesser Copyleft',
1415             'cc:SourceCode' => 'Source Code',
1416             'cc:ShareAlike' => 'Share Alike',
1417             'cc:Notice' => 'Notice',
1418             'cc:Attribution' => 'Attribution',
1419             },
1420             },
1421             prohibits => {
1422             List => 'Bag',
1423             Resource => 1,
1424             PrintConv => {
1425             'cc:HighIncomeNationUse' => 'High Income Nation Use',
1426             'cc:CommercialUse' => 'Commercial Use',
1427             },
1428             },
1429             jurisdiction => { Resource => 1 },
1430             legalcode => { Name => 'LegalCode', Resource => 1 },
1431             deprecatedOn => { %dateTimeInfo, Groups => { 2 => 'Time' } },
1432             );
1433              
1434             # Description Explorer namespace properties (dex) (ref 6)
1435             %Image::ExifTool::XMP::dex = (
1436             %xmpTableDefaults,
1437             GROUPS => { 1 => 'XMP-dex', 2 => 'Image' },
1438             NAMESPACE => 'dex',
1439             NOTES => q{
1440             Description Explorer namespace tags. These tags are not very common. The
1441             Source and Rating tags are avoided when writing due to name conflicts with
1442             other XMP tags. (see L)
1443             },
1444             crc32 => { Name => 'CRC32', Writable => 'integer' },
1445             source => { Avoid => 1 },
1446             shortdescription => {
1447             Name => 'ShortDescription',
1448             Writable => 'lang-alt',
1449             },
1450             licensetype => {
1451             Name => 'LicenseType',
1452             PrintConv => {
1453             unknown => 'Unknown',
1454             shareware => 'Shareware',
1455             freeware => 'Freeware',
1456             adware => 'Adware',
1457             demo => 'Demo',
1458             commercial => 'Commercial',
1459             'public domain' => 'Public Domain',
1460             'open source' => 'Open Source',
1461             },
1462             },
1463             revision => { },
1464             rating => { Avoid => 1 },
1465             os => { Name => 'OS', Writable => 'integer' },
1466             ffid => { Name => 'FFID' },
1467             );
1468              
1469             # iView MediaPro namespace properties (mediapro) (ref PH)
1470             %Image::ExifTool::XMP::MediaPro = (
1471             %xmpTableDefaults,
1472             GROUPS => { 1 => 'XMP-mediapro', 2 => 'Image' },
1473             NAMESPACE => 'mediapro',
1474             NOTES => 'iView MediaPro namespace tags.',
1475             Event => {
1476             Avoid => 1,
1477             Notes => 'avoided due to conflict with XMP-iptcExt:Event',
1478             },
1479             Location => {
1480             Avoid => 1,
1481             Groups => { 2 => 'Location' },
1482             Notes => 'avoided due to conflict with XMP-iptcCore:Location',
1483             },
1484             Status => { },
1485             People => { List => 'Bag' },
1486             UserFields => { List => 'Bag' },
1487             CatalogSets => { List => 'Bag' },
1488             );
1489              
1490             # Microsoft ExpressionMedia namespace properties (expressionmedia)
1491             # (ref https://exiftool.org/forum/index.php/topic,4235.0.html)
1492             %Image::ExifTool::XMP::ExpressionMedia = (
1493             %xmpTableDefaults,
1494             GROUPS => { 1 => 'XMP-expressionmedia', 2 => 'Image' },
1495             NAMESPACE => 'expressionmedia',
1496             AVOID => 1,
1497             NOTES => q{
1498             Microsoft Expression Media namespace tags. These tags are avoided when
1499             writing due to name conflicts with tags in other schemas.
1500             },
1501             Event => { },
1502             Status => { },
1503             People => { List => 'Bag' },
1504             CatalogSets => { List => 'Bag' },
1505             );
1506              
1507             # DigiKam namespace tags (ref PH)
1508             %Image::ExifTool::XMP::digiKam = (
1509             %xmpTableDefaults,
1510             GROUPS => { 1 => 'XMP-digiKam', 2 => 'Image' },
1511             NAMESPACE => 'digiKam',
1512             NOTES => 'DigiKam namespace tags.',
1513             CaptionsAuthorNames => { Writable => 'lang-alt' },
1514             CaptionsDateTimeStamps => { Writable => 'lang-alt', Groups => { 2 => 'Time' } },
1515             TagsList => { List => 'Seq' },
1516             ColorLabel => { },
1517             PickLabel => { },
1518             ImageHistory => { Avoid => 1, Notes => 'different format from EXIF:ImageHistory' },
1519             LensCorrectionSettings => { },
1520             ImageUniqueID => { Avoid => 1 },
1521             );
1522              
1523             # SWF namespace tags (ref PH)
1524             %Image::ExifTool::XMP::swf = (
1525             %xmpTableDefaults,
1526             GROUPS => { 1 => 'XMP-swf', 2 => 'Image' },
1527             NAMESPACE => 'swf',
1528             NOTES => 'Adobe SWF namespace tags.',
1529             type => { Avoid => 1 },
1530             bgalpha => { Name => 'BackgroundAlpha', Writable => 'integer' },
1531             forwardlock => { Name => 'ForwardLock', Writable => 'boolean' },
1532             maxstorage => { Name => 'MaxStorage', Writable => 'integer' }, # (CS5)
1533             );
1534              
1535             # Sony Ericsson cell phone location tags
1536             # refs: http://www.opencellid.org/api
1537             # http://zonetag.research.yahoo.com/faq_location.php
1538             # http://www.cs.columbia.edu/sip/drafts/LIF%20TS%20101%20v2.0.0.pdf
1539             %Image::ExifTool::XMP::cell = (
1540             %xmpTableDefaults,
1541             GROUPS => { 1 => 'XMP-cell', 2 => 'Location' },
1542             NAMESPACE => 'cell',
1543             NOTES => 'Location tags written by some Sony Ericsson phones.',
1544             mcc => { Name => 'MobileCountryCode' },
1545             mnc => { Name => 'MobileNetworkCode' },
1546             lac => { Name => 'LocationAreaCode' },
1547             cellid => { Name => 'CellTowerID' },
1548             cgi => { Name => 'CellGlobalID' },
1549             r => { Name => 'CellR' }, # (what is this? Radius?)
1550             );
1551              
1552             # Apple adjustment settings (ref PH)
1553             %Image::ExifTool::XMP::aas = (
1554             %xmpTableDefaults,
1555             GROUPS => { 1 => 'XMP-aas', 2 => 'Image' },
1556             NAMESPACE => 'aas',
1557             NOTES => 'Apple Adjustment Settings used by iPhone/iPad.',
1558             CropX => { Writable => 'integer', Avoid => 1 },
1559             CropY => { Writable => 'integer', Avoid => 1 },
1560             CropW => { Writable => 'integer', Avoid => 1 },
1561             CropH => { Writable => 'integer', Avoid => 1 },
1562             AffineA => { Writable => 'real' },
1563             AffineB => { Writable => 'real' },
1564             AffineC => { Writable => 'real' },
1565             AffineD => { Writable => 'real' },
1566             AffineX => { Writable => 'real' },
1567             AffineY => { Writable => 'real' },
1568             Vibrance => { Writable => 'real', Avoid => 1 },
1569             Curve0x => { Writable => 'real' },
1570             Curve0y => { Writable => 'real' },
1571             Curve1x => { Writable => 'real' },
1572             Curve1y => { Writable => 'real' },
1573             Curve2x => { Writable => 'real' },
1574             Curve2y => { Writable => 'real' },
1575             Curve3x => { Writable => 'real' },
1576             Curve3y => { Writable => 'real' },
1577             Curve4x => { Writable => 'real' },
1578             Curve4y => { Writable => 'real' },
1579             Shadows => { Writable => 'real', Avoid => 1 },
1580             Highlights => { Writable => 'real', Avoid => 1 },
1581             # the following from StarGeek
1582             FaceBalanceOrigI => { Writable => 'real' },
1583             FaceBalanceOrigQ => { Writable => 'real' },
1584             FaceBalanceStrength => { Writable => 'real' },
1585             FaceBalanceWarmth => { Writable => 'real' },
1586             );
1587              
1588             # Adobe creatorAtom properties (ref PH)
1589             %Image::ExifTool::XMP::creatorAtom = (
1590             %xmpTableDefaults,
1591             GROUPS => { 1 => 'XMP-creatorAtom', 2 => 'Image' },
1592             NAMESPACE => 'creatorAtom',
1593             NOTES => 'Adobe creatorAtom tags, written by After Effects.',
1594             macAtom => {
1595             Struct => {
1596             STRUCT_NAME => 'MacAtom',
1597             NAMESPACE => 'creatorAtom',
1598             applicationCode => { },
1599             invocationAppleEvent => { },
1600             posixProjectPath => { },
1601             },
1602             },
1603             windowsAtom => {
1604             Struct => {
1605             STRUCT_NAME => 'WindowsAtom',
1606             NAMESPACE => 'creatorAtom',
1607             extension => { },
1608             invocationFlags => { },
1609             uncProjectPath => { },
1610             },
1611             },
1612             aeProjectLink => { # (After Effects Project Link)
1613             Struct => {
1614             STRUCT_NAME => 'AEProjectLink',
1615             NAMESPACE => 'creatorAtom',
1616             renderTimeStamp => { Writable => 'integer' },
1617             compositionID => { },
1618             renderQueueItemID => { },
1619             renderOutputModuleIndex => { },
1620             fullPath => { },
1621             },
1622             },
1623             );
1624              
1625             # FastPictureViewer namespace properties (http://www.fastpictureviewer.com/help/#rtfcomments)
1626             %Image::ExifTool::XMP::fpv = (
1627             %xmpTableDefaults,
1628             GROUPS => { 1 => 'XMP-fpv', 2 => 'Image' },
1629             NAMESPACE => 'fpv',
1630             NOTES => q{
1631             Fast Picture Viewer tags (see
1632             L).
1633             },
1634             RichTextComment => { },
1635             );
1636              
1637             # Apple FaceInfo namespace properties (ref PH)
1638             %Image::ExifTool::XMP::apple_fi = (
1639             %xmpTableDefaults,
1640             GROUPS => { 1 => 'XMP-apple-fi', 2 => 'Image' },
1641             NAMESPACE => 'apple-fi',
1642             NOTES => q{
1643             Face information tags written by the Apple iPhone 5 inside the mwg-rs
1644             RegionExtensions.
1645             },
1646             Timestamp => {
1647             Name => 'TimeStamp',
1648             Writable => 'integer',
1649             # (don't know how to convert this)
1650             },
1651             FaceID => { Writable => 'integer' },
1652             AngleInfoRoll => { Writable => 'integer' },
1653             AngleInfoYaw => { Writable => 'integer' },
1654             ConfidenceLevel => { Writable => 'integer' },
1655             );
1656              
1657             # Google audio namespace
1658             %Image::ExifTool::XMP::GAudio = (
1659             %xmpTableDefaults,
1660             GROUPS => { 1 => 'XMP-GAudio', 2 => 'Audio' },
1661             NAMESPACE => 'GAudio',
1662             Data => {
1663             Name => 'AudioData',
1664             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1665             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1666             },
1667             Mime => { Name => 'AudioMimeType' },
1668             );
1669              
1670             # Google image namespace
1671             %Image::ExifTool::XMP::GImage = (
1672             %xmpTableDefaults,
1673             GROUPS => { 1 => 'XMP-GImage', 2 => 'Image' },
1674             NAMESPACE => 'GImage',
1675             Data => {
1676             Name => 'ImageData',
1677             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1678             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1679             },
1680             Mime => { Name => 'ImageMimeType' },
1681             );
1682              
1683             # Google panorama namespace properties
1684             # (ref https://exiftool.org/forum/index.php/topic,4569.0.html)
1685             %Image::ExifTool::XMP::GPano = (
1686             %xmpTableDefaults,
1687             GROUPS => { 1 => 'XMP-GPano', 2 => 'Image' },
1688             NAMESPACE => 'GPano',
1689             NOTES => q{
1690             Panorama tags written by Google Photosphere. See
1691             L for the specification.
1692             },
1693             UsePanoramaViewer => { Writable => 'boolean' },
1694             CaptureSoftware => { },
1695             StitchingSoftware => { },
1696             ProjectionType => { },
1697             PoseHeadingDegrees => { Writable => 'real' },
1698             PosePitchDegrees => { Writable => 'real' },
1699             PoseRollDegrees => { Writable => 'real' },
1700             InitialViewHeadingDegrees => { Writable => 'real' },
1701             InitialViewPitchDegrees => { Writable => 'real' },
1702             InitialViewRollDegrees => { Writable => 'real' },
1703             InitialHorizontalFOVDegrees => { Writable => 'real' },
1704             InitialVerticalFOVDegrees => { Writable => 'real' },
1705             FirstPhotoDate => { %dateTimeInfo, Groups => { 2 => 'Time' } },
1706             LastPhotoDate => { %dateTimeInfo, Groups => { 2 => 'Time' } },
1707             SourcePhotosCount => { Writable => 'integer' },
1708             ExposureLockUsed => { Writable => 'boolean' },
1709             CroppedAreaImageWidthPixels => { Writable => 'real' },
1710             CroppedAreaImageHeightPixels => { Writable => 'real' },
1711             FullPanoWidthPixels => { Writable => 'real' },
1712             FullPanoHeightPixels => { Writable => 'real' },
1713             CroppedAreaLeftPixels => { Writable => 'real' },
1714             CroppedAreaTopPixels => { Writable => 'real' },
1715             InitialCameraDolly => { Writable => 'real' },
1716             # (the following have been observed, but are not in the specification)
1717             LargestValidInteriorRectLeft => { Writable => 'real' },
1718             LargestValidInteriorRectTop => { Writable => 'real' },
1719             LargestValidInteriorRectWidth => { Writable => 'real' },
1720             LargestValidInteriorRectHeight => { Writable => 'real' },
1721             );
1722              
1723             # Google Spherical Images namespace (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md)
1724             %Image::ExifTool::XMP::GSpherical = (
1725             %xmpTableDefaults,
1726             GROUPS => { 1 => 'XMP-GSpherical', 2 => 'Image' },
1727             WRITE_GROUP => 'GSpherical', # write in special location for video files
1728             NAMESPACE => 'GSpherical',
1729             AVOID => 1,
1730             NOTES => q{
1731             Not actually XMP. These RDF/XML tags are used in Google spherical MP4
1732             videos. These tags are written into the video track of MOV/MP4 files, and
1733             not at the top level like other XMP tags. See
1734             L
1735             for the specification.
1736             },
1737             # (avoid due to conflicts with XMP-GPano tags)
1738             Spherical => { Writable => 'boolean' },
1739             Stitched => { Writable => 'boolean' },
1740             StitchingSoftware => { },
1741             ProjectionType => { },
1742             StereoMode => { },
1743             SourceCount => { Writable => 'integer' },
1744             InitialViewHeadingDegrees => { Writable => 'real' },
1745             InitialViewPitchDegrees => { Writable => 'real' },
1746             InitialViewRollDegrees => { Writable => 'real' },
1747             Timestamp => {
1748             Name => 'TimeStamp',
1749             Groups => { 2 => 'Time' },
1750             Writable => 'integer',
1751             Shift => 'Time',
1752             ValueConv => 'ConvertUnixTime($val)', #(NC)
1753             ValueConvInv => 'GetUnixTime($val)',
1754             PrintConv => '$self->ConvertDateTime($val)',
1755             PrintConvInv => '$self->InverseDateTime($val)',
1756             },
1757             FullPanoWidthPixels => { Writable => 'integer' },
1758             FullPanoHeightPixels => { Writable => 'integer' },
1759             CroppedAreaImageWidthPixels => { Writable => 'integer' },
1760             CroppedAreaImageHeightPixels=> { Writable => 'integer' },
1761             CroppedAreaLeftPixels => { Writable => 'integer' },
1762             CroppedAreaTopPixels => { Writable => 'integer' },
1763             );
1764              
1765             # Google depthmap information (ref https://developers.google.com/depthmap-metadata/reference)
1766             %Image::ExifTool::XMP::GDepth = (
1767             GROUPS => { 0 => 'XMP', 1 => 'XMP-GDepth', 2 => 'Image' },
1768             NAMESPACE => 'GDepth',
1769             AVOID => 1, # (too many potential tag name conflicts)
1770             NOTES => q{
1771             Google depthmap information. See
1772             L for the specification.
1773             },
1774             WRITABLE => 'string', # (default to string-type tags)
1775             PRIORITY => 0,
1776             Format => {
1777             PrintConv => {
1778             RangeInverse => 'RangeInverse',
1779             RangeLinear => 'RangeLinear',
1780             },
1781             },
1782             Near => { Writable => 'real' },
1783             Far => { Writable => 'real' },
1784             Mime => { },
1785             Data => {
1786             Name => 'DepthImage',
1787             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1788             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1789             },
1790             Units => { },
1791             MeasureType => {
1792             PrintConv => {
1793             OpticalAxis => 'OpticalAxis',
1794             OpticalRay => 'OpticalRay',
1795             },
1796             },
1797             ConfidenceMime => { },
1798             Confidence => {
1799             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1800             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1801             },
1802             Manufacturer=> { },
1803             Model => { },
1804             Software => { },
1805             ImageWidth => { Writable => 'real' },
1806             ImageHeight => { Writable => 'real' },
1807             );
1808              
1809             # Google focus namespace
1810             %Image::ExifTool::XMP::GFocus = (
1811             %xmpTableDefaults,
1812             GROUPS => { 1 => 'XMP-GFocus', 2 => 'Image' },
1813             NAMESPACE => 'GFocus',
1814             NOTES => 'Focus information found in Google depthmap images.',
1815             BlurAtInfinity => { Writable => 'real' },
1816             FocalDistance => { Writable => 'real' },
1817             FocalPointX => { Writable => 'real' },
1818             FocalPointY => { Writable => 'real' },
1819             );
1820              
1821             # Google camera namespace (ref PH)
1822             %Image::ExifTool::XMP::GCamera = (
1823             %xmpTableDefaults,
1824             GROUPS => { 1 => 'XMP-GCamera', 2 => 'Camera' },
1825             NAMESPACE => 'GCamera',
1826             NOTES => 'Camera information found in Google panorama images.',
1827             BurstID => { },
1828             BurstPrimary => { },
1829             PortraitNote => { },
1830             PortraitRequest => {
1831             Notes => 'High Definition Render Pipeline (HDRP) data', #PH (guess)
1832             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1833             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1834             },
1835             PortraitVersion => { },
1836             SpecialTypeID => { List => 'Bag' },
1837             PortraitNote => { },
1838             DisableAutoCreation => { List => 'Bag' },
1839             hdrp_makernote => {
1840             Name => 'HDRPMakerNote',
1841             # decoded data starts with the following bytes, but nothing yet is known about its contents:
1842             # 48 44 52 50 02 ef 64 35 6d 5e 70 1e 2c ea e3 4c [HDRP..d5m^p.,..L]
1843             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1844             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1845             },
1846             MicroVideo => { Writable => 'integer' },
1847             MicroVideoVersion => { Writable => 'integer' },
1848             MicroVideoOffset => { Writable => 'integer' },
1849             MicroVideoPresentationTimestampUs => { Writable => 'integer' },
1850             );
1851              
1852             # Google creations namespace (ref PH)
1853             %Image::ExifTool::XMP::GCreations = (
1854             %xmpTableDefaults,
1855             GROUPS => { 1 => 'XMP-GCreations', 2 => 'Camera' },
1856             NAMESPACE => 'GCreations',
1857             NOTES => 'Google creations tags.',
1858             CameraBurstID => { },
1859             );
1860              
1861             # Google depth-map Device namespace (ref 13)
1862             %Image::ExifTool::XMP::Device = (
1863             %xmpTableDefaults,
1864             GROUPS => { 1 => 'XMP-Device', 2 => 'Camera' },
1865             NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1866             NOTES => q{
1867             Google depth-map Device tags. See
1868             L for
1869             the specification.
1870             },
1871             Container => {
1872             Struct => {
1873             STRUCT_NAME => 'DeviceContainer',
1874             NAMESPACE => { Container => 'http://ns.google.com/photos/dd/1.0/container/' },
1875             Directory => {
1876             List => 'Seq',
1877             Struct => {
1878             STRUCT_NAME => 'DeviceDirectory',
1879             NAMESPACE => { Container => 'http://ns.google.com/photos/dd/1.0/container/' },
1880             Item => {
1881             Struct => {
1882             STRUCT_NAME => 'DeviceItem',
1883             NAMESPACE => { Item => 'http://ns.google.com/photos/dd/1.0/item/' },
1884             Mime => { },
1885             Length => { Writable => 'integer' },
1886             Padding => { Writable => 'integer' },
1887             DataURI => { },
1888             },
1889             },
1890             },
1891             }
1892             },
1893             },
1894             Profiles => {
1895             List => 'Seq',
1896             FlatName => '',
1897             Struct => {
1898             STRUCT_NAME => 'DeviceProfiles',
1899             NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1900             Profile => {
1901             Struct => {
1902             STRUCT_NAME => 'DeviceProfile',
1903             NAMESPACE => { Profile => 'http://ns.google.com/photos/dd/1.0/profile/' },
1904             CameraIndices => { List => 'Seq', Writable => 'integer' },
1905             Type => { },
1906             },
1907             },
1908             },
1909             },
1910             Cameras => {
1911             List => 'Seq',
1912             FlatName => '',
1913             Struct => {
1914             STRUCT_NAME => 'DeviceCameras',
1915             NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1916             Camera => {
1917             Struct => {
1918             STRUCT_NAME => 'DeviceCamera',
1919             NAMESPACE => { Camera => 'http://ns.google.com/photos/dd/1.0/camera/' },
1920             DepthMap => {
1921             Struct => {
1922             STRUCT_NAME => 'DeviceDepthMap',
1923             NAMESPACE => { DepthMap => 'http://ns.google.com/photos/dd/1.0/depthmap/' },
1924             ConfidenceURI => { },
1925             DepthURI => { },
1926             Far => { Writable => 'real' },
1927             Format => { },
1928             ItemSemantic=> { },
1929             MeasureType => { },
1930             Near => { Writable => 'real' },
1931             Units => { },
1932             Software => { },
1933             FocalTableEntryCount => { Writable => 'integer' },
1934             FocalTable => { }, # (base64)
1935             },
1936             },
1937             Image => {
1938             Struct => {
1939             STRUCT_NAME => 'DeviceImage',
1940             NAMESPACE => { Image => 'http://ns.google.com/photos/dd/1.0/image/' },
1941             ItemSemantic=> { },
1942             ItemURI => { },
1943             },
1944             },
1945             ImagingModel => {
1946             Struct => {
1947             STRUCT_NAME => 'DeviceImagingModel',
1948             NAMESPACE => { ImagingModel => 'http://ns.google.com/photos/dd/1.0/imagingmodel/' },
1949             Distortion => { }, # (base64)
1950             DistortionCount => { Writable => 'integer' },
1951             FocalLengthX => { Writable => 'real' },
1952             FocalLengthY => { Writable => 'real' },
1953             ImageHeight => { Writable => 'integer' },
1954             ImageWidth => { Writable => 'integer' },
1955             PixelAspectRatio=> { Writable => 'real' },
1956             PrincipalPointX => { Writable => 'real' },
1957             PrincipalPointY => { Writable => 'real' },
1958             Skew => { Writable => 'real' },
1959             },
1960             },
1961             PointCloud => {
1962             Struct => {
1963             STRUCT_NAME => 'DevicePointCloud',
1964             NAMESPACE => { PointCloud => 'http://ns.google.com/photos/dd/1.0/pointcloud/' },
1965             PointCloud => { Writable => 'integer' },
1966             Points => { },
1967             Metric => { Writable => 'boolean' },
1968             },
1969             },
1970             Pose => { Struct => \%sPose },
1971             LightEstimate => {
1972             Struct => {
1973             STRUCT_NAME => 'DeviceLightEstimate',
1974             NAMESPACE => { LightEstimate => 'http://ns.google.com/photos/dd/1.0/lightestimate/' },
1975             ColorCorrectionR => { Writable => 'real' },
1976             ColorCorrectionG => { Writable => 'real' },
1977             ColorCorrectionB => { Writable => 'real' },
1978             PixelIntensity => { Writable => 'real' },
1979             },
1980             },
1981             VendorInfo => { Struct => \%sVendorInfo },
1982             AppInfo => { Struct => \%sAppInfo },
1983             Trait => { },
1984             },
1985             },
1986             },
1987             },
1988             VendorInfo => { Struct => \%sVendorInfo },
1989             AppInfo => { Struct => \%sAppInfo },
1990             EarthPos => { Struct => \%sEarthPose },
1991             Pose => { Struct => \%sPose },
1992             Planes => {
1993             List => 'Seq',
1994             FlatName => '',
1995             Struct => {
1996             STRUCT_NAME => 'DevicePlanes',
1997             NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1998             Plane => {
1999             Struct => {
2000             STRUCT_NAME => 'DevicePlane',
2001             NAMESPACE => { Plane => 'http://ns.google.com/photos/dd/1.0/plane/' },
2002             Pose => { Struct => \%sPose },
2003             ExtentX => { Writable => 'real' },
2004             ExtentZ => { Writable => 'real' },
2005             BoundaryVertexCount => { Writable => 'integer' },
2006             Boundary => { },
2007             },
2008             },
2009             },
2010             },
2011             );
2012              
2013             # Getty Images namespace (ref PH)
2014             %Image::ExifTool::XMP::GettyImages = (
2015             %xmpTableDefaults,
2016             GROUPS => { 1 => 'XMP-getty', 2 => 'Image' },
2017             NAMESPACE => 'GettyImagesGIFT',
2018             NOTES => q{
2019             The actual Getty Images namespace prefix is "GettyImagesGIFT", which is the
2020             prefix recorded in the file, but ExifTool shortens this for the family 1
2021             group name.
2022             },
2023             Personality => { List => 'Bag' },
2024             OriginalFilename => { Name => 'OriginalFileName' },
2025             ParentMEID => { },
2026             # the following from StarGeek
2027             AssetID => { },
2028             CallForImage => { },
2029             CameraFilename => { },
2030             CameraMakeModel => { Avoid => 1 },
2031             Composition => { },
2032             CameraSerialNumber => { Avoid => 1 },
2033             ExclusiveCoverage => { },
2034             GIFTFtpPriority => { },
2035             ImageRank => { },
2036             MediaEventIdDate => { },
2037             OriginalCreateDateTime => { %dateTimeInfo, Groups => { 2 => 'Time' }, Avoid => 1 },
2038             ParentMediaEventID => { },
2039             PrimaryFTP => { List => 'Bag' },
2040             RoutingDestinations => { List => 'Bag' },
2041             RoutingExclusions => { List => 'Bag' },
2042             SecondaryFTP => { List => 'Bag' },
2043             TimeShot => { },
2044             );
2045              
2046             # RED smartphone images (ref PH)
2047             %Image::ExifTool::XMP::LImage = (
2048             %xmpTableDefaults,
2049             GROUPS => { 1 => 'XMP-LImage', 2 => 'Image' },
2050             NAMESPACE => 'LImage',
2051             NOTES => 'Tags written by RED smartphones.',
2052             MajorVersion => { },
2053             MinorVersion => { },
2054             RightAlbedo => {
2055             Notes => 'Right stereoscopic image',
2056             Groups => { 2 => 'Preview' },
2057             ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
2058             ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
2059             },
2060             );
2061              
2062             # SVG namespace properties (ref 9)
2063             %Image::ExifTool::XMP::SVG = (
2064             GROUPS => { 0 => 'SVG', 1 => 'SVG', 2 => 'Image' },
2065             NAMESPACE => 'svg',
2066             LANG_INFO => \&GetLangInfo,
2067             NOTES => q{
2068             SVG (Scalable Vector Graphics) image tags. By default, only the top-level
2069             SVG and Metadata tags are extracted from these images, but all graphics tags
2070             may be extracted by setting the Unknown option to 2 (-U on the command
2071             line). The SVG tags are not part of XMP as such, but are included with the
2072             XMP module for convenience. (see L)
2073             },
2074             version => 'SVGVersion',
2075             id => 'ID',
2076             metadataId => 'MetadataID',
2077             width => {
2078             Name => 'ImageWidth',
2079             ValueConv => '$val =~ s/px$//; $val',
2080             },
2081             height => {
2082             Name => 'ImageHeight',
2083             ValueConv => '$val =~ s/px$//; $val',
2084             },
2085             );
2086              
2087             # table to add tags in other namespaces
2088             %Image::ExifTool::XMP::otherSVG = (
2089             GROUPS => { 0 => 'SVG', 2 => 'Unknown' },
2090             LANG_INFO => \&GetLangInfo,
2091             NAMESPACE => undef, # variable namespace
2092             );
2093              
2094             #------------------------------------------------------------------------------
2095             # Generate crd tags
2096             # Inputs: 0) tag table ref
2097             sub Init_crd($)
2098             {
2099 12     12 0 31 my $tagTablePtr = shift;
2100             # import tags from CRS namespace
2101 12         46 my $crsTable = GetTagTable('Image::ExifTool::XMP::crs');
2102 12         26 my $tag;
2103 12         49 foreach $tag (Image::ExifTool::TagTableKeys($crsTable)) {
2104 3024         3414 my $crsInfo = $$crsTable{$tag};
2105 3024         9938 my $tagInfo = $$tagTablePtr{$tag} = { %$crsInfo };
2106 3024 50       5508 $$tagInfo{Groups} = { 0 => 'XMP', 1 => 'XMP-crd' , 2 => $$crsInfo{Groups}{2} } if $$crsInfo{Groups};
2107             }
2108             }
2109              
2110              
2111             1; #end
2112              
2113             __END__