@webex/ladon-ts 5.4.6 → 5.5.0

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/build/module/index.d.ts +3 -2
  3. package/build/module/index.js +35 -34
  4. package/build/module/index.js.map +1 -1
  5. package/build/module/lib/config-builder.d.ts +1 -1
  6. package/build/module/lib/config-builder.js +59 -58
  7. package/build/module/lib/config-builder.js.map +1 -1
  8. package/build/module/lib/config-types.d.ts +1 -1
  9. package/build/module/lib/config-types.js.map +1 -1
  10. package/build/module/lib/generator-types.d.ts +25 -0
  11. package/build/module/lib/generator.d.ts +2 -74
  12. package/build/module/lib/pipeline.js +16 -26
  13. package/build/module/lib/pipeline.js.map +1 -1
  14. package/build/module/lib/preload.js +4 -4
  15. package/build/module/lib/preload.js.map +1 -1
  16. package/build/module/lib/resource-loader.d.ts +22 -0
  17. package/build/module/lib/resource-loader.js +33 -0
  18. package/build/module/lib/resource-loader.js.map +1 -0
  19. package/build/module/lib/util.d.ts +1 -2
  20. package/build/module/lib/util.js +63 -82
  21. package/build/module/lib/util.js.map +1 -1
  22. package/build/module/lib/version.d.ts +1 -1
  23. package/build/module/lib/version.js +1 -1
  24. package/build/module/lib/version.js.map +1 -1
  25. package/build/module/lib/worker-generator.d.ts +15 -0
  26. package/build/module/lib/worker-generator.js +93 -0
  27. package/build/module/lib/worker-generator.js.map +1 -0
  28. package/build/module/lib/worker-manager.d.ts +41 -0
  29. package/build/module/lib/worker-manager.js +63 -0
  30. package/build/module/lib/worker-manager.js.map +1 -0
  31. package/build/worker/segmentation.js +791 -791
  32. package/build/worker/segmentation.js.map +1 -1
  33. package/package.json +1 -4
  34. package/build/module/lib/generator.js +0 -224
  35. package/build/module/lib/generator.js.map +0 -1
  36. package/build/module/lib/shared-resource-manager.d.ts +0 -93
  37. package/build/module/lib/shared-resource-manager.js +0 -166
  38. package/build/module/lib/shared-resource-manager.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import { WorkerGenerator as n, LocalGenerator as h } from "./generator.js";
2
- import { BlurRenderer as u } from "./renderer/blur-renderer.js";
3
- import { PassthroughRenderer as o } from "./renderer/passthrough-renderer.js";
4
- import { ReplacementRenderer as d } from "./renderer/replacement-renderer.js";
5
- import { resizeImage as m } from "./util.js";
6
- class w {
7
- constructor(e, t, s, r) {
8
- this.inputCanvas = e, this.outputCanvas = t, this.config = s, this.videoElement = r, this.loaded = !1, this.frameQueue = [], this.maskQueue = [];
1
+ import { WorkerGenerator as n } from "./worker-generator.js";
2
+ import { BlurRenderer as h } from "./renderer/blur-renderer.js";
3
+ import { PassthroughRenderer as u } from "./renderer/passthrough-renderer.js";
4
+ import { ReplacementRenderer as o } from "./renderer/replacement-renderer.js";
5
+ import { resizeImage as d } from "./util.js";
6
+ class k {
7
+ constructor(e, t, s, i) {
8
+ this.inputCanvas = e, this.outputCanvas = t, this.config = s, this.videoElement = i, this.loaded = !1, this.frameQueue = [], this.maskQueue = [];
9
9
  const a = this.inputCanvas.getContext("2d", {
10
10
  alpha: !1,
11
11
  willReadFrequently: !0
@@ -27,8 +27,8 @@ class w {
27
27
  throw new Error("[ladon-ts] - pipeline is not loaded.");
28
28
  const s = this.getInputFrameData(t);
29
29
  if (s instanceof Uint8ClampedArray ? ((!this.frameDataBuffer || this.frameDataBuffer.length !== s.length) && (this.frameDataBuffer = new Uint8ClampedArray(s.length)), this.frameDataBuffer.set(s), this.frameQueue.push({ timestamp: e, frameData: this.frameDataBuffer })) : this.frameQueue.push({ timestamp: e, frameData: s }), t || !this.lastMaskResult) {
30
- const r = s, a = this.getMaskImageData(r), i = await this.generator.getLadonOutput(a, e);
31
- this.maskQueue.push({ timestamp: i.timestamp, maskResult: i }), this.lastMaskResult = i, await this.renderSyncedFrameAndMask(), await this.generator.postRender(a, e);
30
+ const i = s, a = this.getMaskImageData(i), r = await this.generator.getLadonOutput(a, e);
31
+ this.maskQueue.push({ timestamp: r.timestamp, maskResult: r }), this.lastMaskResult = r, await this.renderSyncedFrameAndMask(), await this.generator.postRender(a, e);
32
32
  } else
33
33
  this.maskQueue.push({ timestamp: e, maskResult: this.lastMaskResult }), await this.renderSyncedFrameAndMask();
34
34
  return this.createInferenceResult(e, t);
@@ -65,7 +65,7 @@ class w {
65
65
  * @returns {Uint8ClampedArray} - The processed mask image data.
66
66
  */
67
67
  getMaskImageData(e) {
68
- return this.config.mask.inputSize.width === this.config.input.width ? e : m(
68
+ return this.config.mask.inputSize.width === this.config.input.width ? e : d(
69
69
  e,
70
70
  this.config.input.width,
71
71
  this.config.input.height,
@@ -109,28 +109,18 @@ class w {
109
109
  async load() {
110
110
  switch (this.config.render.type) {
111
111
  case "blur":
112
- this.renderer = new u(this.outputCanvas, this.config);
112
+ this.renderer = new h(this.outputCanvas, this.config);
113
113
  break;
114
114
  case "passthrough":
115
- this.renderer = new o(this.outputCanvas, this.config);
115
+ this.renderer = new u(this.outputCanvas, this.config);
116
116
  break;
117
117
  case "replacement":
118
- this.renderer = new d(this.outputCanvas, this.config);
118
+ this.renderer = new o(this.outputCanvas, this.config);
119
119
  break;
120
120
  default:
121
121
  throw new Error("[ladon-ts] - renderer not implemented.");
122
122
  }
123
- switch (await this.renderer.load(), this.config.mask.generator) {
124
- case "local":
125
- this.generator = new h(this.config);
126
- break;
127
- case "worker":
128
- this.generator = new n(this.config);
129
- break;
130
- default:
131
- throw new Error("[ladon-ts] - generator not implemented.");
132
- }
133
- await this.generator.load(), this.loaded = !0;
123
+ await this.renderer.load(), this.generator = new n(this.config), await this.generator.load(), this.loaded = !0;
134
124
  }
135
125
  /**
136
126
  * Resets the frame and mask queues.
@@ -150,6 +140,6 @@ class w {
150
140
  }
151
141
  }
152
142
  export {
153
- w as Pipeline
143
+ k as Pipeline
154
144
  };
155
145
  //# sourceMappingURL=pipeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sources":["../../../src/lib/pipeline.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport {\n FacesAndLandmarks,\n FrameData,\n LadonOutput,\n LocalGenerator,\n MaskGenerator,\n WorkerGenerator,\n} from './generator';\nimport { BlurRenderer, LadonRenderer, PassthroughRenderer, ReplacementRenderer } from './renderer';\nimport { resizeImage } from './util';\n\nexport interface IFrameInferenceResult {\n facesAndLandmarks: FacesAndLandmarks;\n gesture: Float32Array;\n motion: number;\n skipped: boolean;\n timestamp: number;\n}\n\nexport interface IPipeline {\n onFrame(timestamp: number, maskNeeded?: boolean): Promise<IFrameInferenceResult>;\n isLoaded(): boolean;\n load(): Promise<void>;\n destroy(): void;\n}\n\nexport class Pipeline implements IPipeline {\n private generator?: MaskGenerator;\n private renderer?: LadonRenderer;\n private loaded = false;\n\n private inputCanvasCtx: CanvasRenderingContext2D;\n private lastMaskResult?: LadonOutput;\n\n private frameQueue: Array<{ timestamp: number; frameData: FrameData }> = [];\n private maskQueue: Array<{ timestamp: number; maskResult: LadonOutput }> = [];\n\n private frameDataBuffer?: Uint8ClampedArray;\n\n constructor(\n private inputCanvas: HTMLCanvasElement,\n private outputCanvas: HTMLCanvasElement,\n public readonly config: PipelineConfig,\n private readonly videoElement?: HTMLVideoElement\n ) {\n const inputCanvasCtx = this.inputCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true,\n });\n\n if (!inputCanvasCtx) {\n throw new Error('[ladon-ts] - error getting input context 2d');\n }\n this.inputCanvasCtx = inputCanvasCtx;\n }\n\n /**\n * Processes a single frame and returns the inference result.\n *\n * @param timestamp - The timestamp of the frame.\n * @param performInference - Flag to perform mask inference.\n * @returns The result of the frame processing.\n * @throws If the pipeline (generator or renderer) is not loaded.\n */\n public async onFrame(\n timestamp: number,\n performInference = true\n ): Promise<IFrameInferenceResult> {\n if (!this.generator || !this.renderer) {\n throw new Error('[ladon-ts] - pipeline is not loaded.');\n }\n\n // Get the current frame (raw image data or video element)\n const frameData = this.getInputFrameData(performInference);\n\n // Reuse or create buffer for frame data copies, which is needed to ensure the data is not modified\n // or garbage collected before the inference is done.\n if (frameData instanceof Uint8ClampedArray) {\n if (!this.frameDataBuffer || this.frameDataBuffer.length !== frameData.length) {\n this.frameDataBuffer = new Uint8ClampedArray(frameData.length);\n }\n this.frameDataBuffer.set(frameData);\n this.frameQueue.push({ timestamp, frameData: this.frameDataBuffer });\n } else {\n // For video elements, just pass the reference\n this.frameQueue.push({ timestamp, frameData });\n }\n\n if (performInference || !this.lastMaskResult) {\n // Perform inference and add the new mask to the mask queue\n const rawImageData = frameData as Uint8ClampedArray;\n const maskImageData = this.getMaskImageData(rawImageData);\n const maskResult = await this.generator.getLadonOutput(maskImageData, timestamp);\n // Add the mask to the queue and use the mask timestamp to sync frames and masks.\n this.maskQueue.push({ timestamp: maskResult.timestamp, maskResult });\n this.lastMaskResult = maskResult;\n\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n\n // Post-process the mask after rendering\n await this.generator.postRender(maskImageData, timestamp);\n } else {\n // Skipping inference. Update the last mask result's timestamp to match the current frame.\n this.maskQueue.push({ timestamp, maskResult: this.lastMaskResult });\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n }\n\n // Return the inference result\n return this.createInferenceResult(timestamp, performInference);\n }\n\n /**\n * Synchronizes frames and masks to ensure they are rendered together.\n */\n private async renderSyncedFrameAndMask(): Promise<void> {\n while (this.frameQueue.length > 0 && this.maskQueue.length > 0) {\n const frame = this.frameQueue[0];\n const maskEntry = this.maskQueue[0];\n\n if (frame.timestamp === maskEntry.timestamp) {\n // Render the frame and mask together\n await this.renderer?.render(frame.frameData, maskEntry.maskResult);\n this.frameQueue.shift();\n this.maskQueue.shift();\n } else if (frame.timestamp < maskEntry.timestamp) {\n // Discard the older frame\n this.frameQueue.shift();\n } else {\n // Discard the older mask\n this.maskQueue.shift();\n }\n }\n }\n\n /**\n * Gets the raw image data from the input canvas context.\n *\n * @param needFreshImageData - Flag to indicate if fresh image data is needed.\n *\n * @returns The raw image data.\n */\n private getInputFrameData(needFreshImageData: boolean): FrameData {\n if (needFreshImageData || !this.videoElement) {\n return this.inputCanvasCtx.getImageData(\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n ).data;\n }\n\n return this.videoElement;\n }\n\n /**\n * Resizes the image data if the model expects a fixed size input.\n *\n * @param {Uint8ClampedArray} rawImageData - The raw image data.\n * @returns {Uint8ClampedArray} - The processed mask image data.\n */\n private getMaskImageData(rawImageData: Uint8ClampedArray): Uint8ClampedArray {\n // Check if resizing is needed based on configuration.\n if (this.config.mask.inputSize.width === this.config.input.width) {\n return rawImageData;\n }\n\n // Resize the image data.\n return resizeImage(\n rawImageData,\n this.config.input.width,\n this.config.input.height,\n this.config.mask.inputSize.width,\n this.config.mask.inputSize.height\n );\n }\n\n /**\n * Creates the inference result object.\n *\n * @param {number} timestamp - The timestamp of the frame.\n * @param {boolean} performedInference - Indicates if the inference was performed.\n * @returns {IFrameInferenceResult} - The result object containing inference details.\n */\n private createInferenceResult(\n timestamp: number,\n performedInference: boolean\n ): IFrameInferenceResult {\n if (!this.lastMaskResult) {\n return {\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n skipped: true,\n timestamp,\n };\n }\n\n return {\n facesAndLandmarks: this.lastMaskResult.facesAndLandmarks,\n gesture: this.lastMaskResult.gesture,\n motion: this.lastMaskResult.motion,\n skipped: !performedInference,\n timestamp,\n };\n }\n\n /**\n * Checks if the pipeline is loaded.\n *\n * @returns True if the pipeline is loaded, false otherwise.\n */\n public isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Loads the pipeline components such as the generator and renderer.\n */\n public async load(): Promise<void> {\n switch (this.config.render.type) {\n case 'blur':\n this.renderer = new BlurRenderer(this.outputCanvas, this.config);\n break;\n case 'passthrough':\n this.renderer = new PassthroughRenderer(this.outputCanvas, this.config);\n break;\n case 'replacement':\n this.renderer = new ReplacementRenderer(this.outputCanvas, this.config);\n break;\n default:\n throw new Error('[ladon-ts] - renderer not implemented.');\n }\n\n await this.renderer.load();\n\n switch (this.config.mask.generator) {\n case 'local':\n this.generator = new LocalGenerator(this.config);\n break;\n case 'worker':\n this.generator = new WorkerGenerator(this.config);\n break;\n default:\n throw new Error('[ladon-ts] - generator not implemented.');\n }\n\n await this.generator.load();\n\n this.loaded = true;\n }\n\n /**\n * Resets the frame and mask queues.\n */\n private resetQueues(): void {\n this.frameQueue = [];\n this.maskQueue = [];\n }\n\n public reset(): void {\n this.resetQueues();\n this.lastMaskResult = undefined;\n }\n\n /**\n * Destroys the pipeline and cleans up resources.\n */\n public destroy(): void {\n this.reset();\n this.generator?.destroy();\n this.renderer?.destroy();\n this.frameDataBuffer = undefined;\n }\n}\n"],"names":["Pipeline","inputCanvas","outputCanvas","config","videoElement","inputCanvasCtx","timestamp","performInference","frameData","rawImageData","maskImageData","maskResult","frame","maskEntry","_a","needFreshImageData","resizeImage","performedInference","BlurRenderer","PassthroughRenderer","ReplacementRenderer","LocalGenerator","WorkerGenerator","_b"],"mappings":"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"}
1
+ {"version":3,"file":"pipeline.js","sources":["../../../src/lib/pipeline.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport {\n FacesAndLandmarks,\n FrameData,\n LadonOutput,\n MaskGenerator,\n WorkerGenerator,\n} from './generator';\nimport { BlurRenderer, LadonRenderer, PassthroughRenderer, ReplacementRenderer } from './renderer';\nimport { resizeImage } from './util';\n\nexport interface IFrameInferenceResult {\n facesAndLandmarks: FacesAndLandmarks;\n gesture: Float32Array;\n motion: number;\n skipped: boolean;\n timestamp: number;\n}\n\nexport interface IPipeline {\n onFrame(timestamp: number, maskNeeded?: boolean): Promise<IFrameInferenceResult>;\n isLoaded(): boolean;\n load(): Promise<void>;\n destroy(): void;\n}\n\nexport class Pipeline implements IPipeline {\n private generator?: MaskGenerator;\n private renderer?: LadonRenderer;\n private loaded = false;\n\n private inputCanvasCtx: CanvasRenderingContext2D;\n private lastMaskResult?: LadonOutput;\n\n private frameQueue: Array<{ timestamp: number; frameData: FrameData }> = [];\n private maskQueue: Array<{ timestamp: number; maskResult: LadonOutput }> = [];\n\n private frameDataBuffer?: Uint8ClampedArray;\n\n constructor(\n private inputCanvas: HTMLCanvasElement,\n private outputCanvas: HTMLCanvasElement,\n public readonly config: PipelineConfig,\n private readonly videoElement?: HTMLVideoElement\n ) {\n const inputCanvasCtx = this.inputCanvas.getContext('2d', {\n alpha: false,\n willReadFrequently: true,\n });\n\n if (!inputCanvasCtx) {\n throw new Error('[ladon-ts] - error getting input context 2d');\n }\n this.inputCanvasCtx = inputCanvasCtx;\n }\n\n /**\n * Processes a single frame and returns the inference result.\n *\n * @param timestamp - The timestamp of the frame.\n * @param performInference - Flag to perform mask inference.\n * @returns The result of the frame processing.\n * @throws If the pipeline (generator or renderer) is not loaded.\n */\n public async onFrame(\n timestamp: number,\n performInference = true\n ): Promise<IFrameInferenceResult> {\n if (!this.generator || !this.renderer) {\n throw new Error('[ladon-ts] - pipeline is not loaded.');\n }\n\n // Get the current frame (raw image data or video element)\n const frameData = this.getInputFrameData(performInference);\n\n // Reuse or create buffer for frame data copies, which is needed to ensure the data is not modified\n // or garbage collected before the inference is done.\n if (frameData instanceof Uint8ClampedArray) {\n if (!this.frameDataBuffer || this.frameDataBuffer.length !== frameData.length) {\n this.frameDataBuffer = new Uint8ClampedArray(frameData.length);\n }\n this.frameDataBuffer.set(frameData);\n this.frameQueue.push({ timestamp, frameData: this.frameDataBuffer });\n } else {\n // For video elements, just pass the reference\n this.frameQueue.push({ timestamp, frameData });\n }\n\n if (performInference || !this.lastMaskResult) {\n // Perform inference and add the new mask to the mask queue\n const rawImageData = frameData as Uint8ClampedArray;\n const maskImageData = this.getMaskImageData(rawImageData);\n const maskResult = await this.generator.getLadonOutput(maskImageData, timestamp);\n // Add the mask to the queue and use the mask timestamp to sync frames and masks.\n this.maskQueue.push({ timestamp: maskResult.timestamp, maskResult });\n this.lastMaskResult = maskResult;\n\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n\n // Post-process the mask after rendering\n await this.generator.postRender(maskImageData, timestamp);\n } else {\n // Skipping inference. Update the last mask result's timestamp to match the current frame.\n this.maskQueue.push({ timestamp, maskResult: this.lastMaskResult });\n // Sync frames and masks to render together\n await this.renderSyncedFrameAndMask();\n }\n\n // Return the inference result\n return this.createInferenceResult(timestamp, performInference);\n }\n\n /**\n * Synchronizes frames and masks to ensure they are rendered together.\n */\n private async renderSyncedFrameAndMask(): Promise<void> {\n while (this.frameQueue.length > 0 && this.maskQueue.length > 0) {\n const frame = this.frameQueue[0];\n const maskEntry = this.maskQueue[0];\n\n if (frame.timestamp === maskEntry.timestamp) {\n // Render the frame and mask together\n await this.renderer?.render(frame.frameData, maskEntry.maskResult);\n this.frameQueue.shift();\n this.maskQueue.shift();\n } else if (frame.timestamp < maskEntry.timestamp) {\n // Discard the older frame\n this.frameQueue.shift();\n } else {\n // Discard the older mask\n this.maskQueue.shift();\n }\n }\n }\n\n /**\n * Gets the raw image data from the input canvas context.\n *\n * @param needFreshImageData - Flag to indicate if fresh image data is needed.\n *\n * @returns The raw image data.\n */\n private getInputFrameData(needFreshImageData: boolean): FrameData {\n if (needFreshImageData || !this.videoElement) {\n return this.inputCanvasCtx.getImageData(\n 0,\n 0,\n this.config.input.width,\n this.config.input.height\n ).data;\n }\n\n return this.videoElement;\n }\n\n /**\n * Resizes the image data if the model expects a fixed size input.\n *\n * @param {Uint8ClampedArray} rawImageData - The raw image data.\n * @returns {Uint8ClampedArray} - The processed mask image data.\n */\n private getMaskImageData(rawImageData: Uint8ClampedArray): Uint8ClampedArray {\n // Check if resizing is needed based on configuration.\n if (this.config.mask.inputSize.width === this.config.input.width) {\n return rawImageData;\n }\n\n // Resize the image data.\n return resizeImage(\n rawImageData,\n this.config.input.width,\n this.config.input.height,\n this.config.mask.inputSize.width,\n this.config.mask.inputSize.height\n );\n }\n\n /**\n * Creates the inference result object.\n *\n * @param {number} timestamp - The timestamp of the frame.\n * @param {boolean} performedInference - Indicates if the inference was performed.\n * @returns {IFrameInferenceResult} - The result object containing inference details.\n */\n private createInferenceResult(\n timestamp: number,\n performedInference: boolean\n ): IFrameInferenceResult {\n if (!this.lastMaskResult) {\n return {\n facesAndLandmarks: { data: new Float32Array(0), dims: [] },\n gesture: new Float32Array(0),\n motion: 0,\n skipped: true,\n timestamp,\n };\n }\n\n return {\n facesAndLandmarks: this.lastMaskResult.facesAndLandmarks,\n gesture: this.lastMaskResult.gesture,\n motion: this.lastMaskResult.motion,\n skipped: !performedInference,\n timestamp,\n };\n }\n\n /**\n * Checks if the pipeline is loaded.\n *\n * @returns True if the pipeline is loaded, false otherwise.\n */\n public isLoaded(): boolean {\n return this.loaded;\n }\n\n /**\n * Loads the pipeline components such as the generator and renderer.\n */\n public async load(): Promise<void> {\n switch (this.config.render.type) {\n case 'blur':\n this.renderer = new BlurRenderer(this.outputCanvas, this.config);\n break;\n case 'passthrough':\n this.renderer = new PassthroughRenderer(this.outputCanvas, this.config);\n break;\n case 'replacement':\n this.renderer = new ReplacementRenderer(this.outputCanvas, this.config);\n break;\n default:\n throw new Error('[ladon-ts] - renderer not implemented.');\n }\n\n await this.renderer.load();\n\n this.generator = new WorkerGenerator(this.config);\n await this.generator.load();\n\n this.loaded = true;\n }\n\n /**\n * Resets the frame and mask queues.\n */\n private resetQueues(): void {\n this.frameQueue = [];\n this.maskQueue = [];\n }\n\n public reset(): void {\n this.resetQueues();\n this.lastMaskResult = undefined;\n }\n\n /**\n * Destroys the pipeline and cleans up resources.\n */\n public destroy(): void {\n this.reset();\n this.generator?.destroy();\n this.renderer?.destroy();\n this.frameDataBuffer = undefined;\n }\n}\n"],"names":["Pipeline","inputCanvas","outputCanvas","config","videoElement","inputCanvasCtx","timestamp","performInference","frameData","rawImageData","maskImageData","maskResult","frame","maskEntry","_a","needFreshImageData","resizeImage","performedInference","BlurRenderer","PassthroughRenderer","ReplacementRenderer","WorkerGenerator","_b"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { sharedResourceManager as r } from "./shared-resource-manager.js";
2
- const o = async (e) => {
3
- e.mask.generator === "worker" ? await r.preloadWorker(e) : await r.loadModel(e);
1
+ import { workerManager as o } from "./worker-manager.js";
2
+ const e = async (r) => {
3
+ await o.preloadWorker(r);
4
4
  };
5
5
  export {
6
- o as preload
6
+ e as preload
7
7
  };
8
8
  //# sourceMappingURL=preload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"preload.js","sources":["../../../src/lib/preload.ts"],"sourcesContent":["import { PreloadConfig } from './config-types';\nimport { sharedResourceManager } from './shared-resource-manager';\n\n/**\n * Preload the resources using the provided configuration. This function is used to preload the model\n * and the worker before creating the pipeline.\n *\n * @param config - The configuration object.\n */\nexport const preload = async (config: PreloadConfig) => {\n if (config.mask.generator === 'worker') {\n await sharedResourceManager.preloadWorker(config);\n } else {\n await sharedResourceManager.loadModel(config);\n }\n};\n"],"names":["preload","config","sharedResourceManager"],"mappings":";AASa,MAAAA,IAAU,OAAOC,MAA0B;AAChD,EAAAA,EAAO,KAAK,cAAc,WACpB,MAAAC,EAAsB,cAAcD,CAAM,IAE1C,MAAAC,EAAsB,UAAUD,CAAM;AAEpD;"}
1
+ {"version":3,"file":"preload.js","sources":["../../../src/lib/preload.ts"],"sourcesContent":["import { PreloadConfig } from './config-types';\nimport { workerManager } from './worker-manager';\n\n/**\n * Preload the resources using the provided configuration. This function is used to preload the model\n * and the worker before creating the pipeline.\n *\n * @param config - The configuration object.\n */\nexport const preload = async (config: PreloadConfig) => {\n await workerManager.preloadWorker(config);\n};\n"],"names":["preload","config","workerManager"],"mappings":";AASa,MAAAA,IAAU,OAAOC,MAA0B;AAC9C,QAAAC,EAAc,cAAcD,CAAM;AAC5C;"}
@@ -0,0 +1,22 @@
1
+ import { PreloadConfig } from './config-types';
2
+ export declare class ResourceLoader {
3
+ /**
4
+ * In-memory cache for resolved URLs. This is used to avoid redundant network requests for
5
+ * the same asset URI. The cache is a Map where the key is the asset URI and the value is
6
+ * the resolved URL.
7
+ */
8
+ private resolvedUriCache;
9
+ /**
10
+ * Resolves the full URL for a given asset. Non-file URIs are treated as paths and resolved
11
+ * using the `toAbsoluteURI` method. If the assetUri is already resolved, or if it's found in
12
+ * cache, it will be returned directly. If an assetUrlResolver function is provided in the
13
+ * configuration, it will be used to resolve the URL if the assetUri is not fully qualified,
14
+ * a blob URL, or in the cache.
15
+ *
16
+ * @param config - The preload configuration.
17
+ * @param assetUri - The asset URI from the config.
18
+ * @returns The resolved full URL.
19
+ */
20
+ resolveUri(config: PreloadConfig, assetUri?: string): Promise<string>;
21
+ }
22
+ export declare const resourceLoader: ResourceLoader;
@@ -0,0 +1,33 @@
1
+ import { isResolvedUri as l, toAbsoluteURI as s } from "./util.js";
2
+ class t {
3
+ constructor() {
4
+ this.resolvedUriCache = /* @__PURE__ */ new Map();
5
+ }
6
+ /**
7
+ * Resolves the full URL for a given asset. Non-file URIs are treated as paths and resolved
8
+ * using the `toAbsoluteURI` method. If the assetUri is already resolved, or if it's found in
9
+ * cache, it will be returned directly. If an assetUrlResolver function is provided in the
10
+ * configuration, it will be used to resolve the URL if the assetUri is not fully qualified,
11
+ * a blob URL, or in the cache.
12
+ *
13
+ * @param config - The preload configuration.
14
+ * @param assetUri - The asset URI from the config.
15
+ * @returns The resolved full URL.
16
+ */
17
+ async resolveUri(o, e) {
18
+ if (!e)
19
+ throw new Error("Asset URI is undefined.");
20
+ if (this.resolvedUriCache.has(e))
21
+ return this.resolvedUriCache.get(e);
22
+ let r;
23
+ if (l(e) ? r = e : e.match(/\.[a-z0-9]+$/i) ? typeof o.assetUrlResolver == "function" && (r = await o.assetUrlResolver(e, o)) : r = s(e, o.baseUrl), !r)
24
+ throw new Error(`Failed to resolve asset URI: ${e}`);
25
+ return this.resolvedUriCache.set(e, r), r;
26
+ }
27
+ }
28
+ const d = new t();
29
+ export {
30
+ t as ResourceLoader,
31
+ d as resourceLoader
32
+ };
33
+ //# sourceMappingURL=resource-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-loader.js","sources":["../../../src/lib/resource-loader.ts"],"sourcesContent":["import { PreloadConfig } from './config-types';\nimport { isResolvedUri, toAbsoluteURI } from './util';\n\nexport class ResourceLoader {\n /**\n * In-memory cache for resolved URLs. This is used to avoid redundant network requests for\n * the same asset URI. The cache is a Map where the key is the asset URI and the value is\n * the resolved URL.\n */\n private resolvedUriCache: Map<string, string> = new Map();\n\n /**\n * Resolves the full URL for a given asset. Non-file URIs are treated as paths and resolved\n * using the `toAbsoluteURI` method. If the assetUri is already resolved, or if it's found in\n * cache, it will be returned directly. If an assetUrlResolver function is provided in the\n * configuration, it will be used to resolve the URL if the assetUri is not fully qualified,\n * a blob URL, or in the cache.\n *\n * @param config - The preload configuration.\n * @param assetUri - The asset URI from the config.\n * @returns The resolved full URL.\n */\n public async resolveUri(config: PreloadConfig, assetUri?: string): Promise<string> {\n if (!assetUri) {\n throw new Error('Asset URI is undefined.');\n }\n\n // Check if the URL is already cached\n if (this.resolvedUriCache.has(assetUri)) {\n return this.resolvedUriCache.get(assetUri) as string;\n }\n\n let resolvedUrl: string | undefined;\n\n if (isResolvedUri(assetUri)) {\n // If the assetUri is fully qualified or a blob URL, return it directly.\n // (Assets uris are resolved before being sent to the worker.)\n resolvedUrl = assetUri;\n } else if (!assetUri.match(/\\.[a-z0-9]+$/i)) {\n // Resolve as an absolute path to a non-file endpoint (e.g., wasmPaths).\n resolvedUrl = toAbsoluteURI(assetUri, config.baseUrl);\n } else if (typeof config.assetUrlResolver === 'function') {\n // Resolve via assetUrlResolver. This delegates the resolution logic to the caller.\n resolvedUrl = await config.assetUrlResolver(assetUri, config);\n }\n\n if (!resolvedUrl) {\n throw new Error(`Failed to resolve asset URI: ${assetUri}`);\n }\n\n // Cache the resolved URL\n this.resolvedUriCache.set(assetUri, resolvedUrl);\n\n return resolvedUrl;\n }\n}\n\n// The resource loader is a singleton that can be used to load resources\nexport const resourceLoader = new ResourceLoader();\n"],"names":["ResourceLoader","config","assetUri","resolvedUrl","isResolvedUri","toAbsoluteURI","resourceLoader"],"mappings":";AAGO,MAAMA,EAAe;AAAA,EAArB,cAAA;AAMK,SAAA,uCAA4C,IAAI;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaxD,MAAa,WAAWC,GAAuBC,GAAoC;AAC/E,QAAI,CAACA;AACK,YAAA,IAAI,MAAM,yBAAyB;AAI7C,QAAI,KAAK,iBAAiB,IAAIA,CAAQ;AAC3B,aAAA,KAAK,iBAAiB,IAAIA,CAAQ;AAGzC,QAAAC;AAcJ,QAZIC,EAAcF,CAAQ,IAGRC,IAAAD,IACNA,EAAS,MAAM,eAAe,IAG/B,OAAOD,EAAO,oBAAqB,eAE1CE,IAAc,MAAMF,EAAO,iBAAiBC,GAAUD,CAAM,KAH9CE,IAAAE,EAAcH,GAAUD,EAAO,OAAO,GAMpD,CAACE;AACD,YAAM,IAAI,MAAM,gCAAgCD,CAAQ,EAAE;AAIzD,gBAAA,iBAAiB,IAAIA,GAAUC,CAAW,GAExCA;AAAA,EAAA;AAEf;AAGa,MAAAG,IAAiB,IAAIN,EAAe;"}
@@ -48,7 +48,6 @@ export declare function bilinearUpsample(input: Float32Array, srcWidth: number,
48
48
  * @returns {Uint8ClampedArray} The upsampled image data in Uint8ClampedArray format.
49
49
  */
50
50
  export declare function lanczos3Upsample(input: Float32Array, srcWidth: number, srcHeight: number, targetWidth: number, targetHeight: number): Uint8ClampedArray;
51
- export declare const toAbsoluteURI: (relativeURL: string, baseURL?: string) => string;
52
51
  export declare function compileShader(gl: WebGL2RenderingContext, shader_type: number, source: string): WebGLShader;
53
52
  export declare function linkProgram(gl: WebGL2RenderingContext, vertex_shader: WebGLShader, fragment_shader: WebGLShader): WebGLProgram;
54
53
  /**
@@ -61,4 +60,4 @@ export declare function linkProgram(gl: WebGL2RenderingContext, vertex_shader: W
61
60
  * @returns Whether the URI is already resolved.
62
61
  */
63
62
  export declare function isResolvedUri(uri: string): boolean;
64
- export declare function loadAndCacheFile(fileUrl: string): Promise<ArrayBufferLike | Uint8Array>;
63
+ export declare const toAbsoluteURI: (relativeURL: string, baseURL?: string) => string;
@@ -1,76 +1,75 @@
1
- var C = /* @__PURE__ */ ((o) => (o.Nearest = "nearest", o))(C || {});
2
- const E = (o, r, s, n, t) => {
3
- const a = new Uint8ClampedArray(n * t * 4), m = r / n, M = s / t, i = r * 4;
4
- let c = 0;
5
- for (let e = 0; e < t; e++) {
6
- const l = Math.floor(e * M) * i;
7
- for (let f = 0; f < n; f++) {
8
- const u = l + Math.floor(f * m) * 4;
9
- a[c++] = o[u], a[c++] = o[u + 1], a[c++] = o[u + 2], a[c++] = o[u + 3];
1
+ var U = /* @__PURE__ */ ((o) => (o.Nearest = "nearest", o))(U || {});
2
+ const A = (o, n, u, r, e) => {
3
+ const l = new Uint8ClampedArray(r * e * 4), p = n / r, y = u / e, s = n * 4;
4
+ let a = 0;
5
+ for (let t = 0; t < e; t++) {
6
+ const f = Math.floor(t * y) * s;
7
+ for (let c = 0; c < r; c++) {
8
+ const m = f + Math.floor(c * p) * 4;
9
+ l[a++] = o[m], l[a++] = o[m + 1], l[a++] = o[m + 2], l[a++] = o[m + 3];
10
10
  }
11
11
  }
12
- return a;
12
+ return l;
13
13
  };
14
- function I(o, r, s, n, t) {
15
- const a = new Uint8ClampedArray(n * t);
16
- if (r === n && s === t) {
17
- for (let i = 0; i < o.length; i++)
18
- a[i] = Math.min(Math.max(o[i], 0), 255);
19
- return a;
14
+ function d(o, n, u, r, e) {
15
+ const l = new Uint8ClampedArray(r * e);
16
+ if (n === r && u === e) {
17
+ for (let s = 0; s < o.length; s++)
18
+ l[s] = Math.min(Math.max(o[s], 0), 255);
19
+ return l;
20
20
  }
21
- const m = (r - 1) / (n - 1), M = (s - 1) / (t - 1);
22
- for (let i = 0; i < t; i++)
23
- for (let c = 0; c < n; c++) {
24
- const e = m * c, l = M * i, f = Math.floor(e), u = Math.floor(l), d = Math.min(Math.ceil(e), r - 1), S = Math.min(Math.ceil(l), s - 1), y = e - f, h = l - u, p = o[u * r + f], w = o[u * r + d], P = o[S * r + f], x = o[S * r + d], k = p * (1 - y) * (1 - h) + w * y * (1 - h) + P * (1 - y) * h + x * y * h;
25
- a[i * n + c] = Math.min(Math.max(k, 0), 255);
21
+ const p = (n - 1) / (r - 1), y = (u - 1) / (e - 1);
22
+ for (let s = 0; s < e; s++)
23
+ for (let a = 0; a < r; a++) {
24
+ const t = p * a, f = y * s, c = Math.floor(t), m = Math.floor(f), S = Math.min(Math.ceil(t), n - 1), x = Math.min(Math.ceil(f), u - 1), w = t - c, i = f - m, M = o[m * n + c], h = o[m * n + S], k = o[x * n + c], P = o[x * n + S], I = M * (1 - w) * (1 - i) + h * w * (1 - i) + k * (1 - w) * i + P * w * i;
25
+ l[s * r + a] = Math.min(Math.max(I, 0), 255);
26
26
  }
27
- return a;
27
+ return l;
28
28
  }
29
- function R(o, r, s, n, t) {
30
- const a = new Uint8ClampedArray(n * t), m = r / n, M = s / t, i = (e, l) => {
31
- if (e === 0) return 1;
32
- if (e < 0 && (e = -e), e < l) {
33
- const f = Math.PI * e;
34
- return l * Math.sin(f) * Math.sin(f / l) / (f * f);
29
+ function E(o, n, u, r, e) {
30
+ const l = new Uint8ClampedArray(r * e), p = n / r, y = u / e, s = (t, f) => {
31
+ if (t === 0) return 1;
32
+ if (t < 0 && (t = -t), t < f) {
33
+ const c = Math.PI * t;
34
+ return f * Math.sin(c) * Math.sin(c / f) / (c * c);
35
35
  }
36
36
  return 0;
37
- }, c = 3;
38
- for (let e = 0; e < t; e++)
39
- for (let l = 0; l < n; l++) {
40
- const f = l * m, u = e * M, d = Math.floor(f), S = Math.floor(u);
41
- let y = 0, h = 0;
42
- for (let p = S - c + 1; p <= S + c; p++)
43
- for (let w = d - c + 1; w <= d + c; w++)
44
- if (w >= 0 && w < r && p >= 0 && p < s) {
45
- const P = o[p * r + w], x = i(f - w, c) * i(u - p, c);
46
- y += P * x, h += x;
37
+ }, a = 3;
38
+ for (let t = 0; t < e; t++)
39
+ for (let f = 0; f < r; f++) {
40
+ const c = f * p, m = t * y, S = Math.floor(c), x = Math.floor(m);
41
+ let w = 0, i = 0;
42
+ for (let M = x - a + 1; M <= x + a; M++)
43
+ for (let h = S - a + 1; h <= S + a; h++)
44
+ if (h >= 0 && h < n && M >= 0 && M < u) {
45
+ const k = o[M * n + h], P = s(c - h, a) * s(m - M, a);
46
+ w += k * P, i += P;
47
47
  }
48
- a[e * n + l] = h !== 0 ? Math.round(y / h) : 0;
48
+ l[t * r + f] = i !== 0 ? Math.round(w / i) : 0;
49
49
  }
50
- return a;
50
+ return l;
51
51
  }
52
- const A = (o, r) => !r || o.startsWith("http") ? new URL(o).href : o ? r.replace(/\/+$/, "") + "/" + o.replace(/^\/+/, "") : r;
53
- function L(o, r, s) {
54
- const n = o.createShader(r);
55
- if (!n)
52
+ function L(o, n, u) {
53
+ const r = o.createShader(n);
54
+ if (!r)
56
55
  throw new Error("[ladon-ts] - error creating shader");
57
- if (o.shaderSource(n, s), o.compileShader(n), !o.getShaderParameter(n, o.COMPILE_STATUS)) {
58
- const t = o.getShaderInfoLog(n) ?? "unknown error compiling shader.";
59
- throw new Error("[ladon-ts] - " + t);
56
+ if (o.shaderSource(r, u), o.compileShader(r), !o.getShaderParameter(r, o.COMPILE_STATUS)) {
57
+ const e = o.getShaderInfoLog(r) ?? "unknown error compiling shader.";
58
+ throw new Error("[ladon-ts] - " + e);
60
59
  }
61
- return n;
60
+ return r;
62
61
  }
63
- function T(o, r, s) {
64
- const n = o.createProgram();
65
- if (!n)
62
+ function R(o, n, u) {
63
+ const r = o.createProgram();
64
+ if (!r)
66
65
  throw new Error("[ladon-ts] - error creating GPU program");
67
- if (o.attachShader(n, r), o.attachShader(n, s), o.linkProgram(n), !o.getProgramParameter(n, o.LINK_STATUS)) {
68
- const t = o.getProgramInfoLog(n) ?? "unknown error linking program.";
69
- throw new Error("[ladon-ts] - " + t);
66
+ if (o.attachShader(r, n), o.attachShader(r, u), o.linkProgram(r), !o.getProgramParameter(r, o.LINK_STATUS)) {
67
+ const e = o.getProgramInfoLog(r) ?? "unknown error linking program.";
68
+ throw new Error("[ladon-ts] - " + e);
70
69
  }
71
- return n;
70
+ return r;
72
71
  }
73
- function b(o) {
72
+ function C(o) {
74
73
  if (o.startsWith("blob:"))
75
74
  return !0;
76
75
  try {
@@ -79,33 +78,15 @@ function b(o) {
79
78
  return !1;
80
79
  }
81
80
  }
82
- async function U(o) {
83
- const r = await caches.open("ladon-cache"), s = await r.match(o);
84
- if (s)
85
- return s.arrayBuffer();
86
- const n = await fetch(o);
87
- if (!n.ok)
88
- throw new Error(`Failed to fetch file: ${o}`);
89
- const t = n.headers.get("Content-Type") || "application/octet-stream";
90
- if (!t.includes("application/wasm") && !t.includes("binary/octet-stream"))
91
- throw new Error(`Unexpected MIME type: ${t} for ${o}`);
92
- const a = await n.arrayBuffer(), m = new Response(a, {
93
- headers: {
94
- "Content-Type": t,
95
- "Content-Length": a.byteLength.toString()
96
- }
97
- });
98
- return await r.put(o, m), a;
99
- }
81
+ const T = (o, n) => !n || o.startsWith("http") ? new URL(o).href : o ? n.replace(/\/+$/, "") + "/" + o.replace(/^\/+/, "") : n;
100
82
  export {
101
- C as InterpolationMethod,
102
- I as bilinearUpsample,
83
+ U as InterpolationMethod,
84
+ d as bilinearUpsample,
103
85
  L as compileShader,
104
- b as isResolvedUri,
105
- R as lanczos3Upsample,
106
- T as linkProgram,
107
- U as loadAndCacheFile,
108
- E as resizeImage,
109
- A as toAbsoluteURI
86
+ C as isResolvedUri,
87
+ E as lanczos3Upsample,
88
+ R as linkProgram,
89
+ A as resizeImage,
90
+ T as toAbsoluteURI
110
91
  };
111
92
  //# sourceMappingURL=util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sources":["../../../src/lib/util.ts"],"sourcesContent":["export enum InterpolationMethod {\n Nearest = 'nearest',\n}\n\n/**\n * Resizes an image from the source dimensions to target dimensions.\n *\n * @param {Uint8ClampedArray} imageData The source image data in Uint8ClampedArray format.\n * @param {number} srcWidth The width of the source image.\n * @param {number} srcHeight The height of the source image.\n * @param {number} targetWidth The width of the target image.\n * @param {number} targetHeight The height of the target image.\n *\n * @returns {Uint8ClampedArray} The target image data in Uint8ClampedArray format.\n *\n * @example\n * const targetData = resizeImage(sourceData, 800, 600, 400, 300);\n *\n * @note The function uses a \"nearest neighbor\" algorithm for resizing,\n * which is fast but might not provide the best quality for all images.\n */\nexport const resizeImage = (\n imageData: Uint8ClampedArray,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n): Uint8ClampedArray => {\n const targetData = new Uint8ClampedArray(targetWidth * targetHeight * 4);\n const xRatio = srcWidth / targetWidth;\n const yRatio = srcHeight / targetHeight;\n const scaledSrcWidth = srcWidth * 4;\n let offset = 0;\n\n for (let y = 0; y < targetHeight; y++) {\n const srcY = Math.floor(y * yRatio) * scaledSrcWidth;\n for (let x = 0; x < targetWidth; x++) {\n const srcOffset = srcY + Math.floor(x * xRatio) * 4;\n\n targetData[offset++] = imageData[srcOffset];\n targetData[offset++] = imageData[srcOffset + 1];\n targetData[offset++] = imageData[srcOffset + 2];\n targetData[offset++] = imageData[srcOffset + 3];\n }\n }\n\n return targetData;\n};\n\n/**\n * Upsamples an image using the bilinear interpolation method. The input image is expected to be in\n * Float32Array format. The output image is in Uint8ClampedArray format. The input image is expected\n * to be in the [0, 1] range. The output image is in the [0, 255] range.\n *\n * @param {Float32Array} input The input image data in Float32Array format.\n * @param {number} srcWidth The width of the source image.\n * @param {number} srcHeight The height of the source image.\n * @param {number} targetWidth The width of the target image.\n * @param {number} targetHeight The height of the target image.\n *\n * @returns {Uint8ClampedArray} The upsampled image data in Uint8ClampedArray format.\n *\n */\nexport function bilinearUpsample(\n input: Float32Array,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n) {\n const output = new Uint8ClampedArray(targetWidth * targetHeight);\n\n // If the source and target dimensions are the same, just copy the input to the output.\n // The output is expected to be in the [0, 255] range\n if (srcWidth === targetWidth && srcHeight === targetHeight) {\n for (let i = 0; i < input.length; i++) {\n output[i] = Math.min(Math.max(input[i], 0), 255);\n }\n return output;\n }\n\n const xRatio = (srcWidth - 1) / (targetWidth - 1);\n const yRatio = (srcHeight - 1) / (targetHeight - 1);\n\n for (let i = 0; i < targetHeight; i++) {\n for (let j = 0; j < targetWidth; j++) {\n const x = xRatio * j;\n const y = yRatio * i;\n\n const xL = Math.floor(x);\n const yL = Math.floor(y);\n const xH = Math.min(Math.ceil(x), srcWidth - 1);\n const yH = Math.min(Math.ceil(y), srcHeight - 1);\n\n const xWeight = x - xL;\n const yWeight = y - yL;\n\n const a = input[yL * srcWidth + xL];\n const b = input[yL * srcWidth + xH];\n const c = input[yH * srcWidth + xL];\n const d = input[yH * srcWidth + xH];\n\n const value =\n a * (1 - xWeight) * (1 - yWeight) +\n b * xWeight * (1 - yWeight) +\n c * (1 - xWeight) * yWeight +\n d * xWeight * yWeight;\n\n output[i * targetWidth + j] = Math.min(Math.max(value, 0), 255);\n }\n }\n\n return output;\n}\n\n/**\n * Upsamples an image using the Lanczos3 interpolation method. The input image is expected to be in\n * Float32Array format. The output image is in Uint8ClampedArray format. The input image is expected\n * to be in the [0, 1] range. The output image is in the [0, 255] range.\n *\n * @param {Float32Array} input The input image data in Float32Array format.\n * @param {number} srcWidth The width of the source image.\n * @param {number} srcHeight The height of the source image.\n * @param {number} targetWidth The width of the target image.\n * @param {number} targetHeight The height of the target image.\n *\n * @returns {Uint8ClampedArray} The upsampled image data in Uint8ClampedArray format.\n */\nexport function lanczos3Upsample(\n input: Float32Array,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n) {\n const output = new Uint8ClampedArray(targetWidth * targetHeight);\n\n const xRatio = srcWidth / targetWidth;\n const yRatio = srcHeight / targetHeight;\n\n const lanczos = (x: number, a: number) => {\n if (x === 0) return 1;\n if (x < 0) x = -x;\n if (x < a) {\n const piX = Math.PI * x;\n return (a * Math.sin(piX) * Math.sin(piX / a)) / (piX * piX);\n }\n return 0;\n };\n\n const a = 3; // Lanczos parameter\n\n for (let i = 0; i < targetHeight; i++) {\n for (let j = 0; j < targetWidth; j++) {\n const x = j * xRatio;\n const y = i * yRatio;\n\n const xL = Math.floor(x);\n const yL = Math.floor(y);\n\n let value = 0;\n let weightSum = 0;\n\n for (let ky = yL - a + 1; ky <= yL + a; ky++) {\n for (let kx = xL - a + 1; kx <= xL + a; kx++) {\n if (kx >= 0 && kx < srcWidth && ky >= 0 && ky < srcHeight) {\n const pixel = input[ky * srcWidth + kx];\n const weight = lanczos(x - kx, a) * lanczos(y - ky, a);\n value += pixel * weight;\n weightSum += weight;\n }\n }\n }\n\n output[i * targetWidth + j] = weightSum !== 0 ? Math.round(value / weightSum) : 0;\n }\n }\n\n return output;\n}\n\nexport const toAbsoluteURI = (relativeURL: string, baseURL?: string) => {\n // adapted from - https://github.com/axios/axios/blob/fe7d09bb08fa1c0e414956b7fc760c80459b0a43/lib/helpers/combineURLs.js\n\n if (!baseURL || relativeURL.startsWith('http')) {\n return new URL(relativeURL).href;\n }\n\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n};\n\nexport function compileShader(\n gl: WebGL2RenderingContext,\n shader_type: number,\n source: string\n): WebGLShader {\n const shader = gl.createShader(shader_type);\n\n if (!shader) {\n throw new Error('[ladon-ts] - error creating shader');\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const error = gl.getShaderInfoLog(shader) ?? 'unknown error compiling shader.';\n throw new Error('[ladon-ts] - ' + error);\n }\n\n return shader;\n}\n\nexport function linkProgram(\n gl: WebGL2RenderingContext,\n vertex_shader: WebGLShader,\n fragment_shader: WebGLShader\n): WebGLProgram {\n const program = gl.createProgram();\n\n if (!program) {\n throw new Error('[ladon-ts] - error creating GPU program');\n }\n\n gl.attachShader(program, vertex_shader);\n gl.attachShader(program, fragment_shader);\n\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const error = gl.getProgramInfoLog(program) ?? 'unknown error linking program.';\n throw new Error('[ladon-ts] - ' + error);\n }\n\n return program;\n}\n\n/**\n * Determines if a URI is already resolved.\n * A resolved URI is either:\n * - A blob URL (starts with 'blob:')\n * - A fully qualified URL (e.g., http:// or https://)\n *\n * @param uri - The URI to check.\n * @returns Whether the URI is already resolved.\n */\nexport function isResolvedUri(uri: string): boolean {\n if (uri.startsWith('blob:')) {\n // Blob URIs are resolved\n return true;\n }\n\n try {\n // Throws if the URI is not a valid full URL\n new URL(uri);\n return true;\n } catch {\n // Not a fully qualified URL\n return false;\n }\n}\n\nexport async function loadAndCacheFile(fileUrl: string): Promise<ArrayBufferLike | Uint8Array> {\n const cache = await caches.open('ladon-cache');\n\n // Try to get the file from cache using its full URL\n const cachedResponse = await cache.match(fileUrl);\n if (cachedResponse) {\n return cachedResponse.arrayBuffer();\n }\n\n // If not in cache, fetch and cache the file\n const response = await fetch(fileUrl);\n\n // Ensure the response is valid\n if (!response.ok) {\n throw new Error(`Failed to fetch file: ${fileUrl}`);\n }\n\n const contentType = response.headers.get('Content-Type') || 'application/octet-stream';\n\n // Validate expected MIME types\n if (!contentType.includes('application/wasm') && !contentType.includes('binary/octet-stream')) {\n throw new Error(`Unexpected MIME type: ${contentType} for ${fileUrl}`);\n }\n\n const fileBinary = await response.arrayBuffer();\n\n // Cache the response with proper headers\n const cachedResponseWithHeaders = new Response(fileBinary, {\n headers: {\n 'Content-Type': contentType,\n 'Content-Length': fileBinary.byteLength.toString(),\n },\n });\n\n // Store the response in the cache using the full URL as the key\n await cache.put(fileUrl, cachedResponseWithHeaders);\n\n return fileBinary;\n}\n"],"names":["InterpolationMethod","resizeImage","imageData","srcWidth","srcHeight","targetWidth","targetHeight","targetData","xRatio","yRatio","scaledSrcWidth","offset","y","srcY","x","srcOffset","bilinearUpsample","input","output","j","xL","yL","xH","yH","xWeight","yWeight","a","b","c","d","value","lanczos3Upsample","lanczos","piX","i","weightSum","ky","kx","pixel","weight","toAbsoluteURI","relativeURL","baseURL","compileShader","gl","shader_type","source","shader","error","linkProgram","vertex_shader","fragment_shader","program","isResolvedUri","uri","loadAndCacheFile","fileUrl","cache","cachedResponse","response","contentType","fileBinary","cachedResponseWithHeaders"],"mappings":"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"}
1
+ {"version":3,"file":"util.js","sources":["../../../src/lib/util.ts"],"sourcesContent":["export enum InterpolationMethod {\n Nearest = 'nearest',\n}\n\n/**\n * Resizes an image from the source dimensions to target dimensions.\n *\n * @param {Uint8ClampedArray} imageData The source image data in Uint8ClampedArray format.\n * @param {number} srcWidth The width of the source image.\n * @param {number} srcHeight The height of the source image.\n * @param {number} targetWidth The width of the target image.\n * @param {number} targetHeight The height of the target image.\n *\n * @returns {Uint8ClampedArray} The target image data in Uint8ClampedArray format.\n *\n * @example\n * const targetData = resizeImage(sourceData, 800, 600, 400, 300);\n *\n * @note The function uses a \"nearest neighbor\" algorithm for resizing,\n * which is fast but might not provide the best quality for all images.\n */\nexport const resizeImage = (\n imageData: Uint8ClampedArray,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n): Uint8ClampedArray => {\n const targetData = new Uint8ClampedArray(targetWidth * targetHeight * 4);\n const xRatio = srcWidth / targetWidth;\n const yRatio = srcHeight / targetHeight;\n const scaledSrcWidth = srcWidth * 4;\n let offset = 0;\n\n for (let y = 0; y < targetHeight; y++) {\n const srcY = Math.floor(y * yRatio) * scaledSrcWidth;\n for (let x = 0; x < targetWidth; x++) {\n const srcOffset = srcY + Math.floor(x * xRatio) * 4;\n\n targetData[offset++] = imageData[srcOffset];\n targetData[offset++] = imageData[srcOffset + 1];\n targetData[offset++] = imageData[srcOffset + 2];\n targetData[offset++] = imageData[srcOffset + 3];\n }\n }\n\n return targetData;\n};\n\n/**\n * Upsamples an image using the bilinear interpolation method. The input image is expected to be in\n * Float32Array format. The output image is in Uint8ClampedArray format. The input image is expected\n * to be in the [0, 1] range. The output image is in the [0, 255] range.\n *\n * @param {Float32Array} input The input image data in Float32Array format.\n * @param {number} srcWidth The width of the source image.\n * @param {number} srcHeight The height of the source image.\n * @param {number} targetWidth The width of the target image.\n * @param {number} targetHeight The height of the target image.\n *\n * @returns {Uint8ClampedArray} The upsampled image data in Uint8ClampedArray format.\n *\n */\nexport function bilinearUpsample(\n input: Float32Array,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n) {\n const output = new Uint8ClampedArray(targetWidth * targetHeight);\n\n // If the source and target dimensions are the same, just copy the input to the output.\n // The output is expected to be in the [0, 255] range\n if (srcWidth === targetWidth && srcHeight === targetHeight) {\n for (let i = 0; i < input.length; i++) {\n output[i] = Math.min(Math.max(input[i], 0), 255);\n }\n return output;\n }\n\n const xRatio = (srcWidth - 1) / (targetWidth - 1);\n const yRatio = (srcHeight - 1) / (targetHeight - 1);\n\n for (let i = 0; i < targetHeight; i++) {\n for (let j = 0; j < targetWidth; j++) {\n const x = xRatio * j;\n const y = yRatio * i;\n\n const xL = Math.floor(x);\n const yL = Math.floor(y);\n const xH = Math.min(Math.ceil(x), srcWidth - 1);\n const yH = Math.min(Math.ceil(y), srcHeight - 1);\n\n const xWeight = x - xL;\n const yWeight = y - yL;\n\n const a = input[yL * srcWidth + xL];\n const b = input[yL * srcWidth + xH];\n const c = input[yH * srcWidth + xL];\n const d = input[yH * srcWidth + xH];\n\n const value =\n a * (1 - xWeight) * (1 - yWeight) +\n b * xWeight * (1 - yWeight) +\n c * (1 - xWeight) * yWeight +\n d * xWeight * yWeight;\n\n output[i * targetWidth + j] = Math.min(Math.max(value, 0), 255);\n }\n }\n\n return output;\n}\n\n/**\n * Upsamples an image using the Lanczos3 interpolation method. The input image is expected to be in\n * Float32Array format. The output image is in Uint8ClampedArray format. The input image is expected\n * to be in the [0, 1] range. The output image is in the [0, 255] range.\n *\n * @param {Float32Array} input The input image data in Float32Array format.\n * @param {number} srcWidth The width of the source image.\n * @param {number} srcHeight The height of the source image.\n * @param {number} targetWidth The width of the target image.\n * @param {number} targetHeight The height of the target image.\n *\n * @returns {Uint8ClampedArray} The upsampled image data in Uint8ClampedArray format.\n */\nexport function lanczos3Upsample(\n input: Float32Array,\n srcWidth: number,\n srcHeight: number,\n targetWidth: number,\n targetHeight: number\n) {\n const output = new Uint8ClampedArray(targetWidth * targetHeight);\n\n const xRatio = srcWidth / targetWidth;\n const yRatio = srcHeight / targetHeight;\n\n const lanczos = (x: number, a: number) => {\n if (x === 0) return 1;\n if (x < 0) x = -x;\n if (x < a) {\n const piX = Math.PI * x;\n return (a * Math.sin(piX) * Math.sin(piX / a)) / (piX * piX);\n }\n return 0;\n };\n\n const a = 3; // Lanczos parameter\n\n for (let i = 0; i < targetHeight; i++) {\n for (let j = 0; j < targetWidth; j++) {\n const x = j * xRatio;\n const y = i * yRatio;\n\n const xL = Math.floor(x);\n const yL = Math.floor(y);\n\n let value = 0;\n let weightSum = 0;\n\n for (let ky = yL - a + 1; ky <= yL + a; ky++) {\n for (let kx = xL - a + 1; kx <= xL + a; kx++) {\n if (kx >= 0 && kx < srcWidth && ky >= 0 && ky < srcHeight) {\n const pixel = input[ky * srcWidth + kx];\n const weight = lanczos(x - kx, a) * lanczos(y - ky, a);\n value += pixel * weight;\n weightSum += weight;\n }\n }\n }\n\n output[i * targetWidth + j] = weightSum !== 0 ? Math.round(value / weightSum) : 0;\n }\n }\n\n return output;\n}\n\nexport function compileShader(\n gl: WebGL2RenderingContext,\n shader_type: number,\n source: string\n): WebGLShader {\n const shader = gl.createShader(shader_type);\n\n if (!shader) {\n throw new Error('[ladon-ts] - error creating shader');\n }\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const error = gl.getShaderInfoLog(shader) ?? 'unknown error compiling shader.';\n throw new Error('[ladon-ts] - ' + error);\n }\n\n return shader;\n}\n\nexport function linkProgram(\n gl: WebGL2RenderingContext,\n vertex_shader: WebGLShader,\n fragment_shader: WebGLShader\n): WebGLProgram {\n const program = gl.createProgram();\n\n if (!program) {\n throw new Error('[ladon-ts] - error creating GPU program');\n }\n\n gl.attachShader(program, vertex_shader);\n gl.attachShader(program, fragment_shader);\n\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n const error = gl.getProgramInfoLog(program) ?? 'unknown error linking program.';\n throw new Error('[ladon-ts] - ' + error);\n }\n\n return program;\n}\n\n/**\n * Determines if a URI is already resolved.\n * A resolved URI is either:\n * - A blob URL (starts with 'blob:')\n * - A fully qualified URL (e.g., http:// or https://)\n *\n * @param uri - The URI to check.\n * @returns Whether the URI is already resolved.\n */\nexport function isResolvedUri(uri: string): boolean {\n if (uri.startsWith('blob:')) {\n // Blob URIs are resolved\n return true;\n }\n\n try {\n // Throws if the URI is not a valid full URL\n new URL(uri);\n return true;\n } catch {\n // Not a fully qualified URL\n return false;\n }\n}\n\nexport const toAbsoluteURI = (relativeURL: string, baseURL?: string) => {\n // adapted from - https://github.com/axios/axios/blob/fe7d09bb08fa1c0e414956b7fc760c80459b0a43/lib/helpers/combineURLs.js\n\n if (!baseURL || relativeURL.startsWith('http')) {\n return new URL(relativeURL).href;\n }\n\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n};\n"],"names":["InterpolationMethod","resizeImage","imageData","srcWidth","srcHeight","targetWidth","targetHeight","targetData","xRatio","yRatio","scaledSrcWidth","offset","y","srcY","x","srcOffset","bilinearUpsample","input","output","i","j","xL","yL","xH","yH","xWeight","yWeight","a","b","c","d","value","lanczos3Upsample","lanczos","piX","weightSum","ky","kx","pixel","weight","compileShader","gl","shader_type","source","shader","error","linkProgram","vertex_shader","fragment_shader","program","isResolvedUri","uri","toAbsoluteURI","relativeURL","baseURL"],"mappings":"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"}
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "5.4.6";
1
+ export declare const LIB_VERSION = "5.5.0";
@@ -1,4 +1,4 @@
1
- const o = "5.4.6";
1
+ const o = "5.5.0";
2
2
  export {
3
3
  o as LIB_VERSION
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../../../src/lib/version.ts"],"sourcesContent":["export const LIB_VERSION = '5.4.6';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
1
+ {"version":3,"file":"version.js","sources":["../../../src/lib/version.ts"],"sourcesContent":["export const LIB_VERSION = '5.5.0';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
@@ -0,0 +1,15 @@
1
+ import { PipelineConfig } from './config-types';
2
+ import { LadonOutput, MaskGenerator } from './generator-types';
3
+ export declare class WorkerGenerator implements MaskGenerator {
4
+ readonly config: PipelineConfig;
5
+ private lastMask;
6
+ private lastResult;
7
+ private newMask;
8
+ private worker?;
9
+ constructor(config: PipelineConfig);
10
+ getLadonOutput(_: Uint8ClampedArray): Promise<LadonOutput>;
11
+ load(): Promise<void>;
12
+ isLoaded(): boolean;
13
+ postRender(input: Uint8ClampedArray, timestamp: number): Promise<void>;
14
+ destroy(): void;
15
+ }
@@ -0,0 +1,93 @@
1
+ import { workerManager as a } from "./worker-manager.js";
2
+ class m {
3
+ constructor(t) {
4
+ this.config = t, this.newMask = !0, this.lastMask = new Float32Array(
5
+ this.config.mask.outputSize.height * this.config.mask.outputSize.width
6
+ ), this.lastResult = {
7
+ data: this.lastMask,
8
+ facesAndLandmarks: { data: new Float32Array(0), dims: [] },
9
+ gesture: new Float32Array(0),
10
+ motion: 0,
11
+ timestamp: 0,
12
+ warm: !1
13
+ };
14
+ }
15
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
16
+ async getLadonOutput(t) {
17
+ const e = {
18
+ data: this.lastMask,
19
+ facesAndLandmarks: this.lastResult.facesAndLandmarks,
20
+ gesture: this.lastResult.gesture,
21
+ motion: this.lastResult.motion,
22
+ timestamp: this.lastResult.timestamp,
23
+ warm: this.newMask
24
+ };
25
+ return this.newMask = !1, e;
26
+ }
27
+ async load() {
28
+ const t = await a.prepareWorkerConfig(this.config);
29
+ if (this.worker = a.getWorker(), this.worker ?? (this.worker = await a.initializeWorker(t)), !this.worker)
30
+ throw new Error("[ladon-ts] - worker is not defined.");
31
+ this.worker.onmessage = (s) => {
32
+ if (s.data.type === "log") {
33
+ const { message: o, severity: n } = s.data, i = `[ladon-ts] Message received from worker: ${o}`;
34
+ switch (n) {
35
+ case "warn":
36
+ console.warn(i);
37
+ break;
38
+ case "error":
39
+ console.error(i);
40
+ break;
41
+ default:
42
+ console.log(i);
43
+ }
44
+ } else if (s.data.status === "generated")
45
+ this.lastMask = s.data.mask, this.lastResult = {
46
+ data: s.data.mask,
47
+ facesAndLandmarks: s.data.facesAndLandmarks,
48
+ gesture: s.data.gesture,
49
+ motion: s.data.motion,
50
+ timestamp: s.data.timestamp,
51
+ warm: !0
52
+ }, this.newMask = !0;
53
+ else {
54
+ const o = a.getWorkerUrl();
55
+ o && URL.revokeObjectURL(o), r == null || r();
56
+ }
57
+ };
58
+ const e = {
59
+ baseUrl: t.baseUrl,
60
+ input: t.input,
61
+ mask: t.mask,
62
+ wasmUri: t.wasmUri,
63
+ render: { type: "passthrough" }
64
+ };
65
+ this.worker.postMessage({ type: "init", config: e });
66
+ let r;
67
+ return new Promise((s) => {
68
+ r = s;
69
+ });
70
+ }
71
+ isLoaded() {
72
+ return !!this.worker;
73
+ }
74
+ async postRender(t, e) {
75
+ if (!this.worker)
76
+ throw new Error("[ladon-ts] - worker is not defined.");
77
+ this.worker.postMessage(
78
+ {
79
+ type: "generate",
80
+ image: t,
81
+ timestamp: e
82
+ },
83
+ [t.buffer]
84
+ );
85
+ }
86
+ destroy() {
87
+ a.terminateWorker();
88
+ }
89
+ }
90
+ export {
91
+ m as WorkerGenerator
92
+ };
93
+ //# sourceMappingURL=worker-generator.js.map