2013-12-11 13:31:11 +00:00
|
|
|
package qr
|
|
|
|
|
2013-12-13 12:53:27 +00:00
|
|
|
import (
|
|
|
|
"github.com/boombuler/barcode/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
type errorCorrection struct {
|
|
|
|
fld *utils.GaloisField
|
2013-12-11 13:31:11 +00:00
|
|
|
polynomes map[byte][]byte
|
|
|
|
}
|
|
|
|
|
2014-08-11 08:34:45 +00:00
|
|
|
var ec = newGF()
|
2013-12-11 13:31:11 +00:00
|
|
|
|
2013-12-13 12:53:27 +00:00
|
|
|
func newGF() *errorCorrection {
|
|
|
|
return &errorCorrection{utils.NewGaloisField(285), make(map[byte][]byte)}
|
2013-12-11 13:31:11 +00:00
|
|
|
}
|
|
|
|
|
2013-12-13 12:53:27 +00:00
|
|
|
func (ec *errorCorrection) getPolynomial(eccc byte) []byte {
|
|
|
|
_, ok := ec.polynomes[eccc]
|
2013-12-11 13:31:11 +00:00
|
|
|
if !ok {
|
|
|
|
if eccc == 1 {
|
2013-12-13 12:53:27 +00:00
|
|
|
ec.polynomes[eccc] = []byte{0, 0}
|
2013-12-11 13:31:11 +00:00
|
|
|
} else {
|
2013-12-13 12:53:27 +00:00
|
|
|
b1 := ec.getPolynomial(eccc - 1)
|
2013-12-11 13:31:11 +00:00
|
|
|
result := make([]byte, eccc+1)
|
|
|
|
for x := 0; x < len(b1); x++ {
|
|
|
|
tmp1 := (int(b1[x]) + int(eccc-1)) % 255
|
|
|
|
if x == 0 {
|
|
|
|
result[x] = b1[x]
|
|
|
|
} else {
|
2013-12-13 12:53:27 +00:00
|
|
|
tmp0 := int(ec.fld.ALogTbl[result[x]]) ^ int(ec.fld.ALogTbl[b1[x]])
|
|
|
|
result[x] = byte(ec.fld.LogTbl[tmp0])
|
2013-12-11 13:31:11 +00:00
|
|
|
}
|
|
|
|
result[x+1] = byte(tmp1)
|
|
|
|
}
|
2013-12-13 12:53:27 +00:00
|
|
|
ec.polynomes[eccc] = result
|
2013-12-11 13:31:11 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2013-12-13 12:53:27 +00:00
|
|
|
return ec.polynomes[eccc]
|
2013-12-11 13:31:11 +00:00
|
|
|
}
|
|
|
|
|
2013-12-13 12:53:27 +00:00
|
|
|
func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte {
|
2013-12-11 13:31:11 +00:00
|
|
|
tmp := make([]byte, len(data)+int(eccCount))
|
|
|
|
copy(tmp, data)
|
2013-12-13 12:53:27 +00:00
|
|
|
generator := ec.getPolynomial(eccCount)
|
2013-12-11 13:31:11 +00:00
|
|
|
|
|
|
|
for i := 0; i < len(data); i++ {
|
2013-12-13 12:53:27 +00:00
|
|
|
alpha := ec.fld.LogTbl[tmp[i]]
|
2013-12-11 13:31:11 +00:00
|
|
|
for j := 0; j < len(generator); j++ {
|
|
|
|
idx := (int(alpha) + int(generator[j])) % 255
|
2013-12-13 12:53:27 +00:00
|
|
|
polyJ := ec.fld.ALogTbl[idx]
|
|
|
|
tmp[i+j] = byte(ec.fld.AddOrSub(int(tmp[i+j]), polyJ))
|
2013-12-11 13:31:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tmp[len(data):]
|
|
|
|
}
|