18
18
#include <string.h>
19
19
#include <stdbool.h>
20
20
#include <stdlib.h>
21
+ #ifdef QUIRC_USE_TGMATH
22
+ #include <tgmath.h>
23
+ #else
21
24
#include <math.h>
25
+ #endif // QUIRC_USE_TGMATH
22
26
#include "quirc_internal.h"
23
27
24
28
/************************************************************************
@@ -62,21 +66,21 @@ static int line_intersect(const struct quirc_point *p0,
62
66
return 1 ;
63
67
}
64
68
65
- static void perspective_setup (double * c ,
69
+ static void perspective_setup (quirc_float_t * c ,
66
70
const struct quirc_point * rect ,
67
- double w , double h )
71
+ quirc_float_t w , quirc_float_t h )
68
72
{
69
- double x0 = rect [0 ].x ;
70
- double y0 = rect [0 ].y ;
71
- double x1 = rect [1 ].x ;
72
- double y1 = rect [1 ].y ;
73
- double x2 = rect [2 ].x ;
74
- double y2 = rect [2 ].y ;
75
- double x3 = rect [3 ].x ;
76
- double y3 = rect [3 ].y ;
77
-
78
- double wden = w * (x2 * y3 - x3 * y2 + (x3 - x2 )* y1 + x1 * (y2 - y3 ));
79
- double hden = h * (x2 * y3 + x1 * (y2 - y3 ) - x3 * y2 + (x3 - x2 )* y1 );
73
+ quirc_float_t x0 = rect [0 ].x ;
74
+ quirc_float_t y0 = rect [0 ].y ;
75
+ quirc_float_t x1 = rect [1 ].x ;
76
+ quirc_float_t y1 = rect [1 ].y ;
77
+ quirc_float_t x2 = rect [2 ].x ;
78
+ quirc_float_t y2 = rect [2 ].y ;
79
+ quirc_float_t x3 = rect [3 ].x ;
80
+ quirc_float_t y3 = rect [3 ].y ;
81
+
82
+ quirc_float_t wden = w * (x2 * y3 - x3 * y2 + (x3 - x2 )* y1 + x1 * (y2 - y3 ));
83
+ quirc_float_t hden = h * (x2 * y3 + x1 * (y2 - y3 ) - x3 * y2 + (x3 - x2 )* y1 );
80
84
81
85
c [0 ] = (x1 * (x2 * y3 - x3 * y2 ) + x0 * (- x2 * y3 + x3 * y2 + (x2 - x3 )* y1 ) +
82
86
x1 * (x3 - x2 )* y0 ) / wden ;
@@ -93,24 +97,24 @@ static void perspective_setup(double *c,
93
97
hden ;
94
98
}
95
99
96
- static void perspective_map (const double * c ,
97
- double u , double v , struct quirc_point * ret )
100
+ static void perspective_map (const quirc_float_t * c ,
101
+ quirc_float_t u , quirc_float_t v , struct quirc_point * ret )
98
102
{
99
- double den = c [6 ]* u + c [7 ]* v + 1.0 ;
100
- double x = (c [0 ]* u + c [1 ]* v + c [2 ]) / den ;
101
- double y = (c [3 ]* u + c [4 ]* v + c [5 ]) / den ;
103
+ quirc_float_t den = c [6 ]* u + c [7 ]* v + 1.0 ;
104
+ quirc_float_t x = (c [0 ]* u + c [1 ]* v + c [2 ]) / den ;
105
+ quirc_float_t y = (c [3 ]* u + c [4 ]* v + c [5 ]) / den ;
102
106
103
107
ret -> x = (int ) rint (x );
104
108
ret -> y = (int ) rint (y );
105
109
}
106
110
107
- static void perspective_unmap (const double * c ,
111
+ static void perspective_unmap (const quirc_float_t * c ,
108
112
const struct quirc_point * in ,
109
- double * u , double * v )
113
+ quirc_float_t * u , quirc_float_t * v )
110
114
{
111
- double x = in -> x ;
112
- double y = in -> y ;
113
- double den = - c [0 ]* c [7 ]* y + c [1 ]* c [6 ]* y + (c [3 ]* c [7 ]- c [4 ]* c [6 ])* x +
115
+ quirc_float_t x = in -> x ;
116
+ quirc_float_t y = in -> y ;
117
+ quirc_float_t den = - c [0 ]* c [7 ]* y + c [1 ]* c [6 ]* y + (c [3 ]* c [7 ]- c [4 ]* c [6 ])* x +
114
118
c [0 ]* c [4 ] - c [1 ]* c [3 ];
115
119
116
120
* u = - (c [1 ]* (y - c [5 ]) - c [2 ]* c [7 ]* y + (c [5 ]* c [7 ]- c [4 ])* x + c [2 ]* c [4 ]) /
@@ -299,16 +303,16 @@ static uint8_t otsu(const struct quirc *q)
299
303
}
300
304
301
305
// Calculate weighted sum of histogram values
302
- double sum = 0 ;
306
+ quirc_float_t sum = 0 ;
303
307
unsigned int i = 0 ;
304
308
for (i = 0 ; i <= UINT8_MAX ; ++ i ) {
305
309
sum += i * histogram [i ];
306
310
}
307
311
308
312
// Compute threshold
309
- double sumB = 0 ;
313
+ quirc_float_t sumB = 0 ;
310
314
unsigned int q1 = 0 ;
311
- double max = 0 ;
315
+ quirc_float_t max = 0 ;
312
316
uint8_t threshold = 0 ;
313
317
for (i = 0 ; i <= UINT8_MAX ; ++ i ) {
314
318
// Weighted background
@@ -322,10 +326,10 @@ static uint8_t otsu(const struct quirc *q)
322
326
break ;
323
327
324
328
sumB += i * histogram [i ];
325
- const double m1 = sumB / q1 ;
326
- const double m2 = (sum - sumB ) / q2 ;
327
- const double m1m2 = m1 - m2 ;
328
- const double variance = m1m2 * m1m2 * q1 * q2 ;
329
+ const quirc_float_t m1 = sumB / q1 ;
330
+ const quirc_float_t m2 = (sum - sumB ) / q2 ;
331
+ const quirc_float_t m1m2 = m1 - m2 ;
332
+ const quirc_float_t variance = m1m2 * m1m2 * q1 * q2 ;
329
333
if (variance >= max ) {
330
334
threshold = i ;
331
335
max = variance ;
@@ -582,7 +586,7 @@ static void find_alignment_pattern(struct quirc *q, int index)
582
586
int size_estimate ;
583
587
int step_size = 1 ;
584
588
int dir = 0 ;
585
- double u , v ;
589
+ quirc_float_t u , v ;
586
590
587
591
/* Grab our previous estimate of the alignment pattern corner */
588
592
memcpy (& b , & qr -> align , sizeof (b ));
@@ -648,10 +652,10 @@ static void find_leftmost_to_line(void *user_data, int y, int left, int right)
648
652
}
649
653
}
650
654
651
- static double length (struct quirc_point a , struct quirc_point b )
655
+ static quirc_float_t length (struct quirc_point a , struct quirc_point b )
652
656
{
653
- double x = abs (a .x - b .x ) + 1 ;
654
- double y = abs (a .y - b .y ) + 1 ;
657
+ quirc_float_t x = abs (a .x - b .x ) + 1 ;
658
+ quirc_float_t y = abs (a .y - b .y ) + 1 ;
655
659
return sqrt (x * x + y * y );
656
660
}
657
661
/* Estimate grid size by determing distance between capstones
@@ -664,15 +668,15 @@ static void measure_grid_size(struct quirc *q, int index)
664
668
struct quirc_capstone * b = & (q -> capstones [qr -> caps [1 ]]);
665
669
struct quirc_capstone * c = & (q -> capstones [qr -> caps [2 ]]);
666
670
667
- double ab = length (b -> corners [0 ], a -> corners [3 ]);
668
- double capstone_ab_size = (length (b -> corners [0 ], b -> corners [3 ]) + length (a -> corners [0 ], a -> corners [3 ]))/2.0 ;
669
- double ver_grid = 7.0 * ab / capstone_ab_size ;
671
+ quirc_float_t ab = length (b -> corners [0 ], a -> corners [3 ]);
672
+ quirc_float_t capstone_ab_size = (length (b -> corners [0 ], b -> corners [3 ]) + length (a -> corners [0 ], a -> corners [3 ]))/2.0 ;
673
+ quirc_float_t ver_grid = 7.0 * ab / capstone_ab_size ;
670
674
671
- double bc = length (b -> corners [0 ], c -> corners [1 ]);
672
- double capstone_bc_size = (length (b -> corners [0 ], b -> corners [1 ]) + length (c -> corners [0 ], c -> corners [1 ]))/2.0 ;
673
- double hor_grid = 7.0 * bc / capstone_bc_size ;
675
+ quirc_float_t bc = length (b -> corners [0 ], c -> corners [1 ]);
676
+ quirc_float_t capstone_bc_size = (length (b -> corners [0 ], b -> corners [1 ]) + length (c -> corners [0 ], c -> corners [1 ]))/2.0 ;
677
+ quirc_float_t hor_grid = 7.0 * bc / capstone_bc_size ;
674
678
675
- double grid_size_estimate = (ver_grid + hor_grid ) / 2 ;
679
+ quirc_float_t grid_size_estimate = (ver_grid + hor_grid ) / 2 ;
676
680
677
681
int ver = (int )((grid_size_estimate - 17.0 + 2.0 ) / 4.0 );
678
682
@@ -703,7 +707,7 @@ static int fitness_cell(const struct quirc *q, int index, int x, int y)
703
707
704
708
for (v = 0 ; v < 3 ; v ++ )
705
709
for (u = 0 ; u < 3 ; u ++ ) {
706
- static const double offsets [] = {0.3 , 0.5 , 0.7 };
710
+ static const quirc_float_t offsets [] = {0.3 , 0.5 , 0.7 };
707
711
struct quirc_point p ;
708
712
709
713
perspective_map (qr -> c , x + offsets [u ],
@@ -806,7 +810,7 @@ static void jiggle_perspective(struct quirc *q, int index)
806
810
struct quirc_grid * qr = & q -> grids [index ];
807
811
int best = fitness_all (q , index );
808
812
int pass ;
809
- double adjustments [8 ];
813
+ quirc_float_t adjustments [8 ];
810
814
int i ;
811
815
812
816
for (i = 0 ; i < 8 ; i ++ )
@@ -816,9 +820,9 @@ static void jiggle_perspective(struct quirc *q, int index)
816
820
for (i = 0 ; i < 16 ; i ++ ) {
817
821
int j = i >> 1 ;
818
822
int test ;
819
- double old = qr -> c [j ];
820
- double step = adjustments [j ];
821
- double new ;
823
+ quirc_float_t old = qr -> c [j ];
824
+ quirc_float_t step = adjustments [j ];
825
+ quirc_float_t new ;
822
826
823
827
if (i & 1 )
824
828
new = old + step ;
@@ -998,7 +1002,7 @@ static void record_qr_grid(struct quirc *q, int a, int b, int c)
998
1002
999
1003
struct neighbour {
1000
1004
int index ;
1001
- double distance ;
1005
+ quirc_float_t distance ;
1002
1006
};
1003
1007
1004
1008
struct neighbour_list {
@@ -1015,7 +1019,7 @@ static void test_neighbours(struct quirc *q, int i,
1015
1019
const struct neighbour * hn = & hlist -> n [j ];
1016
1020
for (int k = 0 ; k < vlist -> count ; k ++ ) {
1017
1021
const struct neighbour * vn = & vlist -> n [k ];
1018
- double squareness = fabs (1.0 - hn -> distance / vn -> distance );
1022
+ quirc_float_t squareness = fabs (1.0 - hn -> distance / vn -> distance );
1019
1023
if (squareness < 0.2 )
1020
1024
record_qr_grid (q , hn -> index , i , vn -> index );
1021
1025
}
@@ -1037,7 +1041,7 @@ static void test_grouping(struct quirc *q, unsigned int i)
1037
1041
*/
1038
1042
for (j = 0 ; j < q -> num_capstones ; j ++ ) {
1039
1043
struct quirc_capstone * c2 = & q -> capstones [j ];
1040
- double u , v ;
1044
+ quirc_float_t u , v ;
1041
1045
1042
1046
if (i == j )
1043
1047
continue ;
0 commit comments