File Coverage

lib/Image/Info/BMP.pm
Criterion Covered Total %
statement 34 55 61.8
branch 10 16 62.5
condition 6 9 66.6
subroutine 3 3 100.0
pod 1 1 100.0
total 54 84 64.2


line stmt bran cond sub pod time code
1             package Image::Info::BMP;
2             $VERSION = '1.04';
3 3     3   8125 use strict;
  3         5  
  3         161  
4              
5 3     3   32 use constant _CAN_LITTLE_ENDIAN_PACK => $] >= 5.009002;
  3         6  
  3         2476  
6              
7             sub process_file {
8 4     4 1 8 my($info, $source, $opts) = @_;
9 4         6 my(@comments, @warnings, @header, %info, $buf, $total);
10              
11 4 50       45 read($source, $buf, 54) == 54 or die "Can't reread BMP header: $!";
12 4         26 @header = unpack((_CAN_LITTLE_ENDIAN_PACK
13             ? "vVv2V2Vl<v2V2V2V2"
14             : "vVv2V2V2v2V2V2V2"
15             ), $buf);
16 4         8 $total += length($buf);
17              
18 4 100 66     21 if( $header[9] && $header[9] < 24 ){
19 3         12 $info->push_info(0, "color_type" => "Indexed-RGB");
20             }
21             else{
22 1         5 $info->push_info(0, "color_type" => "RGB");
23             }
24 4         14 $info->push_info(0, "file_media_type" => "image/bmp");
25 4 100 66     14 if( $header[10] == 1 || $header[10] == 2){
26 3         7 $info->push_info(0, "file_ext" => "rle");
27             }
28             else{
29 1         4 $info->push_info(0, "file_ext" => "bmp"); # || dib
30             }
31              
32 4         15 $info->push_info(0, "height", (_CAN_LITTLE_ENDIAN_PACK
33             ? abs($header[7])
34             : ($header[7] >= 2**31 ? 2**32 - $header[7] : $header[7])
35             ));
36 4         19 $info->push_info(0, "resolution", "$header[12]/$header[13]");
37 4         16 $info->push_info(0, "width", $header[6]);
38 4         9 $info->push_info(0, "BitsPerSample" => $header[9]);
39 4         40 $info->push_info(0, "SamplesPerPixel", $header[8]);
40              
41 4         10 $info->push_info(0, "BMP_ColorsImportant", $header[15]);
42 4 100       14 $info->push_info(0, "BMP_Origin",
43             $header[7]>1 ? 1 : 0 );
44 4         16 $info->push_info(0, "ColorTableSize", $header[14]);
45 4         15 $info->push_info(0, "Compression", [
46             'none',
47             'RLE8',
48             'RLE4',
49             'BITFIELDS', #V4
50             'JPEG', #V5
51             'PNG', #V5
52             ]->[$header[10]]);
53             #Version 5 Header amendments
54             # XXX Discard for now, need a test image
55 4 50       11 if( $header[5] > 40 ){
56 0         0 read($source, $buf, $header[5]-40); # XXX test
57 0         0 $total += length($buf);
58 0         0 my @v5 = unpack("V38", $buf);
59 0         0 splice(@v5, 5, 27);
60 0         0 $info->push_info(0, "BMP_MaskRed", $v5[0]);
61 0         0 $info->push_info(0, "BMP_MaskGreen", $v5[1]);
62 0         0 $info->push_info(0, "BMP_MaskBlue", $v5[2]);
63 0         0 $info->push_info(0, "BMP_MaskAlpha", $v5[3]);
64             # $info->push_info(0, "BMP_color_type", $v5[4]);
65 0         0 $info->push_info(0, "BMP_GammaRed", $v5[5]);
66 0         0 $info->push_info(0, "BMP_GammaGreen", $v5[6]);
67 0         0 $info->push_info(0, "BMP_GammaBlue", $v5[7]);
68             }
69 4 50 66     18 if( $header[9] < 24 && $opts->{ColorPalette} ){
70 0         0 my(@color, @palette);
71 0         0 for(my $i=0; $i<$header[14]; $i++){
72 0 0       0 read($source, $buf, 4) == 4 or die "Can't read: $!";
73 0         0 $total += length($buf);
74 0         0 @color = unpack("C3", $buf);
75             # Damn M$, BGR instead of RGB
76 0         0 push @palette, sprintf("#%02x%02x%02x",
77             $color[2], $color[1], $color[0]);
78             }
79 0         0 $info->push_info(0, "ColorPalette", @palette);
80             }
81              
82             #Verify size # XXX Cheat and do -s if it's an actual file?
83 4         26 while( read($source, $buf, 1024) ){
84 16         43 $total += length($buf);
85             }
86 4 50       13 if( $header[1] != $total ){
87 0         0 push @warnings, "Size mismatch."
88             }
89              
90 4         10 for (@comments) {
91 0         0 $info->push_info(0, "Comment", $_);
92             }
93              
94 4         15 for (@warnings) {
95 0           $info->push_info(0, "Warn", $_);
96             }
97             }
98             1;
99             __END__
100              
101             =pod
102              
103             =head1 NAME
104              
105             Image::Info::BMP - Windows Device Independent Bitmap support for Image::Info
106              
107             =head1 SYNOPSIS
108              
109             use Image::Info qw(image_info dim);
110              
111             my $info = image_info("image.bmp");
112             if (my $error = $info->{error}) {
113             die "Can't parse image info: $error\n";
114             }
115             my $color = $info->{color_type};
116              
117             my($w, $h) = dim($info);
118              
119             =head1 DESCRIPTION
120              
121             This module supplies the standard key names
122             except for Gamma, Interlace, LastModificationTime, as well as:
123              
124             =over
125              
126             =item BMP_ColorsImportant
127              
128             Specifies the number of color indexes that are required for
129             displaying the bitmap. If this value is zero, all colors are required.
130              
131             =item BMP_Origin
132              
133             If true the bitmap is a bottom-up DIB and its origin is the lower-left corner.
134             Otherwise, the bitmap is a top-down DIB and its origin is the upper-left
135             corner.
136              
137             =item ColorPalette
138              
139             Reference to an array of all colors used.
140             This key is only present if C<image_info> is invoked
141             as C<image_info($file, ColorPalette=E<gt>1)>.
142              
143             =item ColorTableSize
144              
145             The number of colors the image uses.
146             If 0 then this is a true color image.
147             The number of colors I<available> is 2 ^ B<BitsPerSample>.
148              
149             =back
150              
151             =head1 METHODS
152              
153             =head2 process_file()
154            
155             $info->process_file($source, $options);
156              
157             Processes one file and sets the found info fields in the C<$info> object.
158              
159             =head1 SEE ALSO
160              
161             L<Image::Info>
162              
163             =head1 NOTES
164              
165             For more information about BMP see L<http://msdn.microsoft.com>.
166              
167             Random notes:
168              
169             warn if height is negative and compress is not RGB or BITFILEDS (0 or 3)
170             ICO and CUR support?
171             ### v5
172             If bit depth is 0, it relies upon underlying JPG/PNG :-(
173             Extra Information
174             DWORD bV5RedMask;
175             DWORD bV5GreenMask;
176             DWORD bV5BlueMask;
177             DWORD bV5AlphaMask;
178             DWORD bV5CSType;
179             CIEXYZTRIPLE bV5EndPoints; #3*CIEXYZ #CIEXYZ = 3*FXPT2DOT30#FXPT2DOT30 = long
180             DWORD bV5GammaRed;
181             DWORD bV5GammaGreen;
182             DWORD bV5GammaBlue;
183             DWORD bV5Intent;
184             DWORD bV5ProfileData;
185             DWORD bV5ProfileSize;
186              
187             =head1 DIAGNOSTICS
188              
189             =over
190              
191             =item Size mismatch
192              
193             The image may be correct, but the filesize does not match the internally stored
194             value.
195              
196             =back
197              
198             =head1 BUGS
199              
200             The current implementation only functions on little-endian architectures.
201             Consequently erroneous data concerning compression (including
202             B<file_ext> and B<file_mime_type>) may be reported.
203              
204             =head1 AUTHOR
205              
206             Jerrad Pierce <belg4mit@mit.edu>/<webmaster@pthbb.org>
207              
208             This library is free software; you can redistribute it and/or
209             modify it under the same terms as Perl itself.
210              
211             =begin register
212              
213             MAGIC: /^BM/
214              
215             This module supports the Microsoft Device Independent Bitmap format
216             (BMP, DIB, RLE).
217              
218             For more information see L<Image::Info::BMP>.
219              
220             =end register
221              
222             =cut