@alexislours/ltd-textures 1.0.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.
- package/LICENSE +661 -0
- package/README.md +55 -0
- package/build/ugc.wasm +0 -0
- package/dist/bridge.d.ts +24 -0
- package/dist/browser.d.ts +6 -0
- package/dist/browser.js +16 -0
- package/dist/browser.js.map +1 -0
- package/dist/chunk-Q7WR2GWO.js +446 -0
- package/dist/chunk-Q7WR2GWO.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/threadPool.d.ts +15 -0
- package/dist/types.d.ts +18 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +72 -0
- package/dist/worker.js.map +1 -0
- package/package.json +64 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const Bc1Mode: {
|
|
2
|
+
readonly Auto: 0;
|
|
3
|
+
readonly FourColor: 1;
|
|
4
|
+
readonly ThreeColor: 2;
|
|
5
|
+
};
|
|
6
|
+
export type Bc1Mode = (typeof Bc1Mode)[keyof typeof Bc1Mode];
|
|
7
|
+
export declare const FitMode: {
|
|
8
|
+
readonly Fill: 0;
|
|
9
|
+
readonly Contain: 1;
|
|
10
|
+
readonly Cover: 2;
|
|
11
|
+
};
|
|
12
|
+
export type FitMode = (typeof FitMode)[keyof typeof FitMode];
|
|
13
|
+
export type Matte = {
|
|
14
|
+
r: number;
|
|
15
|
+
g: number;
|
|
16
|
+
b: number;
|
|
17
|
+
a: number;
|
|
18
|
+
};
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/worker.ts
|
|
2
|
+
var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null && typeof self === "undefined";
|
|
3
|
+
var listen;
|
|
4
|
+
var post;
|
|
5
|
+
if (isNode) {
|
|
6
|
+
const wt = await import(
|
|
7
|
+
/* @vite-ignore */
|
|
8
|
+
"worker_threads"
|
|
9
|
+
);
|
|
10
|
+
const port = wt.parentPort;
|
|
11
|
+
if (!port) throw new Error("worker has no parentPort");
|
|
12
|
+
listen = (cb) => port.on("message", cb);
|
|
13
|
+
post = (msg, transfer) => port.postMessage(msg, transfer ?? []);
|
|
14
|
+
} else {
|
|
15
|
+
const scope = self;
|
|
16
|
+
listen = (cb) => {
|
|
17
|
+
scope.onmessage = (e) => cb(e.data);
|
|
18
|
+
};
|
|
19
|
+
post = (msg, transfer) => scope.postMessage(msg, transfer ?? []);
|
|
20
|
+
}
|
|
21
|
+
var importObject = {
|
|
22
|
+
env: {
|
|
23
|
+
abort() {
|
|
24
|
+
throw new Error("ugc.wasm aborted in worker");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var wasmExports = null;
|
|
29
|
+
listen((msg) => {
|
|
30
|
+
handle(msg).catch((err) => {
|
|
31
|
+
const id = msg && msg.id;
|
|
32
|
+
post({ type: "error", id, error: String(err) });
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
async function handle(msg) {
|
|
36
|
+
if (msg.type === "init") {
|
|
37
|
+
const result = await WebAssembly.instantiate(msg.wasmBytes, importObject);
|
|
38
|
+
wasmExports = result.instance.exports;
|
|
39
|
+
post({ type: "ready" });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (msg.type === "encode") {
|
|
43
|
+
const exp = wasmExports;
|
|
44
|
+
if (!exp) throw new Error("worker not initialized");
|
|
45
|
+
const { id, op, linF, srgbU, w, h, mode } = msg;
|
|
46
|
+
const pixels = w * h;
|
|
47
|
+
const linLen = pixels * 16;
|
|
48
|
+
const srgbLen = pixels * 4;
|
|
49
|
+
const outLen = op === "bc1" ? pixels / 16 * 8 : pixels / 16 * 16;
|
|
50
|
+
const m = exp.mark();
|
|
51
|
+
let outAB;
|
|
52
|
+
try {
|
|
53
|
+
const linPtr = exp.alloc(linLen);
|
|
54
|
+
const srgbPtr = exp.alloc(srgbLen);
|
|
55
|
+
const outPtr = exp.alloc(outLen);
|
|
56
|
+
const memBuf = exp.memory.buffer;
|
|
57
|
+
new Float32Array(memBuf, linPtr, pixels * 4).set(linF);
|
|
58
|
+
new Uint8Array(memBuf, srgbPtr, srgbLen).set(srgbU);
|
|
59
|
+
if (op === "bc1") {
|
|
60
|
+
exp.bc1Encode(linPtr, srgbPtr, outPtr, w, h, mode);
|
|
61
|
+
} else {
|
|
62
|
+
exp.bc3Encode(linPtr, srgbPtr, outPtr, w, h);
|
|
63
|
+
}
|
|
64
|
+
outAB = new ArrayBuffer(outLen);
|
|
65
|
+
new Uint8Array(outAB).set(new Uint8Array(memBuf, outPtr, outLen));
|
|
66
|
+
} finally {
|
|
67
|
+
exp.release(m);
|
|
68
|
+
}
|
|
69
|
+
post({ type: "done", id, blocks: outAB }, [outAB]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/worker.ts"],"sourcesContent":["export {};\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":";AA0CA,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
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alexislours/ltd-textures",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Tegra/Switch block-linear (de)swizzle, BC1/BC3 transcode, sRGB/linear conversion, and image resize, in WebAssembly.",
|
|
5
|
+
"license": "AGPL-3.0-or-later",
|
|
6
|
+
"author": "Alexis Lours",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"keywords": [
|
|
10
|
+
"wasm",
|
|
11
|
+
"tegra",
|
|
12
|
+
"switch",
|
|
13
|
+
"texture",
|
|
14
|
+
"bcn",
|
|
15
|
+
"bc1",
|
|
16
|
+
"bc3",
|
|
17
|
+
"dxt",
|
|
18
|
+
"swizzle",
|
|
19
|
+
"block-linear"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/alexislours/ltd-save-editor.git",
|
|
24
|
+
"directory": "packages/ltd-textures"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/alexislours/ltd-save-editor/tree/dev/packages/ltd-textures#readme",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./browser": {
|
|
33
|
+
"types": "./dist/browser.d.ts",
|
|
34
|
+
"import": "./dist/browser.js"
|
|
35
|
+
},
|
|
36
|
+
"./worker": {
|
|
37
|
+
"types": "./dist/worker.d.ts",
|
|
38
|
+
"import": "./dist/worker.js"
|
|
39
|
+
},
|
|
40
|
+
"./ugc.wasm": "./build/ugc.wasm"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"build/ugc.wasm"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build:wasm": "asc assembly/index.ts --config asconfig.json --target release",
|
|
48
|
+
"build:wasm:debug": "asc assembly/index.ts --config asconfig.json --target debug",
|
|
49
|
+
"build": "npm run build:wasm && tsup && tsc -p tsconfig.build.json",
|
|
50
|
+
"check": "tsc -p tsconfig.json",
|
|
51
|
+
"lint:pkg": "publint --strict && attw --pack --profile esm-only --exclude-entrypoints ugc.wasm",
|
|
52
|
+
"prepublishOnly": "npm run build"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@arethetypeswrong/cli": "^0.18.3",
|
|
56
|
+
"@types/node": "^24.12.3",
|
|
57
|
+
"assemblyscript": "^0.28.17",
|
|
58
|
+
"publint": "^0.3.21",
|
|
59
|
+
"tsup": "^8.5.0"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
}
|
|
64
|
+
}
|