source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MinoltaRaw.pm@ 34921

Last change on this file since 34921 was 34921, checked in by anupama, 3 years ago

Committing the improvements to EmbeddedMetaPlugin's processing of Keywords vs other metadata fields. Keywords were literally stored as arrays of words rather than phrases in PDFs (at least in Diego's sample PDF), whereas other meta fields like Subjects and Creators stored them as arrays of phrases. To get both to work, Kathy updated EXIF to a newer version, to retrieve the actual EXIF values stored in the PDF. And Kathy and Dr Bainbridge came up with a new option that I added called apply_join_before_split_to_metafields that's a regex which can list the metadata fields to apply the join_before_split to and whcih previously always got applied to all metadata fields. Now it's applied to any *Keywords metafields by default, as that's the metafield we have experience of that behaves differently to the others, as it stores by word instead of phrases. Tested on Diego's sample PDF. Diego has double-checked it to works on his sample PDF too, setting the split char to ; and turning on the join_before_split and leaving apply_join_before_split_to_metafields at its default of .*Keywords. File changes are strings.properties for the tooltip, the plugin introducing the option and working with it and Kathy's EXIF updates affecting cpan/File and cpan/Image.

File size: 16.5 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# 3) Igal Milchtaich private communication (A100)
11#------------------------------------------------------------------------------
12
13package Image::ExifTool::MinoltaRaw;
14
15use strict;
16use vars qw($VERSION);
17use Image::ExifTool qw(:DataAccess :Utils);
18use Image::ExifTool::Minolta;
19
20$VERSION = '1.16';
21
22sub ProcessMRW($$;$);
23sub WriteMRW($$;$);
24
25# Minolta MRW tags
26%Image::ExifTool::MinoltaRaw::Main = (
27 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
28 PROCESS_PROC => \&Image::ExifTool::MinoltaRaw::ProcessMRW,
29 WRITE_PROC => \&Image::ExifTool::MinoltaRaw::WriteMRW,
30 NOTES => 'These tags are used in Minolta RAW format (MRW) images.',
31 "\0TTW" => { # TIFF Tags
32 Name => 'MinoltaTTW',
33 SubDirectory => {
34 TagTable => 'Image::ExifTool::Exif::Main',
35 # this EXIF information starts with a TIFF header
36 ProcessProc => \&Image::ExifTool::ProcessTIFF,
37 WriteProc => \&Image::ExifTool::WriteTIFF,
38 },
39 },
40 "\0PRD" => { # Raw Picture Dimensions
41 Name => 'MinoltaPRD',
42 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::PRD' },
43 },
44 "\0WBG" => { # White Balance Gains
45 Name => 'MinoltaWBG',
46 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::WBG' },
47 },
48 "\0RIF" => { # Requested Image Format
49 Name => 'MinoltaRIF',
50 SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::RIF' },
51 },
52 # "\0CSA" is padding
53);
54
55# Minolta MRW PRD information (ref 2)
56%Image::ExifTool::MinoltaRaw::PRD = (
57 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
58 WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
59 CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
60 WRITABLE => 1,
61 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
62 DATAMEMBER => [ 0 ],
63 FIRST_ENTRY => 0,
64 0 => {
65 Name => 'FirmwareID',
66 Format => 'string[8]',
67 RawConv => '$$self{MinoltaPRD} = 1 if $$self{FILE_TYPE} eq "MRW"; $val', # used in decoding RIF info
68 },
69 8 => {
70 Name => 'SensorHeight',
71 Format => 'int16u',
72 },
73 10 => {
74 Name => 'SensorWidth',
75 Format => 'int16u',
76 },
77 12 => {
78 Name => 'ImageHeight',
79 Format => 'int16u',
80 },
81 14 => {
82 Name => 'ImageWidth',
83 Format => 'int16u',
84 },
85 16 => {
86 Name => 'RawDepth',
87 Format => 'int8u',
88 },
89 17 => {
90 Name => 'BitDepth',
91 Format => 'int8u',
92 },
93 18 => {
94 Name => 'StorageMethod',
95 Format => 'int8u',
96 PrintConv => {
97 82 => 'Padded',
98 89 => 'Linear',
99 },
100 },
101 23 => {
102 Name => 'BayerPattern',
103 Format => 'int8u',
104 PrintConv => {
105 # 0 - seen in some Sony A850 ARW images
106 1 => 'RGGB',
107 4 => 'GBRG',
108 },
109 },
110);
111
112# Minolta MRW WBG information (ref 2)
113%Image::ExifTool::MinoltaRaw::WBG = (
114 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
115 WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
116 CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
117 WRITABLE => 1,
118 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
119 FIRST_ENTRY => 0,
120 0 => {
121 Name => 'WBScale',
122 Format => 'int8u[4]',
123 },
124 4 => [
125 {
126 Condition => '$$self{Model} =~ /DiMAGE A200\b/',
127 Name => 'WB_GBRGLevels',
128 Format => 'int16u[4]',
129 Notes => 'DiMAGE A200',
130 },
131 {
132 Name => 'WB_RGGBLevels',
133 Format => 'int16u[4]',
134 Notes => 'other models',
135 },
136 ],
137);
138
139# Minolta MRW RIF information (ref 2)
140%Image::ExifTool::MinoltaRaw::RIF = (
141 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
142 WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
143 CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
144 WRITABLE => 1,
145 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
146 FIRST_ENTRY => 0,
147 1 => {
148 Name => 'Saturation',
149 Format => 'int8s',
150 },
151 2 => {
152 Name => 'Contrast',
153 Format => 'int8s',
154 },
155 3 => {
156 Name => 'Sharpness',
157 Format => 'int8s',
158 },
159 4 => {
160 Name => 'WBMode',
161 PrintConv => 'Image::ExifTool::MinoltaRaw::ConvertWBMode($val)',
162 },
163 5 => {
164 Name => 'ProgramMode',
165 PrintConv => {
166 0 => 'None',
167 1 => 'Portrait',
168 2 => 'Text',
169 3 => 'Night Portrait',
170 4 => 'Sunset',
171 5 => 'Sports',
172 # have seen these values in Sony ARW images: - PH
173 # 7, 128, 129, 160
174 },
175 },
176 6 => {
177 Name => 'ISOSetting',
178 RawConv => '$val == 255 ? undef : $val',
179 PrintConv => { #3
180 0 => 'Auto',
181 48 => 100,
182 56 => 200,
183 64 => 400,
184 72 => 800,
185 80 => 1600,
186 174 => '80 (Zone Matching Low)',
187 184 => '200 (Zone Matching High)',
188 OTHER => sub {
189 my ($val, $inv) = @_;
190 return int(2 ** (($val-48)/8) * 100 + 0.5) unless $inv;
191 # (must check for zero below in inverse conversion)
192 return 48 + 8*log($val/100)/log(2) if Image::ExifTool::IsFloat($val) and $val != 0;
193 return undef;
194 },
195 },
196 #ValueConv => '2 ** (($val-48)/8) * 100',
197 #ValueConvInv => '48 + 8*log($val/100)/log(2)',
198 #PrintConv => 'int($val + 0.5)',
199 #PrintConvInv => '$val',
200 },
201 7 => [
202 {
203 Name => 'ColorMode',
204 Condition => '$$self{Make} !~ /^SONY/',
205 Priority => 0,
206 Writable => 'int32u',
207 PrintConv => \%Image::ExifTool::Minolta::minoltaColorMode,
208 },
209 { #3
210 Name => 'ColorMode',
211 Condition => '$$self{Model} eq "DSLR-A100"',
212 Writable => 'int32u',
213 Notes => 'Sony A100',
214 Priority => 0,
215 PrintHex => 1,
216 PrintConv => \%Image::ExifTool::Minolta::sonyColorMode,
217 },
218 ],
219 # NOTE: WB_RBLevels up to Custom also apply to Minolta models which write PRD info (ref IB)
220 8 => { #3
221 Name => 'WB_RBLevelsTungsten',
222 Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
223 Format => 'int16u[2]',
224 Notes => 'these WB_RBLevels currently decoded only for the Sony A100',
225 },
226 12 => { #3
227 Name => 'WB_RBLevelsDaylight',
228 Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
229 Format => 'int16u[2]',
230 },
231 16 => { #3
232 Name => 'WB_RBLevelsCloudy',
233 Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
234 Format => 'int16u[2]',
235 },
236 20 => { #3
237 Name => 'WB_RBLevelsCoolWhiteF',
238 Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
239 Format => 'int16u[2]',
240 },
241 24 => { #3
242 Name => 'WB_RBLevelsFlash',
243 Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
244 Format => 'int16u[2]',
245 },
246 28 => { #3
247 Name => 'WB_RBLevelsCustom', #IB
248 Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
249 Format => 'int16u[2]',
250 },
251 32 => { #3
252 Name => 'WB_RBLevelsShade',
253 Condition => '$$self{Model} eq "DSLR-A100"',
254 Format => 'int16u[2]',
255 },
256 36 => { #3
257 Name => 'WB_RBLevelsDaylightF',
258 Condition => '$$self{Model} eq "DSLR-A100"',
259 Format => 'int16u[2]',
260 },
261 40 => { #3
262 Name => 'WB_RBLevelsDayWhiteF',
263 Condition => '$$self{Model} eq "DSLR-A100"',
264 Format => 'int16u[2]',
265 },
266 44 => { #3
267 Name => 'WB_RBLevelsWhiteF',
268 Condition => '$$self{Model} eq "DSLR-A100"',
269 Format => 'int16u[2]',
270 },
271 56 => {
272 Name => 'ColorFilter',
273 Condition => '$$self{Make} !~ /^SONY/',
274 Format => 'int8s',
275 Notes => 'Minolta models',
276 },
277 57 => 'BWFilter',
278 58 => {
279 Name => 'ZoneMatching',
280 Condition => '$$self{Make} !~ /^SONY/',
281 Priority => 0,
282 Notes => 'Minolta models',
283 PrintConv => {
284 0 => 'ISO Setting Used',
285 1 => 'High Key',
286 2 => 'Low Key',
287 },
288 },
289 59 => {
290 Name => 'Hue',
291 Format => 'int8s',
292 },
293 60 => {
294 Name => 'ColorTemperature',
295 Condition => '$$self{Make} !~ /^SONY/',
296 Notes => 'Minolta models',
297 ValueConv => '$val * 100',
298 ValueConvInv => '$val / 100',
299 },
300 74 => { #3
301 Name => 'ZoneMatching',
302 Condition => '$$self{Make} =~ /^SONY/',
303 Priority => 0,
304 Notes => 'Sony models',
305 PrintConv => {
306 0 => 'ISO Setting Used',
307 1 => 'High Key',
308 2 => 'Low Key',
309 },
310 },
311 76 => { #3
312 Name => 'ColorTemperature',
313 Condition => '$$self{Model} eq "DSLR-A100"',
314 Notes => 'A100',
315 ValueConv => '$val * 100',
316 ValueConvInv => '$val / 100',
317 PrintConv => '$val ? $val : "Auto"',
318 PrintConvInv => '$val=~/Auto/i ? 0 : $val',
319 },
320 77 => { #3
321 Name => 'ColorFilter',
322 Condition => '$$self{Model} eq "DSLR-A100"',
323 Notes => 'A100',
324 },
325 78 => { #3
326 Name => 'ColorTemperature',
327 Condition => '$$self{Model} =~ /^DSLR-A(200|700)$/',
328 Notes => 'A200 and A700',
329 ValueConv => '$val * 100',
330 ValueConvInv => '$val / 100',
331 PrintConv => '$val ? $val : "Auto"',
332 PrintConvInv => '$val=~/Auto/i ? 0 : $val',
333 },
334 79 => { #3
335 Name => 'ColorFilter',
336 Condition => '$$self{Model} =~ /^DSLR-A(200|700)$/',
337 Notes => 'A200 and A700',
338 },
339 80 => { #3
340 Name => 'RawDataLength',
341 Condition => '$$self{Model} eq "DSLR-A100"',
342 Format => 'int32u',
343 Notes => 'A100',
344 Writable => 0,
345 },
346);
347
348#------------------------------------------------------------------------------
349# PrintConv for WBMode
350sub ConvertWBMode($)
351{
352 my $val = shift;
353 my %mrwWB = (
354 0 => 'Auto',
355 1 => 'Daylight',
356 2 => 'Cloudy',
357 3 => 'Tungsten',
358 4 => 'Flash/Fluorescent',
359 5 => 'Fluorescent',
360 6 => 'Shade',
361 7 => 'User 1',
362 8 => 'User 2',
363 9 => 'User 3',
364 10 => 'Temperature',
365 );
366 my $lo = $val & 0x0f;
367 my $wbstr = $mrwWB{$lo} || "Unknown ($lo)";
368 my $hi = $val >> 4;
369 $wbstr .= ' (' . ($hi - 8) . ')' if $hi >= 6 and $hi <=12;
370 return $wbstr;
371}
372
373#------------------------------------------------------------------------------
374# Write MRW directory (eg. in ARW images)
375# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
376# Returns: new MRW data or undef on error
377sub WriteMRW($$;$)
378{
379 my ($et, $dirInfo, $tagTablePtr) = @_;
380 $et or return 1; # allow dummy access
381 my $buff = '';
382 $$dirInfo{OutFile} = \$buff;
383 ProcessMRW($et, $dirInfo, $tagTablePtr) > 0 or undef $buff;
384 return $buff;
385}
386
387#------------------------------------------------------------------------------
388# Read or write Minolta MRW file
389# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
390# Returns: 1 on success, 0 if this wasn't a valid MRW file, or -1 on write error
391# Notes: File pointer must be set to start of MRW in RAF upon entry
392sub ProcessMRW($$;$)
393{
394 my ($et, $dirInfo, $tagTablePtr) = @_;
395 my $raf = $$dirInfo{RAF};
396 my $outfile = $$dirInfo{OutFile};
397 my $verbose = $et->Options('Verbose');
398 my $out = $et->Options('TextOut');
399 my ($data, $err, $outBuff);
400
401 if ($$dirInfo{DataPt}) {
402 # make a RAF object for MRW information extracted from other file types
403 $raf = new File::RandomAccess($$dirInfo{DataPt});
404 # MRW information in DNG images may not start at beginning of data block
405 $raf->Seek($$dirInfo{DirStart}, 0) if $$dirInfo{DirStart};
406 }
407 $raf->Read($data,8) == 8 or return 0;
408 # "\0MRM" for big-endian (MRW images), and
409 # "\0MRI" for little-endian (MRWInfo in ARW images)
410 $data =~ /^\0MR([MI])/ or return 0;
411 my $hdr = "\0MR$1";
412 SetByteOrder($1 . $1);
413 $et->SetFileType();
414 $tagTablePtr = GetTagTable('Image::ExifTool::MinoltaRaw::Main');
415 if ($outfile) {
416 $et->InitWriteDirs('TIFF'); # use same write dirs as TIFF
417 $outBuff = '';
418 }
419 my $pos = $raf->Tell();
420 my $offset = Get32u(\$data, 4) + $pos;
421 my $rtnVal = 1;
422 $verbose and printf $out " [MRW Data Offset: 0x%x]\n", $offset;
423 # loop through MRW segments (ref 1)
424 while ($pos < $offset) {
425 $raf->Read($data,8) == 8 or $err = 1, last;
426 $pos += 8;
427 my $tag = substr($data, 0, 4);
428 my $len = Get32u(\$data, 4);
429 if ($verbose) {
430 print $out "MRW ",$et->Printable($tag)," segment ($len bytes):\n";
431 if ($verbose > 2) {
432 $raf->Read($data,$len) == $len and $raf->Seek($pos,0) or $err = 1, last;
433 $et->VerboseDump(\$data);
434 }
435 }
436 my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
437 if ($tagInfo and $$tagInfo{SubDirectory}) {
438 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
439 my $buff;
440 # save shift for values stored with wrong base offset
441 $$et{MRW_WrongBase} = -($raf->Tell());
442 $raf->Read($buff, $len) == $len or $err = 1, last;
443 my %subdirInfo = (
444 DataPt => \$buff,
445 DataLen => $len,
446 DataPos => $pos,
447 DirStart => 0,
448 DirLen => $len,
449 DirName => $$tagInfo{Name},
450 Parent => 'MRW',
451 NoTiffEnd => 1, # no end-of-TIFF check
452 );
453 if ($outfile) {
454 my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
455 my $val = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
456 if (defined $val and length $val) {
457 # pad to an even 4 bytes (can't hurt, and it seems to be the standard)
458 $val .= "\0" x (4 - (length($val) & 0x03)) if length($val) & 0x03;
459 $outBuff .= $tag . Set32u(length $val) . $val;
460 } elsif (not defined $val) {
461 $outBuff .= $data . $buff; # copy over original information
462 }
463 } else {
464 my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
465 $et->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
466 }
467 } elsif ($outfile) {
468 # add this segment to the output buffer
469 my $buff;
470 $raf->Read($buff, $len) == $len or $err = 1, last;
471 $outBuff .= $data . $buff;
472 } else {
473 # skip this segment
474 $raf->Seek($pos+$len, 0) or $err = 1, last;
475 }
476 $pos += $len;
477 }
478 $pos == $offset or $err = 1; # meta information length check
479
480 if ($outfile) {
481 # write the file header then the buffered meta information
482 Write($outfile, $hdr, Set32u(length $outBuff), $outBuff) or $rtnVal = -1;
483 # copy over image data
484 while ($raf->Read($outBuff, 65536)) {
485 Write($outfile, $outBuff) or $rtnVal = -1;
486 }
487 # Sony IDC utility corrupts MRWInfo when writing ARW images,
488 # so make this a minor error for these images
489 $err and $et->Error("MRW format error", $$et{TIFF_TYPE} eq 'ARW');
490 } else {
491 $err and $et->Warn("MRW format error");
492 }
493 return $rtnVal;
494}
495
4961; # end
497
498__END__
499
500=head1 NAME
501
502Image::ExifTool::MinoltaRaw - Read/write Konica-Minolta RAW (MRW) information
503
504=head1 SYNOPSIS
505
506This module is loaded automatically by Image::ExifTool when required.
507
508=head1 DESCRIPTION
509
510This module contains definitions required by Image::ExifTool to read and
511write Konica-Minolta RAW (MRW) images.
512
513=head1 AUTHOR
514
515Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
516
517This library is free software; you can redistribute it and/or modify it
518under the same terms as Perl itself.
519
520=head1 REFERENCES
521
522=over 4
523
524=item L<http://www.cybercom.net/~dcoffin/dcraw/>
525
526=item L<http://www.chauveau-central.net/mrw-format/>
527
528=back
529
530=head1 SEE ALSO
531
532L<Image::ExifTool::TagNames/MinoltaRaw Tags>,
533L<Image::ExifTool::Minolta(3pm)|Image::ExifTool::Minolta>,
534L<Image::ExifTool(3pm)|Image::ExifTool>
535
536=cut
Note: See TracBrowser for help on using the repository browser.