quirc 0.0.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +30 -0
- data/ext/quirc/embed/Makefile +1 -1
- data/ext/quirc/embed/lib/decode.c +27 -7
- data/ext/quirc/embed/lib/identify.c +66 -69
- data/ext/quirc/embed/lib/quirc.c +55 -16
- data/ext/quirc/embed/lib/quirc.h +7 -2
- data/ext/quirc/embed/lib/quirc_internal.h +2 -1
- data/ext/quirc/extconf.rb +1 -0
- data/lib/quirc.rb +4 -0
- data/lib/quirc/version.rb +1 -1
- data/test/fixtures/hello.gz +1 -0
- data/test/helper.rb +11 -2
- data/test/test_decode.rb +25 -2
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d88ac4b65801a83205e14ffa1b9b7154bc53410dcab9110f3e397c320c415e09
|
4
|
+
data.tar.gz: 305c828b7db112e3ecff1bf7ee6a082a437c8a3cbd1292430401494847b84c13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19d8b284668492e248faf07f6c68ce23c873f38d0d2b1242157b59f41332107e4ec5886c8e5d8f50f3bf5b34b2b25eef29d1b803b15001b67fd64eefb40537a1
|
7
|
+
data.tar.gz: 29fee645c7acdedf4f242c6138164641ae79109e57de7950d0ccdb729744eead0a0354f0f2e0240098266bc76024098027244c0e7c524cf4696652db8cad53e2
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -3,5 +3,35 @@
|
|
3
3
|
[Quirc](https://github.com/dlbeer/quirc) is a small C library for extracting and decode QR codes from images.
|
4
4
|
This project is a Ruby binding for that library with the library embedded.
|
5
5
|
|
6
|
+
## Example
|
7
|
+
You have to supply a [ChunkyPNG](http://chunkypng.com/) object or a binary string of the grayscale image with width and height.
|
8
|
+
```ruby
|
9
|
+
require 'chunky_png'
|
10
|
+
require 'quirc'
|
11
|
+
|
12
|
+
img = ChunkyPNG::Image.from_file('path_to_image.png')
|
13
|
+
res = Quirc.decode(img).first
|
14
|
+
puts res.payload
|
15
|
+
```
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
require 'base64'
|
19
|
+
require 'zlib'
|
20
|
+
require 'quirc'
|
21
|
+
|
22
|
+
encoded = <<~EOD
|
23
|
+
eJzt0kEOwyAMRNHe/9LpFo1mwK1IYqQ/mwQDfl5wXYQQQgghT+cziZ7Tb+Ue
|
24
|
+
7vvurL76Vvvhvuvqu0jvqHoP9wx3dh73fHdWxz3Hrc5TvYfbx01RP83j7uH2
|
25
|
+
cCtzuf+7g7uvr74ZrY9r967cedxebrrjZtK9tMbt4Y7+L/V/Tdzn3DRH+td5
|
26
|
+
0hq3h5veR+qjNTcPbh+3Mpd7Qzt6497vat+Voe9Oa7j93GpdrXGt+7i9XO3j
|
27
|
+
+jknzYB7huvmGM+7GXHPcWeOM3B7upV5Rlvvun3cHm6K+qt5qibucy4hhBBC
|
28
|
+
yN58AXWDGDc=
|
29
|
+
EOD
|
30
|
+
|
31
|
+
img = Zlib::Inflate.inflate(Base64.decode64(encoded))
|
32
|
+
res = Quirc.decode(img, 120, 120).first
|
33
|
+
puts res.payload
|
34
|
+
```
|
35
|
+
|
6
36
|
## License
|
7
37
|
This software is licensed under the MIT License. [View the license](LICENSE).
|
data/ext/quirc/embed/Makefile
CHANGED
@@ -117,7 +117,7 @@ static const uint8_t gf256_log[256] = {
|
|
117
117
|
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
|
118
118
|
};
|
119
119
|
|
120
|
-
const
|
120
|
+
static const struct galois_field gf256 = {
|
121
121
|
.p = 255,
|
122
122
|
.log = gf256_log,
|
123
123
|
.exp = gf256_exp
|
@@ -409,7 +409,6 @@ struct datastream {
|
|
409
409
|
static inline int grid_bit(const struct quirc_code *code, int x, int y)
|
410
410
|
{
|
411
411
|
int p = y * code->size + x;
|
412
|
-
|
413
412
|
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
|
414
413
|
}
|
415
414
|
|
@@ -790,12 +789,18 @@ static quirc_decode_error_t decode_kanji(struct quirc_data *data,
|
|
790
789
|
|
791
790
|
for (i = 0; i < count; i++) {
|
792
791
|
int d = take_bits(ds, 13);
|
792
|
+
int msB = d / 0xc0;
|
793
|
+
int lsB = d % 0xc0;
|
794
|
+
int intermediate = (msB << 8) | lsB;
|
793
795
|
uint16_t sjw;
|
794
796
|
|
795
|
-
if (
|
796
|
-
|
797
|
-
|
798
|
-
|
797
|
+
if (intermediate + 0x8140 <= 0x9ffc) {
|
798
|
+
/* bytes are in the range 0x8140 to 0x9FFC */
|
799
|
+
sjw = intermediate + 0x8140;
|
800
|
+
} else {
|
801
|
+
/* bytes are in the range 0xE040 to 0xEBBF */
|
802
|
+
sjw = intermediate + 0xc140;
|
803
|
+
}
|
799
804
|
|
800
805
|
data->payload[data->payload_len++] = sjw >> 8;
|
801
806
|
data->payload[data->payload_len++] = sjw & 0xff;
|
@@ -868,7 +873,7 @@ static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
|
868
873
|
done:
|
869
874
|
|
870
875
|
/* Add nul terminator to all payloads */
|
871
|
-
if (data->payload_len >= sizeof(data->payload))
|
876
|
+
if (data->payload_len >= (int) sizeof(data->payload))
|
872
877
|
data->payload_len--;
|
873
878
|
data->payload[data->payload_len] = 0;
|
874
879
|
|
@@ -911,3 +916,18 @@ quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
|
911
916
|
|
912
917
|
return QUIRC_SUCCESS;
|
913
918
|
}
|
919
|
+
|
920
|
+
void quirc_flip(struct quirc_code *code)
|
921
|
+
{
|
922
|
+
struct quirc_code flipped = {0};
|
923
|
+
unsigned int offset = 0;
|
924
|
+
for (int y = 0; y < code->size; y++) {
|
925
|
+
for (int x = 0; x < code->size; x++) {
|
926
|
+
if (grid_bit(code, y, x)) {
|
927
|
+
flipped.cell_bitmap[offset >> 3u] |= (1u << (offset & 7u));
|
928
|
+
}
|
929
|
+
offset++;
|
930
|
+
}
|
931
|
+
}
|
932
|
+
memcpy(&code->cell_bitmap, &flipped.cell_bitmap, sizeof(flipped.cell_bitmap));
|
933
|
+
}
|
@@ -14,6 +14,7 @@
|
|
14
14
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
15
15
|
*/
|
16
16
|
|
17
|
+
#include <limits.h>
|
17
18
|
#include <string.h>
|
18
19
|
#include <stdlib.h>
|
19
20
|
#include <math.h>
|
@@ -98,8 +99,8 @@ static void perspective_map(const double *c,
|
|
98
99
|
double x = (c[0]*u + c[1]*v + c[2]) / den;
|
99
100
|
double y = (c[3]*u + c[4]*v + c[5]) / den;
|
100
101
|
|
101
|
-
ret->x = rint(x);
|
102
|
-
ret->y = rint(y);
|
102
|
+
ret->x = (int) rint(x);
|
103
|
+
ret->y = (int) rint(y);
|
103
104
|
}
|
104
105
|
|
105
106
|
static void perspective_unmap(const double *c,
|
@@ -174,62 +175,55 @@ static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
|
|
174
175
|
* Adaptive thresholding
|
175
176
|
*/
|
176
177
|
|
177
|
-
|
178
|
-
#define THRESHOLD_S_DEN 8
|
179
|
-
#define THRESHOLD_T 5
|
180
|
-
|
181
|
-
static void threshold(struct quirc *q)
|
178
|
+
static uint8_t otsu(const struct quirc *q)
|
182
179
|
{
|
183
|
-
int
|
184
|
-
|
185
|
-
|
186
|
-
int
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
*/
|
195
|
-
if (threshold_s < THRESHOLD_S_MIN)
|
196
|
-
threshold_s = THRESHOLD_S_MIN;
|
197
|
-
|
198
|
-
for (y = 0; y < q->h; y++) {
|
199
|
-
int row_average[q->w];
|
200
|
-
|
201
|
-
memset(row_average, 0, sizeof(row_average));
|
202
|
-
|
203
|
-
for (x = 0; x < q->w; x++) {
|
204
|
-
int w, u;
|
180
|
+
int numPixels = q->w * q->h;
|
181
|
+
|
182
|
+
// Calculate histogram
|
183
|
+
unsigned int histogram[UINT8_MAX + 1];
|
184
|
+
(void)memset(histogram, 0, sizeof(histogram));
|
185
|
+
uint8_t* ptr = q->image;
|
186
|
+
int length = numPixels;
|
187
|
+
while (length--) {
|
188
|
+
uint8_t value = *ptr++;
|
189
|
+
histogram[value]++;
|
190
|
+
}
|
205
191
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
}
|
192
|
+
// Calculate weighted sum of histogram values
|
193
|
+
unsigned int sum = 0;
|
194
|
+
unsigned int i = 0;
|
195
|
+
for (i = 0; i <= UINT8_MAX; ++i) {
|
196
|
+
sum += i * histogram[i];
|
197
|
+
}
|
213
198
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
199
|
+
// Compute threshold
|
200
|
+
int sumB = 0;
|
201
|
+
int q1 = 0;
|
202
|
+
double max = 0;
|
203
|
+
uint8_t threshold = 0;
|
204
|
+
for (i = 0; i <= UINT8_MAX; ++i) {
|
205
|
+
// Weighted background
|
206
|
+
q1 += histogram[i];
|
207
|
+
if (q1 == 0)
|
208
|
+
continue;
|
218
209
|
|
219
|
-
|
220
|
-
|
221
|
-
|
210
|
+
// Weighted foreground
|
211
|
+
const int q2 = numPixels - q1;
|
212
|
+
if (q2 == 0)
|
213
|
+
break;
|
222
214
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
215
|
+
sumB += i * histogram[i];
|
216
|
+
const double m1 = (double)sumB / q1;
|
217
|
+
const double m2 = ((double)sum - sumB) / q2;
|
218
|
+
const double m1m2 = m1 - m2;
|
219
|
+
const double variance = m1m2 * m1m2 * q1 * q2;
|
220
|
+
if (variance >= max) {
|
221
|
+
threshold = i;
|
222
|
+
max = variance;
|
229
223
|
}
|
230
|
-
|
231
|
-
row += q->w;
|
232
224
|
}
|
225
|
+
|
226
|
+
return threshold;
|
233
227
|
}
|
234
228
|
|
235
229
|
static void area_count(void *user_data, int y, int left, int right)
|
@@ -427,7 +421,7 @@ static void finder_scan(struct quirc *q, int y)
|
|
427
421
|
{
|
428
422
|
quirc_pixel_t *row = q->pixels + y * q->w;
|
429
423
|
int x;
|
430
|
-
int last_color;
|
424
|
+
int last_color = 0;
|
431
425
|
int run_length = 0;
|
432
426
|
int run_count = 0;
|
433
427
|
int pb[5];
|
@@ -662,8 +656,11 @@ static int measure_timing_pattern(struct quirc *q, int index)
|
|
662
656
|
/* Choose the nearest allowable grid size */
|
663
657
|
size = scan * 2 + 13;
|
664
658
|
ver = (size - 15) / 4;
|
665
|
-
|
659
|
+
if (ver > QUIRC_MAX_VERSION) {
|
660
|
+
return -1;
|
661
|
+
}
|
666
662
|
|
663
|
+
qr->grid_size = ver * 4 + 17;
|
667
664
|
return 0;
|
668
665
|
}
|
669
666
|
|
@@ -858,8 +855,8 @@ static void rotate_capstone(struct quirc_capstone *cap,
|
|
858
855
|
{
|
859
856
|
struct quirc_point copy[4];
|
860
857
|
int j;
|
861
|
-
int best;
|
862
|
-
int best_score;
|
858
|
+
int best = 0;
|
859
|
+
int best_score = INT_MAX;
|
863
860
|
|
864
861
|
for (j = 0; j < 4; j++) {
|
865
862
|
struct quirc_point *p = &cap->corners[j];
|
@@ -1076,17 +1073,18 @@ static void test_grouping(struct quirc *q, int i)
|
|
1076
1073
|
test_neighbours(q, i, &hlist, &vlist);
|
1077
1074
|
}
|
1078
1075
|
|
1079
|
-
static void pixels_setup(struct quirc *q)
|
1076
|
+
static void pixels_setup(struct quirc *q, uint8_t threshold)
|
1080
1077
|
{
|
1081
|
-
if (
|
1078
|
+
if (QUIRC_PIXEL_ALIAS_IMAGE) {
|
1082
1079
|
q->pixels = (quirc_pixel_t *)q->image;
|
1083
|
-
}
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
uint8_t* source = q->image;
|
1083
|
+
quirc_pixel_t* dest = q->pixels;
|
1084
|
+
int length = q->w * q->h;
|
1085
|
+
while (length--) {
|
1086
|
+
uint8_t value = *source++;
|
1087
|
+
*dest++ = (value < threshold) ? QUIRC_PIXEL_BLACK : QUIRC_PIXEL_WHITE;
|
1090
1088
|
}
|
1091
1089
|
}
|
1092
1090
|
|
@@ -1108,8 +1106,8 @@ void quirc_end(struct quirc *q)
|
|
1108
1106
|
{
|
1109
1107
|
int i;
|
1110
1108
|
|
1111
|
-
|
1112
|
-
|
1109
|
+
uint8_t threshold = otsu(q);
|
1110
|
+
pixels_setup(q, threshold);
|
1113
1111
|
|
1114
1112
|
for (i = 0; i < q->h; i++)
|
1115
1113
|
finder_scan(q, i);
|
@@ -1140,11 +1138,10 @@ void quirc_extract(const struct quirc *q, int index,
|
|
1140
1138
|
|
1141
1139
|
for (y = 0; y < qr->grid_size; y++) {
|
1142
1140
|
int x;
|
1143
|
-
|
1144
1141
|
for (x = 0; x < qr->grid_size; x++) {
|
1145
|
-
if (read_cell(q, index, x, y) > 0)
|
1142
|
+
if (read_cell(q, index, x, y) > 0) {
|
1146
1143
|
code->cell_bitmap[i >> 3] |= (1 << (i & 7));
|
1147
|
-
|
1144
|
+
}
|
1148
1145
|
i++;
|
1149
1146
|
}
|
1150
1147
|
}
|
data/ext/quirc/embed/lib/quirc.c
CHANGED
@@ -36,34 +36,73 @@ struct quirc *quirc_new(void)
|
|
36
36
|
|
37
37
|
void quirc_destroy(struct quirc *q)
|
38
38
|
{
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
free(q->image);
|
40
|
+
/* q->pixels may alias q->image when their type representation is of the
|
41
|
+
same size, so we need to be careful here to avoid a double free */
|
42
|
+
if (!QUIRC_PIXEL_ALIAS_IMAGE)
|
42
43
|
free(q->pixels);
|
43
|
-
|
44
44
|
free(q);
|
45
45
|
}
|
46
46
|
|
47
47
|
int quirc_resize(struct quirc *q, int w, int h)
|
48
48
|
{
|
49
|
-
uint8_t
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
49
|
+
uint8_t *image = NULL;
|
50
|
+
quirc_pixel_t *pixels = NULL;
|
51
|
+
|
52
|
+
/*
|
53
|
+
* XXX: w and h should be size_t (or at least unsigned) as negatives
|
54
|
+
* values would not make much sense. The downside is that it would break
|
55
|
+
* both the API and ABI. Thus, at the moment, let's just do a sanity
|
56
|
+
* check.
|
57
|
+
*/
|
58
|
+
if (w < 0 || h < 0)
|
59
|
+
goto fail;
|
60
|
+
|
61
|
+
/*
|
62
|
+
* alloc a new buffer for q->image. We avoid realloc(3) because we want
|
63
|
+
* on failure to be leave `q` in a consistant, unmodified state.
|
64
|
+
*/
|
65
|
+
image = calloc(w, h);
|
66
|
+
if (!image)
|
67
|
+
goto fail;
|
68
|
+
|
69
|
+
/* compute the "old" (i.e. currently allocated) and the "new"
|
70
|
+
(i.e. requested) image dimensions */
|
71
|
+
size_t olddim = q->w * q->h;
|
72
|
+
size_t newdim = w * h;
|
73
|
+
size_t min = (olddim < newdim ? olddim : newdim);
|
74
|
+
|
75
|
+
/*
|
76
|
+
* copy the data into the new buffer, avoiding (a) to read beyond the
|
77
|
+
* old buffer when the new size is greater and (b) to write beyond the
|
78
|
+
* new buffer when the new size is smaller, hence the min computation.
|
79
|
+
*/
|
80
|
+
(void)memcpy(image, q->image, min);
|
81
|
+
|
82
|
+
/* alloc a new buffer for q->pixels if needed */
|
83
|
+
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
|
84
|
+
pixels = calloc(newdim, sizeof(quirc_pixel_t));
|
85
|
+
if (!pixels)
|
86
|
+
goto fail;
|
60
87
|
}
|
61
88
|
|
62
|
-
q
|
89
|
+
/* alloc succeeded, update `q` with the new size and buffers */
|
63
90
|
q->w = w;
|
64
91
|
q->h = h;
|
92
|
+
free(q->image);
|
93
|
+
q->image = image;
|
94
|
+
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
|
95
|
+
free(q->pixels);
|
96
|
+
q->pixels = pixels;
|
97
|
+
}
|
65
98
|
|
66
99
|
return 0;
|
100
|
+
/* NOTREACHED */
|
101
|
+
fail:
|
102
|
+
free(image);
|
103
|
+
free(pixels);
|
104
|
+
|
105
|
+
return -1;
|
67
106
|
}
|
68
107
|
|
69
108
|
int quirc_count(const struct quirc *q)
|
data/ext/quirc/embed/lib/quirc.h
CHANGED
@@ -78,7 +78,9 @@ typedef enum {
|
|
78
78
|
const char *quirc_strerror(quirc_decode_error_t err);
|
79
79
|
|
80
80
|
/* Limits on the maximum size of QR-codes and their content. */
|
81
|
-
#define
|
81
|
+
#define QUIRC_MAX_VERSION 40
|
82
|
+
#define QUIRC_MAX_GRID_SIZE (QUIRC_MAX_VERSION * 4 + 17)
|
83
|
+
#define QUIRC_MAX_BITMAP (((QUIRC_MAX_GRID_SIZE * QUIRC_MAX_GRID_SIZE) + 7) / 8)
|
82
84
|
#define QUIRC_MAX_PAYLOAD 8896
|
83
85
|
|
84
86
|
/* QR-code ECC types. */
|
@@ -121,7 +123,7 @@ struct quirc_code {
|
|
121
123
|
* is a bitmask giving the actual values of cells. If the cell
|
122
124
|
* at (x, y) is black, then the following bit is set:
|
123
125
|
*
|
124
|
-
* cell_bitmap[i
|
126
|
+
* cell_bitmap[i >> 3] & (1 << (i & 7))
|
125
127
|
*
|
126
128
|
* where i = (y * size) + x.
|
127
129
|
*/
|
@@ -166,6 +168,9 @@ void quirc_extract(const struct quirc *q, int index,
|
|
166
168
|
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
|
167
169
|
struct quirc_data *data);
|
168
170
|
|
171
|
+
/* Flip a QR-code according to optional mirror feature of ISO 18004:2015 */
|
172
|
+
void quirc_flip(struct quirc_code *code);
|
173
|
+
|
169
174
|
#ifdef __cplusplus
|
170
175
|
}
|
171
176
|
#endif
|
@@ -28,12 +28,13 @@
|
|
28
28
|
#endif
|
29
29
|
#define QUIRC_MAX_CAPSTONES 32
|
30
30
|
#define QUIRC_MAX_GRIDS 8
|
31
|
-
|
32
31
|
#define QUIRC_PERSPECTIVE_PARAMS 8
|
33
32
|
|
34
33
|
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
34
|
+
#define QUIRC_PIXEL_ALIAS_IMAGE 1
|
35
35
|
typedef uint8_t quirc_pixel_t;
|
36
36
|
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
37
|
+
#define QUIRC_PIXEL_ALIAS_IMAGE 0
|
37
38
|
typedef uint16_t quirc_pixel_t;
|
38
39
|
#else
|
39
40
|
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
data/ext/quirc/extconf.rb
CHANGED
data/lib/quirc.rb
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
module Quirc
|
4
4
|
def self.decode(image, width=nil, height=nil)
|
5
|
+
unless image.respond_to?(:to_grayscale_stream) || (width && height)
|
6
|
+
raise ArgumentError, "Arguments width and height are required if binary string is passed"
|
7
|
+
end
|
8
|
+
|
5
9
|
width ||= image.public_send(:width)
|
6
10
|
height ||= image.public_send(:height)
|
7
11
|
if image.respond_to?(:to_grayscale_stream)
|
data/lib/quirc/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
x���A� D������f��Hb�?�~^p]�B!O�3���o����V����H�z�wv�|wV�=ǭ�S����MQ?�����p+s����������k���y�^n��fҽ�����/�M���4G��y�����G�57n�2�{C;z���jߕ��Nk���j]�q����\���9'̀{���ϻq�qg�3p{��yF[�}�n���y�&�s.!�B��|u�7
|
data/test/helper.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "zlib"
|
4
|
+
|
3
5
|
require "minitest/autorun"
|
4
6
|
require "oily_png"
|
7
|
+
|
5
8
|
require "quirc"
|
6
9
|
|
7
10
|
module TestHelpers
|
11
|
+
def binary_fixture(*path)
|
12
|
+
Zlib::Inflate.inflate(File.binread(File.join(__dir__, "fixtures", *path)))
|
13
|
+
end
|
14
|
+
|
8
15
|
def image_fixture(*path)
|
9
16
|
ChunkyPNG::Image.from_file(File.join(__dir__, "fixtures", *path))
|
10
17
|
end
|
11
18
|
end
|
12
19
|
|
13
|
-
|
14
|
-
|
20
|
+
module Minitest
|
21
|
+
class Spec
|
22
|
+
include TestHelpers
|
23
|
+
end
|
15
24
|
end
|
data/test/test_decode.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "helper
|
3
|
+
require "helper"
|
4
4
|
|
5
5
|
describe Quirc do
|
6
|
+
describe "binary string" do
|
7
|
+
it "should decode" do
|
8
|
+
result = Quirc.decode(binary_fixture("hello.gz"), 120, 120).first
|
9
|
+
assert_equal 1, result.ecc_level
|
10
|
+
assert_equal "Hello World!", result.payload
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
6
14
|
describe "error levels" do
|
7
15
|
it "should decode all error levels" do
|
8
16
|
%i[m l h q].each_with_index do |level, no|
|
@@ -16,9 +24,24 @@ describe Quirc do
|
|
16
24
|
|
17
25
|
describe "errors" do
|
18
26
|
it "should throw error if image size is not equal to buffer" do
|
19
|
-
assert_raises ArgumentError
|
27
|
+
e = assert_raises ArgumentError do
|
20
28
|
Quirc::Decoder.new(1, 2).decode("abc")
|
21
29
|
end
|
30
|
+
assert_equal "Decoder is allocated for 1x2 images", e.message
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should throw error if width is not specified with binary string" do
|
34
|
+
e = assert_raises ArgumentError do
|
35
|
+
Quirc.decode("", nil, 1)
|
36
|
+
end
|
37
|
+
assert_equal "Arguments width and height are required if binary string is passed", e.message
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should throw error if width height not specified with binary string" do
|
41
|
+
e = assert_raises ArgumentError, "Decoder is allocated for 1x2 images" do
|
42
|
+
Quirc.decode("", nil, 1)
|
43
|
+
end
|
44
|
+
assert_equal "Arguments width and height are required if binary string is passed", e.message
|
22
45
|
end
|
23
46
|
end
|
24
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quirc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Middag
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '5.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: oily_png
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
@@ -39,33 +39,33 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake-compiler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
47
|
+
version: '1.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
54
|
+
version: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rubocop
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.4.1
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 1.4.1
|
69
69
|
description: Ruby bindings for C library quirc that extracts and decode QR images
|
70
70
|
email: jacob@gaddim.nl
|
71
71
|
executables: []
|
@@ -91,9 +91,10 @@ files:
|
|
91
91
|
- test/fixtures/hello-120-utf8-l.png
|
92
92
|
- test/fixtures/hello-120-utf8-m.png
|
93
93
|
- test/fixtures/hello-120-utf8-q.png
|
94
|
+
- test/fixtures/hello.gz
|
94
95
|
- test/helper.rb
|
95
96
|
- test/test_decode.rb
|
96
|
-
homepage: https://github.com/middagj/quirc
|
97
|
+
homepage: https://github.com/middagj/quirc-ruby
|
97
98
|
licenses:
|
98
99
|
- MIT
|
99
100
|
metadata: {}
|
@@ -105,15 +106,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
106
|
requirements:
|
106
107
|
- - ">="
|
107
108
|
- !ruby/object:Gem::Version
|
108
|
-
version: '2.
|
109
|
+
version: '2.4'
|
109
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
111
|
requirements:
|
111
112
|
- - ">="
|
112
113
|
- !ruby/object:Gem::Version
|
113
114
|
version: '0'
|
114
115
|
requirements: []
|
115
|
-
|
116
|
-
rubygems_version: 2.6.11
|
116
|
+
rubygems_version: 3.0.6
|
117
117
|
signing_key:
|
118
118
|
specification_version: 4
|
119
119
|
summary: QR decoder based on quirc
|
@@ -122,5 +122,6 @@ test_files:
|
|
122
122
|
- test/fixtures/hello-120-utf8-l.png
|
123
123
|
- test/fixtures/hello-120-utf8-m.png
|
124
124
|
- test/fixtures/hello-120-utf8-q.png
|
125
|
+
- test/fixtures/hello.gz
|
125
126
|
- test/helper.rb
|
126
127
|
- test/test_decode.rb
|