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             #------------------------------------------------------------------------------
12              
13             package Image::ExifTool::Reconyx;
14              
15 14     14   118 use strict;
  14         52  
  14         560  
16 14     14   92 use vars qw($VERSION);
  14         52  
  14         10984  
17              
18             $VERSION = '1.06';
19              
20             # info for Type2 version tags
21             my %versionInfo = (
22             Format => 'undef[7]',
23             ValueConv => 'sprintf("V%.2x.%.2x %.4x:%.2x:%.2x Rev.%s", unpack("CCvCCa", $val))',
24             ValueConvInv => q{
25             my @v = $val =~ /^V([0-9a-f]+)\.([0-9a-f]+) (\d{4}):(\d{2}):(\d{2})\s*Rev\.(\w)/i or return undef;
26             pack('CCvCCa', map(hex, @v[0..4]), $v[5]);
27             },
28             );
29              
30             # maker notes for Reconyx Hyperfire cameras (ref PH)
31             %Image::ExifTool::Reconyx::Main = (
32             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
33             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
34             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
35             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
36             TAG_PREFIX => 'Reconyx',
37             FORMAT => 'int16u',
38             WRITABLE => 1,
39             FIRST_ENTRY => 0,
40             NOTES => q{
41             The following tags are extracted from the maker notes of Reconyx Hyperfire
42             cameras such as the HC500, HC600 and PC900.
43             },
44             0x00 => { #1
45             Name => 'MakerNoteVersion',
46             PrintConv => 'sprintf("0x%.4x", $val)',
47             Writable => 0, # (we use this for identification, 0xf101 --> rev 1.0)
48             PrintConvInv => 'hex $val',
49             },
50             0x01 => { #1
51             Name => 'FirmwareVersion',
52             Format => 'int16u[3]',
53             PrintConv => '$val=~tr/ /./; $val',
54             Writable => 0, # (we use this for identification, 0x0003 --> ver 2 or 3)
55             },
56             0x04 => { #1
57             Name => 'FirmwareDate',
58             Format => 'int16u[2]',
59             ValueConv => q{
60             my @v = split(' ',$val);
61             sprintf('%.4x:%.2x:%.2x', $v[0], $v[1]>>8, $v[1]&0xff);
62             },
63             ValueConvInv => q{
64             my @v = split(':', $val);
65             hex($v[0]) . ' ' . hex($v[1] . $v[2]);
66             },
67             },
68             0x06 => {
69             Name => 'TriggerMode',
70             Format => 'string[2]',
71             PrintConv => {
72             C => 'CodeLoc Not Entered', #1
73             E => 'External Sensor', #1
74             M => 'Motion Detection',
75             T => 'Time Lapse',
76             },
77             },
78             0x07 => {
79             Name => 'Sequence',
80             Format => 'int16u[2]',
81             PrintConv => '$val =~ s/ / of /; $val',
82             PrintConvInv => 'join(" ", $val=~/\d+/g)',
83             },
84             0x09 => { #1
85             Name => 'EventNumber',
86             Format => 'int16u[2]',
87             ValueConv => 'my @v=split(" ",$val); ($v[0]<<16) + $v[1]',
88             ValueConvInv => '($val>>16) . " " . ($val&0xffff)',
89             },
90             0x0b => {
91             Name => 'DateTimeOriginal',
92             Description => 'Date/Time Original',
93             Format => 'int16u[6]',
94             Groups => { 2 => 'Time' },
95             Priority => 0, # (not as reliable as EXIF)
96             Shift => 'Time',
97             ValueConv => q{
98             my @a = split ' ', $val;
99             # have seen these values written big-endian when everything else is little-endian
100             if ($a[0] & 0xff00 and not $a[0] & 0xff) {
101             $_ = ($_ >> 8) | (($_ & 0xff) << 8) foreach @a;
102             }
103             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @a[5,3,4,2,1,0]);
104             },
105             ValueConvInv => q{
106             my @a = ($val =~ /\d+/g);
107             return undef unless @a >= 6;
108             join ' ', @a[5,4,3,1,2,0];
109             },
110             PrintConv => '$self->ConvertDateTime($val)',
111             PrintConvInv => '$self->InverseDateTime($val)',
112             },
113             0x12 => {
114             Name => 'MoonPhase',
115             Groups => { 2 => 'Time' },
116             PrintConv => {
117             0 => 'New',
118             1 => 'New Crescent',
119             2 => 'First Quarter',
120             3 => 'Waxing Gibbous',
121             4 => 'Full',
122             5 => 'Waning Gibbous',
123             6 => 'Last Quarter',
124             7 => 'Old Crescent',
125             },
126             },
127             0x13 => {
128             Name => 'AmbientTemperatureFahrenheit',
129             Format => 'int16s',
130             PrintConv => '"$val F"',
131             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
132             },
133             0x14 => {
134             Name => 'AmbientTemperature',
135             Format => 'int16s',
136             PrintConv => '"$val C"',
137             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
138             },
139             0x15 => {
140             Name => 'SerialNumber',
141             Format => 'undef[30]',
142             RawConv => '$_ = $self->Decode($val, "UCS2"); s/\0.*//; $_',
143             RawConvInv => q{
144             $_ = $self->Encode($val, "UCS2");
145             $_ = substr($_, 0, 30) if length($_) > 30;
146             return $_;
147             },
148             },
149             0x24 => 'Contrast', #1
150             0x25 => 'Brightness', #1
151             0x26 => 'Sharpness', #1
152             0x27 => 'Saturation', #1
153             0x28 => {
154             Name => 'InfraredIlluminator',
155             PrintConv => { 0 => 'Off', 1 => 'On' },
156             },
157             0x29 => 'MotionSensitivity', #1
158             0x2a => { #1
159             Name => 'BatteryVoltage',
160             ValueConv => '$val / 1000',
161             ValueConvInv => '$val * 1000',
162             PrintConv => '"$val V"',
163             PrintConvInv => '$val=~s/ ?V$//; $val',
164             },
165             0x2b => {
166             Name => 'UserLabel',
167             Format => 'string[22]', #1 (but manual says 16-char limit)
168             },
169             );
170              
171             # maker notes for Reconyx UltraFire cameras (ref PH)
172             %Image::ExifTool::Reconyx::Type2 = (
173             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
174             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
175             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
176             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
177             TAG_PREFIX => 'Reconyx',
178             WRITABLE => 1,
179             FIRST_ENTRY => 0,
180             NOTES => 'Tags extracted from models such as the UltraFire.',
181             # 0x0a - int32u makernote ID 0x00020000 #2
182             # 0x0e - int16u makernote size #2
183             # 0x12 - int32u public structure ID 0x07f100001 #2
184             # 0x16 - int16u public structure size #2 (0x5d = start of public ID to end of UserLabel)
185             0x18 => { Name => 'FirmwareVersion', %versionInfo },
186             0x1f => { Name => 'Micro1Version', %versionInfo }, #2
187             0x26 => { Name => 'BootLoaderVersion', %versionInfo }, #2
188             0x2d => { Name => 'Micro2Version', %versionInfo }, #2
189             0x34 => {
190             Name => 'TriggerMode',
191             Format => 'undef[1]',
192             PrintConv => {
193             M => 'Motion Detection',
194             T => 'Time Lapse',
195             P => 'Point and Shoot', #2
196             },
197             },
198             0x35 => {
199             Name => 'Sequence',
200             Format => 'int8u[2]',
201             PrintConv => '$val =~ s/ / of /; $val',
202             PrintConvInv => 'join(" ", $val=~/\d+/g)',
203             },
204             0x37 => { #2
205             Name => 'EventNumber',
206             Format => 'int32u',
207             },
208             0x3b => {
209             Name => 'DateTimeOriginal',
210             Description => 'Date/Time Original',
211             Format => 'int8u[7]',
212             Groups => { 2 => 'Time' },
213             Priority => 0, # (not as reliable as EXIF)
214             Shift => 'Time',
215             ValueConv => q{
216             my @a = split ' ', $val;
217             $a[5] += pop(@a) * 256;
218             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', reverse @a);
219             },
220             ValueConvInv => q{
221             my @a = ($val =~ /\d+/g);
222             return undef unless @a >= 6;
223             unshift @a, ($a[0] >> 8);
224             $a[1] -= $a[0] * 256;
225             join ' ', @a[6,5,4,3,2,1,0];
226             },
227             PrintConv => '$self->ConvertDateTime($val)',
228             PrintConvInv => '$self->InverseDateTime($val)',
229             },
230             0x42 => { #2
231             Name => 'DayOfWeek',
232             Groups => { 2 => 'Time' },
233             PrintConv => {
234             0 => 'Sunday',
235             1 => 'Monday',
236             2 => 'Tuesday',
237             3 => 'Wednesday',
238             4 => 'Thursday',
239             5 => 'Friday',
240             6 => 'Saturday',
241             },
242             },
243             0x43 => {
244             Name => 'MoonPhase',
245             Groups => { 2 => 'Time' },
246             PrintConv => {
247             0 => 'New',
248             1 => 'New Crescent',
249             2 => 'First Quarter',
250             3 => 'Waxing Gibbous',
251             4 => 'Full',
252             5 => 'Waning Gibbous',
253             6 => 'Last Quarter',
254             7 => 'Old Crescent',
255             },
256             },
257             0x44 => {
258             Name => 'AmbientTemperatureFahrenheit',
259             Format => 'int16s',
260             PrintConv => '"$val F"',
261             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
262             },
263             0x46 => {
264             Name => 'AmbientTemperature',
265             Format => 'int16s',
266             PrintConv => '"$val C"',
267             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
268             },
269             0x48 => {
270             Name => 'Illumination',
271             PrintConv => { 0 => 'Off', 1 => 'On' },
272             },
273             0x49 => {
274             Name => 'BatteryVoltage',
275             Format => 'int16u',
276             ValueConv => '$val / 1000',
277             ValueConvInv => '$val * 1000',
278             PrintConv => '"$val V"',
279             PrintConvInv => '$val=~s/ ?V$//; $val',
280             },
281             0x4b => {
282             Name => 'SerialNumber',
283             Format => 'string[15]',
284             },
285             0x5a => {
286             Name => 'UserLabel',
287             Format => 'string[21]',
288             },
289             );
290              
291             # maker notes for Reconyx HF2 PRO cameras (ref 3)
292             %Image::ExifTool::Reconyx::Type3 = (
293             GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
294             PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
295             WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
296             CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
297             TAG_PREFIX => 'Reconyx',
298             WRITABLE => 1,
299             FIRST_ENTRY => 0,
300             NOTES => 'Tags extracted from models such as the HF2 PRO.',
301             # 0x0a => { Name => 'StructureVersion', Format => 'int16u' },
302             # 0x0c => { Name => 'ParentFileSize', Format => 'int32u' },
303             0x10 => { Name => 'FileNumber', Format => 'int16u' },
304             0x12 => { Name => 'DirectoryNumber', Format => 'int16u' },
305             # 0x14 => { Name => 'DirCreateDate', Format => 'int16u' },
306             # 0x16 => { Name => 'DirCreateTime', Format => 'int16u' },
307             # 0x18 - int16[8] SDCardLabel
308             # 0x28 => { Name => 'MakerNoteVersion', Format => 'int16u' },
309             0x2a => {
310             Name => 'FirmwareVersion',
311             Format => 'int16u[3]',
312             ValueConv => 'my @a = split " ",$val; sprintf("%d.%d%c",@a)',
313             ValueConvInv => '$val=~/(\d+)\.(\d+)([a-zA-Z])/ ? "$1 $2 ".ord($3) : undef',
314             },
315             0x30 => {
316             Name => 'FirmwareDate',
317             Format => 'int16u[2]',
318             ValueConv => 'my ($y,$d) = split " ", $val; sprintf("%.4x:%.2x:%.2x",$y,$d>>8,$d&0xff)',
319             ValueConvInv => 'my @a=split ":", $val; hex($a[0])." ".hex($a[1].$a[2])',
320             },
321             0x34 => {
322             Name => 'TriggerMode', #PH (NC) (called EventType in the Reconyx code)
323             Format => 'string[2]',
324             PrintConv => {
325             M => 'Motion Detection', # (seen this one only)
326             T => 'Time Lapse', # (NC)
327             P => 'Point and Shoot', # (NC)
328             },
329             },
330             0x36 => {
331             Name => 'Sequence',
332             Format => 'int16u[2]',
333             PrintConv => '$val =~ s/ / of /; $val',
334             PrintConvInv => 'join(" ", $val=~/\d+/g)',
335             },
336             0x3a => {
337             Name => 'EventNumber',
338             Format => 'int16u[2]',
339             ValueConv => 'my @a=split " ",$val;($a[0]<<16)+$a[1]',
340             ValueConvInv => '($val >> 16) . " " . ($val & 0xffff)',
341             },
342             0x3e => {
343             Name => 'DateTimeOriginal',
344             Description => 'Date/Time Original',
345             Format => 'int16u[6]',
346             Groups => { 2 => 'Time' },
347             Priority => 0, # (not as reliable as EXIF)
348             Shift => 'Time',
349             ValueConv => q{
350             my @a = split ' ', $val;
351             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', reverse @a);
352             },
353             ValueConvInv => q{
354             my @a = ($val =~ /\d+/g);
355             return undef unless @a >= 6;
356             join ' ', @a[6,5,4,3,2,1,0];
357             },
358             PrintConv => '$self->ConvertDateTime($val)',
359             PrintConvInv => '$self->InverseDateTime($val)',
360             },
361             0x4a => { #2
362             Name => 'DayOfWeek',
363             Groups => { 2 => 'Time' },
364             Format => 'int16u',
365             PrintConv => {
366             0 => 'Sunday',
367             1 => 'Monday',
368             2 => 'Tuesday',
369             3 => 'Wednesday',
370             4 => 'Thursday',
371             5 => 'Friday',
372             6 => 'Saturday',
373             },
374             },
375             0x4c => {
376             Name => 'MoonPhase',
377             Groups => { 2 => 'Time' },
378             Format => 'int16u',
379             PrintConv => {
380             0 => 'New',
381             1 => 'New Crescent',
382             2 => 'First Quarter',
383             3 => 'Waxing Gibbous',
384             4 => 'Full',
385             5 => 'Waning Gibbous',
386             6 => 'Last Quarter',
387             7 => 'Old Crescent',
388             },
389             },
390             0x4e => {
391             Name => 'AmbientTemperatureFahrenheit',
392             Format => 'int16s',
393             PrintConv => '"$val F"',
394             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
395             },
396             0x50 => {
397             Name => 'AmbientTemperature',
398             Format => 'int16s',
399             PrintConv => '"$val C"',
400             PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
401             },
402             0x52 => { Name => 'Contrast', Format => 'int16u' },
403             0x54 => { Name => 'Brightness', Format => 'int16u' },
404             0x56 => { Name => 'Sharpness', Format => 'int16u' },
405             0x58 => { Name => 'Saturation', Format => 'int16u' },
406             0x5a => { Name => 'Flash', Format => 'int16u', PrintConv => { 0 => 'Off', 1 => 'On' } },
407             0x5c => { Name => 'AmbientInfrared', Format => 'int16u' },
408             0x5e => { Name => 'AmbientLight', Format => 'int16u' },
409             0x60 => { Name => 'MotionSensitivity', Format => 'int16u' },
410             0x62 => { Name => 'BatteryVoltage', Format => 'int16u' },
411             0x64 => { Name => 'BatteryVoltageAvg', Format => 'int16u' },
412             0x66 => { Name => 'BatteryType', Format => 'int16u' },
413             0x68 => { Name => 'UserLabel', Format => 'string[22]' },
414             0x7e => { Name => 'SerialNumber', Format => 'unicode[15]' },
415             );
416              
417             __END__