File Coverage

blib/lib/PDF/API2/Resource/XObject/Image/JPEG.pm
Criterion Covered Total %
statement 69 71 97.1
branch 18 30 60.0
condition 12 30 40.0
subroutine 9 9 100.0
pod 1 2 50.0
total 109 142 76.7


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