~ubuntu-branches/ubuntu/karmic/libimage-exiftool-perl/karmic

« back to all changes in this revision

Viewing changes to lib/Image/ExifTool/Exif.pm

  • Committer: Bazaar Package Importer
  • Author(s): Mari Wang
  • Date: 2008-02-04 20:32:53 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080204203253-mpbal8trlfe1fz5d
Tags: 7.00-1
* Upload of new production release (Closes: #456430)
* Added Recommends: libcompress-zlib-perl (Closes: #435589)
* Package now includes iptc2xmp.args and xmp2iptc.args, they are put
  into /usr/share/libimage-exiftool/ (Closes: #436100)
* Updated standards-version (3.7.2 -> 3.7.3). No changes needed.
* Lots of updates and bugfixes compared to last debian version
  (6.90).  See the Changes file for details
* Upload sponsored by Petter Reinholdtsen

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
use Image::ExifTool qw(:DataAccess :Utils);
34
34
use Image::ExifTool::MakerNotes;
35
35
 
36
 
$VERSION = '2.36';
 
36
$VERSION = '2.42';
37
37
 
38
38
sub ProcessExif($$$);
39
39
sub WriteExif($$$);
43
43
sub ValidateIFD($;$);
44
44
 
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);
47
47
 
48
48
@formatName = (
49
 
    'err','int8u','string','int16u',
50
 
    'int32u','rational64u','int8s','undef',
51
 
    'int16s','int32s','rational64s','float',
52
 
    'double', 'ifd'
 
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)
53
54
);
54
55
 
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]
72
76
);
73
77
 
74
78
# EXIF LightSource PrintConv values
107
111
    9 => 'JBIG B&W', #3
108
112
    10 => 'JBIG Color', #3
109
113
    32766 => 'Next', #3
 
114
    32769 => 'Epson ERF Compressed', #PH
110
115
    32771 => 'CCIRLEW', #3
111
116
    32773 => 'PackBits',
112
117
    32809 => 'Thunderscan', #3
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
 
133
    
126
134
);
127
135
 
128
136
%photometricInterpretation = (
726
734
    0x212 => {
727
735
        Name => 'YCbCrSubSampling',
728
736
        PrintConv => {
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
735
743
        },
736
744
        Priority => 0,
737
745
    },
1569
1577
            Flags => 'SubIFD',
1570
1578
            Format => 'int32u',
1571
1579
            SubDirectory => {
 
1580
                DirName => 'SR2Private',
1572
1581
                TagTable => 'Image::ExifTool::Sony::SR2Private',
1573
 
                DirName => 'SR2Private',
1574
1582
                Start => '$val',
1575
1583
            },
1576
1584
        },
1638
1646
    0xc68e => 'MaskedAreas',
1639
1647
    0xc68f => {
1640
1648
        Name => 'AsShotICCProfile',
 
1649
        Binary => 1,
 
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',
1643
1654
        },
1644
1655
    },
1645
1656
    0xc690 => 'AsShotPreProfileMatrix',
1646
1657
    0xc691 => {
1647
1658
        Name => 'CurrentICCProfile',
 
1659
        Binary => 1,
 
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',
1650
1664
        },
1651
1665
    },
1749
1763
            D/1440, where D is the focal plane diagonal in mm
1750
1764
        },
1751
1765
        Groups => { 2 => 'Camera' },
1752
 
        Require => {
1753
 
            0 => 'ScaleFactor35efl',
1754
 
        },
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)',
1757
1769
    },
1758
1770
    HyperfocalDistance => {
1804
1816
        ValueConv => '"$val[0] $val[1]"',
1805
1817
        PrintConv => '$self->ConvertDateTime($val)',
1806
1818
    },
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' },
1812
 
        Require => {
1813
 
            0 => 'DateTimeCreated',
1814
 
        },
 
1824
        Require => 'DateTimeCreated',
1815
1825
        ValueConv => '$val[0]',
1816
1826
        PrintConv => '$prt[0]',
1817
1827
    },
1860
1870
            return undef if defined $val[2] and not $val[2];
1861
1871
            return Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],'PreviewImage');
1862
1872
        },
1863
 
        ValueConvInv => '$val',
1864
1873
    },
1865
1874
    JpgFromRaw => {
1866
1875
        Writable => 1,
1874
1883
            1 => 'JpgFromRawLength',
1875
1884
        },
1876
1885
        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"JpgFromRaw")',
1877
 
        ValueConvInv => '$val',
1878
1886
    },
1879
1887
    OtherImage => {
1880
1888
        Require => {
1922
1930
            1 => 'WB_RGBGLevels',
1923
1931
            2 => 'WB_RBGGLevels',
1924
1932
            3 => 'WB_GRBGLevels',
1925
 
            4 => 'WB_RBLevels',
1926
 
            5 => 'WB_RedLevel',
1927
 
            6 => 'WB_GreenLevel',
 
1933
            4 => 'WB_GRGBLevels',
 
1934
            5 => 'WB_RBLevels',
 
1935
            6 => 'WBRedLevel',
 
1936
            7 => 'WBGreenLevel',
1928
1937
        },
1929
1938
        ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(0,@val)',
1930
1939
        PrintConv => 'int($val * 1e6 + 0.5) * 1e-6',
1936
1945
            1 => 'WB_RGBGLevels',
1937
1946
            2 => 'WB_RBGGLevels',
1938
1947
            3 => 'WB_GRBGLevels',
1939
 
            4 => 'WB_RBLevels',
1940
 
            5 => 'WB_BlueLevel',
1941
 
            6 => 'WB_GreenLevel',
 
1948
            4 => 'WB_GRGBLevels',
 
1949
            5 => 'WB_RBLevels',
 
1950
            6 => 'WBBlueLevel',
 
1951
            7 => 'WBGreenLevel',
1942
1952
        },
1943
1953
        ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(1,@val)',
1944
1954
        PrintConv => 'int($val * 1e6 + 0.5) * 1e-6',
2153
2163
 
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)
2164
2175
);
2165
2176
sub RedBlueBalance($@)
2279
2290
        $image = $exifTool->ExtractBinary($offset, $len, $tag);
2280
2291
        return undef unless defined $image;
2281
2292
    }
2282
 
    $exifTool->HtmlDump($offset, $len, "$tag data", undef, 8);
2283
2293
    return $exifTool->ValidateImage(\$image, $tag);
2284
2294
}
2285
2295
 
2379
2389
            my $hdrLen = $dirStart + $dataPos + $base - $makerAddr;
2380
2390
            $exifTool->HtmlDump($makerAddr, $hdrLen, "MakerNotes header", $name) if $hdrLen > 0;
2381
2391
        }
2382
 
        my $str = "$name entry count";
2383
2392
        $exifTool->HtmlDump($dirStart + $dataPos + $base, 2, "$name entries",
2384
2393
                 "Entry count: $numEntries");
2385
2394
        my $tip;
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
2408
2417
            next;
2409
2418
        }
 
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;
2459
2469
                    }
2460
2470
                    $tagStr or $tagStr = sprintf("tag 0x%x",$tagID);
2480
2490
                }
2481
2491
            }
2482
2492
        }
2483
 
        my $formatStr = $formatName[$format];   # get name of this format
2484
2493
        # treat single unknown byte as int8u
2485
2494
        $formatStr = 'int8u' if $format == 7 and $count == 1;
2486
2495
 
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);
2512
2521
        }
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};
2805
 
                } else {
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,
2810
2819
                        Base       => $base,
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;