File Coverage

blib/lib/Data/BitStream/Code/Rice.pm
Criterion Covered Total %
statement 46 47 97.8
branch 27 34 79.4
condition 3 3 100.0
subroutine 7 7 100.0
pod 2 2 100.0
total 85 93 91.4


line stmt bran cond sub pod time code
1             package Data::BitStream::Code::Rice;
2 28     28   22327 use strict;
  28         78  
  28         990  
3 28     28   170 use warnings;
  28         62  
  28         1665  
4             BEGIN {
5 28     28   73 $Data::BitStream::Code::Rice::AUTHORITY = 'cpan:DANAJ';
6 28         3551 $Data::BitStream::Code::Rice::VERSION = '0.08';
7             }
8              
9             our $CODEINFO = { package => __PACKAGE__,
10             name => 'Rice',
11             universal => 0,
12             params => 1,
13             encodesub => sub {shift->put_rice(@_)},
14             decodesub => sub {shift->get_rice(@_)}, };
15              
16 28     28   169 use Moo::Role;
  28         74  
  28         214  
17             requires qw(read write put_unary get_unary);
18              
19             sub put_rice {
20 2456     2456 1 25943 my $self = shift;
21 2456 100       11531 my $sub = shift if ref $_[0] eq 'CODE'; ## no critic
22 2456         3341 my $k = shift;
23              
24 2456 50       6369 $self->error_code('param', 'k must be >= 0') unless $k >= 0;
25 2456 50       5207 return( (defined $sub) ? $sub->($self, @_) : $self->put_unary(@_) ) if $k==0;
    100          
26              
27 2455         4468 foreach my $val (@_) {
28 8185 100 100     43253 $self->error_code('zeroval') unless defined $val and $val >= 0;
29 8179         10836 my $q = $val >> $k;
30 8179         15194 my $r = $val - ($q << $k);
31 8179 100       29909 (defined $sub) ? $sub->($self, $q) : $self->put_unary($q);
32 8179         24229 $self->write($k, $r);
33             }
34 2449         7792 1;
35             }
36             sub get_rice {
37 2522     2522 1 24022 my $self = shift;
38 2522 100       7868 my $sub = shift if ref $_[0] eq 'CODE'; ## no critic ## no critic
39 2522         3363 my $k = shift;
40              
41 2522 50       6689 $self->error_code('param', 'k must be >= 0') unless $k >= 0;
42 2522 50       5355 return( (defined $sub) ? $sub->($self, @_) : $self->get_unary(@_) ) if $k==0;
    100          
43              
44 2521         3141 my $count = shift;
45 2521 100       5110 if (!defined $count) { $count = 1; }
  2455 50       3211  
    0          
46 66         112 elsif ($count < 0) { $count = ~0; } # Get everything
47 0         0 elsif ($count == 0) { return; }
48              
49 2521         3329 my @vals;
50 2521         8634 $self->code_pos_start('Rice');
51 2521         74743 while ($count-- > 0) {
52 8317         23152 $self->code_pos_set;
53 8317 100       271243 my $q = (defined $sub) ? $sub->($self) : $self->get_unary();
54 8309 100       18387 last unless defined $q;
55 8240         29984 my $remainder = $self->read($k);
56 8240 100       17147 $self->error_off_stream unless defined $remainder;
57 8239         27426 push @vals, ($q << $k) | $remainder;
58             }
59 2512         6792 $self->code_pos_end;
60 2512 100       77857 wantarray ? @vals : $vals[-1];
61             }
62 28     28   23935 no Moo::Role;
  28         66  
  28         150  
63             1;
64              
65             # ABSTRACT: A Role implementing Rice codes
66              
67             =pod
68              
69             =head1 NAME
70              
71             Data::BitStream::Code::Rice - A Role implementing Rice codes
72              
73             =head1 VERSION
74              
75             version 0.08
76              
77             =head1 DESCRIPTION
78              
79             A role written for L that provides get and set methods for
80             Rice codes. The role applies to a stream object.
81              
82             Note that this is just the Rice code (C) themselves,
83             and does not include algorithms for data adaptation.
84              
85             These codes are sometimes called GPO2 (Golomb-power-of-2) codes.
86              
87             Beware that with the default unary coding for the quotient, these codes can
88             become extraordinarily long for values much larger than C<2^k>.
89              
90             "I<...a Rice code (and by extension a Golomb code) is very well suited to
91             peaked distributions with few small values or large values. As noted earlier,
92             the Rice(k) code is extremely efficient for values in the general range
93             C<2^(k-1) < N < 2^(k+2)>>"
94             -- Lossless Compression Handbook, page 75, by Khalid Sayood
95              
96             =head1 METHODS
97              
98             =head2 Provided Object Methods
99              
100             =over 4
101              
102             =item B< put_rice($k, $value) >
103              
104             =item B< put_rice($k, @values) >
105              
106             Insert one or more values as Rice codes with parameter k. Returns 1.
107              
108             =item B< put_rice(sub { ... }, $k, @values) >
109              
110             Insert one or more values as Rice codes using the user provided subroutine
111             instead of the traditional Unary code for the base. For example, the so-called
112             "Exponential-Golomb" encoding can be performed using the sub:
113              
114             sub { shift->put_gamma(@_); }
115              
116             =item B< get_rice($k) >
117              
118             =item B< get_rice($k, $count) >
119              
120             Decode one or more Rice codes from the stream. If count is omitted,
121             one value will be read. If count is negative, values will be read until
122             the end of the stream is reached. In scalar context it returns the last
123             code read; in array context it returns an array of all codes read.
124              
125             =item B< get_rice(sub { ... }, $k) >
126              
127             Similar to the regular get method except using the user provided subroutine
128             instead of unary encoding the base. For example:
129              
130             sub { shift->get_gamma(@_); }
131              
132             =back
133              
134             =head2 Parameters
135              
136             The parameter C must be an integer greater than or equal to 0.
137              
138             The quotient CE k> is encoded using unary (or via the user
139             supplied subroutine), followed by the lowest C bits.
140              
141             Note: if C then the result will be coded purely using unary (or the
142             supplied sub) coding.
143              
144             Note: this is a special case of a C code where C.
145              
146             Rice coding is often preceded by a step that adapts the parameter to the
147             data seen so far. Rice's paper encodes 21-pixel prediction blocks using one
148             of three codes. The JPEG-LS LOCO-I algorithm uses a constantly adapting k
149             parameter to encode the prediction errors.
150              
151             =head2 Required Methods
152              
153             =over 4
154              
155             =item B< read >
156              
157             =item B< write >
158              
159             =item B< get_unary >
160              
161             =item B< put_unary >
162              
163             These methods are required for the role.
164              
165             =back
166              
167             =head1 SEE ALSO
168              
169             =over 4
170              
171             =item L
172              
173             =item L
174              
175             =item L
176              
177             =item L
178              
179             =item S.W. Golomb, "Run-length encodings", IEEE Transactions on Information Theory, vol 12, no 3, pp 399-401, 1966.
180              
181             =item R.F. Rice and R. Plaunt, "Adaptive Variable-Length Coding for Efficient Compression of Spacecraft Television Data", IEEE Transactions on Communications, vol 16, no 9, pp 889-897, Dec. 1971.
182              
183             =back
184              
185             =head1 AUTHORS
186              
187             Dana Jacobsen
188              
189             =head1 COPYRIGHT
190              
191             Copyright 2011 by Dana Jacobsen
192              
193             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
194              
195             =cut