| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- package main
- import (
- "encoding/binary"
- "fmt"
- "image"
- "image/png"
- "log"
- "net"
- "os"
- "strings"
- "time"
- )
- func Scan(brotherIP string, brotherPort int, resolution int, color string, adf bool) ([]byte, int, int) {
- log.Println("Valid IP address, opening socket...")
- socket, err := net.Dial("tcp", fmt.Sprintf("%s:%d", brotherIP, brotherPort))
- HandleError(err)
- defer socket.Close()
- width, heigth := SendRequest(socket, resolution, color, adf)
- bytes := GetScanBytes(socket)
- return RemoveHeaders(bytes), width, heigth
- }
- func SendRequest(socket net.Conn, resolution int, _mode string, adf bool) (int, int) {
- mode, compression := GetCompressionMode(_mode)
- log.Println("Reading scanner status...")
- status := ReadPacket(socket)[:7]
- if status != "+OK 200" {
- HandleError(fmt.Errorf("invalid reply from scanner: %s", status))
- }
- log.Println("Leasing options...")
- request := []byte(fmt.Sprintf("\x1bI\nR=%d,%d\nM=%s\n\x80", resolution, resolution, mode))
- SendPacket(socket, request)
- offer := ReadPacket(socket)
- if !adf {
- log.Println("Disabling automatic document feeder (ADF)")
- request = []byte("\x1bD\nADF\n\x80")
- SendPacket(socket, request)
- ReadPacket(socket)
- }
- log.Println("Sending scan request...")
- offerOptions := strings.Split(offer, ",")
- width, height := 0, 0
- fmt.Sscanf(offerOptions[4], "%d", &width)
- fmt.Sscanf(offerOptions[6], "%d", &height)
- requestFormat := "\x1bX\nR=%v,%v\nM=%s\nC=%s\nJ=MID\nB=50\nN=50\nA=0,0,%v,%v\n\x80"
- request = []byte(fmt.Sprintf(requestFormat, offerOptions[1], offerOptions[1], mode, compression, width, height))
- SendPacket(socket, request)
- log.Println("Scanning started...")
- return width, height
- }
- func GetScanBytes(socket net.Conn) []byte {
- log.Println("Getting packets...")
- packet := make([]byte, 2048)
- scanBytes := make([]byte, 0)
- readPackets:
- for {
- socket.SetDeadline(time.Now().Add(time.Second * 5))
- bytes, err := socket.Read(packet)
- switch err := err.(type) {
- case net.Error:
- if err.Timeout() {
- break readPackets
- }
- case nil:
- scanBytes = append(scanBytes, packet[:bytes]...)
- default:
- HandleError(err)
- }
- }
- return scanBytes
- }
- func SaveImage(data []byte, width int, height int, name string, color string) {
- log.Println("Saving image...")
- _, compression := GetCompressionMode(color)
- if compression != "JPEG" {
- img := image.NewGray(image.Rectangle{
- image.Point{0, 0},
- image.Point{width, height},
- })
- for y := 0; y < height-40; y++ {
- for x := 0; x < width; x++ {
- img.SetGray(x, y, colorToGray(data[y*width+x]))
- }
- }
- file, err := os.Create(name)
- HandleError(err)
- png.Encode(file, img)
- } else {
- err := os.WriteFile(name, data, 0644)
- HandleError(err)
- }
- }
- func RemoveHeaders(scan []byte) []byte {
- log.Println("Removing headers from bytes...")
- const headerLen int = 12
- payloadLen := binary.LittleEndian.Uint16(scan[headerLen-2 : headerLen])
- chunkSize := int(payloadLen) + headerLen
- scanOutput := make([]byte, 0)
- for i := 0; i < len(scan)-chunkSize; i += chunkSize {
- scanOutput = append(scanOutput, scan[i+headerLen:i+chunkSize]...)
- }
- return scanOutput
- }
|