qrencoder 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: