@pixagram/renderart 0.2.2 → 0.3.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/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 wasmMemory = null;
625
+ var wasmReady = false;
625
626
  var initPromise = null;
626
- var wasmUrl = "";
627
- var cachedUint8Memory = null;
628
- var WASM_VECTOR_LEN = 0;
629
- function getUint8Memory() {
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 response = await fetch(url);
661
- if (!response.ok) {
662
- throw new Error(`Failed to fetch WASM: ${response.status} ${response.statusText}`);
663
- }
664
- const bytes = await response.arrayBuffer();
665
- const imports = {
666
- __wbindgen_placeholder__: {
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('./renderart_wasm.js');
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 new Error(`Failed to initialize WASM: ${e}. Make sure the .wasm file is served at: ${url}`);
649
+ throw initError;
688
650
  }
689
651
  })();
690
652
  return initPromise;
691
653
  }
692
654
  function isWasmLoaded() {
693
- return wasm !== null;
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 (!wasm) {
664
+ if (!wasmReady) {
697
665
  await initWasm();
698
666
  }
699
667
  }
700
- function getOutputData(ptr, len) {
701
- const buffer = getUint8Memory().subarray(ptr, ptr + len);
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.ready = false;
679
+ this.initialized = false;
726
680
  }
727
- /** Create and initialize renderer (auto-loads WASM) */
681
+ /** Create and initialize renderer */
728
682
  static async create() {
729
- await ensureWasm();
730
683
  const renderer = new _CrtCpuRenderer();
731
- renderer.ready = true;
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.ready && isWasmLoaded();
694
+ return this.initialized && wasmReady;
736
695
  }
696
+ /** Render CRT effect */
737
697
  render(input, options = {}) {
738
- if (!this.ready || !wasm) {
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 ptr = passArray8ToWasm(data);
746
- const resultPtr = wasm.crt_upscale_raw(
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 ? 1 : 0,
758
- options.enableScanlines !== false ? 1 : 0,
759
- options.enableMask !== false ? 1 : 0
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(resultPtr, outLen),
766
- width: outWidth,
767
- height: outHeight
720
+ data: getOutputData(result),
721
+ width: result.width,
722
+ height: result.height
768
723
  };
769
724
  }
725
+ /** Dispose resources */
770
726
  dispose() {
771
- this.ready = false;
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.ready = false;
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.ready = true;
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.ready && isWasmLoaded();
762
+ return this.initialized && wasmReady;
786
763
  }
764
+ /** Render hexagonal effect */
787
765
  render(input, options = {}) {
788
- if (!this.ready || !wasm) {
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 orientation = options.orientation === "pointy-top" ? 1 : 0;
796
- const ptr = passArray8ToWasm(data);
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 ? 1 : 0,
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(resultPtr, outLen),
813
- width: dims.width,
814
- height: dims.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
- const SQRT3 = 1.732050808;
819
- scale = Math.min(32, Math.max(2, scale));
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.ready = false;
800
+ this.initialized = false;
842
801
  }
843
802
  };
844
803
  var XbrzCpuRenderer = class _XbrzCpuRenderer {
845
804
  constructor() {
846
- this.ready = false;
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.ready = true;
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.ready && isWasmLoaded();
820
+ return this.initialized && wasmReady;
856
821
  }
822
+ /** Render xBRZ scaling */
857
823
  render(input, options = {}) {
858
- if (!this.ready || !wasm) {
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 ptr = passArray8ToWasm(data);
866
- const resultPtr = wasm.xbrz_upscale_raw(
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(resultPtr, outLen),
882
- width: outWidth,
883
- height: outHeight
842
+ data: getOutputData(result),
843
+ width: result.width,
844
+ height: result.height
884
845
  };
885
846
  }
847
+ /** Dispose resources */
886
848
  dispose() {
887
- this.ready = false;
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(wasmUrl2) {
1083
- await initWasm(wasmUrl2);
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