Florian Sundermann 11 лет назад
Родитель
Сommit
bccb3d2ede
14 измененных файлов с 196 добавлено и 219 удалено
  1. 2 1
      qr/alphanumeric.go
  2. 4 4
      qr/alphanumeric_test.go
  3. 1 0
      qr/automatic.go
  4. 4 4
      qr/automatic_test.go
  5. 101 168
      qr/encoder.go
  6. 32 2
      qr/encoder_test.go
  7. 1 1
      qr/errorcorrection.go
  8. 2 1
      qr/numeric.go
  9. 4 0
      qr/numeric_test.go
  10. 13 12
      qr/qrcode.go
  11. 1 0
      qr/unicode.go
  12. 1 1
      qr/unicode_test.go
  13. 25 23
      qr/versioninfo.go
  14. 5 2
      qr/versioninfo_test.go

+ 2 - 1
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 $%*+-./:"

+ 4 - 4
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()
 	}

+ 1 - 0
qr/automatic.go

@@ -2,6 +2,7 @@ package qr
 
 import (
 	"fmt"
+
 	"github.com/boombuler/barcode/utils"
 )
 

+ 4 - 4
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 {

+ 101 - 168
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)) {
 	}
 }
 
-func drawVersionInfo(vi *versionInfo, set func(int, int, bool)) {
-	var versionInfoBits []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},
+}
 
-	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}
-	}
+func drawVersionInfo(vi *versionInfo, set func(int, int, bool)) {
+	versionInfoBits, ok := versionInfoBitsByVersion[vi.Version]
 
-	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

+ 32 - 2
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 {

+ 1 - 1
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)}

+ 2 - 1
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) {

+ 4 - 0
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()
+	}
 }

+ 13 - 12
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)

+ 1 - 0
qr/unicode.go

@@ -2,6 +2,7 @@ package qr
 
 import (
 	"errors"
+
 	"github.com/boombuler/barcode/utils"
 )
 

+ 1 - 1
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")
 	}

+ 25 - 23
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++
 			}
 		}
 

+ 5 - 2
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}},