File Coverage

blib/lib/Video/Pattern.pm
Criterion Covered Total %
statement 76 85 89.4
branch 19 24 79.1
condition 2 3 66.6
subroutine 14 14 100.0
pod 2 2 100.0
total 113 128 88.2


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