encoder.go 1.6 KB

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