forked from yeqown/go-qrcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
matrix.go
180 lines (151 loc) · 3.48 KB
/
matrix.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package qrcode
import (
"errors"
"fmt"
)
var (
// ErrorOutRangeOfW x out of range of Width
ErrorOutRangeOfW = errors.New("out of range of width")
// ErrorOutRangeOfH y out of range of Height
ErrorOutRangeOfH = errors.New("out of range of height")
)
// newMatrix generate a matrix with map[][]qrbool
func newMatrix(width, height int) *Matrix {
mat := make([][]qrvalue, width)
for w := 0; w < width; w++ {
mat[w] = make([]qrvalue, height)
}
m := &Matrix{
mat: mat,
width: width,
height: height,
}
m.init()
return m
}
// Matrix is a matrix data type
// width:3 height: 4 for [3][4]int
type Matrix struct {
mat [][]qrvalue
width int
height int
}
// do some init work
func (m *Matrix) init() {
for w := 0; w < m.width; w++ {
for h := 0; h < m.height; h++ {
m.mat[w][h] = QRValue_INIT_V0
}
}
}
// print to stdout
func (m *Matrix) print() {
m.iter(IterDirection_ROW, func(x, y int, s qrvalue) {
fmt.Printf("%s ", s)
if (x + 1) == m.width {
fmt.Println()
}
})
}
// Copy matrix into a new Matrix
func (m *Matrix) Copy() *Matrix {
mat2 := make([][]qrvalue, m.width)
for w := 0; w < m.width; w++ {
mat2[w] = make([]qrvalue, m.height)
copy(mat2[w], m.mat[w])
}
m2 := &Matrix{
width: m.width,
height: m.height,
mat: mat2,
}
return m2
}
// Width ... width
func (m *Matrix) Width() int {
return m.width
}
// Height ... height
func (m *Matrix) Height() int {
return m.height
}
// set [w][h] as true
func (m *Matrix) set(w, h int, c qrvalue) error {
if w >= m.width || w < 0 {
return ErrorOutRangeOfW
}
if h >= m.height || h < 0 {
return ErrorOutRangeOfH
}
m.mat[w][h] = c
return nil
}
// at state qrvalue from matrix with position {x, y}
func (m *Matrix) at(w, h int) (qrvalue, error) {
if w >= m.width || w < 0 {
return QRValue_INIT_V0, ErrorOutRangeOfW
}
if h >= m.height || h < 0 {
return QRValue_INIT_V0, ErrorOutRangeOfH
}
return m.mat[w][h], nil
}
// iterDirection scan matrix direction
type iterDirection uint8
const (
// IterDirection_ROW for row first
IterDirection_ROW iterDirection = iota + 1
// IterDirection_COLUMN for column first
IterDirection_COLUMN
)
// Iterate the Matrix with loop direction IterDirection_ROW major or IterDirection_COLUMN major.
// IterDirection_COLUMN is recommended.
func (m *Matrix) Iterate(direction iterDirection, fn func(x, y int, s QRValue)) {
m.iter(direction, fn)
}
func (m *Matrix) iter(dir iterDirection, visitFn func(x int, y int, v qrvalue)) {
// row direction first
if dir == IterDirection_ROW {
for h := 0; h < m.height; h++ {
for w := 0; w < m.width; w++ {
visitFn(w, h, m.mat[w][h])
}
}
return
}
// column direction first
for w := 0; w < m.width; w++ {
for h := 0; h < m.height; h++ {
visitFn(w, h, m.mat[w][h])
}
}
}
// Row return a row of matrix, cur should be y dimension.
func (m *Matrix) Row(cur int) []qrvalue {
if cur >= m.height || cur < 0 {
return nil
}
col := make([]qrvalue, m.height)
for w := 0; w < m.width; w++ {
col[w] = m.mat[w][cur]
}
return col
}
// Col return a slice of column, cur should be x dimension.
func (m *Matrix) Col(cur int) []qrvalue {
if cur >= m.width || cur < 0 {
return nil
}
return m.mat[cur]
}
// Bitmap outputs the QR Code as a matrix of pixels, each represented by a single bit.
func (m *Matrix) Bitmap() [][]bool {
table := make([][]bool, m.Height())
for t := range table {
table[t] = make([]bool, m.Width())
}
m.iter(IterDirection_ROW, func(x, y int, s qrvalue) {
table[y][x] = s.qrbool()
})
return table
}