source: gsdl/trunk/perllib/cpan/Image/ExifTool/MinoltaRaw.pm@ 16842

Last change on this file since 16842 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: 10.3 KB
Line 
1#------------------------------------------------------------------------------
2# File: MinoltaRaw.pm
3#
4# Description: Read/write Konica-Minolta RAW (MRW) meta information
5#
6# Revisions: 03/11/2006 - P. Harvey Split out from Minolta.pm
7#
8# References: 1) http://www.cybercom.net/~dcoffin/dcraw/
9# 2) http://www.chauveau-central.net/mrw-format/
10#------------------------------------------------------------------------------
11
12package Image::ExifTool::MinoltaRaw;
13
14use strict;
15use vars qw($VERSION);
16use Image::ExifTool qw(:DataAccess :Utils);
17
18$VERSION = '1.02';
19
20# Minolta MRW tags
21%Image::ExifTool::MinoltaRaw::Main = (
22 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
23 NOTES => 'These tags are used in Minolta RAW format (MRW) images.',
24 "\0TTW" => {
25 Name => 'MinoltaTTW',
26 SubDirectory => {
27 TagTable => 'Image::ExifTool::Exif::Main',
28 # this EXIF information starts with a TIFF header
29 ProcessProc => \&Image::ExifTool::ProcessTIFF,
30 WriteProc => \&Image::ExifTool::WriteTIFF,
31 },
32 },
33 "\0PRD" => {
34 Name => 'MinoltaPRD',
35 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::PRD' },
36 },
37 "\0WBG" => {
38 Name => 'MinoltaWBG',
39 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::WBG' },
40 },
41 "\0RIF" => {
42 Name => 'MinoltaRIF',
43 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::RIF' },
44 },
45);
46
47# Minolta MRW PRD information (ref 2)
48%Image::ExifTool::MinoltaRaw::PRD = (
49 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
50 WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
51 CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
52 WRITABLE => 1,
53 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
54 FIRST_ENTRY => 0,
55 0 => {
56 Name => 'FirmwareID',
57 Format => 'string[8]',
58 },
59 8 => {
60 Name => 'SensorHeight',
61 Format => 'int16u',
62 },
63 10 => {
64 Name => 'SensorWidth',
65 Format => 'int16u',
66 },
67 12 => {
68 Name => 'ImageHeight',
69 Format => 'int16u',
70 },
71 14 => {
72 Name => 'ImageWidth',
73 Format => 'int16u',
74 },
75 16 => {
76 Name => 'RawDepth',
77 Format => 'int8u',
78 },
79 17 => {
80 Name => 'BitDepth',
81 Format => 'int8u',
82 },
83 18 => {
84 Name => 'StorageMethod',
85 Format => 'int8u',
86 PrintConv => {
87 82 => 'Padded',
88 89 => 'Linear',
89 },
90 },
91 23 => {
92 Name => 'BayerPattern',
93 Format => 'int8u',
94 PrintConv => {
95 1 => 'RGGB',
96 4 => 'GBRG',
97 },
98 },
99);
100
101# Minolta MRW WBG information (ref 2)
102%Image::ExifTool::MinoltaRaw::WBG = (
103 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
104 WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
105 CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
106 WRITABLE => 1,
107 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
108 FIRST_ENTRY => 0,
109 0 => {
110 Name => 'WBScale',
111 Format => 'int8u[4]',
112 },
113 4 => {
114 Name => 'WBLevels',
115 Format => 'int16u[4]',
116 },
117);
118
119# Minolta MRW RIF information (ref 2)
120%Image::ExifTool::MinoltaRaw::RIF = (
121 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
122 WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
123 CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
124 WRITABLE => 1,
125 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
126 FIRST_ENTRY => 0,
127 1 => {
128 Name => 'Saturation',
129 Format => 'int8s',
130 },
131 2 => {
132 Name => 'Contrast',
133 Format => 'int8s',
134 },
135 3 => {
136 Name => 'Sharpness',
137 Format => 'int8s',
138 },
139 4 => {
140 Name => 'WBMode',
141 PrintConv => 'Image::ExifTool::MinoltaRaw::ConvertWBMode($val)',
142 },
143 5 => {
144 Name => 'ProgramMode',
145 PrintConv => {
146 0 => 'None',
147 1 => 'Portrait',
148 2 => 'Text',
149 3 => 'Night Portrait',
150 4 => 'Sunset',
151 5 => 'Sports',
152 },
153 },
154 6 => {
155 Name => 'ISOSetting',
156 ValueConv => '2 ** (($val-48)/8) * 100',
157 ValueConvInv => '48 + 8*log($val/100)/log(2)',
158 PrintConv => 'int($val + 0.5)',
159 PrintConvInv => '$val',
160 },
161 7 => {
162 Name => 'ColorMode',
163 PrintHex => 1,
164 PrintConv => {
165 0 => 'Normal',
166 1 => 'Black & White',
167 2 => 'Vivid color',
168 3 => 'Solarization',
169 4 => 'Adobe RGB',
170 13 => 'Natural sRGB',
171 14 => 'Natural+ sRGB',
172 0x84 => 'Adobe RGB', # what does the high bit mean?
173 },
174 },
175 56 => {
176 Name => 'ColorFilter',
177 Format => 'int8s',
178 },
179 57 => 'BWFilter',
180 58 => {
181 Name => 'ZoneMatching',
182 PrintConv => {
183 0 => 'ISO Setting Used',
184 1 => 'High Key',
185 2 => 'Low Key',
186 },
187 },
188 59 => {
189 Name => 'Hue',
190 Format => 'int8s',
191 },
192 60 => {
193 Name => 'ColorTemperature',
194 ValueConv => '$val * 100',
195 ValueConvInv => '$val / 100',
196 },
197);
198
199#------------------------------------------------------------------------------
200# PrintConv for WBMode
201sub ConvertWBMode($)
202{
203 my $val = shift;
204 my %mrwWB = (
205 0 => 'Auto',
206 1 => 'Daylight',
207 2 => 'Cloudy',
208 3 => 'Tungsten',
209 4 => 'Flash/Fluorescent',
210 5 => 'Fluorescent',
211 6 => 'Shade',
212 7 => 'User 1',
213 8 => 'User 2',
214 9 => 'User 3',
215 10 => 'Temperature',
216 );
217 my $lo = $val & 0x0f;
218 my $wbstr = $mrwWB{$lo} || "Unknown ($lo)";
219 my $hi = $val >> 4;
220 $wbstr .= ' (' . ($hi - 8) . ')' if $hi >= 6 and $hi <=12;
221 return $wbstr;
222}
223
224#------------------------------------------------------------------------------
225# Read or write Minolta MRW file
226# Inputs: 0) ExifTool object reference, 1) dirInfo reference
227# Returns: 1 on success, 0 if this wasn't a valid MRW file, or -1 on write error
228sub ProcessMRW($$)
229{
230 my ($exifTool, $dirInfo) = @_;
231 my $raf = $$dirInfo{RAF};
232 my $outfile = $$dirInfo{OutFile};
233 my $verbose = $exifTool->Options('Verbose');
234 my $out = $exifTool->Options('TextOut');
235 my ($data, $err, $outBuff);
236
237 $raf->Read($data,8) == 8 or return 0;
238 $data =~ /^\0MRM/ or return 0;
239 $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
240 SetByteOrder('MM');
241 my $tagTablePtr = GetTagTable('Image::ExifTool::MinoltaRaw::Main');
242 if ($outfile) {
243 $exifTool->InitWriteDirs('TIFF'); # use same write dirs as TIFF
244 $outBuff = '';
245 }
246 my $offset = Get32u(\$data, 4) + 8;
247 my $pos = 8;
248 my $rtnVal = 1;
249 $verbose and printf $out " [MRW Data Offset: 0x%x]\n", $offset;
250 # loop through MRW segments (ref 1)
251 while ($pos < $offset) {
252 $raf->Read($data,8) == 8 or $err = 1, last;
253 $pos += 8;
254 my $tag = substr($data, 0, 4);
255 my $len = Get32u(\$data, 4);
256 if ($verbose) {
257 print $out "MRW ",$exifTool->Printable($tag)," segment ($len bytes):\n";
258 if ($verbose > 2) {
259 $raf->Read($data,$len) == $len and $raf->Seek($pos,0) or $err = 1, last;
260 my %parms = (Addr => $pos, Out => $out);
261 $parms{MaxLen} = 96 unless $verbose > 3;
262 Image::ExifTool::HexDump(\$data,undef,%parms);
263 }
264 }
265 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
266 if ($tagInfo and $$tagInfo{SubDirectory}) {
267 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
268 my $buff;
269 $raf->Read($buff, $len) == $len or $err = 1, last;
270 my %subdirInfo = (
271 DataPt => \$buff,
272 DataLen => $len,
273 DataPos => $pos,
274 DirStart => 0,
275 DirLen => $len,
276 DirName => $$tagInfo{Name},
277 Parent => 'MRW',
278 NoTiffEnd => 1, # no end-of-TIFF check
279 );
280 if ($outfile) {
281 my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
282 my $val = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
283 if (defined $val and length $val) {
284 # pad to an even 4 bytes (can't hurt, and it seems to be the standard)
285 $val .= "\0" x (4 - (length($val) & 0x03)) if length($val) & 0x03;
286 $outBuff .= $tag . Set32u(length $val) . $val;
287 } elsif (not defined $val) {
288 $outBuff .= $data . $buff; # copy over original information
289 }
290 } else {
291 my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
292 $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
293 }
294 } elsif ($outfile) {
295 # add this segment to the output buffer
296 my $buff;
297 $raf->Read($buff, $len) == $len or $err = 1, last;
298 $outBuff .= $data . $buff;
299 } else {
300 # skip this segment
301 $raf->Seek($pos+$len, 0) or $err = 1, last;
302 }
303 $pos += $len;
304 }
305 $pos == $offset or $err = 1; # meta information length check
306
307 if ($outfile) {
308 # write the file header then the buffered meta information
309 Write($outfile, "\0MRM", Set32u(length $outBuff), $outBuff) or $rtnVal = -1;
310 # copy over image data
311 while ($raf->Read($outBuff, 65536)) {
312 Write($outfile, $outBuff) or $rtnVal = -1;
313 }
314 }
315 $err and $exifTool->Error("MRW format error");
316 return $rtnVal;
317}
318
3191; # end
320
321__END__
322
323=head1 NAME
324
325Image::ExifTool::MinoltaRaw - Read/write Konica-Minolta RAW (MRW) information
326
327=head1 SYNOPSIS
328
329This module is loaded automatically by Image::ExifTool when required.
330
331=head1 DESCRIPTION
332
333This module contains definitions required by Image::ExifTool to read and
334write Konica-Minolta RAW (MRW) images.
335
336=head1 AUTHOR
337
338Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
339
340This library is free software; you can redistribute it and/or modify it
341under the same terms as Perl itself.
342
343=head1 REFERENCES
344
345=over 4
346
347=item L<http://www.cybercom.net/~dcoffin/dcraw/>
348
349=item L<http://www.chauveau-central.net/mrw-format/>
350
351=back
352
353=head1 SEE ALSO
354
355L<Image::ExifTool::TagNames/MinoltaRaw Tags>,
356L<Image::ExifTool::Minolta(3pm)|Image::ExifTool::Minolta>,
357L<Image::ExifTool(3pm)|Image::ExifTool>
358
359=cut
Note: See TracBrowser for help on using the repository browser.