]>
Commit | Line | Data |
---|---|---|
923cd220 PO |
1 | /* |
2 | * noVNC: HTML5 VNC client | |
412d9306 | 3 | * Copyright (C) 2019 The noVNC Authors |
923cd220 PO |
4 | * Licensed under MPL 2.0 (see LICENSE.txt) |
5 | * | |
6 | * See README.md for usage and integration instructions. | |
7 | * | |
8 | */ | |
9 | ||
10 | import * as Log from '../util/logging.js'; | |
11 | ||
12 | export default class HextileDecoder { | |
13 | constructor() { | |
14 | this._tiles = 0; | |
15 | this._lastsubencoding = 0; | |
16 | } | |
17 | ||
18 | decodeRect(x, y, width, height, sock, display, depth) { | |
19 | if (this._tiles === 0) { | |
20 | this._tiles_x = Math.ceil(width / 16); | |
21 | this._tiles_y = Math.ceil(height / 16); | |
22 | this._total_tiles = this._tiles_x * this._tiles_y; | |
23 | this._tiles = this._total_tiles; | |
24 | } | |
25 | ||
26 | while (this._tiles > 0) { | |
27 | let bytes = 1; | |
28 | ||
29 | if (sock.rQwait("HEXTILE", bytes)) { | |
30 | return false; | |
31 | } | |
32 | ||
8a189a62 JD |
33 | let rQ = sock.rQ; |
34 | let rQi = sock.rQi; | |
923cd220 PO |
35 | |
36 | let subencoding = rQ[rQi]; // Peek | |
37 | if (subencoding > 30) { // Raw | |
d3ed883a | 38 | throw new Error("Illegal hextile subencoding (subencoding: " + |
923cd220 PO |
39 | subencoding + ")"); |
40 | } | |
41 | ||
42 | const curr_tile = this._total_tiles - this._tiles; | |
43 | const tile_x = curr_tile % this._tiles_x; | |
44 | const tile_y = Math.floor(curr_tile / this._tiles_x); | |
45 | const tx = x + tile_x * 16; | |
46 | const ty = y + tile_y * 16; | |
47 | const tw = Math.min(16, (x + width) - tx); | |
48 | const th = Math.min(16, (y + height) - ty); | |
49 | ||
50 | // Figure out how much we are expecting | |
51 | if (subencoding & 0x01) { // Raw | |
52 | bytes += tw * th * 4; | |
53 | } else { | |
54 | if (subencoding & 0x02) { // Background | |
55 | bytes += 4; | |
56 | } | |
57 | if (subencoding & 0x04) { // Foreground | |
58 | bytes += 4; | |
59 | } | |
60 | if (subencoding & 0x08) { // AnySubrects | |
61 | bytes++; // Since we aren't shifting it off | |
62 | ||
63 | if (sock.rQwait("HEXTILE", bytes)) { | |
64 | return false; | |
65 | } | |
66 | ||
67 | let subrects = rQ[rQi + bytes - 1]; // Peek | |
68 | if (subencoding & 0x10) { // SubrectsColoured | |
69 | bytes += subrects * (4 + 2); | |
70 | } else { | |
71 | bytes += subrects * 2; | |
72 | } | |
73 | } | |
74 | } | |
75 | ||
76 | if (sock.rQwait("HEXTILE", bytes)) { | |
77 | return false; | |
78 | } | |
79 | ||
80 | // We know the encoding and have a whole tile | |
81 | rQi++; | |
82 | if (subencoding === 0) { | |
83 | if (this._lastsubencoding & 0x01) { | |
84 | // Weird: ignore blanks are RAW | |
85 | Log.Debug(" Ignoring blank after RAW"); | |
86 | } else { | |
87 | display.fillRect(tx, ty, tw, th, this._background); | |
88 | } | |
89 | } else if (subencoding & 0x01) { // Raw | |
90 | display.blitImage(tx, ty, tw, th, rQ, rQi); | |
91 | rQi += bytes - 1; | |
92 | } else { | |
93 | if (subencoding & 0x02) { // Background | |
94 | this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | |
95 | rQi += 4; | |
96 | } | |
97 | if (subencoding & 0x04) { // Foreground | |
98 | this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | |
99 | rQi += 4; | |
100 | } | |
101 | ||
102 | display.startTile(tx, ty, tw, th, this._background); | |
103 | if (subencoding & 0x08) { // AnySubrects | |
104 | let subrects = rQ[rQi]; | |
105 | rQi++; | |
106 | ||
107 | for (let s = 0; s < subrects; s++) { | |
108 | let color; | |
109 | if (subencoding & 0x10) { // SubrectsColoured | |
110 | color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | |
111 | rQi += 4; | |
112 | } else { | |
113 | color = this._foreground; | |
114 | } | |
115 | const xy = rQ[rQi]; | |
116 | rQi++; | |
117 | const sx = (xy >> 4); | |
118 | const sy = (xy & 0x0f); | |
119 | ||
120 | const wh = rQ[rQi]; | |
121 | rQi++; | |
122 | const sw = (wh >> 4) + 1; | |
123 | const sh = (wh & 0x0f) + 1; | |
124 | ||
125 | display.subTile(sx, sy, sw, sh, color); | |
126 | } | |
127 | } | |
128 | display.finishTile(); | |
129 | } | |
17eea957 | 130 | sock.rQi = rQi; |
923cd220 PO |
131 | this._lastsubencoding = subencoding; |
132 | this._tiles--; | |
133 | } | |
134 | ||
135 | return true; | |
136 | } | |
137 | } |