encoder.go 1.5 KB

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