qrencode.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package libqrencode wraps the C libqrencode library.
  5. // The qr package (in this package's parent directory)
  6. // does not use any C wrapping. This code is here only
  7. // for use during that package's tests.
  8. package libqrencode
  9. /*
  10. #cgo LDFLAGS: -lqrencode
  11. #include <qrencode.h>
  12. */
  13. import "C"
  14. import (
  15. "fmt"
  16. "image"
  17. "image/color"
  18. "unsafe"
  19. )
  20. type Version int
  21. type Mode int
  22. const (
  23. Numeric Mode = C.QR_MODE_NUM
  24. Alphanumeric Mode = C.QR_MODE_AN
  25. EightBit Mode = C.QR_MODE_8
  26. )
  27. type Level int
  28. const (
  29. L Level = C.QR_ECLEVEL_L
  30. M Level = C.QR_ECLEVEL_M
  31. Q Level = C.QR_ECLEVEL_Q
  32. H Level = C.QR_ECLEVEL_H
  33. )
  34. type Pixel int
  35. const (
  36. Black Pixel = 1 << iota
  37. DataECC
  38. Format
  39. PVersion
  40. Timing
  41. Alignment
  42. Finder
  43. NonData
  44. )
  45. type Code struct {
  46. Version int
  47. Width int
  48. Pixel [][]Pixel
  49. Scale int
  50. }
  51. func (*Code) ColorModel() color.Model {
  52. return color.RGBAModel
  53. }
  54. func (c *Code) Bounds() image.Rectangle {
  55. d := (c.Width + 8) * c.Scale
  56. return image.Rect(0, 0, d, d)
  57. }
  58. var (
  59. white color.Color = color.RGBA{0xFF, 0xFF, 0xFF, 0xFF}
  60. black color.Color = color.RGBA{0x00, 0x00, 0x00, 0xFF}
  61. blue color.Color = color.RGBA{0x00, 0x00, 0x80, 0xFF}
  62. red color.Color = color.RGBA{0xFF, 0x40, 0x40, 0xFF}
  63. yellow color.Color = color.RGBA{0xFF, 0xFF, 0x00, 0xFF}
  64. gray color.Color = color.RGBA{0x80, 0x80, 0x80, 0xFF}
  65. green color.Color = color.RGBA{0x22, 0x8B, 0x22, 0xFF}
  66. )
  67. func (c *Code) At(x, y int) color.Color {
  68. x = x/c.Scale - 4
  69. y = y/c.Scale - 4
  70. if 0 <= x && x < c.Width && 0 <= y && y < c.Width {
  71. switch p := c.Pixel[y][x]; {
  72. case p&Black == 0:
  73. // nothing
  74. case p&DataECC != 0:
  75. return black
  76. case p&Format != 0:
  77. return blue
  78. case p&PVersion != 0:
  79. return red
  80. case p&Timing != 0:
  81. return yellow
  82. case p&Alignment != 0:
  83. return gray
  84. case p&Finder != 0:
  85. return green
  86. }
  87. }
  88. return white
  89. }
  90. type Chunk struct {
  91. Mode Mode
  92. Text string
  93. }
  94. func Encode(version Version, level Level, mode Mode, text string) (*Code, error) {
  95. return EncodeChunk(version, level, Chunk{mode, text})
  96. }
  97. func EncodeChunk(version Version, level Level, chunk ...Chunk) (*Code, error) {
  98. qi, err := C.QRinput_new2(C.int(version), C.QRecLevel(level))
  99. if qi == nil {
  100. return nil, fmt.Errorf("QRinput_new2: %v", err)
  101. }
  102. defer C.QRinput_free(qi)
  103. for _, ch := range chunk {
  104. data := []byte(ch.Text)
  105. n, err := C.QRinput_append(qi, C.QRencodeMode(ch.Mode), C.int(len(data)), (*C.uchar)(&data[0]))
  106. if n < 0 {
  107. return nil, fmt.Errorf("QRinput_append %q: %v", data, err)
  108. }
  109. }
  110. qc, err := C.QRcode_encodeInput(qi)
  111. if qc == nil {
  112. return nil, fmt.Errorf("QRinput_encodeInput: %v", err)
  113. }
  114. c := &Code{
  115. Version: int(qc.version),
  116. Width: int(qc.width),
  117. Scale: 16,
  118. }
  119. pix := make([]Pixel, c.Width*c.Width)
  120. cdat := (*[1000 * 1000]byte)(unsafe.Pointer(qc.data))[:len(pix)]
  121. for i := range pix {
  122. pix[i] = Pixel(cdat[i])
  123. }
  124. c.Pixel = make([][]Pixel, c.Width)
  125. for i := range c.Pixel {
  126. c.Pixel[i] = pix[i*c.Width : (i+1)*c.Width]
  127. }
  128. return c, nil
  129. }