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   61736 use strict;
  4         11  
  4         183  
4 4     4   25 use warnings;
  4         9  
  4         151  
5 4     4   102 use 5.020000;
  4         17  
  4         148  
6 4     4   22 use feature 'signatures';
  4         5  
  4         563  
7 4     4   22 no warnings 'experimental::signatures';
  4         7  
  4         194  
8 4     4   23 use base qw( Exporter );
  4         6  
  4         1013  
9             BEGIN {
10 4     4   299 eval q{
  4     4   2535  
  4         25254  
  4         33  
11             use POSIX qw( pow );
12             };
13 4 50       6629 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.06'; # VERSION
33              
34              
35             sub _round :prototype($)
36             {
37 4 100   4   36 return $_[0] ? int($_[0] + $_[0]/abs($_[0]*2)) : 0;
38             }
39              
40             sub _log2 :prototype($)
41             {
42 4     4   31 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   533 my($exact, $list) = @_;
50 5         7 my $answer;
51             my $diff;
52 5         15 for(@$list)
53             {
54 60         78 my $maybe = abs($_ - $exact);
55 60 100 100     237 if((!defined $answer) || $maybe < $diff)
56             {
57 41         39 $answer = $_;
58 41         58 $diff = $maybe;
59             }
60             }
61 5         32 $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 25 sub ev ($aperture, $time)
  4 50       15  
  4         7  
  4         6  
87 4         6 {
88 4         18 return _round _log2 $aperture*$aperture/$time;
89             }
90              
91              
92 2 50   2 1 14 sub aperture ($ev, $time, $apertures = \@apertures )
  2 50       8  
  2 100       3  
  2         4  
  2         6  
93 2         2 {
94 2         43 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       13  
  3 100       6  
  3         4  
  3         12  
99 3         6 {
100 3         83 return _closest $aperture*$aperture/pow(2, $ev), $times;
101             }
102              
103             1;
104              
105             __END__