quirc 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.
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mkmf"
4
+
5
+ ROOT = File.expand_path(File.join(__dir__, "..", ".."))
6
+ SRC_DIR = File.join(__dir__, "embed")
7
+ TMP_DIR = File.join(ROOT, "tmp", RUBY_PLATFORM)
8
+ BUILD_DIR = File.join(TMP_DIR, "quirc-1.0")
9
+ LIB_FILE = File.join(BUILD_DIR, "libquirc.a")
10
+
11
+ def build_library
12
+ Dir.mkdir(BUILD_DIR) unless File.exist?(BUILD_DIR)
13
+ system({ "BUILD_DIR" => BUILD_DIR }, "make", "-C", SRC_DIR) or raise "Error building quirc"
14
+ end
15
+
16
+ find_header("quirc.h", "#{SRC_DIR}/lib") or missing("quirc.h")
17
+ build_library
18
+ $LOCAL_LIBS << LIB_FILE
19
+
20
+ create_makefile("quirc/quirc")
@@ -0,0 +1,92 @@
1
+ #include <ruby.h>
2
+ #include <quirc.h>
3
+
4
+ static VALUE mQuirc, cDecoder, cResult;
5
+
6
+ static void decoder_free(struct quirc *qr) {
7
+ quirc_destroy(qr);
8
+ }
9
+
10
+ static VALUE decoder_alloc(VALUE self) {
11
+ struct quirc *qr = quirc_new();
12
+ if (qr == NULL) {
13
+ rb_raise(rb_const_get(rb_cObject, rb_intern("NoMemoryError")), "Could not allocate memory");
14
+ }
15
+ return Data_Wrap_Struct(self, NULL, decoder_free, qr);
16
+ }
17
+
18
+ static VALUE decoder_m_initialize(VALUE self, VALUE width, VALUE height) {
19
+ struct quirc *qr;
20
+
21
+ Data_Get_Struct(self, struct quirc, qr);
22
+ if (quirc_resize(qr, NUM2INT(width), NUM2INT(height)) < 0) {
23
+ rb_raise(rb_const_get(rb_cObject, rb_intern("NoMemoryError")), "Could not allocate memory");
24
+ }
25
+ rb_iv_set(self, "@width", width);
26
+ rb_iv_set(self, "@height", height);
27
+
28
+ return Qnil;
29
+ }
30
+
31
+ static VALUE decoder_m_decode(VALUE self, VALUE image) {
32
+ struct quirc *qr;
33
+ int width, height, size;
34
+ uint8_t *buffer;
35
+ int num_codes;
36
+ VALUE results;
37
+
38
+ Check_Type(image, T_STRING);
39
+ Data_Get_Struct(self, struct quirc, qr);
40
+
41
+ buffer = quirc_begin(qr, &width, &height);
42
+ size = width * height;
43
+ if (RSTRING_LEN(image) != size) {
44
+ rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")), "Decoder is allocated for %dx%d images", width, height);
45
+ }
46
+ memcpy(buffer, StringValuePtr(image), size);
47
+ quirc_end(qr);
48
+
49
+ num_codes = quirc_count(qr);
50
+ results = rb_ary_new2(num_codes);
51
+ for (int i = 0; i < num_codes; i++) {
52
+ struct quirc_code code;
53
+ struct quirc_data data;
54
+ quirc_decode_error_t err;
55
+ VALUE item;
56
+
57
+ quirc_extract(qr, i, &code);
58
+ err = quirc_decode(&code, &data);
59
+ if (err) continue;
60
+
61
+ item = rb_class_new_instance(0, NULL, cResult);
62
+ rb_iv_set(item, "@version", INT2FIX(data.version));
63
+ rb_iv_set(item, "@ecc_level", INT2FIX(data.ecc_level));
64
+ rb_iv_set(item, "@mask", INT2FIX(data.mask));
65
+ rb_iv_set(item, "@data_type", INT2FIX(data.data_type));
66
+ rb_iv_set(item, "@payload", rb_str_freeze(rb_str_new((const char *) data.payload, data.payload_len)));
67
+ rb_iv_set(item, "@eci", INT2NUM(data.eci));
68
+ rb_ary_push(results, item);
69
+ }
70
+
71
+ return results;
72
+ }
73
+
74
+ void Init_quirc(void) {
75
+ mQuirc = rb_const_get(rb_cObject, rb_intern("Quirc"));
76
+ rb_define_const(mQuirc, "LIB_VERSION", rb_str_freeze(rb_str_new_cstr(quirc_version())));
77
+
78
+ cDecoder = rb_define_class_under(mQuirc, "Decoder", rb_cObject);
79
+ rb_define_alloc_func(cDecoder, decoder_alloc);
80
+ rb_define_method(cDecoder, "initialize", decoder_m_initialize, 2);
81
+ rb_define_method(cDecoder, "decode", decoder_m_decode, 1);
82
+ rb_define_attr(cDecoder, "width", 1, 0);
83
+ rb_define_attr(cDecoder, "height", 1, 0);
84
+
85
+ cResult = rb_define_class_under(mQuirc, "Result", rb_cObject);
86
+ rb_define_attr(cResult, "version", 1, 0);
87
+ rb_define_attr(cResult, "ecc_level", 1, 0);
88
+ rb_define_attr(cResult, "mask", 1, 0);
89
+ rb_define_attr(cResult, "data_type", 1, 0);
90
+ rb_define_attr(cResult, "payload", 1, 0);
91
+ rb_define_attr(cResult, "eci", 1, 0);
92
+ }
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Quirc
4
+ def self.decode(image, width=nil, height=nil)
5
+ width ||= image.public_send(:width)
6
+ height ||= image.public_send(:height)
7
+ if image.respond_to?(:to_grayscale_stream)
8
+ Decoder.new(width, height).decode(image.to_grayscale_stream)
9
+ else
10
+ Decoder.new(width, height).decode(image)
11
+ end
12
+ end
13
+ end
14
+
15
+ require "quirc/version"
16
+ require "quirc/quirc"
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Quirc
4
+ VERSION = "0.0.1".freeze
5
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest/autorun"
4
+ require "oily_png"
5
+ require "quirc"
6
+
7
+ module TestHelpers
8
+ def image_fixture(*path)
9
+ ChunkyPNG::Image.from_file(File.join(__dir__, "fixtures", *path))
10
+ end
11
+ end
12
+
13
+ class Minitest::Spec
14
+ include TestHelpers
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "helper.rb"
4
+
5
+ describe Quirc do
6
+ describe "error levels" do
7
+ it "should decode all error levels" do
8
+ %i[m l h q].each_with_index do |level, no|
9
+ image = image_fixture("hello-120-utf8-#{level}.png")
10
+ result = Quirc.decode(image).first
11
+ assert_equal no, result.ecc_level
12
+ assert_equal "Hello World!", result.payload
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "errors" do
18
+ it "should throw error if image size is not equal to buffer" do
19
+ assert_raises ArgumentError, "Decoder is allocated for 1x2 images" do
20
+ Quirc::Decoder.new(1, 2).decode("abc")
21
+ end
22
+ end
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quirc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jacob Middag
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-compiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.48'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.48'
55
+ - !ruby/object:Gem::Dependency
56
+ name: oily_png
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ description: Ruby bindings for C library quirc that extracts and decode QR images
70
+ email: jacob@gaddim.nl
71
+ executables: []
72
+ extensions:
73
+ - ext/quirc/extconf.rb
74
+ extra_rdoc_files: []
75
+ files:
76
+ - LICENSE
77
+ - README.md
78
+ - ext/quirc/embed/LICENSE
79
+ - ext/quirc/embed/Makefile
80
+ - ext/quirc/embed/lib/decode.c
81
+ - ext/quirc/embed/lib/identify.c
82
+ - ext/quirc/embed/lib/quirc.c
83
+ - ext/quirc/embed/lib/quirc.h
84
+ - ext/quirc/embed/lib/quirc_internal.h
85
+ - ext/quirc/embed/lib/version_db.c
86
+ - ext/quirc/extconf.rb
87
+ - ext/quirc/quirc.c
88
+ - lib/quirc.rb
89
+ - lib/quirc/version.rb
90
+ - test/fixtures/hello-120-utf8-h.png
91
+ - test/fixtures/hello-120-utf8-l.png
92
+ - test/fixtures/hello-120-utf8-m.png
93
+ - test/fixtures/hello-120-utf8-q.png
94
+ - test/helper.rb
95
+ - test/test_decode.rb
96
+ homepage: https://github.com/middagj/quirc
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '2.0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.6.11
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: QR decoder based on quirc
120
+ test_files:
121
+ - test/fixtures/hello-120-utf8-h.png
122
+ - test/fixtures/hello-120-utf8-l.png
123
+ - test/fixtures/hello-120-utf8-m.png
124
+ - test/fixtures/hello-120-utf8-q.png
125
+ - test/helper.rb
126
+ - test/test_decode.rb