-
Notifications
You must be signed in to change notification settings - Fork 87
/
mask.go
138 lines (120 loc) · 2.91 KB
/
mask.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package qrcode
// maskPatternModulo ...
// mask Pattern ref to: https://www.thonky.com/qr-code-tutorial/mask-patterns
type maskPatternModulo uint32
const (
// modulo0 (x+y) mod 2 == 0
modulo0 maskPatternModulo = iota
// modulo1 (x) mod 2 == 0
modulo1
// modulo2 (y) mod 3 == 0
modulo2
// modulo3 (x+y) mod 3 == 0
modulo3
// modulo4 (floor (x/ 2) + floor (y/ 3) mod 2 == 0
modulo4
// modulo5 (x * y) mod 2) + (x * y) mod 3) == 0
modulo5
// modulo6 (x * y) mod 2) + (x * y) mod 3) mod 2 == 0
modulo6
// modulo7 (x + y) mod 2) + (x * y) mod 3) mod 2 == 0
modulo7
)
type mask struct {
mat *Matrix // matrix
mode maskPatternModulo // mode
moduloFn moduloFunc // moduloFn masking function
}
// newMask ...
func newMask(mat *Matrix, mode maskPatternModulo) *mask {
m := &mask{
mat: mat.Copy(),
mode: mode,
moduloFn: getModuloFunc(mode),
}
m.masking()
return m
}
// moduloFunc to define what's modulo func
type moduloFunc func(int, int) bool
func getModuloFunc(mode maskPatternModulo) (f moduloFunc) {
f = nil
switch mode {
case modulo0:
f = modulo0Func
case modulo1:
f = modulo1Func
case modulo2:
f = modulo2Func
case modulo3:
f = modulo3Func
case modulo4:
f = modulo4Func
case modulo5:
f = modulo5Func
case modulo6:
f = modulo6Func
case modulo7:
f = modulo7Func
}
return
}
// init generate maks by mode
func (m *mask) masking() {
moduloFn := m.moduloFn
if moduloFn == nil {
panic("impossible panic, contact maintainer plz")
}
m.mat.iter(IterDirection_COLUMN, func(x, y int, s qrvalue) {
// skip the function modules
if v, _ := m.mat.at(x, y); v.qrtype() != QRType_INIT {
_ = m.mat.set(x, y, QRValue_INIT_V0)
return
}
if moduloFn(x, y) {
_ = m.mat.set(x, y, QRValue_DATA_V1)
} else {
_ = m.mat.set(x, y, QRValue_DATA_V0)
}
})
}
// modulo0Func for maskPattern function
// modulo0 (x+y) mod 2 == 0
func modulo0Func(x, y int) bool {
return (x+y)%2 == 0
}
// modulo1Func for maskPattern function
// modulo1 (y) mod 2 == 0
func modulo1Func(x, y int) bool {
return y%2 == 0
}
// modulo2Func for maskPattern function
// modulo2 (x) mod 3 == 0
func modulo2Func(x, y int) bool {
return x%3 == 0
}
// modulo3Func for maskPattern function
// modulo3 (x+y) mod 3 == 0
func modulo3Func(x, y int) bool {
return (x+y)%3 == 0
}
// modulo4Func for maskPattern function
// modulo4 (floor (x/ 2) + floor (y/ 3) mod 2 == 0
func modulo4Func(x, y int) bool {
return (x/3+y/2)%2 == 0
}
// modulo5Func for maskPattern function
// modulo5 (x * y) mod 2 + (x * y) mod 3 == 0
func modulo5Func(x, y int) bool {
return (x*y)%2+(x*y)%3 == 0
}
// modulo6Func for maskPattern function
// modulo6 (x * y) mod 2) + (x * y) mod 3) mod 2 == 0
func modulo6Func(x, y int) bool {
return ((x*y)%2+(x*y)%3)%2 == 0
}
// modulo7Func for maskPattern function
// modulo7 (x + y) mod 2) + (x * y) mod 3) mod 2 == 0
func modulo7Func(x, y int) bool {
return ((x+y)%2+(x*y)%3)%2 == 0
}