cheetah_qrcode 1.0.2 → 1.0.4
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 +4 -4
- data/ext/cheetah_qrcode/cheetah_qrcode.c +46 -38
- data/lib/cheetah_qrcode/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a68495ab66ea6215e93529c0b209671296ac3f440be78c383e5ea65c8344c971
|
4
|
+
data.tar.gz: 3e6878b91abd7c059ee8d49477a694083f79b99770da9b5fd11dd5aebdabdea5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9224f5cb85e7644bd90caee0bab897298362e095638b7556d36a91c948322e46a5ed609fa4e9591a8a52f32e49ae43dbfcd34a4da9fce21eb0bc5204285fe2d1
|
7
|
+
data.tar.gz: cbebc39cd356cdc55538299936f39bf5ce28f5e92c6981c501de8cad723c3fb1aa25bd079eb3cda3d140a4162da308d5dab509c9ffa807be9593b10a59767d39
|
@@ -24,12 +24,20 @@ static VALUE encode_text(int argc, VALUE* argv, VALUE self) {
|
|
24
24
|
rb_raise(rb_eTypeError, "Invalid text");
|
25
25
|
}
|
26
26
|
|
27
|
-
if (rb_type(arg_ec_level)
|
28
|
-
arg_ec_level = RB_SYM2ID(arg_ec_level);
|
29
|
-
} else {
|
27
|
+
if (rb_type(arg_ec_level) != T_SYMBOL) {
|
30
28
|
rb_raise(rb_eTypeError, "Invalid error correction level, use :L, :M, :Q, :H");
|
31
29
|
}
|
32
30
|
|
31
|
+
if (rb_type(arg_border) != T_FIXNUM) {
|
32
|
+
rb_raise(rb_eTypeError, "Invalid border");
|
33
|
+
}
|
34
|
+
|
35
|
+
if (rb_type(arg_size) != T_FIXNUM) {
|
36
|
+
rb_raise(rb_eTypeError, "Invalid size");
|
37
|
+
}
|
38
|
+
|
39
|
+
arg_ec_level = RB_SYM2ID(arg_ec_level);
|
40
|
+
|
33
41
|
if (arg_ec_level == rb_intern("L") || arg_ec_level == rb_intern("l")) {
|
34
42
|
qrcode_ec_level = qrcodegen_Ecc_LOW;
|
35
43
|
} else if (arg_ec_level == rb_intern("M") || arg_ec_level == rb_intern("m")) {
|
@@ -42,16 +50,18 @@ static VALUE encode_text(int argc, VALUE* argv, VALUE self) {
|
|
42
50
|
rb_raise(rb_eTypeError, "Invalid error correction level, use :L, :M, :Q, :H");
|
43
51
|
}
|
44
52
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
qrcode_border = RB_NUM2UINT(arg_border);
|
54
|
+
|
55
|
+
// The max version qrcode is only 117 wide
|
56
|
+
if (qrcode_border > 128) {
|
57
|
+
rb_raise(rb_eTypeError, "Border too large");
|
49
58
|
}
|
50
59
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
60
|
+
image_size = RB_NUM2UINT(arg_size);
|
61
|
+
|
62
|
+
// 204800x204800 will use 5000MiB memory for image buffer
|
63
|
+
if (image_size > 204800) {
|
64
|
+
rb_raise(rb_eTypeError, "Image size too large");
|
55
65
|
}
|
56
66
|
|
57
67
|
bool ok = qrcodegen_encodeText(
|
@@ -96,7 +106,21 @@ static VALUE encode_text(int argc, VALUE* argv, VALUE self) {
|
|
96
106
|
// Create image initialized to 0 (Entirely black image)
|
97
107
|
image = calloc(image_length, sizeof(uint8_t));
|
98
108
|
if (!image) {
|
99
|
-
rb_raise(rb_eRuntimeError, "Unable to create image buffer");
|
109
|
+
rb_raise(rb_eRuntimeError, "Unable to create image buffer for %lu bytes", image_length);
|
110
|
+
}
|
111
|
+
|
112
|
+
// Lookup map for qrcode-to-image pixel conversion
|
113
|
+
size_t image_scale_map[qrcode_size + 1];
|
114
|
+
|
115
|
+
// First pixel always start at 0
|
116
|
+
image_scale_map[0] = 0;
|
117
|
+
|
118
|
+
// Last pixel always end at image_size
|
119
|
+
image_scale_map[qrcode_size] = image_size;
|
120
|
+
|
121
|
+
// Precompute image scale pixels
|
122
|
+
for (size_t i = 1; i < qrcode_size; i++) {
|
123
|
+
image_scale_map[i] = (size_t)(i * image_scale);
|
100
124
|
}
|
101
125
|
|
102
126
|
// Loop through qrcode to find white modules to write into image
|
@@ -108,48 +132,32 @@ static VALUE encode_text(int argc, VALUE* argv, VALUE self) {
|
|
108
132
|
}
|
109
133
|
|
110
134
|
// Map current qrcode module to image coordinates
|
111
|
-
size_t ix_begin =
|
112
|
-
size_t ix_end =
|
113
|
-
size_t iy_begin =
|
114
|
-
size_t iy_end =
|
115
|
-
|
116
|
-
// Fix offset for the first pixel
|
117
|
-
if (qx == 0) {
|
118
|
-
ix_begin = 0;
|
119
|
-
}
|
120
|
-
if (qy == 0) {
|
121
|
-
iy_begin = 0;
|
122
|
-
}
|
123
|
-
|
124
|
-
// For boundary safety
|
125
|
-
if (ix_end > image_size) {
|
126
|
-
ix_end = image_size;
|
127
|
-
}
|
128
|
-
if (iy_end > image_size) {
|
129
|
-
iy_end = image_size;
|
130
|
-
}
|
135
|
+
size_t ix_begin = image_scale_map[qx];
|
136
|
+
size_t ix_end = image_scale_map[qx + 1];
|
137
|
+
size_t iy_begin = image_scale_map[qy];
|
138
|
+
size_t iy_end = image_scale_map[qy + 1];
|
131
139
|
|
132
140
|
// Fill white pixels into image at unit of bytes
|
133
141
|
for (size_t iy = iy_begin; iy < iy_end; iy++) {
|
134
142
|
size_t ix = ix_begin;
|
135
|
-
size_t
|
143
|
+
size_t bits_remaining = ix_end - ix_begin;
|
136
144
|
|
137
|
-
while (
|
145
|
+
while (bits_remaining > 0) {
|
138
146
|
size_t i = (iy * image_scanline_width) + (ix / 8);
|
139
147
|
|
140
148
|
uint8_t byte_value = 0xFF;
|
141
149
|
uint8_t bits_needed = 8 - (ix % 8);
|
142
150
|
|
143
|
-
if (bits_needed >
|
144
|
-
|
145
|
-
|
151
|
+
if (bits_needed > bits_remaining) {
|
152
|
+
bits_needed = bits_remaining;
|
153
|
+
byte_value <<= (8 - bits_needed);
|
146
154
|
}
|
147
155
|
|
148
156
|
byte_value >>= (ix % 8);
|
149
157
|
image[i] |= byte_value;
|
150
158
|
|
151
159
|
ix += bits_needed;
|
152
|
-
|
160
|
+
bits_remaining -= bits_needed;
|
153
161
|
}
|
154
162
|
}
|
155
163
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheetah_qrcode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- atitan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|