We don't know how long the caller will hang on to this data, so we need to be safe by default and assume it will kept indefinitely. That means we can't return a reference to the internal buffer, as that will get overwritten with future messages. We want to avoid unnecessary copying in performance critical code, though. So allow code to explicitly ask for a shared buffer, assuming they know the data needs to be consumed immediately.
60 lines
1.6 KiB
JavaScript
60 lines
1.6 KiB
JavaScript
/*
|
|
* noVNC: HTML5 VNC client
|
|
* Copyright (C) 2019 The noVNC Authors
|
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
|
*
|
|
* See README.md for usage and integration instructions.
|
|
*
|
|
*/
|
|
|
|
export default class RawDecoder {
|
|
constructor() {
|
|
this._lines = 0;
|
|
}
|
|
|
|
decodeRect(x, y, width, height, sock, display, depth) {
|
|
if ((width === 0) || (height === 0)) {
|
|
return true;
|
|
}
|
|
|
|
if (this._lines === 0) {
|
|
this._lines = height;
|
|
}
|
|
|
|
const pixelSize = depth == 8 ? 1 : 4;
|
|
const bytesPerLine = width * pixelSize;
|
|
|
|
while (this._lines > 0) {
|
|
if (sock.rQwait("RAW", bytesPerLine)) {
|
|
return false;
|
|
}
|
|
|
|
const curY = y + (height - this._lines);
|
|
|
|
let data = sock.rQshiftBytes(bytesPerLine, false);
|
|
|
|
// Convert data if needed
|
|
if (depth == 8) {
|
|
const newdata = new Uint8Array(width * 4);
|
|
for (let i = 0; i < width; i++) {
|
|
newdata[i * 4 + 0] = ((data[i] >> 0) & 0x3) * 255 / 3;
|
|
newdata[i * 4 + 1] = ((data[i] >> 2) & 0x3) * 255 / 3;
|
|
newdata[i * 4 + 2] = ((data[i] >> 4) & 0x3) * 255 / 3;
|
|
newdata[i * 4 + 3] = 255;
|
|
}
|
|
data = newdata;
|
|
}
|
|
|
|
// Max sure the image is fully opaque
|
|
for (let i = 0; i < width; i++) {
|
|
data[i * 4 + 3] = 255;
|
|
}
|
|
|
|
display.blitImage(x, curY, width, 1, data, 0);
|
|
this._lines--;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|