JezK
Edit File: XMP2.pl
#------------------------------------------------------------------------------ # File: XMP2.pl # # Description: Additional XMP namespace definitions # # Revisions: 10/12/2008 - P. Harvey Created # # References: 1) PLUS - http://ns.useplus.org/ # 2) PRISM - http://www.prismstandard.org/ # 3) http://www.portfoliofaq.com/pfaq/v7mappings.htm # 5) http://creativecommons.org/technology/xmp # --> changed to http://wiki.creativecommons.org/Companion_File_metadata_specification (2007/12/21) # 6) http://www.optimasc.com/products/fileid/xmp-extensions.pdf # 9) http://www.w3.org/TR/SVG11/ # 11) http://www.extensis.com/en/support/kb_article.jsp?articleNumber=6102211 # 12) XMPSpecificationPart3_May2013, page 58 #------------------------------------------------------------------------------ package Image::ExifTool::XMP; use strict; use Image::ExifTool qw(:Utils); use Image::ExifTool::XMP; # structure definitions my %sCuePointParam = ( STRUCT_NAME => 'CuePointParam', NAMESPACE => 'xmpDM', key => { }, value => { }, ); my %sMarker = ( STRUCT_NAME => 'Marker', NAMESPACE => 'xmpDM', comment => { }, duration => { }, location => { }, name => { }, startTime => { }, target => { }, type => { }, # added Oct 2008 cuePointParams => { Struct => \%sCuePointParam, List => 'Seq' }, cuePointType=> { }, probability => { Writable => 'real' }, speaker => { }, ); my %sTime = ( STRUCT_NAME => 'Time', NAMESPACE => 'xmpDM', scale => { Writable => 'rational' }, value => { Writable => 'integer' }, ); my %sTimecode = ( STRUCT_NAME => 'Timecode', NAMESPACE => 'xmpDM', timeFormat => { PrintConv => { '24Timecode' => '24 fps', '25Timecode' => '25 fps', '2997DropTimecode' => '29.97 fps (drop)', '2997NonDropTimecode' => '29.97 fps (non-drop)', '30Timecode' => '30 fps', '50Timecode' => '50 fps', '5994DropTimecode' => '59.94 fps (drop)', '5994NonDropTimecode' => '59.94 fps (non-drop)', '60Timecode' => '60 fps', '23976Timecode' => '23.976 fps', }, }, timeValue => { }, value => { Writable => 'integer' }, ); # XMP Dynamic Media namespace properties (xmpDM) %Image::ExifTool::XMP::xmpDM = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-xmpDM', 2 => 'Image' }, NAMESPACE => 'xmpDM', NOTES => 'XMP Dynamic Media namespace tags.', absPeakAudioFilePath=> { }, album => { }, altTapeName => { }, altTimecode => { Struct => \%sTimecode }, artist => { Avoid => 1, Groups => { 2 => 'Author' } }, audioModDate => { Groups => { 2 => 'Time' }, %dateTimeInfo }, audioSampleRate => { Writable => 'integer' }, audioSampleType => { PrintConv => { '8Int' => '8-bit integer', '16Int' => '16-bit integer', '24Int' => '24-bit integer', '32Int' => '32-bit integer', '32Float' => '32-bit float', 'Compressed' => 'Compressed', 'Packed' => 'Packed', 'Other' => 'Other', }, }, audioChannelType => { PrintConv => { 'Mono' => 'Mono', 'Stereo' => 'Stereo', '5.1' => '5.1', '7.1' => '7.1', '16 Channel' => '16 Channel', 'Other' => 'Other', }, }, audioCompressor => { }, beatSpliceParams => { Struct => { STRUCT_NAME => 'BeatSpliceStretch', NAMESPACE => 'xmpDM', riseInDecibel => { Writable => 'real' }, riseInTimeDuration => { Struct => \%sTime }, useFileBeatsMarker => { Writable => 'boolean' }, }, }, cameraAngle => { }, cameraLabel => { }, cameraModel => { }, cameraMove => { }, client => { }, comment => { Name => 'DMComment' }, composer => { Groups => { 2 => 'Author' } }, contributedMedia => { Struct => { STRUCT_NAME => 'Media', NAMESPACE => 'xmpDM', duration => { Struct => \%sTime }, managed => { Writable => 'boolean' }, path => { }, startTime => { Struct => \%sTime }, track => { }, webStatement=> { }, }, List => 'Bag', }, copyright => { Avoid => 1, Groups => { 2 => 'Author' } }, # (deprecated) director => { }, directorPhotography => { }, discNumber => { }, #12 duration => { Struct => \%sTime }, engineer => { }, fileDataRate => { Writable => 'rational' }, genre => { }, good => { Writable => 'boolean' }, instrument => { }, introTime => { Struct => \%sTime }, key => { PrintConvColumns => 3, PrintConv => { 'C' => 'C', 'C#' => 'C#', 'D' => 'D', 'D#' => 'D#', 'E' => 'E', 'F' => 'F', 'F#' => 'F#', 'G' => 'G', 'G#' => 'G#', 'A' => 'A', 'A#' => 'A#', 'B' => 'B', }, }, logComment => { }, loop => { Writable => 'boolean' }, lyrics => { }, #12 numberOfBeats => { Writable => 'real' }, markers => { Struct => \%sMarker, List => 'Seq' }, metadataModDate => { Groups => { 2 => 'Time' }, %dateTimeInfo }, outCue => { Struct => \%sTime }, partOfCompilation=>{ }, #12 projectName => { }, projectRef => { Struct => { STRUCT_NAME => 'ProjectLink', NAMESPACE => 'xmpDM', path => { }, type => { PrintConv => { movie => 'Movie', still => 'Still Image', audio => 'Audio', custom => 'Custom', }, }, }, }, pullDown => { PrintConvColumns => 2, PrintConv => { 'WSSWW' => 'WSSWW', 'SSWWW' => 'SSWWW', 'SWWWS' => 'SWWWS', 'WWWSS' => 'WWWSS', 'WWSSW' => 'WWSSW', 'WWWSW' => 'WWWSW', 'WWSWW' => 'WWSWW', 'WSWWW' => 'WSWWW', 'SWWWW' => 'SWWWW', 'WWWWS' => 'WWWWS', }, }, relativePeakAudioFilePath => { }, relativeTimestamp => { Struct => \%sTime }, releaseDate => { Groups => { 2 => 'Time' }, %dateTimeInfo }, resampleParams => { Struct => { STRUCT_NAME => 'ResampleStretch', NAMESPACE => 'xmpDM', quality => { PrintConv => { Low => 'Low', Medium => 'Medium', High => 'High' } }, }, }, scaleType => { PrintConv => { Major => 'Major', Minor => 'Minor', Both => 'Both', Neither => 'Neither', }, }, scene => { Avoid => 1 }, shotDate => { Groups => { 2 => 'Time' }, %dateTimeInfo }, shotDay => { }, shotLocation => { }, shotName => { }, shotNumber => { }, shotSize => { }, speakerPlacement=> { }, startTimecode => { Struct => \%sTimecode }, stretchMode => { PrintConv => { 'Fixed length' => 'Fixed length', 'Time-Scale' => 'Time-Scale', 'Resample' => 'Resample', 'Beat Splice' => 'Beat Splice', 'Hybrid' => 'Hybrid', }, }, takeNumber => { Writable => 'integer' }, tapeName => { }, tempo => { Writable => 'real' }, timeScaleParams => { Struct => { STRUCT_NAME => 'TimeScaleStretch', NAMESPACE => 'xmpDM', frameOverlappingPercentage => { Writable => 'real' }, frameSize => { Writable => 'real' }, quality => { PrintConv => { Low => 'Low', Medium => 'Medium', High => 'High' } }, }, }, timeSignature => { PrintConvColumns => 3, PrintConv => { '2/4' => '2/4', '3/4' => '3/4', '4/4' => '4/4', '5/4' => '5/4', '7/4' => '7/4', '6/8' => '6/8', '9/8' => '9/8', '12/8'=> '12/8', 'other' => 'other', }, }, trackNumber => { Writable => 'integer' }, Tracks => { Struct => { STRUCT_NAME => 'Track', NAMESPACE => 'xmpDM', frameRate => { }, markers => { Struct => \%sMarker, List => 'Seq' }, trackName => { }, trackType => { }, }, List => 'Bag', }, videoAlphaMode => { PrintConv => { 'straight' => 'Straight', 'pre-multiplied', => 'Pre-multiplied', 'none' => 'None', }, }, videoAlphaPremultipleColor => { Struct => \%sColorant }, videoAlphaUnityIsTransparent => { Writable => 'boolean' }, videoColorSpace => { PrintConv => { 'sRGB' => 'sRGB', 'CCIR-601' => 'CCIR-601', 'CCIR-709' => 'CCIR-709', }, }, videoCompressor => { }, videoFieldOrder => { PrintConv => { Upper => 'Upper', Lower => 'Lower', Progressive => 'Progressive', }, }, videoFrameRate => { }, videoFrameSize => { Struct => \%sDimensions }, videoModDate => { Groups => { 2 => 'Time' }, %dateTimeInfo }, videoPixelAspectRatio => { Writable => 'rational' }, videoPixelDepth => { PrintConv => { '8Int' => '8-bit integer', '16Int' => '16-bit integer', '24Int' => '24-bit integer', '32Int' => '32-bit integer', '32Float' => '32-bit float', 'Other' => 'Other', }, }, ); #------------------------------------------------------------------------------ # PLUS vocabulary conversions my %plusVocab = ( ValueConv => '$val =~ s{http://ns.useplus.org/ldf/vocab/}{}; $val', ValueConvInv => '"http://ns.useplus.org/ldf/vocab/$val"', ); # PLUS License Data Format 1.2.0 structures # (this seems crazy to me -- why did they define different ID/Name structures # for each field rather than just re-using the same structure?) my %plusLicensee = ( STRUCT_NAME => 'Licensee', NAMESPACE => 'plus', TYPE => 'plus:LicenseeDetail', LicenseeID => { }, LicenseeName=> { }, ); my %plusEndUser = ( STRUCT_NAME => 'EndUser', NAMESPACE => 'plus', TYPE => 'plus:EndUserDetail', EndUserID => { }, EndUserName => { }, ); my %plusLicensor = ( STRUCT_NAME => 'Licensor', NAMESPACE => 'plus', TYPE => 'plus:LicensorDetail', LicensorID => { }, LicensorName => { }, LicensorStreetAddress => { }, LicensorExtendedAddress => { }, LicensorCity => { }, LicensorRegion => { }, LicensorPostalCode => { }, LicensorCountry => { }, LicensorTelephoneType1 => { %plusVocab, PrintConv => { 'work' => 'Work', 'cell' => 'Cell', 'fax' => 'FAX', 'home' => 'Home', 'pager' => 'Pager', }, }, LicensorTelephone1 => { }, LicensorTelephoneType2 => { %plusVocab, PrintConv => { 'work' => 'Work', 'cell' => 'Cell', 'fax' => 'FAX', 'home' => 'Home', 'pager' => 'Pager', }, }, LicensorTelephone2 => { }, LicensorEmail => { }, LicensorURL => { }, ); my %plusCopyrightOwner = ( STRUCT_NAME => 'CopyrightOwner', NAMESPACE => 'plus', TYPE => 'plus:CopyrightOwnerDetail', CopyrightOwnerID => { }, CopyrightOwnerName => { }, ); my %plusImageCreator = ( STRUCT_NAME => 'ImageCreator', NAMESPACE => 'plus', TYPE => 'plus:ImageCreatorDetail', ImageCreatorID => { }, ImageCreatorName => { }, ); my %plusImageSupplier = ( STRUCT_NAME => 'ImageSupplier', NAMESPACE => 'plus', TYPE => 'plus:ImageSupplierDetail', ImageSupplierID => { }, ImageSupplierName => { }, ); # PLUS License Data Format 1.2.0 (plus) (ref 1) %Image::ExifTool::XMP::plus = ( %xmpTableDefaults, GROUPS => { 0 => 'XMP', 1 => 'XMP-plus', 2 => 'Author' }, NAMESPACE => 'plus', NOTES => q{ PLUS License Data Format 1.2.0 namespace tags. Note that all controlled-vocabulary tags in this table (ie. tags with a fixed set of values) have raw values which begin with "http://ns.useplus.org/ldf/vocab/", but to reduce clutter this prefix has been removed from the values shown below. (see L<http://ns.useplus.org/>) }, Version => { Name => 'PLUSVersion' }, Licensee => { FlatName => '', Struct => \%plusLicensee, List => 'Seq', }, EndUser => { FlatName => '', Struct => \%plusEndUser, List => 'Seq', }, Licensor => { FlatName => '', Struct => \%plusLicensor, List => 'Seq', }, LicensorNotes => { Writable => 'lang-alt' }, MediaSummaryCode => { }, LicenseStartDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, LicenseEndDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, MediaConstraints => { Writable => 'lang-alt' }, RegionConstraints => { Writable => 'lang-alt' }, ProductOrServiceConstraints => { Writable => 'lang-alt' }, ImageFileConstraints => { List => 'Bag', %plusVocab, PrintConv => { 'IF-MFN' => 'Maintain File Name', 'IF-MID' => 'Maintain ID in File Name', 'IF-MMD' => 'Maintain Metadata', 'IF-MFT' => 'Maintain File Type', }, }, ImageAlterationConstraints => { List => 'Bag', %plusVocab, PrintConv => { 'AL-CRP' => 'No Cropping', 'AL-FLP' => 'No Flipping', 'AL-RET' => 'No Retouching', 'AL-CLR' => 'No Colorization', 'AL-DCL' => 'No De-Colorization', 'AL-MRG' => 'No Merging', }, }, ImageDuplicationConstraints => { %plusVocab, PrintConv => { 'DP-NDC' => 'No Duplication Constraints', 'DP-LIC' => 'Duplication Only as Necessary Under License', 'DP-NOD' => 'No Duplication', }, }, ModelReleaseStatus => { %plusVocab, PrintConv => { 'MR-NON' => 'None', 'MR-NAP' => 'Not Applicable', 'MR-UMR' => 'Unlimited Model Releases', 'MR-LMR' => 'Limited or Incomplete Model Releases', }, }, ModelReleaseID => { List => 'Bag' }, MinorModelAgeDisclosure => { %plusVocab, PrintConv => { 'AG-UNK' => 'Age Unknown', 'AG-A25' => 'Age 25 or Over', 'AG-A24' => 'Age 24', 'AG-A23' => 'Age 23', 'AG-A22' => 'Age 22', 'AG-A21' => 'Age 21', 'AG-A20' => 'Age 20', 'AG-A19' => 'Age 19', 'AG-A18' => 'Age 18', 'AG-A17' => 'Age 17', 'AG-A16' => 'Age 16', 'AG-A15' => 'Age 15', 'AG-U14' => 'Age 14 or Under', }, }, PropertyReleaseStatus => { %plusVocab, PrintConv => { 'PR-NON' => 'None', 'PR-NAP' => 'Not Applicable', 'PR-UPR' => 'Unlimited Property Releases', 'PR-LPR' => 'Limited or Incomplete Property Releases', }, }, PropertyReleaseID => { List => 'Bag' }, OtherConstraints => { Writable => 'lang-alt' }, CreditLineRequired => { %plusVocab, PrintConv => { 'CR-NRQ' => 'Not Required', 'CR-COI' => 'Credit on Image', 'CR-CAI' => 'Credit Adjacent To Image', 'CR-CCA' => 'Credit in Credits Area', }, }, AdultContentWarning => { %plusVocab, PrintConv => { 'CW-NRQ' => 'Not Required', 'CW-AWR' => 'Adult Content Warning Required', 'CW-UNK' => 'Unknown', }, }, OtherLicenseRequirements => { Writable => 'lang-alt' }, TermsAndConditionsText => { Writable => 'lang-alt' }, TermsAndConditionsURL => { }, OtherConditions => { Writable => 'lang-alt' }, ImageType => { %plusVocab, PrintConv => { 'TY-PHO' => 'Photographic Image', 'TY-ILL' => 'Illustrated Image', 'TY-MCI' => 'Multimedia or Composited Image', 'TY-VID' => 'Video', 'TY-OTR' => 'Other', }, }, LicensorImageID => { }, FileNameAsDelivered => { }, ImageFileFormatAsDelivered => { %plusVocab, PrintConv => { 'FF-JPG' => 'JPEG Interchange Formats (JPG, JIF, JFIF)', 'FF-TIF' => 'Tagged Image File Format (TIFF)', 'FF-GIF' => 'Graphics Interchange Format (GIF)', 'FF-RAW' => 'Proprietary RAW Image Format', 'FF-DNG' => 'Digital Negative (DNG)', 'FF-EPS' => 'Encapsulated PostScript (EPS)', 'FF-BMP' => 'Windows Bitmap (BMP)', 'FF-PSD' => 'Photoshop Document (PSD)', 'FF-PIC' => 'Macintosh Picture (PICT)', 'FF-PNG' => 'Portable Network Graphics (PNG)', 'FF-WMP' => 'Windows Media Photo (HD Photo)', 'FF-OTR' => 'Other', }, }, ImageFileSizeAsDelivered => { %plusVocab, PrintConv => { 'SZ-U01' => 'Up to 1 MB', 'SZ-U10' => 'Up to 10 MB', 'SZ-U30' => 'Up to 30 MB', 'SZ-U50' => 'Up to 50 MB', 'SZ-G50' => 'Greater than 50 MB', }, }, CopyrightStatus => { %plusVocab, PrintConv => { 'CS-PRO' => 'Protected', 'CS-PUB' => 'Public Domain', 'CS-UNK' => 'Unknown', }, }, CopyrightRegistrationNumber => { }, FirstPublicationDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, CopyrightOwner => { FlatName => '', Struct => \%plusCopyrightOwner, List => 'Seq', }, CopyrightOwnerImageID => { }, ImageCreator => { FlatName => '', Struct => \%plusImageCreator, List => 'Seq', }, ImageCreatorImageID => { }, ImageSupplier => { FlatName => '', Struct => \%plusImageSupplier, List => 'Seq', }, ImageSupplierImageID => { }, LicenseeImageID => { }, LicenseeImageNotes => { Writable => 'lang-alt' }, OtherImageInfo => { Writable => 'lang-alt' }, LicenseID => { }, LicensorTransactionID => { List => 'Bag' }, LicenseeTransactionID => { List => 'Bag' }, LicenseeProjectReference=> { List => 'Bag' }, LicenseTransactionDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, Reuse => { %plusVocab, PrintConv => { 'RE-REU' => 'Repeat Use', 'RE-NAP' => 'Not Applicable', }, }, OtherLicenseDocuments => { List => 'Bag' }, OtherLicenseInfo => { Writable => 'lang-alt' }, # Note: these are Bag's of lang-alt lists -- a nested list tag! Custom1 => { List => 'Bag', Writable => 'lang-alt' }, Custom2 => { List => 'Bag', Writable => 'lang-alt' }, Custom3 => { List => 'Bag', Writable => 'lang-alt' }, Custom4 => { List => 'Bag', Writable => 'lang-alt' }, Custom5 => { List => 'Bag', Writable => 'lang-alt' }, Custom6 => { List => 'Bag', Writable => 'lang-alt' }, Custom7 => { List => 'Bag', Writable => 'lang-alt' }, Custom8 => { List => 'Bag', Writable => 'lang-alt' }, Custom9 => { List => 'Bag', Writable => 'lang-alt' }, Custom10 => { List => 'Bag', Writable => 'lang-alt' }, ); #------------------------------------------------------------------------------ # PRISM # # NOTE: The "Avoid" flag is set for all PRISM tags # my %obsolete = ( # Notes => 'obsolete in 2.0', # ValueConvInv => sub { # my ($val, $self) = @_; # unless ($self->Options('IgnoreMinorErrors')) { # warn "Warning: [minor] Attempt to write obsolete tag\n"; # return undef; # } # return $val; # } # ); # Publishing Requirements for Industry Standard Metadata 2.1 (prism) (ref 2) %Image::ExifTool::XMP::prism = ( %xmpTableDefaults, GROUPS => { 0 => 'XMP', 1 => 'XMP-prism', 2 => 'Document' }, NAMESPACE => 'prism', NOTES => q{ Publishing Requirements for Industry Standard Metadata 2.1 namespace tags. (see L<http://www.prismstandard.org/>) }, aggregationType => { List => 'Bag' }, alternateTitle => { List => 'Bag' }, byteCount => { Writable => 'integer' }, channel => { List => 'Bag' }, complianceProfile=>{ PrintConv => { three => 'Three' } }, copyright => { Groups => { 2 => 'Author' } }, corporateEntity => { List => 'Bag' }, coverDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, coverDisplayDate=> { }, creationDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, dateRecieved => { %dateTimeInfo, Groups => { 2 => 'Time'} }, distributor => { }, doi => { Name => 'DOI', Description => 'Digital Object Identifier' }, edition => { }, eIssn => { }, embargoDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, endingPage => { }, event => { List => 'Bag' }, expirationDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, genre => { List => 'Bag' }, hasAlternative => { List => 'Bag' }, hasCorrection => { }, hasPreviousVersion => { }, hasTranslation => { List => 'Bag' }, industry => { List => 'Bag' }, isCorrectionOf => { List => 'Bag' }, issn => { Name => 'ISSN' }, issueIdentifier => { }, issueName => { }, isTranslationOf => { }, keyword => { List => 'Bag' }, killDate => { %dateTimeInfo, Groups => { 2 => 'Time'} }, location => { List => 'Bag' }, # metadataContainer => { }, (not valid for PRISM XMP) modificationDate=> { %dateTimeInfo, Groups => { 2 => 'Time'} }, number => { }, object => { List => 'Bag' }, organization => { List => 'Bag' }, originPlatform => { List => 'Bag', PrintConv => { email => 'E-Mail', mobile => 'Mobile', broadcast => 'Broadcast', web => 'Web', 'print' => 'Print', recordableMedia => 'Recordable Media', other => 'Other', }, }, pageRange => { List => 'Bag' }, person => { }, publicationDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, publicationName => { }, rightsAgent => { }, section => { }, startingPage => { }, subsection1 => { }, subsection2 => { }, subsection3 => { }, subsection4 => { }, teaser => { List => 'Bag' }, ticker => { List => 'Bag' }, timePeriod => { }, url => { Name => 'URL', List => 'Bag' }, versionIdentifier => { }, volume => { }, wordCount => { Writable => 'integer' }, # new in PRISM 2.1 isbn => { Name => 'ISBN' }, # tags that existed in version 1.3 # category => { %obsolete, List => 'Bag' }, # hasFormat => { %obsolete, List => 'Bag' }, # hasPart => { %obsolete, List => 'Bag' }, # isFormatOf => { %obsolete, List => 'Bag' }, # isPartOf => { %obsolete }, # isReferencedBy => { %obsolete, List => 'Bag' }, # isRequiredBy => { %obsolete, List => 'Bag' }, # isVersionOf => { %obsolete }, # objectTitle => { %obsolete, List => 'Bag' }, # receptionDate => { %obsolete }, # references => { %obsolete, List => 'Bag' }, # requires => { %obsolete, List => 'Bag' }, # tags in older versions # page # contentLength # creationTime # expirationTime # hasVersion # isAlternativeFor # isBasedOn # isBasisFor # modificationTime # publicationTime # receptionTime # releaseTime ); # PRISM Rights Language 2.1 namespace (prl) (ref 2) %Image::ExifTool::XMP::prl = ( %xmpTableDefaults, GROUPS => { 0 => 'XMP', 1 => 'XMP-prl', 2 => 'Document' }, NAMESPACE => 'prl', NOTES => q{ PRISM Rights Language 2.1 namespace tags. (see L<http://www.prismstandard.org/>) }, geography => { List => 'Bag' }, industry => { List => 'Bag' }, usage => { List => 'Bag' }, ); # PRISM Usage Rights 2.1 namespace (prismusagerights) (ref 2) %Image::ExifTool::XMP::pur = ( %xmpTableDefaults, GROUPS => { 0 => 'XMP', 1 => 'XMP-pur', 2 => 'Document' }, NAMESPACE => 'pur', NOTES => q{ Prism Usage Rights 2.1 namespace tags. (see L<http://www.prismstandard.org/>) }, adultContentWarning => { List => 'Bag' }, agreement => { List => 'Bag' }, copyright => { Writable => 'lang-alt', Groups => { 2 => 'Author' } }, creditLine => { List => 'Bag' }, embargoDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, exclusivityEndDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, expirationDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, imageSizeRestriction=> { }, optionEndDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, permissions => { List => 'Bag' }, restrictions => { List => 'Bag' }, reuseProhibited => { Writable => 'boolean' }, rightsAgent => { }, rightsOwner => { }, usageFee => { List => 'Bag' }, ); # DICOM namespace properties (DICOM) (ref PH, written by CS3) %Image::ExifTool::XMP::DICOM = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-DICOM', 2 => 'Image' }, NAMESPACE => 'DICOM', NOTES => q{ DICOM namespace tags. These XMP tags allow some DICOM information to be stored in files of other than DICOM format. See the L<DICOM Tags documentation|Image::ExifTool::TagNames/DICOM Tags> for a list of tags available in DICOM-format files. }, # change some tag names to correspond with DICOM tags PatientName => { }, PatientID => { }, PatientSex => { }, PatientDOB => { Name => 'PatientBirthDate', Groups => { 2 => 'Time' }, %dateTimeInfo, }, StudyID => { }, StudyPhysician => { }, StudyDateTime => { Groups => { 2 => 'Time' }, %dateTimeInfo }, StudyDescription => { }, SeriesNumber => { }, SeriesModality => { }, SeriesDateTime => { Groups => { 2 => 'Time' }, %dateTimeInfo }, SeriesDescription => { }, EquipmentInstitution => { }, EquipmentManufacturer => { }, ); # PixelLive namespace properties (PixelLive) (ref 3) %Image::ExifTool::XMP::PixelLive = ( GROUPS => { 1 => 'XMP-PixelLive', 2 => 'Image' }, NAMESPACE => 'PixelLive', NOTES => q{ PixelLive namespace tags. These tags are not writable becase they are very uncommon and I haven't been able to locate a reference which gives the namespace URI. }, AUTHOR => { Name => 'Author', Avoid => 1, Groups => { 2 => 'Author' } }, COMMENTS => { Name => 'Comments', Avoid => 1 }, COPYRIGHT => { Name => 'Copyright',Avoid => 1, Groups => { 2 => 'Author' } }, DATE => { Name => 'Date', Avoid => 1, Groups => { 2 => 'Time' } }, GENRE => { Name => 'Genre', Avoid => 1 }, TITLE => { Name => 'Title', Avoid => 1 }, ); # Extensis Portfolio tags (extensis) (ref 11) %Image::ExifTool::XMP::extensis = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-extensis', 2 => 'Image' }, NAMESPACE => 'extensis', NOTES => 'Tags used by Extensis Portfolio.', Approved => { Writable => 'boolean' }, ApprovedBy => { }, ClientName => { }, JobName => { }, JobStatus => { }, RoutedTo => { }, RoutingNotes => { }, WorkToDo => { }, ); # IDimager structures (ref PH) my %sTagStruct; %sTagStruct = ( STRUCT_NAME => 'TagStructure', NAMESPACE => 'ics', LabelName => { }, Reference => { }, ParentReference => { }, SubLabels => { Struct => \%sTagStruct, List => 'Bag' }, ); my %sSubVersion = ( STRUCT_NAME => 'SubVersion', NAMESPACE => 'ics', VersRef => { }, FileName => { }, ); # IDimager namespace (ics) (ref PH) %Image::ExifTool::XMP::ics = ( %xmpTableDefaults, GROUPS => { 0 => 'XMP', 1 => 'XMP-ics', 2 => 'Image' }, NAMESPACE => 'ics', NOTES => q{ Tags used by IDimager. Nested TagStructure structures are unrolled to an arbitrary depth of 6 to avoid infinite recursion. }, ImageRef => { }, TagStructure => { Struct => \%sTagStruct, List => 'Bag' }, TagStructureLabelName => { Name => 'LabelName1', Flat => 1 }, TagStructureReference => { Name => 'Reference1', Flat => 1 }, TagStructureSubLabels => { Name => 'SubLables1', Flat => 1 }, TagStructureParentReference => { Name => 'ParentReference1', Flat => 1 }, TagStructureSubLabelsLabelName => { Name => 'LabelName2', Flat => 1 }, TagStructureSubLabelsReference => { Name => 'Reference2', Flat => 1 }, TagStructureSubLabelsSubLabels => { Name => 'SubLables2', Flat => 1 }, TagStructureSubLabelsParentReference => { Name => 'ParentReference2', Flat => 1 }, TagStructureSubLabelsSubLabelsLabelName => { Name => 'LabelName3', Flat => 1 }, TagStructureSubLabelsSubLabelsReference => { Name => 'Reference3', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabels => { Name => 'SubLables3', Flat => 1 }, TagStructureSubLabelsSubLabelsParentReference => { Name => 'ParentReference3', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName4', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference4', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels4', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference4', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName5', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference5', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels5', Flat => 1, NoSubStruct => 1 }, # break infinite recursion TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference5', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName6', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference6', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference6', Flat => 1 }, SubVersions => { Struct => \%sSubVersion, List => 'Bag' }, SubVersionsVersRef => { Name => 'SubVersionReference', Flat => 1 }, SubVersionsFileName => { Name => 'SubVersionFileName', Flat => 1 }, ); # ACDSee namespace (acdsee) (ref PH) %Image::ExifTool::XMP::acdsee = ( %xmpTableDefaults, GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee', 2 => 'Image' }, NAMESPACE => 'acdsee', NOTES => q{ ACD Systems ACDSee namespace tags. (A note to software developers: Re-inventing your own private tags instead of using the equivalent tags in standard XMP namespaces defeats one of the most valuable features of metadata: interoperability. Your applications mumble to themselves instead of speaking out for the rest of the world to hear.) }, author => { Avoid => 1, Groups => { 2 => 'Author' } }, caption => { Avoid => 1 }, categories => { Avoid => 1 }, datetime => { Name => 'DateTime', Avoid => 1, Groups => { 2 => 'Time' }, %dateTimeInfo }, keywords => { Avoid => 1, List => 'Bag' }, notes => { Avoid => 1 }, rating => { Avoid => 1, Writable => 'real' }, # integer? tagged => { Avoid => 1, Writable => 'boolean' }, rawrppused => { Writable => 'boolean' }, rpp => { Name => 'RPP', Writable => 'lang-alt', Notes => 'raw processing settings in XML format', Binary => 1, }, dpp => { Name => 'DPP', Writable => 'lang-alt', Notes => 'newer version of XML raw processing settings', Binary => 1, }, ); # Picture Licensing Universal System namespace properties (xmpPLUS) %Image::ExifTool::XMP::xmpPLUS = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-xmpPLUS', 2 => 'Author' }, NAMESPACE => 'xmpPLUS', NOTES => 'XMP Picture Licensing Universal System (PLUS) namespace tags.', CreditLineReq => { Writable => 'boolean' }, ReuseAllowed => { Writable => 'boolean' }, ); # Creative Commons namespace properties (cc) (ref 5) %Image::ExifTool::XMP::cc = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-cc', 2 => 'Author' }, NAMESPACE => 'cc', NOTES => q{ Creative Commons namespace tags. Note that the CC specification for XMP is non-existent, so ExifTool must make some assumptions about the format of the specific properties in XMP (see L<http://creativecommons.org/ns>). }, # Work properties license => { Resource => 1 }, attributionName => { }, attributionURL => { Resource => 1 }, morePermissions => { Resource => 1 }, useGuidelines => { Resource => 1 }, # License properties permits => { List => 'Bag', Resource => 1, PrintConv => { 'cc:Sharing' => 'Sharing', 'cc:DerivativeWorks' => 'Derivative Works', 'cc:Reproduction' => 'Reproduction', 'cc:Distribution' => 'Distribution', }, }, requires => { List => 'Bag', Resource => 1, PrintConv => { 'cc:Copyleft' => 'Copyleft', 'cc:LesserCopyleft' => 'Lesser Copyleft', 'cc:SourceCode' => 'Source Code', 'cc:ShareAlike' => 'Share Alike', 'cc:Notice' => 'Notice', 'cc:Attribution' => 'Attribution', }, }, prohibits => { List => 'Bag', Resource => 1, PrintConv => { 'cc:HighIncomeNationUse' => 'High Income Nation Use', 'cc:CommercialUse' => 'Commercial Use', }, }, jurisdiction => { Resource => 1 }, legalcode => { Name => 'LegalCode', Resource => 1 }, deprecatedOn => { %dateTimeInfo, Groups => { 2 => 'Time' } }, ); # Description Explorer namespace properties (dex) (ref 6) %Image::ExifTool::XMP::dex = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-dex', 2 => 'Image' }, NAMESPACE => 'dex', NOTES => q{ Description Explorer namespace tags. These tags are not very common. The Source and Rating tags are avoided when writing due to name conflicts with other XMP tags. (see L<http://www.optimasc.com/products/fileid/>) }, crc32 => { Name => 'CRC32', Writable => 'integer' }, source => { Avoid => 1 }, shortdescription => { Name => 'ShortDescription', Writable => 'lang-alt', }, licensetype => { Name => 'LicenseType', PrintConv => { unknown => 'Unknown', shareware => 'Shareware', freeware => 'Freeware', adware => 'Adware', demo => 'Demo', commercial => 'Commercial', 'public domain' => 'Public Domain', 'open source' => 'Open Source', }, }, revision => { }, rating => { Avoid => 1 }, os => { Name => 'OS', Writable => 'integer' }, ffid => { Name => 'FFID' }, ); # iView MediaPro namespace properties (mediapro) (ref PH) %Image::ExifTool::XMP::MediaPro = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-mediapro', 2 => 'Image' }, NAMESPACE => 'mediapro', NOTES => 'iView MediaPro namespace tags.', Event => { Avoid => 1, Notes => 'avoided due to conflict with XMP-iptcExt:Event', }, Location => { Avoid => 1, Groups => { 2 => 'Location' }, Notes => 'avoided due to conflict with XMP-iptcCore:Location', }, Status => { }, People => { List => 'Bag' }, UserFields => { List => 'Bag' }, CatalogSets => { List => 'Bag' }, ); # Microsoft ExpressionMedia namespace properties (expressionmedia) # (ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4235.0.html) %Image::ExifTool::XMP::ExpressionMedia = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-expressionmedia', 2 => 'Image' }, NAMESPACE => 'expressionmedia', NOTES => q{ Microsoft Expression Media namespace tags. These tags are avoided when writing due to name conflicts with tags in other schemas. }, Event => { Avoid => 1 }, Status => { Avoid => 1 }, People => { Avoid => 1, List => 'Bag' }, CatalogSets => { Avoid => 1, List => 'Bag' }, ); # DigiKam namespace tags (ref PH) %Image::ExifTool::XMP::digiKam = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-digiKam', 2 => 'Image' }, NAMESPACE => 'digiKam', NOTES => 'DigiKam namespace tags.', CaptionsAuthorNames => { Writable => 'lang-alt' }, CaptionsDateTimeStamps => { Writable => 'lang-alt', Groups => { 2 => 'Time' } }, TagsList => { List => 'Seq' }, ColorLabel => { }, PickLabel => { }, ); # SWF namespace tags (ref PH) %Image::ExifTool::XMP::swf = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-swf', 2 => 'Image' }, NAMESPACE => 'swf', NOTES => 'Adobe SWF namespace tags.', type => { Avoid => 1 }, bgalpha => { Name => 'BackgroundAlpha', Writable => 'integer' }, forwardlock => { Name => 'ForwardLock', Writable => 'boolean' }, maxstorage => { Name => 'MaxStorage', Writable => 'integer' }, # (CS5) ); # Sony Ericsson cell phone location tags # refs: http://www.opencellid.org/api # http://zonetag.research.yahoo.com/faq_location.php # http://www.cs.columbia.edu/sip/drafts/LIF%20TS%20101%20v2.0.0.pdf %Image::ExifTool::XMP::cell = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-cell', 2 => 'Location' }, NAMESPACE => 'cell', NOTES => 'Location tags written by some Sony Ericsson phones.', mcc => { Name => 'MobileCountryCode' }, mnc => { Name => 'MobileNetworkCode' }, lac => { Name => 'LocationAreaCode' }, cellid => { Name => 'CellTowerID' }, cgi => { Name => 'CellGlobalID' }, r => { Name => 'CellR' }, # (what is this? Radius?) ); # Apple adjustment settings (ref PH) %Image::ExifTool::XMP::aas = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-aas', 2 => 'Image' }, NAMESPACE => 'aas', NOTES => 'Apple Adjustment Settings used by iPhone/iPad.', CropX => { Writable => 'integer', Avoid => 1 }, CropY => { Writable => 'integer', Avoid => 1 }, CropW => { Writable => 'integer', Avoid => 1 }, CropH => { Writable => 'integer', Avoid => 1 }, AffineA => { Writable => 'real' }, AffineB => { Writable => 'real' }, AffineC => { Writable => 'real' }, AffineD => { Writable => 'real' }, AffineX => { Writable => 'real' }, AffineY => { Writable => 'real' }, Vibrance => { Writable => 'real', Avoid => 1 }, Curve0x => { Writable => 'real' }, Curve0y => { Writable => 'real' }, Curve1x => { Writable => 'real' }, Curve1y => { Writable => 'real' }, Curve2x => { Writable => 'real' }, Curve2y => { Writable => 'real' }, Curve3x => { Writable => 'real' }, Curve3y => { Writable => 'real' }, Curve4x => { Writable => 'real' }, Curve4y => { Writable => 'real' }, Shadows => { Writable => 'real', Avoid => 1 }, Highlights => { Writable => 'real', Avoid => 1 }, ); # FastPictureViewer namespace properties (http://www.fastpictureviewer.com/help/#rtfcomments) %Image::ExifTool::XMP::fpv = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-fpv', 2 => 'Image' }, NAMESPACE => 'fpv', NOTES => q{ Fast Picture Viewer tags (see L<http://www.fastpictureviewer.com/help/#rtfcomments>). }, RichTextComment => { }, ); # Apple FaceInfo namespace properties (ref PH) %Image::ExifTool::XMP::apple_fi = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-apple-fi', 2 => 'Image' }, NAMESPACE => 'apple-fi', NOTES => q{ Face information tags written by the Apple iPhone 5 inside the mwg-rs RegionExtensions. }, Timestamp => { Name => 'TimeStamp', Writable => 'integer', # (don't know how to convert this) }, FaceID => { Writable => 'integer' }, AngleInfoRoll => { Writable => 'integer' }, AngleInfoYaw => { Writable => 'integer' }, ConfidenceLevel => { Writable => 'integer' }, ); # Google panorama namespace properties # (ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4569.0.html) %Image::ExifTool::XMP::GPano = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-GPano', 2 => 'Image' }, NAMESPACE => 'GPano', NOTES => q{ Panorama tags written by Google Photosphere. See L<https://developers.google.com/panorama/metadata/> for the specification. }, UsePanoramaViewer => { Writable => 'boolean' }, CaptureSoftware => { }, StitchingSoftware => { }, ProjectionType => { }, PoseHeadingDegrees => { Writable => 'real' }, PosePitchDegrees => { Writable => 'real' }, PoseRollDegrees => { Writable => 'real' }, InitialViewHeadingDegrees => { Writable => 'integer' }, InitialViewPitchDegrees => { Writable => 'integer' }, InitialViewRollDegrees => { Writable => 'integer' }, InitialHorizontalFOVDegrees => { Writable => 'real' }, FirstPhotoDate => { %dateTimeInfo, Groups => { 2 => 'Time' } }, LastPhotoDate => { %dateTimeInfo, Groups => { 2 => 'Time' } }, SourcePhotosCount => { Writable => 'integer' }, ExposureLockUsed => { Writable => 'boolean' }, CroppedAreaImageWidthPixels => { Writable => 'integer' }, CroppedAreaImageHeightPixels => { Writable => 'integer' }, FullPanoWidthPixels => { Writable => 'integer' }, FullPanoHeightPixels => { Writable => 'integer' }, CroppedAreaLeftPixels => { Writable => 'integer' }, CroppedAreaTopPixels => { Writable => 'integer' }, # (the following have been observed, but are not in the specification) LargestValidInteriorRectLeft => { Writable => 'integer' }, LargestValidInteriorRectTop => { Writable => 'integer' }, LargestValidInteriorRectWidth => { Writable => 'integer' }, LargestValidInteriorRectHeight => { Writable => 'integer' }, ); # Getty Images namespace (ref PH) %Image::ExifTool::XMP::GettyImages = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-getty', 2 => 'Image' }, NAMESPACE => 'GettyImagesGIFT', NOTES => q{ The actual Getty Images namespace prefix is "GettyImagesGIFT", which is the prefix recorded in the file, but ExifTool shortens this for the "XMP-getty" family 1 group name. }, Personality => { }, OriginalFilename => { }, ParentMEID => { }, ); # SVG namespace properties (ref 9) %Image::ExifTool::XMP::SVG = ( GROUPS => { 0 => 'SVG', 1 => 'SVG', 2 => 'Image' }, NAMESPACE => 'svg', LANG_INFO => \&GetLangInfo, NOTES => q{ SVG (Scalable Vector Graphics) image tags. By default, only the top-level SVG and Metadata tags are extracted from these images, but all graphics tags may be extracted by setting the Unknown option to 2 (-U on the command line). The SVG tags are not part of XMP as such, but are included with the XMP module for convenience. (see L<http://www.w3.org/TR/SVG11/>) }, version => 'SVGVersion', id => 'ID', metadataId => 'MetadataID', width => 'ImageWidth', height => 'ImageHeight', ); # table to add tags in other namespaces %Image::ExifTool::XMP::otherSVG = ( GROUPS => { 0 => 'SVG', 2 => 'Unknown' }, LANG_INFO => \&GetLangInfo, NAMESPACE => undef, # variable namespace ); # set "Avoid" flag for all PRISM tags my ($table, $key); foreach $table ( \%Image::ExifTool::XMP::prism, \%Image::ExifTool::XMP::prl, \%Image::ExifTool::XMP::pur) { foreach $key (TagTableKeys($table)) { $table->{$key}->{Avoid} = 1; } } 1; #end __END__ =head1 NAME Image::ExifTool::XMP2.pl - Additional XMP namespace definitions =head1 SYNOPSIS This module is loaded automatically by Image::ExifTool when required. =head1 DESCRIPTION This file contains definitions for less common XMP namespaces. =head1 AUTHOR Copyright 2003-2014, Phil Harvey (phil at owl.phy.queensu.ca) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 REFERENCES =over 4 =item L<http://ns.useplus.org/> =item L<http://www.prismstandard.org/> =item L<http://www.portfoliofaq.com/pfaq/v7mappings.htm> =item L<http://creativecommons.org/technology/xmp> =item L<http://www.optimasc.com/products/fileid/xmp-extensions.pdf> =item L<http://www.w3.org/TR/SVG11/> =back =head1 SEE ALSO L<Image::ExifTool::TagNames/XMP Tags>, L<Image::ExifTool(3pm)|Image::ExifTool> =cut