File Coverage

blib/lib/Image/JpegCheck.pm
Criterion Covered Total %
statement 52 55 94.5
branch 14 18 77.7
condition 4 6 66.6
subroutine 10 10 100.0
pod 1 1 100.0
total 81 90 90.0


line stmt bran cond sub pod time code
1             package Image::JpegCheck;
2 5     5   149935 use strict;
  5         12  
  5         201  
3 5     5   27 use warnings;
  5         11  
  5         134  
4 5     5   124 use 5.008001;
  5         19  
  5         202  
5 5     5   5498 use bytes;
  5         52  
  5         32  
6 5     5   149 use Fcntl ':seek';
  5         16  
  5         699  
7 5     5   33 use Carp ();
  5         9  
  5         1892  
8             our $VERSION = '0.10';
9             our @ISA = qw/Exporter/;
10             our @EXPORT = ('is_jpeg');
11              
12             sub is_jpeg {
13 4110     4110 1 2340033 my ($file, ) = @_;
14 4110 100       10865 if (ref $file) {
15 4106 100       14659 if (ref $file eq 'GLOB') {
    100          
    50          
16 4         10 return Image::JpegCheck::_is_jpeg($file);
17             } elsif (ref $file eq 'SCALAR') {
18 4101 50   2   46427 open my $fh, '<', $file or die $!;
  2         19  
  2         3  
  2         15  
19 4101         12135 return Image::JpegCheck::_is_jpeg($fh);
20             } elsif (ref $file eq 'Path::Class::File') {
21 0         0 return Image::JpegCheck::_is_jpeg($file->openr);
22             } else {
23 1         246 Carp::croak('is_jpeg requires file-glob or filename');
24             }
25             } else {
26 4 50       306 open my $fh, '<', $file or die $!;
27 4         13 binmode $fh;
28 4         11 my $ret = Image::JpegCheck::_is_jpeg($fh);
29 4         132 close $fh;
30 4         18 return $ret;
31             }
32             }
33              
34             use constant {
35 5         2159 SIZE_FIRST => 0xC0, # Range of segment identifier codes
36             SIZE_LAST => 0xC3, # that hold size info.
37             SECTION_MARKER => "\xFF",
38             SOI => "\xFF\xD8",
39             EOI => "\xFF\xD9",
40             EOI_RE => qr/\xFF\xD9\xFF*$/,
41             READ_SIZE => 512,
42             BYTE_STUFFING => "\xFF"x512,
43 5     5   32 };
  5         10  
44              
45             sub _is_jpeg {
46 4109     4109   6152 my $fh = $_[0];
47 4109         5234 my ($buf, $code, $marker, $len);
48              
49 4109         9081 read($fh, $buf, 2);
50 4109 100       10243 return 0 if $buf ne SOI;
51              
52 4106         4412 while (1) {
53 20524         28686 read($fh, $buf, 2);
54 20524         59401 ($marker, $code) = unpack("a a", $buf); # read segment header
55              
56 20524   66     59821 while ( $code eq SECTION_MARKER && ($marker = $code) ) {
57 108         252 read($fh, $buf, 1);
58 108         659 ($code) = unpack("a", $buf);
59             }
60 20524         27864 read($fh, $buf, 2);
61 20524         31660 $len = unpack( "n", $buf );
62 20524         22975 $code = ord($code);
63              
64 20524 50 66     105261 if ($marker ne SECTION_MARKER) {
    100          
65 0         0 return 0; # invalid marker
66             } elsif (($code >= SIZE_FIRST) && ($code <= SIZE_LAST)) {
67 4106         22280 return 1; # got a size info
68             } else {
69 16418         25060 seek $fh, $len-2, SEEK_CUR; # skip segment body
70             }
71             }
72 0         0 die "should not reach here";
73             }
74              
75             1;
76             __END__