quirc 0.0.1

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