add support for depth in barcode generations

- Introduced depth parameter to EncodeWithDepth function to allow generating barcodes with specified color depth.
- Updated Encode function to use EncodeWithDepth with a default depth of 16.
This commit is contained in:
zhaori96 2024-07-24 10:29:23 -03:00
parent f3630e1cd4
commit 87ab0677e3
15 changed files with 114 additions and 47 deletions

View File

@ -13,10 +13,11 @@ type aztecCode struct {
*utils.BitList *utils.BitList
size int size int
content []byte content []byte
depth int
} }
func newAztecCode(size int) *aztecCode { func newAztecCode(size int, depth int) *aztecCode {
return &aztecCode{utils.NewBitList(size * size), size, nil} return &aztecCode{utils.NewBitList(size * size), size, nil, 16}
} }
func (c *aztecCode) Content() string { func (c *aztecCode) Content() string {
@ -28,7 +29,7 @@ func (c *aztecCode) Metadata() barcode.Metadata {
} }
func (c *aztecCode) ColorModel() color.Model { func (c *aztecCode) ColorModel() color.Model {
return color.Gray16Model return utils.ColorModel(c.depth)
} }
func (c *aztecCode) Bounds() image.Rectangle { func (c *aztecCode) Bounds() image.Rectangle {
@ -37,9 +38,9 @@ func (c *aztecCode) Bounds() image.Rectangle {
func (c *aztecCode) At(x, y int) color.Color { func (c *aztecCode) At(x, y int) color.Color {
if c.GetBit(x*c.size + y) { if c.GetBit(x*c.size + y) {
return color.Black return utils.BlackColor(c.depth)
} }
return color.White return utils.WhiteColor(c.depth)
} }
func (c *aztecCode) set(x, y int) { func (c *aztecCode) set(x, y int) {

View File

@ -123,7 +123,12 @@ func drawBullsEye(matrix *aztecCode, center, size int) {
} }
// Encode returns an aztec barcode with the given content // Encode returns an aztec barcode with the given content
func Encode(data []byte, minECCPercent int, userSpecifiedLayers int) (barcode.Barcode, error) { func Encode(data []byte, minECCPercent int, userSpecifiedLayers int) (barcode.Barcode, error){
return EncodeWithDepth(data, minECCPercent, userSpecifiedLayers, 16)
}
// Encode returns an aztec barcode with the given content
func EncodeWithDepth(data []byte, minECCPercent int, userSpecifiedLayers int, depth int) (barcode.Barcode, error) {
bits := highlevelEncode(data) bits := highlevelEncode(data)
eccBits := ((bits.Len() * minECCPercent) / 100) + 11 eccBits := ((bits.Len() * minECCPercent) / 100) + 11
totalSizeBits := bits.Len() + eccBits totalSizeBits := bits.Len() + eccBits
@ -215,7 +220,7 @@ func Encode(data []byte, minECCPercent int, userSpecifiedLayers int) (barcode.Ba
alignmentMap[origCenter+i] = center + newOffset + 1 alignmentMap[origCenter+i] = center + newOffset + 1
} }
} }
code := newAztecCode(matrixSize) code := newAztecCode(matrixSize, depth)
code.content = data code.content = data
// draw data bits // draw data bits

View File

@ -33,7 +33,7 @@ var encodingTable = map[rune][]bool{
} }
// Encode creates a codabar barcode for the given content // Encode creates a codabar barcode for the given content
func Encode(content string) (barcode.Barcode, error) { func EncodeWithDepth(content string, depth int) (barcode.Barcode, error) {
checkValid, _ := regexp.Compile(`[ABCD][0123456789\-\$\:/\.\+]*[ABCD]$`) checkValid, _ := regexp.Compile(`[ABCD][0123456789\-\$\:/\.\+]*[ABCD]$`)
if content == "!" || checkValid.ReplaceAllString(content, "!") != "!" { if content == "!" || checkValid.ReplaceAllString(content, "!") != "!" {
return nil, fmt.Errorf("can not encode \"%s\"", content) return nil, fmt.Errorf("can not encode \"%s\"", content)
@ -45,5 +45,10 @@ func Encode(content string) (barcode.Barcode, error) {
} }
resBits.AddBit(encodingTable[r]...) resBits.AddBit(encodingTable[r]...)
} }
return utils.New1DCode(barcode.TypeCodabar, content, resBits), nil return utils.New1DCodeWithDepth(barcode.TypeCodabar, content, resBits, depth), nil
}
// Encode creates a codabar barcode for the given content
func Encode(content string) (barcode.Barcode, error) {
return EncodeWithDepth(content, 16)
} }

View File

@ -156,7 +156,7 @@ func getCodeIndexList(content []rune) *utils.BitList {
} }
// Encode creates a Code 128 barcode for the given content // Encode creates a Code 128 barcode for the given content
func Encode(content string) (barcode.BarcodeIntCS, error) { func EncodeWithDepth(content string, depth int) (barcode.BarcodeIntCS, error) {
contentRunes := strToRunes(content) contentRunes := strToRunes(content)
if len(contentRunes) <= 0 || len(contentRunes) > 80 { 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)) return nil, fmt.Errorf("content length should be between 1 and 80 runes but got %d", len(contentRunes))
@ -180,7 +180,12 @@ func Encode(content string) (barcode.BarcodeIntCS, error) {
sum = sum % 103 sum = sum % 103
result.AddBit(encodingTable[sum]...) result.AddBit(encodingTable[sum]...)
result.AddBit(encodingTable[stopSymbol]...) result.AddBit(encodingTable[stopSymbol]...)
return utils.New1DCodeIntCheckSum(barcode.TypeCode128, content, result, sum), nil return utils.New1DCodeIntCheckSumWithDepth(barcode.TypeCode128, content, result, sum, depth), nil
}
// Encode creates a Code 128 barcode for the given content
func Encode(content string) (barcode.BarcodeIntCS, error) {
return EncodeWithDepth(content, 16)
} }
func EncodeWithoutChecksum(content string) (barcode.Barcode, error) { func EncodeWithoutChecksum(content string) (barcode.Barcode, error) {

View File

@ -113,7 +113,7 @@ func prepare(content string) (string, error) {
// Encode returns a code39 barcode for the given content // 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 // 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.BarcodeIntCS, error) { func EncodeWithDepth(content string, includeChecksum bool, fullASCIIMode bool, depth int) (barcode.BarcodeIntCS, error) {
if fullASCIIMode { if fullASCIIMode {
var err error var err error
content, err = prepare(content) content, err = prepare(content)
@ -148,5 +148,11 @@ func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.B
if err != nil { if err != nil {
checkSum = 0 checkSum = 0
} }
return utils.New1DCodeIntCheckSum(barcode.TypeCode39, content, result, int(checkSum)), nil return utils.New1DCodeIntCheckSumWithDepth(barcode.TypeCode39, content, result, int(checkSum), depth), 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.BarcodeIntCS, error) {
return EncodeWithDepth(content, includeChecksum, fullASCIIMode, 16)
} }

View File

@ -74,9 +74,7 @@ func prepare(content string) (string, error) {
return result, nil return result, nil
} }
// Encode returns a code93 barcode for the given content func EncodeWithDepth(content string, includeChecksum bool, fullASCIIMode bool, depth int) (barcode.Barcode, error) {
// if includeChecksum is set to true, two checksum characters are calculated and added to the content
func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.Barcode, error) {
if fullASCIIMode { if fullASCIIMode {
var err error var err error
content, err = prepare(content) content, err = prepare(content)
@ -104,7 +102,13 @@ func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.B
} }
result.AddBit(true) result.AddBit(true)
return utils.New1DCode(barcode.TypeCode93, content, result), nil return utils.New1DCodeWithDepth(barcode.TypeCode93, content, result, depth), nil
}
// Encode returns a code93 barcode for the given content
// if includeChecksum is set to true, two checksum characters are calculated and added to the content
func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.Barcode, error) {
return EncodeWithDepth(content, includeChecksum, fullASCIIMode, 16)
} }
func getChecksum(content string, maxWeight int) rune { func getChecksum(content string, maxWeight int) rune {

View File

@ -11,13 +11,15 @@ type codeLayout struct {
matrix *utils.BitList matrix *utils.BitList
occupy *utils.BitList occupy *utils.BitList
size *dmCodeSize size *dmCodeSize
depth int
} }
func newCodeLayout(size *dmCodeSize) *codeLayout { func newCodeLayout(size *dmCodeSize, depth int) *codeLayout {
result := new(codeLayout) result := new(codeLayout)
result.matrix = utils.NewBitList(size.MatrixColumns() * size.MatrixRows()) result.matrix = utils.NewBitList(size.MatrixColumns() * size.MatrixRows())
result.occupy = utils.NewBitList(size.MatrixColumns() * size.MatrixRows()) result.occupy = utils.NewBitList(size.MatrixColumns() * size.MatrixRows())
result.size = size result.size = size
result.depth = depth
return result return result
} }
@ -159,7 +161,7 @@ func (l *codeLayout) SetValues(data []byte) {
} }
func (l *codeLayout) Merge() *datamatrixCode { func (l *codeLayout) Merge() *datamatrixCode {
result := newDataMatrixCode(l.size) result := newDataMatrixCodeWithDepth(l.size, l.depth)
//dotted horizontal lines //dotted horizontal lines
for r := 0; r < l.size.Rows; r += (l.size.RegionRows() + 2) { for r := 0; r < l.size.Rows; r += (l.size.RegionRows() + 2) {

View File

@ -12,10 +12,15 @@ type datamatrixCode struct {
*utils.BitList *utils.BitList
*dmCodeSize *dmCodeSize
content string content string
depth int
}
func newDataMatrixCodeWithDepth(size *dmCodeSize, depth int) *datamatrixCode {
return &datamatrixCode{utils.NewBitList(size.Rows * size.Columns), size, "", depth}
} }
func newDataMatrixCode(size *dmCodeSize) *datamatrixCode { func newDataMatrixCode(size *dmCodeSize) *datamatrixCode {
return &datamatrixCode{utils.NewBitList(size.Rows * size.Columns), size, ""} return &datamatrixCode{utils.NewBitList(size.Rows * size.Columns), size, "", 16}
} }
func (c *datamatrixCode) Content() string { func (c *datamatrixCode) Content() string {
@ -27,7 +32,7 @@ func (c *datamatrixCode) Metadata() barcode.Metadata {
} }
func (c *datamatrixCode) ColorModel() color.Model { func (c *datamatrixCode) ColorModel() color.Model {
return color.Gray16Model return utils.ColorModel(c.depth)
} }
func (c *datamatrixCode) Bounds() image.Rectangle { func (c *datamatrixCode) Bounds() image.Rectangle {
@ -36,9 +41,9 @@ func (c *datamatrixCode) Bounds() image.Rectangle {
func (c *datamatrixCode) At(x, y int) color.Color { func (c *datamatrixCode) At(x, y int) color.Color {
if c.get(x, y) { if c.get(x, y) {
return color.Black return utils.BlackColor(c.depth)
} }
return color.White return utils.WhiteColor(c.depth)
} }
func (c *datamatrixCode) get(x, y int) bool { func (c *datamatrixCode) get(x, y int) bool {

View File

@ -8,7 +8,7 @@ import (
) )
// Encode returns a Datamatrix barcode for the given content // Encode returns a Datamatrix barcode for the given content
func Encode(content string) (barcode.Barcode, error) { func EncodeWithDepth(content string, depth int) (barcode.Barcode, error) {
data := encodeText(content) data := encodeText(content)
var size *dmCodeSize var size *dmCodeSize
@ -23,7 +23,7 @@ func Encode(content string) (barcode.Barcode, error) {
} }
data = addPadding(data, size.DataCodewords()) data = addPadding(data, size.DataCodewords())
data = ec.calcECC(data, size) data = ec.calcECC(data, size)
code := render(data, size) code := render(data, size, depth)
if code != nil { if code != nil {
code.content = content code.content = content
return code, nil return code, nil
@ -31,8 +31,13 @@ func Encode(content string) (barcode.Barcode, error) {
return nil, errors.New("unable to render barcode") return nil, errors.New("unable to render barcode")
} }
func render(data []byte, size *dmCodeSize) *datamatrixCode { // Encode returns a Datamatrix barcode for the given content
cl := newCodeLayout(size) func Encode(content string) (barcode.Barcode, error) {
return EncodeWithDepth(content, 16)
}
func render(data []byte, size *dmCodeSize, depth int) *datamatrixCode {
cl := newCodeLayout(size, depth)
cl.SetValues(data) cl.SetValues(data)

View File

@ -158,7 +158,7 @@ func encodeEAN13(code string) *utils.BitList {
} }
// Encode returns a EAN 8 or EAN 13 barcode for the given code // Encode returns a EAN 8 or EAN 13 barcode for the given code
func Encode(code string) (barcode.BarcodeIntCS, error) { func EncodeWithDepth(code string, depth int) (barcode.BarcodeIntCS, error) {
var checkSum int var checkSum int
if len(code) == 7 || len(code) == 12 { if len(code) == 7 || len(code) == 12 {
code += string(calcCheckNum(code)) code += string(calcCheckNum(code))
@ -175,13 +175,18 @@ func Encode(code string) (barcode.BarcodeIntCS, error) {
if len(code) == 8 { if len(code) == 8 {
result := encodeEAN8(code) result := encodeEAN8(code)
if result != nil { if result != nil {
return utils.New1DCodeIntCheckSum(barcode.TypeEAN8, code, result, checkSum), nil return utils.New1DCodeIntCheckSumWithDepth(barcode.TypeEAN8, code, result, checkSum, depth), nil
} }
} else if len(code) == 13 { } else if len(code) == 13 {
result := encodeEAN13(code) result := encodeEAN13(code)
if result != nil { if result != nil {
return utils.New1DCodeIntCheckSum(barcode.TypeEAN13, code, result, checkSum), nil return utils.New1DCodeIntCheckSumWithDepth(barcode.TypeEAN13, code, result, checkSum, depth), nil
} }
} }
return nil, errors.New("invalid ean code data") return nil, errors.New("invalid ean code data")
} }
// Encode returns a EAN 8 or EAN 13 barcode for the given code
func Encode(code string) (barcode.BarcodeIntCS, error) {
return EncodeWithDepth(code, 16)
}

View File

@ -15,7 +15,7 @@ const (
// Encodes the given data as PDF417 barcode. // Encodes the given data as PDF417 barcode.
// securityLevel should be between 0 and 8. The higher the number, the more // securityLevel should be between 0 and 8. The higher the number, the more
// additional error-correction codes are added. // additional error-correction codes are added.
func Encode(data string, securityLevel byte) (barcode.Barcode, error) { func EncodeWithDepth(data string, securityLevel byte, depth int) (barcode.Barcode, error) {
if securityLevel >= 9 { if securityLevel >= 9 {
return nil, fmt.Errorf("Invalid security level %d", securityLevel) return nil, fmt.Errorf("Invalid security level %d", securityLevel)
} }
@ -34,6 +34,7 @@ func Encode(data string, securityLevel byte) (barcode.Barcode, error) {
barcode := new(pdfBarcode) barcode := new(pdfBarcode)
barcode.data = data barcode.data = data
barcode.depth = depth
codeWords, err := encodeData(dataWords, columns, sl) codeWords, err := encodeData(dataWords, columns, sl)
if err != nil { if err != nil {
@ -70,6 +71,13 @@ func Encode(data string, securityLevel byte) (barcode.Barcode, error) {
return barcode, nil return barcode, nil
} }
// Encodes the given data as PDF417 barcode.
// securityLevel should be between 0 and 8. The higher the number, the more
// additional error-correction codes are added.
func Encode(data string, securityLevel byte) (barcode.Barcode, error) {
return EncodeWithDepth(data, securityLevel, 16)
}
func encodeData(dataWords []int, columns int, sl securitylevel) ([]int, error) { func encodeData(dataWords []int, columns int, sl securitylevel) ([]int, error) {
dataCount := len(dataWords) dataCount := len(dataWords)

View File

@ -12,6 +12,7 @@ type pdfBarcode struct {
data string data string
width int width int
code *utils.BitList code *utils.BitList
depth int
} }
func (c *pdfBarcode) Metadata() barcode.Metadata { func (c *pdfBarcode) Metadata() barcode.Metadata {
@ -23,7 +24,7 @@ func (c *pdfBarcode) Content() string {
} }
func (c *pdfBarcode) ColorModel() color.Model { func (c *pdfBarcode) ColorModel() color.Model {
return color.Gray16Model return utils.ColorModel(c.depth)
} }
func (c *pdfBarcode) Bounds() image.Rectangle { func (c *pdfBarcode) Bounds() image.Rectangle {
@ -34,7 +35,7 @@ func (c *pdfBarcode) Bounds() image.Rectangle {
func (c *pdfBarcode) At(x, y int) color.Color { func (c *pdfBarcode) At(x, y int) color.Color {
if c.code.GetBit((y/moduleHeight)*c.width + x) { if c.code.GetBit((y/moduleHeight)*c.width + x) {
return color.Black return utils.BlackColor(c.depth)
} }
return color.White return utils.WhiteColor(c.depth)
} }

View File

@ -55,7 +55,7 @@ func (e Encoding) String() string {
} }
// Encode returns a QR barcode with the given content, error correction level and uses the given encoding // 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) { func EncodeWithDepth(content string, level ErrorCorrectionLevel, mode Encoding, depth int) (barcode.Barcode, error) {
bits, vi, err := mode.getEncoder()(content, level) bits, vi, err := mode.getEncoder()(content, level)
if err != nil { if err != nil {
return nil, err return nil, err
@ -63,19 +63,23 @@ func Encode(content string, level ErrorCorrectionLevel, mode Encoding) (barcode.
blocks := splitToBlocks(bits.IterateBytes(), vi) blocks := splitToBlocks(bits.IterateBytes(), vi)
data := blocks.interleave(vi) data := blocks.interleave(vi)
result := render(data, vi) result := render(data, vi, depth)
result.content = content result.content = content
return result, nil return result, nil
} }
func render(data []byte, vi *versionInfo) *qrcode { func Encode(content string, level ErrorCorrectionLevel, mode Encoding) (barcode.Barcode, error) {
return EncodeWithDepth(content, level, mode, 16)
}
func render(data []byte, vi *versionInfo, depth int) *qrcode {
dim := vi.modulWidth() dim := vi.modulWidth()
results := make([]*qrcode, 8) results := make([]*qrcode, 8)
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
results[i] = newBarcode(dim) results[i] = newBarCodeWithDepth(dim, depth)
} }
occupied := newBarcode(dim) occupied := newBarCodeWithDepth(dim, depth)
setAll := func(x int, y int, val bool) { setAll := func(x int, y int, val bool) {
occupied.Set(x, y, true) occupied.Set(x, y, true)

View File

@ -13,6 +13,7 @@ type qrcode struct {
dimension int dimension int
data *utils.BitList data *utils.BitList
content string content string
depth int
} }
func (qr *qrcode) Content() string { func (qr *qrcode) Content() string {
@ -24,7 +25,7 @@ func (qr *qrcode) Metadata() barcode.Metadata {
} }
func (qr *qrcode) ColorModel() color.Model { func (qr *qrcode) ColorModel() color.Model {
return color.Gray16Model return utils.ColorModel(qr.depth)
} }
func (qr *qrcode) Bounds() image.Rectangle { func (qr *qrcode) Bounds() image.Rectangle {
@ -33,9 +34,9 @@ func (qr *qrcode) Bounds() image.Rectangle {
func (qr *qrcode) At(x, y int) color.Color { func (qr *qrcode) At(x, y int) color.Color {
if qr.Get(x, y) { if qr.Get(x, y) {
return color.Black return utils.BlackColor(qr.depth)
} }
return color.White return utils.WhiteColor(qr.depth)
} }
func (qr *qrcode) Get(x, y int) bool { func (qr *qrcode) Get(x, y int) bool {
@ -158,9 +159,14 @@ func (qr *qrcode) calcPenaltyRule4() uint {
return uint(math.Min(floor, ceil) * 10) return uint(math.Min(floor, ceil) * 10)
} }
func newBarcode(dim int) *qrcode { func newBarCodeWithDepth(dim int, depth int) *qrcode {
res := new(qrcode) res := new(qrcode)
res.dimension = dim res.dimension = dim
res.data = utils.NewBitList(dim * dim) res.data = utils.NewBitList(dim * dim)
res.depth = depth
return res return res
} }
func newBarcode(dim int) *qrcode {
return newBarCodeWithDepth(dim, 16)
}

View File

@ -78,8 +78,8 @@ func AddCheckSum(content string) (string, error) {
return content + string(utils.IntToRune(sum%10)), nil return content + string(utils.IntToRune(sum%10)), nil
} }
// Encode creates a codabar barcode for the given content // Encode creates a codabar barcode for the given content and depth
func Encode(content string, interleaved bool) (barcode.Barcode, error) { func EncodeWithDepth(content string, interleaved bool, depth int) (barcode.Barcode, error) {
if content == "" { if content == "" {
return nil, errors.New("content is empty") return nil, errors.New("content is empty")
} }
@ -131,8 +131,13 @@ func Encode(content string, interleaved bool) (barcode.Barcode, error) {
resBits.AddBit(mode.end...) resBits.AddBit(mode.end...)
if interleaved { if interleaved {
return utils.New1DCode(barcode.Type2of5Interleaved, content, resBits), nil return utils.New1DCodeWithDepth(barcode.Type2of5Interleaved, content, resBits, depth), nil
} else { } else {
return utils.New1DCode(barcode.Type2of5, content, resBits), nil return utils.New1DCodeWithDepth(barcode.Type2of5, content, resBits, depth), nil
} }
} }
// Encode creates a codabar barcode for the given content
func Encode(content string, interleaved bool) (barcode.Barcode, error) {
return EncodeWithDepth(content, interleaved, 16)
}