8
8
# References: 1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
9
9
# 2) http://homepage3.nifty.com/kamisaka/makernote/makernote_fuji.htm
10
10
# 3) Michael Meissner private communication
11
# 4) Paul Samuelson private communication (S5)
12
# 5) http://www.cybercom.net/~dcoffin/dcraw/
11
13
#------------------------------------------------------------------------------
13
15
package Image::ExifTool::FujiFilm;
16
18
use vars qw($VERSION);
17
use Image::ExifTool qw(:DataAccess);
19
use Image::ExifTool qw(:DataAccess :Utils);
18
20
use Image::ExifTool::Exif;
22
24
%Image::ExifTool::FujiFilm::Main = (
23
25
WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
297
# tags in RAF images (ref 5)
298
%Image::ExifTool::FujiFilm::RAF = (
299
GROUPS => { 0 => 'RAF', 1 => 'RAF', 2 => 'Image' },
300
NOTES => 'Tags extracted from FujiFilm RAF-format information.',
302
Name => 'RawImageFullSize',
304
Groups => { 1 => 'RAF2' }, # (so RAF2 shows up in family 1 list)
306
Notes => 'including borders',
307
ValueConv => 'my @v=reverse split(" ",$val);"@v"',
308
PrintConv => '$val=~tr/ /x/; $val',
312
Name => 'RawImageSize',
313
Condition => '$$self{CameraModel} eq "FinePixS2Pro"',
317
my @v=split(" ",$val);
321
PrintConv => '$val=~tr/ /x/; $val',
324
Name => 'RawImageSize',
327
# values are height then width, adjusted for the layout
329
my @v=reverse split(" ",$val);
330
$$self{FujiLayout} and $v[0]/=2, $v[1]*=2;
333
PrintConv => '$val=~tr/ /x/; $val',
337
Name => 'FujiLayout',
340
my ($v) = split ' ', $val;
341
$$self{FujiLayout} = $v & 0x80 ? 1 : 0;
346
Name => 'WB_GRGBLevels',
352
#------------------------------------------------------------------------------
353
# get information from FujiFilm RAF directory
354
# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref
355
# Returns: 1 if this was a valid FujiFilm directory
356
sub ProcessFujiDir($$$)
358
my ($exifTool, $dirInfo, $tagTablePtr) = @_;
359
my $raf = $$dirInfo{RAF};
360
my $offset = $$dirInfo{DirStart};
361
$raf->Seek($offset, 0) or return 0;
363
$raf->Read($buff, 4) or return 0;
364
my $entries = unpack 'N', $buff;
365
$entries < 256 or return 0;
368
$raf->Read($buff,4) or return 0;
369
my ($tag, $len) = unpack 'nn', $buff;
371
$raf->Read($vbuf, $len) or return 0;
372
my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
373
if ($tagInfo and $$tagInfo{Format}) {
374
$val = ReadValue(\$vbuf, 0, $$tagInfo{Format}, $$tagInfo{Count}, $len);
375
next unless defined $val;
379
$exifTool->HandleTag($tagTablePtr, $tag, $val);
289
384
#------------------------------------------------------------------------------
290
385
# get information from FujiFilm RAW file
291
386
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
293
388
sub ProcessRAF($$)
295
390
my ($exifTool, $dirInfo) = @_;
297
393
my $raf = $$dirInfo{RAF};
298
$raf->Read($buff,8) == 8 or return 0;
299
$buff eq 'FUJIFILM' or return 0;
300
$raf->Seek(84, 0) or return 0;
301
$raf->Read($buff, 4) == 4 or return 0;
303
my $base = Get32u(\$buff, 0) + 12;
394
$raf->Read($buff,8) == 8 or return 0;
395
$buff eq 'FUJIFILM' or return 0;
396
$raf->Seek(84, 0) or return 0;
397
$raf->Read($buff, 8) == 8 or return 0;
398
my ($pos, $len) = unpack('NN', $buff);
399
$pos & 0x8000 and return 0;
400
$raf->Seek($pos, 0) or return 0;
401
$raf->Read($buff, $len) == $len or return 0;
404
RAF => new File::RandomAccess(\$buff),
309
return $exifTool->ProcessTIFF(\%dirInfo);
406
$$exifTool{BASE} += $pos;
407
my $rtnVal = $exifTool->ProcessJPEG(\%dirInfo);
408
$$exifTool{BASE} -= $pos;
409
$exifTool->FoundTag('PreviewImage', \$buff) if $rtnVal;
411
if ($raf->Seek(92, 0) and $raf->Read($buff, 4)) {
412
my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::RAF');
415
DirStart => unpack('N', $buff),
417
$$exifTool{SET_GROUP1} = 'RAF';
418
ProcessFujiDir($exifTool, \%dirInfo, $tagTablePtr) or $warn = 1;
420
# extract information from 2nd image if available
422
$raf->Seek(120, 0) or return 0;
423
$raf->Read($buff, 4) or return 0;
424
my $start = unpack('N',$buff);
426
$$dirInfo{DirStart} = $start;
427
$$exifTool{SET_GROUP1} = 'RAF2';
428
ProcessFujiDir($exifTool, \%dirInfo, $tagTablePtr) or $warn = 1;
431
delete $$exifTool{SET_GROUP1};
435
$warn and $exifTool->Warn('Possibly corrupt RAF information');