-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrdp60.go
132 lines (108 loc) · 3.28 KB
/
rdp60.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
package go_bitmap
import (
"bytes"
"image"
"image/color"
"io"
)
func decompressColorPlane(r io.Reader, w, h int) []byte {
result := make([]byte, 0)
size := w * h
for size > 0 {
controlByte := ReadByte(r)
nRunLength := controlByte & 0x0F
cRawBytes := (controlByte & 0xF0) >> 4
//glog.Debugf("nRunLength: %v", nRunLength)
//glog.Debugf("cRawBytes: %v", cRawBytes)
// ==> 如果 nRunLength 字段设置为 1,则实际运行长度为 16 加上 cRawBytes 中的值。
// 在解码时,假定 rawValues 字段中的 RAW 字节数为零。这给出了 31 个值的最大运行长度
// ==> 如果 nRunLength 字段设置为 2,则实际运行长度为 32 加上 cRawBytes 中的值。
// 在解码时,假定 rawValues 字段中的 RAW 字节数为零。这给出了 47 个值的最大运行长度。
if nRunLength == 1 {
nRunLength = 16 + cRawBytes
cRawBytes = 0
} else if nRunLength == 2 {
nRunLength = 32 + cRawBytes
cRawBytes = 0
}
if cRawBytes != 0 {
data := ReadBytes(r, int(cRawBytes))
result = append(result, data...)
//glog.Debugf("--> data: %x", data)
size -= int(cRawBytes)
}
if nRunLength != 0 {
//glog.Debugf("nRunLength = %v", nRunLength)
//glog.Debugf("resultLen = %v", len(result))
// 行首,set(0), else set 上一个字符
if len(result)%w == 0 {
//glog.Debugf("write black")
for i := 0; i < int(nRunLength); i++ {
result = append(result, 0)
}
} else {
b := result[len(result)-1]
for i := 0; i < int(nRunLength); i++ {
result = append(result, b)
}
}
//data := ReadBytes(r, int(nRunLength))
//glog.Debugf("data: %x", data)
size -= int(nRunLength)
}
}
//glog.Debugf("final: %v", len(result))
for y := w; y < len(result); y += w {
for x, e := y, y+w; x < e; x++ { // e->end, per line
delta := result[x]
if delta%2 == 0 {
delta >>= 1
} else {
delta = 255 - ((delta - 1) >> 1)
}
result[x] = result[x-w] + delta
}
}
return result
}
func (m *BitMap) LoadRDP60(option *Option) *BitMap {
r := bytes.NewReader(option.Data)
formatHeader := ReadByte(r)
//glog.Debugf("format Header: %x", formatHeader)
cll := formatHeader & 0x7 // color loss level
//glog.Debugf("cll: %x", cll)
cs := ((formatHeader & 0x08) >> 3) == 1 // whether chroma subsampling is being used
//glog.Debugf("cs: %v", cs)
rle := ((formatHeader & 0x10) >> 4) == 1
//glog.Debugf("rle: %v", rle)
na := ((formatHeader & 0x20) >> 5) == 1 //Indicates if an alpha plane is present.
//glog.Debugf("na: %v", na)
if cll == 0 && cs == true {
ThrowError("Chroma subsampling requires YCoCg and does not work with RGB data")
}
if cs == true {
ThrowError("not implement [cs]")
}
if !rle {
ThrowError("not implement [!rle]")
}
w, h := option.Width, option.Height
// RLE Decompression
if !na {
//glog.Debugf("has Alpha")
decompressColorPlane(r, w, h) // read rle alpha plane
}
cr := decompressColorPlane(r, w, h) // read rle alpha plane
cg := decompressColorPlane(r, w, h) // read rle alpha plane
cb := decompressColorPlane(r, w, h) // read rle alpha plane
img := image.NewRGBA(image.Rect(0, 0, w, h))
pos := 0
for y := 1; y <= h; y++ {
for x := 0; x < w; x++ {
img.Set(x, h-y, color.RGBA{R: cr[pos], G: cg[pos], B: cb[pos], A: 255})
pos++
}
}
m.Image = img
return m
}