rqrcode 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -1
- data/COPYING +19 -0
- data/README +44 -44
- data/lib/rqrcode/core_ext/array.rb +1 -1
- data/lib/rqrcode/core_ext/array/behavior.rb +2 -2
- data/lib/rqrcode/core_ext/integer.rb +1 -1
- data/lib/rqrcode/core_ext/integer/bitwise.rb +2 -2
- data/lib/rqrcode/extensions.rb +0 -0
- data/lib/rqrcode/extensions/image.rb +1006 -0
- data/lib/rqrcode/qrcode.rb +3 -923
- data/lib/rqrcode/qrcode/qr_8bit_byte.rb +35 -0
- data/lib/rqrcode/qrcode/qr_bit_buffer.rb +56 -0
- data/lib/rqrcode/qrcode/qr_code.rb +394 -0
- data/lib/rqrcode/qrcode/qr_math.rb +63 -0
- data/lib/rqrcode/qrcode/qr_polynomial.rb +78 -0
- data/lib/rqrcode/qrcode/qr_rs_block.rb +134 -0
- data/lib/rqrcode/qrcode/qr_util.rb +254 -0
- data/test/{unit/qrcode_test.rb → runtest.rb} +2 -1
- metadata +23 -22
- data/test/test_helper.rb +0 -2
- data/test/unit/test_data.rb +0 -21
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRMath
|
15
|
+
|
16
|
+
module_eval {
|
17
|
+
exp_table = Array.new(256)
|
18
|
+
log_table = Array.new(256)
|
19
|
+
|
20
|
+
( 0...8 ).each do |i|
|
21
|
+
exp_table[i] = 1 << i
|
22
|
+
end
|
23
|
+
|
24
|
+
( 8...256 ).each do |i|
|
25
|
+
exp_table[i] = exp_table[i - 4] \
|
26
|
+
^ exp_table[i - 5] \
|
27
|
+
^ exp_table[i - 6] \
|
28
|
+
^ exp_table[i - 8]
|
29
|
+
end
|
30
|
+
|
31
|
+
( 0...255 ).each do |i|
|
32
|
+
log_table[exp_table[i] ] = i
|
33
|
+
end
|
34
|
+
|
35
|
+
EXP_TABLE = exp_table
|
36
|
+
LOG_TABLE = log_table
|
37
|
+
}
|
38
|
+
|
39
|
+
class << self
|
40
|
+
|
41
|
+
def glog(n)
|
42
|
+
raise QRCodeRunTimeError, "glog(#{n})" if ( n < 1 )
|
43
|
+
LOG_TABLE[n]
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def gexp(n)
|
48
|
+
while n < 0
|
49
|
+
n = n + 255
|
50
|
+
end
|
51
|
+
|
52
|
+
while n >= 256
|
53
|
+
n = n - 255
|
54
|
+
end
|
55
|
+
|
56
|
+
EXP_TABLE[n]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRPolynomial
|
15
|
+
|
16
|
+
def initialize( num, shift )
|
17
|
+
raise QRCodeRunTimeError, "#{num.size}/#{shift}" if num.empty?
|
18
|
+
offset = 0
|
19
|
+
|
20
|
+
while offset < num.size && num[offset] == 0
|
21
|
+
offset = offset + 1
|
22
|
+
end
|
23
|
+
|
24
|
+
@num = Array.new( num.size - offset + shift )
|
25
|
+
|
26
|
+
( 0...num.size - offset ).each do |i|
|
27
|
+
@num[i] = num[i + offset]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def get( index )
|
33
|
+
@num[index]
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def get_length
|
38
|
+
@num.size
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def multiply( e )
|
43
|
+
num = Array.new( get_length + e.get_length - 1 )
|
44
|
+
|
45
|
+
( 0...get_length ).each do |i|
|
46
|
+
( 0...e.get_length ).each do |j|
|
47
|
+
tmp = num[i + j].nil? ? 0 : num[i + j]
|
48
|
+
num[i + j] = tmp ^ QRMath.gexp(QRMath.glog( get(i) ) + QRMath.glog(e.get(j)))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
return QRPolynomial.new( num, 0 )
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def mod( e )
|
57
|
+
if get_length - e.get_length < 0
|
58
|
+
return self
|
59
|
+
end
|
60
|
+
|
61
|
+
ratio = QRMath.glog(get(0)) - QRMath.glog(e.get(0))
|
62
|
+
num = Array.new(get_length)
|
63
|
+
|
64
|
+
( 0...get_length ).each do |i|
|
65
|
+
num[i] = get(i)
|
66
|
+
end
|
67
|
+
|
68
|
+
( 0...e.get_length ).each do |i|
|
69
|
+
tmp = num[i].nil? ? 0 : num[i]
|
70
|
+
num[i] = tmp ^ QRMath.gexp(QRMath.glog(e.get(i)) + ratio)
|
71
|
+
end
|
72
|
+
|
73
|
+
return QRPolynomial.new( num, 0 ).mod(e)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRRSBlock
|
15
|
+
attr_reader :data_count, :total_count
|
16
|
+
|
17
|
+
def initialize( total_count, data_count )
|
18
|
+
@total_count = total_count
|
19
|
+
@data_count = data_count
|
20
|
+
end
|
21
|
+
|
22
|
+
RS_BLOCK_TABLE = [
|
23
|
+
|
24
|
+
# L
|
25
|
+
# M
|
26
|
+
# Q
|
27
|
+
# H
|
28
|
+
|
29
|
+
# 1
|
30
|
+
[1, 26, 19],
|
31
|
+
[1, 26, 16],
|
32
|
+
[1, 26, 13],
|
33
|
+
[1, 26, 9],
|
34
|
+
|
35
|
+
# 2
|
36
|
+
[1, 44, 34],
|
37
|
+
[1, 44, 28],
|
38
|
+
[1, 44, 22],
|
39
|
+
[1, 44, 16],
|
40
|
+
|
41
|
+
# 3
|
42
|
+
[1, 70, 55],
|
43
|
+
[1, 70, 44],
|
44
|
+
[2, 35, 17],
|
45
|
+
[2, 35, 13],
|
46
|
+
|
47
|
+
# 4
|
48
|
+
[1, 100, 80],
|
49
|
+
[2, 50, 32],
|
50
|
+
[2, 50, 24],
|
51
|
+
[4, 25, 9],
|
52
|
+
|
53
|
+
# 5
|
54
|
+
[1, 134, 108],
|
55
|
+
[2, 67, 43],
|
56
|
+
[2, 33, 15, 2, 34, 16],
|
57
|
+
[2, 33, 11, 2, 34, 12],
|
58
|
+
|
59
|
+
# 6
|
60
|
+
[2, 86, 68],
|
61
|
+
[4, 43, 27],
|
62
|
+
[4, 43, 19],
|
63
|
+
[4, 43, 15],
|
64
|
+
|
65
|
+
# 7
|
66
|
+
[2, 98, 78],
|
67
|
+
[4, 49, 31],
|
68
|
+
[2, 32, 14, 4, 33, 15],
|
69
|
+
[4, 39, 13, 1, 40, 14],
|
70
|
+
|
71
|
+
# 8
|
72
|
+
[2, 121, 97],
|
73
|
+
[2, 60, 38, 2, 61, 39],
|
74
|
+
[4, 40, 18, 2, 41, 19],
|
75
|
+
[4, 40, 14, 2, 41, 15],
|
76
|
+
|
77
|
+
# 9
|
78
|
+
[2, 146, 116],
|
79
|
+
[3, 58, 36, 2, 59, 37],
|
80
|
+
[4, 36, 16, 4, 37, 17],
|
81
|
+
[4, 36, 12, 4, 37, 13],
|
82
|
+
|
83
|
+
# 10
|
84
|
+
[2, 86, 68, 2, 87, 69],
|
85
|
+
[4, 69, 43, 1, 70, 44],
|
86
|
+
[6, 43, 19, 2, 44, 20],
|
87
|
+
[6, 43, 15, 2, 44, 16]
|
88
|
+
|
89
|
+
]
|
90
|
+
|
91
|
+
|
92
|
+
def QRRSBlock.get_rs_blocks( type_no, error_correct_level )
|
93
|
+
rs_block = QRRSBlock.get_rs_block_table( type_no, error_correct_level )
|
94
|
+
|
95
|
+
if rs_block.nil?
|
96
|
+
raise QRCodeRunTimeError,
|
97
|
+
"bad rsblock @ typeno: #{type_no}/error_correct_level:#{error_correct_level}"
|
98
|
+
end
|
99
|
+
|
100
|
+
length = rs_block.size / 3
|
101
|
+
list = []
|
102
|
+
|
103
|
+
( 0...length ).each do |i|
|
104
|
+
count = rs_block[i * 3 + 0]
|
105
|
+
total_count = rs_block[i * 3 + 1]
|
106
|
+
data_count = rs_block[i * 3 + 2]
|
107
|
+
|
108
|
+
( 0...count ).each do |j|
|
109
|
+
list << QRRSBlock.new( total_count, data_count )
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
list
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def QRRSBlock.get_rs_block_table( type_number, error_correct_level )
|
118
|
+
case error_correct_level
|
119
|
+
when QRERRORCORRECTLEVEL[:l]
|
120
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 0]
|
121
|
+
when QRERRORCORRECTLEVEL[:m]
|
122
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 1]
|
123
|
+
when QRERRORCORRECTLEVEL[:q]
|
124
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 2]
|
125
|
+
when QRERRORCORRECTLEVEL[:h]
|
126
|
+
QRRSBlock::RS_BLOCK_TABLE[(type_number - 1) * 4 + 3]
|
127
|
+
else
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2004 by Duncan Robertson (duncan@whomwah.com).
|
5
|
+
# All rights reserved.
|
6
|
+
|
7
|
+
# Permission is granted for use, copying, modification, distribution,
|
8
|
+
# and distribution of modified versions of this work as long as the
|
9
|
+
# above copyright notice is included.
|
10
|
+
#++
|
11
|
+
|
12
|
+
module RQRCode #:nodoc:
|
13
|
+
|
14
|
+
class QRUtil
|
15
|
+
|
16
|
+
PATTERN_POSITION_TABLE = [
|
17
|
+
|
18
|
+
[],
|
19
|
+
[6, 18],
|
20
|
+
[6, 22],
|
21
|
+
[6, 26],
|
22
|
+
[6, 30],
|
23
|
+
[6, 34],
|
24
|
+
[6, 22, 38],
|
25
|
+
[6, 24, 42],
|
26
|
+
[6, 26, 46],
|
27
|
+
[6, 28, 50],
|
28
|
+
[6, 30, 54],
|
29
|
+
[6, 32, 58],
|
30
|
+
[6, 34, 62],
|
31
|
+
[6, 26, 46, 66],
|
32
|
+
[6, 26, 48, 70],
|
33
|
+
[6, 26, 50, 74],
|
34
|
+
[6, 30, 54, 78],
|
35
|
+
[6, 30, 56, 82],
|
36
|
+
[6, 30, 58, 86],
|
37
|
+
[6, 34, 62, 90],
|
38
|
+
[6, 28, 50, 72, 94],
|
39
|
+
[6, 26, 50, 74, 98],
|
40
|
+
[6, 30, 54, 78, 102],
|
41
|
+
[6, 28, 54, 80, 106],
|
42
|
+
[6, 32, 58, 84, 110],
|
43
|
+
[6, 30, 58, 86, 114],
|
44
|
+
[6, 34, 62, 90, 118],
|
45
|
+
[6, 26, 50, 74, 98, 122],
|
46
|
+
[6, 30, 54, 78, 102, 126],
|
47
|
+
[6, 26, 52, 78, 104, 130],
|
48
|
+
[6, 30, 56, 82, 108, 134],
|
49
|
+
[6, 34, 60, 86, 112, 138],
|
50
|
+
[6, 30, 58, 86, 114, 142],
|
51
|
+
[6, 34, 62, 90, 118, 146],
|
52
|
+
[6, 30, 54, 78, 102, 126, 150],
|
53
|
+
[6, 24, 50, 76, 102, 128, 154],
|
54
|
+
[6, 28, 54, 80, 106, 132, 158],
|
55
|
+
[6, 32, 58, 84, 110, 136, 162],
|
56
|
+
[6, 26, 54, 82, 110, 138, 166],
|
57
|
+
[6, 30, 58, 86, 114, 142, 170]
|
58
|
+
]
|
59
|
+
|
60
|
+
G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0
|
61
|
+
G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0
|
62
|
+
G15_MASK = 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1
|
63
|
+
|
64
|
+
|
65
|
+
def QRUtil.get_bch_type_info( data )
|
66
|
+
d = data << 10
|
67
|
+
while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15) >= 0
|
68
|
+
d ^= (G15 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G15)))
|
69
|
+
end
|
70
|
+
(( data << 10 ) | d) ^ G15_MASK
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def QRUtil.get_bch_type_number( data )
|
75
|
+
d = data << 12
|
76
|
+
while QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18) >= 0
|
77
|
+
d ^= (G18 << (QRUtil.get_bch_digit(d) - QRUtil.get_bch_digit(G18)))
|
78
|
+
end
|
79
|
+
( data << 12 ) | d
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def QRUtil.get_bch_digit( data )
|
84
|
+
digit = 0
|
85
|
+
|
86
|
+
while data != 0
|
87
|
+
digit = digit + 1
|
88
|
+
data = (data).rszf(1)
|
89
|
+
end
|
90
|
+
|
91
|
+
digit
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def QRUtil.get_pattern_position( type_number )
|
96
|
+
PATTERN_POSITION_TABLE[ type_number - 1 ]
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
def QRUtil.get_mask( mask_pattern, i, j )
|
101
|
+
case mask_pattern
|
102
|
+
when QRMASKPATTERN[:pattern000]
|
103
|
+
(i + j) % 2 == 0
|
104
|
+
when QRMASKPATTERN[:pattern001]
|
105
|
+
i % 2 == 0
|
106
|
+
when QRMASKPATTERN[:pattern010]
|
107
|
+
j % 3 == 0
|
108
|
+
when QRMASKPATTERN[:pattern011]
|
109
|
+
(i + j) % 3 == 0
|
110
|
+
when QRMASKPATTERN[:pattern100]
|
111
|
+
((i / 2).floor + (j / 3).floor ) % 2 == 0
|
112
|
+
when QRMASKPATTERN[:pattern101]
|
113
|
+
(i * j) % 2 + (i * j) % 3 == 0
|
114
|
+
when QRMASKPATTERN[:pattern110]
|
115
|
+
( (i * j) % 2 + (i * j) % 3) % 2 == 0
|
116
|
+
when QRMASKPATTERN[:pattern111]
|
117
|
+
( (i * j) % 3 + (i + j) % 2) % 2 == 0
|
118
|
+
else
|
119
|
+
raise QRCodeRunTimeError, "bad mask_pattern: #{mask_pattern}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
def QRUtil.get_error_correct_polynomial( error_correct_length )
|
125
|
+
a = QRPolynomial.new( [1], 0 )
|
126
|
+
|
127
|
+
( 0...error_correct_length ).each do |i|
|
128
|
+
a = a.multiply( QRPolynomial.new( [1, QRMath.gexp(i)], 0 ) )
|
129
|
+
end
|
130
|
+
|
131
|
+
a
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
def QRUtil.get_length_in_bits( mode, type )
|
136
|
+
if 1 <= type && type < 10
|
137
|
+
|
138
|
+
# 1 - 9
|
139
|
+
case mode
|
140
|
+
when QRMODE[:mode_number] : 10
|
141
|
+
when QRMODE[:mode_alpha_num] : 9
|
142
|
+
when QRMODE[:mode_8bit_byte] : 8
|
143
|
+
when QRMODE[:mode_kanji] : 8
|
144
|
+
else
|
145
|
+
raise QRCodeRunTimeError, "mode: #{mode}"
|
146
|
+
end
|
147
|
+
|
148
|
+
elsif type < 27
|
149
|
+
|
150
|
+
# 10 -26
|
151
|
+
case mode
|
152
|
+
when QRMODE[:mode_number] : 12
|
153
|
+
when QRMODE[:mode_alpha_num] : 11
|
154
|
+
when QRMODE[:mode_8bit_byte] : 16
|
155
|
+
when QRMODE[:mode_kanji] : 10
|
156
|
+
else
|
157
|
+
raise QRCodeRunTimeError, "mode: #{mode}"
|
158
|
+
end
|
159
|
+
|
160
|
+
elsif type < 41
|
161
|
+
|
162
|
+
# 27 - 40
|
163
|
+
case mode
|
164
|
+
when QRMODE[:mode_number] : 14
|
165
|
+
when QRMODE[:mode_alpha_num] : 13
|
166
|
+
when QRMODE[:mode_8bit_byte] : 16
|
167
|
+
when QRMODE[:mode_kanji] : 12
|
168
|
+
else
|
169
|
+
raise QRCodeRunTimeError, "mode: #{mode}"
|
170
|
+
end
|
171
|
+
|
172
|
+
else
|
173
|
+
raise QRCodeRunTimeError, "type: #{type}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
def QRUtil.get_lost_point( qr_code )
|
179
|
+
module_count = qr_code.module_count
|
180
|
+
lost_point = 0
|
181
|
+
|
182
|
+
# level1
|
183
|
+
( 0...module_count ).each do |row|
|
184
|
+
( 0...module_count ).each do |col|
|
185
|
+
same_count = 0
|
186
|
+
dark = qr_code.is_dark( row, col )
|
187
|
+
|
188
|
+
( -1..1 ).each do |r|
|
189
|
+
next if row + r < 0 || module_count <= row + r
|
190
|
+
|
191
|
+
( -1..1 ).each do |c|
|
192
|
+
next if col + c < 0 || module_count <= col + c
|
193
|
+
next if r == 0 && c == 0
|
194
|
+
if dark == qr_code.is_dark( row + r, col + c )
|
195
|
+
same_count += 1
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
if same_count > 5
|
201
|
+
lost_point += (3 + same_count - 5)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# level 2
|
207
|
+
( 0...( module_count - 1 ) ).each do |row|
|
208
|
+
( 0...( module_count - 1 ) ).each do |col|
|
209
|
+
count = 0
|
210
|
+
count = count + 1 if qr_code.is_dark( row, col )
|
211
|
+
count = count + 1 if qr_code.is_dark( row + 1, col )
|
212
|
+
count = count + 1 if qr_code.is_dark( row, col + 1 )
|
213
|
+
count = count + 1 if qr_code.is_dark( row + 1, col + 1 )
|
214
|
+
lost_point = lost_point + 3 if (count == 0 || count == 4)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# level 3
|
219
|
+
( 0...module_count ).each do |row|
|
220
|
+
( 0...( module_count - 6 ) ).each do |col|
|
221
|
+
if qr_code.is_dark( row, col ) && !qr_code.is_dark( row, col + 1 ) && qr_code.is_dark( row, col + 2 ) && qr_code.is_dark( row, col + 3 ) && qr_code.is_dark( row, col + 4 ) && !qr_code.is_dark( row, col + 5 ) && qr_code.is_dark( row, col + 6 )
|
222
|
+
lost_point = lost_point + 40
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
( 0...module_count ).each do |col|
|
228
|
+
( 0...( module_count - 6 ) ).each do |row|
|
229
|
+
if qr_code.is_dark(row, col) && !qr_code.is_dark(row + 1, col) && qr_code.is_dark(row + 2, col) && qr_code.is_dark(row + 3, col) && qr_code.is_dark(row + 4, col) && !qr_code.is_dark(row + 5, col) && qr_code.is_dark(row + 6, col)
|
230
|
+
lost_point = lost_point + 40
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# level 4
|
236
|
+
dark_count = 0
|
237
|
+
|
238
|
+
( 0...module_count ).each do |col|
|
239
|
+
( 0...module_count ).each do |row|
|
240
|
+
if qr_code.is_dark(row, col)
|
241
|
+
dark_count = dark_count + 1
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
ratio = (100 * dark_count / module_count / module_count - 50).abs / 5
|
247
|
+
lost_point = lost_point * 10
|
248
|
+
|
249
|
+
lost_point
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|