updated docs and code cleanup
This commit is contained in:
parent
bccb3d2ede
commit
d0cdae0475
|
@ -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.
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue