| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- package datamatrix
- import (
- "github.com/boombuler/barcode/utils"
- )
- type errorCorrection struct {
- fld *utils.GaloisField
- polynomes map[int][]int
- }
- var ec *errorCorrection = newErrorCorrection()
- func newErrorCorrection() *errorCorrection {
- result := new(errorCorrection)
- result.fld = utils.NewGaloisField(301)
- result.polynomes = make(map[int][]int)
- return result
- }
- func (ec *errorCorrection) getPolynomial(count int) []int {
- poly, ok := ec.polynomes[count]
- if !ok {
- idx := 1
- poly = make([]int, count+1)
- poly[0] = 1
- for i := 1; i <= count; i++ {
- poly[i] = 1
- for j := i - 1; j > 0; j-- {
- if poly[j] != 0 {
- poly[j] = ec.fld.ALogTbl[(int(ec.fld.LogTbl[poly[j]])+idx)%255]
- }
- poly[j] = ec.fld.AddOrSub(poly[j], poly[j-1])
- }
- poly[0] = ec.fld.ALogTbl[(int(ec.fld.LogTbl[poly[0]])+idx)%255]
- idx++
- }
- poly = poly[0:count]
- ec.polynomes[count] = poly
- }
- return poly
- }
- func (ec *errorCorrection) calcECCBlock(data []byte, poly []int) []byte {
- ecc := make([]byte, len(poly)+1)
- for i := 0; i < len(data); i++ {
- k := ec.fld.AddOrSub(int(ecc[0]), int(data[i]))
- for j := 0; j < len(ecc)-1; j++ {
- ecc[j] = byte(ec.fld.AddOrSub(int(ecc[j+1]), ec.fld.Multiply(k, poly[len(ecc)-j-2])))
- }
- }
- return ecc
- }
- func (ec *errorCorrection) calcECC(data []byte, size *dmCodeSize) []byte {
- poly := ec.getPolynomial(size.ErrorCorrectionCodewordsPerBlock())
- dataSize := len(data)
- // make some space for error correction codes
- data = append(data, make([]byte, size.ECCCount)...)
- for block := 0; block < size.BlockCount; block++ {
- dataCnt := size.DataCodewordsForBlock(block)
- buff := make([]byte, dataCnt)
- // copy the data for the current block to buff
- j := 0
- for i := block; i < dataSize; i += size.BlockCount {
- buff[j] = data[i]
- j++
- }
- // calc the error correction codes
- ecc := ec.calcECCBlock(buff, poly)
- // and append them to the result
- j = 0
- for i := block; i < size.ErrorCorrectionCodewordsPerBlock()*size.BlockCount; i += size.BlockCount {
- data[dataSize+i] = ecc[j]
- j++
- }
- }
- return data
- }
|