source: gs2-extensions/parallel-building/trunk/src/perllib/cpan/Image/ExifTool/RSRC.pm@ 24626

Last change on this file since 24626 was 24626, checked in by jmt12, 13 years ago

An (almost) complete copy of the perllib directory from a (circa SEP2011) head checkout from Greenstone 2 trunk - in order to try and make merging in this extension a little easier later on (as there have been some major changes to buildcol.pl commited in the main trunk but not in the x64 branch)

  • Property svn:executable set to *
File size: 8.6 KB
Line 
1#------------------------------------------------------------------------------
2# File: RSRC.pm
3#
4# Description: Read Mac OS Resource information
5#
6# Revisions: 2010/03/17 - P. Harvey Created
7#
8# References: 1) http://developer.apple.com/legacy/mac/library/documentation/mac/MoreToolbox/MoreToolbox-99.html
9#------------------------------------------------------------------------------
10
11package Image::ExifTool::RSRC;
12
13use strict;
14use vars qw($VERSION);
15use Image::ExifTool qw(:DataAccess :Utils);
16
17$VERSION = '1.02';
18
19# Information decoded from Mac OS resources
20%Image::ExifTool::RSRC::Main = (
21 GROUPS => { 2 => 'Document' },
22 NOTES => q{
23 Tags extracted from Mac OS resource files and DFONT files. These tags may
24 also be extracted from the resource fork of any file in OS X, either by
25 adding "/rsrc" to the filename to process the resource fork alone, or by
26 using the ExtractEmbedded (-ee) option to process the resource fork as a
27 sub-document of the main file.
28 },
29 '8BIM' => {
30 Name => 'PhotoshopInfo',
31 SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Main' },
32 },
33 'sfnt' => {
34 Name => 'Font',
35 SubDirectory => { TagTable => 'Image::ExifTool::Font::Name' },
36 },
37 'usro_0x0000' => 'OpenWithApplication',
38 'vers_0x0001' => 'ApplicationVersion',
39 'STR _0xbff3' => 'ApplicationMissingMsg',
40 'STR _0xbff4' => 'CreatorApplication',
41 # the following written by Photoshop
42 # (ref http://www.adobe.ca/devnet/photoshop/psir/ps_image_resources.pdf)
43 'STR#_0x0080' => 'Keywords',
44 'TEXT_0x0080' => 'Description',
45 # don't extract PICT's because the clip region isn't set properly
46 # in the PICT resource for some reason. Also, a dummy 512-byte
47 # header would have to be added to create a valid PICT file.
48 # 'PICT' => { Name => 'PreviewPICT', Binary => 1 },
49);
50
51#------------------------------------------------------------------------------
52# Read information from a Mac resource file (ref 1)
53# Inputs: 0) ExifTool ref, 1) dirInfo ref
54# Returns: 1 on success, 0 if this wasn't a valid resource file
55sub ProcessRSRC($$)
56{
57 my ($exifTool, $dirInfo) = @_;
58 my $raf = $$dirInfo{RAF};
59 my ($hdr, $map, $buff, $i, $j);
60
61 # attempt to validate the format as thoroughly as practical
62 return 0 unless $raf->Read($hdr, 30) == 30;
63 my ($datOff, $mapOff, $datLen, $mapLen) = unpack('N*', $hdr);
64 return 0 unless $raf->Seek(0, 2);
65 my $fLen = $raf->Tell();
66 return 0 if $datOff < 0x10 or $datOff + $datLen > $fLen;
67 return 0 if $mapOff < 0x10 or $mapOff + $mapLen > $fLen or $mapLen < 30;
68 return 0 if $datOff < $mapOff and $datOff + $datLen > $mapOff;
69 return 0 if $mapOff < $datOff and $mapOff + $mapLen > $datOff;
70
71 # read the resource map
72 $raf->Seek($mapOff, 0) and $raf->Read($map, $mapLen) == $mapLen or return 0;
73 SetByteOrder('MM');
74 my $typeOff = Get16u(\$map, 24);
75 my $nameOff = Get16u(\$map, 26);
76 my $numTypes = Get16u(\$map, 28);
77
78 # validate offsets in the resource map
79 return 0 if $typeOff < 28 or $nameOff < 30;
80
81 $exifTool->SetFileType('RSRC') unless $$exifTool{IN_RESOURCE};
82 my $verbose = $exifTool->Options('Verbose');
83 my $tagTablePtr = GetTagTable('Image::ExifTool::RSRC::Main');
84
85 # parse resource type list
86 for ($i=0; $i<=$numTypes; ++$i) {
87 my $off = $typeOff + 2 + 8 * $i; # offset of entry in type list
88 last if $off + 8 > $mapLen;
89 my $resType = substr($map,$off,4); # resource type
90 my $resNum = Get16u(\$map,$off+4); # number of resources - 1
91 my $refOff = Get16u(\$map,$off+6) + $typeOff; # offset to first resource reference
92 # loop through all resources
93 for ($j=0; $j<=$resNum; ++$j) {
94 my $roff = $refOff + 12 * $j;
95 last if $roff + 12 > $mapLen;
96 # read only the 24-bit resource data offset
97 my $id = Get16u(\$map,$roff);
98 my $resOff = (Get32u(\$map,$roff+4) & 0x00ffffff) + $datOff;
99 my $resNameOff = Get16u(\$map,$roff+2) + $nameOff + $mapOff;
100 my ($tag, $val, $valLen);
101 my $tagInfo = $$tagTablePtr{$resType};
102 if ($tagInfo) {
103 $tag = $resType;
104 } else {
105 $tag = sprintf('%s_0x%.4x', $resType, $id);
106 $tagInfo = $$tagTablePtr{$tag};
107 }
108 # read the resource data if necessary
109 if ($tagInfo or $verbose) {
110 unless ($raf->Seek($resOff, 0) and $raf->Read($buff, 4) == 4 and
111 ($valLen = unpack('N', $buff)) < 1024000 and # arbitrary size limit
112 $raf->Read($val, $valLen) == $valLen)
113 {
114 $exifTool->Warn("Error reading $resType resource");
115 next;
116 }
117 }
118 if ($verbose) {
119 my ($resName, $nameLen);
120 $resName = '' unless $raf->Seek($resNameOff, 0) and $raf->Read($buff, 1) and
121 ($nameLen = ord $buff) != 0 and $raf->Read($resName, $nameLen) == $nameLen;
122 $exifTool->VPrint(0,sprintf("$resType resource ID 0x%.4x (offset 0x%.4x, $valLen bytes, name='$resName'):\n", $id, $resOff));
123 $exifTool->VerboseDump(\$val);
124 }
125 next unless $tagInfo;
126 if ($resType eq 'vers') {
127 # parse the 'vers' resource to get the long version string
128 next unless $valLen > 8;
129 # long version string is after short version
130 my $p = 7 + Get8u(\$val, 6);
131 next if $p >= $valLen;
132 my $vlen = Get8u(\$val, $p++);
133 next if $p + $vlen > $valLen;
134 my $tagTablePtr = GetTagTable('Image::ExifTool::RSRC::Main');
135 $val = $exifTool->Decode(substr($val, $p, $vlen), 'MacRoman');
136 } elsif ($resType eq 'sfnt') {
137 # parse the OTF font block
138 $raf->Seek($resOff + 4, 0) or next;
139 $$dirInfo{Base} = $resOff + 4;
140 require Image::ExifTool::Font;
141 unless (Image::ExifTool::Font::ProcessOTF($exifTool, $dirInfo)) {
142 $exifTool->Warn('Unrecognized sfnt resource format');
143 }
144 $exifTool->OverrideFileType('DFONT');
145 next;
146 } elsif ($resType eq '8BIM') {
147 my $ttPtr = GetTagTable('Image::ExifTool::Photoshop::Main');
148 $exifTool->HandleTag($ttPtr, $id, $val,
149 DataPt => \$val,
150 DataPos => $resOff + 4,
151 Size => $valLen,
152 Start => 0,
153 Parent => 'RSRC',
154 );
155 next;
156 } elsif ($resType eq 'STR ' and $valLen > 1) {
157 # extract Pascal string
158 my $len = ord $val;
159 next unless $valLen >= $len + 1;
160 $val = substr($val, 1, $len);
161 } elsif ($resType eq 'usro' and $valLen > 4) {
162 my $len = unpack('N', $val);
163 next unless $valLen >= $len + 4;
164 ($val = substr($val, 4, $len)) =~ s/\0.*//g; # truncate at null
165 } elsif ($resType eq 'STR#' and $valLen > 2) {
166 # extract list of strings (ref http://simtech.sourceforge.net/tech/strings.html)
167 my $num = unpack('n', $val);
168 next if $num & 0xf000; # (ignore special-format STR# resources)
169 my ($i, @vals);
170 my $pos = 2;
171 for ($i=0; $i<$num; ++$i) {
172 last if $pos >= $valLen;
173 my $len = ord substr($val, $pos++, 1);
174 last if $pos + $len > $valLen;
175 push @vals, substr($val, $pos, $len);
176 $pos += $len;
177 }
178 $val = \@vals;
179 } elsif ($resType ne 'TEXT') {
180 next;
181 }
182 $exifTool->HandleTag($tagTablePtr, $tag, $val);
183 }
184 }
185 return 1;
186}
187
1881; # end
189
190__END__
191
192=head1 NAME
193
194Image::ExifTool::RSRC - Read Mac OS Resource information
195
196=head1 SYNOPSIS
197
198This module is used by Image::ExifTool
199
200=head1 DESCRIPTION
201
202This module contains routines required by Image::ExifTool to read Mac OS
203resource files.
204
205=head1 AUTHOR
206
207Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
208
209This library is free software; you can redistribute it and/or modify it
210under the same terms as Perl itself.
211
212=head1 REFERENCES
213
214=over 4
215
216=item L<http://developer.apple.com/legacy/mac/library/documentation/mac/MoreToolbox/MoreToolbox-99.html>
217
218=back
219
220=head1 SEE ALSO
221
222L<Image::ExifTool::TagNames/RSRC Tags>,
223L<Image::ExifTool(3pm)|Image::ExifTool>
224
225=cut
226
Note: See TracBrowser for help on using the repository browser.