forked from amitbet/vnc2video
-
Notifications
You must be signed in to change notification settings - Fork 0
/
encoding_hextile.go
160 lines (140 loc) · 4.46 KB
/
encoding_hextile.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package vnc2video
import (
"image"
"image/color"
"image/draw"
"io"
"github.com/amitbet/vnc2video/logger"
)
const (
HextileRaw = 1
HextileBackgroundSpecified = 2
HextileForegroundSpecified = 4
HextileAnySubrects = 8
HextileSubrectsColoured = 16
)
type HextileEncoding struct {
//Colors []Color
bytes []byte
Image draw.Image
}
func (enc *HextileEncoding) SetTargetImage(img draw.Image) {
enc.Image = img
}
func (*HextileEncoding) Supported(Conn) bool {
return true
}
func (enc *HextileEncoding) Reset() error {
//enc.decoders = make([]io.Reader, 4)
//enc.decoderBuffs = make([]*bytes.Buffer, 4)
return nil
}
func (z *HextileEncoding) Type() EncodingType {
return EncHextile
}
func (z *HextileEncoding) WriteTo(w io.Writer) (n int, err error) {
return w.Write(z.bytes)
}
func (enc *HextileEncoding) Write(c Conn, rect *Rectangle) error {
return nil
}
func (z *HextileEncoding) Read(r Conn, rect *Rectangle) error {
//func (z *HextileEncoding) Read(pixelFmt *PixelFormat, rect *Rectangle, r io.Reader) (Encoding, error) {
//bytesPerPixel := int(r.PixelFormat().BPP) / 8
pf := r.PixelFormat()
var bgCol *color.RGBA
var fgCol *color.RGBA
var err error
var dimensions byte
var subencoding byte
//r.StartByteCollection()
// defer func() {
// z.bytes = r.EndByteCollection()
// }()
logger.Tracef("HextileEncoding.Read: got hextile rect: %v", rect)
for ty := rect.Y; ty < rect.Y+rect.Height; ty += 16 {
th := 16
if rect.Y+rect.Height-ty < 16 {
th = int(rect.Y) + int(rect.Height) - int(ty)
}
for tx := rect.X; tx < rect.X+rect.Width; tx += 16 {
tw := 16
if rect.X+rect.Width-tx < 16 {
tw = int(rect.X) + int(rect.Width) - int(tx)
}
//handle Hextile Subrect(tx, ty, tw, th):
subencoding, err = ReadUint8(r)
if err != nil {
logger.Errorf("HextileEncoding.Read: error in hextile reader: %v", err)
return err
}
if (subencoding & HextileRaw) != 0 {
rawEnc := r.GetEncInstance(EncRaw)
rawEnc.Read(r, &Rectangle{X: uint16(tx), Y: uint16(ty), Width: uint16(tw), Height: uint16(th), EncType: EncRaw, Enc: rawEnc})
//ReadBytes(tw*th*int(pf.BPP)/8, r)
continue
}
if (subencoding & HextileBackgroundSpecified) != 0 {
//ReadBytes(int(bytesPerPixel), r)
bgCol, err = ReadColor(r, &pf)
if err != nil {
logger.Errorf("HextileEncoding.Read: error in hextile bg color reader: %v", err)
return err
}
//logger.Tracef("%v %v", rBounds, bgCol)
}
rBounds := image.Rectangle{Min: image.Point{int(tx), int(ty)}, Max: image.Point{int(tx) + int(tw), int(ty) + int(th)}}
//logger.Tracef("filling background rect: %v, col: %v", rBounds, bgCol)
FillRect(z.Image, &rBounds, bgCol)
if (subencoding & HextileForegroundSpecified) != 0 {
fgCol, err = ReadColor(r, &pf)
if err != nil {
logger.Errorf("HextileEncoding.Read: error in hextile fg color reader: %v", err)
return err
}
}
if (subencoding & HextileAnySubrects) == 0 {
//logger.Trace("hextile reader: no Subrects")
continue
}
nSubrects, err := ReadUint8(r)
if err != nil {
return err
}
//bufsize := int(nSubrects) * 2
colorSpecified := ((subencoding & HextileSubrectsColoured) != 0)
for i := 0; i < int(nSubrects); i++ {
var color *color.RGBA
if colorSpecified {
color, err = ReadColor(r, &pf)
if err != nil {
logger.Error("HextileEncoding.Read: problem reading color from connection: ", err)
return err
}
} else {
color = fgCol
}
//int color = colorSpecified ? renderer.readPixelColor(transport) : colors[FG_COLOR_INDEX];
fgCol = color
dimensions, err = ReadUint8(r) // bits 7-4 for x, bits 3-0 for y
if err != nil {
logger.Error("HextileEncoding.Read: problem reading dimensions from connection: ", err)
return err
}
subtileX := dimensions >> 4 & 0x0f
subtileY := dimensions & 0x0f
dimensions, err = ReadUint8(r) // bits 7-4 for w, bits 3-0 for h
if err != nil {
logger.Error("HextileEncoding.Read: problem reading 2nd dimensions from connection: ", err)
return err
}
subtileWidth := 1 + (dimensions >> 4 & 0x0f)
subtileHeight := 1 + (dimensions & 0x0f)
subrectBounds := image.Rectangle{Min: image.Point{int(tx) + int(subtileX), int(ty) + int(subtileY)}, Max: image.Point{int(tx) + int(subtileX) + int(subtileWidth), int(ty) + int(subtileY) + int(subtileHeight)}}
FillRect(z.Image, &subrectBounds, color)
//logger.Tracef("%v", subrectBounds)
}
}
}
return nil
}