qr_reader 0.0.1
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 +7 -0
- data/CHANGELOG.md +16 -0
- data/LICENSE.txt +21 -0
- data/NOTICE +14 -0
- data/README.md +222 -0
- data/exe/qr_reader +66 -0
- data/lib/qr_reader/binarizer.rb +170 -0
- data/lib/qr_reader/bit_matrix.rb +120 -0
- data/lib/qr_reader/decoder/bitstream_parser.rb +307 -0
- data/lib/qr_reader/decoder/character_set.rb +163 -0
- data/lib/qr_reader/decoder/codewords.rb +164 -0
- data/lib/qr_reader/decoder/data_mask.rb +57 -0
- data/lib/qr_reader/decoder/format_reader.rb +204 -0
- data/lib/qr_reader/decoder/function_patterns.rb +62 -0
- data/lib/qr_reader/decoder/galois_field.rb +69 -0
- data/lib/qr_reader/decoder/reed_solomon.rb +312 -0
- data/lib/qr_reader/decoder.rb +241 -0
- data/lib/qr_reader/detector/alignment_grid.rb +127 -0
- data/lib/qr_reader/detector/alignment_pattern_finder.rb +191 -0
- data/lib/qr_reader/detector/candidate/dimension.rb +237 -0
- data/lib/qr_reader/detector/candidate/strokes.rb +126 -0
- data/lib/qr_reader/detector/candidate.rb +436 -0
- data/lib/qr_reader/detector/finder_pattern.rb +63 -0
- data/lib/qr_reader/detector/finder_pattern_finder.rb +199 -0
- data/lib/qr_reader/detector/geometry.rb +118 -0
- data/lib/qr_reader/detector/grid_sampler.rb +350 -0
- data/lib/qr_reader/detector/pattern_sets.rb +235 -0
- data/lib/qr_reader/detector/perspective_transform.rb +117 -0
- data/lib/qr_reader/detector/pure_detector.rb +197 -0
- data/lib/qr_reader/detector.rb +215 -0
- data/lib/qr_reader/errors.rb +14 -0
- data/lib/qr_reader/format_information.rb +79 -0
- data/lib/qr_reader/formats/bmp.rb +434 -0
- data/lib/qr_reader/formats/ccitt.rb +81 -0
- data/lib/qr_reader/formats/gif.rb +272 -0
- data/lib/qr_reader/formats/jpeg.rb +152 -0
- data/lib/qr_reader/formats/pdf.rb +2935 -0
- data/lib/qr_reader/formats/png.rb +311 -0
- data/lib/qr_reader/formats/pnm.rb +286 -0
- data/lib/qr_reader/formats/tiff.rb +1345 -0
- data/lib/qr_reader/formats.rb +279 -0
- data/lib/qr_reader/image.rb +231 -0
- data/lib/qr_reader/kernels/binarizer.rb +475 -0
- data/lib/qr_reader/kernels/ccitt.rb +554 -0
- data/lib/qr_reader/kernels/detector.rb +587 -0
- data/lib/qr_reader/kernels/image.rb +65 -0
- data/lib/qr_reader/kernels/jpeg.rb +3421 -0
- data/lib/qr_reader/kernels/lzw.rb +173 -0
- data/lib/qr_reader/kernels/pixels.rb +116 -0
- data/lib/qr_reader/kernels/png.rb +1138 -0
- data/lib/qr_reader/kernels.rb +14 -0
- data/lib/qr_reader/native_kernels.rb +130 -0
- data/lib/qr_reader/reader.rb +348 -0
- data/lib/qr_reader/result.rb +49 -0
- data/lib/qr_reader/symbol_version.rb +173 -0
- data/lib/qr_reader/version.rb +5 -0
- data/lib/qr_reader.rb +77 -0
- metadata +103 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module QrReader
|
|
4
|
+
# Static properties of a QR Code Model 2 symbol version (1..40):
|
|
5
|
+
# dimension, alignment pattern centres, error correction block layout and
|
|
6
|
+
# the 18-bit version information word (versions 7+).
|
|
7
|
+
class SymbolVersion
|
|
8
|
+
# Error correction levels in the order of their 2-bit format code.
|
|
9
|
+
# Format bits: L = 01, M = 00, Q = 11, H = 10.
|
|
10
|
+
EC_LEVELS = %i[L M Q H].freeze
|
|
11
|
+
EC_LEVEL_FOR_BITS = %i[M L H Q].freeze # index = 2-bit value from format info
|
|
12
|
+
|
|
13
|
+
# Per version, per level (L, M, Q, H):
|
|
14
|
+
# [ec_codewords_per_block, count1, data_codewords1, count2, data_codewords2]
|
|
15
|
+
# (count2 / data_codewords2 are 0 when there is a single block group).
|
|
16
|
+
EC_TABLE = [
|
|
17
|
+
nil,
|
|
18
|
+
[[7, 1, 19, 0, 0], [10, 1, 16, 0, 0], [13, 1, 13, 0, 0], [17, 1, 9, 0, 0]],
|
|
19
|
+
[[10, 1, 34, 0, 0], [16, 1, 28, 0, 0], [22, 1, 22, 0, 0], [28, 1, 16, 0, 0]],
|
|
20
|
+
[[15, 1, 55, 0, 0], [26, 1, 44, 0, 0], [18, 2, 17, 0, 0], [22, 2, 13, 0, 0]],
|
|
21
|
+
[[20, 1, 80, 0, 0], [18, 2, 32, 0, 0], [26, 2, 24, 0, 0], [16, 4, 9, 0, 0]],
|
|
22
|
+
[[26, 1, 108, 0, 0], [24, 2, 43, 0, 0], [18, 2, 15, 2, 16], [22, 2, 11, 2, 12]],
|
|
23
|
+
[[18, 2, 68, 0, 0], [16, 4, 27, 0, 0], [24, 4, 19, 0, 0], [28, 4, 15, 0, 0]],
|
|
24
|
+
[[20, 2, 78, 0, 0], [18, 4, 31, 0, 0], [18, 2, 14, 4, 15], [26, 4, 13, 1, 14]],
|
|
25
|
+
[[24, 2, 97, 0, 0], [22, 2, 38, 2, 39], [22, 4, 18, 2, 19], [26, 4, 14, 2, 15]],
|
|
26
|
+
[[30, 2, 116, 0, 0], [22, 3, 36, 2, 37], [20, 4, 16, 4, 17], [24, 4, 12, 4, 13]],
|
|
27
|
+
[[18, 2, 68, 2, 69], [26, 4, 43, 1, 44], [24, 6, 19, 2, 20], [28, 6, 15, 2, 16]],
|
|
28
|
+
[[20, 4, 81, 0, 0], [30, 1, 50, 4, 51], [28, 4, 22, 4, 23], [24, 3, 12, 8, 13]],
|
|
29
|
+
[[24, 2, 92, 2, 93], [22, 6, 36, 2, 37], [26, 4, 20, 6, 21], [28, 7, 14, 4, 15]],
|
|
30
|
+
[[26, 4, 107, 0, 0], [22, 8, 37, 1, 38], [24, 8, 20, 4, 21], [22, 12, 11, 4, 12]],
|
|
31
|
+
[[30, 3, 115, 1, 116], [24, 4, 40, 5, 41], [20, 11, 16, 5, 17], [24, 11, 12, 5, 13]],
|
|
32
|
+
[[22, 5, 87, 1, 88], [24, 5, 41, 5, 42], [30, 5, 24, 7, 25], [24, 11, 12, 7, 13]],
|
|
33
|
+
[[24, 5, 98, 1, 99], [28, 7, 45, 3, 46], [24, 15, 19, 2, 20], [30, 3, 15, 13, 16]],
|
|
34
|
+
[[28, 1, 107, 5, 108], [28, 10, 46, 1, 47], [28, 1, 22, 15, 23], [28, 2, 14, 17, 15]],
|
|
35
|
+
[[30, 5, 120, 1, 121], [26, 9, 43, 4, 44], [28, 17, 22, 1, 23], [28, 2, 14, 19, 15]],
|
|
36
|
+
[[28, 3, 113, 4, 114], [26, 3, 44, 11, 45], [26, 17, 21, 4, 22], [26, 9, 13, 16, 14]],
|
|
37
|
+
[[28, 3, 107, 5, 108], [26, 3, 41, 13, 42], [30, 15, 24, 5, 25], [28, 15, 15, 10, 16]],
|
|
38
|
+
[[28, 4, 116, 4, 117], [26, 17, 42, 0, 0], [28, 17, 22, 6, 23], [30, 19, 16, 6, 17]],
|
|
39
|
+
[[28, 2, 111, 7, 112], [28, 17, 46, 0, 0], [30, 7, 24, 16, 25], [24, 34, 13, 0, 0]],
|
|
40
|
+
[[30, 4, 121, 5, 122], [28, 4, 47, 14, 48], [30, 11, 24, 14, 25], [30, 16, 15, 14, 16]],
|
|
41
|
+
[[30, 6, 117, 4, 118], [28, 6, 45, 14, 46], [30, 11, 24, 16, 25], [30, 30, 16, 2, 17]],
|
|
42
|
+
[[26, 8, 106, 4, 107], [28, 8, 47, 13, 48], [30, 7, 24, 22, 25], [30, 22, 15, 13, 16]],
|
|
43
|
+
[[28, 10, 114, 2, 115], [28, 19, 46, 4, 47], [28, 28, 22, 6, 23], [30, 33, 16, 4, 17]],
|
|
44
|
+
[[30, 8, 122, 4, 123], [28, 22, 45, 3, 46], [30, 8, 23, 26, 24], [30, 12, 15, 28, 16]],
|
|
45
|
+
[[30, 3, 117, 10, 118], [28, 3, 45, 23, 46], [30, 4, 24, 31, 25], [30, 11, 15, 31, 16]],
|
|
46
|
+
[[30, 7, 116, 7, 117], [28, 21, 45, 7, 46], [30, 1, 23, 37, 24], [30, 19, 15, 26, 16]],
|
|
47
|
+
[[30, 5, 115, 10, 116], [28, 19, 47, 10, 48], [30, 15, 24, 25, 25], [30, 23, 15, 25, 16]],
|
|
48
|
+
[[30, 13, 115, 3, 116], [28, 2, 46, 29, 47], [30, 42, 24, 1, 25], [30, 23, 15, 28, 16]],
|
|
49
|
+
[[30, 17, 115, 0, 0], [28, 10, 46, 23, 47], [30, 10, 24, 35, 25], [30, 19, 15, 35, 16]],
|
|
50
|
+
[[30, 17, 115, 1, 116], [28, 14, 46, 21, 47], [30, 29, 24, 19, 25], [30, 11, 15, 46, 16]],
|
|
51
|
+
[[30, 13, 115, 6, 116], [28, 14, 46, 23, 47], [30, 44, 24, 7, 25], [30, 59, 16, 1, 17]],
|
|
52
|
+
[[30, 12, 121, 7, 122], [28, 12, 47, 26, 48], [30, 39, 24, 14, 25], [30, 22, 15, 41, 16]],
|
|
53
|
+
[[30, 6, 121, 14, 122], [28, 6, 47, 34, 48], [30, 46, 24, 10, 25], [30, 2, 15, 64, 16]],
|
|
54
|
+
[[30, 17, 122, 4, 123], [28, 29, 46, 14, 47], [30, 49, 24, 10, 25], [30, 24, 15, 46, 16]],
|
|
55
|
+
[[30, 4, 122, 18, 123], [28, 13, 46, 32, 47], [30, 48, 24, 14, 25], [30, 42, 15, 32, 16]],
|
|
56
|
+
[[30, 20, 117, 4, 118], [28, 40, 47, 7, 48], [30, 43, 24, 22, 25], [30, 10, 15, 67, 16]],
|
|
57
|
+
[[30, 19, 118, 6, 119], [28, 18, 47, 31, 48], [30, 34, 24, 34, 25], [30, 20, 15, 61, 16]]
|
|
58
|
+
].freeze
|
|
59
|
+
|
|
60
|
+
VERSION_INFO_GENERATOR = 0x1F25
|
|
61
|
+
|
|
62
|
+
# Error correction block layout for one level of one version.
|
|
63
|
+
EcBlocks = Struct.new(:ec_codewords_per_block, :groups) do
|
|
64
|
+
# Array of data codeword counts, one entry per block, in transmission order.
|
|
65
|
+
def data_codewords_per_block
|
|
66
|
+
groups.flat_map { |count, data| [data] * count }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def block_count
|
|
70
|
+
groups.sum { |count, _| count }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def total_data_codewords
|
|
74
|
+
groups.sum { |count, data| count * data }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
attr_reader :number, :dimension, :alignment_centers, :total_codewords, :version_info_bits
|
|
79
|
+
|
|
80
|
+
def initialize(number)
|
|
81
|
+
@number = number
|
|
82
|
+
@dimension = 17 + 4 * number
|
|
83
|
+
@alignment_centers = self.class.compute_alignment_centers(number).freeze
|
|
84
|
+
@ec_blocks = EC_TABLE[number].map do |ec, c1, d1, c2, d2|
|
|
85
|
+
groups = [[c1, d1]]
|
|
86
|
+
groups << [c2, d2] if c2.positive?
|
|
87
|
+
EcBlocks.new(ec, groups.freeze).freeze
|
|
88
|
+
end.freeze
|
|
89
|
+
@total_codewords = self.class.raw_data_modules(number) / 8
|
|
90
|
+
@version_info_bits = number >= 7 ? self.class.encode_version_info(number) : nil
|
|
91
|
+
freeze
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# EcBlocks for the given level (:L, :M, :Q, :H).
|
|
95
|
+
def ec_blocks(level)
|
|
96
|
+
@ec_blocks[EC_LEVELS.index(level) || raise(ArgumentError, "unknown EC level #{level.inspect}")]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def data_codewords(level)
|
|
100
|
+
ec_blocks(level).total_data_codewords
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def inspect
|
|
104
|
+
"#<QrReader::SymbolVersion #{@number} (#{@dimension}x#{@dimension})>"
|
|
105
|
+
end
|
|
106
|
+
alias to_s inspect
|
|
107
|
+
|
|
108
|
+
class << self
|
|
109
|
+
# Version for a number in 1..40, or nil.
|
|
110
|
+
def [](number)
|
|
111
|
+
ALL[number - 1] if number.is_a?(Integer) && number.between?(1, 40)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Version for a symbol dimension (21, 25, ... 177), or nil when the
|
|
115
|
+
# dimension is not 1 mod 4 or out of range.
|
|
116
|
+
def for_dimension(dimension)
|
|
117
|
+
return nil unless (dimension % 4) == 1
|
|
118
|
+
|
|
119
|
+
self[(dimension - 17) / 4]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Decodes an 18-bit version information word read from the symbol.
|
|
123
|
+
# Returns the version whose code word is closest in Hamming distance,
|
|
124
|
+
# provided the distance is at most 3, else nil.
|
|
125
|
+
def decode_version_info(bits)
|
|
126
|
+
best = nil
|
|
127
|
+
best_distance = 4
|
|
128
|
+
7.upto(40) do |v|
|
|
129
|
+
code = ALL[v - 1].version_info_bits
|
|
130
|
+
return ALL[v - 1] if code == bits
|
|
131
|
+
|
|
132
|
+
distance = (code ^ bits).digits(2).sum
|
|
133
|
+
if distance < best_distance
|
|
134
|
+
best = ALL[v - 1]
|
|
135
|
+
best_distance = distance
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
best
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Alignment pattern centre coordinates (same for rows and columns).
|
|
142
|
+
def compute_alignment_centers(version)
|
|
143
|
+
return [] if version == 1
|
|
144
|
+
|
|
145
|
+
count = version / 7 + 2
|
|
146
|
+
last = 17 + 4 * version - 7
|
|
147
|
+
step = version == 32 ? 26 : (version * 4 + count * 2 + 1) / (count * 2 - 2) * 2
|
|
148
|
+
result = [6]
|
|
149
|
+
(count - 1).times { |i| result.insert(1, last - i * step) }
|
|
150
|
+
result
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Number of modules available for data + EC codewords (incl. remainder bits).
|
|
154
|
+
def raw_data_modules(version)
|
|
155
|
+
result = (16 * version + 128) * version + 64
|
|
156
|
+
if version >= 2
|
|
157
|
+
align = version / 7 + 2
|
|
158
|
+
result -= (25 * align - 10) * align - 55
|
|
159
|
+
result -= 36 if version >= 7
|
|
160
|
+
end
|
|
161
|
+
result
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def encode_version_info(version)
|
|
165
|
+
rem = version
|
|
166
|
+
12.times { rem = (rem << 1) ^ ((rem >> 11) * VERSION_INFO_GENERATOR) }
|
|
167
|
+
(version << 12) | rem
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
ALL = (1..40).map { |n| new(n) }.freeze
|
|
172
|
+
end
|
|
173
|
+
end
|
data/lib/qr_reader.rb
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "qr_reader/version"
|
|
4
|
+
require_relative "qr_reader/errors"
|
|
5
|
+
require_relative "qr_reader/kernels"
|
|
6
|
+
require_relative "qr_reader/image"
|
|
7
|
+
require_relative "qr_reader/bit_matrix"
|
|
8
|
+
require_relative "qr_reader/result"
|
|
9
|
+
require_relative "qr_reader/symbol_version"
|
|
10
|
+
require_relative "qr_reader/format_information"
|
|
11
|
+
require_relative "qr_reader/formats"
|
|
12
|
+
require_relative "qr_reader/formats/ccitt"
|
|
13
|
+
require_relative "qr_reader/formats/tiff"
|
|
14
|
+
require_relative "qr_reader/formats/pdf"
|
|
15
|
+
require_relative "qr_reader/decoder"
|
|
16
|
+
require_relative "qr_reader/detector"
|
|
17
|
+
require_relative "qr_reader/reader"
|
|
18
|
+
require_relative "qr_reader/native_kernels"
|
|
19
|
+
|
|
20
|
+
# Pure-Ruby QR code reader.
|
|
21
|
+
#
|
|
22
|
+
# QrReader.decode("photo.jpg") # => "https://example.com" or nil
|
|
23
|
+
# QrReader.decode_all("scan.pdf") # => ["first code", "second code"]
|
|
24
|
+
# QrReader.read("label.png") # => #<data QrReader::Result text=..., version=3, ...>
|
|
25
|
+
# QrReader.scan("scans.tiff") { |code| puts "page #{code.page}: #{code.text}" }
|
|
26
|
+
#
|
|
27
|
+
# Every method accepts a file path (String or Pathname), an IO, encoded image
|
|
28
|
+
# bytes (PNG, JPEG, GIF, BMP, PNM, TIFF, PDF), a QrReader::Image, or a
|
|
29
|
+
# ChunkyPNG-style canvas (#width, #height, #pixels), plus these options:
|
|
30
|
+
#
|
|
31
|
+
# try_harder: true - fall back to slower strategies when the fast ones find nothing
|
|
32
|
+
# inverted: :auto - also look for light-on-dark codes (true: only those, false: never)
|
|
33
|
+
module QrReader
|
|
34
|
+
class << self
|
|
35
|
+
# Text of the first QR code found, or nil.
|
|
36
|
+
def decode(input, **options)
|
|
37
|
+
read(input, **options)&.text
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Like #decode, but raises NotFoundError when no code can be read.
|
|
41
|
+
def decode!(input, **options)
|
|
42
|
+
decode(input, **options) or raise NotFoundError, "no QR code found"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Texts of all QR codes found (on all pages), possibly empty.
|
|
46
|
+
def decode_all(input, **options)
|
|
47
|
+
read_all(input, **options).map(&:text)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# First QR code found as a Result (text plus metadata), or nil.
|
|
51
|
+
def read(input, **options)
|
|
52
|
+
Reader.new(**options).read(input)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# All QR codes found (on all pages) as Results, possibly empty.
|
|
56
|
+
def read_all(input, **options)
|
|
57
|
+
Reader.new(**options).read_all(input)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Yields each QR code (a Result) as soon as it is decoded, page by page;
|
|
61
|
+
# +break+ out to stop early. Returns an Enumerator when no block is given.
|
|
62
|
+
def scan(input, **options, &block)
|
|
63
|
+
return enum_for(:scan, input, **options) unless block
|
|
64
|
+
|
|
65
|
+
Reader.new(**options).scan(input, &block)
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Loads an image (path, IO, encoded bytes, Image or ChunkyPNG-style canvas)
|
|
70
|
+
# as a grayscale QrReader::Image; multi-page documents yield their first page.
|
|
71
|
+
def load_image(input)
|
|
72
|
+
Reader.load_image(input)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
QrReader::NativeKernels.install
|
metadata
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: qr_reader
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Andi Idogawa
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Detects and decodes QR codes in photos and scanned documents (PNG, JPEG,
|
|
13
|
+
GIF, BMP, PNM, TIFF incl. CCITT fax, PDF) without native extensions or external
|
|
14
|
+
tools.
|
|
15
|
+
email:
|
|
16
|
+
- andi@idogawa.com
|
|
17
|
+
executables:
|
|
18
|
+
- qr_reader
|
|
19
|
+
extensions: []
|
|
20
|
+
extra_rdoc_files: []
|
|
21
|
+
files:
|
|
22
|
+
- CHANGELOG.md
|
|
23
|
+
- LICENSE.txt
|
|
24
|
+
- NOTICE
|
|
25
|
+
- README.md
|
|
26
|
+
- exe/qr_reader
|
|
27
|
+
- lib/qr_reader.rb
|
|
28
|
+
- lib/qr_reader/binarizer.rb
|
|
29
|
+
- lib/qr_reader/bit_matrix.rb
|
|
30
|
+
- lib/qr_reader/decoder.rb
|
|
31
|
+
- lib/qr_reader/decoder/bitstream_parser.rb
|
|
32
|
+
- lib/qr_reader/decoder/character_set.rb
|
|
33
|
+
- lib/qr_reader/decoder/codewords.rb
|
|
34
|
+
- lib/qr_reader/decoder/data_mask.rb
|
|
35
|
+
- lib/qr_reader/decoder/format_reader.rb
|
|
36
|
+
- lib/qr_reader/decoder/function_patterns.rb
|
|
37
|
+
- lib/qr_reader/decoder/galois_field.rb
|
|
38
|
+
- lib/qr_reader/decoder/reed_solomon.rb
|
|
39
|
+
- lib/qr_reader/detector.rb
|
|
40
|
+
- lib/qr_reader/detector/alignment_grid.rb
|
|
41
|
+
- lib/qr_reader/detector/alignment_pattern_finder.rb
|
|
42
|
+
- lib/qr_reader/detector/candidate.rb
|
|
43
|
+
- lib/qr_reader/detector/candidate/dimension.rb
|
|
44
|
+
- lib/qr_reader/detector/candidate/strokes.rb
|
|
45
|
+
- lib/qr_reader/detector/finder_pattern.rb
|
|
46
|
+
- lib/qr_reader/detector/finder_pattern_finder.rb
|
|
47
|
+
- lib/qr_reader/detector/geometry.rb
|
|
48
|
+
- lib/qr_reader/detector/grid_sampler.rb
|
|
49
|
+
- lib/qr_reader/detector/pattern_sets.rb
|
|
50
|
+
- lib/qr_reader/detector/perspective_transform.rb
|
|
51
|
+
- lib/qr_reader/detector/pure_detector.rb
|
|
52
|
+
- lib/qr_reader/errors.rb
|
|
53
|
+
- lib/qr_reader/format_information.rb
|
|
54
|
+
- lib/qr_reader/formats.rb
|
|
55
|
+
- lib/qr_reader/formats/bmp.rb
|
|
56
|
+
- lib/qr_reader/formats/ccitt.rb
|
|
57
|
+
- lib/qr_reader/formats/gif.rb
|
|
58
|
+
- lib/qr_reader/formats/jpeg.rb
|
|
59
|
+
- lib/qr_reader/formats/pdf.rb
|
|
60
|
+
- lib/qr_reader/formats/png.rb
|
|
61
|
+
- lib/qr_reader/formats/pnm.rb
|
|
62
|
+
- lib/qr_reader/formats/tiff.rb
|
|
63
|
+
- lib/qr_reader/image.rb
|
|
64
|
+
- lib/qr_reader/kernels.rb
|
|
65
|
+
- lib/qr_reader/kernels/binarizer.rb
|
|
66
|
+
- lib/qr_reader/kernels/ccitt.rb
|
|
67
|
+
- lib/qr_reader/kernels/detector.rb
|
|
68
|
+
- lib/qr_reader/kernels/image.rb
|
|
69
|
+
- lib/qr_reader/kernels/jpeg.rb
|
|
70
|
+
- lib/qr_reader/kernels/lzw.rb
|
|
71
|
+
- lib/qr_reader/kernels/pixels.rb
|
|
72
|
+
- lib/qr_reader/kernels/png.rb
|
|
73
|
+
- lib/qr_reader/native_kernels.rb
|
|
74
|
+
- lib/qr_reader/reader.rb
|
|
75
|
+
- lib/qr_reader/result.rb
|
|
76
|
+
- lib/qr_reader/symbol_version.rb
|
|
77
|
+
- lib/qr_reader/version.rb
|
|
78
|
+
homepage: https://github.com/largo/qr_reader
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata:
|
|
82
|
+
rubygems_mfa_required: 'true'
|
|
83
|
+
source_code_uri: https://github.com/largo/qr_reader
|
|
84
|
+
changelog_uri: https://github.com/largo/qr_reader/blob/main/CHANGELOG.md
|
|
85
|
+
bug_tracker_uri: https://github.com/largo/qr_reader/issues
|
|
86
|
+
rdoc_options: []
|
|
87
|
+
require_paths:
|
|
88
|
+
- lib
|
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '3.2'
|
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
requirements: []
|
|
100
|
+
rubygems_version: 4.0.20
|
|
101
|
+
specification_version: 4
|
|
102
|
+
summary: Fast, accurate QR code reader in pure Ruby.
|
|
103
|
+
test_files: []
|