File Coverage

blib/lib/Image/ExifTool/Reconyx.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             # File: Reconyx.pm
3             #
4             # Description: Reconyx maker notes tags
5             #
6             # Revisions: 2011-01-11 - P. Harvey Created
7             #
8             # References: 1) RCNX_MN10.pdf (courtesy of Reconyx Inc.)
9             # 2) ultrafire_makernote.pdf (courtesy of Reconyx Inc.)
10             # 3) Reconyx private communication
11             # 4) "Reconyx Metadata 1_4.pdf"
12             #------------------------------------------------------------------------------
13              
14             package Image::ExifTool::Reconyx;
15              
16 14     14   109 use strict;
  14         52  
  14         697  
17 14     14   133 use vars qw($VERSION);
  14         30  
  14         22589  
18              
19             $VERSION = '1.07';
20              
21             # info for Type2 version tags
22             my %versionInfo = (
23             Format => 'undef[7]',
24             ValueConv => 'sprintf("%.2x.%.2x %.4x:%.2x:%.2x Rev.%s", unpack("CCvCCa", $val))',
25             ValueConvInv => q{
26             my @v = $val =~ /^([0-9a-f]+)\.([0-9a-f]+) (\d{4}):(\d{2}):(\d{2})\s*Rev\.(\w)/i or return undef;
27             pack('CCvCCa', map(hex, @v[0..4]), $v[5]);
28             },
29             );
30              
31             my %moonPhase = (
32             0 => 'New',
33             1 => 'New Crescent',
34             2 => 'First Quarter',
35             3 => 'Waxing Gibbous',
36             4 => 'Full',
37             5 => 'Waning Gibbous',
38             6 => 'Last Quarter',
39             7 => 'Old Crescent',
40             );
41              
42             my %sunday0 = (
43             0 => 'Sunday',
44             1 => 'Monday',
45             2 => 'Tuesday',
46             3 => 'Wednesday',
47             4 => 'Thursday',
48             5 => 'Friday',
49             6 => 'Saturday',
50             );
51              
52             my %sunday1 = (
53             1 => 'Sunday',
54             2 => 'Monday',
55             3 => 'Tuesday',
56             4 => 'Wednesday',
57             5 => 'Thursday',
58             6 => 'Friday',
59             7 => 'Saturday',
60             );
61              
62             my %convUnicode = (
63             ValueConv => '$self->Decode($val, "UCS2", "II")',
64             ValueConvInv => '$self->Encode($val, "UCS2", "II")',
65             );
66              
67             # maker notes for Reconyx HyperFire cameras (ref PH)
68             %Image::ExifTool::Reconyx::HyperFire = (
69             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
70             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
71             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
72             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
73             TAG_PREFIX => 'Reconyx',
74             FORMAT => 'int16u',
75             WRITABLE => 1,
76             FIRST_ENTRY => 0,
77             NOTES => q{
78             The following tags are extracted from the maker notes of Reconyx RapidFire
79             and HyperFire models such as the HC500, HC600 and PC900.
80             },
81             0x00 => { #1
82             Name => 'MakerNoteVersion',
83             Writable => 0, # (we use this for identification, 0xf101 --> rev 1.0)
84             PrintConv => 'sprintf("0x%.4x", $val)',
85             PrintConvInv => 'hex $val',
86             },
87             0x01 => { #1
88             Name => 'FirmwareVersion',
89             Format => 'int16u[3]',
90             Writable => 0, # (we use this for identification, 0x0003 --> ver 2 or 3)
91             PrintConv => '$val=~tr/ /./; $val',
92             },
93             0x04 => { #1
94             Name => 'FirmwareDate',
95             Format => 'int16u[2]',
96             ValueConv => q{
97             my @v = split(' ',$val);
98             sprintf('%.4x:%.2x:%.2x', $v[0], $v[1]>>8, $v[1]&0xff);
99             },
100             ValueConvInv => q{
101             my @v = split(':', $val);
102             hex($v[0]) . ' ' . hex($v[1] . $v[2]);
103             },
104             },
105             0x06 => {
106             Name => 'TriggerMode',
107             Format => 'string[2]',
108             PrintConv => {
109             C => 'CodeLoc Not Entered', #1
110             E => 'External Sensor', #1
111             M => 'Motion Detection',
112             T => 'Time Lapse',
113             },
114             },
115             0x07 => {
116             Name => 'Sequence',
117             Format => 'int16u[2]',
118             PrintConv => '$val =~ s/ / of /; $val',
119             PrintConvInv => 'join(" ", $val=~/\d+/g)',
120             },
121             0x09 => { #1
122             Name => 'EventNumber',
123             Format => 'int16u[2]',
124             ValueConv => 'my @v=split(" ",$val); ($v[0]<<16) + $v[1]',
125             ValueConvInv => '($val>>16) . " " . ($val&0xffff)',
126             },
127             0x0b => {
128             Name => 'DateTimeOriginal',
129             Description => 'Date/Time Original',
130             Format => 'int16u[6]',
131             Groups => { 2 => 'Time' },
132             Priority => 0, # (not as reliable as EXIF)
133             Shift => 'Time',
134             ValueConv => q{
135             my @a = split ' ', $val;
136             # have seen these values written big-endian when everything else is little-endian
137             if ($a[0] & 0xff00 and not $a[0] & 0xff) {
138             $_ = ($_ >> 8) | (($_ & 0xff) << 8) foreach @a;
139             }
140             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @a[5,3,4,2,1,0]);
141             },
142             ValueConvInv => q{
143             my @a = ($val =~ /\d+/g);
144             return undef unless @a >= 6;
145             join ' ', @a[5,4,3,1,2,0];
146             },
147             PrintConv => '$self->ConvertDateTime($val)',
148             PrintConvInv => '$self->InverseDateTime($val)',
149             },
150             0x12 => {
151             Name => 'MoonPhase',
152             Groups => { 2 => 'Time' },
153             PrintConv => \%moonPhase,
154             },
155             0x13 => {
156             Name => 'AmbientTemperatureFahrenheit',
157             Format => 'int16s',
158             PrintConv => '"$val F"',
159             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
160             },
161             0x14 => {
162             Name => 'AmbientTemperature',
163             Format => 'int16s',
164             PrintConv => '"$val C"',
165             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
166             },
167             0x15 => { Name => 'SerialNumber', Format => 'unicode[15]', %convUnicode },
168             0x24 => 'Contrast', #1
169             0x25 => 'Brightness', #1
170             0x26 => 'Sharpness', #1
171             0x27 => 'Saturation', #1
172             0x28 => {
173             Name => 'InfraredIlluminator',
174             PrintConv => { 0 => 'Off', 1 => 'On' },
175             },
176             0x29 => 'MotionSensitivity', #1
177             0x2a => { #1
178             Name => 'BatteryVoltage',
179             ValueConv => '$val / 1000',
180             ValueConvInv => '$val * 1000',
181             PrintConv => '"$val V"',
182             PrintConvInv => '$val=~s/ ?V$//; $val',
183             },
184             0x2b => {
185             Name => 'UserLabel',
186             Format => 'string[22]', #1 (but manual says 16-char limit)
187             },
188             );
189              
190             # maker notes for Reconyx UltraFire cameras (ref PH)
191             %Image::ExifTool::Reconyx::UltraFire = (
192             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
193             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
194             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
195             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
196             TAG_PREFIX => 'Reconyx',
197             WRITABLE => 1,
198             FIRST_ENTRY => 0,
199             NOTES => 'Maker notes tags for Reconyx UltraFire models.',
200             # 0x0a - int32u makernote ID 0x00020000 #2
201             # 0x0e - int16u makernote size #2
202             # 0x12 - int32u public structure ID 0x07f100001 #2
203             # 0x16 - int16u public structure size #2 (0x5d = start of public ID to end of UserLabel)
204             0x18 => { Name => 'FirmwareVersion', %versionInfo },
205             0x1f => { Name => 'Micro1Version', %versionInfo }, #2
206             0x26 => { Name => 'BootLoaderVersion', %versionInfo }, #2
207             0x2d => { Name => 'Micro2Version', %versionInfo }, #2
208             0x34 => {
209             Name => 'TriggerMode',
210             Format => 'undef[1]',
211             PrintConv => {
212             M => 'Motion Detection',
213             T => 'Time Lapse',
214             P => 'Point and Shoot', #2
215             },
216             },
217             0x35 => {
218             Name => 'Sequence',
219             Format => 'int8u[2]',
220             PrintConv => '$val =~ s/ / of /; $val',
221             PrintConvInv => 'join(" ", $val=~/\d+/g)',
222             },
223             0x37 => { #2
224             Name => 'EventNumber',
225             Format => 'int32u',
226             },
227             0x3b => {
228             Name => 'DateTimeOriginal',
229             Description => 'Date/Time Original',
230             Format => 'int8u[7]',
231             Groups => { 2 => 'Time' },
232             Priority => 0, # (not as reliable as EXIF)
233             Shift => 'Time',
234             ValueConv => 'sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d", reverse unpack("C5v",$val))',
235             ValueConvInv => q{
236             my @a = ($val =~ /\d+/g);
237             return undef unless @a >= 6;
238             pack('C5v', @a[5,4,3,2,1,0]);
239             },
240             PrintConv => '$self->ConvertDateTime($val)',
241             PrintConvInv => '$self->InverseDateTime($val)',
242             },
243             0x42 => { #2
244             Name => 'DayOfWeek',
245             Groups => { 2 => 'Time' },
246             PrintConv => \%sunday0,
247             },
248             0x43 => {
249             Name => 'MoonPhase',
250             Groups => { 2 => 'Time' },
251             PrintConv => \%moonPhase,
252             },
253             0x44 => {
254             Name => 'AmbientTemperatureFahrenheit',
255             Format => 'int16s',
256             PrintConv => '"$val F"',
257             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
258             },
259             0x46 => {
260             Name => 'AmbientTemperature',
261             Format => 'int16s',
262             PrintConv => '"$val C"',
263             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
264             },
265             0x48 => {
266             Name => 'Illumination',
267             PrintConv => { 0 => 'Off', 1 => 'On' },
268             },
269             0x49 => {
270             Name => 'BatteryVoltage',
271             Format => 'int16u',
272             ValueConv => '$val / 1000',
273             ValueConvInv => '$val * 1000',
274             PrintConv => '"$val V"',
275             PrintConvInv => '$val=~s/ ?V$//; $val',
276             },
277             0x4b => { Name => 'SerialNumber', Format => 'string[15]' },
278             0x5a => { Name => 'UserLabel', Format => 'string[21]' },
279             );
280              
281             # maker notes for Reconyx HF2 PRO cameras (ref 3)
282             %Image::ExifTool::Reconyx::HyperFire2 = (
283             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
284             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
285             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
286             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
287             TAG_PREFIX => 'Reconyx',
288             WRITABLE => 1,
289             FIRST_ENTRY => 0,
290             NOTES => 'Maker notes tags for Reconyx HyperFire 2 models.',
291             # 0x0a => { Name => 'StructureVersion', Format => 'int16u' },
292             # 0x0c => { Name => 'ParentFileSize', Format => 'int32u' },
293             0x10 => { Name => 'FileNumber', Format => 'int16u' },
294             0x12 => { Name => 'DirectoryNumber', Format => 'int16u' },
295             0x14 => {
296             Name => 'DirectoryCreateDate',
297             Format => 'int16u[2]',
298             Groups => { 2 => 'Time' },
299             Shift => 'Time',
300             # similar to ZIP date/time, but date word comes first
301             ValueConv => q{
302             my @a = split / /, $val;
303             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d',
304             ($a[0] >> 9) + 1980, # year
305             ($a[0] >> 5) & 0x0f, # month
306             $a[0] & 0x1f, # day
307             ($a[1] >> 11) & 0x1f, # hour
308             ($a[1] >> 5) & 0x3f, # minute
309             ($a[1] & 0x1f) * 2 # second
310             );
311             },
312             ValueConvInv => q{
313             my @a = $val =~ /\d+/g;
314             sprintf('%d %d', (($a[0]-1980) << 9) | ($a[1] << 5) | $a[2],
315             ($a[3] << 11) | ($a[4] << 5) | int($a[5] / 2));
316             },
317             PrintConv => '$self->ConvertDateTime($val)',
318             PrintConvInv => '$self->InverseDateTime($val)',
319             },
320             # 0x18 - int16[8] SDCardLabel
321             # 0x28 => { Name => 'MakerNoteVersion', Format => 'int16u' },
322             0x2a => {
323             Name => 'FirmwareVersion',
324             Format => 'int16u[3]',
325             ValueConv => 'my @a = split " ",$val; sprintf("%d.%d%c",@a)',
326             ValueConvInv => '$val=~/(\d+)\.(\d+)([a-zA-Z])/ ? "$1 $2 ".ord($3) : undef',
327             },
328             0x30 => {
329             Name => 'FirmwareDate',
330             Format => 'int16u[2]',
331             ValueConv => 'my ($y,$d) = split " ", $val; sprintf("%.4x:%.2x:%.2x",$y,$d>>8,$d&0xff)',
332             ValueConvInv => 'my @a=split ":", $val; hex($a[0])." ".hex($a[1].$a[2])',
333             },
334             0x34 => {
335             Name => 'TriggerMode', #PH (NC) (called EventType in the Reconyx code)
336             Format => 'string[2]',
337             PrintConv => {
338             M => 'Motion Detection', # (seen this one only)
339             T => 'Time Lapse', # (NC)
340             P => 'Point and Shoot', # (NC)
341             },
342             },
343             0x36 => {
344             Name => 'Sequence',
345             Format => 'int16u[2]',
346             PrintConv => '$val =~ s/ / of /; $val',
347             PrintConvInv => 'join(" ", $val=~/\d+/g)',
348             },
349             0x3a => {
350             Name => 'EventNumber',
351             Format => 'int16u[2]',
352             ValueConv => 'my @a=split " ",$val;($a[0]<<16)+$a[1]',
353             ValueConvInv => '($val >> 16) . " " . ($val & 0xffff)',
354             },
355             0x3e => {
356             Name => 'DateTimeOriginal',
357             Description => 'Date/Time Original',
358             Format => 'int16u[6]',
359             Groups => { 2 => 'Time' },
360             Priority => 0, # (not as reliable as EXIF)
361             Shift => 'Time',
362             ValueConv => q{
363             my @a = split ' ', $val;
364             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', reverse @a);
365             },
366             ValueConvInv => q{
367             my @a = ($val =~ /\d+/g);
368             return undef unless @a >= 6;
369             join ' ', @a[5,4,3,2,1,0];
370             },
371             PrintConv => '$self->ConvertDateTime($val)',
372             PrintConvInv => '$self->InverseDateTime($val)',
373             },
374             0x4a => { #2
375             Name => 'DayOfWeek',
376             Groups => { 2 => 'Time' },
377             Format => 'int16u',
378             PrintConv => \%sunday0,
379             },
380             0x4c => {
381             Name => 'MoonPhase',
382             Groups => { 2 => 'Time' },
383             Format => 'int16u',
384             PrintConv => \%moonPhase,
385             },
386             0x4e => {
387             Name => 'AmbientTemperatureFahrenheit',
388             Format => 'int16s',
389             PrintConv => '"$val F"',
390             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
391             },
392             0x50 => {
393             Name => 'AmbientTemperature',
394             Format => 'int16s',
395             PrintConv => '"$val C"',
396             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
397             },
398             0x52 => { Name => 'Contrast', Format => 'int16u' },
399             0x54 => { Name => 'Brightness', Format => 'int16u' },
400             0x56 => { Name => 'Sharpness', Format => 'int16u' },
401             0x58 => { Name => 'Saturation', Format => 'int16u' },
402             0x5a => { Name => 'Flash', Format => 'int16u', PrintConv => { 0 => 'Off', 1 => 'On' } },
403             0x5c => { Name => 'AmbientInfrared', Format => 'int16u' },
404             0x5e => { Name => 'AmbientLight', Format => 'int16u' },
405             0x60 => { Name => 'MotionSensitivity', Format => 'int16u' },
406             0x62 => { Name => 'BatteryVoltage', Format => 'int16u' },
407             0x64 => { Name => 'BatteryVoltageAvg', Format => 'int16u' },
408             0x66 => { Name => 'BatteryType', Format => 'int16u' },
409             0x68 => { Name => 'UserLabel', Format => 'string[22]' },
410             0x7e => { Name => 'SerialNumber', Format => 'unicode[15]', %convUnicode },
411             );
412              
413             # maker notes for Reconyx MicroFire cameras (ref 4) (no samples for testing)
414             %Image::ExifTool::Reconyx::MicroFire = (
415             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
416             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
417             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
418             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
419             TAG_PREFIX => 'Reconyx',
420             WRITABLE => 1,
421             FIRST_ENTRY => 0,
422             NOTES => 'Maker notes tags for Reconyx MicroFire cameras.',
423             0x10 => { Name => 'FileNumber', Format => 'int16u' },
424             0x12 => { Name => 'DirectoryNumber', Format => 'int16u' },
425             0x14 => {
426             Name => 'DirectoryCreateDate',
427             Format => 'int16u[2]',
428             Groups => { 2 => 'Time' },
429             Shift => 'Time',
430             # similar to ZIP date/time, but date word comes first
431             ValueConv => q{
432             my @a = split / /, $val;
433             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d',
434             ($a[0] >> 9) + 1980, # year
435             ($a[0] >> 5) & 0x0f, # month
436             $a[0] & 0x1f, # day
437             ($a[1] >> 11) & 0x1f, # hour
438             ($a[1] >> 5) & 0x3f, # minute
439             ($a[1] & 0x1f) * 2 # second
440             );
441             },
442             ValueConvInv => q{
443             my @a = $val =~ /\d+/g;
444             sprintf('%d %d', (($a[0]-1980) << 9) | ($a[1] << 5) | $a[2],
445             ($a[3] << 11) | ($a[4] << 5) | int($a[5]/2));
446             },
447             PrintConv => '$self->ConvertDateTime($val)',
448             PrintConvInv => '$self->InverseDateTime($val)',
449             },
450             0x18 => {
451             Name => 'SDCardID',
452             Format => 'int16u[8]',
453             PrintConv => 'join "-", map sprintf("%.4x",$_), split / /, $val',
454             },
455             # 0x28 - INFO structure version
456             0x2a => {
457             Name => 'FirmwareVersion',
458             Format => 'int16u[3]',
459             ValueConv => 'my @a = split " ",$val; sprintf("%d.%d%c",@a)',
460             ValueConvInv => '$val=~/(\d+)\.(\d+)([a-zA-Z])/ ? "$1 $2 ".ord($3) : undef',
461             },
462             0x30 => {
463             Name => 'FirmwareDate',
464             Format => 'int16u[2]',
465             ValueConv => 'my ($y,$d) = split " ", $val; sprintf("%.4x:%.2x:%.2x",$y,$d>>8,$d&0xff)',
466             ValueConvInv => 'my @a=split ":", $val; hex($a[0])." ".hex($a[1].$a[2])',
467             },
468             0x34 => {
469             Name => 'BluetoothFirmwareVersion',
470             Format => 'int16u[3]',
471             ValueConv => 'my @a = split " ",$val; sprintf("%d.%d%c",@a)',
472             ValueConvInv => '$val=~/(\d+)\.(\d+)([a-zA-Z])/ ? "$1 $2 ".ord($3) : undef',
473             },
474             0x3a => {
475             Name => 'BluetoothFirmwareDate',
476             Format => 'int16u',
477             ValueConv => q{
478             sprintf('%.4d:%.2d:%.2d',
479             ($val >> 9) + 1980, # year
480             ($val >> 5) & 0x0f, # month
481             $val & 0x1f, # day
482             );
483             },
484             ValueConvInv => q{
485             my @a = $val =~ /\d+/g;
486             return (($a[0]-1980) << 9) | ($a[1] << 5) | $a[2];
487             },
488             },
489             0x3c => {
490             Name => 'WifiFirmwareVersion',
491             Format => 'int16u[3]',
492             ValueConv => 'my @a = split " ",$val; sprintf("%d.%d%c",@a)',
493             ValueConvInv => '$val=~/(\d+)\.(\d+)([a-zA-Z])/ ? "$1 $2 ".ord($3) : undef',
494             },
495             0x42 => {
496             Name => 'WifiFirmwareDate',
497             Format => 'int16u',
498             ValueConv => q{
499             sprintf('%.4d:%.2d:%.2d',
500             ($val >> 9) + 1980, # year
501             ($val >> 5) & 0x0f, # month
502             $val & 0x1f, # day
503             );
504             },
505             ValueConvInv => q{
506             my @a = $val =~ /\d+/g;
507             return (($a[0]-1980) << 9) | ($a[1] << 5) | $a[2];
508             },
509             },
510             0x44 => {
511             Name => 'TriggerMode',
512             Format => 'string[2]',
513             PrintConv => {
514             M => 'Motion Sensor',
515             E => 'External Sensor',
516             T => 'Time Lapse',
517             C => 'CodeLoc Not Entered',
518             },
519             },
520             0x46 => {
521             Name => 'Sequence',
522             Format => 'int16u[2]',
523             PrintConv => '$val =~ s/ / of /; $val',
524             PrintConvInv => 'join(" ", $val=~/\d+/g)',
525             },
526             0x4a => {
527             Name => 'EventNumber',
528             Format => 'int16u[2]',
529             ValueConv => 'my @a=split " ",$val;($a[0]<<16)+$a[1]',
530             ValueConvInv => '($val >> 16) . " " . ($val & 0xffff)',
531             },
532             0x4e => {
533             Name => 'DateTimeOriginal',
534             Description => 'Date/Time Original',
535             Format => 'int16u[6]',
536             Groups => { 2 => 'Time' },
537             Priority => 0, # (not as reliable as EXIF)
538             Shift => 'Time',
539             ValueConv => q{
540             my @a = split ' ', $val;
541             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @a[5,3,4,2,1,0]);
542             },
543             ValueConvInv => q{
544             my @a = ($val =~ /\d+/g);
545             return undef unless @a >= 6;
546             join ' ', @a[5,4,3,1,2,0];
547             },
548             PrintConv => '$self->ConvertDateTime($val)',
549             PrintConvInv => '$self->InverseDateTime($val)',
550             },
551             0x5a => {
552             Name => 'DayOfWeek',
553             Format => 'int16u',
554             Groups => { 2 => 'Time' },
555             PrintConv => \%sunday1,
556             },
557             0x5c => {
558             Name => 'MoonPhase',
559             Format => 'int16u',
560             Groups => { 2 => 'Time' },
561             PrintConv => \%moonPhase,
562             },
563             0x5e => {
564             Name => 'AmbientTemperatureFahrenheit',
565             Format => 'int16s',
566             PrintConv => '"$val F"',
567             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
568             },
569             0x60 => {
570             Name => 'AmbientTemperature',
571             Format => 'int16s',
572             PrintConv => '"$val C"',
573             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
574             },
575             0x62 => { Name => 'Contrast', Format => 'int16u' },
576             0x64 => { Name => 'Brightness', Format => 'int16u' },
577             0x66 => { Name => 'Sharpness', Format => 'int16u' },
578             0x68 => { Name => 'Saturation', Format => 'int16u' },
579             0x6a => { Name => 'Flash', Format => 'int8u', PrintConv => { 0 => 'Off', 1 => 'On' } },
580             0x6c => { Name => 'AmbientInfrared', Format => 'int16u' },
581             0x6e => { Name => 'AmbientLight', Format => 'int16u' },
582             0x70 => { Name => 'MotionSensitivity', Format => 'int16u' },
583             0x72 => { Name => 'BatteryVoltage', Format => 'int16u',
584             ValueConv => '$val / 1000', ValueConvInv => '$val * 1000',
585             },
586             0x74 => { Name => 'BatteryType', Format => 'int16u',
587             PrintConv => {
588             0 => 'Lithium',
589             1 => 'NiMH',
590             2 => 'Alkaline',
591             3 => 'Lead Acid',
592             },
593             },
594             0x76 => { Name => 'UserLabel', Format => 'string[22]' },
595             0x8c => { Name => 'SerialNumber', Format => 'unicode[15]', %convUnicode },
596             );
597              
598             # maker notes for Reconyx HyperFire 4K (ref 4)
599             %Image::ExifTool::Reconyx::HyperFire4K = (
600             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
601             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
602             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
603             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
604             TAG_PREFIX => 'Reconyx',
605             WRITABLE => 1,
606             FIRST_ENTRY => 0,
607             NOTES => 'Maker notes tags for Reconyx HyperFire 4K models.',
608             # 0x0c => { Name => 'AgregateStructureVersion', Format => 'int32u' },
609             # 0x10 => { Name => 'AgregateStructureSize', Format => 'int32u' },
610             # 0x14 => { Name => 'InfoStructureVersion', Format => 'int32u' },
611             # 0x18 => { Name => 'InfoStructureSize', Format => 'int16u' },
612             0x1a => { Name => 'FirmwareVersion', %versionInfo },
613             0x21 => { Name => 'UIBFirmwareVersion', %versionInfo },
614             0x28 => {
615             Name => 'TriggerMode',
616             Format => 'undef[1]',
617             PrintConv => {
618             M => 'Motion Sensor',
619             E => 'External Sensor',
620             T => 'Time Lapse',
621             C => 'CodeLoc Not Entered',
622             S => 'Cell Status',
623             L => 'Cell Live View',
624             },
625             },
626             0x29 => {
627             Name => 'Sequence',
628             Format => 'int8u[2]',
629             PrintConv => '$val =~ s/ / of /; $val',
630             PrintConvInv => 'join(" ", $val=~/\d+/g)',
631             },
632             0x2b => {
633             Name => 'EventNumber',
634             Format => 'int32u',
635             },
636             0x2f => {
637             Name => 'DateTimeOriginal',
638             Description => 'Date/Time Original',
639             Format => 'undef[7]',
640             Groups => { 2 => 'Time' },
641             Priority => 0, # (not as reliable as EXIF)
642             Shift => 'Time',
643             ValueConv => 'sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d", reverse unpack("C5v",$val))',
644             ValueConvInv => q{
645             my @a = ($val =~ /\d+/g);
646             return undef unless @a >= 6;
647             pack('C5v', @a[5,4,3,2,1,0]);
648             },
649             PrintConv => '$self->ConvertDateTime($val)',
650             PrintConvInv => '$self->InverseDateTime($val)',
651             },
652             0x36 => {
653             Name => 'DayOfWeek',
654             Groups => { 2 => 'Time' },
655             PrintConv => \%sunday1,
656             },
657             0x37 => {
658             Name => 'MoonPhase',
659             Groups => { 2 => 'Time' },
660             PrintConv => \%moonPhase,
661             },
662             0x38 => {
663             Name => 'AmbientTemperatureFahrenheit',
664             Format => 'int16s',
665             PrintConv => '"$val F"',
666             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
667             },
668             0x3a => {
669             Name => 'AmbientTemperature',
670             Format => 'int16s',
671             PrintConv => '"$val C"',
672             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
673             },
674             0x3c => { Name => 'Contrast', Format => 'int16u' },
675             0x3e => { Name => 'Brightness', Format => 'int16u' },
676             0x40 => { Name => 'Sharpness', Format => 'int16u' },
677             0x42 => { Name => 'Saturation', Format => 'int16u' },
678             0x44 => { Name => 'Flash', Format => 'int8u', PrintConv => { 0 => 'Off', 1 => 'On' } },
679             0x45 => { Name => 'AmbientLight', Format => 'int32u' },
680             0x49 => { Name => 'MotionSensitivity', Format => 'int16u' },
681             0x4b => { Name => 'BatteryVoltage', Format => 'int16u',
682             ValueConv => '$val / 1000', ValueConvInv => '$val * 1000',
683             },
684             0x4d => { Name => 'BatteryVoltageAvg', Format => 'int16u',
685             ValueConv => '$val / 1000', ValueConvInv => '$val * 1000',
686             },
687             0x4f => { Name => 'BatteryType', Format => 'int16u',
688             PrintConv => {
689             1 => 'NiMH',
690             2 => 'Lithium',
691             3 => 'External',
692             4 => 'SC10 Solar',
693             },
694             },
695             0x51 => { Name => 'UserLabel', Format => 'string[51]' },
696             0x84 => { Name => 'SerialNumber', Format => 'string[15]' },
697             0x93 => { Name => 'DirectoryNumber', Format => 'int16u' },
698             0x95 => { Name => 'FileNumber', Format => 'int16u' },
699             );
700              
701             __END__