Filename | /usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/ImageInfo.pm |
Statements | Executed 30 statements in 4.22ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 141µs | 311µs | new | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 34µs | 34µs | BEGIN@83 | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 30µs | 55µs | BEGIN@86 | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 24µs | 30µs | BEGIN@87 | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 22µs | 159µs | BEGIN@84 | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 20µs | 29µs | BEGIN@85 | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 20µs | 94µs | BEGIN@90 | Mail::SpamAssassin::Plugin::ImageInfo::
1 | 1 | 1 | 20µs | 72µs | BEGIN@88 | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | __ANON__[:141] | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | __ANON__[:179] | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | __ANON__[:216] | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | _get_images | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | image_count | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | image_name_regex | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | image_named | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | image_size_exact | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | image_size_range | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | image_to_text_ratio | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | pixel_coverage | Mail::SpamAssassin::Plugin::ImageInfo::
0 | 0 | 0 | 0s | 0s | result_check | Mail::SpamAssassin::Plugin::ImageInfo::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # <@LICENSE> | ||||
2 | # Licensed to the Apache Software Foundation (ASF) under one or more | ||||
3 | # contributor license agreements. See the NOTICE file distributed with | ||||
4 | # this work for additional information regarding copyright ownership. | ||||
5 | # The ASF licenses this file to you under the Apache License, Version 2.0 | ||||
6 | # (the "License"); you may not use this file except in compliance with | ||||
7 | # the License. You may obtain a copy of the License at: | ||||
8 | # | ||||
9 | # http://www.apache.org/licenses/LICENSE-2.0 | ||||
10 | # | ||||
11 | # Unless required by applicable law or agreed to in writing, software | ||||
12 | # distributed under the License is distributed on an "AS IS" BASIS, | ||||
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
14 | # See the License for the specific language governing permissions and | ||||
15 | # limitations under the License. | ||||
16 | # </@LICENSE> | ||||
17 | # | ||||
18 | # ------------------------------------------------------- | ||||
19 | # ImageInfo Plugin for SpamAssassin | ||||
20 | # Version: 0.7 | ||||
21 | # Created: 2006-08-02 | ||||
22 | # Modified: 2007-01-17 | ||||
23 | # | ||||
24 | # Changes: | ||||
25 | # 0.7 - added image_name_regex to allow pattern matching on the image name | ||||
26 | # - added support for image/pjpeg content types (progressive jpeg) | ||||
27 | # - updated imageinfo.cf with a few sample rules for using image_name_regex() | ||||
28 | # 0.6 - fixed dems_ bug in image_size_range_ | ||||
29 | # 0.5 - added image_named and image_to_text_ratio | ||||
30 | # 0.4 - added image_size_exact and image_size_range | ||||
31 | # 0.3 - added jpeg support | ||||
32 | # 0.2 - optimized by theo | ||||
33 | # 0.1 - added gif/png support | ||||
34 | # | ||||
35 | # | ||||
36 | # Usage: | ||||
37 | # image_count() | ||||
38 | # | ||||
39 | # body RULENAME eval:image_count(<type>,<min>,[max]) | ||||
40 | # type: 'all','gif','png', or 'jpeg' | ||||
41 | # min: required, message contains at least this | ||||
42 | # many images | ||||
43 | # max: optional, if specified, message must not | ||||
44 | # contain more than this number of images | ||||
45 | # | ||||
46 | # image_count() examples | ||||
47 | # | ||||
48 | # body ONE_IMAGE eval:image_count('all',1,1) | ||||
49 | # body ONE_OR_MORE_IMAGES eval:image_count('all',1) | ||||
50 | # body ONE_PNG eval:image_count('png',1,1) | ||||
51 | # body TWO_GIFS eval:image_count('gif',2,2) | ||||
52 | # body MANY_JPEGS eval:image_count('gif',5) | ||||
53 | # | ||||
54 | # pixel_coverage() | ||||
55 | # | ||||
56 | # body RULENAME eval:pixel_coverage(<type>,<min>,[max]) | ||||
57 | # type: 'all','gif','png', or 'jpeg' | ||||
58 | # min: required, message contains at least this | ||||
59 | # much pixel area | ||||
60 | # max: optional, if specified, message must not | ||||
61 | # contain more than this much pixel area | ||||
62 | # | ||||
63 | # pixel_coverage() examples | ||||
64 | # | ||||
65 | # body LARGE_IMAGE_AREA eval:pixel_coverage('all',150000) # catches any images that are 150k pixel/sq or higher | ||||
66 | # body SMALL_GIF_AREA eval:pixel_coverage('gif',1,40000) # catches only gifs that 1 to 40k pixel/sql | ||||
67 | # | ||||
68 | # image_name_regex() | ||||
69 | # | ||||
70 | # body RULENAME eval:image_name_regex(<regex>) | ||||
71 | # regex: full quoted regexp, see examples below | ||||
72 | # | ||||
73 | # image_name_regex() examples | ||||
74 | # | ||||
75 | # body CG_DOUBLEDOT_GIF eval:image_name_regex('/^\w{2,9}\.\.gif$/i') # catches double dot gifs abcd..gif | ||||
76 | # | ||||
77 | # | ||||
78 | # | ||||
79 | # ------------------------------------------------------- | ||||
80 | |||||
81 | package Mail::SpamAssassin::Plugin::ImageInfo; | ||||
82 | |||||
83 | 2 | 63µs | 1 | 34µs | # spent 34µs within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@83 which was called:
# once (34µs+0s) by Mail::SpamAssassin::PluginHandler::load_plugin at line 83 # spent 34µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@83 |
84 | 2 | 58µs | 2 | 296µs | # spent 159µs (22+137) within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@84 which was called:
# once (22µs+137µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 84 # spent 159µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@84
# spent 137µs making 1 call to Exporter::import |
85 | 2 | 53µs | 2 | 38µs | # spent 29µs (20+9) within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@85 which was called:
# once (20µs+9µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 85 # spent 29µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@85
# spent 9µs making 1 call to strict::import |
86 | 2 | 53µs | 2 | 80µs | # spent 55µs (30+25) within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@86 which was called:
# once (30µs+25µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 86 # spent 55µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@86
# spent 25µs making 1 call to warnings::import |
87 | 2 | 55µs | 2 | 37µs | # spent 30µs (24+6) within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@87 which was called:
# once (24µs+6µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 87 # spent 30µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@87
# spent 6µs making 1 call to bytes::import |
88 | 2 | 65µs | 2 | 125µs | # spent 72µs (20+53) within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@88 which was called:
# once (20µs+53µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 88 # spent 72µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@88
# spent 53µs making 1 call to re::import |
89 | |||||
90 | 2 | 3.74ms | 2 | 167µs | # spent 94µs (20+73) within Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@90 which was called:
# once (20µs+73µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 90 # spent 94µs making 1 call to Mail::SpamAssassin::Plugin::ImageInfo::BEGIN@90
# spent 73µs making 1 call to vars::import |
91 | 1 | 15µs | @ISA = qw(Mail::SpamAssassin::Plugin); | ||
92 | |||||
93 | # constructor: register the eval rule | ||||
94 | # spent 311µs (141+171) within Mail::SpamAssassin::Plugin::ImageInfo::new which was called:
# once (141µs+171µs) by Mail::SpamAssassin::PluginHandler::load_plugin at line 1 of (eval 109)[Mail/SpamAssassin/PluginHandler.pm:129] | ||||
95 | 1 | 2µs | my $class = shift; | ||
96 | 1 | 2µs | my $mailsaobject = shift; | ||
97 | |||||
98 | # some boilerplate... | ||||
99 | 1 | 2µs | $class = ref($class) || $class; | ||
100 | 1 | 11µs | 1 | 20µs | my $self = $class->SUPER::new($mailsaobject); # spent 20µs making 1 call to Mail::SpamAssassin::Plugin::new |
101 | 1 | 2µs | bless ($self, $class); | ||
102 | |||||
103 | 1 | 12µs | 1 | 34µs | $self->register_eval_rule ("image_count"); # spent 34µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
104 | 1 | 6µs | 1 | 21µs | $self->register_eval_rule ("pixel_coverage"); # spent 21µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
105 | 1 | 6µs | 1 | 19µs | $self->register_eval_rule ("image_size_exact"); # spent 19µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
106 | 1 | 6µs | 1 | 23µs | $self->register_eval_rule ("image_size_range"); # spent 23µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
107 | 1 | 6µs | 1 | 18µs | $self->register_eval_rule ("image_named"); # spent 18µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
108 | 1 | 6µs | 1 | 18µs | $self->register_eval_rule ("image_name_regex"); # spent 18µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
109 | 1 | 6µs | 1 | 19µs | $self->register_eval_rule ("image_to_text_ratio"); # spent 19µs making 1 call to Mail::SpamAssassin::Plugin::register_eval_rule |
110 | |||||
111 | 1 | 10µs | return $self; | ||
112 | } | ||||
113 | |||||
114 | # ----------------------------------------- | ||||
115 | |||||
116 | my %get_details = ( | ||||
117 | 'gif' => sub { | ||||
118 | my ($pms, $part) = @_; | ||||
119 | my $header = $part->decode(13); | ||||
120 | |||||
121 | # make sure this is actually a valid gif.. | ||||
122 | return unless $header =~ s/^GIF(8[79]a)//; | ||||
123 | my $version = $1; | ||||
124 | |||||
125 | my ($width, $height, $packed, $bgcolor, $aspect) = unpack("vvCCC", $header); | ||||
126 | my $color_table_size = 1 << (($packed & 0x07) + 1); | ||||
127 | |||||
128 | # for future enhancements | ||||
129 | #my $global_color_table = $packed & 0x80; | ||||
130 | #my $has_global_color_table = $global_color_table ? 1 : 0; | ||||
131 | #my $sorted_colors = ($packed & 0x08)?1:0; | ||||
132 | #my $resolution = ((($packed & 0x70) >> 4) + 1); | ||||
133 | |||||
134 | if ($height && $width) { | ||||
135 | my $area = $width * $height; | ||||
136 | $pms->{imageinfo}->{pc_gif} += $area; | ||||
137 | $pms->{imageinfo}->{dems_gif}->{"${height}x${width}"} = 1; | ||||
138 | $pms->{imageinfo}->{names_all}->{$part->{'name'}} = 1 if $part->{'name'}; | ||||
139 | dbg("imageinfo: gif image ".($part->{'name'} ? $part->{'name'} : '')." is $height x $width pixels ($area pixels sq.), with $color_table_size color table"); | ||||
140 | } | ||||
141 | }, | ||||
142 | |||||
143 | 'png' => sub { | ||||
144 | my ($pms, $part) = @_; | ||||
145 | my $data = $part->decode(); | ||||
146 | |||||
147 | return unless (substr($data, 0, 8) eq "\x89PNG\x0d\x0a\x1a\x0a"); | ||||
148 | |||||
149 | my $datalen = length $data; | ||||
150 | my $pos = 8; | ||||
151 | my $chunksize = 8; | ||||
152 | my ($width, $height) = ( 0, 0 ); | ||||
153 | my ($depth, $ctype, $compression, $filter, $interlace); | ||||
154 | |||||
155 | while ($pos < $datalen) { | ||||
156 | my ($len, $type) = unpack("Na4", substr($data, $pos, $chunksize)); | ||||
157 | $pos += $chunksize; | ||||
158 | |||||
159 | last if $type eq "IEND"; # end of png image. | ||||
160 | |||||
161 | next unless ( $type eq "IHDR" && $len == 13 ); | ||||
162 | |||||
163 | my $bytes = substr($data, $pos, $len + 4); | ||||
164 | my $crc = unpack("N", substr($bytes, -4, 4, "")); | ||||
165 | |||||
166 | if ($type eq "IHDR" && $len == 13) { | ||||
167 | ($width, $height, $depth, $ctype, $compression, $filter, $interlace) = unpack("NNCCCCC", $bytes); | ||||
168 | last; | ||||
169 | } | ||||
170 | } | ||||
171 | |||||
172 | if ($height && $width) { | ||||
173 | my $area = $width * $height; | ||||
174 | $pms->{imageinfo}->{pc_png} += $area; | ||||
175 | $pms->{imageinfo}->{dems_png}->{"${height}x${width}"} = 1; | ||||
176 | $pms->{imageinfo}->{names_all}->{$part->{'name'}} = 1 if $part->{'name'}; | ||||
177 | dbg("imageinfo: png image ".($part->{'name'} ? $part->{'name'} : '')." is $height x $width pixels ($area pixels sq.)"); | ||||
178 | } | ||||
179 | }, | ||||
180 | |||||
181 | 'jpeg' => sub { | ||||
182 | my ($pms, $part) = @_; | ||||
183 | |||||
184 | my $data = $part->decode(); | ||||
185 | |||||
186 | my $index = substr($data, 0, 2); | ||||
187 | return unless $index eq "\xFF\xD8"; | ||||
188 | |||||
189 | my $pos = 2; | ||||
190 | my $chunksize = 4; | ||||
191 | my ($prec, $height, $width, $comps) = (undef,0,0,undef); | ||||
192 | while (1) { | ||||
193 | my ($xx, $mark, $len) = unpack("CCn", substr($data, $pos, $chunksize)); | ||||
194 | last if (!defined $xx || $xx != 0xFF); | ||||
195 | last if (!defined $mark || $mark == 0xDA || $mark == 0xD9); | ||||
196 | last if (!defined $len || $len < 2); | ||||
197 | $pos += $chunksize; | ||||
198 | my $block = substr($data, $pos, $len - 2); | ||||
199 | my $blocklen = length($block); | ||||
200 | if ( ($mark >= 0xC0 && $mark <= 0xC3) || ($mark >= 0xC5 && $mark <= 0xC7) || | ||||
201 | ($mark >= 0xC9 && $mark <= 0xCB) || ($mark >= 0xCD && $mark <= 0xCF) ) { | ||||
202 | ($prec, $height, $width, $comps) = unpack("CnnC", substr($block, 0, 6, "")); | ||||
203 | last; | ||||
204 | } | ||||
205 | $pos += $blocklen; | ||||
206 | } | ||||
207 | |||||
208 | if ($height && $width) { | ||||
209 | my $area = $height * $width; | ||||
210 | $pms->{imageinfo}->{pc_jpeg} += $area; | ||||
211 | $pms->{imageinfo}->{dems_jpeg}->{"${height}x${width}"} = 1; | ||||
212 | $pms->{imageinfo}->{names_all}->{$part->{'name'}} = 1 if $part->{'name'}; | ||||
213 | dbg("imageinfo: jpeg image ".($part->{'name'} ? $part->{'name'} : '')." is $height x $width pixels ($area pixels sq.)"); | ||||
214 | } | ||||
215 | |||||
216 | }, | ||||
217 | |||||
218 | 1 | 23µs | ); | ||
219 | |||||
220 | sub _get_images { | ||||
221 | my ($self,$pms) = @_; | ||||
222 | my $result = 0; | ||||
223 | |||||
224 | foreach my $type ( 'all', keys %get_details ) { | ||||
225 | $pms->{'imageinfo'}->{"pc_$type"} = 0; | ||||
226 | $pms->{'imageinfo'}->{"count_$type"} = 0; | ||||
227 | } | ||||
228 | |||||
229 | foreach my $p ($pms->{msg}->find_parts(qr@^image/(?:gif|png|jpeg)$@, 1)) { | ||||
230 | # make sure its base64 encoded | ||||
231 | my $cte = lc($p->get_header('content-transfer-encoding') || ''); | ||||
232 | next if ($cte !~ /^base64$/); | ||||
233 | |||||
234 | my ($type) = $p->{'type'} =~ m@/(\w+)$@; | ||||
235 | if ($type && exists $get_details{$type}) { | ||||
236 | $get_details{$type}->($pms,$p); | ||||
237 | $pms->{'imageinfo'}->{"count_$type"} ++; | ||||
238 | } | ||||
239 | } | ||||
240 | |||||
241 | foreach my $name ( keys %{$pms->{'imageinfo'}->{"names_all"}} ) { | ||||
242 | dbg("imageinfo: image name $name found"); | ||||
243 | } | ||||
244 | |||||
245 | foreach my $type ( keys %get_details ) { | ||||
246 | $pms->{'imageinfo'}->{'pc_all'} += $pms->{'imageinfo'}->{"pc_$type"}; | ||||
247 | $pms->{'imageinfo'}->{'count_all'} += $pms->{'imageinfo'}->{"count_$type"}; | ||||
248 | foreach my $dem ( keys %{$pms->{'imageinfo'}->{"dems_$type"}} ) { | ||||
249 | dbg("imageinfo: adding $dem to dems_all"); | ||||
250 | $pms->{'imageinfo'}->{'dems_all'}->{$dem} = 1; | ||||
251 | } | ||||
252 | } | ||||
253 | } | ||||
254 | |||||
255 | # ----------------------------------------- | ||||
256 | |||||
257 | sub image_named { | ||||
258 | my ($self,$pms,$body,$name) = @_; | ||||
259 | return unless (defined $name); | ||||
260 | |||||
261 | # make sure we have image data read in. | ||||
262 | if (!exists $pms->{'imageinfo'}) { | ||||
263 | $self->_get_images($pms); | ||||
264 | } | ||||
265 | |||||
266 | return 0 unless (exists $pms->{'imageinfo'}->{"names_all"}); | ||||
267 | return 1 if (exists $pms->{'imageinfo'}->{"names_all"}->{$name}); | ||||
268 | return 0; | ||||
269 | } | ||||
270 | |||||
271 | # ----------------------------------------- | ||||
272 | |||||
273 | sub image_name_regex { | ||||
274 | my ($self,$pms,$body,$re) = @_; | ||||
275 | return unless (defined $re); | ||||
276 | |||||
277 | # make sure we have image data read in. | ||||
278 | if (!exists $pms->{'imageinfo'}) { | ||||
279 | $self->_get_images($pms); | ||||
280 | } | ||||
281 | |||||
282 | return 0 unless (exists $pms->{'imageinfo'}->{"names_all"}); | ||||
283 | |||||
284 | my $hit = 0; | ||||
285 | foreach my $name (keys %{$pms->{'imageinfo'}->{"names_all"}}) { | ||||
286 | dbg("imageinfo: checking image named $name against regex $re"); | ||||
287 | if (eval { $name =~ /$re/ }) { $hit = 1 } | ||||
288 | dbg("imageinfo: error in regex /$re/ - $@") if $@; | ||||
289 | if ($hit) { | ||||
290 | dbg("imageinfo: image_name_regex hit on $name"); | ||||
291 | return 1; | ||||
292 | } | ||||
293 | } | ||||
294 | return 0; | ||||
295 | |||||
296 | } | ||||
297 | |||||
298 | # ----------------------------------------- | ||||
299 | |||||
300 | sub image_count { | ||||
301 | my ($self,$pms,$body,$type,$min,$max) = @_; | ||||
302 | |||||
303 | return unless defined $min; | ||||
304 | |||||
305 | # make sure we have image data read in. | ||||
306 | if (!exists $pms->{'imageinfo'}) { | ||||
307 | $self->_get_images($pms); | ||||
308 | } | ||||
309 | |||||
310 | # dbg("imageinfo: count: $min, ".($max ? $max:'').", $type, ".$pms->{'imageinfo'}->{"count_$type"}); | ||||
311 | return result_check($min, $max, $pms->{'imageinfo'}->{"count_$type"}); | ||||
312 | } | ||||
313 | |||||
314 | # ----------------------------------------- | ||||
315 | |||||
316 | sub pixel_coverage { | ||||
317 | my ($self,$pms,$body,$type,$min,$max) = @_; | ||||
318 | |||||
319 | return unless (defined $type && defined $min); | ||||
320 | |||||
321 | # make sure we have image data read in. | ||||
322 | if (!exists $pms->{'imageinfo'}) { | ||||
323 | $self->_get_images($pms); | ||||
324 | } | ||||
325 | |||||
326 | # dbg("imageinfo: pc_$type: $min, ".($max ? $max:'').", $type, ".$pms->{'imageinfo'}->{"pc_$type"}); | ||||
327 | return result_check($min, $max, $pms->{'imageinfo'}->{"pc_$type"}); | ||||
328 | } | ||||
329 | |||||
330 | # ----------------------------------------- | ||||
331 | |||||
332 | sub image_to_text_ratio { | ||||
333 | my ($self,$pms,$body,$type,$min,$max) = @_; | ||||
334 | return unless (defined $type && defined $min && defined $max); | ||||
335 | |||||
336 | # make sure we have image data read in. | ||||
337 | if (!exists $pms->{'imageinfo'}) { | ||||
338 | $self->_get_images($pms); | ||||
339 | } | ||||
340 | |||||
341 | # depending on how you call this eval (body vs rawbody), | ||||
342 | # the $textlen will differ. | ||||
343 | my $textlen = length(join('',@$body)); | ||||
344 | |||||
345 | return 0 unless ( $textlen > 0 && exists $pms->{'imageinfo'}->{"pc_$type"} && $pms->{'imageinfo'}->{"pc_$type"} > 0); | ||||
346 | |||||
347 | my $ratio = $textlen / $pms->{'imageinfo'}->{"pc_$type"}; | ||||
348 | dbg("imageinfo: image ratio=$ratio, min=$min max=$max"); | ||||
349 | return result_check($min, $max, $ratio, 1); | ||||
350 | } | ||||
351 | |||||
352 | # ----------------------------------------- | ||||
353 | |||||
354 | sub image_size_exact { | ||||
355 | my ($self,$pms,$body,$type,$height,$width) = @_; | ||||
356 | return unless (defined $type && defined $height && defined $width); | ||||
357 | |||||
358 | # make sure we have image data read in. | ||||
359 | if (!exists $pms->{'imageinfo'}) { | ||||
360 | $self->_get_images($pms); | ||||
361 | } | ||||
362 | |||||
363 | return 0 unless (exists $pms->{'imageinfo'}->{"dems_$type"}); | ||||
364 | return 1 if (exists $pms->{'imageinfo'}->{"dems_$type"}->{"${height}x${width}"}); | ||||
365 | return 0; | ||||
366 | } | ||||
367 | |||||
368 | # ----------------------------------------- | ||||
369 | |||||
370 | sub image_size_range { | ||||
371 | my ($self,$pms,$body,$type,$minh,$minw,$maxh,$maxw) = @_; | ||||
372 | return unless (defined $type && defined $minh && defined $minw); | ||||
373 | |||||
374 | # make sure we have image data read in. | ||||
375 | if (!exists $pms->{'imageinfo'}) { | ||||
376 | $self->_get_images($pms); | ||||
377 | } | ||||
378 | |||||
379 | my $name = 'dems_'.$type; | ||||
380 | return unless (exists $pms->{'imageinfo'}->{$name}); | ||||
381 | |||||
382 | foreach my $dem ( keys %{$pms->{'imageinfo'}->{"dems_$type"}}) { | ||||
383 | my ($h,$w) = split(/x/,$dem); | ||||
384 | next if ($h < $minh); # height less than min height | ||||
385 | next if ($w < $minw); # width less than min width | ||||
386 | next if (defined $maxh && $h > $maxh); # height more than max height | ||||
387 | next if (defined $maxw && $w > $maxw); # width more than max width | ||||
388 | |||||
389 | # if we make it here, we have a match | ||||
390 | return 1; | ||||
391 | } | ||||
392 | |||||
393 | return 0; | ||||
394 | } | ||||
395 | |||||
396 | # ----------------------------------------- | ||||
397 | |||||
398 | sub result_check { | ||||
399 | my ($min, $max, $value, $nomaxequal) = @_; | ||||
400 | return 0 unless defined $value; | ||||
401 | return 0 if ($value < $min); | ||||
402 | return 0 if (defined $max && $value > $max); | ||||
403 | return 0 if (defined $nomaxequal && $nomaxequal && $value == $max); | ||||
404 | return 1; | ||||
405 | } | ||||
406 | |||||
407 | # ----------------------------------------- | ||||
408 | |||||
409 | 1 | 13µs | 1; |