Files
LoganandClaude 76ec9387f0 feat(rdp): 新增 RDP 远程桌面/SMB/账单同步能力 + 清理编译产物
主要变更:
- RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、
  backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API
- Windows SMB 文件传输:backend/pkg/winsmb
- 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情
- Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs
- 服务器导入助手:server_import_helpers、ImportCredentialSettings
- 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块)
- 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-*
- .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-04 01:50:36 +08:00

431 lines
9.0 KiB
Go

package rle
import "fmt"
func decompress3(output *[]uint8, width, height int, input []uint8, size int) bool {
var (
prevline, line, count int
opcode, offset, code int
x int = width
lastopcode int = -1
insertmix, bicolour, isfillormix bool
mixmask, mask uint8
colour1 = [3]uint8{0, 0, 0}
colour2 = [3]uint8{0, 0, 0}
mix = [3]uint8{0xff, 0xff, 0xff}
fom_mask uint8
)
out := *output
for len(input) != 0 {
fom_mask = 0
code = CVAL(&input)
opcode = code >> 4
/* Handle different opcode forms */
switch opcode {
case 0xc, 0xd, 0xe:
opcode -= 6
count = code & 0xf
offset = 16
break
case 0xf:
opcode = code & 0xf
if opcode < 9 {
count = CVAL(&input)
count |= CVAL(&input) << 8
} else {
count = 1
if opcode < 0xb {
count = 8
}
}
offset = 0
break
default:
opcode >>= 1
count = code & 0x1f
offset = 32
break
}
/* Handle strange cases for counts */
if offset != 0 {
isfillormix = ((opcode == 2) || (opcode == 7))
if count == 0 {
if isfillormix {
count = CVAL(&input) + 1
} else {
count = CVAL(&input) + offset
}
} else if isfillormix {
count <<= 3
}
}
/* Read preliminary data */
switch opcode {
case 0: /* Fill */
if (lastopcode == opcode) && !((x == width) && (prevline == 0)) {
insertmix = true
}
break
case 8: /* Bicolour */
CVAL3(&input, &colour1)
CVAL3(&input, &colour2)
break
case 3: /* Colour */
CVAL3(&input, &colour2)
break
case 6: /* SetMix/Mix */
fallthrough
case 7: /* SetMix/FillOrMix */
CVAL3(&input, &mix)
opcode -= 5
break
case 9: /* FillOrMix_1 */
mask = 0x03
opcode = 0x02
fom_mask = 3
break
case 0x0a: /* FillOrMix_2 */
mask = 0x05
opcode = 0x02
fom_mask = 5
break
}
lastopcode = opcode
mixmask = 0
/* Output body */
for count > 0 {
if x >= width {
if height <= 0 {
return false
}
x = 0
height--
prevline = line
line = height * width * 3
}
switch opcode {
case 0: /* Fill */
if insertmix {
if prevline == 0 {
out[3*x+line] = mix[0]
out[3*x+line+1] = mix[1]
out[3*x+line+2] = mix[2]
} else {
out[3*x+line] = out[prevline+3*x] ^ mix[0]
out[3*x+line+1] = out[prevline+3*x+1] ^ mix[1]
out[3*x+line+2] = out[prevline+3*x+2] ^ mix[2]
}
insertmix = false
count--
x++
}
n := min(count, width-x)
if prevline == 0 {
clear(out[3*x+line : 3*x+line+3*n])
} else {
dstBase := 3*x + line
srcBase := prevline + 3*x
copy(out[dstBase:dstBase+3*n], out[srcBase:srcBase+3*n])
}
count -= n
x += n
break
case 1: /* Mix */
n := min(count, width-x)
dst1 := out[3*x+line : 3*x+line+3*n]
if prevline == 0 {
// Exponential-doubling copy: O(log n) memcpy calls
dst1[0], dst1[1], dst1[2] = mix[0], mix[1], mix[2]
for wrote := 3; wrote < len(dst1); {
wrote += copy(dst1[wrote:], dst1[:wrote])
}
} else {
src1 := out[prevline+3*x : prevline+3*x+3*n]
for i := 0; i+2 < len(dst1); i += 3 {
dst1[i] = src1[i] ^ mix[0]
dst1[i+1] = src1[i+1] ^ mix[1]
dst1[i+2] = src1[i+2] ^ mix[2]
}
}
count -= n
x += n
break
case 2: /* Fill or Mix */
if prevline == 0 {
base := 3*x + line
for count > 0 && x < width {
mixmask = mixmask << 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[base] = mix[0]
out[base+1] = mix[1]
out[base+2] = mix[2]
} else {
out[base] = 0
out[base+1] = 0
out[base+2] = 0
}
base += 3
count--
x++
}
} else {
base := 3*x + line
prev := prevline + 3*x
for count > 0 && x < width {
mixmask = mixmask << 1
if mixmask == 0 {
mask = fom_mask
if fom_mask == 0 {
mask = uint8(CVAL(&input))
mixmask = 1
}
}
if mask&mixmask != 0 {
out[base] = out[prev] ^ mix[0]
out[base+1] = out[prev+1] ^ mix[1]
out[base+2] = out[prev+2] ^ mix[2]
} else {
out[base] = out[prev]
out[base+1] = out[prev+1]
out[base+2] = out[prev+2]
}
base += 3
prev += 3
count--
x++
}
}
break
case 3: /* Colour */
n := min(count, width-x)
seg3 := out[3*x+line : 3*x+line+3*n]
seg3[0], seg3[1], seg3[2] = colour2[0], colour2[1], colour2[2]
for wrote := 3; wrote < len(seg3); {
wrote += copy(seg3[wrote:], seg3[:wrote])
}
count -= n
x += n
break
case 4: /* Copy */
for count > 0 && x < width {
n := min(count, width-x)
if len(input) < n*3 {
return false
}
copy(out[3*x+line:3*x+line+n*3], input[:n*3])
input = input[n*3:]
count -= n
x += n
}
break
case 8: /* Bicolour */
base8 := 3*x + line
for count > 0 && x < width {
if bicolour {
out[base8] = colour2[0]
out[base8+1] = colour2[1]
out[base8+2] = colour2[2]
bicolour = false
} else {
out[base8] = colour1[0]
out[base8+1] = colour1[1]
out[base8+2] = colour1[2]
bicolour = true
count++
}
base8 += 3
count--
x++
}
break
case 0xd: /* White */
n3 := min(count, width-x)
seg3 := out[3*x+line : 3*x+line+3*n3]
for i := range seg3 {
seg3[i] = 0xff
}
count -= n3
x += n3
break
case 0xe: /* Black */
n2 := min(count, width-x)
clear(out[3*x+line : 3*x+line+3*n2])
count -= n2
x += n2
break
default:
fmt.Printf("bitmap opcode 0x%x\n", opcode)
return false
}
}
}
return true
}
/* decompress a colour plane */
func processPlane(in *[]uint8, width, height int, output *[]uint8, j int) (int, bool) {
var (
indexw int
indexh int
code int
collen int
replen int
color uint8
x uint8
revcode int
lastline int
thisline int
)
ln := len(*in)
out := *output // hoist pointer dereference; writes to out[i] affect the underlying array
readByte := func() (uint8, bool) {
if len(*in) == 0 {
return 0, false
}
v := (*in)[0]
*in = (*in)[1:]
return v, true
}
writePixel := func(pos int, value uint8) bool {
if pos < 0 || pos >= len(out) {
return false
}
out[pos] = value
return true
}
lastline = 0
indexh = 0
i := 0
for indexh < height {
thisline = j + (width * height * 4) - ((indexh + 1) * width * 4)
color = 0
indexw = 0
i = thisline
if lastline == 0 {
for indexw < width {
b, ok := readByte()
if !ok {
return ln - len(*in), false
}
code = int(b)
replen = int(code & 0xf)
collen = int((code >> 4) & 0xf)
revcode = (replen << 4) | collen
if (revcode <= 47) && (revcode >= 16) {
replen = revcode
collen = 0
}
for collen > 0 {
if indexw >= width {
return ln - len(*in), false
}
v, ok := readByte()
if !ok {
return ln - len(*in), false
}
color = v
if !writePixel(i, color) {
return ln - len(*in), false
}
i += 4
indexw++
collen--
}
for replen > 0 {
if indexw >= width {
break
}
if !writePixel(i, color) {
return ln - len(*in), false
}
i += 4
indexw++
replen--
}
}
} else {
// prevOffset is constant per row: indexw*4+lastline == i+(lastline-thisline)
// because i == thisline+indexw*4. Pre-computing it eliminates a multiply
// per pixel in both inner loops.
prevOffset := lastline - thisline
for indexw < width {
b, ok := readByte()
if !ok {
return ln - len(*in), false
}
code = int(b)
replen = int(code & 0xf)
collen = int((code >> 4) & 0xf)
revcode = (replen << 4) | collen
if (revcode <= 47) && (revcode >= 16) {
replen = revcode
collen = 0
}
for collen > 0 {
if indexw >= width {
return ln - len(*in), false
}
v, ok := readByte()
if !ok {
return ln - len(*in), false
}
x = v
if x&1 != 0 {
x = x >> 1
x = x + 1
color = -x
} else {
x = x >> 1
color = x
}
if i+prevOffset < 0 || i+prevOffset >= len(out) {
return ln - len(*in), false
}
x = out[i+prevOffset] + color
if !writePixel(i, x) {
return ln - len(*in), false
}
i += 4
indexw++
collen--
}
for replen > 0 {
if indexw >= width {
break
}
if i+prevOffset < 0 || i+prevOffset >= len(out) {
return ln - len(*in), false
}
x = out[i+prevOffset] + color
if !writePixel(i, x) {
return ln - len(*in), false
}
i += 4
indexw++
replen--
}
}
}
indexh++
lastline = thisline
}
return ln - len(*in), true
}
/* 4 byte bitmap decompress */