@webex/ladon-ts 5.5.0 → 5.6.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.
@@ -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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"}
@@ -1,5 +1,5 @@
1
- var U = /* @__PURE__ */ ((o) => (o.Nearest = "nearest", o))(U || {});
2
- const A = (o, n, u, r, e) => {
1
+ var I = /* @__PURE__ */ ((o) => (o.Nearest = "nearest", o))(I || {});
2
+ const U = (o, n, u, r, e) => {
3
3
  const l = new Uint8ClampedArray(r * e * 4), p = n / r, y = u / e, s = n * 4;
4
4
  let a = 0;
5
5
  for (let t = 0; t < e; t++) {
@@ -11,7 +11,7 @@ const A = (o, n, u, r, e) => {
11
11
  }
12
12
  return l;
13
13
  };
14
- function d(o, n, u, r, e) {
14
+ function A(o, n, u, r, e) {
15
15
  const l = new Uint8ClampedArray(r * e);
16
16
  if (n === r && u === e) {
17
17
  for (let s = 0; s < o.length; s++)
@@ -21,12 +21,12 @@ function d(o, n, u, r, e) {
21
21
  const p = (n - 1) / (r - 1), y = (u - 1) / (e - 1);
22
22
  for (let s = 0; s < e; s++)
23
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);
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], E = 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(E, 0), 255);
26
26
  }
27
27
  return l;
28
28
  }
29
- function E(o, n, u, r, e) {
29
+ function d(o, n, u, r, e) {
30
30
  const l = new Uint8ClampedArray(r * e), p = n / r, y = u / e, s = (t, f) => {
31
31
  if (t === 0) return 1;
32
32
  if (t < 0 && (t = -t), t < f) {
@@ -52,20 +52,20 @@ function E(o, n, u, r, e) {
52
52
  function L(o, n, u) {
53
53
  const r = o.createShader(n);
54
54
  if (!r)
55
- throw new Error("[ladon-ts] - error creating shader");
55
+ throw new Error("[ladon-ts] Error creating shader");
56
56
  if (o.shaderSource(r, u), o.compileShader(r), !o.getShaderParameter(r, o.COMPILE_STATUS)) {
57
57
  const e = o.getShaderInfoLog(r) ?? "unknown error compiling shader.";
58
- throw new Error("[ladon-ts] - " + e);
58
+ throw new Error("[ladon-ts] " + e);
59
59
  }
60
60
  return r;
61
61
  }
62
62
  function R(o, n, u) {
63
63
  const r = o.createProgram();
64
64
  if (!r)
65
- throw new Error("[ladon-ts] - error creating GPU program");
65
+ throw new Error("[ladon-ts] Error creating GPU program");
66
66
  if (o.attachShader(r, n), o.attachShader(r, u), o.linkProgram(r), !o.getProgramParameter(r, o.LINK_STATUS)) {
67
67
  const e = o.getProgramInfoLog(r) ?? "unknown error linking program.";
68
- throw new Error("[ladon-ts] - " + e);
68
+ throw new Error("[ladon-ts] " + e);
69
69
  }
70
70
  return r;
71
71
  }
@@ -80,13 +80,13 @@ function C(o) {
80
80
  }
81
81
  const T = (o, n) => !n || o.startsWith("http") ? new URL(o).href : o ? n.replace(/\/+$/, "") + "/" + o.replace(/^\/+/, "") : n;
82
82
  export {
83
- U as InterpolationMethod,
84
- d as bilinearUpsample,
83
+ I as InterpolationMethod,
84
+ A as bilinearUpsample,
85
85
  L as compileShader,
86
86
  C as isResolvedUri,
87
- E as lanczos3Upsample,
87
+ d as lanczos3Upsample,
88
88
  R as linkProgram,
89
- A as resizeImage,
89
+ U as resizeImage,
90
90
  T as toAbsoluteURI
91
91
  };
92
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 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":"AAAY,IAAAA,sBAAAA,OACRA,EAAA,UAAU,WADFA,IAAAA,KAAA,CAAA,CAAA;AAqBL,MAAMC,IAAc,CACvBC,GACAC,GACAC,GACAC,GACAC,MACoB;AACpB,QAAMC,IAAa,IAAI,kBAAkBF,IAAcC,IAAe,CAAC,GACjEE,IAASL,IAAWE,GACpBI,IAASL,IAAYE,GACrBI,IAAiBP,IAAW;AAClC,MAAIQ,IAAS;AAEb,WAASC,IAAI,GAAGA,IAAIN,GAAcM,KAAK;AACnC,UAAMC,IAAO,KAAK,MAAMD,IAAIH,CAAM,IAAIC;AACtC,aAASI,IAAI,GAAGA,IAAIT,GAAaS,KAAK;AAClC,YAAMC,IAAYF,IAAO,KAAK,MAAMC,IAAIN,CAAM,IAAI;AAEvC,MAAAD,EAAAI,GAAQ,IAAIT,EAAUa,CAAS,GAC1CR,EAAWI,GAAQ,IAAIT,EAAUa,IAAY,CAAC,GAC9CR,EAAWI,GAAQ,IAAIT,EAAUa,IAAY,CAAC,GAC9CR,EAAWI,GAAQ,IAAIT,EAAUa,IAAY,CAAC;AAAA,IAAA;AAAA,EAClD;AAGG,SAAAR;AACX;AAgBO,SAASS,EACZC,GACAd,GACAC,GACAC,GACAC,GACF;AACE,QAAMY,IAAS,IAAI,kBAAkBb,IAAcC,CAAY;AAI3D,MAAAH,MAAaE,KAAeD,MAAcE,GAAc;AACxD,aAASa,IAAI,GAAGA,IAAIF,EAAM,QAAQE;AACvB,MAAAD,EAAAC,CAAC,IAAI,KAAK,IAAI,KAAK,IAAIF,EAAME,CAAC,GAAG,CAAC,GAAG,GAAG;AAE5C,WAAAD;AAAA,EAAA;AAGL,QAAAV,KAAUL,IAAW,MAAME,IAAc,IACzCI,KAAUL,IAAY,MAAME,IAAe;AAEjD,WAASa,IAAI,GAAGA,IAAIb,GAAca;AAC9B,aAASC,IAAI,GAAGA,IAAIf,GAAae,KAAK;AAClC,YAAMN,IAAIN,IAASY,GACbR,IAAIH,IAASU,GAEbE,IAAK,KAAK,MAAMP,CAAC,GACjBQ,IAAK,KAAK,MAAMV,CAAC,GACjBW,IAAK,KAAK,IAAI,KAAK,KAAKT,CAAC,GAAGX,IAAW,CAAC,GACxCqB,IAAK,KAAK,IAAI,KAAK,KAAKZ,CAAC,GAAGR,IAAY,CAAC,GAEzCqB,IAAUX,IAAIO,GACdK,IAAUd,IAAIU,GAEdK,IAAIV,EAAMK,IAAKnB,IAAWkB,CAAE,GAC5BO,IAAIX,EAAMK,IAAKnB,IAAWoB,CAAE,GAC5BM,IAAIZ,EAAMO,IAAKrB,IAAWkB,CAAE,GAC5BS,IAAIb,EAAMO,IAAKrB,IAAWoB,CAAE,GAE5BQ,IACFJ,KAAK,IAAIF,MAAY,IAAIC,KACzBE,IAAIH,KAAW,IAAIC,KACnBG,KAAK,IAAIJ,KAAWC,IACpBI,IAAIL,IAAUC;AAEX,MAAAR,EAAAC,IAAId,IAAce,CAAC,IAAI,KAAK,IAAI,KAAK,IAAIW,GAAO,CAAC,GAAG,GAAG;AAAA,IAAA;AAI/D,SAAAb;AACX;AAeO,SAASc,EACZf,GACAd,GACAC,GACAC,GACAC,GACF;AACE,QAAMY,IAAS,IAAI,kBAAkBb,IAAcC,CAAY,GAEzDE,IAASL,IAAWE,GACpBI,IAASL,IAAYE,GAErB2B,IAAU,CAACnB,GAAWa,MAAc;AAClC,QAAAb,MAAM,EAAU,QAAA;AAEpB,QADIA,IAAI,MAAGA,IAAI,CAACA,IACZA,IAAIa,GAAG;AACD,YAAAO,IAAM,KAAK,KAAKpB;AACda,aAAAA,IAAI,KAAK,IAAIO,CAAG,IAAI,KAAK,IAAIA,IAAMP,CAAC,KAAMO,IAAMA;AAAA,IAAA;AAErD,WAAA;AAAA,EACX,GAEM,IAAI;AAEV,WAASf,IAAI,GAAGA,IAAIb,GAAca;AAC9B,aAASC,IAAI,GAAGA,IAAIf,GAAae,KAAK;AAClC,YAAMN,IAAIM,IAAIZ,GACRI,IAAIO,IAAIV,GAERY,IAAK,KAAK,MAAMP,CAAC,GACjBQ,IAAK,KAAK,MAAMV,CAAC;AAEvB,UAAImB,IAAQ,GACRI,IAAY;AAEhB,eAASC,IAAKd,IAAK,IAAI,GAAGc,KAAMd,IAAK,GAAGc;AACpC,iBAASC,IAAKhB,IAAK,IAAI,GAAGgB,KAAMhB,IAAK,GAAGgB;AACpC,cAAIA,KAAM,KAAKA,IAAKlC,KAAYiC,KAAM,KAAKA,IAAKhC,GAAW;AACvD,kBAAMkC,IAAQrB,EAAMmB,IAAKjC,IAAWkC,CAAE,GAChCE,IAASN,EAAQnB,IAAIuB,GAAI,CAAC,IAAIJ,EAAQrB,IAAIwB,GAAI,CAAC;AACrD,YAAAL,KAASO,IAAQC,GACJJ,KAAAI;AAAA,UAAA;AAKlB,MAAArB,EAAAC,IAAId,IAAce,CAAC,IAAIe,MAAc,IAAI,KAAK,MAAMJ,IAAQI,CAAS,IAAI;AAAA,IAAA;AAIjF,SAAAjB;AACX;AAEgB,SAAAsB,EACZC,GACAC,GACAC,GACW;AACL,QAAAC,IAASH,EAAG,aAAaC,CAAW;AAE1C,MAAI,CAACE;AACK,UAAA,IAAI,MAAM,oCAAoC;AAMxD,MAHGH,EAAA,aAAaG,GAAQD,CAAM,GAC9BF,EAAG,cAAcG,CAAM,GAEnB,CAACH,EAAG,mBAAmBG,GAAQH,EAAG,cAAc,GAAG;AACnD,UAAMI,IAAQJ,EAAG,iBAAiBG,CAAM,KAAK;AACvC,UAAA,IAAI,MAAM,kBAAkBC,CAAK;AAAA,EAAA;AAGpC,SAAAD;AACX;AAEgB,SAAAE,EACZL,GACAM,GACAC,GACY;AACN,QAAAC,IAAUR,EAAG,cAAc;AAEjC,MAAI,CAACQ;AACK,UAAA,IAAI,MAAM,yCAAyC;AAQ7D,MALGR,EAAA,aAAaQ,GAASF,CAAa,GACnCN,EAAA,aAAaQ,GAASD,CAAe,GAExCP,EAAG,YAAYQ,CAAO,GAElB,CAACR,EAAG,oBAAoBQ,GAASR,EAAG,WAAW,GAAG;AAClD,UAAMI,IAAQJ,EAAG,kBAAkBQ,CAAO,KAAK;AACzC,UAAA,IAAI,MAAM,kBAAkBJ,CAAK;AAAA,EAAA;AAGpC,SAAAI;AACX;AAWO,SAASC,EAAcC,GAAsB;AAC5C,MAAAA,EAAI,WAAW,OAAO;AAEf,WAAA;AAGP,MAAA;AAEA,eAAI,IAAIA,CAAG,GACJ;AAAA,EAAA,QACH;AAEG,WAAA;AAAA,EAAA;AAEf;AAEa,MAAAC,IAAgB,CAACC,GAAqBC,MAG3C,CAACA,KAAWD,EAAY,WAAW,MAAM,IAClC,IAAI,IAAIA,CAAW,EAAE,OAGzBA,IACDC,EAAQ,QAAQ,QAAQ,EAAE,IAAI,MAAMD,EAAY,QAAQ,QAAQ,EAAE,IAClEC;"}
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.5.0";
1
+ export declare const LIB_VERSION = "5.6.0";
@@ -1,4 +1,4 @@
1
- const o = "5.5.0";
1
+ const o = "5.6.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.5.0';\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.6.0';\n"],"names":["LIB_VERSION"],"mappings":"AAAO,MAAMA,IAAc;"}
@@ -2,14 +2,35 @@ import { PipelineConfig } from './config-types';
2
2
  import { LadonOutput, MaskGenerator } from './generator-types';
3
3
  export declare class WorkerGenerator implements MaskGenerator {
4
4
  readonly config: PipelineConfig;
5
- private lastMask;
6
5
  private lastResult;
7
6
  private newMask;
8
- private worker?;
9
7
  constructor(config: PipelineConfig);
10
- getLadonOutput(_: Uint8ClampedArray): Promise<LadonOutput>;
11
- load(): Promise<void>;
12
8
  isLoaded(): boolean;
9
+ getLadonOutput(): Promise<LadonOutput>;
10
+ /**
11
+ * Loads the worker and initializes it with the provided configuration.
12
+ * The worker is responsible for processing the input image and generating the mask.
13
+ * Prepares the worker configuration by resolving the final URLs and paths to send to the worker.
14
+ *
15
+ * @returns A promise that resolves when the worker is loaded and initialized.
16
+ */
17
+ load(): Promise<void>;
18
+ /**
19
+ * Sends the input image to the worker for processing.
20
+ * The input image is expected to be a Uint8ClampedArray.
21
+ * Claims ownership of the input tensor's buffer and forwards it to the worker.
22
+ *
23
+ * @param input - The input image as a Uint8ClampedArray.
24
+ * @param timestamp - The timestamp of the input image.
25
+ */
13
26
  postRender(input: Uint8ClampedArray, timestamp: number): Promise<void>;
14
- destroy(): void;
27
+ /**
28
+ * Destroys the worker and cleans up resources.
29
+ * First it sends a message to the worker to destroy itself,
30
+ * then it waits for the worker to respond with a 'destroyed' message.
31
+ * After that, it terminates the worker and revokes the URL if it exists.
32
+ *
33
+ * @returns A promise that resolves when the worker is destroyed.
34
+ */
35
+ destroy(): Promise<void>;
15
36
  }
@@ -1,10 +1,10 @@
1
- import { workerManager as a } from "./worker-manager.js";
1
+ import { workerManager as t } from "./worker-manager.js";
2
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,
3
+ constructor(e) {
4
+ this.config = e, this.newMask = !0, this.lastResult = {
5
+ data: new Float32Array(
6
+ this.config.mask.outputSize.height * this.config.mask.outputSize.width
7
+ ),
8
8
  facesAndLandmarks: { data: new Float32Array(0), dims: [] },
9
9
  gesture: new Float32Array(0),
10
10
  motion: 0,
@@ -12,10 +12,12 @@ class m {
12
12
  warm: !1
13
13
  };
14
14
  }
15
- /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
16
- async getLadonOutput(t) {
15
+ isLoaded() {
16
+ return !!t.getWorker();
17
+ }
18
+ async getLadonOutput() {
17
19
  const e = {
18
- data: this.lastMask,
20
+ data: this.lastResult.data,
19
21
  facesAndLandmarks: this.lastResult.facesAndLandmarks,
20
22
  gesture: this.lastResult.gesture,
21
23
  motion: this.lastResult.motion,
@@ -24,67 +26,69 @@ class m {
24
26
  };
25
27
  return this.newMask = !1, e;
26
28
  }
29
+ /**
30
+ * Loads the worker and initializes it with the provided configuration.
31
+ * The worker is responsible for processing the input image and generating the mask.
32
+ * Prepares the worker configuration by resolving the final URLs and paths to send to the worker.
33
+ *
34
+ * @returns A promise that resolves when the worker is loaded and initialized.
35
+ */
27
36
  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}`;
37
+ const e = await t.prepareWorkerConfig(this.config);
38
+ return new Promise((a) => {
39
+ t.onInitialized(() => {
40
+ a();
41
+ }), t.onGenerated((s) => {
42
+ this.lastResult = {
43
+ data: s.mask,
44
+ facesAndLandmarks: s.facesAndLandmarks,
45
+ gesture: s.gesture,
46
+ motion: s.motion,
47
+ timestamp: s.timestamp,
48
+ warm: !0
49
+ }, this.newMask = !0;
50
+ }), t.onLog((s, n) => {
51
+ const r = `[ladon-ts] Message received from worker: ${s}`;
34
52
  switch (n) {
35
53
  case "warn":
36
- console.warn(i);
54
+ console.warn(r);
37
55
  break;
38
56
  case "error":
39
- console.error(i);
57
+ console.error(r);
40
58
  break;
41
59
  default:
42
- console.log(i);
60
+ console.log(r);
43
61
  }
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;
62
+ }), (async () => (await (t.getWorker() ?? t.initializeWorker(e)), t.sendInit({
63
+ baseUrl: e.baseUrl,
64
+ input: e.input,
65
+ mask: e.mask,
66
+ wasmUri: e.wasmUri,
67
+ render: { type: "passthrough" }
68
+ })))();
69
69
  });
70
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
- );
71
+ /**
72
+ * Sends the input image to the worker for processing.
73
+ * The input image is expected to be a Uint8ClampedArray.
74
+ * Claims ownership of the input tensor's buffer and forwards it to the worker.
75
+ *
76
+ * @param input - The input image as a Uint8ClampedArray.
77
+ * @param timestamp - The timestamp of the input image.
78
+ */
79
+ async postRender(e, a) {
80
+ t.sendGenerate(e, a);
85
81
  }
82
+ /**
83
+ * Destroys the worker and cleans up resources.
84
+ * First it sends a message to the worker to destroy itself,
85
+ * then it waits for the worker to respond with a 'destroyed' message.
86
+ * After that, it terminates the worker and revokes the URL if it exists.
87
+ *
88
+ * @returns A promise that resolves when the worker is destroyed.
89
+ */
86
90
  destroy() {
87
- a.terminateWorker();
91
+ return t.destroyWorker();
88
92
  }
89
93
  }
90
94
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"worker-generator.js","sources":["../../../src/lib/worker-generator.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport { LadonOutput, MaskGenerator } from './generator-types';\nimport { workerManager } from './worker-manager';\n\nexport class WorkerGenerator implements MaskGenerator {\n private lastMask: Float32Array;\n private lastResult: LadonOutput;\n private newMask = true;\n private worker?: Worker;\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 workerManager.prepareWorkerConfig(this.config);\n\n this.worker = workerManager.getWorker();\n this.worker ??= await workerManager.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 = workerManager.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 workerManager.terminateWorker();\n }\n}\n"],"names":["WorkerGenerator","config","_","toReturn","workerManager","event","message","severity","msg","workerUrl","resolutionCb","workerConfig","resolve","input","timestamp"],"mappings":"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"}
1
+ {"version":3,"file":"worker-generator.js","sources":["../../../src/lib/worker-generator.ts"],"sourcesContent":["import { PipelineConfig } from './config-types';\nimport { LadonOutput, MaskGenerator, WorkerGeneratedResult } from './generator-types';\nimport { workerManager } from './worker-manager';\n\nexport class WorkerGenerator implements MaskGenerator {\n private lastResult: LadonOutput;\n private newMask = true;\n\n constructor(public readonly config: PipelineConfig) {\n this.lastResult = {\n data: new Float32Array(\n this.config.mask.outputSize.height * this.config.mask.outputSize.width\n ),\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 isLoaded(): boolean {\n return !!workerManager.getWorker();\n }\n\n public async getLadonOutput(): Promise<LadonOutput> {\n const toReturn = {\n data: this.lastResult.data,\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 /**\n * Loads the worker and initializes it with the provided configuration.\n * The worker is responsible for processing the input image and generating the mask.\n * Prepares the worker configuration by resolving the final URLs and paths to send to the worker.\n *\n * @returns A promise that resolves when the worker is loaded and initialized.\n */\n public async load(): Promise<void> {\n const config = await workerManager.prepareWorkerConfig(this.config);\n\n // Listen for worker events\n return new Promise<void>((resolve) => {\n workerManager.onInitialized(() => {\n resolve();\n });\n workerManager.onGenerated((data: WorkerGeneratedResult) => {\n this.lastResult = {\n data: data.mask,\n facesAndLandmarks: data.facesAndLandmarks,\n gesture: data.gesture,\n motion: data.motion,\n timestamp: data.timestamp,\n warm: true,\n };\n this.newMask = true;\n });\n workerManager.onLog((message, severity) => {\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 });\n\n // Initialize the worker if not already done, then always send init\n (async () => {\n await (workerManager.getWorker() ?? workerManager.initializeWorker(config));\n workerManager.sendInit({\n baseUrl: config.baseUrl,\n input: config.input,\n mask: config.mask,\n wasmUri: config.wasmUri,\n render: { type: 'passthrough' },\n });\n })();\n });\n }\n\n /**\n * Sends the input image to the worker for processing.\n * The input image is expected to be a Uint8ClampedArray.\n * Claims ownership of the input tensor's buffer and forwards it to the worker.\n *\n * @param input - The input image as a Uint8ClampedArray.\n * @param timestamp - The timestamp of the input image.\n */\n public async postRender(input: Uint8ClampedArray, timestamp: number): Promise<void> {\n workerManager.sendGenerate(input, timestamp);\n }\n\n /**\n * Destroys the worker and cleans up resources.\n * First it sends a message to the worker to destroy itself,\n * then it waits for the worker to respond with a 'destroyed' message.\n * After that, it terminates the worker and revokes the URL if it exists.\n *\n * @returns A promise that resolves when the worker is destroyed.\n */\n public destroy(): Promise<void> {\n return workerManager.destroyWorker();\n }\n}\n"],"names":["WorkerGenerator","config","workerManager","toReturn","resolve","data","message","severity","msg","input","timestamp"],"mappings":";AAIO,MAAMA,EAAyC;AAAA,EAIlD,YAA4BC,GAAwB;AAAxB,SAAA,SAAAA,GAF5B,KAAQ,UAAU,IAGd,KAAK,aAAa;AAAA,MACd,MAAM,IAAI;AAAA,QACN,KAAK,OAAO,KAAK,WAAW,SAAS,KAAK,OAAO,KAAK,WAAW;AAAA,MACrE;AAAA,MACA,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,EAGG,WAAoB;AAChB,WAAA,CAAC,CAACC,EAAc,UAAU;AAAA,EAAA;AAAA,EAGrC,MAAa,iBAAuC;AAChD,UAAMC,IAAW;AAAA,MACb,MAAM,KAAK,WAAW;AAAA,MACtB,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUX,MAAa,OAAsB;AAC/B,UAAMF,IAAS,MAAMC,EAAc,oBAAoB,KAAK,MAAM;AAG3D,WAAA,IAAI,QAAc,CAACE,MAAY;AAClC,MAAAF,EAAc,cAAc,MAAM;AACtB,QAAAE,EAAA;AAAA,MAAA,CACX,GACaF,EAAA,YAAY,CAACG,MAAgC;AACvD,aAAK,aAAa;AAAA,UACd,MAAMA,EAAK;AAAA,UACX,mBAAmBA,EAAK;AAAA,UACxB,SAASA,EAAK;AAAA,UACd,QAAQA,EAAK;AAAA,UACb,WAAWA,EAAK;AAAA,UAChB,MAAM;AAAA,QACV,GACA,KAAK,UAAU;AAAA,MAAA,CAClB,GACaH,EAAA,MAAM,CAACI,GAASC,MAAa;AACjC,cAAAC,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,MACvB,CACH,IAGA,aACG,OAAON,EAAc,UAAe,KAAAA,EAAc,iBAAiBD,CAAM,IACzEC,EAAc,SAAS;AAAA,QACnB,SAASD,EAAO;AAAA,QAChB,OAAOA,EAAO;AAAA,QACd,MAAMA,EAAO;AAAA,QACb,SAASA,EAAO;AAAA,QAChB,QAAQ,EAAE,MAAM,cAAc;AAAA,MAAA,CACjC;AAAA,IACF,CACN;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWL,MAAa,WAAWQ,GAA0BC,GAAkC;AAClE,IAAAR,EAAA,aAAaO,GAAOC,CAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxC,UAAyB;AAC5B,WAAOR,EAAc,cAAc;AAAA,EAAA;AAE3C;"}
@@ -1,4 +1,5 @@
1
- import { PreloadConfig, WorkerConfig } from './config-types';
1
+ import { PipelineConfig, PreloadConfig, WorkerConfig } from './config-types';
2
+ import { WorkerGeneratedResult } from './generator-types';
2
3
  /**
3
4
  * Worker manager class to handle the initialization and termination of the segmenation
4
5
  * web worker. This class is responsible for loading the worker script, resolving the
@@ -8,6 +9,16 @@ import { PreloadConfig, WorkerConfig } from './config-types';
8
9
  export declare class WorkerManager {
9
10
  private worker?;
10
11
  private workerUrl?;
12
+ private destroyPromise;
13
+ private onInitializedCallbacks;
14
+ private onGeneratedCallbacks;
15
+ private onLogCallbacks;
16
+ /**
17
+ * Get the current worker instance.
18
+ *
19
+ * @returns The current worker instance or undefined if not initialized.
20
+ */
21
+ getWorker(): Worker | undefined;
11
22
  /**
12
23
  * Initialize the worker using the provided configuration.
13
24
  *
@@ -15,6 +26,13 @@ export declare class WorkerManager {
15
26
  * @returns A promise that resolves when the worker is initialized.
16
27
  */
17
28
  initializeWorker(config: WorkerConfig): Promise<Worker>;
29
+ /**
30
+ * Destroys the worker gracefully by sending a destroy message and waiting for confirmation.
31
+ *
32
+ * @returns A promise that resolves when the worker is destroyed.
33
+ * If no worker is available, it resolves immediately.
34
+ */
35
+ destroyWorker(): Promise<void>;
18
36
  /**
19
37
  * Terminate the worker.
20
38
  */
@@ -26,8 +44,6 @@ export declare class WorkerManager {
26
44
  * @returns A promise that resolves when the worker is preloaded.
27
45
  */
28
46
  preloadWorker(config: PreloadConfig): Promise<void>;
29
- getWorker(): Worker | undefined;
30
- getWorkerUrl(): string | undefined;
31
47
  /**
32
48
  * Prepare the worker configuration by resolving the final URLs and paths to send to the
33
49
  * worker. This is necessary because we can't send functions to the worker. We also need to
@@ -37,5 +53,46 @@ export declare class WorkerManager {
37
53
  * @returns The worker configuration.
38
54
  */
39
55
  prepareWorkerConfig(config: PreloadConfig): Promise<any>;
56
+ /**
57
+ * Register a callback for when the worker is initialized.
58
+ */
59
+ onInitialized(callback: () => void): void;
60
+ /**
61
+ * Register a callback for when the worker generates output.
62
+ *
63
+ * @param callback - The callback function to be called with the generated data.
64
+ * @param data - The generated data from the worker.
65
+ * @param data.mask - The generated mask.
66
+ * @param data.facesAndLandmarks - The detected faces and landmarks.
67
+ * @param data.gesture - The detected gesture.
68
+ * @param data.motion - The detected motion.
69
+ */
70
+ onGenerated(callback: (data: WorkerGeneratedResult) => void): void;
71
+ /**
72
+ * Register a callback for log messages from the worker.
73
+ *
74
+ * @param callback - The callback function to be called with the log message and severity.
75
+ * @param severity - The severity of the log message (e.g., 'info', 'warn', 'error').
76
+ */
77
+ onLog(callback: (message: string, severity: string) => void): void;
78
+ /**
79
+ * Send an init message to the worker.
80
+ *
81
+ * @param config - The configuration object to initialize the worker.
82
+ * @param config.baseUrl - The base URL for loading assets.
83
+ * @param config.input - The input configuration for the worker.
84
+ * @param config.mask - The mask configuration for the worker.
85
+ * @param config.wasmUri - The URI for the WebAssembly module.
86
+ * @param config.workerUri - The URI for the worker script.
87
+ * @param config.assetUrlResolver - The function to resolve asset URLs.
88
+ */
89
+ sendInit(config: PipelineConfig): void;
90
+ /**
91
+ * Send a generate message to the worker.
92
+ *
93
+ * @param input - The input image data as a Uint8ClampedArray.
94
+ * @param timestamp - The timestamp of the input image.
95
+ */
96
+ sendGenerate(input: Uint8ClampedArray, timestamp: number): void;
40
97
  }
41
98
  export declare const workerManager: WorkerManager;