0.6.9
This commit is contained in:
206
bin/lib/Image/ExifTool/ISO.pm
Normal file
206
bin/lib/Image/ExifTool/ISO.pm
Normal file
@@ -0,0 +1,206 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# File: ISO.pm
|
||||
#
|
||||
# Description: Read information from ISO 9660 disk images
|
||||
#
|
||||
# Revisions: 2016-04-07 - P. Harvey created
|
||||
#
|
||||
# References: 1) http://wiki.osdev.org/ISO_9660
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
package Image::ExifTool::ISO;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION);
|
||||
use Image::ExifTool qw(:DataAccess :Utils);
|
||||
|
||||
$VERSION = '1.01';
|
||||
|
||||
# trim trailing spaces and ignore tag if empty
|
||||
my %rawStr = (
|
||||
RawConv => sub {
|
||||
my $val = shift;
|
||||
$val =~ s/ +$//;
|
||||
return length($val) ? $val : undef;
|
||||
},
|
||||
);
|
||||
|
||||
# tag info for date/time tags
|
||||
my %dateInfo = (
|
||||
Format => 'undef[17]',
|
||||
Groups => { 2 => 'Time' },
|
||||
ValueConv => q{
|
||||
return undef if $val !~ /[^0\0 ]/; # ignore if empty
|
||||
if ($val =~ s/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.)/$1:$2:$3 $4:$5:$6.$7/s) {
|
||||
$val .= TimeZoneString(unpack('c', $8) * 15);
|
||||
}
|
||||
return $val;
|
||||
},
|
||||
PrintConv => '$self->ConvertDateTime($val)',
|
||||
);
|
||||
|
||||
# lookup for volume descriptor types
|
||||
my %volumeDescriptorType = (
|
||||
0 => 'Boot Record',
|
||||
1 => 'Primary Volume',
|
||||
2 => 'Supplementary Volume',
|
||||
3 => 'Volume Partition',
|
||||
255 => 'Terminator',
|
||||
);
|
||||
|
||||
# ISO tags
|
||||
%Image::ExifTool::ISO::Main = (
|
||||
GROUPS => { 2 => 'Other' },
|
||||
NOTES => 'Tags extracted from ISO 9660 disk images.',
|
||||
0 => {
|
||||
Name => 'BootRecord',
|
||||
SubDirectory => { TagTable => 'Image::ExifTool::ISO::BootRecord' },
|
||||
},
|
||||
1 => {
|
||||
Name => 'PrimaryVolume',
|
||||
SubDirectory => { TagTable => 'Image::ExifTool::ISO::PrimaryVolume' },
|
||||
},
|
||||
);
|
||||
|
||||
%Image::ExifTool::ISO::BootRecord = (
|
||||
GROUPS => { 2 => 'Other' },
|
||||
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
||||
# 0 => { Name => 'VolumeType', PrintConv => \%volumeDescriptorType }, # (0 for boot record)
|
||||
# 1 => { Name => 'Identifier', Format => 'undef[5]' }, # (always "CD001")
|
||||
# 6 => 'VolumeDesriptorVersion', # (always 1)
|
||||
# always extract BootSystem, even if empty, as an indication that this is bootable
|
||||
7 => { Name => 'BootSystem', Format => 'string[32]', ValueConv => '$val=~s/ +$//; $val' },
|
||||
39 => { Name => 'BootIdentifier', Format => 'string[32]', %rawStr },
|
||||
);
|
||||
|
||||
%Image::ExifTool::ISO::PrimaryVolume = (
|
||||
GROUPS => { 2 => 'Other' },
|
||||
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
||||
# 0 => { Name => 'VolumeType', PrintConv => \%volumeDescriptorType }, # (1 for primary volume)
|
||||
# 1 => { Name => 'Identifier', Format => 'undef[5]' }, # (always "CD001")
|
||||
# 6 => 'VolumeDesriptorVersion', # (always 1)
|
||||
8 => { Name => 'System', Format => 'string[32]', %rawStr },
|
||||
40 => { Name => 'VolumeName', Format => 'string[32]', %rawStr },
|
||||
80 => { Name => 'VolumeBlockCount', Format => 'int32u' },
|
||||
120 => { Name => 'VolumeSetDiskCount', Format => 'int16u', Unknown => 1 },
|
||||
124 => { Name => 'VolumeSetDiskNumber', Format => 'int16u', Unknown => 1 },
|
||||
128 => { Name => 'VolumeBlockSize', Format => 'int16u' },
|
||||
132 => { Name => 'PathTableSize', Format => 'int32u', Unknown => 1 },
|
||||
140 => { Name => 'PathTableLocation', Format => 'int32u', Unknown => 1 },
|
||||
174 => {
|
||||
Name => 'RootDirectoryCreateDate',
|
||||
Format => 'undef[7]',
|
||||
Groups => { 2 => 'Time' },
|
||||
ValueConv => q{
|
||||
my @a = unpack('C6c', $val);
|
||||
$a[0] += 1900;
|
||||
$a[6] = TimeZoneString($a[6] * 15);
|
||||
return sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d%s', @a);
|
||||
},
|
||||
PrintConv => '$self->ConvertDateTime($val)',
|
||||
},
|
||||
190 => { Name => 'VolumeSetName', Format => 'string[128]', %rawStr },
|
||||
318 => { Name => 'Publisher', Format => 'string[128]', %rawStr },
|
||||
446 => { Name => 'DataPreparer', Format => 'string[128]', %rawStr },
|
||||
574 => { Name => 'Software', Format => 'string[128]', %rawStr },
|
||||
702 => { Name => 'CopyrightFileName', Format => 'string[38]', %rawStr },
|
||||
740 => { Name => 'AbstractFileName', Format => 'string[36]', %rawStr },
|
||||
776 => { Name => 'BibligraphicFileName',Format => 'string[37]', %rawStr },
|
||||
813 => { Name => 'VolumeCreateDate', %dateInfo },
|
||||
830 => { Name => 'VolumeModifyDate', %dateInfo },
|
||||
847 => { Name => 'VolumeExpirationDate',%dateInfo },
|
||||
864 => { Name => 'VolumeEffectiveDate', %dateInfo },
|
||||
#881 => 'FileStructureVersion', # (always 1)
|
||||
);
|
||||
|
||||
# ISO Composite tags
|
||||
%Image::ExifTool::ISO::Composite = (
|
||||
GROUPS => { 2 => 'Other' },
|
||||
VolumeSize => {
|
||||
Require => {
|
||||
0 => 'ISO:VolumeBlockCount',
|
||||
1 => 'ISO:VolumeBlockSize',
|
||||
},
|
||||
ValueConv => '$val[0] * $val[1]',
|
||||
PrintConv => \&Image::ExifTool::ConvertFileSize,
|
||||
},
|
||||
);
|
||||
|
||||
# add our composite tags
|
||||
Image::ExifTool::AddCompositeTags('Image::ExifTool::ISO');
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Extract information from an ISO 9660 disk image
|
||||
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
||||
# Returns: 1 on success, 0 if this wasn't a valid ISO 9660 image
|
||||
sub ProcessISO($$)
|
||||
{
|
||||
my ($et, $dirInfo) = @_;
|
||||
my $raf = $$dirInfo{RAF};
|
||||
my ($buff, $tagTablePtr);
|
||||
|
||||
# verify this is a valid ISO file
|
||||
return 0 unless $raf->Seek(32768, 0);
|
||||
|
||||
while ($raf->Read($buff, 2048) == 2048) {
|
||||
last unless $buff =~ /^[\0-\x03\xff]CD001/;
|
||||
unless ($tagTablePtr) {
|
||||
$et->SetFileType(); # set the FileType tag
|
||||
SetByteOrder('II'); # read little-endian values only
|
||||
$tagTablePtr = GetTagTable('Image::ExifTool::ISO::Main');
|
||||
}
|
||||
my $type = unpack('C', $buff);
|
||||
$et->VPrint(0, "Volume descriptor type $type ($volumeDescriptorType{$type})\n");
|
||||
last if $type == 255; # stop at terminator
|
||||
next unless $$tagTablePtr{$type};
|
||||
my $subTablePtr = GetTagTable($$tagTablePtr{$type}{SubDirectory}{TagTable});
|
||||
my %dirInfo = (
|
||||
DataPt => \$buff,
|
||||
DataPos => $raf->Tell() - 2048,
|
||||
DirStart => 0,
|
||||
DirLen => length($buff),
|
||||
);
|
||||
$et->ProcessDirectory(\%dirInfo, $subTablePtr);
|
||||
}
|
||||
return $tagTablePtr ? 1 : 0;
|
||||
}
|
||||
|
||||
1; # end
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Image::ExifTool::ISO - Read information from ISO 9660 disk images
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
This module is used by Image::ExifTool
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module contains definitions required by Image::ExifTool to read
|
||||
information from ISO 9660 disk images.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca)
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it
|
||||
under the same terms as Perl itself.
|
||||
|
||||
=head1 REFERENCES
|
||||
|
||||
=over 4
|
||||
|
||||
=item L<http://wiki.osdev.org/ISO_9660>
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Image::ExifTool::TagNames/ISO Tags>,
|
||||
L<Image::ExifTool(3pm)|Image::ExifTool>
|
||||
|
||||
=cut
|
||||
|
||||
Reference in New Issue
Block a user