test_pie/external/exiftool/lib/Image/ExifTool/ISO.pm

207 lines
6.8 KiB
Perl

#------------------------------------------------------------------------------
# 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