$VERSION
=
'1.01'
;
my
%rawStr
= (
RawConv
=>
sub
{
my
$val
=
shift
;
$val
=~ s/ +$//;
return
length
(
$val
) ?
$val
:
undef
;
},
);
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)'
,
);
my
%volumeDescriptorType
= (
0
=>
'Boot Record'
,
1
=>
'Primary Volume'
,
2
=>
'Supplementary Volume'
,
3
=>
'Volume Partition'
,
255
=>
'Terminator'
,
);
%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
,
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
,
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
},
);
%Image::ExifTool::ISO::Composite
= (
GROUPS
=> {
2
=>
'Other'
},
VolumeSize
=> {
Require
=> {
0
=>
'ISO:VolumeBlockCount'
,
1
=>
'ISO:VolumeBlockSize'
,
},
ValueConv
=>
'$val[0] * $val[1]'
,
PrintConv
=> \
&Image::ExifTool::ConvertFileSize
,
},
);
Image::ExifTool::AddCompositeTags(
'Image::ExifTool::ISO'
);
sub
ProcessISO($$)
{
my
(
$et
,
$dirInfo
) =
@_
;
my
$raf
=
$$dirInfo
{RAF};
my
(
$buff
,
$tagTablePtr
);
return
0
unless
$raf
->Seek(32768, 0);
while
(
$raf
->Read(
$buff
, 2048) == 2048) {
last
unless
$buff
=~ /^[\0-\x03\xff]CD001/;
unless
(
$tagTablePtr
) {
$et
->SetFileType();
SetByteOrder(
'II'
);
$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;
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;