source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIFF.pm@ 20999

Last change on this file since 20999 was 16842, checked in by davidb, 16 years ago

ExifTool added to cpan area to support metadata extraction from files such as JPEG. Primarily targetted as Image files (hence the Image folder name decided upon by the ExifTool author) it also can handle video such as flash and audio such as Wav

File size: 9.3 KB
Line 
1#------------------------------------------------------------------------------
2# File: MIFF.pm
3#
4# Description: Read Magick Image File Format meta information
5#
6# Revisions: 06/10/2005 - P. Harvey Created
7#
8# References: 1) http://www.imagemagick.org/script/miff.php
9# 2) http://www.cs.uni.edu/Help/ImageMagick/www/miff.html
10#------------------------------------------------------------------------------
11
12package Image::ExifTool::MIFF;
13
14use strict;
15use vars qw($VERSION);
16use Image::ExifTool qw(:DataAccess :Utils);
17
18$VERSION = '1.03';
19
20# MIFF chunks
21%Image::ExifTool::MIFF::Main = (
22 GROUPS => { 2 => 'Image' },
23 NOTES => q{
24The MIFF format allows aribrary tag names to be used. Only the standard tag
25names are listed below, however ExifTool will decode any tags found in the
26image.
27 },
28 'background-color' => 'BackgroundColor',
29 'blue-primary' => 'BluePrimary',
30 'border-color' => 'BorderColor',
31 'matt-color' => 'MattColor',
32 class => 'Class',
33 colors => 'Colors',
34 colorspace => 'Colorspace',
35 columns => 'ImageWidth',
36 compression => 'Compression',
37 delay => 'Delay',
38 depth => 'Depth',
39 dispose => 'Dispose',
40 gamma => 'Gamma',
41 'green-primary' => 'GreenPrimary',
42 id => 'ID',
43 iterations => 'Iterations',
44 label => 'Label',
45 matte => 'Matte',
46 montage => 'Montage',
47 packets => 'Packets',
48 page => 'Page',
49 # profile tags. Note the SubDirectory is not used by ProcessMIFF(),
50 # but is inserted for documentation purposes only
51 'profile-APP1' => [
52 # [this list is just for the sake of the documentation]
53 {
54 Name => 'APP1_Profile',
55 SubDirectory => {
56 TagTable => 'Image::ExifTool::Exif::Main',
57 },
58 },
59 {
60 Name => 'APP1_Profile',
61 SubDirectory => {
62 TagTable => 'Image::ExifTool::XMP::Main',
63 },
64 },
65 ],
66 'profile-exif' => { # haven't seen this, but it would make sense - PH
67 Name => 'EXIF_Profile',
68 SubDirectory => {
69 TagTable => 'Image::ExifTool::Exif::Main',
70 },
71 },
72 'profile-icc' => {
73 Name => 'ICC_Profile',
74 SubDirectory => {
75 TagTable => 'Image::ExifTool::ICC_Profile::Main',
76 },
77 },
78 'profile-iptc' => {
79 Name => 'IPTC_Profile',
80 SubDirectory => {
81 TagTable => 'Image::ExifTool::Photoshop::Main',
82 },
83 },
84 'profile-xmp' => { # haven't seen this, but it would make sense - PH
85 Name => 'XMP_Profile',
86 SubDirectory => {
87 TagTable => 'Image::ExifTool::XMP::Main',
88 },
89 },
90 'red-primary' => 'RedPrimary',
91 'rendering-intent' => 'RenderingIntent',
92 resolution => 'Resolution',
93 rows => 'ImageHeight',
94 scene => 'Scene',
95 signature => 'Signature',
96 units => 'Units',
97 'white-point' => 'WhitePoint',
98);
99
100#------------------------------------------------------------------------------
101# Extract meta information from a MIFF image
102# Inputs: 0) ExifTool object reference, 1) dirInfo reference
103# Returns: 1 on success, 0 if this wasn't a valid MIFF image
104sub ProcessMIFF($$)
105{
106 my ($exifTool, $dirInfo) = @_;
107 my $raf = $$dirInfo{RAF};
108 my $verbose = $exifTool->{OPTIONS}->{Verbose};
109 my ($hdr, $buff);
110
111 # validate the MIFF file (note: MIFF files _may_ begin with other
112 # characters, but this starting sequence is strongly suggested.)
113 return 0 unless $raf->Read($hdr, 14) == 14;
114 return 0 unless $hdr eq 'id=ImageMagick';
115 $exifTool->SetFileType(); # set the FileType tag
116
117 # set end-of-line character sequence to read to end of the TEXT
118 # section for new-type MIFF files (text ends with Colon+Ctrl-Z)
119 # Old MIFF files end with Colon+Linefeed, so this will likely
120 # slurp those entire files, which will be slower, but will work
121 # OK except that the profile information won't be decoded
122 my $oldsep = $/;
123 $/ = ":\x1a";
124
125 my $mode = '';
126 my @profiles;
127 if ($raf->ReadLine($buff)) {
128 chomp $buff; # remove end-of-line chars
129 my $tagTablePtr = GetTagTable('Image::ExifTool::MIFF::Main');
130 my @entries = split ' ', $buff;
131 unshift @entries, $hdr; # put the ID back in
132 my ($tag, $val);
133 foreach (@entries) {
134 if ($mode eq 'com') {
135 $mode = '' if /\}$/;
136 next;
137 } elsif (/^\{/) {
138 $mode = 'com'; # read to the end of the comment
139 next;
140 }
141 if ($mode eq 'val') {
142 $val .= " $_"; # join back together with a space
143 next unless /\}$/;
144 $mode = '';
145 $val =~ s/(^\{|\}$)//g; # remove braces
146 } elsif (/(.+)=(.+)/) {
147 ($tag, $val) = ($1, $2);
148 if ($val =~ /^\{/) {
149 $mode = 'val'; # read to the end of the value data
150 next;
151 }
152 } elsif (/^:/) {
153 # this could be the end of an old-style MIFF file
154 last;
155 } else {
156 # something we don't recognize -- stop parsing here
157 $exifTool->Warn('Unrecognized MIFF data');
158 last;
159 }
160 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
161 unless ($tagInfo) {
162 $tagInfo = { Name => $tag };
163 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
164 }
165 $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
166 Table => $tagTablePtr,
167 DataPt => \$val,
168 );
169 # handle profile tags specially
170 if ($tag =~ /^profile-(.*)/) {
171 push @profiles, [$1, $val];
172 } else {
173 $exifTool->FoundTag($tagInfo, $val);
174 }
175 }
176 }
177 $/ = $oldsep; # restore separator to original value
178
179 # process profile information
180 foreach (@profiles) {
181 my ($type, $len) = @{$_};
182 unless ($len =~ /^\d+$/) {
183 $exifTool->Warn("Invalid length for $type profile");
184 last; # don't try to read the rest
185 }
186 unless ($raf->Read($buff, $len) == $len) {
187 $exifTool->Warn("Error reading $type profile ($len bytes)");
188 next;
189 }
190 my $processed = 0;
191 my %dirInfo = (
192 Parent => 'PNG',
193 DataPt => \$buff,
194 DataPos => $raf->Tell() - $len,
195 DataLen => $len,
196 DirStart => 0,
197 DirLen => $len,
198 );
199 if ($type eq 'icc') {
200 # ICC Profile information
201 my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
202 $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
203 } elsif ($type eq 'iptc') {
204 if ($buff =~ /^8BIM/) {
205 # Photoshop information
206 my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
207 $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
208 }
209 # I haven't seen 'exif' or 'xmp' profile types yet, but I have seen them
210 # in newer PNG files so presumably they are possible here as well - PH
211 } elsif ($type eq 'APP1' or $type eq 'exif' or $type eq 'xmp') {
212 if ($buff =~ /^$Image::ExifTool::exifAPP1hdr/) {
213 # APP1 EXIF
214 my $hdrLen = length($Image::ExifTool::exifAPP1hdr);
215 $dirInfo{DirStart} += $hdrLen;
216 $dirInfo{DirLen} -= $hdrLen;
217 # use the usual position for EXIF data: 12 bytes from start of file
218 # (this may be wrong, but I can't see where the PNG stores this information)
219 $dirInfo{Base} = 12; # this is the usual value
220 $processed = $exifTool->ProcessTIFF(\%dirInfo);
221 } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
222 # APP1 XMP
223 my $hdrLen = length($Image::ExifTool::xmpAPP1hdr);
224 my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
225 $dirInfo{DirStart} += $hdrLen;
226 $dirInfo{DirLen} -= $hdrLen;
227 $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
228 }
229 }
230 unless ($processed) {
231 $exifTool->Warn("Unknown MIFF $type profile data");
232 if ($verbose) {
233 $exifTool->VerboseDir($type, 0, $len);
234 Image::ExifTool::HexDump(\$buff, undef,
235 Out => $exifTool->Options('TextOut')
236 ) if $verbose > 2;
237 }
238 }
239 }
240 return 1;
241}
242
2431; # end
244
245__END__
246
247=head1 NAME
248
249Image::ExifTool::MIFF - Read Magick Image File Format meta information
250
251=head1 SYNOPSIS
252
253This module is used by Image::ExifTool
254
255=head1 DESCRIPTION
256
257This module contains routines required by Image::ExifTool to read MIFF
258(Magick Image File Format) images.
259
260=head1 AUTHOR
261
262Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
263
264This library is free software; you can redistribute it and/or modify it
265under the same terms as Perl itself.
266
267=head1 REFERENCES
268
269=over 4
270
271=item L<http://www.imagemagick.org/script/miff.php>
272
273=item L<http://www.cs.uni.edu/Help/ImageMagick/www/miff.html>
274
275=back
276
277=head1 SEE ALSO
278
279L<Image::ExifTool::TagNames/MIFF Tags>,
280L<Image::ExifTool(3pm)|Image::ExifTool>
281
282=cut
283
Note: See TracBrowser for help on using the repository browser.