43
43
sub ValidateIFD($;$);
45
45
# byte sizes for the various EXIF format types below
46
@formatSize = (0,1,1,2,4,8,1,1,2,4,8,4,8,4);
46
@formatSize = (undef,1,1,2,4,8,1,1,2,4,8,4,8,4,undef,undef,8,8,8);
49
'err','int8u','string','int16u',
50
'int32u','rational64u','int8s','undef',
51
'int16s','int32s','rational64s','float',
49
undef, 'int8u', 'string', 'int16u',
50
'int32u', 'rational64u', 'int8s', 'undef',
51
'int16s', 'int32s', 'rational64s', 'float',
52
'double', 'ifd', undef, undef, # (14 is unicode, 15 is complex? http://remotesensing.org/libtiff/bigtiffdesign.html)
53
'int64u', 'int64s', 'ifd8', # (new BigTIFF formats)
55
56
# hash to look up EXIF format numbers by name
69
70
'float' => 11, # FLOAT
70
71
'double' => 12, # DOUBLE
71
72
'ifd' => 13, # IFD (with int32u format)
73
'int64u' => 16, # LONG8 [BigTIFF]
74
'int64s' => 17, # SLONG8 [BigTIFF]
75
'ifd8' => 18, # IFD8 (with int64u format) [BigTIFF]
74
78
# EXIF LightSource PrintConv values
122
127
34676 => 'SGILog', #3
123
128
34677 => 'SGILog24', #3
124
129
34712 => 'JPEG 2000', #3
125
34713 => 'Nikon NEF Compressed',
130
34713 => 'Nikon NEF Compressed', #PH
131
65000 => 'Kodak DCR Compressed', #PH
132
65535 => 'Pentax PEF Compressed', #Jens
128
136
%photometricInterpretation = (
727
735
Name => 'YCbCrSubSampling',
729
'1 1' => 'YCbCr4:4:4', #PH
730
'2 1' => 'YCbCr4:2:2', #6
731
'2 2' => 'YCbCr4:2:0', #6
732
'4 1' => 'YCbCr4:1:1', #6
733
'4 2' => 'YCbCr4:1:0', #PH
734
'1 2' => 'YCbCr4:4:0', #PH
737
'1 1' => 'YCbCr4:4:4 (1 1)', #PH
738
'2 1' => 'YCbCr4:2:2 (2 1)', #6
739
'2 2' => 'YCbCr4:2:0 (2 2)', #6
740
'4 1' => 'YCbCr4:1:1 (4 1)', #6
741
'4 2' => 'YCbCr4:1:0 (4 2)', #PH
742
'1 2' => 'YCbCr4:4:0 (1 2)', #PH
1638
1646
0xc68e => 'MaskedAreas',
1640
1648
Name => 'AsShotICCProfile',
1650
Writable => 'undef', # must be defined here so tag will be extracted if specified
1641
1651
SubDirectory => {
1652
DirName => 'AsShotICCProfile',
1642
1653
TagTable => 'Image::ExifTool::ICC_Profile::Main',
1645
1656
0xc690 => 'AsShotPreProfileMatrix',
1647
1658
Name => 'CurrentICCProfile',
1660
Writable => 'undef', # must be defined here so tag will be extracted if specified
1648
1661
SubDirectory => {
1662
DirName => 'CurrentICCProfile',
1649
1663
TagTable => 'Image::ExifTool::ICC_Profile::Main',
1749
1763
D/1440, where D is the focal plane diagonal in mm
1751
1765
Groups => { 2 => 'Camera' },
1753
0 => 'ScaleFactor35efl',
1755
ValueConv => 'sqrt(24*24+36*36) / ($val[0] * 1440)',
1766
Require => 'ScaleFactor35efl',
1767
ValueConv => 'sqrt(24*24+36*36) / ($val * 1440)',
1756
1768
PrintConv => 'sprintf("%.3f mm",$val)',
1758
1770
HyperfocalDistance => {
1804
1816
ValueConv => '"$val[0] $val[1]"',
1805
1817
PrintConv => '$self->ConvertDateTime($val)',
1807
# set the original date/time from DateTimeCreated if not set already
1819
# create DateTimeOriginal from DateTimeCreated if not set already
1808
1820
DateTimeOriginal => {
1809
1821
Condition => 'not defined($oldVal)',
1810
1822
Description => 'Date/Time Original',
1811
1823
Groups => { 2 => 'Time' },
1813
0 => 'DateTimeCreated',
1824
Require => 'DateTimeCreated',
1815
1825
ValueConv => '$val[0]',
1816
1826
PrintConv => '$prt[0]',
2154
2164
#------------------------------------------------------------------------------
2155
2165
# Calculate Red/BlueBalance
2156
# Inputs: 0) 0=red, 1=blue, 1-5) WB_RGGB/RGBG/RBGG/GRBG/RBLevels,
2157
# 6) red or blue level, 7) green level
2166
# Inputs: 0) 0=red, 1=blue, 1-6) WB_RGGB/RGBG/RBGG/GRBG/GRGB/RBLevels,
2167
# 7) red or blue level, 8) green level
2158
2168
my @rggbLookup = (
2159
2169
[ 0, 1, 2, 3 ], # RGGB
2160
2170
[ 0, 1, 3, 2 ], # RGBG
2161
2171
[ 0, 2, 3, 1 ], # RBGG
2162
2172
[ 1, 0, 3, 2 ], # GRBG
2173
[ 1, 0, 2, 3 ], # GRGB
2163
2174
[ 0, 256, 256, 1 ], # RB (green level is 256)
2165
2176
sub RedBlueBalance($@)
2279
2290
$image = $exifTool->ExtractBinary($offset, $len, $tag);
2280
2291
return undef unless defined $image;
2282
$exifTool->HtmlDump($offset, $len, "$tag data", undef, 8);
2283
2293
return $exifTool->ValidateImage(\$image, $tag);
2379
2389
my $hdrLen = $dirStart + $dataPos + $base - $makerAddr;
2380
2390
$exifTool->HtmlDump($makerAddr, $hdrLen, "MakerNotes header", $name) if $hdrLen > 0;
2382
my $str = "$name entry count";
2383
2392
$exifTool->HtmlDump($dirStart + $dataPos + $base, 2, "$name entries",
2384
2393
"Entry count: $numEntries");
2400
2409
my $count = Get32u($dataPt, $entry+4);
2401
2410
if ($format < 1 or $format > 13) {
2402
2411
$exifTool->HtmlDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
2403
"Bad format value: $format", 1);
2412
"Bad format type: $format", 1);
2404
2413
# warn unless the IFD was just padded with zeros
2405
2414
$format and $exifTool->Warn(
2406
2415
sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID));
2407
2416
return 0 unless $index; # assume corrupted IFD if this is our first entry
2419
my $formatStr = $formatName[$format]; # get name of this format
2410
2420
my $size = $count * $formatSize[$format];
2411
2421
my $valueDataPt = $dataPt;
2412
2422
my $valueDataPos = $dataPos;
2454
2464
if ($tagInfo) {
2455
2465
$tagStr = $$tagInfo{Name};
2456
2466
} elsif (defined $tagInfo) {
2457
my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '');
2467
my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);
2458
2468
$tagStr = $$tmpInfo{Name} if $tmpInfo;
2460
2470
$tagStr or $tagStr = sprintf("tag 0x%x",$tagID);
2508
2517
if (defined $tagInfo and not $tagInfo) {
2509
2518
# GetTagInfo() required the value for a Condition
2510
2519
my $tmpVal = substr($$valueDataPt, $valuePtr, $size < 48 ? $size : 48);
2511
$tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$tmpVal);
2520
$tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$tmpVal, $formatStr, $count);
2513
2522
# override EXIF format if specified
2514
2523
my $origFormStr;
2802
2811
if ($doMaker and $doMaker eq '2') {
2803
2812
# extract maker notes without rebuilding (no fixup information)
2804
2813
delete $exifTool->{MAKER_NOTE_FIXUP};
2806
# this is a pain, but we must rebuild maker notes to include
2807
# all the value data if data was outside the maker notes
2814
} elsif (not $$tagInfo{NotIFD}) {
2815
# this is a pain, but we must rebuild EXIF-typemaker notes to
2816
# include all the value data if data was outside the maker notes
2808
2817
my %makerDirInfo = (
2809
2818
Name => $tagStr,
2837
2846
# convert to absolute offsets if this tag is an offset
2838
2847
if ($$tagInfo{IsOffset}) {
2839
2848
my $offsetBase = $$tagInfo{IsOffset} eq '2' ? $firstBase : $base;
2849
$offsetBase += $$exifTool{BASE};
2840
2850
my @vals = split(' ',$val);
2841
2851
foreach $val (@vals) {
2842
2852
$val += $offsetBase;