| 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__ |