File Coverage

blib/lib/Image/ExifTool/HP.pm
Criterion Covered Total %
statement 9 57 15.7
branch 0 22 0.0
condition 0 20 0.0
subroutine 3 5 60.0
pod 0 2 0.0
total 12 106 11.3


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             # File: HP.pm
3             #
4             # Description: Hewlett-Packard maker notes tags
5             #
6             # Revisions: 2007-05-03 - P. Harvey Created
7             #------------------------------------------------------------------------------
8              
9             package Image::ExifTool::HP;
10              
11 26     26   157 use strict;
  26         51  
  26         708  
12 26     26   126 use vars qw($VERSION);
  26         51  
  26         841  
13 26     26   137 use Image::ExifTool qw(:DataAccess :Utils);
  26         49  
  26         23844  
14              
15             $VERSION = '1.04';
16              
17             sub ProcessHP($$$);
18             sub ProcessTDHD($$$);
19              
20             # HP EXIF-format maker notes (or is it Vivitar?)
21             %Image::ExifTool::HP::Main = (
22             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
23             NOTES => q{
24             These tables list tags found in the maker notes of some Hewlett-Packard
25             camera models.
26              
27             The first table lists tags found in the EXIF-format maker notes of the
28             PhotoSmart 720 (also used by the Vivitar ViviCam 3705, 3705B and 3715).
29             },
30             0x0e00 => {
31             Name => 'PrintIM',
32             Description => 'Print Image Matching',
33             SubDirectory => {
34             TagTable => 'Image::ExifTool::PrintIM::Main',
35             },
36             },
37             );
38              
39             # other types of HP maker notes
40             %Image::ExifTool::HP::Type2 = (
41             PROCESS_PROC => \&ProcessHP,
42             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
43             NOTES => 'These tags are used by the PhotoSmart E427.',
44             'PreviewImage' => {
45             Name => 'PreviewImage',
46             Groups => { 2 => 'Preview' },
47             RawConv => '$self->ValidateImage(\$val,$tag)',
48             },
49             'Serial Number' => 'SerialNumber',
50             'Lens Shading' => 'LensShading',
51             );
52              
53             %Image::ExifTool::HP::Type4 = (
54             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
55             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
56             NOTES => 'These tags are used by the PhotoSmart M627.',
57             0x0c => {
58             Name => 'MaxAperture',
59             Format => 'int16u',
60             ValueConv => '$val / 10',
61             },
62             0x10 => {
63             Name => 'ExposureTime',
64             Format => 'int32u',
65             ValueConv => '$val / 1e6',
66             PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
67             },
68             0x14 => {
69             Name => 'CameraDateTime',
70             Groups => { 2 => 'Time' },
71             Format => 'string[20]',
72             },
73             0x34 => {
74             Name => 'ISO',
75             Format => 'int16u',
76             },
77             0x5c => {
78             Name => 'SerialNumber',
79             Format => 'string[26]',
80             RawConv => '$val =~ s/^SERIAL NUMBER:// ? $val : undef',
81             },
82             );
83              
84             %Image::ExifTool::HP::Type6 = (
85             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
86             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
87             NOTES => 'These tags are used by the PhotoSmart M425, M525 and M527.',
88             0x0c => {
89             Name => 'FNumber',
90             Format => 'int16u',
91             ValueConv => '$val / 10',
92             },
93             0x10 => {
94             Name => 'ExposureTime',
95             Format => 'int32u',
96             ValueConv => '$val / 1e6',
97             PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
98             },
99             0x14 => {
100             Name => 'CameraDateTime',
101             Groups => { 2 => 'Time' },
102             Format => 'string[20]',
103             },
104             0x34 => {
105             Name => 'ISO',
106             Format => 'int16u',
107             },
108             0x58 => {
109             Name => 'SerialNumber',
110             Format => 'string[26]',
111             RawConv => '$val =~ s/^SERIAL NUMBER:// ? $val : undef',
112             },
113             );
114              
115             # proprietary format TDHD data written by Photosmart R837 (ref PH)
116             %Image::ExifTool::HP::TDHD = (
117             PROCESS_PROC => \&ProcessTDHD,
118             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
119             NOTES => q{
120             These tags are extracted from the APP6 "TDHD" segment of Photosmart R837
121             JPEG images. Many other unknown tags exist in is data, and can be seen with
122             the L (-u) option.
123             },
124             # (all subdirectories except TDHD and LSLV are automatically recognized
125             # by their "type" word of 0x10001)
126             TDHD => {
127             Name => 'TDHD',
128             SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
129             },
130             LSLV => {
131             Name => 'LSLV',
132             SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
133             },
134             FWRV => 'FirmwareVersion',
135             CMSN => 'SerialNumber', # (unverified)
136             # LTEM - some temperature?
137             );
138              
139             #------------------------------------------------------------------------------
140             # Process HP APP6 TDHD metadata (ref PH)
141             # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
142             # Returns: 1 on success
143             sub ProcessTDHD($$$)
144             {
145 0     0 0   my ($et, $dirInfo, $tagTablePtr) = @_;
146 0           my $dataPt = $$dirInfo{DataPt};
147 0           my $dataPos = $$dirInfo{DataPos};
148 0           my $pos = $$dirInfo{DirStart};
149 0           my $dirEnd = $pos + $$dirInfo{DirLen};
150 0   0       my $unknown = $et->Options('Unknown') || $et->Options('Verbose');
151 0           $et->VerboseDir('TDHD', undef, $$dirInfo{DirLen});
152 0           SetByteOrder('II');
153 0           while ($pos + 12 < $dirEnd) {
154 0           my $tag = substr($$dataPt, $pos, 4);
155 0           my $type = Get32u($dataPt, $pos + 4);
156 0           my $size = Get32u($dataPt, $pos + 8);
157 0           $pos += 12;
158 0 0 0       last if $size < 0 or $pos + $size > $dirEnd;
159 0 0         if ($type == 0x10001) {
160             # this is a subdirectory containing more tags
161 0           my %dirInfo = (
162             DataPt => $dataPt,
163             DataPos => $dataPos,
164             DirStart => $pos,
165             DirLen => $size,
166             );
167 0           $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
168             } else {
169 0 0 0       if (not $$tagTablePtr{$tag} and $unknown) {
170 0           my $name = $tag;
171 0           $name =~ tr/-_A-Za-z0-9//dc; # remove invalid characters
172 0           my %tagInfo = (
173             Name => "HP_TDHD_$name",
174             Unknown => 1,
175             );
176             # guess format based on data size
177 0 0         if ($size == 1) {
    0          
    0          
    0          
178 0           $tagInfo{Format} = 'int8u';
179             } elsif ($size == 2) {
180 0           $tagInfo{Format} = 'int16u';
181             } elsif ($size == 4) {
182 0           $tagInfo{Format} = 'int32s';
183             } elsif ($size > 80) {
184 0           $tagInfo{Binary} = 1;
185             }
186 0           AddTagToTable($tagTablePtr, $tag, \%tagInfo);
187             }
188 0           $et->HandleTag($tagTablePtr, $tag, undef,
189             DataPt => $dataPt,
190             DataPos => $dataPos,
191             Start => $pos,
192             Size => $size,
193             );
194             }
195 0           $pos += $size;
196             }
197 0           return 1;
198             }
199              
200             #------------------------------------------------------------------------------
201             # Process HP maker notes
202             # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
203             # Returns: 1 on success, otherwise returns 0 and sets a Warning
204             sub ProcessHP($$$)
205             {
206 0     0 0   my ($et, $dirInfo, $tagTablePtr) = @_;
207 0           my $dataPt = $$dirInfo{DataPt};
208 0           my $dataLen = $$dirInfo{DataLen};
209 0   0       my $dirStart = $$dirInfo{DirStart} || 0;
210 0   0       my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
211              
212             # look for known text-type tags
213 0 0 0       if ($dirStart or $dirLen != length($$dataPt)) {
214 0           my $buff = substr($$dataPt, $dirStart, $dirLen);
215 0           $dataPt = \$buff;
216             }
217 0           my $tagID;
218             # brute-force scan for PreviewImage
219 0 0 0       if ($$tagTablePtr{PreviewImage} and $$dataPt =~ /(\xff\xd8\xff\xdb.*\xff\xd9)/gs) {
220 0           $et->HandleTag($tagTablePtr, 'PreviewImage', $1);
221             # truncate preview to speed subsequent tag scans
222 0           my $buff = substr($$dataPt, 0, pos($$dataPt)-length($1));
223 0           $dataPt = \$buff;
224             }
225             # scan for other tag ID's
226 0           foreach $tagID (sort(TagTableKeys($tagTablePtr))) {
227 0 0         next if $tagID eq 'PreviewImage';
228 0 0         next unless $$dataPt =~ /$tagID:\s*([\x20-\x7f]+)/i;
229 0           $et->HandleTag($tagTablePtr, $tagID, $1);
230             }
231 0           return 1;
232             }
233              
234             1; # end
235              
236             __END__