@xterm/addon-image 0.10.0-beta.211 → 0.10.0-beta.213

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xterm/addon-image",
3
- "version": "0.10.0-beta.211",
3
+ "version": "0.10.0-beta.213",
4
4
  "author": {
5
5
  "name": "The xterm.js authors",
6
6
  "url": "https://xtermjs.org/"
@@ -25,10 +25,10 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "sixel": "^0.16.0",
28
- "xterm-wasm-parts": "^0.3.0"
28
+ "xterm-wasm-parts": "^0.4.1"
29
29
  },
30
- "commit": "605a7c6e3020b23155ad0544c3e56e88dd295c20",
30
+ "commit": "5ef4f865432bf248e360a23344d740d8b91317e4",
31
31
  "peerDependencies": {
32
- "@xterm/xterm": "^6.1.0-beta.211"
32
+ "@xterm/xterm": "^6.1.0-beta.213"
33
33
  }
34
34
  }
package/src/IIPHandler.ts CHANGED
@@ -7,6 +7,7 @@ import { ImageRenderer } from './ImageRenderer';
7
7
  import { IIPImageStorage } from './IIPImageStorage';
8
8
  import { CELL_SIZE_DEFAULT } from './ImageStorage';
9
9
  import Base64Decoder from 'xterm-wasm-parts/lib/base64/Base64Decoder.wasm';
10
+ import QoiDecoder from 'xterm-wasm-parts/lib/qoi/QoiDecoder.wasm';
10
11
  import { HeaderParser, IHeaderFields, HeaderState } from './IIPHeaderParser';
11
12
  import { imageType, UNSUPPORTED_TYPE } from './IIPMetrics';
12
13
 
@@ -36,6 +37,7 @@ export class IIPHandler implements IOscHandler, IResetHandler {
36
37
  private _hp = new HeaderParser();
37
38
  private _header: IHeaderFields = DEFAULT_HEADER;
38
39
  private _dec: Base64Decoder;
40
+ private _qoiDec: QoiDecoder;
39
41
  private _metrics = UNSUPPORTED_TYPE;
40
42
 
41
43
  constructor(
@@ -47,6 +49,7 @@ export class IIPHandler implements IOscHandler, IResetHandler {
47
49
  const maxEncodedBytes = Math.ceil(this._opts.iipSizeLimit * 4 / 3);
48
50
  const initialBytes = Math.min(DecoderConst.INITIAL_DATA, maxEncodedBytes);
49
51
  this._dec = new Base64Decoder(DecoderConst.KEEP_DATA, maxEncodedBytes, initialBytes);
52
+ this._qoiDec = new QoiDecoder(DecoderConst.KEEP_DATA);
50
53
  }
51
54
 
52
55
  public reset(): void {}
@@ -115,27 +118,27 @@ export class IIPHandler implements IOscHandler, IResetHandler {
115
118
  return true;
116
119
  }
117
120
 
118
- // HACK: The types on Blob are too restrictive, this is a Uint8Array so the browser accepts it
119
- const blob = new Blob([this._dec.data8 as Uint8Array<ArrayBuffer>], { type: this._metrics.mime });
120
- this._dec.release();
121
-
122
- if (!window.createImageBitmap) {
123
- const url = URL.createObjectURL(blob);
124
- const img = new Image();
125
- return new Promise<boolean>(r => {
126
- img.addEventListener('load', () => {
127
- URL.revokeObjectURL(url);
128
- const canvas = ImageRenderer.createCanvas(window.document, w, h);
129
- canvas.getContext('2d')?.drawImage(img, 0, 0, w, h);
130
- this._storage.addImage(canvas);
131
- r(true);
132
- });
133
- img.src = url;
134
- // sanity measure to avoid terminal blocking from dangling promise
135
- // happens from corrupt data (onload never gets fired)
136
- setTimeout(() => r(true), 1000);
137
- });
121
+ let blob: Blob | ImageData;
122
+ if (this._metrics.mime === 'image/qoi') {
123
+ const data = this._qoiDec.decode(this._dec.data8);
124
+ blob = new ImageData(
125
+ new Uint8ClampedArray(data.buffer, data.byteOffset, data.byteLength),
126
+ this._qoiDec.width,
127
+ this._qoiDec.height
128
+ );
129
+ this._qoiDec.release();
130
+ if (w === this._qoiDec.width && h === this._qoiDec.height) {
131
+ // use fast-path if we don't need to rescale
132
+ this._dec.release();
133
+ const canvas = ImageRenderer.createCanvas(undefined, this._qoiDec.width, this._qoiDec.height);
134
+ canvas.getContext('2d')?.putImageData(blob, 0, 0);
135
+ this._storage.addImage(canvas);
136
+ return true;
137
+ }
138
+ } else {
139
+ blob = new Blob([this._dec.data8], { type: this._metrics.mime });
138
140
  }
141
+ this._dec.release();
139
142
  return createImageBitmap(blob, { resizeWidth: w, resizeHeight: h })
140
143
  .then(bm => {
141
144
  this._storage.addImage(bm);
package/src/IIPMetrics.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
 
7
- export type ImageType = 'image/png' | 'image/jpeg' | 'image/gif' | 'unsupported' | '';
7
+ export type ImageType = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/qoi' | 'unsupported' | '';
8
8
 
9
9
  export interface IMetrics {
10
10
  mime: ImageType;
@@ -45,6 +45,14 @@ export function imageType(d: Uint8Array): IMetrics {
45
45
  height: d[9] << 8 | d[8]
46
46
  };
47
47
  }
48
+ // QOI: qoif
49
+ if (d32[0] === 0x66696F71) {
50
+ return {
51
+ mime: 'image/qoi',
52
+ width: d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7],
53
+ height: d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11]
54
+ };
55
+ }
48
56
  return UNSUPPORTED_TYPE;
49
57
  }
50
58
 
package/src/ImageAddon.ts CHANGED
@@ -16,6 +16,47 @@ import { SixelImageStorage } from './SixelImageStorage';
16
16
  import { IIPImageStorage } from './IIPImageStorage';
17
17
  import { ITerminalExt, IImageAddonOptions, IResetHandler } from './Types';
18
18
 
19
+
20
+ /**
21
+ * Document VT features provided by this addon.
22
+ *
23
+ * @vt: #E[Supported via @xterm/addon-image.] DCS SIXEL "SIXEL Graphics" "DCS Ps ; Ps ; Ps ; q Pt ST" "Draw SIXEL image."
24
+ *
25
+ * Sixel support is provided by the addon @xterm/addon-image with these limitations:
26
+ * - immediate coloring (no shared palette, allows high color settings of `img2sixel`)
27
+ * - max. palette size of 4096 colors
28
+ * - max. pixel width of 16K
29
+ * - max. 25 MB per sixel sequence
30
+ * - VT340 cursor positioning (begin of last sixel data row)
31
+ *
32
+ * See [addon readme](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-image) for more details.
33
+ *
34
+ *
35
+ * @vt: #E[Supported via @xterm/addon-image.] OSC 1337 "iTerm2 Commands" "OSC 1337 ; Pt BEL" "Custom iTerm2 commands."
36
+ *
37
+ * Only the inline image protocol (IIP) is supported by the addon @xterm/addon-image with
38
+ * the following limitations:
39
+ * - sequence:
40
+ * - format: `OSC 1337 ; File=inline=1 ; size=<unencoded size> ; ... : <base64 payload> BEL`
41
+ * - size param must be set and payload may not exceed CEIL(size * 4 / 3)
42
+ * - strict base64 handling as of RFC4648 §4 (standard alphabet, optional padding,
43
+ * no separator bytes allowed)
44
+ * - supported params: size, name, width, height, preserveAspectRatio
45
+ * - image formats: PNG, JPEG and GIF
46
+ * - no animation support (renders first image of a GIF)
47
+ * - no multipart support
48
+ * - VT340 cursor positioning (begin of last sixel data row)
49
+ *
50
+ * See [addon readme](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-image)
51
+ * and [iTerm2 IIP docs](https://iterm2.com/documentation-images.html) for more details.
52
+ *
53
+ *
54
+ * @vt: #E[Supported via @xterm/addon-image.] APC KITTY_GRAPHICS "Kitty Graphics" "APC G Pt ST" "Kitty Graphics Protocol."
55
+ *
56
+ * Kitty graphics support is provided by the addon @xterm/addon-image.
57
+ * Note that while basic image output already works, this is still work in progress.
58
+ */
59
+
19
60
  // default values of addon ctor options
20
61
  const DEFAULT_OPTIONS: IImageAddonOptions = {
21
62
  enableSizeReports: true,
@@ -166,7 +207,7 @@ export class ImageAddon implements ITerminalAddon, IImageApi {
166
207
  this._disposeLater(
167
208
  kittyStorage,
168
209
  kittyHandler,
169
- terminal._core._inputHandler._parser.registerApcHandler(0x47, kittyHandler)
210
+ terminal._core._inputHandler._parser.registerApcHandler({ final: 'G' }, kittyHandler)
170
211
  );
171
212
  }
172
213
  }