From d0cdae0475382ba458601f96946ae002a8a49038 Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Mon, 11 Aug 2014 11:11:24 +0200 Subject: [PATCH] updated docs and code cleanup --- README.md | 16 +++++ codabar/encoder.go | 13 ++-- code128/encode.go | 7 +- code39/encoder.go | 10 +-- datamatrix/encoder.go | 152 +++++++++++++++++++++--------------------- ean/encoder.go | 9 +-- scaledbarcode.go | 2 +- utils/base1dcode.go | 5 +- utils/bitlist.go | 24 +++---- utils/galoisfield.go | 5 ++ 10 files changed, 137 insertions(+), 106 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..ef1c917 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +##Introduction## +This is a package for GO which can be used to create different types of barcodes. + +##Supported Barcode Types## +* Codabar +* Code 128 +* Code 39 +* EAN 8 +* EAN 13 +* Datamatrix +* QR Codes + +##Documentation## +See [GoDoc](https://godoc.org/github.com/boombuler/barcode) + +To create a barcode use the Encode function from one of the subpackages. diff --git a/codabar/encoder.go b/codabar/encoder.go index 31243fe..dce0ac4 100644 --- a/codabar/encoder.go +++ b/codabar/encoder.go @@ -1,13 +1,15 @@ +// Package codabar can create Codabar barcodes package codabar import ( "fmt" + "regexp" + "github.com/boombuler/barcode" "github.com/boombuler/barcode/utils" - "regexp" ) -var encodingTable map[rune][]bool = map[rune][]bool{ +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}, @@ -30,6 +32,7 @@ var encodingTable map[rune][]bool = map[rune][]bool{ '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, "!") != "!" { @@ -40,11 +43,7 @@ func Encode(content string) (barcode.Barcode, error) { if i > 0 { resBits.AddBit(false) } - bits, ok := encodingTable[r] - if !ok { - return nil, fmt.Errorf("can not encode \"%s\"", content) - } - resBits.AddBit(bits...) + resBits.AddBit(encodingTable[r]...) } return utils.New1DCode("Codabar", content, resBits), nil } diff --git a/code128/encode.go b/code128/encode.go index 50386cf..6c6a927 100644 --- a/code128/encode.go +++ b/code128/encode.go @@ -1,11 +1,13 @@ +// Package code128 can create Code128 barcodes package code128 import ( "fmt" - "github.com/boombuler/barcode" - "github.com/boombuler/barcode/utils" "strings" "unicode/utf8" + + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/utils" ) func strToRunes(str string) []rune { @@ -65,6 +67,7 @@ func getCodeIndexList(content []rune) *utils.BitList { 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 { diff --git a/code39/encoder.go b/code39/encoder.go index 1d596fd..6575c1c 100644 --- a/code39/encoder.go +++ b/code39/encoder.go @@ -1,10 +1,12 @@ +// Package code39 can create Code39 barcodes package code39 import ( "errors" + "strings" + "github.com/boombuler/barcode" "github.com/boombuler/barcode/utils" - "strings" ) type encodeInfo struct { @@ -12,7 +14,7 @@ type encodeInfo struct { data []bool } -var encodeTable map[rune]encodeInfo = map[rune]encodeInfo{ +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}}, @@ -59,7 +61,7 @@ var encodeTable map[rune]encodeInfo = map[rune]encodeInfo{ '*': encodeInfo{-1, []bool{true, false, false, true, false, true, true, false, true, true, false, true}}, } -var extendedTable map[rune]string = map[rune]string{ +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`, @@ -108,7 +110,7 @@ func prepare(content string) (string, error) { return result, nil } -// encodes the given string as a code39 barcode +// 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 { diff --git a/datamatrix/encoder.go b/datamatrix/encoder.go index 63f0752..64a2f16 100644 --- a/datamatrix/encoder.go +++ b/datamatrix/encoder.go @@ -1,75 +1,77 @@ -package datamatrix - -import ( - "errors" - "github.com/boombuler/barcode" -) - -// Encodes the given content as a DataMatrix code -func Encode(content string) (barcode.Barcode, error) { - data := encodeText(content) - - var size *dmCodeSize = nil - 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) - - setters := cl.IterateSetter() - for _, b := range data { - (<-setters)(b) - } - return cl.Merge() -} - -func encodeText(content string) []byte { - result := make([]byte, 0) - 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 -} +// 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) + + setters := cl.IterateSetter() + for _, b := range data { + (<-setters)(b) + } + 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/ean/encoder.go b/ean/encoder.go index 5363bb9..6fc32c0 100644 --- a/ean/encoder.go +++ b/ean/encoder.go @@ -1,8 +1,9 @@ -// package for EAN barcode generation. +// Package ean can create EAN 8 and EAN 13 barcodes. package ean import ( "errors" + "github.com/boombuler/barcode" "github.com/boombuler/barcode/utils" ) @@ -14,7 +15,7 @@ type encodedNumber struct { CheckSum []bool } -var encoderTable map[rune]encodedNumber = map[rune]encodedNumber{ +var encoderTable = map[rune]encodedNumber{ '0': encodedNumber{ []bool{false, false, false, true, true, false, true}, []bool{false, true, false, false, true, true, true}, @@ -170,7 +171,7 @@ func encodeEAN13(code string) *utils.BitList { return result } -// encodes the given EAN 8 or EAN 13 number to a barcode image +// Encode returns a EAN 8 or EAN 13 barcode for the given code func Encode(code string) (barcode.Barcode, error) { if len(code) == 7 || len(code) == 12 { code += string(calcCheckNum(code)) @@ -178,7 +179,7 @@ func Encode(code string) (barcode.Barcode, error) { check := code[0 : len(code)-1] check += string(calcCheckNum(check)) if check != code { - return nil, errors.New("checksum missmatch!") + return nil, errors.New("checksum missmatch") } } diff --git a/scaledbarcode.go b/scaledbarcode.go index cfe427e..0a330ef 100644 --- a/scaledbarcode.go +++ b/scaledbarcode.go @@ -36,7 +36,7 @@ func (bc *scaledBarcode) At(x, y int) color.Color { return bc.wrapperFunc(x, y) } -// returns a resized barcode with the given width and height. +// 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: diff --git a/utils/base1dcode.go b/utils/base1dcode.go index bf4c606..ffd772e 100644 --- a/utils/base1dcode.go +++ b/utils/base1dcode.go @@ -1,9 +1,11 @@ +// Package utils contain some utilities which are needed to create barcodes package utils import ( - "github.com/boombuler/barcode" "image" "image/color" + + "github.com/boombuler/barcode" ) type base1DCode struct { @@ -35,6 +37,7 @@ func (c *base1DCode) At(x, y int) color.Color { return color.White } +// 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) barcode.Barcode { return &base1DCode{bars, codeKind, content} } diff --git a/utils/bitlist.go b/utils/bitlist.go index 04de950..5cdb581 100644 --- a/utils/bitlist.go +++ b/utils/bitlist.go @@ -1,12 +1,12 @@ package utils -// utility class that contains bits +// BitList is a list that contains bits type BitList struct { count int data []int32 } -// returns a new BitList with the given length +// NewBitList returns a new BitList with the given length // all bits are initialize with false func NewBitList(capacity int) *BitList { bl := new(BitList) @@ -19,7 +19,7 @@ func NewBitList(capacity int) *BitList { return bl } -// returns the number of contained bits +// Len returns the number of contained bits func (bl *BitList) Len() int { return bl.count } @@ -37,7 +37,7 @@ func (bl *BitList) grow() { bl.data = nd } -// appends the given bits to the end of the list +// 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 @@ -49,7 +49,7 @@ func (bl *BitList) AddBit(bits ...bool) { } } -// sets the bit at the given index to the given value +// 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) @@ -60,32 +60,32 @@ func (bl *BitList) SetBit(index int, value bool) { } } -// returns the bit at the given index +// 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 } -// appends all 8 bits of the given byte to the end of the list +// 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) } } -// appends the last (LSB) 'count' bits of 'b' the the end of the list +// 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) } } -// returns all bits of the BitList as a []byte +// 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 += 1 + len++ } result := make([]byte, len) for i := 0; i < len; i++ { @@ -95,7 +95,7 @@ func (bl *BitList) GetBytes() []byte { return result } -// iterates through all bytes contained in the BitList +// IterateBytes iterates through all bytes contained in the BitList func (bl *BitList) IterateBytes() <-chan byte { res := make(chan byte) @@ -108,7 +108,7 @@ func (bl *BitList) IterateBytes() <-chan byte { shift -= 8 if shift < 0 { shift = 24 - i += 1 + i++ } c -= 8 } diff --git a/utils/galoisfield.go b/utils/galoisfield.go index 09117d9..6eb6e11 100644 --- a/utils/galoisfield.go +++ b/utils/galoisfield.go @@ -1,10 +1,12 @@ 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 @@ -28,10 +30,12 @@ func NewGaloisField(pp int) *GaloisField { return result } +// 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 @@ -39,6 +43,7 @@ func (gf *GaloisField) Multiply(a, b int) int { 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")