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