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