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 | use strict;
|
---|
12 | use vars qw($VERSION);
|
---|
13 | use Image::ExifTool qw(:DataAccess :Utils);
|
---|
14 |
|
---|
15 | $VERSION = '1.02';
|
---|
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 | RawConv => '$self->ValidateImage(\$val,$tag)',
|
---|
47 | },
|
---|
48 | 'Serial Number' => 'SerialNumber',
|
---|
49 | 'Lens Shading' => 'LensShading',
|
---|
50 | );
|
---|
51 |
|
---|
52 | %Image::ExifTool::HP::Type4 = (
|
---|
53 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
54 | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
---|
55 | NOTES => 'These tags are used by the PhotoSmart M627.',
|
---|
56 | 0x0c => {
|
---|
57 | Name => 'MaxAperture',
|
---|
58 | Format => 'int16u',
|
---|
59 | ValueConv => '$val / 10',
|
---|
60 | },
|
---|
61 | 0x10 => {
|
---|
62 | Name => 'ExposureTime',
|
---|
63 | Format => 'int32u',
|
---|
64 | ValueConv => '$val / 1e6',
|
---|
65 | PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
---|
66 | },
|
---|
67 | 0x14 => {
|
---|
68 | Name => 'CameraDateTime',
|
---|
69 | Groups => { 2 => 'Time' },
|
---|
70 | Format => 'string[20]',
|
---|
71 | },
|
---|
72 | 0x34 => {
|
---|
73 | Name => 'ISO',
|
---|
74 | Format => 'int16u',
|
---|
75 | },
|
---|
76 | 0x5c => {
|
---|
77 | Name => 'SerialNumber',
|
---|
78 | Format => 'string[26]',
|
---|
79 | RawConv => '$val =~ s/^SERIAL NUMBER:// ? $val : undef',
|
---|
80 | },
|
---|
81 | );
|
---|
82 |
|
---|
83 | %Image::ExifTool::HP::Type6 = (
|
---|
84 | PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
---|
85 | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
---|
86 | NOTES => 'These tags are used by the PhotoSmart M425, M525 and M527.',
|
---|
87 | 0x0c => {
|
---|
88 | Name => 'FNumber',
|
---|
89 | Format => 'int16u',
|
---|
90 | ValueConv => '$val / 10',
|
---|
91 | },
|
---|
92 | 0x10 => {
|
---|
93 | Name => 'ExposureTime',
|
---|
94 | Format => 'int32u',
|
---|
95 | ValueConv => '$val / 1e6',
|
---|
96 | PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
|
---|
97 | },
|
---|
98 | 0x14 => {
|
---|
99 | Name => 'CameraDateTime',
|
---|
100 | Groups => { 2 => 'Time' },
|
---|
101 | Format => 'string[20]',
|
---|
102 | },
|
---|
103 | 0x34 => {
|
---|
104 | Name => 'ISO',
|
---|
105 | Format => 'int16u',
|
---|
106 | },
|
---|
107 | 0x58 => {
|
---|
108 | Name => 'SerialNumber',
|
---|
109 | Format => 'string[26]',
|
---|
110 | RawConv => '$val =~ s/^SERIAL NUMBER:// ? $val : undef',
|
---|
111 | },
|
---|
112 | );
|
---|
113 |
|
---|
114 | # proprietary format TDHD data written by Photosmart R837 (ref PH)
|
---|
115 | %Image::ExifTool::HP::TDHD = (
|
---|
116 | PROCESS_PROC => \&ProcessTDHD,
|
---|
117 | GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
|
---|
118 | NOTES => q{
|
---|
119 | These tags are extracted from the APP6 "TDHD" segment of Photosmart R837
|
---|
120 | JPEG images. Many other unknown tags exist in is data, and can be seen with
|
---|
121 | the Unknown (-u) option.
|
---|
122 | },
|
---|
123 | # (all subdirectories except TDHD and LSLV are automatically recognized
|
---|
124 | # by their "type" word of 0x10001)
|
---|
125 | TDHD => {
|
---|
126 | Name => 'TDHD',
|
---|
127 | SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
|
---|
128 | },
|
---|
129 | LSLV => {
|
---|
130 | Name => 'LSLV',
|
---|
131 | SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
|
---|
132 | },
|
---|
133 | FWRV => 'FirmwareVersion',
|
---|
134 | CMSN => 'SerialNumber', # (unverified)
|
---|
135 | # LTEM - some temperature?
|
---|
136 | );
|
---|
137 |
|
---|
138 | #------------------------------------------------------------------------------
|
---|
139 | # Process HP APP6 TDHD metadata (ref PH)
|
---|
140 | # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
---|
141 | # Returns: 1 on success
|
---|
142 | sub ProcessTDHD($$$)
|
---|
143 | {
|
---|
144 | my ($exifTool, $dirInfo, $tagTablePtr) = @_;
|
---|
145 | my $dataPt = $$dirInfo{DataPt};
|
---|
146 | my $dataPos = $$dirInfo{DataPos};
|
---|
147 | my $pos = $$dirInfo{DirStart};
|
---|
148 | my $dirEnd = $pos + $$dirInfo{DirLen};
|
---|
149 | my $unknown = $exifTool->Options('Unknown') || $exifTool->Options('Verbose');
|
---|
150 | $exifTool->VerboseDir('TDHD', undef, $$dirInfo{DirLen});
|
---|
151 | SetByteOrder('II');
|
---|
152 | while ($pos + 12 < $dirEnd) {
|
---|
153 | my $tag = substr($$dataPt, $pos, 4);
|
---|
154 | my $type = Get32u($dataPt, $pos + 4);
|
---|
155 | my $size = Get32u($dataPt, $pos + 8);
|
---|
156 | $pos += 12;
|
---|
157 | last if $size < 0 or $pos + $size > $dirEnd;
|
---|
158 | if ($type == 0x10001) {
|
---|
159 | # this is a subdirectory containing more tags
|
---|
160 | my %dirInfo = (
|
---|
161 | DataPt => $dataPt,
|
---|
162 | DataPos => $dataPos,
|
---|
163 | DirStart => $pos,
|
---|
164 | DirLen => $size,
|
---|
165 | );
|
---|
166 | $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
---|
167 | } else {
|
---|
168 | if (not $$tagTablePtr{$tag} and $unknown) {
|
---|
169 | my $name = $tag;
|
---|
170 | $name =~ tr/-_A-Za-z0-9//dc; # remove invalid characters
|
---|
171 | my %tagInfo = (
|
---|
172 | Name => "HP_TDHD_$name",
|
---|
173 | Unknown => 1,
|
---|
174 | );
|
---|
175 | # guess format based on data size
|
---|
176 | if ($size == 1) {
|
---|
177 | $tagInfo{Format} = 'int8u';
|
---|
178 | } elsif ($size == 2) {
|
---|
179 | $tagInfo{Format} = 'int16u';
|
---|
180 | } elsif ($size == 4) {
|
---|
181 | $tagInfo{Format} = 'int32s';
|
---|
182 | } elsif ($size > 80) {
|
---|
183 | $tagInfo{Binary} = 1;
|
---|
184 | }
|
---|
185 | Image::ExifTool::AddTagToTable($tagTablePtr, $tag, \%tagInfo);
|
---|
186 | }
|
---|
187 | $exifTool->HandleTag($tagTablePtr, $tag, undef,
|
---|
188 | DataPt => $dataPt,
|
---|
189 | DataPos => $dataPos,
|
---|
190 | Start => $pos,
|
---|
191 | Size => $size,
|
---|
192 | );
|
---|
193 | }
|
---|
194 | $pos += $size;
|
---|
195 | }
|
---|
196 | return 1;
|
---|
197 | }
|
---|
198 |
|
---|
199 | #------------------------------------------------------------------------------
|
---|
200 | # Process HP maker notes
|
---|
201 | # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
---|
202 | # Returns: 1 on success, otherwise returns 0 and sets a Warning
|
---|
203 | sub ProcessHP($$$)
|
---|
204 | {
|
---|
205 | my ($exifTool, $dirInfo, $tagTablePtr) = @_;
|
---|
206 | my $dataPt = $$dirInfo{DataPt};
|
---|
207 | my $dataLen = $$dirInfo{DataLen};
|
---|
208 | my $dirStart = $$dirInfo{DirStart} || 0;
|
---|
209 | my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
|
---|
210 |
|
---|
211 | # look for known text-type tags
|
---|
212 | if ($dirStart or $dirLen != length($$dataPt)) {
|
---|
213 | my $buff = substr($$dataPt, $dirStart, $dirLen);
|
---|
214 | $dataPt = \$buff;
|
---|
215 | }
|
---|
216 | my $tagID;
|
---|
217 | # brute-force scan for PreviewImage
|
---|
218 | if ($$tagTablePtr{PreviewImage} and $$dataPt =~ /(\xff\xd8\xff\xdb.*\xff\xd9)/gs) {
|
---|
219 | $exifTool->HandleTag($tagTablePtr, 'PreviewImage', $1);
|
---|
220 | # truncate preview to speed subsequent tag scans
|
---|
221 | my $buff = substr($$dataPt, 0, pos($$dataPt)-length($1));
|
---|
222 | $dataPt = \$buff;
|
---|
223 | }
|
---|
224 | # scan for other tag ID's
|
---|
225 | foreach $tagID (sort(TagTableKeys($tagTablePtr))) {
|
---|
226 | next if $tagID eq 'PreviewImage';
|
---|
227 | next unless $$dataPt =~ /$tagID:\s*([\x20-\x7f]+)/i;
|
---|
228 | $exifTool->HandleTag($tagTablePtr, $tagID, $1);
|
---|
229 | }
|
---|
230 | return 1;
|
---|
231 | }
|
---|
232 |
|
---|
233 | 1; # end
|
---|
234 |
|
---|
235 | __END__
|
---|
236 |
|
---|
237 | =head1 NAME
|
---|
238 |
|
---|
239 | Image::ExifTool::HP - Hewlett-Packard maker notes tags
|
---|
240 |
|
---|
241 | =head1 SYNOPSIS
|
---|
242 |
|
---|
243 | This module is loaded automatically by Image::ExifTool when required.
|
---|
244 |
|
---|
245 | =head1 DESCRIPTION
|
---|
246 |
|
---|
247 | This module contains definitions required by Image::ExifTool to interpret
|
---|
248 | Hewlett-Packard maker notes.
|
---|
249 |
|
---|
250 | =head1 AUTHOR
|
---|
251 |
|
---|
252 | Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
|
---|
253 |
|
---|
254 | This library is free software; you can redistribute it and/or modify it
|
---|
255 | under the same terms as Perl itself.
|
---|
256 |
|
---|
257 | =head1 SEE ALSO
|
---|
258 |
|
---|
259 | L<Image::ExifTool::TagNames/HP Tags>,
|
---|
260 | L<Image::ExifTool(3pm)|Image::ExifTool>
|
---|
261 |
|
---|
262 | =cut
|
---|