- 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/WritePostScript.pl
r24107 r34921 95 95 sub WritePSDirectory($$$$$) 96 96 { 97 my ($e xifTool, $outfile, $dirName, $dataPt, $flags) = @_;97 my ($et, $outfile, $dirName, $dataPt, $flags) = @_; 98 98 my $success = 2; 99 99 my $len = $dataPt ? length($$dataPt) : 0; … … 117 117 pos($$dataPt) = 0; 118 118 unless ($$dataPt =~ /(.*)(<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d)/sg) { 119 $e xifTool->Warn('No XMP packet start');119 $et->Warn('No XMP packet start'); 120 120 return WriteXMPDir($outfile, $flags, $$dataPt); 121 121 } … … 124 124 my $p1 = pos($$dataPt); 125 125 unless ($$dataPt =~ m{<\?xpacket end=.(w|r).\?>}sg) { 126 $e xifTool->Warn('No XMP packet end');126 $et->Warn('No XMP packet end'); 127 127 return WriteXMPDir($outfile, $flags, $$dataPt); 128 128 } … … 143 143 } 144 144 my $tagTablePtr = Image::ExifTool::GetTagTable("Image::ExifTool::${dirName}::Main"); 145 my $val = $e xifTool->WriteDirectory(\%dirInfo, $tagTablePtr);145 my $val = $et->WriteDirectory(\%dirInfo, $tagTablePtr); 146 146 if (defined $val) { 147 147 $dataPt = \$val; # use modified directory … … 157 157 # so instead we write a blank XMP record 158 158 $val = <<EMPTY_XMP; 159 <?xpacket begin=' ' id='W5M0MpCehiHzreSzNTczkc9d'?>159 <?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?> 160 160 <x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool $Image::ExifTool::VERSION'> 161 161 </x:xmpmeta> 162 162 EMPTY_XMP 163 $val .= ((' ' x 100) . "\n") x 24 unless $ exifTool->Options('Compact');163 $val .= ((' ' x 100) . "\n") x 24 unless $$et{OPTIONS}{Compact}{NoPadding}; 164 164 $val .= q{<?xpacket end='w'?>}; 165 165 $dataPt = \$val; … … 239 239 Write($outfile, $endToken, $/) or $success = 0; 240 240 } else { 241 $e xifTool->Warn("Can't write PS directory $dirName");241 $et->Warn("Can't write PS directory $dirName"); 242 242 } 243 243 undef $val; … … 263 263 } 264 264 my $line = "%%$tag: $val"; 265 # postscript line limit is 255 characters 265 # postscript line limit is 255 characters (but it seems that 266 # the limit may be 254 characters if the DOS CR/LF is used) 266 267 # --> split if necessary using continuation comment "%%+" 267 268 my $n; 268 for ($n=25 5; length($line)>$n; $n+=255+length($/)) {269 for ($n=254; length($line)>$n; $n+=254+length($/)) { 269 270 substr($line, $n, 0) = "$/%%+"; 270 271 } … … 278 279 sub WriteNewTags($$$) 279 280 { 280 my ($e xifTool, $outfile, $newTags) = @_;281 my ($et, $outfile, $newTags) = @_; 281 282 my $success = 1; 282 283 my $tag; … … 288 289 foreach $tag (sort keys %$newTags) { 289 290 my $tagInfo = $$newTags{$tag}; 290 my $nvHash = $e xifTool->GetNewValueHash($tagInfo);291 next unless Image::ExifTool::IsCreating($nvHash);292 my $val = Image::ExifTool::GetNewValues($nvHash);293 $e xifTool->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);291 my $nvHash = $et->GetNewValueHash($tagInfo); 292 next unless $$nvHash{IsCreating}; 293 my $val = $et->GetNewValue($nvHash); 294 $et->VerboseValue("+ PostScript:$$tagInfo{Name}", $val); 294 295 Write($outfile, EncodeTag($tag, $val)) or $success = 0; 295 ++$ exifTool->{CHANGED};296 ++$$et{CHANGED}; 296 297 } 297 298 # write XMP hint if necessary … … 300 301 %$newTags = (); # all done with new tags 301 302 return $success; 302 }303 304 #------------------------------------------------------------------------------305 # check to be sure we haven't read past end of PS data in DOS-style file306 # Inputs: 0) RAF ref, 1) pointer to end of PS, 2) data307 # - modifies data and sets RAF to EOF if end of PS is reached308 sub CheckPSEnd($$$)309 {310 my $pos = $_[0]->Tell();311 if ($pos >= $_[1]) {312 $_[0]->Seek(0, 2); # seek to end of file so we can't read any more313 $_[2] = substr($_[2], 0, length($_[2]) - $pos + $_[1]) if $pos > $_[1];314 }315 }316 317 #------------------------------------------------------------------------------318 # Split into lines ending in any CR, LF or CR+LF combination319 # (this is annoying, and could be avoided if EPS files didn't mix linefeeds!)320 # Inputs: 0) data pointer, 1) reference to lines array321 # Notes: Updates data to contain next line and fills list with remaining lines322 sub SplitLine($$)323 {324 my ($dataPt, $lines) = @_;325 for (;;) {326 my $endl;327 # find the position of the first LF (\x0a)328 $endl = pos($$dataPt), pos($$dataPt) = 0 if $$dataPt =~ /\x0a/g;329 if ($$dataPt =~ /\x0d/g) { # find the first CR (\x0d)330 if (defined $endl) {331 # (remember, CR+LF is a DOS newline...)332 $endl = pos($$dataPt) if pos($$dataPt) < $endl - 1;333 } else {334 $endl = pos($$dataPt);335 }336 } elsif (not defined $endl) {337 push @$lines, $$dataPt;338 last;339 }340 # split into separate lines341 if (length $$dataPt == $endl) {342 push @$lines, $$dataPt;343 last;344 } else {345 push @$lines, substr($$dataPt, 0, $endl);346 $$dataPt = substr($$dataPt, $endl);347 }348 }349 $$dataPt = shift @$lines; # set $$dataPt to first line350 303 } 351 304 … … 357 310 sub WritePS($$) 358 311 { 359 my ($e xifTool, $dirInfo) = @_;360 $e xifToolor return 1; # allow dummy access to autoload this package312 my ($et, $dirInfo) = @_; 313 $et or return 1; # allow dummy access to autoload this package 361 314 my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::PostScript::Main'); 362 315 my $raf = $$dirInfo{RAF}; 363 316 my $outfile = $$dirInfo{OutFile}; 364 my $verbose = $e xifTool->Options('Verbose');365 my $out = $e xifTool->Options('TextOut');317 my $verbose = $et->Options('Verbose'); 318 my $out = $et->Options('TextOut'); 366 319 my ($data, $buff, %flags, $err, $mode, $endToken); 367 my ($dos, $psStart, $ps End, $psNewStart, $xmpHint);320 my ($dos, $psStart, $psNewStart, $xmpHint, @lines); 368 321 369 322 $raf->Read($data, 4) == 4 or return 0; … … 387 340 $raf->Read($data, 4) == 4 and $data eq '%!PS') 388 341 { 389 $e xifTool->Error('Invalid PS header');342 $et->Error('Invalid PS header'); 390 343 return 1; 391 344 } 392 $ psEnd= $psStart + Get32u(\$dos, 8);345 $$raf{PSEnd} = $psStart + Get32u(\$dos, 8); 393 346 my $base = Get32u(\$dos, 20); 394 347 Set16u(0xffff, \$dos, 28); # ignore checksum … … 400 353 NoTiffEnd => 1, # no end-of-TIFF check 401 354 ); 402 $buff = $e xifTool->WriteTIFF(\%dirInfo);355 $buff = $et->WriteTIFF(\%dirInfo); 403 356 SetByteOrder('II'); # (WriteTIFF may change this) 404 357 if ($buff) { … … 408 361 my $len = Get32u(\$dos, 24); 409 362 unless ($raf->Seek($base, 0) and $raf->Read($buff, $len) == $len) { 410 $e xifTool->Error('Error reading embedded TIFF');363 $et->Error('Error reading embedded TIFF'); 411 364 return 1; 412 365 } 413 $e xifTool->Warn('Bad embedded TIFF');366 $et->Warn('Bad embedded TIFF'); 414 367 } 415 368 Set32u(0, \$dos, 12); # zero metafile pointer … … 421 374 my $len = Get32u(\$dos, 16); 422 375 unless ($raf->Seek($base, 0) and $raf->Read($buff, $len) == $len) { 423 $e xifTool->Error('Error reading metafile section');376 $et->Error('Error reading metafile section'); 424 377 return 1; 425 378 } … … 438 391 local $/ = GetInputRecordSeparator($raf); 439 392 unless ($/ and $raf->ReadLine($buff)) { 440 $e xifTool->Error('Invalid PostScript data');393 $et->Error('Invalid PostScript data'); 441 394 return 1; 442 395 } 443 396 $data .= $buff; 444 397 unless ($data =~ /^%!PS-Adobe-3\.(\d+)\b/ and $1 < 2) { 445 if ($e xifTool->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 1)) {398 if ($et->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 2)) { 446 399 return 1; 447 400 } … … 452 405 453 406 # get hash of new information keyed by tagID and directories to add/edit 454 my $newTags = $e xifTool->GetNewTagInfoHash($tagTablePtr);407 my $newTags = $et->GetNewTagInfoHash($tagTablePtr); 455 408 456 409 # figure out which directories we need to write (PostScript takes priority) 457 $e xifTool->InitWriteDirs(\%psMap, 'PostScript');458 my $addDirs = $ exifTool->{ADD_DIRS};459 my $editDirs = $ exifTool->{EDIT_DIRS};410 $et->InitWriteDirs(\%psMap, 'PostScript'); 411 my $addDirs = $$et{ADD_DIRS}; 412 my $editDirs = $$et{EDIT_DIRS}; 460 413 my %doneDir; 461 414 462 415 # set XMP hint flag (1 for adding, 0 for deleting, undef for no change) 463 416 $xmpHint = 1 if $$addDirs{XMP}; 464 $xmpHint = 0 if $$e xifTool{DEL_GROUP}{XMP};417 $xmpHint = 0 if $$et{DEL_GROUP}{XMP}; 465 418 $$newTags{XMP_HINT} = $xmpHint if $xmpHint; # add special tag to newTags list 466 419 467 my (@lines, $changedNL);468 my $altnl = ($/ eq "\x0d") ? "\x0a" : "\x0d";469 470 420 for (;;) { 471 if (@lines) { 472 $data = shift @lines; 473 } else { 474 $raf->ReadLine($data) or last; 475 $dos and CheckPSEnd($raf, $psEnd, $data); 476 # split line if it contains other newline sequences 477 if ($data =~ /$altnl/) { 478 if (length($data) > 500000 and IsPC()) { 479 # patch for Windows memory problem 480 unless ($changedNL) { 481 $changedNL = 1; 482 my $t = $/; 483 $/ = $altnl; 484 $altnl = $t; 485 $raf->Seek(-length($data), 1); 486 next; 487 } 488 } else { 489 # split into separate lines 490 SplitLine(\$data, \@lines); 491 } 492 } 493 } 494 undef $changedNL; 421 @lines or GetNextLine($raf, \@lines) or last; 422 $data = shift @lines; 495 423 if ($endToken) { 496 424 # look for end token … … 499 427 # found end: process this information 500 428 if ($mode) { 501 $doneDir{$mode} and $e xifTool->Error("Multiple $mode directories", 1);429 $doneDir{$mode} and $et->Error("Multiple $mode directories", 1); 502 430 $doneDir{$mode} = 1; 503 WritePSDirectory($e xifTool, $outfile, $mode, \$buff, \%flags) or $err = 1;431 WritePSDirectory($et, $outfile, $mode, \$buff, \%flags) or $err = 1; 504 432 # write end token if we wrote the begin token 505 433 Write($outfile, $data) or $err = 1 if $flags{WROTE_BEGIN}; … … 531 459 } elsif ($data =~ m{^(%{1,2})(Begin)(?!Object:)(.*?)[:\x0d\x0a]}i) { 532 460 # comments section is over... write any new tags now 533 WriteNewTags($e xifTool, $outfile, $newTags) or $err = 1 if %$newTags;461 WriteNewTags($et, $outfile, $newTags) or $err = 1 if %$newTags; 534 462 undef $xmpHint; 535 463 # the beginning of a data block (can only write XMP and Photoshop) … … 558 486 # (because Illustrator doesn't care if the Creator is changed) 559 487 if ($tag eq 'Creator' and $val =~ /^Adobe Illustrator/) { 560 # disable writing XMP to PS-format Adobe Illustrator files and 561 # older Illustrator EPS files becaues it confuses Illustrator 562 # (Illustrator 8 and older write PS-Adobe-3.0, newer write PS-Adobe-3.1) 563 if ($$editDirs{XMP} and $psRev == 0) { 564 if ($flags{EPS}) { 565 $exifTool->Warn("Can't write XMP to Illustrator 8 or older EPS files"); 566 } else { 567 $exifTool->Warn("Can't write XMP to PS-format AI files"); 568 } 488 # disable writing XMP to PostScript-format Adobe Illustrator files 489 # because it confuses Illustrator 490 if ($$editDirs{XMP}) { 491 $et->Warn("Can't write XMP to PostScript-format Illustrator files"); 569 492 # pretend like we wrote it already so we won't try to add it later 570 493 $doneDir{XMP} = 1; … … 574 497 # --> find a better way to do this! 575 498 if ($$newTags{$tag}) { 576 $e xifTool->Warn("Can't change Postscript:Creator of Illustrator files");499 $et->Warn("Can't change Postscript:Creator of Illustrator files"); 577 500 delete $$newTags{$tag}; 578 501 } … … 584 507 # decode comment string (reading continuation lines if necessary) 585 508 $val = DecodeComment($val, $raf, \@lines, \$data); 586 $val = join $e xifTool->Options('ListSep'), @$val if ref $val eq 'ARRAY';587 my $nvHash = $e xifTool->GetNewValueHash($tagInfo);588 if ( Image::ExifTool::IsOverwriting($nvHash, $val)) {589 $e xifTool->VerboseValue("- PostScript:$$tagInfo{Name}", $val);590 $val = Image::ExifTool::GetNewValues($nvHash);591 ++$ exifTool->{CHANGED};509 $val = join $et->Options('ListSep'), @$val if ref $val eq 'ARRAY'; 510 my $nvHash = $et->GetNewValueHash($tagInfo); 511 if ($et->IsOverwriting($nvHash, $val)) { 512 $et->VerboseValue("- PostScript:$$tagInfo{Name}", $val); 513 $val = $et->GetNewValue($nvHash); 514 ++$$et{CHANGED}; 592 515 next unless defined $val; # next if tag is being deleted 593 $e xifTool->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);516 $et->VerboseValue("+ PostScript:$$tagInfo{Name}", $val); 594 517 $data = EncodeTag($tag, $val); 595 518 } … … 612 535 { 613 536 # write new tags at end of comments section 614 WriteNewTags($e xifTool, $outfile, $newTags) or $err = 1;537 WriteNewTags($et, $outfile, $newTags) or $err = 1; 615 538 undef $xmpHint; 616 539 } … … 629 552 if ($plateFile) { 630 553 # PlateFile comments may contain offsets so we can't edit these files! 631 $e xifTool->Warn("Can only edit PostScript information DCS Plate files");554 $et->Warn("Can only edit PostScript information DCS Plate files"); 632 555 last; 633 556 } 634 557 next unless $$addDirs{$dir} or $dir eq 'XMP'; 635 558 $flags{WROTE_BEGIN} = 0; 636 WritePSDirectory($e xifTool, $outfile, $dir, undef, \%flags) or $err = 1;559 WritePSDirectory($et, $outfile, $dir, undef, \%flags) or $err = 1; 637 560 $doneDir{$dir} = 1; 638 561 } … … 646 569 } else { 647 570 $raf->ReadLine($data) or undef($data), last; 648 $dos and CheckPSEnd($raf, $psEnd,$data);571 $dos and CheckPSEnd($raf, \$data); 649 572 if ($data =~ /[\x0d\x0a]%%EOF\b/g) { 650 573 # split data before "%%EOF" … … 664 587 Write($outfile, @lines) or $err = 1 if @lines; 665 588 while ($raf->Read($data, 65536)) { 666 $dos and CheckPSEnd($raf, $psEnd,$data);589 $dos and CheckPSEnd($raf, \$data); 667 590 Write($outfile, $data) or $err = 1; 668 591 } … … 684 607 seek($outfile, $pos, 0)) 685 608 { 686 $e xifTool->Error("Can't write DOS-style PS files in non-seekable stream");609 $et->Error("Can't write DOS-style PS files in non-seekable stream"); 687 610 $err = 1; 688 611 } … … 696 619 foreach $dir (qw{Photoshop ICC_Profile XMP}) { 697 620 push @notDone, $dir if $$editDirs{$dir} and not $doneDir{$dir} and 698 not $$e xifTool{DEL_GROUP}{$dir};699 } 700 @notDone and $e xifTool->Warn("Couldn't write ".join('/',@notDone).' information');701 } 702 $endToken and $e xifTool->Error("File missing $endToken");621 not $$et{DEL_GROUP}{$dir}; 622 } 623 @notDone and $et->Warn("Couldn't write ".join('/',@notDone).' information'); 624 } 625 $endToken and $et->Error("File missing $endToken"); 703 626 return $err ? -1 : 1; 704 627 } … … 764 687 =head1 AUTHOR 765 688 766 Copyright 2003-20 11, Phil Harvey (phil at owl.phy.queensu.ca)689 Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com) 767 690 768 691 This library is free software; you can redistribute it and/or modify it
Note:
See TracChangeset
for help on using the changeset viewer.