qrencoder 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.
@@ -0,0 +1,5 @@
1
+ == 1.0.0 / 2007-01-03
2
+
3
+ * Initial release
4
+ * Wooo!
5
+
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/qrencoder
6
+ lib/qrencoder.rb
7
+ test/test_qrencoder.rb
@@ -0,0 +1,107 @@
1
+ qrencoder
2
+ by Jacob Harris
3
+ http://www.nimblecode.com/
4
+ http://nycrb.rubyforge.org/qrencoder
5
+
6
+ == DESCRIPTION:
7
+
8
+ This Gem is a wrapper around an useful open-source library for creating QR
9
+ Codes, a two-dimensional bar code format popular in Japan (and readable by cell
10
+ phones even) created by the Denso-Wave Corporation in 1994. These bar codes look
11
+ like the following:
12
+
13
+ http://www.denso-wave.com/qrcode/images/qrcode.gif
14
+
15
+ The specification for QR codes is readable at
16
+ http://www.denso-wave.com/qrcode/index-e.html. QR Code is not the only 2-D
17
+ barcode standard in existence, and it is in wider use in Japan than elsewhere.
18
+ Notable competitors include PDF417, Semacode/DataMatrix, and Maxi Code (seen on
19
+ UPS labels) in North America; ShotCode in the UK; and an additional format used
20
+ in Korea. All vary in look and capacity, but QR code has one of the largest
21
+ information densities and capacities among them with the following maximum data
22
+
23
+ * Numeric 7,089
24
+ * Alphanumeric 4,296
25
+ * 8-Bit 2,953
26
+ * Kanji 1,817
27
+
28
+ All of these in a square that may range from 21 to 177 pixels a side (there are
29
+ 40 different "versions" of the code that specify different sizes). In addition,
30
+ multiple levels of error correction are possible which might also influence the
31
+ final size.
32
+
33
+ == FEATURES/PROBLEMS:
34
+
35
+ * This gem requires you to build and install an external C library
36
+ * The QREncode lib this GEM is built around is NOT thread-safe!
37
+
38
+ == SYNOPSIS:
39
+
40
+ There are 4 initialization methods for creating a QR code, two for strings, two
41
+ for data. Both of these come in a simpler variant which take the string/data to
42
+ be encoded. The second argument is a QR Code version (used to pick the size of
43
+ the final QR Code); this version is adjusted upwards if the data is too large to
44
+ fit within the specified version.
45
+
46
+ img = QRCode.encode_string(text, 1)
47
+ puts "#{img.version}" #=> 7
48
+ puts "#{img.width}" #=> 34
49
+ img.save_png("/tmp/foo.png")
50
+
51
+ You can retrieve the pixels of the output image directly or use the included
52
+ methods to save a PNG file directly.
53
+
54
+ == REQUIREMENTS:
55
+
56
+ This gem requires you to build the C library lib <tt>libqrcode.a</tt> available
57
+ from http://megaui.net/fukuchi/works/qrencode/index.en.html.
58
+
59
+ Normally, the build process also expects you to install <tt>libpng</tt>, but
60
+ this is only used for the <tt>qrenc</tt> command-line utility and can be avoided
61
+ if you run the following build sequence:
62
+
63
+ ./configure --without-tools
64
+ make
65
+ sudo make install
66
+
67
+ This gem also requires the following gems to be installed:
68
+
69
+ * ruby-inline
70
+ * png
71
+
72
+ == INSTALL:
73
+
74
+ * First build the <tt>libqrencode</tt> library following the instructions above.
75
+ * Then <tt>sudo gem install qrencoder --include-dependencies</tt>
76
+
77
+ == QRCODE LICENSE:
78
+
79
+ The QR Code specification was created and patented by the Denso Corporation of
80
+ Japan. Although the Denso Corporation retains their patent, it is "open in the
81
+ sense that the specification of QR Code is disclosed and that the patent right
82
+ owned by Denso Wave is not exercised." according to their website.
83
+
84
+ == LICENSE:
85
+
86
+ (The MIT License)
87
+
88
+ Copyright (c) 2007
89
+
90
+ Permission is hereby granted, free of charge, to any person obtaining
91
+ a copy of this software and associated documentation files (the
92
+ 'Software'), to deal in the Software without restriction, including
93
+ without limitation the rights to use, copy, modify, merge, publish,
94
+ distribute, sublicense, and/or sell copies of the Software, and to
95
+ permit persons to whom the Software is furnished to do so, subject to
96
+ the following conditions:
97
+
98
+ The above copyright notice and this permission notice shall be
99
+ included in all copies or substantial portions of the Software.
100
+
101
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
102
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
103
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
104
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
105
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
106
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
107
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/qrencoder.rb'
6
+
7
+ Hoe.new('qrencoder', QRCode::GEM_VERSION) do |p|
8
+ p.rubyforge_name = 'nycrb'
9
+ p.author = 'Jacob Harris'
10
+ p.email = 'harrisj@schizopolis.net'
11
+ p.summary = 'A gem for creating 2-dimensional barcodes following the QR Code specification.'
12
+ # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
13
+ p.url = 'http://nycrb.rubyforge.org/qrencoder'
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ p.extra_deps << ['RubyInline', '>=3.6.2']
16
+ p.extra_deps << ['png', '>=1.0.0']
17
+ end
18
+
19
+ # vim: syntax=Ruby
File without changes
@@ -0,0 +1,282 @@
1
+ require 'rubygems'
2
+ require 'inline'
3
+ require 'png'
4
+
5
+ class QRCode
6
+ GEM_VERSION = '1.0.0'
7
+
8
+ # Encoding modes
9
+ QR_MODE_NUM = 0
10
+ QR_MODE_AN = 1
11
+ QR_MODE_8 = 2
12
+ QR_MODE_KANJI = 3
13
+
14
+ # Error correction
15
+ QR_ECLEVEL_L = 0
16
+ QR_ECLEVEL_M = 1
17
+ QR_ECLEVEL_Q = 2
18
+ QR_ECLEVEL_H = 3
19
+
20
+ ##
21
+ # Version of the symbol. A QR Code version indicates the size of the 2-D
22
+ # barcode in modules. See #qrencode_string for a more detailed description of
23
+ # the version. Note that the version returned might be larger than the version
24
+ # specified for an encode_string if the requested version is for a barcode too
25
+ # small to encode the data.
26
+ def version; end;
27
+
28
+ ##
29
+ # Width of the symbol in modules. This value usually corresponds to 1 module
30
+ # is 1 pixel, but you could conceivably scale it up if you wanted to.
31
+ def width; end;
32
+
33
+ ##
34
+ # Returns the raw data of the QRcode within a single array of width*width
35
+ # elements. Each item is a byte of data of which only the least significant
36
+ # bit is the pixel. The full use of each bit from Least Significant to Most is
37
+ # as follows
38
+ #
39
+ # * 1=black/0=white
40
+ # * data and ecc code area
41
+ # * format information
42
+ # * version information
43
+ # * timing pattern
44
+ # * alignment pattern
45
+ # * finder pattern and separator
46
+ # * non-data modules (format, timing, etc.)
47
+ #
48
+ # This structure allows the QRcode spec to store multiple types of information
49
+ # within the allocated output buffers, but you usually only care about the pixel
50
+ # color. For those cases, just use the #pixels or #points methods.
51
+ def data; end;
52
+
53
+ ##
54
+ # Returns the QRcode as an array of rows where each item in a row represents
55
+ # the value of the pixel (1=black, 0=white)
56
+ def pixels; end;
57
+
58
+ ##
59
+ # Returns the black pixels of the encoded image as an array of coordinate pairs.
60
+ def points; end;
61
+
62
+ ##
63
+ # Encodes a QR code from a string. This version of the method assumes the
64
+ # input data is 8-bit ASCII and that you want the most basic error correction.
65
+ # For more detailed control over those parameters, use #encode_string_ex. This
66
+ # method takes 2 arguments: a string to encode and a QRCode <tt>version</tt>
67
+ # which essentially determines the size of the QRCode.
68
+ #
69
+ # What is the version? Each QRCode is made up
70
+ # of <b>modules</b> which are the basic display element of a QRCode and may
71
+ # be made up of 1 or more pixels (here, it's just 1 module is 1 pixel).
72
+ # Version 1 is a 21x21
73
+ # module square, while the maximum version 40 is 177x177 modules. The full
74
+ # module reference is here http://www.denso-wave.com/qrcode/vertable1-e.html
75
+ #
76
+ # Should you encode more text than can fit in a module, the encoder will scale
77
+ # up to the smallest version able to contain your data. Unless you want to
78
+ # specifically fix your barcode to a certain version, it's fine to just set
79
+ # the version argument to 1 and let #encode_string figure out the proper size.
80
+ def encode_string; end;
81
+
82
+ ##
83
+ # This function is similar in purpose to #encode_string, but it allows you to
84
+ # explicitly specify the encoding and error correction level. There are 4
85
+ # arguments to this function:
86
+ #
87
+ # * <tt>string</tt> the string to encode
88
+ # * <tt>version</tt> the version of the QR Code (see #encode_string for explanation)
89
+ # * <tt>error correction level</tt>
90
+ # * <tt>encoding mode</tt>
91
+ #
92
+ # The following four Constants can be specified for error correction levels, each
93
+ # specified with the maximum approximate error rate they can compensate for, as
94
+ # well as the maximum capacity of an 8-bit data QR Code with the error encoding:
95
+ #
96
+ # * <tt>QR_ECLEVEL_L</tt> - 7%/2953 [default]
97
+ # * <tt>QR_ECLEVEL_M</tt> - 15%/2331
98
+ # * <tt>QR_ECLEVEL_Q</tt> - 25%/1663
99
+ # * <tt>QR_ECLEVEL_H</tt> - 30%/1273
100
+ #
101
+ # Higher error rates are suitable for applications where the QR Code is likely
102
+ # to be smudged or damaged, but as is apparent here, they can radically reduce
103
+ # the maximum data capacity of a QR Code.
104
+ #
105
+ # There are also 4 possible encodings for a QR Code which can modify the
106
+ # maximum data capacity. These are specified with four possible Constants, each
107
+ # listed here with the maximum capacity available for that encoding at the lowest
108
+ # error correction rate.
109
+ #
110
+ # * <tt>QR_MODE_NUM</tt> - Numeric/7089
111
+ # * <tt>QR_MODE_AN</tt> - Alphanumeric/4296
112
+ # * <tt>QR_MODE_8</tt> - 8-bit ASCII/2953 [default]
113
+ # * <tt>QR_MODE_KANJI</tt> - Kanji (JIS-1 & 2)/1817
114
+ #
115
+ # Note that the QR Code specification seemingly predates the rise and triumph
116
+ # of UTF-8, and the specification makes no requirement that writers and readers
117
+ # use ISO-8859-1 or UTF-8 or whatever to interpret the data in a barcode. If you
118
+ # encode in UTF-8, it might be read as ISO-8859-1 or not.
119
+ def encode_string_ex; end;
120
+
121
+ # now for the inlines
122
+ inline do |builder|
123
+ builder.add_link_flags "-lqrencode"
124
+ builder.include '"qrencode.h"'
125
+
126
+ builder.prefix <<-"END"
127
+ static void qrcode_free(void *p) {
128
+ QRcode *qrcode = (QRcode *) p;
129
+ QRcode_free(qrcode);
130
+ }
131
+ END
132
+
133
+ builder.c <<-"END"
134
+ int width() {
135
+ QRcode *qrcode;
136
+ Data_Get_Struct(self, QRcode, qrcode);
137
+ return qrcode->width;
138
+ }
139
+ END
140
+
141
+ builder.c <<-"END"
142
+ int version() {
143
+ QRcode *qrcode;
144
+ Data_Get_Struct(self, QRcode, qrcode);
145
+ return qrcode->version;
146
+ }
147
+ END
148
+
149
+ builder.c <<-"END"
150
+ VALUE data() {
151
+ QRcode *qrcode;
152
+ VALUE out;
153
+ unsigned char *p, b;
154
+ int i, max;
155
+
156
+ Data_Get_Struct(self, QRcode, qrcode);
157
+ p = qrcode->data;
158
+ max = qrcode->width * qrcode->width;
159
+ out = rb_ary_new2(max);
160
+
161
+ for (i=0; i < max; i++) {
162
+ b = *p;
163
+ rb_ary_push(out, INT2FIX(b));
164
+ p++;
165
+ }
166
+
167
+ return out;
168
+ }
169
+ END
170
+
171
+ builder.c <<-"END"
172
+ VALUE pixels() {
173
+ QRcode *qrcode;
174
+ VALUE out, row;
175
+ unsigned char *p;
176
+ int x, y, bit;
177
+
178
+ Data_Get_Struct(self, QRcode, qrcode);
179
+ p = qrcode->data;
180
+ out = rb_ary_new2(qrcode->width);
181
+
182
+ for (y=0; y < qrcode->width; y++) {
183
+ row = rb_ary_new2(qrcode->width);
184
+
185
+ for (x=0; x < qrcode->width; x++) {
186
+ bit = *p & 1;
187
+ rb_ary_push(row, INT2FIX(bit));
188
+ p++;
189
+ }
190
+
191
+ rb_ary_push(out, row);
192
+ }
193
+
194
+ return out;
195
+ }
196
+ END
197
+
198
+ builder.c <<-"END"
199
+ VALUE points() {
200
+ QRcode *qrcode;
201
+ VALUE out, point;
202
+ unsigned char *p;
203
+ int x, y, bit;
204
+
205
+ Data_Get_Struct(self, QRcode, qrcode);
206
+ p = qrcode->data;
207
+ out = rb_ary_new2(qrcode->width);
208
+
209
+ for (y=0; y < qrcode->width; y++) {
210
+ for (x=0; x < qrcode->width; x++) {
211
+ bit = *p & 1;
212
+
213
+ if (bit) {
214
+ point = rb_ary_new2(2);
215
+ rb_ary_push(point, INT2FIX(x));
216
+ rb_ary_push(point, INT2FIX(y));
217
+ rb_ary_push(out, point);
218
+ }
219
+
220
+ p++;
221
+ }
222
+ }
223
+
224
+ return out;
225
+ }
226
+ END
227
+
228
+ builder.c_singleton <<-"END"
229
+ VALUE encode_string_ex(const char *string, int version, int eclevel, int mode) {
230
+ QRcode *code;
231
+ VALUE klass;
232
+
233
+ code = QRcode_encodeString(string, version, eclevel, mode);
234
+ klass = rb_const_get_at(rb_cObject, rb_intern("QRCode"));
235
+ return Data_Wrap_Struct(klass, NULL, qrcode_free, code);
236
+ }
237
+ END
238
+
239
+ builder.c_singleton <<-"END"
240
+ VALUE encode_string(const char *string, int version) {
241
+ QRcode *code;
242
+ VALUE klass;
243
+
244
+ code = QRcode_encodeString(string, version, QR_ECLEVEL_L, QR_MODE_8);
245
+ klass = rb_const_get_at(rb_cObject, rb_intern("QRCode"));
246
+ return Data_Wrap_Struct(klass, NULL, qrcode_free, code);
247
+ }
248
+ END
249
+
250
+ # builder.c <<-"END"
251
+ # VALUE encode_data_ex(const char *data, int len, int version, int eclevel, int mode) {
252
+ # QRcode *code;
253
+ # QRinput *input;
254
+ #
255
+ # input = QRinput_new();
256
+ # QRinput_append(input, mode, data, len);
257
+ # code = QRcode_encode(input, version, eclevel);
258
+ # Qrinput_free(input);
259
+ # return Data_Wrap_Struct(CLASS_OF(self), NULL, qrcode_free, code);
260
+ # }
261
+ # END
262
+ end
263
+
264
+ ##
265
+ # Height of the symbol. Since QR Codes are square, this is the same as the
266
+ # width but this alias is provided if you want to avoid confusion.
267
+ alias :height :width
268
+
269
+ ##
270
+ # Save the QRcode to a PNG file. You can also specify a margin in pixels around
271
+ # the image, although the specification requests it should be at least 4 px.
272
+ def save_png(path, margin=4)
273
+ canvas = PNG::Canvas.new width + (2*margin), width+(2*margin)
274
+
275
+ points.each do |p|
276
+ canvas.point p[0]+margin, p[1]+margin, PNG::Color::Black
277
+ end
278
+
279
+ png = PNG.new canvas
280
+ png.save path
281
+ end
282
+ end
@@ -0,0 +1,99 @@
1
+ require 'rubygems'
2
+ require 'inline'
3
+ require 'enumerator'
4
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
5
+ require './lib/qrencoder.rb'
6
+
7
+ class TestQRCode < Test::Unit::TestCase
8
+ inline do |builder|
9
+ builder.add_link_flags "-lqrencode"
10
+ builder.include '"qrencode.h"'
11
+
12
+ builder.c <<-"END"
13
+ VALUE test_img_data(const char *string, int version) {
14
+ QRcode *code;
15
+ VALUE out;
16
+ int i, width;
17
+ unsigned char *p;
18
+
19
+ code = QRcode_encodeString(string, version, QR_ECLEVEL_L, QR_MODE_8);
20
+
21
+ p = code->data;
22
+ width = code->width;
23
+ out = rb_ary_new2(width*width);
24
+
25
+ for (i=0; i < width*width; i++) {
26
+ unsigned char bit;
27
+ bit = *p;
28
+ rb_ary_push(out, INT2FIX(bit));
29
+ p++;
30
+ }
31
+
32
+ return out;
33
+ }
34
+ END
35
+ end
36
+
37
+ def setup
38
+ @q = QRCode.encode_string("hi", 1)
39
+ end
40
+
41
+ def test_class_encode_string
42
+ assert_equal 1, @q.version
43
+ assert_equal 21, @q.width
44
+ end
45
+
46
+ def test_class_encode_string_ex
47
+ #raise NotImplementedError, 'Need to write test_class_encode_string_ex'
48
+ end
49
+
50
+ def test_data
51
+ assert_equal test_img_data("hi", 1), @q.data
52
+ end
53
+
54
+ def test_height
55
+ assert_equal @q.width, @q.height
56
+ end
57
+
58
+ def test_pixels
59
+ arr = []
60
+ test_img_data("hi", 1).each_slice(@q.width) do |a|
61
+ arr << a.map { |p| p & 0x1 }
62
+ end
63
+
64
+ assert_equal arr, @q.pixels
65
+ end
66
+
67
+ def test_points
68
+ arr = []
69
+ y = 0
70
+
71
+ test_img_data("hi", 1).each_slice(@q.width) do |r|
72
+ x = 0;
73
+
74
+ r.each do |p|
75
+ if (p & 0x1) == 1
76
+ arr << [x, y]
77
+ end
78
+
79
+ x += 1
80
+ end
81
+
82
+ y += 1
83
+ end
84
+
85
+ assert_equal arr, @q.points
86
+ end
87
+
88
+ # def test_save_png
89
+ # raise NotImplementedError, 'Need to write test_save_png'
90
+ # end
91
+
92
+ def test_version
93
+ assert_equal 1, @q.version
94
+ end
95
+
96
+ def test_width
97
+ assert_equal 21, @q.width
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.1
3
+ specification_version: 1
4
+ name: qrencoder
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-01-24 00:00:00 -05:00
8
+ summary: A gem for creating 2-dimensional barcodes following the QR Code specification.
9
+ require_paths:
10
+ - lib
11
+ email: harrisj@schizopolis.net
12
+ homepage: http://nycrb.rubyforge.org/qrencoder
13
+ rubyforge_project: nycrb
14
+ description: The author was too lazy to write a description
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Jacob Harris
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - bin/qrencoder
37
+ - lib/qrencoder.rb
38
+ - test/test_qrencoder.rb
39
+ test_files:
40
+ - test/test_qrencoder.rb
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables:
46
+ - qrencoder
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies:
52
+ - !ruby/object:Gem::Dependency
53
+ name: RubyInline
54
+ version_requirement:
55
+ version_requirements: !ruby/object:Gem::Version::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 3.6.2
60
+ version:
61
+ - !ruby/object:Gem::Dependency
62
+ name: png
63
+ version_requirement:
64
+ version_requirements: !ruby/object:Gem::Version::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.0
69
+ version:
70
+ - !ruby/object:Gem::Dependency
71
+ name: hoe
72
+ version_requirement:
73
+ version_requirements: !ruby/object:Gem::Version::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 1.1.7
78
+ version: