- Timestamp:
- 2021-02-26T19:39:51+13:00 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MWG.pm
r24107 r34921 15 15 use Image::ExifTool qw(:DataAccess :Utils); 16 16 use Image::ExifTool::Exif; 17 18 $VERSION = '1.08'; 19 20 # enable MWG strict mode by default 21 # (causes non-standard EXIF, IPTC and XMP to be ignored) 22 $Image::ExifTool::MWG::strict = 1 unless defined $Image::ExifTool::MWG::strict; 17 use Image::ExifTool::XMP; 18 19 $VERSION = '1.24'; 23 20 24 21 sub RecoverTruncatedIPTC($$$); … … 27 24 sub OverwriteStringList($$$$); 28 25 26 my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags 27 29 28 # MWG Composite tags 30 29 %Image::ExifTool::MWG::Composite = ( 31 30 GROUPS => { 0 => 'Composite', 1 => 'MWG', 2 => 'Image' }, 32 31 VARS => { NO_ID => 1 }, 32 WRITE_PROC => \&Image::ExifTool::DummyWriteProc, 33 33 NOTES => q{ 34 The Metadata Working Group (MWG) recommendations provide a set of rules to35 allow certain overlapping EXIF, IPTC and XMP tags to be reconciled when36 reading, and synchronized when writing. The ExifTool MWG module is designed37 to aid in the implementation of these recommendations. (See38 L<http://www.metadataworkinggroup.org/> for the complete MWG technical39 specifications.)40 41 34 The table below lists special Composite tags which are used to access other 42 35 tags based on the MWG 2.0 recommendations. These tags are only accessible 43 when the MWG module is loaded. The MWG module is loaded automatically by44 the exiftool application if MWG is specified as a group for any tag on the45 command line, or manually with the C<-use MWG> option. Via the API, the MWG46 module is loaded with "C<use Image::ExifTool::MWG>".36 when explicitly loaded, but this is done automatically by the exiftool 37 application if MWG is specified as a group for any tag on the command line, 38 or manually with the C<-use MWG> option. Via the API, the MWG Composite 39 tags are loaded by calling "C<Image::ExifTool::MWG::Load()>". 47 40 48 41 When reading, the value of each MWG tag is B<Derived From> the specified … … 59 52 tag is generated when non-standard metadata is encountered. This feature 60 53 may be disabled by setting C<$Image::ExifTool::MWG::strict = 0> in the 61 ExifTool config file(or from your Perl script when using the API). Note54 L<ExifTool config file|../config.html> (or from your Perl script when using the API). Note 62 55 that the behaviour when writing is not changed: ExifTool always creates new 63 56 records only in the standard location, but writes new tags to any 64 57 EXIF/IPTC/XMP records that exist. 65 58 66 A complication of the specification is that although the MWG:Creator 59 Contrary to the EXIF specification, the MWG recommends that EXIF "ASCII" 60 string values be stored as UTF-8. To honour this, the exiftool application 61 sets the default internal EXIF string encoding to "UTF8" when the MWG module 62 is loaded, but via the API this must be done manually by setting the 63 L<CharsetEXIF|../ExifTool.html#CharsetEXIF> option. 64 65 A complication of the MWG specification is that although the MWG:Creator 67 66 property may consist of multiple values, the associated EXIF tag 68 67 (EXIF:Artist) is only a simple string. To resolve this discrepancy the MWG … … 80 79 3 => 'IPTCDigest', 81 80 }, 82 ValueConv => q{81 RawConv => q{ 83 82 return $val[1] if not defined $val[2] or (defined $val[1] and 84 83 (not defined $val[3] or $val[2] eq $val[3])); … … 88 87 WriteCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', 89 88 WriteAlso => { 90 # only write Keywords if IPTC exists ( ie. set EditGroup option)89 # only write Keywords if IPTC exists (eg. set EditGroup option) 91 90 'IPTC:Keywords' => '$opts{EditGroup} = 1; $val', 92 91 'XMP-dc:Subject' => '$val', … … 102 101 4 => 'IPTCDigest', 103 102 }, 104 ValueConv => q{103 RawConv => q{ 105 104 return $val[0] if defined $val[0] and $val[0] !~ /^ *$/; 106 105 return $val[2] if not defined $val[3] or (defined $val[2] and … … 119 118 Description => 'Date/Time Original', 120 119 Groups => { 2 => 'Time' }, 121 Notes => '"creation date of the intellectual content being shown" - MWG', 122 Writable => 1, 123 Desire => { 124 0 => 'EXIF:DateTimeOriginal', 125 1 => 'EXIF:SubSecTimeOriginal', 120 Notes => '"specifies when a photo was taken" - MWG', 121 Writable => 1, 122 Shift => 0, # don't shift this tag 123 Desire => { 124 0 => 'Composite:SubSecDateTimeOriginal', 125 1 => 'EXIF:DateTimeOriginal', 126 126 2 => 'IPTC:DateCreated', 127 127 3 => 'IPTC:TimeCreated', … … 130 130 6 => 'IPTCDigest', 131 131 }, 132 # must check for validity in RawConv to avoid hiding a same-named tag, 133 # but IPTC dates use a ValueConv so we need to derive the value there 134 RawConv => q{ 135 (defined $val[0] or defined $val[1] or $val[2] or 136 (defined $val[4] and (not defined $val[5] or not defined $val[6] 137 or $val[5] eq $val[6]))) ? $val : undef 138 }, 132 139 ValueConv => q{ 133 if (defined $val[0] and $val[0] !~ /^[: ]*$/) { 134 return ($val[1] and $val[1] !~ /^ *$/) ? "$val[0].$val[1]" : $val[0]; 135 } 140 return $val[0] if defined $val[0] and $val[0] !~ /^[: ]*$/; 141 return $val[1] if defined $val[1] and $val[1] !~ /^[: ]*$/; 136 142 return $val[4] if not defined $val[5] or (defined $val[4] and 137 143 (not defined $val[6] or $val[5] eq $val[6])); … … 146 152 # set EXIF date/time values according to PrintConv option instead 147 153 # of defaulting to Type=ValueConv to allow reformatting to be applied 148 'EXIF:DateTimeOriginal' => 'delete $opts{Type}; $val', 149 'EXIF:SubSecTimeOriginal' => 'delete $opts{Type}; $val', 150 'IPTC:DateCreated' => '$opts{EditGroup} = 1; $val', 151 'IPTC:TimeCreated' => '$opts{EditGroup} = 1; $val', 152 'XMP-photoshop:DateCreated' => '$val', 154 'Composite:SubSecDateTimeOriginal' => 'delete $opts{Type}; $val', 155 'IPTC:DateCreated' => '$opts{EditGroup} = 1; $val', 156 'IPTC:TimeCreated' => '$opts{EditGroup} = 1; $val', 157 'XMP-photoshop:DateCreated' => '$val', 153 158 }, 154 159 }, 155 160 CreateDate => { 156 161 Groups => { 2 => 'Time' }, 157 Notes => '"creation date of the digital representation" - MWG', 158 Writable => 1, 159 Desire => { 160 0 => 'EXIF:CreateDate', 161 1 => 'EXIF:SubSecTimeDigitized', 162 Notes => '"specifies when an image was digitized" - MWG', 163 Writable => 1, 164 Shift => 0, # don't shift this tag 165 Desire => { 166 0 => 'Composite:SubSecCreateDate', 167 1 => 'EXIF:CreateDate', 162 168 2 => 'IPTC:DigitalCreationDate', 163 169 3 => 'IPTC:DigitalCreationTime', … … 166 172 6 => 'IPTCDigest', 167 173 }, 174 RawConv => q{ 175 (defined $val[0] or defined $val[1] or $val[2] or 176 (defined $val[4] and (not defined $val[5] or not defined $val[6] 177 or $val[5] eq $val[6]))) ? $val : undef 178 }, 168 179 ValueConv => q{ 169 if (defined $val[0] and $val[0] !~ /^[: ]*$/) { 170 return ($val[1] and $val[1] !~ /^ *$/) ? "$val[0].$val[1]" : $val[0]; 171 } 180 return $val[0] if defined $val[0] and $val[0] !~ /^[: ]*$/; 181 return $val[1] if defined $val[1] and $val[1] !~ /^[: ]*$/; 172 182 return $val[4] if not defined $val[5] or (defined $val[4] and 173 183 (not defined $val[6] or $val[5] eq $val[6])); … … 180 190 WriteCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', 181 191 WriteAlso => { 182 'EXIF:CreateDate' => 'delete $opts{Type}; $val', 183 'EXIF:SubSecTimeDigitized' => 'delete $opts{Type}; $val', 184 'IPTC:DigitalCreationDate' => '$opts{EditGroup} = 1; $val', 185 'IPTC:DigitalCreationTime' => '$opts{EditGroup} = 1; $val', 186 'XMP-xmp:CreateDate' => '$val', 192 'Composite:SubSecCreateDate' => 'delete $opts{Type}; $val', 193 'IPTC:DigitalCreationDate' => '$opts{EditGroup} = 1; $val', 194 'IPTC:DigitalCreationTime' => '$opts{EditGroup} = 1; $val', 195 'XMP-xmp:CreateDate' => '$val', 187 196 }, 188 197 }, 189 198 ModifyDate => { 190 199 Groups => { 2 => 'Time' }, 191 Notes => '"modification date of the digital image file" - MWG', 192 Writable => 1, 193 Desire => { 194 0 => 'EXIF:ModifyDate', 195 1 => 'EXIF:SubSecTime', 200 Notes => '"specifies when a file was modified by the user" - MWG', 201 Writable => 1, 202 Shift => 0, # don't shift this tag 203 Desire => { 204 0 => 'Composite:SubSecModifyDate', 205 1 => 'EXIF:ModifyDate', 196 206 2 => 'XMP-xmp:ModifyDate', 197 207 3 => 'CurrentIPTCDigest', 198 208 4 => 'IPTCDigest', 199 209 }, 200 ValueConv => q{ 201 if (defined $val[0] and $val[0] !~ /^[: ]*$/) { 202 return ($val[1] and $val[1] !~ /^ *$/) ? "$val[0].$val[1]" : $val[0]; 203 } 210 RawConv => q{ 211 return $val[0] if defined $val[0] and $val[0] !~ /^[: ]*$/; 212 return $val[1] if defined $val[1] and $val[1] !~ /^[: ]*$/; 204 213 return $val[2] if not defined $val[3] or not defined $val[4] or $val[3] eq $val[4]; 205 214 return undef; … … 212 221 WriteCheck => '""', 213 222 WriteAlso => { 214 'EXIF:ModifyDate' => 'delete $opts{Type}; $val', 215 'EXIF:SubSecTime' => 'delete $opts{Type}; $val', 216 'XMP-xmp:ModifyDate' => '$val', 223 'Composite:SubSecModifyDate' => 'delete $opts{Type}; $val', 224 'XMP-xmp:ModifyDate' => '$val', 217 225 }, 218 226 }, … … 248 256 4 => 'IPTCDigest', 249 257 }, 250 ValueConv => q{258 RawConv => q{ 251 259 return $val[0] if defined $val[0] and $val[0] !~ /^ *$/; 252 260 return $val[2] if not defined $val[3] or (defined $val[2] and … … 257 265 WriteCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', 258 266 WriteAlso => { 259 'EXIF:Copyright' => '$val', 267 'EXIF:Copyright' => q{ 268 # encode if necessary (not automatic because Format is 'undef') 269 my $enc = $self->Options('CharsetEXIF'); 270 if ($enc) { 271 my $v = $val; 272 $self->Encode($v,$enc); 273 return $v; 274 } 275 return $val; 276 }, 260 277 'IPTC:CopyrightNotice' => '$opts{EditGroup} = 1; $val', 261 278 'XMP-dc:Rights' => '$val', … … 272 289 4 => 'IPTCDigest', 273 290 }, 274 ValueConv => q{291 RawConv => q{ 275 292 return $val[0] if defined $val[0] and $val[0] !~ /^ *$/; 276 293 return $val[2] if not defined $val[3] or (defined $val[2] and … … 292 309 0 => 'IPTC:Country-PrimaryLocationName', # (64-character limit) 293 310 1 => 'XMP-photoshop:Country', 294 2 => 'CurrentIPTCDigest', 295 3 => 'IPTCDigest', 296 }, 297 ValueConv => q{ 298 return $val[1] if not defined $val[2] or (defined $val[1] and 299 (not defined $val[3] or $val[2] eq $val[3])); 300 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 64); 311 2 => 'XMP-iptcExt:LocationShownCountryName', 312 3 => 'CurrentIPTCDigest', 313 4 => 'IPTCDigest', 314 }, 315 RawConv => q{ 316 my $xmpVal = $val[2] || $val[1]; 317 return $xmpVal if not defined $val[3] or (defined $xmpVal and 318 (not defined $val[4] or $val[3] eq $val[4])); 319 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 64); 301 320 }, 302 321 DelCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', … … 304 323 WriteAlso => { 305 324 'IPTC:Country-PrimaryLocationName' => '$opts{EditGroup} = 1; $val', 306 'XMP-photoshop:Country' => '$val', 325 'XMP-photoshop:Country' => '$val', # (legacy) 326 'XMP-iptcExt:LocationShownCountryName' => '$val', 307 327 }, 308 328 }, … … 313 333 0 => 'IPTC:Province-State', # (32-character limit) 314 334 1 => 'XMP-photoshop:State', 315 2 => 'CurrentIPTCDigest', 316 3 => 'IPTCDigest', 317 }, 318 ValueConv => q{ 319 return $val[1] if not defined $val[2] or (defined $val[1] and 320 (not defined $val[3] or $val[2] eq $val[3])); 321 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 32); 335 2 => 'XMP-iptcExt:LocationShownProvinceState', 336 3 => 'CurrentIPTCDigest', 337 4 => 'IPTCDigest', 338 }, 339 RawConv => q{ 340 my $xmpVal = $val[2] || $val[1]; 341 return $xmpVal if not defined $val[3] or (defined $xmpVal and 342 (not defined $val[4] or $val[3] eq $val[4])); 343 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 32); 322 344 }, 323 345 DelCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', … … 325 347 WriteAlso => { 326 348 'IPTC:Province-State' => '$opts{EditGroup} = 1; $val', 327 'XMP-photoshop:State' => '$val', 349 'XMP-photoshop:State' => '$val', # (legacy) 350 'XMP-iptcExt:LocationShownProvinceState' => '$val', 328 351 }, 329 352 }, … … 334 357 0 => 'IPTC:City', # (32-character limit) 335 358 1 => 'XMP-photoshop:City', 336 2 => 'CurrentIPTCDigest', 337 3 => 'IPTCDigest', 338 }, 339 ValueConv => q{ 340 return $val[1] if not defined $val[2] or (defined $val[1] and 341 (not defined $val[3] or $val[2] eq $val[3])); 342 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 32); 359 2 => 'XMP-iptcExt:LocationShownCity', 360 3 => 'CurrentIPTCDigest', 361 4 => 'IPTCDigest', 362 }, 363 RawConv => q{ 364 my $xmpVal = $val[2] || $val[1]; 365 return $xmpVal if not defined $val[3] or (defined $xmpVal and 366 (not defined $val[4] or $val[3] eq $val[4])); 367 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 32); 343 368 }, 344 369 DelCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', … … 346 371 WriteAlso => { 347 372 'IPTC:City' => '$opts{EditGroup} = 1; $val', 348 'XMP-photoshop:City' => '$val', 373 'XMP-photoshop:City' => '$val', # (legacy) 374 'XMP-iptcExt:LocationShownCity' => '$val', 349 375 }, 350 376 }, … … 355 381 0 => 'IPTC:Sub-location', # (32-character limit) 356 382 1 => 'XMP-iptcCore:Location', 357 2 => 'CurrentIPTCDigest', 358 3 => 'IPTCDigest', 359 }, 360 ValueConv => q{ 361 return $val[1] if not defined $val[2] or (defined $val[1] and 362 (not defined $val[3] or $val[2] eq $val[3])); 363 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 32); 383 2 => 'XMP-iptcExt:LocationShownSublocation', 384 3 => 'CurrentIPTCDigest', 385 4 => 'IPTCDigest', 386 }, 387 RawConv => q{ 388 my $xmpVal = $val[2] || $val[1]; 389 return $xmpVal if not defined $val[3] or (defined $xmpVal and 390 (not defined $val[4] or $val[3] eq $val[4])); 391 return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 32); 364 392 }, 365 393 DelCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)', … … 367 395 WriteAlso => { 368 396 'IPTC:Sub-location' => '$opts{EditGroup} = 1; $val', 369 'XMP-iptcCore:Location' => '$val', 397 'XMP-iptcCore:Location' => '$val', # (legacy) 398 'XMP-iptcExt:LocationShownSublocation' => '$val', 370 399 }, 371 400 }, 372 401 ); 373 402 374 unless ($Image::ExifTool::documentOnly) { 403 # MWG XMP structures 404 my %sExtensions = ( 405 STRUCT_NAME => 'MWG Extensions', 406 NAMESPACE => undef, # variable namespace 407 NOTES => q{ 408 This structure may contain any top-level XMP tags, but none have been 409 pre-defined in ExifTool. Since no flattened tags have been pre-defined, 410 RegionExtensions is writable only as a structure (eg. 411 C<{xmp-dc:creator=me,rating=5}>). Fields for this structure are identified 412 using the standard ExifTool tag name (with optional leading group name, 413 and/or trailing language code, and/or trailing C<#> symbol to disable print 414 conversion). 415 }, 416 ); 417 my %sRegionStruct = ( 418 STRUCT_NAME => 'MWG RegionStruct', 419 NAMESPACE => 'mwg-rs', 420 Area => { Struct => \%Image::ExifTool::XMP::sArea }, 421 Type => { 422 PrintConv => { 423 Face => 'Face', 424 Pet => 'Pet', 425 Focus => 'Focus', 426 BarCode => 'BarCode', 427 }, 428 }, 429 Name => { }, 430 Description => { }, 431 FocusUsage => { 432 PrintConv => { 433 EvaluatedUsed => 'Evaluated, Used', 434 EvaluatedNotUsed => 'Evaluated, Not Used', 435 NotEvaluatedNotUsed => 'Not Evaluated, Not Used', 436 }, 437 }, 438 BarCodeValue=> { }, 439 Extensions => { Struct => \%sExtensions }, 440 Rotation => { # (observed in LR6 XMP) 441 Writable => 'real', 442 Notes => 'not part of MWG 2.0 spec', 443 }, 444 seeAlso => { Namespace => 'rdfs', Resource => 1 }, 445 ); 446 my %sKeywordStruct; 447 %sKeywordStruct = ( 448 STRUCT_NAME => 'MWG KeywordStruct', 449 NAMESPACE => 'mwg-kw', 450 Keyword => { }, 451 Applied => { Writable => 'boolean' }, 452 Children => { Struct => \%sKeywordStruct, List => 'Bag' }, 453 ); 454 455 # MWG 2.0 XMP region namespace tags 456 %Image::ExifTool::MWG::Regions = ( 457 %Image::ExifTool::XMP::xmpTableDefaults, 458 GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-rs', 2 => 'Image' }, 459 NAMESPACE => 'mwg-rs', 460 NOTES => q{ 461 Image region metadata defined by the MWG 2.0 specification. These tags 462 may be accessed without the need to load the MWG Composite tags above. See 463 L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> 464 for the official specification. 465 }, 466 Regions => { 467 Name => 'RegionInfo', 468 FlatName => 'Region', 469 Struct => { 470 STRUCT_NAME => 'MWG RegionInfo', 471 NAMESPACE => 'mwg-rs', 472 RegionList => { 473 FlatName => 'Region', 474 Struct => \%sRegionStruct, 475 List => 'Bag', 476 }, 477 AppliedToDimensions => { Struct => \%Image::ExifTool::XMP::sDimensions }, 478 }, 479 }, 480 RegionsRegionList => { Flat => 1, Name => 'RegionList' }, 481 ); 482 483 # MWG 2.0 XMP hierarchical keyword namespace tags 484 %Image::ExifTool::MWG::Keywords = ( 485 %Image::ExifTool::XMP::xmpTableDefaults, 486 GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-kw', 2 => 'Image' }, 487 NAMESPACE => 'mwg-kw', 488 NOTES => q{ 489 Hierarchical keywords metadata defined by the MWG 2.0 specification. 490 ExifTool unrolls keyword structures to an arbitrary depth of 6 to allow 491 individual levels to be accessed with different tag names, and to avoid 492 infinite recursion. See 493 L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> 494 for the official specification. 495 }, 496 # arbitrarily define only the first 6 levels of the keyword hierarchy 497 Keywords => { 498 Name => 'KeywordInfo', 499 Struct => { 500 STRUCT_NAME => 'MWG KeywordInfo', 501 NAMESPACE => 'mwg-kw', 502 Hierarchy => { Struct => \%sKeywordStruct, List => 'Bag' }, 503 }, 504 }, 505 KeywordsHierarchy => { Name => 'HierarchicalKeywords', Flat => 1 }, 506 KeywordsHierarchyKeyword => { Name => 'HierarchicalKeywords1', Flat => 1 }, 507 KeywordsHierarchyApplied => { Name => 'HierarchicalKeywords1Applied', Flat => 1 }, 508 KeywordsHierarchyChildren => { Name => 'HierarchicalKeywords1Children', Flat => 1 }, 509 KeywordsHierarchyChildrenKeyword => { Name => 'HierarchicalKeywords2', Flat => 1 }, 510 KeywordsHierarchyChildrenApplied => { Name => 'HierarchicalKeywords2Applied', Flat => 1 }, 511 KeywordsHierarchyChildrenChildren => { Name => 'HierarchicalKeywords2Children', Flat => 1 }, 512 KeywordsHierarchyChildrenChildrenKeyword => { Name => 'HierarchicalKeywords3', Flat => 1 }, 513 KeywordsHierarchyChildrenChildrenApplied => { Name => 'HierarchicalKeywords3Applied', Flat => 1 }, 514 KeywordsHierarchyChildrenChildrenChildren => { Name => 'HierarchicalKeywords3Children', Flat => 1 }, 515 KeywordsHierarchyChildrenChildrenChildrenKeyword => { Name => 'HierarchicalKeywords4', Flat => 1 }, 516 KeywordsHierarchyChildrenChildrenChildrenApplied => { Name => 'HierarchicalKeywords4Applied', Flat => 1 }, 517 KeywordsHierarchyChildrenChildrenChildrenChildren => { Name => 'HierarchicalKeywords4Children', Flat => 1 }, 518 KeywordsHierarchyChildrenChildrenChildrenChildrenKeyword => { Name => 'HierarchicalKeywords5', Flat => 1 }, 519 KeywordsHierarchyChildrenChildrenChildrenChildrenApplied => { Name => 'HierarchicalKeywords5Applied', Flat => 1 }, 520 KeywordsHierarchyChildrenChildrenChildrenChildrenChildren => { Name => 'HierarchicalKeywords5Children', Flat => 1, NoSubStruct => 1 }, # break infinite recursion 521 KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenKeyword => { Name => 'HierarchicalKeywords6', Flat => 1 }, 522 KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenApplied => { Name => 'HierarchicalKeywords6Applied', Flat => 1 }, 523 ); 524 525 # MWG 2.0 XMP collections namespace tags 526 %Image::ExifTool::MWG::Collections = ( 527 %Image::ExifTool::XMP::xmpTableDefaults, 528 GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-coll', 2 => 'Image' }, 529 NAMESPACE => 'mwg-coll', 530 NOTES => q{ 531 Collections metadata defined by the MWG 2.0 specification. See 532 L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> 533 for the official specification. 534 }, 535 Collections => { 536 FlatName => '', 537 List => 'Bag', 538 Struct => { 539 STRUCT_NAME => 'MWG CollectionInfo', 540 NAMESPACE => 'mwg-coll', 541 CollectionName => { }, 542 CollectionURI => { }, 543 }, 544 }, 545 ); 546 547 548 #------------------------------------------------------------------------------ 549 # Load the MWG Composite tags 550 sub Load() 551 { 552 return if $mwgLoaded; 553 375 554 # add our composite tags 376 555 Image::ExifTool::AddCompositeTags('Image::ExifTool::MWG'); … … 379 558 Image::ExifTool::AddTagsToLookup(\%Image::ExifTool::MWG::Composite, 380 559 'Image::ExifTool::Composite'); 381 } 382 383 # modify EXIF:Artist to behave as a List-type tag 384 { 560 561 # modify EXIF:Artist to behave as a list-type tag 385 562 my $artist = $Image::ExifTool::Exif::Main{0x13b}; 386 563 $$artist{List} = 1; 387 564 $$artist{IsOverwriting} = \&OverwriteStringList; 388 565 $$artist{RawConv} = \&StringToList; 566 567 # enable MWG strict mode if not set already 568 # (causes non-standard EXIF, IPTC and XMP to be ignored) 569 $Image::ExifTool::MWG::strict = 1 unless defined $Image::ExifTool::MWG::strict; 570 571 $mwgLoaded = 1; 389 572 } 390 573 … … 414 597 sub StringToList($$) 415 598 { 416 my ($str, $e xifTool) = @_;599 my ($str, $et) = @_; 417 600 my (@vals, $inQuotes); 418 601 my @t = split '; ', $str, -1; … … 433 616 } 434 617 } 435 $e xifTool->Warn('Incorrectly quoted MWG string-list value') if $inQuotes;618 $et->Warn('Incorrectly quoted MWG string-list value') if $inQuotes; 436 619 return @vals > 1 ? \@vals : $vals[0]; 437 620 } … … 439 622 #------------------------------------------------------------------------------ 440 623 # Handle logic for overwriting EXIF string-type list tag 441 # Inputs: 0) new value hashref, 1) new value hash ref,624 # Inputs: 0) ExifTool ref, 1) new value hash ref, 442 625 # 2) old string value (or undef if it didn't exist), 3) new value ref 443 626 # Returns: 1 and sets the new value for the tag … … 445 628 { 446 629 local $_; 447 my ($e xifTool, $nvHash, $val, $newValuePt) = @_;630 my ($et, $nvHash, $val, $newValuePt) = @_; 448 631 my (@new, $delIndex); 632 my $writeMode = $et->Options('WriteMode'); 633 if ($writeMode ne 'wcg') { 634 if (defined $val) { 635 $writeMode =~ /w/i or return 0; 636 } else { 637 $writeMode =~ /c/i or return 0; 638 } 639 } 449 640 if ($$nvHash{DelValue} and defined $val) { 450 641 # preserve specified old values 451 my $old = StringToList($val, $e xifTool);642 my $old = StringToList($val, $et); 452 643 my @old = ref $old eq 'ARRAY' ? @$old : $old; 453 644 if (@{$$nvHash{DelValue}}) { … … 485 676 sub ReconcileIPTCDigest($) 486 677 { 487 my $e xifTool= shift;678 my $et = shift; 488 679 489 680 # set new value for IPTCDigest if not done already 490 681 unless ($Image::ExifTool::Photoshop::iptcDigestInfo and 491 $ exifTool->{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo})682 $$et{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo}) 492 683 { 493 684 # write new IPTCDigest only if it doesn't exist or 494 685 # is the same as the digest of the original IPTC 495 686 my @a; # (capture warning messages) 496 @a = $e xifTool->SetNewValue('Photoshop:IPTCDigest', 'old', Protected => 1, DelValue => 1);497 @a = $e xifTool->SetNewValue('Photoshop:IPTCDigest', 'new', Protected => 1);687 @a = $et->SetNewValue('Photoshop:IPTCDigest', 'old', Protected => 1, DelValue => 1); 688 @a = $et->SetNewValue('Photoshop:IPTCDigest', 'new', Protected => 1); 498 689 } 499 690 return ''; … … 516 707 } 517 708 return \@vals; 518 } elsif (defined $iptc and length $iptc == $limit) { 709 } elsif (defined $iptc and length $iptc == $limit) { 519 710 $xmp = $$xmp[0] if ref $xmp; # take first element of list 520 711 return $xmp if length $xmp > $limit and $iptc eq substr($xmp, 0, $limit); … … 533 724 =head1 SYNOPSIS 534 725 535 # enable MWG tags (strict mode enabled by default)726 # enable MWG Composite tags 536 727 use Image::ExifTool::MWG; 728 Image::ExifTool::MWG::Load(); 729 730 # enable MWG strict mode 731 $Image::ExifTool::MWG::strict = 1; 537 732 538 733 # disable MWG strict mode … … 541 736 =head1 DESCRIPTION 542 737 543 The MWG module contains tag definitions which are designed to simplify544 implementation of the Metadata Working Group guidelines. These special MWG 545 composite tags are enabled simply by loading this module:738 The MWG module contains Composite tag definitions which are designed to 739 simplify implementation of the Metadata Working Group guidelines. These 740 special MWG Composite tags are enabled by calling the Load() method: 546 741 547 742 use Image::ExifTool::MWG; 548 549 When the MWG module is loaded, "strict MWG conformance" is enabled by 550 default. In this mode, ExifTool will generate a Warning tag instead of 551 extracting EXIF, IPTC and XMP from non-standard locations. The strict mode 552 may be disabled by setting the MWG "strict" flag to zero (either before or 553 after loading the MWG module): 743 Image::ExifTool::MWG::Load(); 744 745 By default, loading the MWG Composite tags enables "strict MWG conformance" 746 unless previously enabled or disabled by the user. In this mode, ExifTool 747 will generate a Warning instead of extracting EXIF, IPTC and XMP from 748 non-standard locations. The strict mode may be disabled or enabled at any 749 time by setting the MWG "strict" flag to 0 or 1. eg) 554 750 555 751 $Image::ExifTool::MWG::strict = 0; 556 752 753 This module also contains the MWG XMP tags which are loaded automatically by 754 ExifTool as required, and are independent of the MWG Composite tags which 755 must be loaded explicitly as described above. 756 557 757 =head1 AUTHOR 558 758 559 Copyright 2003-20 11, Phil Harvey (phil at owl.phy.queensu.ca)759 Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com) 560 760 561 761 This library is free software; you can redistribute it and/or modify it
Note:
See TracChangeset
for help on using the changeset viewer.