File Coverage

blib/lib/Photography/EV.pm
Criterion Covered Total %
statement 53 63 84.1
branch 15 26 57.6
condition 3 3 100.0
subroutine 14 14 100.0
pod 3 3 100.0
total 88 109 80.7


line stmt bran cond sub pod time code
1             package Photography::EV;
2              
3 4     4   69818 use strict;
  4         9  
  4         165  
4 4     4   22 use warnings;
  4         8  
  4         173  
5 4     4   81 use 5.020000;
  4         16  
  4         147  
6 4     4   19 use feature 'signatures';
  4         7  
  4         542  
7 4     4   22 no warnings 'experimental::signatures';
  4         6  
  4         185  
8 4     4   18 use base qw( Exporter );
  4         8  
  4         1075  
9             BEGIN {
10 4     4   344 eval q{
  4     4   2485  
  4         25873  
  4         26  
11             use POSIX qw( pow );
12             };
13 4 50       6952 if($@)
14             {
15 0 0       0 *pow = sub ($x, $exponent)
  0 0       0  
  0         0  
  0         0  
16 0         0 {
17 0         0 my $value = 1;
18 0         0 for(1..$exponent)
19             {
20 0         0 $value *= $x;
21             }
22 0         0 $value;
23             }
24 0         0 }
25             }
26            
27              
28             our @EXPORT_OK = qw( ev aperture shutter_speed );
29             our @EXPORT = @EXPORT_OK;
30              
31             # ABSTRACT: Calculate exposure value (EV)
32             our $VERSION = '0.05'; # VERSION
33              
34              
35             sub _round :prototype($)
36             {
37 4 100   4   26 return $_[0] ? int($_[0] + $_[0]/abs($_[0]*2)) : 0;
38             }
39              
40             sub _log2 :prototype($)
41             {
42 4     4   20 return log($_[0])/log(2);
43             }
44              
45             # returns the closest value in @$list to $exact
46             # returns undef if @$list is empty
47             sub _closest :prototype($$)
48             {
49 5     5   530 my($exact, $list) = @_;
50 5         8 my $answer;
51             my $diff;
52 5         13 for(@$list)
53             {
54 60         79 my $maybe = abs($_ - $exact);
55 60 100 100     225 if((!defined $answer) || $maybe < $diff)
56             {
57 41         43 $answer = $_;
58 41         54 $diff = $maybe;
59             }
60             }
61 5         33 $answer;
62             }
63              
64             my @apertures = qw(
65             1.0
66             1.4
67             2.8
68             4.0
69             5.6
70             8.0
71             11
72             16
73             22
74             32
75             45
76             64
77             );
78              
79             my @times = (
80             (map { $_ * 60 } qw( 32 16 8 4 2 )),
81             ( qw( 60 30 15 8 4 2 1)),
82             (map { 1 / $_ } qw( 2 4 8 15 30 125 250 500 1000 2000 4000 8000 ))
83             );
84              
85              
86 4 50   4 1 18 sub ev ($aperture, $time)
  4 50       10  
  4         5  
  4         5  
87 4         4 {
88 4         13 return _round _log2 $aperture*$aperture/$time;
89             }
90              
91              
92 2 50   2 1 12 sub aperture ($ev, $time, $apertures = \@apertures )
  2 50       8  
  2 100       4  
  2         3  
  2         7  
93 2         4 {
94 2         41 return _closest sqrt pow(2, $ev)*$time, $apertures;
95             }
96              
97              
98 3 50   3 1 20 sub shutter_speed ($ev, $aperture, $times = \@times )
  3 50       11  
  3 100       5  
  3         4  
  3         10  
99 3         4 {
100 3         77 return _closest $aperture*$aperture/pow(2, $ev), $times;
101             }
102              
103             1;
104              
105             __END__