HP.pm 8.0 KB

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