bugfix for datamatrix error correction
more tests and code cleanup
This commit is contained in:
1 parent
e754f1b44c
commit
e5d11acdbf
19 files changed
+291
-157
No files matched your search
+3
-3
@@ -3,7 +3,7 @@ package qr
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ func stringToAlphaIdx(content string) <-chan int {
|
||||
return result
|
||||
}
|
||||
|
||||
func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
|
||||
func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) {
|
||||
|
||||
contentLenIsOdd := len(content)%2 == 1
|
||||
contentBitCount := (len(content) / 2) * 11
|
||||
@@ -37,7 +37,7 @@ func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*barcode.BitL
|
||||
return nil, nil, errors.New("To much data to encode")
|
||||
}
|
||||
|
||||
res := new(barcode.BitList)
|
||||
res := new(utils.BitList)
|
||||
res.AddBits(int(alphaNumericMode), 4)
|
||||
res.AddBits(len(content), vi.charCountBits(alphaNumericMode))
|
||||
|
||||
|
||||
+2
-2
@@ -2,10 +2,10 @@ package qr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/utils"
|
||||
)
|
||||
|
||||
func encodeAuto(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
|
||||
func encodeAuto(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) {
|
||||
bits, vi, _ := Numeric.getEncoder()(content, ecl)
|
||||
if bits != nil && vi != nil {
|
||||
return bits, vi, nil
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ func splitToBlocks(data <-chan byte, vi *versionInfo) blockList {
|
||||
for cw := 0; cw < int(vi.DataCodeWordsPerBlockInGroup1); cw++ {
|
||||
blk.data[cw] = <-data
|
||||
}
|
||||
blk.ecc = gf.calcECC(blk.data, vi.ErrorCorrectionCodewordsPerBlock)
|
||||
blk.ecc = ec.calcECC(blk.data, vi.ErrorCorrectionCodewordsPerBlock)
|
||||
result[b] = blk
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func splitToBlocks(data <-chan byte, vi *versionInfo) blockList {
|
||||
for cw := 0; cw < int(vi.DataCodeWordsPerBlockInGroup2); cw++ {
|
||||
blk.data[cw] = <-data
|
||||
}
|
||||
blk.ecc = gf.calcECC(blk.data, vi.ErrorCorrectionCodewordsPerBlock)
|
||||
blk.ecc = ec.calcECC(blk.data, vi.ErrorCorrectionCodewordsPerBlock)
|
||||
result[int(vi.NumberOfBlocksInGroup1)+b] = blk
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -4,10 +4,11 @@ package qr
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/utils"
|
||||
"image"
|
||||
)
|
||||
|
||||
type encodeFn func(content string, eccLevel ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error)
|
||||
type encodeFn func(content string, eccLevel ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error)
|
||||
|
||||
type Encoding byte
|
||||
|
||||
@@ -463,7 +464,7 @@ func drawVersionInfo(vi *versionInfo, set func(int, int, bool)) {
|
||||
|
||||
}
|
||||
|
||||
func addPaddingAndTerminator(bl *barcode.BitList, vi *versionInfo) {
|
||||
func addPaddingAndTerminator(bl *utils.BitList, vi *versionInfo) {
|
||||
for i := 0; i < 4 && bl.Len() < vi.totalDataBytes()*8; i++ {
|
||||
bl.AddBit(false)
|
||||
}
|
||||
|
||||
+22
-39
@@ -1,73 +1,56 @@
|
||||
package qr
|
||||
|
||||
type galoisField struct {
|
||||
aLogTbl []byte
|
||||
logTbl []byte
|
||||
import (
|
||||
"github.com/boombuler/barcode/utils"
|
||||
)
|
||||
|
||||
type errorCorrection struct {
|
||||
fld *utils.GaloisField
|
||||
polynomes map[byte][]byte
|
||||
}
|
||||
|
||||
var gf *galoisField = newGF()
|
||||
var ec *errorCorrection = newGF()
|
||||
|
||||
func newGF() *galoisField {
|
||||
result := new(galoisField)
|
||||
result.polynomes = make(map[byte][]byte)
|
||||
result.aLogTbl = make([]byte, 255)
|
||||
result.logTbl = make([]byte, 256)
|
||||
|
||||
result.aLogTbl[0] = 1
|
||||
|
||||
x := 1
|
||||
for i := 1; i < 255; i++ {
|
||||
x = x * 2
|
||||
if x > 255 {
|
||||
x = x ^ 285
|
||||
}
|
||||
result.aLogTbl[i] = byte(x)
|
||||
}
|
||||
|
||||
for i := 1; i < 255; i++ {
|
||||
result.logTbl[result.aLogTbl[i]] = byte(i)
|
||||
}
|
||||
|
||||
return result
|
||||
func newGF() *errorCorrection {
|
||||
return &errorCorrection{utils.NewGaloisField(285), make(map[byte][]byte)}
|
||||
}
|
||||
|
||||
func (gf *galoisField) getPolynom(eccc byte) []byte {
|
||||
_, ok := gf.polynomes[eccc]
|
||||
func (ec *errorCorrection) getPolynomial(eccc byte) []byte {
|
||||
_, ok := ec.polynomes[eccc]
|
||||
if !ok {
|
||||
if eccc == 1 {
|
||||
gf.polynomes[eccc] = []byte{0, 0}
|
||||
ec.polynomes[eccc] = []byte{0, 0}
|
||||
} else {
|
||||
b1 := gf.getPolynom(eccc - 1)
|
||||
b1 := ec.getPolynomial(eccc - 1)
|
||||
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 {
|
||||
tmp0 := int(gf.aLogTbl[result[x]]) ^ int(gf.aLogTbl[b1[x]])
|
||||
result[x] = gf.logTbl[tmp0]
|
||||
tmp0 := int(ec.fld.ALogTbl[result[x]]) ^ int(ec.fld.ALogTbl[b1[x]])
|
||||
result[x] = byte(ec.fld.LogTbl[tmp0])
|
||||
}
|
||||
result[x+1] = byte(tmp1)
|
||||
}
|
||||
gf.polynomes[eccc] = result
|
||||
ec.polynomes[eccc] = result
|
||||
|
||||
}
|
||||
}
|
||||
return gf.polynomes[eccc]
|
||||
return ec.polynomes[eccc]
|
||||
}
|
||||
|
||||
func (gf *galoisField) calcECC(data []byte, eccCount byte) []byte {
|
||||
func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte {
|
||||
tmp := make([]byte, len(data)+int(eccCount))
|
||||
copy(tmp, data)
|
||||
generator := gf.getPolynom(eccCount)
|
||||
generator := ec.getPolynomial(eccCount)
|
||||
|
||||
for i := 0; i < len(data); i++ {
|
||||
alpha := gf.logTbl[tmp[i]]
|
||||
alpha := ec.fld.LogTbl[tmp[i]]
|
||||
for j := 0; j < len(generator); j++ {
|
||||
idx := (int(alpha) + int(generator[j])) % 255
|
||||
polyJ := gf.aLogTbl[idx]
|
||||
tmp[i+j] = (tmp[i+j] ^ polyJ)
|
||||
polyJ := ec.fld.ALogTbl[idx]
|
||||
tmp[i+j] = byte(ec.fld.AddOrSub(int(tmp[i+j]), polyJ))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@ import (
|
||||
|
||||
func Test_LogTables(t *testing.T) {
|
||||
for i := 1; i <= 255; i++ {
|
||||
tmp := gf.logTbl[i]
|
||||
if byte(i) != gf.aLogTbl[tmp] {
|
||||
tmp := ec.fld.LogTbl[i]
|
||||
if i != ec.fld.ALogTbl[tmp] {
|
||||
t.Errorf("Invalid LogTables: %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
if gf.aLogTbl[11] != 232 || gf.aLogTbl[87] != 127 || gf.aLogTbl[225] != 36 {
|
||||
if ec.fld.ALogTbl[11] != 232 || ec.fld.ALogTbl[87] != 127 || ec.fld.ALogTbl[225] != 36 {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Polynoms(t *testing.T) {
|
||||
func Test_GetPolynomial(t *testing.T) {
|
||||
doTest := func(b []byte) {
|
||||
cnt := byte(len(b) - 1)
|
||||
if bytes.Compare(gf.getPolynom(cnt), b) != 0 {
|
||||
t.Errorf("Failed getPolynom(%d)", cnt)
|
||||
if bytes.Compare(ec.getPolynomial(cnt), b) != 0 {
|
||||
t.Errorf("Failed getPolynomial(%d)", cnt)
|
||||
}
|
||||
}
|
||||
doTest([]byte{0, 0})
|
||||
@@ -34,7 +34,7 @@ func Test_Polynoms(t *testing.T) {
|
||||
func Test_ErrorCorrection(t *testing.T) {
|
||||
doTest := func(b []byte, ecc []byte) {
|
||||
cnt := byte(len(ecc))
|
||||
if bytes.Compare(gf.calcECC(b, cnt), ecc) != 0 {
|
||||
if bytes.Compare(ec.calcECC(b, cnt), ecc) != 0 {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -3,11 +3,11 @@ package qr
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/utils"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
|
||||
func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) {
|
||||
contentBitCount := (len(content) / 3) * 10
|
||||
switch len(content) % 3 {
|
||||
case 1:
|
||||
@@ -19,7 +19,7 @@ func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*barcode.BitList,
|
||||
if vi == nil {
|
||||
return nil, nil, errors.New("To much data to encode")
|
||||
}
|
||||
res := new(barcode.BitList)
|
||||
res := new(utils.BitList)
|
||||
res.AddBits(int(numericMode), 4)
|
||||
res.AddBits(len(content), vi.charCountBits(numericMode))
|
||||
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ package qr
|
||||
|
||||
import (
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/utils"
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
|
||||
type qrcode struct {
|
||||
dimension int
|
||||
data *barcode.BitList
|
||||
data *utils.BitList
|
||||
content string
|
||||
}
|
||||
|
||||
@@ -159,6 +160,6 @@ func (qr *qrcode) calcPenaltyRule4() uint {
|
||||
func newBarcode(dim int) *qrcode {
|
||||
res := new(qrcode)
|
||||
res.dimension = dim
|
||||
res.data = barcode.NewBitList(dim * dim)
|
||||
res.data = utils.NewBitList(dim * dim)
|
||||
return res
|
||||
}
|
||||
+3
-3
@@ -2,10 +2,10 @@ package qr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/utils"
|
||||
)
|
||||
|
||||
func encodeUnicode(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
|
||||
func encodeUnicode(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) {
|
||||
data := []byte(content)
|
||||
|
||||
vi := findSmallestVersionInfo(ecl, byteMode, len(data)*8)
|
||||
@@ -15,7 +15,7 @@ func encodeUnicode(content string, ecl ErrorCorrectionLevel) (*barcode.BitList,
|
||||
|
||||
// It's not correct to add the unicode bytes to the result directly but most readers can't handle the
|
||||
// required ECI header...
|
||||
res := new(barcode.BitList)
|
||||
res := new(utils.BitList)
|
||||
res.AddBits(int(byteMode), 4)
|
||||
res.AddBits(len(content), vi.charCountBits(byteMode))
|
||||
for _, b := range data {
|
||||
|
||||
Reference in new issue
Block a user