- Timestamp:
- 2011-06-01T12:33:42+12:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PNG.pm
r16842 r24107 12 12 # 3) http://www.libpng.org/pub/mng/ 13 13 # 4) http://www.libpng.org/pub/png/spec/register/ 14 # 15 # Notes: I haven't found a sample PNG image with a 'iTXt' chunk, so 16 # this part of the code is still untested. 17 # 18 # Writing meta information in PNG images is a pain in the butt 14 # 5) ftp://ftp.simplesystems.org/pub/png/documents/pngext-1.4.0-pdg.html 15 # 16 # Notes: Writing meta information in PNG images is a pain in the butt 19 17 # for a number of reasons: One biggie is that you have to 20 18 # decompress then decode the ASCII/hex profile information before … … 29 27 use Image::ExifTool qw(:DataAccess :Utils); 30 28 31 $VERSION = '1. 15';29 $VERSION = '1.24'; 32 30 33 31 sub ProcessPNG_tEXt($$$); … … 38 36 sub AddChunks($$); 39 37 sub Add_iCCP($$); 38 sub GetLangInfo($$); 39 sub BuildTextChunk($$$$$); 40 40 41 41 my $noCompressLib; … … 48 48 ); 49 49 50 # map for directories in PNG images 51 my %pngMap = ( 52 IFD1 => 'IFD0', 53 EXIF => 'IFD0', # to write EXIF as a block 54 ExifIFD => 'IFD0', 55 GPS => 'IFD0', 56 SubIFD => 'IFD0', 57 GlobParamIFD => 'IFD0', 58 PrintIM => 'IFD0', 59 InteropIFD => 'ExifIFD', 60 MakerNotes => 'ExifIFD', 61 IFD0 => 'PNG', 62 XMP => 'PNG', 63 ICC_Profile => 'PNG', 64 Photoshop => 'PNG', 65 IPTC => 'Photoshop', 66 MakerNotes => 'ExifIFD', 67 ); 68 50 69 # color type of current image 51 70 $Image::ExifTool::PNG::colorType = -1; … … 55 74 WRITE_PROC => \&Image::ExifTool::DummyWriteProc, 56 75 GROUPS => { 2 => 'Image' }, 76 PREFERRED => 1, # always add these tags when writing 77 NOTES => q{ 78 Tags extracted from PNG images. See 79 L<http://www.libpng.org/pub/png/spec/1.2/> for the official PNG 1.2 80 specification. 81 }, 57 82 bKGD => { 58 83 Name => 'BackgroundColor', … … 62 87 Name => 'PrimaryChromaticities', 63 88 SubDirectory => { TagTable => 'Image::ExifTool::PNG::PrimaryChromaticities' }, 89 }, 90 dSIG => { 91 Name => 'DigitalSignature', 92 Binary => 1, 64 93 }, 65 94 fRAc => { … … 130 159 Name => 'SignificantBits', 131 160 ValueConv => 'join(" ",unpack("C*",$val))', 161 }, 162 sCAL => { # png 1.4.0 163 Name => 'SubjectScale', 164 SubDirectory => { TagTable => 'Image::ExifTool::PNG::SubjectScale' }, 132 165 }, 133 166 sPLT => { … … 145 178 3 => 'Absolute Colorimetric', 146 179 }, 180 }, 181 sTER => { # png 1.4.0 182 Name => 'StereoImage', 183 SubDirectory => { TagTable => 'Image::ExifTool::PNG::StereoImage' }, 147 184 }, 148 185 tEXt => { … … 162 199 }, 163 200 PrintConv => '$self->ConvertDateTime($val)', 164 PrintConvInv => '$ val',201 PrintConvInv => '$self->InverseDateTime($val)', 165 202 }, 166 203 tRNS => { … … 175 212 Notes => 'obsolete location specified by older XMP draft', 176 213 SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, 214 }, 215 vpAg => { # private imagemagick chunk 216 Name => 'VirtualPage', 217 SubDirectory => { TagTable => 'Image::ExifTool::PNG::VirtualPage' }, 177 218 }, 178 219 zTXt => { … … 256 297 ); 257 298 299 # PNG sCAL chunk 300 %Image::ExifTool::PNG::SubjectScale = ( 301 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 302 GROUPS => { 2 => 'Image' }, 303 0 => { 304 Name => 'SubjectUnits', 305 PrintConv => { 1 => 'Meters', 2 => 'Radians' }, 306 }, 307 1 => { 308 Name => 'SubjectPixelWidth', 309 Format => 'var_string', 310 }, 311 2 => { 312 Name => 'SubjectPixelHeight', 313 Format => 'var_string', 314 }, 315 ); 316 317 # PNG vpAg chunk 318 %Image::ExifTool::PNG::VirtualPage = ( 319 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 320 GROUPS => { 2 => 'Image' }, 321 FORMAT => 'int32u', 322 0 => 'VirtualImageWidth', 323 1 => 'VirtualImageHeight', 324 2 => { 325 Name => 'VirtualPageUnits', 326 Format => 'int8u', 327 # what is the conversion for this? 328 }, 329 ); 330 331 # PNG sTER chunk 332 %Image::ExifTool::PNG::StereoImage = ( 333 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 334 GROUPS => { 2 => 'Image' }, 335 0 => { 336 Name => 'StereoMode', 337 PrintConv => { 338 0 => 'Cross-fuse Layout', 339 1 => 'Diverging-fuse Layout', 340 }, 341 }, 342 ); 343 258 344 my %unreg = ( Notes => 'unregistered' ); 259 345 … … 266 352 PREFERRED => 1, # always add these tags when writing 267 353 GROUPS => { 2 => 'Image' }, 354 LANG_INFO => \&GetLangInfo, 268 355 NOTES => q{ 269 The PNG TextualData format allows aribrary tag names to be used. The tags 270 listed below are the only ones that can be written (unless new user-defined 271 tags are added via the configuration file), however ExifTool will extract 272 any other TextualData tags that are found. 273 274 The information for the TextualData tags may be stored as tEXt, zTXt or iTXt 275 chunks in the PNG image. ExifTool will read and edit tags in their original 276 form, but tEXt chunks are written by default when creating new tags. 277 Compressed zTXt chunks are written only if Compress::Zlib is available, and 278 only for profile information or when the -z (Compress) option is specified. 279 280 Some of the tags below are not registered as part of the PNG specification, 281 but are included here because they are generated by other software such as 282 ImageMagick. 356 The PNG TextualData format allows arbitrary tag names to be used. The tags 357 listed below are the only ones that can be written (unless new user-defined 358 tags are added via the configuration file), however ExifTool will extract 359 any other TextualData tags that are found. 360 361 These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image. By 362 default ExifTool writes new string-value tags as as uncompressed tEXt, or 363 compressed zTXt if the Compress (-z) option is used and Compress::Zlib is 364 available. Alternate language tags and values containing special characters 365 (unless the Latin character set is used) are written as iTXt, and compressed 366 if the Compress option is used and Compress::Zlib is available. Raw profile 367 information is always created as compressed zTXt if Compress::Zlib is 368 available, or tEXt otherwise. Standard XMP is written as uncompressed iTXt. 369 370 Alternate languages are accessed by suffixing the tag name with a '-', 371 followed by an RFC 3066 language code (ie. "PNG:Comment-fr", or 372 "Title-en-US"). See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 3066 373 specification. 374 375 Some of the tags below are not registered as part of the PNG specification, 376 but are included here because they are generated by other software such as 377 ImageMagick. 283 378 }, 284 379 Title => { }, … … 306 401 Make => { %unreg, Groups => { 2 => 'Camera' } }, 307 402 Model => { %unreg, Groups => { 2 => 'Camera' } }, 403 'create-date'=> { 404 Name => 'CreateDate', 405 Groups => { 2 => 'Time' }, 406 Shift => 'Time', 407 %unreg, 408 ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)', 409 ValueConvInv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::FormatXMPDate($val)', 410 PrintConv => '$self->ConvertDateTime($val)', 411 PrintConvInv => '$self->InverseDateTime($val,undef,1)', 412 }, 413 'modify-date'=> { 414 Name => 'ModDate', # (to distinguish from tIME chunk "ModifyDate") 415 Groups => { 2 => 'Time' }, 416 Shift => 'Time', 417 %unreg, 418 ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)', 419 ValueConvInv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::FormatXMPDate($val)', 420 PrintConv => '$self->ConvertDateTime($val)', 421 PrintConvInv => '$self->InverseDateTime($val,undef,1)', 422 }, 308 423 TimeStamp => { %unreg, Groups => { 2 => 'Time' }, Shift => 'Time' }, 309 424 URL => { %unreg }, … … 311 426 Name => 'XMP', 312 427 Notes => q{ 313 location according to the XMP specification -- this is where ExifTool will 314 add a new XMP chunk if the image didn't already contain XMP 428 unregistered, but this is the location according to the XMP specification, 429 and is where ExifTool will add a new XMP chunk if the image didn't already 430 contain XMP 315 431 }, 316 432 SubDirectory => { … … 323 439 # (No condition because this is just for BuildTagLookup) 324 440 Name => 'APP1_Profile', 441 %unreg, 325 442 SubDirectory => { 326 443 TagTable=>'Image::ExifTool::Exif::Main', … … 338 455 'Raw profile type exif' => { 339 456 Name => 'EXIF_Profile', 457 %unreg, 340 458 SubDirectory => { 341 459 TagTable=>'Image::ExifTool::Exif::Main', … … 345 463 'Raw profile type icc' => { 346 464 Name => 'ICC_Profile', 465 %unreg, 347 466 SubDirectory => { 348 467 TagTable => 'Image::ExifTool::ICC_Profile::Main', … … 352 471 'Raw profile type icm' => { 353 472 Name => 'ICC_Profile', 473 %unreg, 354 474 SubDirectory => { 355 475 TagTable => 'Image::ExifTool::ICC_Profile::Main', … … 359 479 'Raw profile type iptc' => { 360 480 Name => 'IPTC_Profile', 481 %unreg, 361 482 SubDirectory => { 362 483 TagTable => 'Image::ExifTool::Photoshop::Main', … … 366 487 'Raw profile type xmp' => { 367 488 Name => 'XMP_Profile', 489 %unreg, 368 490 SubDirectory => { 369 491 TagTable => 'Image::ExifTool::XMP::Main', … … 379 501 { 380 502 return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_); 503 } 504 505 #------------------------------------------------------------------------------ 506 # Get standard case for language code (this routine copied from XMP.pm) 507 # Inputs: 0) Language code 508 # Returns: Language code in standard case 509 sub StandardLangCase($) 510 { 511 my $lang = shift; 512 # make 2nd subtag uppercase only if it is 2 letters 513 return lc($1) . uc($2) . lc($3) if $lang =~ /^([a-z]{2,3}|[xi])(-[a-z]{2})\b(.*)/i; 514 return lc($lang); 515 } 516 517 #------------------------------------------------------------------------------ 518 # Get localized version of tagInfo hash 519 # Inputs: 0) tagInfo hash ref, 1) language code (ie. "x-default") 520 # Returns: new tagInfo hash ref, or undef if invalid 521 sub GetLangInfo($$) 522 { 523 my ($tagInfo, $lang) = @_; 524 $lang =~ tr/_/-/; # RFC 3066 specifies '-' as a separator 525 # no alternate languages for XMP or raw profile directories 526 return undef if $$tagInfo{SubDirectory}; 527 # language code must normalized for use in tag ID 528 return Image::ExifTool::GetLangInfo($tagInfo, StandardLangCase($lang)); 381 529 } 382 530 … … 386 534 # 2) Tag ID, 3) Tag value, 4) [optional] compressed data flag: 387 535 # 0=not compressed, 1=unknown compression, 2-N=compression with type N-2 388 # 5) optional output buffer reference 536 # 5) optional output buffer ref, 6) character encoding (tEXt/zTXt/iTXt only) 537 # 6) optional language code 389 538 # Returns: 1 on success 390 sub FoundPNG($$$$;$$ )539 sub FoundPNG($$$$;$$$$) 391 540 { 392 my ($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff) = @_; 541 my ($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, $enc, $lang) = @_; 542 return 0 unless defined $val; 543 my $verbose = $exifTool->Options('Verbose'); 544 my $id = $tag; # generate tag ID which include language code 545 if ($lang) { 546 # case of language code must be normalized since they are case insensitive 547 $lang = StandardLangCase($lang); 548 $id .= '-' . $lang; 549 } 550 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $id) || 551 # (some software forgets to capitalize first letter) 552 $exifTool->GetTagInfo($tagTablePtr, ucfirst($id)); 553 # create alternate language tag if necessary 554 if (not $tagInfo and $lang) { 555 $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) || 556 $exifTool->GetTagInfo($tagTablePtr, ucfirst($tag)); 557 $tagInfo = GetLangInfo($tagInfo, $lang) if $tagInfo; 558 } 559 # 560 # uncompress data if necessary 561 # 393 562 my ($wasCompressed, $deflateErr); 394 return 0 unless defined $val;395 #396 # First, uncompress data if requested397 #398 my $verbose = $exifTool->Options('Verbose');399 my $out = $exifTool->Options('TextOut');400 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) ||401 # (some software forgets to capitalize first letter)402 $exifTool->GetTagInfo($tagTablePtr, ucfirst($tag));403 404 563 if ($compressed and $compressed > 1) { 405 564 if ($compressed == 2) { # Inflate/Deflate compression … … 416 575 } 417 576 } elsif (not $noCompressLib) { 418 $noCompressLib = 1; 419 my $verb = $outBuff ? 'write' : 'decode'; 420 $deflateErr = "Install Compress::Zlib to $verb compressed information"; 577 $deflateErr = "Install Compress::Zlib to read compressed information"; 421 578 } else { 422 579 $deflateErr = ''; # flag deflate error but no warning … … 429 586 $exifTool->VerboseDir("Unable to decompress $$tagInfo{Name}", 0, length($val)); 430 587 } 431 $exifTool->Warn($deflateErr) if $deflateErr and not $outBuff; 588 # issue warning if relevant 589 if ($deflateErr and (not $outBuff or 590 ($tagInfo and $$tagInfo{SubDirectory} and $$exifTool{EDIT_DIRS}{$$tagInfo{Name}}))) 591 { 592 $exifTool->Warn($deflateErr); 593 $noCompressLib = 1 if $deflateErr =~ /^Install/; 594 } 595 } 596 # translate character encoding if necessary (tEXt/zTXt/iTXt string values only) 597 if ($enc and not $compressed and not ($tagInfo and $$tagInfo{SubDirectory})) { 598 $val = $exifTool->Decode($val, $enc); 432 599 } 433 600 # … … 444 611 $wasCompressed and $name = "Decompressed $name"; 445 612 $exifTool->VerboseDir($name, 0, $len); 446 my %parms = ( Prefix => $exifTool->{INDENT}, Out => $out ); 447 $parms{MaxLen} = 96 unless $verbose > 3; 448 Image::ExifTool::HexDump(\$val, undef, %parms); 613 $exifTool->VerboseDump(\$val); 449 614 } 450 615 # don't indent next directory (since it is really the same data) … … 457 622 return 1 if $outBuff and not $$subTable{WRITE_PROC}; 458 623 my %subdirInfo = ( 459 DataPt => \$val,624 DataPt => \$val, 460 625 DirStart => 0, 461 DataLen => $len,462 DirLen => $len,463 DirName => $tagName,464 TagInfo => $tagInfo,626 DataLen => $len, 627 DirLen => $len, 628 DirName => $tagName, 629 TagInfo => $tagInfo, 465 630 ReadOnly => 1, # (only used by WriteXMP) 466 OutBuff => $outBuff,631 OutBuff => $outBuff, 467 632 ); 468 633 # no need to re-decompress if already done … … 482 647 if ($outBuff) { 483 648 my $writable = $tagInfo->{Writable}; 649 my $isOverwriting; 484 650 if ($writable or ($$tagTablePtr{WRITABLE} and 485 651 not defined $writable and not $$tagInfo{SubDirectory})) 486 652 { 487 653 # write new value for this tag if necessary 488 my ($isOverwriting, $newVal);654 my $newVal; 489 655 if ($exifTool->{DEL_GROUP}->{PNG}) { 490 656 # remove this tag now, but keep in ADD_PNG list to add back later … … 492 658 } else { 493 659 # remove this from the list of PNG tags to add 494 delete $exifTool->{ADD_PNG}->{$ tag};660 delete $exifTool->{ADD_PNG}->{$id}; 495 661 # (also handle case of tEXt tags written with lowercase first letter) 496 delete $exifTool->{ADD_PNG}->{ucfirst($ tag)};497 my $n ewValueHash = $exifTool->GetNewValueHash($tagInfo);498 $isOverwriting = Image::ExifTool::IsOverwriting($n ewValueHash);662 delete $exifTool->{ADD_PNG}->{ucfirst($id)}; 663 my $nvHash = $exifTool->GetNewValueHash($tagInfo); 664 $isOverwriting = Image::ExifTool::IsOverwriting($nvHash); 499 665 if (defined $deflateErr) { 500 $newVal = Image::ExifTool::GetNewValues($n ewValueHash);501 # can only write tag now if unconditionally deleting it502 if ($isOverwriting > 0 and not defined $newVal) {666 $newVal = Image::ExifTool::GetNewValues($nvHash); 667 # can only write tag now if always overwriting 668 if ($isOverwriting > 0) { 503 669 $val = '<deflate error>'; 504 } els e{505 $isOverwriting = 0; # can't rewrite this compressed text670 } elsif ($isOverwriting) { 671 $isOverwriting = 0; # can't overwrite 506 672 $exifTool->Warn($deflateErr) if $deflateErr; 507 673 } 508 674 } else { 509 675 if ($isOverwriting < 0) { 510 $isOverwriting = Image::ExifTool::IsOverwriting($n ewValueHash, $val);676 $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val); 511 677 } 512 678 # (must get new value after IsOverwriting() in case it was shifted) 513 $newVal = Image::ExifTool::GetNewValues($n ewValueHash);679 $newVal = Image::ExifTool::GetNewValues($nvHash); 514 680 } 515 681 } 516 682 if ($isOverwriting) { 517 $$outBuff = 683 $$outBuff = (defined $newVal) ? $newVal : ''; 518 684 ++$exifTool->{CHANGED}; 519 if ($verbose > 1) { 520 print $out " - PNG:$tagName = '",$exifTool->Printable($val),"'\n"; 521 print $out " + PNG:$tagName = '",$exifTool->Printable($newVal),"'\n" if defined $newVal; 522 } 685 $exifTool->VerboseValue("- PNG:$tagName", $val); 686 $exifTool->VerboseValue("+ PNG:$tagName", $newVal) if defined $newVal; 523 687 } 524 688 } 525 if ($$outBuff) { 526 if ($wasCompressed) { 689 if (defined $$outBuff and length $$outBuff) { 690 if ($enc) { # must be tEXt/zTXt/iTXt if $enc is set 691 $$outBuff = BuildTextChunk($exifTool, $tag, $tagInfo, $$outBuff, $lang); 692 } elsif ($wasCompressed) { 527 693 # re-compress the output data 528 694 my $deflate; … … 537 703 } 538 704 $$outBuff or $exifTool->Warn("PNG:$tagName not written (compress error)"); 539 } elsif ($exifTool->Options('Compress')) {540 $exifTool->Warn("PNG:$tagName not compressed (uncompressed tag existed)", 1);541 705 } 542 706 } … … 548 712 ($name = $tag) =~ s/\s+(.)/\u$1/g; # remove white space from tag name 549 713 $tagInfo = { Name => $name }; 714 $$tagInfo{LangCode} = $lang if $lang; 550 715 # make unknown profiles binary data type 551 $$tagInfo{ ValueConv} = '\$val'if $tag =~ /^Raw profile type /;716 $$tagInfo{Binary} = 1 if $tag =~ /^Raw profile type /; 552 717 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo); 553 718 } … … 605 770 if ($verbose > 2) { 606 771 $exifTool->VerboseDir("Decoded $tagName", 0, $len); 607 my %parms = ( 608 Prefix => $exifTool->{INDENT}, 609 Out => $exifTool->Options('TextOut'), 610 ); 611 $parms{MaxLen} = 96 unless $verbose > 3; 612 Image::ExifTool::HexDump(\$buff, undef, %parms); 772 $exifTool->VerboseDump(\$buff); 613 773 } 614 774 # don't indent next directory (since it is really the same data) … … 647 807 $dirInfo{DirStart} += $hdrLen; 648 808 $dirInfo{DirLen} -= $hdrLen; 649 $processed = $exifTool->ProcessTIFF(\%dirInfo);650 809 if ($outBuff) { 651 if ($$outBuff) { 652 $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff; 653 } else { 654 $$outBuff = '' if $processed; 655 } 810 $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr, 811 \&Image::ExifTool::WriteTIFF); 812 $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff; 656 813 delete $$addDirs{IFD0}; 814 } else { 815 $processed = $exifTool->ProcessTIFF(\%dirInfo); 657 816 } 658 817 } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) { … … 673 832 # TIFF information (haven't seen this, but what the heck...) 674 833 return 1 if $outBuff and not $$editDirs{IFD0}; 675 $processed = $exifTool->ProcessTIFF(\%dirInfo);676 834 if ($outBuff) { 677 if ($$outBuff) { 678 $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff; 679 } else { 680 $$outBuff = '' if $processed; 681 } 835 $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr, 836 \&Image::ExifTool::WriteTIFF); 837 $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff; 682 838 delete $$addDirs{IFD0}; 839 } else { 840 $processed = $exifTool->ProcessTIFF(\%dirInfo); 683 841 } 684 842 } else { … … 687 845 $exifTool->Warn("Unknown raw profile '$profName'"); 688 846 } 689 if ($outBuff and $$outBuff) {847 if ($outBuff and defined $$outBuff and length $$outBuff) { 690 848 if ($exifTool->{CHANGED} != $oldChanged) { 691 849 my $hdr = sprintf("\n%s\n%8d\n", $profileType, length($$outBuff)); … … 703 861 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 704 862 # Returns: 1 on success 863 # Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag 705 864 sub ProcessPNG_Compressed($$$) 706 865 { … … 712 871 my $hdr = $tag . "\0" . substr($val, 0, 1); 713 872 $val = substr($val, 1); # remove compression method byte 873 my $success; 874 my $outBuff = $$dirInfo{OutBuff}; 714 875 # use the PNG chunk tag instead of the embedded tag name for iCCP chunks 715 876 if ($$dirInfo{TagInfo} and $$dirInfo{TagInfo}->{Name} eq 'ICC_Profile') { 716 877 $tag = 'iCCP'; 717 878 $tagTablePtr = \%Image::ExifTool::PNG::Main; 718 }719 my $outBuff = $$dirInfo{OutBuff};720 my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);721 # add header back onto this chunk if we are writing722 $$outBuff = $hdr . $$outBuff if $outBuff and $$outBuff;723 return $ rtnVal;879 $success = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff); 880 $$outBuff = $hdr . $$outBuff if $outBuff and $$outBuff; 881 } else { 882 $success = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'Latin'); 883 } 884 return $success; 724 885 } 725 886 … … 728 889 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 729 890 # Returns: 1 on success 891 # Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag 730 892 sub ProcessPNG_tEXt($$$) 731 893 { … … 733 895 my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2; 734 896 my $outBuff = $$dirInfo{OutBuff}; 735 my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, undef, $outBuff); 736 # add header back onto this chunk if we are writing 737 $$outBuff = $tag . "\0" . $$outBuff if $outBuff and $$outBuff; 738 return $rtnVal; 897 return FoundPNG($exifTool, $tagTablePtr, $tag, $val, undef, $outBuff, 'Latin'); 739 898 } 740 899 … … 743 902 # Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table 744 903 # Returns: 1 on success 904 # Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag 745 905 sub ProcessPNG_iTXt($$$) 746 906 { … … 753 913 $compressed and $compressed = 2 + $meth; 754 914 my $outBuff = $$dirInfo{OutBuff}; 755 my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff); 756 if ($outBuff and $$outBuff) { 757 $$outBuff = $tag . "\0" . substr($dat, 0, 2) . "$lang\0$trans\0" . $$outBuff; 758 } 759 return $rtnVal; 915 return FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'UTF8', $lang); 760 916 } 761 917 … … 777 933 return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig}; 778 934 if ($outfile) { 935 delete $$exifTool{TextChunkType}; 779 936 Write($outfile, $sig) or $err = 1 if $outfile; 780 937 # can only add tags in Main and TextualData tables … … 782 939 \%Image::ExifTool::PNG::Main, 783 940 \%Image::ExifTool::PNG::TextualData); 784 # initialize with same directories as JPEG, but PNG tags takepriority785 $exifTool->InitWriteDirs( 'JPEG','PNG');941 # initialize with same directories, with PNG tags taking priority 942 $exifTool->InitWriteDirs(\%pngMap,'PNG'); 786 943 } 787 944 my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}}; … … 847 1004 if ($chunk eq $hdrChunk) { 848 1005 $foundHdr = 1; 1006 } elsif ($hdrChunk eq 'IHDR' and $chunk eq 'CgBI') { 1007 $exifTool->Warn('Non-standard PNG image (Apple iPhone format)'); 849 1008 } else { 850 1009 $exifTool->Warn("$fileType image did not start with $hdrChunk"); … … 862 1021 } 863 1022 print $out "$fileType $chunk ($len bytes):\n"; 864 if ($verbose > 2) { 865 my %dumpParms = ( Out => $out ); 866 $dumpParms{MaxLen} = 96 if $verbose <= 4; 867 Image::ExifTool::HexDump(\$dbuf, undef, %dumpParms); 868 } 1023 $exifTool->VerboseDump(\$dbuf, Addr => $raf->Tell() - $len - 4) if $verbose > 2; 869 1024 } 870 1025 # only extract information from chunks in our tables … … 877 1032 } 878 1033 if ($outfile) { 879 if ($theBuff) { 880 $hbuf = pack('Na4',length($theBuff), $chunk); 1034 if (defined $theBuff) { 1035 next unless length $theBuff; # empty if we deleted the information 1036 # change chunk type if necessary 1037 if ($$exifTool{TextChunkType}) { 1038 $chunk = $$exifTool{TextChunkType}; 1039 delete $$exifTool{TextChunkType}; 1040 } 1041 $hbuf = pack('Na4', length($theBuff), $chunk); 881 1042 $dbuf = $theBuff; 882 1043 my $crc = CalculateCRC(\$hbuf, undef, 4); 883 1044 $crc = CalculateCRC(\$dbuf, $crc); 884 1045 $cbuf = pack('N', $crc); 885 } elsif (defined $theBuff) {886 next; # empty if we deleted the information887 1046 } 888 1047 Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1; … … 913 1072 =head1 AUTHOR 914 1073 915 Copyright 2003-20 07, Phil Harvey (phil at owl.phy.queensu.ca)1074 Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca) 916 1075 917 1076 This library is free software; you can redistribute it and/or modify it
Note:
See TracChangeset
for help on using the changeset viewer.