Exif.pm (Image-ExifTool-12.57) | : | Exif.pm (Image-ExifTool-12.58) | ||
---|---|---|---|---|
skipping to change at line 68 | skipping to change at line 68 | |||
$VERSION = '4.43'; | $VERSION = '4.43'; | |||
sub ProcessExif($$$); | sub ProcessExif($$$); | |||
sub WriteExif($$$); | sub WriteExif($$$); | |||
sub CheckExif($$$); | sub CheckExif($$$); | |||
sub RebuildMakerNotes($$$); | sub RebuildMakerNotes($$$); | |||
sub EncodeExifText($$); | sub EncodeExifText($$); | |||
sub ValidateIFD($;$); | sub ValidateIFD($;$); | |||
sub ValidateImageData($$$;$); | sub ValidateImageData($$$;$); | |||
sub AddImageDataMD5($$$); | ||||
sub ProcessTiffIFD($$$); | sub ProcessTiffIFD($$$); | |||
sub PrintParameter($$$); | sub PrintParameter($$$); | |||
sub GetOffList($$$$$); | sub GetOffList($$$$$); | |||
sub PrintOpcode($$$); | sub PrintOpcode($$$); | |||
sub PrintLensInfo($); | sub PrintLensInfo($); | |||
sub InverseOffsetTime($$); | sub InverseOffsetTime($$); | |||
sub ConvertLensInfo($); | sub ConvertLensInfo($); | |||
# size limit for loading binary data block into memory | # size limit for loading binary data block into memory | |||
sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; } | sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; } | |||
skipping to change at line 576 | skipping to change at line 577 | |||
RawConv => '$val =~ s/\s+$//; $$self{Model} = $val', | RawConv => '$val =~ s/\s+$//; $$self{Model} = $val', | |||
}, | }, | |||
0x111 => [ | 0x111 => [ | |||
{ | { | |||
Condition => q[ | Condition => q[ | |||
$$self{TIFF_TYPE} eq 'MRW' and $$self{DIR_NAME} eq 'IFD0' and | $$self{TIFF_TYPE} eq 'MRW' and $$self{DIR_NAME} eq 'IFD0' and | |||
$$self{Model} =~ /^DiMAGE A200/ | $$self{Model} =~ /^DiMAGE A200/ | |||
], | ], | |||
Name => 'StripOffsets', | Name => 'StripOffsets', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x117, # point to associated byte counts | OffsetPair => 0x117, # point to associated byte counts | |||
# A200 stores this information in the wrong byte order!! | # A200 stores this information in the wrong byte order!! | |||
ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val)))) ;\$val', | ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val)))) ;\$val', | |||
ByteOrder => 'LittleEndian', | ByteOrder => 'LittleEndian', | |||
}, | }, | |||
{ | { | |||
Condition => '$$self{Compression} and $$self{Compression} eq "34892" ', # DNG Lossy JPEG | Condition => '$$self{Compression} and $$self{Compression} eq "34892" ', # DNG Lossy JPEG | |||
Name => 'OtherImageStart', | Name => 'OtherImageStart', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x117, # point to associated byte counts | OffsetPair => 0x117, # point to associated byte counts | |||
DataTag => 'OtherImage', | DataTag => 'OtherImage', | |||
}, | }, | |||
{ | { | |||
# (APP1 IFD2 is for Leica JPEG preview) | # (APP1 IFD2 is for Leica JPEG preview) | |||
Condition => q[ | Condition => q[ | |||
not ($$self{TIFF_TYPE} eq 'CR2' and $$self{DIR_NAME} eq 'IFD0') and | not ($$self{TIFF_TYPE} eq 'CR2' and $$self{DIR_NAME} eq 'IFD0') and | |||
not ($$self{TIFF_TYPE} =~ /^(DNG|TIFF)$/ and $$self{Compression} eq '7' and $$self{SubfileType} ne '0') and | not ($$self{TIFF_TYPE} =~ /^(DNG|TIFF)$/ and $$self{Compression} eq '7' and $$self{SubfileType} ne '0') and | |||
not ($$self{TIFF_TYPE} eq 'APP1' and $$self{DIR_NAME} eq 'IFD2') | not ($$self{TIFF_TYPE} eq 'APP1' and $$self{DIR_NAME} eq 'IFD2') | |||
], | ], | |||
Name => 'StripOffsets', | Name => 'StripOffsets', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x117, # point to associated byte counts | OffsetPair => 0x117, # point to associated byte counts | |||
ValueConv => 'length($val) > 32 ? \$val : $val', | ValueConv => 'length($val) > 32 ? \$val : $val', | |||
}, | }, | |||
{ | { | |||
# PreviewImageStart in IFD0 of CR2 images | # PreviewImageStart in IFD0 of CR2 images | |||
Condition => '$$self{TIFF_TYPE} eq "CR2"', | Condition => '$$self{TIFF_TYPE} eq "CR2"', | |||
Name => 'PreviewImageStart', | Name => 'PreviewImageStart', | |||
IsOffset => 1, | IsOffset => 1, | |||
OffsetPair => 0x117, | OffsetPair => 0x117, | |||
Notes => q{ | Notes => q{ | |||
skipping to change at line 633 | skipping to change at line 637 | |||
DataTag => 'PreviewImage', | DataTag => 'PreviewImage', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'All', # (writes to specific group of associated Co mposite tag) | WriteGroup => 'All', # (writes to specific group of associated Co mposite tag) | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
{ | { | |||
# JpgFromRawStart in various IFD's of DNG images except SubIFD2 | # JpgFromRawStart in various IFD's of DNG images except SubIFD2 | |||
Name => 'JpgFromRawStart', | Name => 'JpgFromRawStart', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x117, | OffsetPair => 0x117, | |||
DataTag => 'JpgFromRaw', | DataTag => 'JpgFromRaw', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'SubIFD2', | WriteGroup => 'SubIFD2', | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
], | ], | |||
0x112 => { | 0x112 => { | |||
Name => 'Orientation', | Name => 'Orientation', | |||
skipping to change at line 936 | skipping to change at line 941 | |||
}, | }, | |||
0x143 => { | 0x143 => { | |||
Name => 'TileLength', | Name => 'TileLength', | |||
Protected => 1, | Protected => 1, | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'IFD0', | WriteGroup => 'IFD0', | |||
}, | }, | |||
0x144 => { | 0x144 => { | |||
Name => 'TileOffsets', | Name => 'TileOffsets', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x145, | OffsetPair => 0x145, | |||
ValueConv => 'length($val) > 32 ? \$val : $val', | ValueConv => 'length($val) > 32 ? \$val : $val', | |||
}, | }, | |||
0x145 => { | 0x145 => { | |||
Name => 'TileByteCounts', | Name => 'TileByteCounts', | |||
OffsetPair => 0x144, | OffsetPair => 0x144, | |||
ValueConv => 'length($val) > 32 ? \$val : $val', | ValueConv => 'length($val) > 32 ? \$val : $val', | |||
}, | }, | |||
0x146 => 'BadFaxLines', #3 | 0x146 => 'BadFaxLines', #3 | |||
0x147 => { #3 | 0x147 => { #3 | |||
skipping to change at line 1190 | skipping to change at line 1196 | |||
DataTag => 'PreviewImage', | DataTag => 'PreviewImage', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'IFD0', | WriteGroup => 'IFD0', | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
{ | { | |||
Name => 'JpgFromRawStart', | Name => 'JpgFromRawStart', | |||
Condition => '$$self{DIR_NAME} eq "SubIFD"', | Condition => '$$self{DIR_NAME} eq "SubIFD"', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x202, | OffsetPair => 0x202, | |||
DataTag => 'JpgFromRaw', | DataTag => 'JpgFromRaw', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'SubIFD', | WriteGroup => 'SubIFD', | |||
# JpgFromRaw is in SubIFD of NEF, NRW and SRW files | # JpgFromRaw is in SubIFD of NEF, NRW and SRW files | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
{ | { | |||
Name => 'JpgFromRawStart', | Name => 'JpgFromRawStart', | |||
Condition => '$$self{DIR_NAME} eq "IFD2"', | Condition => '$$self{DIR_NAME} eq "IFD2"', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x202, | OffsetPair => 0x202, | |||
DataTag => 'JpgFromRaw', | DataTag => 'JpgFromRaw', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'IFD2', | WriteGroup => 'IFD2', | |||
# JpgFromRaw is in IFD2 of PEF files | # JpgFromRaw is in IFD2 of PEF files | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
{ | { | |||
Name => 'OtherImageStart', | Name => 'OtherImageStart', | |||
Condition => '$$self{DIR_NAME} eq "SubIFD1"', | Condition => '$$self{DIR_NAME} eq "SubIFD1"', | |||
IsImageData => 1, | ||||
IsOffset => 1, | IsOffset => 1, | |||
OffsetPair => 0x202, | OffsetPair => 0x202, | |||
DataTag => 'OtherImage', | DataTag => 'OtherImage', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'SubIFD1', | WriteGroup => 'SubIFD1', | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
{ | { | |||
Name => 'OtherImageStart', | Name => 'OtherImageStart', | |||
Condition => '$$self{DIR_NAME} eq "SubIFD2"', | Condition => '$$self{DIR_NAME} eq "SubIFD2"', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x202, | OffsetPair => 0x202, | |||
DataTag => 'OtherImage', | DataTag => 'OtherImage', | |||
Writable => 'int32u', | Writable => 'int32u', | |||
WriteGroup => 'SubIFD2', | WriteGroup => 'SubIFD2', | |||
Protected => 2, | Protected => 2, | |||
Permanent => 1, | Permanent => 1, | |||
}, | }, | |||
{ | { | |||
Name => 'OtherImageStart', | Name => 'OtherImageStart', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0x202, | OffsetPair => 0x202, | |||
}, | }, | |||
], | ], | |||
0x202 => [ | 0x202 => [ | |||
{ | { | |||
Name => 'ThumbnailLength', | Name => 'ThumbnailLength', | |||
Notes => q{ | Notes => q{ | |||
called JPEGInterchangeFormatLength in the specification, this is | called JPEGInterchangeFormatLength in the specification, this is | |||
ThumbnailLength in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW | ThumbnailLength in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW | |||
images and AVI and MOV videos, and the SubIFD in IFD1 of SRW ima ges; | images and AVI and MOV videos, and the SubIFD in IFD1 of SRW ima ges; | |||
skipping to change at line 2971 | skipping to change at line 2982 | |||
1 => 'Page', | 1 => 'Page', | |||
} }, | } }, | |||
}, | }, | |||
0xbc80 => 'ImageWidth', #13 | 0xbc80 => 'ImageWidth', #13 | |||
0xbc81 => 'ImageHeight', #13 | 0xbc81 => 'ImageHeight', #13 | |||
0xbc82 => 'WidthResolution', #13 | 0xbc82 => 'WidthResolution', #13 | |||
0xbc83 => 'HeightResolution', #13 | 0xbc83 => 'HeightResolution', #13 | |||
0xbcc0 => { #13 | 0xbcc0 => { #13 | |||
Name => 'ImageOffset', | Name => 'ImageOffset', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0xbcc1, # point to associated byte count | OffsetPair => 0xbcc1, # point to associated byte count | |||
}, | }, | |||
0xbcc1 => { #13 | 0xbcc1 => { #13 | |||
Name => 'ImageByteCount', | Name => 'ImageByteCount', | |||
OffsetPair => 0xbcc0, # point to associated offset | OffsetPair => 0xbcc0, # point to associated offset | |||
}, | }, | |||
0xbcc2 => { #13 | 0xbcc2 => { #13 | |||
Name => 'AlphaOffset', | Name => 'AlphaOffset', | |||
IsOffset => 1, | IsOffset => 1, | |||
IsImageData => 1, | ||||
OffsetPair => 0xbcc3, # point to associated byte count | OffsetPair => 0xbcc3, # point to associated byte count | |||
}, | }, | |||
0xbcc3 => { #13 | 0xbcc3 => { #13 | |||
Name => 'AlphaByteCount', | Name => 'AlphaByteCount', | |||
OffsetPair => 0xbcc2, # point to associated offset | OffsetPair => 0xbcc2, # point to associated offset | |||
}, | }, | |||
0xbcc4 => { #13 | 0xbcc4 => { #13 | |||
Name => 'ImageDataDiscard', | Name => 'ImageDataDiscard', | |||
PrintConv => { | PrintConv => { | |||
0 => 'Full Resolution', | 0 => 'Full Resolution', | |||
skipping to change at line 5887 | skipping to change at line 5900 | |||
my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart; | my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart; | |||
my $dirName = $$dirInfo{DirName}; | my $dirName = $$dirInfo{DirName}; | |||
my $base = $$dirInfo{Base} || 0; | my $base = $$dirInfo{Base} || 0; | |||
my $firstBase = $base; | my $firstBase = $base; | |||
my $raf = $$dirInfo{RAF}; | my $raf = $$dirInfo{RAF}; | |||
my $verbose = $et->Options('Verbose'); | my $verbose = $et->Options('Verbose'); | |||
my $validate = $et->Options('Validate'); | my $validate = $et->Options('Validate'); | |||
my $saveFormat = $et->Options('SaveFormat'); | my $saveFormat = $et->Options('SaveFormat'); | |||
my $htmlDump = $$et{HTML_DUMP}; | my $htmlDump = $$et{HTML_DUMP}; | |||
my $success = 1; | my $success = 1; | |||
my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffN ame); | my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffN ame, $doMD5); | |||
my $inMakerNotes = $$tagTablePtr{GROUPS}{0} eq 'MakerNotes'; | my $inMakerNotes = $$tagTablePtr{GROUPS}{0} eq 'MakerNotes'; | |||
my $isExif = ($tagTablePtr eq \%Image::ExifTool::Exif::Main); | my $isExif = ($tagTablePtr eq \%Image::ExifTool::Exif::Main); | |||
# set flag to calculate image data MD5 if requested | ||||
$doMD5 = 1 if $$et{ImageDataMD5} and (($$et{FILE_TYPE} eq 'TIFF' and not $ba | ||||
se and not $inMakerNotes) or | ||||
($$et{FILE_TYPE} eq 'RAF' and $dirName eq 'FujiIFD')); | ||||
# set encoding to assume for strings | # set encoding to assume for strings | |||
$strEnc = $et->Options('CharsetEXIF') if $$tagTablePtr{GROUPS}{0} eq 'EXIF'; | $strEnc = $et->Options('CharsetEXIF') if $$tagTablePtr{GROUPS}{0} eq 'EXIF'; | |||
# ignore non-standard EXIF while in strict MWG compatibility mode | # ignore non-standard EXIF while in strict MWG compatibility mode | |||
if (($validate or $Image::ExifTool::MWG::strict) and $dirName eq 'IFD0' and | if (($validate or $Image::ExifTool::MWG::strict) and $dirName eq 'IFD0' and | |||
$isExif and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/) | $isExif and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/) | |||
{ | { | |||
my $path = $et->MetadataPath(); | my $path = $et->MetadataPath(); | |||
unless ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) { | unless ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) { | |||
if ($Image::ExifTool::MWG::strict) { | if ($Image::ExifTool::MWG::strict) { | |||
skipping to change at line 6727 | skipping to change at line 6744 | |||
my $self = $et; | my $self = $et; | |||
#### eval WrongBase ($self) | #### eval WrongBase ($self) | |||
$offsetBase += eval $$tagInfo{WrongBase} || 0; | $offsetBase += eval $$tagInfo{WrongBase} || 0; | |||
} | } | |||
my @vals = split(' ',$val); | my @vals = split(' ',$val); | |||
foreach $val (@vals) { | foreach $val (@vals) { | |||
$val += $offsetBase; | $val += $offsetBase; | |||
} | } | |||
$val = join(' ', @vals); | $val = join(' ', @vals); | |||
} | } | |||
if ($validate) { | if ($validate or $doMD5) { | |||
if ($$tagInfo{OffsetPair}) { | if ($$tagInfo{OffsetPair}) { | |||
$offsetInfo{$tagID} = [ $tagInfo, $val ]; | $offsetInfo{$tagID} = [ $tagInfo, $val ]; | |||
} elsif ($saveForValidate{$tagID} and $isExif) { | } elsif ($saveForValidate{$tagID} and $isExif) { | |||
$offsetInfo{$tagID} = $val; | $offsetInfo{$tagID} = $val; | |||
} | } | |||
} | } | |||
# save the value of this tag | # save the value of this tag | |||
$tagKey = $et->FoundTag($tagInfo, $val); | $tagKey = $et->FoundTag($tagInfo, $val); | |||
if (defined $tagKey) { | if (defined $tagKey) { | |||
# set the group 1 name for tags in specified tables | # set the group 1 name for tags in specified tables | |||
$et->SetGroup($tagKey, $dirName) if $$tagTablePtr{SET_GROUP1}; | $et->SetGroup($tagKey, $dirName) if $$tagTablePtr{SET_GROUP1}; | |||
# save original components of rational numbers (used when copying) | # save original components of rational numbers (used when copying) | |||
$$et{RATIONAL}{$tagKey} = $rational if defined $rational; | $$et{RATIONAL}{$tagKey} = $rational if defined $rational; | |||
$$et{TAG_EXTRA}{$tagKey}{G6} = $saveFormat if $saveFormat; | $$et{TAG_EXTRA}{$tagKey}{G6} = $saveFormat if $saveFormat; | |||
} | } | |||
} | } | |||
# validate image data offsets for this IFD | if (%offsetInfo) { | |||
if ($validate and %offsetInfo) { | # calculate image data MD5 if requested | |||
Image::ExifTool::Validate::ValidateOffsetInfo($et, \%offsetInfo, $$dirIn | AddImageDataMD5($et, $dirInfo, \%offsetInfo) if $doMD5; | |||
fo{DirName}, $inMakerNotes) | # validate image data offsets for this IFD (note: modifies %offsetInfo) | |||
Image::ExifTool::Validate::ValidateOffsetInfo($et, \%offsetInfo, $dirNam | ||||
e, $inMakerNotes) if $validate; | ||||
} | } | |||
# scan for subsequent IFD's if specified | # scan for subsequent IFD's if specified | |||
if ($$dirInfo{Multi} and $bytesFromEnd >= 4) { | if ($$dirInfo{Multi} and $bytesFromEnd >= 4) { | |||
# use same directory information for trailing directory, | # use same directory information for trailing directory, | |||
# but change the start location (ProcessDirectory will | # but change the start location (ProcessDirectory will | |||
# test to make sure we don't reprocess the same dir twice) | # test to make sure we don't reprocess the same dir twice) | |||
my %newDirInfo = %$dirInfo; | my %newDirInfo = %$dirInfo; | |||
$newDirInfo{Multi} = 0; # prevent recursion | $newDirInfo{Multi} = 0; # prevent recursion | |||
$newDirInfo{OffsetName} = $nextOffName; | $newDirInfo{OffsetName} = $nextOffName; | |||
End of changes. 17 change blocks. | ||||
6 lines changed or deleted | 26 lines changed or added |