JavaScript 65.5%
Python 17.8%
CSS 13%
HTML 3.7%
1/*2 * noVNC: HTML5 VNC client3 * Copyright (C) 2019 The noVNC authors4 * Licensed under MPL 2.0 (see LICENSE.txt)5 *6 * See README.md for usage and integration instructions.7 *8 */910import * as Log from '../util/logging.js';1112export default class HextileDecoder {13 constructor() {14 this._tiles = 0;15 this._lastsubencoding = 0;16 this._tileBuffer = new Uint8Array(16 * 16 * 4);17 }1819 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;25 }2627 while (this._tiles > 0) {28 let bytes = 1;2930 if (sock.rQwait("HEXTILE", bytes)) {31 return false;32 }3334 let subencoding = sock.rQpeek8();35 if (subencoding > 30) { // Raw36 throw new Error("Illegal hextile subencoding (subencoding: " +37 subencoding + ")");38 }3940 const currTile = this._totalTiles - this._tiles;41 const tileX = currTile % this._tilesX;42 const tileY = Math.floor(currTile / this._tilesX);43 const tx = x + tileX * 16;44 const ty = y + tileY * 16;45 const tw = Math.min(16, (x + width) - tx);46 const th = Math.min(16, (y + height) - ty);4748 // Figure out how much we are expecting49 if (subencoding & 0x01) { // Raw50 bytes += tw * th * 4;51 } else {52 if (subencoding & 0x02) { // Background53 bytes += 4;54 }55 if (subencoding & 0x04) { // Foreground56 bytes += 4;57 }58 if (subencoding & 0x08) { // AnySubrects59 bytes++; // Since we aren't shifting it off6061 if (sock.rQwait("HEXTILE", bytes)) {62 return false;63 }6465 let subrects = sock.rQpeekBytes(bytes).at(-1);66 if (subencoding & 0x10) { // SubrectsColoured67 bytes += subrects * (4 + 2);68 } else {69 bytes += subrects * 2;70 }71 }72 }7374 if (sock.rQwait("HEXTILE", bytes)) {75 return false;76 }7778 // We know the encoding and have a whole tile79 sock.rQshift8();80 if (subencoding === 0) {81 if (this._lastsubencoding & 0x01) {82 // Weird: ignore blanks are RAW83 Log.Debug(" Ignoring blank after RAW");84 } else {85 display.fillRect(tx, ty, tw, th, this._background);86 }87 } else if (subencoding & 0x01) { // Raw88 let pixels = tw * th;89 let data = sock.rQshiftBytes(pixels * 4, false);90 // Max sure the image is fully opaque91 for (let i = 0;i < pixels;i++) {92 data[i * 4 + 3] = 255;93 }94 display.blitImage(tx, ty, tw, th, data, 0);95 } else {96 if (subencoding & 0x02) { // Background97 this._background = new Uint8Array(sock.rQshiftBytes(4));98 }99 if (subencoding & 0x04) { // Foreground100 this._foreground = new Uint8Array(sock.rQshiftBytes(4));101 }102103 this._startTile(tx, ty, tw, th, this._background);104 if (subencoding & 0x08) { // AnySubrects105 let subrects = sock.rQshift8();106107 for (let s = 0; s < subrects; s++) {108 let color;109 if (subencoding & 0x10) { // SubrectsColoured110 color = sock.rQshiftBytes(4);111 } else {112 color = this._foreground;113 }114 const xy = sock.rQshift8();115 const sx = (xy >> 4);116 const sy = (xy & 0x0f);117118 const wh = sock.rQshift8();119 const sw = (wh >> 4) + 1;120 const sh = (wh & 0x0f) + 1;121122 this._subTile(sx, sy, sw, sh, color);123 }124 }125 this._finishTile(display);126 }127 this._lastsubencoding = subencoding;128 this._tiles--;129 }130131 return true;132 }133134 // start updating a tile135 _startTile(x, y, width, height, color) {136 this._tileX = x;137 this._tileY = y;138 this._tileW = width;139 this._tileH = height;140141 const red = color[0];142 const green = color[1];143 const blue = color[2];144145 const data = this._tileBuffer;146 for (let i = 0; i < width * height * 4; i += 4) {147 data[i] = red;148 data[i + 1] = green;149 data[i + 2] = blue;150 data[i + 3] = 255;151 }152 }153154 // update sub-rectangle of the current tile155 _subTile(x, y, w, h, color) {156 const red = color[0];157 const green = color[1];158 const blue = color[2];159 const xend = x + w;160 const yend = y + h;161162 const data = this._tileBuffer;163 const width = this._tileW;164 for (let j = y; j < yend; j++) {165 for (let i = x; i < xend; i++) {166 const p = (i + (j * width)) * 4;167 data[p] = red;168 data[p + 1] = green;169 data[p + 2] = blue;170 data[p + 3] = 255;171 }172 }173 }174175 // draw the current tile to the screen176 _finishTile(display) {177 display.blitImage(this._tileX, this._tileY,178 this._tileW, this._tileH,179 this._tileBuffer, 0);180 }181}182