diff options
| author | Felix Hanley <felix@userspace.com.au> | 2016-11-21 15:56:46 +0000 |
|---|---|---|
| committer | Felix Hanley <felix@userspace.com.au> | 2016-11-21 15:56:46 +0000 |
| commit | 411565dc3c87851017376545383d4afa65d9f833 (patch) | |
| tree | 44733ff8242c193a95115b27f9e4e88ad3eadde1 /vendor/github.com/boombuler/barcode | |
| parent | 98da73fe927ee67b62c1f286b0adb649a20c373c (diff) | |
| download | crjw-maps-411565dc3c87851017376545383d4afa65d9f833.tar.gz crjw-maps-411565dc3c87851017376545383d4afa65d9f833.tar.bz2 | |
Add vendor code
Diffstat (limited to 'vendor/github.com/boombuler/barcode')
28 files changed, 2977 insertions, 0 deletions
diff --git a/vendor/github.com/boombuler/barcode/LICENSE b/vendor/github.com/boombuler/barcode/LICENSE new file mode 100644 index 0000000..862b0dd --- /dev/null +++ b/vendor/github.com/boombuler/barcode/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Florian Sundermann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/boombuler/barcode/barcode.go b/vendor/github.com/boombuler/barcode/barcode.go new file mode 100644 index 0000000..7e147f2 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/barcode.go @@ -0,0 +1,21 @@ +package barcode + +import "image" + +// Contains some meta information about a barcode +type Metadata struct { + // the name of the barcode kind + CodeKind string + // contains 1 for 1D barcodes or 2 for 2D barcodes + Dimensions byte +} + +// a rendered and encoded barcode +type Barcode interface { + image.Image + // returns some meta information about the barcode + Metadata() Metadata + // the data that was encoded in this barcode + Content() string + CheckSum() int +} diff --git a/vendor/github.com/boombuler/barcode/codabar/encoder.go b/vendor/github.com/boombuler/barcode/codabar/encoder.go new file mode 100644 index 0000000..69cf1a9 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/codabar/encoder.go @@ -0,0 +1,49 @@ +// Package codabar can create Codabar barcodes +package codabar + +import ( + "fmt" + "regexp" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +var encodingTable = map[rune][]bool{ + '0': []bool{true, false, true, false, true, false, false, true, true}, + '1': []bool{true, false, true, false, true, true, false, false, true}, + '2': []bool{true, false, true, false, false, true, false, true, true}, + '3': []bool{true, true, false, false, true, false, true, false, true}, + '4': []bool{true, false, true, true, false, true, false, false, true}, + '5': []bool{true, true, false, true, false, true, false, false, true}, + '6': []bool{true, false, false, true, false, true, false, true, true}, + '7': []bool{true, false, false, true, false, true, true, false, true}, + '8': []bool{true, false, false, true, true, false, true, false, true}, + '9': []bool{true, true, false, true, false, false, true, false, true}, + '-': []bool{true, false, true, false, false, true, true, false, true}, + '$': []bool{true, false, true, true, false, false, true, false, true}, + ':': []bool{true, true, false, true, false, true, true, false, true, true}, + '/': []bool{true, true, false, true, true, false, true, false, true, true}, + '.': []bool{true, true, false, true, true, false, true, true, false, true}, + '+': []bool{true, false, true, true, false, false, true, true, false, false, true, true}, + 'A': []bool{true, false, true, true, false, false, true, false, false, true}, + 'B': []bool{true, false, true, false, false, true, false, false, true, true}, + 'C': []bool{true, false, false, true, false, false, true, false, true, true}, + 'D': []bool{true, false, true, false, false, true, true, false, false, true}, +} + +// Encode creates a codabar barcode for the given content +func Encode(content string) (barcode.Barcode, error) { + checkValid, _ := regexp.Compile(`[ABCD][0123456789\-\$\:/\.\+]*[ABCD]$`) + if content == "!" || checkValid.ReplaceAllString(content, "!") != "!" { + return nil, fmt.Errorf("can not encode \"%s\"", content) + } + resBits := new(utils.BitList) + for i, r := range content { + if i > 0 { + resBits.AddBit(false) + } + resBits.AddBit(encodingTable[r]...) + } + return utils.New1DCode("Codabar", content, resBits, 0), nil +} diff --git a/vendor/github.com/boombuler/barcode/code128/encode.go b/vendor/github.com/boombuler/barcode/code128/encode.go new file mode 100644 index 0000000..757347e --- /dev/null +++ b/vendor/github.com/boombuler/barcode/code128/encode.go @@ -0,0 +1,130 @@ +// Package code128 can create Code128 barcodes +package code128 + +import ( + "fmt" + "strings" + "unicode/utf8" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +func strToRunes(str string) []rune { + result := make([]rune, utf8.RuneCountInString(str)) + i := 0 + for _, r := range str { + result[i] = r + i++ + } + return result +} + +func shouldUseCTable(nextRunes []rune, curEncoding byte) bool { + requiredDigits := 4 + if curEncoding == startCSymbol { + requiredDigits = 2 + } + if len(nextRunes) < requiredDigits { + return false + } + for i := 0; i < requiredDigits; i++ { + if i%2 == 0 && nextRunes[i] == FNC1 { + requiredDigits++ + if len(nextRunes) < requiredDigits { + return false + } + continue + } + if nextRunes[i] < '0' || nextRunes[i] > '9' { + return false + } + } + return true +} + +func getCodeIndexList(content []rune) *utils.BitList { + result := new(utils.BitList) + curEncoding := byte(0) + for i := 0; i < len(content); i++ { + if shouldUseCTable(content[i:], curEncoding) { + if curEncoding != startCSymbol { + if curEncoding == byte(0) { + result.AddByte(startCSymbol) + } else { + result.AddByte(codeCSymbol) + } + curEncoding = startCSymbol + } + if content[i] == FNC1 { + result.AddByte(102) + } else { + + idx := (content[i] - '0') * 10 + i++ + idx = idx + (content[i] - '0') + result.AddByte(byte(idx)) + } + } else { + if curEncoding != startBSymbol { + if curEncoding == byte(0) { + result.AddByte(startBSymbol) + } else { + result.AddByte(codeBSymbol) + } + curEncoding = startBSymbol + } + var idx int + switch content[i] { + case FNC1: + idx = 102 + break + case FNC2: + idx = 97 + break + case FNC3: + idx = 96 + break + case FNC4: + idx = 100 + break + default: + idx = strings.IndexRune(bTable, content[i]) + break + } + + if idx < 0 { + return nil + } + result.AddByte(byte(idx)) + } + } + return result +} + +// Encode creates a Code 128 barcode for the given content +func Encode(content string) (barcode.Barcode, error) { + contentRunes := strToRunes(content) + if len(contentRunes) <= 0 || len(contentRunes) > 80 { + return nil, fmt.Errorf("content length should be between 1 and 80 runes but got %d", len(contentRunes)) + } + idxList := getCodeIndexList(contentRunes) + + if idxList == nil { + return nil, fmt.Errorf("\"%s\" could not be encoded", content) + } + + result := new(utils.BitList) + sum := 0 + for i, idx := range idxList.GetBytes() { + if i == 0 { + sum = int(idx) + } else { + sum += i * int(idx) + } + result.AddBit(encodingTable[idx]...) + } + result.AddBit(encodingTable[sum%103]...) + result.AddBit(encodingTable[stopSymbol]...) + return utils.New1DCode("Code 128", content, result, sum%103), nil +} diff --git a/vendor/github.com/boombuler/barcode/code128/encodingtable.go b/vendor/github.com/boombuler/barcode/code128/encodingtable.go new file mode 100644 index 0000000..a32b31c --- /dev/null +++ b/vendor/github.com/boombuler/barcode/code128/encodingtable.go @@ -0,0 +1,133 @@ +package code128 + +var encodingTable = [107][]bool{ + []bool{true, true, false, true, true, false, false, true, true, false, false}, + []bool{true, true, false, false, true, true, false, true, true, false, false}, + []bool{true, true, false, false, true, true, false, false, true, true, false}, + []bool{true, false, false, true, false, false, true, true, false, false, false}, + []bool{true, false, false, true, false, false, false, true, true, false, false}, + []bool{true, false, false, false, true, false, false, true, true, false, false}, + []bool{true, false, false, true, true, false, false, true, false, false, false}, + []bool{true, false, false, true, true, false, false, false, true, false, false}, + []bool{true, false, false, false, true, true, false, false, true, false, false}, + []bool{true, true, false, false, true, false, false, true, false, false, false}, + []bool{true, true, false, false, true, false, false, false, true, false, false}, + []bool{true, true, false, false, false, true, false, false, true, false, false}, + []bool{true, false, true, true, false, false, true, true, true, false, false}, + []bool{true, false, false, true, true, false, true, true, true, false, false}, + []bool{true, false, false, true, true, false, false, true, true, true, false}, + []bool{true, false, true, true, true, false, false, true, true, false, false}, + []bool{true, false, false, true, true, true, false, true, true, false, false}, + []bool{true, false, false, true, true, true, false, false, true, true, false}, + []bool{true, true, false, false, true, true, true, false, false, true, false}, + []bool{true, true, false, false, true, false, true, true, true, false, false}, + []bool{true, true, false, false, true, false, false, true, true, true, false}, + []bool{true, true, false, true, true, true, false, false, true, false, false}, + []bool{true, true, false, false, true, true, true, false, true, false, false}, + []bool{true, true, true, false, true, true, false, true, true, true, false}, + []bool{true, true, true, false, true, false, false, true, true, false, false}, + []bool{true, true, true, false, false, true, false, true, true, false, false}, + []bool{true, true, true, false, false, true, false, false, true, true, false}, + []bool{true, true, true, false, true, true, false, false, true, false, false}, + []bool{true, true, true, false, false, true, true, false, true, false, false}, + []bool{true, true, true, false, false, true, true, false, false, true, false}, + []bool{true, true, false, true, true, false, true, true, false, false, false}, + []bool{true, true, false, true, true, false, false, false, true, true, false}, + []bool{true, true, false, false, false, true, true, false, true, true, false}, + []bool{true, false, true, false, false, false, true, true, false, false, false}, + []bool{true, false, false, false, true, false, true, true, false, false, false}, + []bool{true, false, false, false, true, false, false, false, true, true, false}, + []bool{true, false, true, true, false, false, false, true, false, false, false}, + []bool{true, false, false, false, true, true, false, true, false, false, false}, + []bool{true, false, false, false, true, true, false, false, false, true, false}, + []bool{true, true, false, true, false, false, false, true, false, false, false}, + []bool{true, true, false, false, false, true, false, true, false, false, false}, + []bool{true, true, false, false, false, true, false, false, false, true, false}, + []bool{true, false, true, true, false, true, true, true, false, false, false}, + []bool{true, false, true, true, false, false, false, true, true, true, false}, + []bool{true, false, false, false, true, true, false, true, true, true, false}, + []bool{true, false, true, true, true, false, true, true, false, false, false}, + []bool{true, false, true, true, true, false, false, false, true, true, false}, + []bool{true, false, false, false, true, true, true, false, true, true, false}, + []bool{true, true, true, false, true, true, true, false, true, true, false}, + []bool{true, true, false, true, false, false, false, true, true, true, false}, + []bool{true, true, false, false, false, true, false, true, true, true, false}, + []bool{true, true, false, true, true, true, false, true, false, false, false}, + []bool{true, true, false, true, true, true, false, false, false, true, false}, + []bool{true, true, false, true, true, true, false, true, true, true, false}, + []bool{true, true, true, false, true, false, true, true, false, false, false}, + []bool{true, true, true, false, true, false, false, false, true, true, false}, + []bool{true, true, true, false, false, false, true, false, true, true, false}, + []bool{true, true, true, false, true, true, false, true, false, false, false}, + []bool{true, true, true, false, true, true, false, false, false, true, false}, + []bool{true, true, true, false, false, false, true, true, false, true, false}, + []bool{true, true, true, false, true, true, true, true, false, true, false}, + []bool{true, true, false, false, true, false, false, false, false, true, false}, + []bool{true, true, true, true, false, false, false, true, false, true, false}, + []bool{true, false, true, false, false, true, true, false, false, false, false}, + []bool{true, false, true, false, false, false, false, true, true, false, false}, + []bool{true, false, false, true, false, true, true, false, false, false, false}, + []bool{true, false, false, true, false, false, false, false, true, true, false}, + []bool{true, false, false, false, false, true, false, true, true, false, false}, + []bool{true, false, false, false, false, true, false, false, true, true, false}, + []bool{true, false, true, true, false, false, true, false, false, false, false}, + []bool{true, false, true, true, false, false, false, false, true, false, false}, + []bool{true, false, false, true, true, false, true, false, false, false, false}, + []bool{true, false, false, true, true, false, false, false, false, true, false}, + []bool{true, false, false, false, false, true, true, false, true, false, false}, + []bool{true, false, false, false, false, true, true, false, false, true, false}, + []bool{true, true, false, false, false, false, true, false, false, true, false}, + []bool{true, true, false, false, true, false, true, false, false, false, false}, + []bool{true, true, true, true, false, true, true, true, false, true, false}, + []bool{true, true, false, false, false, false, true, false, true, false, false}, + []bool{true, false, false, false, true, true, true, true, false, true, false}, + []bool{true, false, true, false, false, true, true, true, true, false, false}, + []bool{true, false, false, true, false, true, true, true, true, false, false}, + []bool{true, false, false, true, false, false, true, true, true, true, false}, + []bool{true, false, true, true, true, true, false, false, true, false, false}, + []bool{true, false, false, true, true, true, true, false, true, false, false}, + []bool{true, false, false, true, true, true, true, false, false, true, false}, + []bool{true, true, true, true, false, true, false, false, true, false, false}, + []bool{true, true, true, true, false, false, true, false, true, false, false}, + []bool{true, true, true, true, false, false, true, false, false, true, false}, + []bool{true, true, false, true, true, false, true, true, true, true, false}, + []bool{true, true, false, true, true, true, true, false, true, true, false}, + []bool{true, true, true, true, false, true, true, false, true, true, false}, + []bool{true, false, true, false, true, true, true, true, false, false, false}, + []bool{true, false, true, false, false, false, true, true, true, true, false}, + []bool{true, false, false, false, true, false, true, true, true, true, false}, + []bool{true, false, true, true, true, true, false, true, false, false, false}, + []bool{true, false, true, true, true, true, false, false, false, true, false}, + []bool{true, true, true, true, false, true, false, true, false, false, false}, + []bool{true, true, true, true, false, true, false, false, false, true, false}, + []bool{true, false, true, true, true, false, true, true, true, true, false}, + []bool{true, false, true, true, true, true, false, true, true, true, false}, + []bool{true, true, true, false, true, false, true, true, true, true, false}, + []bool{true, true, true, true, false, true, false, true, true, true, false}, + []bool{true, true, false, true, false, false, false, false, true, false, false}, + []bool{true, true, false, true, false, false, true, false, false, false, false}, + []bool{true, true, false, true, false, false, true, true, true, false, false}, + []bool{true, true, false, false, false, true, true, true, false, true, false, true, true}, +} + +// const startASymbol byte = 103 +const startBSymbol byte = 104 +const startCSymbol byte = 105 + +const codeBSymbol byte = 100 +const codeCSymbol byte = 99 + +const stopSymbol byte = 106 + +const ( + // FNC1 - Special Function 1 + FNC1 = '\u00f1' + // FNC2 - Special Function 2 + FNC2 = '\u00f2' + // FNC3 - Special Function 3 + FNC3 = '\u00f3' + // FNC4 - Special Function 4 + FNC4 = '\u00f4' +) + +const bTable = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" diff --git a/vendor/github.com/boombuler/barcode/code39/encoder.go b/vendor/github.com/boombuler/barcode/code39/encoder.go new file mode 100644 index 0000000..669450f --- /dev/null +++ b/vendor/github.com/boombuler/barcode/code39/encoder.go @@ -0,0 +1,152 @@ +// Package code39 can create Code39 barcodes +package code39 + +import ( + "errors" + "strconv" + "strings" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +type encodeInfo struct { + value int + data []bool +} + +var encodeTable = map[rune]encodeInfo{ + '0': encodeInfo{0, []bool{true, false, true, false, false, true, true, false, true, true, false, true}}, + '1': encodeInfo{1, []bool{true, true, false, true, false, false, true, false, true, false, true, true}}, + '2': encodeInfo{2, []bool{true, false, true, true, false, false, true, false, true, false, true, true}}, + '3': encodeInfo{3, []bool{true, true, false, true, true, false, false, true, false, true, false, true}}, + '4': encodeInfo{4, []bool{true, false, true, false, false, true, true, false, true, false, true, true}}, + '5': encodeInfo{5, []bool{true, true, false, true, false, false, true, true, false, true, false, true}}, + '6': encodeInfo{6, []bool{true, false, true, true, false, false, true, true, false, true, false, true}}, + '7': encodeInfo{7, []bool{true, false, true, false, false, true, false, true, true, false, true, true}}, + '8': encodeInfo{8, []bool{true, true, false, true, false, false, true, false, true, true, false, true}}, + '9': encodeInfo{9, []bool{true, false, true, true, false, false, true, false, true, true, false, true}}, + 'A': encodeInfo{10, []bool{true, true, false, true, false, true, false, false, true, false, true, true}}, + 'B': encodeInfo{11, []bool{true, false, true, true, false, true, false, false, true, false, true, true}}, + 'C': encodeInfo{12, []bool{true, true, false, true, true, false, true, false, false, true, false, true}}, + 'D': encodeInfo{13, []bool{true, false, true, false, true, true, false, false, true, false, true, true}}, + 'E': encodeInfo{14, []bool{true, true, false, true, false, true, true, false, false, true, false, true}}, + 'F': encodeInfo{15, []bool{true, false, true, true, false, true, true, false, false, true, false, true}}, + 'G': encodeInfo{16, []bool{true, false, true, false, true, false, false, true, true, false, true, true}}, + 'H': encodeInfo{17, []bool{true, true, false, true, false, true, false, false, true, true, false, true}}, + 'I': encodeInfo{18, []bool{true, false, true, true, false, true, false, false, true, true, false, true}}, + 'J': encodeInfo{19, []bool{true, false, true, false, true, true, false, false, true, true, false, true}}, + 'K': encodeInfo{20, []bool{true, true, false, true, false, true, false, true, false, false, true, true}}, + 'L': encodeInfo{21, []bool{true, false, true, true, false, true, false, true, false, false, true, true}}, + 'M': encodeInfo{22, []bool{true, true, false, true, true, false, true, false, true, false, false, true}}, + 'N': encodeInfo{23, []bool{true, false, true, false, true, true, false, true, false, false, true, true}}, + 'O': encodeInfo{24, []bool{true, true, false, true, false, true, true, false, true, false, false, true}}, + 'P': encodeInfo{25, []bool{true, false, true, true, false, true, true, false, true, false, false, true}}, + 'Q': encodeInfo{26, []bool{true, false, true, false, true, false, true, true, false, false, true, true}}, + 'R': encodeInfo{27, []bool{true, true, false, true, false, true, false, true, true, false, false, true}}, + 'S': encodeInfo{28, []bool{true, false, true, true, false, true, false, true, true, false, false, true}}, + 'T': encodeInfo{29, []bool{true, false, true, false, true, true, false, true, true, false, false, true}}, + 'U': encodeInfo{30, []bool{true, true, false, false, true, false, true, false, true, false, true, true}}, + 'V': encodeInfo{31, []bool{true, false, false, true, true, false, true, false, true, false, true, true}}, + 'W': encodeInfo{32, []bool{true, true, false, false, true, true, false, true, false, true, false, true}}, + 'X': encodeInfo{33, []bool{true, false, false, true, false, true, true, false, true, false, true, true}}, + 'Y': encodeInfo{34, []bool{true, true, false, false, true, false, true, true, false, true, false, true}}, + 'Z': encodeInfo{35, []bool{true, false, false, true, true, false, true, true, false, true, false, true}}, + '-': encodeInfo{36, []bool{true, false, false, true, false, true, false, true, true, false, true, true}}, + '.': encodeInfo{37, []bool{true, true, false, false, true, false, true, false, true, true, false, true}}, + ' ': encodeInfo{38, []bool{true, false, false, true, true, false, true, false, true, true, false, true}}, + '$': encodeInfo{39, []bool{true, false, false, true, false, false, true, false, false, true, false, true}}, + '/': encodeInfo{40, []bool{true, false, false, true, false, false, true, false, true, false, false, true}}, + '+': encodeInfo{41, []bool{true, false, false, true, false, true, false, false, true, false, false, true}}, + '%': encodeInfo{42, []bool{true, false, true, false, false, true, false, false, true, false, false, true}}, + '*': encodeInfo{-1, []bool{true, false, false, true, false, true, true, false, true, true, false, true}}, +} + +var extendedTable = map[rune]string{ + 0: `%U`, 1: `$A`, 2: `$B`, 3: `$C`, 4: `$D`, 5: `$E`, 6: `$F`, 7: `$G`, 8: `$H`, 9: `$I`, 10: `$J`, + 11: `$K`, 12: `$L`, 13: `$M`, 14: `$N`, 15: `$O`, 16: `$P`, 17: `$Q`, 18: `$R`, 19: `$S`, 20: `$T`, + 21: `$U`, 22: `$V`, 23: `$W`, 24: `$X`, 25: `$Y`, 26: `$Z`, 27: `%A`, 28: `%B`, 29: `%C`, 30: `%D`, + 31: `%E`, 33: `/A`, 34: `/B`, 35: `/C`, 36: `/D`, 37: `/E`, 38: `/F`, 39: `/G`, 40: `/H`, 41: `/I`, + 42: `/J`, 43: `/K`, 44: `/L`, 47: `/O`, 58: `/Z`, 59: `%F`, 60: `%G`, 61: `%H`, 62: `%I`, 63: `%J`, + 64: `%V`, 91: `%K`, 92: `%L`, 93: `%M`, 94: `%N`, 95: `%O`, 96: `%W`, 97: `+A`, 98: `+B`, 99: `+C`, + 100: `+D`, 101: `+E`, 102: `+F`, 103: `+G`, 104: `+H`, 105: `+I`, 106: `+J`, 107: `+K`, 108: `+L`, + 109: `+M`, 110: `+N`, 111: `+O`, 112: `+P`, 113: `+Q`, 114: `+R`, 115: `+S`, 116: `+T`, 117: `+U`, + 118: `+V`, 119: `+W`, 120: `+X`, 121: `+Y`, 122: `+Z`, 123: `%P`, 124: `%Q`, 125: `%R`, 126: `%S`, + 127: `%T`, +} + +func getChecksum(content string) string { + sum := 0 + for _, r := range content { + info, ok := encodeTable[r] + if !ok || info.value < 0 { + return "#" + } + + sum += info.value + } + + sum = sum % 43 + for r, v := range encodeTable { + if v.value == sum { + return string(r) + } + } + return "#" +} + +func prepare(content string) (string, error) { + result := "" + for _, r := range content { + if r > 127 { + return "", errors.New("Only ASCII strings can be encoded") + } + val, ok := extendedTable[r] + if ok { + result += val + } else { + result += string([]rune{r}) + } + } + return result, nil +} + +// Encode returns a code39 barcode for the given content +// if includeChecksum is set to true, a checksum character is calculated and added to the content +func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.Barcode, error) { + if fullASCIIMode { + var err error + content, err = prepare(content) + if err != nil { + return nil, err + } + } else if strings.ContainsRune(content, '*') { + return nil, errors.New("invalid data! try full ascii mode") + } + + data := "*" + content + if includeChecksum { + data += getChecksum(content) + } + data += "*" + + result := new(utils.BitList) + + for i, r := range data { + if i != 0 { + result.AddBit(false) + } + + info, ok := encodeTable[r] + if !ok { + return nil, errors.New("invalid data! try full ascii mode") + } + result.AddBit(info.data...) + } + + checkSum, err := strconv.ParseInt(getChecksum(content), 10, 64) + if err != nil { + checkSum = 0 + } + return utils.New1DCode("Code 39", content, result, int(checkSum)), nil +} diff --git a/vendor/github.com/boombuler/barcode/datamatrix/codelayout.go b/vendor/github.com/boombuler/barcode/datamatrix/codelayout.go new file mode 100644 index 0000000..923b135 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/datamatrix/codelayout.go @@ -0,0 +1,213 @@ +package datamatrix
+
+import (
+ "github.com/boombuler/barcode/utils"
+ "strconv"
+)
+
+type setValFunc func(byte)
+
+type codeLayout struct {
+ matrix *utils.BitList
+ occupy *utils.BitList
+ size *dmCodeSize
+}
+
+func newCodeLayout(size *dmCodeSize) *codeLayout {
+ result := new(codeLayout)
+ result.matrix = utils.NewBitList(size.MatrixColumns() * size.MatrixRows())
+ result.occupy = utils.NewBitList(size.MatrixColumns() * size.MatrixRows())
+ result.size = size
+ return result
+}
+
+func (l *codeLayout) Occupied(row, col int) bool {
+ return l.occupy.GetBit(col + row*l.size.MatrixColumns())
+}
+
+func (l *codeLayout) Set(row, col int, value, bitNum byte) {
+ val := ((value >> (7 - bitNum)) & 1) == 1
+ if row < 0 {
+ row += l.size.MatrixRows()
+ col += 4 - ((l.size.MatrixRows() + 4) % 8)
+ }
+ if col < 0 {
+ col += l.size.MatrixColumns()
+ row += 4 - ((l.size.MatrixColumns() + 4) % 8)
+ }
+ if l.Occupied(row, col) {
+ panic("Field already occupied row: " + strconv.Itoa(row) + " col: " + strconv.Itoa(col))
+ }
+
+ l.occupy.SetBit(col+row*l.size.MatrixColumns(), true)
+
+ l.matrix.SetBit(col+row*l.size.MatrixColumns(), val)
+}
+
+func (l *codeLayout) SetSimple(row, col int, value byte) {
+ l.Set(row-2, col-2, value, 0)
+ l.Set(row-2, col-1, value, 1)
+ l.Set(row-1, col-2, value, 2)
+ l.Set(row-1, col-1, value, 3)
+ l.Set(row-1, col-0, value, 4)
+ l.Set(row-0, col-2, value, 5)
+ l.Set(row-0, col-1, value, 6)
+ l.Set(row-0, col-0, value, 7)
+}
+
+func (l *codeLayout) Corner1(value byte) {
+ l.Set(l.size.MatrixRows()-1, 0, value, 0)
+ l.Set(l.size.MatrixRows()-1, 1, value, 1)
+ l.Set(l.size.MatrixRows()-1, 2, value, 2)
+ l.Set(0, l.size.MatrixColumns()-2, value, 3)
+ l.Set(0, l.size.MatrixColumns()-1, value, 4)
+ l.Set(1, l.size.MatrixColumns()-1, value, 5)
+ l.Set(2, l.size.MatrixColumns()-1, value, 6)
+ l.Set(3, l.size.MatrixColumns()-1, value, 7)
+}
+
+func (l *codeLayout) Corner2(value byte) {
+ l.Set(l.size.MatrixRows()-3, 0, value, 0)
+ l.Set(l.size.MatrixRows()-2, 0, value, 1)
+ l.Set(l.size.MatrixRows()-1, 0, value, 2)
+ l.Set(0, l.size.MatrixColumns()-4, value, 3)
+ l.Set(0, l.size.MatrixColumns()-3, value, 4)
+ l.Set(0, l.size.MatrixColumns()-2, value, 5)
+ l.Set(0, l.size.MatrixColumns()-1, value, 6)
+ l.Set(1, l.size.MatrixColumns()-1, value, 7)
+}
+
+func (l *codeLayout) Corner3(value byte) {
+ l.Set(l.size.MatrixRows()-3, 0, value, 0)
+ l.Set(l.size.MatrixRows()-2, 0, value, 1)
+ l.Set(l.size.MatrixRows()-1, 0, value, 2)
+ l.Set(0, l.size.MatrixColumns()-2, value, 3)
+ l.Set(0, l.size.MatrixColumns()-1, value, 4)
+ l.Set(1, l.size.MatrixColumns()-1, value, 5)
+ l.Set(2, l.size.MatrixColumns()-1, value, 6)
+ l.Set(3, l.size.MatrixColumns()-1, value, 7)
+}
+
+func (l *codeLayout) Corner4(value byte) {
+ l.Set(l.size.MatrixRows()-1, 0, value, 0)
+ l.Set(l.size.MatrixRows()-1, l.size.MatrixColumns()-1, value, 1)
+ l.Set(0, l.size.MatrixColumns()-3, value, 2)
+ l.Set(0, l.size.MatrixColumns()-2, value, 3)
+ l.Set(0, l.size.MatrixColumns()-1, value, 4)
+ l.Set(1, l.size.MatrixColumns()-3, value, 5)
+ l.Set(1, l.size.MatrixColumns()-2, value, 6)
+ l.Set(1, l.size.MatrixColumns()-1, value, 7)
+}
+
+func (l *codeLayout) SetValues(data []byte) {
+ idx := 0
+ row := 4
+ col := 0
+
+ for (row < l.size.MatrixRows()) || (col < l.size.MatrixColumns()) {
+ if (row == l.size.MatrixRows()) && (col == 0) {
+ l.Corner1(data[idx])
+ idx++
+ }
+ if (row == l.size.MatrixRows()-2) && (col == 0) && (l.size.MatrixColumns()%4 != 0) {
+ l.Corner2(data[idx])
+ idx++
+ }
+ if (row == l.size.MatrixRows()-2) && (col == 0) && (l.size.MatrixColumns()%8 == 4) {
+ l.Corner3(data[idx])
+ idx++
+ }
+
+ if (row == l.size.MatrixRows()+4) && (col == 2) && (l.size.MatrixColumns()%8 == 0) {
+ l.Corner4(data[idx])
+ idx++
+ }
+
+ for true {
+ if (row < l.size.MatrixRows()) && (col >= 0) && !l.Occupied(row, col) {
+ l.SetSimple(row, col, data[idx])
+ idx++
+ }
+ row -= 2
+ col += 2
+ if (row < 0) || (col >= l.size.MatrixColumns()) {
+ break
+ }
+ }
+ row += 1
+ col += 3
+
+ for true {
+ if (row >= 0) && (col < l.size.MatrixColumns()) && !l.Occupied(row, col) {
+ l.SetSimple(row, col, data[idx])
+ idx++
+ }
+ row += 2
+ col -= 2
+ if (row >= l.size.MatrixRows()) || (col < 0) {
+ break
+ }
+ }
+ row += 3
+ col += 1
+ }
+
+ if !l.Occupied(l.size.MatrixRows()-1, l.size.MatrixColumns()-1) {
+ l.Set(l.size.MatrixRows()-1, l.size.MatrixColumns()-1, 255, 0)
+ l.Set(l.size.MatrixRows()-2, l.size.MatrixColumns()-2, 255, 0)
+ }
+}
+
+func (l *codeLayout) Merge() *datamatrixCode {
+ result := newDataMatrixCode(l.size)
+
+ //dotted horizontal lines
+ for r := 0; r < l.size.Rows; r += (l.size.RegionRows() + 2) {
+ for c := 0; c < l.size.Columns; c += 2 {
+ result.set(c, r, true)
+ }
+ }
+
+ //solid horizontal line
+ for r := l.size.RegionRows() + 1; r < l.size.Rows; r += (l.size.RegionRows() + 2) {
+ for c := 0; c < l.size.Columns; c++ {
+ result.set(c, r, true)
+ }
+ }
+
+ //dotted vertical lines
+ for c := l.size.RegionColumns() + 1; c < l.size.Columns; c += (l.size.RegionColumns() + 2) {
+ for r := 1; r < l.size.Rows; r += 2 {
+ result.set(c, r, true)
+ }
+ }
+
+ //solid vertical line
+ for c := 0; c < l.size.Columns; c += (l.size.RegionColumns() + 2) {
+ for r := 0; r < l.size.Rows; r++ {
+ result.set(c, r, true)
+ }
+ }
+ count := 0
+ for hRegion := 0; hRegion < l.size.RegionCountHorizontal; hRegion++ {
+ for vRegion := 0; vRegion < l.size.RegionCountVertical; vRegion++ {
+ for x := 0; x < l.size.RegionColumns(); x++ {
+ colMatrix := (l.size.RegionColumns() * hRegion) + x
+ colResult := ((2 + l.size.RegionColumns()) * hRegion) + x + 1
+
+ for y := 0; y < l.size.RegionRows(); y++ {
+ rowMatrix := (l.size.RegionRows() * vRegion) + y
+ rowResult := ((2 + l.size.RegionRows()) * vRegion) + y + 1
+ val := l.matrix.GetBit(colMatrix + rowMatrix*l.size.MatrixColumns())
+ if val {
+ count++
+ }
+
+ result.set(colResult, rowResult, val)
+ }
+ }
+ }
+ }
+
+ return result
+}
diff --git a/vendor/github.com/boombuler/barcode/datamatrix/codesize.go b/vendor/github.com/boombuler/barcode/datamatrix/codesize.go new file mode 100644 index 0000000..c63eb8c --- /dev/null +++ b/vendor/github.com/boombuler/barcode/datamatrix/codesize.go @@ -0,0 +1,73 @@ +package datamatrix
+
+type dmCodeSize struct {
+ Rows int
+ Columns int
+ RegionCountHorizontal int
+ RegionCountVertical int
+ ECCCount int
+ BlockCount int
+}
+
+func (s *dmCodeSize) RegionRows() int {
+ return (s.Rows - (s.RegionCountHorizontal * 2)) / s.RegionCountHorizontal
+}
+
+func (s *dmCodeSize) RegionColumns() int {
+ return (s.Columns - (s.RegionCountVertical * 2)) / s.RegionCountVertical
+}
+
+func (s *dmCodeSize) MatrixRows() int {
+ return s.RegionRows() * s.RegionCountHorizontal
+}
+
+func (s *dmCodeSize) MatrixColumns() int {
+ return s.RegionColumns() * s.RegionCountVertical
+}
+
+func (s *dmCodeSize) DataCodewords() int {
+ return ((s.MatrixColumns() * s.MatrixRows()) / 8) - s.ECCCount
+}
+
+func (s *dmCodeSize) DataCodewordsForBlock(idx int) int {
+ if s.Rows == 144 && s.Columns == 144 {
+ // Special Case...
+ if idx < 8 {
+ return 156
+ } else {
+ return 155
+ }
+ }
+ return s.DataCodewords() / s.BlockCount
+}
+
+func (s *dmCodeSize) ErrorCorrectionCodewordsPerBlock() int {
+ return s.ECCCount / s.BlockCount
+}
+
+var codeSizes []*dmCodeSize = []*dmCodeSize{
+ &dmCodeSize{10, 10, 1, 1, 5, 1},
+ &dmCodeSize{12, 12, 1, 1, 7, 1},
+ &dmCodeSize{14, 14, 1, 1, 10, 1},
+ &dmCodeSize{16, 16, 1, 1, 12, 1},
+ &dmCodeSize{18, 18, 1, 1, 14, 1},
+ &dmCodeSize{20, 20, 1, 1, 18, 1},
+ &dmCodeSize{22, 22, 1, 1, 20, 1},
+ &dmCodeSize{24, 24, 1, 1, 24, 1},
+ &dmCodeSize{26, 26, 1, 1, 28, 1},
+ &dmCodeSize{32, 32, 2, 2, 36, 1},
+ &dmCodeSize{36, 36, 2, 2, 42, 1},
+ &dmCodeSize{40, 40, 2, 2, 48, 1},
+ &dmCodeSize{44, 44, 2, 2, 56, 1},
+ &dmCodeSize{48, 48, 2, 2, 68, 1},
+ &dmCodeSize{52, 52, 2, 2, 84, 2},
+ &dmCodeSize{64, 64, 4, 4, 112, 2},
+ &dmCodeSize{72, 72, 4, 4, 144, 4},
+ &dmCodeSize{80, 80, 4, 4, 192, 4},
+ &dmCodeSize{88, 88, 4, 4, 224, 4},
+ &dmCodeSize{96, 96, 4, 4, 272, 4},
+ &dmCodeSize{104, 104, 4, 4, 336, 6},
+ &dmCodeSize{120, 120, 6, 6, 408, 6},
+ &dmCodeSize{132, 132, 6, 6, 496, 8},
+ &dmCodeSize{144, 144, 6, 6, 620, 10},
+}
diff --git a/vendor/github.com/boombuler/barcode/datamatrix/datamatrixcode.go b/vendor/github.com/boombuler/barcode/datamatrix/datamatrixcode.go new file mode 100644 index 0000000..0e60269 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/datamatrix/datamatrixcode.go @@ -0,0 +1,53 @@ +package datamatrix
+
+import (
+ "github.com/boombuler/barcode"
+ "github.com/boombuler/barcode/utils"
+ "image"
+ "image/color"
+)
+
+type datamatrixCode struct {
+ *utils.BitList
+ *dmCodeSize
+ content string
+}
+
+func newDataMatrixCode(size *dmCodeSize) *datamatrixCode {
+ return &datamatrixCode{utils.NewBitList(size.Rows * size.Columns), size, ""}
+}
+
+func (c *datamatrixCode) Content() string {
+ return c.content
+}
+
+func (c *datamatrixCode) Metadata() barcode.Metadata {
+ return barcode.Metadata{"DataMatrix", 2}
+}
+
+func (c *datamatrixCode) ColorModel() color.Model {
+ return color.Gray16Model
+}
+
+func (c *datamatrixCode) Bounds() image.Rectangle {
+ return image.Rect(0, 0, c.Columns, c.Rows)
+}
+
+func (c *datamatrixCode) At(x, y int) color.Color {
+ if c.get(x, y) {
+ return color.Black
+ }
+ return color.White
+}
+
+func (c *datamatrixCode) CheckSum() int {
+ return 0
+}
+
+func (c *datamatrixCode) get(x, y int) bool {
+ return c.GetBit(x*c.Rows + y)
+}
+
+func (c *datamatrixCode) set(x, y int, value bool) {
+ c.SetBit(x*c.Rows+y, value)
+}
diff --git a/vendor/github.com/boombuler/barcode/datamatrix/encoder.go b/vendor/github.com/boombuler/barcode/datamatrix/encoder.go new file mode 100644 index 0000000..b8921dc --- /dev/null +++ b/vendor/github.com/boombuler/barcode/datamatrix/encoder.go @@ -0,0 +1,75 @@ +// Package datamatrix can create Datamatrix barcodes +package datamatrix + +import ( + "errors" + + "github.com/boombuler/barcode" +) + +// Encode returns a Datamatrix barcode for the given content +func Encode(content string) (barcode.Barcode, error) { + data := encodeText(content) + + var size *dmCodeSize + for _, s := range codeSizes { + if s.DataCodewords() >= len(data) { + size = s + break + } + } + if size == nil { + return nil, errors.New("to much data to encode") + } + data = addPadding(data, size.DataCodewords()) + data = ec.calcECC(data, size) + code := render(data, size) + if code != nil { + code.content = content + return code, nil + } + return nil, errors.New("unable to render barcode") +} + +func render(data []byte, size *dmCodeSize) *datamatrixCode { + cl := newCodeLayout(size) + + cl.SetValues(data) + + return cl.Merge() +} + +func encodeText(content string) []byte { + var result []byte + input := []byte(content) + + for i := 0; i < len(input); { + c := input[i] + i++ + + if c >= '0' && c <= '9' && i < len(input) && input[i] >= '0' && input[i] <= '9' { + // two numbers... + c2 := input[i] + i++ + cw := byte(((c-'0')*10 + (c2 - '0')) + 130) + result = append(result, cw) + } else if c > 127 { + // not correct... needs to be redone later... + result = append(result, 235, c-127) + } else { + result = append(result, c+1) + } + } + return result +} + +func addPadding(data []byte, toCount int) []byte { + if len(data) < toCount { + data = append(data, 129) + } + for len(data) < toCount { + R := ((149 * (len(data) + 1)) % 253) + 1 + data = append(data, byte((129+R)%254)) + } + return data +} diff --git a/vendor/github.com/boombuler/barcode/datamatrix/errorcorrection.go b/vendor/github.com/boombuler/barcode/datamatrix/errorcorrection.go new file mode 100644 index 0000000..ef5876b --- /dev/null +++ b/vendor/github.com/boombuler/barcode/datamatrix/errorcorrection.go @@ -0,0 +1,85 @@ +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
+}
diff --git a/vendor/github.com/boombuler/barcode/ean/encoder.go b/vendor/github.com/boombuler/barcode/ean/encoder.go new file mode 100644 index 0000000..d89294f --- /dev/null +++ b/vendor/github.com/boombuler/barcode/ean/encoder.go @@ -0,0 +1,187 @@ +// Package ean can create EAN 8 and EAN 13 barcodes. +package ean + +import ( + "errors" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +type encodedNumber struct { + LeftOdd []bool + LeftEven []bool + Right []bool + CheckSum []bool +} + +var encoderTable = map[rune]encodedNumber{ + '0': encodedNumber{ + []bool{false, false, false, true, true, false, true}, + []bool{false, true, false, false, true, true, true}, + []bool{true, true, true, false, false, true, false}, + []bool{false, false, false, false, false, false}, + }, + '1': encodedNumber{ + []bool{false, false, true, true, false, false, true}, + []bool{false, true, true, false, false, true, true}, + []bool{true, true, false, false, true, true, false}, + []bool{false, false, true, false, true, true}, + }, + '2': encodedNumber{ + []bool{false, false, true, false, false, true, true}, + []bool{false, false, true, true, false, true, true}, + []bool{true, true, false, true, true, false, false}, + []bool{false, false, true, true, false, true}, + }, + '3': encodedNumber{ + []bool{false, true, true, true, true, false, true}, + []bool{false, true, false, false, false, false, true}, + []bool{true, false, false, false, false, true, false}, + []bool{false, false, true, true, true, false}, + }, + '4': encodedNumber{ + []bool{false, true, false, false, false, true, true}, + []bool{false, false, true, true, true, false, true}, + []bool{true, false, true, true, true, false, false}, + []bool{false, true, false, false, true, true}, + }, + '5': encodedNumber{ + []bool{false, true, true, false, false, false, true}, + []bool{false, true, true, true, false, false, true}, + []bool{true, false, false, true, true, true, false}, + []bool{false, true, true, false, false, true}, + }, + '6': encodedNumber{ + []bool{false, true, false, true, true, true, true}, + []bool{false, false, false, false, true, false, true}, + []bool{true, false, true, false, false, false, false}, + []bool{false, true, true, true, false, false}, + }, + '7': encodedNumber{ + []bool{false, true, true, true, false, true, true}, + []bool{false, false, true, false, false, false, true}, + []bool{true, false, false, false, true, false, false}, + []bool{false, true, false, true, false, true}, + }, + '8': encodedNumber{ + []bool{false, true, true, false, true, true, true}, + []bool{false, false, false, true, false, false, true}, + []bool{true, false, false, true, false, false, false}, + []bool{false, true, false, true, true, false}, + }, + '9': encodedNumber{ + []bool{false, false, false, true, false, true, true}, + []bool{false, false, true, false, true, true, true}, + []bool{true, true, true, false, true, false, false}, + []bool{false, true, true, false, true, false}, + }, +} + +func calcCheckNum(code string) rune { + x3 := len(code) == 7 + sum := 0 + for _, r := range code { + curNum := utils.RuneToInt(r) + if curNum < 0 || curNum > 9 { + return 'B' + } + if x3 { + curNum = curNum * 3 + } + x3 = !x3 + sum += curNum + } + + return utils.IntToRune((10 - (sum % 10)) % 10) +} + +func encodeEAN8(code string) *utils.BitList { + result := new(utils.BitList) + result.AddBit(true, false, true) + + for cpos, r := range code { + num, ok := encoderTable[r] + if !ok { + return nil + } + var data []bool + if cpos < 4 { + data = num.LeftOdd + } else { + data = num.Right + } + + if cpos == 4 { + result.AddBit(false, true, false, true, false) + } + result.AddBit(data...) + } + result.AddBit(true, false, true) + + return result +} + +func encodeEAN13(code string) *utils.BitList { + result := new(utils.BitList) + result.AddBit(true, false, true) + + var firstNum []bool + for cpos, r := range code { + num, ok := encoderTable[r] + if !ok { + return nil + } + if cpos == 0 { + firstNum = num.CheckSum + continue + } + + var data []bool + if cpos < 7 { // Left + if firstNum[cpos-1] { + data = num.LeftEven + } else { + data = num.LeftOdd + } + } else { + data = num.Right + } + + if cpos == 7 { + result.AddBit(false, true, false, true, false) + } + result.AddBit(data...) + } + result.AddBit(true, false, true) + return result +} + +// Encode returns a EAN 8 or EAN 13 barcode for the given code +func Encode(code string) (barcode.Barcode, error) { + var checkSum int + if len(code) == 7 || len(code) == 12 { + code += string(calcCheckNum(code)) + checkSum = utils.RuneToInt(calcCheckNum(code)) + } else if len(code) == 8 || len(code) == 13 { + check := code[0 : len(code)-1] + check += string(calcCheckNum(check)) + if check != code { + return nil, errors.New("checksum missmatch") + } + checkSum = utils.RuneToInt(rune(code[len(code)-1])) + } + + if len(code) == 8 { + result := encodeEAN8(code) + if result != nil { + return utils.New1DCode("EAN 8", code, result, checkSum), nil + } + } else if len(code) == 13 { + result := encodeEAN13(code) + if result != nil { + return utils.New1DCode("EAN 13", code, result, checkSum), nil + } + } + return nil, errors.New("invalid ean code data") +} diff --git a/vendor/github.com/boombuler/barcode/qr/alphanumeric.go b/vendor/github.com/boombuler/barcode/qr/alphanumeric.go new file mode 100644 index 0000000..4ded7c8 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/alphanumeric.go @@ -0,0 +1,66 @@ +package qr + +import ( + "errors" + "fmt" + "strings" + + "github.com/boombuler/barcode/utils" +) + +const charSet string = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + +func stringToAlphaIdx(content string) <-chan int { + result := make(chan int) + go func() { + for _, r := range content { + idx := strings.IndexRune(charSet, r) + result <- idx + if idx < 0 { + break + } + } + close(result) + }() + + return result +} + +func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { + + contentLenIsOdd := len(content)%2 == 1 + contentBitCount := (len(content) / 2) * 11 + if contentLenIsOdd { + contentBitCount += 6 + } + vi := findSmallestVersionInfo(ecl, alphaNumericMode, contentBitCount) + if vi == nil { + return nil, nil, errors.New("To much data to encode") + } + + res := new(utils.BitList) + res.AddBits(int(alphaNumericMode), 4) + res.AddBits(len(content), vi.charCountBits(alphaNumericMode)) + + encoder := stringToAlphaIdx(content) + + for idx := 0; idx < len(content)/2; idx++ { + c1 := <-encoder + c2 := <-encoder + if c1 < 0 || c2 < 0 { + return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric) + } + res.AddBits(c1*45+c2, 11) + } + if contentLenIsOdd { + c := <-encoder + if c < 0 { + return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric) + } + res.AddBits(c, 6) + } + + addPaddingAndTerminator(res, vi) + + return res, vi, nil +} diff --git a/vendor/github.com/boombuler/barcode/qr/automatic.go b/vendor/github.com/boombuler/barcode/qr/automatic.go new file mode 100644 index 0000000..e7c5601 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/automatic.go @@ -0,0 +1,23 @@ +package qr + +import ( + "fmt" + + "github.com/boombuler/barcode/utils" +) + +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 + } + bits, vi, _ = AlphaNumeric.getEncoder()(content, ecl) + if bits != nil && vi != nil { + return bits, vi, nil + } + bits, vi, _ = Unicode.getEncoder()(content, ecl) + if bits != nil && vi != nil { + return bits, vi, nil + } + return nil, nil, fmt.Errorf("No encoding found to encode \"%s\"", content) +} diff --git a/vendor/github.com/boombuler/barcode/qr/blocks.go b/vendor/github.com/boombuler/barcode/qr/blocks.go new file mode 100644 index 0000000..d317378 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/blocks.go @@ -0,0 +1,59 @@ +package qr + +type block struct { + data []byte + ecc []byte +} +type blockList []*block + +func splitToBlocks(data <-chan byte, vi *versionInfo) blockList { + result := make(blockList, vi.NumberOfBlocksInGroup1+vi.NumberOfBlocksInGroup2) + + for b := 0; b < int(vi.NumberOfBlocksInGroup1); b++ { + blk := new(block) + blk.data = make([]byte, vi.DataCodeWordsPerBlockInGroup1) + for cw := 0; cw < int(vi.DataCodeWordsPerBlockInGroup1); cw++ { + blk.data[cw] = <-data + } + blk.ecc = ec.calcECC(blk.data, vi.ErrorCorrectionCodewordsPerBlock) + result[b] = blk + } + + for b := 0; b < int(vi.NumberOfBlocksInGroup2); b++ { + blk := new(block) + blk.data = make([]byte, vi.DataCodeWordsPerBlockInGroup2) + for cw := 0; cw < int(vi.DataCodeWordsPerBlockInGroup2); cw++ { + blk.data[cw] = <-data + } + blk.ecc = ec.calcECC(blk.data, vi.ErrorCorrectionCodewordsPerBlock) + result[int(vi.NumberOfBlocksInGroup1)+b] = blk + } + + return result +} + +func (bl blockList) interleave(vi *versionInfo) []byte { + var maxCodewordCount int + if vi.DataCodeWordsPerBlockInGroup1 > vi.DataCodeWordsPerBlockInGroup2 { + maxCodewordCount = int(vi.DataCodeWordsPerBlockInGroup1) + } else { + maxCodewordCount = int(vi.DataCodeWordsPerBlockInGroup2) + } + resultLen := (vi.DataCodeWordsPerBlockInGroup1+vi.ErrorCorrectionCodewordsPerBlock)*vi.NumberOfBlocksInGroup1 + + (vi.DataCodeWordsPerBlockInGroup2+vi.ErrorCorrectionCodewordsPerBlock)*vi.NumberOfBlocksInGroup2 + + result := make([]byte, 0, resultLen) + for i := 0; i < maxCodewordCount; i++ { + for b := 0; b < len(bl); b++ { + if len(bl[b].data) > i { + result = append(result, bl[b].data[i]) + } + } + } + for i := 0; i < int(vi.ErrorCorrectionCodewordsPerBlock); i++ { + for b := 0; b < len(bl); b++ { + result = append(result, bl[b].ecc[i]) + } + } + return result +} diff --git a/vendor/github.com/boombuler/barcode/qr/encoder.go b/vendor/github.com/boombuler/barcode/qr/encoder.go new file mode 100644 index 0000000..2c6ab21 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/encoder.go @@ -0,0 +1,416 @@ +// Package qr can be used to create QR barcodes. +package qr + +import ( + "image" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +type encodeFn func(content string, eccLevel ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) + +// Encoding mode for QR Codes. +type Encoding byte + +const ( + // Auto will choose ths best matching encoding + Auto Encoding = iota + // Numeric encoding only encodes numbers [0-9] + Numeric + // AlphaNumeric encoding only encodes uppercase letters, numbers and [Space], $, %, *, +, -, ., /, : + AlphaNumeric + // Unicode encoding encodes the string as utf-8 + Unicode + // only for testing purpose + unknownEncoding +) + +func (e Encoding) getEncoder() encodeFn { + switch e { + case Auto: + return encodeAuto + case Numeric: + return encodeNumeric + case AlphaNumeric: + return encodeAlphaNumeric + case Unicode: + return encodeUnicode + } + return nil +} + +func (e Encoding) String() string { + switch e { + case Auto: + return "Auto" + case Numeric: + return "Numeric" + case AlphaNumeric: + return "AlphaNumeric" + case Unicode: + return "Unicode" + } + return "" +} + +// 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 + } + + blocks := splitToBlocks(bits.IterateBytes(), vi) + data := blocks.interleave(vi) + result := render(data, vi) + result.content = content + return result, nil +} + +func render(data []byte, vi *versionInfo) *qrcode { + dim := vi.modulWidth() + results := make([]*qrcode, 8) + for i := 0; i < 8; i++ { + results[i] = newBarcode(dim) + } + + occupied := newBarcode(dim) + + setAll := func(x int, y int, val bool) { + occupied.Set(x, y, true) + for i := 0; i < 8; i++ { + results[i].Set(x, y, val) + } + } + + drawFinderPatterns(vi, setAll) + drawAlignmentPatterns(occupied, vi, setAll) + + //Timing Pattern: + var i int + for i = 0; i < dim; i++ { + if !occupied.Get(i, 6) { + setAll(i, 6, i%2 == 0) + } + if !occupied.Get(6, i) { + setAll(6, i, i%2 == 0) + } + } + // Dark Module + setAll(8, dim-8, true) + + drawVersionInfo(vi, setAll) + drawFormatInfo(vi, -1, occupied.Set) + for i := 0; i < 8; i++ { + drawFormatInfo(vi, i, results[i].Set) + } + + // Write the data + var curBitNo int + + for pos := range iterateModules(occupied) { + var curBit bool + if curBitNo < len(data)*8 { + curBit = ((data[curBitNo/8] >> uint(7-(curBitNo%8))) & 1) == 1 + } else { + curBit = false + } + + for i := 0; i < 8; i++ { + setMasked(pos.X, pos.Y, curBit, i, results[i].Set) + } + curBitNo++ + } + + lowestPenalty := ^uint(0) + lowestPenaltyIdx := -1 + for i := 0; i < 8; i++ { + p := results[i].calcPenalty() + if p < lowestPenalty { + lowestPenalty = p + lowestPenaltyIdx = i + } + } + return results[lowestPenaltyIdx] +} + +func setMasked(x, y int, val bool, mask int, set func(int, int, bool)) { + switch mask { + case 0: + val = val != (((y + x) % 2) == 0) + break + case 1: + val = val != ((y % 2) == 0) + break + case 2: + val = val != ((x % 3) == 0) + break + case 3: + val = val != (((y + x) % 3) == 0) + break + case 4: + val = val != (((y/2 + x/3) % 2) == 0) + break + case 5: + val = val != (((y*x)%2)+((y*x)%3) == 0) + break + case 6: + val = val != ((((y*x)%2)+((y*x)%3))%2 == 0) + break + case 7: + val = val != ((((y+x)%2)+((y*x)%3))%2 == 0) + } + set(x, y, val) +} + +func iterateModules(occupied *qrcode) <-chan image.Point { + result := make(chan image.Point) + allPoints := make(chan image.Point) + go func() { + curX := occupied.dimension - 1 + curY := occupied.dimension - 1 + isUpward := true + + for true { + if isUpward { + allPoints <- image.Pt(curX, curY) + allPoints <- image.Pt(curX-1, curY) + curY-- + if curY < 0 { + curY = 0 + curX -= 2 + if curX == 6 { + curX-- + } + if curX < 0 { + break + } + isUpward = false + } + } else { + allPoints <- image.Pt(curX, curY) + allPoints <- image.Pt(curX-1, curY) + curY++ + if curY >= occupied.dimension { + curY = occupied.dimension - 1 + curX -= 2 + if curX == 6 { + curX-- + } + isUpward = true + if curX < 0 { + break + } + } + } + } + + close(allPoints) + }() + go func() { + for pt := range allPoints { + if !occupied.Get(pt.X, pt.Y) { + result <- pt + } + } + close(result) + }() + return result +} + +func drawFinderPatterns(vi *versionInfo, set func(int, int, bool)) { + dim := vi.modulWidth() + drawPattern := func(xoff int, yoff int) { + for x := -1; x < 8; x++ { + for y := -1; y < 8; y++ { + val := (x == 0 || x == 6 || y == 0 || y == 6 || (x > 1 && x < 5 && y > 1 && y < 5)) && (x <= 6 && y <= 6 && x >= 0 && y >= 0) + + if x+xoff >= 0 && x+xoff < dim && y+yoff >= 0 && y+yoff < dim { + set(x+xoff, y+yoff, val) + } + } + } + } + drawPattern(0, 0) + drawPattern(0, dim-7) + drawPattern(dim-7, 0) +} + +func drawAlignmentPatterns(occupied *qrcode, vi *versionInfo, set func(int, int, bool)) { + drawPattern := func(xoff int, yoff int) { + for x := -2; x <= 2; x++ { + for y := -2; y <= 2; y++ { + val := x == -2 || x == 2 || y == -2 || y == 2 || (x == 0 && y == 0) + set(x+xoff, y+yoff, val) + } + } + } + positions := vi.alignmentPatternPlacements() + + for _, x := range positions { + for _, y := range positions { + if occupied.Get(x, y) { + continue + } + drawPattern(x, y) + } + } +} + +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 + + 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 { + dim := vi.modulWidth() + set(0, 8, formatInfo[0]) + set(1, 8, formatInfo[1]) + set(2, 8, formatInfo[2]) + set(3, 8, formatInfo[3]) + set(4, 8, formatInfo[4]) + set(5, 8, formatInfo[5]) + set(7, 8, formatInfo[6]) + set(8, 8, formatInfo[7]) + set(8, 7, formatInfo[8]) + set(8, 5, formatInfo[9]) + set(8, 4, formatInfo[10]) + set(8, 3, formatInfo[11]) + set(8, 2, formatInfo[12]) + set(8, 1, formatInfo[13]) + set(8, 0, formatInfo[14]) + + set(8, dim-1, formatInfo[0]) + set(8, dim-2, formatInfo[1]) + set(8, dim-3, formatInfo[2]) + set(8, dim-4, formatInfo[3]) + set(8, dim-5, formatInfo[4]) + set(8, dim-6, formatInfo[5]) + set(8, dim-7, formatInfo[6]) + set(dim-8, 8, formatInfo[7]) + set(dim-7, 8, formatInfo[8]) + set(dim-6, 8, formatInfo[9]) + set(dim-5, 8, formatInfo[10]) + set(dim-4, 8, formatInfo[11]) + set(dim-3, 8, formatInfo[12]) + set(dim-2, 8, formatInfo[13]) + set(dim-1, 8, formatInfo[14]) + } +} + +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)) { + versionInfoBits, ok := versionInfoBitsByVersion[vi.Version] + + if ok && len(versionInfoBits) > 0 { + for i := 0; i < len(versionInfoBits); i++ { + x := (vi.modulWidth() - 11) + i%3 + y := i / 3 + set(x, y, versionInfoBits[len(versionInfoBits)-i-1]) + set(y, x, versionInfoBits[len(versionInfoBits)-i-1]) + } + } + +} + +func addPaddingAndTerminator(bl *utils.BitList, vi *versionInfo) { + for i := 0; i < 4 && bl.Len() < vi.totalDataBytes()*8; i++ { + bl.AddBit(false) + } + + for bl.Len()%8 != 0 { + bl.AddBit(false) + } + + for i := 0; bl.Len() < vi.totalDataBytes()*8; i++ { + if i%2 == 0 { + bl.AddByte(236) + } else { + bl.AddByte(17) + } + } +} diff --git a/vendor/github.com/boombuler/barcode/qr/errorcorrection.go b/vendor/github.com/boombuler/barcode/qr/errorcorrection.go new file mode 100644 index 0000000..950fa82 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/errorcorrection.go @@ -0,0 +1,54 @@ +package qr + +import ( + "github.com/boombuler/barcode/utils" + "sync" +) + +type errorCorrection struct { + fld *utils.GaloisField + + m *sync.Mutex + polynomes []*utils.GFPoly +} + +var ec = newGF() + +func newGF() *errorCorrection { + fld := utils.NewGaloisField(285) + + return &errorCorrection{fld, + new(sync.Mutex), + []*utils.GFPoly{ + utils.NewGFPoly(fld, []byte{1}), + }, + } +} + +func (ec *errorCorrection) getPolynomial(degree int) *utils.GFPoly { + ec.m.Lock() + defer ec.m.Unlock() + + if degree >= len(ec.polynomes) { + last := ec.polynomes[len(ec.polynomes)-1] + for d := len(ec.polynomes); d <= degree; d++ { + next := last.Multiply(utils.NewGFPoly(ec.fld, []byte{1, byte(ec.fld.ALogTbl[d-1])})) + ec.polynomes = append(ec.polynomes, next) + last = next + } + } + return ec.polynomes[degree] +} + +func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte { + generator := ec.getPolynomial(int(eccCount)) + info := utils.NewGFPoly(ec.fld, data) + info = info.MultByMonominal(int(eccCount), 1) + + _, remainder := info.Divide(generator) + + result := make([]byte, eccCount) + numZero := int(eccCount) - len(remainder.Coefficients) + copy(result[numZero:], remainder.Coefficients) + return result +} diff --git a/vendor/github.com/boombuler/barcode/qr/numeric.go b/vendor/github.com/boombuler/barcode/qr/numeric.go new file mode 100644 index 0000000..49b44cc --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/numeric.go @@ -0,0 +1,56 @@ +package qr + +import ( + "errors" + "fmt" + "strconv" + + "github.com/boombuler/barcode/utils" +) + +func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { + contentBitCount := (len(content) / 3) * 10 + switch len(content) % 3 { + case 1: + contentBitCount += 4 + case 2: + contentBitCount += 7 + } + vi := findSmallestVersionInfo(ecl, numericMode, contentBitCount) + if vi == nil { + return nil, nil, errors.New("To much data to encode") + } + res := new(utils.BitList) + res.AddBits(int(numericMode), 4) + res.AddBits(len(content), vi.charCountBits(numericMode)) + + for pos := 0; pos < len(content); pos += 3 { + var curStr string + if pos+3 <= len(content) { + curStr = content[pos : pos+3] + } else { + curStr = content[pos:] + } + + i, err := strconv.Atoi(curStr) + if err != nil || i < 0 { + return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, Numeric) + } + var bitCnt byte + switch len(curStr) % 3 { + case 0: + bitCnt = 10 + case 1: + bitCnt = 4 + break + case 2: + bitCnt = 7 + break + } + + res.AddBits(i, bitCnt) + } + + addPaddingAndTerminator(res, vi) + return res, vi, nil +} diff --git a/vendor/github.com/boombuler/barcode/qr/qrcode.go b/vendor/github.com/boombuler/barcode/qr/qrcode.go new file mode 100644 index 0000000..ab123ce --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/qrcode.go @@ -0,0 +1,170 @@ +package qr + +import ( + "image" + "image/color" + "math" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +type qrcode struct { + dimension int + data *utils.BitList + content string +} + +func (qr *qrcode) Content() string { + return qr.content +} + +func (qr *qrcode) Metadata() barcode.Metadata { + return barcode.Metadata{"QR Code", 2} +} + +func (qr *qrcode) ColorModel() color.Model { + return color.Gray16Model +} + +func (qr *qrcode) Bounds() image.Rectangle { + return image.Rect(0, 0, qr.dimension, qr.dimension) +} + +func (qr *qrcode) At(x, y int) color.Color { + if qr.Get(x, y) { + return color.Black + } + return color.White +} + +func (qr *qrcode) Get(x, y int) bool { + return qr.data.GetBit(x*qr.dimension + y) +} + +func (qr *qrcode) Set(x, y int, val bool) { + qr.data.SetBit(x*qr.dimension+y, val) +} + +func (qr *qrcode) CheckSum() int { + return 0 +} + +func (qr *qrcode) calcPenalty() uint { + return qr.calcPenaltyRule1() + qr.calcPenaltyRule2() + qr.calcPenaltyRule3() + qr.calcPenaltyRule4() +} + +func (qr *qrcode) calcPenaltyRule1() uint { + var result uint + for x := 0; x < qr.dimension; x++ { + checkForX := false + var cntX uint + checkForY := false + var cntY uint + + for y := 0; y < qr.dimension; y++ { + if qr.Get(x, y) == checkForX { + cntX++ + } else { + checkForX = !checkForX + if cntX >= 5 { + result += cntX - 2 + } + cntX = 1 + } + + if qr.Get(y, x) == checkForY { + cntY++ + } else { + checkForY = !checkForY + if cntY >= 5 { + result += cntY - 2 + } + cntY = 1 + } + } + + if cntX >= 5 { + result += cntX - 2 + } + if cntY >= 5 { + result += cntY - 2 + } + } + + return result +} + +func (qr *qrcode) calcPenaltyRule2() uint { + var result uint + for x := 0; x < qr.dimension-1; x++ { + for y := 0; y < qr.dimension-1; y++ { + check := qr.Get(x, y) + if qr.Get(x, y+1) == check && qr.Get(x+1, y) == check && qr.Get(x+1, y+1) == check { + result += 3 + } + } + } + return result +} + +func (qr *qrcode) calcPenaltyRule3() uint { + 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 + for x := 0; x <= qr.dimension-len(pattern1); x++ { + for y := 0; y < qr.dimension; y++ { + pattern1XFound := true + pattern2XFound := true + pattern1YFound := true + pattern2YFound := true + + for i := 0; i < len(pattern1); i++ { + iv := qr.Get(x+i, y) + if iv != pattern1[i] { + pattern1XFound = false + } + if iv != pattern2[i] { + pattern2XFound = false + } + iv = qr.Get(y, x+i) + if iv != pattern1[i] { + pattern1YFound = false + } + if iv != pattern2[i] { + pattern2YFound = false + } + } + if pattern1XFound || pattern2XFound { + result += 40 + } + if pattern1YFound || pattern2YFound { + result += 40 + } + } + } + + return result +} + +func (qr *qrcode) calcPenaltyRule4() uint { + totalNum := qr.data.Len() + trueCnt := 0 + for i := 0; i < totalNum; i++ { + if qr.data.GetBit(i) { + trueCnt++ + } + } + percDark := float64(trueCnt) * 100 / float64(totalNum) + floor := math.Abs(math.Floor(percDark/5) - 10) + ceil := math.Abs(math.Ceil(percDark/5) - 10) + return uint(math.Min(floor, ceil) * 10) +} + +func newBarcode(dim int) *qrcode { + res := new(qrcode) + res.dimension = dim + res.data = utils.NewBitList(dim * dim) + return res +} diff --git a/vendor/github.com/boombuler/barcode/qr/unicode.go b/vendor/github.com/boombuler/barcode/qr/unicode.go new file mode 100644 index 0000000..a9135ab --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/unicode.go @@ -0,0 +1,27 @@ +package qr + +import ( + "errors" + + "github.com/boombuler/barcode/utils" +) + +func encodeUnicode(content string, ecl ErrorCorrectionLevel) (*utils.BitList, *versionInfo, error) { + data := []byte(content) + + vi := findSmallestVersionInfo(ecl, byteMode, len(data)*8) + if vi == nil { + return nil, nil, errors.New("To much data to encode") + } + + // 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(utils.BitList) + res.AddBits(int(byteMode), 4) + res.AddBits(len(content), vi.charCountBits(byteMode)) + for _, b := range data { + res.AddByte(b) + } + addPaddingAndTerminator(res, vi) + return res, vi, nil +} diff --git a/vendor/github.com/boombuler/barcode/qr/versioninfo.go b/vendor/github.com/boombuler/barcode/qr/versioninfo.go new file mode 100644 index 0000000..6852a57 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/qr/versioninfo.go @@ -0,0 +1,310 @@ +package qr + +import "math" + +// ErrorCorrectionLevel indicates the amount of "backup data" stored in the QR code +type ErrorCorrectionLevel byte + +const ( + // L recovers 7% of data + L ErrorCorrectionLevel = iota + // M recovers 15% of data + M + // Q recovers 25% of data + Q + // H recovers 30% of data + H +) + +func (ecl ErrorCorrectionLevel) String() string { + switch ecl { + case L: + return "L" + case M: + return "M" + case Q: + return "Q" + case H: + return "H" + } + return "unknown" +} + +type encodingMode byte + +const ( + numericMode encodingMode = 1 + alphaNumericMode encodingMode = 2 + byteMode encodingMode = 4 + kanjiMode encodingMode = 8 +) + +type versionInfo struct { + Version byte + Level ErrorCorrectionLevel + ErrorCorrectionCodewordsPerBlock byte + NumberOfBlocksInGroup1 byte + DataCodeWordsPerBlockInGroup1 byte + NumberOfBlocksInGroup2 byte + DataCodeWordsPerBlockInGroup2 byte +} + +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}, + &versionInfo{1, H, 17, 1, 9, 0, 0}, + &versionInfo{2, L, 10, 1, 34, 0, 0}, + &versionInfo{2, M, 16, 1, 28, 0, 0}, + &versionInfo{2, Q, 22, 1, 22, 0, 0}, + &versionInfo{2, H, 28, 1, 16, 0, 0}, + &versionInfo{3, L, 15, 1, 55, 0, 0}, + &versionInfo{3, M, 26, 1, 44, 0, 0}, + &versionInfo{3, Q, 18, 2, 17, 0, 0}, + &versionInfo{3, H, 22, 2, 13, 0, 0}, + &versionInfo{4, L, 20, 1, 80, 0, 0}, + &versionInfo{4, M, 18, 2, 32, 0, 0}, + &versionInfo{4, Q, 26, 2, 24, 0, 0}, + &versionInfo{4, H, 16, 4, 9, 0, 0}, + &versionInfo{5, L, 26, 1, 108, 0, 0}, + &versionInfo{5, M, 24, 2, 43, 0, 0}, + &versionInfo{5, Q, 18, 2, 15, 2, 16}, + &versionInfo{5, H, 22, 2, 11, 2, 12}, + &versionInfo{6, L, 18, 2, 68, 0, 0}, + &versionInfo{6, M, 16, 4, 27, 0, 0}, + &versionInfo{6, Q, 24, 4, 19, 0, 0}, + &versionInfo{6, H, 28, 4, 15, 0, 0}, + &versionInfo{7, L, 20, 2, 78, 0, 0}, + &versionInfo{7, M, 18, 4, 31, 0, 0}, + &versionInfo{7, Q, 18, 2, 14, 4, 15}, + &versionInfo{7, H, 26, 4, 13, 1, 14}, + &versionInfo{8, L, 24, 2, 97, 0, 0}, + &versionInfo{8, M, 22, 2, 38, 2, 39}, + &versionInfo{8, Q, 22, 4, 18, 2, 19}, + &versionInfo{8, H, 26, 4, 14, 2, 15}, + &versionInfo{9, L, 30, 2, 116, 0, 0}, + &versionInfo{9, M, 22, 3, 36, 2, 37}, + &versionInfo{9, Q, 20, 4, 16, 4, 17}, + &versionInfo{9, H, 24, 4, 12, 4, 13}, + &versionInfo{10, L, 18, 2, 68, 2, 69}, + &versionInfo{10, M, 26, 4, 43, 1, 44}, + &versionInfo{10, Q, 24, 6, 19, 2, 20}, + &versionInfo{10, H, 28, 6, 15, 2, 16}, + &versionInfo{11, L, 20, 4, 81, 0, 0}, + &versionInfo{11, M, 30, 1, 50, 4, 51}, + &versionInfo{11, Q, 28, 4, 22, 4, 23}, + &versionInfo{11, H, 24, 3, 12, 8, 13}, + &versionInfo{12, L, 24, 2, 92, 2, 93}, + &versionInfo{12, M, 22, 6, 36, 2, 37}, + &versionInfo{12, Q, 26, 4, 20, 6, 21}, + &versionInfo{12, H, 28, 7, 14, 4, 15}, + &versionInfo{13, L, 26, 4, 107, 0, 0}, + &versionInfo{13, M, 22, 8, 37, 1, 38}, + &versionInfo{13, Q, 24, 8, 20, 4, 21}, + &versionInfo{13, H, 22, 12, 11, 4, 12}, + &versionInfo{14, L, 30, 3, 115, 1, 116}, + &versionInfo{14, M, 24, 4, 40, 5, 41}, + &versionInfo{14, Q, 20, 11, 16, 5, 17}, + &versionInfo{14, H, 24, 11, 12, 5, 13}, + &versionInfo{15, L, 22, 5, 87, 1, 88}, + &versionInfo{15, M, 24, 5, 41, 5, 42}, + &versionInfo{15, Q, 30, 5, 24, 7, 25}, + &versionInfo{15, H, 24, 11, 12, 7, 13}, + &versionInfo{16, L, 24, 5, 98, 1, 99}, + &versionInfo{16, M, 28, 7, 45, 3, 46}, + &versionInfo{16, Q, 24, 15, 19, 2, 20}, + &versionInfo{16, H, 30, 3, 15, 13, 16}, + &versionInfo{17, L, 28, 1, 107, 5, 108}, + &versionInfo{17, M, 28, 10, 46, 1, 47}, + &versionInfo{17, Q, 28, 1, 22, 15, 23}, + &versionInfo{17, H, 28, 2, 14, 17, 15}, + &versionInfo{18, L, 30, 5, 120, 1, 121}, + &versionInfo{18, M, 26, 9, 43, 4, 44}, + &versionInfo{18, Q, 28, 17, 22, 1, 23}, + &versionInfo{18, H, 28, 2, 14, 19, 15}, + &versionInfo{19, L, 28, 3, 113, 4, 114}, + &versionInfo{19, M, 26, 3, 44, 11, 45}, + &versionInfo{19, Q, 26, 17, 21, 4, 22}, + &versionInfo{19, H, 26, 9, 13, 16, 14}, + &versionInfo{20, L, 28, 3, 107, 5, 108}, + &versionInfo{20, M, 26, 3, 41, 13, 42}, + &versionInfo{20, Q, 30, 15, 24, 5, 25}, + &versionInfo{20, H, 28, 15, 15, 10, 16}, + &versionInfo{21, L, 28, 4, 116, 4, 117}, + &versionInfo{21, M, 26, 17, 42, 0, 0}, + &versionInfo{21, Q, 28, 17, 22, 6, 23}, + &versionInfo{21, H, 30, 19, 16, 6, 17}, + &versionInfo{22, L, 28, 2, 111, 7, 112}, + &versionInfo{22, M, 28, 17, 46, 0, 0}, + &versionInfo{22, Q, 30, 7, 24, 16, 25}, + &versionInfo{22, H, 24, 34, 13, 0, 0}, + &versionInfo{23, L, 30, 4, 121, 5, 122}, + &versionInfo{23, M, 28, 4, 47, 14, 48}, + &versionInfo{23, Q, 30, 11, 24, 14, 25}, + &versionInfo{23, H, 30, 16, 15, 14, 16}, + &versionInfo{24, L, 30, 6, 117, 4, 118}, + &versionInfo{24, M, 28, 6, 45, 14, 46}, + &versionInfo{24, Q, 30, 11, 24, 16, 25}, + &versionInfo{24, H, 30, 30, 16, 2, 17}, + &versionInfo{25, L, 26, 8, 106, 4, 107}, + &versionInfo{25, M, 28, 8, 47, 13, 48}, + &versionInfo{25, Q, 30, 7, 24, 22, 25}, + &versionInfo{25, H, 30, 22, 15, 13, 16}, + &versionInfo{26, L, 28, 10, 114, 2, 115}, + &versionInfo{26, M, 28, 19, 46, 4, 47}, + &versionInfo{26, Q, 28, 28, 22, 6, 23}, + &versionInfo{26, H, 30, 33, 16, 4, 17}, + &versionInfo{27, L, 30, 8, 122, 4, 123}, + &versionInfo{27, M, 28, 22, 45, 3, 46}, + &versionInfo{27, Q, 30, 8, 23, 26, 24}, + &versionInfo{27, H, 30, 12, 15, 28, 16}, + &versionInfo{28, L, 30, 3, 117, 10, 118}, + &versionInfo{28, M, 28, 3, 45, 23, 46}, + &versionInfo{28, Q, 30, 4, 24, 31, 25}, + &versionInfo{28, H, 30, 11, 15, 31, 16}, + &versionInfo{29, L, 30, 7, 116, 7, 117}, + &versionInfo{29, M, 28, 21, 45, 7, 46}, + &versionInfo{29, Q, 30, 1, 23, 37, 24}, + &versionInfo{29, H, 30, 19, 15, 26, 16}, + &versionInfo{30, L, 30, 5, 115, 10, 116}, + &versionInfo{30, M, 28, 19, 47, 10, 48}, + &versionInfo{30, Q, 30, 15, 24, 25, 25}, + &versionInfo{30, H, 30, 23, 15, 25, 16}, + &versionInfo{31, L, 30, 13, 115, 3, 116}, + &versionInfo{31, M, 28, 2, 46, 29, 47}, + &versionInfo{31, Q, 30, 42, 24, 1, 25}, + &versionInfo{31, H, 30, 23, 15, 28, 16}, + &versionInfo{32, L, 30, 17, 115, 0, 0}, + &versionInfo{32, M, 28, 10, 46, 23, 47}, + &versionInfo{32, Q, 30, 10, 24, 35, 25}, + &versionInfo{32, H, 30, 19, 15, 35, 16}, + &versionInfo{33, L, 30, 17, 115, 1, 116}, + &versionInfo{33, M, 28, 14, 46, 21, 47}, + &versionInfo{33, Q, 30, 29, 24, 19, 25}, + &versionInfo{33, H, 30, 11, 15, 46, 16}, + &versionInfo{34, L, 30, 13, 115, 6, 116}, + &versionInfo{34, M, 28, 14, 46, 23, 47}, + &versionInfo{34, Q, 30, 44, 24, 7, 25}, + &versionInfo{34, H, 30, 59, 16, 1, 17}, + &versionInfo{35, L, 30, 12, 121, 7, 122}, + &versionInfo{35, M, 28, 12, 47, 26, 48}, + &versionInfo{35, Q, 30, 39, 24, 14, 25}, + &versionInfo{35, H, 30, 22, 15, 41, 16}, + &versionInfo{36, L, 30, 6, 121, 14, 122}, + &versionInfo{36, M, 28, 6, 47, 34, 48}, + &versionInfo{36, Q, 30, 46, 24, 10, 25}, + &versionInfo{36, H, 30, 2, 15, 64, 16}, + &versionInfo{37, L, 30, 17, 122, 4, 123}, + &versionInfo{37, M, 28, 29, 46, 14, 47}, + &versionInfo{37, Q, 30, 49, 24, 10, 25}, + &versionInfo{37, H, 30, 24, 15, 46, 16}, + &versionInfo{38, L, 30, 4, 122, 18, 123}, + &versionInfo{38, M, 28, 13, 46, 32, 47}, + &versionInfo{38, Q, 30, 48, 24, 14, 25}, + &versionInfo{38, H, 30, 42, 15, 32, 16}, + &versionInfo{39, L, 30, 20, 117, 4, 118}, + &versionInfo{39, M, 28, 40, 47, 7, 48}, + &versionInfo{39, Q, 30, 43, 24, 22, 25}, + &versionInfo{39, H, 30, 10, 15, 67, 16}, + &versionInfo{40, L, 30, 19, 118, 6, 119}, + &versionInfo{40, M, 28, 18, 47, 31, 48}, + &versionInfo{40, Q, 30, 34, 24, 34, 25}, + &versionInfo{40, H, 30, 20, 15, 61, 16}, +} + +func (vi *versionInfo) totalDataBytes() int { + g1Data := int(vi.NumberOfBlocksInGroup1) * int(vi.DataCodeWordsPerBlockInGroup1) + g2Data := int(vi.NumberOfBlocksInGroup2) * int(vi.DataCodeWordsPerBlockInGroup2) + return (g1Data + g2Data) +} + +func (vi *versionInfo) charCountBits(m encodingMode) byte { + switch m { + case numericMode: + if vi.Version < 10 { + return 10 + } else if vi.Version < 27 { + return 12 + } + return 14 + + case alphaNumericMode: + if vi.Version < 10 { + return 9 + } else if vi.Version < 27 { + return 11 + } + return 13 + + case byteMode: + if vi.Version < 10 { + return 8 + } + return 16 + + case kanjiMode: + if vi.Version < 10 { + return 8 + } else if vi.Version < 27 { + return 10 + } + return 12 + default: + return 0 + } +} + +func (vi *versionInfo) modulWidth() int { + return ((int(vi.Version) - 1) * 4) + 21 +} + +func (vi *versionInfo) alignmentPatternPlacements() []int { + if vi.Version == 1 { + return make([]int, 0) + } + + first := 6 + last := vi.modulWidth() - 7 + space := float64(last - first) + count := int(math.Ceil(space/28)) + 1 + + result := make([]int, count) + result[0] = first + result[len(result)-1] = last + if count > 2 { + step := int(math.Ceil(float64(last-first) / float64(count-1))) + if step%2 == 1 { + frac := float64(last-first) / float64(count-1) + _, x := math.Modf(frac) + if x >= 0.5 { + frac = math.Ceil(frac) + } else { + frac = math.Floor(frac) + } + + if int(frac)%2 == 0 { + step-- + } else { + step++ + } + } + + for i := 1; i <= count-2; i++ { + result[i] = last - (step * (count - 1 - i)) + } + } + + return result +} + +func findSmallestVersionInfo(ecl ErrorCorrectionLevel, mode encodingMode, dataBits int) *versionInfo { + dataBits = dataBits + 4 // mode indicator + for _, vi := range versionInfos { + if vi.Level == ecl { + if (vi.totalDataBytes() * 8) >= (dataBits + int(vi.charCountBits(mode))) { + return vi + } + } + } + return nil +} diff --git a/vendor/github.com/boombuler/barcode/scaledbarcode.go b/vendor/github.com/boombuler/barcode/scaledbarcode.go new file mode 100644 index 0000000..c59c9fe --- /dev/null +++ b/vendor/github.com/boombuler/barcode/scaledbarcode.go @@ -0,0 +1,115 @@ +package barcode + +import ( + "errors" + "fmt" + "image" + "image/color" + "math" +) + +type wrapFunc func(x, y int) color.Color + +type scaledBarcode struct { + wrapped Barcode + wrapperFunc wrapFunc + rect image.Rectangle +} + +func (bc *scaledBarcode) Content() string { + return bc.wrapped.Content() +} + +func (bc *scaledBarcode) Metadata() Metadata { + return bc.wrapped.Metadata() +} + +func (bc *scaledBarcode) ColorModel() color.Model { + return bc.wrapped.ColorModel() +} + +func (bc *scaledBarcode) Bounds() image.Rectangle { + return bc.rect +} + +func (bc *scaledBarcode) At(x, y int) color.Color { + return bc.wrapperFunc(x, y) +} + +func (bc *scaledBarcode) CheckSum() int { + return bc.wrapped.CheckSum() +} + +// Scale returns a resized barcode with the given width and height. +func Scale(bc Barcode, width, height int) (Barcode, error) { + switch bc.Metadata().Dimensions { + case 1: + return scale1DCode(bc, width, height) + case 2: + return scale2DCode(bc, width, height) + } + + return nil, errors.New("unsupported barcode format") +} + +func scale2DCode(bc Barcode, width, height int) (Barcode, error) { + orgBounds := bc.Bounds() + orgWidth := orgBounds.Max.X - orgBounds.Min.X + orgHeight := orgBounds.Max.Y - orgBounds.Min.Y + + factor := int(math.Min(float64(width)/float64(orgWidth), float64(height)/float64(orgHeight))) + if factor <= 0 { + return nil, fmt.Errorf("can not scale barcode to an image smaller then %dx%d", orgWidth, orgHeight) + } + + offsetX := (width - (orgWidth * factor)) / 2 + offsetY := (height - (orgHeight * factor)) / 2 + + wrap := func(x, y int) color.Color { + if x < offsetX || y < offsetY { + return color.White + } + x = (x - offsetX) / factor + y = (y - offsetY) / factor + if x >= orgWidth || y >= orgHeight { + return color.White + } + return bc.At(x, y) + } + + return &scaledBarcode{ + bc, + wrap, + image.Rect(0, 0, width, height), + }, nil +} + +func scale1DCode(bc Barcode, width, height int) (Barcode, error) { + orgBounds := bc.Bounds() + orgWidth := orgBounds.Max.X - orgBounds.Min.X + factor := int(float64(width) / float64(orgWidth)) + + if factor <= 0 { + return nil, fmt.Errorf("can not scale barcode to an image smaller then %dx1", orgWidth) + } + offsetX := (width - (orgWidth * factor)) / 2 + + wrap := func(x, y int) color.Color { + if x < offsetX { + return color.White + } + x = (x - offsetX) / factor + + if x >= orgWidth { + return color.White + } + return bc.At(x, 0) + } + + return &scaledBarcode{ + bc, + wrap, + image.Rect(0, 0, width, height), + }, nil + +} diff --git a/vendor/github.com/boombuler/barcode/twooffive/encoder.go b/vendor/github.com/boombuler/barcode/twooffive/encoder.go new file mode 100644 index 0000000..de3ae97 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/twooffive/encoder.go @@ -0,0 +1,138 @@ +// Package twooffive can create interleaved and standard "2 of 5" barcodes. +package twooffive + +import ( + "errors" + "fmt" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" +) + +const patternWidth = 5 + +type pattern [patternWidth]bool +type encodeInfo struct { + start []bool + end []bool + widths map[bool]int +} + +var ( + encodingTable = map[rune]pattern{ + '0': pattern{false, false, true, true, false}, + '1': pattern{true, false, false, false, true}, + '2': pattern{false, true, false, false, true}, + '3': pattern{true, true, false, false, false}, + '4': pattern{false, false, true, false, true}, + '5': pattern{true, false, true, false, false}, + '6': pattern{false, true, true, false, false}, + '7': pattern{false, false, false, true, true}, + '8': pattern{true, false, false, true, false}, + '9': pattern{false, true, false, true, false}, + } + + modes = map[bool]encodeInfo{ + false: encodeInfo{ // non-interleaved + start: []bool{true, true, false, true, true, false, true, false}, + end: []bool{true, true, false, true, false, true, true}, + widths: map[bool]int{ + true: 3, + false: 1, + }, + }, + true: encodeInfo{ // interleaved + start: []bool{true, false, true, false}, + end: []bool{true, true, false, true}, + widths: map[bool]int{ + true: 2, + false: 1, + }, + }, + } + nonInterleavedSpace = pattern{false, false, false, false, false} +) + +// AddCheckSum calculates the correct check-digit and appends it to the given content. +func AddCheckSum(content string) (string, error) { + if content == "" { + return "", errors.New("content is empty") + } + + even := len(content)%2 == 1 + sum := 0 + for _, r := range content { + if _, ok := encodingTable[r]; ok { + value := utils.RuneToInt(r) + if even { + sum += value * 3 + } else { + sum += value + } + even = !even + } else { + return "", fmt.Errorf("can not encode \"%s\"", content) + } + } + + return content + string(utils.IntToRune(sum%10)), nil +} + +// Encode creates a codabar barcode for the given content +func Encode(content string, interleaved bool) (barcode.Barcode, error) { + if content == "" { + return nil, errors.New("content is empty") + } + + if interleaved && len(content)%2 == 1 { + return nil, errors.New("can only encode even number of digits in interleaved mode") + } + + mode := modes[interleaved] + resBits := new(utils.BitList) + resBits.AddBit(mode.start...) + + var lastRune *rune + for _, r := range content { + var a, b pattern + if interleaved { + if lastRune == nil { + lastRune = new(rune) + *lastRune = r + continue + } else { + var o1, o2 bool + a, o1 = encodingTable[*lastRune] + b, o2 = encodingTable[r] + if !o1 || !o2 { + return nil, fmt.Errorf("can not encode \"%s\"", content) + } + lastRune = nil + } + } else { + var ok bool + a, ok = encodingTable[r] + if !ok { + return nil, fmt.Errorf("can not encode \"%s\"", content) + } + b = nonInterleavedSpace + } + + for i := 0; i < patternWidth; i++ { + for x := 0; x < mode.widths[a[i]]; x++ { + resBits.AddBit(true) + } + for x := 0; x < mode.widths[b[i]]; x++ { + resBits.AddBit(false) + } + } + } + + resBits.AddBit(mode.end...) + + kindTxt := "" + if interleaved { + kindTxt = " (interleaved)" + } + return utils.New1DCode("2 of 5"+kindTxt, content, resBits, -1), nil +} diff --git a/vendor/github.com/boombuler/barcode/utils/base1dcode.go b/vendor/github.com/boombuler/barcode/utils/base1dcode.go new file mode 100644 index 0000000..22a2e30 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/utils/base1dcode.go @@ -0,0 +1,48 @@ +// Package utils contain some utilities which are needed to create barcodes +package utils + +import ( + "image" + "image/color" + + "github.com/boombuler/barcode" +) + +type base1DCode struct { + *BitList + kind string + content string + checksum int +} + +func (c *base1DCode) Content() string { + return c.content +} + +func (c *base1DCode) Metadata() barcode.Metadata { + return barcode.Metadata{c.kind, 1} +} + +func (c *base1DCode) ColorModel() color.Model { + return color.Gray16Model +} + +func (c *base1DCode) Bounds() image.Rectangle { + return image.Rect(0, 0, c.Len(), 1) +} + +func (c *base1DCode) At(x, y int) color.Color { + if c.GetBit(x) { + return color.Black + } + return color.White +} + +func (c *base1DCode) CheckSum() int { + return c.checksum +} + +// New1DCode creates a new 1D barcode where the bars are represented by the bits in the bars BitList +func New1DCode(codeKind, content string, bars *BitList, checksum int) barcode.Barcode { + return &base1DCode{bars, codeKind, content, checksum} +} diff --git a/vendor/github.com/boombuler/barcode/utils/bitlist.go b/vendor/github.com/boombuler/barcode/utils/bitlist.go new file mode 100644 index 0000000..5cdb581 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/utils/bitlist.go @@ -0,0 +1,119 @@ +package utils + +// BitList is a list that contains bits +type BitList struct { + count int + data []int32 +} + +// NewBitList returns a new BitList with the given length +// all bits are initialize with false +func NewBitList(capacity int) *BitList { + bl := new(BitList) + bl.count = capacity + x := 0 + if capacity%32 != 0 { + x = 1 + } + bl.data = make([]int32, capacity/32+x) + return bl +} + +// Len returns the number of contained bits +func (bl *BitList) Len() int { + return bl.count +} + +func (bl *BitList) grow() { + growBy := len(bl.data) + if growBy < 128 { + growBy = 128 + } else if growBy >= 1024 { + growBy = 1024 + } + + nd := make([]int32, len(bl.data)+growBy) + copy(nd, bl.data) + bl.data = nd +} + +// AddBit appends the given bits to the end of the list +func (bl *BitList) AddBit(bits ...bool) { + for _, bit := range bits { + itmIndex := bl.count / 32 + for itmIndex >= len(bl.data) { + bl.grow() + } + bl.SetBit(bl.count, bit) + bl.count++ + } +} + +// SetBit sets the bit at the given index to the given value +func (bl *BitList) SetBit(index int, value bool) { + itmIndex := index / 32 + itmBitShift := 31 - (index % 32) + if value { + bl.data[itmIndex] = bl.data[itmIndex] | 1<<uint(itmBitShift) + } else { + bl.data[itmIndex] = bl.data[itmIndex] & ^(1 << uint(itmBitShift)) + } +} + +// GetBit returns the bit at the given index +func (bl *BitList) GetBit(index int) bool { + itmIndex := index / 32 + itmBitShift := 31 - (index % 32) + return ((bl.data[itmIndex] >> uint(itmBitShift)) & 1) == 1 +} + +// AddByte appends all 8 bits of the given byte to the end of the list +func (bl *BitList) AddByte(b byte) { + for i := 7; i >= 0; i-- { + bl.AddBit(((b >> uint(i)) & 1) == 1) + } +} + +// AddBits appends the last (LSB) 'count' bits of 'b' the the end of the list +func (bl *BitList) AddBits(b int, count byte) { + for i := int(count - 1); i >= 0; i-- { + bl.AddBit(((b >> uint(i)) & 1) == 1) + } +} + +// GetBytes returns all bits of the BitList as a []byte +func (bl *BitList) GetBytes() []byte { + len := bl.count >> 3 + if (bl.count % 8) != 0 { + len++ + } + result := make([]byte, len) + for i := 0; i < len; i++ { + shift := (3 - (i % 4)) * 8 + result[i] = (byte)((bl.data[i/4] >> uint(shift)) & 0xFF) + } + return result +} + +// IterateBytes iterates through all bytes contained in the BitList +func (bl *BitList) IterateBytes() <-chan byte { + res := make(chan byte) + + go func() { + c := bl.count + shift := 24 + i := 0 + for c > 0 { + res <- byte((bl.data[i] >> uint(shift)) & 0xFF) + shift -= 8 + if shift < 0 { + shift = 24 + i++ + } + c -= 8 + } + close(res) + }() + + return res +} diff --git a/vendor/github.com/boombuler/barcode/utils/galoisfield.go b/vendor/github.com/boombuler/barcode/utils/galoisfield.go new file mode 100644 index 0000000..6f077d7 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/utils/galoisfield.go @@ -0,0 +1,62 @@ +package utils + +// GaloisField encapsulates galois field arithmetics +type GaloisField struct { + ALogTbl []int + LogTbl []int +} + +// NewGaloisField creates a new falois field +func NewGaloisField(pp int) *GaloisField { + result := new(GaloisField) + fldSize := 256 + + result.ALogTbl = make([]int, fldSize) + result.LogTbl = make([]int, fldSize) + + x := 1 + for i := 0; i < fldSize; i++ { + result.ALogTbl[i] = x + x = x * 2 + if x >= fldSize { + x = (x ^ pp) & (fldSize - 1) + } + } + + for i := 0; i < fldSize; i++ { + result.LogTbl[result.ALogTbl[i]] = int(i) + } + + return result +} + +func (gf *GaloisField) Zero() *GFPoly { + return NewGFPoly(gf, []byte{0}) +} + +// AddOrSub add or substract two numbers +func (gf *GaloisField) AddOrSub(a, b int) int { + return a ^ b +} + +// Multiply multiplys two numbers +func (gf *GaloisField) Multiply(a, b int) int { + if a == 0 || b == 0 { + return 0 + } + return gf.ALogTbl[(gf.LogTbl[a]+gf.LogTbl[b])%255] +} + +// Divide divides two numbers +func (gf *GaloisField) Divide(a, b int) int { + if b == 0 { + panic("divide by zero") + } else if a == 0 { + return 0 + } + return gf.ALogTbl[(gf.LogTbl[a]-gf.LogTbl[b])%255] +} + +func (gf *GaloisField) Invers(num int) int { + return gf.ALogTbl[255-gf.LogTbl[num]] +} diff --git a/vendor/github.com/boombuler/barcode/utils/gfpoly.go b/vendor/github.com/boombuler/barcode/utils/gfpoly.go new file mode 100644 index 0000000..54686de --- /dev/null +++ b/vendor/github.com/boombuler/barcode/utils/gfpoly.go @@ -0,0 +1,103 @@ +package utils + +type GFPoly struct { + gf *GaloisField + Coefficients []byte +} + +func (gp *GFPoly) Degree() int { + return len(gp.Coefficients) - 1 +} + +func (gp *GFPoly) Zero() bool { + return gp.Coefficients[0] == 0 +} + +// GetCoefficient returns the coefficient of x ^ degree +func (gp *GFPoly) GetCoefficient(degree int) byte { + return gp.Coefficients[gp.Degree()-degree] +} + +func (gp *GFPoly) AddOrSubstract(other *GFPoly) *GFPoly { + if gp.Zero() { + return other + } else if other.Zero() { + return gp + } + smallCoeff := gp.Coefficients + largeCoeff := other.Coefficients + if len(smallCoeff) > len(largeCoeff) { + largeCoeff, smallCoeff = smallCoeff, largeCoeff + } + sumDiff := make([]byte, len(largeCoeff)) + lenDiff := len(largeCoeff) - len(smallCoeff) + copy(sumDiff, largeCoeff[:lenDiff]) + for i := lenDiff; i < len(largeCoeff); i++ { + sumDiff[i] = byte(gp.gf.AddOrSub(int(smallCoeff[i-lenDiff]), int(largeCoeff[i]))) + } + return NewGFPoly(gp.gf, sumDiff) +} + +func (gp *GFPoly) MultByMonominal(degree int, coeff byte) *GFPoly { + if coeff == 0 { + return gp.gf.Zero() + } + size := len(gp.Coefficients) + result := make([]byte, size+degree) + for i := 0; i < size; i++ { + result[i] = byte(gp.gf.Multiply(int(gp.Coefficients[i]), int(coeff))) + } + return NewGFPoly(gp.gf, result) +} + +func (gp *GFPoly) Multiply(other *GFPoly) *GFPoly { + if gp.Zero() || other.Zero() { + return gp.gf.Zero() + } + aCoeff := gp.Coefficients + aLen := len(aCoeff) + bCoeff := other.Coefficients + bLen := len(bCoeff) + product := make([]byte, aLen+bLen-1) + for i := 0; i < aLen; i++ { + ac := int(aCoeff[i]) + for j := 0; j < bLen; j++ { + bc := int(bCoeff[j]) + product[i+j] = byte(gp.gf.AddOrSub(int(product[i+j]), gp.gf.Multiply(ac, bc))) + } + } + return NewGFPoly(gp.gf, product) +} + +func (gp *GFPoly) Divide(other *GFPoly) (quotient *GFPoly, remainder *GFPoly) { + quotient = gp.gf.Zero() + remainder = gp + fld := gp.gf + denomLeadTerm := other.GetCoefficient(other.Degree()) + inversDenomLeadTerm := fld.Invers(int(denomLeadTerm)) + for remainder.Degree() >= other.Degree() && !remainder.Zero() { + degreeDiff := remainder.Degree() - other.Degree() + scale := byte(fld.Multiply(int(remainder.GetCoefficient(remainder.Degree())), inversDenomLeadTerm)) + term := other.MultByMonominal(degreeDiff, scale) + itQuot := NewMonominalPoly(fld, degreeDiff, scale) + quotient = quotient.AddOrSubstract(itQuot) + remainder = remainder.AddOrSubstract(term) + } + return +} + +func NewMonominalPoly(field *GaloisField, degree int, coeff byte) *GFPoly { + if coeff == 0 { + return field.Zero() + } + result := make([]byte, degree+1) + result[0] = coeff + return NewGFPoly(field, result) +} + +func NewGFPoly(field *GaloisField, coefficients []byte) *GFPoly { + for len(coefficients) > 1 && coefficients[0] == 0 { + coefficients = coefficients[1:] + } + return &GFPoly{field, coefficients} +} diff --git a/vendor/github.com/boombuler/barcode/utils/runeint.go b/vendor/github.com/boombuler/barcode/utils/runeint.go new file mode 100644 index 0000000..d2e5e61 --- /dev/null +++ b/vendor/github.com/boombuler/barcode/utils/runeint.go @@ -0,0 +1,19 @@ +package utils + +// RuneToInt converts a rune between '0' and '9' to an integer between 0 and 9 +// If the rune is outside of this range -1 is returned. +func RuneToInt(r rune) int { + if r >= '0' && r <= '9' { + return int(r - '0') + } + return -1 +} + +// IntToRune converts a digit 0 - 9 to the rune '0' - '9'. If the given int is outside +// of this range 'F' is returned! +func IntToRune(i int) rune { + if i >= 0 && i <= 9 { + return rune(i + '0') + } + return 'F' +} |
