File Coverage

blib/lib/Video/Pattern.pm
Criterion Covered Total %
statement 76 87 87.3
branch 21 28 75.0
condition 2 3 66.6
subroutine 14 14 100.0
pod 2 2 100.0
total 115 134 85.8


line stmt bran cond sub pod time code
1             package Video::Pattern;
2              
3             # Pragmas.
4 4     4   187857 use strict;
  4         7  
  4         92  
5 4     4   19 use warnings;
  4         5  
  4         106  
6              
7             # Modules.
8 4     4   2269 use Class::Utils qw(set_params);
  4         104863  
  4         109  
9 4     4   205 use Error::Pure qw(err);
  4         7  
  4         149  
10 4     4   18 use English;
  4         8  
  4         27  
11 4     4   2150 use File::Basename qw(fileparse);
  4         8  
  4         259  
12 4     4   3252 use File::Spec::Functions qw(catfile);
  4         3001  
  4         217  
13 4     4   2198 use Image::Random;
  4         138418  
  4         127  
14 4     4   44 use Readonly;
  4         10  
  4         164  
15 4     4   3373 use Video::Delay::Const;
  4         756  
  4         3248  
16              
17             # Constants.
18             Readonly::Scalar our $EMPTY_STR => q{};
19             Readonly::Scalar our $MILISECONDS_IN_SECOND => 1000;
20             Readonly::Scalar our $MINUTS_IN_HOUR => 60;
21             Readonly::Scalar our $SECONDS_IN_MINUTE => 60;
22              
23             # Version.
24             our $VERSION = 0.08;
25              
26             # Constructor.
27             sub new {
28 12     12 1 21480 my ($class, @params) = @_;
29              
30             # Create object.
31 12         28 my $self = bless {}, $class;
32              
33             # Delay generator.
34 12         64 $self->{'delay_generator'} = Video::Delay::Const->new(
35             'const' => 1000,
36             );
37              
38             # Duration.
39 12         255 $self->{'duration'} = 10000;
40              
41             # Frame per second.
42 12         23 $self->{'fps'} = 60;
43              
44             # Image generator.
45 12         19 $self->{'image_generator'} = undef;
46              
47             # Image type.
48 12         25 $self->{'image_type'} = 'bmp';
49              
50             # Process params.
51 12         31 set_params($self, @params);
52              
53             # Check fps value.
54 10 100 66     153 if (! defined $self->{'fps'} || $self->{'fps'} !~ m/^\d+$/ms) {
55 2         24 err "Parameter 'fps' must be numeric value.";
56             }
57              
58             # Check and process duration value.
59 8         31 $self->_check_and_process_duration;
60              
61             # Own image generator.
62 5 100       14 if (! defined $self->{'image_generator'}) {
63             $self->{'image_generator'} = Image::Random->new(
64             'height' => 1080,
65 4         32 'type' => $self->{'image_type'},
66             'width' => 1920,
67             );
68             } else {
69 1         7 $self->{'image_type'} = $self->{'image_generator'}->type;
70             }
71              
72             # Object.
73 5         27086 return $self;
74             }
75              
76             # Create images to output directory.
77             sub create {
78 1     1 1 979 my ($self, $output_dir) = @_;
79 1         29 my $delay = 0;
80 1         2 my $image;
81 1         8 foreach my $frame_num (0 .. $self->{'duration'} / 1000
82             * $self->{'fps'}) {
83              
84             my $image_path = catfile($output_dir,
85             (sprintf '%03d', $frame_num).'.'.
86 601         3567 $self->{'image_type'});
87              
88             # Create new image.
89 601 100       1349 if ($delay <= 0) {
90 10         81 $self->{'image_generator'}->create($image_path);
91 10         1575676 $image = $image_path;
92 10         122 $delay = $self->{'delay_generator'}->delay;
93              
94             # Symlink to old image.
95             } else {
96 591         7242 my ($image_filename) = fileparse($image);
97 591         1376 $self->_symlink($image_filename, $image_path);
98             }
99              
100             # Decrement delay.
101 601         1591 $delay -= 1000 / $self->{'fps'};
102             }
103 1         8 return;
104             }
105              
106             # Check and process duration.
107             sub _check_and_process_duration {
108 8     8   15 my $self = shift;
109 8         13 my $err = 0;
110 8 100       53 if (! defined $self->{'duration'}) {
    100          
111 1         3 $err = 1;
112             } elsif ($self->{'duration'} =~ m/^(\d+)(\w*)$/ms) {
113 6         20 my $duration_value = $1;
114 6         15 my $duration_suffix = $2;
115 6 100       24 if ($duration_suffix ne $EMPTY_STR) {
116 3 100       15 if ($duration_suffix eq 's') {
    100          
    50          
    50          
117 1         6 $self->{'duration'} = $duration_value
118             * $MILISECONDS_IN_SECOND;
119             } elsif ($duration_suffix eq 'ms') {
120 1         4 $self->{'duration'} = $duration_value;
121             } elsif ($duration_suffix eq 'min') {
122 0         0 $self->{'duration'} = $duration_value
123             * $MILISECONDS_IN_SECOND
124             * $SECONDS_IN_MINUTE;
125             } elsif ($duration_suffix eq 'h') {
126 0         0 $self->{'duration'} = $duration_value
127             * $MILISECONDS_IN_SECOND
128             * $SECONDS_IN_MINUTE
129             * $MINUTS_IN_HOUR;
130             } else {
131 1         2 $err = 1;
132             }
133             }
134             } else {
135 1         2 $err = 1;
136             }
137              
138 8 100       23 if ($err) {
139 3         10 err "Parameter 'duration' must be numeric value or numeric ".
140             "value with time suffix.";
141             }
142 5         10 return;
143             }
144              
145             # Symlink.
146             sub _symlink {
147 591     591   955 my ($self, $from, $to) = @_;
148 591 50       1269 if ($OSNAME eq 'MSWin32') {
149 0         0 eval {
150 0         0 require Win32::Symlink;
151             };
152 0         0 my $has_symlink;
153 0 0       0 if (! $EVAL_ERROR) {
154 0         0 $has_symlink = eval {
155 0         0 Win32::Symlink::symlink($from => $to);
156             };
157             }
158 0 0       0 if (! $has_symlink) {
159 0         0 require File::Copy;
160 0         0 File::Copy::copy($from, $to);
161             }
162             } else {
163 591         38340 symlink $from, $to;
164             }
165             }
166             1;
167              
168             __END__