github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/encoding_tightpng.go (about) 1 package vnc2video 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "image" 8 "image/color" 9 "image/draw" 10 "image/png" 11 "io" 12 "github.com/amitbet/vnc2video/logger" 13 ) 14 15 func (*TightPngEncoding) Supported(Conn) bool { 16 return true 17 } 18 func (*TightPngEncoding) Reset() error { 19 return nil 20 } 21 22 func (enc *TightPngEncoding) Write(c Conn, rect *Rectangle) error { 23 if err := writeTightCC(c, enc.TightCC); err != nil { 24 return err 25 } 26 cmp := enc.TightCC.Compression 27 switch cmp { 28 case TightCompressionPNG: 29 buf := bPool.Get().(*bytes.Buffer) 30 buf.Reset() 31 defer bPool.Put(buf) 32 pngEnc := &png.Encoder{CompressionLevel: png.BestSpeed} 33 //pngEnc := &png.Encoder{CompressionLevel: png.NoCompression} 34 if err := pngEnc.Encode(buf, enc.Image); err != nil { 35 return err 36 } 37 if err := writeTightLength(c, buf.Len()); err != nil { 38 return err 39 } 40 41 if _, err := buf.WriteTo(c); err != nil { 42 return err 43 } 44 case TightCompressionFill: 45 var tpx TightPixel 46 r, g, b, _ := enc.Image.At(0, 0).RGBA() 47 tpx.R = uint8(r) 48 tpx.G = uint8(g) 49 tpx.B = uint8(b) 50 if err := binary.Write(c, binary.BigEndian, tpx); err != nil { 51 return err 52 } 53 default: 54 return fmt.Errorf("unknown tight compression %d", cmp) 55 } 56 return nil 57 } 58 59 type TightPngEncoding struct { 60 TightCC *TightCC 61 Image draw.Image 62 } 63 64 func (*TightPngEncoding) Type() EncodingType { return EncTightPng } 65 66 func (enc *TightPngEncoding) Read(c Conn, rect *Rectangle) error { 67 tcc, err := readTightCC(c) 68 logger.Trace("starting to read a tight rect: %v", rect) 69 if err != nil { 70 return err 71 } 72 enc.TightCC = tcc 73 cmp := enc.TightCC.Compression 74 switch cmp { 75 case TightCompressionPNG: 76 l, err := readTightLength(c) 77 if err != nil { 78 return err 79 } 80 img, err := png.Decode(io.LimitReader(c, int64(l))) 81 if err != nil { 82 return err 83 } 84 //draw.Draw(enc.Image, enc.Image.Bounds(), img, image.Point{X: int(rect.X), Y: int(rect.Y)}, draw.Src) 85 DrawImage(enc.Image, img, image.Point{X: int(rect.X), Y: int(rect.Y)}) 86 case TightCompressionFill: 87 var tpx TightPixel 88 if err := binary.Read(c, binary.BigEndian, &tpx); err != nil { 89 return err 90 } 91 //enc.Image = image.NewRGBA(image.Rect(0, 0, 1, 1)) 92 col := color.RGBA{R: tpx.R, G: tpx.G, B: tpx.B, A: 1} 93 myRect := MakeRectFromVncRect(rect) 94 FillRect(enc.Image, &myRect, col) 95 //enc.Image.(draw.Image).Set(0, 0, color.RGBA{R: tpx.R, G: tpx.G, B: tpx.B, A: 1}) 96 default: 97 return fmt.Errorf("unknown compression %d", cmp) 98 } 99 return nil 100 } 101 102 func (enc *TightPngEncoding) SetTargetImage(img draw.Image) { 103 enc.Image = img 104 }