File Coverage

blib/lib/PDF/Builder/Resource/XObject/Image/JPEG.pm
Criterion Covered Total %
statement 62 73 84.9
branch 17 32 53.1
condition 11 21 52.3
subroutine 9 9 100.0
pod 1 2 50.0
total 100 137 72.9


line stmt bran cond sub pod time code
1             package PDF::Builder::Resource::XObject::Image::JPEG;
2              
3 2     2   1091 use base 'PDF::Builder::Resource::XObject::Image';
  2         4  
  2         614  
4              
5 2     2   15 use strict;
  2         4  
  2         41  
6 2     2   10 use warnings;
  2         4  
  2         110  
7              
8             our $VERSION = '3.023'; # VERSION
9             our $LAST_UPDATE = '3.017'; # manually update whenever code is changed
10              
11 2     2   13 use IO::File;
  2         4  
  2         358  
12 2     2   15 use PDF::Builder::Util;
  2         4  
  2         319  
13 2     2   16 use PDF::Builder::Basic::PDF::Utils;
  2         4  
  2         226  
14 2     2   16 use Scalar::Util qw(weaken);
  2         4  
  2         1337  
15              
16             =head1 NAME
17              
18             PDF::Builder::Resource::XObject::Image::JPEG - support routines for JPEG image library. Inherits from L
19              
20             =cut
21              
22             sub new {
23 2     2 1 6 my ($class, $pdf, $file, $name) = @_;
24              
25 2         10 my $fh = IO::File->new();
26              
27 2 50       87 $class = ref($class) if ref $class;
28              
29 2   33     12 my $self = $class->SUPER::new($pdf, $name || 'Jx' . pdfkey());
30 2 50       7 $pdf->new_obj($self) unless $self->is_obj($pdf);
31              
32 2         4 $self->{' apipdf'} = $pdf;
33 2         7 weaken $self->{' apipdf'};
34              
35 2 50       6 if (ref($file)) {
36 0         0 $fh = $file;
37             } else {
38 2 100       100 open $fh, "<", $file or die "$!: $file";
39             }
40 1         7 binmode($fh, ':raw');
41              
42 1         5 $self->read_jpeg($fh);
43              
44 1 50       5 if (ref($file)) {
45 0         0 seek($fh, 0, 0);
46 0         0 $self->{' stream'} = '';
47 0         0 my $buf = '';
48 0         0 while (!eof($fh)) {
49 0         0 read($fh, $buf, 512);
50 0         0 $self->{' stream'} .= $buf;
51             }
52 0         0 $self->{'Length'} = PDFNum(length $self->{' stream'});
53             } else {
54 1         20 $self->{'Length'} = PDFNum(-s $file);
55 1         3 $self->{' streamfile'} = $file;
56             }
57              
58 1         11 $self->filters('DCTDecode');
59 1         2 $self->{' nofilt'} = 1;
60              
61 1         21 return $self;
62             }
63              
64             sub read_jpeg {
65 1     1 0 2 my ($self, $fh) = @_;
66              
67 1         3 my ($buf, $p, $h, $w, $c, $ff, $mark, $len);
68              
69 1         12 $fh->seek(0,0);
70 1         24 $fh->read($buf,2);
71 1         34 while (1) {
72 5         15 $fh->read($buf, 4);
73 5         29 my ($ff, $mark, $len) = unpack('CCn', $buf);
74 5 50       13 last if $ff != 0xFF;
75 5 50 33     19 last if $mark == 0xDA || $mark == 0xD9; # SOS/EOI
76 5 50       11 last if $len < 2;
77 5 50       15 last if $fh->eof();
78 5         37 $fh->read($buf, $len - 2);
79 5 100       27 next if $mark == 0xFE;
80 4 100 66     12 next if $mark >= 0xE0 && $mark <= 0xEF;
81 3 50 66     18 if ($mark >= 0xC0 && $mark <= 0xCF && $mark != 0xC4 && $mark != 0xC8 && $mark != 0xCC) {
      66        
      66        
      33        
82 1         5 ($p, $h, $w, $c) = unpack('CnnC', substr($buf, 0, 6));
83 1         3 last;
84             }
85             }
86              
87 1         8 $self->width($w);
88 1         6 $self->height($h);
89 1         6 $self->bits_per_component($p);
90              
91 1 50       3 if (!defined $c) { return $self; }
  0         0  
92 1 50       4 if ($c == 3) {
    0          
    0          
93 1         5 $self->colorspace('DeviceRGB');
94             } elsif ($c == 4) {
95 0         0 $self->colorspace('DeviceCMYK');
96             } elsif ($c == 1) {
97 0         0 $self->colorspace('DeviceGray');
98             }
99              
100 1         2 return $self;
101             }
102              
103             1;