Implement gradient filter of tight decoder, fixing issue #1767
This commit is a basic implementation of the gradient filter required by qemu `lossy` option.
This commit is contained in:
parent
10ee10ce56
commit
c187b2e5e0
|
@ -285,7 +285,73 @@ export default class TightDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
_gradientFilter(streamId, x, y, width, height, sock, display, depth) {
|
_gradientFilter(streamId, x, y, width, height, sock, display, depth) {
|
||||||
throw new Error("Gradient filter not implemented");
|
// assume the TPIXEL is 3 bytes long
|
||||||
|
const uncompressedSize = width * height * 3;
|
||||||
|
let data;
|
||||||
|
|
||||||
|
if (uncompressedSize === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uncompressedSize < 12) {
|
||||||
|
if (sock.rQwait("TIGHT", uncompressedSize)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = sock.rQshiftBytes(uncompressedSize);
|
||||||
|
} else {
|
||||||
|
data = this._readData(sock);
|
||||||
|
if (data === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._zlibs[streamId].setInput(data);
|
||||||
|
data = this._zlibs[streamId].inflate(uncompressedSize);
|
||||||
|
this._zlibs[streamId].setInput(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rgbx = new Uint8Array(4 * width * height);
|
||||||
|
|
||||||
|
let rgbxIndex = 0, dataIndex = 0;
|
||||||
|
let left = new Uint8Array(3);
|
||||||
|
for (let x = 0; x < width; x++) {
|
||||||
|
for (let c = 0; c < 3; c++) {
|
||||||
|
const prediction = left[c];
|
||||||
|
const value = data[dataIndex++] + prediction;
|
||||||
|
rgbx[rgbxIndex++] = value;
|
||||||
|
left[c] = value;
|
||||||
|
}
|
||||||
|
rgbx[rgbxIndex++] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
let upperIndex = 0;
|
||||||
|
let upper = new Uint8Array(3),
|
||||||
|
upperleft = new Uint8Array(3);
|
||||||
|
for (let y = 1; y < height; y++) {
|
||||||
|
left.fill(0);
|
||||||
|
upperleft.fill(0);
|
||||||
|
for (let x = 0; x < width; x++) {
|
||||||
|
for (let c = 0; c < 3; c++) {
|
||||||
|
upper[c] = rgbx[upperIndex++];
|
||||||
|
let prediction = left[c] + upper[c] - upperleft[c];
|
||||||
|
if (prediction < 0) {
|
||||||
|
prediction = 0;
|
||||||
|
} else if (prediction > 255) {
|
||||||
|
prediction = 255;
|
||||||
|
}
|
||||||
|
const value = data[dataIndex++] + prediction;
|
||||||
|
rgbx[rgbxIndex++] = value;
|
||||||
|
upperleft[c] = upper[c];
|
||||||
|
left[c] = value;
|
||||||
|
}
|
||||||
|
rgbx[rgbxIndex++] = 255;
|
||||||
|
upperIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display.blitImage(x, y, width, height, rgbx, 0, false);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_readData(sock) {
|
_readData(sock) {
|
||||||
|
|
Loading…
Reference in New Issue