File Coverage

lib/Image/Info/XPM.pm
Criterion Covered Total %
statement 28 70 40.0
branch 3 30 10.0
condition n/a
subroutine 3 5 60.0
pod 1 1 100.0
total 35 106 33.0


line stmt bran cond sub pod time code
1             package Image::Info::XPM;
2             $VERSION = '1.09';
3 3     3   2175 use strict;
  3         5  
  3         154  
4 3     3   495 use Image::Xpm 1.09;
  3         3410  
  3         3083  
5              
6              
7             sub process_file{
8 3     3 1 8 my($info, $source, $opts) = @_;
9              
10             local $SIG{__WARN__} = sub {
11 0     0   0 $info->push_info(0, "Warn", shift);
12 3         27 };
13              
14 3         23 my $i = Image::Xpm->new(-width => 0, -height => 0);
15             # loading the file as a separate step avoids a "-r" test, this would
16             # file with in-memory strings (aka fake files)
17 3         555 $i->load($source);
18              
19 3         2071 $info->push_info(0, "color_type" => "Indexed-RGB");
20 3         10 $info->push_info(0, "file_ext" => "xpm");
21 3         9 $info->push_info(0, "file_media_type" => "image/x-xpixmap");
22 3         10 $info->push_info(0, "height", $i->get(-height));
23 3         9 $info->push_info(0, "resolution", "1/1");
24 3         10 $info->push_info(0, "width", $i->get(-width));
25 3         10 $info->push_info(0, "BitsPerSample" => 8);
26 3         7 $info->push_info(0, "SamplesPerPixel", 1);
27              
28 3         8 $info->push_info(0, "XPM_CharactersPerPixel" => $i->get(-cpp) );
29             # XXX is this always?
30 3         9 $info->push_info(0, "ColorResolution", 8);
31 3         22 $info->push_info(0, "ColorTableSize" => $i->get(-ncolours) );
32 3 50       14 if( $opts->{ColorPalette} ){
33 0         0 $info->push_info(0, "ColorPalette" => [keys %{$i->get(-cindex)}] );
  0         0  
34             }
35 3 50       11 if( $opts->{L1D_Histogram} ){
36             #Do Histograms
37 0         0 my(%RGB, @l1dhist, $R, $G, $B, $color);
38 0         0 for(my $y=0; $y<$i->get(-height); $y++){
39 0         0 for(my $x=0; $x<$i->get(-width); $x++){
40 0         0 $color = $i->xy($x, $y);
41 0 0       0 if( $color =~ /^(none|opaque)$/i ) {
    0          
    0          
    0          
    0          
42 0         0 next;
43             } elsif( $color !~ /^#/ ){
44 0 0       0 unless( exists($RGB{white}) ){
45 0         0 local $_;
46 0 0       0 if( open(RGB, _get_rgb_txt()) ){
47 0         0 while(<RGB>){
48 0 0       0 next if /^\s*!/;
49 0         0 /(\d+)\s+(\d+)\s+(\d+)\s+(.*)/;
50 0         0 $RGB{$4}=[$1,$2,$3];
51             }
52             }
53             else{
54 0         0 $RGB{white} = "0 but true";
55 0         0 $info->push_info(0, "Warn", "Unable to open RGB database, you may need to set \$Image::Info::XPM::RGBLIB");
56             }
57             }
58 0         0 $R = $RGB{$color}->[0];
59 0         0 $G = $RGB{$color}->[1];
60 0         0 $B = $RGB{$color}->[2];
61             }
62             elsif (length $color == 7) {
63 0         0 $R = hex(substr($color,1,2));
64 0         0 $G = hex(substr($color,3,2));
65 0         0 $B = hex(substr($color,5,2));
66             }
67             elsif (length $color == 13) {
68 0         0 $R = hex(substr($color,1,2));
69 0         0 $G = hex(substr($color,5,2));
70 0         0 $B = hex(substr($color,9,2));
71             }
72             elsif (length $color == 4) {
73 0         0 $R = hex(substr($color,1,1))*16;
74 0         0 $G = hex(substr($color,2,1))*16;
75 0         0 $B = hex(substr($color,3,1))*16;
76             }
77             else {
78 0         0 warn "Unexpected length in color specification '$color'";
79             }
80 0 0       0 if( $opts->{L1D_Histogram} ){
81 0         0 $l1dhist[(.3*$R + .59*$G + .11*$B)]++;
82             }
83             }
84             }
85 0 0       0 if( $opts->{L1D_Histogram} ){
86 0         0 $info->push_info(0, "L1D_Histogram", [@l1dhist]);
87             }
88             }
89 3         9 $info->push_info(0, "HotSpotX" => $i->get(-hotx) );
90 3         9 $info->push_info(0, "HotSpotY" => $i->get(-hoty) );
91 3 50       8 $info->push_info(0, 'XPM_Extension-'.ucfirst($i->get(-extname)) => $i->get(-extlines)) if
92             $i->get(-extname);
93              
94 3         35 for (@{$i->get(-comments)}) {
  3         9  
95 0           $info->push_info(0, "Comment", $_);
96             }
97             }
98              
99             sub _get_rgb_txt{
100 0 0   0     return $Image::Info::XPM::RGBLIB if defined $Image::Info::XPM::RGBLIB;
101             # list taken from Tk::ColorEditor
102 0           for my $try(
103             '/usr/local/lib/X11/rgb.txt',
104             '/usr/lib/X11/rgb.txt',
105             '/usr/X11R6/lib/X11/rgb.txt',
106             '/usr/local/X11R5/lib/X11/rgb.txt',
107             '/X11/R5/lib/X11/rgb.txt',
108             '/X11/R4/lib/rgb/rgb.txt',
109             '/usr/openwin/lib/X11/rgb.txt',
110             '/usr/share/X11/rgb.txt', # This is the Debian and RH5 location
111             '/usr/X11/share/X11/rgb.txt', # seen on a Mac OS X 10.5.1 system
112             '/usr/X11R6/share/X11/rgb.txt', # seen on a OpenBSD 4.2 system
113             '/etc/X11R6/rgb.txt',
114             '/etc/X11/rgb.txt', # seen on HP-UX 11.31
115             ){
116 0 0         if( -r $try ){
117 0           $Image::Info::XPM::RGBLIB = $try;
118 0           return $try;
119             }
120             }
121 0           undef;
122             }
123              
124             1;
125             __END__
126              
127             =head1 NAME
128              
129             Image::Info::XPM - XPM support for Image::Info
130              
131             =head1 SYNOPSIS
132              
133             use Image::Info qw(image_info dim);
134              
135             my $info = image_info("image.xpm");
136             if (my $error = $info->{error}) {
137             die "Can't parse image info: $error\n";
138             }
139             my $color = $info->{color_type};
140              
141             my($w, $h) = dim($info);
142              
143             =head1 DESCRIPTION
144              
145             This modules supplies the standard key names
146             except for Compression, Gamma, Interlace, LastModificationTime, as well as:
147              
148             =over
149              
150             =item ColorPalette
151              
152             Reference to an array of all colors used.
153             This key is only present if C<image_info> is invoked
154             as C<image_info($file, ColorPaletteE<gt>=1)>.
155              
156             =item ColorTableSize
157              
158             The number of colors the image uses.
159              
160             =item HotSpotX
161              
162             The x-coord of the image's hotspot.
163             Set to -1 if there is no hotspot.
164              
165             =item HotSpotY
166              
167             The y-coord of the image's hotspot.
168             Set to -1 if there is no hotspot.
169              
170             =item L1D_Histogram
171              
172             Reference to an array representing a one dimensional luminance
173             histogram. This key is only present if C<image_info> is invoked
174             as C<image_info($file, L1D_Histogram=E<gt>1)>. The range is from 0 to 255,
175             however auto-vivification is used so a null field is also 0,
176             and the array may not actually contain 255 fields.
177              
178             =item XPM_CharactersPerPixel
179              
180             This is typically 1 or 2. See L<Image::Xpm>.
181              
182             =item XPM_Extension-.*
183              
184             XPM Extensions (the most common is XPMEXT) if present.
185              
186             =back
187              
188             =head1 METHODS
189              
190             =head2 process_file()
191            
192             $info->process_file($source, $options);
193              
194             Processes one file and sets the found info fields in the C<$info> object.
195              
196             =head1 FILES
197              
198             This module requires L<Image::Xpm>
199              
200             I<$Image::Info::XPM::RGBLIB> is set to F</usr/X11R6/lib/X11/rgb.txt>
201             or an equivalent path (see the C<_get_rgb_txt> function for the
202             complete list) by default, this is used to resolve textual color names
203             to their RGB counterparts.
204              
205             =head1 SEE ALSO
206              
207             L<Image::Info>, L<Image::Xpm>
208              
209             =head1 NOTES
210              
211             For more information about XPM see
212             L<ftp://ftp.x.org/contrib/libraries/xpm-README.html>
213              
214             =head1 CAVEATS
215              
216             While the module attempts to be as robust as possible, it may not recognize
217             older XPMs (Versions 1-3), if this is the case try inserting S</* XPM */>
218             as the first line.
219              
220             =head1 AUTHOR
221              
222             Jerrad Pierce <belg4mit@mit.edu>/<webmaster@pthbb.org>
223              
224             Tels - (c) 2006.
225              
226             Now maintained by Slaven Rezic <srezic@cpan.org>.
227              
228             This library is free software; you can redistribute it and/or
229             modify it under the same terms as Perl itself.
230              
231             =cut
232              
233             =begin register
234              
235             MAGIC: /(^\/\* XPM \*\/)|(static\s+char\s+\*\w+\[\]\s*=\s*{\s*"\d+)/
236              
237             See L<Image::Info::XPM> for details.
238              
239             =end register
240              
241             =cut