- 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/WriteIPTC.pl
r24107 r34921 86 86 my $code = $iptcCharsetInv{uc($val)}; 87 87 unless ($code) { 88 if (($code = $val) =~ s/ESC /\x1b/g) { # translate ESC chars88 if (($code = $val) =~ s/ESC */\x1b/ig) { # translate ESC chars 89 89 $code =~ s/, \x1b/\x1b/g; # remove comma separators 90 90 $code =~ tr/ //d; # remove spaces … … 102 102 sub CheckIPTC($$$) 103 103 { 104 my ($e xifTool, $tagInfo, $valPtr) = @_;105 my $format = $$tagInfo{Format} || $ tagInfo->{Table}->{FORMAT} || '';104 my ($et, $tagInfo, $valPtr) = @_; 105 my $format = $$tagInfo{Format} || $$tagInfo{Table}{FORMAT} || ''; 106 106 if ($format =~ /^int(\d+)/) { 107 107 my $bytes = int(($1 || 0) / 8); 108 if ($bytes ne 1 and $bytes ne 2 and $bytes ne4) {108 if ($bytes != 1 and $bytes != 2 and $bytes != 4) { 109 109 return "Can't write $bytes-byte integer"; 110 110 } … … 128 128 } 129 129 } 130 if (defined $minlen ) {130 if (defined $minlen and $fmt ne 'string') { # (must truncate strings later, after recoding) 131 131 $maxlen or $maxlen = $minlen; 132 return "String too short (minlen is $minlen)" if $len < $minlen; 133 if ($len > $maxlen and not $exifTool->Options('IgnoreMinorErrors')) { 134 $$exifTool{CHECK_WARN} = "[minor] IPTC:$$tagInfo{Name} exceeds length limit (truncated)"; 132 if ($len < $minlen) { 133 unless ($$et{OPTIONS}{IgnoreMinorErrors}) { 134 return "[Minor] String too short (minlen is $minlen)"; 135 } 136 $$et{CHECK_WARN} = "String too short for IPTC:$$tagInfo{Name} (written anyway)"; 137 } elsif ($len > $maxlen and not $$et{OPTIONS}{IgnoreMinorErrors}) { 138 $$et{CHECK_WARN} = "[Minor] IPTC:$$tagInfo{Name} exceeds length limit (truncated)"; 135 139 $$valPtr = substr($$valPtr, 0, $maxlen); 136 140 } … … 150 154 sub FormatIPTC($$$$$;$) 151 155 { 152 my ($e xifTool, $tagInfo, $valPtr, $xlatPtr, $rec, $read) = @_;156 my ($et, $tagInfo, $valPtr, $xlatPtr, $rec, $read) = @_; 153 157 my $format = $$tagInfo{Format} || $$tagInfo{Table}{FORMAT}; 154 158 return unless $format; … … 177 181 if ($rec == 1) { 178 182 if ($$tagInfo{Name} eq 'CodedCharacterSet') { 179 $$xlatPtr = HandleCodedCharset($e xifTool, $$valPtr);183 $$xlatPtr = HandleCodedCharset($et, $$valPtr); 180 184 } 181 185 } elsif ($$xlatPtr and $rec < 7 and $$valPtr =~ /[\x80-\xff]/) { 182 TranslateCodedString($exifTool, $valPtr, $xlatPtr, $read); 186 TranslateCodedString($et, $valPtr, $xlatPtr, $read); 187 } 188 # must check length now (after any string recoding) 189 if (not $read and $format =~ /^string\[(\d+),?(\d*)\]$/) { 190 my ($minlen, $maxlen) = ($1, $2); 191 my $len = length $$valPtr; 192 $maxlen or $maxlen = $minlen; 193 if ($len < $minlen) { 194 if ($et->Warn("String too short for IPTC:$$tagInfo{Name} (padded)", 2)) { 195 $$valPtr .= ' ' x ($minlen - $len); 196 } 197 } elsif ($len > $maxlen) { 198 if ($et->Warn("IPTC:$$tagInfo{Name} exceeds length limit (truncated)", 2)) { 199 $$valPtr = substr($$valPtr, 0, $maxlen); 200 # make sure UTF-8 is still valid 201 if (($$xlatPtr || $et->Options('Charset')) eq 'UTF8') { 202 require Image::ExifTool::XMP; 203 Image::ExifTool::XMP::FixUTF8($valPtr,'.'); 204 } 205 } 206 } 183 207 } 184 208 } … … 192 216 { 193 217 my $val = shift; 194 unless ($val =~ s /.*(\d{4}):?(\d{2}):?(\d{2}).*/$1$2$3/s) {218 unless ($val =~ s{^.*(\d{4})[-:/.]?(\d{2})[-:/.]?(\d{2}).*}{$1$2$3}s) { 195 219 warn "Invalid date format (use YYYY:mm:dd)\n"; 196 220 undef $val; … … 214 238 $tz = '+0000'; # UTC 215 239 } else { 216 # use local system timezone by default 240 # use local system timezone by default 217 241 my (@tm, $time); 218 if ($date and $date =~ /^(\d{4}):(\d{2}):(\d{2})\s*$/ and eval 'require Time::Local') {242 if ($date and $date =~ /^(\d{4}):(\d{2}):(\d{2})\s*$/ and eval { require Time::Local }) { 219 243 # we were given a date too, so determine the local timezone 220 244 # offset at the specified date/time 221 my @d = ($3,$2-1,$1 -1900);245 my @d = ($3,$2-1,$1); 222 246 $val =~ /(\d{2})(\d{2})(\d{2})/; 223 247 @tm = ($3,$2,$1,@d); … … 238 262 undef $val; # time format error 239 263 } 264 return $val; 265 } 266 267 #------------------------------------------------------------------------------ 268 # Inverse print conversion for IPTC date or time value 269 # Inputs: 0) ExifTool ref, 1) IPTC date or 'now' 270 # Returns: IPTC date 271 sub InverseDateOrTime($$) 272 { 273 my ($et, $val) = @_; 274 return $et->TimeNow() if lc($val) eq 'now'; 240 275 return $val; 241 276 } … … 292 327 sub DoWriteIPTC($$$) 293 328 { 294 my ($e xifTool, $dirInfo, $tagTablePtr) = @_;295 my $verbose = $e xifTool->Options('Verbose');296 my $out = $e xifTool->Options('TextOut');329 my ($et, $dirInfo, $tagTablePtr) = @_; 330 my $verbose = $et->Options('Verbose'); 331 my $out = $et->Options('TextOut'); 297 332 298 333 # avoid editing IPTC directory unless necessary: … … 300 335 # - avoids changing current MD5 digest unnecessarily 301 336 # - avoids adding mandatory tags unless some other IPTC is changed 302 unless (exists $$e xifTool{EDIT_DIRS}{$$dirInfo{DirName}} or303 # standard IPTC tags in other locations should be edited too ( ie. AFCP_IPTC)304 ($tagTablePtr = \%Image::ExifTool::IPTC::Main and exists $$exifTool{EDIT_DIRS}{IPTC}))337 unless (exists $$et{EDIT_DIRS}{$$dirInfo{DirName}} or 338 # standard IPTC tags in other locations should be edited too (eg. AFCP_IPTC) 339 ($tagTablePtr eq \%Image::ExifTool::IPTC::Main and exists $$et{EDIT_DIRS}{IPTC})) 305 340 { 306 print $out "$$e xifTool{INDENT} [nothing changed]\n" if $verbose;341 print $out "$$et{INDENT} [nothing changed]\n" if $verbose; 307 342 return undef; 308 343 } … … 317 352 318 353 # start by assuming default IPTC encoding 319 my $xlat = $e xifTool->Options('CharsetIPTC');320 undef $xlat if $xlat eq $e xifTool->Options('Charset');354 my $xlat = $et->Options('CharsetIPTC'); 355 undef $xlat if $xlat eq $et->Options('Charset'); 321 356 322 357 # make sure our dataLen is defined (note: allow zero length directory) … … 330 365 substr($$dataPt, $start + 3, 1) eq "\x1c") 331 366 { 332 $e xifTool->Warn('IPTC data was improperly byte-swapped');367 $et->Warn('IPTC data was improperly byte-swapped'); 333 368 my $newData = pack('N*', unpack('V*', substr($$dataPt, $start, $dirLen) . "\0\0\0")); 334 369 $dataPt = \$newData; … … 339 374 my %recordNum; 340 375 foreach $tag (Image::ExifTool::TagTableKeys($tagTablePtr)) { 341 $tagInfo = $ tagTablePtr->{$tag};376 $tagInfo = $$tagTablePtr{$tag}; 342 377 $$tagInfo{SubDirectory} or next; 343 my $table = $ tagInfo->{SubDirectory}->{TagTable} or next;378 my $table = $$tagInfo{SubDirectory}{TagTable} or next; 344 379 my $subTablePtr = Image::ExifTool::GetTagTable($table); 345 380 $recordNum{$subTablePtr} = $tag; … … 348 383 # loop through new values and accumulate all IPTC information 349 384 # into lists based on their IPTC record type 350 foreach $tagInfo ($e xifTool->GetNewTagInfoList()) {385 foreach $tagInfo ($et->GetNewTagInfoList()) { 351 386 my $table = $$tagInfo{Table}; 352 387 my $record = $recordNum{$table}; … … 392 427 if ($rec < $lastRec) { 393 428 if ($rec == 0) { 394 return undef if $e xifTool->Warn("IPTC record 0 encountered, subsequent records ignored", 1);429 return undef if $et->Warn("IPTC record 0 encountered, subsequent records ignored", 2); 395 430 undef $rec; 396 431 $pos = $dirEnd; 397 432 $len = 0; 398 433 } else { 399 return undef if $e xifTool->Warn("IPTC doesn't conform to spec: Records out of sequence", 1);434 return undef if $et->Warn("IPTC doesn't conform to spec: Records out of sequence", 2); 400 435 } 401 436 } … … 455 490 next if $foundRec{$lastRec}->{$mandTag}; 456 491 unless ($subTablePtr) { 457 $tagInfo = $ tagTablePtr->{$lastRec};492 $tagInfo = $$tagTablePtr{$lastRec}; 458 493 $tagInfo and $$tagInfo{SubDirectory} or warn("WriteIPTC: Internal error 1\n"), next; 459 $ tagInfo->{SubDirectory}->{TagTable} or next;460 $subTablePtr = Image::ExifTool::GetTagTable($ tagInfo->{SubDirectory}->{TagTable});494 $$tagInfo{SubDirectory}{TagTable} or next; 495 $subTablePtr = Image::ExifTool::GetTagTable($$tagInfo{SubDirectory}{TagTable}); 461 496 } 462 $tagInfo = $ subTablePtr->{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next;463 my $value = $ mandatory->{$mandTag};464 $e xifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value, ' (mandatory)');497 $tagInfo = $$subTablePtr{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next; 498 my $value = $$mandatory{$mandTag}; 499 $et->VerboseValue("+ IPTC:$$tagInfo{Name}", $value, ' (mandatory)'); 465 500 # apply necessary format conversions 466 FormatIPTC($e xifTool, $tagInfo, \$value, \$xlat, $lastRec);501 FormatIPTC($et, $tagInfo, \$value, \$xlat, $lastRec); 467 502 $len = length $value; 468 503 # generate our new entry … … 470 505 $newData .= $entry . $value; # add entry to new IPTC data 471 506 # (don't mark as changed if just mandatory tags changed) 472 # ++$ exifTool->{CHANGED};507 # ++$$et{CHANGED}; 473 508 } 474 509 } … … 487 522 } 488 523 my $newTag = $$tagInfo{TagID}; 489 my $nvHash = $e xifTool->GetNewValueHash($tagInfo);524 my $nvHash = $et->GetNewValueHash($tagInfo); 490 525 # only add new values if... 491 526 my ($doSet, @values); … … 496 531 } elsif ($$tagInfo{List}) { 497 532 # ...tag is List and it existed before or we are creating it 498 $doSet = 1 if $found or Image::ExifTool::IsCreating($nvHash);533 $doSet = 1 if $found ? not $$nvHash{CreateOnly} : $$nvHash{IsCreating}; 499 534 } else { 500 535 # ...tag didn't exist before and we are creating it 501 $doSet = 1 if not $found and Image::ExifTool::IsCreating($nvHash);536 $doSet = 1 if not $found and $$nvHash{IsCreating}; 502 537 } 503 538 if ($doSet) { 504 @values = Image::ExifTool::GetNewValues($nvHash);539 @values = $et->GetNewValue($nvHash); 505 540 @values and $foundRec{$newRec}->{$newTag} = $found | 0x04; 506 541 # write tags for each value in list 507 542 my $value; 508 543 foreach $value (@values) { 509 $e xifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value);544 $et->VerboseValue("+ $$dirInfo{DirName}:$$tagInfo{Name}", $value); 510 545 # reset allMandatory flag if a non-mandatory tag is written 511 546 if ($allMandatory) { 512 547 my $mandatory = $mandatory{$newRec}; 513 $allMandatory = 0 unless $mandatory and $ mandatory->{$newTag};548 $allMandatory = 0 unless $mandatory and $$mandatory{$newTag}; 514 549 } 515 550 # apply necessary format conversions 516 FormatIPTC($e xifTool, $tagInfo, \$value, \$xlat, $newRec);551 FormatIPTC($et, $tagInfo, \$value, \$xlat, $newRec); 517 552 # (note: IPTC string values are NOT null terminated) 518 553 $len = length $value; … … 526 561 } 527 562 $newData .= $entry . $value; # add entry to new IPTC data 528 ++$ exifTool->{CHANGED};563 ++$$et{CHANGED}; 529 564 } 530 565 } … … 553 588 $tagInfo = $set{$rec}->{$tag}; 554 589 if ($tagInfo) { 555 my $nvHash = $e xifTool->GetNewValueHash($tagInfo);590 my $nvHash = $et->GetNewValueHash($tagInfo); 556 591 $len = $pos - $valuePtr; 557 592 my $val = substr($$dataPt, $valuePtr, $len); 593 # remove null terminator if it exists (written by braindead software like Picasa 2.0) 594 $val =~ s/\0+$// if $$tagInfo{Format} and $$tagInfo{Format} =~ /^string/; 558 595 my $oldXlat = $xlat; 559 FormatIPTC($e xifTool, $tagInfo, \$val, \$xlat, $rec, 1);560 if ( Image::ExifTool::IsOverwriting($nvHash, $val)) {596 FormatIPTC($et, $tagInfo, \$val, \$xlat, $rec, 1); 597 if ($et->IsOverwriting($nvHash, $val)) { 561 598 $xlat = $oldXlat; # don't change translation (not writing this value) 562 $e xifTool->VerboseValue("- IPTC:$$tagInfo{Name}", $val);563 ++$ exifTool->{CHANGED};599 $et->VerboseValue("- $$dirInfo{DirName}:$$tagInfo{Name}", $val); 600 ++$$et{CHANGED}; 564 601 # set deleted flag to indicate we found and deleted this tag 565 602 $foundRec{$rec}->{$tag} |= 0x02; … … 577 614 # handle CodedCharacterSet tag 578 615 my $val = substr($$dataPt, $valuePtr, $pos - $valuePtr); 579 $xlat = HandleCodedCharset($e xifTool, $val);616 $xlat = HandleCodedCharset($et, $val); 580 617 } 581 618 # reset allMandatory flag if a non-mandatory tag is written 582 619 if ($allMandatory) { 583 620 my $mandatory = $mandatory{$rec}; 584 unless ($mandatory and $ mandatory->{$tag}) {621 unless ($mandatory and $$mandatory{$tag}) { 585 622 $allMandatory = 0; 586 623 } … … 591 628 # make sure the rest of the data is zero 592 629 if ($tail < $dirEnd) { 593 my $ trailer= substr($$dataPt, $tail, $dirEnd-$tail);594 if ($ trailer=~ /[^\0]/) {595 return undef if $e xifTool->Warn('Unrecognized data in IPTC trailer', 1);630 my $pad = substr($$dataPt, $tail, $dirEnd-$tail); 631 if ($pad =~ /[^\0]/) { 632 return undef if $et->Warn('Unrecognized data in IPTC padding', 2); 596 633 } 597 634 } … … 606 643 sub WriteIPTC($$$) 607 644 { 608 my ($e xifTool, $dirInfo, $tagTablePtr) = @_;609 $e xifToolor return 1; # allow dummy access to autoload this package610 611 my $newData = DoWriteIPTC($e xifTool, $dirInfo, $tagTablePtr);645 my ($et, $dirInfo, $tagTablePtr) = @_; 646 $et or return 1; # allow dummy access to autoload this package 647 648 my $newData = DoWriteIPTC($et, $dirInfo, $tagTablePtr); 612 649 613 650 # calculate standard IPTC digests only if we are writing or deleting 614 651 # Photoshop:IPTCDigest with a value of 'new' or 'old' 615 652 while ($Image::ExifTool::Photoshop::iptcDigestInfo) { 616 my $nvHash = $ exifTool->{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo};653 my $nvHash = $$et{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo}; 617 654 last unless defined $nvHash; 618 last unless IsStandardIPTC($e xifTool->MetadataPath());619 my @values = Image::ExifTool::GetNewValues($nvHash);655 last unless IsStandardIPTC($et->MetadataPath()); 656 my @values = $et->GetNewValue($nvHash); 620 657 push @values, @{$$nvHash{DelValue}} if $$nvHash{DelValue}; 621 658 my $new = grep /^new$/, @values; 622 659 my $old = grep /^old$/, @values; 623 660 last unless $new or $old; 624 unless (eval 'require Digest::MD5') {625 $e xifTool->Warn('Digest::MD5 must be installed to calculate IPTC digest');661 unless (eval { require Digest::MD5 }) { 662 $et->Warn('Digest::MD5 must be installed to calculate IPTC digest'); 626 663 last; 627 664 } … … 638 675 } 639 676 # set NewIPTCDigest data member unless IPTC is being deleted 640 $$e xifTool{NewIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;677 $$et{NewIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt; 641 678 } 642 679 if ($old) { 643 680 if ($new and not defined $newData) { 644 $$e xifTool{OldIPTCDigest} = $$exifTool{NewIPTCDigest};681 $$et{OldIPTCDigest} = $$et{NewIPTCDigest}; 645 682 } elsif ($$dirInfo{DataPt}) { #(may be undef if creating new IPTC) 646 683 $dataPt = $$dirInfo{DataPt}; … … 649 686 $dataPt = \$buff; 650 687 } 651 $$e xifTool{OldIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;688 $$et{OldIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt; 652 689 } 653 690 } 654 691 last; 655 692 } 693 # set changed if ForceWrite tag was set to "IPTC" 694 ++$$et{CHANGED} if defined $newData and length $newData and $$et{FORCE_WRITE}{IPTC}; 656 695 return $newData; 657 696 } … … 677 716 =head1 AUTHOR 678 717 679 Copyright 2003-20 11, Phil Harvey (phil at owl.phy.queensu.ca)718 Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com) 680 719 681 720 This library is free software; you can redistribute it and/or modify it
Note:
See TracChangeset
for help on using the changeset viewer.