@webex/ladon-ts 5.1.0 → 5.4.1

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/CHANGELOG.md CHANGED
@@ -2,20 +2,70 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ## [5.1.0](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.1.0) (2025-01-15)
5
+ ### [5.4.1](https://github.com/beyonddunbar/ladon-ts/compare/v5.4.0...v5.4.1) (2025-03-11)
6
+
7
+ ## [5.4.0](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.4.0) (2025-03-11)
8
+
9
+
10
+ ### Features
11
+
12
+ * upgrade onnx version ([0a5a0ad](https://github.com/beyonddunbar/ladon-ts/commit/0a5a0adbfeb70ddae824c74c8a7f03090d813243))
13
+ * fetch and cache assets locally; load them as array buffers ([f1cc74e](https://github.com/beyonddunbar/ladon-ts/commit/f1cc74ed60122f3873cb25014568e2a3ab20eee5))
14
+ * passthrough with generator to support step away ([#20](https://github.com/beyonddunbar/ladon-ts/issues/20)) ([f7e6b58](https://github.com/beyonddunbar/ladon-ts/commit/f7e6b5814d75f42daee67c6174fc1eb80a684b54))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * lint ([f2a8f94](https://github.com/beyonddunbar/ladon-ts/commit/f2a8f94012a3e17ccdbdc47cc1a60ebf5f163448))
20
+ * publish missing worker files in build folder ([#18](https://github.com/beyonddunbar/ladon-ts/issues/18)) ([de1b8d9](https://github.com/beyonddunbar/ladon-ts/commit/de1b8d9122ff1b2f9eaf3883a3c52a96e56225a2))
21
+ * webgl syntax error ([#22](https://github.com/beyonddunbar/ladon-ts/issues/22)) ([5a7e513](https://github.com/beyonddunbar/ladon-ts/commit/5a7e513bfd2b39f2b5c1a5b8b9c892f99a017285))
22
+ * yarn build error ([#16](https://github.com/beyonddunbar/ladon-ts/issues/16)) ([38eb5af](https://github.com/beyonddunbar/ladon-ts/commit/38eb5afa8c37947187af3d0b4fe061971b8a2436))
23
+
24
+ ## [5.3.0](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.3.0) (2025-03-11)
6
25
 
7
26
 
8
27
  ### Features
9
28
 
29
+ * upgrade onnx version ([0a5a0ad](https://github.com/beyonddunbar/ladon-ts/commit/0a5a0adbfeb70ddae824c74c8a7f03090d813243))
30
+ * fetch and cache assets locally; load them as array buffers ([f1cc74e](https://github.com/beyonddunbar/ladon-ts/commit/f1cc74ed60122f3873cb25014568e2a3ab20eee5))
10
31
  * passthrough with generator to support step away ([#20](https://github.com/beyonddunbar/ladon-ts/issues/20)) ([f7e6b58](https://github.com/beyonddunbar/ladon-ts/commit/f7e6b5814d75f42daee67c6174fc1eb80a684b54))
11
32
 
12
33
 
13
34
  ### Bug Fixes
14
35
 
15
- * lint ([b904fd7](https://github.com/beyonddunbar/ladon-ts/commit/b904fd74dca183d8cfbd1bebb44d433868d8b606))
36
+ * lint ([f2a8f94](https://github.com/beyonddunbar/ladon-ts/commit/f2a8f94012a3e17ccdbdc47cc1a60ebf5f163448))
16
37
  * publish missing worker files in build folder ([#18](https://github.com/beyonddunbar/ladon-ts/issues/18)) ([de1b8d9](https://github.com/beyonddunbar/ladon-ts/commit/de1b8d9122ff1b2f9eaf3883a3c52a96e56225a2))
38
+ * webgl syntax error ([#22](https://github.com/beyonddunbar/ladon-ts/issues/22)) ([5a7e513](https://github.com/beyonddunbar/ladon-ts/commit/5a7e513bfd2b39f2b5c1a5b8b9c892f99a017285))
17
39
  * yarn build error ([#16](https://github.com/beyonddunbar/ladon-ts/issues/16)) ([38eb5af](https://github.com/beyonddunbar/ladon-ts/commit/38eb5afa8c37947187af3d0b4fe061971b8a2436))
18
40
 
41
+ ## [5.2.0](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.2.0) (2025-01-17)
42
+
43
+
44
+ ### Features
45
+
46
+ * passthrough with generator to support step away ([#20](https://github.com/beyonddunbar/ladon-ts/issues/20)) ([f7e6b58](https://github.com/beyonddunbar/ladon-ts/commit/f7e6b5814d75f42daee67c6174fc1eb80a684b54))
47
+
48
+
49
+ ### Bug Fixes
50
+
51
+ * publish missing worker files in build folder ([#18](https://github.com/beyonddunbar/ladon-ts/issues/18)) ([de1b8d9](https://github.com/beyonddunbar/ladon-ts/commit/de1b8d9122ff1b2f9eaf3883a3c52a96e56225a2))
52
+ * webgl syntax error ([#22](https://github.com/beyonddunbar/ladon-ts/issues/22)) ([5a7e513](https://github.com/beyonddunbar/ladon-ts/commit/5a7e513bfd2b39f2b5c1a5b8b9c892f99a017285))
53
+ * yarn build error ([#16](https://github.com/beyonddunbar/ladon-ts/issues/16)) ([38eb5af](https://github.com/beyonddunbar/ladon-ts/commit/38eb5afa8c37947187af3d0b4fe061971b8a2436))
54
+
55
+ ## [5.1.0](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.1.0) (2025-01-15)
56
+
57
+
58
+ ### Features
59
+
60
+ * passthrough with generator to support step away ([#20](https://github.com/beyonddunbar/ladon-ts/issues/20)) ([f7e6b58](https://github.com/beyonddunbar/ladon-ts/commit/f7e6b5814d75f42daee67c6174fc1eb80a684b54))
61
+
62
+
63
+ ### Bug Fixes
64
+
65
+ * lint ([b904fd7](https://github.com/beyonddunbar/ladon-ts/commit/b904fd74dca183d8cfbd1bebb44d433868d8b606))
66
+ * publish missing worker files in build folder ([#18](https://github.com/beyonddunbar/ladon-ts/issues/18)) ([de1b8d9](https://github.com/beyonddunbar/ladon-ts/commit/de1b8d9122ff1b2f9eaf3883a3c52a96e56225a2))
67
+ * yarn build error ([#16](https://github.com/beyonddunbar/ladon-ts/issues/16)) ([38eb5af](https://github.com/beyonddunbar/ladon-ts/commit/38eb5afa8c37947187af3d0b4fe061971b8a2436))
68
+
19
69
  ### [5.0.3](https://github.com/beyonddunbar/ladon-ts/compare/v5.0.1...v5.0.3) (2024-12-17)
20
70
 
21
71
 
@@ -1,4 +1,4 @@
1
- const e = "1.15.1b", t = "0.7.7.2", i = "segmentation.js", n = { int: "https://models.int.infra.intelligence.webex.com", prod: "https://models.intelligence.webex.com" }, o = { models: "ladon/models", wasm: "ladon/wasm", workers: "ladon/workers" }, l = { weak: { kernelSize: 9, sigma: 2 }, moderate: { kernelSize: 15, sigma: 6 }, strong: { kernelSize: 25, sigma: 11 }, stronger: { kernelSize: 37, sigma: 17 }, strongest: { kernelSize: 49, sigma: 23 } }, h = { tiny: { modelFile: "tiny-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 48, modelRank: 4 }, low: { modelFile: "low-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 48, modelRank: 4 }, medium: { modelFile: "medium-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 36, modelRank: 4 }, high: { modelFile: "medium-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 24, modelRank: 4 }, ultra: { modelFile: "medium-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 0, modelRank: 4 } }, s = "${BASE_PATH_MODELS}/${MODEL_VERSION}/${MODEL_FILE}", a = "${BASE_PATH_WASM}/${ONNX_VERSION}/", d = "${BASE_PATH_WORKERS}/${LIB_VERSION}/${WORKER_FILE}", m = {
1
+ const e = "1.20.1", t = "0.7.7.2", i = "segmentation.js", n = { int: "https://models.int.infra.intelligence.webex.com", prod: "https://models.intelligence.webex.com" }, o = { models: "ladon/models", wasm: "ladon/wasm", workers: "ladon/workers" }, l = { weak: { kernelSize: 9, sigma: 2 }, moderate: { kernelSize: 15, sigma: 6 }, strong: { kernelSize: 25, sigma: 11 }, stronger: { kernelSize: 37, sigma: 17 }, strongest: { kernelSize: 49, sigma: 23 } }, h = { tiny: { modelFile: "tiny-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 48, modelRank: 4 }, low: { modelFile: "low-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 48, modelRank: 4 }, medium: { modelFile: "medium-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 36, modelRank: 4 }, high: { modelFile: "medium-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 24, modelRank: 4 }, ultra: { modelFile: "medium-640x360.onnx", inputSize: { width: 640, height: 360 }, outputSize: { width: 640, height: 360 }, upscaleSize: { width: 640, height: 360 }, generationIntervalMs: 0, modelRank: 4 } }, s = "${BASE_PATH_MODELS}/${MODEL_VERSION}/${MODEL_FILE}", a = "${BASE_PATH_WASM}/${ONNX_VERSION}/", d = "${BASE_PATH_WORKERS}/${LIB_VERSION}/${WORKER_FILE}", m = {
2
2
  onnxVersion: e,
3
3
  modelVersion: t,
4
4
  workerFile: i,
@@ -1,41 +1,42 @@
1
- import { getBlurConfig as o, getConfig as t, getPreloadConfig as p } from "./lib/config.js";
2
- import { ConfigurationBuilder as l } from "./lib/config-builder.js";
3
- import { BlurStrength as m, Quality as f } from "./lib/config-types.js";
4
- import { LocalGenerator as x, NullGenerator as g, WorkerGenerator as d } from "./lib/generator.js";
1
+ import { getBlurConfig as o, getConfig as t, getPreloadConfig as a } from "./lib/config.js";
2
+ import { ConfigurationBuilder as n } from "./lib/config-builder.js";
3
+ import { BlurStrength as m, Quality as i } from "./lib/config-types.js";
4
+ import { LocalGenerator as d, NullGenerator as x, WorkerGenerator as g } from "./lib/generator.js";
5
5
  import { Pipeline as u } from "./lib/pipeline.js";
6
6
  import { BlurRenderer as h } from "./lib/renderer/blur-renderer.js";
7
7
  import { PassthroughRenderer as B } from "./lib/renderer/passthrough-renderer.js";
8
- import { ReplacementRenderer as C } from "./lib/renderer/replacement-renderer.js";
8
+ import { ReplacementRenderer as I } from "./lib/renderer/replacement-renderer.js";
9
9
  import { WebGLRenderer as P } from "./lib/renderer/webgl-renderer.js";
10
- import { InterpolationMethod as b, bilinearUpsample as L, compileShader as S, isResolvedUri as k, lanczos3Upsample as z, linkProgram as M, resizeImage as N, toAbsoluteURI as W } from "./lib/util.js";
10
+ import { InterpolationMethod as b, bilinearUpsample as L, compileShader as S, isResolvedUri as k, lanczos3Upsample as z, linkProgram as A, loadAndCacheFile as M, resizeImage as N, toAbsoluteURI as W } from "./lib/util.js";
11
11
  import { LIB_VERSION as y } from "./lib/version.js";
12
- import { sharedResourceManager as E } from "./lib/shared-resource-manager.js";
12
+ import { sharedResourceManager as F } from "./lib/shared-resource-manager.js";
13
13
  import { preload as Q } from "./lib/preload.js";
14
14
  export {
15
15
  h as BlurRenderer,
16
16
  m as BlurStrength,
17
- l as ConfigurationBuilder,
17
+ n as ConfigurationBuilder,
18
18
  b as InterpolationMethod,
19
19
  y as LIB_VERSION,
20
- x as LocalGenerator,
21
- g as NullGenerator,
20
+ d as LocalGenerator,
21
+ x as NullGenerator,
22
22
  B as PassthroughRenderer,
23
23
  u as Pipeline,
24
- f as Quality,
25
- C as ReplacementRenderer,
24
+ i as Quality,
25
+ I as ReplacementRenderer,
26
26
  P as WebGLRenderer,
27
- d as WorkerGenerator,
27
+ g as WorkerGenerator,
28
28
  L as bilinearUpsample,
29
29
  S as compileShader,
30
30
  o as getBlurConfig,
31
31
  t as getConfig,
32
- p as getPreloadConfig,
32
+ a as getPreloadConfig,
33
33
  k as isResolvedUri,
34
34
  z as lanczos3Upsample,
35
- M as linkProgram,
35
+ A as linkProgram,
36
+ M as loadAndCacheFile,
36
37
  Q as preload,
37
38
  N as resizeImage,
38
- E as sharedResourceManager,
39
+ F as sharedResourceManager,
39
40
  W as toAbsoluteURI
40
41
  };
41
42
  //# sourceMappingURL=index.js.map
@@ -12,7 +12,7 @@ export declare enum BlurStrength {
12
12
  STRONGER = "STRONGER",
13
13
  STRONGEST = "STRONGEST"
14
14
  }
15
- export declare type ResolutionConfig = {
15
+ export type ResolutionConfig = {
16
16
  readonly height: number;
17
17
  readonly width: number;
18
18
  };
@@ -29,8 +29,8 @@ export interface ModelQualityConfig {
29
29
  readonly outputSize: ResolutionConfig;
30
30
  readonly upscaleSize: ResolutionConfig;
31
31
  }
32
- export declare type InputConfig = ResolutionConfig;
33
- export declare type AssetUrlResolver = (assetUri: string, config: PreloadConfig) => Promise<string>;
32
+ export type InputConfig = ResolutionConfig;
33
+ export type AssetUrlResolver = (assetUri: string, config: PreloadConfig) => Promise<string>;
34
34
  export interface RenderConfig {
35
35
  readonly type: 'blur' | 'passthrough' | 'replacement';
36
36
  readonly horizontalMirror?: boolean;
@@ -48,8 +48,8 @@ export interface ReplacementConfig extends RenderConfig {
48
48
  export interface PassthroughConfig extends RenderConfig {
49
49
  readonly type: 'passthrough';
50
50
  }
51
- export declare type Generator = 'local' | 'worker';
52
- export declare type BaseMaskConfig = {
51
+ export type Generator = 'local' | 'worker';
52
+ export type BaseMaskConfig = {
53
53
  readonly generator: Generator;
54
54
  readonly generationIntervalMs: number;
55
55
  readonly modelRank: number;
@@ -59,16 +59,16 @@ export declare type BaseMaskConfig = {
59
59
  readonly outputSize?: ResolutionConfig;
60
60
  readonly upscaleSize?: ResolutionConfig;
61
61
  };
62
- export declare type MaskConfig = BaseMaskConfig & SizeConfig;
63
- export declare type PreloadConfig = {
62
+ export type MaskConfig = BaseMaskConfig & SizeConfig;
63
+ export type PreloadConfig = {
64
64
  readonly baseUrl?: string;
65
65
  readonly wasmUri: string;
66
66
  readonly mask: BaseMaskConfig;
67
67
  readonly executionProviders?: string[];
68
68
  readonly assetUrlResolver?: AssetUrlResolver;
69
69
  };
70
- export declare type WorkerConfig = Omit<PreloadConfig, 'assetUrlResolver'>;
71
- export declare type PipelineConfig = PreloadConfig & {
70
+ export type WorkerConfig = Omit<PreloadConfig, 'assetUrlResolver'>;
71
+ export type PipelineConfig = PreloadConfig & {
72
72
  readonly render: BlurConfig | RenderConfig | ReplacementConfig;
73
73
  readonly input: InputConfig;
74
74
  readonly mask: MaskConfig;
@@ -5,7 +5,7 @@ declare global {
5
5
  url: string;
6
6
  }
7
7
  }
8
- export declare type FrameData = Uint8ClampedArray | HTMLVideoElement;
8
+ export type FrameData = Uint8ClampedArray | HTMLVideoElement;
9
9
  export interface FacesAndLandmarks {
10
10
  data: Float32Array;
11
11
  dims: readonly number[];
@@ -1,5 +1,5 @@
1
1
  import * as c from "onnxruntime-web";
2
- import { sharedResourceManager as n } from "./shared-resource-manager.js";
2
+ import { sharedResourceManager as d } from "./shared-resource-manager.js";
3
3
  class R {
4
4
  constructor(t) {
5
5
  this.config = t, this.lastMaskGenerationTime = 0;
@@ -30,19 +30,19 @@ class R {
30
30
  preprocess(t, a) {
31
31
  const {
32
32
  modelRank: e,
33
- inputSize: r,
33
+ inputSize: l,
34
34
  outputSize: s
35
- } = this.config.mask, { height: o, width: l } = r, d = o * l;
36
- this.output ?? (this.output = new Float32Array(d * e));
35
+ } = this.config.mask, { height: r, width: i } = l, o = r * i;
36
+ this.output ?? (this.output = new Float32Array(o * e));
37
37
  const k = t.length / 4;
38
- for (let i = 0; i < 3; i++)
39
- for (let h = 0; h < k; h++)
40
- this.output[h + i * d] = t[h * 4 + (2 - i)];
41
- const w = s.width / l, g = s.height / o;
42
- for (let i = 0; i < l; i++) {
43
- const h = Math.floor(i * w);
44
- for (let m = 0; m < o; m++) {
45
- const f = Math.floor(m * g), p = h + f * s.width, M = i + m * l + 3 * d, y = Math.min(Math.max(a[p], 0), 255);
38
+ for (let n = 0; n < 3; n++)
39
+ for (let m = 0; m < k; m++)
40
+ this.output[m + n * o] = t[m * 4 + (2 - n)];
41
+ const w = s.width / i, g = s.height / r;
42
+ for (let n = 0; n < i; n++) {
43
+ const m = Math.floor(n * w);
44
+ for (let h = 0; h < r; h++) {
45
+ const f = Math.floor(h * g), p = m + f * s.width, M = n + h * i + 3 * o, y = Math.min(Math.max(a[p], 0), 255);
46
46
  this.output[M] = y;
47
47
  }
48
48
  }
@@ -52,7 +52,7 @@ class R {
52
52
  return Date.now() - this.lastMaskGenerationTime;
53
53
  }
54
54
  async getLadonOutput(t, a) {
55
- var s, o, l, d;
55
+ var s, r, i, o;
56
56
  if (!this.maskModel)
57
57
  throw new Error("[ladon-ts] - mask model not loaded.");
58
58
  if (this.getTimeSinceLastGeneration() < this.config.mask.generationIntervalMs)
@@ -70,25 +70,25 @@ class R {
70
70
  this.config.mask.modelRank,
71
71
  this.config.mask.inputSize.height,
72
72
  this.config.mask.inputSize.width
73
- ]), r = await this.maskModel.run({ input: e });
74
- return this.lastMask = r.segmentation, this.lastResult = {
73
+ ]), l = await this.maskModel.run({ input: e });
74
+ return this.lastMask = l.segmentation, this.lastResult = {
75
75
  data: this.lastMask.data ?? new Float32Array(0),
76
76
  facesAndLandmarks: {
77
- data: ((s = r.faces_and_landmarks) == null ? void 0 : s.data) ?? new Float32Array(0),
78
- dims: ((o = r.faces_and_landmarks) == null ? void 0 : o.dims) ?? []
77
+ data: ((s = l.faces_and_landmarks) == null ? void 0 : s.data) ?? new Float32Array(0),
78
+ dims: ((r = l.faces_and_landmarks) == null ? void 0 : r.dims) ?? []
79
79
  },
80
- gesture: ((l = r.gesture) == null ? void 0 : l.data) ?? new Float32Array(0),
81
- motion: ((d = r.motion) == null ? void 0 : d.data[0]) ?? 0,
80
+ gesture: ((i = l.gesture) == null ? void 0 : i.data) ?? new Float32Array(0),
81
+ motion: ((o = l.motion) == null ? void 0 : o.data[0]) ?? 0,
82
82
  timestamp: a,
83
83
  warm: !0
84
84
  }, this.lastResult;
85
85
  }
86
86
  async load() {
87
- const t = await n.resolveUri(
87
+ const t = await d.resolveUri(
88
88
  this.config,
89
89
  this.config.mask.modelUri
90
90
  );
91
- if (this.maskModel = n.getModelSession(t), this.maskModel ?? (this.maskModel = await n.loadModel(this.config)), !this.maskModel)
91
+ if (this.maskModel = d.getModelSession(t), this.maskModel ?? (this.maskModel = await d.loadModel(this.config)), !this.maskModel)
92
92
  throw new Error("Failed to load the ONNX model.");
93
93
  }
94
94
  isLoaded() {
@@ -154,9 +154,36 @@ class F {
154
154
  return this.newMask = !1, a;
155
155
  }
156
156
  async load() {
157
- const t = await n.prepareWorkerConfig(this.config);
158
- if (this.worker = n.getWorker(), this.worker ?? (this.worker = await n.initializeWorker(t)), !this.worker)
157
+ const t = await d.prepareWorkerConfig(this.config);
158
+ if (this.worker = d.getWorker(), this.worker ?? (this.worker = await d.initializeWorker(t)), !this.worker)
159
159
  throw new Error("[ladon-ts] - worker is not defined.");
160
+ this.worker.onmessage = (s) => {
161
+ if (s.data.type === "log") {
162
+ const { message: r, severity: i } = s.data, o = `[ladon-ts] Message received from worker: ${r}`;
163
+ switch (i) {
164
+ case "warn":
165
+ console.warn(o);
166
+ break;
167
+ case "error":
168
+ console.error(o);
169
+ break;
170
+ default:
171
+ console.log(o);
172
+ }
173
+ } else if (s.data.status === "generated")
174
+ this.lastMask = s.data.mask, this.lastResult = {
175
+ data: s.data.mask,
176
+ facesAndLandmarks: s.data.facesAndLandmarks,
177
+ gesture: s.data.gesture,
178
+ motion: s.data.motion,
179
+ timestamp: s.data.timestamp,
180
+ warm: !0
181
+ }, this.newMask = !0;
182
+ else {
183
+ const r = d.getWorkerUrl();
184
+ r && URL.revokeObjectURL(r), e == null || e();
185
+ }
186
+ };
160
187
  const a = {
161
188
  baseUrl: t.baseUrl,
162
189
  input: t.input,
@@ -166,24 +193,9 @@ class F {
166
193
  };
167
194
  this.worker.postMessage({ type: "init", config: a });
168
195
  let e;
169
- const r = new Promise((s) => {
196
+ return new Promise((s) => {
170
197
  e = s;
171
198
  });
172
- return this.worker.onmessage = (s) => {
173
- if (s.data.status === "generated")
174
- this.lastMask = s.data.mask, this.lastResult = {
175
- data: s.data.mask,
176
- facesAndLandmarks: s.data.facesAndLandmarks,
177
- gesture: s.data.gesture,
178
- motion: s.data.motion,
179
- timestamp: s.data.timestamp,
180
- warm: !0
181
- }, this.newMask = !0;
182
- else {
183
- const o = n.getWorkerUrl();
184
- o && URL.revokeObjectURL(o), e == null || e();
185
- }
186
- }, r;
187
199
  }
188
200
  isLoaded() {
189
201
  return !!this.worker;
@@ -201,7 +213,7 @@ class F {
201
213
  );
202
214
  }
203
215
  destroy() {
204
- n.terminateWorker();
216
+ d.terminateWorker();
205
217
  }
206
218
  }
207
219
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sources":["../../../src/lib/generator.ts"],"sourcesContent":["import * as ort from 'onnxruntime-web';\n\nimport { PipelineConfig } from './config-types';\nimport { sharedResourceManager } from './shared-resource-manager';\n\ndeclare global {\n interface ImportMeta {\n url: string;\n }\n}\n\nexport type FrameData = Uint8ClampedArray | HTMLVideoElement;\n\nexport interface FacesAndLandmarks {\n data: Float32Array;\n dims: readonly number[];\n}\nexport interface LadonOutput {\n data: Float32Array; // 1x1x144x256 or 1x1x360x640\n facesAndLandmarks: FacesAndLandmarks; // 1x1x9x16x1439\n gesture: Float32Array; // 1x9\n motion: number; // 1x1x1x1\n timestamp: number;\n warm: boolean;\n}\n\nexport interface MaskGenerator {\n getLadonOutput(input: Uint8ClampedArray, timestamp: number): Promise<LadonOutput>;\n load(): Promise<void>;\n isLoaded(): boolean;\n postRender(input: Uint8ClampedArray, timestamp: number): Promise<void>;\n destroy(): void;\n}\n\nexport class LocalGenerator implements MaskGenerator {\n private lastResult: LadonOutput;\n private lastMask: ort.Tensor;\n private maskModel?: ort.InferenceSession;\n private lastMaskGenerationTime = 0;\n private output?: Float32Array;\n\n constructor(public readonly config: PipelineConfig) {\n const { height, width } = this.config.mask.outputSize;\n this.lastMask = new ort.Tensor('float32', new Float32Array(height * width), [\n 1,\n 1,\n height,\n width,\n ]);\n this.lastResult = {\n data: this.lastMask.data,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n /**\n * This method preprocesses an input Uint8ClampedArray to a Float32Array\n * while maintaining memory efficiency by reusing a class-scoped output buffer.\n * If the model rank is 4 (e.g., newer tiny model), it sets an alpha channel value.\n *\n * @param {Uint8ClampedArray} input - The input data to be preprocessed\n * @param {Float32Array} alpha - The alpha channel data\n * @returns {Float32Array} - The processed data\n */\n private preprocess(input: Uint8ClampedArray, alpha: Float32Array): Float32Array {\n const {\n modelRank: model_rank,\n inputSize: input_size,\n outputSize: output_size,\n } = this.config.mask;\n const { height, width } = input_size;\n const numImagePixels = height * width;\n\n // Initialize the output buffer if it is not already set\n this.output ??= new Float32Array(numImagePixels * model_rank);\n\n const numInputPixels = input.length / 4; // Divide by 4 for RGBA\n\n // Directly copy channels (assumes fixed order like BGR or RGB)\n for (let channel = 0; channel < 3; channel++) {\n for (let pixel = 0; pixel < numInputPixels; pixel++) {\n // Map input channels directly to output\n this.output[pixel + channel * numImagePixels] = input[pixel * 4 + (2 - channel)];\n }\n }\n\n // Scaling factors for width and height\n const widthScale = output_size.width / width;\n const heightScale = output_size.height / height;\n\n // Process alpha channel\n for (let x = 0; x < width; x++) {\n const nearestNeighborX = Math.floor(x * widthScale);\n for (let y = 0; y < height; y++) {\n const nearestNeighborY = Math.floor(y * heightScale);\n const maskIdx = nearestNeighborX + nearestNeighborY * output_size.width;\n const outputIdx = x + y * width + 3 * numImagePixels;\n\n // Normalize and scale alpha to [0, 255]\n const normalizedValue = Math.min(Math.max(alpha[maskIdx], 0), 255);\n this.output[outputIdx] = normalizedValue;\n }\n }\n\n return this.output;\n }\n\n public getTimeSinceLastGeneration(): number {\n return Date.now() - this.lastMaskGenerationTime;\n }\n\n public async getLadonOutput(input: Uint8ClampedArray, timestamp: number): Promise<LadonOutput> {\n if (!this.maskModel) {\n throw new Error('[ladon-ts] - mask model not loaded.');\n }\n\n if (this.getTimeSinceLastGeneration() < this.config.mask.generationIntervalMs) {\n return {\n data: this.lastMask.data,\n facesAndLandmarks: this.lastResult.facesAndLandmarks,\n gesture: this.lastResult.gesture,\n motion: this.lastResult.motion,\n timestamp: this.lastResult.timestamp,\n warm: false,\n };\n }\n\n this.lastMaskGenerationTime = Date.now();\n\n const imageTensor = new ort.Tensor('float32', this.preprocess(input, this.lastMask.data), [\n 1,\n this.config.mask.modelRank,\n this.config.mask.inputSize.height,\n this.config.mask.inputSize.width,\n ]);\n\n const results = await this.maskModel.run({ input: imageTensor });\n this.lastMask = results.segmentation;\n\n this.lastResult = {\n data: this.lastMask.data ?? new Float32Array(0),\n facesAndLandmarks: {\n data: results.faces_and_landmarks?.data ?? new Float32Array(0),\n dims: results.faces_and_landmarks?.dims ?? ([] as readonly number[]),\n },\n gesture: results.gesture?.data ?? new Float32Array(0),\n motion: results.motion?.data[0] ?? 0,\n timestamp,\n warm: true,\n };\n\n return this.lastResult;\n }\n\n async load() {\n const modelUrl = await sharedResourceManager.resolveUri(\n this.config,\n this.config.mask.modelUri\n );\n\n // Attempt to retrieve a preloaded InferenceSession from the shared resource manager.\n this.maskModel = sharedResourceManager.getModelSession(modelUrl);\n // If the model is not preloaded, load it from the provided model URL.\n this.maskModel ??= await sharedResourceManager.loadModel(this.config);\n\n if (!this.maskModel) {\n throw new Error('Failed to load the ONNX model.');\n }\n }\n\n public isLoaded(): boolean {\n return !!this.maskModel;\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async postRender(_: Uint8ClampedArray): Promise<void> {\n // empty for local generator\n }\n\n public destroy(): void {\n // empty for local generator\n }\n}\n\nexport class NullGenerator implements MaskGenerator {\n private lastMask: Float32Array;\n\n constructor(public readonly config: PipelineConfig) {\n this.lastMask = new Float32Array(\n this.config.mask.outputSize.height * this.config.mask.outputSize.width\n );\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async getLadonOutput(_: Uint8ClampedArray): Promise<LadonOutput> {\n return {\n data: this.lastMask,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n public async load(): Promise<void> {\n // empty for null generator\n }\n\n public isLoaded(): boolean {\n return true;\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async postRender(_: Uint8ClampedArray): Promise<void> {\n // empty for null generator\n }\n\n public destroy(): void {\n // empty for null generator\n }\n}\n\nexport class WorkerGenerator implements MaskGenerator {\n private lastMask: Float32Array;\n private newMask = true;\n private worker?: Worker;\n private lastResult: LadonOutput;\n\n constructor(public readonly config: PipelineConfig) {\n this.lastMask = new Float32Array(\n this.config.mask.outputSize.height * this.config.mask.outputSize.width\n );\n this.lastResult = {\n data: this.lastMask,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async getLadonOutput(_: Uint8ClampedArray): Promise<LadonOutput> {\n const toReturn = {\n data: this.lastMask,\n facesAndLandmarks: this.lastResult.facesAndLandmarks,\n gesture: this.lastResult.gesture,\n motion: this.lastResult.motion,\n timestamp: this.lastResult.timestamp,\n warm: this.newMask,\n };\n\n this.newMask = false;\n\n return toReturn;\n }\n\n public async load(): Promise<void> {\n // Prepare the worker configuration by resolving the final URLs and paths to send to the worker.\n const config = await sharedResourceManager.prepareWorkerConfig(this.config);\n\n this.worker = sharedResourceManager.getWorker();\n this.worker ??= await sharedResourceManager.initializeWorker(config);\n\n if (!this.worker) {\n throw new Error('[ladon-ts] - worker is not defined.');\n }\n\n const workerConfig: PipelineConfig = {\n baseUrl: config.baseUrl,\n input: config.input,\n mask: config.mask,\n wasmUri: config.wasmUri,\n render: { type: 'passthrough' },\n };\n\n this.worker.postMessage({ type: 'init', config: workerConfig });\n\n let resolutionCb: () => void;\n const result = new Promise<void>((resolve) => {\n resolutionCb = resolve;\n });\n\n this.worker.onmessage = (event) => {\n if (event.data.status === 'generated') {\n this.lastMask = event.data.mask;\n this.lastResult = {\n data: event.data.mask,\n facesAndLandmarks: event.data.facesAndLandmarks,\n gesture: event.data.gesture,\n motion: event.data.motion,\n timestamp: event.data.timestamp,\n warm: true,\n };\n this.newMask = true;\n } else {\n const workerUrl = sharedResourceManager.getWorkerUrl();\n\n if (workerUrl) {\n URL.revokeObjectURL(workerUrl);\n }\n\n resolutionCb?.();\n }\n };\n\n return result;\n }\n\n public isLoaded(): boolean {\n return !!this.worker;\n }\n\n public async postRender(input: Uint8ClampedArray, timestamp: number): Promise<void> {\n // claim ownership of the input tensor's buffer and forward to worker\n\n if (!this.worker) {\n throw new Error('[ladon-ts] - worker is not defined.');\n }\n\n this.worker.postMessage(\n {\n type: 'generate',\n image: input,\n timestamp,\n },\n [input.buffer]\n );\n }\n\n public destroy(): void {\n sharedResourceManager.terminateWorker();\n }\n}\n"],"names":["LocalGenerator","config","height","width","ort","input","alpha","model_rank","input_size","output_size","numImagePixels","numInputPixels","channel","pixel","widthScale","heightScale","x","nearestNeighborX","y","nearestNeighborY","maskIdx","outputIdx","normalizedValue","timestamp","imageTensor","results","_a","_b","_c","_d","modelUrl","sharedResourceManager","_","NullGenerator","WorkerGenerator","toReturn","workerConfig","resolutionCb","result","resolve","event","workerUrl"],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sources":["../../../src/lib/generator.ts"],"sourcesContent":["import * as ort from 'onnxruntime-web';\n\nimport { PipelineConfig } from './config-types';\nimport { sharedResourceManager } from './shared-resource-manager';\n\ndeclare global {\n interface ImportMeta {\n url: string;\n }\n}\n\nexport type FrameData = Uint8ClampedArray | HTMLVideoElement;\n\nexport interface FacesAndLandmarks {\n data: Float32Array;\n dims: readonly number[];\n}\nexport interface LadonOutput {\n data: Float32Array; // 1x1x144x256 or 1x1x360x640\n facesAndLandmarks: FacesAndLandmarks; // 1x1x9x16x1439\n gesture: Float32Array; // 1x9\n motion: number; // 1x1x1x1\n timestamp: number;\n warm: boolean;\n}\n\nexport interface MaskGenerator {\n getLadonOutput(input: Uint8ClampedArray, timestamp: number): Promise<LadonOutput>;\n load(): Promise<void>;\n isLoaded(): boolean;\n postRender(input: Uint8ClampedArray, timestamp: number): Promise<void>;\n destroy(): void;\n}\n\nexport class LocalGenerator implements MaskGenerator {\n private lastResult: LadonOutput;\n private lastMask: ort.Tensor;\n private maskModel?: ort.InferenceSession;\n private lastMaskGenerationTime = 0;\n private output?: Float32Array;\n\n constructor(public readonly config: PipelineConfig) {\n const { height, width } = this.config.mask.outputSize;\n this.lastMask = new ort.Tensor('float32', new Float32Array(height * width), [\n 1,\n 1,\n height,\n width,\n ]);\n this.lastResult = {\n data: this.lastMask.data,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n /**\n * This method preprocesses an input Uint8ClampedArray to a Float32Array\n * while maintaining memory efficiency by reusing a class-scoped output buffer.\n * If the model rank is 4 (e.g., newer tiny model), it sets an alpha channel value.\n *\n * @param {Uint8ClampedArray} input - The input data to be preprocessed\n * @param {Float32Array} alpha - The alpha channel data\n * @returns {Float32Array} - The processed data\n */\n private preprocess(input: Uint8ClampedArray, alpha: Float32Array): Float32Array {\n const {\n modelRank: model_rank,\n inputSize: input_size,\n outputSize: output_size,\n } = this.config.mask;\n const { height, width } = input_size;\n const numImagePixels = height * width;\n\n // Initialize the output buffer if it is not already set\n this.output ??= new Float32Array(numImagePixels * model_rank);\n\n const numInputPixels = input.length / 4; // Divide by 4 for RGBA\n\n // Directly copy channels (assumes fixed order like BGR or RGB)\n for (let channel = 0; channel < 3; channel++) {\n for (let pixel = 0; pixel < numInputPixels; pixel++) {\n // Map input channels directly to output\n this.output[pixel + channel * numImagePixels] = input[pixel * 4 + (2 - channel)];\n }\n }\n\n // Scaling factors for width and height\n const widthScale = output_size.width / width;\n const heightScale = output_size.height / height;\n\n // Process alpha channel\n for (let x = 0; x < width; x++) {\n const nearestNeighborX = Math.floor(x * widthScale);\n for (let y = 0; y < height; y++) {\n const nearestNeighborY = Math.floor(y * heightScale);\n const maskIdx = nearestNeighborX + nearestNeighborY * output_size.width;\n const outputIdx = x + y * width + 3 * numImagePixels;\n\n // Normalize and scale alpha to [0, 255]\n const normalizedValue = Math.min(Math.max(alpha[maskIdx], 0), 255);\n this.output[outputIdx] = normalizedValue;\n }\n }\n\n return this.output;\n }\n\n public getTimeSinceLastGeneration(): number {\n return Date.now() - this.lastMaskGenerationTime;\n }\n\n public async getLadonOutput(input: Uint8ClampedArray, timestamp: number): Promise<LadonOutput> {\n if (!this.maskModel) {\n throw new Error('[ladon-ts] - mask model not loaded.');\n }\n\n if (this.getTimeSinceLastGeneration() < this.config.mask.generationIntervalMs) {\n return {\n data: this.lastMask.data,\n facesAndLandmarks: this.lastResult.facesAndLandmarks,\n gesture: this.lastResult.gesture,\n motion: this.lastResult.motion,\n timestamp: this.lastResult.timestamp,\n warm: false,\n };\n }\n\n this.lastMaskGenerationTime = Date.now();\n\n const imageTensor = new ort.Tensor('float32', this.preprocess(input, this.lastMask.data), [\n 1,\n this.config.mask.modelRank,\n this.config.mask.inputSize.height,\n this.config.mask.inputSize.width,\n ]);\n\n const results = await this.maskModel.run({ input: imageTensor });\n this.lastMask = results.segmentation;\n\n this.lastResult = {\n data: this.lastMask.data ?? new Float32Array(0),\n facesAndLandmarks: {\n data: results.faces_and_landmarks?.data ?? new Float32Array(0),\n dims: results.faces_and_landmarks?.dims ?? ([] as readonly number[]),\n },\n gesture: results.gesture?.data ?? new Float32Array(0),\n motion: results.motion?.data[0] ?? 0,\n timestamp,\n warm: true,\n };\n\n return this.lastResult;\n }\n\n async load() {\n const modelUrl = await sharedResourceManager.resolveUri(\n this.config,\n this.config.mask.modelUri\n );\n\n // Attempt to retrieve a preloaded InferenceSession from the shared resource manager.\n this.maskModel = sharedResourceManager.getModelSession(modelUrl);\n // If the model is not preloaded, load it from the provided model URL.\n this.maskModel ??= await sharedResourceManager.loadModel(this.config);\n\n if (!this.maskModel) {\n throw new Error('Failed to load the ONNX model.');\n }\n }\n\n public isLoaded(): boolean {\n return !!this.maskModel;\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async postRender(_: Uint8ClampedArray): Promise<void> {\n // empty for local generator\n }\n\n public destroy(): void {\n // empty for local generator\n }\n}\n\nexport class NullGenerator implements MaskGenerator {\n private lastMask: Float32Array;\n\n constructor(public readonly config: PipelineConfig) {\n this.lastMask = new Float32Array(\n this.config.mask.outputSize.height * this.config.mask.outputSize.width\n );\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async getLadonOutput(_: Uint8ClampedArray): Promise<LadonOutput> {\n return {\n data: this.lastMask,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n public async load(): Promise<void> {\n // empty for null generator\n }\n\n public isLoaded(): boolean {\n return true;\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async postRender(_: Uint8ClampedArray): Promise<void> {\n // empty for null generator\n }\n\n public destroy(): void {\n // empty for null generator\n }\n}\n\nexport class WorkerGenerator implements MaskGenerator {\n private lastMask: Float32Array;\n private newMask = true;\n private worker?: Worker;\n private lastResult: LadonOutput;\n\n constructor(public readonly config: PipelineConfig) {\n this.lastMask = new Float32Array(\n this.config.mask.outputSize.height * this.config.mask.outputSize.width\n );\n this.lastResult = {\n data: this.lastMask,\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n timestamp: 0,\n warm: false,\n };\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n public async getLadonOutput(_: Uint8ClampedArray): Promise<LadonOutput> {\n const toReturn = {\n data: this.lastMask,\n facesAndLandmarks: this.lastResult.facesAndLandmarks,\n gesture: this.lastResult.gesture,\n motion: this.lastResult.motion,\n timestamp: this.lastResult.timestamp,\n warm: this.newMask,\n };\n\n this.newMask = false;\n\n return toReturn;\n }\n\n public async load(): Promise<void> {\n // Prepare the worker configuration by resolving the final URLs and paths to send to the worker.\n const config = await sharedResourceManager.prepareWorkerConfig(this.config);\n\n this.worker = sharedResourceManager.getWorker();\n this.worker ??= await sharedResourceManager.initializeWorker(config);\n\n if (!this.worker) {\n throw new Error('[ladon-ts] - worker is not defined.');\n }\n\n this.worker.onmessage = (event) => {\n if (event.data.type === 'log') {\n // Forward log messages from the worker to the console.\n const { message, severity } = event.data;\n const msg = `[ladon-ts] Message received from worker: ${message}`;\n switch (severity) {\n case 'warn':\n console.warn(msg);\n break;\n case 'error':\n console.error(msg);\n break;\n default:\n console.log(msg);\n }\n } else if (event.data.status === 'generated') {\n // Update the last mask and result with the new data from the worker.\n this.lastMask = event.data.mask;\n this.lastResult = {\n data: event.data.mask,\n facesAndLandmarks: event.data.facesAndLandmarks,\n gesture: event.data.gesture,\n motion: event.data.motion,\n timestamp: event.data.timestamp,\n warm: true,\n };\n this.newMask = true;\n } else {\n // Clean up the worker and revoke the URL when the worker is finished\n const workerUrl = sharedResourceManager.getWorkerUrl();\n if (workerUrl) {\n URL.revokeObjectURL(workerUrl);\n }\n resolutionCb?.();\n }\n };\n\n const workerConfig: PipelineConfig = {\n baseUrl: config.baseUrl,\n input: config.input,\n mask: config.mask,\n wasmUri: config.wasmUri,\n render: { type: 'passthrough' },\n };\n\n this.worker.postMessage({ type: 'init', config: workerConfig });\n\n let resolutionCb: () => void;\n const result = new Promise<void>((resolve) => {\n resolutionCb = resolve;\n });\n\n return result;\n }\n\n public isLoaded(): boolean {\n return !!this.worker;\n }\n\n public async postRender(input: Uint8ClampedArray, timestamp: number): Promise<void> {\n // claim ownership of the input tensor's buffer and forward to worker\n\n if (!this.worker) {\n throw new Error('[ladon-ts] - worker is not defined.');\n }\n\n this.worker.postMessage(\n {\n type: 'generate',\n image: input,\n timestamp,\n },\n [input.buffer]\n );\n }\n\n public destroy(): void {\n sharedResourceManager.terminateWorker();\n }\n}\n"],"names":["LocalGenerator","config","height","width","ort","input","alpha","model_rank","input_size","output_size","numImagePixels","numInputPixels","channel","pixel","widthScale","heightScale","x","nearestNeighborX","y","nearestNeighborY","maskIdx","outputIdx","normalizedValue","timestamp","imageTensor","results","_a","_b","_c","_d","modelUrl","sharedResourceManager","_","NullGenerator","WorkerGenerator","toReturn","event","message","severity","msg","workerUrl","resolutionCb","workerConfig","resolve"],"mappings":";;AAkCO,MAAMA,EAAwC;AAAA,EAOjD,YAA4BC,GAAwB;AAAxB,SAAA,SAAAA,GAH5B,KAAQ,yBAAyB;AAI7B,UAAM,EAAE,QAAAC,GAAQ,OAAAC,EAAA,IAAU,KAAK,OAAO,KAAK;AACtC,SAAA,WAAW,IAAIC,EAAI,OAAO,WAAW,IAAI,aAAaF,IAASC,CAAK,GAAG;AAAA,MACxE;AAAA,MACA;AAAA,MACAD;AAAA,MACAC;AAAA,IAAA,CACH,GACD,KAAK,aAAa;AAAA,MACd,MAAM,KAAK,SAAS;AAAA,MACpB,mBAAmB,EAAE,MAAM,IAAI,aAAa,CAAC,GAAG,MAAM,GAAG;AAAA,MACzD,SAAS,IAAI,aAAa,CAAC;AAAA,MAC3B,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,MAAM;AAAA,IACV;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYI,WAAWE,GAA0BC,GAAmC;AACtE,UAAA;AAAA,MACF,WAAWC;AAAA,MACX,WAAWC;AAAA,MACX,YAAYC;AAAA,IAAA,IACZ,KAAK,OAAO,MACV,EAAE,QAAAP,GAAQ,OAAAC,EAAA,IAAUK,GACpBE,IAAiBR,IAASC;AAGhC,SAAK,WAAL,KAAK,SAAW,IAAI,aAAaO,IAAiBH,CAAU;AAEtD,UAAAI,IAAiBN,EAAM,SAAS;AAGtC,aAASO,IAAU,GAAGA,IAAU,GAAGA;AAC/B,eAASC,IAAQ,GAAGA,IAAQF,GAAgBE;AAEnC,aAAA,OAAOA,IAAQD,IAAUF,CAAc,IAAIL,EAAMQ,IAAQ,KAAK,IAAID,EAAQ;AAKjF,UAAAE,IAAaL,EAAY,QAAQN,GACjCY,IAAcN,EAAY,SAASP;AAGzC,aAASc,IAAI,GAAGA,IAAIb,GAAOa,KAAK;AAC5B,YAAMC,IAAmB,KAAK,MAAMD,IAAIF,CAAU;AAClD,eAASI,IAAI,GAAGA,IAAIhB,GAAQgB,KAAK;AAC7B,cAAMC,IAAmB,KAAK,MAAMD,IAAIH,CAAW,GAC7CK,IAAUH,IAAmBE,IAAmBV,EAAY,OAC5DY,IAAYL,IAAIE,IAAIf,IAAQ,IAAIO,GAGhCY,IAAkB,KAAK,IAAI,KAAK,IAAIhB,EAAMc,CAAO,GAAG,CAAC,GAAG,GAAG;AAC5D,aAAA,OAAOC,CAAS,IAAIC;AAAA,MAAA;AAAA,IAC7B;AAGJ,WAAO,KAAK;AAAA,EAAA;AAAA,EAGT,6BAAqC;AACjC,WAAA,KAAK,QAAQ,KAAK;AAAA,EAAA;AAAA,EAG7B,MAAa,eAAejB,GAA0BkB,GAAyC;;AACvF,QAAA,CAAC,KAAK;AACA,YAAA,IAAI,MAAM,qCAAqC;AAGzD,QAAI,KAAK,2BAA2B,IAAI,KAAK,OAAO,KAAK;AAC9C,aAAA;AAAA,QACH,MAAM,KAAK,SAAS;AAAA,QACpB,mBAAmB,KAAK,WAAW;AAAA,QACnC,SAAS,KAAK,WAAW;AAAA,QACzB,QAAQ,KAAK,WAAW;AAAA,QACxB,WAAW,KAAK,WAAW;AAAA,QAC3B,MAAM;AAAA,MACV;AAGC,SAAA,yBAAyB,KAAK,IAAI;AAEjC,UAAAC,IAAc,IAAIpB,EAAI,OAAO,WAAW,KAAK,WAAWC,GAAO,KAAK,SAAS,IAAI,GAAG;AAAA,MACtF;AAAA,MACA,KAAK,OAAO,KAAK;AAAA,MACjB,KAAK,OAAO,KAAK,UAAU;AAAA,MAC3B,KAAK,OAAO,KAAK,UAAU;AAAA,IAAA,CAC9B,GAEKoB,IAAU,MAAM,KAAK,UAAU,IAAI,EAAE,OAAOD,GAAa;AAC/D,gBAAK,WAAWC,EAAQ,cAExB,KAAK,aAAa;AAAA,MACd,MAAM,KAAK,SAAS,QAAQ,IAAI,aAAa,CAAC;AAAA,MAC9C,mBAAmB;AAAA,QACf,QAAMC,IAAAD,EAAQ,wBAAR,gBAAAC,EAA6B,SAAQ,IAAI,aAAa,CAAC;AAAA,QAC7D,QAAMC,IAAAF,EAAQ,wBAAR,gBAAAE,EAA6B,SAAS,CAAA;AAAA,MAChD;AAAA,MACA,WAASC,IAAAH,EAAQ,YAAR,gBAAAG,EAAiB,SAAQ,IAAI,aAAa,CAAC;AAAA,MACpD,UAAQC,IAAAJ,EAAQ,WAAR,gBAAAI,EAAgB,KAAK,OAAM;AAAA,MACnC,WAAAN;AAAA,MACA,MAAM;AAAA,IACV,GAEO,KAAK;AAAA,EAAA;AAAA,EAGhB,MAAM,OAAO;AACH,UAAAO,IAAW,MAAMC,EAAsB;AAAA,MACzC,KAAK;AAAA,MACL,KAAK,OAAO,KAAK;AAAA,IACrB;AAOI,QAJC,KAAA,YAAYA,EAAsB,gBAAgBD,CAAQ,GAE/D,KAAK,cAAL,KAAK,YAAc,MAAMC,EAAsB,UAAU,KAAK,MAAM,IAEhE,CAAC,KAAK;AACA,YAAA,IAAI,MAAM,gCAAgC;AAAA,EACpD;AAAA,EAGG,WAAoB;AAChB,WAAA,CAAC,CAAC,KAAK;AAAA,EAAA;AAAA;AAAA,EAIlB,MAAa,WAAWC,GAAqC;AAAA,EAAA;AAAA,EAItD,UAAgB;AAAA,EAAA;AAG3B;AAEO,MAAMC,EAAuC;AAAA,EAGhD,YAA4BhC,GAAwB;AAAxB,SAAA,SAAAA,GACxB,KAAK,WAAW,IAAI;AAAA,MAChB,KAAK,OAAO,KAAK,WAAW,SAAS,KAAK,OAAO,KAAK,WAAW;AAAA,IACrE;AAAA,EAAA;AAAA;AAAA,EAIJ,MAAa,eAAe+B,GAA4C;AAC7D,WAAA;AAAA,MACH,MAAM,KAAK;AAAA,MACX,mBAAmB,EAAE,MAAM,IAAI,aAAa,CAAC,GAAG,MAAM,GAAG;AAAA,MACzD,SAAS,IAAI,aAAa,CAAC;AAAA,MAC3B,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,MAAM;AAAA,IACV;AAAA,EAAA;AAAA,EAGJ,MAAa,OAAsB;AAAA,EAAA;AAAA,EAI5B,WAAoB;AAChB,WAAA;AAAA,EAAA;AAAA;AAAA,EAIX,MAAa,WAAWA,GAAqC;AAAA,EAAA;AAAA,EAItD,UAAgB;AAAA,EAAA;AAG3B;AAEO,MAAME,EAAyC;AAAA,EAMlD,YAA4BjC,GAAwB;AAAxB,SAAA,SAAAA,GAJ5B,KAAQ,UAAU,IAKd,KAAK,WAAW,IAAI;AAAA,MAChB,KAAK,OAAO,KAAK,WAAW,SAAS,KAAK,OAAO,KAAK,WAAW;AAAA,IACrE,GACA,KAAK,aAAa;AAAA,MACd,MAAM,KAAK;AAAA,MACX,mBAAmB,EAAE,MAAM,IAAI,aAAa,CAAC,GAAG,MAAM,GAAG;AAAA,MACzD,SAAS,IAAI,aAAa,CAAC;AAAA,MAC3B,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,MAAM;AAAA,IACV;AAAA,EAAA;AAAA;AAAA,EAIJ,MAAa,eAAe+B,GAA4C;AACpE,UAAMG,IAAW;AAAA,MACb,MAAM,KAAK;AAAA,MACX,mBAAmB,KAAK,WAAW;AAAA,MACnC,SAAS,KAAK,WAAW;AAAA,MACzB,QAAQ,KAAK,WAAW;AAAA,MACxB,WAAW,KAAK,WAAW;AAAA,MAC3B,MAAM,KAAK;AAAA,IACf;AAEA,gBAAK,UAAU,IAERA;AAAA,EAAA;AAAA,EAGX,MAAa,OAAsB;AAE/B,UAAMlC,IAAS,MAAM8B,EAAsB,oBAAoB,KAAK,MAAM;AAKtE,QAHC,KAAA,SAASA,EAAsB,UAAU,GAC9C,KAAK,WAAL,KAAK,SAAW,MAAMA,EAAsB,iBAAiB9B,CAAM,IAE/D,CAAC,KAAK;AACA,YAAA,IAAI,MAAM,qCAAqC;AAGpD,SAAA,OAAO,YAAY,CAACmC,MAAU;AAC3B,UAAAA,EAAM,KAAK,SAAS,OAAO;AAE3B,cAAM,EAAE,SAAAC,GAAS,UAAAC,EAAS,IAAIF,EAAM,MAC9BG,IAAM,4CAA4CF,CAAO;AAC/D,gBAAQC,GAAU;AAAA,UACd,KAAK;AACD,oBAAQ,KAAKC,CAAG;AAChB;AAAA,UACJ,KAAK;AACD,oBAAQ,MAAMA,CAAG;AACjB;AAAA,UACJ;AACI,oBAAQ,IAAIA,CAAG;AAAA,QAAA;AAAA,MAEhB,WAAAH,EAAM,KAAK,WAAW;AAExB,aAAA,WAAWA,EAAM,KAAK,MAC3B,KAAK,aAAa;AAAA,UACd,MAAMA,EAAM,KAAK;AAAA,UACjB,mBAAmBA,EAAM,KAAK;AAAA,UAC9B,SAASA,EAAM,KAAK;AAAA,UACpB,QAAQA,EAAM,KAAK;AAAA,UACnB,WAAWA,EAAM,KAAK;AAAA,UACtB,MAAM;AAAA,QACV,GACA,KAAK,UAAU;AAAA,WACZ;AAEG,cAAAI,IAAYT,EAAsB,aAAa;AACrD,QAAIS,KACA,IAAI,gBAAgBA,CAAS,GAElBC,KAAA,QAAAA;AAAA,MAAA;AAAA,IAEvB;AAEA,UAAMC,IAA+B;AAAA,MACjC,SAASzC,EAAO;AAAA,MAChB,OAAOA,EAAO;AAAA,MACd,MAAMA,EAAO;AAAA,MACb,SAASA,EAAO;AAAA,MAChB,QAAQ,EAAE,MAAM,cAAc;AAAA,IAClC;AAEA,SAAK,OAAO,YAAY,EAAE,MAAM,QAAQ,QAAQyC,GAAc;AAE1D,QAAAD;AAKG,WAJQ,IAAI,QAAc,CAACE,MAAY;AAC3B,MAAAF,IAAAE;AAAA,IAAA,CAClB;AAAA,EAEM;AAAA,EAGJ,WAAoB;AAChB,WAAA,CAAC,CAAC,KAAK;AAAA,EAAA;AAAA,EAGlB,MAAa,WAAWtC,GAA0BkB,GAAkC;AAG5E,QAAA,CAAC,KAAK;AACA,YAAA,IAAI,MAAM,qCAAqC;AAGzD,SAAK,OAAO;AAAA,MACR;AAAA,QACI,MAAM;AAAA,QACN,OAAOlB;AAAA,QACP,WAAAkB;AAAA,MACJ;AAAA,MACA,CAAClB,EAAM,MAAM;AAAA,IACjB;AAAA,EAAA;AAAA,EAGG,UAAgB;AACnB,IAAA0B,EAAsB,gBAAgB;AAAA,EAAA;AAE9C;"}
@@ -1,7 +1,7 @@
1
1
  import { PipelineConfig } from '../config-types';
2
2
  import { FrameData, LadonOutput } from '../generator';
3
3
 
4
- declare type TextureInitializer = () => void;
4
+ type TextureInitializer = () => void;
5
5
  export declare abstract class WebGLRenderer {
6
6
  output_canvas: HTMLCanvasElement;
7
7
  readonly config: PipelineConfig;
@@ -44,7 +44,7 @@ uniform vec2 u_resolution;
44
44
  `, this.shared_shader_functions = `
45
45
  float get_mask(vec2 uv) {
46
46
  float maskValue = texture(u_mask, uv).r;
47
- return smoothstep(0.0, 1.0, maskValue) ( );
47
+ return smoothstep(0.0, 1.0, maskValue);
48
48
  }
49
49
  `;
50
50
  const e = this.output_canvas.getContext("webgl2", { antialias: !0 });
@@ -1 +1 @@
1
- {"version":3,"file":"webgl-renderer.js","sources":["../../../../src/lib/renderer/webgl-renderer.ts"],"sourcesContent":["// webgl-renderer.ts\n\nimport { PipelineConfig } from '../config-types';\nimport { FrameData, LadonOutput } from '../generator';\nimport { bilinearUpsample } from '../util';\n\ntype TextureInitializer = () => void;\nexport abstract class WebGLRenderer {\n protected intermediate_canvas?: HTMLCanvasElement;\n protected output_canvas_2d?: CanvasRenderingContext2D;\n\n protected gl: WebGL2RenderingContext;\n\n protected image_texture!: WebGLTexture;\n protected mask_texture!: WebGLTexture;\n\n protected verts = new Float32Array([\n -1.0,\n -1.0,\n 0.0, // Vertex 1\n -1.0,\n 1.0,\n 0.0, // Vertex 2\n 1.0,\n 1.0,\n 0.0, // Vertex 3\n 1.0,\n 1.0,\n 0.0, // Vertex 4\n 1.0,\n -1.0,\n 0.0, // Vertex 5\n -1.0,\n -1.0,\n 0.0, // Vertex 6\n ]);\n\n protected vertex_shader_src = `#version 300 es\n\nin vec4 position;\n\nvoid main() {\n gl_Position = position;\n}\n`;\n\n // Shared fragment shader code\n protected fragment_shader_header = `#version 300 es\nprecision highp float;\n\nout vec4 outColor;\n\nuniform sampler2D u_image;\nuniform sampler2D u_mask;\nuniform vec2 u_resolution;\n`;\n\n // Shared shader functions for enhanced edge blending\n protected shared_shader_functions = `\nfloat get_mask(vec2 uv) {\n float maskValue = texture(u_mask, uv).r;\n return smoothstep(0.0, 1.0, maskValue) ( );\n}\n`;\n\n constructor(public output_canvas: HTMLCanvasElement, public readonly config: PipelineConfig) {\n const gl = this.output_canvas.getContext('webgl2', { antialias: true });\n\n if (!gl) {\n const output_2d = this.output_canvas.getContext('2d');\n\n if (!output_2d) {\n throw new Error('[ladon-ts] - output canvas context must be webgl2 or 2d');\n }\n\n this.output_canvas_2d = output_2d;\n this.intermediate_canvas = document.createElement('canvas');\n this.intermediate_canvas.height = this.config.input.height;\n this.intermediate_canvas.width = this.config.input.width;\n\n const gl_intermediate = this.intermediate_canvas.getContext('webgl2', {\n antialias: true,\n });\n\n if (!gl_intermediate) {\n throw new Error('[ladon-ts] - error getting output context webgl');\n }\n\n this.gl = gl_intermediate;\n } else {\n this.gl = gl;\n }\n\n // Initialize textures and buffers\n this.initTexturesAndBuffers();\n }\n\n protected initTexturesAndBuffers() {\n // Initialize image texture\n this.image_texture = this.createTexture(\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height\n );\n\n // Initialize mask texture\n this.mask_texture = this.createTexture(\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n // Create and bind vertex array\n const vertex_array = this.gl.createVertexArray();\n if (!vertex_array) {\n throw new Error('[ladon-ts] - error creating vertex array');\n }\n this.gl.bindVertexArray(vertex_array);\n\n // Create and bind buffer\n const buffer = this.gl.createBuffer();\n if (!buffer) {\n throw new Error('[ladon-ts] - error creating buffer');\n }\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.verts, this.gl.STATIC_DRAW);\n this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);\n this.gl.enableVertexAttribArray(0);\n\n this.gl.viewport(0, 0, this.config.input.width, this.config.input.height);\n }\n\n protected createTexture(\n internalFormat: number,\n width: number,\n height: number,\n initializeTexture: TextureInitializer = () => {\n // Default initializer creates an empty texture\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n internalFormat,\n width,\n height,\n 0,\n internalFormat === this.gl.RGBA ? this.gl.RGBA : this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n null\n );\n }\n ): WebGLTexture {\n const texture = this.gl.createTexture();\n if (!texture) {\n throw new Error('[ladon-ts] - error creating texture');\n }\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n // Set texture parameters\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\n // Initialize the texture using the provided function\n initializeTexture();\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, null);\n return texture;\n }\n\n protected getUVCalculation() {\n if (this.config.render.horizontalMirror) {\n // Flip both x and y coordinates when horizontal mirroring\n return `vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n // Default behavior (no mirroring)\n return `vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n protected setSharedUniforms(program: WebGLProgram) {\n const u_resolution = this.gl.getUniformLocation(program, 'u_resolution');\n if (!u_resolution) {\n throw new Error('[ladon-ts] - error finding \"u_resolution\" uniform');\n }\n this.gl.uniform2f(u_resolution, this.config.input.width, this.config.input.height);\n\n const u_image = this.gl.getUniformLocation(program, 'u_image');\n if (!u_image) {\n throw new Error('[ladon-ts] - error finding \"u_image\" uniform');\n }\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n this.gl.uniform1i(u_image, 0);\n\n const u_mask = this.gl.getUniformLocation(program, 'u_mask');\n if (u_mask) {\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.uniform1i(u_mask, 1);\n }\n }\n\n protected uploadVideoStream(input: FrameData) {\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n\n // Upload video frame or image data to the texture\n if (input instanceof HTMLVideoElement) {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n } else {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height,\n 0,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n }\n }\n\n protected uploadMask(mask?: LadonOutput) {\n // The mask may not be included if it has not been generated (e.g., frame skipped).\n if (mask?.warm) {\n const maskData = bilinearUpsample(\n mask.data,\n this.config.mask.outputSize.width,\n this.config.mask.outputSize.height,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height,\n 0,\n this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n maskData\n );\n }\n }\n\n protected postDraw() {\n if (this.output_canvas_2d && this.intermediate_canvas) {\n this.output_canvas_2d.drawImage(\n this.intermediate_canvas,\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n );\n }\n }\n}\n"],"names":["WebGLRenderer","output_canvas","config","gl","output_2d","gl_intermediate","vertex_array","buffer","internalFormat","width","height","initializeTexture","texture","program","u_resolution","u_image","u_mask","input","mask","maskData","bilinearUpsample"],"mappings":"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"}
1
+ {"version":3,"file":"webgl-renderer.js","sources":["../../../../src/lib/renderer/webgl-renderer.ts"],"sourcesContent":["// webgl-renderer.ts\n\nimport { PipelineConfig } from '../config-types';\nimport { FrameData, LadonOutput } from '../generator';\nimport { bilinearUpsample } from '../util';\n\ntype TextureInitializer = () => void;\nexport abstract class WebGLRenderer {\n protected intermediate_canvas?: HTMLCanvasElement;\n protected output_canvas_2d?: CanvasRenderingContext2D;\n\n protected gl: WebGL2RenderingContext;\n\n protected image_texture!: WebGLTexture;\n protected mask_texture!: WebGLTexture;\n\n protected verts = new Float32Array([\n -1.0,\n -1.0,\n 0.0, // Vertex 1\n -1.0,\n 1.0,\n 0.0, // Vertex 2\n 1.0,\n 1.0,\n 0.0, // Vertex 3\n 1.0,\n 1.0,\n 0.0, // Vertex 4\n 1.0,\n -1.0,\n 0.0, // Vertex 5\n -1.0,\n -1.0,\n 0.0, // Vertex 6\n ]);\n\n protected vertex_shader_src = `#version 300 es\n\nin vec4 position;\n\nvoid main() {\n gl_Position = position;\n}\n`;\n\n // Shared fragment shader code\n protected fragment_shader_header = `#version 300 es\nprecision highp float;\n\nout vec4 outColor;\n\nuniform sampler2D u_image;\nuniform sampler2D u_mask;\nuniform vec2 u_resolution;\n`;\n\n // Shared shader functions for enhanced edge blending\n protected shared_shader_functions = `\nfloat get_mask(vec2 uv) {\n float maskValue = texture(u_mask, uv).r;\n return smoothstep(0.0, 1.0, maskValue);\n}\n`;\n\n constructor(public output_canvas: HTMLCanvasElement, public readonly config: PipelineConfig) {\n const gl = this.output_canvas.getContext('webgl2', { antialias: true });\n\n if (!gl) {\n const output_2d = this.output_canvas.getContext('2d');\n\n if (!output_2d) {\n throw new Error('[ladon-ts] - output canvas context must be webgl2 or 2d');\n }\n\n this.output_canvas_2d = output_2d;\n this.intermediate_canvas = document.createElement('canvas');\n this.intermediate_canvas.height = this.config.input.height;\n this.intermediate_canvas.width = this.config.input.width;\n\n const gl_intermediate = this.intermediate_canvas.getContext('webgl2', {\n antialias: true,\n });\n\n if (!gl_intermediate) {\n throw new Error('[ladon-ts] - error getting output context webgl');\n }\n\n this.gl = gl_intermediate;\n } else {\n this.gl = gl;\n }\n\n // Initialize textures and buffers\n this.initTexturesAndBuffers();\n }\n\n protected initTexturesAndBuffers() {\n // Initialize image texture\n this.image_texture = this.createTexture(\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height\n );\n\n // Initialize mask texture\n this.mask_texture = this.createTexture(\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n // Create and bind vertex array\n const vertex_array = this.gl.createVertexArray();\n if (!vertex_array) {\n throw new Error('[ladon-ts] - error creating vertex array');\n }\n this.gl.bindVertexArray(vertex_array);\n\n // Create and bind buffer\n const buffer = this.gl.createBuffer();\n if (!buffer) {\n throw new Error('[ladon-ts] - error creating buffer');\n }\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, this.verts, this.gl.STATIC_DRAW);\n this.gl.vertexAttribPointer(0, 3, this.gl.FLOAT, false, 0, 0);\n this.gl.enableVertexAttribArray(0);\n\n this.gl.viewport(0, 0, this.config.input.width, this.config.input.height);\n }\n\n protected createTexture(\n internalFormat: number,\n width: number,\n height: number,\n initializeTexture: TextureInitializer = () => {\n // Default initializer creates an empty texture\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n internalFormat,\n width,\n height,\n 0,\n internalFormat === this.gl.RGBA ? this.gl.RGBA : this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n null\n );\n }\n ): WebGLTexture {\n const texture = this.gl.createTexture();\n if (!texture) {\n throw new Error('[ladon-ts] - error creating texture');\n }\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n\n // Set texture parameters\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n\n // Initialize the texture using the provided function\n initializeTexture();\n\n this.gl.bindTexture(this.gl.TEXTURE_2D, null);\n return texture;\n }\n\n protected getUVCalculation() {\n if (this.config.render.horizontalMirror) {\n // Flip both x and y coordinates when horizontal mirroring\n return `vec2 st = vec2(1.0 - gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n // Default behavior (no mirroring)\n return `vec2 st = vec2(gl_FragCoord.x / u_resolution.x, 1.0 - gl_FragCoord.y / u_resolution.y);`;\n }\n\n protected setSharedUniforms(program: WebGLProgram) {\n const u_resolution = this.gl.getUniformLocation(program, 'u_resolution');\n if (!u_resolution) {\n throw new Error('[ladon-ts] - error finding \"u_resolution\" uniform');\n }\n this.gl.uniform2f(u_resolution, this.config.input.width, this.config.input.height);\n\n const u_image = this.gl.getUniformLocation(program, 'u_image');\n if (!u_image) {\n throw new Error('[ladon-ts] - error finding \"u_image\" uniform');\n }\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n this.gl.uniform1i(u_image, 0);\n\n const u_mask = this.gl.getUniformLocation(program, 'u_mask');\n if (u_mask) {\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.uniform1i(u_mask, 1);\n }\n }\n\n protected uploadVideoStream(input: FrameData) {\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.image_texture);\n\n // Upload video frame or image data to the texture\n if (input instanceof HTMLVideoElement) {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n } else {\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.RGBA,\n this.config.input.width,\n this.config.input.height,\n 0,\n this.gl.RGBA,\n this.gl.UNSIGNED_BYTE,\n input\n );\n }\n }\n\n protected uploadMask(mask?: LadonOutput) {\n // The mask may not be included if it has not been generated (e.g., frame skipped).\n if (mask?.warm) {\n const maskData = bilinearUpsample(\n mask.data,\n this.config.mask.outputSize.width,\n this.config.mask.outputSize.height,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height\n );\n\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.mask_texture);\n this.gl.texImage2D(\n this.gl.TEXTURE_2D,\n 0,\n this.gl.R8,\n this.config.mask.upscaleSize.width,\n this.config.mask.upscaleSize.height,\n 0,\n this.gl.RED,\n this.gl.UNSIGNED_BYTE,\n maskData\n );\n }\n }\n\n protected postDraw() {\n if (this.output_canvas_2d && this.intermediate_canvas) {\n this.output_canvas_2d.drawImage(\n this.intermediate_canvas,\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n );\n }\n }\n}\n"],"names":["WebGLRenderer","output_canvas","config","gl","output_2d","gl_intermediate","vertex_array","buffer","internalFormat","width","height","initializeTexture","texture","program","u_resolution","u_image","u_mask","input","mask","maskData","bilinearUpsample"],"mappings":"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"}