File: errorcorrection.go

package info (click to toggle)
golang-barcode 0.0~git20140830-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch
  • size: 280 kB
  • ctags: 270
  • sloc: makefile: 4
file content (82 lines) | stat: -rw-r--r-- 2,137 bytes parent folder | download | duplicates (2)
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
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 {
	buff := make([]byte, size.DataCodewordsPerBlock())
	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++ {
		// 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
}