]>
git.proxmox.com Git - mirror_novnc.git/blob - core/decoders/hextile.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2019 The noVNC Authors
4 * Licensed under MPL 2.0 (see LICENSE.txt)
6 * See README.md for usage and integration instructions.
10 import * as Log
from '../util/logging.js';
12 export default class HextileDecoder
{
15 this._lastsubencoding
= 0;
16 this._tileBuffer
= new Uint8Array(16 * 16 * 4);
19 decodeRect(x
, y
, width
, height
, sock
, display
, depth
) {
20 if (this._tiles
=== 0) {
21 this._tilesX
= Math
.ceil(width
/ 16);
22 this._tilesY
= Math
.ceil(height
/ 16);
23 this._totalTiles
= this._tilesX
* this._tilesY
;
24 this._tiles
= this._totalTiles
;
27 while (this._tiles
> 0) {
30 if (sock
.rQwait("HEXTILE", bytes
)) {
37 let subencoding
= rQ
[rQi
]; // Peek
38 if (subencoding
> 30) { // Raw
39 throw new Error("Illegal hextile subencoding (subencoding: " +
43 const currTile
= this._totalTiles
- this._tiles
;
44 const tileX
= currTile
% this._tilesX
;
45 const tileY
= Math
.floor(currTile
/ this._tilesX
);
46 const tx
= x
+ tileX
* 16;
47 const ty
= y
+ tileY
* 16;
48 const tw
= Math
.min(16, (x
+ width
) - tx
);
49 const th
= Math
.min(16, (y
+ height
) - ty
);
51 // Figure out how much we are expecting
52 if (subencoding
& 0x01) { // Raw
55 if (subencoding
& 0x02) { // Background
58 if (subencoding
& 0x04) { // Foreground
61 if (subencoding
& 0x08) { // AnySubrects
62 bytes
++; // Since we aren't shifting it off
64 if (sock
.rQwait("HEXTILE", bytes
)) {
68 let subrects
= rQ
[rQi
+ bytes
- 1]; // Peek
69 if (subencoding
& 0x10) { // SubrectsColoured
70 bytes
+= subrects
* (4 + 2);
72 bytes
+= subrects
* 2;
77 if (sock
.rQwait("HEXTILE", bytes
)) {
81 // We know the encoding and have a whole tile
83 if (subencoding
=== 0) {
84 if (this._lastsubencoding
& 0x01) {
85 // Weird: ignore blanks are RAW
86 Log
.Debug(" Ignoring blank after RAW");
88 display
.fillRect(tx
, ty
, tw
, th
, this._background
);
90 } else if (subencoding
& 0x01) { // Raw
91 display
.blitImage(tx
, ty
, tw
, th
, rQ
, rQi
);
94 if (subencoding
& 0x02) { // Background
95 this._background
= [rQ
[rQi
], rQ
[rQi
+ 1], rQ
[rQi
+ 2], rQ
[rQi
+ 3]];
98 if (subencoding
& 0x04) { // Foreground
99 this._foreground
= [rQ
[rQi
], rQ
[rQi
+ 1], rQ
[rQi
+ 2], rQ
[rQi
+ 3]];
103 this._startTile(tx
, ty
, tw
, th
, this._background
);
104 if (subencoding
& 0x08) { // AnySubrects
105 let subrects
= rQ
[rQi
];
108 for (let s
= 0; s
< subrects
; s
++) {
110 if (subencoding
& 0x10) { // SubrectsColoured
111 color
= [rQ
[rQi
], rQ
[rQi
+ 1], rQ
[rQi
+ 2], rQ
[rQi
+ 3]];
114 color
= this._foreground
;
118 const sx
= (xy
>> 4);
119 const sy
= (xy
& 0x0f);
123 const sw
= (wh
>> 4) + 1;
124 const sh
= (wh
& 0x0f) + 1;
126 this._subTile(sx
, sy
, sw
, sh
, color
);
129 this._finishTile(display
);
132 this._lastsubencoding
= subencoding
;
139 // start updating a tile
140 _startTile(x
, y
, width
, height
, color
) {
144 this._tileH
= height
;
146 const red
= color
[2];
147 const green
= color
[1];
148 const blue
= color
[0];
150 const data
= this._tileBuffer
;
151 for (let i
= 0; i
< width
* height
* 4; i
+= 4) {
159 // update sub-rectangle of the current tile
160 _subTile(x
, y
, w
, h
, color
) {
161 const red
= color
[2];
162 const green
= color
[1];
163 const blue
= color
[0];
167 const data
= this._tileBuffer
;
168 const width
= this._tileW
;
169 for (let j
= y
; j
< yend
; j
++) {
170 for (let i
= x
; i
< xend
; i
++) {
171 const p
= (i
+ (j
* width
)) * 4;
180 // draw the current tile to the screen
181 _finishTile(display
) {
182 display
.blitImage(this._tileX
, this._tileY
,
183 this._tileW
, this._tileH
,
184 this._tileBuffer
, 0);