exiftool_vendored 10.65.0 → 11.41.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of exiftool_vendored might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/Changes +818 -19
- data/bin/MANIFEST +38 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +48 -44
- data/bin/arg_files/exif2xmp.args +4 -1
- data/bin/arg_files/gps2xmp.args +4 -1
- data/bin/arg_files/iptcCore.args +8 -0
- data/bin/arg_files/xmp2exif.args +4 -1
- data/bin/arg_files/xmp2gps.args +4 -1
- data/bin/config_files/dji.config +131 -0
- data/bin/config_files/example.config +6 -2
- data/bin/config_files/gps2utm.config +256 -256
- data/bin/config_files/nksc.config +146 -0
- data/bin/config_files/picasa_faces.config +382 -382
- data/bin/exiftool +688 -408
- data/bin/fmt_files/gpx.fmt +10 -6
- data/bin/fmt_files/gpx_wpt.fmt +10 -6
- data/bin/fmt_files/kml.fmt +8 -5
- data/bin/lib/File/RandomAccess.pm +48 -8
- data/bin/lib/File/RandomAccess.pod +21 -2
- data/bin/lib/Image/ExifTool.pm +645 -256
- data/bin/lib/Image/ExifTool.pod +219 -164
- data/bin/lib/Image/ExifTool/AES.pm +1 -1
- data/bin/lib/Image/ExifTool/AFCP.pm +3 -8
- data/bin/lib/Image/ExifTool/AIFF.pm +12 -4
- data/bin/lib/Image/ExifTool/APE.pm +1 -1
- data/bin/lib/Image/ExifTool/APP12.pm +1 -1
- data/bin/lib/Image/ExifTool/ASF.pm +19 -6
- data/bin/lib/Image/ExifTool/Apple.pm +13 -5
- data/bin/lib/Image/ExifTool/Audible.pm +1 -1
- data/bin/lib/Image/ExifTool/BMP.pm +1 -1
- data/bin/lib/Image/ExifTool/BPG.pm +17 -15
- data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
- data/bin/lib/Image/ExifTool/BigTIFF.pm +30 -15
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +103 -52
- data/bin/lib/Image/ExifTool/Canon.pm +684 -112
- data/bin/lib/Image/ExifTool/CanonCustom.pm +119 -9
- data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +13 -26
- data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
- data/bin/lib/Image/ExifTool/Casio.pm +1 -1
- data/bin/lib/Image/ExifTool/Charset.pm +1 -1
- data/bin/lib/Image/ExifTool/DICOM.pm +12 -5
- data/bin/lib/Image/ExifTool/DJI.pm +51 -3
- data/bin/lib/Image/ExifTool/DNG.pm +15 -8
- data/bin/lib/Image/ExifTool/DPX.pm +1 -1
- data/bin/lib/Image/ExifTool/DV.pm +1 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +63 -23
- data/bin/lib/Image/ExifTool/DjVu.pm +4 -2
- data/bin/lib/Image/ExifTool/EXE.pm +30 -6
- data/bin/lib/Image/ExifTool/Exif.pm +351 -109
- data/bin/lib/Image/ExifTool/FITS.pm +148 -0
- data/bin/lib/Image/ExifTool/FLAC.pm +2 -2
- data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
- data/bin/lib/Image/ExifTool/FLIR.pm +109 -13
- data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
- data/bin/lib/Image/ExifTool/Flash.pm +3 -3
- data/bin/lib/Image/ExifTool/FlashPix.pm +433 -9
- data/bin/lib/Image/ExifTool/Font.pm +2 -2
- data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
- data/bin/lib/Image/ExifTool/FujiFilm.pm +336 -16
- data/bin/lib/Image/ExifTool/GE.pm +1 -1
- data/bin/lib/Image/ExifTool/GIF.pm +5 -7
- data/bin/lib/Image/ExifTool/GIMP.pm +39 -3
- data/bin/lib/Image/ExifTool/GPS.pm +48 -22
- data/bin/lib/Image/ExifTool/GeoTiff.pm +23 -23
- data/bin/lib/Image/ExifTool/Geotag.pm +80 -45
- data/bin/lib/Image/ExifTool/GoPro.pm +709 -0
- data/bin/lib/Image/ExifTool/H264.pm +40 -18
- data/bin/lib/Image/ExifTool/HP.pm +1 -1
- data/bin/lib/Image/ExifTool/HTML.pm +19 -12
- data/bin/lib/Image/ExifTool/HtmlDump.pm +37 -26
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +297 -23
- data/bin/lib/Image/ExifTool/ID3.pm +12 -7
- data/bin/lib/Image/ExifTool/IPTC.pm +48 -19
- data/bin/lib/Image/ExifTool/ISO.pm +1 -1
- data/bin/lib/Image/ExifTool/ITC.pm +1 -1
- data/bin/lib/Image/ExifTool/Import.pm +13 -9
- data/bin/lib/Image/ExifTool/InDesign.pm +3 -5
- data/bin/lib/Image/ExifTool/JPEG.pm +22 -11
- data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
- data/bin/lib/Image/ExifTool/JSON.pm +3 -3
- data/bin/lib/Image/ExifTool/JVC.pm +1 -1
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
- data/bin/lib/Image/ExifTool/Kodak.pm +1233 -58
- data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/LNK.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/de.pm +33 -24
- data/bin/lib/Image/ExifTool/Lang/en_ca.pm +64 -2
- data/bin/lib/Image/ExifTool/Lang/en_gb.pm +64 -2
- data/bin/lib/Image/ExifTool/Lang/es.pm +8 -4
- data/bin/lib/Image/ExifTool/Lang/fi.pm +46 -4
- data/bin/lib/Image/ExifTool/Lang/fr.pm +5 -3
- data/bin/lib/Image/ExifTool/Lang/it.pm +6 -3
- data/bin/lib/Image/ExifTool/Lang/ja.pm +15 -3
- data/bin/lib/Image/ExifTool/Lang/ko.pm +5 -2
- data/bin/lib/Image/ExifTool/Lang/nl.pm +6 -3
- data/bin/lib/Image/ExifTool/Lang/pl.pm +2 -2
- data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/tr.pm +4 -2
- data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
- data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
- data/bin/lib/Image/ExifTool/Lytro.pm +4 -8
- data/bin/lib/Image/ExifTool/M2TS.pm +10 -9
- data/bin/lib/Image/ExifTool/MIE.pm +12 -8
- data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
- data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
- data/bin/lib/Image/ExifTool/MNG.pm +1 -1
- data/bin/lib/Image/ExifTool/MOI.pm +1 -1
- data/bin/lib/Image/ExifTool/MPC.pm +1 -1
- data/bin/lib/Image/ExifTool/MPEG.pm +2 -3
- data/bin/lib/Image/ExifTool/MPF.pm +6 -6
- data/bin/lib/Image/ExifTool/MWG.pm +4 -4
- data/bin/lib/Image/ExifTool/MXF.pm +2 -2
- data/bin/lib/Image/ExifTool/MacOS.pm +184 -34
- data/bin/lib/Image/ExifTool/MakerNotes.pm +101 -18
- data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +5 -3
- data/bin/lib/Image/ExifTool/Minolta.pm +89 -62
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
- data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +1511 -380
- data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
- data/bin/lib/Image/ExifTool/NikonCustom.pm +2758 -2935
- data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
- data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
- data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +47 -8
- data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
- data/bin/lib/Image/ExifTool/Opus.pm +1 -1
- data/bin/lib/Image/ExifTool/PCX.pm +138 -0
- data/bin/lib/Image/ExifTool/PDF.pm +58 -42
- data/bin/lib/Image/ExifTool/PGF.pm +1 -1
- data/bin/lib/Image/ExifTool/PICT.pm +1 -1
- data/bin/lib/Image/ExifTool/PLIST.pm +12 -5
- data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
- data/bin/lib/Image/ExifTool/PNG.pm +108 -10
- data/bin/lib/Image/ExifTool/PPM.pm +3 -3
- data/bin/lib/Image/ExifTool/PSP.pm +1 -1
- data/bin/lib/Image/ExifTool/Palm.pm +1 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +299 -31
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +201 -19
- data/bin/lib/Image/ExifTool/Pentax.pm +164 -143
- data/bin/lib/Image/ExifTool/PhaseOne.pm +12 -5
- data/bin/lib/Image/ExifTool/PhotoCD.pm +9 -10
- data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +230 -60
- data/bin/lib/Image/ExifTool/PostScript.pm +29 -4
- data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
- data/bin/lib/Image/ExifTool/Qualcomm.pm +2 -2
- data/bin/lib/Image/ExifTool/QuickTime.pm +1539 -279
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1857 -0
- data/bin/lib/Image/ExifTool/README +84 -46
- data/bin/lib/Image/ExifTool/RIFF.pm +116 -23
- data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
- data/bin/lib/Image/ExifTool/RTF.pm +6 -4
- data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
- data/bin/lib/Image/ExifTool/Rawzor.pm +3 -2
- data/bin/lib/Image/ExifTool/Real.pm +1 -1
- data/bin/lib/Image/ExifTool/Reconyx.pm +261 -7
- data/bin/lib/Image/ExifTool/Red.pm +325 -0
- data/bin/lib/Image/ExifTool/Ricoh.pm +3 -7
- data/bin/lib/Image/ExifTool/Samsung.pm +95 -25
- data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
- data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
- data/bin/lib/Image/ExifTool/Shift.pl +26 -12
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +36 -30
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -8
- data/bin/lib/Image/ExifTool/Sony.pm +531 -177
- data/bin/lib/Image/ExifTool/SonyIDC.pm +63 -3
- data/bin/lib/Image/ExifTool/Stim.pm +2 -2
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +23 -23
- data/bin/lib/Image/ExifTool/TagLookup.pm +6352 -5062
- data/bin/lib/Image/ExifTool/TagNames.pod +3024 -565
- data/bin/lib/Image/ExifTool/Theora.pm +1 -1
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -2
- data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
- data/bin/lib/Image/ExifTool/VCard.pm +47 -9
- data/bin/lib/Image/ExifTool/Validate.pm +391 -99
- data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
- data/bin/lib/Image/ExifTool/WTV.pm +319 -0
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +91 -18
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +6 -6
- data/bin/lib/Image/ExifTool/WritePDF.pl +13 -12
- data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePostScript.pl +2 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +764 -121
- data/bin/lib/Image/ExifTool/WriteXMP.pl +176 -67
- data/bin/lib/Image/ExifTool/Writer.pl +490 -246
- data/bin/lib/Image/ExifTool/XMP.pm +216 -76
- data/bin/lib/Image/ExifTool/XMP2.pl +54 -10
- data/bin/lib/Image/ExifTool/XMPStruct.pl +14 -11
- data/bin/lib/Image/ExifTool/ZIP.pm +60 -15
- data/bin/lib/Image/ExifTool/iWork.pm +12 -5
- data/bin/perl-Image-ExifTool.spec +46 -44
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +14 -4
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
16
|
use Image::ExifTool::Exif;
|
17
17
|
|
18
|
-
$VERSION = '1.
|
18
|
+
$VERSION = '1.06';
|
19
19
|
|
20
20
|
sub WritePhaseOne($$$);
|
21
21
|
sub ProcessPhaseOne($$$);
|
@@ -85,6 +85,7 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
|
|
85
85
|
Binary => 1,
|
86
86
|
PutFirst => 1,
|
87
87
|
Writable => 0,
|
88
|
+
Drop => 1, # don't copy to other file types
|
88
89
|
},
|
89
90
|
0x0110 => { #1
|
90
91
|
Name => 'SensorCalibration',
|
@@ -259,6 +260,7 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
|
|
259
260
|
CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
|
260
261
|
GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
261
262
|
TAG_PREFIX => 'SensorCalibration',
|
263
|
+
WRITE_GROUP => 'PhaseOne',
|
262
264
|
VARS => { ENTRY_SIZE => 12 }, # (entries do not contain a format field)
|
263
265
|
0x0400 => {
|
264
266
|
Name => 'SensorDefects',
|
@@ -434,7 +436,7 @@ sub WritePhaseOne($$$)
|
|
434
436
|
|
435
437
|
# nothing to do if we aren't changing any PhaseOne tags
|
436
438
|
my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
|
437
|
-
return undef unless %$newTags;
|
439
|
+
return undef unless %$newTags or $$et{DropTags} or $$et{EDIT_DIRS}{PhaseOne};
|
438
440
|
|
439
441
|
my $dataPt = $$dirInfo{DataPt};
|
440
442
|
my $dataPos = $$dirInfo{DataPos} || 0;
|
@@ -502,7 +504,8 @@ sub WritePhaseOne($$$)
|
|
502
504
|
$valuePtr += $dirStart;
|
503
505
|
}
|
504
506
|
my $value = substr($$dataPt, $valuePtr, $size);
|
505
|
-
my $tagInfo = $$newTags{$tagID} ||
|
507
|
+
my $tagInfo = $$newTags{$tagID} || $$tagTablePtr{$tagID};
|
508
|
+
$tagInfo = $et->GetTagInfo($tagTablePtr, $tagID) if $tagInfo and ref($tagInfo) ne 'HASH';
|
506
509
|
if ($$newTags{$tagID}) {
|
507
510
|
$formatStr = $$tagInfo{Format} if $$tagInfo{Format};
|
508
511
|
my $count = int($size / Image::ExifTool::FormatSize($formatStr));
|
@@ -533,6 +536,10 @@ sub WritePhaseOne($$$)
|
|
533
536
|
$value = $newValue;
|
534
537
|
$size = length $newValue;
|
535
538
|
}
|
539
|
+
} elsif ($$et{DropTags} and (($tagInfo and $$tagInfo{Drop}) or $size > 8192)) {
|
540
|
+
# decrease the number of entries in the directory
|
541
|
+
Set32u(Get32u(\$dirBuff, 0) - 1, \$dirBuff, 0);
|
542
|
+
next; # drop this tag
|
536
543
|
}
|
537
544
|
# add the tagID, possibly format size, and size to this directory entry
|
538
545
|
$dirBuff .= substr($$dataPt, $entry, $entrySize - 8) . Set32u($size);
|
@@ -571,7 +578,7 @@ sub ProcessPhaseOne($$$)
|
|
571
578
|
{
|
572
579
|
my ($et, $dirInfo, $tagTablePtr) = @_;
|
573
580
|
my $dataPt = $$dirInfo{DataPt};
|
574
|
-
my $dataPos = $$dirInfo{DataPos} || 0;
|
581
|
+
my $dataPos = ($$dirInfo{DataPos} || 0) + ($$dirInfo{Base} || 0);
|
575
582
|
my $dirStart = $$dirInfo{DirStart} || 0;
|
576
583
|
my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
|
577
584
|
my $binary = $et->Options('Binary');
|
@@ -704,7 +711,7 @@ One maker notes.
|
|
704
711
|
|
705
712
|
=head1 AUTHOR
|
706
713
|
|
707
|
-
Copyright 2003-
|
714
|
+
Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
|
708
715
|
|
709
716
|
This library is free software; you can redistribute it and/or modify it
|
710
717
|
under the same terms as Perl itself.
|
@@ -13,9 +13,8 @@ package Image::ExifTool::PhotoCD;
|
|
13
13
|
use strict;
|
14
14
|
use vars qw($VERSION);
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
|
-
use Image::ExifTool::Exif; # (for Composite:ImageSize)
|
17
16
|
|
18
|
-
$VERSION = '1.
|
17
|
+
$VERSION = '1.03';
|
19
18
|
|
20
19
|
sub ProcessExtData($$$);
|
21
20
|
|
@@ -411,22 +410,22 @@ sub ProcessExtData($$$);
|
|
411
410
|
1538.1 => {
|
412
411
|
Name => 'ImageWidth',
|
413
412
|
Mask => 0x0c,
|
414
|
-
#
|
415
|
-
ValueConv => '($$self{Orient} & 0x01 ? 512 : 768) * (
|
413
|
+
# 0=Base (768x512), 1=4Base (1536x1024), 2=16Base (3072x2048)
|
414
|
+
ValueConv => '($$self{Orient} & 0x01 ? 512 : 768) * ($val * 2 || 1)',
|
416
415
|
},
|
417
416
|
1538.2 => {
|
418
417
|
Name => 'ImageHeight',
|
419
418
|
Mask => 0x0c,
|
420
|
-
ValueConv => '($$self{Orient} & 0x01 ? 768 : 512) * (
|
419
|
+
ValueConv => '($$self{Orient} & 0x01 ? 768 : 512) * ($val * 2 || 1)',
|
421
420
|
},
|
422
421
|
1538.3 => {
|
423
422
|
Name => 'CompressionClass',
|
424
423
|
Mask => 0x60,
|
425
424
|
PrintConv => {
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
425
|
+
0 => 'Class 1 - 35mm film; Pictoral hard copy',
|
426
|
+
1 => 'Class 2 - Large format film',
|
427
|
+
2 => 'Class 3 - Text and graphics, high resolution',
|
428
|
+
3 => 'Class 4 - Text and graphics, high dynamic range',
|
430
429
|
},
|
431
430
|
},
|
432
431
|
#1544 => 'InterleaveRatio',
|
@@ -485,7 +484,7 @@ information from Kodak Photo CD Image Pac (PCD) files.
|
|
485
484
|
|
486
485
|
=head1 AUTHOR
|
487
486
|
|
488
|
-
Copyright 2003-
|
487
|
+
Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
|
489
488
|
|
490
489
|
This library is free software; you can redistribute it and/or modify it
|
491
490
|
under the same terms as Perl itself.
|
@@ -236,7 +236,7 @@ write information written by the Camera Bits Photo Mechanic software.
|
|
236
236
|
|
237
237
|
=head1 AUTHOR
|
238
238
|
|
239
|
-
Copyright 2003-
|
239
|
+
Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
|
240
240
|
|
241
241
|
This library is free software; you can redistribute it and/or modify it
|
242
242
|
under the same terms as Perl itself.
|
@@ -28,7 +28,7 @@ use strict;
|
|
28
28
|
use vars qw($VERSION $AUTOLOAD $iptcDigestInfo);
|
29
29
|
use Image::ExifTool qw(:DataAccess :Utils);
|
30
30
|
|
31
|
-
$VERSION = '1.
|
31
|
+
$VERSION = '1.63';
|
32
32
|
|
33
33
|
sub ProcessPhotoshop($$$);
|
34
34
|
sub WritePhotoshop($$$);
|
@@ -486,7 +486,13 @@ my %unicodeString = (
|
|
486
486
|
# tags extracted from layer information
|
487
487
|
# (tag ID's are for convenience only)
|
488
488
|
_xcnt => { Name => 'LayerCount', Format => 'int16u' },
|
489
|
-
_xrct => {
|
489
|
+
_xrct => {
|
490
|
+
Name => 'LayerRectangles',
|
491
|
+
Format => 'int32u',
|
492
|
+
Count => 4,
|
493
|
+
List => 1,
|
494
|
+
Notes => 'top left bottom right',
|
495
|
+
},
|
490
496
|
_xnam => { Name => 'LayerNames',
|
491
497
|
Format => 'string',
|
492
498
|
List => 1,
|
@@ -499,6 +505,7 @@ my %unicodeString = (
|
|
499
505
|
Name => 'LayerBlendModes',
|
500
506
|
Format => 'undef',
|
501
507
|
List => 1,
|
508
|
+
RawConv => 'GetByteOrder() eq "II" ? pack "N*", unpack "V*", $val : $val',
|
502
509
|
PrintConv => {
|
503
510
|
pass => 'Pass Through',
|
504
511
|
norm => 'Normal',
|
@@ -562,13 +569,27 @@ my %unicodeString = (
|
|
562
569
|
Groups => { 2 => 'Time' },
|
563
570
|
List => 1,
|
564
571
|
RawConv => q{
|
565
|
-
return '' unless $val =~ /
|
566
|
-
my $tmp = $
|
572
|
+
return '' unless $val =~ /layerTime(doub|buod)(.{8})/s;
|
573
|
+
my $tmp = $2;
|
567
574
|
return GetDouble(\$tmp, 0);
|
568
575
|
},
|
569
576
|
ValueConv => 'length $val ? ConvertUnixTime($val,1) : ""',
|
570
577
|
PrintConv => 'length $val ? $self->ConvertDateTime($val) : ""',
|
571
|
-
}
|
578
|
+
},
|
579
|
+
);
|
580
|
+
|
581
|
+
# tags extracted from ImageSourceData found in TIFF images (ref PH)
|
582
|
+
%Image::ExifTool::Photoshop::DocumentData = (
|
583
|
+
PROCESS_PROC => \&ProcessDocumentData,
|
584
|
+
GROUPS => { 2 => 'Image' },
|
585
|
+
Layr => {
|
586
|
+
Name => 'Layers',
|
587
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Layers' },
|
588
|
+
},
|
589
|
+
Lr16 => { # (NC)
|
590
|
+
Name => 'Layers',
|
591
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Layers' },
|
592
|
+
},
|
572
593
|
);
|
573
594
|
|
574
595
|
# image data
|
@@ -626,16 +647,16 @@ sub ConvertPascalString($$)
|
|
626
647
|
}
|
627
648
|
|
628
649
|
#------------------------------------------------------------------------------
|
629
|
-
# Process Photoshop layers and mask information
|
650
|
+
# Process Photoshop layers and mask information section of PSD/PSB file
|
630
651
|
# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
|
631
652
|
# Returns: 1 on success (and seeks to the end of this section)
|
632
|
-
sub
|
653
|
+
sub ProcessLayersAndMask($$$)
|
633
654
|
{
|
634
655
|
local $_;
|
635
656
|
my ($et, $dirInfo, $tagTablePtr) = @_;
|
636
657
|
my $raf = $$dirInfo{RAF};
|
637
658
|
my $fileType = $$et{VALUE}{FileType};
|
638
|
-
my
|
659
|
+
my $data;
|
639
660
|
|
640
661
|
return 0 unless $fileType eq 'PSD' or $fileType eq 'PSB'; # (no layer section in CS1 files)
|
641
662
|
|
@@ -644,91 +665,222 @@ sub ProcessLayers($$$)
|
|
644
665
|
|
645
666
|
# read the layer information header
|
646
667
|
my $n = $psiz * 2 + 2;
|
647
|
-
my $dataPos = $raf->Tell();
|
648
668
|
$raf->Read($data, $n) == $n or return 0;
|
649
|
-
my %dinfo = ( DataPt => \$data, DataPos => $dataPos );
|
650
669
|
my $tot = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0); # length of layer and mask info
|
651
|
-
|
652
|
-
my $
|
670
|
+
return 1 if $tot == 0;
|
671
|
+
my $end = $raf->Tell() - $psiz - 2 + $tot;
|
672
|
+
$data = substr $data, $psiz;
|
673
|
+
my $len = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0); # length of layer info section
|
674
|
+
my $num = Get16s(\$data, $psiz);
|
675
|
+
# check for Lr16 block if layers length is 0 (ref https://forums.adobe.com/thread/1540914)
|
676
|
+
if ($len == 0 and $num == 0) {
|
677
|
+
$raf->Read($data,10) == 10 or return 0;
|
678
|
+
if ($data =~/^..8BIMLr16/s) {
|
679
|
+
$raf->Read($data, $psiz+2) == $psiz+2 or return 0;
|
680
|
+
$len = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0);
|
681
|
+
} else {
|
682
|
+
$raf->Seek(-10, 1) or return 0;
|
683
|
+
}
|
684
|
+
}
|
685
|
+
$len += 2; # include layer count with layer info section
|
686
|
+
$raf->Seek(-2, 1) or return 0;
|
687
|
+
my %dinfo = (
|
688
|
+
RAF => $raf,
|
689
|
+
DirLen => $len,
|
690
|
+
);
|
691
|
+
$$et{IsPSB} = $psb; # set PSB flag
|
692
|
+
ProcessLayers($et, \%dinfo, $tagTablePtr);
|
693
|
+
|
694
|
+
# seek to the end of this section and return success flag
|
695
|
+
return $raf->Seek($end, 0) ? 1 : 0;
|
696
|
+
}
|
697
|
+
|
698
|
+
#------------------------------------------------------------------------------
|
699
|
+
# Process Photoshop layers (beginning with layer count)
|
700
|
+
# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
|
701
|
+
# Returns: 1 on success
|
702
|
+
# Notes: Uses ExifTool IsPSB member to determine whether file is PSB format
|
703
|
+
sub ProcessLayers($$$)
|
704
|
+
{
|
705
|
+
local $_;
|
706
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
707
|
+
my ($i, $n, %count, $buff, $buf2);
|
708
|
+
my $raf = $$dirInfo{RAF};
|
709
|
+
my $dirLen = $$dirInfo{DirLen};
|
710
|
+
my $verbose = $$et{OPTIONS}{Verbose};
|
711
|
+
my %dinfo = ( DataPt => \$buff, Base => $raf->Tell() );
|
712
|
+
my $pos = 0;
|
713
|
+
return 0 if $dirLen < 2;
|
714
|
+
$raf->Read($buff, 2) == 2 or return 0;
|
715
|
+
my $num = Get16s(\$buff, 0);
|
653
716
|
$num = -$num if $num < 0; # (first channel is transparency data if negative)
|
654
|
-
$et->
|
655
|
-
$et->
|
656
|
-
$dataPos += $n; # point to start of layer information section
|
717
|
+
$et->VerboseDir('Layers', $num, $dirLen);
|
718
|
+
$et->HandleTag($tagTablePtr, '_xcnt', $num, Start => $pos, Size => 2, %dinfo); # LayerCount
|
657
719
|
my $oldIndent = $$et{INDENT};
|
658
720
|
$$et{INDENT} .= '| ';
|
659
721
|
|
660
|
-
|
722
|
+
$pos += 2;
|
723
|
+
my $psb = $$et{IsPSB}; # is PSB format?
|
724
|
+
my $psiz = $psb ? 8 : 4;
|
661
725
|
for ($i=0; $i<$num; ++$i) {
|
662
726
|
$et->VPrint(0, $oldIndent.'+ [Layer '.($i+1)." of $num]\n");
|
663
|
-
last if $pos + 18 > $
|
664
|
-
|
665
|
-
$
|
666
|
-
$dinfo{DataPos} = $dataPos + $pos;
|
727
|
+
last if $pos + 18 > $dirLen;
|
728
|
+
$raf->Read($buff, 18) == 18 or last;
|
729
|
+
$dinfo{DataPos} = $pos;
|
667
730
|
# save the layer rectangle
|
668
|
-
$et->HandleTag($tagTablePtr, '_xrct', undef, Size => 16, %dinfo);
|
669
|
-
my $numChannels = Get16u(\$
|
670
|
-
$
|
671
|
-
|
672
|
-
$
|
673
|
-
$
|
731
|
+
$et->HandleTag($tagTablePtr, '_xrct', undef, Start => 0, Size => 16, %dinfo);
|
732
|
+
my $numChannels = Get16u(\$buff, 16);
|
733
|
+
$n = (2 + $psiz) * $numChannels; # size of channel information
|
734
|
+
$raf->Seek($n, 1) or last;
|
735
|
+
$pos += 18 + $n;
|
736
|
+
last if $pos + 20 > $dirLen;
|
737
|
+
$raf->Read($buff, 20) == 20 or last;
|
738
|
+
$dinfo{DataPos} = $pos;
|
739
|
+
my $sig = substr($buff, 0, 4);
|
740
|
+
$sig =~ /^(8BIM|MIB8)$/ or last; # verify signature
|
674
741
|
$et->HandleTag($tagTablePtr, '_xbnd', undef, Start => 4, Size => 4, %dinfo);
|
675
742
|
$et->HandleTag($tagTablePtr, '_xopc', undef, Start => 8, Size => 1, %dinfo);
|
676
|
-
my $nxt = $pos + 16 + Get32u(\$
|
677
|
-
$n = Get32u(\$
|
743
|
+
my $nxt = $pos + 16 + Get32u(\$buff, 12);
|
744
|
+
$n = Get32u(\$buff, 16); # get size of layer mask data
|
678
745
|
$pos += 20 + $n; # skip layer mask data
|
679
|
-
last if $pos + 4 > $
|
680
|
-
$raf->Seek($
|
681
|
-
$
|
682
|
-
$n = Get32u(\$data, 0); # get size of layer blending ranges
|
746
|
+
last if $pos + 4 > $dirLen;
|
747
|
+
$raf->Seek($n, 1) and $raf->Read($buff, 4) == 4 or last;
|
748
|
+
$n = Get32u(\$buff, 0); # get size of layer blending ranges
|
683
749
|
$pos += 4 + $n; # skip layer blending ranges data
|
684
|
-
last if $pos + 1 > $
|
685
|
-
$raf->Seek($
|
686
|
-
$
|
687
|
-
|
688
|
-
|
689
|
-
$
|
690
|
-
$
|
691
|
-
$
|
750
|
+
last if $pos + 1 > $dirLen;
|
751
|
+
$raf->Seek($n, 1) and $raf->Read($buff, 1) == 1 or last;
|
752
|
+
$n = Get8u(\$buff, 0); # get length of layer name
|
753
|
+
last if $pos + 1 + $n > $dirLen;
|
754
|
+
$raf->Read($buff, $n) == $n or last;
|
755
|
+
$dinfo{DataPos} = $pos + 1;
|
756
|
+
$et->HandleTag($tagTablePtr, '_xnam', undef, Start => 0, Size => $n, %dinfo);
|
757
|
+
my $frag = ($n + 1) & 0x3;
|
758
|
+
$raf->Seek(4 - $frag, 1) or last if $frag;
|
692
759
|
$n = ($n + 4) & 0xfffffffc; # +1 for length byte then pad to multiple of 4 bytes
|
693
760
|
$pos += $n;
|
694
761
|
# process additional layer info
|
695
762
|
while ($pos + 12 <= $nxt) {
|
696
|
-
$raf->
|
697
|
-
my $
|
763
|
+
$raf->Read($buff, 12) == 12 or last;
|
764
|
+
my $dat = substr($buff, 0, 8);
|
765
|
+
$dat = pack 'N*', unpack 'V*', $dat if GetByteOrder() eq 'II';
|
766
|
+
my $sig = substr($dat, 0, 4);
|
698
767
|
last unless $sig eq '8BIM' or $sig eq '8B64'; # verify signature
|
699
|
-
my $tag = substr($
|
768
|
+
my $tag = substr($dat, 4, 4);
|
700
769
|
# (some structures have an 8-byte size word [augh!]
|
701
770
|
# --> it would be great if '8B64' indicated a 64-bit version, and this may well
|
702
771
|
# be the case, but it is not mentioned in the Photoshop file format specification)
|
703
772
|
if ($psb and $tag =~ /^(LMsk|Lr16|Lr32|Layr|Mt16|Mt32|Mtrn|Alph|FMsk|lnk2|FEid|FXid|PxSD)$/) {
|
704
773
|
last if $pos + 16 > $nxt;
|
705
|
-
$raf->Read($
|
706
|
-
$
|
707
|
-
$n = Get64u(\$
|
774
|
+
$raf->Read($buf2, 4) == 4 or last;
|
775
|
+
$buff .= $buf2;
|
776
|
+
$n = Get64u(\$buff, 8);
|
708
777
|
$pos += 4;
|
709
778
|
} else {
|
710
|
-
$n = Get32u(\$
|
779
|
+
$n = Get32u(\$buff, 8);
|
711
780
|
}
|
712
781
|
$pos += 12;
|
713
782
|
last if $pos + $n > $nxt;
|
714
|
-
$
|
715
|
-
$
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
$
|
783
|
+
$frag = $n & 0x3;
|
784
|
+
if ($$tagTablePtr{$tag} or $verbose) {
|
785
|
+
# pad with empty entries if necessary to keep the same index for each item in the layer
|
786
|
+
$count{$tag} = 0 unless defined $count{$tag};
|
787
|
+
$raf->Read($buff, $n) == $n or last;
|
788
|
+
$dinfo{DataPos} = $pos;
|
789
|
+
while ($count{$tag} < $i) {
|
790
|
+
$et->HandleTag($tagTablePtr, $tag, '');
|
791
|
+
++$count{$tag};
|
792
|
+
}
|
793
|
+
$et->HandleTag($tagTablePtr, $tag, undef, Start => 0, Size => $n, %dinfo);
|
720
794
|
++$count{$tag};
|
795
|
+
if ($frag) {
|
796
|
+
$raf->Seek(4 - $frag, 1) or last;
|
797
|
+
$n += 4 - $frag; # pad to multiple of 4 bytes (PH NC)
|
798
|
+
}
|
799
|
+
} else {
|
800
|
+
$n += 4 - $frag if $frag;
|
801
|
+
$raf->Seek($n, 1) or last;
|
721
802
|
}
|
722
|
-
$et->HandleTag($tagTablePtr, $tag, undef, %dinfo);
|
723
|
-
++$count{$tag};
|
724
803
|
$pos += $n; # step to start of next structure
|
725
804
|
}
|
726
805
|
$pos = $nxt;
|
727
806
|
}
|
728
807
|
$$et{INDENT} = $oldIndent;
|
729
|
-
|
730
|
-
|
731
|
-
|
808
|
+
return 1;
|
809
|
+
}
|
810
|
+
|
811
|
+
#------------------------------------------------------------------------------
|
812
|
+
# Process Photoshop ImageSourceData
|
813
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
814
|
+
# Returns: 1 on success
|
815
|
+
sub ProcessDocumentData($$$)
|
816
|
+
{
|
817
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
818
|
+
my $verbose = $$et{OPTIONS}{Verbose};
|
819
|
+
my $raf = $$dirInfo{RAF};
|
820
|
+
my $dirLen = $$dirInfo{DirLen};
|
821
|
+
my $pos = 36; # length of header
|
822
|
+
my $buff;
|
823
|
+
|
824
|
+
$et->VerboseDir('Photoshop Document Data', undef, $dirLen);
|
825
|
+
unless ($raf) {
|
826
|
+
my $dataPt = $$dirInfo{DataPt};
|
827
|
+
my $start = $$dirInfo{DirStart} || 0;
|
828
|
+
$raf = new File::RandomAccess($dataPt);
|
829
|
+
$raf->Seek($start, 0) if $start;
|
830
|
+
$dirLen = length $$dataPt - $start unless defined $dirLen;
|
831
|
+
$et->VerboseDump($dataPt, Start => $start, Len => $dirLen, Base => $$dirInfo{Base});
|
832
|
+
}
|
833
|
+
unless ($raf->Read($buff, $pos) == $pos and
|
834
|
+
$buff =~ /^Adobe Photoshop Document Data (Block|V0002)\0/)
|
835
|
+
{
|
836
|
+
$et->Warn('Invalid Photoshop Document Data');
|
837
|
+
return 0;
|
838
|
+
}
|
839
|
+
my $psb = ($1 eq 'V0002');
|
840
|
+
my %dinfo = ( DataPt => \$buff );
|
841
|
+
my ($n, $setOrder);
|
842
|
+
$$et{IsPSB} = $psb; # set PSB flag (needed when handling Layers directory)
|
843
|
+
while ($pos + 12 <= $dirLen) {
|
844
|
+
$raf->Read($buff, 8) == 8 or last;
|
845
|
+
# set byte order according to byte order of first signature
|
846
|
+
SetByteOrder($buff =~ /^(8BIM|8B64)/ ? 'MM' : 'II') if $pos == 36;
|
847
|
+
$buff = pack 'N*', unpack 'V*', $buff if GetByteOrder() eq 'II';
|
848
|
+
my $sig = substr($buff, 0, 4);
|
849
|
+
last unless $sig eq '8BIM' or $sig eq '8B64'; # verify signature
|
850
|
+
my $tag = substr($buff, 4, 4);
|
851
|
+
if ($psb and $tag =~ /^(LMsk|Lr16|Lr32|Layr|Mt16|Mt32|Mtrn|Alph|FMsk|lnk2|FEid|FXid|PxSD)$/) {
|
852
|
+
last if $pos + 16 > $dirLen;
|
853
|
+
$raf->Read($buff, 8) == 8 or last;
|
854
|
+
$n = Get64u(\$buff, 0);
|
855
|
+
$pos += 4;
|
856
|
+
} else {
|
857
|
+
$raf->Read($buff, 4) == 4 or last;
|
858
|
+
$n = Get32u(\$buff, 0);
|
859
|
+
}
|
860
|
+
$pos += 12;
|
861
|
+
last if $pos + $n > $dirLen;
|
862
|
+
my $pad = (4 - ($n & 3)) & 3; # number of padding bytes
|
863
|
+
my $tagInfo = $$tagTablePtr{$tag};
|
864
|
+
if ($tagInfo or $verbose) {
|
865
|
+
if ($tagInfo and $$tagInfo{SubDirectory}) {
|
866
|
+
my $fpos = $raf->Tell() + $n + $pad;
|
867
|
+
my $subTable = GetTagTable($$tagInfo{SubDirectory}{TagTable});
|
868
|
+
$et->ProcessDirectory({ RAF => $raf, DirLen => $n }, $subTable);
|
869
|
+
$raf->Seek($fpos, 0) or last;
|
870
|
+
} else {
|
871
|
+
$dinfo{DataPos} = $raf->Tell();
|
872
|
+
$dinfo{Start} = 0;
|
873
|
+
$dinfo{Size} = $n;
|
874
|
+
$raf->Read($buff, $n) == $n or last;
|
875
|
+
$et->HandleTag($tagTablePtr, $tag, undef, %dinfo);
|
876
|
+
$raf->Seek($pad, 1) or last;
|
877
|
+
}
|
878
|
+
} else {
|
879
|
+
$raf->Seek($n + $pad, 1) or last;
|
880
|
+
}
|
881
|
+
$pos += $n + $pad; # step to start of next structure
|
882
|
+
}
|
883
|
+
return 1;
|
732
884
|
}
|
733
885
|
|
734
886
|
#------------------------------------------------------------------------------
|
@@ -745,6 +897,23 @@ sub ProcessPhotoshop($$$)
|
|
745
897
|
my $verbose = $et->Options('Verbose');
|
746
898
|
my $success = 0;
|
747
899
|
|
900
|
+
# ignore non-standard XMP while in strict MWG compatibility mode
|
901
|
+
if (($Image::ExifTool::MWG::strict or $et->Options('Validate')) and
|
902
|
+
$$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
|
903
|
+
{
|
904
|
+
my $path = $et->MetadataPath();
|
905
|
+
unless ($path =~ /^(JPEG-APP13-Photoshop|TIFF-IFD0-Photoshop|PSD)$/) {
|
906
|
+
if ($Image::ExifTool::MWG::strict) {
|
907
|
+
$et->Warn("Ignored non-standard Photoshop at $path");
|
908
|
+
return 1;
|
909
|
+
} else {
|
910
|
+
$et->Warn("Non-standard Photoshop at $path", 1);
|
911
|
+
}
|
912
|
+
}
|
913
|
+
}
|
914
|
+
if ($$et{FILE_TYPE} eq 'JPEG' and $$dirInfo{Parent} ne 'APP13') {
|
915
|
+
$$et{LOW_PRIORITY_DIR}{'*'} = 1; # lower priority of all these tags
|
916
|
+
}
|
748
917
|
SetByteOrder('MM'); # Photoshop is always big-endian
|
749
918
|
$verbose and $et->VerboseDir('Photoshop', 0, $$dirInfo{DirLen});
|
750
919
|
|
@@ -809,6 +978,7 @@ sub ProcessPhotoshop($$$)
|
|
809
978
|
$size += 1 if $size & 0x01; # size is padded to an even # bytes
|
810
979
|
$pos += $size;
|
811
980
|
}
|
981
|
+
delete $$et{LOW_PRIORITY_DIR}{'*'};
|
812
982
|
return $success;
|
813
983
|
}
|
814
984
|
|
@@ -905,7 +1075,7 @@ sub ProcessPSD($$)
|
|
905
1075
|
$tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Layers');
|
906
1076
|
my $oldIndent = $$et{INDENT};
|
907
1077
|
$$et{INDENT} .= '| ';
|
908
|
-
if (
|
1078
|
+
if (ProcessLayersAndMask($et, \%dirInfo, $tagTablePtr) and
|
909
1079
|
# read compression mode from image data section
|
910
1080
|
$raf->Read($data,2) == 2)
|
911
1081
|
{
|
@@ -957,7 +1127,7 @@ be preserved when copying Photoshop information via user-defined tags.
|
|
957
1127
|
|
958
1128
|
=head1 AUTHOR
|
959
1129
|
|
960
|
-
Copyright 2003-
|
1130
|
+
Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
|
961
1131
|
|
962
1132
|
This library is free software; you can redistribute it and/or modify it
|
963
1133
|
under the same terms as Perl itself.
|