qrio 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ |##|##|##|#| *| $|$$|.$|$_| #|##|##|##|
2
+ |# | | |#| *|$ |$$|..|_$| #| | | #|
3
+ |# |##|# |#| *| |__|.$|__| #| #|##| #|
4
+ |# |##|# |#| *| |_ |.$|_ | #| #|##| #|
5
+ |# |##|# |#| *|. |$$|_.|$ | #| #|##| #|
6
+ |# | | |#| *|$.|$$|__| $| #| | | #|
7
+ |##|##|##|#| %| %| %| %| %| #|##|##|##|
8
+ | | | | | *|..| |_$| | | | | |
9
+ |**|**|**|%|**|..| $|_$| $|**|**|**|**|
10
+ | $|$_| $| |$$| $|.$| $|__|$$|.$|__| |
11
+ |$ |$_|$ |%|__|$ |$$| |_$| |..|__|$ |
12
+ |$ |$_|$ | |$_| |..| $|__| |..|$_| |
13
+ | $|_ | |%|_ |$ |. |$$|_ |$$|_$|$_| |
14
+ |X |$ |. | |$$|_ | $|. | | |_$| |$$|
15
+ |XX|$ |$.|%| |$_|$$|..| $|..|__| |__|
16
+ |XX|$ |$.| |$ |__| |.$| |..|__|$ |__|
17
+ |XX| $|..|%| $|$_| $|$$| #|##|##| $|__|
18
+ | | | | | *| $|$_| $|$#| | #|__| $|
19
+ |##|##|##|#| *|$ |$$| |$#| #| #|__| |
20
+ |# | | |#| *| |__|$$|$#| | #|$_| |
21
+ |# |##|# |#| *| $|_ | |$#|##|##|$$| |
22
+ |# |##|# |#| *|. |$ |. |__|$$|$_| |$_|
23
+ |# |##|# |#| *|$.|$$|..|__|$.|_$| |__|
24
+ |# | | |#| *|..| |$$| $| |__| $|__|
25
+ |##|##|##|#| *|.$| $|..|$$| |__| |__|
@@ -0,0 +1,25 @@
1
+ |##|##|##|#| #| |# | |##| #|##|##|##|
2
+ |# | | |#| #| | #|# |##| #| | | #|
3
+ |# |##|# |#| #| #| #| | #| #| #|##| #|
4
+ |# |##|# |#| #|# |# |##|# | #| #|##| #|
5
+ |# |##|# |#| #| #|# | #|##| #| #|##| #|
6
+ |# | | |#| #| | #|# |##| #| | | #|
7
+ |##|##|##|#| #| #| #| #| #| #|##|##|##|
8
+ | | | | | #|# |# |##|# | | | | |
9
+ |##|##|##|#|##| #| | | |##|##|##|##|
10
+ | |##| | | #|##|##|##|# | #|##|# |# |
11
+ | | | |#| #|##|# | #| | #| #| #|##|
12
+ |##|##|##| | |# |# |##|# |# |# | |# |
13
+ |##|# |# |#| #|##| #|# | #|# | |##| #|
14
+ |##|##| #| | #|# |##|# |# |# |##|# | #|
15
+ | #| | |#| #|##|# | #| | #| #| #| #|
16
+ |# |##|##| | |# |# |##|# |# |# | |# |
17
+ | #|##|# |#| |##| |# | #|##|##| | #|
18
+ | | | | | #|##| |##| #| | #|# |##|
19
+ |##|##|##|#| #|##|# | #|##| #| #| #| #|
20
+ |# | | |#| #|# |# | #| #| | #| |# |
21
+ |# |##|# |#| #| | #| #|##|##|##|# | #|
22
+ |# |##|# |#| #|# | |# |# | #| |# | |
23
+ |# |##|# |#| #|##|# | #| #|##| | #| #|
24
+ |# | | |#| #|# |# | #|##|# |# |##|# |
25
+ |##|##|##|#| #| | | #|# | #| #| #| #|
@@ -0,0 +1,100 @@
1
+ 01000010
2
+ 11110110
3
+ 11110110
4
+ 11000110
5
+ 00000110
6
+ 01110110
7
+ 11010010
8
+ 11110010
9
+ 10000111
10
+ 10010111
11
+ 11110111
12
+ 11110111
13
+ 01000111
14
+ 01000110
15
+ 00100111
16
+ 00010111
17
+ 01000111
18
+ 10000111
19
+ 01010110
20
+ 00100110
21
+ 00000111
22
+ 01010110
23
+ 00100111
24
+ 10010110
25
+ 00110011
26
+ 00100010
27
+ 10010111
28
+ 11110000
29
+ 10100010
30
+ 11100110
31
+ 00110110
32
+ 11101100
33
+ 11110010
34
+ 00110110
35
+ 11110110
36
+ 00010001
37
+ 01010000
38
+ 01110010
39
+ 00010010
40
+ 00110100
41
+ 00100001
42
+ 11101101
43
+ 10001010
44
+ 00010011
45
+ 10001110
46
+ 11100110
47
+ 11000111
48
+ 00010001
49
+ 11000101
50
+ 10011011
51
+ 10101110
52
+ 00100101
53
+ 11011111
54
+ 00010101
55
+ 10111101
56
+ 11111111
57
+ 10111000
58
+ 00011111
59
+ 00010110
60
+ 01010000
61
+ 01111110
62
+ 10010101
63
+ 10010001
64
+ 10111100
65
+ 01011100
66
+ 10000011
67
+ 00001010
68
+ 11010010
69
+ 01100011
70
+ 11010011
71
+ 11110101
72
+ 11001001
73
+ 00000111
74
+ 01111111
75
+ 11011001
76
+ 01110011
77
+ 00000101
78
+ 10110001
79
+ 00111000
80
+ 10111110
81
+ 10111011
82
+ 01000010
83
+ 10100000
84
+ 10001100
85
+ 11001100
86
+ 11000100
87
+ 11100110
88
+ 00111110
89
+ 00011110
90
+ 11011100
91
+ 10001111
92
+ 01111010
93
+ 11110100
94
+ 00111111
95
+ 10010000
96
+ 10101010
97
+ 00100100
98
+ 11110100
99
+ 01011110
100
+ 11011101
@@ -0,0 +1,33 @@
1
+ xxxxxxx x x x x x xxxxxxx
2
+ x x x xxxxxx xxx x x x
3
+ x xxx x xx xxx xx xxxx x xxx x
4
+ x xxx x x x xx x x xx x xxx x
5
+ x xxx x xx xx x xxxx xx x xxx x
6
+ x x xxx x xxxx x x
7
+ xxxxxxx x x x x x x x x x xxxxxxx
8
+ xxx x x xxx xx
9
+ xx xx xx x xxx x x xx
10
+ xx x xx xx x xxxxx x xxx
11
+ xxx xx xxxxxxxx xx x xxx
12
+ xxx x x xx xx xxxx xxxxxx
13
+ x xxx xxx x x xx x x x x x
14
+ xx x x x xxxxx x x xx x x x
15
+ x xxx x x xx xx x xx
16
+ x xxx x x x xx xxxx x x x
17
+ x xx x x x x x x x xx xx x
18
+ x xx x x x x xxxx x
19
+ x x xxxx xxxx xxxx xx xxx xx x
20
+ x xx xxxx x x xxxx xxxx
21
+ x x x x xxx x x x x
22
+ xx x xx x x x xxx xx
23
+ x x x x x x x x xx xx xxx
24
+ x x x x xx x x xx xx xx xxx
25
+ xxxxx x xxx x xx xxxxx
26
+ xx x x x x xx xx x
27
+ xxxxxxx xxx xx xxxxxxxx x xx
28
+ x x xxx xx x x xx xxxx
29
+ x xxx x xxx xx xx xx xxxxxx x
30
+ x xxx x xxx x x x x x x
31
+ x xxx x x x x x x x xx x xx
32
+ x x x xx x x x xxxx
33
+ xxxxxxx x x x x x xxxx xx
@@ -0,0 +1,34 @@
1
+ require_relative '../lib/qrio'
2
+ require 'test/unit'
3
+
4
+ class TestHorizontalMatch < Test::Unit::TestCase
5
+ def test_adjacency_detection
6
+ hmatch1 = Qrio::HorizontalMatch.build(2, 0, 8)
7
+ hmatch2 = Qrio::HorizontalMatch.build(3, 0, 8)
8
+ hmatch3 = Qrio::HorizontalMatch.build(3, 5, 13)
9
+
10
+ assert hmatch1.origin_matches?(hmatch2)
11
+ assert hmatch1.terminus_matches?(hmatch2)
12
+ assert hmatch1.endpoints_match?(hmatch2)
13
+ assert hmatch1.offset_matches?(hmatch2)
14
+ assert hmatch1.adjacent?(hmatch2)
15
+
16
+ refute hmatch1.adjacent?(hmatch3)
17
+
18
+ # slice1 = @s.new(3, 26, 82, 39)
19
+ # slice2 = @s.new(3, 40, 81, 58)
20
+ # assert slice1.adjacent?(slice2)
21
+ end
22
+
23
+ def test_slice_sorting
24
+ input = [
25
+ [2, 0, 8],
26
+ [3, 1, 9],
27
+ [4, 0, 8]
28
+ ].map{|c| Qrio::HorizontalMatch.build(*c) }
29
+ output = input.sort
30
+
31
+ assert_equal [0, 1, 0], output.map{|s| s.left }
32
+ assert_equal [2, 3, 4], output.map{|s| s.top }
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ require_relative '../lib/qrio'
2
+ require 'test/unit'
3
+
4
+ class TestMatrix < Test::Unit::TestCase
5
+ def test_random_access
6
+ matrix = Qrio::Matrix.new([1, 1, 0, 0], 2, 2)
7
+ assert_equal 2, matrix.rows.length
8
+ assert_equal 2, matrix.columns.length
9
+
10
+ assert_equal [1, 1], matrix.rows[0]
11
+ assert_equal [0, 0], matrix.rows[1]
12
+ assert_equal [1, 0], matrix.columns[0]
13
+ assert_equal [1, 0], matrix.columns[1]
14
+
15
+ assert_equal 1, matrix[0, 0]
16
+ assert_equal 0, matrix[0, 1]
17
+ assert_equal 1, matrix[1, 0]
18
+ assert_equal 0, matrix[1, 1]
19
+ end
20
+
21
+ def test_rotation
22
+ matrix = Qrio::Matrix.new([1, 0, 1, 0, 0, 0, 0, 1, 0], 3, 3)
23
+ rotated = matrix.rotate
24
+
25
+ assert_equal [0, 0, 1], rotated.rows[0]
26
+ assert_equal [1, 0, 0], rotated.rows[1]
27
+ assert_equal [0, 0, 1], rotated.rows[2]
28
+ end
29
+
30
+ def test_extraction
31
+ matrix = Qrio::Matrix.new([
32
+ 1, 0, 0, 0,
33
+ 0, 1, 1, 0,
34
+ 0, 0, 1, 0,
35
+ 0, 0, 0, 1
36
+ ], 4, 4)
37
+
38
+ center = matrix.extract(1, 1, 2, 2)
39
+ assert_equal 2, center.width
40
+ assert_equal 2, center.height
41
+
42
+ assert_equal [1, 1], center.rows[0]
43
+ assert_equal [0, 1], center.rows[1]
44
+
45
+ extracted = matrix.extract(1, 1, 3, 2)
46
+ assert_equal 3, extracted.width
47
+ assert_equal 2, extracted.height
48
+
49
+ assert_equal [1, 1, 0], extracted.rows[0]
50
+ assert_equal [0, 1, 0], extracted.rows[1]
51
+ end
52
+
53
+ def test_set_bit
54
+ bits = Array.new(25, false)
55
+ matrix = Qrio::Matrix.new(bits, 5, 5)
56
+ refute matrix[4, 4]
57
+ refute matrix.rows.last.last
58
+ refute matrix.columns.last.last
59
+
60
+ matrix[4, 4] = true
61
+
62
+ assert matrix[4, 4]
63
+ assert matrix.rows.last.last
64
+ assert matrix.columns.last.last
65
+ end
66
+ end
@@ -0,0 +1,164 @@
1
+ require_relative '../lib/qrio'
2
+ require 'test/unit'
3
+
4
+ class TestQrMatrix < Test::Unit::TestCase
5
+ def setup
6
+ @bits, @qr = make_qr("block_test")
7
+ end
8
+
9
+ def test_to_s
10
+ assert_equal bits_to_string(@bits, @qr.width), @qr.to_s
11
+ end
12
+
13
+ def test_format_detection
14
+ @qr[1, 8] = false
15
+ assert_equal 'M', @qr.error_correction_level
16
+ end
17
+
18
+
19
+ def test_dimensions
20
+ assert_equal 25, @qr.width
21
+ assert_equal 25, @qr.height
22
+ end
23
+
24
+ def test_position_detection
25
+ assert @qr.in_finder_pattern?(0, 6)
26
+ assert @qr.in_finder_pattern?(0, 7)
27
+ assert @qr.in_finder_pattern?(0, 8)
28
+ refute @qr.in_finder_pattern?(0, 9)
29
+
30
+ assert @qr.in_finder_pattern?(6, 0)
31
+ assert @qr.in_finder_pattern?(7, 0)
32
+ assert @qr.in_finder_pattern?(8, 0)
33
+ refute @qr.in_finder_pattern?(9, 0)
34
+
35
+ assert @qr.in_finder_pattern?(8, 3)
36
+
37
+ assert @qr.in_alignment_line?(14, 6)
38
+ assert @qr.in_alignment_line?(6, 14)
39
+
40
+
41
+ assert_equal 2, @qr.version
42
+ assert @qr.in_alignment_pattern?(16, 16)
43
+ assert @qr.in_alignment_pattern?(18, 18)
44
+ assert @qr.in_alignment_pattern?(20, 20)
45
+
46
+ refute @qr.in_alignment_pattern?(15, 16)
47
+ refute @qr.in_alignment_pattern?(16, 15)
48
+
49
+ refute @qr.in_alignment_pattern?(21, 20)
50
+ refute @qr.in_alignment_pattern?(20, 21)
51
+ end
52
+
53
+ def test_alignment_pattern_detection_by_version
54
+ # version one has no alignment patterns
55
+ v1 = Qrio::QrMatrix.new(Array.new(441, false), 21, 21)
56
+ assert_equal 1, v1.version
57
+
58
+ (0...20).each do |c|
59
+ refute v1.in_alignment_pattern?(c, c)
60
+ end
61
+
62
+ # construct versions 2 - 10 and verify alignment patterns
63
+ [18, 22, 26, 30, 34, [22, 38], [24, 42], [26, 46], [28, 50]].each_with_index do |ap_centers, index|
64
+ version = index + 2
65
+ dimension = version * 4 + 17
66
+ bits = Array.new(dimension * dimension, false)
67
+
68
+ qr = Qrio::QrMatrix.new(bits, dimension, dimension)
69
+ assert_equal version, qr.version
70
+
71
+ qr.draw_alignment_patterns
72
+ verify_alignment_centers(qr, *ap_centers)
73
+ qr.raw_bytes.each do |byte|
74
+ assert_equal 0, byte
75
+ end
76
+ end
77
+ end
78
+
79
+ def test_read_raw_bytes
80
+ bytes = @qr.raw_bytes
81
+ bytes.each_with_index do |byte, index|
82
+ assert_equal index + 1, byte
83
+ end
84
+ end
85
+
86
+ def test_unmask
87
+ @qr[3,8] = false
88
+ assert_equal 0, @qr.mask_pattern
89
+
90
+ _, @masked = make_qr("masked0")
91
+ @qr.unmask
92
+
93
+ assert_equal @masked.raw_bytes, @qr.raw_bytes
94
+ end
95
+
96
+ def test_text
97
+ _, qrio = make_qr("qrio")
98
+ qrio.unmask
99
+ assert_equal fixture_content("qrio-codewords.txt").split("\n"),
100
+ qrio.raw_bytes.map{|b| b.to_s(2).rjust(8, '0') }
101
+
102
+ assert_equal 4, qrio.version
103
+ assert_equal 'H', qrio.error_correction_level
104
+ assert_equal 4, qrio.block_count
105
+ assert_equal 16, qrio.ecc_bytes_per_block
106
+
107
+ assert_equal "https://github.com/rubysolo/qrio", qrio.text
108
+ end
109
+
110
+ private
111
+
112
+ def verify_alignment_centers(qr, *centers)
113
+ cols = *centers.dup
114
+ rows = *centers.dup
115
+
116
+ refute qr.in_alignment_pattern? 6, 6
117
+ refute qr.in_alignment_pattern? qr.width - 7, 8
118
+ refute qr.in_alignment_pattern? 8, qr.height - 7
119
+
120
+ cols.each do |cy|
121
+ rows.each do |cx|
122
+ assert qr.in_alignment_pattern?(cx, cy), "(#{ cx }, #{ cy }) should be ap center (version #{ qr.version })"
123
+ assert qr.in_alignment_pattern?(cx - 2, cy - 2)
124
+ assert qr.in_alignment_pattern?(cx - 2, cy + 2)
125
+ assert qr.in_alignment_pattern?(cx + 2, cy - 2)
126
+ assert qr.in_alignment_pattern?(cx + 2, cy + 2)
127
+
128
+ refute qr.in_alignment_pattern?(cx - 3, cy - 2), "(#{ cx - 3}, #{ cy - 2}) should be outside alignment pattern (version #{ qr.version })"
129
+ refute qr.in_alignment_pattern?(cx - 2, cy - 3)
130
+ refute qr.in_alignment_pattern?(cx + 3, cy + 2)
131
+ refute qr.in_alignment_pattern?(cx + 2, cy + 3)
132
+ end
133
+ end
134
+ end
135
+
136
+ def fixture_content(filename)
137
+ IO.read(File.expand_path("../fixtures/#{ filename }", __FILE__))
138
+ end
139
+
140
+ def make_qr(which)
141
+ raw = fixture_content("#{ which }.qr")
142
+ data = raw.strip.gsub(/\|/, '').split(/\n/)
143
+
144
+ width = data.first.length
145
+ height = data.length
146
+ off = ' _.,'.split(//)
147
+
148
+ bits = data.join('').split(//).map{|s| ! off.include?(s) }
149
+ [bits, Qrio::QrMatrix.new(bits, width, height)]
150
+ end
151
+
152
+ def bits_to_string(bits, width)
153
+ chars = bits.map{|b| b ? '#' : ' ' }
154
+ string = []
155
+ while row = chars.slice!(0, width)
156
+ break if row.nil? || row.empty?
157
+ string << row.join
158
+ end
159
+ string << nil
160
+
161
+ string.join("\n")
162
+ end
163
+
164
+ end