File Coverage

blib/lib/PDF/API2/Basic/PDF/Filter/LZWDecode.pm
Criterion Covered Total %
statement 9 62 14.5
branch 0 22 0.0
condition 0 9 0.0
subroutine 3 6 50.0
pod 2 3 66.6
total 14 102 13.7


line stmt bran cond sub pod time code
1             package PDF::API2::Basic::PDF::Filter::LZWDecode;
2              
3 44     44   341 use base 'PDF::API2::Basic::PDF::Filter::FlateDecode';
  44         115  
  44         6307  
4              
5 44     44   303 use strict;
  44         119  
  44         1151  
6 44     44   288 no warnings qw[ deprecated recursion uninitialized ];
  44         123  
  44         30179  
7              
8             our $VERSION = '2.045'; # VERSION
9              
10             sub new {
11 0     0 1   my ($class, $decode_parms) = @_;
12 0           my $self = {
13             DecodeParms => $decode_parms,
14             };
15              
16 0           $self->{'table'} = [map { pack('C', $_) } (0 .. 255, 0, 0)];
  0            
17 0           $self->{'initial_code_length'} = 9;
18 0           $self->{'code_length'} = 9;
19 0           $self->{'clear_table'} = 256;
20 0           $self->{'eod_marker'} = 257;
21 0           $self->{'next_code'} = 258;
22              
23 0           bless $self, $class;
24 0           return $self;
25             }
26              
27             sub infilt {
28 0     0 1   my ($self, $data, $is_last) = @_;
29 0           my ($code, $result);
30 0           my $partial_code = $self->{'partial_code'};
31 0           my $partial_bits = $self->{'partial_bits'};
32              
33 0           my $early_change = 1;
34 0 0 0       if ($self->{'DecodeParms'} and $self->{'DecodeParms'}->{'EarlyChange'}) {
35 0           $early_change = $self->{'DecodeParms'}->{'EarlyChange'}->val();
36             }
37              
38 0           while ($data ne '') {
39 0           ($code, $partial_code, $partial_bits) = $self->read_dat(\$data, $partial_code, $partial_bits, $self->{'code_length'});
40 0 0         last unless defined $code;
41              
42 0 0         unless ($early_change) {
43 0 0 0       if ($self->{'next_code'} == (1 << $self->{'code_length'}) and $self->{'code_length'} < 12) {
44 0           $self->{'code_length'}++;
45             }
46             }
47              
48 0 0         if ($code == $self->{'clear_table'}) {
    0          
    0          
49 0           $self->{'code_length'} = $self->{'initial_code_length'};
50 0           $self->{'next_code'} = $self->{'eod_marker'} + 1;
51 0           next;
52             }
53             elsif ($code == $self->{'eod_marker'}) {
54 0           last;
55             }
56             elsif ($code > $self->{'eod_marker'}) {
57 0           $self->{'table'}[$self->{'next_code'}] = $self->{'table'}[$code];
58 0           $self->{'table'}[$self->{'next_code'}] .= substr($self->{'table'}[$code + 1], 0, 1);
59 0           $result .= $self->{'table'}[$self->{'next_code'}];
60 0           $self->{'next_code'}++;
61             }
62             else {
63 0           $self->{'table'}[$self->{'next_code'}] = $self->{'table'}[$code];
64 0           $result .= $self->{'table'}[$self->{'next_code'}];
65 0           $self->{'next_code'}++;
66             }
67              
68 0 0         if ($early_change) {
69 0 0 0       if ($self->{'next_code'} == (1 << $self->{'code_length'}) and $self->{'code_length'} < 12) {
70 0           $self->{'code_length'}++;
71             }
72             }
73             }
74 0           $self->{'partial_code'} = $partial_code;
75 0           $self->{'partial_bits'} = $partial_bits;
76 0           return $result;
77             }
78              
79             sub read_dat {
80 0     0 0   my ($self, $data_ref, $partial_code, $partial_bits, $code_length) = @_;
81 0 0         $partial_bits = 0 unless defined $partial_bits;
82              
83 0           while ($partial_bits < $code_length) {
84 0 0         return (undef, $partial_code, $partial_bits) unless length($$data_ref);
85 0           $partial_code = ($partial_code << 8) + unpack('C', $$data_ref);
86 0           substr($$data_ref, 0, 1) = '';
87 0           $partial_bits += 8;
88             }
89              
90 0           my $code = $partial_code >> ($partial_bits - $code_length);
91 0           $partial_code &= (1 << ($partial_bits - $code_length)) - 1;
92 0           $partial_bits -= $code_length;
93              
94 0           return ($code, $partial_code, $partial_bits);
95             }
96              
97             1;