File Coverage

blib/lib/Device/PaPiRus.pm
Criterion Covered Total %
statement 27 29 93.1
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 37 39 94.8


line stmt bran cond sub pod time code
1             package Device::PaPiRus;
2             #---AUTOPRAGMASTART---
3 1     1   15386 use 5.012;
  1         2  
4 1     1   3 use strict;
  1         1  
  1         22  
5 1     1   4 use warnings;
  1         5  
  1         26  
6 1     1   672859 use diagnostics;
  1         3314606  
  1         8  
7 1     1   865 use mro 'c3';
  1         747  
  1         3  
8 1     1   505702 use English qw( -no_match_vars );
  1         9114  
  1         9  
9 1     1   530 use Carp;
  1         2  
  1         145  
10             our $VERSION = 1.0;
11 1     1   621 no if $] >= 5.017011, warnings => 'experimental::smartmatch';
  1         9  
  1         5  
12 1     1   1443304 use Fatal qw( close );
  1         1978898  
  1         8  
13             #---AUTOPRAGMAEND---
14              
15 1     1   1344 use GD;
  0            
  0            
16              
17             sub new {
18             my ($proto, %config) = @_;
19             my $class = ref($proto) || $proto;
20              
21             my $self = {};
22              
23             bless $self, $class; # bless with our class
24              
25             # Let's load the display size
26             open(my $ifh, '<', '/dev/epd/panel') or croak($OS_ERROR);
27             my $line = <$ifh>;
28             close $ifh;
29             if($line =~ /\ (\d+)x(\d+)\ /) {
30             ($self->{width}, $self->{height}) = ($1, $2);
31             } else {
32             croak("Can't read panel dimensions!");
33             }
34              
35             # Default
36             $self->{threshold} = 150;
37             $self->{randomize_white} = 0;
38             $self->{randomize_black} = 0;
39              
40             return $self;
41             }
42              
43             sub getWidth {
44             my ($self) = @_;
45              
46             return $self->{width};
47             }
48              
49             sub getHeight {
50             my ($self) = @_;
51              
52             return $self->{height};
53             }
54              
55             sub fullUpdate {
56             my ($self, $img) = @_;
57              
58             return $self->updateImage($img, 'U');
59             }
60              
61             sub partialUpdate {
62             my ($self, $img) = @_;
63              
64             return $self->updateImage($img, 'P');
65             }
66              
67             sub randomizeWhite {
68             my ($self, $val) = @_;
69              
70             $self->{randomize_white} = $val;
71             return;
72             }
73              
74             sub randomizeBlack {
75             my ($self, $val) = @_;
76              
77             $self->{randomize_black} = $val;
78             return;
79             }
80              
81             sub setThreshold {
82             my ($self, $threshold) = @_;
83              
84             $threshold = 0 + $threshold;
85             if($threshold < 0) {
86             croak("Threshold can not be less than zero");
87             } elsif($threshold > 255) {
88             croak("Threshold can not be larger than 255");
89             }
90             $self->{threshold} = $threshold;
91             return;
92             }
93              
94              
95             sub updateImage {
96             my ($self, $img, $mode) = @_;
97             my $outimg = '';
98              
99             my ($sourcewidth, $sourceheight) = $img->getBounds();
100             if($sourcewidth != $self->{width} || $sourceheight != $self->{height}) {
101             croak('Image dimensions (' . $sourcewidth . 'x' . $sourceheight . ') do not match panel size (' . $self->{width} . 'x' . $self->{height} . ')!');
102             }
103              
104             # We need to read 8 pixels of the image in one go, turn them into pure black&white bits and stuff the 8 of them into a single byte,
105             # correcting for endianess and all that...
106             for(my $y = 0; $y < $self->{height}; $y++) {
107             for(my $x = 0; $x < ($self->{width} / 8); $x++) {
108             my $buf = '';
109             for(my $offs = 0; $offs < 8; $offs++) {
110             my $index = $img->getPixel(($x*8) + $offs,$y);
111             my ($r,$g,$b) = $img->rgb($index);
112             my $grey = int(($r+$g+$b)/3);
113             if($grey > $self->{threshold}) {
114             if($self->{randomize_white} && int(rand(10000)) % 4 == 0) {
115             $buf .= "1";
116             } else {
117             $buf .= "0";
118             }
119             } else {
120             if($self->{randomize_black} && int(rand(10000)) % 4 == 0) {
121             $buf .= "0";
122             } else {
123             $buf .= "1";
124             }
125             }
126             }
127             my $byte = pack('b8', $buf);
128             $outimg .= $byte;
129             }
130             }
131              
132             open(my $ofh, '>', '/dev/epd/display') or croak($!);
133             binmode $ofh;
134             print $ofh $outimg;
135             close $ofh;
136              
137             open(my $cfh, '>', '/dev/epd/command') or croak($!);
138             print $cfh $mode;
139             close $cfh;
140              
141             return;
142             }
143              
144              
145             1;
146             __END__