ai-remote 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/index.js +1 -6
  2. package/dist/{protocols/index.d.ts → protocols.d.ts} +2 -0
  3. package/dist/protocols.js +24 -0
  4. package/package.json +15 -10
  5. package/dist/protocols/index.js +0 -34
  6. package/dist/protocols/rdp/buffer.d.ts +0 -38
  7. package/dist/protocols/rdp/buffer.js +0 -169
  8. package/dist/protocols/rdp/caps.d.ts +0 -49
  9. package/dist/protocols/rdp/caps.js +0 -259
  10. package/dist/protocols/rdp/cert.d.ts +0 -18
  11. package/dist/protocols/rdp/cert.js +0 -134
  12. package/dist/protocols/rdp/client.d.ts +0 -56
  13. package/dist/protocols/rdp/client.js +0 -1069
  14. package/dist/protocols/rdp/cliprdr.d.ts +0 -27
  15. package/dist/protocols/rdp/cliprdr.js +0 -239
  16. package/dist/protocols/rdp/credssp.d.ts +0 -34
  17. package/dist/protocols/rdp/credssp.js +0 -253
  18. package/dist/protocols/rdp/crypto.d.ts +0 -63
  19. package/dist/protocols/rdp/crypto.js +0 -368
  20. package/dist/protocols/rdp/display.d.ts +0 -38
  21. package/dist/protocols/rdp/display.js +0 -588
  22. package/dist/protocols/rdp/gcc.d.ts +0 -23
  23. package/dist/protocols/rdp/gcc.js +0 -131
  24. package/dist/protocols/rdp/keymap.d.ts +0 -9
  25. package/dist/protocols/rdp/keymap.js +0 -131
  26. package/dist/protocols/rdp/mcs.d.ts +0 -40
  27. package/dist/protocols/rdp/mcs.js +0 -222
  28. package/dist/protocols/rdp/ntlm.d.ts +0 -61
  29. package/dist/protocols/rdp/ntlm.js +0 -304
  30. package/dist/protocols/rdp/pdu.d.ts +0 -155
  31. package/dist/protocols/rdp/pdu.js +0 -443
  32. package/dist/protocols/rdp/rail.d.ts +0 -119
  33. package/dist/protocols/rdp/rail.js +0 -382
  34. package/dist/protocols/rdp/rle.d.ts +0 -13
  35. package/dist/protocols/rdp/rle.js +0 -275
  36. package/dist/protocols/rdp/sec.d.ts +0 -59
  37. package/dist/protocols/rdp/sec.js +0 -155
  38. package/dist/protocols/rdp/session.d.ts +0 -62
  39. package/dist/protocols/rdp/session.js +0 -306
  40. package/dist/protocols/rdp/tls.d.ts +0 -18
  41. package/dist/protocols/rdp/tls.js +0 -353
  42. package/dist/protocols/rdp/vchannel.d.ts +0 -28
  43. package/dist/protocols/rdp/vchannel.js +0 -58
  44. package/dist/protocols/rdp/x224.d.ts +0 -40
  45. package/dist/protocols/rdp/x224.js +0 -109
  46. package/dist/protocols/ssh/kex.d.ts +0 -97
  47. package/dist/protocols/ssh/kex.js +0 -176
  48. package/dist/protocols/ssh/messages.d.ts +0 -50
  49. package/dist/protocols/ssh/messages.js +0 -54
  50. package/dist/protocols/ssh/session.d.ts +0 -66
  51. package/dist/protocols/ssh/session.js +0 -608
  52. package/dist/protocols/ssh/terminal.d.ts +0 -46
  53. package/dist/protocols/ssh/terminal.js +0 -190
  54. package/dist/protocols/ssh/transport.d.ts +0 -62
  55. package/dist/protocols/ssh/transport.js +0 -612
  56. package/dist/protocols/ssh/wire.d.ts +0 -52
  57. package/dist/protocols/ssh/wire.js +0 -188
  58. package/dist/protocols/types.d.ts +0 -127
  59. package/dist/protocols/types.js +0 -0
  60. package/dist/protocols/vnc/input.d.ts +0 -5
  61. package/dist/protocols/vnc/input.js +0 -15
  62. package/dist/protocols/vnc/session.d.ts +0 -12
  63. package/dist/protocols/vnc/session.js +0 -258
  64. package/dist/shared/connection.d.ts +0 -81
  65. package/dist/shared/connection.js +0 -113
  66. package/dist/shared/device.d.ts +0 -26
  67. package/dist/shared/device.js +0 -0
  68. package/dist/shared/hosts.d.ts +0 -63
  69. package/dist/shared/hosts.js +0 -132
  70. package/dist/shared/icons.d.ts +0 -46
  71. package/dist/shared/icons.js +0 -41
  72. package/dist/shared/protocol.d.ts +0 -28
  73. package/dist/shared/protocol.js +0 -39
  74. package/dist/shared/signals.d.ts +0 -37
  75. package/dist/shared/signals.js +0 -41
@@ -1,382 +0,0 @@
1
- import { Reader, Writer } from "./buffer.js";
2
- const RAIL_ORDER = {
3
- EXEC: 1,
4
- ACTIVATE: 2,
5
- SYSPARAM: 3,
6
- SYSCOMMAND: 4,
7
- HANDSHAKE: 5,
8
- WINDOW_MOVE: 8,
9
- CLIENT_STATUS: 11,
10
- EXEC_RESULT: 128,
11
- HANDSHAKE_EX: 19
12
- };
13
- const RAIL_EXEC_RESULT = {
14
- 0: "The remote application started.",
15
- 1: "The RemoteApp host could not load its application monitoring hook.",
16
- 2: "The RemoteApp host could not decode the application launch request.",
17
- 3: "The requested application is not in the host RemoteApp allowlist.",
18
- 5: "The requested remote application was not found.",
19
- 6: "The RemoteApp host could not start the requested application.",
20
- 7: "The RemoteApp session is locked and cannot start the application."
21
- };
22
- const SYS_COMMAND = {
23
- MINIMIZE: 61472,
24
- MAXIMIZE: 61488,
25
- CLOSE: 61536,
26
- RESTORE: 61728
27
- };
28
- const SHOW_STATE = {
29
- HIDDEN: 0,
30
- MINIMIZED: 2,
31
- MAXIMIZED: 3,
32
- NORMAL: 5
33
- };
34
- const WINDOW_ORDER = {
35
- TYPE_WINDOW: 16777216,
36
- STATE_NEW: 268435456,
37
- STATE_DELETED: 536870912,
38
- ICON: 1073741824,
39
- CACHED_ICON: 2147483648
40
- };
41
- const WINDOW_FIELD = {
42
- OWNER: 2,
43
- TITLE: 4,
44
- STYLE: 8,
45
- SHOW: 16,
46
- WND_RECTS: 256,
47
- WND_SIZE: 1024,
48
- WND_OFFSET: 2048,
49
- CLIENT_AREA_OFFSET: 16384,
50
- CLIENT_DELTA: 32768,
51
- CLIENT_AREA_SIZE: 65536,
52
- RP_CONTENT: 131072,
53
- ROOT_PARENT: 262144,
54
- VISIBILITY: 524288,
55
- VIS_OFFSET: 2097152
56
- };
57
- const STYLE_CHILD = 1073741824;
58
- const EX_STYLE_TOOLWINDOW = 128;
59
- const EX_STYLE_NOACTIVATE = 134217728;
60
- const DRAWING_ORDER_CLASS_MASK = 3;
61
- const DRAWING_ORDER_ALT_SECONDARY = 2;
62
- const ALTSEC_WINDOW = 11;
63
- const CLIENT_BUILD = 2600;
64
- const CLIENT_STATUS_SUPPRESS_ICON_ORDERS = 1024;
65
- const SYSTEM_PARAMETER = {
66
- MOUSE_BUTTON_SWAP: 33,
67
- DRAG_FULL_WINDOWS: 37,
68
- WORK_AREA: 47,
69
- HIGH_CONTRAST: 67,
70
- KEYBOARD_PREF: 69,
71
- KEYBOARD_CUES: 4107
72
- };
73
- function utf16Bytes(text) {
74
- const writer = new Writer(text.length * 2);
75
- writer.utf16le(text);
76
- return writer.take();
77
- }
78
- function pdu(orderType, body) {
79
- const writer = new Writer(body.length + 4);
80
- writer.u16le(orderType).u16le(body.length + 4).raw(body);
81
- return writer.take();
82
- }
83
- function signed32(value) {
84
- return value | 0;
85
- }
86
- function railHandshake(buildNumber = CLIENT_BUILD) {
87
- return pdu(RAIL_ORDER.HANDSHAKE, new Writer(4).u32le(buildNumber).take());
88
- }
89
- function railClientStatus(flags = CLIENT_STATUS_SUPPRESS_ICON_ORDERS) {
90
- return pdu(RAIL_ORDER.CLIENT_STATUS, new Writer(4).u32le(flags).take());
91
- }
92
- function railBooleanSystemParameter(parameter, enabled) {
93
- return pdu(RAIL_ORDER.SYSPARAM, new Writer(5).u32le(parameter).u8(enabled ? 1 : 0).take());
94
- }
95
- function railHighContrast() {
96
- const body = new Writer(16);
97
- body.u32le(SYSTEM_PARAMETER.HIGH_CONTRAST);
98
- body.u32le(126);
99
- body.u32le(2);
100
- body.u16le(0).u16le(0);
101
- return pdu(RAIL_ORDER.SYSPARAM, body.take());
102
- }
103
- function railWorkArea(width, height) {
104
- const body = new Writer(12);
105
- body.u32le(SYSTEM_PARAMETER.WORK_AREA);
106
- body.u16le(0).u16le(0).u16le(width).u16le(height);
107
- return pdu(RAIL_ORDER.SYSPARAM, body.take());
108
- }
109
- function railSystemParameters(width, height) {
110
- return [
111
- railHighContrast(),
112
- railBooleanSystemParameter(SYSTEM_PARAMETER.MOUSE_BUTTON_SWAP, false),
113
- railBooleanSystemParameter(SYSTEM_PARAMETER.KEYBOARD_PREF, false),
114
- railBooleanSystemParameter(SYSTEM_PARAMETER.DRAG_FULL_WINDOWS, true),
115
- railBooleanSystemParameter(SYSTEM_PARAMETER.KEYBOARD_CUES, false),
116
- railWorkArea(width, height)
117
- ];
118
- }
119
- function railActivate(windowId, enabled = true) {
120
- const body = new Writer(5);
121
- body.u32le(windowId).u8(enabled ? 1 : 0);
122
- return pdu(RAIL_ORDER.ACTIVATE, body.take());
123
- }
124
- function railSysCommand(windowId, command) {
125
- const body = new Writer(6);
126
- body.u32le(windowId).u16le(command);
127
- return pdu(RAIL_ORDER.SYSCOMMAND, body.take());
128
- }
129
- function railWindowMove(windowId, { left, top, right, bottom }) {
130
- const body = new Writer(12);
131
- body.u32le(windowId);
132
- body.u16le(left & 65535).u16le(top & 65535);
133
- body.u16le(right & 65535).u16le(bottom & 65535);
134
- return pdu(RAIL_ORDER.WINDOW_MOVE, body.take());
135
- }
136
- function railExecute({ program, workingDir = "", arguments: args = "" }) {
137
- const exe = utf16Bytes(program || "");
138
- const cwd = utf16Bytes(workingDir || "");
139
- const argv = utf16Bytes(args || "");
140
- if (exe.length === 0 || exe.length > 520) {
141
- throw new Error("RemoteApp program must be between 1 and 260 Unicode characters.");
142
- }
143
- if (cwd.length > 520) throw new Error("RemoteApp working directory is too long.");
144
- if (argv.length > 16e3) throw new Error("RemoteApp arguments are too long.");
145
- const body = new Writer(8 + exe.length + cwd.length + argv.length);
146
- body.u16le(0);
147
- body.u16le(exe.length).u16le(cwd.length).u16le(argv.length);
148
- body.raw(exe).raw(cwd).raw(argv);
149
- return pdu(RAIL_ORDER.EXEC, body.take());
150
- }
151
- function decodeUtf16(bytes) {
152
- let result = "";
153
- for (let i = 0; i + 1 < bytes.length; i += 2) {
154
- const codeUnit = bytes[i] | bytes[i + 1] << 8;
155
- if (codeUnit === 0) break;
156
- result += String.fromCharCode(codeUnit);
157
- }
158
- return result;
159
- }
160
- function readRectangles(reader, count) {
161
- const rectangles = [];
162
- for (let index = 0; index < count && reader.remaining >= 8; index++) {
163
- const left = reader.u16le();
164
- const top = reader.u16le();
165
- const right = reader.u16le();
166
- const bottom = reader.u16le();
167
- rectangles.push({ left, top, right, bottom });
168
- }
169
- return rectangles;
170
- }
171
- function parseWindowFields(reader, fieldFlags) {
172
- const fields = {};
173
- if (fieldFlags & WINDOW_FIELD.OWNER) fields.ownerWindowId = reader.u32le();
174
- if (fieldFlags & WINDOW_FIELD.STYLE) {
175
- fields.style = reader.u32le();
176
- fields.extendedStyle = reader.u32le();
177
- }
178
- if (fieldFlags & WINDOW_FIELD.SHOW) fields.showState = reader.u8();
179
- if (fieldFlags & WINDOW_FIELD.TITLE) {
180
- const titleBytes = reader.u16le();
181
- fields.title = decodeUtf16(reader.raw(Math.min(titleBytes, reader.remaining)));
182
- }
183
- if (fieldFlags & WINDOW_FIELD.CLIENT_AREA_OFFSET) {
184
- fields.clientOffsetX = signed32(reader.u32le());
185
- fields.clientOffsetY = signed32(reader.u32le());
186
- }
187
- if (fieldFlags & WINDOW_FIELD.CLIENT_AREA_SIZE) {
188
- fields.clientWidth = signed32(reader.u32le());
189
- fields.clientHeight = signed32(reader.u32le());
190
- }
191
- if (fieldFlags & WINDOW_FIELD.RP_CONTENT) reader.u8();
192
- if (fieldFlags & WINDOW_FIELD.ROOT_PARENT) reader.u32le();
193
- if (fieldFlags & WINDOW_FIELD.WND_OFFSET) {
194
- fields.x = signed32(reader.u32le());
195
- fields.y = signed32(reader.u32le());
196
- }
197
- if (fieldFlags & WINDOW_FIELD.CLIENT_DELTA) {
198
- reader.u32le();
199
- reader.u32le();
200
- }
201
- if (fieldFlags & WINDOW_FIELD.WND_SIZE) {
202
- fields.width = signed32(reader.u32le());
203
- fields.height = signed32(reader.u32le());
204
- }
205
- if (fieldFlags & WINDOW_FIELD.WND_RECTS) {
206
- fields.windowRects = readRectangles(reader, reader.u16le());
207
- }
208
- if (fieldFlags & WINDOW_FIELD.VIS_OFFSET) {
209
- fields.visibleOffsetX = signed32(reader.u32le());
210
- fields.visibleOffsetY = signed32(reader.u32le());
211
- }
212
- if (fieldFlags & WINDOW_FIELD.VISIBILITY) {
213
- fields.visibilityRects = readRectangles(reader, reader.u16le());
214
- }
215
- return fields;
216
- }
217
- function isPrimaryWindow(candidate) {
218
- if (!candidate) return false;
219
- if (candidate.ownerWindowId) return false;
220
- if ((candidate.style || 0) & STYLE_CHILD) return false;
221
- if ((candidate.extendedStyle || 0) & (EX_STYLE_TOOLWINDOW | EX_STYLE_NOACTIVATE)) return false;
222
- return true;
223
- }
224
- function parseRemoteAppWindowOrders(reader) {
225
- if (reader.remaining < 6) throw new Error("RDP RemoteApp orders update is truncated.");
226
- reader.u16le();
227
- const numberOrders = reader.u16le();
228
- reader.u16le();
229
- const events = [];
230
- for (let index = 0; index < numberOrders && reader.remaining > 0; index++) {
231
- const orderStart = reader.offset;
232
- const controlFlags = reader.u8();
233
- const orderClass = controlFlags & DRAWING_ORDER_CLASS_MASK;
234
- const orderType = controlFlags >> 2;
235
- if (orderClass !== DRAWING_ORDER_ALT_SECONDARY || orderType !== ALTSEC_WINDOW) break;
236
- if (reader.remaining < 6) throw new Error("RDP RemoteApp window-order header is truncated.");
237
- const orderSize = reader.u16le();
238
- const fieldFlags = reader.u32le();
239
- const orderEnd = orderStart + orderSize;
240
- if (orderSize < 7 || orderEnd > reader.bytes.length) {
241
- throw new Error("RDP RemoteApp window order has an invalid size.");
242
- }
243
- const describesWindow = Boolean(fieldFlags & WINDOW_ORDER.TYPE_WINDOW);
244
- const isIconOrder = Boolean(fieldFlags & (WINDOW_ORDER.ICON | WINDOW_ORDER.CACHED_ICON));
245
- if (describesWindow && !isIconOrder && orderEnd - reader.offset >= 4) {
246
- const windowId = reader.u32le();
247
- let fields = {};
248
- try {
249
- fields = parseWindowFields(reader, fieldFlags);
250
- } catch (error) {
251
- console.warn("[RDP] Dropped an unreadable RemoteApp window order", {
252
- windowId,
253
- fieldFlags: `0x${(fieldFlags >>> 0).toString(16)}`,
254
- error: error instanceof Error ? error.message : String(error)
255
- });
256
- }
257
- let type = "update";
258
- if (fieldFlags & WINDOW_ORDER.STATE_DELETED) type = "deleted";
259
- else if (fieldFlags & WINDOW_ORDER.STATE_NEW) type = "new";
260
- events.push({ type, windowId, fieldFlags, ...fields });
261
- }
262
- reader.offset = orderEnd;
263
- if (reader.offset <= orderStart) break;
264
- }
265
- return events;
266
- }
267
- function parseRailPdus(bytes) {
268
- const reader = new Reader(bytes);
269
- const messages = [];
270
- while (reader.remaining >= 4) {
271
- const orderType = reader.u16le();
272
- const orderLength = reader.u16le();
273
- if (orderLength < 4 || orderLength - 4 > reader.remaining) {
274
- throw new Error("RDP RemoteApp channel delivered a malformed PDU.");
275
- }
276
- const body = new Reader(reader.raw(orderLength - 4));
277
- if (orderType === RAIL_ORDER.HANDSHAKE && body.remaining >= 4) {
278
- messages.push({ type: "handshake", buildNumber: body.u32le() });
279
- continue;
280
- }
281
- if (orderType === RAIL_ORDER.HANDSHAKE_EX && body.remaining >= 8) {
282
- messages.push({ type: "handshake", buildNumber: body.u32le(), flags: body.u32le(), extended: true });
283
- continue;
284
- }
285
- if (orderType === RAIL_ORDER.EXEC_RESULT && body.remaining >= 12) {
286
- const flags = body.u16le();
287
- const result = body.u16le();
288
- const rawResult = body.u32le();
289
- body.u16le();
290
- const nameLength = body.u16le();
291
- const program = decodeUtf16(body.raw(Math.min(nameLength, body.remaining)));
292
- messages.push({ type: "execute-result", flags, result, rawResult, program });
293
- continue;
294
- }
295
- messages.push({ type: "unknown", orderType, body: body.rest().slice() });
296
- }
297
- return messages;
298
- }
299
- class RailChannel {
300
- application;
301
- width;
302
- height;
303
- send;
304
- onReady;
305
- onResult;
306
- started;
307
- constructor({ application, width, height, send, onReady, onResult }) {
308
- this.application = application;
309
- this.width = width;
310
- this.height = height;
311
- this.send = send;
312
- this.onReady = onReady;
313
- this.onResult = onResult;
314
- this.started = false;
315
- }
316
- receive(bytes) {
317
- for (const message of parseRailPdus(bytes)) {
318
- if (message.type === "handshake") {
319
- if (this.started) continue;
320
- this.started = true;
321
- this.send(railHandshake(CLIENT_BUILD));
322
- this.send(railClientStatus());
323
- for (const systemParameter of railSystemParameters(this.width, this.height)) {
324
- this.send(systemParameter);
325
- }
326
- this.send(railExecute(this.application));
327
- this.onReady?.(message);
328
- continue;
329
- }
330
- if (message.type === "execute-result") {
331
- this.onResult?.({
332
- ...message,
333
- ok: message.result === 0,
334
- message: RAIL_EXEC_RESULT[message.result] || `The RemoteApp host returned launch result 0x${message.result.toString(16).padStart(4, "0")}.`
335
- });
336
- }
337
- }
338
- }
339
- /** Republish the client's work area, which is what maximize resizes into. */
340
- setWorkArea(width, height) {
341
- if (!this.started || width <= 0 || height <= 0) return false;
342
- if (width === this.width && height === this.height) return false;
343
- this.width = width;
344
- this.height = height;
345
- this.send(railWorkArea(width, height));
346
- return true;
347
- }
348
- activate(windowId) {
349
- if (!this.started) return false;
350
- this.send(railActivate(windowId, true));
351
- return true;
352
- }
353
- sysCommand(windowId, command) {
354
- if (!this.started) return false;
355
- this.send(railSysCommand(windowId, command));
356
- return true;
357
- }
358
- moveWindow(windowId, rectangle) {
359
- if (!this.started) return false;
360
- this.send(railWindowMove(windowId, rectangle));
361
- return true;
362
- }
363
- }
364
- export {
365
- RAIL_EXEC_RESULT,
366
- RAIL_ORDER,
367
- RailChannel,
368
- SHOW_STATE,
369
- SYS_COMMAND,
370
- WINDOW_ORDER,
371
- isPrimaryWindow,
372
- parseRailPdus,
373
- parseRemoteAppWindowOrders,
374
- railActivate,
375
- railClientStatus,
376
- railExecute,
377
- railHandshake,
378
- railSysCommand,
379
- railSystemParameters,
380
- railWindowMove,
381
- railWorkArea
382
- };
@@ -1,13 +0,0 @@
1
- export declare function rleDecompress(src: Uint8Array, width: number, height: number, bytesPerPixel: number): Uint32Array<ArrayBuffer>;
2
- /**
3
- * Reverse the row order of a decoded rectangle. RDP stores bitmaps bottom-up
4
- * and a canvas expects top-down, so without this every rectangle is painted
5
- * upside down.
6
- */
7
- export declare function flipRows(pixels: Uint8Array, width: number): Uint32Array<ArrayBuffer> | Uint8Array<ArrayBufferLike>;
8
- /** Read uncompressed bitmap data, which RDP stores bottom-up. */
9
- export declare function readUncompressed(src: Uint8Array, width: number, height: number, bytesPerPixel: number): Uint32Array<ArrayBuffer>;
10
- /** Expand raw pixel values into RGBA for putImageData. */
11
- export declare function pixelsToRgba(pixels: Uint8Array, bitsPerPixel: number, palette: Uint32Array): Uint8ClampedArray<ArrayBuffer>;
12
- /** Decode one TS_BITMAP_DATA rectangle to RGBA. */
13
- export declare function decodeBitmapRect(rect: BitmapRect, palette: Uint32Array): Uint8ClampedArray<ArrayBuffer>;
@@ -1,275 +0,0 @@
1
- const REGULAR_BG_RUN = 0;
2
- const REGULAR_FG_RUN = 1;
3
- const REGULAR_FGBG_IMAGE = 2;
4
- const REGULAR_COLOR_RUN = 3;
5
- const REGULAR_COLOR_IMAGE = 4;
6
- const LITE_SET_FG_FG_RUN = 12;
7
- const LITE_SET_FG_FGBG_IMAGE = 13;
8
- const LITE_DITHERED_RUN = 14;
9
- const MEGA_MEGA_BG_RUN = 240;
10
- const MEGA_MEGA_FG_RUN = 241;
11
- const MEGA_MEGA_FGBG_IMAGE = 242;
12
- const MEGA_MEGA_COLOR_RUN = 243;
13
- const MEGA_MEGA_COLOR_IMAGE = 244;
14
- const MEGA_MEGA_SET_FG_RUN = 246;
15
- const MEGA_MEGA_SET_FGBG_IMAGE = 247;
16
- const MEGA_MEGA_DITHERED_RUN = 248;
17
- const SPECIAL_FGBG_1 = 249;
18
- const SPECIAL_FGBG_2 = 250;
19
- const SPECIAL_WHITE = 253;
20
- const SPECIAL_BLACK = 254;
21
- const MASK_SPECIAL_FGBG_1 = 3;
22
- const MASK_SPECIAL_FGBG_2 = 5;
23
- function extractCodeId(header) {
24
- if ((header & 192) !== 192) return header >> 5;
25
- if ((header & 240) === 240) return header;
26
- return header >> 4;
27
- }
28
- function rleDecompress(src, width, height, bytesPerPixel) {
29
- const pixels = new Uint32Array(width * height);
30
- const white = bytesPerPixel >= 4 ? 4294967295 : (1 << bytesPerPixel * 8) - 1;
31
- let srcOffset = 0;
32
- let dest = 0;
33
- let foreground = white;
34
- let insertForegroundPixel = false;
35
- let firstLine = true;
36
- const readPixel = () => {
37
- let value = 0;
38
- for (let i = 0; i < bytesPerPixel; i++) value |= src[srcOffset + i] << i * 8;
39
- srcOffset += bytesPerPixel;
40
- return value >>> 0;
41
- };
42
- const runLengthOf = (code) => {
43
- const header = src[srcOffset];
44
- if (code === REGULAR_FGBG_IMAGE) {
45
- const packed = header & 31;
46
- if (packed === 0) {
47
- srcOffset += 2;
48
- return src[srcOffset - 1] + 1;
49
- }
50
- srcOffset += 1;
51
- return packed * 8;
52
- }
53
- if (code === LITE_SET_FG_FGBG_IMAGE) {
54
- const packed = header & 15;
55
- if (packed === 0) {
56
- srcOffset += 2;
57
- return src[srcOffset - 1] + 1;
58
- }
59
- srcOffset += 1;
60
- return packed * 8;
61
- }
62
- if (code === REGULAR_BG_RUN || code === REGULAR_FG_RUN || code === REGULAR_COLOR_RUN || code === REGULAR_COLOR_IMAGE) {
63
- const packed = header & 31;
64
- if (packed === 0) {
65
- srcOffset += 2;
66
- return src[srcOffset - 1] + 32;
67
- }
68
- srcOffset += 1;
69
- return packed;
70
- }
71
- if (code === LITE_SET_FG_FG_RUN || code === LITE_DITHERED_RUN) {
72
- const packed = header & 15;
73
- if (packed === 0) {
74
- srcOffset += 2;
75
- return src[srcOffset - 1] + 16;
76
- }
77
- srcOffset += 1;
78
- return packed;
79
- }
80
- const length = src[srcOffset + 1] | src[srcOffset + 2] << 8;
81
- srcOffset += 3;
82
- return length;
83
- };
84
- const writeFgBgImage = (bitmask, count) => {
85
- let mask = 1;
86
- for (let i = 0; i < count; i++) {
87
- if (firstLine) {
88
- pixels[dest] = bitmask & mask ? foreground : 0;
89
- } else {
90
- const above = pixels[dest - width];
91
- pixels[dest] = bitmask & mask ? (above ^ foreground) >>> 0 : above;
92
- }
93
- dest++;
94
- mask = mask << 1 & 255;
95
- }
96
- };
97
- while (srcOffset < src.length && dest < pixels.length) {
98
- if (firstLine && dest >= width) firstLine = false;
99
- const code = extractCodeId(src[srcOffset]);
100
- if (code === REGULAR_BG_RUN || code === MEGA_MEGA_BG_RUN) {
101
- let runLength = runLengthOf(code);
102
- if (firstLine) {
103
- if (insertForegroundPixel) {
104
- pixels[dest++] = foreground;
105
- runLength--;
106
- }
107
- while (runLength-- > 0 && dest < pixels.length) pixels[dest++] = 0;
108
- } else {
109
- if (insertForegroundPixel) {
110
- pixels[dest] = (pixels[dest - width] ^ foreground) >>> 0;
111
- dest++;
112
- runLength--;
113
- }
114
- while (runLength-- > 0 && dest < pixels.length) {
115
- pixels[dest] = pixels[dest - width];
116
- dest++;
117
- }
118
- }
119
- insertForegroundPixel = true;
120
- continue;
121
- }
122
- insertForegroundPixel = false;
123
- switch (code) {
124
- case REGULAR_FG_RUN:
125
- case MEGA_MEGA_FG_RUN:
126
- case LITE_SET_FG_FG_RUN:
127
- case MEGA_MEGA_SET_FG_RUN: {
128
- let runLength = runLengthOf(code);
129
- if (code === LITE_SET_FG_FG_RUN || code === MEGA_MEGA_SET_FG_RUN) foreground = readPixel();
130
- if (firstLine) {
131
- while (runLength-- > 0 && dest < pixels.length) pixels[dest++] = foreground;
132
- } else {
133
- while (runLength-- > 0 && dest < pixels.length) {
134
- pixels[dest] = (pixels[dest - width] ^ foreground) >>> 0;
135
- dest++;
136
- }
137
- }
138
- break;
139
- }
140
- case LITE_DITHERED_RUN:
141
- case MEGA_MEGA_DITHERED_RUN: {
142
- let runLength = runLengthOf(code);
143
- const pixelA = readPixel();
144
- const pixelB = readPixel();
145
- while (runLength-- > 0 && dest < pixels.length - 1) {
146
- pixels[dest++] = pixelA;
147
- pixels[dest++] = pixelB;
148
- }
149
- break;
150
- }
151
- case REGULAR_COLOR_RUN:
152
- case MEGA_MEGA_COLOR_RUN: {
153
- let runLength = runLengthOf(code);
154
- const color = readPixel();
155
- while (runLength-- > 0 && dest < pixels.length) pixels[dest++] = color;
156
- break;
157
- }
158
- case REGULAR_FGBG_IMAGE:
159
- case MEGA_MEGA_FGBG_IMAGE:
160
- case LITE_SET_FG_FGBG_IMAGE:
161
- case MEGA_MEGA_SET_FGBG_IMAGE: {
162
- let runLength = runLengthOf(code);
163
- if (code === LITE_SET_FG_FGBG_IMAGE || code === MEGA_MEGA_SET_FGBG_IMAGE) {
164
- foreground = readPixel();
165
- }
166
- while (runLength > 8) {
167
- writeFgBgImage(src[srcOffset++], 8);
168
- runLength -= 8;
169
- }
170
- if (runLength > 0) writeFgBgImage(src[srcOffset++], runLength);
171
- break;
172
- }
173
- case REGULAR_COLOR_IMAGE:
174
- case MEGA_MEGA_COLOR_IMAGE: {
175
- let runLength = runLengthOf(code);
176
- while (runLength-- > 0 && dest < pixels.length) pixels[dest++] = readPixel();
177
- break;
178
- }
179
- case SPECIAL_FGBG_1:
180
- srcOffset++;
181
- writeFgBgImage(MASK_SPECIAL_FGBG_1, 8);
182
- break;
183
- case SPECIAL_FGBG_2:
184
- srcOffset++;
185
- writeFgBgImage(MASK_SPECIAL_FGBG_2, 8);
186
- break;
187
- case SPECIAL_WHITE:
188
- srcOffset++;
189
- pixels[dest++] = white;
190
- break;
191
- case SPECIAL_BLACK:
192
- srcOffset++;
193
- pixels[dest++] = 0;
194
- break;
195
- default:
196
- throw new Error(`RDP: unsupported bitmap compression order 0x${code.toString(16)}`);
197
- }
198
- }
199
- return pixels;
200
- }
201
- function flipRows(pixels, width) {
202
- if (width <= 0) return pixels;
203
- const height = Math.floor(pixels.length / width);
204
- if (height < 2) return pixels;
205
- const flipped = new Uint32Array(pixels.length);
206
- for (let y = 0; y < height; y++) {
207
- flipped.set(pixels.subarray(y * width, (y + 1) * width), (height - 1 - y) * width);
208
- }
209
- return flipped;
210
- }
211
- function readUncompressed(src, width, height, bytesPerPixel) {
212
- const pixels = new Uint32Array(width * height);
213
- for (let y = 0; y < height; y++) {
214
- const destRow = (height - 1 - y) * width;
215
- let offset = y * width * bytesPerPixel;
216
- for (let x = 0; x < width; x++) {
217
- let value = 0;
218
- for (let i = 0; i < bytesPerPixel; i++) value |= src[offset + i] << i * 8;
219
- pixels[destRow + x] = value >>> 0;
220
- offset += bytesPerPixel;
221
- }
222
- }
223
- return pixels;
224
- }
225
- function pixelsToRgba(pixels, bitsPerPixel, palette) {
226
- const rgba = new Uint8ClampedArray(pixels.length * 4);
227
- for (let i = 0; i < pixels.length; i++) {
228
- const value = pixels[i];
229
- let r;
230
- let g;
231
- let b;
232
- switch (bitsPerPixel) {
233
- case 15:
234
- r = (value >> 10 & 31) * 255 / 31;
235
- g = (value >> 5 & 31) * 255 / 31;
236
- b = (value & 31) * 255 / 31;
237
- break;
238
- case 16:
239
- r = (value >> 11 & 31) * 255 / 31;
240
- g = (value >> 5 & 63) * 255 / 63;
241
- b = (value & 31) * 255 / 31;
242
- break;
243
- case 8: {
244
- const index = (value & 255) * 3;
245
- r = palette ? palette[index] : value;
246
- g = palette ? palette[index + 1] : value;
247
- b = palette ? palette[index + 2] : value;
248
- break;
249
- }
250
- default:
251
- r = value >> 16 & 255;
252
- g = value >> 8 & 255;
253
- b = value & 255;
254
- break;
255
- }
256
- const offset = i * 4;
257
- rgba[offset] = r;
258
- rgba[offset + 1] = g;
259
- rgba[offset + 2] = b;
260
- rgba[offset + 3] = 255;
261
- }
262
- return rgba;
263
- }
264
- function decodeBitmapRect(rect, palette) {
265
- const bytesPerPixel = Math.max(1, Math.ceil(rect.bitsPerPixel / 8));
266
- const pixels = rect.compressed ? flipRows(rleDecompress(rect.data, rect.width, rect.height, bytesPerPixel), rect.width) : readUncompressed(rect.data, rect.width, rect.height, bytesPerPixel);
267
- return pixelsToRgba(pixels, rect.bitsPerPixel, palette);
268
- }
269
- export {
270
- decodeBitmapRect,
271
- flipRows,
272
- pixelsToRgba,
273
- readUncompressed,
274
- rleDecompress
275
- };