Image-ExifTool
view release on metacpan or search on metacpan
lib/Image/ExifTool/FlashPix.pm view on Meta::CPAN
}
}
}
#------------------------------------------------------------------------------
# Extract names of comment authors (ref 6)
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
sub ProcessCommentBy($$$)
{
my ($et, $dirInfo, $tagTablePtr) = @_;
my $dataPt = $$dirInfo{DataPt};
my $pos = $$dirInfo{DirStart};
my $end = $$dirInfo{DirLen} + $pos;
$et->VerboseDir($$dirInfo{DirName});
while ($pos + 2 < $end) {
my $len = Get16u($dataPt, $pos);
$pos += 2;
last if $pos + $len * 2 > $end;
my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UTF16');
$pos += $len * 2;
$et->HandleTag($tagTablePtr, CommentBy => $author);
}
return 1;
}
#------------------------------------------------------------------------------
# Extract last-saved-by names (ref 5)
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
sub ProcessLastSavedBy($$$)
{
my ($et, $dirInfo, $tagTablePtr) = @_;
my $dataPt = $$dirInfo{DataPt};
my $pos = $$dirInfo{DirStart};
my $end = $$dirInfo{DirLen} + $pos;
return 0 if $pos + 6 > $end;
$et->VerboseDir($$dirInfo{DirName});
my $num = Get16u($dataPt, $pos+2);
$pos += 6;
while ($num >= 2) {
last if $pos + 2 > $end;
my $len = Get16u($dataPt, $pos);
$pos += 2;
last if $pos + $len * 2 > $end;
my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UTF16');
$pos += $len * 2;
last if $pos + 2 > $end;
$len = Get16u($dataPt, $pos);
$pos += 2;
last if $pos + $len * 2 > $end;
my $path = $et->Decode(substr($$dataPt, $pos, $len*2), 'UTF16');
$pos += $len * 2;
$et->HandleTag($tagTablePtr, LastSavedBy => "$author ($path)");
$num -= 2;
}
return 1;
}
#------------------------------------------------------------------------------
# Check FPX byte order mark (BOM) and set byte order appropriately
# Inputs: 0) data ref, 1) offset to BOM
# Returns: true on success
sub CheckBOM($$)
{
my ($dataPt, $pos) = @_;
my $bom = Get16u($dataPt, $pos);
return 1 if $bom == 0xfffe;
return 0 unless $bom == 0xfeff;
ToggleByteOrder();
return 1;
}
#------------------------------------------------------------------------------
# Process FlashPix properties
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
sub ProcessProperties($$$)
{
my ($et, $dirInfo, $tagTablePtr) = @_;
my $dataPt = $$dirInfo{DataPt};
my $pos = $$dirInfo{DirStart} || 0;
my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $pos;
my $dirEnd = $pos + $dirLen;
my $verbose = $et->Options('Verbose');
my $n;
if ($dirLen < 48) {
$et->Warn('Truncated FPX properties');
return 0;
}
# check and set our byte order if necessary
unless (CheckBOM($dataPt, $pos)) {
$et->Warn('Bad FPX property byte order mark');
return 0;
}
# get position of start of section
$pos = Get32u($dataPt, $pos + 44);
if ($pos < 48) {
$et->Warn('Bad FPX property section offset');
return 0;
}
for ($n=0; $n<2; ++$n) {
my %dictionary; # dictionary to translate user-defined properties
my $codePage;
last if $pos + 8 > $dirEnd;
# read property section header
my $size = Get32u($dataPt, $pos);
last unless $size;
my $numEntries = Get32u($dataPt, $pos + 4);
$verbose and $et->VerboseDir('Property Info', $numEntries, $size);
if ($pos + 8 + 8 * $numEntries > $dirEnd) {
$et->Warn('Truncated property list');
last;
}
my $index;
for ($index=0; $index<$numEntries; ++$index) {
my $entry = $pos + 8 + 8 * $index;
my $tag = Get32u($dataPt, $entry);
my $offset = Get32u($dataPt, $entry + 4);
my $valStart = $pos + 4 + $offset;
last if $valStart >= $dirEnd;
my $valPos = $valStart;
my $type = Get32u($dataPt, $pos + $offset);
if ($tag == 0) {
# read dictionary to get tag name lookup for this property set
my $i;
for ($i=0; $i<$type; ++$i) {
last if $valPos + 8 > $dirEnd;
$tag = Get32u($dataPt, $valPos);
my $len = Get32u($dataPt, $valPos + 4);
$valPos += 8 + $len;
last if $valPos > $dirEnd;
my $name = substr($$dataPt, $valPos - $len, $len);
$name =~ s/\0.*//s;
next unless length $name;
$dictionary{$tag} = $name;
next if $$tagTablePtr{$name};
$tag = $name;
$name =~ s/(^| )([a-z])/\U$2/g; # start with uppercase
$name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
next unless length $name;
$et->VPrint(0, "$$et{INDENT}\[adding $name]\n") if $verbose;
AddTagToTable($tagTablePtr, $tag, { Name => $name });
}
next;
}
# use tag name from dictionary if available
my ($custom, $val);
if (defined $dictionary{$tag}) {
$tag = $dictionary{$tag};
$custom = 1;
}
( run in 3.784 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )