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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +7 -0
- data/ext/quirc/embed/LICENSE +16 -0
- data/ext/quirc/embed/Makefile +35 -0
- data/ext/quirc/embed/lib/decode.c +913 -0
- data/ext/quirc/embed/lib/identify.c +1151 -0
- data/ext/quirc/embed/lib/quirc.c +91 -0
- data/ext/quirc/embed/lib/quirc.h +173 -0
- data/ext/quirc/embed/lib/quirc_internal.h +114 -0
- data/ext/quirc/embed/lib/version_db.c +421 -0
- data/ext/quirc/extconf.rb +20 -0
- data/ext/quirc/quirc.c +92 -0
- data/lib/quirc.rb +16 -0
- data/lib/quirc/version.rb +5 -0
- data/test/fixtures/hello-120-utf8-h.png +0 -0
- data/test/fixtures/hello-120-utf8-l.png +0 -0
- data/test/fixtures/hello-120-utf8-m.png +0 -0
- data/test/fixtures/hello-120-utf8-q.png +0 -0
- data/test/helper.rb +15 -0
- data/test/test_decode.rb +24 -0
- metadata +126 -0
@@ -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")
|
data/ext/quirc/quirc.c
ADDED
@@ -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
|
+
}
|
data/lib/quirc.rb
ADDED
@@ -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"
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/test/helper.rb
ADDED
@@ -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
|
data/test/test_decode.rb
ADDED
@@ -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
|