line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Imager::Search::Driver::HTML24; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Basic search driver implemented in terms of 8-bit |
4
|
|
|
|
|
|
|
# HTML-style strings ( #003399 ) |
5
|
|
|
|
|
|
|
|
6
|
5
|
|
|
5
|
|
5590
|
use 5.006; |
|
5
|
|
|
|
|
19
|
|
|
5
|
|
|
|
|
200
|
|
7
|
5
|
|
|
5
|
|
28
|
use strict; |
|
5
|
|
|
|
|
12
|
|
|
5
|
|
|
|
|
161
|
|
8
|
5
|
|
|
5
|
|
609
|
use Imager::Search::Match (); |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
81
|
|
9
|
5
|
|
|
5
|
|
563
|
use Imager::Search::Driver (); |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
97
|
|
10
|
|
|
|
|
|
|
|
11
|
5
|
|
|
5
|
|
25
|
use vars qw{$VERSION @ISA}; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
433
|
|
12
|
|
|
|
|
|
|
BEGIN { |
13
|
5
|
|
|
5
|
|
12
|
$VERSION = '1.01'; |
14
|
5
|
|
|
|
|
3306
|
@ISA = 'Imager::Search::Driver'; |
15
|
|
|
|
|
|
|
} |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
##################################################################### |
22
|
|
|
|
|
|
|
# Imager::Search::Driver Methods |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub image_string { |
25
|
3
|
|
|
3
|
1
|
6
|
my $self = shift; |
26
|
3
|
|
|
|
|
4
|
my $imager = shift; |
27
|
3
|
|
|
|
|
7
|
my $string = ''; |
28
|
3
|
|
|
|
|
10
|
my $height = $imager->getheight; |
29
|
3
|
|
|
|
|
35
|
foreach my $row ( 0 .. $height - 1 ) { |
30
|
|
|
|
|
|
|
# Get the string for the row |
31
|
5012
|
|
|
|
|
25284
|
$string .= join('', |
32
|
103
|
|
|
|
|
304
|
map { sprintf( "#%02X%02X%02X", ($_->rgba)[0..2] ) } |
33
|
|
|
|
|
|
|
$imager->getscanline( y => $row ) |
34
|
|
|
|
|
|
|
); |
35
|
|
|
|
|
|
|
} |
36
|
3
|
|
|
|
|
22
|
return \$string; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub pattern_lines { |
40
|
5
|
|
|
5
|
1
|
10
|
my $self = shift; |
41
|
5
|
|
|
|
|
7
|
my $imager = shift; |
42
|
5
|
|
|
|
|
8
|
my @lines = (); |
43
|
5
|
|
|
|
|
16
|
my $height = $imager->getheight; |
44
|
5
|
|
|
|
|
49
|
foreach my $row ( 0 .. $height - 1 ) { |
45
|
54
|
|
|
|
|
103
|
$lines[$row] = $self->pattern_line($imager, $row); |
46
|
|
|
|
|
|
|
} |
47
|
5
|
|
|
|
|
25
|
return \@lines; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub pattern_line { |
51
|
54
|
|
|
54
|
0
|
63
|
my ($self, $imager, $row) = @_; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Get the colour array |
54
|
54
|
|
|
|
|
55
|
my $line = ''; |
55
|
54
|
|
|
|
|
53
|
my $this = ''; |
56
|
54
|
|
|
|
|
63
|
my $more = 1; |
57
|
54
|
|
|
|
|
138
|
foreach my $color ( $imager->getscanline( y => $row ) ) { |
58
|
678
|
|
|
|
|
2999
|
my ($r, $g, $b, undef) = $color->rgba; |
59
|
678
|
|
|
|
|
1174
|
my $string = sprintf("#%02X%02X%02X", $r, $g, $b); |
60
|
678
|
100
|
|
|
|
1162
|
if ( $this eq $string ) { |
61
|
484
|
|
|
|
|
444
|
$more++; |
62
|
484
|
|
|
|
|
596
|
next; |
63
|
|
|
|
|
|
|
} |
64
|
194
|
100
|
|
|
|
389
|
$line .= ($more > 1) ? "(?:$this){$more}" : $this; # if $this; (conveniently works without the if) :) |
65
|
194
|
|
|
|
|
184
|
$more = 1; |
66
|
194
|
|
|
|
|
254
|
$this = $string; |
67
|
|
|
|
|
|
|
} |
68
|
54
|
100
|
|
|
|
508
|
$line .= ($more > 1) ? "(?:$this){$more}" : $this; |
69
|
|
|
|
|
|
|
|
70
|
54
|
|
|
|
|
144
|
return $line; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub pattern_regexp { |
74
|
4
|
|
|
4
|
1
|
21
|
my $self = shift; |
75
|
4
|
|
|
|
|
9
|
my $pattern = shift; |
76
|
4
|
|
|
|
|
7
|
my $width = shift; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# Assemble the regular expression |
79
|
4
|
|
|
|
|
13
|
my $pixels = $width - $pattern->width; |
80
|
4
|
|
|
|
|
17
|
my $newline = '.{' . ($pixels * 7) . '}'; |
81
|
4
|
|
|
|
|
13
|
my $lines = $pattern->lines; |
82
|
4
|
|
|
|
|
18
|
my $string = join( $newline, @$lines ); |
83
|
|
|
|
|
|
|
|
84
|
4
|
|
|
|
|
135
|
return qr/$string/si; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
sub match_object { |
88
|
7
|
|
|
7
|
1
|
12
|
my $self = shift; |
89
|
7
|
|
|
|
|
11
|
my $image = shift; |
90
|
7
|
|
|
|
|
9
|
my $pattern = shift; |
91
|
7
|
|
|
|
|
10
|
my $byte = shift; |
92
|
7
|
|
|
|
|
18
|
my $pixel = $byte / 7; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# If the pixel position isn't an integer we matched |
95
|
|
|
|
|
|
|
# at a position that is not a pixel boundary, and thus |
96
|
|
|
|
|
|
|
# this match is a false positive. Shortcut to fail. |
97
|
7
|
50
|
|
|
|
21
|
unless ( $pixel == int($pixel) ) { |
98
|
0
|
|
|
|
|
0
|
return; # undef or null list |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Calculate the basic geometry of the match |
102
|
7
|
|
|
|
|
21
|
my $top = int( $pixel / $image->width ); |
103
|
7
|
|
|
|
|
16
|
my $left = $pixel % $image->width; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# If the match overlaps the newline boundary or falls off the bottom |
106
|
|
|
|
|
|
|
# of the image, this is also a false positive. Shortcut to fail. |
107
|
7
|
50
|
|
|
|
90
|
if ( $left > $image->width - $pattern->width ) { |
108
|
0
|
|
|
|
|
0
|
return; # undef or null list |
109
|
|
|
|
|
|
|
} |
110
|
7
|
50
|
|
|
|
41
|
if ( $top > $image->height - $pattern->height ) { |
111
|
0
|
|
|
|
|
0
|
return; # undef or null list |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# This is a legitimate match. |
115
|
|
|
|
|
|
|
# Convert to a match object and return. |
116
|
7
|
|
|
|
|
55
|
return Imager::Search::Match->new( |
117
|
|
|
|
|
|
|
name => $pattern->name, |
118
|
|
|
|
|
|
|
top => $top, |
119
|
|
|
|
|
|
|
left => $left, |
120
|
|
|
|
|
|
|
height => $pattern->height, |
121
|
|
|
|
|
|
|
width => $pattern->width, |
122
|
|
|
|
|
|
|
); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
1; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=pod |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head1 NAME |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Imager::Search::Driver::HTML24 - Simple Imager::Search reference driver |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head1 DESCRIPTION |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
B is a simple reference driver for |
136
|
|
|
|
|
|
|
L. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
It uses a HTML color string (such as #RRGGBB) for each pixel, providing |
139
|
|
|
|
|
|
|
both a simple text expression of the colour, as well as a hash pixel |
140
|
|
|
|
|
|
|
separator. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
This colour pattern provides for 24-bit (3 channel, 8-bits per challel) |
143
|
|
|
|
|
|
|
colour depth, suitable for use with the 24-bit L. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Search patterns are compressed, so that a horizontal stream of identical |
146
|
|
|
|
|
|
|
pixels are represented as a single match group. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head1 SUPPORT |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
See the SUPPORT section of the main L module. |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head1 AUTHOR |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
Adam Kennedy Eadamk@cpan.orgE |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head1 COPYRIGHT |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Copyright 2007 Adam Kennedy. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
This program is free software; you can redistribute |
161
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
The full text of the license can be found in the |
164
|
|
|
|
|
|
|
LICENSE file included with this module. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=cut |