rqrcode_core 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +12 -14
- data/.gitignore +1 -0
- data/CHANGELOG.md +30 -0
- data/Gemfile.lock +34 -5
- data/README.md +35 -12
- data/Rakefile +12 -8
- data/lib/rqrcode_core/qrcode.rb +9 -9
- data/lib/rqrcode_core/qrcode/qr_8bit_byte.rb +3 -5
- data/lib/rqrcode_core/qrcode/qr_alphanumeric.rb +8 -10
- data/lib/rqrcode_core/qrcode/qr_bit_buffer.rb +14 -24
- data/lib/rqrcode_core/qrcode/qr_code.rb +246 -253
- data/lib/rqrcode_core/qrcode/qr_math.rb +9 -10
- data/lib/rqrcode_core/qrcode/qr_numeric.rb +6 -6
- data/lib/rqrcode_core/qrcode/qr_polynomial.rb +15 -15
- data/lib/rqrcode_core/qrcode/qr_rs_block.rb +6 -8
- data/lib/rqrcode_core/qrcode/qr_util.rb +46 -47
- data/lib/rqrcode_core/version.rb +1 -1
- data/rqrcode_core.gemspec +18 -18
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8882bf435375ba687cabacd9f79ec6e8ee6d820264e24375ce3cc69f5ac3cde2
|
4
|
+
data.tar.gz: 5b7e795cdcc8ec3e232fd586157612c8fe72174ae6a31bd7a1b07201e25e64ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7de9ae7b15f8a102e1bc9529dc0bdd4147b3e1f11b3098eb4ca4e89c041ea19a7931f8ccf959ff1aed252f62682a80577771229e75a187b36be94f25a63921e8
|
7
|
+
data.tar.gz: 1b986e1ba66995331c545d840ed358945a6ef7c6f94e483df5ee2f1b3954e59238f39de3aac25ad92b45b91c0a45f0aebfa7ec69ae257dcc4414a18264e81b6a
|
data/.github/workflows/ruby.yml
CHANGED
@@ -10,22 +10,20 @@ on:
|
|
10
10
|
- master
|
11
11
|
|
12
12
|
jobs:
|
13
|
-
|
14
|
-
name: Test Ruby ${{ matrix.ruby_version }} on ${{ matrix.os }}
|
15
|
-
runs-on: ${{ matrix.os }}
|
13
|
+
Build:
|
16
14
|
strategy:
|
15
|
+
fail-fast: false
|
17
16
|
matrix:
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
os: [ubuntu-latest, macos-latest]
|
18
|
+
ruby: [2.5, 2.6, 2.7, 3.0]
|
19
|
+
runs-on: ${{ matrix.os }}
|
21
20
|
steps:
|
22
21
|
- uses: actions/checkout@v1
|
23
|
-
-
|
24
|
-
uses: actions/setup-ruby@v1
|
22
|
+
- uses: ruby/setup-ruby@v1
|
25
23
|
with:
|
26
|
-
ruby-version: ${{ matrix.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
ruby-version: ${{ matrix.ruby }}
|
25
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
26
|
+
- name: Run Tests
|
27
|
+
run: bundle exec rake test
|
28
|
+
- name: StandardRB Check
|
29
|
+
run: bundle exec standardrb --format progress
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [1.0.0] - 2021-04-23
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
|
14
|
+
- README updated
|
15
|
+
- Small documentation clarification [@smnscp](https://github.com/smnscp).
|
16
|
+
- Rakefile cleaned up. You can now just run `rake` which will run specs and fix linting using `standardrb`
|
17
|
+
|
18
|
+
### Breaking Changes
|
19
|
+
|
20
|
+
- Very niche but a breaking change never the less. The `to_s` method *no longer* accepts the `:true` and `:false` arguments, but prefers `:dark` and `:light`.
|
21
|
+
|
22
|
+
## [0.2.0] - 2020-12-26
|
23
|
+
|
24
|
+
### Changed
|
25
|
+
|
26
|
+
- fix `required_ruby_version` for Ruby 3 support
|
27
|
+
|
28
|
+
[unreleased]: https://github.com/whomwah/rqrcode_core/compare/v1.0.0...HEAD
|
29
|
+
[1.0.0]: https://github.com/whomwah/rqrcode_core/compare/v0.2.0...v1.0.0
|
30
|
+
[0.2.0]: https://github.com/whomwah/rqrcode_core/compare/v0.1.2...v0.2.0
|
data/Gemfile.lock
CHANGED
@@ -1,22 +1,51 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rqrcode_core (0.
|
4
|
+
rqrcode_core (1.0.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
|
10
|
-
|
9
|
+
ast (2.4.2)
|
10
|
+
minitest (5.14.4)
|
11
|
+
parallel (1.20.1)
|
12
|
+
parser (3.0.1.0)
|
13
|
+
ast (~> 2.4.1)
|
14
|
+
rainbow (3.0.0)
|
15
|
+
rake (13.0.3)
|
16
|
+
regexp_parser (2.1.1)
|
17
|
+
rexml (3.2.5)
|
18
|
+
rubocop (1.12.1)
|
19
|
+
parallel (~> 1.10)
|
20
|
+
parser (>= 3.0.0.0)
|
21
|
+
rainbow (>= 2.2.2, < 4.0)
|
22
|
+
regexp_parser (>= 1.8, < 3.0)
|
23
|
+
rexml
|
24
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
25
|
+
ruby-progressbar (~> 1.7)
|
26
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
27
|
+
rubocop-ast (1.4.1)
|
28
|
+
parser (>= 2.7.1.5)
|
29
|
+
rubocop-performance (1.10.1)
|
30
|
+
rubocop (>= 0.90.0, < 2.0)
|
31
|
+
rubocop-ast (>= 0.4.0)
|
32
|
+
ruby-progressbar (1.11.0)
|
33
|
+
standard (1.0.5)
|
34
|
+
rubocop (= 1.12.1)
|
35
|
+
rubocop-performance (= 1.10.1)
|
36
|
+
standardrb (1.0.0)
|
37
|
+
standard
|
38
|
+
unicode-display_width (2.0.0)
|
11
39
|
|
12
40
|
PLATFORMS
|
13
41
|
ruby
|
14
42
|
|
15
43
|
DEPENDENCIES
|
16
|
-
bundler (
|
44
|
+
bundler (~> 2.0)
|
17
45
|
minitest (~> 5.0)
|
18
46
|
rake (~> 13.0)
|
19
47
|
rqrcode_core!
|
48
|
+
standardrb (~> 1.0)
|
20
49
|
|
21
50
|
BUNDLED WITH
|
22
|
-
2.2.
|
51
|
+
2.2.15
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-

|
2
2
|
|
3
3
|
# RQRCodeCore
|
4
4
|
|
@@ -18,7 +18,7 @@ Features:
|
|
18
18
|
Add this line to your application's Gemfile:
|
19
19
|
|
20
20
|
```ruby
|
21
|
-
gem
|
21
|
+
gem "rqrcode_core"
|
22
22
|
```
|
23
23
|
|
24
24
|
And then execute:
|
@@ -32,8 +32,8 @@ Or install it yourself as:
|
|
32
32
|
## Basic Usage
|
33
33
|
|
34
34
|
```ruby
|
35
|
-
$ require
|
36
|
-
$ qr = RQRCodeCore::QRCode.new(
|
35
|
+
$ require "rqrcode_core"
|
36
|
+
$ qr = RQRCodeCore::QRCode.new("https://kyan.com")
|
37
37
|
$ puts qr.to_s
|
38
38
|
```
|
39
39
|
|
@@ -49,12 +49,12 @@ x xxx x xxxxx x xx x xxx x
|
|
49
49
|
## Doing your own rendering
|
50
50
|
|
51
51
|
```ruby
|
52
|
-
require
|
52
|
+
require "rqrcode_core"
|
53
53
|
|
54
|
-
qr = RQRCodeCore::QRCode.new(
|
55
|
-
qr.
|
54
|
+
qr = RQRCodeCore::QRCode.new("https://kyan.com")
|
55
|
+
qr.rows.each do |row|
|
56
56
|
row.each do |col|
|
57
|
-
print col ?
|
57
|
+
print col ? "#" : " "
|
58
58
|
end
|
59
59
|
|
60
60
|
print "\n"
|
@@ -68,7 +68,7 @@ The library expects a string to be parsed in, other args are optional.
|
|
68
68
|
```
|
69
69
|
string - the string you wish to encode
|
70
70
|
|
71
|
-
size - the size of the qrcode (
|
71
|
+
size - the size (integer) of the qrcode (defaults to smallest size needed to encode the string)
|
72
72
|
|
73
73
|
level - the error correction level, can be:
|
74
74
|
* Level :l 7% of code can be restored
|
@@ -85,13 +85,36 @@ mode - the mode of the qrcode (defaults to alphanumeric or byte_8bit, dependin
|
|
85
85
|
|
86
86
|
#### Example
|
87
87
|
|
88
|
-
```
|
89
|
-
|
88
|
+
```ruby
|
89
|
+
RQRCodeCore::QRCode.new("http://kyan.com", size: 1, level: :m, mode: :alphanumeric)
|
90
90
|
```
|
91
91
|
|
92
92
|
## Development
|
93
93
|
|
94
|
-
|
94
|
+
### Tests
|
95
|
+
|
96
|
+
You can run the test suite using:
|
97
|
+
|
98
|
+
```
|
99
|
+
$ ./bin/setup
|
100
|
+
$ rake
|
101
|
+
```
|
102
|
+
|
103
|
+
or try the project from the console with:
|
104
|
+
|
105
|
+
```
|
106
|
+
$ ./bin/console
|
107
|
+
```
|
108
|
+
|
109
|
+
### Linting
|
110
|
+
|
111
|
+
The project uses [standardrb](https://github.com/testdouble/standard) and can be run with:
|
112
|
+
|
113
|
+
```
|
114
|
+
$ ./bin/setup
|
115
|
+
$ rake standard # check
|
116
|
+
$ rake standard:fix # fix
|
117
|
+
```
|
95
118
|
|
96
119
|
## Contributing
|
97
120
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
|
2
|
-
require "rake/testtask"
|
1
|
+
begin
|
2
|
+
require "rake/testtask"
|
3
|
+
require "standard/rake"
|
3
4
|
|
4
|
-
Rake::TestTask.new(:test) do |t|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.libs << "lib"
|
8
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
9
|
+
end
|
9
10
|
|
10
|
-
task :
|
11
|
+
task default: [:test, "standard:fix"]
|
12
|
+
rescue LoadError
|
13
|
+
# no standard/rspec available
|
14
|
+
end
|
data/lib/rqrcode_core/qrcode.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
3
|
+
require "rqrcode_core/qrcode/qr_8bit_byte"
|
4
|
+
require "rqrcode_core/qrcode/qr_alphanumeric"
|
5
|
+
require "rqrcode_core/qrcode/qr_bit_buffer"
|
6
|
+
require "rqrcode_core/qrcode/qr_code"
|
7
|
+
require "rqrcode_core/qrcode/qr_math"
|
8
|
+
require "rqrcode_core/qrcode/qr_numeric"
|
9
|
+
require "rqrcode_core/qrcode/qr_polynomial"
|
10
|
+
require "rqrcode_core/qrcode/qr_rs_block"
|
11
|
+
require "rqrcode_core/qrcode/qr_util"
|
@@ -4,18 +4,16 @@ module RQRCodeCore
|
|
4
4
|
class QR8bitByte
|
5
5
|
attr_reader :mode
|
6
6
|
|
7
|
-
def initialize(
|
7
|
+
def initialize(data)
|
8
8
|
@mode = QRMODE[:mode_8bit_byte]
|
9
|
-
@data = data
|
9
|
+
@data = data
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
12
|
def get_length
|
14
13
|
@data.bytesize
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
def write( buffer)
|
16
|
+
def write(buffer)
|
19
17
|
buffer.byte_encoding_start(get_length)
|
20
18
|
@data.each_byte do |b|
|
21
19
|
buffer.put(b, 8)
|
@@ -1,20 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RQRCodeCore
|
4
|
-
ALPHANUMERIC = [
|
4
|
+
ALPHANUMERIC = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", " ", "$", "%", "*", "+", "-", ".", "/", ":"]
|
5
5
|
|
6
6
|
class QRAlphanumeric
|
7
7
|
attr_reader :mode
|
8
8
|
|
9
|
-
def initialize(
|
9
|
+
def initialize(data)
|
10
10
|
@mode = QRMODE[:mode_alpha_numk]
|
11
11
|
|
12
12
|
raise QRCodeArgumentError, "Not a alpha numeric uppercase string `#{data}`" unless QRAlphanumeric.valid_data?(data)
|
13
13
|
|
14
|
-
@data = data
|
14
|
+
@data = data
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
17
|
def get_length
|
19
18
|
@data.size
|
20
19
|
end
|
@@ -26,18 +25,17 @@ module RQRCodeCore
|
|
26
25
|
true
|
27
26
|
end
|
28
27
|
|
29
|
-
|
30
|
-
def write( buffer)
|
28
|
+
def write(buffer)
|
31
29
|
buffer.alphanumeric_encoding_start(get_length)
|
32
30
|
|
33
|
-
|
31
|
+
@data.size.times do |i|
|
34
32
|
if i % 2 == 0
|
35
33
|
if i == (@data.size - 1)
|
36
34
|
value = ALPHANUMERIC.index(@data[i])
|
37
|
-
buffer.put(
|
35
|
+
buffer.put(value, 6)
|
38
36
|
else
|
39
|
-
value = (ALPHANUMERIC.index(@data[i]) * 45) + ALPHANUMERIC.index(@data[i+1])
|
40
|
-
buffer.put(
|
37
|
+
value = (ALPHANUMERIC.index(@data[i]) * 45) + ALPHANUMERIC.index(@data[i + 1])
|
38
|
+
buffer.put(value, 11)
|
41
39
|
end
|
42
40
|
end
|
43
41
|
end
|
@@ -13,74 +13,64 @@ module RQRCodeCore
|
|
13
13
|
@length = 0
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
def get( index )
|
16
|
+
def get(index)
|
18
17
|
buf_index = (index / 8).floor
|
19
|
-
((
|
18
|
+
((QRUtil.rszf(@buffer[buf_index], 7 - index % 8)) & 1) == 1
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
( 0...length ).each do |i|
|
21
|
+
def put(num, length)
|
22
|
+
(0...length).each do |i|
|
25
23
|
put_bit(((QRUtil.rszf(num, length - i - 1)) & 1) == 1)
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
|
30
27
|
def get_length_in_bits
|
31
28
|
@length
|
32
29
|
end
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
buf_index = ( @length / 8 ).floor
|
31
|
+
def put_bit(bit)
|
32
|
+
buf_index = (@length / 8).floor
|
37
33
|
if @buffer.size <= buf_index
|
38
34
|
@buffer << 0
|
39
35
|
end
|
40
36
|
|
41
37
|
if bit
|
42
|
-
@buffer[buf_index] |=
|
38
|
+
@buffer[buf_index] |= QRUtil.rszf(0x80, @length % 8)
|
43
39
|
end
|
44
40
|
|
45
41
|
@length += 1
|
46
42
|
end
|
47
43
|
|
48
44
|
def byte_encoding_start(length)
|
49
|
-
|
50
|
-
put( QRMODE[:mode_8bit_byte], 4 )
|
45
|
+
put(QRMODE[:mode_8bit_byte], 4)
|
51
46
|
put(length, QRUtil.get_length_in_bits(QRMODE[:mode_8bit_byte], @version))
|
52
|
-
|
53
47
|
end
|
54
48
|
|
55
49
|
def alphanumeric_encoding_start(length)
|
56
|
-
|
57
|
-
put( QRMODE[:mode_alpha_numk], 4 )
|
50
|
+
put(QRMODE[:mode_alpha_numk], 4)
|
58
51
|
put(length, QRUtil.get_length_in_bits(QRMODE[:mode_alpha_numk], @version))
|
59
|
-
|
60
52
|
end
|
61
53
|
|
62
54
|
def numeric_encoding_start(length)
|
63
|
-
|
64
|
-
put( QRMODE[:mode_number], 4 )
|
55
|
+
put(QRMODE[:mode_number], 4)
|
65
56
|
put(length, QRUtil.get_length_in_bits(QRMODE[:mode_number], @version))
|
66
|
-
|
67
57
|
end
|
68
58
|
|
69
59
|
def pad_until(prefered_size)
|
70
60
|
# Align on byte
|
71
61
|
while get_length_in_bits % 8 != 0
|
72
|
-
put_bit(
|
62
|
+
put_bit(false)
|
73
63
|
end
|
74
64
|
|
75
65
|
# Pad with padding code words
|
76
66
|
while get_length_in_bits < prefered_size
|
77
|
-
put(
|
78
|
-
put(
|
67
|
+
put(QRBitBuffer::PAD0, 8)
|
68
|
+
put(QRBitBuffer::PAD1, 8) if get_length_in_bits < prefered_size
|
79
69
|
end
|
80
70
|
end
|
81
71
|
|
82
72
|
def end_of_message(max_data_bits)
|
83
|
-
put(
|
73
|
+
put(0, 4) unless get_length_in_bits + 4 > max_data_bits
|
84
74
|
end
|
85
75
|
end
|
86
76
|
end
|
@@ -2,141 +2,142 @@
|
|
2
2
|
|
3
3
|
module RQRCodeCore
|
4
4
|
QRMODE = {
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
5
|
+
mode_number: 1 << 0,
|
6
|
+
mode_alpha_numk: 1 << 1,
|
7
|
+
mode_8bit_byte: 1 << 2
|
8
8
|
}
|
9
9
|
|
10
10
|
QRMODE_NAME = {
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
11
|
+
number: :mode_number,
|
12
|
+
alphanumeric: :mode_alpha_numk,
|
13
|
+
byte_8bit: :mode_8bit_byte
|
14
14
|
}
|
15
15
|
|
16
16
|
QRERRORCORRECTLEVEL = {
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
17
|
+
l: 1,
|
18
|
+
m: 0,
|
19
|
+
q: 3,
|
20
|
+
h: 2
|
21
21
|
}
|
22
22
|
|
23
23
|
QRMASKPATTERN = {
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
24
|
+
pattern000: 0,
|
25
|
+
pattern001: 1,
|
26
|
+
pattern010: 2,
|
27
|
+
pattern011: 3,
|
28
|
+
pattern100: 4,
|
29
|
+
pattern101: 5,
|
30
|
+
pattern110: 6,
|
31
|
+
pattern111: 7
|
32
32
|
}
|
33
33
|
|
34
34
|
QRMASKCOMPUTATIONS = [
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
proc { |i, j| (i + j) % 2 == 0 },
|
36
|
+
proc { |i, j| i % 2 == 0 },
|
37
|
+
proc { |i, j| j % 3 == 0 },
|
38
|
+
proc { |i, j| (i + j) % 3 == 0 },
|
39
|
+
proc { |i, j| ((i / 2).floor + (j / 3).floor) % 2 == 0 },
|
40
|
+
proc { |i, j| (i * j) % 2 + (i * j) % 3 == 0 },
|
41
|
+
proc { |i, j| ((i * j) % 2 + (i * j) % 3) % 2 == 0 },
|
42
|
+
proc { |i, j| ((i * j) % 3 + (i + j) % 2) % 2 == 0 }
|
43
43
|
]
|
44
44
|
|
45
45
|
QRPOSITIONPATTERNLENGTH = (7 + 1) * 2 + 1
|
46
46
|
QRFORMATINFOLENGTH = 15
|
47
47
|
|
48
|
-
#http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable1-e.html
|
49
|
-
#http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable2-e.html
|
50
|
-
#http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable3-e.html
|
51
|
-
#http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable4-e.html
|
48
|
+
# http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable1-e.html
|
49
|
+
# http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable2-e.html
|
50
|
+
# http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable3-e.html
|
51
|
+
# http://web.archive.org/web/20110710094955/http://www.denso-wave.com/qrcode/vertable4-e.html
|
52
52
|
# Each array contains levels max chars from level 1 to level 40
|
53
53
|
QRMAXDIGITS = {
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
54
|
+
l: {
|
55
|
+
mode_number: [
|
56
|
+
41, 77, 127, 187, 255, 322, 370, 461, 552, 652, 772,
|
57
|
+
883, 1022, 1101, 1250, 1408, 1548, 1725, 1903, 2061,
|
58
|
+
2232, 2409, 2620, 2812, 3057, 3283, 3514, 3669, 3909, 4158,
|
59
|
+
4417, 4686, 4965, 5253, 5529, 5836, 6153, 6479, 6743, 7089
|
60
|
+
],
|
61
|
+
mode_alpha_numk: [
|
62
|
+
25, 47, 77, 114, 154, 195, 224, 279, 335, 395,
|
63
|
+
468, 535, 619, 667, 758, 854, 938, 1046, 1153, 1249,
|
64
|
+
1352, 1460, 1588, 1704, 1853, 1990, 2132, 2223, 2369, 2520,
|
65
|
+
2677, 2840, 3009, 3183, 3351, 3537, 3729, 3927, 4087, 4296
|
66
|
+
],
|
67
|
+
mode_8bit_byte: [
|
68
|
+
17, 32, 53, 78, 106, 134, 154, 192, 230, 271,
|
69
|
+
321, 367, 425, 458, 520, 586, 644, 718, 792, 858,
|
70
|
+
929, 1003, 1091, 1171, 1273, 1367, 1465, 1528, 1628, 1732,
|
71
|
+
1840, 1952, 2068, 2188, 2303, 2431, 2563, 2699, 2809, 2953
|
72
|
+
]
|
73
|
+
},
|
74
|
+
m: {
|
75
|
+
mode_number: [
|
76
|
+
34, 63, 101, 149, 202, 255, 293, 365, 432, 513,
|
77
|
+
604, 691, 796, 871, 991, 1082, 1212, 1346, 1500, 1600,
|
78
|
+
1708, 1872, 2059, 2188, 2395, 2544, 2701, 2857, 3035, 3289,
|
79
|
+
3486, 3693, 3909, 4134, 4343, 4588, 4775, 5039, 5313, 5596
|
80
|
+
],
|
81
|
+
mode_alpha_numk: [
|
82
|
+
20, 38, 61, 90, 122, 154, 178, 221, 262, 311,
|
83
|
+
366, 419, 483, 528, 600, 656, 734, 816, 909, 970,
|
84
|
+
1035, 1134, 1248, 1326, 1451, 1542, 1637, 1732, 1839, 1994,
|
85
|
+
2113, 2238, 2369, 2506, 2632, 2780, 2894, 3054, 3220, 3391
|
86
|
+
],
|
87
|
+
mode_8bit_byte: [
|
88
|
+
14, 26, 42, 62, 84, 106, 122, 152, 180, 213,
|
89
|
+
251, 287, 331, 362, 412, 450, 504, 560, 624, 666,
|
90
|
+
711, 779, 857, 911, 997, 1059, 1125, 1190, 1264, 1370,
|
91
|
+
1452, 1538, 1628, 1722, 1809, 1911, 1989, 2099, 2213, 2331
|
92
|
+
]
|
93
|
+
},
|
94
|
+
q: {
|
95
|
+
mode_number: [
|
96
|
+
27, 48, 77, 111, 144, 178, 207, 259, 312, 364,
|
97
|
+
427, 489, 580, 621, 703, 775, 876, 948, 1063, 1159,
|
98
|
+
1224, 1358, 1468, 1588, 1718, 1804, 1933, 2085, 2181, 2358,
|
99
|
+
2473, 2670, 2805, 2949, 3081, 3244, 3417, 3599, 3791, 3993
|
100
|
+
],
|
101
|
+
mode_alpha_numk: [
|
102
|
+
16, 29, 47, 67, 87, 108, 125, 157, 189, 221,
|
103
|
+
259, 296, 352, 376, 426, 470, 531, 574, 644, 702,
|
104
|
+
742, 823, 890, 963, 1041, 1094, 1172, 1263, 1322, 1429,
|
105
|
+
1499, 1618, 1700, 1787, 1867, 1966, 2071, 2181, 2298, 2420
|
106
|
+
],
|
107
|
+
mode_8bit_byte: [
|
108
|
+
11, 20, 32, 46, 60, 74, 86, 108, 130, 151,
|
109
|
+
177, 203, 241, 258, 292, 22, 364, 394, 442, 482,
|
110
|
+
509, 565, 611, 661, 715, 751, 805, 868, 908, 982,
|
111
|
+
1030, 1112, 1168, 1228, 1283, 1351, 1423, 1499, 1579, 1663
|
112
|
+
]
|
113
|
+
},
|
114
|
+
h: {
|
115
|
+
mode_number: [
|
116
|
+
17, 34, 58, 82, 106, 139, 154, 202, 235, 288, 331, 374, 427, 468, 530, 602, 674,
|
117
|
+
331, 374, 427, 468, 530, 602, 674, 746, 813, 919,
|
118
|
+
969, 1056, 1108, 1228, 1286, 1425, 1501, 1581, 1677, 1782,
|
119
|
+
1897, 2022, 2157, 2301, 2361, 2524, 2625, 2735, 2927, 3057
|
120
|
+
|
121
|
+
],
|
122
|
+
mode_alpha_numk: [
|
123
|
+
10, 20, 35, 50, 64, 84, 93, 122, 143, 174, 200,
|
124
|
+
200, 227, 259, 283, 321, 365, 408, 452, 493, 557,
|
125
|
+
587, 640, 672, 744, 779, 864, 910, 958, 1016, 1080,
|
126
|
+
1150, 1226, 1307, 1394, 1431, 1530, 1591, 1658, 1774, 1852
|
127
|
+
],
|
128
|
+
mode_8bit_byte: [
|
129
|
+
7, 14, 24, 34, 44, 58, 64, 84, 98, 119,
|
130
|
+
137, 155, 177, 194, 220, 250, 280, 310, 338, 382,
|
131
|
+
403, 439, 461, 511, 535, 593, 625, 658, 698, 742,
|
132
|
+
790, 842, 898, 958, 983, 1051, 1093, 1139, 1219, 1273
|
133
|
+
]
|
134
|
+
}
|
135
135
|
}
|
136
136
|
|
137
137
|
# StandardErrors
|
138
138
|
|
139
139
|
class QRCodeArgumentError < ArgumentError; end
|
140
|
+
|
140
141
|
class QRCodeRunTimeError < RuntimeError; end
|
141
142
|
|
142
143
|
# == Creation
|
@@ -154,7 +155,7 @@ module RQRCodeCore
|
|
154
155
|
# Expects a string to be parsed in, other args are optional
|
155
156
|
#
|
156
157
|
# # string - the string you wish to encode
|
157
|
-
# # size - the size of the qrcode (
|
158
|
+
# # size - the size (Integer) of the qrcode (defaults to smallest size needed to encode the string)
|
158
159
|
# # level - the error correction level, can be:
|
159
160
|
# * Level :l 7% of code can be restored
|
160
161
|
# * Level :m 15% of code can be restored
|
@@ -169,54 +170,53 @@ module RQRCodeCore
|
|
169
170
|
# qr = RQRCodeCore::QRCode.new('hello world', size: 1, level: :m, mode: :alphanumeric)
|
170
171
|
#
|
171
172
|
|
172
|
-
def initialize(
|
173
|
+
def initialize(string, *args)
|
173
174
|
if !string.is_a? String
|
174
175
|
raise QRCodeArgumentError, "The passed data is #{string.class}, not String"
|
175
176
|
end
|
176
177
|
|
177
|
-
options
|
178
|
-
level
|
178
|
+
options = extract_options!(args)
|
179
|
+
level = (options[:level] || :h).to_sym
|
179
180
|
|
180
181
|
if !QRERRORCORRECTLEVEL.has_key?(level)
|
181
182
|
raise QRCodeArgumentError, "Unknown error correction level `#{level.inspect}`"
|
182
183
|
end
|
183
184
|
|
184
|
-
@data
|
185
|
+
@data = string
|
185
186
|
|
186
|
-
mode
|
187
|
+
mode = QRMODE_NAME[(options[:mode] || "").to_sym]
|
187
188
|
# If mode is not explicitely given choose mode according to data type
|
188
|
-
mode ||=
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
QRMODE_NAME[:byte_8bit]
|
189
|
+
mode ||= if RQRCodeCore::QRNumeric.valid_data?(@data)
|
190
|
+
QRMODE_NAME[:number]
|
191
|
+
elsif QRAlphanumeric.valid_data?(@data)
|
192
|
+
QRMODE_NAME[:alphanumeric]
|
193
|
+
else
|
194
|
+
QRMODE_NAME[:byte_8bit]
|
195
195
|
end
|
196
196
|
|
197
|
-
max_size_array
|
198
|
-
size
|
197
|
+
max_size_array = QRMAXDIGITS[level][mode]
|
198
|
+
size = options[:size] || smallest_size_for(string, max_size_array)
|
199
199
|
|
200
200
|
if size > QRUtil.max_size
|
201
201
|
raise QRCodeArgumentError, "Given size greater than maximum possible size of #{QRUtil.max_size}"
|
202
202
|
end
|
203
203
|
|
204
|
-
@error_correct_level
|
205
|
-
@version
|
206
|
-
@module_count
|
207
|
-
@modules
|
208
|
-
@data_list
|
204
|
+
@error_correct_level = QRERRORCORRECTLEVEL[level]
|
205
|
+
@version = size
|
206
|
+
@module_count = @version * 4 + QRPOSITIONPATTERNLENGTH
|
207
|
+
@modules = Array.new(@module_count)
|
208
|
+
@data_list =
|
209
209
|
case mode
|
210
210
|
when :mode_number
|
211
|
-
QRNumeric.new(
|
211
|
+
QRNumeric.new(@data)
|
212
212
|
when :mode_alpha_numk
|
213
|
-
QRAlphanumeric.new(
|
213
|
+
QRAlphanumeric.new(@data)
|
214
214
|
else
|
215
|
-
QR8bitByte.new(
|
215
|
+
QR8bitByte.new(@data)
|
216
216
|
end
|
217
217
|
|
218
|
-
@data_cache
|
219
|
-
|
218
|
+
@data_cache = nil
|
219
|
+
make
|
220
220
|
end
|
221
221
|
|
222
222
|
# <tt>checked?</tt> is called with a +col+ and +row+ parameter. This will
|
@@ -227,7 +227,7 @@ module RQRCodeCore
|
|
227
227
|
# instance.checked?( 10, 10 ) => true
|
228
228
|
#
|
229
229
|
|
230
|
-
def checked?(
|
230
|
+
def checked?(row, col)
|
231
231
|
if !row.between?(0, @module_count - 1) || !col.between?(0, @module_count - 1)
|
232
232
|
raise QRCodeRunTimeError, "Invalid row/column pair: #{row}, #{col}"
|
233
233
|
end
|
@@ -241,7 +241,7 @@ module RQRCodeCore
|
|
241
241
|
# generated as a string. It will not be able to be read
|
242
242
|
# in this format by a QR Code reader, but will give you an
|
243
243
|
# idea if the final outout. It takes two optional args
|
244
|
-
# +:
|
244
|
+
# +:dark+ and +:light+ which are there for you to choose
|
245
245
|
# how the output looks. Here's an example of it's use:
|
246
246
|
#
|
247
247
|
# instance.to_s =>
|
@@ -255,11 +255,11 @@ module RQRCodeCore
|
|
255
255
|
# EQEEEQEQQEEEEEQEQQQQQQQEEQEQEEEQE
|
256
256
|
#
|
257
257
|
|
258
|
-
def to_s(
|
259
|
-
options
|
260
|
-
dark
|
261
|
-
light
|
262
|
-
quiet_zone_size
|
258
|
+
def to_s(*args)
|
259
|
+
options = extract_options!(args)
|
260
|
+
dark = options[:dark] || "x"
|
261
|
+
light = options[:light] || " "
|
262
|
+
quiet_zone_size = options[:quiet_zone_size] || 0
|
263
263
|
|
264
264
|
rows = []
|
265
265
|
|
@@ -309,7 +309,7 @@ module RQRCodeCore
|
|
309
309
|
|
310
310
|
def make #:nodoc:
|
311
311
|
prepare_common_patterns
|
312
|
-
make_impl(
|
312
|
+
make_impl(false, get_best_mask_pattern)
|
313
313
|
end
|
314
314
|
|
315
315
|
private
|
@@ -326,7 +326,7 @@ module RQRCodeCore
|
|
326
326
|
@common_patterns = @modules.map(&:clone)
|
327
327
|
end
|
328
328
|
|
329
|
-
def make_impl(
|
329
|
+
def make_impl(test, mask_pattern) #:nodoc:
|
330
330
|
@modules = @common_patterns.map(&:clone)
|
331
331
|
|
332
332
|
place_format_info(test, mask_pattern)
|
@@ -338,20 +338,19 @@ module RQRCodeCore
|
|
338
338
|
)
|
339
339
|
end
|
340
340
|
|
341
|
-
map_data(
|
341
|
+
map_data(@data_cache, mask_pattern)
|
342
342
|
end
|
343
343
|
|
344
|
-
|
345
|
-
def place_position_probe_pattern( row, col ) #:nodoc:
|
344
|
+
def place_position_probe_pattern(row, col) #:nodoc:
|
346
345
|
(-1..7).each do |r|
|
347
|
-
next
|
346
|
+
next unless (row + r).between?(0, @module_count - 1)
|
348
347
|
|
349
348
|
(-1..7).each do |c|
|
350
|
-
next
|
349
|
+
next unless (col + c).between?(0, @module_count - 1)
|
351
350
|
|
352
351
|
is_vert_line = (r.between?(0, 6) && (c == 0 || c == 6))
|
353
352
|
is_horiz_line = (c.between?(0, 6) && (r == 0 || r == 6))
|
354
|
-
is_square = r.between?(2,4) && c.between?(2, 4)
|
353
|
+
is_square = r.between?(2, 4) && c.between?(2, 4)
|
355
354
|
|
356
355
|
is_part_of_probe = is_vert_line || is_horiz_line || is_square
|
357
356
|
@modules[row + r][col + c] = is_part_of_probe
|
@@ -359,14 +358,13 @@ module RQRCodeCore
|
|
359
358
|
end
|
360
359
|
end
|
361
360
|
|
362
|
-
|
363
361
|
def get_best_mask_pattern #:nodoc:
|
364
362
|
min_lost_point = 0
|
365
363
|
pattern = 0
|
366
364
|
|
367
|
-
(
|
368
|
-
make_impl(
|
369
|
-
lost_point = QRUtil.get_lost_points(
|
365
|
+
(0...8).each do |i|
|
366
|
+
make_impl(true, i)
|
367
|
+
lost_point = QRUtil.get_lost_points(modules)
|
370
368
|
|
371
369
|
if i == 0 || min_lost_point > lost_point
|
372
370
|
min_lost_point = lost_point
|
@@ -376,14 +374,12 @@ module RQRCodeCore
|
|
376
374
|
pattern
|
377
375
|
end
|
378
376
|
|
379
|
-
|
380
377
|
def place_timing_pattern #:nodoc:
|
381
|
-
(
|
378
|
+
(8...@module_count - 8).each do |i|
|
382
379
|
@modules[i][6] = @modules[6][i] = i % 2 == 0
|
383
380
|
end
|
384
381
|
end
|
385
382
|
|
386
|
-
|
387
383
|
def place_position_adjust_pattern #:nodoc:
|
388
384
|
positions = QRUtil.get_pattern_positions(@version)
|
389
385
|
|
@@ -391,9 +387,9 @@ module RQRCodeCore
|
|
391
387
|
positions.each do |col|
|
392
388
|
next unless @modules[row][col].nil?
|
393
389
|
|
394
|
-
(
|
395
|
-
(
|
396
|
-
is_part_of_pattern = (r.abs == 2 || c.abs == 2 || (
|
390
|
+
(-2..2).each do |r|
|
391
|
+
(-2..2).each do |c|
|
392
|
+
is_part_of_pattern = (r.abs == 2 || c.abs == 2 || (r == 0 && c == 0))
|
397
393
|
@modules[row + r][col + c] = is_part_of_pattern
|
398
394
|
end
|
399
395
|
end
|
@@ -401,69 +397,65 @@ module RQRCodeCore
|
|
401
397
|
end
|
402
398
|
end
|
403
399
|
|
404
|
-
|
405
400
|
def place_version_info(test) #:nodoc:
|
406
401
|
bits = QRUtil.get_bch_version(@version)
|
407
402
|
|
408
|
-
(
|
409
|
-
mod = (
|
410
|
-
@modules[
|
411
|
-
@modules[
|
403
|
+
(0...18).each do |i|
|
404
|
+
mod = (!test && ((bits >> i) & 1) == 1)
|
405
|
+
@modules[(i / 3).floor][ i % 3 + @module_count - 8 - 3 ] = mod
|
406
|
+
@modules[i % 3 + @module_count - 8 - 3][ (i / 3).floor ] = mod
|
412
407
|
end
|
413
408
|
end
|
414
409
|
|
415
|
-
|
416
410
|
def place_format_info(test, mask_pattern) #:nodoc:
|
417
411
|
data = (@error_correct_level << 3 | mask_pattern)
|
418
412
|
bits = QRUtil.get_bch_format_info(data)
|
419
413
|
|
420
414
|
QRFORMATINFOLENGTH.times do |i|
|
421
|
-
mod = (!test && (
|
415
|
+
mod = (!test && ((bits >> i) & 1) == 1)
|
422
416
|
|
423
417
|
# vertical
|
424
|
-
if i < 6
|
425
|
-
|
418
|
+
row = if i < 6
|
419
|
+
i
|
426
420
|
elsif i < 8
|
427
|
-
|
421
|
+
i + 1
|
428
422
|
else
|
429
|
-
|
423
|
+
@module_count - 15 + i
|
430
424
|
end
|
431
425
|
@modules[row][8] = mod
|
432
426
|
|
433
427
|
# horizontal
|
434
|
-
if i < 8
|
435
|
-
|
428
|
+
col = if i < 8
|
429
|
+
@module_count - i - 1
|
436
430
|
elsif i < 9
|
437
|
-
|
431
|
+
15 - i - 1 + 1
|
438
432
|
else
|
439
|
-
|
433
|
+
15 - i - 1
|
440
434
|
end
|
441
435
|
@modules[8][col] = mod
|
442
436
|
end
|
443
437
|
|
444
438
|
# fixed module
|
445
|
-
@modules[
|
439
|
+
@modules[@module_count - 8][8] = !test
|
446
440
|
end
|
447
441
|
|
448
|
-
|
449
|
-
def map_data( data, mask_pattern ) #:nodoc:
|
442
|
+
def map_data(data, mask_pattern) #:nodoc:
|
450
443
|
inc = -1
|
451
444
|
row = @module_count - 1
|
452
445
|
bit_index = 7
|
453
446
|
byte_index = 0
|
454
447
|
|
455
|
-
(
|
456
|
-
col
|
448
|
+
(@module_count - 1).step(1, -2) do |col|
|
449
|
+
col -= 1 if col <= 6
|
457
450
|
|
458
|
-
|
459
|
-
(
|
460
|
-
|
461
|
-
if @modules[row][ col - c ].nil?
|
451
|
+
loop do
|
452
|
+
(0...2).each do |c|
|
453
|
+
if @modules[row][col - c].nil?
|
462
454
|
dark = false
|
463
455
|
if byte_index < data.size && !data[byte_index].nil?
|
464
|
-
dark = ((
|
456
|
+
dark = ((QRUtil.rszf(data[byte_index], bit_index) & 1) == 1)
|
465
457
|
end
|
466
|
-
mask = QRUtil.get_mask(
|
458
|
+
mask = QRUtil.get_mask(mask_pattern, row, col - c)
|
467
459
|
dark = !dark if mask
|
468
460
|
@modules[row][ col - c ] = dark
|
469
461
|
bit_index -= 1
|
@@ -488,8 +480,8 @@ module RQRCodeCore
|
|
488
480
|
|
489
481
|
def smallest_size_for(string, max_size_array) #:nodoc:
|
490
482
|
l = string.bytesize
|
491
|
-
ver = max_size_array.index{|i| i >= l}
|
492
|
-
raise QRCodeRunTimeError,"code length overflow. (#{l} digits > any version capacity)" unless ver
|
483
|
+
ver = max_size_array.index { |i| i >= l }
|
484
|
+
raise QRCodeRunTimeError, "code length overflow. (#{l} digits > any version capacity)" unless ver
|
493
485
|
ver + 1
|
494
486
|
end
|
495
487
|
|
@@ -497,90 +489,91 @@ module RQRCodeCore
|
|
497
489
|
arr.last.is_a?(::Hash) ? arr.pop : {}
|
498
490
|
end
|
499
491
|
|
500
|
-
|
501
|
-
|
502
|
-
sum
|
503
|
-
|
504
|
-
|
505
|
-
return max_data_bytes * 8
|
506
|
-
end
|
507
|
-
|
508
|
-
def QRCode.create_data(version, error_correct_level, data_list) #:nodoc:
|
509
|
-
rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level)
|
510
|
-
max_data_bits = QRCode.count_max_data_bits(rs_blocks)
|
511
|
-
buffer = QRBitBuffer.new(version)
|
512
|
-
|
513
|
-
data_list.write(buffer)
|
514
|
-
buffer.end_of_message(max_data_bits)
|
492
|
+
class << self
|
493
|
+
def count_max_data_bits(rs_blocks)
|
494
|
+
max_data_bytes = rs_blocks.reduce(0) do |sum, rs_block|
|
495
|
+
sum + rs_block.data_count
|
496
|
+
end
|
515
497
|
|
516
|
-
|
517
|
-
raise QRCodeRunTimeError, "code length overflow. (#{buffer.get_length_in_bits}>#{max_data_bits}). (Try a larger size!)"
|
498
|
+
max_data_bytes * 8
|
518
499
|
end
|
519
500
|
|
520
|
-
|
501
|
+
def create_data(version, error_correct_level, data_list) #:nodoc:
|
502
|
+
rs_blocks = QRRSBlock.get_rs_blocks(version, error_correct_level)
|
503
|
+
max_data_bits = QRCode.count_max_data_bits(rs_blocks)
|
504
|
+
buffer = QRBitBuffer.new(version)
|
521
505
|
|
522
|
-
|
523
|
-
|
506
|
+
data_list.write(buffer)
|
507
|
+
buffer.end_of_message(max_data_bits)
|
524
508
|
|
509
|
+
if buffer.get_length_in_bits > max_data_bits
|
510
|
+
raise QRCodeRunTimeError, "code length overflow. (#{buffer.get_length_in_bits}>#{max_data_bits}). (Try a larger size!)"
|
511
|
+
end
|
525
512
|
|
526
|
-
|
527
|
-
offset = 0
|
528
|
-
max_dc_count = 0
|
529
|
-
max_ec_count = 0
|
530
|
-
dcdata = Array.new( rs_blocks.size )
|
531
|
-
ecdata = Array.new( rs_blocks.size )
|
513
|
+
buffer.pad_until(max_data_bits)
|
532
514
|
|
533
|
-
|
534
|
-
|
535
|
-
ec_count = rs_block.total_count - dc_count
|
536
|
-
max_dc_count = [ max_dc_count, dc_count ].max
|
537
|
-
max_ec_count = [ max_ec_count, ec_count ].max
|
515
|
+
QRCode.create_bytes(buffer, rs_blocks)
|
516
|
+
end
|
538
517
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
dcdata
|
518
|
+
def create_bytes(buffer, rs_blocks) #:nodoc:
|
519
|
+
offset = 0
|
520
|
+
max_dc_count = 0
|
521
|
+
max_ec_count = 0
|
522
|
+
dcdata = Array.new(rs_blocks.size)
|
523
|
+
ecdata = Array.new(rs_blocks.size)
|
524
|
+
|
525
|
+
rs_blocks.each_with_index do |rs_block, r|
|
526
|
+
dc_count = rs_block.data_count
|
527
|
+
ec_count = rs_block.total_count - dc_count
|
528
|
+
max_dc_count = [max_dc_count, dc_count].max
|
529
|
+
max_ec_count = [max_ec_count, ec_count].max
|
530
|
+
|
531
|
+
dcdata_block = Array.new(dc_count)
|
532
|
+
dcdata_block.size.times do |i|
|
533
|
+
dcdata_block[i] = 0xff & buffer.buffer[i + offset]
|
534
|
+
end
|
535
|
+
dcdata[r] = dcdata_block
|
544
536
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
537
|
+
offset += dc_count
|
538
|
+
rs_poly = QRUtil.get_error_correct_polynomial(ec_count)
|
539
|
+
raw_poly = QRPolynomial.new(dcdata[r], rs_poly.get_length - 1)
|
540
|
+
mod_poly = raw_poly.mod(rs_poly)
|
549
541
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
542
|
+
ecdata_block = Array.new(rs_poly.get_length - 1)
|
543
|
+
ecdata_block.size.times do |i|
|
544
|
+
mod_index = i + mod_poly.get_length - ecdata_block.size
|
545
|
+
ecdata_block[i] = mod_index >= 0 ? mod_poly.get(mod_index) : 0
|
546
|
+
end
|
547
|
+
ecdata[r] = ecdata_block
|
554
548
|
end
|
555
|
-
ecdata[r] = ecdata_block
|
556
|
-
end
|
557
549
|
|
558
|
-
|
559
|
-
|
560
|
-
|
550
|
+
total_code_count = rs_blocks.reduce(0) do |sum, rs_block|
|
551
|
+
sum + rs_block.total_count
|
552
|
+
end
|
561
553
|
|
562
|
-
|
563
|
-
|
554
|
+
data = Array.new(total_code_count)
|
555
|
+
index = 0
|
564
556
|
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
557
|
+
max_dc_count.times do |i|
|
558
|
+
rs_blocks.size.times do |r|
|
559
|
+
if i < dcdata[r].size
|
560
|
+
data[index] = dcdata[r][i]
|
561
|
+
index += 1
|
562
|
+
end
|
570
563
|
end
|
571
564
|
end
|
572
|
-
end
|
573
565
|
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
566
|
+
max_ec_count.times do |i|
|
567
|
+
rs_blocks.size.times do |r|
|
568
|
+
if i < ecdata[r].size
|
569
|
+
data[index] = ecdata[r][i]
|
570
|
+
index += 1
|
571
|
+
end
|
579
572
|
end
|
580
573
|
end
|
581
|
-
end
|
582
574
|
|
583
|
-
|
575
|
+
data
|
576
|
+
end
|
584
577
|
end
|
585
578
|
end
|
586
579
|
end
|