backend.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package main
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "image"
  6. "image/png"
  7. "log"
  8. "net"
  9. "os"
  10. "strings"
  11. "time"
  12. )
  13. func Scan(brotherIP string, brotherPort int, resolution int, color string, adf bool) ([]byte, int, int) {
  14. log.Println("Valid IP address, opening socket...")
  15. socket, err := net.Dial("tcp", fmt.Sprintf("%s:%d", brotherIP, brotherPort))
  16. HandleError(err)
  17. defer socket.Close()
  18. width, heigth := SendRequest(socket, resolution, color, adf)
  19. bytes := GetScanBytes(socket)
  20. return RemoveHeaders(bytes), width, heigth
  21. }
  22. func SendRequest(socket net.Conn, resolution int, _mode string, adf bool) (int, int) {
  23. mode, compression := GetCompressionMode(_mode)
  24. log.Println("Reading scanner status...")
  25. status := ReadPacket(socket)[:7]
  26. if status != "+OK 200" {
  27. HandleError(fmt.Errorf("invalid reply from scanner: %s", status))
  28. }
  29. log.Println("Leasing options...")
  30. request := []byte(fmt.Sprintf("\x1bI\nR=%d,%d\nM=%s\n\x80", resolution, resolution, mode))
  31. SendPacket(socket, request)
  32. offer := ReadPacket(socket)
  33. if !adf {
  34. log.Println("Disabling automatic document feeder (ADF)")
  35. request = []byte("\x1bD\nADF\n\x80")
  36. SendPacket(socket, request)
  37. ReadPacket(socket)
  38. }
  39. log.Println("Sending scan request...")
  40. offerOptions := strings.Split(offer, ",")
  41. width, height := 0, 0
  42. fmt.Sscanf(offerOptions[4], "%d", &width)
  43. fmt.Sscanf(offerOptions[6], "%d", &height)
  44. requestFormat := "\x1bX\nR=%v,%v\nM=%s\nC=%s\nJ=MID\nB=50\nN=50\nA=0,0,%v,%v\n\x80"
  45. request = []byte(fmt.Sprintf(requestFormat, offerOptions[1], offerOptions[1], mode, compression, width, height))
  46. SendPacket(socket, request)
  47. log.Println("Scanning started...")
  48. return width, height
  49. }
  50. func GetScanBytes(socket net.Conn) []byte {
  51. log.Println("Getting packets...")
  52. packet := make([]byte, 2048)
  53. scanBytes := make([]byte, 0)
  54. readPackets:
  55. for {
  56. socket.SetDeadline(time.Now().Add(time.Second * 5))
  57. bytes, err := socket.Read(packet)
  58. switch err := err.(type) {
  59. case net.Error:
  60. if err.Timeout() {
  61. break readPackets
  62. }
  63. case nil:
  64. scanBytes = append(scanBytes, packet[:bytes]...)
  65. default:
  66. HandleError(err)
  67. }
  68. }
  69. return scanBytes
  70. }
  71. func SaveImage(data []byte, width int, height int, name string, color string) {
  72. log.Println("Saving image...")
  73. _, compression := GetCompressionMode(color)
  74. if compression != "JPEG" {
  75. img := image.NewGray(image.Rectangle{
  76. image.Point{0, 0},
  77. image.Point{width, height},
  78. })
  79. for y := 0; y < height-40; y++ {
  80. for x := 0; x < width; x++ {
  81. img.SetGray(x, y, colorToGray(data[y*width+x]))
  82. }
  83. }
  84. file, err := os.Create(name)
  85. HandleError(err)
  86. png.Encode(file, img)
  87. } else {
  88. err := os.WriteFile(name, data, 0644)
  89. HandleError(err)
  90. }
  91. }
  92. func RemoveHeaders(scan []byte) []byte {
  93. log.Println("Removing headers from bytes...")
  94. const headerLen int = 12
  95. payloadLen := binary.LittleEndian.Uint16(scan[headerLen-2 : headerLen])
  96. chunkSize := int(payloadLen) + headerLen
  97. scanOutput := make([]byte, 0)
  98. for i := 0; i < len(scan)-chunkSize; i += chunkSize {
  99. scanOutput = append(scanOutput, scan[i+headerLen:i+chunkSize]...)
  100. }
  101. return scanOutput
  102. }