diff --git a/qr/alphanumeric.go b/qr/alphanumeric.go index 7770b93..4ded7c8 100644 --- a/qr/alphanumeric.go +++ b/qr/alphanumeric.go @@ -3,8 +3,9 @@ package qr import ( "errors" "fmt" - "github.com/boombuler/barcode/utils" "strings" + + "github.com/boombuler/barcode/utils" ) const charSet string = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" diff --git a/qr/alphanumeric_test.go b/qr/alphanumeric_test.go index 476c1d6..d8b1d38 100644 --- a/qr/alphanumeric_test.go +++ b/qr/alphanumeric_test.go @@ -5,11 +5,11 @@ import ( "testing" ) -func makeString(length int) string { +func makeString(length int, content string) string { res := "" for i := 0; i < length; i++ { - res += "A" + res += content } return res @@ -24,11 +24,11 @@ func Test_AlphaNumericEncoding(t *testing.T) { t.Errorf("\"HELLO WORLD\" failed to encode: %s", err) } - x, vi, err = encode(makeString(4296), L) + x, vi, err = encode(makeString(4296, "A"), L) if x == nil || vi == nil || err != nil { t.Fail() } - x, vi, err = encode(makeString(4297), L) + x, vi, err = encode(makeString(4297, "A"), L) if x != nil || vi != nil || err == nil { t.Fail() } diff --git a/qr/automatic.go b/qr/automatic.go index 6f10cc6..e7c5601 100644 --- a/qr/automatic.go +++ b/qr/automatic.go @@ -2,6 +2,7 @@ package qr import ( "fmt" + "github.com/boombuler/barcode/utils" ) diff --git a/qr/automatic_test.go b/qr/automatic_test.go index f4f606d..07587d4 100644 --- a/qr/automatic_test.go +++ b/qr/automatic_test.go @@ -7,10 +7,10 @@ import ( func Test_AutomaticEncoding(t *testing.T) { tests := map[string]encodeFn{ - "0123456789": Numeric.getEncoder(), - "ALPHA NUMERIC": AlphaNumeric.getEncoder(), - "unicode encoing": Unicode.getEncoder(), - "very long unicode encoding" + makeString(3000): nil, + "0123456789": Numeric.getEncoder(), + "ALPHA NUMERIC": AlphaNumeric.getEncoder(), + "unicode encoing": Unicode.getEncoder(), + "very long unicode encoding" + makeString(3000, "A"): nil, } for str, enc := range tests { diff --git a/qr/encoder.go b/qr/encoder.go index 656da04..2c6ab21 100644 --- a/qr/encoder.go +++ b/qr/encoder.go @@ -1,26 +1,29 @@ -// package for QR barcode generation. +// Package qr can be used to create QR barcodes. package qr import ( - "fmt" + "image" + "github.com/boombuler/barcode" "github.com/boombuler/barcode/utils" - "image" ) type encodeFn func(content string, eccLevel ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) +// Encoding mode for QR Codes. type Encoding byte const ( - // Choose best matching encoding + // Auto will choose ths best matching encoding Auto Encoding = iota - // Encode only numbers [0-9] + // Numeric encoding only encodes numbers [0-9] Numeric - // Encode only uppercase letters, numbers and [Space], $, %, *, +, -, ., /, : + // AlphaNumeric encoding only encodes uppercase letters, numbers and [Space], $, %, *, +, -, ., /, : AlphaNumeric - // Encodes string as utf-8 + // Unicode encoding encodes the string as utf-8 Unicode + // only for testing purpose + unknownEncoding ) func (e Encoding) getEncoder() encodeFn { @@ -51,15 +54,12 @@ func (e Encoding) String() string { return "" } -// Encodes the given content to a QR barcode +// Encode returns a QR barcode with the given content, error correction level and uses the given encoding func Encode(content string, level ErrorCorrectionLevel, mode Encoding) (barcode.Barcode, error) { bits, vi, err := mode.getEncoder()(content, level) if err != nil { return nil, err } - if bits == nil || vi == nil { - return nil, fmt.Errorf("Unable to encode \"%s\" with error correction level %s and encoding mode %s", content, level, mode) - } blocks := splitToBlocks(bits.IterateBytes(), vi) data := blocks.interleave(vi) @@ -107,7 +107,7 @@ func render(data []byte, vi *versionInfo) *qrcode { } // Write the data - var curBitNo int = 0 + var curBitNo int for pos := range iterateModules(occupied) { var curBit bool @@ -120,7 +120,7 @@ func render(data []byte, vi *versionInfo) *qrcode { for i := 0; i < 8; i++ { setMasked(pos.X, pos.Y, curBit, i, results[i].Set) } - curBitNo += 1 + curBitNo++ } lowestPenalty := ^uint(0) @@ -176,12 +176,12 @@ func iterateModules(occupied *qrcode) <-chan image.Point { if isUpward { allPoints <- image.Pt(curX, curY) allPoints <- image.Pt(curX-1, curY) - curY -= 1 + curY-- if curY < 0 { curY = 0 curX -= 2 if curX == 6 { - curX -= 1 + curX-- } if curX < 0 { break @@ -191,12 +191,12 @@ func iterateModules(occupied *qrcode) <-chan image.Point { } else { allPoints <- image.Pt(curX, curY) allPoints <- image.Pt(curX-1, curY) - curY += 1 + curY++ if curY >= occupied.dimension { curY = occupied.dimension - 1 curX -= 2 if curX == 6 { - curX -= 1 + curX-- } isUpward = true if curX < 0 { @@ -258,89 +258,56 @@ func drawAlignmentPatterns(occupied *qrcode, vi *versionInfo, set func(int, int, } } +var formatInfos = map[ErrorCorrectionLevel]map[int][]bool{ + L: { + 0: []bool{true, true, true, false, true, true, true, true, true, false, false, false, true, false, false}, + 1: []bool{true, true, true, false, false, true, false, true, true, true, true, false, false, true, true}, + 2: []bool{true, true, true, true, true, false, true, true, false, true, false, true, false, true, false}, + 3: []bool{true, true, true, true, false, false, false, true, false, false, true, true, true, false, true}, + 4: []bool{true, true, false, false, true, true, false, false, false, true, false, true, true, true, true}, + 5: []bool{true, true, false, false, false, true, true, false, false, false, true, true, false, false, false}, + 6: []bool{true, true, false, true, true, false, false, false, true, false, false, false, false, false, true}, + 7: []bool{true, true, false, true, false, false, true, false, true, true, true, false, true, true, false}, + }, + M: { + 0: []bool{true, false, true, false, true, false, false, false, false, false, true, false, false, true, false}, + 1: []bool{true, false, true, false, false, false, true, false, false, true, false, false, true, false, true}, + 2: []bool{true, false, true, true, true, true, false, false, true, true, true, true, true, false, false}, + 3: []bool{true, false, true, true, false, true, true, false, true, false, false, true, false, true, true}, + 4: []bool{true, false, false, false, true, false, true, true, true, true, true, true, false, false, true}, + 5: []bool{true, false, false, false, false, false, false, true, true, false, false, true, true, true, false}, + 6: []bool{true, false, false, true, true, true, true, true, false, false, true, false, true, true, true}, + 7: []bool{true, false, false, true, false, true, false, true, false, true, false, false, false, false, false}, + }, + Q: { + 0: []bool{false, true, true, false, true, false, true, false, true, false, true, true, true, true, true}, + 1: []bool{false, true, true, false, false, false, false, false, true, true, false, true, false, false, false}, + 2: []bool{false, true, true, true, true, true, true, false, false, true, true, false, false, false, true}, + 3: []bool{false, true, true, true, false, true, false, false, false, false, false, false, true, true, false}, + 4: []bool{false, true, false, false, true, false, false, true, false, true, true, false, true, false, false}, + 5: []bool{false, true, false, false, false, false, true, true, false, false, false, false, false, true, true}, + 6: []bool{false, true, false, true, true, true, false, true, true, false, true, true, false, true, false}, + 7: []bool{false, true, false, true, false, true, true, true, true, true, false, true, true, false, true}, + }, + H: { + 0: []bool{false, false, true, false, true, true, false, true, false, false, false, true, false, false, true}, + 1: []bool{false, false, true, false, false, true, true, true, false, true, true, true, true, true, false}, + 2: []bool{false, false, true, true, true, false, false, true, true, true, false, false, true, true, true}, + 3: []bool{false, false, true, true, false, false, true, true, true, false, true, false, false, false, false}, + 4: []bool{false, false, false, false, true, true, true, false, true, true, false, false, false, true, false}, + 5: []bool{false, false, false, false, false, true, false, false, true, false, true, false, true, false, true}, + 6: []bool{false, false, false, true, true, false, true, false, false, false, false, true, true, false, false}, + 7: []bool{false, false, false, true, false, false, false, false, false, true, true, true, false, true, true}, + }, +} + func drawFormatInfo(vi *versionInfo, usedMask int, set func(int, int, bool)) { var formatInfo []bool - switch vi.Level { - case L: - switch usedMask { - case 0: - formatInfo = []bool{true, true, true, false, true, true, true, true, true, false, false, false, true, false, false} - case 1: - formatInfo = []bool{true, true, true, false, false, true, false, true, true, true, true, false, false, true, true} - case 2: - formatInfo = []bool{true, true, true, true, true, false, true, true, false, true, false, true, false, true, false} - case 3: - formatInfo = []bool{true, true, true, true, false, false, false, true, false, false, true, true, true, false, true} - case 4: - formatInfo = []bool{true, true, false, false, true, true, false, false, false, true, false, true, true, true, true} - case 5: - formatInfo = []bool{true, true, false, false, false, true, true, false, false, false, true, true, false, false, false} - case 6: - formatInfo = []bool{true, true, false, true, true, false, false, false, true, false, false, false, false, false, true} - case 7: - formatInfo = []bool{true, true, false, true, false, false, true, false, true, true, true, false, true, true, false} - } - case M: - switch usedMask { - case 0: - formatInfo = []bool{true, false, true, false, true, false, false, false, false, false, true, false, false, true, false} - case 1: - formatInfo = []bool{true, false, true, false, false, false, true, false, false, true, false, false, true, false, true} - case 2: - formatInfo = []bool{true, false, true, true, true, true, false, false, true, true, true, true, true, false, false} - case 3: - formatInfo = []bool{true, false, true, true, false, true, true, false, true, false, false, true, false, true, true} - case 4: - formatInfo = []bool{true, false, false, false, true, false, true, true, true, true, true, true, false, false, true} - case 5: - formatInfo = []bool{true, false, false, false, false, false, false, true, true, false, false, true, true, true, false} - case 6: - formatInfo = []bool{true, false, false, true, true, true, true, true, false, false, true, false, true, true, true} - case 7: - formatInfo = []bool{true, false, false, true, false, true, false, true, false, true, false, false, false, false, false} - } - case Q: - switch usedMask { - case 0: - formatInfo = []bool{false, true, true, false, true, false, true, false, true, false, true, true, true, true, true} - case 1: - formatInfo = []bool{false, true, true, false, false, false, false, false, true, true, false, true, false, false, false} - case 2: - formatInfo = []bool{false, true, true, true, true, true, true, false, false, true, true, false, false, false, true} - case 3: - formatInfo = []bool{false, true, true, true, false, true, false, false, false, false, false, false, true, true, false} - case 4: - formatInfo = []bool{false, true, false, false, true, false, false, true, false, true, true, false, true, false, false} - case 5: - formatInfo = []bool{false, true, false, false, false, false, true, true, false, false, false, false, false, true, true} - case 6: - formatInfo = []bool{false, true, false, true, true, true, false, true, true, false, true, true, false, true, false} - case 7: - formatInfo = []bool{false, true, false, true, false, true, true, true, true, true, false, true, true, false, true} - } - case H: - switch usedMask { - case 0: - formatInfo = []bool{false, false, true, false, true, true, false, true, false, false, false, true, false, false, true} - case 1: - formatInfo = []bool{false, false, true, false, false, true, true, true, false, true, true, true, true, true, false} - case 2: - formatInfo = []bool{false, false, true, true, true, false, false, true, true, true, false, false, true, true, true} - case 3: - formatInfo = []bool{false, false, true, true, false, false, true, true, true, false, true, false, false, false, false} - case 4: - formatInfo = []bool{false, false, false, false, true, true, true, false, true, true, false, false, false, true, false} - case 5: - formatInfo = []bool{false, false, false, false, false, true, false, false, true, false, true, false, true, false, true} - case 6: - formatInfo = []bool{false, false, false, true, true, false, true, false, false, false, false, true, true, false, false} - case 7: - formatInfo = []bool{false, false, false, true, false, false, false, false, false, true, true, true, false, true, true} - } - } if usedMask == -1 { formatInfo = []bool{true, true, true, true, true, true, true, true, true, true, true, true, true, true, true} // Set all to true cause -1 --> occupied mask. + } else { + formatInfo = formatInfos[vi.Level][usedMask] } if len(formatInfo) == 15 { @@ -379,81 +346,47 @@ func drawFormatInfo(vi *versionInfo, usedMask int, set func(int, int, bool)) { } } +var versionInfoBitsByVersion = map[byte][]bool{ + 7: []bool{false, false, false, true, true, true, true, true, false, false, true, false, false, true, false, true, false, false}, + 8: []bool{false, false, true, false, false, false, false, true, false, true, true, false, true, true, true, true, false, false}, + 9: []bool{false, false, true, false, false, true, true, false, true, false, true, false, false, true, true, false, false, true}, + 10: []bool{false, false, true, false, true, false, false, true, false, false, true, true, false, true, false, false, true, true}, + 11: []bool{false, false, true, false, true, true, true, false, true, true, true, true, true, true, false, true, true, false}, + 12: []bool{false, false, true, true, false, false, false, true, true, true, false, true, true, false, false, false, true, false}, + 13: []bool{false, false, true, true, false, true, true, false, false, false, false, true, false, false, false, true, true, true}, + 14: []bool{false, false, true, true, true, false, false, true, true, false, false, false, false, false, true, true, false, true}, + 15: []bool{false, false, true, true, true, true, true, false, false, true, false, false, true, false, true, false, false, false}, + 16: []bool{false, true, false, false, false, false, true, false, true, true, false, true, true, true, true, false, false, false}, + 17: []bool{false, true, false, false, false, true, false, true, false, false, false, true, false, true, true, true, false, true}, + 18: []bool{false, true, false, false, true, false, true, false, true, false, false, false, false, true, false, true, true, true}, + 19: []bool{false, true, false, false, true, true, false, true, false, true, false, false, true, true, false, false, true, false}, + 20: []bool{false, true, false, true, false, false, true, false, false, true, true, false, true, false, false, true, true, false}, + 21: []bool{false, true, false, true, false, true, false, true, true, false, true, false, false, false, false, false, true, true}, + 22: []bool{false, true, false, true, true, false, true, false, false, false, true, true, false, false, true, false, false, true}, + 23: []bool{false, true, false, true, true, true, false, true, true, true, true, true, true, false, true, true, false, false}, + 24: []bool{false, true, true, false, false, false, true, true, true, false, true, true, false, false, false, true, false, false}, + 25: []bool{false, true, true, false, false, true, false, false, false, true, true, true, true, false, false, false, false, true}, + 26: []bool{false, true, true, false, true, false, true, true, true, true, true, false, true, false, true, false, true, true}, + 27: []bool{false, true, true, false, true, true, false, false, false, false, true, false, false, false, true, true, true, false}, + 28: []bool{false, true, true, true, false, false, true, true, false, false, false, false, false, true, true, false, true, false}, + 29: []bool{false, true, true, true, false, true, false, false, true, true, false, false, true, true, true, true, true, true}, + 30: []bool{false, true, true, true, true, false, true, true, false, true, false, true, true, true, false, true, false, true}, + 31: []bool{false, true, true, true, true, true, false, false, true, false, false, true, false, true, false, false, false, false}, + 32: []bool{true, false, false, false, false, false, true, false, false, true, true, true, false, true, false, true, false, true}, + 33: []bool{true, false, false, false, false, true, false, true, true, false, true, true, true, true, false, false, false, false}, + 34: []bool{true, false, false, false, true, false, true, false, false, false, true, false, true, true, true, false, true, false}, + 35: []bool{true, false, false, false, true, true, false, true, true, true, true, false, false, true, true, true, true, true}, + 36: []bool{true, false, false, true, false, false, true, false, true, true, false, false, false, false, true, false, true, true}, + 37: []bool{true, false, false, true, false, true, false, true, false, false, false, false, true, false, true, true, true, false}, + 38: []bool{true, false, false, true, true, false, true, false, true, false, false, true, true, false, false, true, false, false}, + 39: []bool{true, false, false, true, true, true, false, true, false, true, false, true, false, false, false, false, false, true}, + 40: []bool{true, false, true, false, false, false, true, true, false, false, false, true, true, false, true, false, false, true}, +} + func drawVersionInfo(vi *versionInfo, set func(int, int, bool)) { - var versionInfoBits []bool + versionInfoBits, ok := versionInfoBitsByVersion[vi.Version] - switch vi.Version { - case 7: - versionInfoBits = []bool{false, false, false, true, true, true, true, true, false, false, true, false, false, true, false, true, false, false} - case 8: - versionInfoBits = []bool{false, false, true, false, false, false, false, true, false, true, true, false, true, true, true, true, false, false} - case 9: - versionInfoBits = []bool{false, false, true, false, false, true, true, false, true, false, true, false, false, true, true, false, false, true} - case 10: - versionInfoBits = []bool{false, false, true, false, true, false, false, true, false, false, true, true, false, true, false, false, true, true} - case 11: - versionInfoBits = []bool{false, false, true, false, true, true, true, false, true, true, true, true, true, true, false, true, true, false} - case 12: - versionInfoBits = []bool{false, false, true, true, false, false, false, true, true, true, false, true, true, false, false, false, true, false} - case 13: - versionInfoBits = []bool{false, false, true, true, false, true, true, false, false, false, false, true, false, false, false, true, true, true} - case 14: - versionInfoBits = []bool{false, false, true, true, true, false, false, true, true, false, false, false, false, false, true, true, false, true} - case 15: - versionInfoBits = []bool{false, false, true, true, true, true, true, false, false, true, false, false, true, false, true, false, false, false} - case 16: - versionInfoBits = []bool{false, true, false, false, false, false, true, false, true, true, false, true, true, true, true, false, false, false} - case 17: - versionInfoBits = []bool{false, true, false, false, false, true, false, true, false, false, false, true, false, true, true, true, false, true} - case 18: - versionInfoBits = []bool{false, true, false, false, true, false, true, false, true, false, false, false, false, true, false, true, true, true} - case 19: - versionInfoBits = []bool{false, true, false, false, true, true, false, true, false, true, false, false, true, true, false, false, true, false} - case 20: - versionInfoBits = []bool{false, true, false, true, false, false, true, false, false, true, true, false, true, false, false, true, true, false} - case 21: - versionInfoBits = []bool{false, true, false, true, false, true, false, true, true, false, true, false, false, false, false, false, true, true} - case 22: - versionInfoBits = []bool{false, true, false, true, true, false, true, false, false, false, true, true, false, false, true, false, false, true} - case 23: - versionInfoBits = []bool{false, true, false, true, true, true, false, true, true, true, true, true, true, false, true, true, false, false} - case 24: - versionInfoBits = []bool{false, true, true, false, false, false, true, true, true, false, true, true, false, false, false, true, false, false} - case 25: - versionInfoBits = []bool{false, true, true, false, false, true, false, false, false, true, true, true, true, false, false, false, false, true} - case 26: - versionInfoBits = []bool{false, true, true, false, true, false, true, true, true, true, true, false, true, false, true, false, true, true} - case 27: - versionInfoBits = []bool{false, true, true, false, true, true, false, false, false, false, true, false, false, false, true, true, true, false} - case 28: - versionInfoBits = []bool{false, true, true, true, false, false, true, true, false, false, false, false, false, true, true, false, true, false} - case 29: - versionInfoBits = []bool{false, true, true, true, false, true, false, false, true, true, false, false, true, true, true, true, true, true} - case 30: - versionInfoBits = []bool{false, true, true, true, true, false, true, true, false, true, false, true, true, true, false, true, false, true} - case 31: - versionInfoBits = []bool{false, true, true, true, true, true, false, false, true, false, false, true, false, true, false, false, false, false} - case 32: - versionInfoBits = []bool{true, false, false, false, false, false, true, false, false, true, true, true, false, true, false, true, false, true} - case 33: - versionInfoBits = []bool{true, false, false, false, false, true, false, true, true, false, true, true, true, true, false, false, false, false} - case 34: - versionInfoBits = []bool{true, false, false, false, true, false, true, false, false, false, true, false, true, true, true, false, true, false} - case 35: - versionInfoBits = []bool{true, false, false, false, true, true, false, true, true, true, true, false, false, true, true, true, true, true} - case 36: - versionInfoBits = []bool{true, false, false, true, false, false, true, false, true, true, false, false, false, false, true, false, true, true} - case 37: - versionInfoBits = []bool{true, false, false, true, false, true, false, true, false, false, false, false, true, false, true, true, true, false} - case 38: - versionInfoBits = []bool{true, false, false, true, true, false, true, false, true, false, false, true, true, false, false, true, false, false} - case 39: - versionInfoBits = []bool{true, false, false, true, true, true, false, true, false, true, false, true, false, false, false, false, false, true} - case 40: - versionInfoBits = []bool{true, false, true, false, false, false, true, true, false, false, false, true, true, false, true, false, false, true} - } - - if len(versionInfoBits) > 0 { + if ok && len(versionInfoBits) > 0 { for i := 0; i < len(versionInfoBits); i++ { x := (vi.modulWidth() - 11) + i%3 y := i / 3 diff --git a/qr/encoder_test.go b/qr/encoder_test.go index 9304faf..c45b757 100644 --- a/qr/encoder_test.go +++ b/qr/encoder_test.go @@ -2,13 +2,14 @@ package qr import ( "fmt" - "github.com/boombuler/barcode" "image/png" "os" "testing" + + "github.com/boombuler/barcode" ) -var qrHelloWorldHUni []bool = []bool{true, true, true, true, true, true, true, false, true, false, true, false, true, false, false, false, true, false, true, true, true, true, true, true, true, +var qrHelloWorldHUni = []bool{true, true, true, true, true, true, true, false, true, false, true, false, true, false, false, false, true, false, true, true, true, true, true, true, true, true, false, false, false, false, false, true, false, true, true, false, false, false, true, true, true, false, false, true, false, false, false, false, false, true, true, false, true, true, true, false, true, false, true, false, true, false, true, true, false, true, true, false, true, false, true, true, true, false, true, true, false, true, true, true, false, true, false, false, false, false, true, true, false, true, true, false, false, true, false, true, true, true, false, true, @@ -35,6 +36,35 @@ var qrHelloWorldHUni []bool = []bool{true, true, true, true, true, true, true, f true, true, true, true, true, true, true, false, false, false, false, true, false, false, true, false, true, false, false, true, false, false, true, true, true, } +func Test_GetUnknownEncoder(t *testing.T) { + if unknownEncoding.getEncoder() != nil { + t.Fail() + } +} + +func Test_EncodingStringer(t *testing.T) { + tests := map[Encoding]string{ + Auto: "Auto", + Numeric: "Numeric", + AlphaNumeric: "AlphaNumeric", + Unicode: "Unicode", + unknownEncoding: "", + } + + for enc, str := range tests { + if enc.String() != str { + t.Fail() + } + } +} + +func Test_InvalidEncoding(t *testing.T) { + _, err := Encode("hello world", H, Numeric) + if err == nil { + t.Fail() + } +} + func Test_Encode(t *testing.T) { res, err := Encode("hello world", H, Unicode) if err != nil { diff --git a/qr/errorcorrection.go b/qr/errorcorrection.go index 6b056ba..da7a4bc 100644 --- a/qr/errorcorrection.go +++ b/qr/errorcorrection.go @@ -9,7 +9,7 @@ type errorCorrection struct { polynomes map[byte][]byte } -var ec *errorCorrection = newGF() +var ec = newGF() func newGF() *errorCorrection { return &errorCorrection{utils.NewGaloisField(285), make(map[byte][]byte)} diff --git a/qr/numeric.go b/qr/numeric.go index 2575d7e..49b44cc 100644 --- a/qr/numeric.go +++ b/qr/numeric.go @@ -3,8 +3,9 @@ package qr import ( "errors" "fmt" - "github.com/boombuler/barcode/utils" "strconv" + + "github.com/boombuler/barcode/utils" ) func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { diff --git a/qr/numeric_test.go b/qr/numeric_test.go index 22c6838..21aa9e3 100644 --- a/qr/numeric_test.go +++ b/qr/numeric_test.go @@ -19,4 +19,8 @@ func Test_NumericEncoding(t *testing.T) { if err == nil { t.Error("Numeric encoding should not be able to encode \"foo\"") } + x, vi, err = encode(makeString(14297, "1"), H) + if x != nil || vi != nil || err == nil { + t.Fail() + } } diff --git a/qr/qrcode.go b/qr/qrcode.go index c615675..b7ac26d 100644 --- a/qr/qrcode.go +++ b/qr/qrcode.go @@ -1,11 +1,12 @@ package qr import ( - "github.com/boombuler/barcode" - "github.com/boombuler/barcode/utils" "image" "image/color" "math" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" ) type qrcode struct { @@ -50,16 +51,16 @@ func (qr *qrcode) calcPenalty() uint { } func (qr *qrcode) calcPenaltyRule1() uint { - var result uint = 0 + var result uint for x := 0; x < qr.dimension; x++ { checkForX := false - var cntX uint = 0 + var cntX uint checkForY := false - var cntY uint = 0 + var cntY uint for y := 0; y < qr.dimension; y++ { if qr.Get(x, y) == checkForX { - cntX += 1 + cntX++ } else { checkForX = !checkForX if cntX >= 5 { @@ -69,7 +70,7 @@ func (qr *qrcode) calcPenaltyRule1() uint { } if qr.Get(y, x) == checkForY { - cntY += 1 + cntY++ } else { checkForY = !checkForY if cntY >= 5 { @@ -91,7 +92,7 @@ func (qr *qrcode) calcPenaltyRule1() uint { } func (qr *qrcode) calcPenaltyRule2() uint { - var result uint = 0 + var result uint for x := 0; x < qr.dimension-1; x++ { for y := 0; y < qr.dimension-1; y++ { check := qr.Get(x, y) @@ -104,10 +105,10 @@ func (qr *qrcode) calcPenaltyRule2() uint { } func (qr *qrcode) calcPenaltyRule3() uint { - var pattern1 []bool = []bool{true, false, true, true, true, false, true, false, false, false, false} - var pattern2 []bool = []bool{false, false, false, false, true, false, true, true, true, false, true} + pattern1 := []bool{true, false, true, true, true, false, true, false, false, false, false} + pattern2 := []bool{false, false, false, false, true, false, true, true, true, false, true} - var result uint = 0 + var result uint for x := 0; x <= qr.dimension-len(pattern1); x++ { for y := 0; y < qr.dimension; y++ { pattern1XFound := true @@ -148,7 +149,7 @@ func (qr *qrcode) calcPenaltyRule4() uint { trueCnt := 0 for i := 0; i < totalNum; i++ { if qr.data.GetBit(i) { - trueCnt += 1 + trueCnt++ } } percDark := float64(trueCnt) * 100 / float64(totalNum) diff --git a/qr/unicode.go b/qr/unicode.go index cf418b8..a9135ab 100644 --- a/qr/unicode.go +++ b/qr/unicode.go @@ -2,6 +2,7 @@ package qr import ( "errors" + "github.com/boombuler/barcode/utils" ) diff --git a/qr/unicode_test.go b/qr/unicode_test.go index 1a3da7b..76e5fbf 100644 --- a/qr/unicode_test.go +++ b/qr/unicode_test.go @@ -11,7 +11,7 @@ func Test_UnicodeEncoding(t *testing.T) { if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{64, 20, 16, 236, 17, 236, 17, 236, 17}) != 0 { t.Errorf("\"A\" failed to encode: %s", err) } - _, _, err = encode(makeString(3000), H) + _, _, err = encode(makeString(3000, "A"), H) if err == nil { t.Error("Unicode encoding should not be able to encode a 3kb string") } diff --git a/qr/versioninfo.go b/qr/versioninfo.go index 3653988..6852a57 100644 --- a/qr/versioninfo.go +++ b/qr/versioninfo.go @@ -2,16 +2,17 @@ package qr import "math" +// ErrorCorrectionLevel indicates the amount of "backup data" stored in the QR code type ErrorCorrectionLevel byte const ( - // Recovers 7% of data + // L recovers 7% of data L ErrorCorrectionLevel = iota - // Recovers 15% of data + // M recovers 15% of data M - // Recovers 25% of data + // Q recovers 25% of data Q - // Recovers 30% of data + // H recovers 30% of data H ) @@ -48,7 +49,7 @@ type versionInfo struct { DataCodeWordsPerBlockInGroup2 byte } -var versionInfos []*versionInfo = []*versionInfo{ +var versionInfos = []*versionInfo{ &versionInfo{1, L, 7, 1, 19, 0, 0}, &versionInfo{1, M, 10, 1, 16, 0, 0}, &versionInfo{1, Q, 13, 1, 13, 0, 0}, @@ -218,38 +219,39 @@ func (vi *versionInfo) totalDataBytes() int { } func (vi *versionInfo) charCountBits(m encodingMode) byte { - if m == numericMode { + switch m { + case numericMode: if vi.Version < 10 { return 10 } else if vi.Version < 27 { return 12 - } else { - return 14 } - } else if m == alphaNumericMode { + return 14 + + case alphaNumericMode: if vi.Version < 10 { return 9 } else if vi.Version < 27 { return 11 - } else { - return 13 } - } else if m == byteMode { + return 13 + + case byteMode: if vi.Version < 10 { return 8 - } else { - return 16 } - } else if m == kanjiMode { + return 16 + + case kanjiMode: if vi.Version < 10 { return 8 } else if vi.Version < 27 { return 10 - } else { - return 12 } + return 12 + default: + return 0 } - return 0 } func (vi *versionInfo) modulWidth() int { @@ -261,9 +263,9 @@ func (vi *versionInfo) alignmentPatternPlacements() []int { return make([]int, 0) } - var first int = 6 - var last int = vi.modulWidth() - 7 - var space float64 = float64(last - first) + first := 6 + last := vi.modulWidth() - 7 + space := float64(last - first) count := int(math.Ceil(space/28)) + 1 result := make([]int, count) @@ -281,9 +283,9 @@ func (vi *versionInfo) alignmentPatternPlacements() []int { } if int(frac)%2 == 0 { - step -= 1 + step-- } else { - step += 1 + step++ } } diff --git a/qr/versioninfo_test.go b/qr/versioninfo_test.go index 28f2a2f..f41aa37 100644 --- a/qr/versioninfo_test.go +++ b/qr/versioninfo_test.go @@ -2,7 +2,7 @@ package qr import "testing" -var testvi *versionInfo = &versionInfo{7, M, 0, 1, 10, 2, 5} // Fake versionInfo to run some of the tests +var testvi = &versionInfo{7, M, 0, 1, 10, 2, 5} // Fake versionInfo to run some of the tests func Test_ErrorCorrectionStringer(t *testing.T) { tests := map[ErrorCorrectionLevel]string{ @@ -56,6 +56,9 @@ func Test_CharCountBits(t *testing.T) { if v3.charCountBits(kanjiMode) != 12 { t.Fail() } + if v1.charCountBits(encodingMode(3)) != 0 { + t.Fail() + } } func Test_TotalDataBytes(t *testing.T) { @@ -92,7 +95,7 @@ type aligmnentTest struct { patterns []int } -var allAligmnentTests []*aligmnentTest = []*aligmnentTest{ +var allAligmnentTests = []*aligmnentTest{ &aligmnentTest{1, []int{}}, &aligmnentTest{2, []int{6, 18}}, &aligmnentTest{3, []int{6, 22}},