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   1569 use base 'PDF::API2::Resource::XObject::Image';
  3         7  
  3         1037  
4              
5 3     3   22 use strict;
  3         8  
  3         63  
6 3     3   15 use warnings;
  3         7  
  3         169  
7              
8             our $VERSION = '2.044'; # VERSION
9              
10 3     3   22 use IO::File;
  3         6  
  3         520  
11 3     3   22 use PDF::API2::Util;
  3         6  
  3         424  
12 3     3   21 use PDF::API2::Basic::PDF::Utils;
  3         6  
  3         223  
13 3     3   19 use Scalar::Util qw(weaken);
  3         9  
  3         1983  
14              
15             sub new {
16 4     4 1 13 my ($class, $pdf, $file, $name) = @_;
17 4         26 my $fh = IO::File->new();
18              
19 4 50       167 $class = ref($class) if ref($class);
20              
21 4   33     26 my $self = $class->SUPER::new($pdf, $name || 'Jx' . pdfkey());
22 4 50       14 $pdf->new_obj($self) unless $self->is_obj($pdf);
23              
24 4         12 $self->{' apipdf'} = $pdf;
25 4         12 weaken $self->{' apipdf'};
26              
27 4 100       10 if (ref($file)) {
28 1         2 $fh = $file;
29             }
30             else {
31 3 100       160 open $fh, "<", $file or die "$!: $file";
32             }
33 3         30 binmode $fh, ':raw';
34              
35 3         11 $self->read_jpeg($fh);
36              
37 3 100       8 if (ref($file)) {
38 1         13 seek $fh, 0, 0;
39 1         4 $self->{' stream'} = '';
40 1         2 my $buf = '';
41 1         12 while (!eof($fh)) {
42 2         12 read $fh, $buf, 512;
43 2         9 $self->{' stream'} .= $buf;
44             }
45 1         8 $self->{'Length'} = PDFNum(length $self->{' stream'});
46             }
47             else {
48 2         39 $self->{'Length'} = PDFNum(-s $file);
49 2         6 $self->{' streamfile'} = $file;
50             }
51              
52 3         25 $self->filters('DCTDecode');
53 3         7 $self->{' nofilt'} = 1;
54              
55 3         260 return $self;
56             }
57              
58             sub read_jpeg {
59 3     3 0 12 my ($self, $fh) = @_;
60 3         17 my ($buf, $p, $h, $w, $c, $ff, $mark, $len);
61              
62 3         35 $fh->seek(0,0);
63 3         65 $fh->read($buf,2);
64 3         113 while (1) {
65 15         44 $fh->read($buf, 4);
66 15         103 my ($ff, $mark, $len) = unpack('CCn', $buf);
67 15 50       39 last if $ff != 0xFF;
68 15 50 33     55 last if $mark == 0xDA || $mark == 0xD9; # SOS/EOI
69 15 50       37 last if $len < 2;
70 15 50       53 last if $fh->eof();
71 15         110 $fh->read($buf, $len - 2);
72 15 100       78 next if $mark == 0xFE;
73 12 100 66     34 next if $mark >= 0xE0 && $mark <= 0xEF;
74 9 50 66     57 if ($mark >= 0xC0 && $mark <= 0xCF && $mark != 0xC4 && $mark != 0xC8 && $mark != 0xCC) {
      66        
      66        
      33        
75 3         19 ($p, $h, $w, $c) = unpack('CnnC', substr($buf, 0, 6));
76 3         9 last;
77             }
78             }
79              
80 3         24 $self->width($w);
81 3         15 $self->height($h);
82 3         13 $self->bpc($p);
83              
84 3 50 33     26 if (defined($c) and $c == 3) {
    0 0        
    0 0        
85 3         15 $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;