git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/barcode/datamatrix/encoder.go (about)

     1  // Package datamatrix can create Datamatrix barcodes
     2  package datamatrix
     3  
     4  import (
     5  	"errors"
     6  
     7  	"git.sr.ht/~pingoo/stdx/barcode"
     8  )
     9  
    10  // Encode returns a Datamatrix barcode for the given content
    11  func Encode(content string) (barcode.Barcode, error) {
    12  	data := encodeText(content)
    13  
    14  	var size *dmCodeSize
    15  	for _, s := range codeSizes {
    16  		if s.DataCodewords() >= len(data) {
    17  			size = s
    18  			break
    19  		}
    20  	}
    21  	if size == nil {
    22  		return nil, errors.New("to much data to encode")
    23  	}
    24  	data = addPadding(data, size.DataCodewords())
    25  	data = ec.calcECC(data, size)
    26  	code := render(data, size)
    27  	if code != nil {
    28  		code.content = content
    29  		return code, nil
    30  	}
    31  	return nil, errors.New("unable to render barcode")
    32  }
    33  
    34  func render(data []byte, size *dmCodeSize) *datamatrixCode {
    35  	cl := newCodeLayout(size)
    36  
    37  	cl.SetValues(data)
    38  
    39  	return cl.Merge()
    40  }
    41  
    42  func encodeText(content string) []byte {
    43  	var result []byte
    44  	input := []byte(content)
    45  
    46  	for i := 0; i < len(input); {
    47  		c := input[i]
    48  		i++
    49  
    50  		if c >= '0' && c <= '9' && i < len(input) && input[i] >= '0' && input[i] <= '9' {
    51  			// two numbers...
    52  			c2 := input[i]
    53  			i++
    54  			cw := byte(((c-'0')*10 + (c2 - '0')) + 130)
    55  			result = append(result, cw)
    56  		} else if c > 127 {
    57  			// not correct... needs to be redone later...
    58  			result = append(result, 235, c-127)
    59  		} else {
    60  			result = append(result, c+1)
    61  		}
    62  	}
    63  	return result
    64  }
    65  
    66  func addPadding(data []byte, toCount int) []byte {
    67  	if len(data) < toCount {
    68  		data = append(data, 129)
    69  	}
    70  	for len(data) < toCount {
    71  		R := ((149 * (len(data) + 1)) % 253) + 1
    72  		tmp := 129 + R
    73  		if tmp > 254 {
    74  			tmp = tmp - 254
    75  		}
    76  
    77  		data = append(data, byte(tmp))
    78  	}
    79  	return data
    80  }