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 }