forked from makiuchi-d/gozxing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
error_correction.go
156 lines (146 loc) · 5.24 KB
/
error_correction.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
package encoder
import (
"github.com/kaxap/gozxing"
)
var (
// Lookup table which factors to use for which number of error correction codewords.
// See FACTORS.
factorSets = []int{
5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68,
}
// Precomputed polynomial factors for ECC 200.
factors = [][]int{
{228, 48, 15, 111, 62},
{23, 68, 144, 134, 240, 92, 254},
{28, 24, 185, 166, 223, 248, 116, 255, 110, 61},
{175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120},
{41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242},
{156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185},
{83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90, 188},
{15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, 174, 186, 172},
{52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172,
254, 124, 12, 181, 184, 96, 50, 193},
{211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121,
17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255},
{245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182,
229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25,
225, 98, 81, 112},
{77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8,
175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101,
248, 202, 69, 50, 150, 177, 226, 5, 9, 5},
{245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87,
191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138,
186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19},
{175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235,
150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232,
144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28,
155, 43, 203, 107, 233, 53, 143, 46},
{242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37,
185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71,
161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31,
176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204},
{220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127,
213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236,
66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239,
181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63,
96, 103, 82, 186},
}
moduloValue = 0x12d
log []int
alog []int
)
func init() {
//Create log and antilog table
log = make([]int, 256)
alog = make([]int, 255)
p := 1
for i := 0; i < 255; i++ {
alog[i] = p
log[p] = i
p *= 2
if p >= 256 {
p ^= moduloValue
}
}
}
// createECC200 Creates the ECC200 error correction for an encoded message.
//
// @param codewords the codewords
// @param symbolInfo information about the symbol to be encoded
// @return the codewords with interleaved error correction.
//
func ErrorCorrection_EncodeECC200(codewords []byte, symbolInfo *SymbolInfo) ([]byte, error) {
if len(codewords) != symbolInfo.GetDataCapacity() {
return nil, gozxing.NewWriterException(
"IllegalArgumentException: The number of codewords does not match the selected symbol")
}
sb := make([]byte, 0, symbolInfo.GetDataCapacity()+symbolInfo.GetErrorCodewords())
sb = append(sb, codewords...)
blockCount := symbolInfo.GetInterleavedBlockCount()
if blockCount == 1 {
ecc, e := createECCBlock(codewords, symbolInfo.GetErrorCodewords())
if e != nil {
return sb, e
}
sb = append(sb, ecc...)
} else {
sb = sb[:cap(sb)]
dataSizes := make([]int, blockCount)
errorSizes := make([]int, blockCount)
for i := 0; i < blockCount; i++ {
dataSizes[i] = symbolInfo.GetDataLengthForInterleavedBlock(i + 1)
errorSizes[i] = symbolInfo.GetErrorLengthForInterleavedBlock(i + 1)
}
for block := 0; block < blockCount; block++ {
temp := make([]byte, 0, dataSizes[block])
for d := block; d < symbolInfo.GetDataCapacity(); d += blockCount {
temp = append(temp, codewords[d])
}
ecc, _ := createECCBlock(temp, errorSizes[block])
pos := 0
for e := block; e < errorSizes[block]*blockCount; e += blockCount {
sb[symbolInfo.GetDataCapacity()+e] = ecc[pos]
pos++
}
}
}
return sb, nil
}
func createECCBlock(codewords []byte, numECWords int) ([]byte, error) {
start := 0
length := len(codewords)
table := -1
for i := 0; i < len(factorSets); i++ {
if factorSets[i] == numECWords {
table = i
break
}
}
if table < 0 {
return codewords, gozxing.NewWriterException(
"IllegalArgumentException: Illegal number of error correction codewords specified: %d",
numECWords)
}
poly := factors[table]
ecc := make([]int, numECWords)
for i := start; i < start+length; i++ {
m := ecc[numECWords-1] ^ int(codewords[i])
for k := numECWords - 1; k > 0; k-- {
if m != 0 && poly[k] != 0 {
ecc[k] = ecc[k-1] ^ alog[(log[m]+log[poly[k]])%255]
} else {
ecc[k] = ecc[k-1]
}
}
if m != 0 && poly[0] != 0 {
ecc[0] = alog[(log[m]+log[poly[0]])%255]
} else {
ecc[0] = 0
}
}
eccReversed := make([]byte, numECWords)
for i := 0; i < numECWords; i++ {
eccReversed[i] = byte(ecc[numECWords-i-1])
}
return eccReversed, nil
}