@pixagram/renderart 0.2.2 → 0.3.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/README.md +148 -71
- package/dist/index.d.mts +36 -24
- package/dist/index.d.ts +36 -24
- package/dist/index.js +118 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +116 -155
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -10
- package/pkg/LICENSE +21 -0
- package/pkg/README.md +223 -0
- package/pkg/renderart_wasm.d.ts +52 -0
- package/pkg/renderart_wasm.js +5 -0
- package/pkg/renderart_wasm_bg.js +283 -0
- package/pkg/renderart_wasm_bg.wasm +0 -0
- package/pkg/renderart_wasm_bg.wasm.d.ts +24 -0
- package/wasm/renderart_wasm.wasm +0 -0
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
3
4
|
// src/crt-gpu.ts
|
|
4
5
|
var VERTEX_SHADER = `#version 300 es
|
|
5
6
|
layout(location = 0) in vec2 position;
|
|
@@ -621,131 +622,88 @@ var HEX_PRESETS = {
|
|
|
621
622
|
|
|
622
623
|
// src/wasm-loader.ts
|
|
623
624
|
var wasm = null;
|
|
624
|
-
var
|
|
625
|
+
var wasmReady = false;
|
|
625
626
|
var initPromise = null;
|
|
626
|
-
var
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
if (cachedUint8Memory === null || cachedUint8Memory.byteLength === 0) {
|
|
631
|
-
cachedUint8Memory = new Uint8Array(wasmMemory.buffer);
|
|
632
|
-
}
|
|
633
|
-
return cachedUint8Memory;
|
|
634
|
-
}
|
|
635
|
-
function passArray8ToWasm(arg) {
|
|
636
|
-
const ptr = wasm.__wbindgen_malloc(arg.length);
|
|
637
|
-
getUint8Memory().set(arg, ptr);
|
|
638
|
-
WASM_VECTOR_LEN = arg.length;
|
|
639
|
-
return ptr;
|
|
640
|
-
}
|
|
641
|
-
function setWasmUrl(url) {
|
|
642
|
-
wasmUrl = url;
|
|
643
|
-
}
|
|
644
|
-
function getDefaultWasmUrl() {
|
|
645
|
-
if (wasmUrl) return wasmUrl;
|
|
646
|
-
const paths = [
|
|
647
|
-
"/renderart_wasm_bg.wasm",
|
|
648
|
-
"/wasm/renderart_wasm_bg.wasm",
|
|
649
|
-
"/static/wasm/renderart_wasm_bg.wasm",
|
|
650
|
-
"/assets/wasm/renderart_wasm_bg.wasm"
|
|
651
|
-
];
|
|
652
|
-
return paths[0];
|
|
653
|
-
}
|
|
654
|
-
async function initWasm(customUrl) {
|
|
655
|
-
if (wasm) return;
|
|
627
|
+
var initError = null;
|
|
628
|
+
async function initWasm(wasmUrl) {
|
|
629
|
+
if (wasmReady) return;
|
|
630
|
+
if (initError) throw initError;
|
|
656
631
|
if (initPromise) return initPromise;
|
|
657
|
-
const url = customUrl || getDefaultWasmUrl();
|
|
658
632
|
initPromise = (async () => {
|
|
659
633
|
try {
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
__wbindgen_throw: (ptr, len) => {
|
|
668
|
-
const msg = new TextDecoder().decode(getUint8Memory().subarray(ptr, ptr + len));
|
|
669
|
-
throw new Error(msg);
|
|
670
|
-
}
|
|
671
|
-
},
|
|
672
|
-
wbg: {
|
|
673
|
-
__wbindgen_throw: (ptr, len) => {
|
|
674
|
-
const msg = new TextDecoder().decode(getUint8Memory().subarray(ptr, ptr + len));
|
|
675
|
-
throw new Error(msg);
|
|
676
|
-
}
|
|
634
|
+
const wasmModule = await import('../pkg/renderart_wasm');
|
|
635
|
+
let url = wasmUrl;
|
|
636
|
+
if (!url) {
|
|
637
|
+
try {
|
|
638
|
+
url = new URL("./renderart_wasm_bg.wasm", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href))).href;
|
|
639
|
+
} catch {
|
|
640
|
+
url = "renderart_wasm_bg.wasm";
|
|
677
641
|
}
|
|
678
|
-
};
|
|
679
|
-
const { instance } = await WebAssembly.instantiate(bytes, imports);
|
|
680
|
-
wasm = instance.exports;
|
|
681
|
-
wasmMemory = wasm.memory;
|
|
682
|
-
if (wasm.__wbindgen_start) {
|
|
683
|
-
wasm.__wbindgen_start();
|
|
684
642
|
}
|
|
643
|
+
await wasmModule.default(url);
|
|
644
|
+
wasm = wasmModule;
|
|
645
|
+
wasmReady = true;
|
|
685
646
|
} catch (e) {
|
|
647
|
+
initError = new Error(`Failed to initialize WASM: ${e}`);
|
|
686
648
|
initPromise = null;
|
|
687
|
-
throw
|
|
649
|
+
throw initError;
|
|
688
650
|
}
|
|
689
651
|
})();
|
|
690
652
|
return initPromise;
|
|
691
653
|
}
|
|
692
654
|
function isWasmLoaded() {
|
|
693
|
-
return
|
|
655
|
+
return wasmReady;
|
|
656
|
+
}
|
|
657
|
+
function hasWasmError() {
|
|
658
|
+
return initError !== null;
|
|
659
|
+
}
|
|
660
|
+
function getWasmError() {
|
|
661
|
+
return initError;
|
|
694
662
|
}
|
|
695
663
|
async function ensureWasm() {
|
|
696
|
-
if (!
|
|
664
|
+
if (!wasmReady) {
|
|
697
665
|
await initWasm();
|
|
698
666
|
}
|
|
699
667
|
}
|
|
700
|
-
function getOutputData(
|
|
701
|
-
const
|
|
668
|
+
function getOutputData(result) {
|
|
669
|
+
const memory = wasm.get_memory();
|
|
670
|
+
const buffer = new Uint8Array(memory.buffer, result.ptr, result.len);
|
|
702
671
|
return new Uint8ClampedArray(buffer.slice());
|
|
703
672
|
}
|
|
704
673
|
function toUint8Array(input) {
|
|
705
674
|
const data = input instanceof ImageData ? input.data : input.data;
|
|
706
675
|
return data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
707
676
|
}
|
|
708
|
-
function parseColorToU32(color, defaultVal) {
|
|
709
|
-
if (color === void 0) return defaultVal;
|
|
710
|
-
if (typeof color === "number") return color;
|
|
711
|
-
if (color === "transparent") return 0;
|
|
712
|
-
if (color.startsWith("#")) {
|
|
713
|
-
const hex = color.slice(1);
|
|
714
|
-
if (hex.length === 6) {
|
|
715
|
-
return parseInt(hex, 16) << 8 | 255;
|
|
716
|
-
}
|
|
717
|
-
if (hex.length === 8) {
|
|
718
|
-
return parseInt(hex, 16);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
return defaultVal;
|
|
722
|
-
}
|
|
723
677
|
var CrtCpuRenderer = class _CrtCpuRenderer {
|
|
724
678
|
constructor() {
|
|
725
|
-
this.
|
|
679
|
+
this.initialized = false;
|
|
726
680
|
}
|
|
727
|
-
/** Create and initialize renderer
|
|
681
|
+
/** Create and initialize renderer */
|
|
728
682
|
static async create() {
|
|
729
|
-
await ensureWasm();
|
|
730
683
|
const renderer = new _CrtCpuRenderer();
|
|
731
|
-
renderer.
|
|
684
|
+
await renderer.init();
|
|
732
685
|
return renderer;
|
|
733
686
|
}
|
|
687
|
+
/** Initialize (loads WASM if needed) */
|
|
688
|
+
async init() {
|
|
689
|
+
await ensureWasm();
|
|
690
|
+
this.initialized = true;
|
|
691
|
+
}
|
|
692
|
+
/** Check if renderer is ready */
|
|
734
693
|
isReady() {
|
|
735
|
-
return this.
|
|
694
|
+
return this.initialized && wasmReady;
|
|
736
695
|
}
|
|
696
|
+
/** Render CRT effect */
|
|
737
697
|
render(input, options = {}) {
|
|
738
|
-
if (!this.
|
|
739
|
-
throw new Error("Renderer not initialized");
|
|
698
|
+
if (!this.initialized || !wasm) {
|
|
699
|
+
throw new Error("Renderer not initialized. Call init() first or use CrtCpuRenderer.create()");
|
|
740
700
|
}
|
|
741
701
|
const data = toUint8Array(input);
|
|
742
702
|
const width = input.width;
|
|
743
703
|
const height = input.height;
|
|
744
704
|
const scale = Math.min(32, Math.max(2, options.scale ?? 3));
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
ptr,
|
|
748
|
-
WASM_VECTOR_LEN,
|
|
705
|
+
const result = wasm.crt_upscale_config(
|
|
706
|
+
data,
|
|
749
707
|
width,
|
|
750
708
|
height,
|
|
751
709
|
scale,
|
|
@@ -754,118 +712,124 @@ var CrtCpuRenderer = class _CrtCpuRenderer {
|
|
|
754
712
|
options.scanHardness ?? -4,
|
|
755
713
|
options.scanOpacity ?? 0.5,
|
|
756
714
|
options.maskOpacity ?? 0.3,
|
|
757
|
-
options.enableWarp !== false
|
|
758
|
-
options.enableScanlines !== false
|
|
759
|
-
options.enableMask !== false
|
|
715
|
+
options.enableWarp !== false,
|
|
716
|
+
options.enableScanlines !== false,
|
|
717
|
+
options.enableMask !== false
|
|
760
718
|
);
|
|
761
|
-
const outWidth = width * scale;
|
|
762
|
-
const outHeight = height * scale;
|
|
763
|
-
const outLen = outWidth * outHeight * 4;
|
|
764
719
|
return {
|
|
765
|
-
data: getOutputData(
|
|
766
|
-
width:
|
|
767
|
-
height:
|
|
720
|
+
data: getOutputData(result),
|
|
721
|
+
width: result.width,
|
|
722
|
+
height: result.height
|
|
768
723
|
};
|
|
769
724
|
}
|
|
725
|
+
/** Dispose resources */
|
|
770
726
|
dispose() {
|
|
771
|
-
this.
|
|
727
|
+
this.initialized = false;
|
|
772
728
|
}
|
|
773
729
|
};
|
|
730
|
+
function parseColorToU32(color, defaultVal) {
|
|
731
|
+
if (color === void 0) return defaultVal;
|
|
732
|
+
if (typeof color === "number") return color;
|
|
733
|
+
if (color === "transparent") return 0;
|
|
734
|
+
if (color.startsWith("#")) {
|
|
735
|
+
const hex = color.slice(1);
|
|
736
|
+
if (hex.length === 6) {
|
|
737
|
+
return parseInt(hex, 16) << 8 | 255;
|
|
738
|
+
}
|
|
739
|
+
if (hex.length === 8) {
|
|
740
|
+
return parseInt(hex, 16);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return defaultVal;
|
|
744
|
+
}
|
|
774
745
|
var HexCpuRenderer = class _HexCpuRenderer {
|
|
775
746
|
constructor() {
|
|
776
|
-
this.
|
|
747
|
+
this.initialized = false;
|
|
777
748
|
}
|
|
749
|
+
/** Create and initialize renderer */
|
|
778
750
|
static async create() {
|
|
779
|
-
await ensureWasm();
|
|
780
751
|
const renderer = new _HexCpuRenderer();
|
|
781
|
-
renderer.
|
|
752
|
+
await renderer.init();
|
|
782
753
|
return renderer;
|
|
783
754
|
}
|
|
755
|
+
/** Initialize (loads WASM if needed) */
|
|
756
|
+
async init() {
|
|
757
|
+
await ensureWasm();
|
|
758
|
+
this.initialized = true;
|
|
759
|
+
}
|
|
760
|
+
/** Check if renderer is ready */
|
|
784
761
|
isReady() {
|
|
785
|
-
return this.
|
|
762
|
+
return this.initialized && wasmReady;
|
|
786
763
|
}
|
|
764
|
+
/** Render hexagonal effect */
|
|
787
765
|
render(input, options = {}) {
|
|
788
|
-
if (!this.
|
|
789
|
-
throw new Error("Renderer not initialized");
|
|
766
|
+
if (!this.initialized || !wasm) {
|
|
767
|
+
throw new Error("Renderer not initialized. Call init() first or use HexCpuRenderer.create()");
|
|
790
768
|
}
|
|
791
769
|
const data = toUint8Array(input);
|
|
792
770
|
const width = input.width;
|
|
793
771
|
const height = input.height;
|
|
794
772
|
const scale = Math.min(32, Math.max(2, options.scale ?? 16));
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
const resultPtr = wasm.hex_upscale_raw(
|
|
798
|
-
ptr,
|
|
799
|
-
WASM_VECTOR_LEN,
|
|
773
|
+
const result = wasm.hex_upscale_config(
|
|
774
|
+
data,
|
|
800
775
|
width,
|
|
801
776
|
height,
|
|
802
777
|
scale,
|
|
803
|
-
orientation,
|
|
804
|
-
options.drawBorders
|
|
778
|
+
options.orientation === "pointy-top" ? 1 : 0,
|
|
779
|
+
options.drawBorders ?? false,
|
|
805
780
|
parseColorToU32(options.borderColor, 673720575),
|
|
806
781
|
options.borderThickness ?? 1,
|
|
807
782
|
parseColorToU32(options.backgroundColor, 0)
|
|
808
783
|
);
|
|
809
|
-
const dims = this.getDimensions(width, height, scale, options.orientation);
|
|
810
|
-
const outLen = dims.width * dims.height * 4;
|
|
811
784
|
return {
|
|
812
|
-
data: getOutputData(
|
|
813
|
-
width:
|
|
814
|
-
height:
|
|
785
|
+
data: getOutputData(result),
|
|
786
|
+
width: result.width,
|
|
787
|
+
height: result.height
|
|
815
788
|
};
|
|
816
789
|
}
|
|
790
|
+
/** Get output dimensions */
|
|
817
791
|
getDimensions(srcWidth, srcHeight, scale, orientation = "flat-top") {
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
if (orientation === "flat-top") {
|
|
821
|
-
const hSpacing = scale * 1.5;
|
|
822
|
-
const vSpacing = scale * SQRT3;
|
|
823
|
-
const cellWidth = scale * 2;
|
|
824
|
-
const cellHeight = scale * SQRT3;
|
|
825
|
-
return {
|
|
826
|
-
width: Math.ceil(srcWidth * hSpacing + cellWidth),
|
|
827
|
-
height: Math.ceil(srcHeight * vSpacing + cellHeight)
|
|
828
|
-
};
|
|
829
|
-
} else {
|
|
830
|
-
const hSpacing = scale * SQRT3;
|
|
831
|
-
const vSpacing = scale * 1.5;
|
|
832
|
-
const cellWidth = scale * SQRT3;
|
|
833
|
-
const cellHeight = scale * 2;
|
|
834
|
-
return {
|
|
835
|
-
width: Math.ceil(srcWidth * hSpacing + cellWidth),
|
|
836
|
-
height: Math.ceil(srcHeight * vSpacing + cellHeight)
|
|
837
|
-
};
|
|
792
|
+
if (!this.initialized || !wasm) {
|
|
793
|
+
throw new Error("Renderer not initialized");
|
|
838
794
|
}
|
|
795
|
+
const dims = wasm.hex_get_dimensions(srcWidth, srcHeight, scale, orientation === "pointy-top" ? 1 : 0);
|
|
796
|
+
return { width: dims[0], height: dims[1] };
|
|
839
797
|
}
|
|
798
|
+
/** Dispose resources */
|
|
840
799
|
dispose() {
|
|
841
|
-
this.
|
|
800
|
+
this.initialized = false;
|
|
842
801
|
}
|
|
843
802
|
};
|
|
844
803
|
var XbrzCpuRenderer = class _XbrzCpuRenderer {
|
|
845
804
|
constructor() {
|
|
846
|
-
this.
|
|
805
|
+
this.initialized = false;
|
|
847
806
|
}
|
|
807
|
+
/** Create and initialize renderer */
|
|
848
808
|
static async create() {
|
|
849
|
-
await ensureWasm();
|
|
850
809
|
const renderer = new _XbrzCpuRenderer();
|
|
851
|
-
renderer.
|
|
810
|
+
await renderer.init();
|
|
852
811
|
return renderer;
|
|
853
812
|
}
|
|
813
|
+
/** Initialize (loads WASM if needed) */
|
|
814
|
+
async init() {
|
|
815
|
+
await ensureWasm();
|
|
816
|
+
this.initialized = true;
|
|
817
|
+
}
|
|
818
|
+
/** Check if renderer is ready */
|
|
854
819
|
isReady() {
|
|
855
|
-
return this.
|
|
820
|
+
return this.initialized && wasmReady;
|
|
856
821
|
}
|
|
822
|
+
/** Render xBRZ scaling */
|
|
857
823
|
render(input, options = {}) {
|
|
858
|
-
if (!this.
|
|
859
|
-
throw new Error("Renderer not initialized");
|
|
824
|
+
if (!this.initialized || !wasm) {
|
|
825
|
+
throw new Error("Renderer not initialized. Call init() first or use XbrzCpuRenderer.create()");
|
|
860
826
|
}
|
|
861
827
|
const data = toUint8Array(input);
|
|
862
828
|
const width = input.width;
|
|
863
829
|
const height = input.height;
|
|
864
830
|
const scale = Math.min(6, Math.max(2, options.scale ?? 2));
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
ptr,
|
|
868
|
-
WASM_VECTOR_LEN,
|
|
831
|
+
const result = wasm.xbrz_upscale_config(
|
|
832
|
+
data,
|
|
869
833
|
width,
|
|
870
834
|
height,
|
|
871
835
|
scale,
|
|
@@ -874,17 +838,15 @@ var XbrzCpuRenderer = class _XbrzCpuRenderer {
|
|
|
874
838
|
options.dominantDirectionThreshold ?? 4.4,
|
|
875
839
|
options.steepDirectionThreshold ?? 2.2
|
|
876
840
|
);
|
|
877
|
-
const outWidth = width * scale;
|
|
878
|
-
const outHeight = height * scale;
|
|
879
|
-
const outLen = outWidth * outHeight * 4;
|
|
880
841
|
return {
|
|
881
|
-
data: getOutputData(
|
|
882
|
-
width:
|
|
883
|
-
height:
|
|
842
|
+
data: getOutputData(result),
|
|
843
|
+
width: result.width,
|
|
844
|
+
height: result.height
|
|
884
845
|
};
|
|
885
846
|
}
|
|
847
|
+
/** Dispose resources */
|
|
886
848
|
dispose() {
|
|
887
|
-
this.
|
|
849
|
+
this.initialized = false;
|
|
888
850
|
}
|
|
889
851
|
};
|
|
890
852
|
var XBRZ_PRESETS = {
|
|
@@ -1079,8 +1041,8 @@ var RenderArt = class _RenderArt {
|
|
|
1079
1041
|
return new _RenderArt(true);
|
|
1080
1042
|
}
|
|
1081
1043
|
/** Pre-initialize WASM for faster first CPU render */
|
|
1082
|
-
async preloadWasm(
|
|
1083
|
-
await initWasm(
|
|
1044
|
+
async preloadWasm(wasmUrl) {
|
|
1045
|
+
await initWasm(wasmUrl);
|
|
1084
1046
|
}
|
|
1085
1047
|
get capabilities() {
|
|
1086
1048
|
return { ...this._capabilities };
|
|
@@ -1104,9 +1066,10 @@ exports.RenderArt = RenderArt;
|
|
|
1104
1066
|
exports.XBRZ_PRESETS = XBRZ_PRESETS;
|
|
1105
1067
|
exports.XbrzCpuRenderer = XbrzCpuRenderer;
|
|
1106
1068
|
exports.XbrzEngine = XbrzEngine;
|
|
1069
|
+
exports.getWasmError = getWasmError;
|
|
1070
|
+
exports.hasWasmError = hasWasmError;
|
|
1107
1071
|
exports.hexGetDimensions = hexGetDimensions;
|
|
1108
1072
|
exports.initWasm = initWasm;
|
|
1109
1073
|
exports.isWasmLoaded = isWasmLoaded;
|
|
1110
|
-
exports.setWasmUrl = setWasmUrl;
|
|
1111
1074
|
//# sourceMappingURL=index.js.map
|
|
1112
1075
|
//# sourceMappingURL=index.js.map
|