1 | #------------------------------------------------------------------------------
|
---|
2 | # File: Rawzor.pm
|
---|
3 | #
|
---|
4 | # Description: Read meta information from Rawzor compressed images
|
---|
5 | #
|
---|
6 | # Revisions: 09/09/2008 - P. Harvey Created
|
---|
7 | #
|
---|
8 | # References: 1) http://www.rawzor.com/
|
---|
9 | #------------------------------------------------------------------------------
|
---|
10 |
|
---|
11 | package Image::ExifTool::Rawzor;
|
---|
12 |
|
---|
13 | use strict;
|
---|
14 | use vars qw($VERSION);
|
---|
15 | use Image::ExifTool qw(:DataAccess :Utils);
|
---|
16 |
|
---|
17 | $VERSION = '1.01';
|
---|
18 |
|
---|
19 | # currently support this version Rawzor images
|
---|
20 | my $implementedRawzorVersion = 199; # (up to version 1.99)
|
---|
21 |
|
---|
22 | # Rawzor-specific tags
|
---|
23 | %Image::ExifTool::Rawzor::Main = (
|
---|
24 | GROUPS => { 2 => 'Other' },
|
---|
25 | VARS => { NO_ID => 1 },
|
---|
26 | NOTES => q{
|
---|
27 | Rawzor files store compressed images of other formats. As well as the
|
---|
28 | information listed below, exiftool uncompresses and extracts the meta
|
---|
29 | information from the original image.
|
---|
30 | },
|
---|
31 | OriginalFileType => { },
|
---|
32 | OriginalFileSize => {
|
---|
33 | PrintConv => $Image::ExifTool::Extra{FileSize}->{PrintConv},
|
---|
34 | },
|
---|
35 | RawzorRequiredVersion => {
|
---|
36 | ValueConv => '$val / 100',
|
---|
37 | PrintConv => 'sprintf("%.2f", $val)',
|
---|
38 | },
|
---|
39 | RawzorCreatorVersion => {
|
---|
40 | ValueConv => '$val / 100',
|
---|
41 | PrintConv => 'sprintf("%.2f", $val)',
|
---|
42 | },
|
---|
43 | # compression factor is originalSize/compressedSize (and compression
|
---|
44 | # ratio is the inverse - ref "Data Compression" by David Salomon)
|
---|
45 | CompressionFactor => { PrintConv => 'sprintf("%.2f", $val)' },
|
---|
46 | );
|
---|
47 |
|
---|
48 | #------------------------------------------------------------------------------
|
---|
49 | # Extract information from a Rawzor file
|
---|
50 | # Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
---|
51 | # Returns: 1 on success, 0 if this wasn't a valid Rawzor file
|
---|
52 | sub ProcessRWZ($$)
|
---|
53 | {
|
---|
54 | my ($exifTool, $dirInfo) = @_;
|
---|
55 | my $raf = $$dirInfo{RAF};
|
---|
56 | my ($buff, $buf2);
|
---|
57 |
|
---|
58 | # read the Rawzor file header:
|
---|
59 | # 0 string - "rawzor" signature
|
---|
60 | # 6 int16u - Required SDK version
|
---|
61 | # 8 int16u - Creator SDK version
|
---|
62 | # 10 int64u - RWZ file size
|
---|
63 | # 18 int64u - original raw file size
|
---|
64 | # 26 undef[12] - reserved
|
---|
65 | # 38 int64u - metadata offset
|
---|
66 | $raf->Read($buff, 46) == 46 and $buff =~ /^rawzor/ or return 0;
|
---|
67 |
|
---|
68 | SetByteOrder('II');
|
---|
69 | my $reqVers = Get16u(\$buff, 6);
|
---|
70 | my $creatorVers = Get16u(\$buff, 8);
|
---|
71 | my $rwzSize = Get64u(\$buff, 10);
|
---|
72 | my $origSize = Get64u(\$buff, 18);
|
---|
73 | my $tagTablePtr = GetTagTable('Image::ExifTool::Rawzor::Main');
|
---|
74 | $exifTool->HandleTag($tagTablePtr, RawzorRequiredVersion => $reqVers);
|
---|
75 | $exifTool->HandleTag($tagTablePtr, RawzorCreatorVersion => $creatorVers);
|
---|
76 | $exifTool->HandleTag($tagTablePtr, OriginalFileSize => $origSize);
|
---|
77 | $exifTool->HandleTag($tagTablePtr, CompressionFactor => $origSize/$rwzSize) if $rwzSize;
|
---|
78 | # check version numbers
|
---|
79 | if ($reqVers > $implementedRawzorVersion) {
|
---|
80 | $exifTool->Warn("Version $reqVers Rawzor images not yet supported");
|
---|
81 | return 1;
|
---|
82 | }
|
---|
83 | my $metaOffset = Get64u(\$buff, 38);
|
---|
84 | if ($metaOffset > 0x7fffffff) {
|
---|
85 | $exifTool->Warn('Bad metadata offset');
|
---|
86 | return 1;
|
---|
87 | }
|
---|
88 | # check for the ability to uncompress the information
|
---|
89 | unless (eval 'require IO::Uncompress::Bunzip2') {
|
---|
90 | $exifTool->Warn('Install IO::Compress::Bzip2 to decode Rawzor bzip2 compression');
|
---|
91 | return 1;
|
---|
92 | }
|
---|
93 | # read the metadata header:
|
---|
94 | # 0 int64u - metadata section 0 end (offset in original file)
|
---|
95 | # 8 int64u - metadata section 1 start
|
---|
96 | # 16 int64u - metadata section 1 end
|
---|
97 | # 24 int64u - metadata section 2 start
|
---|
98 | # 32 undef[4] - reserved
|
---|
99 | # 36 int32u - original metadata size
|
---|
100 | # 40 int32u - compressed metadata size
|
---|
101 | unless ($raf->Seek($metaOffset, 0) and $raf->Read($buff, 44) == 44) {
|
---|
102 | $exifTool->Warn('Error reading metadata header');
|
---|
103 | return 1;
|
---|
104 | }
|
---|
105 | my $metaSize = Get32u(\$buff, 36);
|
---|
106 | if ($metaSize) {
|
---|
107 | # validate the metadata header and read the compressed metadata
|
---|
108 | my $end0 = Get64u(\$buff, 0);
|
---|
109 | my $pos1 = Get64u(\$buff, 8);
|
---|
110 | my $end1 = Get64u(\$buff, 16);
|
---|
111 | my $pos2 = Get64u(\$buff, 24);
|
---|
112 | my $len = Get32u(\$buff, 40);
|
---|
113 | unless ($raf->Read($buff, $len) == $len and
|
---|
114 | $end0 + ($end1 - $pos1) + ($origSize - $pos2) == $metaSize and
|
---|
115 | $end0 <= $pos1 and $pos1 <= $end1 and $end1 <= $pos2)
|
---|
116 | {
|
---|
117 | $exifTool->Warn('Error reading image metadata');
|
---|
118 | return 1;
|
---|
119 | }
|
---|
120 | # uncompress the metadata
|
---|
121 | unless (IO::Uncompress::Bunzip2::bunzip2(\$buff, \$buf2) and
|
---|
122 | length($buf2) eq $metaSize)
|
---|
123 | {
|
---|
124 | $exifTool->Warn('Error uncompressing image metadata');
|
---|
125 | return 1;
|
---|
126 | }
|
---|
127 | # re-assemble the original file (sans image data)
|
---|
128 | undef $buff; # (can't hurt to free memory as soon as possible)
|
---|
129 | $buff = substr($buf2, 0, $end0) . ("\0" x ($pos1 - $end0)) .
|
---|
130 | substr($buf2, $end0, $end1 - $pos1) . ("\0" x ($pos2 - $end1)) .
|
---|
131 | substr($buf2, $end0 + $end1 - $pos1, $origSize - $pos2);
|
---|
132 | undef $buf2;
|
---|
133 |
|
---|
134 | # extract original information by calling ExtractInfo recursively
|
---|
135 | $exifTool->ExtractInfo(\$buff, { ReEntry => 1 });
|
---|
136 | undef $buff;
|
---|
137 | }
|
---|
138 | # set OriginalFileType from FileType of original file
|
---|
139 | # then change FileType and MIMEType to indicate a Rawzor image
|
---|
140 | my $origFileType = $exifTool->{VALUE}->{FileType};
|
---|
141 | if ($origFileType) {
|
---|
142 | $exifTool->HandleTag($tagTablePtr, OriginalFileType => $origFileType);
|
---|
143 | $exifTool->{VALUE}->{FileType} = 'RWZ';
|
---|
144 | $exifTool->{VALUE}->{MIMEType} = 'image/x-rawzor';
|
---|
145 | } else {
|
---|
146 | $exifTool->HandleTag($tagTablePtr, OriginalFileType => 'Unknown');
|
---|
147 | $exifTool->SetFileType();
|
---|
148 | }
|
---|
149 | return 1;
|
---|
150 | }
|
---|
151 |
|
---|
152 | 1; # end
|
---|
153 |
|
---|
154 | __END__
|
---|
155 |
|
---|
156 | =head1 NAME
|
---|
157 |
|
---|
158 | Image::ExifTool::Rawzor - Read meta information from Rawzor compressed images
|
---|
159 |
|
---|
160 | =head1 SYNOPSIS
|
---|
161 |
|
---|
162 | This module is used by Image::ExifTool
|
---|
163 |
|
---|
164 | =head1 DESCRIPTION
|
---|
165 |
|
---|
166 | This module contains definitions required by Image::ExifTool to extract meta
|
---|
167 | information from Rawzor compressed images.
|
---|
168 |
|
---|
169 | =head1 AUTHOR
|
---|
170 |
|
---|
171 | Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
|
---|
172 |
|
---|
173 | This library is free software; you can redistribute it and/or modify it
|
---|
174 | under the same terms as Perl itself.
|
---|
175 |
|
---|
176 | =head1 REFERENCES
|
---|
177 |
|
---|
178 | =over 4
|
---|
179 |
|
---|
180 | =item L<http://www.rawzor.com/>
|
---|
181 |
|
---|
182 | =back
|
---|
183 |
|
---|
184 | =head1 SEE ALSO
|
---|
185 |
|
---|
186 | L<Image::ExifTool::TagNames/Rawzor Tags>,
|
---|
187 | L<Image::ExifTool(3pm)|Image::ExifTool>
|
---|
188 |
|
---|
189 | =cut
|
---|
190 |
|
---|