"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/Image/ExifTool.pm" between
Image-ExifTool-12.57.tar.gz and Image-ExifTool-12.58.tar.gz

About: ExifTool is a platform-independent Perl library plus a command-line application for reading, writing and editing meta information in a wide variety of files.

ExifTool.pm  (Image-ExifTool-12.57):ExifTool.pm  (Image-ExifTool-12.58)
skipping to change at line 32 skipping to change at line 32
use overload; use overload;
use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
%allTables @tableOrder $exifAPP1hdr $xmpAPP1hdr $xmpExtAPP1hdr %allTables @tableOrder $exifAPP1hdr $xmpAPP1hdr $xmpExtAPP1hdr
$psAPP13hdr $psAPP13old @loadAllTables %UserDefined $evalWarning $psAPP13hdr $psAPP13old @loadAllTables %UserDefined $evalWarning
%noWriteFile %magicNumber @langs $defaultLang %langName %charsetName %noWriteFile %magicNumber @langs $defaultLang %langName %charsetName
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd %mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir %jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
%static_vars); %static_vars);
$VERSION = '12.57'; $VERSION = '12.58';
$RELEASE = ''; $RELEASE = '';
@ISA = qw(Exporter); @ISA = qw(Exporter);
%EXPORT_TAGS = ( %EXPORT_TAGS = (
# all public non-object-oriented functions: # all public non-object-oriented functions:
Public => [qw( Public => [qw(
ImageInfo GetTagName GetShortcuts GetAllTags GetWritableTags ImageInfo GetTagName GetShortcuts GetAllTags GetWritableTags
GetAllGroups GetDeleteGroups GetFileType CanWrite CanCreate GetAllGroups GetDeleteGroups GetFileType CanWrite CanCreate
AddUserDefinedTags AddUserDefinedTags
)], )],
# exports not part of the public API, but used by ExifTool modules: # exports not part of the public API, but used by ExifTool modules:
skipping to change at line 1824 skipping to change at line 1824
SphericalVideoXML => { SphericalVideoXML => {
Groups => { 0 => 'QuickTime', 1 => 'GSpherical', 2 => 'Video' }, Groups => { 0 => 'QuickTime', 1 => 'GSpherical', 2 => 'Video' },
# (group 1 is 'GSpherical' to trigger creation of this tag when writing, # (group 1 is 'GSpherical' to trigger creation of this tag when writing,
# but when reading the family 1 group is the track number) # but when reading the family 1 group is the track number)
Flags => [ 'Writable', 'Binary', 'Protected' ], Flags => [ 'Writable', 'Binary', 'Protected' ],
Notes => q{ Notes => q{
the SphericalVideoXML block from MP4/MOV videos. This tag is genera ted only the SphericalVideoXML block from MP4/MOV videos. This tag is genera ted only
if specifically requested if specifically requested
}, },
}, },
ImageDataMD5 => {
Notes => q{
MD5 of image data. Generated only if specifically requested for JPEG
and
TIFF-based images, except Panasonic raw for now. Includes image data
,
OtherImage and JpgFromRaw in the MD5, but not ThumbnailImage or Prev
iewImage
},
},
); );
# tags defined by UserParam option (added at runtime) # tags defined by UserParam option (added at runtime)
%Image::ExifTool::UserParam = ( %Image::ExifTool::UserParam = (
GROUPS => { 0 => 'UserParam', 1 => 'UserParam', 2 => 'Other' }, GROUPS => { 0 => 'UserParam', 1 => 'UserParam', 2 => 'Other' },
PRIORITY => 0, PRIORITY => 0,
); );
# YCbCrSubSampling values (used by JPEG SOF, EXIF and XMP) # YCbCrSubSampling values (used by JPEG SOF, EXIF and XMP)
%Image::ExifTool::JPEG::yCbCrSubSampling = ( %Image::ExifTool::JPEG::yCbCrSubSampling = (
skipping to change at line 2483 skipping to change at line 2490
# generate sequence number if necessary # generate sequence number if necessary
$self->FoundTag('FileSequence', $$self{FILE_SEQUENCE}) if $$req{filesequ ence} or $reqAll; $self->FoundTag('FileSequence', $$self{FILE_SEQUENCE}) if $$req{filesequ ence} or $reqAll;
if ($$req{processingtime} or $reqAll) { if ($$req{processingtime} or $reqAll) {
eval { require Time::HiRes; @startTime = Time::HiRes::gettimeofday() }; eval { require Time::HiRes; @startTime = Time::HiRes::gettimeofday() };
if (not @startTime and $$req{processingtime}) { if (not @startTime and $$req{processingtime}) {
$self->WarnOnce('Install Time::HiRes to generate ProcessingTime' ); $self->WarnOnce('Install Time::HiRes to generate ProcessingTime' );
} }
} }
# create MD5 object if ImageDataMD5 is requested
if ($$req{imagedatamd5} and not $$self{ImageDataMD5}) {
if (require Digest::MD5) {
$$self{ImageDataMD5} = Digest::MD5->new;
} else {
$self->WarnOnce('Install Digest::MD5 to calculate image data MD5
');
}
}
++$$self{FILE_SEQUENCE}; # count files read ++$$self{FILE_SEQUENCE}; # count files read
} }
my $filename = $$self{FILENAME}; # image file name ('' if already open) my $filename = $$self{FILENAME}; # image file name ('' if already open)
my $raf = $$self{RAF}; # RandomAccess object my $raf = $$self{RAF}; # RandomAccess object
local *EXIFTOOL_FILE; # avoid clashes with global namespace local *EXIFTOOL_FILE; # avoid clashes with global namespace
my $realname = $filename; my $realname = $filename;
unless ($raf) { unless ($raf) {
skipping to change at line 2873 skipping to change at line 2888
} }
} }
# restore original options # restore original options
%saveOptions and $$self{OPTIONS} = \%saveOptions; %saveOptions and $$self{OPTIONS} = \%saveOptions;
if ($reEntry) { if ($reEntry) {
# restore necessary members when exiting re-entrant code # restore necessary members when exiting re-entrant code
$$self{$_} = $$reEntry{$_} foreach keys %$reEntry; $$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
SetByteOrder($saveOrder); SetByteOrder($saveOrder);
} elsif ($$self{ImageDataMD5}) {
my $digest = $$self{ImageDataMD5}->hexdigest;
# (don't store empty digest)
$self->FoundTag(ImageDataMD5 => $digest) unless $digest eq 'd41d8cd98f00
b204e9800998ecf8427e';
} }
# ($type may be undef without an Error when processing sub-documents) # ($type may be undef without an Error when processing sub-documents)
return 0 if not defined $type or exists $$self{VALUE}{Error}; return 0 if not defined $type or exists $$self{VALUE}{Error};
return 1; return 1;
} }
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Get hash of extracted meta information # Get hash of extracted meta information
# Inputs: 0) ExifTool object reference # Inputs: 0) ExifTool object reference
skipping to change at line 4300 skipping to change at line 4319
return @rtn if defined $rtn[0]; return @rtn if defined $rtn[0];
} }
$self->Warn("GetFileTime error for '${file}'"); $self->Warn("GetFileTime error for '${file}'");
return (); return ();
} }
$file = *FH; # (not \*FH, so *FH will be kept open until $file goes out of scope) $file = *FH; # (not \*FH, so *FH will be kept open until $file goes out of scope)
} }
# on Windows, try to work around incorrect file times when daylight saving t ime is in effect # on Windows, try to work around incorrect file times when daylight saving t ime is in effect
if ($^O eq 'MSWin32') { if ($^O eq 'MSWin32') {
if (not eval { require Win32::API }) { if (not eval { require Win32::API }) {
$self->WarnOnce('Install Win32::API for proper handling of Windows f ile times'); $self->WarnOnce('Install Win32::API for proper handling of Windows f ile times', 1);
} elsif (not eval { require Win32API::File }) { } elsif (not eval { require Win32API::File }) {
$self->WarnOnce('Install Win32API::File for proper handling of Windo ws file times'); $self->WarnOnce('Install Win32API::File for proper handling of Windo ws file times', 1);
} else { } else {
# get Win32 handle, needed for GetFileTime # get Win32 handle, needed for GetFileTime
my $win32Handle = eval { Win32API::File::GetOsFHandle($file) }; my $win32Handle = eval { Win32API::File::GetOsFHandle($file) };
unless ($win32Handle) { unless ($win32Handle) {
$self->Warn("Win32API::File::GetOsFHandle returned invalid handl e"); $self->Warn("Win32API::File::GetOsFHandle returned invalid handl e");
return (); return ();
} }
# get FILETIME structs # get FILETIME structs
my ($atime, $mtime, $ctime, $time); my ($atime, $mtime, $ctime, $time);
$atime = $mtime = $ctime = pack 'LL', 0, 0; $atime = $mtime = $ctime = pack 'LL', 0, 0;
skipping to change at line 5871 skipping to change at line 5890
} else { } else {
$val = sprintf("%.1f days", $val / (24 * 3600)); $val = sprintf("%.1f days", $val / (24 * 3600));
} }
} }
return $val; return $val;
} }
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Patched timelocal() that fixes ActivePerl timezone bug # Patched timelocal() that fixes ActivePerl timezone bug
# Inputs/Returns: same as timelocal() # Inputs/Returns: same as timelocal()
# Notes: must 'require Time::Local' before calling this routine # Notes: must 'require Time::Local' before calling this routine.
# Also note that year should be full year, and not relative to 1900 as with loca
ltime
sub TimeLocal(@) sub TimeLocal(@)
{ {
my $tm = Time::Local::timelocal(@_); my $tm = Time::Local::timelocal(@_);
if ($^O eq 'MSWin32') { if ($^O eq 'MSWin32') {
# patch for ActivePerl timezone bug # patch for ActivePerl timezone bug
my @t2 = localtime($tm); my @t2 = localtime($tm);
my $t2 = Time::Local::timelocal(@t2); my $t2 = Time::Local::timelocal(@t2);
# adjust timelocal() return value to be consistent with localtime() # adjust timelocal() return value to be consistent with localtime()
$tm += $tm - $t2; $tm += $tm - $t2;
} }
skipping to change at line 6341 skipping to change at line 6361
my $options = $$self{OPTIONS}; my $options = $$self{OPTIONS};
my $verbose = $$options{Verbose}; my $verbose = $$options{Verbose};
my $out = $$options{TextOut}; my $out = $$options{TextOut};
my $fast = $$options{FastScan} || 0; my $fast = $$options{FastScan} || 0;
my $raf = $$dirInfo{RAF}; my $raf = $$dirInfo{RAF};
my $req = $$self{REQ_TAG_LOOKUP}; my $req = $$self{REQ_TAG_LOOKUP};
my $htmlDump = $$self{HTML_DUMP}; my $htmlDump = $$self{HTML_DUMP};
my %dumpParms = ( Out => $out ); my %dumpParms = ( Out => $out );
my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk); my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $fli rTotal); my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $fli rTotal);
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP); my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP, $md5);
# get pointer to MD5 object if it exists and we are the top-level JPEG
$md5 = $$self{ImageDataMD5} if $$self{FILE_TYPE} eq 'JPEG' and not $$self{DO
C_NUM};
# check to be sure this is a valid JPG (or J2C, or EXV) file # check to be sure this is a valid JPG (or J2C, or EXV) file
return 0 unless $raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/; return 0 unless $raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/;
if ($s eq "\xff\x01") { if ($s eq "\xff\x01") {
return 0 unless $raf->Read($s, 5) == 5 and $s eq 'Exiv2'; return 0 unless $raf->Read($s, 5) == 5 and $s eq 'Exiv2';
$$self{FILE_TYPE} = 'EXV'; $$self{FILE_TYPE} = 'EXV';
} }
my $appBytes = 0; my $appBytes = 0;
my $calcImageLen = $$req{jpegimagelength}; my $calcImageLen = $$req{jpegimagelength};
if ($$options{RequestAll} and $$options{RequestAll} > 2) { if ($$options{RequestAll} and $$options{RequestAll} > 2) {
skipping to change at line 6389 skipping to change at line 6412
# set marker and data pointer for current segment # set marker and data pointer for current segment
my $marker = $nextMarker; my $marker = $nextMarker;
my $segDataPt = $nextSegDataPt; my $segDataPt = $nextSegDataPt;
my $segPos = $nextSegPos; my $segPos = $nextSegPos;
my $skipped; my $skipped;
undef $nextMarker; undef $nextMarker;
undef $nextSegDataPt; undef $nextSegDataPt;
# #
# read ahead to the next segment unless we have reached EOI, SOS or SOD # read ahead to the next segment unless we have reached EOI, SOS or SOD
# #
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTraile unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTraile
r) or $marker==0x93)) { r and not $md5) or
$marker==0x93))
{
# read up to next marker (JPEG markers begin with 0xff) # read up to next marker (JPEG markers begin with 0xff)
my $buff; my $buff;
$raf->ReadLine($buff) or last; $raf->ReadLine($buff) or last;
$skipped = length($buff) - 1; $skipped = length($buff) - 1;
# JPEG markers can be padded with unlimited 0xff's # JPEG markers can be padded with unlimited 0xff's
for (;;) { for (;;) {
$raf->Read($ch, 1) or last Marker; $raf->Read($ch, 1) or last Marker;
$nextMarker = ord($ch); $nextMarker = ord($ch);
last unless $nextMarker == 0xff; last unless $nextMarker == 0xff;
++$skipped; ++$skipped;
skipping to change at line 6419 skipping to change at line 6444
last unless $raf->Read($buff, $len) == $len; last unless $raf->Read($buff, $len) == $len;
$nextSegDataPt = \$buff; # set pointer to our next data $nextSegDataPt = \$buff; # set pointer to our next data
} elsif ($markerLenBytes{$nextMarker} == 4) { } elsif ($markerLenBytes{$nextMarker} == 4) {
# handle J2C extensions with 4-byte length word # handle J2C extensions with 4-byte length word
last unless $raf->Read($s, 4) == 4; last unless $raf->Read($s, 4) == 4;
my $len = unpack('N',$s); # get data length my $len = unpack('N',$s); # get data length
last unless defined($len) and $len >= 4; last unless defined($len) and $len >= 4;
$nextSegPos = $raf->Tell(); $nextSegPos = $raf->Tell();
$len -= 4; # subtract size of length word $len -= 4; # subtract size of length word
last unless $raf->Seek($len, 1); last unless $raf->Seek($len, 1);
} elsif ($md5 and defined $marker and ($marker == 0x00 or $marker ==
0xda)) {
$md5->add($buff); # (note: this includes the terminating 0xff'
s)
} }
# read second segment too if this was the first # read second segment too if this was the first
next unless defined $marker; next unless defined $marker;
} }
# set some useful variables for the current segment # set some useful variables for the current segment
my $markerName = JpegMarkerName($marker); my $markerName = JpegMarkerName($marker);
$$path[$pn] = $markerName; $$path[$pn] = $markerName;
# issue warning if we skipped some garbage # issue warning if we skipped some garbage
if ($skipped and not $foundSOS and $markerName ne 'SOS') { if ($skipped and not $foundSOS and $markerName ne 'SOS') {
$self->Warn("Skipped unknown $skipped bytes after JPEG $markerName s egment", 1); $self->Warn("Skipped unknown $skipped bytes after JPEG $markerName s egment", 1);
skipping to change at line 6629 skipping to change at line 6656
if ($$self{LeicaTrailer}) { if ($$self{LeicaTrailer}) {
require Image::ExifTool::Panasonic; require Image::ExifTool::Panasonic;
Image::ExifTool::Panasonic::ProcessLeicaTrailer($self); Image::ExifTool::Panasonic::ProcessLeicaTrailer($self);
$wantTrailer = 1 if $$self{LeicaTrailer}; $wantTrailer = 1 if $$self{LeicaTrailer};
} else { } else {
$wantTrailer = 1 if $$options{ExtractEmbedded}; $wantTrailer = 1 if $$options{ExtractEmbedded};
} }
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump; next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
} }
# must scan to EOI if Validate or JpegCompressionFactor used # must scan to EOI if Validate or JpegCompressionFactor used
next if $$options{Validate} or $calcImageLen or $$req{trailer}; next if $$options{Validate} or $calcImageLen or $$req{trailer} or $m d5;
# nothing interesting to parse after start of scan (SOS) # nothing interesting to parse after start of scan (SOS)
$success = 1; $success = 1;
last; # all done parsing file last; # all done parsing file
} elsif ($marker == 0x93) { } elsif ($marker == 0x93) {
pop @$path; pop @$path;
$verbose and print $out "JPEG SOD\n"; $verbose and print $out "JPEG SOD\n";
$success = 1; $success = 1;
next if $verbose > 2 or $htmlDump; next if $verbose > 2 or $htmlDump;
last; # all done parsing file last; # all done parsing file
} elsif (defined $markerLenBytes{$marker}) { } elsif (defined $markerLenBytes{$marker}) {
skipping to change at line 7012 skipping to change at line 7039
$dumpType = 'InfiRay Data', $dumpType = 'InfiRay Data',
} elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) { } elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
$dumpType = 'PreviewImage'; # (Samsung, HP, BenQ) $dumpType = 'PreviewImage'; # (Samsung, HP, BenQ)
$preview = $$segDataPt; $preview = $$segDataPt;
} }
if ($preview and $nextMarker ne 0xe4) { # this preview continues in APP4 if ($preview and $nextMarker ne 0xe4) { # this preview continues in APP4
$self->FoundTag('PreviewImage', $preview); $self->FoundTag('PreviewImage', $preview);
undef $preview; undef $preview;
} }
} elsif ($marker == 0xe4) { # APP4 (InfiRay, "SCALADO", FPXR, Pr eviewImage) } elsif ($marker == 0xe4) { # APP4 (InfiRay, "SCALADO", FPXR, DJ I, PreviewImage)
if ($$segDataPt =~ /^SCALADO\0/ and $length >= 16) { if ($$segDataPt =~ /^SCALADO\0/ and $length >= 16) {
$dumpType = 'SCALADO'; $dumpType = 'SCALADO';
my ($num, $idx, $len) = unpack('x8n2N', $$segDataPt); my ($num, $idx, $len) = unpack('x8n2N', $$segDataPt);
# assume that the segments are in order and just concatinate the m # assume that the segments are in order and just concatinate the m
$scalado = '' unless defined $scalado; $scalado = '' unless defined $scalado;
$scalado .= substr($$segDataPt, 16); $scalado .= substr($$segDataPt, 16);
if ($idx == $num - 1) { if ($idx == $num - 1) {
if ($len != length $scalado) { if ($len != length $scalado) {
$self->Warn('Possibly corrupted APP4 SCALADO data', 1); $self->Warn('Possibly corrupted APP4 SCALADO data', 1);
} }
skipping to change at line 7043 skipping to change at line 7070
$dumpType = 'FPXR'; $dumpType = 'FPXR';
my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main') ; my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main') ;
# set flag if this is the last FPXR segment # set flag if this is the last FPXR segment
$dirInfo{LastFPXR} = not ($nextMarker==$marker and $$nextSegData Pt=~/^FPXR\0/), $dirInfo{LastFPXR} = not ($nextMarker==$marker and $$nextSegData Pt=~/^FPXR\0/),
$self->ProcessDirectory(\%dirInfo, $tagTablePtr); $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^\xaa\x55\x12\x06 /) { } elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^\xaa\x55\x12\x06 /) {
$dumpType = 'DJI ThermalParams'; $dumpType = 'DJI ThermalParams';
DirStart(\%dirInfo, 0, 0); DirStart(\%dirInfo, 0, 0);
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalPara ms'); my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalPara ms');
$self->ProcessDirectory(\%dirInfo, $tagTablePtr); $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^(.{32})?.{32}\x2
c\x01\x20\0/s) {
$dumpType = 'DJI ThermalParams2';
DirStart(\%dirInfo, $1 ? 32 : 0, 0);
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalPara
ms2');
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^.{32}\xaa\x55\x3
8\0/s) {
$dumpType = 'DJI ThermalParams3';
DirStart(\%dirInfo, 32, 0);
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalPara
ms3');
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
} elsif ($$self{HasIJPEG} and $length >= 120) { } elsif ($$self{HasIJPEG} and $length >= 120) {
$dumpType = 'InfiRay Factory'; $dumpType = 'InfiRay Factory';
SetByteOrder('II'); SetByteOrder('II');
my $tagTablePtr = GetTagTable('Image::ExifTool::InfiRay::Factory '); my $tagTablePtr = GetTagTable('Image::ExifTool::InfiRay::Factory ');
$self->ProcessDirectory(\%dirInfo, $tagTablePtr); $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
} elsif ($preview) { } elsif ($preview) {
# continued Samsung S1060 preview from APP3 # continued Samsung S1060 preview from APP3
$dumpType = 'PreviewImage'; $dumpType = 'PreviewImage';
$preview .= $$segDataPt; $preview .= $$segDataPt;
} }
skipping to change at line 7156 skipping to change at line 7193
if ($htmlDump) { if ($htmlDump) {
$self->HDump($segPos-4, 4, 'APP7 header', "Data size: $lengt h bytes"); $self->HDump($segPos-4, 4, 'APP7 header', "Data size: $lengt h bytes");
$self->HDump($segPos, $hdrLen, 'Huawei header', 'APP7 data t ype: Huawei'); $self->HDump($segPos, $hdrLen, 'Huawei header', 'APP7 data t ype: Huawei');
$dumpEnd = $segPos + $length; $dumpEnd = $segPos + $length;
} }
$$self{SET_GROUP0} = 'APP7'; $$self{SET_GROUP0} = 'APP7';
$$self{SET_GROUP1} = 'Huawei'; $$self{SET_GROUP1} = 'Huawei';
$self->ProcessDirectory(\%dirInfo, $tagTablePtr); $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
delete $$self{SET_GROUP0}; delete $$self{SET_GROUP0};
delete $$self{SET_GROUP1}; delete $$self{SET_GROUP1};
} elsif ($$segDataPt =~ /^DJI-DBG\0/) {
$dumpType = 'DJI Info';
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::Info');
DirStart(\%dirInfo, 8, 0);
$$self{SET_GROUP0} = 'APP7';
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
delete $$self{SET_GROUP0};
} elsif ($$segDataPt =~ /^\x1aQualcomm Camera Attributes/) { } elsif ($$segDataPt =~ /^\x1aQualcomm Camera Attributes/) {
# found in HP iPAQ_VoiceMessenger # found in HP iPAQ_VoiceMessenger
$dumpType = 'Qualcomm'; $dumpType = 'Qualcomm';
my $tagTablePtr = GetTagTable('Image::ExifTool::Qualcomm::Main') ; my $tagTablePtr = GetTagTable('Image::ExifTool::Qualcomm::Main') ;
DirStart(\%dirInfo, 27); DirStart(\%dirInfo, 27);
$dirInfo{DirName} = 'Qualcomm'; $dirInfo{DirName} = 'Qualcomm';
$self->ProcessDirectory(\%dirInfo, $tagTablePtr); $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
} elsif ($$self{HasIJPEG} and $length >= 32) { } elsif ($$self{HasIJPEG} and $length >= 32) {
$dumpType = 'InfiRay OpMode'; $dumpType = 'InfiRay OpMode';
SetByteOrder('II'); SetByteOrder('II');
skipping to change at line 7684 skipping to change at line 7728
# dump any other known trailer (eg. A100 RAW Data) # dump any other known trailer (eg. A100 RAW Data)
if ($$self{HTML_DUMP} and $$self{KnownTrailer}) { if ($$self{HTML_DUMP} and $$self{KnownTrailer}) {
my $known = $$self{KnownTrailer}; my $known = $$self{KnownTrailer};
$raf->Seek(0, 2); $raf->Seek(0, 2);
my $len = $raf->Tell() - $$known{Start}; my $len = $raf->Tell() - $$known{Start};
$len -= $$trailInfo{Offset} if $trailInfo; # account for other trailers $len -= $$trailInfo{Offset} if $trailInfo; # account for other trailers
$self->HDump($$known{Start}, $len, "[$$known{Name}]") if $len > 0; $self->HDump($$known{Start}, $len, "[$$known{Name}]") if $len > 0;
} }
} }
# update FileType if necessary now that we know more about the file # update FileType if necessary now that we know more about the file
if ($$self{DNGVersion} and $$self{VALUE}{FileType} !~ /^(DNG|GPR)$/) { if ($$self{DNGVersion} and $$self{FileType} !~ /^(DNG|GPR)$/) {
# override whatever FileType we set since we now know it is DNG # override whatever FileType we set since we now know it is DNG
$self->OverrideFileType($$self{TIFF_TYPE} = 'DNG'); $self->OverrideFileType($$self{TIFF_TYPE} = 'DNG');
} }
if ($$self{TIFF_TYPE} eq 'TIFF') { if ($$self{TIFF_TYPE} eq 'TIFF') {
$self->FoundTag(PageCount => $$self{PageCount}) if $$self{MultiPage} ; $self->FoundTag(PageCount => $$self{PageCount}) if $$self{MultiPage} ;
} }
return 1; return 1;
} }
# #
# rewrite the image # rewrite the image
skipping to change at line 8570 skipping to change at line 8614
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Set the FileType and MIMEType tags # Set the FileType and MIMEType tags
# Inputs: 0) ExifTool object reference # Inputs: 0) ExifTool object reference
# 1) Optional file type (uses FILE_TYPE if not specified) # 1) Optional file type (uses FILE_TYPE if not specified)
# 2) Optional MIME type (uses our lookup if not specified) # 2) Optional MIME type (uses our lookup if not specified)
# 3) Optional recommended extension (converted to lower case; uses FileT ype if undef) # 3) Optional recommended extension (converted to lower case; uses FileT ype if undef)
# Notes: Will NOT set file type twice (subsequent calls ignored) # Notes: Will NOT set file type twice (subsequent calls ignored)
sub SetFileType($;$$$) sub SetFileType($;$$$)
{ {
my ($self, $fileType, $mimeType, $normExt) = @_; my ($self, $fileType, $mimeType, $normExt) = @_;
unless ($$self{VALUE}{FileType} and not $$self{DOC_NUM}) { unless ($$self{FileType} and not $$self{DOC_NUM}) {
my $baseType = $$self{FILE_TYPE}; my $baseType = $$self{FILE_TYPE};
my $ext = $$self{FILE_EXT}; my $ext = $$self{FILE_EXT};
$fileType or $fileType = $baseType; $fileType or $fileType = $baseType;
# handle sub-types which are identified by extension # handle sub-types which are identified by extension
if (defined $ext and $ext ne $fileType and not $$self{DOC_NUM}) { if (defined $ext and $ext ne $fileType and not $$self{DOC_NUM}) {
my ($f,$e) = @fileTypeLookup{$fileType,$ext}; my ($f,$e) = @fileTypeLookup{$fileType,$ext};
if (ref $f eq 'ARRAY' and ref $e eq 'ARRAY' and $$f[0] eq $$e[0]) { if (ref $f eq 'ARRAY' and ref $e eq 'ARRAY' and $$f[0] eq $$e[0]) {
# make sure $fileType was a root type and not another sub-type # make sure $fileType was a root type and not another sub-type
$fileType = $ext if $$f[0] eq $fileType or not $fileTypeLookup{$ $f[0]}; $fileType = $ext if $$f[0] eq $fileType or not $fileTypeLookup{$ $f[0]};
} }
} }
$mimeType or $mimeType = $mimeType{$fileType}; $mimeType or $mimeType = $mimeType{$fileType};
# use base file type if necessary (except if 'TIFF', which is a special case) # use base file type if necessary (except if 'TIFF', which is a special case)
$mimeType = $mimeType{$baseType} unless $mimeType or $baseType eq 'TIFF' ; $mimeType = $mimeType{$baseType} unless $mimeType or $baseType eq 'TIFF' ;
unless (defined $normExt) { unless (defined $normExt) {
$normExt = $fileTypeExt{$fileType}; $normExt = $fileTypeExt{$fileType};
$normExt = $fileType unless defined $normExt; $normExt = $fileType unless defined $normExt;
} }
$$self{FileType} = $fileType; # ($$self{FileType} is the file type of the main document)
$$self{FileType} = $fileType unless $$self{DOC_NUM};
$self->FoundTag('FileType', $fileType); $self->FoundTag('FileType', $fileType);
$self->FoundTag('FileTypeExtension', uc $normExt); $self->FoundTag('FileTypeExtension', uc $normExt);
$self->FoundTag('MIMEType', $mimeType || 'application/unknown'); $self->FoundTag('MIMEType', $mimeType || 'application/unknown');
} }
} }
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Override the FileType and MIMEType tags # Override the FileType and MIMEType tags
# Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extensio n (lower case) # Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extensio n (lower case)
# Notes: does nothing if FileType was not previously defined (ie. when writing) # Notes: does nothing if FileType was not previously defined (ie. when writing)
 End of changes. 17 change blocks. 
12 lines changed or deleted 70 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)