quirc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1151 @@
1
+ /* quirc - QR-code recognition library
2
+ * Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #include <string.h>
18
+ #include <stdlib.h>
19
+ #include <math.h>
20
+ #include "quirc_internal.h"
21
+
22
+ /************************************************************************
23
+ * Linear algebra routines
24
+ */
25
+
26
+ static int line_intersect(const struct quirc_point *p0,
27
+ const struct quirc_point *p1,
28
+ const struct quirc_point *q0,
29
+ const struct quirc_point *q1,
30
+ struct quirc_point *r)
31
+ {
32
+ /* (a, b) is perpendicular to line p */
33
+ int a = -(p1->y - p0->y);
34
+ int b = p1->x - p0->x;
35
+
36
+ /* (c, d) is perpendicular to line q */
37
+ int c = -(q1->y - q0->y);
38
+ int d = q1->x - q0->x;
39
+
40
+ /* e and f are dot products of the respective vectors with p and q */
41
+ int e = a * p1->x + b * p1->y;
42
+ int f = c * q1->x + d * q1->y;
43
+
44
+ /* Now we need to solve:
45
+ * [a b] [rx] [e]
46
+ * [c d] [ry] = [f]
47
+ *
48
+ * We do this by inverting the matrix and applying it to (e, f):
49
+ * [ d -b] [e] [rx]
50
+ * 1/det [-c a] [f] = [ry]
51
+ */
52
+ int det = (a * d) - (b * c);
53
+
54
+ if (!det)
55
+ return 0;
56
+
57
+ r->x = (d * e - b * f) / det;
58
+ r->y = (-c * e + a * f) / det;
59
+
60
+ return 1;
61
+ }
62
+
63
+ static void perspective_setup(double *c,
64
+ const struct quirc_point *rect,
65
+ double w, double h)
66
+ {
67
+ double x0 = rect[0].x;
68
+ double y0 = rect[0].y;
69
+ double x1 = rect[1].x;
70
+ double y1 = rect[1].y;
71
+ double x2 = rect[2].x;
72
+ double y2 = rect[2].y;
73
+ double x3 = rect[3].x;
74
+ double y3 = rect[3].y;
75
+
76
+ double wden = w * (x2*y3 - x3*y2 + (x3-x2)*y1 + x1*(y2-y3));
77
+ double hden = h * (x2*y3 + x1*(y2-y3) - x3*y2 + (x3-x2)*y1);
78
+
79
+ c[0] = (x1*(x2*y3-x3*y2) + x0*(-x2*y3+x3*y2+(x2-x3)*y1) +
80
+ x1*(x3-x2)*y0) / wden;
81
+ c[1] = -(x0*(x2*y3+x1*(y2-y3)-x2*y1) - x1*x3*y2 + x2*x3*y1
82
+ + (x1*x3-x2*x3)*y0) / hden;
83
+ c[2] = x0;
84
+ c[3] = (y0*(x1*(y3-y2)-x2*y3+x3*y2) + y1*(x2*y3-x3*y2) +
85
+ x0*y1*(y2-y3)) / wden;
86
+ c[4] = (x0*(y1*y3-y2*y3) + x1*y2*y3 - x2*y1*y3 +
87
+ y0*(x3*y2-x1*y2+(x2-x3)*y1)) / hden;
88
+ c[5] = y0;
89
+ c[6] = (x1*(y3-y2) + x0*(y2-y3) + (x2-x3)*y1 + (x3-x2)*y0) / wden;
90
+ c[7] = (-x2*y3 + x1*y3 + x3*y2 + x0*(y1-y2) - x3*y1 + (x2-x1)*y0) /
91
+ hden;
92
+ }
93
+
94
+ static void perspective_map(const double *c,
95
+ double u, double v, struct quirc_point *ret)
96
+ {
97
+ double den = c[6]*u + c[7]*v + 1.0;
98
+ double x = (c[0]*u + c[1]*v + c[2]) / den;
99
+ double y = (c[3]*u + c[4]*v + c[5]) / den;
100
+
101
+ ret->x = rint(x);
102
+ ret->y = rint(y);
103
+ }
104
+
105
+ static void perspective_unmap(const double *c,
106
+ const struct quirc_point *in,
107
+ double *u, double *v)
108
+ {
109
+ double x = in->x;
110
+ double y = in->y;
111
+ double den = -c[0]*c[7]*y + c[1]*c[6]*y + (c[3]*c[7]-c[4]*c[6])*x +
112
+ c[0]*c[4] - c[1]*c[3];
113
+
114
+ *u = -(c[1]*(y-c[5]) - c[2]*c[7]*y + (c[5]*c[7]-c[4])*x + c[2]*c[4]) /
115
+ den;
116
+ *v = (c[0]*(y-c[5]) - c[2]*c[6]*y + (c[5]*c[6]-c[3])*x + c[2]*c[3]) /
117
+ den;
118
+ }
119
+
120
+ /************************************************************************
121
+ * Span-based floodfill routine
122
+ */
123
+
124
+ #define FLOOD_FILL_MAX_DEPTH 4096
125
+
126
+ typedef void (*span_func_t)(void *user_data, int y, int left, int right);
127
+
128
+ static void flood_fill_seed(struct quirc *q, int x, int y, int from, int to,
129
+ span_func_t func, void *user_data,
130
+ int depth)
131
+ {
132
+ int left = x;
133
+ int right = x;
134
+ int i;
135
+ quirc_pixel_t *row = q->pixels + y * q->w;
136
+
137
+ if (depth >= FLOOD_FILL_MAX_DEPTH)
138
+ return;
139
+
140
+ while (left > 0 && row[left - 1] == from)
141
+ left--;
142
+
143
+ while (right < q->w - 1 && row[right + 1] == from)
144
+ right++;
145
+
146
+ /* Fill the extent */
147
+ for (i = left; i <= right; i++)
148
+ row[i] = to;
149
+
150
+ if (func)
151
+ func(user_data, y, left, right);
152
+
153
+ /* Seed new flood-fills */
154
+ if (y > 0) {
155
+ row = q->pixels + (y - 1) * q->w;
156
+
157
+ for (i = left; i <= right; i++)
158
+ if (row[i] == from)
159
+ flood_fill_seed(q, i, y - 1, from, to,
160
+ func, user_data, depth + 1);
161
+ }
162
+
163
+ if (y < q->h - 1) {
164
+ row = q->pixels + (y + 1) * q->w;
165
+
166
+ for (i = left; i <= right; i++)
167
+ if (row[i] == from)
168
+ flood_fill_seed(q, i, y + 1, from, to,
169
+ func, user_data, depth + 1);
170
+ }
171
+ }
172
+
173
+ /************************************************************************
174
+ * Adaptive thresholding
175
+ */
176
+
177
+ #define THRESHOLD_S_MIN 1
178
+ #define THRESHOLD_S_DEN 8
179
+ #define THRESHOLD_T 5
180
+
181
+ static void threshold(struct quirc *q)
182
+ {
183
+ int x, y;
184
+ int avg_w = 0;
185
+ int avg_u = 0;
186
+ int threshold_s = q->w / THRESHOLD_S_DEN;
187
+ quirc_pixel_t *row = q->pixels;
188
+
189
+ /*
190
+ * Ensure a sane, non-zero value for threshold_s.
191
+ *
192
+ * threshold_s can be zero if the image width is small. We need to avoid
193
+ * SIGFPE as it will be used as divisor.
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;
205
+
206
+ if (y & 1) {
207
+ w = x;
208
+ u = q->w - 1 - x;
209
+ } else {
210
+ w = q->w - 1 - x;
211
+ u = x;
212
+ }
213
+
214
+ avg_w = (avg_w * (threshold_s - 1)) /
215
+ threshold_s + row[w];
216
+ avg_u = (avg_u * (threshold_s - 1)) /
217
+ threshold_s + row[u];
218
+
219
+ row_average[w] += avg_w;
220
+ row_average[u] += avg_u;
221
+ }
222
+
223
+ for (x = 0; x < q->w; x++) {
224
+ if (row[x] < row_average[x] *
225
+ (100 - THRESHOLD_T) / (200 * threshold_s))
226
+ row[x] = QUIRC_PIXEL_BLACK;
227
+ else
228
+ row[x] = QUIRC_PIXEL_WHITE;
229
+ }
230
+
231
+ row += q->w;
232
+ }
233
+ }
234
+
235
+ static void area_count(void *user_data, int y, int left, int right)
236
+ {
237
+ ((struct quirc_region *)user_data)->count += right - left + 1;
238
+ }
239
+
240
+ static int region_code(struct quirc *q, int x, int y)
241
+ {
242
+ int pixel;
243
+ struct quirc_region *box;
244
+ int region;
245
+
246
+ if (x < 0 || y < 0 || x >= q->w || y >= q->h)
247
+ return -1;
248
+
249
+ pixel = q->pixels[y * q->w + x];
250
+
251
+ if (pixel >= QUIRC_PIXEL_REGION)
252
+ return pixel;
253
+
254
+ if (pixel == QUIRC_PIXEL_WHITE)
255
+ return -1;
256
+
257
+ if (q->num_regions >= QUIRC_MAX_REGIONS)
258
+ return -1;
259
+
260
+ region = q->num_regions;
261
+ box = &q->regions[q->num_regions++];
262
+
263
+ memset(box, 0, sizeof(*box));
264
+
265
+ box->seed.x = x;
266
+ box->seed.y = y;
267
+ box->capstone = -1;
268
+
269
+ flood_fill_seed(q, x, y, pixel, region, area_count, box, 0);
270
+
271
+ return region;
272
+ }
273
+
274
+ struct polygon_score_data {
275
+ struct quirc_point ref;
276
+
277
+ int scores[4];
278
+ struct quirc_point *corners;
279
+ };
280
+
281
+ static void find_one_corner(void *user_data, int y, int left, int right)
282
+ {
283
+ struct polygon_score_data *psd =
284
+ (struct polygon_score_data *)user_data;
285
+ int xs[2] = {left, right};
286
+ int dy = y - psd->ref.y;
287
+ int i;
288
+
289
+ for (i = 0; i < 2; i++) {
290
+ int dx = xs[i] - psd->ref.x;
291
+ int d = dx * dx + dy * dy;
292
+
293
+ if (d > psd->scores[0]) {
294
+ psd->scores[0] = d;
295
+ psd->corners[0].x = xs[i];
296
+ psd->corners[0].y = y;
297
+ }
298
+ }
299
+ }
300
+
301
+ static void find_other_corners(void *user_data, int y, int left, int right)
302
+ {
303
+ struct polygon_score_data *psd =
304
+ (struct polygon_score_data *)user_data;
305
+ int xs[2] = {left, right};
306
+ int i;
307
+
308
+ for (i = 0; i < 2; i++) {
309
+ int up = xs[i] * psd->ref.x + y * psd->ref.y;
310
+ int right = xs[i] * -psd->ref.y + y * psd->ref.x;
311
+ int scores[4] = {up, right, -up, -right};
312
+ int j;
313
+
314
+ for (j = 0; j < 4; j++) {
315
+ if (scores[j] > psd->scores[j]) {
316
+ psd->scores[j] = scores[j];
317
+ psd->corners[j].x = xs[i];
318
+ psd->corners[j].y = y;
319
+ }
320
+ }
321
+ }
322
+ }
323
+
324
+ static void find_region_corners(struct quirc *q,
325
+ int rcode, const struct quirc_point *ref,
326
+ struct quirc_point *corners)
327
+ {
328
+ struct quirc_region *region = &q->regions[rcode];
329
+ struct polygon_score_data psd;
330
+ int i;
331
+
332
+ memset(&psd, 0, sizeof(psd));
333
+ psd.corners = corners;
334
+
335
+ memcpy(&psd.ref, ref, sizeof(psd.ref));
336
+ psd.scores[0] = -1;
337
+ flood_fill_seed(q, region->seed.x, region->seed.y,
338
+ rcode, QUIRC_PIXEL_BLACK,
339
+ find_one_corner, &psd, 0);
340
+
341
+ psd.ref.x = psd.corners[0].x - psd.ref.x;
342
+ psd.ref.y = psd.corners[0].y - psd.ref.y;
343
+
344
+ for (i = 0; i < 4; i++)
345
+ memcpy(&psd.corners[i], &region->seed,
346
+ sizeof(psd.corners[i]));
347
+
348
+ i = region->seed.x * psd.ref.x + region->seed.y * psd.ref.y;
349
+ psd.scores[0] = i;
350
+ psd.scores[2] = -i;
351
+ i = region->seed.x * -psd.ref.y + region->seed.y * psd.ref.x;
352
+ psd.scores[1] = i;
353
+ psd.scores[3] = -i;
354
+
355
+ flood_fill_seed(q, region->seed.x, region->seed.y,
356
+ QUIRC_PIXEL_BLACK, rcode,
357
+ find_other_corners, &psd, 0);
358
+ }
359
+
360
+ static void record_capstone(struct quirc *q, int ring, int stone)
361
+ {
362
+ struct quirc_region *stone_reg = &q->regions[stone];
363
+ struct quirc_region *ring_reg = &q->regions[ring];
364
+ struct quirc_capstone *capstone;
365
+ int cs_index;
366
+
367
+ if (q->num_capstones >= QUIRC_MAX_CAPSTONES)
368
+ return;
369
+
370
+ cs_index = q->num_capstones;
371
+ capstone = &q->capstones[q->num_capstones++];
372
+
373
+ memset(capstone, 0, sizeof(*capstone));
374
+
375
+ capstone->qr_grid = -1;
376
+ capstone->ring = ring;
377
+ capstone->stone = stone;
378
+ stone_reg->capstone = cs_index;
379
+ ring_reg->capstone = cs_index;
380
+
381
+ /* Find the corners of the ring */
382
+ find_region_corners(q, ring, &stone_reg->seed, capstone->corners);
383
+
384
+ /* Set up the perspective transform and find the center */
385
+ perspective_setup(capstone->c, capstone->corners, 7.0, 7.0);
386
+ perspective_map(capstone->c, 3.5, 3.5, &capstone->center);
387
+ }
388
+
389
+ static void test_capstone(struct quirc *q, int x, int y, int *pb)
390
+ {
391
+ int ring_right = region_code(q, x - pb[4], y);
392
+ int stone = region_code(q, x - pb[4] - pb[3] - pb[2], y);
393
+ int ring_left = region_code(q, x - pb[4] - pb[3] -
394
+ pb[2] - pb[1] - pb[0],
395
+ y);
396
+ struct quirc_region *stone_reg;
397
+ struct quirc_region *ring_reg;
398
+ int ratio;
399
+
400
+ if (ring_left < 0 || ring_right < 0 || stone < 0)
401
+ return;
402
+
403
+ /* Left and ring of ring should be connected */
404
+ if (ring_left != ring_right)
405
+ return;
406
+
407
+ /* Ring should be disconnected from stone */
408
+ if (ring_left == stone)
409
+ return;
410
+
411
+ stone_reg = &q->regions[stone];
412
+ ring_reg = &q->regions[ring_left];
413
+
414
+ /* Already detected */
415
+ if (stone_reg->capstone >= 0 || ring_reg->capstone >= 0)
416
+ return;
417
+
418
+ /* Ratio should ideally be 37.5 */
419
+ ratio = stone_reg->count * 100 / ring_reg->count;
420
+ if (ratio < 10 || ratio > 70)
421
+ return;
422
+
423
+ record_capstone(q, ring_left, stone);
424
+ }
425
+
426
+ static void finder_scan(struct quirc *q, int y)
427
+ {
428
+ quirc_pixel_t *row = q->pixels + y * q->w;
429
+ int x;
430
+ int last_color;
431
+ int run_length = 0;
432
+ int run_count = 0;
433
+ int pb[5];
434
+
435
+ memset(pb, 0, sizeof(pb));
436
+ for (x = 0; x < q->w; x++) {
437
+ int color = row[x] ? 1 : 0;
438
+
439
+ if (x && color != last_color) {
440
+ memmove(pb, pb + 1, sizeof(pb[0]) * 4);
441
+ pb[4] = run_length;
442
+ run_length = 0;
443
+ run_count++;
444
+
445
+ if (!color && run_count >= 5) {
446
+ static int check[5] = {1, 1, 3, 1, 1};
447
+ int avg, err;
448
+ int i;
449
+ int ok = 1;
450
+
451
+ avg = (pb[0] + pb[1] + pb[3] + pb[4]) / 4;
452
+ err = avg * 3 / 4;
453
+
454
+ for (i = 0; i < 5; i++)
455
+ if (pb[i] < check[i] * avg - err ||
456
+ pb[i] > check[i] * avg + err)
457
+ ok = 0;
458
+
459
+ if (ok)
460
+ test_capstone(q, x, y, pb);
461
+ }
462
+ }
463
+
464
+ run_length++;
465
+ last_color = color;
466
+ }
467
+ }
468
+
469
+ static void find_alignment_pattern(struct quirc *q, int index)
470
+ {
471
+ struct quirc_grid *qr = &q->grids[index];
472
+ struct quirc_capstone *c0 = &q->capstones[qr->caps[0]];
473
+ struct quirc_capstone *c2 = &q->capstones[qr->caps[2]];
474
+ struct quirc_point a;
475
+ struct quirc_point b;
476
+ struct quirc_point c;
477
+ int size_estimate;
478
+ int step_size = 1;
479
+ int dir = 0;
480
+ double u, v;
481
+
482
+ /* Grab our previous estimate of the alignment pattern corner */
483
+ memcpy(&b, &qr->align, sizeof(b));
484
+
485
+ /* Guess another two corners of the alignment pattern so that we
486
+ * can estimate its size.
487
+ */
488
+ perspective_unmap(c0->c, &b, &u, &v);
489
+ perspective_map(c0->c, u, v + 1.0, &a);
490
+ perspective_unmap(c2->c, &b, &u, &v);
491
+ perspective_map(c2->c, u + 1.0, v, &c);
492
+
493
+ size_estimate = abs((a.x - b.x) * -(c.y - b.y) +
494
+ (a.y - b.y) * (c.x - b.x));
495
+
496
+ /* Spiral outwards from the estimate point until we find something
497
+ * roughly the right size. Don't look too far from the estimate
498
+ * point.
499
+ */
500
+ while (step_size * step_size < size_estimate * 100) {
501
+ static const int dx_map[] = {1, 0, -1, 0};
502
+ static const int dy_map[] = {0, -1, 0, 1};
503
+ int i;
504
+
505
+ for (i = 0; i < step_size; i++) {
506
+ int code = region_code(q, b.x, b.y);
507
+
508
+ if (code >= 0) {
509
+ struct quirc_region *reg = &q->regions[code];
510
+
511
+ if (reg->count >= size_estimate / 2 &&
512
+ reg->count <= size_estimate * 2) {
513
+ qr->align_region = code;
514
+ return;
515
+ }
516
+ }
517
+
518
+ b.x += dx_map[dir];
519
+ b.y += dy_map[dir];
520
+ }
521
+
522
+ dir = (dir + 1) % 4;
523
+ if (!(dir & 1))
524
+ step_size++;
525
+ }
526
+ }
527
+
528
+ static void find_leftmost_to_line(void *user_data, int y, int left, int right)
529
+ {
530
+ struct polygon_score_data *psd =
531
+ (struct polygon_score_data *)user_data;
532
+ int xs[2] = {left, right};
533
+ int i;
534
+
535
+ for (i = 0; i < 2; i++) {
536
+ int d = -psd->ref.y * xs[i] + psd->ref.x * y;
537
+
538
+ if (d < psd->scores[0]) {
539
+ psd->scores[0] = d;
540
+ psd->corners[0].x = xs[i];
541
+ psd->corners[0].y = y;
542
+ }
543
+ }
544
+ }
545
+
546
+ /* Do a Bresenham scan from one point to another and count the number
547
+ * of black/white transitions.
548
+ */
549
+ static int timing_scan(const struct quirc *q,
550
+ const struct quirc_point *p0,
551
+ const struct quirc_point *p1)
552
+ {
553
+ int n = p1->x - p0->x;
554
+ int d = p1->y - p0->y;
555
+ int x = p0->x;
556
+ int y = p0->y;
557
+ int *dom, *nondom;
558
+ int dom_step;
559
+ int nondom_step;
560
+ int a = 0;
561
+ int i;
562
+ int run_length = 0;
563
+ int count = 0;
564
+
565
+ if (p0->x < 0 || p0->y < 0 || p0->x >= q->w || p0->y >= q->h)
566
+ return -1;
567
+ if (p1->x < 0 || p1->y < 0 || p1->x >= q->w || p1->y >= q->h)
568
+ return -1;
569
+
570
+ if (abs(n) > abs(d)) {
571
+ int swap = n;
572
+
573
+ n = d;
574
+ d = swap;
575
+
576
+ dom = &x;
577
+ nondom = &y;
578
+ } else {
579
+ dom = &y;
580
+ nondom = &x;
581
+ }
582
+
583
+ if (n < 0) {
584
+ n = -n;
585
+ nondom_step = -1;
586
+ } else {
587
+ nondom_step = 1;
588
+ }
589
+
590
+ if (d < 0) {
591
+ d = -d;
592
+ dom_step = -1;
593
+ } else {
594
+ dom_step = 1;
595
+ }
596
+
597
+ x = p0->x;
598
+ y = p0->y;
599
+ for (i = 0; i <= d; i++) {
600
+ int pixel;
601
+
602
+ if (y < 0 || y >= q->h || x < 0 || x >= q->w)
603
+ break;
604
+
605
+ pixel = q->pixels[y * q->w + x];
606
+
607
+ if (pixel) {
608
+ if (run_length >= 2)
609
+ count++;
610
+ run_length = 0;
611
+ } else {
612
+ run_length++;
613
+ }
614
+
615
+ a += n;
616
+ *dom += dom_step;
617
+ if (a >= d) {
618
+ *nondom += nondom_step;
619
+ a -= d;
620
+ }
621
+ }
622
+
623
+ return count;
624
+ }
625
+
626
+ /* Try the measure the timing pattern for a given QR code. This does
627
+ * not require the global perspective to have been set up, but it
628
+ * does require that the capstone corners have been set to their
629
+ * canonical rotation.
630
+ *
631
+ * For each capstone, we find a point in the middle of the ring band
632
+ * which is nearest the centre of the code. Using these points, we do
633
+ * a horizontal and a vertical timing scan.
634
+ */
635
+ static int measure_timing_pattern(struct quirc *q, int index)
636
+ {
637
+ struct quirc_grid *qr = &q->grids[index];
638
+ int i;
639
+ int scan;
640
+ int ver;
641
+ int size;
642
+
643
+ for (i = 0; i < 3; i++) {
644
+ static const double us[] = {6.5, 6.5, 0.5};
645
+ static const double vs[] = {0.5, 6.5, 6.5};
646
+ struct quirc_capstone *cap = &q->capstones[qr->caps[i]];
647
+
648
+ perspective_map(cap->c, us[i], vs[i], &qr->tpep[i]);
649
+ }
650
+
651
+ qr->hscan = timing_scan(q, &qr->tpep[1], &qr->tpep[2]);
652
+ qr->vscan = timing_scan(q, &qr->tpep[1], &qr->tpep[0]);
653
+
654
+ scan = qr->hscan;
655
+ if (qr->vscan > scan)
656
+ scan = qr->vscan;
657
+
658
+ /* If neither scan worked, we can't go any further. */
659
+ if (scan < 0)
660
+ return -1;
661
+
662
+ /* Choose the nearest allowable grid size */
663
+ size = scan * 2 + 13;
664
+ ver = (size - 15) / 4;
665
+ qr->grid_size = ver * 4 + 17;
666
+
667
+ return 0;
668
+ }
669
+
670
+ /* Read a cell from a grid using the currently set perspective
671
+ * transform. Returns +/- 1 for black/white, 0 for cells which are
672
+ * out of image bounds.
673
+ */
674
+ static int read_cell(const struct quirc *q, int index, int x, int y)
675
+ {
676
+ const struct quirc_grid *qr = &q->grids[index];
677
+ struct quirc_point p;
678
+
679
+ perspective_map(qr->c, x + 0.5, y + 0.5, &p);
680
+ if (p.y < 0 || p.y >= q->h || p.x < 0 || p.x >= q->w)
681
+ return 0;
682
+
683
+ return q->pixels[p.y * q->w + p.x] ? 1 : -1;
684
+ }
685
+
686
+ static int fitness_cell(const struct quirc *q, int index, int x, int y)
687
+ {
688
+ const struct quirc_grid *qr = &q->grids[index];
689
+ int score = 0;
690
+ int u, v;
691
+
692
+ for (v = 0; v < 3; v++)
693
+ for (u = 0; u < 3; u++) {
694
+ static const double offsets[] = {0.3, 0.5, 0.7};
695
+ struct quirc_point p;
696
+
697
+ perspective_map(qr->c, x + offsets[u],
698
+ y + offsets[v], &p);
699
+ if (p.y < 0 || p.y >= q->h || p.x < 0 || p.x >= q->w)
700
+ continue;
701
+
702
+ if (q->pixels[p.y * q->w + p.x])
703
+ score++;
704
+ else
705
+ score--;
706
+ }
707
+
708
+ return score;
709
+ }
710
+
711
+ static int fitness_ring(const struct quirc *q, int index, int cx, int cy,
712
+ int radius)
713
+ {
714
+ int i;
715
+ int score = 0;
716
+
717
+ for (i = 0; i < radius * 2; i++) {
718
+ score += fitness_cell(q, index, cx - radius + i, cy - radius);
719
+ score += fitness_cell(q, index, cx - radius, cy + radius - i);
720
+ score += fitness_cell(q, index, cx + radius, cy - radius + i);
721
+ score += fitness_cell(q, index, cx + radius - i, cy + radius);
722
+ }
723
+
724
+ return score;
725
+ }
726
+
727
+ static int fitness_apat(const struct quirc *q, int index, int cx, int cy)
728
+ {
729
+ return fitness_cell(q, index, cx, cy) -
730
+ fitness_ring(q, index, cx, cy, 1) +
731
+ fitness_ring(q, index, cx, cy, 2);
732
+ }
733
+
734
+ static int fitness_capstone(const struct quirc *q, int index, int x, int y)
735
+ {
736
+ x += 3;
737
+ y += 3;
738
+
739
+ return fitness_cell(q, index, x, y) +
740
+ fitness_ring(q, index, x, y, 1) -
741
+ fitness_ring(q, index, x, y, 2) +
742
+ fitness_ring(q, index, x, y, 3);
743
+ }
744
+
745
+ /* Compute a fitness score for the currently configured perspective
746
+ * transform, using the features we expect to find by scanning the
747
+ * grid.
748
+ */
749
+ static int fitness_all(const struct quirc *q, int index)
750
+ {
751
+ const struct quirc_grid *qr = &q->grids[index];
752
+ int version = (qr->grid_size - 17) / 4;
753
+ const struct quirc_version_info *info = &quirc_version_db[version];
754
+ int score = 0;
755
+ int i, j;
756
+ int ap_count;
757
+
758
+ /* Check the timing pattern */
759
+ for (i = 0; i < qr->grid_size - 14; i++) {
760
+ int expect = (i & 1) ? 1 : -1;
761
+
762
+ score += fitness_cell(q, index, i + 7, 6) * expect;
763
+ score += fitness_cell(q, index, 6, i + 7) * expect;
764
+ }
765
+
766
+ /* Check capstones */
767
+ score += fitness_capstone(q, index, 0, 0);
768
+ score += fitness_capstone(q, index, qr->grid_size - 7, 0);
769
+ score += fitness_capstone(q, index, 0, qr->grid_size - 7);
770
+
771
+ if (version < 0 || version > QUIRC_MAX_VERSION)
772
+ return score;
773
+
774
+ /* Check alignment patterns */
775
+ ap_count = 0;
776
+ while ((ap_count < QUIRC_MAX_ALIGNMENT) && info->apat[ap_count])
777
+ ap_count++;
778
+
779
+ for (i = 1; i + 1 < ap_count; i++) {
780
+ score += fitness_apat(q, index, 6, info->apat[i]);
781
+ score += fitness_apat(q, index, info->apat[i], 6);
782
+ }
783
+
784
+ for (i = 1; i < ap_count; i++)
785
+ for (j = 1; j < ap_count; j++)
786
+ score += fitness_apat(q, index,
787
+ info->apat[i], info->apat[j]);
788
+
789
+ return score;
790
+ }
791
+
792
+ static void jiggle_perspective(struct quirc *q, int index)
793
+ {
794
+ struct quirc_grid *qr = &q->grids[index];
795
+ int best = fitness_all(q, index);
796
+ int pass;
797
+ double adjustments[8];
798
+ int i;
799
+
800
+ for (i = 0; i < 8; i++)
801
+ adjustments[i] = qr->c[i] * 0.02;
802
+
803
+ for (pass = 0; pass < 5; pass++) {
804
+ for (i = 0; i < 16; i++) {
805
+ int j = i >> 1;
806
+ int test;
807
+ double old = qr->c[j];
808
+ double step = adjustments[j];
809
+ double new;
810
+
811
+ if (i & 1)
812
+ new = old + step;
813
+ else
814
+ new = old - step;
815
+
816
+ qr->c[j] = new;
817
+ test = fitness_all(q, index);
818
+
819
+ if (test > best)
820
+ best = test;
821
+ else
822
+ qr->c[j] = old;
823
+ }
824
+
825
+ for (i = 0; i < 8; i++)
826
+ adjustments[i] *= 0.5;
827
+ }
828
+ }
829
+
830
+ /* Once the capstones are in place and an alignment point has been
831
+ * chosen, we call this function to set up a grid-reading perspective
832
+ * transform.
833
+ */
834
+ static void setup_qr_perspective(struct quirc *q, int index)
835
+ {
836
+ struct quirc_grid *qr = &q->grids[index];
837
+ struct quirc_point rect[4];
838
+
839
+ /* Set up the perspective map for reading the grid */
840
+ memcpy(&rect[0], &q->capstones[qr->caps[1]].corners[0],
841
+ sizeof(rect[0]));
842
+ memcpy(&rect[1], &q->capstones[qr->caps[2]].corners[0],
843
+ sizeof(rect[0]));
844
+ memcpy(&rect[2], &qr->align, sizeof(rect[0]));
845
+ memcpy(&rect[3], &q->capstones[qr->caps[0]].corners[0],
846
+ sizeof(rect[0]));
847
+ perspective_setup(qr->c, rect, qr->grid_size - 7, qr->grid_size - 7);
848
+
849
+ jiggle_perspective(q, index);
850
+ }
851
+
852
+ /* Rotate the capstone with so that corner 0 is the leftmost with respect
853
+ * to the given reference line.
854
+ */
855
+ static void rotate_capstone(struct quirc_capstone *cap,
856
+ const struct quirc_point *h0,
857
+ const struct quirc_point *hd)
858
+ {
859
+ struct quirc_point copy[4];
860
+ int j;
861
+ int best;
862
+ int best_score;
863
+
864
+ for (j = 0; j < 4; j++) {
865
+ struct quirc_point *p = &cap->corners[j];
866
+ int score = (p->x - h0->x) * -hd->y +
867
+ (p->y - h0->y) * hd->x;
868
+
869
+ if (!j || score < best_score) {
870
+ best = j;
871
+ best_score = score;
872
+ }
873
+ }
874
+
875
+ /* Rotate the capstone */
876
+ for (j = 0; j < 4; j++)
877
+ memcpy(&copy[j], &cap->corners[(j + best) % 4],
878
+ sizeof(copy[j]));
879
+ memcpy(cap->corners, copy, sizeof(cap->corners));
880
+ perspective_setup(cap->c, cap->corners, 7.0, 7.0);
881
+ }
882
+
883
+ static void record_qr_grid(struct quirc *q, int a, int b, int c)
884
+ {
885
+ struct quirc_point h0, hd;
886
+ int i;
887
+ int qr_index;
888
+ struct quirc_grid *qr;
889
+
890
+ if (q->num_grids >= QUIRC_MAX_GRIDS)
891
+ return;
892
+
893
+ /* Construct the hypotenuse line from A to C. B should be to
894
+ * the left of this line.
895
+ */
896
+ memcpy(&h0, &q->capstones[a].center, sizeof(h0));
897
+ hd.x = q->capstones[c].center.x - q->capstones[a].center.x;
898
+ hd.y = q->capstones[c].center.y - q->capstones[a].center.y;
899
+
900
+ /* Make sure A-B-C is clockwise */
901
+ if ((q->capstones[b].center.x - h0.x) * -hd.y +
902
+ (q->capstones[b].center.y - h0.y) * hd.x > 0) {
903
+ int swap = a;
904
+
905
+ a = c;
906
+ c = swap;
907
+ hd.x = -hd.x;
908
+ hd.y = -hd.y;
909
+ }
910
+
911
+ /* Record the grid and its components */
912
+ qr_index = q->num_grids;
913
+ qr = &q->grids[q->num_grids++];
914
+
915
+ memset(qr, 0, sizeof(*qr));
916
+ qr->caps[0] = a;
917
+ qr->caps[1] = b;
918
+ qr->caps[2] = c;
919
+ qr->align_region = -1;
920
+
921
+ /* Rotate each capstone so that corner 0 is top-left with respect
922
+ * to the grid.
923
+ */
924
+ for (i = 0; i < 3; i++) {
925
+ struct quirc_capstone *cap = &q->capstones[qr->caps[i]];
926
+
927
+ rotate_capstone(cap, &h0, &hd);
928
+ cap->qr_grid = qr_index;
929
+ }
930
+
931
+ /* Check the timing pattern. This doesn't require a perspective
932
+ * transform.
933
+ */
934
+ if (measure_timing_pattern(q, qr_index) < 0)
935
+ goto fail;
936
+
937
+ /* Make an estimate based for the alignment pattern based on extending
938
+ * lines from capstones A and C.
939
+ */
940
+ if (!line_intersect(&q->capstones[a].corners[0],
941
+ &q->capstones[a].corners[1],
942
+ &q->capstones[c].corners[0],
943
+ &q->capstones[c].corners[3],
944
+ &qr->align))
945
+ goto fail;
946
+
947
+ /* On V2+ grids, we should use the alignment pattern. */
948
+ if (qr->grid_size > 21) {
949
+ /* Try to find the actual location of the alignment pattern. */
950
+ find_alignment_pattern(q, qr_index);
951
+
952
+ /* Find the point of the alignment pattern closest to the
953
+ * top-left of the QR grid.
954
+ */
955
+ if (qr->align_region >= 0) {
956
+ struct polygon_score_data psd;
957
+ struct quirc_region *reg =
958
+ &q->regions[qr->align_region];
959
+
960
+ /* Start from some point inside the alignment pattern */
961
+ memcpy(&qr->align, &reg->seed, sizeof(qr->align));
962
+
963
+ memcpy(&psd.ref, &hd, sizeof(psd.ref));
964
+ psd.corners = &qr->align;
965
+ psd.scores[0] = -hd.y * qr->align.x +
966
+ hd.x * qr->align.y;
967
+
968
+ flood_fill_seed(q, reg->seed.x, reg->seed.y,
969
+ qr->align_region, QUIRC_PIXEL_BLACK,
970
+ NULL, NULL, 0);
971
+ flood_fill_seed(q, reg->seed.x, reg->seed.y,
972
+ QUIRC_PIXEL_BLACK, qr->align_region,
973
+ find_leftmost_to_line, &psd, 0);
974
+ }
975
+ }
976
+
977
+ setup_qr_perspective(q, qr_index);
978
+ return;
979
+
980
+ fail:
981
+ /* We've been unable to complete setup for this grid. Undo what we've
982
+ * recorded and pretend it never happened.
983
+ */
984
+ for (i = 0; i < 3; i++)
985
+ q->capstones[qr->caps[i]].qr_grid = -1;
986
+ q->num_grids--;
987
+ }
988
+
989
+ struct neighbour {
990
+ int index;
991
+ double distance;
992
+ };
993
+
994
+ struct neighbour_list {
995
+ struct neighbour n[QUIRC_MAX_CAPSTONES];
996
+ int count;
997
+ };
998
+
999
+ static void test_neighbours(struct quirc *q, int i,
1000
+ const struct neighbour_list *hlist,
1001
+ const struct neighbour_list *vlist)
1002
+ {
1003
+ int j, k;
1004
+ double best_score = 0.0;
1005
+ int best_h = -1, best_v = -1;
1006
+
1007
+ /* Test each possible grouping */
1008
+ for (j = 0; j < hlist->count; j++)
1009
+ for (k = 0; k < vlist->count; k++) {
1010
+ const struct neighbour *hn = &hlist->n[j];
1011
+ const struct neighbour *vn = &vlist->n[k];
1012
+ double score = fabs(1.0 - hn->distance / vn->distance);
1013
+
1014
+ if (score > 2.5)
1015
+ continue;
1016
+
1017
+ if (best_h < 0 || score < best_score) {
1018
+ best_h = hn->index;
1019
+ best_v = vn->index;
1020
+ best_score = score;
1021
+ }
1022
+ }
1023
+
1024
+ if (best_h < 0 || best_v < 0)
1025
+ return;
1026
+
1027
+ record_qr_grid(q, best_h, i, best_v);
1028
+ }
1029
+
1030
+ static void test_grouping(struct quirc *q, int i)
1031
+ {
1032
+ struct quirc_capstone *c1 = &q->capstones[i];
1033
+ int j;
1034
+ struct neighbour_list hlist;
1035
+ struct neighbour_list vlist;
1036
+
1037
+ if (c1->qr_grid >= 0)
1038
+ return;
1039
+
1040
+ hlist.count = 0;
1041
+ vlist.count = 0;
1042
+
1043
+ /* Look for potential neighbours by examining the relative gradients
1044
+ * from this capstone to others.
1045
+ */
1046
+ for (j = 0; j < q->num_capstones; j++) {
1047
+ struct quirc_capstone *c2 = &q->capstones[j];
1048
+ double u, v;
1049
+
1050
+ if (i == j || c2->qr_grid >= 0)
1051
+ continue;
1052
+
1053
+ perspective_unmap(c1->c, &c2->center, &u, &v);
1054
+
1055
+ u = fabs(u - 3.5);
1056
+ v = fabs(v - 3.5);
1057
+
1058
+ if (u < 0.2 * v) {
1059
+ struct neighbour *n = &hlist.n[hlist.count++];
1060
+
1061
+ n->index = j;
1062
+ n->distance = v;
1063
+ }
1064
+
1065
+ if (v < 0.2 * u) {
1066
+ struct neighbour *n = &vlist.n[vlist.count++];
1067
+
1068
+ n->index = j;
1069
+ n->distance = u;
1070
+ }
1071
+ }
1072
+
1073
+ if (!(hlist.count && vlist.count))
1074
+ return;
1075
+
1076
+ test_neighbours(q, i, &hlist, &vlist);
1077
+ }
1078
+
1079
+ static void pixels_setup(struct quirc *q)
1080
+ {
1081
+ if (sizeof(*q->image) == sizeof(*q->pixels)) {
1082
+ q->pixels = (quirc_pixel_t *)q->image;
1083
+ } else {
1084
+ int x, y;
1085
+ for (y = 0; y < q->h; y++) {
1086
+ for (x = 0; x < q->w; x++) {
1087
+ q->pixels[y * q->w + x] = q->image[y * q->w + x];
1088
+ }
1089
+ }
1090
+ }
1091
+ }
1092
+
1093
+ uint8_t *quirc_begin(struct quirc *q, int *w, int *h)
1094
+ {
1095
+ q->num_regions = QUIRC_PIXEL_REGION;
1096
+ q->num_capstones = 0;
1097
+ q->num_grids = 0;
1098
+
1099
+ if (w)
1100
+ *w = q->w;
1101
+ if (h)
1102
+ *h = q->h;
1103
+
1104
+ return q->image;
1105
+ }
1106
+
1107
+ void quirc_end(struct quirc *q)
1108
+ {
1109
+ int i;
1110
+
1111
+ pixels_setup(q);
1112
+ threshold(q);
1113
+
1114
+ for (i = 0; i < q->h; i++)
1115
+ finder_scan(q, i);
1116
+
1117
+ for (i = 0; i < q->num_capstones; i++)
1118
+ test_grouping(q, i);
1119
+ }
1120
+
1121
+ void quirc_extract(const struct quirc *q, int index,
1122
+ struct quirc_code *code)
1123
+ {
1124
+ const struct quirc_grid *qr = &q->grids[index];
1125
+ int y;
1126
+ int i = 0;
1127
+
1128
+ if (index < 0 || index > q->num_grids)
1129
+ return;
1130
+
1131
+ memset(code, 0, sizeof(*code));
1132
+
1133
+ perspective_map(qr->c, 0.0, 0.0, &code->corners[0]);
1134
+ perspective_map(qr->c, qr->grid_size, 0.0, &code->corners[1]);
1135
+ perspective_map(qr->c, qr->grid_size, qr->grid_size,
1136
+ &code->corners[2]);
1137
+ perspective_map(qr->c, 0.0, qr->grid_size, &code->corners[3]);
1138
+
1139
+ code->size = qr->grid_size;
1140
+
1141
+ for (y = 0; y < qr->grid_size; y++) {
1142
+ int x;
1143
+
1144
+ for (x = 0; x < qr->grid_size; x++) {
1145
+ if (read_cell(q, index, x, y) > 0)
1146
+ code->cell_bitmap[i >> 3] |= (1 << (i & 7));
1147
+
1148
+ i++;
1149
+ }
1150
+ }
1151
+ }