imagescript 1.2.15 → 1.2.17
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/ImageScript.d.ts +233 -223
- package/ImageScript.js +1658 -1646
- package/LICENSE +12 -619
- package/LICENSE.AGPL-3.0 +619 -0
- package/LICENSE.MIT +19 -0
- package/README.md +51 -46
- package/bench/_.mjs +165 -165
- package/bench/all.mjs +3 -3
- package/bench/blur.mjs +58 -58
- package/bench/flip.mjs +62 -62
- package/bench/overlay.mjs +34 -34
- package/bench/package.json +6 -6
- package/bench/readme.md +63 -63
- package/bench/resize.mjs +51 -51
- package/codecs/LICENSE +20 -20
- package/codecs/lib.d.ts +49 -49
- package/codecs/lib.js +5 -5
- package/codecs/node/index.js +2 -2
- package/codecs/node/index.mjs +5 -5
- package/codecs/package.json +13 -13
- package/codecs/readme.md +37 -37
- package/package.json +41 -41
- package/png/node.js +1137 -1137
- package/png/src/crc.mjs +48 -48
- package/png/src/mem.mjs +23 -23
- package/png/src/png.mjs +254 -254
- package/png/src/zlib.mjs +617 -617
- package/tsconfig.json +21 -21
- package/utils/mem.js +25 -25
- package/v2/codecs/magic.js +24 -24
- package/v2/framebuffer.d.ts +66 -66
- package/v2/framebuffer.js +2352 -2352
- package/v2/framebuffer.mjs +125 -125
- package/v2/framebuffer.rs +1263 -1263
- package/v2/index.d.ts +83 -83
- package/v2/index.js +260 -260
- package/v2/ops/blur.mjs +302 -302
- package/v2/ops/color.mjs +276 -276
- package/v2/ops/crop.mjs +63 -63
- package/v2/ops/fill.mjs +32 -32
- package/v2/ops/flip.mjs +32 -32
- package/v2/ops/index.mjs +8 -8
- package/v2/ops/iterator.mjs +33 -33
- package/v2/ops/overlay.mjs +62 -62
- package/v2/ops/resize.mjs +165 -165
- package/v2/ops/rotate.mjs +116 -116
- package/v2/util/mem.mjs +23 -23
- package/wasm/node/font.js +141 -141
- package/wasm/node/gif.js +76 -76
- package/wasm/node/jpeg.js +91 -91
- package/wasm/node/png.js +49 -49
- package/wasm/node/svg.js +55 -55
- package/wasm/node/tiff.js +46 -46
package/wasm/node/font.js
CHANGED
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
const wasm_name = 'font';
|
|
2
|
-
const { join } = require('path');
|
|
3
|
-
const { promises: { readFile } } = require('fs');
|
|
4
|
-
const wasm_path = process.env.IMAGESCRIPT_WASM_SIMD ? 'simd' : 'any';
|
|
5
|
-
|
|
6
|
-
let mod = null;
|
|
7
|
-
module.exports = {
|
|
8
|
-
async init() {
|
|
9
|
-
if (!mod) mod = new WebAssembly.Module(await readFile(join(__dirname, `../${wasm_path}/${wasm_name}.wasm`)));
|
|
10
|
-
|
|
11
|
-
return this.new();
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
new() {
|
|
15
|
-
let registry = null;
|
|
16
|
-
const wasm = new WebAssembly.Instance(mod).exports;
|
|
17
|
-
|
|
18
|
-
class mem {
|
|
19
|
-
static length() { return wasm.wlen(); }
|
|
20
|
-
static alloc(size) { return wasm.walloc(size); }
|
|
21
|
-
static free(ptr, size) { return wasm.wfree(ptr, size); }
|
|
22
|
-
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
|
|
23
|
-
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
|
|
24
|
-
|
|
25
|
-
static copy_and_free(ptr, size) {
|
|
26
|
-
let slice = mem.u8(ptr, size).slice();
|
|
27
|
-
return (wasm.wfree(ptr, size), slice);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const encode_utf8 = 'Deno' in globalThis ? Deno.core.encode : (() => {
|
|
31
|
-
const encoder = new TextEncoder();
|
|
32
|
-
return string => encoder.encode(string);
|
|
33
|
-
})();
|
|
34
|
-
|
|
35
|
-
const decode_utf8 = 'Deno' in globalThis ? Deno.core.decode : (() => {
|
|
36
|
-
const decoder = new TextDecoder();
|
|
37
|
-
return buffer => decoder.decode(buffer);
|
|
38
|
-
})();
|
|
39
|
-
|
|
40
|
-
if ('FinalizationRegistry' in globalThis) {
|
|
41
|
-
registry = new FinalizationRegistry(([t, ptr]) => {
|
|
42
|
-
if (t === 0) wasm.font_free(ptr);
|
|
43
|
-
if (t === 1) wasm.layout_free(ptr);
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
class Font {
|
|
48
|
-
constructor(scale, buffer) {
|
|
49
|
-
this.scale = scale;
|
|
50
|
-
const ptr = mem.alloc(buffer.length);
|
|
51
|
-
mem.u8(ptr, buffer.length).set(buffer);
|
|
52
|
-
this.ptr = wasm.font_new(ptr, buffer.length, scale);
|
|
53
|
-
|
|
54
|
-
if (!this.ptr) throw new Error('invalid font');
|
|
55
|
-
if (registry) registry.register(this, [0, this.ptr], this);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
free() {
|
|
59
|
-
this.ptr = wasm.font_free(this.ptr);
|
|
60
|
-
if (registry) registry.unregister(this);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
has(char) {
|
|
64
|
-
return wasm.font_has(this.ptr, String.prototype.charCodeAt.call(char, 0));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
metrics(char, scale = this.scale) {
|
|
68
|
-
const ptr = wasm.font_metrics(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
|
|
69
|
-
const metrics = JSON.parse(decode_utf8(mem.u8(wasm.font_metrics_buffer(ptr), mem.length())));
|
|
70
|
-
|
|
71
|
-
return (wasm.font_metrics_free(ptr), metrics);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
rasterize(char, scale = this.scale) {
|
|
75
|
-
const ptr = wasm.font_rasterize(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
|
|
76
|
-
|
|
77
|
-
const glyph = {
|
|
78
|
-
buffer: mem.u8(wasm.font_rasterize_buffer(ptr), mem.length()).slice(),
|
|
79
|
-
metrics: JSON.parse(decode_utf8(mem.u8(wasm.font_rasterize_metrics(ptr), mem.length()))),
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return (wasm.font_rasterize_free(ptr), glyph);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
class Layout {
|
|
87
|
-
constructor() {
|
|
88
|
-
this.ptr = wasm.layout_new();
|
|
89
|
-
if (registry) this.refs = [];
|
|
90
|
-
if (registry) registry.register(this, [1, this.ptr], this);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
clear() {
|
|
94
|
-
wasm.layout_clear(this.ptr);
|
|
95
|
-
if (registry) this.refs.length = 0;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
lines() {
|
|
99
|
-
return wasm.layout_lines(this.ptr);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
free() {
|
|
103
|
-
if (registry) this.refs.length = 0;
|
|
104
|
-
this.ptr = wasm.layout_free(this.ptr);
|
|
105
|
-
if (registry) registry.unregister(this);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
reset(options = {}) {
|
|
109
|
-
options = encode_utf8(JSON.stringify(options));
|
|
110
|
-
|
|
111
|
-
if (registry) this.refs.length = 0;
|
|
112
|
-
const ptr = mem.alloc(options.length);
|
|
113
|
-
mem.u8(ptr, options.length).set(options);
|
|
114
|
-
wasm.layout_reset(this.ptr, ptr, options.length);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
append(font, text, init) {
|
|
118
|
-
text = encode_utf8(text);
|
|
119
|
-
const options = init || {};
|
|
120
|
-
if (registry) this.refs.push(font);
|
|
121
|
-
const ptr = mem.alloc(text.length);
|
|
122
|
-
mem.u8(ptr, text.length).set(text);
|
|
123
|
-
const has_color = ('r' in options) || ('g' in options) || ('b' in options);
|
|
124
|
-
wasm.layout_append(this.ptr, font.ptr, ptr, text.length, options.scale == null ? font.scale : options.scale, has_color, options.r, options.g, options.b);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
rasterize(r, g, b) {
|
|
128
|
-
const ptr = wasm.layout_rasterize(this.ptr, r, g, b);
|
|
129
|
-
|
|
130
|
-
const framebuffer = {
|
|
131
|
-
width: wasm.layout_rasterize_width(ptr),
|
|
132
|
-
height: wasm.layout_rasterize_height(ptr),
|
|
133
|
-
buffer: mem.u8(wasm.layout_rasterize_buffer(ptr), mem.length()).slice(),
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return (wasm.layout_rasterize_free(ptr), framebuffer);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return { Font, Layout };
|
|
141
|
-
}
|
|
1
|
+
const wasm_name = 'font';
|
|
2
|
+
const { join } = require('path');
|
|
3
|
+
const { promises: { readFile } } = require('fs');
|
|
4
|
+
const wasm_path = process.env.IMAGESCRIPT_WASM_SIMD ? 'simd' : 'any';
|
|
5
|
+
|
|
6
|
+
let mod = null;
|
|
7
|
+
module.exports = {
|
|
8
|
+
async init() {
|
|
9
|
+
if (!mod) mod = new WebAssembly.Module(await readFile(join(__dirname, `../${wasm_path}/${wasm_name}.wasm`)));
|
|
10
|
+
|
|
11
|
+
return this.new();
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
new() {
|
|
15
|
+
let registry = null;
|
|
16
|
+
const wasm = new WebAssembly.Instance(mod).exports;
|
|
17
|
+
|
|
18
|
+
class mem {
|
|
19
|
+
static length() { return wasm.wlen(); }
|
|
20
|
+
static alloc(size) { return wasm.walloc(size); }
|
|
21
|
+
static free(ptr, size) { return wasm.wfree(ptr, size); }
|
|
22
|
+
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
|
|
23
|
+
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
|
|
24
|
+
|
|
25
|
+
static copy_and_free(ptr, size) {
|
|
26
|
+
let slice = mem.u8(ptr, size).slice();
|
|
27
|
+
return (wasm.wfree(ptr, size), slice);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const encode_utf8 = 'Deno' in globalThis ? Deno.core.encode : (() => {
|
|
31
|
+
const encoder = new TextEncoder();
|
|
32
|
+
return string => encoder.encode(string);
|
|
33
|
+
})();
|
|
34
|
+
|
|
35
|
+
const decode_utf8 = 'Deno' in globalThis ? Deno.core.decode : (() => {
|
|
36
|
+
const decoder = new TextDecoder();
|
|
37
|
+
return buffer => decoder.decode(buffer);
|
|
38
|
+
})();
|
|
39
|
+
|
|
40
|
+
if ('FinalizationRegistry' in globalThis) {
|
|
41
|
+
registry = new FinalizationRegistry(([t, ptr]) => {
|
|
42
|
+
if (t === 0) wasm.font_free(ptr);
|
|
43
|
+
if (t === 1) wasm.layout_free(ptr);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class Font {
|
|
48
|
+
constructor(scale, buffer) {
|
|
49
|
+
this.scale = scale;
|
|
50
|
+
const ptr = mem.alloc(buffer.length);
|
|
51
|
+
mem.u8(ptr, buffer.length).set(buffer);
|
|
52
|
+
this.ptr = wasm.font_new(ptr, buffer.length, scale);
|
|
53
|
+
|
|
54
|
+
if (!this.ptr) throw new Error('invalid font');
|
|
55
|
+
if (registry) registry.register(this, [0, this.ptr], this);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
free() {
|
|
59
|
+
this.ptr = wasm.font_free(this.ptr);
|
|
60
|
+
if (registry) registry.unregister(this);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
has(char) {
|
|
64
|
+
return wasm.font_has(this.ptr, String.prototype.charCodeAt.call(char, 0));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
metrics(char, scale = this.scale) {
|
|
68
|
+
const ptr = wasm.font_metrics(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
|
|
69
|
+
const metrics = JSON.parse(decode_utf8(mem.u8(wasm.font_metrics_buffer(ptr), mem.length())));
|
|
70
|
+
|
|
71
|
+
return (wasm.font_metrics_free(ptr), metrics);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
rasterize(char, scale = this.scale) {
|
|
75
|
+
const ptr = wasm.font_rasterize(this.ptr, String.prototype.charCodeAt.call(char, 0), scale);
|
|
76
|
+
|
|
77
|
+
const glyph = {
|
|
78
|
+
buffer: mem.u8(wasm.font_rasterize_buffer(ptr), mem.length()).slice(),
|
|
79
|
+
metrics: JSON.parse(decode_utf8(mem.u8(wasm.font_rasterize_metrics(ptr), mem.length()))),
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return (wasm.font_rasterize_free(ptr), glyph);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
class Layout {
|
|
87
|
+
constructor() {
|
|
88
|
+
this.ptr = wasm.layout_new();
|
|
89
|
+
if (registry) this.refs = [];
|
|
90
|
+
if (registry) registry.register(this, [1, this.ptr], this);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
clear() {
|
|
94
|
+
wasm.layout_clear(this.ptr);
|
|
95
|
+
if (registry) this.refs.length = 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
lines() {
|
|
99
|
+
return wasm.layout_lines(this.ptr);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
free() {
|
|
103
|
+
if (registry) this.refs.length = 0;
|
|
104
|
+
this.ptr = wasm.layout_free(this.ptr);
|
|
105
|
+
if (registry) registry.unregister(this);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
reset(options = {}) {
|
|
109
|
+
options = encode_utf8(JSON.stringify(options));
|
|
110
|
+
|
|
111
|
+
if (registry) this.refs.length = 0;
|
|
112
|
+
const ptr = mem.alloc(options.length);
|
|
113
|
+
mem.u8(ptr, options.length).set(options);
|
|
114
|
+
wasm.layout_reset(this.ptr, ptr, options.length);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
append(font, text, init) {
|
|
118
|
+
text = encode_utf8(text);
|
|
119
|
+
const options = init || {};
|
|
120
|
+
if (registry) this.refs.push(font);
|
|
121
|
+
const ptr = mem.alloc(text.length);
|
|
122
|
+
mem.u8(ptr, text.length).set(text);
|
|
123
|
+
const has_color = ('r' in options) || ('g' in options) || ('b' in options);
|
|
124
|
+
wasm.layout_append(this.ptr, font.ptr, ptr, text.length, options.scale == null ? font.scale : options.scale, has_color, options.r, options.g, options.b);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
rasterize(r, g, b) {
|
|
128
|
+
const ptr = wasm.layout_rasterize(this.ptr, r, g, b);
|
|
129
|
+
|
|
130
|
+
const framebuffer = {
|
|
131
|
+
width: wasm.layout_rasterize_width(ptr),
|
|
132
|
+
height: wasm.layout_rasterize_height(ptr),
|
|
133
|
+
buffer: mem.u8(wasm.layout_rasterize_buffer(ptr), mem.length()).slice(),
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return (wasm.layout_rasterize_free(ptr), framebuffer);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return { Font, Layout };
|
|
141
|
+
}
|
|
142
142
|
}
|
package/wasm/node/gif.js
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
const wasm_name = 'gif';
|
|
2
|
-
const { join } = require('path');
|
|
3
|
-
const { promises: { readFile } } = require('fs');
|
|
4
|
-
const wasm_path = process.env.IMAGESCRIPT_WASM_SIMD ? 'simd' : 'any';
|
|
5
|
-
|
|
6
|
-
let mod = null;
|
|
7
|
-
module.exports = {
|
|
8
|
-
async init() {
|
|
9
|
-
if (!mod) mod = new WebAssembly.Module(await readFile(join(__dirname, `../${wasm_path}/${wasm_name}.wasm`)));
|
|
10
|
-
|
|
11
|
-
return this.new();
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
new() {
|
|
15
|
-
const wasm = new WebAssembly.Instance(mod, { env: { push_to_stream(id, ptr) { } } }).exports;
|
|
16
|
-
|
|
17
|
-
class mem {
|
|
18
|
-
static length() { return wasm.wlen(); }
|
|
19
|
-
static alloc(size) { return wasm.walloc(size); }
|
|
20
|
-
static free(ptr, size) { return wasm.wfree(ptr, size); }
|
|
21
|
-
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
|
|
22
|
-
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
|
|
23
|
-
|
|
24
|
-
static copy_and_free(ptr, size) {
|
|
25
|
-
let slice = mem.u8(ptr, size).slice();
|
|
26
|
-
return (wasm.wfree(ptr, size), slice);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function load(buffer) {
|
|
31
|
-
return [...new Decoder(buffer).frames()];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
class Decoder {
|
|
35
|
-
constructor(buffer, limit = 0) {
|
|
36
|
-
const bptr = mem.alloc(buffer.length);
|
|
37
|
-
mem.u8(bptr, buffer.length).set(buffer);
|
|
38
|
-
this.ptr = wasm.decoder_new(bptr, buffer.length, limit);
|
|
39
|
-
if (0 === this.ptr) throw new Error('gif: failed to parse gif header');
|
|
40
|
-
|
|
41
|
-
this.width = wasm.decoder_width(this.ptr);
|
|
42
|
-
this.height = wasm.decoder_height(this.ptr);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
free() {
|
|
46
|
-
this.ptr = wasm.decoder_free(this.ptr);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
*frames() {
|
|
50
|
-
let frame;
|
|
51
|
-
while (frame = this.frame()) yield frame;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
frame() {
|
|
55
|
-
const ptr = wasm.decoder_frame(this.ptr);
|
|
56
|
-
|
|
57
|
-
if (1 === ptr) return null;
|
|
58
|
-
if (0 === ptr) throw (this.free(), new Error('gif: failed to decode frame'));
|
|
59
|
-
|
|
60
|
-
const framebuffer = {
|
|
61
|
-
x: wasm.decoder_frame_x(ptr),
|
|
62
|
-
y: wasm.decoder_frame_y(ptr),
|
|
63
|
-
delay: wasm.decoder_frame_delay(ptr),
|
|
64
|
-
width: wasm.decoder_frame_width(ptr),
|
|
65
|
-
height: wasm.decoder_frame_height(ptr),
|
|
66
|
-
dispose: wasm.decoder_frame_dispose(ptr),
|
|
67
|
-
buffer: mem.u8(wasm.decoder_frame_buffer(ptr), mem.length()).slice(),
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
return (wasm.decoder_frame_free(ptr), framebuffer);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return { load, Decoder };
|
|
75
|
-
}
|
|
76
|
-
}
|
|
1
|
+
const wasm_name = 'gif';
|
|
2
|
+
const { join } = require('path');
|
|
3
|
+
const { promises: { readFile } } = require('fs');
|
|
4
|
+
const wasm_path = process.env.IMAGESCRIPT_WASM_SIMD ? 'simd' : 'any';
|
|
5
|
+
|
|
6
|
+
let mod = null;
|
|
7
|
+
module.exports = {
|
|
8
|
+
async init() {
|
|
9
|
+
if (!mod) mod = new WebAssembly.Module(await readFile(join(__dirname, `../${wasm_path}/${wasm_name}.wasm`)));
|
|
10
|
+
|
|
11
|
+
return this.new();
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
new() {
|
|
15
|
+
const wasm = new WebAssembly.Instance(mod, { env: { push_to_stream(id, ptr) { } } }).exports;
|
|
16
|
+
|
|
17
|
+
class mem {
|
|
18
|
+
static length() { return wasm.wlen(); }
|
|
19
|
+
static alloc(size) { return wasm.walloc(size); }
|
|
20
|
+
static free(ptr, size) { return wasm.wfree(ptr, size); }
|
|
21
|
+
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
|
|
22
|
+
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
|
|
23
|
+
|
|
24
|
+
static copy_and_free(ptr, size) {
|
|
25
|
+
let slice = mem.u8(ptr, size).slice();
|
|
26
|
+
return (wasm.wfree(ptr, size), slice);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function load(buffer) {
|
|
31
|
+
return [...new Decoder(buffer).frames()];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class Decoder {
|
|
35
|
+
constructor(buffer, limit = 0) {
|
|
36
|
+
const bptr = mem.alloc(buffer.length);
|
|
37
|
+
mem.u8(bptr, buffer.length).set(buffer);
|
|
38
|
+
this.ptr = wasm.decoder_new(bptr, buffer.length, limit);
|
|
39
|
+
if (0 === this.ptr) throw new Error('gif: failed to parse gif header');
|
|
40
|
+
|
|
41
|
+
this.width = wasm.decoder_width(this.ptr);
|
|
42
|
+
this.height = wasm.decoder_height(this.ptr);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
free() {
|
|
46
|
+
this.ptr = wasm.decoder_free(this.ptr);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
*frames() {
|
|
50
|
+
let frame;
|
|
51
|
+
while (frame = this.frame()) yield frame;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
frame() {
|
|
55
|
+
const ptr = wasm.decoder_frame(this.ptr);
|
|
56
|
+
|
|
57
|
+
if (1 === ptr) return null;
|
|
58
|
+
if (0 === ptr) throw (this.free(), new Error('gif: failed to decode frame'));
|
|
59
|
+
|
|
60
|
+
const framebuffer = {
|
|
61
|
+
x: wasm.decoder_frame_x(ptr),
|
|
62
|
+
y: wasm.decoder_frame_y(ptr),
|
|
63
|
+
delay: wasm.decoder_frame_delay(ptr),
|
|
64
|
+
width: wasm.decoder_frame_width(ptr),
|
|
65
|
+
height: wasm.decoder_frame_height(ptr),
|
|
66
|
+
dispose: wasm.decoder_frame_dispose(ptr),
|
|
67
|
+
buffer: mem.u8(wasm.decoder_frame_buffer(ptr), mem.length()).slice(),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return (wasm.decoder_frame_free(ptr), framebuffer);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { load, Decoder };
|
|
75
|
+
}
|
|
76
|
+
}
|
package/wasm/node/jpeg.js
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
const wasm_name = 'jpeg';
|
|
2
|
-
const { join } = require('path');
|
|
3
|
-
const { promises: { readFile } } = require('fs');
|
|
4
|
-
const wasm_path = process.env.IMAGESCRIPT_WASM_SIMD ? 'simd' : 'any';
|
|
5
|
-
|
|
6
|
-
let mod = null;
|
|
7
|
-
module.exports = {
|
|
8
|
-
async init() {
|
|
9
|
-
if (!mod) mod = new WebAssembly.Module(await readFile(join(__dirname, `../${wasm_path}/${wasm_name}.wasm`)));
|
|
10
|
-
|
|
11
|
-
return this.new();
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
new() {
|
|
15
|
-
const wasm = new WebAssembly.Instance(mod).exports;
|
|
16
|
-
|
|
17
|
-
class mem {
|
|
18
|
-
static length() { return wasm.wlen(); }
|
|
19
|
-
static alloc(size) { return wasm.walloc(size); }
|
|
20
|
-
static free(ptr, size) { return wasm.wfree(ptr, size); }
|
|
21
|
-
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
|
|
22
|
-
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
|
|
23
|
-
|
|
24
|
-
static copy_and_free(ptr, size) {
|
|
25
|
-
let slice = mem.u8(ptr, size).slice();
|
|
26
|
-
return (wasm.wfree(ptr, size), slice);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function decode(buffer, width, height) {
|
|
31
|
-
const bptr = mem.alloc(buffer.length);
|
|
32
|
-
mem.u8(bptr, buffer.length).set(buffer);
|
|
33
|
-
const ptr = wasm.decode(bptr, buffer.length, width, height);
|
|
34
|
-
|
|
35
|
-
if (0 === ptr) throw new Error('jpg: failed to decode');
|
|
36
|
-
if (1 === ptr) throw new Error('jpg: failed to scale decoder');
|
|
37
|
-
|
|
38
|
-
const framebuffer = {
|
|
39
|
-
width: wasm.decode_width(ptr),
|
|
40
|
-
height: wasm.decode_height(ptr),
|
|
41
|
-
format: wasm.decode_format(ptr),
|
|
42
|
-
buffer: mem.u8(wasm.decode_buffer(ptr), mem.length()).slice(),
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return (wasm.decode_free(ptr), framebuffer);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function load(buffer) {
|
|
49
|
-
const framebuffer = decode(buffer);
|
|
50
|
-
|
|
51
|
-
const old = framebuffer.buffer;
|
|
52
|
-
if (2 !== framebuffer.format) framebuffer.buffer = new Uint8Array(4 * framebuffer.width * framebuffer.height);
|
|
53
|
-
|
|
54
|
-
if (0 === framebuffer.format) {
|
|
55
|
-
let offset = 0;
|
|
56
|
-
const view = new DataView(framebuffer.buffer.buffer);
|
|
57
|
-
while (offset < old.length) view.setUint32(4 * offset, old[offset] << 24 | old[offset] << 16 | old[offset++] << 8 | 0xff, false);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
else if (2 === framebuffer.format) {
|
|
61
|
-
let offset = 0;
|
|
62
|
-
while (offset < old.length) {
|
|
63
|
-
const k = old[3 + offset];
|
|
64
|
-
old[offset] = k * old[offset++] / 255;
|
|
65
|
-
old[offset] = k * old[offset++] / 255;
|
|
66
|
-
old[offset] = k * old[offset++] / 255;
|
|
67
|
-
|
|
68
|
-
old[offset++] = 0xff;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
else if (1 === framebuffer.format) {
|
|
73
|
-
let offset = 0;
|
|
74
|
-
let foffset = 0;
|
|
75
|
-
framebuffer.buffer.fill(0xff);
|
|
76
|
-
const length = 3 * framebuffer.width * framebuffer.height;
|
|
77
|
-
|
|
78
|
-
while (offset < length) {
|
|
79
|
-
framebuffer.buffer[foffset++] = old[offset++];
|
|
80
|
-
framebuffer.buffer[foffset++] = old[offset++];
|
|
81
|
-
framebuffer.buffer[foffset++] = old[offset++];
|
|
82
|
-
|
|
83
|
-
foffset++;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return framebuffer;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return { load, decode };
|
|
91
|
-
}
|
|
1
|
+
const wasm_name = 'jpeg';
|
|
2
|
+
const { join } = require('path');
|
|
3
|
+
const { promises: { readFile } } = require('fs');
|
|
4
|
+
const wasm_path = process.env.IMAGESCRIPT_WASM_SIMD ? 'simd' : 'any';
|
|
5
|
+
|
|
6
|
+
let mod = null;
|
|
7
|
+
module.exports = {
|
|
8
|
+
async init() {
|
|
9
|
+
if (!mod) mod = new WebAssembly.Module(await readFile(join(__dirname, `../${wasm_path}/${wasm_name}.wasm`)));
|
|
10
|
+
|
|
11
|
+
return this.new();
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
new() {
|
|
15
|
+
const wasm = new WebAssembly.Instance(mod).exports;
|
|
16
|
+
|
|
17
|
+
class mem {
|
|
18
|
+
static length() { return wasm.wlen(); }
|
|
19
|
+
static alloc(size) { return wasm.walloc(size); }
|
|
20
|
+
static free(ptr, size) { return wasm.wfree(ptr, size); }
|
|
21
|
+
static u8(ptr, size) { return new Uint8Array(wasm.memory.buffer, ptr, size); }
|
|
22
|
+
static u32(ptr, size) { return new Uint32Array(wasm.memory.buffer, ptr, size); }
|
|
23
|
+
|
|
24
|
+
static copy_and_free(ptr, size) {
|
|
25
|
+
let slice = mem.u8(ptr, size).slice();
|
|
26
|
+
return (wasm.wfree(ptr, size), slice);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function decode(buffer, width, height) {
|
|
31
|
+
const bptr = mem.alloc(buffer.length);
|
|
32
|
+
mem.u8(bptr, buffer.length).set(buffer);
|
|
33
|
+
const ptr = wasm.decode(bptr, buffer.length, width, height);
|
|
34
|
+
|
|
35
|
+
if (0 === ptr) throw new Error('jpg: failed to decode');
|
|
36
|
+
if (1 === ptr) throw new Error('jpg: failed to scale decoder');
|
|
37
|
+
|
|
38
|
+
const framebuffer = {
|
|
39
|
+
width: wasm.decode_width(ptr),
|
|
40
|
+
height: wasm.decode_height(ptr),
|
|
41
|
+
format: wasm.decode_format(ptr),
|
|
42
|
+
buffer: mem.u8(wasm.decode_buffer(ptr), mem.length()).slice(),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (wasm.decode_free(ptr), framebuffer);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function load(buffer) {
|
|
49
|
+
const framebuffer = decode(buffer);
|
|
50
|
+
|
|
51
|
+
const old = framebuffer.buffer;
|
|
52
|
+
if (2 !== framebuffer.format) framebuffer.buffer = new Uint8Array(4 * framebuffer.width * framebuffer.height);
|
|
53
|
+
|
|
54
|
+
if (0 === framebuffer.format) {
|
|
55
|
+
let offset = 0;
|
|
56
|
+
const view = new DataView(framebuffer.buffer.buffer);
|
|
57
|
+
while (offset < old.length) view.setUint32(4 * offset, old[offset] << 24 | old[offset] << 16 | old[offset++] << 8 | 0xff, false);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
else if (2 === framebuffer.format) {
|
|
61
|
+
let offset = 0;
|
|
62
|
+
while (offset < old.length) {
|
|
63
|
+
const k = old[3 + offset];
|
|
64
|
+
old[offset] = k * old[offset++] / 255;
|
|
65
|
+
old[offset] = k * old[offset++] / 255;
|
|
66
|
+
old[offset] = k * old[offset++] / 255;
|
|
67
|
+
|
|
68
|
+
old[offset++] = 0xff;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
else if (1 === framebuffer.format) {
|
|
73
|
+
let offset = 0;
|
|
74
|
+
let foffset = 0;
|
|
75
|
+
framebuffer.buffer.fill(0xff);
|
|
76
|
+
const length = 3 * framebuffer.width * framebuffer.height;
|
|
77
|
+
|
|
78
|
+
while (offset < length) {
|
|
79
|
+
framebuffer.buffer[foffset++] = old[offset++];
|
|
80
|
+
framebuffer.buffer[foffset++] = old[offset++];
|
|
81
|
+
framebuffer.buffer[foffset++] = old[offset++];
|
|
82
|
+
|
|
83
|
+
foffset++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return framebuffer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return { load, decode };
|
|
91
|
+
}
|
|
92
92
|
}
|