@novnc/novnc 1.3.0-beta → 1.3.0-g145d235
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.
- package/README.md +13 -3
- package/core/decoders/jpeg.js +141 -0
- package/core/decoders/raw.js +1 -1
- package/core/decoders/zrle.js +185 -0
- package/core/display.js +12 -0
- package/core/encodings.js +4 -0
- package/core/ra2.js +567 -0
- package/core/rfb.js +372 -80
- package/core/util/md5.js +79 -0
- package/docs/API.md +105 -4
- package/lib/base64.js +21 -36
- package/lib/decoders/copyrect.js +2 -13
- package/lib/decoders/hextile.js +14 -46
- package/lib/decoders/jpeg.js +145 -0
- package/lib/decoders/raw.js +7 -24
- package/lib/decoders/rre.js +2 -17
- package/lib/decoders/tight.js +10 -78
- package/lib/decoders/tightpng.js +5 -27
- package/lib/decoders/zrle.js +185 -0
- package/lib/deflator.js +5 -22
- package/lib/des.js +20 -36
- package/lib/display.js +59 -107
- package/lib/encodings.js +7 -8
- package/lib/inflator.js +2 -18
- package/lib/input/domkeytable.js +77 -48
- package/lib/input/fixedkeys.js +8 -3
- package/lib/input/gesturehandler.js +82 -152
- package/lib/input/keyboard.js +50 -90
- package/lib/input/keysym.js +15 -272
- package/lib/input/keysymdef.js +5 -7
- package/lib/input/util.js +44 -86
- package/lib/input/vkeys.js +0 -3
- package/lib/input/xtscancodes.js +2 -170
- package/lib/ra2.js +1033 -0
- package/lib/rfb.js +681 -919
- package/lib/util/browser.js +24 -29
- package/lib/util/cursor.js +21 -65
- package/lib/util/element.js +3 -5
- package/lib/util/events.js +25 -32
- package/lib/util/eventtarget.js +2 -15
- package/lib/util/int.js +2 -3
- package/lib/util/logging.js +3 -21
- package/lib/util/md5.js +83 -0
- package/lib/util/strings.js +3 -5
- package/lib/vendor/pako/lib/utils/common.js +10 -19
- package/lib/vendor/pako/lib/zlib/adler32.js +3 -7
- package/lib/vendor/pako/lib/zlib/constants.js +2 -5
- package/lib/vendor/pako/lib/zlib/crc32.js +5 -12
- package/lib/vendor/pako/lib/zlib/deflate.js +218 -622
- package/lib/vendor/pako/lib/zlib/gzheader.js +1 -13
- package/lib/vendor/pako/lib/zlib/inffast.js +60 -172
- package/lib/vendor/pako/lib/zlib/inflate.js +407 -874
- package/lib/vendor/pako/lib/zlib/inftrees.js +63 -169
- package/lib/vendor/pako/lib/zlib/messages.js +1 -11
- package/lib/vendor/pako/lib/zlib/trees.js +248 -590
- package/lib/vendor/pako/lib/zlib/zstream.js +2 -18
- package/lib/websock.js +33 -86
- package/package.json +2 -7
package/README.md
CHANGED
|
@@ -113,8 +113,13 @@ proxy.
|
|
|
113
113
|
used to specify the location of a running VNC server:
|
|
114
114
|
|
|
115
115
|
`./utils/novnc_proxy --vnc localhost:5901`
|
|
116
|
+
|
|
117
|
+
* If you don't need to expose the web server to public internet, you can
|
|
118
|
+
bind to localhost:
|
|
119
|
+
|
|
120
|
+
`./utils/novnc_proxy --vnc localhost:5901 --listen localhost:6081`
|
|
116
121
|
|
|
117
|
-
* Point your browser to the cut-and-paste URL that is output by the `
|
|
122
|
+
* Point your browser to the cut-and-paste URL that is output by the `novnc_proxy`
|
|
118
123
|
script. Hit the Connect button, enter a password if the VNC server has one
|
|
119
124
|
configured, and enjoy!
|
|
120
125
|
|
|
@@ -123,13 +128,17 @@ Running the command below will install the latest release of noVNC from Snap:
|
|
|
123
128
|
|
|
124
129
|
`sudo snap install novnc`
|
|
125
130
|
|
|
126
|
-
#### Running noVNC
|
|
131
|
+
#### Running noVNC from Snap Directly
|
|
127
132
|
|
|
128
133
|
You can run the Snap-package installed novnc directly with, for example:
|
|
129
134
|
|
|
130
135
|
`novnc --listen 6081 --vnc localhost:5901 # /snap/bin/novnc if /snap/bin is not in your PATH`
|
|
131
136
|
|
|
132
|
-
|
|
137
|
+
If you want to use certificate files, due to standard Snap confinement restrictions you need to have them in the /home/\<user\>/snap/novnc/current/ directory. If your username is jsmith an example command would be:
|
|
138
|
+
|
|
139
|
+
`novnc --listen 8443 --cert ~jsmith/snap/novnc/current/self.crt --key ~jsmith/snap/novnc/current/self.key --vnc ubuntu.example.com:5901`
|
|
140
|
+
|
|
141
|
+
#### Running noVNC from Snap as a Service (Daemon)
|
|
133
142
|
The Snap package also has the capability to run a 'novnc' service which can be
|
|
134
143
|
configured to listen on multiple ports connecting to multiple VNC servers
|
|
135
144
|
(effectively a service runing multiple instances of novnc).
|
|
@@ -203,6 +212,7 @@ that list and you think you should be, feel free to send a PR to fix that.
|
|
|
203
212
|
* UI and Icons : Pierre Ossman, Chris Gordon
|
|
204
213
|
* Original Logo : Michael Sersen
|
|
205
214
|
* tight encoding : Michael Tinglof (Mercuri.ca)
|
|
215
|
+
* RealVNC RSA AES authentication : USTC Vlab Team
|
|
206
216
|
|
|
207
217
|
* Included libraries:
|
|
208
218
|
* base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* noVNC: HTML5 VNC client
|
|
3
|
+
* Copyright (C) 2019 The noVNC Authors
|
|
4
|
+
* Licensed under MPL 2.0 (see LICENSE.txt)
|
|
5
|
+
*
|
|
6
|
+
* See README.md for usage and integration instructions.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export default class JPEGDecoder {
|
|
11
|
+
constructor() {
|
|
12
|
+
// RealVNC will reuse the quantization tables
|
|
13
|
+
// and Huffman tables, so we need to cache them.
|
|
14
|
+
this._quantTables = [];
|
|
15
|
+
this._huffmanTables = [];
|
|
16
|
+
this._cachedQuantTables = [];
|
|
17
|
+
this._cachedHuffmanTables = [];
|
|
18
|
+
|
|
19
|
+
this._jpegLength = 0;
|
|
20
|
+
this._segments = [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
decodeRect(x, y, width, height, sock, display, depth) {
|
|
24
|
+
// A rect of JPEG encodings is simply a JPEG file
|
|
25
|
+
if (!this._parseJPEG(sock.rQslice(0))) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const data = sock.rQshiftBytes(this._jpegLength);
|
|
29
|
+
if (this._quantTables.length != 0 && this._huffmanTables.length != 0) {
|
|
30
|
+
// If there are quantization tables and Huffman tables in the JPEG
|
|
31
|
+
// image, we can directly render it.
|
|
32
|
+
display.imageRect(x, y, width, height, "image/jpeg", data);
|
|
33
|
+
return true;
|
|
34
|
+
} else {
|
|
35
|
+
// Otherwise we need to insert cached tables.
|
|
36
|
+
const sofIndex = this._segments.findIndex(
|
|
37
|
+
x => x[1] == 0xC0 || x[1] == 0xC2
|
|
38
|
+
);
|
|
39
|
+
if (sofIndex == -1) {
|
|
40
|
+
throw new Error("Illegal JPEG image without SOF");
|
|
41
|
+
}
|
|
42
|
+
let segments = this._segments.slice(0, sofIndex);
|
|
43
|
+
segments = segments.concat(this._quantTables.length ?
|
|
44
|
+
this._quantTables :
|
|
45
|
+
this._cachedQuantTables);
|
|
46
|
+
segments.push(this._segments[sofIndex]);
|
|
47
|
+
segments = segments.concat(this._huffmanTables.length ?
|
|
48
|
+
this._huffmanTables :
|
|
49
|
+
this._cachedHuffmanTables,
|
|
50
|
+
this._segments.slice(sofIndex + 1));
|
|
51
|
+
let length = 0;
|
|
52
|
+
for (let i = 0; i < segments.length; i++) {
|
|
53
|
+
length += segments[i].length;
|
|
54
|
+
}
|
|
55
|
+
const data = new Uint8Array(length);
|
|
56
|
+
length = 0;
|
|
57
|
+
for (let i = 0; i < segments.length; i++) {
|
|
58
|
+
data.set(segments[i], length);
|
|
59
|
+
length += segments[i].length;
|
|
60
|
+
}
|
|
61
|
+
display.imageRect(x, y, width, height, "image/jpeg", data);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_parseJPEG(buffer) {
|
|
67
|
+
if (this._quantTables.length != 0) {
|
|
68
|
+
this._cachedQuantTables = this._quantTables;
|
|
69
|
+
}
|
|
70
|
+
if (this._huffmanTables.length != 0) {
|
|
71
|
+
this._cachedHuffmanTables = this._huffmanTables;
|
|
72
|
+
}
|
|
73
|
+
this._quantTables = [];
|
|
74
|
+
this._huffmanTables = [];
|
|
75
|
+
this._segments = [];
|
|
76
|
+
let i = 0;
|
|
77
|
+
let bufferLength = buffer.length;
|
|
78
|
+
while (true) {
|
|
79
|
+
let j = i;
|
|
80
|
+
if (j + 2 > bufferLength) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (buffer[j] != 0xFF) {
|
|
84
|
+
throw new Error("Illegal JPEG marker received (byte: " +
|
|
85
|
+
buffer[j] + ")");
|
|
86
|
+
}
|
|
87
|
+
const type = buffer[j+1];
|
|
88
|
+
j += 2;
|
|
89
|
+
if (type == 0xD9) {
|
|
90
|
+
this._jpegLength = j;
|
|
91
|
+
this._segments.push(buffer.slice(i, j));
|
|
92
|
+
return true;
|
|
93
|
+
} else if (type == 0xDA) {
|
|
94
|
+
// start of scan
|
|
95
|
+
let hasFoundEndOfScan = false;
|
|
96
|
+
for (let k = j + 3; k + 1 < bufferLength; k++) {
|
|
97
|
+
if (buffer[k] == 0xFF && buffer[k+1] != 0x00 &&
|
|
98
|
+
!(buffer[k+1] >= 0xD0 && buffer[k+1] <= 0xD7)) {
|
|
99
|
+
j = k;
|
|
100
|
+
hasFoundEndOfScan = true;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!hasFoundEndOfScan) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
this._segments.push(buffer.slice(i, j));
|
|
108
|
+
i = j;
|
|
109
|
+
continue;
|
|
110
|
+
} else if (type >= 0xD0 && type < 0xD9 || type == 0x01) {
|
|
111
|
+
// No length after marker
|
|
112
|
+
this._segments.push(buffer.slice(i, j));
|
|
113
|
+
i = j;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (j + 2 > bufferLength) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const length = (buffer[j] << 8) + buffer[j+1] - 2;
|
|
120
|
+
if (length < 0) {
|
|
121
|
+
throw new Error("Illegal JPEG length received (length: " +
|
|
122
|
+
length + ")");
|
|
123
|
+
}
|
|
124
|
+
j += 2;
|
|
125
|
+
if (j + length > bufferLength) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
j += length;
|
|
129
|
+
const segment = buffer.slice(i, j);
|
|
130
|
+
if (type == 0xC4) {
|
|
131
|
+
// Huffman tables
|
|
132
|
+
this._huffmanTables.push(segment);
|
|
133
|
+
} else if (type == 0xDB) {
|
|
134
|
+
// Quantization tables
|
|
135
|
+
this._quantTables.push(segment);
|
|
136
|
+
}
|
|
137
|
+
this._segments.push(segment);
|
|
138
|
+
i = j;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
package/core/decoders/raw.js
CHANGED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* noVNC: HTML5 VNC client
|
|
3
|
+
* Copyright (C) 2021 The noVNC Authors
|
|
4
|
+
* Licensed under MPL 2.0 (see LICENSE.txt)
|
|
5
|
+
*
|
|
6
|
+
* See README.md for usage and integration instructions.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import Inflate from "../inflator.js";
|
|
11
|
+
|
|
12
|
+
const ZRLE_TILE_WIDTH = 64;
|
|
13
|
+
const ZRLE_TILE_HEIGHT = 64;
|
|
14
|
+
|
|
15
|
+
export default class ZRLEDecoder {
|
|
16
|
+
constructor() {
|
|
17
|
+
this._length = 0;
|
|
18
|
+
this._inflator = new Inflate();
|
|
19
|
+
|
|
20
|
+
this._pixelBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4);
|
|
21
|
+
this._tileBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
decodeRect(x, y, width, height, sock, display, depth) {
|
|
25
|
+
if (this._length === 0) {
|
|
26
|
+
if (sock.rQwait("ZLib data length", 4)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
this._length = sock.rQshift32();
|
|
30
|
+
}
|
|
31
|
+
if (sock.rQwait("Zlib data", this._length)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const data = sock.rQshiftBytes(this._length);
|
|
36
|
+
|
|
37
|
+
this._inflator.setInput(data);
|
|
38
|
+
|
|
39
|
+
for (let ty = y; ty < y + height; ty += ZRLE_TILE_HEIGHT) {
|
|
40
|
+
let th = Math.min(ZRLE_TILE_HEIGHT, y + height - ty);
|
|
41
|
+
|
|
42
|
+
for (let tx = x; tx < x + width; tx += ZRLE_TILE_WIDTH) {
|
|
43
|
+
let tw = Math.min(ZRLE_TILE_WIDTH, x + width - tx);
|
|
44
|
+
|
|
45
|
+
const tileSize = tw * th;
|
|
46
|
+
const subencoding = this._inflator.inflate(1)[0];
|
|
47
|
+
if (subencoding === 0) {
|
|
48
|
+
// raw data
|
|
49
|
+
const data = this._readPixels(tileSize);
|
|
50
|
+
display.blitImage(tx, ty, tw, th, data, 0, false);
|
|
51
|
+
} else if (subencoding === 1) {
|
|
52
|
+
// solid
|
|
53
|
+
const background = this._readPixels(1);
|
|
54
|
+
display.fillRect(tx, ty, tw, th, [background[0], background[1], background[2]]);
|
|
55
|
+
} else if (subencoding >= 2 && subencoding <= 16) {
|
|
56
|
+
const data = this._decodePaletteTile(subencoding, tileSize, tw, th);
|
|
57
|
+
display.blitImage(tx, ty, tw, th, data, 0, false);
|
|
58
|
+
} else if (subencoding === 128) {
|
|
59
|
+
const data = this._decodeRLETile(tileSize);
|
|
60
|
+
display.blitImage(tx, ty, tw, th, data, 0, false);
|
|
61
|
+
} else if (subencoding >= 130 && subencoding <= 255) {
|
|
62
|
+
const data = this._decodeRLEPaletteTile(subencoding - 128, tileSize);
|
|
63
|
+
display.blitImage(tx, ty, tw, th, data, 0, false);
|
|
64
|
+
} else {
|
|
65
|
+
throw new Error('Unknown subencoding: ' + subencoding);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this._length = 0;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
_getBitsPerPixelInPalette(paletteSize) {
|
|
74
|
+
if (paletteSize <= 2) {
|
|
75
|
+
return 1;
|
|
76
|
+
} else if (paletteSize <= 4) {
|
|
77
|
+
return 2;
|
|
78
|
+
} else if (paletteSize <= 16) {
|
|
79
|
+
return 4;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_readPixels(pixels) {
|
|
84
|
+
let data = this._pixelBuffer;
|
|
85
|
+
const buffer = this._inflator.inflate(3*pixels);
|
|
86
|
+
for (let i = 0, j = 0; i < pixels*4; i += 4, j += 3) {
|
|
87
|
+
data[i] = buffer[j];
|
|
88
|
+
data[i + 1] = buffer[j + 1];
|
|
89
|
+
data[i + 2] = buffer[j + 2];
|
|
90
|
+
data[i + 3] = 255; // Add the Alpha
|
|
91
|
+
}
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_decodePaletteTile(paletteSize, tileSize, tilew, tileh) {
|
|
96
|
+
const data = this._tileBuffer;
|
|
97
|
+
const palette = this._readPixels(paletteSize);
|
|
98
|
+
const bitsPerPixel = this._getBitsPerPixelInPalette(paletteSize);
|
|
99
|
+
const mask = (1 << bitsPerPixel) - 1;
|
|
100
|
+
|
|
101
|
+
let offset = 0;
|
|
102
|
+
let encoded = this._inflator.inflate(1)[0];
|
|
103
|
+
|
|
104
|
+
for (let y=0; y<tileh; y++) {
|
|
105
|
+
let shift = 8-bitsPerPixel;
|
|
106
|
+
for (let x=0; x<tilew; x++) {
|
|
107
|
+
if (shift<0) {
|
|
108
|
+
shift=8-bitsPerPixel;
|
|
109
|
+
encoded = this._inflator.inflate(1)[0];
|
|
110
|
+
}
|
|
111
|
+
let indexInPalette = (encoded>>shift) & mask;
|
|
112
|
+
|
|
113
|
+
data[offset] = palette[indexInPalette * 4];
|
|
114
|
+
data[offset + 1] = palette[indexInPalette * 4 + 1];
|
|
115
|
+
data[offset + 2] = palette[indexInPalette * 4 + 2];
|
|
116
|
+
data[offset + 3] = palette[indexInPalette * 4 + 3];
|
|
117
|
+
offset += 4;
|
|
118
|
+
shift-=bitsPerPixel;
|
|
119
|
+
}
|
|
120
|
+
if (shift<8-bitsPerPixel && y<tileh-1) {
|
|
121
|
+
encoded = this._inflator.inflate(1)[0];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return data;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
_decodeRLETile(tileSize) {
|
|
128
|
+
const data = this._tileBuffer;
|
|
129
|
+
let i = 0;
|
|
130
|
+
while (i < tileSize) {
|
|
131
|
+
const pixel = this._readPixels(1);
|
|
132
|
+
const length = this._readRLELength();
|
|
133
|
+
for (let j = 0; j < length; j++) {
|
|
134
|
+
data[i * 4] = pixel[0];
|
|
135
|
+
data[i * 4 + 1] = pixel[1];
|
|
136
|
+
data[i * 4 + 2] = pixel[2];
|
|
137
|
+
data[i * 4 + 3] = pixel[3];
|
|
138
|
+
i++;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return data;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
_decodeRLEPaletteTile(paletteSize, tileSize) {
|
|
145
|
+
const data = this._tileBuffer;
|
|
146
|
+
|
|
147
|
+
// palette
|
|
148
|
+
const palette = this._readPixels(paletteSize);
|
|
149
|
+
|
|
150
|
+
let offset = 0;
|
|
151
|
+
while (offset < tileSize) {
|
|
152
|
+
let indexInPalette = this._inflator.inflate(1)[0];
|
|
153
|
+
let length = 1;
|
|
154
|
+
if (indexInPalette >= 128) {
|
|
155
|
+
indexInPalette -= 128;
|
|
156
|
+
length = this._readRLELength();
|
|
157
|
+
}
|
|
158
|
+
if (indexInPalette > paletteSize) {
|
|
159
|
+
throw new Error('Too big index in palette: ' + indexInPalette + ', palette size: ' + paletteSize);
|
|
160
|
+
}
|
|
161
|
+
if (offset + length > tileSize) {
|
|
162
|
+
throw new Error('Too big rle length in palette mode: ' + length + ', allowed length is: ' + (tileSize - offset));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (let j = 0; j < length; j++) {
|
|
166
|
+
data[offset * 4] = palette[indexInPalette * 4];
|
|
167
|
+
data[offset * 4 + 1] = palette[indexInPalette * 4 + 1];
|
|
168
|
+
data[offset * 4 + 2] = palette[indexInPalette * 4 + 2];
|
|
169
|
+
data[offset * 4 + 3] = palette[indexInPalette * 4 + 3];
|
|
170
|
+
offset++;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return data;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
_readRLELength() {
|
|
177
|
+
let length = 0;
|
|
178
|
+
let current = 0;
|
|
179
|
+
do {
|
|
180
|
+
current = this._inflator.inflate(1)[0];
|
|
181
|
+
length += current;
|
|
182
|
+
} while (current === 255);
|
|
183
|
+
return length + 1;
|
|
184
|
+
}
|
|
185
|
+
}
|
package/core/display.js
CHANGED
|
@@ -224,6 +224,18 @@ export default class Display {
|
|
|
224
224
|
this.viewportChangePos(0, 0);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
getImageData() {
|
|
228
|
+
return this._drawCtx.getImageData(0, 0, this.width, this.height);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
toDataURL(type, encoderOptions) {
|
|
232
|
+
return this._backbuffer.toDataURL(type, encoderOptions);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
toBlob(callback, type, quality) {
|
|
236
|
+
return this._backbuffer.toBlob(callback, type, quality);
|
|
237
|
+
}
|
|
238
|
+
|
|
227
239
|
// Track what parts of the visible canvas that need updating
|
|
228
240
|
_damage(x, y, w, h) {
|
|
229
241
|
if (x < this._damageBounds.left) {
|
package/core/encodings.js
CHANGED
|
@@ -12,7 +12,9 @@ export const encodings = {
|
|
|
12
12
|
encodingRRE: 2,
|
|
13
13
|
encodingHextile: 5,
|
|
14
14
|
encodingTight: 7,
|
|
15
|
+
encodingZRLE: 16,
|
|
15
16
|
encodingTightPNG: -260,
|
|
17
|
+
encodingJPEG: 21,
|
|
16
18
|
|
|
17
19
|
pseudoEncodingQualityLevel9: -23,
|
|
18
20
|
pseudoEncodingQualityLevel0: -32,
|
|
@@ -38,7 +40,9 @@ export function encodingName(num) {
|
|
|
38
40
|
case encodings.encodingRRE: return "RRE";
|
|
39
41
|
case encodings.encodingHextile: return "Hextile";
|
|
40
42
|
case encodings.encodingTight: return "Tight";
|
|
43
|
+
case encodings.encodingZRLE: return "ZRLE";
|
|
41
44
|
case encodings.encodingTightPNG: return "TightPNG";
|
|
45
|
+
case encodings.encodingJPEG: return "JPEG";
|
|
42
46
|
default: return "[unknown encoding " + num + "]";
|
|
43
47
|
}
|
|
44
48
|
}
|