encoder.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. setters := cl.IterateSetter()
  32. for _, b := range data {
  33. (<-setters)(b)
  34. }
  35. return cl.Merge()
  36. }
  37. func encodeText(content string) []byte {
  38. var result []byte
  39. input := []byte(content)
  40. for i := 0; i < len(input); {
  41. c := input[i]
  42. i++
  43. if c >= '0' && c <= '9' && i < len(input) && input[i] >= '0' && input[i] <= '9' {
  44. // two numbers...
  45. c2 := input[i]
  46. i++
  47. cw := byte(((c-'0')*10 + (c2 - '0')) + 130)
  48. result = append(result, cw)
  49. } else if c > 127 {
  50. // not correct... needs to be redone later...
  51. result = append(result, 235, c-127)
  52. } else {
  53. result = append(result, c+1)
  54. }
  55. }
  56. return result
  57. }
  58. func addPadding(data []byte, toCount int) []byte {
  59. if len(data) < toCount {
  60. data = append(data, 129)
  61. }
  62. for len(data) < toCount {
  63. R := ((149 * (len(data) + 1)) % 253) + 1
  64. data = append(data, byte((129+R)%254))
  65. }
  66. return data
  67. }