@alexislours/ltd-textures 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/bridge.d.ts +67 -0
- package/dist/browser.d.ts +20 -0
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/{chunk-Q7WR2GWO.js → chunk-BJBZAXV7.js} +1 -1
- package/dist/chunk-BJBZAXV7.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +1 -1
- package/dist/threadPool.d.ts +15 -0
- package/dist/types.d.ts +17 -0
- package/dist/worker.d.ts +9 -0
- package/dist/worker.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-Q7WR2GWO.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @alexislours/ltd-textures
|
|
2
2
|
|
|
3
|
+
<div align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/@alexislours/ltd-textures"><img alt="npm" src="https://img.shields.io/npm/v/@alexislours/ltd-textures?style=for-the-badge&logo=npm"></a>
|
|
5
|
+
<a href="https://github.com/alexislours/ltd-save-editor/actions/workflows/packages-ci.yml"><img alt="ci" src="https://img.shields.io/github/actions/workflow/status/alexislours/ltd-save-editor/packages-ci.yml?branch=dev&label=ci&style=for-the-badge&logo=githubactions"></a>
|
|
6
|
+
<a href="./LICENSE"><img alt="license" src="https://img.shields.io/npm/l/@alexislours/ltd-textures?style=for-the-badge&logo=gnu"></a>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
3
9
|
Tegra/Switch GPU texture toolkit in WebAssembly: block-linear (de)swizzle, BC1/BC3 transcode, sRGB/linear conversion, and image resize. No bundler assumptions, no Vite magic; you bring the wasm bytes and (optionally) a worker factory.
|
|
4
10
|
|
|
5
11
|
## Install
|
|
@@ -16,7 +22,7 @@ Portable core. Supply the wasm bytes however your environment loads them:
|
|
|
16
22
|
import { createUgcWasm } from '@alexislours/ltd-textures';
|
|
17
23
|
|
|
18
24
|
const wasm = await createUgcWasm({
|
|
19
|
-
wasm: fetch(
|
|
25
|
+
wasm: fetch(import.meta.resolve('@alexislours/ltd-textures/ugc.wasm')),
|
|
20
26
|
});
|
|
21
27
|
const rgba = wasm.bc3Decode(blocks, width, height);
|
|
22
28
|
```
|
package/dist/bridge.d.ts
CHANGED
|
@@ -1,24 +1,91 @@
|
|
|
1
1
|
import { Bc1Mode, FitMode, type Matte } from './types.js';
|
|
2
2
|
import { type CreateWorker } from './threadPool.js';
|
|
3
|
+
/**
|
|
4
|
+
* The instantiated texture toolkit returned by {@link createUgcWasm}.
|
|
5
|
+
*
|
|
6
|
+
* Every method copies its inputs into WASM memory and returns freshly allocated
|
|
7
|
+
* typed arrays, so callers never hold pointers into the module's heap. RGBA
|
|
8
|
+
* pixel buffers are 8-bit straight-alpha; linear buffers are `Float32Array` with
|
|
9
|
+
* four channels per pixel. The BC encode and decode methods operate on 4x4
|
|
10
|
+
* blocks, so `w` and `h` must both be multiples of 4.
|
|
11
|
+
*/
|
|
3
12
|
export interface UgcWasm {
|
|
13
|
+
/** Decode BC1 (DXT1) blocks to a `width * height * 4` sRGB RGBA8 buffer. */
|
|
4
14
|
bc1Decode(blocks: Uint8Array, w: number, h: number): Uint8Array;
|
|
15
|
+
/** Decode BC3 (DXT5) blocks to a `width * height * 4` sRGB RGBA8 buffer. */
|
|
5
16
|
bc3Decode(blocks: Uint8Array, w: number, h: number): Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* Encode linear-light RGBA to BC1 blocks, using `srgbRgba` for perceptual
|
|
19
|
+
* error weighting. `mode` selects the endpoint strategy; see {@link Bc1Mode}.
|
|
20
|
+
*/
|
|
6
21
|
bc1Encode(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number, mode: Bc1Mode): Uint8Array;
|
|
22
|
+
/** Encode linear-light RGBA to BC1 blocks via the rgbcx reference path (no sRGB weighting). */
|
|
7
23
|
bc1EncodeRgbcx(linRgba: Float32Array, w: number, h: number): Uint8Array;
|
|
24
|
+
/** Encode linear-light RGBA to BC3 blocks, using `srgbRgba` for perceptual error weighting. */
|
|
8
25
|
bc3Encode(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number): Uint8Array;
|
|
26
|
+
/**
|
|
27
|
+
* {@link UgcWasm.bc1Encode} spread across `threads` workers. Requires a
|
|
28
|
+
* {@link CreateWorker} factory; falls back to the synchronous path otherwise.
|
|
29
|
+
*/
|
|
9
30
|
bc1EncodeThreaded(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number, mode: Bc1Mode, threads: number): Promise<Uint8Array>;
|
|
31
|
+
/**
|
|
32
|
+
* {@link UgcWasm.bc3Encode} spread across `threads` workers. Requires a
|
|
33
|
+
* {@link CreateWorker} factory; falls back to the synchronous path otherwise.
|
|
34
|
+
*/
|
|
10
35
|
bc3EncodeThreaded(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number, threads: number): Promise<Uint8Array>;
|
|
36
|
+
/**
|
|
37
|
+
* Convert a Tegra block-linear (swizzled) surface to row-linear pixels.
|
|
38
|
+
*
|
|
39
|
+
* @param bpe Bytes per element (per pixel or per compressed block).
|
|
40
|
+
* @param blockHeight GOB block height in GOBs (1, 2, 4, 8, or 16).
|
|
41
|
+
*/
|
|
11
42
|
deswizzle(swizzled: Uint8Array, width: number, height: number, bpe: number, blockHeight: number): Uint8Array;
|
|
43
|
+
/**
|
|
44
|
+
* Convert row-linear pixels back to a Tegra block-linear surface. When `base`
|
|
45
|
+
* matches the padded output size it is used as the starting buffer so padding
|
|
46
|
+
* bytes are preserved; pass `null` to start from zero.
|
|
47
|
+
*
|
|
48
|
+
* @param bpe Bytes per element (per pixel or per compressed block).
|
|
49
|
+
* @param blockHeight GOB block height in GOBs (1, 2, 4, 8, or 16).
|
|
50
|
+
*/
|
|
12
51
|
swizzle(linear: Uint8Array, width: number, height: number, bpe: number, blockHeight: number, base: Uint8Array | null): Uint8Array;
|
|
52
|
+
/** Convert sRGB RGBA8 to linear-light `Float32Array` RGBA (four channels per pixel). */
|
|
13
53
|
srgbToLinearF32(rgba: Uint8Array): Float32Array;
|
|
54
|
+
/** Quantize linear-light `Float32Array` channels to linear RGBA8. */
|
|
14
55
|
linearF32ToU8(linear: Float32Array): Uint8Array;
|
|
56
|
+
/** Apply the linear-to-sRGB transfer curve to an RGBA8 buffer in place. */
|
|
15
57
|
linearU8ToSrgbU8InPlace(rgba: Uint8Array): void;
|
|
58
|
+
/**
|
|
59
|
+
* Resize an sRGB RGBA8 image to `dstW * dstH`, honoring `fit` ({@link FitMode})
|
|
60
|
+
* and padding any letterboxed area with `matte` ({@link Matte}), or transparent
|
|
61
|
+
* black when `matte` is `null`.
|
|
62
|
+
*/
|
|
16
63
|
resize(rgba: Uint8Array, srcW: number, srcH: number, dstW: number, dstH: number, fit: FitMode, matte: Matte | null): Uint8Array;
|
|
64
|
+
/** Terminate any spawned encode workers and release the thread pool. Safe to call when no pool exists. */
|
|
17
65
|
terminateThreadPool(): Promise<void>;
|
|
18
66
|
}
|
|
67
|
+
/** Any form of compiled WASM bytes accepted by {@link createUgcWasm}, including a `fetch` `Response` and promises thereof. */
|
|
19
68
|
export type WasmSource = ArrayBuffer | Uint8Array | Response | Promise<ArrayBuffer | Uint8Array | Response>;
|
|
69
|
+
/** Options for {@link createUgcWasm}. */
|
|
20
70
|
export interface CreateUgcWasmOptions {
|
|
71
|
+
/** The compiled `ugc.wasm` module bytes, in any {@link WasmSource} form. */
|
|
21
72
|
wasm: WasmSource;
|
|
73
|
+
/** Worker factory enabling the `*Threaded` encode methods; omit for single-threaded use. */
|
|
22
74
|
createWorker?: CreateWorker;
|
|
23
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Compile and instantiate `ugc.wasm`, returning a {@link UgcWasm} toolkit.
|
|
78
|
+
*
|
|
79
|
+
* Pass a {@link CreateWorker} via {@link CreateUgcWasmOptions.createWorker} to
|
|
80
|
+
* enable the multi-threaded encode paths; without it those methods run inline.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { createUgcWasm } from '@alexislours/ltd-textures';
|
|
85
|
+
* import { readFile } from 'node:fs/promises';
|
|
86
|
+
*
|
|
87
|
+
* const ugc = await createUgcWasm({ wasm: await readFile('ugc.wasm') });
|
|
88
|
+
* const rgba = ugc.bc1Decode(blocks, 256, 256);
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
24
91
|
export declare function createUgcWasm(options: CreateUgcWasmOptions): Promise<UgcWasm>;
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-friendly entrypoint that resolves the bundled `ugc.wasm` relative to
|
|
3
|
+
* this module and instantiates it via {@link loadUgcWasm}, so callers do not
|
|
4
|
+
* have to locate or fetch the binary themselves.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
1
8
|
import { type UgcWasm } from './bridge.js';
|
|
2
9
|
import type { CreateWorker } from './threadPool.js';
|
|
10
|
+
/** Options for {@link loadUgcWasm}. */
|
|
3
11
|
export interface BrowserLoadOptions {
|
|
12
|
+
/** Worker factory enabling the threaded encode methods; omit for single-threaded use. */
|
|
4
13
|
createWorker?: CreateWorker;
|
|
5
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Fetch the co-located `ugc.wasm` and return an instantiated {@link UgcWasm}.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { loadUgcWasm } from '@alexislours/ltd-textures/browser';
|
|
21
|
+
*
|
|
22
|
+
* const ugc = await loadUgcWasm();
|
|
23
|
+
* const rgba = ugc.bc3Decode(blocks, 256, 256);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
6
26
|
export declare function loadUgcWasm(options?: BrowserLoadOptions): Promise<UgcWasm>;
|
package/dist/browser.js
CHANGED
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/browser.ts"],"sourcesContent":["/**\n * Browser-friendly entrypoint that resolves the bundled `ugc.wasm` relative to\n * this module and instantiates it via {@link loadUgcWasm}, so callers do not\n * have to locate or fetch the binary themselves.\n *\n * @module\n */\nimport { createUgcWasm, type UgcWasm } from './bridge.js';\nimport type { CreateWorker } from './threadPool.js';\n\n/** Options for {@link loadUgcWasm}. */\nexport interface BrowserLoadOptions {\n /** Worker factory enabling the threaded encode methods; omit for single-threaded use. */\n createWorker?: CreateWorker;\n}\n\nconst WASM_URL = new URL('../build/ugc.wasm', import.meta.url);\n\n/**\n * Fetch the co-located `ugc.wasm` and return an instantiated {@link UgcWasm}.\n *\n * @example\n * ```ts\n * import { loadUgcWasm } from '@alexislours/ltd-textures/browser';\n *\n * const ugc = await loadUgcWasm();\n * const rgba = ugc.bc3Decode(blocks, 256, 256);\n * ```\n */\nexport function loadUgcWasm(options: BrowserLoadOptions = {}): Promise<UgcWasm> {\n return createUgcWasm({\n wasm: fetch(WASM_URL),\n createWorker: options.createWorker,\n });\n}\n"],"mappings":";;;;;AAgBA,IAAM,WAAW,IAAI,IAAI,qBAAqB,YAAY,GAAG;AAatD,SAAS,YAAY,UAA8B,CAAC,GAAqB;AAC9E,SAAO,cAAc;AAAA,IACnB,MAAM,MAAM,QAAQ;AAAA,IACpB,cAAc,QAAQ;AAAA,EACxB,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/threadPool.ts","../src/bridge.ts"],"sourcesContent":["/**\n * BC1 endpoint selection strategy used by the encoder.\n *\n * - `Auto` lets the encoder pick three- or four-color mode per block.\n * - `FourColor` forces the opaque four-color layout.\n * - `ThreeColor` forces the three-color layout with a 1-bit punch-through alpha.\n */\nexport const Bc1Mode = {\n Auto: 0,\n FourColor: 1,\n ThreeColor: 2,\n} as const;\n/** A {@link Bc1Mode} value. */\nexport type Bc1Mode = (typeof Bc1Mode)[keyof typeof Bc1Mode];\n\n/**\n * How a source image is fitted into the destination rectangle when resizing.\n *\n * - `Fill` stretches to the exact destination, ignoring aspect ratio.\n * - `Contain` scales to fit inside and pads the remainder with the matte.\n * - `Cover` scales to cover the destination and crops the overflow.\n */\nexport const FitMode = {\n Fill: 0,\n Contain: 1,\n Cover: 2,\n} as const;\n/** A {@link FitMode} value. */\nexport type FitMode = (typeof FitMode)[keyof typeof FitMode];\n\n/** Straight (non-premultiplied) RGBA fill color, each channel in `[0, 255]`, used to pad letterboxed regions when {@link FitMode.Contain} is selected. */\nexport type Matte = { r: number; g: number; b: number; a: number };\n","import { Bc1Mode } from './types.js';\n\n/**\n * The minimal subset of the DOM/Node `Worker` surface the thread pool relies on.\n *\n * Both the browser `Worker` and a `node:worker_threads` adapter satisfy this shape.\n */\nexport type WorkerLike = {\n postMessage(msg: unknown, transfer?: Transferable[]): void;\n onmessage: ((e: MessageEvent) => void) | null;\n onerror: ((e: ErrorEvent) => void) | null;\n onmessageerror?: ((e: MessageEvent) => void) | null;\n terminate(): void;\n};\n\n/**\n * Factory that spawns a fresh worker running the package's `worker` entrypoint.\n *\n * Supplying this to {@link createUgcWasm} enables the multi-threaded encode paths.\n */\nexport type CreateWorker = () => WorkerLike;\n\ntype WorkerHandle = {\n postMessage(msg: unknown, transfer?: Transferable[]): void;\n setMessageHandler(cb: (msg: WorkerMessage) => void): void;\n setErrorHandler(cb: (err: unknown) => void): void;\n terminate(): void;\n};\n\ntype WorkerMessage =\n | { type: 'ready' }\n | { type: 'done'; id: number; blocks: ArrayBuffer }\n | { type: 'error'; id?: number; error: string };\n\n/**\n * A pool of encode workers that splits a texture into horizontal stripes and\n * encodes them in parallel. Created internally by {@link createUgcWasm} when a\n * {@link CreateWorker} factory is provided.\n */\nexport type ThreadPool = {\n bc1Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n threads: number,\n ): Promise<Uint8Array>;\n bc3Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n threads: number,\n ): Promise<Uint8Array>;\n terminate(): Promise<void>;\n};\n\nconst WORKER_INIT_TIMEOUT_MS = 15000;\n\nfunction formatWorkerErrorEvent(e: unknown): string {\n const ev = e as Partial<ErrorEvent> & { error?: { message?: string; stack?: string } };\n const parts: string[] = [];\n if (ev.message) parts.push(ev.message);\n if (ev.error) {\n if (ev.error.message && ev.error.message !== ev.message) parts.push(ev.error.message);\n if (ev.error.stack) parts.push(ev.error.stack);\n }\n if (ev.filename) parts.push(`at ${ev.filename}:${ev.lineno}:${ev.colno}`);\n return parts.length > 0 ? parts.join(' | ') : 'unknown worker error';\n}\n\nfunction wrapWorker(w: WorkerLike): WorkerHandle {\n return {\n postMessage: (msg, transfer) => w.postMessage(msg, transfer ?? []),\n setMessageHandler: (cb) => {\n w.onmessage = (e: MessageEvent) => cb(e.data as WorkerMessage);\n },\n setErrorHandler: (cb) => {\n w.onerror = (e: unknown) => cb(formatWorkerErrorEvent(e));\n w.onmessageerror = () => cb('messageerror');\n },\n terminate: () => w.terminate(),\n };\n}\n\nexport function createThreadPool(wasmBytes: ArrayBuffer, createWorker: CreateWorker): ThreadPool {\n let pool: WorkerHandle[] | null = null;\n let nextId = 1;\n type Pending = { resolve: (out: Uint8Array) => void; reject: (err: unknown) => void };\n const pending = new Map<number, Pending>();\n\n function rejectAllPending(err: unknown): void {\n for (const [id, cb] of pending) {\n pending.delete(id);\n cb.reject(err);\n }\n }\n\n function dispatchListener(msg: WorkerMessage): void {\n if (msg.type === 'done') {\n const cb = pending.get(msg.id);\n if (cb) {\n pending.delete(msg.id);\n cb.resolve(new Uint8Array(msg.blocks));\n }\n } else if (msg.type === 'error' && msg.id != null) {\n const cb = pending.get(msg.id);\n pending.delete(msg.id);\n cb?.reject(new Error(msg.error));\n }\n }\n\n async function bootWorker(): Promise<WorkerHandle> {\n const handle = wrapWorker(createWorker());\n try {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error('Worker init timed out'));\n }, WORKER_INIT_TIMEOUT_MS);\n const finish = (fn: () => void): void => {\n clearTimeout(timer);\n fn();\n };\n handle.setMessageHandler((msg) => {\n if (msg.type === 'ready') {\n finish(() => {\n handle.setMessageHandler(dispatchListener);\n handle.setErrorHandler((err) => rejectAllPending(new Error(`Worker error: ${err}`)));\n resolve();\n });\n } else if (msg.type === 'error') {\n finish(() => reject(new Error(msg.error)));\n }\n });\n handle.setErrorHandler((err) => {\n finish(() => reject(new Error(`Worker init error: ${err}`)));\n });\n handle.postMessage({ type: 'init', wasmBytes });\n });\n } catch (e) {\n handle.terminate();\n throw e;\n }\n return handle;\n }\n\n async function ensurePool(threads: number): Promise<void> {\n if (pool && pool.length >= threads) return;\n if (!pool) pool = [];\n const need = threads - pool.length;\n if (need <= 0) return;\n const results = await Promise.allSettled(Array.from({ length: need }, () => bootWorker()));\n const fulfilled: WorkerHandle[] = [];\n let firstError: unknown = null;\n for (const r of results) {\n if (r.status === 'fulfilled') fulfilled.push(r.value);\n else if (firstError == null) firstError = r.reason;\n }\n if (firstError != null) {\n for (const h of fulfilled) h.terminate();\n throw firstError;\n }\n pool.push(...fulfilled);\n }\n\n function dispatchEncode(\n idx: number,\n op: 'bc1' | 'bc3',\n linF: Float32Array,\n srgbU: Uint8Array,\n w: number,\n h: number,\n mode: number,\n transfer: Transferable[],\n ): Promise<Uint8Array> {\n const id = nextId++;\n return new Promise<Uint8Array>((resolve, reject) => {\n pending.set(id, { resolve, reject });\n pool![idx].postMessage({ type: 'encode', id, op, linF, srgbU, w, h, mode }, transfer);\n });\n }\n\n function partition(blocksY: number, threads: number): number[] {\n const base = Math.floor(blocksY / threads);\n const extra = blocksY % threads;\n const out: number[] = [];\n for (let i = 0; i < threads; i++) {\n const sz = base + (i < extra ? 1 : 0);\n if (sz > 0) out.push(sz);\n }\n return out;\n }\n\n async function encodeThreaded(\n op: 'bc1' | 'bc3',\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: number,\n threads: number,\n bytesPerBlock: number,\n ): Promise<Uint8Array> {\n if (w % 4 !== 0 || h % 4 !== 0) {\n throw new Error(`encodeThreaded: width and height must be 4-aligned, got ${w}x${h}`);\n }\n await ensurePool(threads);\n const blocksY = h / 4;\n const blocksX = w / 4;\n const sizes = partition(blocksY, threads);\n const promises: Promise<Uint8Array>[] = [];\n let yOff = 0;\n for (let i = 0; i < sizes.length; i++) {\n const sliceBlocksY = sizes[i];\n const slicePxRows = sliceBlocksY * 4;\n const elemStart = yOff * 4 * w * 4;\n const elemEnd = (yOff + sliceBlocksY) * 4 * w * 4;\n const byteStart = yOff * 4 * w * 4;\n const byteEnd = (yOff + sliceBlocksY) * 4 * w * 4;\n const linAB = new ArrayBuffer((elemEnd - elemStart) * 4);\n const linF = new Float32Array(linAB);\n linF.set(linRgba.subarray(elemStart, elemEnd));\n const srgbAB = new ArrayBuffer(byteEnd - byteStart);\n const srgbU = new Uint8Array(srgbAB);\n srgbU.set(srgbRgba.subarray(byteStart, byteEnd));\n promises.push(dispatchEncode(i, op, linF, srgbU, w, slicePxRows, mode, [linAB, srgbAB]));\n yOff += sliceBlocksY;\n }\n const parts = await Promise.all(promises);\n const total = blocksY * blocksX * bytesPerBlock;\n const out = new Uint8Array(total);\n let writeOff = 0;\n for (const p of parts) {\n out.set(p, writeOff);\n writeOff += p.byteLength;\n }\n return out;\n }\n\n return {\n bc1Encode(linRgba, srgbRgba, w, h, mode, threads) {\n return encodeThreaded('bc1', linRgba, srgbRgba, w, h, mode, threads, 8);\n },\n bc3Encode(linRgba, srgbRgba, w, h, threads) {\n return encodeThreaded('bc3', linRgba, srgbRgba, w, h, 0, threads, 16);\n },\n async terminate() {\n rejectAllPending(new Error('Thread pool terminated'));\n if (!pool) return;\n for (const w of pool) w.terminate();\n pool = null;\n },\n };\n}\n","import { Bc1Mode, FitMode, type Matte } from './types.js';\nimport { createThreadPool, type CreateWorker, type ThreadPool } from './threadPool.js';\n\ninterface UgcWasmExports {\n memory: WebAssembly.Memory;\n alloc(size: number): number;\n mark(): number;\n release(m: number): void;\n free(ptr: number): void;\n deswizzleBlockLinear(\n srcPtr: number,\n srcLen: number,\n dstPtr: number,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n ): void;\n swizzleBlockLinear(\n srcPtr: number,\n srcLen: number,\n dstPtr: number,\n dstLen: number,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n basePtr: number,\n baseLen: number,\n ): void;\n srgbU8ToLinearF32(srcPtr: number, dstPtr: number, pixelCount: number): void;\n linearF32ToLinearU8(srcPtr: number, dstPtr: number, count: number): void;\n convertLinearU8ToSrgbU8(rgbaPtr: number, byteLen: number): void;\n bc1Decode(blocksPtr: number, dstPtr: number, texW: number, texH: number): void;\n bc3Decode(blocksPtr: number, dstPtr: number, texW: number, texH: number): void;\n bc1Encode(\n linRgbaPtr: number,\n srgbRgbaPtr: number,\n dstPtr: number,\n texW: number,\n texH: number,\n bc1Mode: number,\n ): void;\n bc1EncodeRgbcx(linRgbaPtr: number, dstPtr: number, texW: number, texH: number): void;\n bc3Encode(\n linRgbaPtr: number,\n srgbRgbaPtr: number,\n dstPtr: number,\n texW: number,\n texH: number,\n ): void;\n resizeRgba(\n srcPtr: number,\n srcW: number,\n srcH: number,\n dstPtr: number,\n dstW: number,\n dstH: number,\n fitMode: number,\n matteR: number,\n matteG: number,\n matteB: number,\n matteA: number,\n ): void;\n}\n\n/**\n * The instantiated texture toolkit returned by {@link createUgcWasm}.\n *\n * Every method copies its inputs into WASM memory and returns freshly allocated\n * typed arrays, so callers never hold pointers into the module's heap. RGBA\n * pixel buffers are 8-bit straight-alpha; linear buffers are `Float32Array` with\n * four channels per pixel. The BC encode and decode methods operate on 4x4\n * blocks, so `w` and `h` must both be multiples of 4.\n */\nexport interface UgcWasm {\n /** Decode BC1 (DXT1) blocks to a `width * height * 4` sRGB RGBA8 buffer. */\n bc1Decode(blocks: Uint8Array, w: number, h: number): Uint8Array;\n /** Decode BC3 (DXT5) blocks to a `width * height * 4` sRGB RGBA8 buffer. */\n bc3Decode(blocks: Uint8Array, w: number, h: number): Uint8Array;\n /**\n * Encode linear-light RGBA to BC1 blocks, using `srgbRgba` for perceptual\n * error weighting. `mode` selects the endpoint strategy; see {@link Bc1Mode}.\n */\n bc1Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n ): Uint8Array;\n /** Encode linear-light RGBA to BC1 blocks via the rgbcx reference path (no sRGB weighting). */\n bc1EncodeRgbcx(linRgba: Float32Array, w: number, h: number): Uint8Array;\n /** Encode linear-light RGBA to BC3 blocks, using `srgbRgba` for perceptual error weighting. */\n bc3Encode(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number): Uint8Array;\n /**\n * {@link UgcWasm.bc1Encode} spread across `threads` workers. Requires a\n * {@link CreateWorker} factory; falls back to the synchronous path otherwise.\n */\n bc1EncodeThreaded(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n threads: number,\n ): Promise<Uint8Array>;\n /**\n * {@link UgcWasm.bc3Encode} spread across `threads` workers. Requires a\n * {@link CreateWorker} factory; falls back to the synchronous path otherwise.\n */\n bc3EncodeThreaded(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n threads: number,\n ): Promise<Uint8Array>;\n /**\n * Convert a Tegra block-linear (swizzled) surface to row-linear pixels.\n *\n * @param bpe Bytes per element (per pixel or per compressed block).\n * @param blockHeight GOB block height in GOBs (1, 2, 4, 8, or 16).\n */\n deswizzle(\n swizzled: Uint8Array,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n ): Uint8Array;\n /**\n * Convert row-linear pixels back to a Tegra block-linear surface. When `base`\n * matches the padded output size it is used as the starting buffer so padding\n * bytes are preserved; pass `null` to start from zero.\n *\n * @param bpe Bytes per element (per pixel or per compressed block).\n * @param blockHeight GOB block height in GOBs (1, 2, 4, 8, or 16).\n */\n swizzle(\n linear: Uint8Array,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n base: Uint8Array | null,\n ): Uint8Array;\n /** Convert sRGB RGBA8 to linear-light `Float32Array` RGBA (four channels per pixel). */\n srgbToLinearF32(rgba: Uint8Array): Float32Array;\n /** Quantize linear-light `Float32Array` channels to linear RGBA8. */\n linearF32ToU8(linear: Float32Array): Uint8Array;\n /** Apply the linear-to-sRGB transfer curve to an RGBA8 buffer in place. */\n linearU8ToSrgbU8InPlace(rgba: Uint8Array): void;\n /**\n * Resize an sRGB RGBA8 image to `dstW * dstH`, honoring `fit` ({@link FitMode})\n * and padding any letterboxed area with `matte` ({@link Matte}), or transparent\n * black when `matte` is `null`.\n */\n resize(\n rgba: Uint8Array,\n srcW: number,\n srcH: number,\n dstW: number,\n dstH: number,\n fit: FitMode,\n matte: Matte | null,\n ): Uint8Array;\n /** Terminate any spawned encode workers and release the thread pool. Safe to call when no pool exists. */\n terminateThreadPool(): Promise<void>;\n}\n\n/** Any form of compiled WASM bytes accepted by {@link createUgcWasm}, including a `fetch` `Response` and promises thereof. */\nexport type WasmSource =\n | ArrayBuffer\n | Uint8Array\n | Response\n | Promise<ArrayBuffer | Uint8Array | Response>;\n\n/** Options for {@link createUgcWasm}. */\nexport interface CreateUgcWasmOptions {\n /** The compiled `ugc.wasm` module bytes, in any {@link WasmSource} form. */\n wasm: WasmSource;\n /** Worker factory enabling the `*Threaded` encode methods; omit for single-threaded use. */\n createWorker?: CreateWorker;\n}\n\nfunction divRoundUp(n: number, d: number): number {\n return Math.floor((n + d - 1) / d);\n}\n\nfunction paddedSwizzleSize(\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n): number {\n const widthInGobs = divRoundUp(width * bpe, 64);\n const paddedHeight = divRoundUp(height, 8 * blockHeight) * (8 * blockHeight);\n return widthInGobs * paddedHeight * 64;\n}\n\nconst importObject: WebAssembly.Imports = {\n env: {\n abort() {\n throw new Error('ugc.wasm aborted');\n },\n },\n};\n\nasync function toBytes(src: WasmSource): Promise<ArrayBuffer> {\n const s = await src;\n if (s instanceof ArrayBuffer) return s;\n if (typeof Response !== 'undefined' && s instanceof Response) return await s.arrayBuffer();\n if (s instanceof Uint8Array) {\n return s.buffer.slice(s.byteOffset, s.byteOffset + s.byteLength) as ArrayBuffer;\n }\n throw new Error('createUgcWasm: unsupported wasm source');\n}\n\nfunction makeWasm(instance: WebAssembly.Instance, pool: ThreadPool | null): UgcWasm {\n const exports = instance.exports as unknown as UgcWasmExports;\n const memory = exports.memory;\n\n function u8(ptr: number, len: number): Uint8Array {\n return new Uint8Array(memory.buffer, ptr, len);\n }\n function f32(ptr: number, len: number): Float32Array {\n return new Float32Array(memory.buffer, ptr, len);\n }\n\n function bc1Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n ): Uint8Array {\n const m = exports.mark();\n try {\n const pixels = w * h;\n const linLen = pixels * 16;\n const srgbLen = pixels * 4;\n const outLen = (pixels / 16) * 8;\n const linPtr = exports.alloc(linLen);\n const srgbPtr = exports.alloc(srgbLen);\n const outPtr = exports.alloc(outLen);\n f32(linPtr, pixels * 4).set(linRgba);\n u8(srgbPtr, srgbLen).set(srgbRgba);\n exports.bc1Encode(linPtr, srgbPtr, outPtr, w, h, mode);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n }\n\n function bc3Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n ): Uint8Array {\n const m = exports.mark();\n try {\n const pixels = w * h;\n const linLen = pixels * 16;\n const srgbLen = pixels * 4;\n const outLen = (pixels / 16) * 16;\n const linPtr = exports.alloc(linLen);\n const srgbPtr = exports.alloc(srgbLen);\n const outPtr = exports.alloc(outLen);\n f32(linPtr, pixels * 4).set(linRgba);\n u8(srgbPtr, srgbLen).set(srgbRgba);\n exports.bc3Encode(linPtr, srgbPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n }\n\n return {\n bc1Decode(blocks, w, h) {\n const m = exports.mark();\n try {\n const inLen = blocks.byteLength;\n const outLen = w * h * 4;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(blocks);\n exports.bc1Decode(inPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n bc3Decode(blocks, w, h) {\n const m = exports.mark();\n try {\n const inLen = blocks.byteLength;\n const outLen = w * h * 4;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(blocks);\n exports.bc3Decode(inPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n bc1Encode,\n bc1EncodeRgbcx(linRgba, w, h) {\n const m = exports.mark();\n try {\n const pixels = w * h;\n const linLen = pixels * 16;\n const outLen = (pixels / 16) * 8;\n const linPtr = exports.alloc(linLen);\n const outPtr = exports.alloc(outLen);\n f32(linPtr, pixels * 4).set(linRgba);\n exports.bc1EncodeRgbcx(linPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n bc3Encode,\n bc1EncodeThreaded(linRgba, srgbRgba, w, h, mode, threads) {\n if (pool) return pool.bc1Encode(linRgba, srgbRgba, w, h, mode, threads);\n return Promise.resolve(bc1Encode(linRgba, srgbRgba, w, h, mode));\n },\n bc3EncodeThreaded(linRgba, srgbRgba, w, h, threads) {\n if (pool) return pool.bc3Encode(linRgba, srgbRgba, w, h, threads);\n return Promise.resolve(bc3Encode(linRgba, srgbRgba, w, h));\n },\n deswizzle(swizzled, width, height, bpe, blockHeight) {\n const m = exports.mark();\n try {\n const inLen = swizzled.byteLength;\n const outLen = width * height * bpe;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(swizzled);\n exports.deswizzleBlockLinear(inPtr, inLen, outPtr, width, height, bpe, blockHeight);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n swizzle(linear, width, height, bpe, blockHeight, base) {\n const m = exports.mark();\n try {\n const inLen = linear.byteLength;\n const outLen = paddedSwizzleSize(width, height, bpe, blockHeight);\n const useBase = base != null && base.byteLength === outLen;\n const baseLen = useBase ? base!.byteLength : 0;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n const basePtr = useBase ? exports.alloc(baseLen) : 0;\n u8(inPtr, inLen).set(linear);\n if (useBase) u8(basePtr, baseLen).set(base!);\n exports.swizzleBlockLinear(\n inPtr,\n inLen,\n outPtr,\n outLen,\n width,\n height,\n bpe,\n blockHeight,\n basePtr,\n baseLen,\n );\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n srgbToLinearF32(rgba) {\n const m = exports.mark();\n try {\n const pixels = rgba.byteLength / 4;\n const inLen = rgba.byteLength;\n const outLen = pixels * 16;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(rgba);\n exports.srgbU8ToLinearF32(inPtr, outPtr, pixels);\n const out = new Float32Array(pixels * 4);\n out.set(f32(outPtr, pixels * 4));\n return out;\n } finally {\n exports.release(m);\n }\n },\n linearF32ToU8(linear) {\n const m = exports.mark();\n try {\n const count = linear.length;\n const inLen = count * 4;\n const outLen = count;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n f32(inPtr, count).set(linear);\n exports.linearF32ToLinearU8(inPtr, outPtr, count);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n linearU8ToSrgbU8InPlace(rgba) {\n const m = exports.mark();\n try {\n const len = rgba.byteLength;\n const ptr = exports.alloc(len);\n u8(ptr, len).set(rgba);\n exports.convertLinearU8ToSrgbU8(ptr, len);\n rgba.set(u8(ptr, len));\n } finally {\n exports.release(m);\n }\n },\n resize(rgba, srcW, srcH, dstW, dstH, fit, matte) {\n const m = exports.mark();\n try {\n const inLen = srcW * srcH * 4;\n const outLen = dstW * dstH * 4;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(rgba);\n const mr = matte ? matte.r : 0;\n const mg = matte ? matte.g : 0;\n const mb = matte ? matte.b : 0;\n const ma = matte ? matte.a : 0;\n exports.resizeRgba(inPtr, srcW, srcH, outPtr, dstW, dstH, fit, mr, mg, mb, ma);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n async terminateThreadPool() {\n if (pool) await pool.terminate();\n },\n };\n}\n\n/**\n * Compile and instantiate `ugc.wasm`, returning a {@link UgcWasm} toolkit.\n *\n * Pass a {@link CreateWorker} via {@link CreateUgcWasmOptions.createWorker} to\n * enable the multi-threaded encode paths; without it those methods run inline.\n *\n * @example\n * ```ts\n * import { createUgcWasm } from '@alexislours/ltd-textures';\n * import { readFile } from 'node:fs/promises';\n *\n * const ugc = await createUgcWasm({ wasm: await readFile('ugc.wasm') });\n * const rgba = ugc.bc1Decode(blocks, 256, 256);\n * ```\n */\nexport async function createUgcWasm(options: CreateUgcWasmOptions): Promise<UgcWasm> {\n const bytes = await toBytes(options.wasm);\n const { instance } = await WebAssembly.instantiate(bytes, importObject);\n const pool = options.createWorker ? createThreadPool(bytes, options.createWorker) : null;\n return makeWasm(instance, pool);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebAssembly toolkit for Tegra/Switch texture data: block-linear
|
|
3
|
+
* (de)swizzling, BC1/BC3 transcoding, sRGB/linear conversion, and image resize.
|
|
4
|
+
*
|
|
5
|
+
* Instantiate the module with {@link createUgcWasm} (bring your own `ugc.wasm`
|
|
6
|
+
* bytes), or use the `@alexislours/ltd-textures/browser` entrypoint to fetch the
|
|
7
|
+
* bundled binary automatically.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { createUgcWasm, Bc1Mode } from '@alexislours/ltd-textures';
|
|
12
|
+
*
|
|
13
|
+
* const ugc = await createUgcWasm({ wasm: wasmBytes });
|
|
14
|
+
* const linear = ugc.srgbToLinearF32(rgba);
|
|
15
|
+
* const blocks = ugc.bc1Encode(linear, rgba, 256, 256, Bc1Mode.Auto);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
1
20
|
export { createUgcWasm, type UgcWasm, type WasmSource, type CreateUgcWasmOptions, } from './bridge.js';
|
|
2
21
|
export { type CreateWorker, type WorkerLike, type ThreadPool } from './threadPool.js';
|
|
3
22
|
export { Bc1Mode, FitMode, type Matte } from './types.js';
|
package/dist/index.js
CHANGED
package/dist/threadPool.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { Bc1Mode } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The minimal subset of the DOM/Node `Worker` surface the thread pool relies on.
|
|
4
|
+
*
|
|
5
|
+
* Both the browser `Worker` and a `node:worker_threads` adapter satisfy this shape.
|
|
6
|
+
*/
|
|
2
7
|
export type WorkerLike = {
|
|
3
8
|
postMessage(msg: unknown, transfer?: Transferable[]): void;
|
|
4
9
|
onmessage: ((e: MessageEvent) => void) | null;
|
|
@@ -6,7 +11,17 @@ export type WorkerLike = {
|
|
|
6
11
|
onmessageerror?: ((e: MessageEvent) => void) | null;
|
|
7
12
|
terminate(): void;
|
|
8
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Factory that spawns a fresh worker running the package's `worker` entrypoint.
|
|
16
|
+
*
|
|
17
|
+
* Supplying this to {@link createUgcWasm} enables the multi-threaded encode paths.
|
|
18
|
+
*/
|
|
9
19
|
export type CreateWorker = () => WorkerLike;
|
|
20
|
+
/**
|
|
21
|
+
* A pool of encode workers that splits a texture into horizontal stripes and
|
|
22
|
+
* encodes them in parallel. Created internally by {@link createUgcWasm} when a
|
|
23
|
+
* {@link CreateWorker} factory is provided.
|
|
24
|
+
*/
|
|
10
25
|
export type ThreadPool = {
|
|
11
26
|
bc1Encode(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number, mode: Bc1Mode, threads: number): Promise<Uint8Array>;
|
|
12
27
|
bc3Encode(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number, threads: number): Promise<Uint8Array>;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BC1 endpoint selection strategy used by the encoder.
|
|
3
|
+
*
|
|
4
|
+
* - `Auto` lets the encoder pick three- or four-color mode per block.
|
|
5
|
+
* - `FourColor` forces the opaque four-color layout.
|
|
6
|
+
* - `ThreeColor` forces the three-color layout with a 1-bit punch-through alpha.
|
|
7
|
+
*/
|
|
1
8
|
export declare const Bc1Mode: {
|
|
2
9
|
readonly Auto: 0;
|
|
3
10
|
readonly FourColor: 1;
|
|
4
11
|
readonly ThreeColor: 2;
|
|
5
12
|
};
|
|
13
|
+
/** A {@link Bc1Mode} value. */
|
|
6
14
|
export type Bc1Mode = (typeof Bc1Mode)[keyof typeof Bc1Mode];
|
|
15
|
+
/**
|
|
16
|
+
* How a source image is fitted into the destination rectangle when resizing.
|
|
17
|
+
*
|
|
18
|
+
* - `Fill` stretches to the exact destination, ignoring aspect ratio.
|
|
19
|
+
* - `Contain` scales to fit inside and pads the remainder with the matte.
|
|
20
|
+
* - `Cover` scales to cover the destination and crops the overflow.
|
|
21
|
+
*/
|
|
7
22
|
export declare const FitMode: {
|
|
8
23
|
readonly Fill: 0;
|
|
9
24
|
readonly Contain: 1;
|
|
10
25
|
readonly Cover: 2;
|
|
11
26
|
};
|
|
27
|
+
/** A {@link FitMode} value. */
|
|
12
28
|
export type FitMode = (typeof FitMode)[keyof typeof FitMode];
|
|
29
|
+
/** Straight (non-premultiplied) RGBA fill color, each channel in `[0, 255]`, used to pad letterboxed regions when {@link FitMode.Contain} is selected. */
|
|
13
30
|
export type Matte = {
|
|
14
31
|
r: number;
|
|
15
32
|
g: number;
|
package/dist/worker.d.ts
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker entrypoint for the BC1/BC3 encode thread pool. Load this module as a
|
|
3
|
+
* web `Worker` or `node:worker_threads` worker and feed it to a
|
|
4
|
+
* {@link createUgcWasm} `createWorker` factory; it instantiates `ugc.wasm` on an
|
|
5
|
+
* `init` message and replies to `encode` messages with packed blocks. It exposes
|
|
6
|
+
* no importable symbols and is not meant to be called directly.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
1
10
|
export {};
|
package/dist/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["/**\n * Worker entrypoint for the BC1/BC3 encode thread pool. Load this module as a\n * web `Worker` or `node:worker_threads` worker and feed it to a\n * {@link createUgcWasm} `createWorker` factory; it instantiates `ugc.wasm` on an\n * `init` message and replies to `encode` messages with packed blocks. It exposes\n * no importable symbols and is not meant to be called directly.\n *\n * @module\n */\nexport {};\n\ninterface WasmEncodeExports {\n memory: WebAssembly.Memory;\n alloc(size: number): number;\n mark(): number;\n release(m: number): void;\n bc1Encode(\n linRgbaPtr: number,\n srgbRgbaPtr: number,\n dstPtr: number,\n texW: number,\n texH: number,\n bc1Mode: number,\n ): void;\n bc3Encode(\n linRgbaPtr: number,\n srgbRgbaPtr: number,\n dstPtr: number,\n texW: number,\n texH: number,\n ): void;\n}\n\ntype InMsg =\n | { type: 'init'; wasmBytes: ArrayBuffer }\n | {\n type: 'encode';\n id: number;\n op: 'bc1' | 'bc3';\n linF: Float32Array;\n srgbU: Uint8Array;\n w: number;\n h: number;\n mode: number;\n };\n\ntype OutMsg =\n | { type: 'ready' }\n | { type: 'done'; id: number; blocks: ArrayBuffer }\n | { type: 'error'; id?: number; error: string };\n\nconst isNode =\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null &&\n typeof self === 'undefined';\n\nlet listen: (cb: (msg: InMsg) => void) => void;\nlet post: (msg: OutMsg, transfer?: Transferable[]) => void;\n\nif (isNode) {\n const wt = await import(/* @vite-ignore */ 'node:worker_threads');\n const port = wt.parentPort;\n if (!port) throw new Error('worker has no parentPort');\n listen = (cb) => port.on('message', cb);\n post = (msg, transfer) => port.postMessage(msg, (transfer ?? []) as unknown as ArrayBuffer[]);\n} else {\n type WorkerScope = {\n onmessage: ((e: MessageEvent) => void) | null;\n postMessage(msg: unknown, transfer?: Transferable[]): void;\n };\n const scope = self as unknown as WorkerScope;\n listen = (cb) => {\n scope.onmessage = (e: MessageEvent) => cb(e.data as InMsg);\n };\n post = (msg, transfer) => scope.postMessage(msg, transfer ?? []);\n}\n\nconst importObject: WebAssembly.Imports = {\n env: {\n abort() {\n throw new Error('ugc.wasm aborted in worker');\n },\n },\n};\n\nlet wasmExports: WasmEncodeExports | null = null;\n\nlisten((msg) => {\n handle(msg).catch((err: unknown) => {\n const id = msg && (msg as { id?: number }).id;\n post({ type: 'error', id, error: String(err) });\n });\n});\n\nasync function handle(msg: InMsg): Promise<void> {\n if (msg.type === 'init') {\n const result = await WebAssembly.instantiate(msg.wasmBytes, importObject);\n wasmExports = result.instance.exports as unknown as WasmEncodeExports;\n post({ type: 'ready' });\n return;\n }\n if (msg.type === 'encode') {\n const exp = wasmExports;\n if (!exp) throw new Error('worker not initialized');\n const { id, op, linF, srgbU, w, h, mode } = msg;\n const pixels = w * h;\n const linLen = pixels * 16;\n const srgbLen = pixels * 4;\n const outLen = op === 'bc1' ? (pixels / 16) * 8 : (pixels / 16) * 16;\n const m = exp.mark();\n let outAB: ArrayBuffer;\n try {\n const linPtr = exp.alloc(linLen);\n const srgbPtr = exp.alloc(srgbLen);\n const outPtr = exp.alloc(outLen);\n const memBuf = exp.memory.buffer;\n new Float32Array(memBuf, linPtr, pixels * 4).set(linF);\n new Uint8Array(memBuf, srgbPtr, srgbLen).set(srgbU);\n if (op === 'bc1') {\n exp.bc1Encode(linPtr, srgbPtr, outPtr, w, h, mode);\n } else {\n exp.bc3Encode(linPtr, srgbPtr, outPtr, w, h);\n }\n outAB = new ArrayBuffer(outLen);\n new Uint8Array(outAB).set(new Uint8Array(memBuf, outPtr, outLen));\n } finally {\n exp.release(m);\n }\n post({ type: 'done', id, blocks: outAB }, [outAB]);\n }\n}\n"],"mappings":";AAmDA,IAAM,SACJ,OAAO,YAAY,eACnB,QAAQ,YAAY,QACpB,QAAQ,SAAS,QAAQ,QACzB,OAAO,SAAS;AAElB,IAAI;AACJ,IAAI;AAEJ,IAAI,QAAQ;AACV,QAAM,KAAK,MAAM;AAAA;AAAA,IAA0B;AAAA,EAAqB;AAChE,QAAM,OAAO,GAAG;AAChB,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,0BAA0B;AACrD,WAAS,CAAC,OAAO,KAAK,GAAG,WAAW,EAAE;AACtC,SAAO,CAAC,KAAK,aAAa,KAAK,YAAY,KAAM,YAAY,CAAC,CAA8B;AAC9F,OAAO;AAKL,QAAM,QAAQ;AACd,WAAS,CAAC,OAAO;AACf,UAAM,YAAY,CAAC,MAAoB,GAAG,EAAE,IAAa;AAAA,EAC3D;AACA,SAAO,CAAC,KAAK,aAAa,MAAM,YAAY,KAAK,YAAY,CAAC,CAAC;AACjE;AAEA,IAAM,eAAoC;AAAA,EACxC,KAAK;AAAA,IACH,QAAQ;AACN,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,IAAI,cAAwC;AAE5C,OAAO,CAAC,QAAQ;AACd,SAAO,GAAG,EAAE,MAAM,CAAC,QAAiB;AAClC,UAAM,KAAK,OAAQ,IAAwB;AAC3C,SAAK,EAAE,MAAM,SAAS,IAAI,OAAO,OAAO,GAAG,EAAE,CAAC;AAAA,EAChD,CAAC;AACH,CAAC;AAED,eAAe,OAAO,KAA2B;AAC/C,MAAI,IAAI,SAAS,QAAQ;AACvB,UAAM,SAAS,MAAM,YAAY,YAAY,IAAI,WAAW,YAAY;AACxE,kBAAc,OAAO,SAAS;AAC9B,SAAK,EAAE,MAAM,QAAQ,CAAC;AACtB;AAAA,EACF;AACA,MAAI,IAAI,SAAS,UAAU;AACzB,UAAM,MAAM;AACZ,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,wBAAwB;AAClD,UAAM,EAAE,IAAI,IAAI,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI;AAC5C,UAAM,SAAS,IAAI;AACnB,UAAM,SAAS,SAAS;AACxB,UAAM,UAAU,SAAS;AACzB,UAAM,SAAS,OAAO,QAAS,SAAS,KAAM,IAAK,SAAS,KAAM;AAClE,UAAM,IAAI,IAAI,KAAK;AACnB,QAAI;AACJ,QAAI;AACF,YAAM,SAAS,IAAI,MAAM,MAAM;AAC/B,YAAM,UAAU,IAAI,MAAM,OAAO;AACjC,YAAM,SAAS,IAAI,MAAM,MAAM;AAC/B,YAAM,SAAS,IAAI,OAAO;AAC1B,UAAI,aAAa,QAAQ,QAAQ,SAAS,CAAC,EAAE,IAAI,IAAI;AACrD,UAAI,WAAW,QAAQ,SAAS,OAAO,EAAE,IAAI,KAAK;AAClD,UAAI,OAAO,OAAO;AAChB,YAAI,UAAU,QAAQ,SAAS,QAAQ,GAAG,GAAG,IAAI;AAAA,MACnD,OAAO;AACL,YAAI,UAAU,QAAQ,SAAS,QAAQ,GAAG,CAAC;AAAA,MAC7C;AACA,cAAQ,IAAI,YAAY,MAAM;AAC9B,UAAI,WAAW,KAAK,EAAE,IAAI,IAAI,WAAW,QAAQ,QAAQ,MAAM,CAAC;AAAA,IAClE,UAAE;AACA,UAAI,QAAQ,CAAC;AAAA,IACf;AACA,SAAK,EAAE,MAAM,QAAQ,IAAI,QAAQ,MAAM,GAAG,CAAC,KAAK,CAAC;AAAA,EACnD;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexislours/ltd-textures",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Tegra/Switch block-linear (de)swizzle, BC1/BC3 transcode, sRGB/linear conversion, and image resize, in WebAssembly.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"author": "Alexis Lours",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"build": "npm run build:wasm && tsup && tsc -p tsconfig.build.json",
|
|
50
50
|
"check": "tsc -p tsconfig.json",
|
|
51
51
|
"lint:pkg": "publint --strict && attw --pack --profile esm-only --exclude-entrypoints ugc.wasm",
|
|
52
|
+
"test": "vitest run",
|
|
52
53
|
"prepublishOnly": "npm run build"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/threadPool.ts","../src/bridge.ts"],"sourcesContent":["export const Bc1Mode = {\n Auto: 0,\n FourColor: 1,\n ThreeColor: 2,\n} as const;\nexport type Bc1Mode = (typeof Bc1Mode)[keyof typeof Bc1Mode];\n\nexport const FitMode = {\n Fill: 0,\n Contain: 1,\n Cover: 2,\n} as const;\nexport type FitMode = (typeof FitMode)[keyof typeof FitMode];\n\nexport type Matte = { r: number; g: number; b: number; a: number };\n","import { Bc1Mode } from './types.js';\n\nexport type WorkerLike = {\n postMessage(msg: unknown, transfer?: Transferable[]): void;\n onmessage: ((e: MessageEvent) => void) | null;\n onerror: ((e: ErrorEvent) => void) | null;\n onmessageerror?: ((e: MessageEvent) => void) | null;\n terminate(): void;\n};\n\nexport type CreateWorker = () => WorkerLike;\n\ntype WorkerHandle = {\n postMessage(msg: unknown, transfer?: Transferable[]): void;\n setMessageHandler(cb: (msg: WorkerMessage) => void): void;\n setErrorHandler(cb: (err: unknown) => void): void;\n terminate(): void;\n};\n\ntype WorkerMessage =\n | { type: 'ready' }\n | { type: 'done'; id: number; blocks: ArrayBuffer }\n | { type: 'error'; id?: number; error: string };\n\nexport type ThreadPool = {\n bc1Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n threads: number,\n ): Promise<Uint8Array>;\n bc3Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n threads: number,\n ): Promise<Uint8Array>;\n terminate(): Promise<void>;\n};\n\nconst WORKER_INIT_TIMEOUT_MS = 15000;\n\nfunction formatWorkerErrorEvent(e: unknown): string {\n const ev = e as Partial<ErrorEvent> & { error?: { message?: string; stack?: string } };\n const parts: string[] = [];\n if (ev.message) parts.push(ev.message);\n if (ev.error) {\n if (ev.error.message && ev.error.message !== ev.message) parts.push(ev.error.message);\n if (ev.error.stack) parts.push(ev.error.stack);\n }\n if (ev.filename) parts.push(`at ${ev.filename}:${ev.lineno}:${ev.colno}`);\n return parts.length > 0 ? parts.join(' | ') : 'unknown worker error';\n}\n\nfunction wrapWorker(w: WorkerLike): WorkerHandle {\n return {\n postMessage: (msg, transfer) => w.postMessage(msg, transfer ?? []),\n setMessageHandler: (cb) => {\n w.onmessage = (e: MessageEvent) => cb(e.data as WorkerMessage);\n },\n setErrorHandler: (cb) => {\n w.onerror = (e: unknown) => cb(formatWorkerErrorEvent(e));\n w.onmessageerror = () => cb('messageerror');\n },\n terminate: () => w.terminate(),\n };\n}\n\nexport function createThreadPool(wasmBytes: ArrayBuffer, createWorker: CreateWorker): ThreadPool {\n let pool: WorkerHandle[] | null = null;\n let nextId = 1;\n type Pending = { resolve: (out: Uint8Array) => void; reject: (err: unknown) => void };\n const pending = new Map<number, Pending>();\n\n function rejectAllPending(err: unknown): void {\n for (const [id, cb] of pending) {\n pending.delete(id);\n cb.reject(err);\n }\n }\n\n function dispatchListener(msg: WorkerMessage): void {\n if (msg.type === 'done') {\n const cb = pending.get(msg.id);\n if (cb) {\n pending.delete(msg.id);\n cb.resolve(new Uint8Array(msg.blocks));\n }\n } else if (msg.type === 'error' && msg.id != null) {\n const cb = pending.get(msg.id);\n pending.delete(msg.id);\n cb?.reject(new Error(msg.error));\n }\n }\n\n async function bootWorker(): Promise<WorkerHandle> {\n const handle = wrapWorker(createWorker());\n try {\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error('Worker init timed out'));\n }, WORKER_INIT_TIMEOUT_MS);\n const finish = (fn: () => void): void => {\n clearTimeout(timer);\n fn();\n };\n handle.setMessageHandler((msg) => {\n if (msg.type === 'ready') {\n finish(() => {\n handle.setMessageHandler(dispatchListener);\n handle.setErrorHandler((err) => rejectAllPending(new Error(`Worker error: ${err}`)));\n resolve();\n });\n } else if (msg.type === 'error') {\n finish(() => reject(new Error(msg.error)));\n }\n });\n handle.setErrorHandler((err) => {\n finish(() => reject(new Error(`Worker init error: ${err}`)));\n });\n handle.postMessage({ type: 'init', wasmBytes });\n });\n } catch (e) {\n handle.terminate();\n throw e;\n }\n return handle;\n }\n\n async function ensurePool(threads: number): Promise<void> {\n if (pool && pool.length >= threads) return;\n if (!pool) pool = [];\n const need = threads - pool.length;\n if (need <= 0) return;\n const results = await Promise.allSettled(Array.from({ length: need }, () => bootWorker()));\n const fulfilled: WorkerHandle[] = [];\n let firstError: unknown = null;\n for (const r of results) {\n if (r.status === 'fulfilled') fulfilled.push(r.value);\n else if (firstError == null) firstError = r.reason;\n }\n if (firstError != null) {\n for (const h of fulfilled) h.terminate();\n throw firstError;\n }\n pool.push(...fulfilled);\n }\n\n function dispatchEncode(\n idx: number,\n op: 'bc1' | 'bc3',\n linF: Float32Array,\n srgbU: Uint8Array,\n w: number,\n h: number,\n mode: number,\n transfer: Transferable[],\n ): Promise<Uint8Array> {\n const id = nextId++;\n return new Promise<Uint8Array>((resolve, reject) => {\n pending.set(id, { resolve, reject });\n pool![idx].postMessage({ type: 'encode', id, op, linF, srgbU, w, h, mode }, transfer);\n });\n }\n\n function partition(blocksY: number, threads: number): number[] {\n const base = Math.floor(blocksY / threads);\n const extra = blocksY % threads;\n const out: number[] = [];\n for (let i = 0; i < threads; i++) {\n const sz = base + (i < extra ? 1 : 0);\n if (sz > 0) out.push(sz);\n }\n return out;\n }\n\n async function encodeThreaded(\n op: 'bc1' | 'bc3',\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: number,\n threads: number,\n bytesPerBlock: number,\n ): Promise<Uint8Array> {\n if (w % 4 !== 0 || h % 4 !== 0) {\n throw new Error(`encodeThreaded: width and height must be 4-aligned, got ${w}x${h}`);\n }\n await ensurePool(threads);\n const blocksY = h / 4;\n const blocksX = w / 4;\n const sizes = partition(blocksY, threads);\n const promises: Promise<Uint8Array>[] = [];\n let yOff = 0;\n for (let i = 0; i < sizes.length; i++) {\n const sliceBlocksY = sizes[i];\n const slicePxRows = sliceBlocksY * 4;\n const elemStart = yOff * 4 * w * 4;\n const elemEnd = (yOff + sliceBlocksY) * 4 * w * 4;\n const byteStart = yOff * 4 * w * 4;\n const byteEnd = (yOff + sliceBlocksY) * 4 * w * 4;\n const linAB = new ArrayBuffer((elemEnd - elemStart) * 4);\n const linF = new Float32Array(linAB);\n linF.set(linRgba.subarray(elemStart, elemEnd));\n const srgbAB = new ArrayBuffer(byteEnd - byteStart);\n const srgbU = new Uint8Array(srgbAB);\n srgbU.set(srgbRgba.subarray(byteStart, byteEnd));\n promises.push(dispatchEncode(i, op, linF, srgbU, w, slicePxRows, mode, [linAB, srgbAB]));\n yOff += sliceBlocksY;\n }\n const parts = await Promise.all(promises);\n const total = blocksY * blocksX * bytesPerBlock;\n const out = new Uint8Array(total);\n let writeOff = 0;\n for (const p of parts) {\n out.set(p, writeOff);\n writeOff += p.byteLength;\n }\n return out;\n }\n\n return {\n bc1Encode(linRgba, srgbRgba, w, h, mode, threads) {\n return encodeThreaded('bc1', linRgba, srgbRgba, w, h, mode, threads, 8);\n },\n bc3Encode(linRgba, srgbRgba, w, h, threads) {\n return encodeThreaded('bc3', linRgba, srgbRgba, w, h, 0, threads, 16);\n },\n async terminate() {\n rejectAllPending(new Error('Thread pool terminated'));\n if (!pool) return;\n for (const w of pool) w.terminate();\n pool = null;\n },\n };\n}\n","import { Bc1Mode, FitMode, type Matte } from './types.js';\nimport { createThreadPool, type CreateWorker, type ThreadPool } from './threadPool.js';\n\ninterface UgcWasmExports {\n memory: WebAssembly.Memory;\n alloc(size: number): number;\n mark(): number;\n release(m: number): void;\n free(ptr: number): void;\n deswizzleBlockLinear(\n srcPtr: number,\n srcLen: number,\n dstPtr: number,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n ): void;\n swizzleBlockLinear(\n srcPtr: number,\n srcLen: number,\n dstPtr: number,\n dstLen: number,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n basePtr: number,\n baseLen: number,\n ): void;\n srgbU8ToLinearF32(srcPtr: number, dstPtr: number, pixelCount: number): void;\n linearF32ToLinearU8(srcPtr: number, dstPtr: number, count: number): void;\n convertLinearU8ToSrgbU8(rgbaPtr: number, byteLen: number): void;\n bc1Decode(blocksPtr: number, dstPtr: number, texW: number, texH: number): void;\n bc3Decode(blocksPtr: number, dstPtr: number, texW: number, texH: number): void;\n bc1Encode(\n linRgbaPtr: number,\n srgbRgbaPtr: number,\n dstPtr: number,\n texW: number,\n texH: number,\n bc1Mode: number,\n ): void;\n bc1EncodeRgbcx(linRgbaPtr: number, dstPtr: number, texW: number, texH: number): void;\n bc3Encode(\n linRgbaPtr: number,\n srgbRgbaPtr: number,\n dstPtr: number,\n texW: number,\n texH: number,\n ): void;\n resizeRgba(\n srcPtr: number,\n srcW: number,\n srcH: number,\n dstPtr: number,\n dstW: number,\n dstH: number,\n fitMode: number,\n matteR: number,\n matteG: number,\n matteB: number,\n matteA: number,\n ): void;\n}\n\nexport interface UgcWasm {\n bc1Decode(blocks: Uint8Array, w: number, h: number): Uint8Array;\n bc3Decode(blocks: Uint8Array, w: number, h: number): Uint8Array;\n bc1Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n ): Uint8Array;\n bc1EncodeRgbcx(linRgba: Float32Array, w: number, h: number): Uint8Array;\n bc3Encode(linRgba: Float32Array, srgbRgba: Uint8Array, w: number, h: number): Uint8Array;\n bc1EncodeThreaded(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n threads: number,\n ): Promise<Uint8Array>;\n bc3EncodeThreaded(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n threads: number,\n ): Promise<Uint8Array>;\n deswizzle(\n swizzled: Uint8Array,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n ): Uint8Array;\n swizzle(\n linear: Uint8Array,\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n base: Uint8Array | null,\n ): Uint8Array;\n srgbToLinearF32(rgba: Uint8Array): Float32Array;\n linearF32ToU8(linear: Float32Array): Uint8Array;\n linearU8ToSrgbU8InPlace(rgba: Uint8Array): void;\n resize(\n rgba: Uint8Array,\n srcW: number,\n srcH: number,\n dstW: number,\n dstH: number,\n fit: FitMode,\n matte: Matte | null,\n ): Uint8Array;\n terminateThreadPool(): Promise<void>;\n}\n\nexport type WasmSource =\n | ArrayBuffer\n | Uint8Array\n | Response\n | Promise<ArrayBuffer | Uint8Array | Response>;\n\nexport interface CreateUgcWasmOptions {\n wasm: WasmSource;\n createWorker?: CreateWorker;\n}\n\nfunction divRoundUp(n: number, d: number): number {\n return Math.floor((n + d - 1) / d);\n}\n\nfunction paddedSwizzleSize(\n width: number,\n height: number,\n bpe: number,\n blockHeight: number,\n): number {\n const widthInGobs = divRoundUp(width * bpe, 64);\n const paddedHeight = divRoundUp(height, 8 * blockHeight) * (8 * blockHeight);\n return widthInGobs * paddedHeight * 64;\n}\n\nconst importObject: WebAssembly.Imports = {\n env: {\n abort() {\n throw new Error('ugc.wasm aborted');\n },\n },\n};\n\nasync function toBytes(src: WasmSource): Promise<ArrayBuffer> {\n const s = await src;\n if (s instanceof ArrayBuffer) return s;\n if (typeof Response !== 'undefined' && s instanceof Response) return await s.arrayBuffer();\n if (s instanceof Uint8Array) {\n return s.buffer.slice(s.byteOffset, s.byteOffset + s.byteLength) as ArrayBuffer;\n }\n throw new Error('createUgcWasm: unsupported wasm source');\n}\n\nfunction makeWasm(instance: WebAssembly.Instance, pool: ThreadPool | null): UgcWasm {\n const exports = instance.exports as unknown as UgcWasmExports;\n const memory = exports.memory;\n\n function u8(ptr: number, len: number): Uint8Array {\n return new Uint8Array(memory.buffer, ptr, len);\n }\n function f32(ptr: number, len: number): Float32Array {\n return new Float32Array(memory.buffer, ptr, len);\n }\n\n function bc1Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n mode: Bc1Mode,\n ): Uint8Array {\n const m = exports.mark();\n try {\n const pixels = w * h;\n const linLen = pixels * 16;\n const srgbLen = pixels * 4;\n const outLen = (pixels / 16) * 8;\n const linPtr = exports.alloc(linLen);\n const srgbPtr = exports.alloc(srgbLen);\n const outPtr = exports.alloc(outLen);\n f32(linPtr, pixels * 4).set(linRgba);\n u8(srgbPtr, srgbLen).set(srgbRgba);\n exports.bc1Encode(linPtr, srgbPtr, outPtr, w, h, mode);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n }\n\n function bc3Encode(\n linRgba: Float32Array,\n srgbRgba: Uint8Array,\n w: number,\n h: number,\n ): Uint8Array {\n const m = exports.mark();\n try {\n const pixels = w * h;\n const linLen = pixels * 16;\n const srgbLen = pixels * 4;\n const outLen = (pixels / 16) * 16;\n const linPtr = exports.alloc(linLen);\n const srgbPtr = exports.alloc(srgbLen);\n const outPtr = exports.alloc(outLen);\n f32(linPtr, pixels * 4).set(linRgba);\n u8(srgbPtr, srgbLen).set(srgbRgba);\n exports.bc3Encode(linPtr, srgbPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n }\n\n return {\n bc1Decode(blocks, w, h) {\n const m = exports.mark();\n try {\n const inLen = blocks.byteLength;\n const outLen = w * h * 4;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(blocks);\n exports.bc1Decode(inPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n bc3Decode(blocks, w, h) {\n const m = exports.mark();\n try {\n const inLen = blocks.byteLength;\n const outLen = w * h * 4;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(blocks);\n exports.bc3Decode(inPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n bc1Encode,\n bc1EncodeRgbcx(linRgba, w, h) {\n const m = exports.mark();\n try {\n const pixels = w * h;\n const linLen = pixels * 16;\n const outLen = (pixels / 16) * 8;\n const linPtr = exports.alloc(linLen);\n const outPtr = exports.alloc(outLen);\n f32(linPtr, pixels * 4).set(linRgba);\n exports.bc1EncodeRgbcx(linPtr, outPtr, w, h);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n bc3Encode,\n bc1EncodeThreaded(linRgba, srgbRgba, w, h, mode, threads) {\n if (pool) return pool.bc1Encode(linRgba, srgbRgba, w, h, mode, threads);\n return Promise.resolve(bc1Encode(linRgba, srgbRgba, w, h, mode));\n },\n bc3EncodeThreaded(linRgba, srgbRgba, w, h, threads) {\n if (pool) return pool.bc3Encode(linRgba, srgbRgba, w, h, threads);\n return Promise.resolve(bc3Encode(linRgba, srgbRgba, w, h));\n },\n deswizzle(swizzled, width, height, bpe, blockHeight) {\n const m = exports.mark();\n try {\n const inLen = swizzled.byteLength;\n const outLen = width * height * bpe;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(swizzled);\n exports.deswizzleBlockLinear(inPtr, inLen, outPtr, width, height, bpe, blockHeight);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n swizzle(linear, width, height, bpe, blockHeight, base) {\n const m = exports.mark();\n try {\n const inLen = linear.byteLength;\n const outLen = paddedSwizzleSize(width, height, bpe, blockHeight);\n const useBase = base != null && base.byteLength === outLen;\n const baseLen = useBase ? base!.byteLength : 0;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n const basePtr = useBase ? exports.alloc(baseLen) : 0;\n u8(inPtr, inLen).set(linear);\n if (useBase) u8(basePtr, baseLen).set(base!);\n exports.swizzleBlockLinear(\n inPtr,\n inLen,\n outPtr,\n outLen,\n width,\n height,\n bpe,\n blockHeight,\n basePtr,\n baseLen,\n );\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n srgbToLinearF32(rgba) {\n const m = exports.mark();\n try {\n const pixels = rgba.byteLength / 4;\n const inLen = rgba.byteLength;\n const outLen = pixels * 16;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(rgba);\n exports.srgbU8ToLinearF32(inPtr, outPtr, pixels);\n const out = new Float32Array(pixels * 4);\n out.set(f32(outPtr, pixels * 4));\n return out;\n } finally {\n exports.release(m);\n }\n },\n linearF32ToU8(linear) {\n const m = exports.mark();\n try {\n const count = linear.length;\n const inLen = count * 4;\n const outLen = count;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n f32(inPtr, count).set(linear);\n exports.linearF32ToLinearU8(inPtr, outPtr, count);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n linearU8ToSrgbU8InPlace(rgba) {\n const m = exports.mark();\n try {\n const len = rgba.byteLength;\n const ptr = exports.alloc(len);\n u8(ptr, len).set(rgba);\n exports.convertLinearU8ToSrgbU8(ptr, len);\n rgba.set(u8(ptr, len));\n } finally {\n exports.release(m);\n }\n },\n resize(rgba, srcW, srcH, dstW, dstH, fit, matte) {\n const m = exports.mark();\n try {\n const inLen = srcW * srcH * 4;\n const outLen = dstW * dstH * 4;\n const inPtr = exports.alloc(inLen);\n const outPtr = exports.alloc(outLen);\n u8(inPtr, inLen).set(rgba);\n const mr = matte ? matte.r : 0;\n const mg = matte ? matte.g : 0;\n const mb = matte ? matte.b : 0;\n const ma = matte ? matte.a : 0;\n exports.resizeRgba(inPtr, srcW, srcH, outPtr, dstW, dstH, fit, mr, mg, mb, ma);\n const out = new Uint8Array(outLen);\n out.set(u8(outPtr, outLen));\n return out;\n } finally {\n exports.release(m);\n }\n },\n async terminateThreadPool() {\n if (pool) await pool.terminate();\n },\n };\n}\n\nexport async function createUgcWasm(options: CreateUgcWasmOptions): Promise<UgcWasm> {\n const bytes = await toBytes(options.wasm);\n const { instance } = await WebAssembly.instantiate(bytes, importObject);\n const pool = options.createWorker ? createThreadPool(bytes, options.createWorker) : null;\n return makeWasm(instance, pool);\n}\n"],"mappings":"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","names":[]}
|