Skip to content

Commit bba115f

Browse files
committed
refactor: import wasm directly
1 parent 69c6b55 commit bba115f

File tree

12 files changed

+155
-324
lines changed

12 files changed

+155
-324
lines changed

ImageScript.d.ts

Lines changed: 0 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -344,15 +344,6 @@ export class Image {
344344
*/
345345
async encodeJPEG(quality?: JPEGQuality): Promise<Uint8Array>;
346346

347-
/**
348-
* Encodes the image into a WEBP.
349-
*
350-
* @param quality `0`-`100`, or `null` for lossless. `0` is lowest quality
351-
* (highest compression) and `100` is highest quality (lowest compression).
352-
* Default: `null`
353-
*/
354-
async encodeWEBP(quality?: null | WEBPQuality): Promise<Uint8Array>;
355-
356347
/**
357348
* Decodes an image (PNG, JPEG or TIFF).
358349
*
@@ -634,113 +625,6 @@ export type PNGCompressionLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
634625
*/
635626
export type SVGScaleMode = 1 | 2 | 3;
636627

637-
/**
638-
* - `0` = **lowest** quality (smallest file size)
639-
* - `100` = **highest** quality (largest file size)
640-
*/
641-
export type WEBPQuality =
642-
| 0
643-
| 1
644-
| 2
645-
| 3
646-
| 4
647-
| 5
648-
| 6
649-
| 7
650-
| 8
651-
| 9
652-
| 10
653-
| 11
654-
| 12
655-
| 13
656-
| 14
657-
| 15
658-
| 16
659-
| 17
660-
| 18
661-
| 19
662-
| 20
663-
| 21
664-
| 22
665-
| 23
666-
| 24
667-
| 25
668-
| 26
669-
| 27
670-
| 28
671-
| 29
672-
| 30
673-
| 31
674-
| 32
675-
| 33
676-
| 34
677-
| 35
678-
| 36
679-
| 37
680-
| 38
681-
| 39
682-
| 40
683-
| 41
684-
| 42
685-
| 43
686-
| 44
687-
| 45
688-
| 46
689-
| 47
690-
| 48
691-
| 49
692-
| 50
693-
| 51
694-
| 52
695-
| 53
696-
| 54
697-
| 55
698-
| 56
699-
| 57
700-
| 58
701-
| 59
702-
| 60
703-
| 61
704-
| 62
705-
| 63
706-
| 64
707-
| 65
708-
| 66
709-
| 67
710-
| 68
711-
| 69
712-
| 70
713-
| 71
714-
| 72
715-
| 73
716-
| 74
717-
| 75
718-
| 76
719-
| 77
720-
| 78
721-
| 79
722-
| 80
723-
| 81
724-
| 82
725-
| 83
726-
| 84
727-
| 85
728-
| 86
729-
| 87
730-
| 88
731-
| 89
732-
| 90
733-
| 91
734-
| 92
735-
| 93
736-
| 94
737-
| 95
738-
| 96
739-
| 97
740-
| 98
741-
| 99
742-
| 100;
743-
744628
/**
745629
* - `0` = **lowest** quality (smallest file size)
746630
* - `100` = **highest** quality (largest file size)

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# ImageScript
22
##### zero-dependency JavaScript image manipulation
3-
[![Discord Server](https://img.shields.io/discord/691713541262147687.svg?label=Discord&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2&style=for-the-badge)](https://discord.gg/8hPrwAH)
3+
![NPM Version](https://img.shields.io/npm/v/imagescript?style=for-the-badge&label=NPM%20(Node.JS))
4+
![JSR Version](https://img.shields.io/jsr/v/%40matmen/imagescript?style=for-the-badge&label=JSR%20(Deno))
45
[![Documentation](https://img.shields.io/badge/Documentation-informational?style=for-the-badge)](https://imagescript.matmen.dev/)
56
[![Github](https://img.shields.io/badge/Github-Repository-181717?logo=github&style=for-the-badge)](https://github.com/matmen/ImageScript)
6-
[![deno.land](https://shields.io/badge/deno.land-gray?logo=deno&style=for-the-badge)](https://deno.land/x/imagescript@1.2.9)
7-
[![NPM](https://nodei.co/npm/imagescript.png)](https://www.npmjs.com/package/imagescript)
7+
[![Discord Server](https://img.shields.io/discord/691713541262147687.svg?label=Discord&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2&style=for-the-badge)](https://discord.gg/8hPrwAH)
88

99
---
1010

@@ -38,8 +38,16 @@ binaries for decoding and encoding.
3838

3939
### Example
4040

41-
[![Example](https://github.com/matmen/ImageScript/raw/master/tests/targets/readme.png)](https://github.com/matmen/ImageScript/blob/master/tests/readme.js)
41+
```js
42+
import {Image} from "jsr:@matmen/imagescript";
43+
44+
const input = await Deno.readFile('./image.png');
45+
const image = await Image.decode(input);
46+
image.rotate(180);
4247

48+
const output = await image.encode();
49+
await Deno.writeFile('./output.png', output);
50+
```
4351
---
4452

4553
If you have any additional questions, feel free to join the [discord support server](https://discord.gg/8hPrwAH).

deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"version": "1.3.1",
44
"exports": "./mod.ts",
55
"imports": {
6-
"@std/bytes": "jsr:@std/bytes@^1.0.0"
6+
"@std/bytes": "jsr:@std/bytes@^1.0.0",
7+
"env": "./utils/wasm/env.js"
78
},
89
"publish": {
910
"exclude": ["tests/"]

example.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {Image} from "jsr:@matmen/imagescript";
2+
3+
const input = await Deno.readFile('./tests/targets/readme.png');
4+
const image = await Image.decode(input);
5+
image.rotate(180);
6+
7+
const output = await image.encode();
8+
await Deno.writeFile('./output.png', output);

utils/wasm/env.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const streams = new Map;
2+
3+
export function emscripten_notify_memory_growth(...args) { console.log(...args) }
4+
export function push_to_stream(id, ptr) {
5+
const mem = streams.get(id).m;
6+
streams.get(id).cb(mem.u8(ptr, mem.length()).slice());
7+
}

utils/wasm/font.js

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,17 @@
1-
let registry;
2-
let wasm_mod;
3-
let ref = { deref() {} };
4-
5-
{
6-
const path = new URL(import.meta.url.replace('.js', '.wasm'));
7-
wasm_mod = new WebAssembly.Module(await ('file:' === path.protocol ? Deno.readFile(path) : fetch(path).then(r => r.arrayBuffer())));
8-
}
1+
import * as wasm from './font.wasm';
92

10-
function wasm() {
11-
return ref.deref() || (ref = new WeakRef(new WebAssembly.Instance(wasm_mod).exports)).deref();
12-
}
3+
let registry;
134

145
class mem {
15-
static length() { return wasm().wlen(); }
16-
static alloc(size) { return wasm().walloc(size); }
17-
static free(ptr, size) { return wasm().wfree(ptr, size); }
18-
static u8(ptr, size) { return new Uint8Array(wasm().memory.buffer, ptr, size); }
19-
static u32(ptr, size) { return new Uint32Array(wasm().memory.buffer, ptr, size); }
6+
static length() { return wasm.wlen(); }
7+
static alloc(size) { return wasm.walloc(size); }
8+
static free(ptr, size) { return wasm.wfree(ptr, size); }
9+
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
10+
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
2011

2112
static copy_and_free(ptr, size) {
2213
let slice = mem.u8(ptr, size).slice();
23-
return (wasm().wfree(ptr, size), slice);
14+
return (wasm.wfree(ptr, size), slice);
2415
}
2516
}
2617

@@ -30,71 +21,71 @@ const encode_utf8 = globalThis.Deno?.core?.encode ?? globalThis.Buffer?.from.bin
3021
if ('FinalizationRegistry' in globalThis) {
3122
registry = new FinalizationRegistry(([t, ptr]) => {
3223
if (!ref.deref()) return;
33-
if (t === 0) wasm().font_free(ptr);
34-
if (t === 1) wasm().layout_free(ptr);
24+
if (t === 0) wasm.font_free(ptr);
25+
if (t === 1) wasm.layout_free(ptr);
3526
});
3627
}
3728

3829
export class Font {
3930
constructor(scale, buffer) {
40-
this._w = wasm();
31+
this._w = wasm;
4132
this.scale = scale;
4233
const ptr = mem.alloc(buffer.length);
4334
mem.u8(ptr, buffer.length).set(buffer);
44-
this.ptr = wasm().font_new(ptr, buffer.length, scale);
35+
this.ptr = wasm.font_new(ptr, buffer.length, scale);
4536

4637
if (!this.ptr) throw new Error('invalid font');
4738
if (registry) registry.register(this, [0, this.ptr], this);
4839
}
4940

5041
free() {
51-
this.ptr = wasm().font_free(this.ptr);
42+
this.ptr = wasm.font_free(this.ptr);
5243
if (registry) registry.unregister(this);
5344
}
5445

5546
has(char) {
56-
return wasm().font_has(this.ptr, String.prototype.charCodeAt.call(char, 0));
47+
return wasm.font_has(this.ptr, String.prototype.charCodeAt.call(char, 0));
5748
}
5849

5950
metrics(char, scale = this.scale) {
60-
const ptr = wasm().font_metrics(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
61-
const metrics = JSON.parse(decode_utf8(mem.u8(wasm().font_metrics_buffer(ptr), mem.length())));
51+
const ptr = wasm.font_metrics(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
52+
const metrics = JSON.parse(decode_utf8(mem.u8(wasm.font_metrics_buffer(ptr), mem.length())));
6253

63-
return (wasm().font_metrics_free(ptr), metrics);
54+
return (wasm.font_metrics_free(ptr), metrics);
6455
}
6556

6657
rasterize(char, scale = this.scale) {
67-
const ptr = wasm().font_rasterize(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
58+
const ptr = wasm.font_rasterize(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
6859

6960
const glyph = {
70-
buffer: mem.u8(wasm().font_rasterize_buffer(ptr), mem.length()).slice(),
71-
metrics: JSON.parse(decode_utf8(mem.u8(wasm().font_rasterize_metrics(ptr), mem.length()))),
61+
buffer: mem.u8(wasm.font_rasterize_buffer(ptr), mem.length()).slice(),
62+
metrics: JSON.parse(decode_utf8(mem.u8(wasm.font_rasterize_metrics(ptr), mem.length()))),
7263
}
7364

74-
return (wasm().font_rasterize_free(ptr), glyph);
65+
return (wasm.font_rasterize_free(ptr), glyph);
7566
}
7667
}
7768

7869
export class Layout {
7970
constructor() {
80-
this._w = wasm();
71+
this._w = wasm;
8172
if (registry) this.refs = [];
82-
this.ptr = wasm().layout_new();
73+
this.ptr = wasm.layout_new();
8374
if (registry) registry.register(this, [1, this.ptr], this);
8475
}
8576

8677
clear() {
87-
wasm().layout_clear(this.ptr);
78+
wasm.layout_clear(this.ptr);
8879
if (registry) this.refs.length = 0;
8980
}
9081

9182
lines() {
92-
return wasm().layout_lines(this.ptr);
83+
return wasm.layout_lines(this.ptr);
9384
}
9485

9586
free() {
9687
if (registry) this.refs.length = 0;
97-
this.ptr = wasm().layout_free(this.ptr);
88+
this.ptr = wasm.layout_free(this.ptr);
9889
if (registry) registry.unregister(this);
9990
}
10091

@@ -104,7 +95,7 @@ export class Layout {
10495
if (registry) this.refs.length = 0;
10596
const ptr = mem.alloc(options.length);
10697
mem.u8(ptr, options.length).set(options);
107-
wasm().layout_reset(this.ptr, ptr, options.length);
98+
wasm.layout_reset(this.ptr, ptr, options.length);
10899
}
109100

110101
append(font, text, init) {
@@ -114,18 +105,18 @@ export class Layout {
114105
const ptr = mem.alloc(text.length);
115106
mem.u8(ptr, text.length).set(text);
116107
const has_color = ('r' in options) || ('g' in options) || ('b' in options);
117-
wasm().layout_append(this.ptr, font.ptr, ptr, text.length, options.scale ?? font.scale, has_color, options.r, options.g, options.b);
108+
wasm.layout_append(this.ptr, font.ptr, ptr, text.length, options.scale ?? font.scale, has_color, options.r, options.g, options.b);
118109
}
119110

120111
rasterize(r, g, b) {
121-
const ptr = wasm().layout_rasterize(this.ptr, r, g, b);
112+
const ptr = wasm.layout_rasterize(this.ptr, r, g, b);
122113

123114
const framebuffer = {
124-
width: wasm().layout_rasterize_width(ptr),
125-
height: wasm().layout_rasterize_height(ptr),
126-
buffer: mem.u8(wasm().layout_rasterize_buffer(ptr), mem.length()).slice(),
115+
width: wasm.layout_rasterize_width(ptr),
116+
height: wasm.layout_rasterize_height(ptr),
117+
buffer: mem.u8(wasm.layout_rasterize_buffer(ptr), mem.length()).slice(),
127118
}
128119

129-
return (wasm().layout_rasterize_free(ptr), framebuffer);
120+
return (wasm.layout_rasterize_free(ptr), framebuffer);
130121
}
131122
}

0 commit comments

Comments
 (0)