| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# ====================================================================== |
|
2
|
|
|
|
|
|
|
# Project: Web Counter Parser |
|
3
|
|
|
|
|
|
|
# Project Leader: Peter Wise |
|
4
|
|
|
|
|
|
|
# Module component: Parse::WebCounter |
|
5
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
6
|
|
|
|
|
|
|
# Module name: Parse::WebCounter |
|
7
|
|
|
|
|
|
|
# Module state: First Release |
|
8
|
|
|
|
|
|
|
# Module notes: Parses Image counters |
|
9
|
|
|
|
|
|
|
# |
|
10
|
|
|
|
|
|
|
# Module filename: Parse::WebCounter.pm |
|
11
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
12
|
|
|
|
|
|
|
# Version Author Date Comment |
|
13
|
|
|
|
|
|
|
# ~~~~~~~~ ~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
14
|
|
|
|
|
|
|
# 0.01 P.J.Wise 08/10/2004 Initial Version |
|
15
|
|
|
|
|
|
|
# 0.02 P.J.Wise 18/12/2006 First Release to CPAN |
|
16
|
|
|
|
|
|
|
# |
|
17
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
18
|
|
|
|
|
|
|
# CVS: |
|
19
|
|
|
|
|
|
|
# ID: $Id: WebCounter.pm,v 1.13 2006/12/19 20:42:27 peter Exp $ |
|
20
|
|
|
|
|
|
|
# |
|
21
|
|
|
|
|
|
|
# ---------------------------------------------------------------------- |
|
22
|
|
|
|
|
|
|
# Notes: |
|
23
|
|
|
|
|
|
|
# ~~~~~~ |
|
24
|
|
|
|
|
|
|
# Module parses web counter images using GD and supplies the numeric |
|
25
|
|
|
|
|
|
|
# value represented by the image. Useful if you have a cron keeping |
|
26
|
|
|
|
|
|
|
# track of the number of hits you are getting per day and you don't |
|
27
|
|
|
|
|
|
|
# have real logs to go by. You will need copies of the images |
|
28
|
|
|
|
|
|
|
# representing the individual digits, or a strip of all of them for |
|
29
|
|
|
|
|
|
|
# it to compare to as the module is not very bright it does a simple |
|
30
|
|
|
|
|
|
|
# image comparison as apposed to any sophisticated image analysis |
|
31
|
|
|
|
|
|
|
# (This is not designed, nor intended to be a Captcha solver). |
|
32
|
|
|
|
|
|
|
# You will need to have GD compiled with support for the image format |
|
33
|
|
|
|
|
|
|
# that your counters are displayed in. (Usually gif) |
|
34
|
|
|
|
|
|
|
# ====================================================================== |
|
35
|
|
|
|
|
|
|
package Parse::WebCounter; |
|
36
|
|
|
|
|
|
|
|
|
37
|
3
|
|
|
3
|
|
135083
|
use 5.008; |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
130
|
|
|
38
|
3
|
|
|
3
|
|
116
|
use strict; |
|
|
3
|
|
|
|
|
8
|
|
|
|
3
|
|
|
|
|
112
|
|
|
39
|
3
|
|
|
3
|
|
18
|
use warnings; |
|
|
3
|
|
|
|
|
8
|
|
|
|
3
|
|
|
|
|
98
|
|
|
40
|
|
|
|
|
|
|
|
|
41
|
3
|
|
|
3
|
|
6786
|
use GD; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
require Exporter; |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# Items to export into callers namespace by default. Note: do not export |
|
48
|
|
|
|
|
|
|
# names by default without a very good reason. Use EXPORT_OK instead. |
|
49
|
|
|
|
|
|
|
# Do not simply export all your public functions/methods/constants. |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# This allows declaration use Parse::WebCounter ':all'; |
|
52
|
|
|
|
|
|
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK |
|
53
|
|
|
|
|
|
|
# will save memory. |
|
54
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( 'all' => [ qw( readImage readDigit |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
) ] ); |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
our @EXPORT = qw( |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
); |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
use vars qw($VERSION); |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$VERSION = '0.02'; |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
72
|
|
|
|
|
|
|
# Parse::WebCounter::new() |
|
73
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
74
|
|
|
|
|
|
|
# Purpose: |
|
75
|
|
|
|
|
|
|
# Constructor |
|
76
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
77
|
|
|
|
|
|
|
# Parameters: |
|
78
|
|
|
|
|
|
|
# takes a Hash or hashref of module parameters recognises the following |
|
79
|
|
|
|
|
|
|
# options |
|
80
|
|
|
|
|
|
|
# Name Default Notes |
|
81
|
|
|
|
|
|
|
# DIGITWIDTH 15 Width of individual digit |
|
82
|
|
|
|
|
|
|
# DIGITHEIGHT 20 Height of individual digit |
|
83
|
|
|
|
|
|
|
# STRIPORDER 1234567890 Order of digits in the image strip (if used) |
|
84
|
|
|
|
|
|
|
# MODE STRIP Use image strip or "DIGITS" |
|
85
|
|
|
|
|
|
|
# TYPE gif File type of images |
|
86
|
|
|
|
|
|
|
# PATTERN a Pattern dir |
|
87
|
|
|
|
|
|
|
# UNKOWNCHAR char Character to use if digit not matched |
|
88
|
|
|
|
|
|
|
# |
|
89
|
|
|
|
|
|
|
# (Image file loaded = PATTERN/STRIP.TYPE or PATTER/0.TYPE -> 9.TYPE) |
|
90
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
|
91
|
|
|
|
|
|
|
# Returns: |
|
92
|
|
|
|
|
|
|
# ObjectRef Self |
|
93
|
|
|
|
|
|
|
# |
|
94
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
95
|
|
|
|
|
|
|
sub new{ |
|
96
|
|
|
|
|
|
|
my $proto = shift; |
|
97
|
|
|
|
|
|
|
my @args = @_; |
|
98
|
|
|
|
|
|
|
my $class = ref($proto) || $proto; |
|
99
|
|
|
|
|
|
|
my $self = {}; |
|
100
|
|
|
|
|
|
|
bless($self,$class); |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
#Defaults... |
|
103
|
|
|
|
|
|
|
$self->{DIGITWIDTH} = 15; |
|
104
|
|
|
|
|
|
|
$self->{DIGITHEIGHT}= 20; |
|
105
|
|
|
|
|
|
|
$self->{STRIPORDER} = "1234567890"; |
|
106
|
|
|
|
|
|
|
$self->{MODE} = "STRIP"; |
|
107
|
|
|
|
|
|
|
$self->{TYPE} = "gif"; |
|
108
|
|
|
|
|
|
|
$self->{PATTERN} = "a"; |
|
109
|
|
|
|
|
|
|
$self->{UNKNOWNCHAR}= "_"; |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
my $rprops; |
|
112
|
|
|
|
|
|
|
if (ref($args[0]) eq 'HASH'){ |
|
113
|
|
|
|
|
|
|
my $rtgash = %{$args[0]}; |
|
114
|
|
|
|
|
|
|
$rprops = $self->_cap_hash($args[0]); |
|
115
|
|
|
|
|
|
|
}else{ |
|
116
|
|
|
|
|
|
|
$rprops = $self->_cap_hash({ @args }); |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
foreach my $k (qw(DIGITWIDTH DIGITHEIGHT STRIPORDER TYPE PATTERN UNKNOWNCHAR)){ |
|
119
|
|
|
|
|
|
|
if (exists($rprops->{$k})){ |
|
120
|
|
|
|
|
|
|
$self->{$k} = $rprops->{$k}; |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
#need to be special with MODE |
|
124
|
|
|
|
|
|
|
if (exists($rprops->{MODE})){ |
|
125
|
|
|
|
|
|
|
$rprops->{MODE} =~ tr/a-z/A-Z/; |
|
126
|
|
|
|
|
|
|
if ($rprops->{MODE} ne "STRIP" && $rprops->{MODE} ne "DIGITS"){ |
|
127
|
|
|
|
|
|
|
warn "Invalid mode " . $rprops->{MODE} . " using default\n"; |
|
128
|
|
|
|
|
|
|
}else{ |
|
129
|
|
|
|
|
|
|
$self->{MODE} = $rprops->{MODE}; |
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
$self->_init(); |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
return $self; |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
140
|
|
|
|
|
|
|
# Parse::WebCounter::_init() |
|
141
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
142
|
|
|
|
|
|
|
# Purpose: |
|
143
|
|
|
|
|
|
|
# Internal function to initialise the class data (loads image strip data) |
|
144
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
145
|
|
|
|
|
|
|
# Parameters: |
|
146
|
|
|
|
|
|
|
# None - pulls data from class object and $ENV |
|
147
|
|
|
|
|
|
|
# |
|
148
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
149
|
|
|
|
|
|
|
# Returns: |
|
150
|
|
|
|
|
|
|
# Nothing |
|
151
|
|
|
|
|
|
|
# |
|
152
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
153
|
|
|
|
|
|
|
sub _init{ |
|
154
|
|
|
|
|
|
|
my $self = shift; |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
if ($self->{MODE} eq "STRIP"){ |
|
157
|
|
|
|
|
|
|
$self->_loadStripImage(); |
|
158
|
|
|
|
|
|
|
}else{ |
|
159
|
|
|
|
|
|
|
$self->_loadDigitImages(); |
|
160
|
|
|
|
|
|
|
} |
|
161
|
|
|
|
|
|
|
} |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
166
|
|
|
|
|
|
|
# Parse::WebCounter::_cap_hash() |
|
167
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
168
|
|
|
|
|
|
|
# Purpose: |
|
169
|
|
|
|
|
|
|
# automagically convert the hash it is given into capitalised keys so users |
|
170
|
|
|
|
|
|
|
# of the module can pass any capitalisation they like as module options |
|
171
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
172
|
|
|
|
|
|
|
# Parameters: |
|
173
|
|
|
|
|
|
|
# HashRef |
|
174
|
|
|
|
|
|
|
# |
|
175
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
176
|
|
|
|
|
|
|
# Returns: |
|
177
|
|
|
|
|
|
|
# HashRef all the keys CAPITALISED |
|
178
|
|
|
|
|
|
|
# |
|
179
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
180
|
|
|
|
|
|
|
sub _cap_hash { |
|
181
|
|
|
|
|
|
|
my $self = shift; |
|
182
|
|
|
|
|
|
|
my $rhash = shift; |
|
183
|
|
|
|
|
|
|
my %hash = map { |
|
184
|
|
|
|
|
|
|
my $k = $_; |
|
185
|
|
|
|
|
|
|
my $v = $rhash->{$k}; |
|
186
|
|
|
|
|
|
|
$k =~ tr/a-z/A-Z/; |
|
187
|
|
|
|
|
|
|
$k => $v; |
|
188
|
|
|
|
|
|
|
} keys(%{$rhash}); |
|
189
|
|
|
|
|
|
|
return \%hash; |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
193
|
|
|
|
|
|
|
# Parse::WebCounter::_loadStripImage() |
|
194
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
195
|
|
|
|
|
|
|
# Purpose: |
|
196
|
|
|
|
|
|
|
# Loads the images required for matching from a single strip of digits in |
|
197
|
|
|
|
|
|
|
# one image and breaks it up into individual ones. |
|
198
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
199
|
|
|
|
|
|
|
# Parameters: None, but uses following class data |
|
200
|
|
|
|
|
|
|
# digitwidth int The width of the digits in the strip |
|
201
|
|
|
|
|
|
|
# digitheight int The height of the digits in the strip |
|
202
|
|
|
|
|
|
|
# strip order string the "order" of the digits ie "1234567890" |
|
203
|
|
|
|
|
|
|
# type string The "type" of image, essentially the extension |
|
204
|
|
|
|
|
|
|
# pattern string the pattern directory to load from relative to current |
|
205
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
206
|
|
|
|
|
|
|
# Returns: |
|
207
|
|
|
|
|
|
|
# Nothing, But stores the image data in the class. |
|
208
|
|
|
|
|
|
|
# |
|
209
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
210
|
|
|
|
|
|
|
sub _loadStripImage{ |
|
211
|
|
|
|
|
|
|
my $self = shift; |
|
212
|
|
|
|
|
|
|
my %reference_images; |
|
213
|
|
|
|
|
|
|
my $filename = $self->{PATTERN} . "/strip." . $self->{TYPE}; |
|
214
|
|
|
|
|
|
|
my $imagestrip = GD::Image->new($filename); |
|
215
|
|
|
|
|
|
|
my $left = 0; |
|
216
|
|
|
|
|
|
|
my @striporder = split('',$self->{STRIPORDER}); |
|
217
|
|
|
|
|
|
|
foreach my $number (@striporder){ |
|
218
|
|
|
|
|
|
|
my $digit = GD::Image->new($self->{DIGITWIDTH}, |
|
219
|
|
|
|
|
|
|
$self->{DIGITHEIGHT}); |
|
220
|
|
|
|
|
|
|
$digit->copy($imagestrip,0,0,$left,0,$self->{DIGITWIDTH} |
|
221
|
|
|
|
|
|
|
,$self->{DIGITHEIGHT}); |
|
222
|
|
|
|
|
|
|
$left += $self->{DIGITWIDTH}; |
|
223
|
|
|
|
|
|
|
$reference_images{$number} = $digit; |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
$self->{REFIMAGES} = \%reference_images; |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
229
|
|
|
|
|
|
|
# Parse::WebCounter::_loadDigitImages() |
|
230
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
231
|
|
|
|
|
|
|
# Purpose: |
|
232
|
|
|
|
|
|
|
# Loads the images required for matching from separate digit files |
|
233
|
|
|
|
|
|
|
# |
|
234
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
235
|
|
|
|
|
|
|
# Parameters: None, but uses following class data |
|
236
|
|
|
|
|
|
|
# digitwidth int The width of the digits in the strip |
|
237
|
|
|
|
|
|
|
# digitheight int The height of the digits in the strip |
|
238
|
|
|
|
|
|
|
# strip order string the "order" of the digits ie "1234567890" |
|
239
|
|
|
|
|
|
|
# type string The "type" of image, essentially the extension |
|
240
|
|
|
|
|
|
|
# pattern string the pattern directory to load from relative to current |
|
241
|
|
|
|
|
|
|
# |
|
242
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
243
|
|
|
|
|
|
|
# Returns: |
|
244
|
|
|
|
|
|
|
# Nothing, But stores the image data in the class. |
|
245
|
|
|
|
|
|
|
# |
|
246
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
247
|
|
|
|
|
|
|
sub _loadDigitImages{ |
|
248
|
|
|
|
|
|
|
my $self = shift; |
|
249
|
|
|
|
|
|
|
my %reference_images; |
|
250
|
|
|
|
|
|
|
my @striporder = split('',$self->{STRIPORDER}); |
|
251
|
|
|
|
|
|
|
foreach my $number (@striporder){ |
|
252
|
|
|
|
|
|
|
$reference_images{$number} = GD::Image->new( $self->{PATTERN} . "/" . $number . "." . $self->{TYPE}); |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
$self->{REFIMAGES} = \%reference_images; |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
260
|
|
|
|
|
|
|
# Parse::WebCounter::readImage(image[,xoffset[,yoffset]]) |
|
261
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
262
|
|
|
|
|
|
|
# Purpose: |
|
263
|
|
|
|
|
|
|
# Reads the given image to determine the value of all the digits within |
|
264
|
|
|
|
|
|
|
# |
|
265
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
266
|
|
|
|
|
|
|
# Parameters: |
|
267
|
|
|
|
|
|
|
# image gdimage The image object to evaluate |
|
268
|
|
|
|
|
|
|
# xoffset int Offset value to use (in case image has a border) |
|
269
|
|
|
|
|
|
|
# yoffset int Offset value |
|
270
|
|
|
|
|
|
|
# |
|
271
|
|
|
|
|
|
|
# Values from classdata used |
|
272
|
|
|
|
|
|
|
# digitwidth int The width of the digits in the strip |
|
273
|
|
|
|
|
|
|
# digitheight int The height of the digits in the strip |
|
274
|
|
|
|
|
|
|
# |
|
275
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
276
|
|
|
|
|
|
|
# Returns: |
|
277
|
|
|
|
|
|
|
# The parsed value of the image. |
|
278
|
|
|
|
|
|
|
# |
|
279
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
280
|
|
|
|
|
|
|
sub readImage{ |
|
281
|
|
|
|
|
|
|
my $self = shift; |
|
282
|
|
|
|
|
|
|
my $image = shift; |
|
283
|
|
|
|
|
|
|
my $xoffset = shift || 0; |
|
284
|
|
|
|
|
|
|
my $yoffset = shift || 0; |
|
285
|
|
|
|
|
|
|
my ($width,$height) = $image->getBounds(); |
|
286
|
|
|
|
|
|
|
my $return = ""; |
|
287
|
|
|
|
|
|
|
for (my $i = $xoffset; $i < $width ; $i += $self->{DIGITWIDTH}){ |
|
288
|
|
|
|
|
|
|
my $digit = GD::Image->new($self->{DIGITWIDTH}, |
|
289
|
|
|
|
|
|
|
$self->{DIGITHEIGHT}); |
|
290
|
|
|
|
|
|
|
$digit->copy($image,0,0,$i,$yoffset, |
|
291
|
|
|
|
|
|
|
$self->{DIGITWIDTH}, |
|
292
|
|
|
|
|
|
|
$self->{DIGITHEIGHT}); |
|
293
|
|
|
|
|
|
|
$return .= $self->readDigit($digit); |
|
294
|
|
|
|
|
|
|
} |
|
295
|
|
|
|
|
|
|
return $return; |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
} |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
301
|
|
|
|
|
|
|
# Parse::WebCounter::readDigit(image) |
|
302
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
303
|
|
|
|
|
|
|
# Purpose: |
|
304
|
|
|
|
|
|
|
# Reads the given image digit to determine the value |
|
305
|
|
|
|
|
|
|
# |
|
306
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
307
|
|
|
|
|
|
|
# Parameters: |
|
308
|
|
|
|
|
|
|
# image gdimage The image object to evaluate |
|
309
|
|
|
|
|
|
|
# |
|
310
|
|
|
|
|
|
|
# Values from classdata used |
|
311
|
|
|
|
|
|
|
# REFIMAGES hashref The stored reference images for comparison |
|
312
|
|
|
|
|
|
|
# UNKNOWNCHAR char The character to return for an unmatched digit ('_') |
|
313
|
|
|
|
|
|
|
# |
|
314
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
315
|
|
|
|
|
|
|
# Returns: |
|
316
|
|
|
|
|
|
|
# The parsed value of the digit, or the UNKNOWNCHAR if the digit could not |
|
317
|
|
|
|
|
|
|
# be matched. |
|
318
|
|
|
|
|
|
|
# |
|
319
|
|
|
|
|
|
|
#------------------------------------------------------------------------------- |
|
320
|
|
|
|
|
|
|
sub readDigit{ |
|
321
|
|
|
|
|
|
|
my $self = shift; |
|
322
|
|
|
|
|
|
|
my $image = shift; |
|
323
|
|
|
|
|
|
|
foreach my $number (keys(%{$self->{REFIMAGES}})){ |
|
324
|
|
|
|
|
|
|
if ($image->compare($self->{REFIMAGES}->{$number}) == 0){ |
|
325
|
|
|
|
|
|
|
return $number; |
|
326
|
|
|
|
|
|
|
} |
|
327
|
|
|
|
|
|
|
} |
|
328
|
|
|
|
|
|
|
return $self->{UNKNOWNCHAR}; |
|
329
|
|
|
|
|
|
|
} |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
1; |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
__END__ |