mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-14 09:39:15 +00:00
Compare commits
405 Commits
oxipng-old
...
update-res
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79dcf73cc5 | ||
|
|
3a5c0aa30c | ||
|
|
f0c3ec9d51 | ||
|
|
1ae93b527c | ||
|
|
a95cb740bf | ||
|
|
de543b3206 | ||
|
|
1542bfb7fd | ||
|
|
bc8d75128f | ||
|
|
d3252bb1bb | ||
|
|
83d9d2c764 | ||
|
|
476268fe19 | ||
|
|
74492af675 | ||
|
|
bd4179aff2 | ||
|
|
27ae47117e | ||
|
|
7da3f07333 | ||
|
|
ed666dd381 | ||
|
|
6f18f08a8e | ||
|
|
eae808cb6f | ||
|
|
0ae99c9228 | ||
|
|
ae7782031d | ||
|
|
7cd6487a28 | ||
|
|
f3dfcae3f0 | ||
|
|
3f7274a6ac | ||
|
|
f5bc715bc0 | ||
|
|
22b04c159d | ||
|
|
92249ac711 | ||
|
|
629d64326d | ||
|
|
4621cbcae9 | ||
|
|
164191d746 | ||
|
|
b22adc9957 | ||
|
|
6b0a675469 | ||
|
|
d7fb0d9b40 | ||
|
|
309947a08f | ||
|
|
6aeaae6160 | ||
|
|
71b3c7dda2 | ||
|
|
48c06e86fa | ||
|
|
1b7d3fa394 | ||
|
|
650db99818 | ||
|
|
7638bb795e | ||
|
|
570e604be0 | ||
|
|
a056d1c363 | ||
|
|
fce61c8c89 | ||
|
|
d60d0ae47d | ||
|
|
8bf741ed4e | ||
|
|
9f660e5178 | ||
|
|
ef2318bcc1 | ||
|
|
364a5db5d5 | ||
|
|
4a01d0d548 | ||
|
|
4a9c28f89f | ||
|
|
3aed873467 | ||
|
|
2b7f059b8f | ||
|
|
33726e9c68 | ||
|
|
3d29f486e7 | ||
|
|
79e8a26f06 | ||
|
|
e8efd54766 | ||
|
|
edcc774c16 | ||
|
|
746b33a590 | ||
|
|
8a264efc67 | ||
|
|
f0af6e97a0 | ||
|
|
043107c101 | ||
|
|
e9e3b923e0 | ||
|
|
aea6e91b1d | ||
|
|
9c4717a13d | ||
|
|
559cabce9e | ||
|
|
7f6a3de7ca | ||
|
|
f3adc87f52 | ||
|
|
6499e9f63d | ||
|
|
ac1f104e49 | ||
|
|
87f89e6b2f | ||
|
|
7f6404d5a8 | ||
|
|
8e857cd393 | ||
|
|
b8f801333d | ||
|
|
499956e216 | ||
|
|
3932ee2c00 | ||
|
|
68177b7590 | ||
|
|
0a2a4122dc | ||
|
|
e6299569d0 | ||
|
|
578ad8c291 | ||
|
|
eaa294b689 | ||
|
|
6e97cfb8d5 | ||
|
|
80a68c48b2 | ||
|
|
98865f8141 | ||
|
|
78da9fd144 | ||
|
|
94c50a989b | ||
|
|
3e525e767c | ||
|
|
dfcc1e24e4 | ||
|
|
f3aa8edfca | ||
|
|
ffd7ee6013 | ||
|
|
64bb09dbc5 | ||
|
|
35fcbc40ed | ||
|
|
1b55a48680 | ||
|
|
88fbb19d29 | ||
|
|
3dc1501ff7 | ||
|
|
b7576c559a | ||
|
|
69ed2e1d56 | ||
|
|
55f7f3d72a | ||
|
|
055d0b4ea1 | ||
|
|
7735346ed0 | ||
|
|
2a06fdbbe0 | ||
|
|
19169199e9 | ||
|
|
76f3c39b78 | ||
|
|
8da52acc4c | ||
|
|
9253522a3a | ||
|
|
cf39a3e5a5 | ||
|
|
a08877f0ac | ||
|
|
2f0dc1c067 | ||
|
|
535d8c9142 | ||
|
|
6dc2ba3bef | ||
|
|
93cfdc8f98 | ||
|
|
671544349e | ||
|
|
d3c1939692 | ||
|
|
99642aef96 | ||
|
|
ac4942b640 | ||
|
|
23cb004a86 | ||
|
|
4b6de60978 | ||
|
|
de204aa56a | ||
|
|
976f811b36 | ||
|
|
855fc9e602 | ||
|
|
a8848e717c | ||
|
|
90b99faf8b | ||
|
|
d3cfffbbcf | ||
|
|
fade7f9be8 | ||
|
|
b10dd055d3 | ||
|
|
7532f01222 | ||
|
|
2df09efdee | ||
|
|
bed4f49a12 | ||
|
|
2b7fefff8b | ||
|
|
bdcf2519ce | ||
|
|
3f8afb72a6 | ||
|
|
2f834db224 | ||
|
|
3541ce7492 | ||
|
|
b6fae0eb4c | ||
|
|
fbaa282f07 | ||
|
|
6136ae7411 | ||
|
|
f024747299 | ||
|
|
66feffcc49 | ||
|
|
24254df7db | ||
|
|
cae73f1f1b | ||
|
|
073a52213e | ||
|
|
0d34485a00 | ||
|
|
65519d539e | ||
|
|
ec44a8e817 | ||
|
|
920f225cb0 | ||
|
|
d5d4bd61ff | ||
|
|
5656d10b67 | ||
|
|
adb4b6468b | ||
|
|
0a293d7f63 | ||
|
|
27cb5afd5b | ||
|
|
5e58fc6b04 | ||
|
|
e820adfc96 | ||
|
|
5a8a114dcb | ||
|
|
a1c685e820 | ||
|
|
377dcfcc1b | ||
|
|
913e67ca93 | ||
|
|
fb1a97c7d4 | ||
|
|
42eef6945d | ||
|
|
d04b08d640 | ||
|
|
c547dd10d3 | ||
|
|
f4579da9c9 | ||
|
|
37dc585d80 | ||
|
|
bc0a425a0f | ||
|
|
b696f246a1 | ||
|
|
e6e197e140 | ||
|
|
1c0e8a1fd3 | ||
|
|
e3e154fa1a | ||
|
|
73b7c437f9 | ||
|
|
719168be77 | ||
|
|
a2021b175c | ||
|
|
9a388fbd13 | ||
|
|
1ba0452540 | ||
|
|
73df9f18f0 | ||
|
|
0e7521877b | ||
|
|
120b37c192 | ||
|
|
5f3502b838 | ||
|
|
33f99432c5 | ||
|
|
85756ff5df | ||
|
|
84e567ad6a | ||
|
|
39281331fa | ||
|
|
438ce2ce63 | ||
|
|
a13e17e256 | ||
|
|
cd6db2d776 | ||
|
|
a08662b617 | ||
|
|
003ec9de35 | ||
|
|
e7f76ca0b8 | ||
|
|
21111e2927 | ||
|
|
445c3ef32c | ||
|
|
9df5542ee1 | ||
|
|
fffc4a0cd1 | ||
|
|
50a8743be3 | ||
|
|
8480bc7dbd | ||
|
|
72e4546922 | ||
|
|
11be5babca | ||
|
|
17e5db2427 | ||
|
|
465093eb07 | ||
|
|
b430ac1041 | ||
|
|
ea96847c1e | ||
|
|
3b5106a61d | ||
|
|
9f611b0b52 | ||
|
|
18a6b3c3e5 | ||
|
|
d9ed4e18ea | ||
|
|
9e757aa896 | ||
|
|
89b58bb446 | ||
|
|
e80ca583cc | ||
|
|
2ecc81b34f | ||
|
|
60e98ee34f | ||
|
|
538ea89ea9 | ||
|
|
3990e11e0a | ||
|
|
0251f88fe5 | ||
|
|
bbcb959b11 | ||
|
|
b5e928bac9 | ||
|
|
6592dee4a9 | ||
|
|
9b3d72191e | ||
|
|
a92e5b48ff | ||
|
|
e355764ab0 | ||
|
|
c5efd5a8bf | ||
|
|
385461944b | ||
|
|
8385ba3274 | ||
|
|
6ca6a77595 | ||
|
|
14c837e894 | ||
|
|
33346d7cb6 | ||
|
|
05d4f531e2 | ||
|
|
ede2c49b12 | ||
|
|
16acd32c68 | ||
|
|
cc90192860 | ||
|
|
3607005fa8 | ||
|
|
7646a64f94 | ||
|
|
c8ce6ce27b | ||
|
|
1240474c4b | ||
|
|
f5e84441c0 | ||
|
|
6bc19d78bc | ||
|
|
a4437d2873 | ||
|
|
cd19650748 | ||
|
|
253315b3b1 | ||
|
|
4203ad9a13 | ||
|
|
6958202f9d | ||
|
|
386fef063f | ||
|
|
d7246ca427 | ||
|
|
fd024853b6 | ||
|
|
bd53d17876 | ||
|
|
3f87f571f4 | ||
|
|
1c69a6f1b7 | ||
|
|
82419cbb6e | ||
|
|
db65630c8d | ||
|
|
b8e54b947f | ||
|
|
f23897108d | ||
|
|
1efe5b21f0 | ||
|
|
fc71b4d249 | ||
|
|
dc81d46556 | ||
|
|
56c2080f43 | ||
|
|
4cc50fcaa5 | ||
|
|
2d67562576 | ||
|
|
76f2d7afa7 | ||
|
|
80fa9c4f21 | ||
|
|
8f215a5b4b | ||
|
|
bffd9cb52a | ||
|
|
74b1ff5b10 | ||
|
|
3c0079fea0 | ||
|
|
c0a9723d20 | ||
|
|
a4f0a76200 | ||
|
|
eb57b0130b | ||
|
|
f8c37c7abc | ||
|
|
72373f8812 | ||
|
|
b285e99e7d | ||
|
|
f9a6b88bb6 | ||
|
|
4a65d506f2 | ||
|
|
3bc03c90fd | ||
|
|
c35dfa4ac5 | ||
|
|
1d2a9a9dde | ||
|
|
925220bb13 | ||
|
|
16d088bfe3 | ||
|
|
b8e22ee435 | ||
|
|
60dea4b932 | ||
|
|
8ae1a42e4b | ||
|
|
cfdc7a46e6 | ||
|
|
afb23adcbf | ||
|
|
3b84a474b8 | ||
|
|
e96bb04e88 | ||
|
|
2e3b8507b2 | ||
|
|
e12c69f1a6 | ||
|
|
d049a23469 | ||
|
|
2633f427c8 | ||
|
|
ff920f1d7b | ||
|
|
fd69560025 | ||
|
|
ba51e47e05 | ||
|
|
409f552274 | ||
|
|
69a7c184bd | ||
|
|
3039c84738 | ||
|
|
bfa5cd085d | ||
|
|
7c282b30b1 | ||
|
|
06fa3c541e | ||
|
|
c9e31ac1f7 | ||
|
|
e248486d3d | ||
|
|
b32a52d236 | ||
|
|
a24b4d6d4d | ||
|
|
b831aa0075 | ||
|
|
bf4d4b78cb | ||
|
|
496896e36e | ||
|
|
6b88ec1f8a | ||
|
|
3af5f3a96d | ||
|
|
ddc5564515 | ||
|
|
bc5da7ef06 | ||
|
|
45221c0b03 | ||
|
|
d29cf2ffa7 | ||
|
|
f6c0b89d1f | ||
|
|
ecd9e06665 | ||
|
|
9e5b66d5f4 | ||
|
|
8c35c3cdaa | ||
|
|
828a6240fe | ||
|
|
eaad0eaee0 | ||
|
|
db76d4417c | ||
|
|
7a6c6ec210 | ||
|
|
8e034f183b | ||
|
|
5a01b34cce | ||
|
|
1399a9bffe | ||
|
|
653c6ed85a | ||
|
|
ebbb7b58cb | ||
|
|
7164e4e315 | ||
|
|
23398d07f9 | ||
|
|
ec2bc3efa2 | ||
|
|
86d78763c1 | ||
|
|
fb5ae36d7e | ||
|
|
51f812625b | ||
|
|
479bfee647 | ||
|
|
a3501a56cd | ||
|
|
c353e286b0 | ||
|
|
8ed01e8a87 | ||
|
|
36ed21b9f4 | ||
|
|
cca41bb449 | ||
|
|
8f787ad0e6 | ||
|
|
9c1170f100 | ||
|
|
5432be4a3f | ||
|
|
7cae821db5 | ||
|
|
19ebb24f03 | ||
|
|
d07512566e | ||
|
|
61929666f3 | ||
|
|
792ffbfcd7 | ||
|
|
9685271bb4 | ||
|
|
5b1a6cc95e | ||
|
|
bf34075e6a | ||
|
|
f1859eeef2 | ||
|
|
fa12b37e53 | ||
|
|
520a5dc9f2 | ||
|
|
7af949b5a5 | ||
|
|
300612b09b | ||
|
|
6f00e9825c | ||
|
|
6ca9c5300e | ||
|
|
cdeb31051b | ||
|
|
ba90517ad7 | ||
|
|
7aff949f47 | ||
|
|
0e8c0da3dd | ||
|
|
3132a207e1 | ||
|
|
88dd0e06c5 | ||
|
|
f507a2464f | ||
|
|
14baa6ebf8 | ||
|
|
5d32126565 | ||
|
|
484ff7ab4c | ||
|
|
36f86385a2 | ||
|
|
436faa17af | ||
|
|
d205ae206f | ||
|
|
6baa5900fc | ||
|
|
fadb53f075 | ||
|
|
1a63387408 | ||
|
|
a316120b69 | ||
|
|
0d1e5ef119 | ||
|
|
b49cfca39d | ||
|
|
ab58df4c2c | ||
|
|
db20f10bd2 | ||
|
|
444cc5a193 | ||
|
|
6c253bc9b4 | ||
|
|
2fd28e174e | ||
|
|
a188692c88 | ||
|
|
b263419e08 | ||
|
|
826e06c727 | ||
|
|
dfcdfb105f | ||
|
|
0508bbb16f | ||
|
|
dfbfa85fd3 | ||
|
|
b99ad4bdc3 | ||
|
|
e801170496 | ||
|
|
91e7c9c5ad | ||
|
|
ca5162ed32 | ||
|
|
0bf87d0c87 | ||
|
|
ce91eb5bae | ||
|
|
8d68056bca | ||
|
|
d0de8e444a | ||
|
|
dfef1f21cc | ||
|
|
2440ac4e87 | ||
|
|
e90db78697 | ||
|
|
5ae15d429c | ||
|
|
89d6b46f3e | ||
|
|
e086f64779 | ||
|
|
9ed3b4f11e | ||
|
|
ece3fa12b4 | ||
|
|
9a35224535 | ||
|
|
ef3faa58bc | ||
|
|
b6a8f7eeba | ||
|
|
d1203d9c42 | ||
|
|
a834b6ae38 | ||
|
|
e7982a73ad | ||
|
|
717342c80c | ||
|
|
075f0e62fd | ||
|
|
bcca31fbed | ||
|
|
007891fc11 | ||
|
|
f8e41952d1 | ||
|
|
e4d64f8a79 | ||
|
|
1654f69ec1 |
2
.clang-format
Normal file
2
.clang-format
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
BasedOnStyle: Chromium
|
||||||
|
ColumnLimit: 100
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
|
||||||
- node
|
|
||||||
- 10
|
|
||||||
- 8
|
|
||||||
cache: npm
|
cache: npm
|
||||||
script: npm run build
|
script: npm run build
|
||||||
|
after_success: npm run sizereport
|
||||||
|
|||||||
5
codecs/hqx/.gitignore
vendored
Normal file
5
codecs/hqx/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
**/*.rs.bk
|
||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/README.md
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "loltest"
|
name = "squooshhqx"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Surma <surma@surma.link>"]
|
authors = ["Surma <surma@surma.link>"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "lib.rs"
|
crate-type = ["cdylib"]
|
||||||
crate-type = ["cdylib", "rlib"]
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["console_error_panic_hook"]
|
default = ["console_error_panic_hook", "wee_alloc"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = "0.2"
|
cfg-if = "0.1.2"
|
||||||
|
wasm-bindgen = "0.2.38"
|
||||||
|
# lazy_static = "1.0.0"
|
||||||
|
hqx = {git = "https://github.com/CryZe/wasmboy-rs", tag="v0.1.2"}
|
||||||
|
|
||||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
# logging them with `console.error`. This is great for development, but requires
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
@@ -19,9 +21,17 @@ wasm-bindgen = "0.2"
|
|||||||
# code size when deploying.
|
# code size when deploying.
|
||||||
console_error_panic_hook = { version = "0.1.1", optional = true }
|
console_error_panic_hook = { version = "0.1.1", optional = true }
|
||||||
|
|
||||||
|
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||||
|
# compared to the default allocator's ~10K. It is slower than the default
|
||||||
|
# allocator, however.
|
||||||
|
#
|
||||||
|
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||||
|
wee_alloc = { version = "0.4.2", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = "0.2"
|
wasm-bindgen-test = "0.2"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
# Tell `rustc` to optimize for small code size.
|
# Tell `rustc` to optimize for small code size.
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
lto = true
|
||||||
12
codecs/hqx/Dockerfile
Normal file
12
codecs/hqx/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
RUN mkdir /opt/binaryen && \
|
||||||
|
curl -L https://github.com/WebAssembly/binaryen/releases/download/1.38.32/binaryen-1.38.32-x86-linux.tar.gz | tar -xzf - -C /opt/binaryen --strip 1
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/binaryen:/opt/wabt:${PATH}"
|
||||||
|
WORKDIR /src
|
||||||
25
codecs/hqx/build.sh
Executable file
25
codecs/hqx/build.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
wasm-pack build
|
||||||
|
wasm-strip pkg/squooshhqx_bg.wasm
|
||||||
|
echo "Optimising Wasm so it doesn't break Chrome (this takes like 10-15mins. get a cup of tea)"
|
||||||
|
echo "Once https://crbug.com/974804 is fixed, we can remove this step"
|
||||||
|
wasm-opt -Os --no-validation -o pkg/squooshhqx_bg.wasm pkg/squooshhqx_bg.wasm
|
||||||
|
rm pkg/.gitignore
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-hqx .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
4
codecs/hqx/package-lock.json
generated
Normal file
4
codecs/hqx/package-lock.json
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "hqx",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
||||||
7
codecs/hqx/package.json
Normal file
7
codecs/hqx/package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "hqx",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-hqx .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
codecs/hqx/pkg/package.json
Normal file
15
codecs/hqx/pkg/package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "squooshhqx",
|
||||||
|
"collaborators": [
|
||||||
|
"Surma <surma@surma.link>"
|
||||||
|
],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"files": [
|
||||||
|
"squooshhqx_bg.wasm",
|
||||||
|
"squooshhqx.js",
|
||||||
|
"squooshhqx.d.ts"
|
||||||
|
],
|
||||||
|
"module": "squooshhqx.js",
|
||||||
|
"types": "squooshhqx.d.ts",
|
||||||
|
"sideEffects": "false"
|
||||||
|
}
|
||||||
9
codecs/hqx/pkg/squooshhqx.d.ts
vendored
Normal file
9
codecs/hqx/pkg/squooshhqx.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/**
|
||||||
|
* @param {Uint32Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} factor
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array;
|
||||||
46
codecs/hqx/pkg/squooshhqx.js
Normal file
46
codecs/hqx/pkg/squooshhqx.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import * as wasm from './squooshhqx_bg.wasm';
|
||||||
|
|
||||||
|
let cachegetUint32Memory = null;
|
||||||
|
function getUint32Memory() {
|
||||||
|
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint32Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
|
function passArray32ToWasm(arg) {
|
||||||
|
const ptr = wasm.__wbindgen_malloc(arg.length * 4);
|
||||||
|
getUint32Memory().set(arg, ptr / 4);
|
||||||
|
WASM_VECTOR_LEN = arg.length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetInt32Memory = null;
|
||||||
|
function getInt32Memory() {
|
||||||
|
if (cachegetInt32Memory === null || cachegetInt32Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU32FromWasm(ptr, len) {
|
||||||
|
return getUint32Memory().subarray(ptr / 4, ptr / 4 + len);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Uint32Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} factor
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image, input_width, input_height, factor) {
|
||||||
|
const retptr = 8;
|
||||||
|
const ret = wasm.resize(retptr, passArray32ToWasm(input_image), WASM_VECTOR_LEN, input_width, input_height, factor);
|
||||||
|
const memi32 = getInt32Memory();
|
||||||
|
const v0 = getArrayU32FromWasm(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1]).slice();
|
||||||
|
wasm.__wbindgen_free(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1] * 4);
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
||||||
5
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
Normal file
5
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
|
export function resize(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
||||||
BIN
codecs/hqx/pkg/squooshhqx_bg.wasm
Normal file
BIN
codecs/hqx/pkg/squooshhqx_bg.wasm
Normal file
Binary file not shown.
55
codecs/hqx/src/lib.rs
Normal file
55
codecs/hqx/src/lib.rs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
extern crate cfg_if;
|
||||||
|
extern crate hqx;
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
|
// allocator.
|
||||||
|
if #[cfg(feature = "wee_alloc")] {
|
||||||
|
extern crate wee_alloc;
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn resize(
|
||||||
|
input_image: Vec<u32>,
|
||||||
|
input_width: usize,
|
||||||
|
input_height: usize,
|
||||||
|
factor: usize,
|
||||||
|
) -> Vec<u32> {
|
||||||
|
let num_output_pixels = input_width * input_height * factor * factor;
|
||||||
|
let mut output_image = Vec::<u32>::with_capacity(num_output_pixels * 4);
|
||||||
|
output_image.resize(num_output_pixels, 0);
|
||||||
|
|
||||||
|
match factor {
|
||||||
|
2 => hqx::hq2x(
|
||||||
|
input_image.as_slice(),
|
||||||
|
output_image.as_mut_slice(),
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
),
|
||||||
|
3 => hqx::hq3x(
|
||||||
|
input_image.as_slice(),
|
||||||
|
output_image.as_mut_slice(),
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
),
|
||||||
|
4 => hqx::hq4x(
|
||||||
|
input_image.as_slice(),
|
||||||
|
output_image.as_mut_slice(),
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return output_image;
|
||||||
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export OPTIMIZE="-Os"
|
export EM_CACHE="${PWD}/node_modules/.em_cache"
|
||||||
|
export OPTIMIZE="-Os -flto --llvm-lto 1"
|
||||||
export LDFLAGS="${OPTIMIZE}"
|
export LDFLAGS="${OPTIMIZE}"
|
||||||
export CFLAGS="${OPTIMIZE}"
|
export CFLAGS="${OPTIMIZE}"
|
||||||
export CPPFLAGS="${OPTIMIZE}"
|
export CPPFLAGS="${OPTIMIZE}"
|
||||||
@@ -11,16 +12,9 @@ echo "============================================="
|
|||||||
echo "Compiling libimagequant"
|
echo "Compiling libimagequant"
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
(
|
(
|
||||||
emcc \
|
cd node_modules/libimagequant
|
||||||
--bind \
|
emconfigure ./configure --disable-sse
|
||||||
${OPTIMIZE} \
|
emmake make static -j`nproc`
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s 'EXPORT_NAME="imagequant"' \
|
|
||||||
-I node_modules/libimagequant \
|
|
||||||
--std=c99 \
|
|
||||||
-c \
|
|
||||||
node_modules/libimagequant/{libimagequant,pam,mediancut,blur,mempool,kmeans,nearest}.c
|
|
||||||
)
|
)
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling wasm module"
|
echo "Compiling wasm module"
|
||||||
@@ -29,14 +23,15 @@ echo "============================================="
|
|||||||
emcc \
|
emcc \
|
||||||
--bind \
|
--bind \
|
||||||
${OPTIMIZE} \
|
${OPTIMIZE} \
|
||||||
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s 'EXPORT_NAME="imagequant"' \
|
-s 'EXPORT_NAME="imagequant"' \
|
||||||
-I node_modules/libimagequant \
|
-I node_modules/libimagequant \
|
||||||
-o ./imagequant.js \
|
-o ./imagequant.js \
|
||||||
--std=c++11 *.o \
|
--std=c++11 \
|
||||||
-x c++ \
|
imagequant.cpp \
|
||||||
imagequant.cpp
|
node_modules/libimagequant/libimagequant.a
|
||||||
)
|
)
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling wasm module done"
|
echo "Compiling wasm module done"
|
||||||
@@ -44,5 +39,5 @@ echo "============================================="
|
|||||||
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
echo "Did you update your docker image?"
|
echo "Did you update your docker image?"
|
||||||
echo "Run \`docker pull trzeci/emscripten\`"
|
echo "Run \`docker pull trzeci/emscripten-upstream\`"
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
|||||||
@@ -1,36 +1,37 @@
|
|||||||
#include "emscripten/bind.h"
|
#include <emscripten/bind.h>
|
||||||
#include "emscripten/val.h"
|
#include <emscripten/val.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "libimagequant.h"
|
#include "libimagequant.h"
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
int version() {
|
int version() {
|
||||||
return (((LIQ_VERSION/10000) % 100) << 16) |
|
return (((LIQ_VERSION / 10000) % 100) << 16) | (((LIQ_VERSION / 100) % 100) << 8) |
|
||||||
(((LIQ_VERSION/100 ) % 100) << 8) |
|
(((LIQ_VERSION / 1) % 100) << 0);
|
||||||
(((LIQ_VERSION/1 ) % 100) << 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RawImage {
|
class RawImage {
|
||||||
public:
|
public:
|
||||||
val buffer;
|
val buffer;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
RawImage(val b, int w, int h)
|
RawImage(val b, int w, int h) : buffer(b), width(w), height(h) {}
|
||||||
: buffer(b), width(w), height(h) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
liq_attr* attr;
|
||||||
liq_attr *attr;
|
liq_image* image;
|
||||||
liq_image *image;
|
liq_result* res;
|
||||||
liq_result *res;
|
|
||||||
uint8_t* result;
|
uint8_t* result;
|
||||||
RawImage quantize(std::string rawimage, int image_width, int image_height, int num_colors, float dithering) {
|
RawImage quantize(std::string rawimage,
|
||||||
|
int image_width,
|
||||||
|
int image_height,
|
||||||
|
int num_colors,
|
||||||
|
float dithering) {
|
||||||
const uint8_t* image_buffer = (uint8_t*)rawimage.c_str();
|
const uint8_t* image_buffer = (uint8_t*)rawimage.c_str();
|
||||||
int size = image_width * image_height;
|
int size = image_width * image_height;
|
||||||
attr = liq_attr_create();
|
attr = liq_attr_create();
|
||||||
@@ -38,12 +39,12 @@ RawImage quantize(std::string rawimage, int image_width, int image_height, int n
|
|||||||
liq_set_max_colors(attr, num_colors);
|
liq_set_max_colors(attr, num_colors);
|
||||||
liq_image_quantize(image, attr, &res);
|
liq_image_quantize(image, attr, &res);
|
||||||
liq_set_dithering_level(res, dithering);
|
liq_set_dithering_level(res, dithering);
|
||||||
uint8_t* image8bit = (uint8_t*) malloc(size);
|
uint8_t* image8bit = (uint8_t*)malloc(size);
|
||||||
result = (uint8_t*) malloc(size * 4);
|
result = (uint8_t*)malloc(size * 4);
|
||||||
liq_write_remapped_image(res, image, image8bit, size);
|
liq_write_remapped_image(res, image, image8bit, size);
|
||||||
const liq_palette *pal = liq_get_palette(res);
|
const liq_palette* pal = liq_get_palette(res);
|
||||||
// Turn palletted image back into an RGBA image
|
// Turn palletted image back into an RGBA image
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
result[i * 4 + 0] = pal->entries[image8bit[i]].r;
|
result[i * 4 + 0] = pal->entries[image8bit[i]].r;
|
||||||
result[i * 4 + 1] = pal->entries[image8bit[i]].g;
|
result[i * 4 + 1] = pal->entries[image8bit[i]].g;
|
||||||
result[i * 4 + 2] = pal->entries[image8bit[i]].b;
|
result[i * 4 + 2] = pal->entries[image8bit[i]].b;
|
||||||
@@ -53,43 +54,41 @@ RawImage quantize(std::string rawimage, int image_width, int image_height, int n
|
|||||||
liq_result_destroy(res);
|
liq_result_destroy(res);
|
||||||
liq_image_destroy(image);
|
liq_image_destroy(image);
|
||||||
liq_attr_destroy(attr);
|
liq_attr_destroy(attr);
|
||||||
return {
|
return {val(typed_memory_view(image_width * image_height * 4, result)), image_width,
|
||||||
val(typed_memory_view(image_width*image_height*4, result)),
|
image_height};
|
||||||
image_width,
|
|
||||||
image_height
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const liq_color zx_colors[] = {
|
const liq_color zx_colors[] = {
|
||||||
{.a = 255, .r = 0, .g = 0, .b = 0}, // regular black
|
{.r = 0, .g = 0, .b = 0, .a = 255}, // regular black
|
||||||
{.a = 255, .r = 0, .g = 0, .b = 215}, // regular blue
|
{.r = 0, .g = 0, .b = 215, .a = 255}, // regular blue
|
||||||
{.a = 255, .r = 215, .g = 0, .b = 0}, // regular red
|
{.r = 215, .g = 0, .b = 0, .a = 255}, // regular red
|
||||||
{.a = 255, .r = 215, .g = 0, .b = 215}, // regular magenta
|
{.r = 215, .g = 0, .b = 215, .a = 255}, // regular magenta
|
||||||
{.a = 255, .r = 0, .g = 215, .b = 0}, // regular green
|
{.r = 0, .g = 215, .b = 0, .a = 255}, // regular green
|
||||||
{.a = 255, .r = 0, .g = 215, .b = 215}, // regular cyan
|
{.r = 0, .g = 215, .b = 215, .a = 255}, // regular cyan
|
||||||
{.a = 255, .r = 215, .g = 215, .b = 0}, // regular yellow
|
{.r = 215, .g = 215, .b = 0, .a = 255}, // regular yellow
|
||||||
{.a = 255, .r = 215, .g = 215, .b = 215}, // regular white
|
{.r = 215, .g = 215, .b = 215, .a = 255}, // regular white
|
||||||
{.a = 255, .r = 0, .g = 0, .b = 255}, // bright blue
|
{.r = 0, .g = 0, .b = 255, .a = 255}, // bright blue
|
||||||
{.a = 255, .r = 255, .g = 0, .b = 0}, // bright red
|
{.r = 255, .g = 0, .b = 0, .a = 255}, // bright red
|
||||||
{.a = 255, .r = 255, .g = 0, .b = 255}, // bright magenta
|
{.r = 255, .g = 0, .b = 255, .a = 255}, // bright magenta
|
||||||
{.a = 255, .r = 0, .g = 255, .b = 0}, // bright green
|
{.r = 0, .g = 255, .b = 0, .a = 255}, // bright green
|
||||||
{.a = 255, .r = 0, .g = 255, .b = 255}, // bright cyan
|
{.r = 0, .g = 255, .b = 255, .a = 255}, // bright cyan
|
||||||
{.a = 255, .r = 255, .g = 255, .b = 0}, // bright yellow
|
{.r = 255, .g = 255, .b = 0, .a = 255}, // bright yellow
|
||||||
{.a = 255, .r = 255, .g = 255, .b = 255} // bright white
|
{.r = 255, .g = 255, .b = 255, .a = 255} // bright white
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t block[8 * 8 * 4];
|
uint8_t block[8 * 8 * 4];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ZX has one bit per pixel, but can assign two colours to an 8x8 block. The two colours must
|
* The ZX has one bit per pixel, but can assign two colours to an 8x8 block. The
|
||||||
* both be 'regular' or 'bright'. Black exists as both regular and bright.
|
* two colours must both be 'regular' or 'bright'. Black exists as both regular
|
||||||
|
* and bright.
|
||||||
*/
|
*/
|
||||||
RawImage zx_quantize(std::string rawimage, int image_width, int image_height, float dithering) {
|
RawImage zx_quantize(std::string rawimage, int image_width, int image_height, float dithering) {
|
||||||
const uint8_t* image_buffer = (uint8_t*) rawimage.c_str();
|
const uint8_t* image_buffer = (uint8_t*)rawimage.c_str();
|
||||||
int size = image_width * image_height;
|
int size = image_width * image_height;
|
||||||
int bytes_per_pixel = 4;
|
int bytes_per_pixel = 4;
|
||||||
result = (uint8_t*) malloc(size * bytes_per_pixel);
|
result = (uint8_t*)malloc(size * bytes_per_pixel);
|
||||||
uint8_t* image8bit = (uint8_t*) malloc(8 * 8);
|
uint8_t* image8bit = (uint8_t*)malloc(8 * 8);
|
||||||
|
|
||||||
// For each 8x8 grid
|
// For each 8x8 grid
|
||||||
for (int block_start_y = 0; block_start_y < image_height; block_start_y += 8) {
|
for (int block_start_y = 0; block_start_y < image_height; block_start_y += 8) {
|
||||||
@@ -99,7 +98,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
int block_width = 8;
|
int block_width = 8;
|
||||||
int block_height = 8;
|
int block_height = 8;
|
||||||
|
|
||||||
// If the block hangs off the right/bottom of the image dimensions, make it smaller to fit.
|
// If the block hangs off the right/bottom of the image dimensions, make
|
||||||
|
// it smaller to fit.
|
||||||
if (block_start_y + block_height > image_height) {
|
if (block_start_y + block_height > image_height) {
|
||||||
block_height = image_height - block_start_y;
|
block_height = image_height - block_start_y;
|
||||||
}
|
}
|
||||||
@@ -125,12 +125,11 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
for (int color_index = 0; color_index < 15; color_index++) {
|
for (int color_index = 0; color_index < 15; color_index++) {
|
||||||
liq_color color = zx_colors[color_index];
|
liq_color color = zx_colors[color_index];
|
||||||
|
|
||||||
// Using Euclidean distance. LibQuant has better methods, but it requires conversion to
|
// Using Euclidean distance. LibQuant has better methods, but it
|
||||||
// LAB, so I don't think it's worth it.
|
// requires conversion to LAB, so I don't think it's worth it.
|
||||||
int distance =
|
int distance = pow(color.r - image_buffer[pixel_start + 0], 2) +
|
||||||
pow(color.r - image_buffer[pixel_start + 0], 2) +
|
pow(color.g - image_buffer[pixel_start + 1], 2) +
|
||||||
pow(color.g - image_buffer[pixel_start + 1], 2) +
|
pow(color.b - image_buffer[pixel_start + 2], 2);
|
||||||
pow(color.b - image_buffer[pixel_start + 2], 2);
|
|
||||||
|
|
||||||
if (distance < smallest_distance) {
|
if (distance < smallest_distance) {
|
||||||
winning_index = color_index;
|
winning_index = color_index;
|
||||||
@@ -151,7 +150,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
|
|
||||||
for (int color_index = 0; color_index < 15; color_index++) {
|
for (int color_index = 0; color_index < 15; color_index++) {
|
||||||
if (color_popularity[color_index] > highest_popularity) {
|
if (color_popularity[color_index] > highest_popularity) {
|
||||||
// Store this as the most popular pixel, and demote the current values:
|
// Store this as the most popular pixel, and demote the current
|
||||||
|
// values:
|
||||||
third_color_index = second_color_index;
|
third_color_index = second_color_index;
|
||||||
third_highest_popularity = second_highest_popularity;
|
third_highest_popularity = second_highest_popularity;
|
||||||
second_color_index = first_color_index;
|
second_color_index = first_color_index;
|
||||||
@@ -169,8 +169,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZX images can't mix bright and regular colours, except black which appears in both.
|
// ZX images can't mix bright and regular colours, except black which
|
||||||
// Resolve any conflict:
|
// appears in both. Resolve any conflict:
|
||||||
while (1) {
|
while (1) {
|
||||||
// If either colour is black, there's no conflict to resolve.
|
// If either colour is black, there's no conflict to resolve.
|
||||||
if (first_color_index != 0 && second_color_index != 0) {
|
if (first_color_index != 0 && second_color_index != 0) {
|
||||||
@@ -183,12 +183,13 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If, during conflict resolving, we now have two of the same colour (because we initially
|
// If, during conflict resolving, we now have two of the same colour
|
||||||
// selected the bright & regular version of the same colour), retry again with the third
|
// (because we initially selected the bright & regular version of the
|
||||||
// most popular colour.
|
// same colour), retry again with the third most popular colour.
|
||||||
if (first_color_index == second_color_index) {
|
if (first_color_index == second_color_index) {
|
||||||
second_color_index = third_color_index;
|
second_color_index = third_color_index;
|
||||||
} else break;
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quantize
|
// Quantize
|
||||||
@@ -200,13 +201,15 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
liq_image_quantize(image, attr, &res);
|
liq_image_quantize(image, attr, &res);
|
||||||
liq_set_dithering_level(res, dithering);
|
liq_set_dithering_level(res, dithering);
|
||||||
liq_write_remapped_image(res, image, image8bit, size);
|
liq_write_remapped_image(res, image, image8bit, size);
|
||||||
const liq_palette *pal = liq_get_palette(res);
|
const liq_palette* pal = liq_get_palette(res);
|
||||||
|
|
||||||
// Turn palletted image back into an RGBA image, and write it into the full size result image.
|
// Turn palletted image back into an RGBA image, and write it into the
|
||||||
for(int y = 0; y < block_height; y++) {
|
// full size result image.
|
||||||
for(int x = 0; x < block_width; x++) {
|
for (int y = 0; y < block_height; y++) {
|
||||||
|
for (int x = 0; x < block_width; x++) {
|
||||||
int image8BitPos = y * block_width + x;
|
int image8BitPos = y * block_width + x;
|
||||||
int resultStartPos = ((block_start_y + y) * bytes_per_pixel * image_width) + ((block_start_x + x) * bytes_per_pixel);
|
int resultStartPos = ((block_start_y + y) * bytes_per_pixel * image_width) +
|
||||||
|
((block_start_x + x) * bytes_per_pixel);
|
||||||
result[resultStartPos + 0] = pal->entries[image8bit[image8BitPos]].r;
|
result[resultStartPos + 0] = pal->entries[image8bit[image8BitPos]].r;
|
||||||
result[resultStartPos + 1] = pal->entries[image8bit[image8BitPos]].g;
|
result[resultStartPos + 1] = pal->entries[image8bit[image8BitPos]].g;
|
||||||
result[resultStartPos + 2] = pal->entries[image8bit[image8BitPos]].b;
|
result[resultStartPos + 2] = pal->entries[image8bit[image8BitPos]].b;
|
||||||
@@ -221,11 +224,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(image8bit);
|
free(image8bit);
|
||||||
return {
|
return {val(typed_memory_view(image_width * image_height * 4, result)), image_width,
|
||||||
val(typed_memory_view(image_width*image_height*4, result)),
|
image_height};
|
||||||
image_width,
|
|
||||||
image_height
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_result() {
|
void free_result() {
|
||||||
@@ -234,9 +234,9 @@ void free_result() {
|
|||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
class_<RawImage>("RawImage")
|
class_<RawImage>("RawImage")
|
||||||
.property("buffer", &RawImage::buffer)
|
.property("buffer", &RawImage::buffer)
|
||||||
.property("width", &RawImage::width)
|
.property("width", &RawImage::width)
|
||||||
.property("height", &RawImage::height);
|
.property("height", &RawImage::height);
|
||||||
|
|
||||||
function("quantize", &quantize);
|
function("quantize", &quantize);
|
||||||
function("zx_quantize", &zx_quantize);
|
function("zx_quantize", &zx_quantize);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
"name": "imagequant",
|
"name": "imagequant",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "napa",
|
"install": "napa",
|
||||||
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten ./build.sh"
|
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten-upstream ./build.sh"
|
||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"libimagequant": "ImageOptim/libimagequant#2.12.1"
|
"libimagequant": "ImageOptim/libimagequant#2.12.1"
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export OPTIMIZE="-Os"
|
export EM_CACHE="${PWD}/node_modules/.em_cache"
|
||||||
|
export OPTIMIZE="-Os -flto --llvm-lto 1"
|
||||||
export LDFLAGS="${OPTIMIZE}"
|
export LDFLAGS="${OPTIMIZE}"
|
||||||
export CFLAGS="${OPTIMIZE}"
|
export CFLAGS="${OPTIMIZE}"
|
||||||
export CPPFLAGS="${OPTIMIZE}"
|
export CPPFLAGS="${OPTIMIZE}"
|
||||||
@@ -15,9 +16,9 @@ echo "Compiling mozjpeg"
|
|||||||
echo "============================================="
|
echo "============================================="
|
||||||
(
|
(
|
||||||
cd node_modules/mozjpeg
|
cd node_modules/mozjpeg
|
||||||
autoreconf -fiv
|
autoreconf -iv
|
||||||
emconfigure ./configure --without-simd
|
emconfigure ./configure -C --without-simd
|
||||||
emmake make libjpeg.la
|
emmake make libjpeg.la rdswitch.o -j`nproc`
|
||||||
)
|
)
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling mozjpeg done"
|
echo "Compiling mozjpeg done"
|
||||||
@@ -30,18 +31,16 @@ echo "============================================="
|
|||||||
emcc \
|
emcc \
|
||||||
--bind \
|
--bind \
|
||||||
${OPTIMIZE} \
|
${OPTIMIZE} \
|
||||||
-s WASM=1 \
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s 'EXPORT_NAME="mozjpeg_enc"' \
|
-s 'EXPORT_NAME="mozjpeg_enc"' \
|
||||||
-I node_modules/mozjpeg \
|
-I node_modules/mozjpeg \
|
||||||
-o ./mozjpeg_enc.js \
|
-o ./mozjpeg_enc.js \
|
||||||
-Wno-deprecated-register \
|
-std=c++11 \
|
||||||
-Wno-writable-strings \
|
|
||||||
node_modules/mozjpeg/rdswitch.c \
|
|
||||||
-x c++ -std=c++11 \
|
|
||||||
mozjpeg_enc.cpp \
|
mozjpeg_enc.cpp \
|
||||||
node_modules/mozjpeg/.libs/libjpeg.a
|
node_modules/mozjpeg/.libs/libjpeg.a \
|
||||||
|
node_modules/mozjpeg/rdswitch.o
|
||||||
)
|
)
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling wasm bindings done"
|
echo "Compiling wasm bindings done"
|
||||||
@@ -49,5 +48,5 @@ echo "============================================="
|
|||||||
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
echo "Did you update your docker image?"
|
echo "Did you update your docker image?"
|
||||||
echo "Run \`docker pull trzeci/emscripten\`"
|
echo "Run \`docker pull trzeci/emscripten-upstream\`"
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
#include "cdjpeg.h"
|
#include "cdjpeg.h"
|
||||||
|
}
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro hackery to turn it
|
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro
|
||||||
// into a string. More details here: https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
// hackery to turn it into a string. More details here:
|
||||||
|
// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) str(s)
|
||||||
#define str(s) #s
|
#define str(s) #s
|
||||||
|
|
||||||
@@ -39,8 +43,8 @@ int version() {
|
|||||||
char buffer[] = xstr(MOZJPEG_VERSION);
|
char buffer[] = xstr(MOZJPEG_VERSION);
|
||||||
int version = 0;
|
int version = 0;
|
||||||
int last_index = 0;
|
int last_index = 0;
|
||||||
for(int i = 0; i < strlen(buffer); i++) {
|
for (int i = 0; i < strlen(buffer); i++) {
|
||||||
if(buffer[i] == '.') {
|
if (buffer[i] == '.') {
|
||||||
buffer[i] = '\0';
|
buffer[i] = '\0';
|
||||||
version = version << 8 | atoi(&buffer[last_index]);
|
version = version << 8 | atoi(&buffer[last_index]);
|
||||||
buffer[i] = '.';
|
buffer[i] = '.';
|
||||||
@@ -55,13 +59,12 @@ uint8_t* last_result;
|
|||||||
struct jpeg_compress_struct cinfo;
|
struct jpeg_compress_struct cinfo;
|
||||||
|
|
||||||
val encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts) {
|
val encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts) {
|
||||||
uint8_t* image_buffer = (uint8_t*) image_in.c_str();
|
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||||
|
|
||||||
// The code below is basically the `write_JPEG_file` function from
|
// The code below is basically the `write_JPEG_file` function from
|
||||||
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
||||||
// I just write to memory instead of a file.
|
// I just write to memory instead of a file.
|
||||||
|
|
||||||
|
|
||||||
/* This struct contains the JPEG compression parameters and pointers to
|
/* This struct contains the JPEG compression parameters and pointers to
|
||||||
* working space (which is allocated as needed by the JPEG library).
|
* working space (which is allocated as needed by the JPEG library).
|
||||||
* It is possible to have several such structures, representing multiple
|
* It is possible to have several such structures, representing multiple
|
||||||
@@ -78,8 +81,8 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
*/
|
*/
|
||||||
struct jpeg_error_mgr jerr;
|
struct jpeg_error_mgr jerr;
|
||||||
/* More stuff */
|
/* More stuff */
|
||||||
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
||||||
int row_stride; /* physical row width in image buffer */
|
int row_stride; /* physical row width in image buffer */
|
||||||
uint8_t* output;
|
uint8_t* output;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
@@ -113,17 +116,17 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
/* First we supply a description of the input image.
|
/* First we supply a description of the input image.
|
||||||
* Four fields of the cinfo struct must be filled in:
|
* Four fields of the cinfo struct must be filled in:
|
||||||
*/
|
*/
|
||||||
cinfo.image_width = image_width; /* image width and height, in pixels */
|
cinfo.image_width = image_width; /* image width and height, in pixels */
|
||||||
cinfo.image_height = image_height;
|
cinfo.image_height = image_height;
|
||||||
cinfo.input_components = 4; /* # of color components per pixel */
|
cinfo.input_components = 4; /* # of color components per pixel */
|
||||||
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
||||||
/* Now use the library's routine to set default compression parameters.
|
/* Now use the library's routine to set default compression parameters.
|
||||||
* (You must set at least cinfo.in_color_space before calling this,
|
* (You must set at least cinfo.in_color_space before calling this,
|
||||||
* since the defaults depend on the source color space.)
|
* since the defaults depend on the source color space.)
|
||||||
*/
|
*/
|
||||||
jpeg_set_defaults(&cinfo);
|
jpeg_set_defaults(&cinfo);
|
||||||
|
|
||||||
jpeg_set_colorspace(&cinfo, (J_COLOR_SPACE) opts.color_space);
|
jpeg_set_colorspace(&cinfo, (J_COLOR_SPACE)opts.color_space);
|
||||||
|
|
||||||
if (opts.quant_table != -1) {
|
if (opts.quant_table != -1) {
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
||||||
@@ -143,17 +146,17 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
||||||
|
|
||||||
// A little hacky to build a string for this, but it means we can use set_quality_ratings which
|
// A little hacky to build a string for this, but it means we can use
|
||||||
// does some useful heuristic stuff.
|
// set_quality_ratings which does some useful heuristic stuff.
|
||||||
std::string quality_str = std::to_string(opts.quality);
|
std::string quality_str = std::to_string(opts.quality);
|
||||||
|
|
||||||
if (opts.separate_chroma_quality && opts.color_space == JCS_YCbCr) {
|
if (opts.separate_chroma_quality && opts.color_space == JCS_YCbCr) {
|
||||||
quality_str += "," + std::to_string(opts.chroma_quality);
|
quality_str += "," + std::to_string(opts.chroma_quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *pqual = quality_str.c_str();
|
char const* pqual = quality_str.c_str();
|
||||||
|
|
||||||
set_quality_ratings(&cinfo, (char*) pqual, opts.baseline);
|
set_quality_ratings(&cinfo, (char*)pqual, opts.baseline);
|
||||||
|
|
||||||
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
||||||
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
||||||
@@ -188,8 +191,8 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
* Here the array is only one element long, but you could pass
|
* Here the array is only one element long, but you could pass
|
||||||
* more than one scanline at a time if that's more convenient.
|
* more than one scanline at a time if that's more convenient.
|
||||||
*/
|
*/
|
||||||
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
|
row_pointer[0] = &image_buffer[cinfo.next_scanline * row_stride];
|
||||||
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 6: Finish compression */
|
/* Step 6: Finish compression */
|
||||||
@@ -210,23 +213,22 @@ void free_result() {
|
|||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<MozJpegOptions>("MozJpegOptions")
|
value_object<MozJpegOptions>("MozJpegOptions")
|
||||||
.field("quality", &MozJpegOptions::quality)
|
.field("quality", &MozJpegOptions::quality)
|
||||||
.field("baseline", &MozJpegOptions::baseline)
|
.field("baseline", &MozJpegOptions::baseline)
|
||||||
.field("arithmetic", &MozJpegOptions::arithmetic)
|
.field("arithmetic", &MozJpegOptions::arithmetic)
|
||||||
.field("progressive", &MozJpegOptions::progressive)
|
.field("progressive", &MozJpegOptions::progressive)
|
||||||
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
||||||
.field("smoothing", &MozJpegOptions::smoothing)
|
.field("smoothing", &MozJpegOptions::smoothing)
|
||||||
.field("color_space", &MozJpegOptions::color_space)
|
.field("color_space", &MozJpegOptions::color_space)
|
||||||
.field("quant_table", &MozJpegOptions::quant_table)
|
.field("quant_table", &MozJpegOptions::quant_table)
|
||||||
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
||||||
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
||||||
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
||||||
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
||||||
.field("chroma_subsample", &MozJpegOptions::chroma_subsample)
|
.field("chroma_subsample", &MozJpegOptions::chroma_subsample)
|
||||||
.field("auto_subsample", &MozJpegOptions::auto_subsample)
|
.field("auto_subsample", &MozJpegOptions::auto_subsample)
|
||||||
.field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality)
|
.field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality)
|
||||||
.field("chroma_quality", &MozJpegOptions::chroma_quality)
|
.field("chroma_quality", &MozJpegOptions::chroma_quality);
|
||||||
;
|
|
||||||
|
|
||||||
function("version", &version);
|
function("version", &version);
|
||||||
function("encode", &encode);
|
function("encode", &encode);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
"name": "mozjpeg_enc",
|
"name": "mozjpeg_enc",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "napa",
|
"install": "napa",
|
||||||
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten ./build.sh"
|
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten-upstream ./build.sh"
|
||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"mozjpeg": "mozilla/mozjpeg#v3.3.1"
|
"mozjpeg": "mozilla/mozjpeg#v3.3.1"
|
||||||
|
|||||||
2
codecs/optipng/.gitignore
vendored
2
codecs/optipng/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
build/
|
|
||||||
*.o
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# OptiPNG
|
|
||||||
|
|
||||||
- Source: <http://optipng.sourceforge.net/>
|
|
||||||
- Version: v0.7.7
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- Docker
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
See `example.html`
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### `int version()`
|
|
||||||
|
|
||||||
Returns the version of optipng as a number. va.b.c is encoded as 0x0a0b0c
|
|
||||||
|
|
||||||
### `ArrayBuffer compress(std::string buffer, {level})`;
|
|
||||||
|
|
||||||
`compress` will re-compress the given PNG image via `buffer`. `level` is a number between 0 and 7.
|
|
||||||
|
|
||||||
### `void free_result()`
|
|
||||||
|
|
||||||
Frees the result created by `compress()`.
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
export OPTIMIZE="-Os"
|
|
||||||
export PREFIX="/src/build"
|
|
||||||
export CFLAGS="${OPTIMIZE} -I${PREFIX}/include/"
|
|
||||||
export CPPFLAGS="${OPTIMIZE} -I${PREFIX}/include/"
|
|
||||||
export LDFLAGS="${OPTIMIZE} -L${PREFIX}/lib/"
|
|
||||||
|
|
||||||
apt-get update
|
|
||||||
apt-get install -qqy autoconf libtool
|
|
||||||
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling zlib"
|
|
||||||
echo "============================================="
|
|
||||||
test -n "$SKIP_ZLIB" || (
|
|
||||||
cd node_modules/zlib
|
|
||||||
emconfigure ./configure --prefix=${PREFIX}/
|
|
||||||
emmake make
|
|
||||||
emmake make install
|
|
||||||
)
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling zlib done"
|
|
||||||
echo "============================================="
|
|
||||||
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling libpng"
|
|
||||||
echo "============================================="
|
|
||||||
test -n "$SKIP_LIBPNG" || (
|
|
||||||
cd node_modules/libpng
|
|
||||||
autoreconf -i
|
|
||||||
emconfigure ./configure --with-zlib-prefix=${PREFIX}/ --prefix=${PREFIX}/
|
|
||||||
emmake make
|
|
||||||
emmake make install
|
|
||||||
)
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling libpng done"
|
|
||||||
echo "============================================="
|
|
||||||
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling optipng"
|
|
||||||
echo "============================================="
|
|
||||||
(
|
|
||||||
emcc \
|
|
||||||
${OPTIMIZE} \
|
|
||||||
-Wno-implicit-function-declaration \
|
|
||||||
-I ${PREFIX}/include \
|
|
||||||
-I node_modules/optipng/src/opngreduc \
|
|
||||||
-I node_modules/optipng/src/pngxtern \
|
|
||||||
-I node_modules/optipng/src/cexcept \
|
|
||||||
-I node_modules/optipng/src/gifread \
|
|
||||||
-I node_modules/optipng/src/pnmio \
|
|
||||||
-I node_modules/optipng/src/minitiff \
|
|
||||||
--std=c99 -c \
|
|
||||||
node_modules/optipng/src/opngreduc/*.c \
|
|
||||||
node_modules/optipng/src/pngxtern/*.c \
|
|
||||||
node_modules/optipng/src/gifread/*.c \
|
|
||||||
node_modules/optipng/src/minitiff/*.c \
|
|
||||||
node_modules/optipng/src/pnmio/*.c \
|
|
||||||
node_modules/optipng/src/optipng/*.c
|
|
||||||
|
|
||||||
emcc \
|
|
||||||
--bind \
|
|
||||||
${OPTIMIZE} \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME="optipng"' \
|
|
||||||
-I ${PREFIX}/include \
|
|
||||||
-I node_modules/optipng/src/opngreduc \
|
|
||||||
-I node_modules/optipng/src/pngxtern \
|
|
||||||
-I node_modules/optipng/src/cexcept \
|
|
||||||
-I node_modules/optipng/src/gifread \
|
|
||||||
-I node_modules/optipng/src/pnmio \
|
|
||||||
-I node_modules/optipng/src/minitiff \
|
|
||||||
-o "optipng.js" \
|
|
||||||
--std=c++11 \
|
|
||||||
optipng.cpp \
|
|
||||||
*.o \
|
|
||||||
${PREFIX}/lib/libz.so ${PREFIX}/lib/libpng.a
|
|
||||||
)
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling optipng done"
|
|
||||||
echo "============================================="
|
|
||||||
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
||||||
echo "Did you update your docker image?"
|
|
||||||
echo "Run \`docker pull trzeci/emscripten\`"
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<script src='optipng.js'></script>
|
|
||||||
<script>
|
|
||||||
const Module = optipng();
|
|
||||||
|
|
||||||
Module.onRuntimeInitialized = async _ => {
|
|
||||||
console.log('Version:', Module.version().toString(16));
|
|
||||||
const image = await fetch('../example_palette.png').then(r => r.arrayBuffer());
|
|
||||||
const newImage = Module.compress(image, {level: 3});
|
|
||||||
console.log('done');
|
|
||||||
Module.free_result();
|
|
||||||
|
|
||||||
console.log(`Old size: ${image.byteLength}, new size: ${newImage.byteLength} (${newImage.byteLength/image.byteLength*100}%)`);
|
|
||||||
const blobURL = URL.createObjectURL(new Blob([newImage], {type: 'image/png'}));
|
|
||||||
const img = document.createElement('img');
|
|
||||||
img.src = blobURL;
|
|
||||||
document.body.appendChild(img);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#include "emscripten/bind.h"
|
|
||||||
#include "emscripten/val.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
using namespace emscripten;
|
|
||||||
|
|
||||||
extern "C" int main(int argc, char *argv[]);
|
|
||||||
|
|
||||||
int version() {
|
|
||||||
// FIXME (@surma): Haven’t found a version in optipng :(
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OptiPngOpts {
|
|
||||||
int level;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t* result;
|
|
||||||
val compress(std::string png, OptiPngOpts opts) {
|
|
||||||
remove("input.png");
|
|
||||||
remove("output.png");
|
|
||||||
FILE* infile = fopen("input.png", "wb");
|
|
||||||
fwrite(png.c_str(), png.length(), 1, infile);
|
|
||||||
fflush(infile);
|
|
||||||
fclose(infile);
|
|
||||||
|
|
||||||
char optlevel[8];
|
|
||||||
sprintf(&optlevel[0], "-o%d", opts.level);
|
|
||||||
char* args[] = {"optipng", optlevel, "-out", "output.png", "input.png"};
|
|
||||||
main(5, args);
|
|
||||||
|
|
||||||
FILE *outfile = fopen("output.png", "rb");
|
|
||||||
fseek(outfile, 0, SEEK_END);
|
|
||||||
int fsize = ftell(outfile);
|
|
||||||
result = (uint8_t*) malloc(fsize);
|
|
||||||
fseek(outfile, 0, SEEK_SET);
|
|
||||||
fread(result, fsize, 1, outfile);
|
|
||||||
return val(typed_memory_view(fsize, result));
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_result() {
|
|
||||||
free(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
|
||||||
value_object<OptiPngOpts>("OptiPngOpts")
|
|
||||||
.field("level", &OptiPngOpts::level);
|
|
||||||
|
|
||||||
function("version", &version);
|
|
||||||
function("compress", &compress);
|
|
||||||
function("free_result", &free_result);
|
|
||||||
}
|
|
||||||
10
codecs/optipng/optipng.d.ts
vendored
10
codecs/optipng/optipng.d.ts
vendored
@@ -1,10 +0,0 @@
|
|||||||
import {EncodeOptions} from "src/codecs/optipng/encoder";
|
|
||||||
|
|
||||||
export interface OptiPngModule extends EmscriptenWasm.Module {
|
|
||||||
compress(data: BufferSource, opts: EncodeOptions): Uint8Array;
|
|
||||||
free_result(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): OptiPngModule;
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
1457
codecs/optipng/package-lock.json
generated
1457
codecs/optipng/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "optipng",
|
|
||||||
"scripts": {
|
|
||||||
"install": "tar-dependency install && napa",
|
|
||||||
"build": "npm run build:wasm",
|
|
||||||
"build:wasm": "docker run --rm -v $(pwd):/src -e SKIP_ZLIB=\"${SKIP_ZLIB}\" -e SKIP_LIBPNG=\"${SKIP_LIBPNG}\" trzeci/emscripten ./build.sh"
|
|
||||||
},
|
|
||||||
"tarDependencies": {
|
|
||||||
"node_modules/optipng": {
|
|
||||||
"url": "https://netcologne.dl.sourceforge.net/project/optipng/OptiPNG/optipng-0.7.7/optipng-0.7.7.tar.gz",
|
|
||||||
"strip": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"napa": {
|
|
||||||
"libpng": "emscripten-ports/libpng",
|
|
||||||
"zlib": "emscripten-ports/zlib"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"napa": "3.0.0",
|
|
||||||
"tar-dependency": "0.0.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
codecs/oxipng/.gitignore
vendored
4
codecs/oxipng/.gitignore
vendored
@@ -1,5 +1 @@
|
|||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
|
||||||
Cargo.lock
|
|
||||||
bin/
|
|
||||||
wasm-pack.log
|
|
||||||
|
|||||||
502
codecs/oxipng/Cargo.lock
generated
Normal file
502
codecs/oxipng/Cargo.lock
generated
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "adler32"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-vec"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "build_const"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudflare-zlib"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cloudflare-zlib-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudflare-zlib-sys"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deflate"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "image"
|
||||||
|
version = "0.23.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-iter 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-rational 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"png 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inflate"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.68"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libdeflater"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "maybe-uninit"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-iter"
|
||||||
|
version = "0.1.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxipng"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"oxipng 2.3.0 (git+https://github.com/shssoichiro/oxipng.git)",
|
||||||
|
"wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxipng"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "git+https://github.com/shssoichiro/oxipng.git#ec8ecf5a800dfb41359d9cf41eed8a730062b9a8"
|
||||||
|
dependencies = [
|
||||||
|
"bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cloudflare-zlib 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libdeflater 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rgb 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "png"
|
||||||
|
version = "0.16.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"deflate 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rgb"
|
||||||
|
version = "0.8.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typed-arena"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zopfli"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typed-arena 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
||||||
|
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||||
|
"checksum bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4523a10839ffae575fb08aa3423026c8cb4687eef43952afb956229d4f246f7"
|
||||||
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||||
|
"checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
|
||||||
|
"checksum bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
|
||||||
|
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||||
|
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||||
|
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
"checksum cloudflare-zlib 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed63a019d55bacd15cadcbcb96bf41b16281417fff393bdb55fa84255fe4b9"
|
||||||
|
"checksum cloudflare-zlib-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e195cb274a0d6ee87e718838a09baecd7cbc9f6075dac256a84cb5842739c06"
|
||||||
|
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||||
|
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||||
|
"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||||
|
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||||
|
"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
|
||||||
|
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||||
|
"checksum deflate 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "050ef6de42a33903b30a7497b76b40d3d58691d4d3eec355348c122444a388f0"
|
||||||
|
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||||
|
"checksum hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
|
||||||
|
"checksum image 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9062b90712d25bc6bb165d110aa59c6b47c849246e341e7b86a98daff9d49f60"
|
||||||
|
"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
|
||||||
|
"checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||||
|
"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||||
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
"checksum libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||||
|
"checksum libdeflater 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246"
|
||||||
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
|
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||||
|
"checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
|
||||||
|
"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
|
||||||
|
"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
|
||||||
|
"checksum num-iter 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
|
||||||
|
"checksum num-rational 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||||
|
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
|
||||||
|
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
|
||||||
|
"checksum oxipng 2.3.0 (git+https://github.com/shssoichiro/oxipng.git)" = "<none>"
|
||||||
|
"checksum png 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46060468187c21c00ffa2a920690b29997d7fd543f5a4d400461e4a7d4fccde8"
|
||||||
|
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||||
|
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||||
|
"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
|
||||||
|
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
||||||
|
"checksum rgb 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "a85b83fd629b0ce765f45316774fa6aaa95947fd74c8e4bbf3c6d1e349701d95"
|
||||||
|
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||||
|
"checksum typed-arena 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
||||||
|
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
"checksum wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
|
||||||
|
"checksum wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
|
||||||
|
"checksum wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
|
||||||
|
"checksum wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
|
||||||
|
"checksum wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
|
||||||
|
"checksum zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4079b79464426ade2a1b0177fb0ce8396ba6b4084267407e333573c666073964"
|
||||||
@@ -1,36 +1,21 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "test"
|
name = "oxipng"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Surma <surma@surma.link>"]
|
authors = ["Ingvar Stepanyan <me@rreverser.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "lib.rs"
|
crate-type = ["cdylib"]
|
||||||
crate-type = ["cdylib", "rlib"]
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["console_error_panic_hook"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = "0.1.2"
|
oxipng = { version = "2.3.0", default-features = false }
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2.48"
|
||||||
oxipng = "2.2.0"
|
log = { version = "0.4", features = ["release_max_level_off"] }
|
||||||
|
|
||||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
|
||||||
# logging them with `console.error`. This is great for development, but requires
|
|
||||||
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
|
||||||
# code size when deploying.
|
|
||||||
console_error_panic_hook = { version = "0.1.1", optional = true }
|
|
||||||
|
|
||||||
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
|
||||||
# compared to the default allocator's ~10K. It is slower than the default
|
|
||||||
# allocator, however.
|
|
||||||
#
|
|
||||||
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
|
||||||
wee_alloc = { version = "0.4.2", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
wasm-bindgen-test = "0.2"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
# Tell `rustc` to optimize for small code size.
|
lto = true
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
oxipng = { git = "https://github.com/shssoichiro/oxipng.git", branch = "master" }
|
||||||
|
|||||||
12
codecs/oxipng/Dockerfile
Normal file
12
codecs/oxipng/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
RUN mkdir /opt/wasi-sdk && \
|
||||||
|
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-8/wasi-sdk-8.0-linux.tar.gz | tar -xzf - -C /opt/wasi-sdk --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/wabt:/opt/wasi-sdk/bin:${PATH}"
|
||||||
|
WORKDIR /src
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
# 🦀🕸️ `wasm-pack-template`
|
|
||||||
|
|
||||||
A template for kick starting a Rust and WebAssembly project using
|
|
||||||
[`wasm-pack`](https://github.com/rustwasm/wasm-pack).
|
|
||||||
|
|
||||||
This template is designed for compiling Rust libraries into WebAssembly and
|
|
||||||
publishing the resulting package to NPM.
|
|
||||||
|
|
||||||
* Want to use the published NPM package in a Website? [Check out
|
|
||||||
`create-wasm-app`.](https://github.com/rustwasm/create-wasm-app)
|
|
||||||
* Want to make a monorepo-style Website without publishing to NPM? Check out
|
|
||||||
[`rust-webpack-template`](https://github.com/rustwasm/rust-webpack-template)
|
|
||||||
and/or
|
|
||||||
[`rust-parcel-template`](https://github.com/rustwasm/rust-parcel-template).
|
|
||||||
|
|
||||||
## 🔋 Batteries Included
|
|
||||||
|
|
||||||
* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating
|
|
||||||
between WebAssembly and JavaScript.
|
|
||||||
* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook)
|
|
||||||
for logging panic messages to the developer console.
|
|
||||||
* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized
|
|
||||||
for small code size.
|
|
||||||
|
|
||||||
## 🚴 Usage
|
|
||||||
|
|
||||||
### 🐑 Use `cargo generate` to Clone this Template
|
|
||||||
|
|
||||||
[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate)
|
|
||||||
|
|
||||||
```
|
|
||||||
cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project
|
|
||||||
cd my-project
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🛠️ Build with `wasm-pack build`
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm-pack build
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔬 Test in Headless Browsers with `wasm-pack test`
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm-pack test --headless --firefox
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🎁 Publish to NPM with `wasm-pack publish`
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm-pack publish
|
|
||||||
```
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
[target.wasm32-unknown-unknown.dependencies]
|
|
||||||
time = {}
|
|
||||||
|
|
||||||
[target.wasm32-unknown-unknown.dependencies.std]
|
|
||||||
features = ["wasm_syscall"]
|
|
||||||
22
codecs/oxipng/build.sh
Normal file
22
codecs/oxipng/build.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
wasm-pack build
|
||||||
|
wasm-strip pkg/oxipng_bg.wasm
|
||||||
|
rm pkg/.gitignore
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-oxipng .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
4
codecs/oxipng/package-lock.json
generated
Normal file
4
codecs/oxipng/package-lock.json
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "oxipng",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
||||||
7
codecs/oxipng/package.json
Normal file
7
codecs/oxipng/package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "oxipng",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-oxipng .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-oxipng ./build.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
# 🦀🕸️ `wasm-pack-template`
|
|
||||||
|
|
||||||
A template for kick starting a Rust and WebAssembly project using
|
|
||||||
[`wasm-pack`](https://github.com/rustwasm/wasm-pack).
|
|
||||||
|
|
||||||
This template is designed for compiling Rust libraries into WebAssembly and
|
|
||||||
publishing the resulting package to NPM.
|
|
||||||
|
|
||||||
* Want to use the published NPM package in a Website? [Check out
|
|
||||||
`create-wasm-app`.](https://github.com/rustwasm/create-wasm-app)
|
|
||||||
* Want to make a monorepo-style Website without publishing to NPM? Check out
|
|
||||||
[`rust-webpack-template`](https://github.com/rustwasm/rust-webpack-template)
|
|
||||||
and/or
|
|
||||||
[`rust-parcel-template`](https://github.com/rustwasm/rust-parcel-template).
|
|
||||||
|
|
||||||
## 🔋 Batteries Included
|
|
||||||
|
|
||||||
* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating
|
|
||||||
between WebAssembly and JavaScript.
|
|
||||||
* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook)
|
|
||||||
for logging panic messages to the developer console.
|
|
||||||
* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized
|
|
||||||
for small code size.
|
|
||||||
|
|
||||||
## 🚴 Usage
|
|
||||||
|
|
||||||
### 🐑 Use `cargo generate` to Clone this Template
|
|
||||||
|
|
||||||
[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate)
|
|
||||||
|
|
||||||
```
|
|
||||||
cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project
|
|
||||||
cd my-project
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🛠️ Build with `wasm-pack build`
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm-pack build
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🔬 Test in Headless Browsers with `wasm-pack test`
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm-pack test --headless --firefox
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🎁 Publish to NPM with `wasm-pack publish`
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm-pack publish
|
|
||||||
```
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,14 +0,0 @@
|
|||||||
const oxipng = require("./oxipng_wasm");
|
|
||||||
const repl = require("repl");
|
|
||||||
const fs = require("fs");
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
// const img = fs.readFileSync("img.png")
|
|
||||||
// const output = oxipng.compress(img, 0);
|
|
||||||
// fs.writeFileSync("output.png", output);
|
|
||||||
console.log(">>>", oxipng.doit());
|
|
||||||
const r = repl.start("node> ");
|
|
||||||
r.context.i = oxipng;
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
9
codecs/oxipng/pkg/oxipng.d.ts
vendored
9
codecs/oxipng/pkg/oxipng.d.ts
vendored
@@ -1,3 +1,8 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
export function compress(arg0: Uint8Array, arg1: number): Uint8Array;
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @param {number} level
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||||
|
|||||||
@@ -1,73 +1,60 @@
|
|||||||
/* tslint:disable */
|
import * as wasm from './oxipng_bg.wasm';
|
||||||
var wasm;
|
|
||||||
|
|
||||||
const TextDecoder = require('util').TextDecoder;
|
const lTextDecoder = typeof TextDecoder === 'undefined' ? require('util').TextDecoder : TextDecoder;
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8');
|
let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
|
||||||
let cachegetUint8Memory = null;
|
cachedTextDecoder.decode();
|
||||||
function getUint8Memory() {
|
|
||||||
if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) {
|
let cachegetUint8Memory0 = null;
|
||||||
cachegetUint8Memory = new Uint8Array(wasm.memory.buffer);
|
function getUint8Memory0() {
|
||||||
|
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||||
}
|
}
|
||||||
return cachegetUint8Memory;
|
return cachegetUint8Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringFromWasm(ptr, len) {
|
function getStringFromWasm0(ptr, len) {
|
||||||
return cachedTextDecoder.decode(getUint8Memory().subarray(ptr, ptr + len));
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.__wbg_log_64e6f53d8e6d5db5 = function(arg0, arg1) {
|
|
||||||
let varg0 = getStringFromWasm(arg0, arg1);
|
|
||||||
console.log(varg0);
|
|
||||||
};
|
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
function passArray8ToWasm(arg) {
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
const ptr = wasm.__wbindgen_malloc(arg.length * 1);
|
const ptr = malloc(arg.length * 1);
|
||||||
getUint8Memory().set(arg, ptr / 1);
|
getUint8Memory0().set(arg, ptr / 1);
|
||||||
WASM_VECTOR_LEN = arg.length;
|
WASM_VECTOR_LEN = arg.length;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayU8FromWasm(ptr, len) {
|
let cachegetInt32Memory0 = null;
|
||||||
return getUint8Memory().subarray(ptr / 1, ptr / 1 + len);
|
function getInt32Memory0() {
|
||||||
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachedGlobalArgumentPtr = null;
|
function getArrayU8FromWasm0(ptr, len) {
|
||||||
function globalArgumentPtr() {
|
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||||
if (cachedGlobalArgumentPtr === null) {
|
|
||||||
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr();
|
|
||||||
}
|
|
||||||
return cachedGlobalArgumentPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachegetUint32Memory = null;
|
|
||||||
function getUint32Memory() {
|
|
||||||
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
|
||||||
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
|
||||||
}
|
|
||||||
return cachegetUint32Memory;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} arg0
|
* @param {Uint8Array} data
|
||||||
* @param {number} arg1
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
module.exports.compress = function(arg0, arg1) {
|
export function optimise(data, level) {
|
||||||
const ptr0 = passArray8ToWasm(arg0);
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
const retptr = globalArgumentPtr();
|
wasm.optimise(8, ptr0, len0, level);
|
||||||
wasm.compress(retptr, ptr0, len0, arg1);
|
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||||
const mem = getUint32Memory();
|
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||||
const rustptr = mem[retptr / 4];
|
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||||
const rustlen = mem[retptr / 4 + 1];
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
|
return v1;
|
||||||
const realRet = getArrayU8FromWasm(rustptr, rustlen).slice();
|
}
|
||||||
wasm.__wbindgen_free(rustptr, rustlen * 1);
|
|
||||||
return realRet;
|
|
||||||
|
|
||||||
|
export const __wbindgen_throw = function(arg0, arg1) {
|
||||||
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
};
|
||||||
|
|
||||||
wasm = require('./oxipng_bg');
|
|
||||||
|
|||||||
6
codecs/oxipng/pkg/oxipng_bg.d.ts
vendored
6
codecs/oxipng/pkg/oxipng_bg.d.ts
vendored
@@ -1,6 +1,8 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
export const memory: WebAssembly.Memory;
|
export const memory: WebAssembly.Memory;
|
||||||
export function __wbindgen_global_argument_ptr(): number;
|
export function optimise(a: number, b: number, c: number, d: number): void;
|
||||||
export function compress(a: number, b: number, c: number, d: number): void;
|
export function malloc(a: number): number;
|
||||||
|
export function free(a: number): void;
|
||||||
export function __wbindgen_malloc(a: number): number;
|
export function __wbindgen_malloc(a: number): number;
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
const path = require('path').join(__dirname, 'oxipng_bg.wasm');
|
|
||||||
const bytes = require('fs').readFileSync(path);
|
|
||||||
let imports = {};
|
|
||||||
imports['./oxipng'] = require('./oxipng');
|
|
||||||
|
|
||||||
const wasmModule = new WebAssembly.Module(bytes);
|
|
||||||
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
|
||||||
module.exports = wasmInstance.exports;
|
|
||||||
Binary file not shown.
3
codecs/oxipng/pkg/oxipng_manual.d.ts
vendored
3
codecs/oxipng/pkg/oxipng_manual.d.ts
vendored
@@ -1,3 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
export function compress(arg0: Uint8Array, arg1: number): Promise<Uint8Array>;
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
import wasmUrl from './oxipng_bg.wasm';
|
|
||||||
|
|
||||||
let wasm;
|
|
||||||
const instancePromise = WebAssembly.instantiateStreaming(fetch(wasmUrl), {
|
|
||||||
"./oxipng": {__wbg_log_64e6f53d8e6d5db5}
|
|
||||||
});
|
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8');
|
|
||||||
|
|
||||||
let cachegetUint8Memory = null;
|
|
||||||
function getUint8Memory() {
|
|
||||||
if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) {
|
|
||||||
cachegetUint8Memory = new Uint8Array(wasm.memory.buffer);
|
|
||||||
}
|
|
||||||
return cachegetUint8Memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStringFromWasm(ptr, len) {
|
|
||||||
return cachedTextDecoder.decode(getUint8Memory().subarray(ptr, ptr + len));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function __wbg_log_64e6f53d8e6d5db5(arg0, arg1) {
|
|
||||||
let varg0 = getStringFromWasm(arg0, arg1);
|
|
||||||
console.log(varg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
|
||||||
|
|
||||||
function passArray8ToWasm(arg) {
|
|
||||||
const ptr = wasm.__wbindgen_malloc(arg.length * 1);
|
|
||||||
getUint8Memory().set(arg, ptr / 1);
|
|
||||||
WASM_VECTOR_LEN = arg.length;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getArrayU8FromWasm(ptr, len) {
|
|
||||||
return getUint8Memory().subarray(ptr / 1, ptr / 1 + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachedGlobalArgumentPtr = null;
|
|
||||||
function globalArgumentPtr() {
|
|
||||||
if (cachedGlobalArgumentPtr === null) {
|
|
||||||
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr();
|
|
||||||
}
|
|
||||||
return cachedGlobalArgumentPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachegetUint32Memory = null;
|
|
||||||
function getUint32Memory() {
|
|
||||||
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
|
||||||
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
|
||||||
}
|
|
||||||
return cachegetUint32Memory;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param {Uint8Array} arg0
|
|
||||||
* @param {number} arg1
|
|
||||||
* @returns {Uint8Array}
|
|
||||||
*/
|
|
||||||
export async function compress(arg0, arg1) {
|
|
||||||
wasm = (await instancePromise).instance.exports;
|
|
||||||
debugger;
|
|
||||||
const ptr0 = passArray8ToWasm(arg0);
|
|
||||||
const len0 = WASM_VECTOR_LEN;
|
|
||||||
const retptr = globalArgumentPtr();
|
|
||||||
wasm.compress(retptr, ptr0, len0, arg1);
|
|
||||||
const mem = getUint32Memory();
|
|
||||||
const rustptr = mem[retptr / 4];
|
|
||||||
const rustlen = mem[retptr / 4 + 1];
|
|
||||||
|
|
||||||
const realRet = getArrayU8FromWasm(rustptr, rustlen).slice();
|
|
||||||
wasm.__wbindgen_free(rustptr, rustlen * 1);
|
|
||||||
return realRet;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
3
codecs/oxipng/pkg/oxipng_wasm.d.ts
vendored
3
codecs/oxipng/pkg/oxipng_wasm.d.ts
vendored
@@ -1,3 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
export function doit(): number;
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
var wasm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
module.exports.doit = function() {
|
|
||||||
return wasm.doit();
|
|
||||||
};
|
|
||||||
|
|
||||||
wasm = require('./oxipng_wasm_bg');
|
|
||||||
3
codecs/oxipng/pkg/oxipng_wasm_bg.d.ts
vendored
3
codecs/oxipng/pkg/oxipng_wasm_bg.d.ts
vendored
@@ -1,3 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
export const memory: WebAssembly.Memory;
|
|
||||||
export function doit(): number;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
const path = require('path').join(__dirname, 'oxipng_wasm_bg.wasm');
|
|
||||||
const bytes = require('fs').readFileSync(path);
|
|
||||||
let imports = {};
|
|
||||||
|
|
||||||
const wasmModule = new WebAssembly.Module(bytes);
|
|
||||||
const wasmInstance = new WebAssembly.Instance(wasmModule, imports);
|
|
||||||
module.exports = wasmInstance.exports;
|
|
||||||
Binary file not shown.
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "oxipng-wasm",
|
"name": "oxipng",
|
||||||
"collaborators": [
|
"collaborators": [
|
||||||
"Surma <surma@surma.link>"
|
"Ingvar Stepanyan <me@rreverser.com>"
|
||||||
],
|
],
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"files": [
|
"files": [
|
||||||
"oxipng_wasm_bg.wasm",
|
"oxipng_bg.wasm",
|
||||||
"oxipng_wasm.js",
|
"oxipng.js",
|
||||||
"oxipng_wasm_bg.js",
|
"oxipng.d.ts"
|
||||||
"oxipng_wasm.d.ts"
|
|
||||||
],
|
],
|
||||||
"main": "oxipng_wasm.js",
|
"module": "oxipng.js",
|
||||||
"types": "oxipng_wasm.d.ts"
|
"types": "oxipng.d.ts",
|
||||||
|
"sideEffects": false
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,10 @@
|
|||||||
extern crate cfg_if;
|
mod malloc_shim;
|
||||||
extern crate wasm_bindgen;
|
|
||||||
// extern crate oxipng;
|
|
||||||
|
|
||||||
mod utils;
|
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use std::time::{Instant};
|
|
||||||
cfg_if! {
|
#[wasm_bindgen(catch)]
|
||||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||||
// allocator.
|
let mut options = oxipng::Options::from_preset(level);
|
||||||
if #[cfg(feature = "wee_alloc")] {
|
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||||
extern crate wee_alloc;
|
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||||
#[global_allocator]
|
|
||||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[wasm_bindgen]
|
|
||||||
// extern {
|
|
||||||
// #[wasm_bindgen(js_namespace = console)]
|
|
||||||
// fn log(s: &str);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[wasm_bindgen]
|
|
||||||
// pub fn compress(img: Vec<u8>, level: u8) -> Vec<u8> {
|
|
||||||
// log(&format!("len: {}, level: {}", img.len(), level));
|
|
||||||
// let mut options = oxipng::Options::from_preset(level);
|
|
||||||
// options.threads = 0;
|
|
||||||
// let result = oxipng::optimize_from_memory(img.as_slice(), &options);
|
|
||||||
// match result {
|
|
||||||
// Ok(v) => v,
|
|
||||||
// Err(e) => e.to_string().as_bytes().to_vec()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn doit() -> u32 {
|
|
||||||
let start = Instant::now();
|
|
||||||
start.elapsed().as_secs() as u32
|
|
||||||
}
|
}
|
||||||
|
|||||||
47
codecs/oxipng/src/malloc_shim.rs
Normal file
47
codecs/oxipng/src/malloc_shim.rs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
//! This is a module that provides `malloc` and `free` for `libdeflate`.
|
||||||
|
//! These implementations are compatible with the standard signatures
|
||||||
|
//! but use Rust allocator instead of including libc one as well.
|
||||||
|
//!
|
||||||
|
//! Rust allocator APIs requires passing size and alignment to the
|
||||||
|
//! `dealloc` function. This is different from C API, which only
|
||||||
|
//! expects a pointer in `free` and expects allocators to take care of
|
||||||
|
//! storing any necessary information elsewhere.
|
||||||
|
//!
|
||||||
|
//! In order to simulate C API, we allocate a `size_and_data_ptr`
|
||||||
|
//! of size `sizeof(usize) + size` where `size` is the requested number
|
||||||
|
//! of bytes. Then, we store `size` at the beginning of the allocated
|
||||||
|
//! chunk (within those `sizeof(usize)` bytes) and return
|
||||||
|
//! `data_ptr = size_and_data_ptr + sizeof(usize)` to the calleer:
|
||||||
|
//!
|
||||||
|
//! [`size`][...actual data]
|
||||||
|
//! -^------------------ `size_and_data_ptr`
|
||||||
|
//! ---------^---------- `data_ptr`
|
||||||
|
//!
|
||||||
|
//! Then, in `free`, the caller gives us `data_ptr`. We can subtract
|
||||||
|
//! `sizeof(usize)` back and get the original `size_and_data_ptr`.
|
||||||
|
//! At this point we can read `size` back and call the Rust `dealloc`
|
||||||
|
//! for the whole allocated chunk.
|
||||||
|
//!
|
||||||
|
//! I've raised an upstream issue to hopefully make this easier in
|
||||||
|
//! future: https://github.com/ebiggers/libdeflate/issues/62
|
||||||
|
|
||||||
|
use std::alloc::*;
|
||||||
|
use std::mem::{align_of, size_of};
|
||||||
|
|
||||||
|
unsafe fn layout_for(size: usize) -> Layout {
|
||||||
|
Layout::from_size_align_unchecked(size_of::<usize>() + size, align_of::<usize>())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 {
|
||||||
|
let size_and_data_ptr = alloc(layout_for(size));
|
||||||
|
*(size_and_data_ptr as *mut usize) = size;
|
||||||
|
size_and_data_ptr.add(size_of::<usize>())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn free(data_ptr: *mut u8) {
|
||||||
|
let size_and_data_ptr = data_ptr.sub(size_of::<usize>());
|
||||||
|
let size = *(size_and_data_ptr as *const usize);
|
||||||
|
dealloc(size_and_data_ptr, layout_for(size))
|
||||||
|
}
|
||||||
1
codecs/oxipng/tmp/.gitignore
vendored
1
codecs/oxipng/tmp/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
target
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[dependencies.std]
|
|
||||||
features = ["wasm_syscall"]
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
I’m trying to activate [the `wasm_syscall` feature][1] in Rust’s stdlib for WebAssembly.
|
|
||||||
|
|
||||||
Here is my `Cargo.toml` and my `Xargo.toml`. But even with this setup the generated wasm file is still hard-coded to panic.
|
|
||||||
|
|
||||||
**HELP?**
|
|
||||||
|
|
||||||
My current command to compile is:
|
|
||||||
|
|
||||||
```
|
|
||||||
xargo build --target wasm32-unknown-unknown --release
|
|
||||||
```
|
|
||||||
|
|
||||||
If you have [`wasm2wat`][2] installed, you can verify the generate code via
|
|
||||||
|
|
||||||
```
|
|
||||||
wasm2wat target/wasm32-unknown-unknown/release/loltest.wasm | grep -A5 perform::
|
|
||||||
```
|
|
||||||
|
|
||||||
[1]: https://github.com/rust-lang/rust/blob/b139669f374eb5024a50eb13f116ff763b1c5935/src/libstd/sys/wasm/mod.rs#L309
|
|
||||||
[2]: https://github.com/WebAssembly/wabt
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
extern crate wasm_bindgen;
|
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
use std::thread::spawn;
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn doit() {
|
|
||||||
// let child = spawn(move || -> u32 {
|
|
||||||
// 5
|
|
||||||
// });
|
|
||||||
// let result = child.join().unwrap();
|
|
||||||
let result = spawn();
|
|
||||||
println!("Result: {}", result);
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
// const oxipng = require("./oxipng_wasm");
|
|
||||||
const repl = require("repl");
|
|
||||||
const fs = require("fs");
|
|
||||||
|
|
||||||
const dec = new TextDecoder();
|
|
||||||
let buffer = '';
|
|
||||||
async function init() {
|
|
||||||
const { instance } = await WebAssembly.instantiate(
|
|
||||||
fs.readFileSync("./target/wasm32-unknown-unknown/release/loltest.wasm"),
|
|
||||||
{
|
|
||||||
__wbindgen_placeholder__: {
|
|
||||||
__wbindgen_describe(v) {
|
|
||||||
console.log(`__wbindgen_desribe(${v})`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
// See https://github.com/rust-lang/rust/blob/master/src/libstd/sys/wasm/mod.rs
|
|
||||||
rust_wasm_syscall(syscall, ptr) {
|
|
||||||
switch(syscall) {
|
|
||||||
case 1: // Write
|
|
||||||
const [fd, dataPtr, len] = new Uint32Array(instance.exports.memory.buffer, ptr, 3 * 4);
|
|
||||||
const fragment = new Uint8Array(instance.exports.memory.buffer, dataPtr, len);
|
|
||||||
buffer += dec.decode(fragment);
|
|
||||||
const idx = buffer.indexOf('\n');
|
|
||||||
if(idx !== -1) {
|
|
||||||
console.log(buffer.slice(0, idx));
|
|
||||||
buffer = buffer.slice(idx);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
case 6: // Time
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return 0; // False, unimplemented
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
instance.exports.doit();
|
|
||||||
} catch{}
|
|
||||||
const r = repl.start("node> ");
|
|
||||||
r.context.i = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
|
||||||
File diff suppressed because it is too large
Load Diff
6
codecs/resize/.gitignore
vendored
Normal file
6
codecs/resize/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
**/*.rs.bk
|
||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/README.md
|
||||||
|
lut.inc
|
||||||
37
codecs/resize/Cargo.toml
Normal file
37
codecs/resize/Cargo.toml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
[package]
|
||||||
|
name = "resize"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Surma <surma@surma.link>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
#crate-type = ["cdylib", "rlib"]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["console_error_panic_hook", "wee_alloc"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cfg-if = "0.1.10"
|
||||||
|
wasm-bindgen = "0.2.63"
|
||||||
|
resize = "0.4.0"
|
||||||
|
|
||||||
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
|
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||||
|
# code size when deploying.
|
||||||
|
console_error_panic_hook = { version = "0.1.6", optional = true }
|
||||||
|
|
||||||
|
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||||
|
# compared to the default allocator's ~10K. It is slower than the default
|
||||||
|
# allocator, however.
|
||||||
|
#
|
||||||
|
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||||
|
wee_alloc = { version = "0.4.5", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
wasm-bindgen-test = "0.3.13"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
# Tell `rustc` to optimize for small code size.
|
||||||
|
opt-level = "s"
|
||||||
|
lto = true
|
||||||
9
codecs/resize/Dockerfile
Normal file
9
codecs/resize/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.15/wabt-1.0.15-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/wabt:${PATH}"
|
||||||
|
WORKDIR /src
|
||||||
23
codecs/resize/build.rs
Normal file
23
codecs/resize/build.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
include!("./src/srgb.rs");
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let mut srgb_to_linear_lut = String::from("static SRGB_TO_LINEAR_LUT: [f32; 256] = [");
|
||||||
|
let mut linear_to_srgb_lut = String::from("static LINEAR_TO_SRGB_LUT: [f32; 256] = [");
|
||||||
|
for i in 0..256 {
|
||||||
|
srgb_to_linear_lut.push_str(&format!("{0:.7}", srgb_to_linear((i as f32) / 255.0)));
|
||||||
|
srgb_to_linear_lut.push_str(",");
|
||||||
|
linear_to_srgb_lut.push_str(&format!("{0:.7}", linear_to_srgb((i as f32) / 255.0)));
|
||||||
|
linear_to_srgb_lut.push_str(",");
|
||||||
|
}
|
||||||
|
srgb_to_linear_lut.pop().unwrap();
|
||||||
|
linear_to_srgb_lut.pop().unwrap();
|
||||||
|
srgb_to_linear_lut.push_str("];");
|
||||||
|
linear_to_srgb_lut.push_str("];");
|
||||||
|
|
||||||
|
let mut file = std::fs::File::create("src/lut.inc")?;
|
||||||
|
file.write_all(srgb_to_linear_lut.as_bytes())?;
|
||||||
|
file.write_all(linear_to_srgb_lut.as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
22
codecs/resize/build.sh
Executable file
22
codecs/resize/build.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
wasm-pack build
|
||||||
|
wasm-strip pkg/resize_bg.wasm
|
||||||
|
rm pkg/.gitignore
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-resize .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
4
codecs/resize/package-lock.json
generated
Normal file
4
codecs/resize/package-lock.json
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
||||||
7
codecs/resize/package.json
Normal file
7
codecs/resize/package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-resize .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-resize ./build.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
codecs/resize/pkg/package.json
Normal file
15
codecs/resize/pkg/package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"collaborators": [
|
||||||
|
"Surma <surma@surma.link>"
|
||||||
|
],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"files": [
|
||||||
|
"resize_bg.wasm",
|
||||||
|
"resize.js",
|
||||||
|
"resize.d.ts"
|
||||||
|
],
|
||||||
|
"module": "resize.js",
|
||||||
|
"types": "resize.d.ts",
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
||||||
14
codecs/resize/pkg/resize.d.ts
vendored
Normal file
14
codecs/resize/pkg/resize.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} output_width
|
||||||
|
* @param {number} output_height
|
||||||
|
* @param {number} typ_idx
|
||||||
|
* @param {boolean} premultiply
|
||||||
|
* @param {boolean} color_space_conversion
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image: Uint8Array, input_width: number, input_height: number, output_width: number, output_height: number, typ_idx: number, premultiply: boolean, color_space_conversion: boolean): Uint8Array;
|
||||||
2
codecs/resize/pkg/resize.js
Normal file
2
codecs/resize/pkg/resize.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import * as wasm from "./resize_bg.wasm";
|
||||||
|
export * from "./resize_bg.js";
|
||||||
6
codecs/resize/pkg/resize_bg.d.ts
vendored
Normal file
6
codecs/resize/pkg/resize_bg.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function resize(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number): void;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
52
codecs/resize/pkg/resize_bg.js
Normal file
52
codecs/resize/pkg/resize_bg.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import * as wasm from './resize_bg.wasm';
|
||||||
|
|
||||||
|
let cachegetUint8Memory0 = null;
|
||||||
|
function getUint8Memory0() {
|
||||||
|
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8Memory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
|
const ptr = malloc(arg.length * 1);
|
||||||
|
getUint8Memory0().set(arg, ptr / 1);
|
||||||
|
WASM_VECTOR_LEN = arg.length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetInt32Memory0 = null;
|
||||||
|
function getInt32Memory0() {
|
||||||
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU8FromWasm0(ptr, len) {
|
||||||
|
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} output_width
|
||||||
|
* @param {number} output_height
|
||||||
|
* @param {number} typ_idx
|
||||||
|
* @param {boolean} premultiply
|
||||||
|
* @param {boolean} color_space_conversion
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
|
||||||
|
var ptr0 = passArray8ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
wasm.resize(8, ptr0, len0, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
|
||||||
|
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||||
|
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||||
|
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||||
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
codecs/resize/pkg/resize_bg.wasm
Normal file
BIN
codecs/resize/pkg/resize_bg.wasm
Normal file
Binary file not shown.
121
codecs/resize/src/lib.rs
Normal file
121
codecs/resize/src/lib.rs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
extern crate cfg_if;
|
||||||
|
extern crate resize;
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
|
use resize::Pixel::RGBA;
|
||||||
|
use resize::Type;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
mod srgb;
|
||||||
|
use srgb::Clamp;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
|
// allocator.
|
||||||
|
if #[cfg(feature = "wee_alloc")] {
|
||||||
|
extern crate wee_alloc;
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include!("./lut.inc");
|
||||||
|
|
||||||
|
// If `with_space_conversion` is true, this function returns 2 functions that
|
||||||
|
// convert from sRGB to linear RGB and vice versa. If `with_space_conversion` is
|
||||||
|
// false, the 2 functions returned do nothing.
|
||||||
|
fn converter_funcs(with_space_conversion: bool) -> ((fn(u8) -> f32), (fn(f32) -> u8)) {
|
||||||
|
if with_space_conversion {
|
||||||
|
(
|
||||||
|
|v| SRGB_TO_LINEAR_LUT[v as usize] * 255.0,
|
||||||
|
|v| (LINEAR_TO_SRGB_LUT[v as usize] * 255.0) as u8,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(|v| v as f32, |v| v as u8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `with_alpha_premultiplication` is true, this function returns a function
|
||||||
|
// that premultiply the alpha channel with the given channel value and another
|
||||||
|
// function that reverses that process. If `with_alpha_premultiplication` is
|
||||||
|
// false, the functions just return the channel value.
|
||||||
|
fn alpha_multiplier_funcs(
|
||||||
|
with_alpha_premultiplication: bool,
|
||||||
|
) -> ((fn(f32, u8) -> u8), (fn(u8, u8) -> f32)) {
|
||||||
|
if with_alpha_premultiplication {
|
||||||
|
(
|
||||||
|
|v, a| (v * (a as f32) / 255.0) as u8,
|
||||||
|
|v, a| (v as f32) * 255.0 / (a as f32).clamp(0.0, 255.0),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(|v, _a| v as u8, |v, _a| v as f32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn resize(
|
||||||
|
mut input_image: Vec<u8>,
|
||||||
|
input_width: usize,
|
||||||
|
input_height: usize,
|
||||||
|
output_width: usize,
|
||||||
|
output_height: usize,
|
||||||
|
typ_idx: usize,
|
||||||
|
premultiply: bool,
|
||||||
|
color_space_conversion: bool,
|
||||||
|
) -> Vec<u8> {
|
||||||
|
let typ = match typ_idx {
|
||||||
|
0 => Type::Triangle,
|
||||||
|
1 => Type::Catrom,
|
||||||
|
2 => Type::Mitchell,
|
||||||
|
3 => Type::Lanczos3,
|
||||||
|
_ => panic!("Nope"),
|
||||||
|
};
|
||||||
|
let num_input_pixels = input_width * input_height;
|
||||||
|
let num_output_pixels = output_width * output_height;
|
||||||
|
|
||||||
|
let (to_linear, to_color_space) = converter_funcs(color_space_conversion);
|
||||||
|
let (premultiplier, demultiplier) = alpha_multiplier_funcs(premultiply);
|
||||||
|
|
||||||
|
// If both options are false, there is no preprocessing on the pixel valus
|
||||||
|
// and we can skip the loop.
|
||||||
|
if premultiply || color_space_conversion {
|
||||||
|
for i in 0..num_input_pixels {
|
||||||
|
for j in 0..3 {
|
||||||
|
input_image[4 * i + j] =
|
||||||
|
premultiplier(to_linear(input_image[4 * i + j]), input_image[4 * i + 3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut resizer = resize::new(
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
output_width,
|
||||||
|
output_height,
|
||||||
|
RGBA,
|
||||||
|
typ,
|
||||||
|
);
|
||||||
|
let mut output_image = Vec::<u8>::with_capacity(num_output_pixels * 4);
|
||||||
|
output_image.resize(num_output_pixels * 4, 0);
|
||||||
|
resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
|
||||||
|
|
||||||
|
if premultiply || color_space_conversion {
|
||||||
|
for i in 0..num_output_pixels {
|
||||||
|
for j in 0..3 {
|
||||||
|
// We don’t need to worry about division by zero, as division by zero
|
||||||
|
// is well-defined on floats to return ±Inf. ±Inf is converted to 0
|
||||||
|
// when casting to integers.
|
||||||
|
output_image[4 * i + j] = to_color_space(demultiplier(
|
||||||
|
output_image[4 * i + j],
|
||||||
|
output_image[4 * i + 3],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_image;
|
||||||
|
}
|
||||||
29
codecs/resize/src/srgb.rs
Normal file
29
codecs/resize/src/srgb.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
pub trait Clamp: std::cmp::PartialOrd + Sized {
|
||||||
|
fn clamp(self, min: Self, max: Self) -> Self {
|
||||||
|
if self.lt(&min) {
|
||||||
|
min
|
||||||
|
} else if self.gt(&max) {
|
||||||
|
max
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clamp for f32 {}
|
||||||
|
|
||||||
|
pub fn srgb_to_linear(v: f32) -> f32 {
|
||||||
|
if v < 0.04045 {
|
||||||
|
v / 12.92
|
||||||
|
} else {
|
||||||
|
((v + 0.055) / 1.055).powf(2.4).clamp(0.0, 1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn linear_to_srgb(v: f32) -> f32 {
|
||||||
|
if v < 0.0031308 {
|
||||||
|
v * 12.92
|
||||||
|
} else {
|
||||||
|
(1.055 * v.powf(1.0 / 2.4) - 0.055).clamp(0.0, 1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
17
codecs/resize/src/utils.rs
Normal file
17
codecs/resize/src/utils.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
use cfg_if::cfg_if;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||||
|
// `set_panic_hook` function at least once during initialization, and then
|
||||||
|
// we will get better error messages if our code ever panics.
|
||||||
|
//
|
||||||
|
// For more details see
|
||||||
|
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||||
|
if #[cfg(feature = "console_error_panic_hook")] {
|
||||||
|
extern crate console_error_panic_hook;
|
||||||
|
pub use self::console_error_panic_hook::set_once as set_panic_hook;
|
||||||
|
} else {
|
||||||
|
#[inline]
|
||||||
|
pub fn set_panic_hook() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
codecs/rotate/.gitignore
vendored
Normal file
2
codecs/rotate/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
14
codecs/rotate/Cargo.toml
Normal file
14
codecs/rotate/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "rotate"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Surma <surma@google.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "rotate"
|
||||||
|
path = "rotate.rs"
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
||||||
8
codecs/rotate/Dockerfile
Normal file
8
codecs/rotate/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/wabt:${PATH}"
|
||||||
|
WORKDIR /src
|
||||||
45
codecs/rotate/benchmark.js
Normal file
45
codecs/rotate/benchmark.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// THIS IS NOT A NODE SCRIPT
|
||||||
|
// This is a d8 script. Please install jsvu[1] and install v8.
|
||||||
|
// Then run `npm run --silent benchmark`.
|
||||||
|
// [1]: https://github.com/GoogleChromeLabs/jsvu
|
||||||
|
async function init() {
|
||||||
|
// Adjustable constants.
|
||||||
|
const imageDimensions = 4096;
|
||||||
|
const iterations = new Array(100);
|
||||||
|
|
||||||
|
// Constants. Don’t change.
|
||||||
|
const imageByteSize = imageDimensions * imageDimensions * 4;
|
||||||
|
const wasmPageSize = 64 * 1024;
|
||||||
|
|
||||||
|
const buffer = readbuffer("rotate.wasm");
|
||||||
|
const { instance } = await WebAssembly.instantiate(buffer);
|
||||||
|
|
||||||
|
const pagesAvailable = Math.floor(
|
||||||
|
instance.exports.memory.buffer.byteLength / wasmPageSize
|
||||||
|
);
|
||||||
|
const pagesNeeded = Math.floor((imageByteSize * 2 + 4) / wasmPageSize) + 1;
|
||||||
|
const additionalPagesNeeded = pagesNeeded - pagesAvailable;
|
||||||
|
if (additionalPagesNeeded > 0) {
|
||||||
|
instance.exports.memory.grow(additionalPagesNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
[0, 90, 180, 270].forEach(rotation => {
|
||||||
|
print(`\n${rotation} degrees`);
|
||||||
|
print(`==============================`);
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
const start = Date.now();
|
||||||
|
instance.exports.rotate(imageDimensions, imageDimensions, rotation);
|
||||||
|
iterations[i] = Date.now() - start;
|
||||||
|
}
|
||||||
|
const average = iterations.reduce((sum, c) => sum + c) / iterations.length;
|
||||||
|
const stddev = Math.sqrt(
|
||||||
|
iterations
|
||||||
|
.map(i => Math.pow(i - average, 2))
|
||||||
|
.reduce((sum, c) => sum + c) / iterations.length
|
||||||
|
);
|
||||||
|
print(`n = ${iterations.length}`);
|
||||||
|
print(`Average: ${average}`);
|
||||||
|
print(`StdDev: ${stddev}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
init().catch(e => console.error(e.stack));
|
||||||
24
codecs/rotate/build.sh
Executable file
24
codecs/rotate/build.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
cargo build \
|
||||||
|
--target wasm32-unknown-unknown \
|
||||||
|
--release
|
||||||
|
cp target/wasm32-unknown-unknown/release/rotate.wasm .
|
||||||
|
wasm-strip rotate.wasm
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-rotate .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
11
codecs/rotate/package.json
Normal file
11
codecs/rotate/package.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "rotate",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-rotate .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-rotate ./build.sh",
|
||||||
|
"benchmark": "echo File size after gzip && npm run benchmark:filesize && echo Optimizing && npm run -s benchmark:optimizing",
|
||||||
|
"benchmark:baseline": "v8 --liftoff --no-wasm-tier-up --no-opt ./benchmark.js",
|
||||||
|
"benchmark:optimizing": "v8 --no-liftoff --no-wasm-tier-up ./benchmark.js",
|
||||||
|
"benchmark:filesize": "cat rotate.wasm | gzip -c9n | wc -c"
|
||||||
|
}
|
||||||
|
}
|
||||||
113
codecs/rotate/rotate.rs
Normal file
113
codecs/rotate/rotate.rs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
|
|
||||||
|
// This function is taken from Zachary Dremann
|
||||||
|
// https://github.com/GoogleChromeLabs/squoosh/pull/462
|
||||||
|
trait HardUnwrap<T> {
|
||||||
|
fn unwrap_hard(self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> HardUnwrap<T> for Option<T> {
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
#[inline]
|
||||||
|
fn unwrap_hard(self) -> T {
|
||||||
|
match self {
|
||||||
|
Some(t) => t,
|
||||||
|
None => std::process::abort(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
fn unwrap_hard(self) -> T {
|
||||||
|
self.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TILE_SIZE: usize = 16;
|
||||||
|
|
||||||
|
fn get_buffers<'a>(width: usize, height: usize) -> (&'a [u32], &'a mut [u32]) {
|
||||||
|
let num_pixels = width * height;
|
||||||
|
let in_b: &[u32];
|
||||||
|
let out_b: &mut [u32];
|
||||||
|
unsafe {
|
||||||
|
in_b = from_raw_parts::<u32>(8 as *const u32, num_pixels);
|
||||||
|
out_b = from_raw_parts_mut::<u32>((num_pixels * 4 + 8) as *mut u32, num_pixels);
|
||||||
|
}
|
||||||
|
return (in_b, out_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_0(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
for (in_p, out_p) in in_b.iter().zip(out_b.iter_mut()) {
|
||||||
|
*out_p = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_90(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
let new_width = height;
|
||||||
|
let _new_height = width;
|
||||||
|
for y_start in (0..height).step_by(TILE_SIZE) {
|
||||||
|
for x_start in (0..width).step_by(TILE_SIZE) {
|
||||||
|
for y in y_start..(y_start + TILE_SIZE).min(height) {
|
||||||
|
let in_offset = y * width;
|
||||||
|
let in_bounds = if x_start + TILE_SIZE < width {
|
||||||
|
(in_offset + x_start)..(in_offset + x_start + TILE_SIZE)
|
||||||
|
} else {
|
||||||
|
(in_offset + x_start)..(in_offset + width)
|
||||||
|
};
|
||||||
|
let in_chunk = in_b.get(in_bounds).unwrap_hard();
|
||||||
|
for (x, in_p) in in_chunk.iter().enumerate() {
|
||||||
|
let new_x = (new_width - 1) - y;
|
||||||
|
let new_y = x + x_start;
|
||||||
|
*out_b.get_mut(new_y * new_width + new_x).unwrap_hard() = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_180(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
for (in_p, out_p) in in_b.iter().zip(out_b.iter_mut().rev()) {
|
||||||
|
*out_p = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_270(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
let new_width = height;
|
||||||
|
let new_height = width;
|
||||||
|
for y_start in (0..height).step_by(TILE_SIZE) {
|
||||||
|
for x_start in (0..width).step_by(TILE_SIZE) {
|
||||||
|
for y in y_start..(y_start + TILE_SIZE).min(height) {
|
||||||
|
let in_offset = y * width;
|
||||||
|
let in_bounds = if x_start + TILE_SIZE < width {
|
||||||
|
(in_offset + x_start)..(in_offset + x_start + TILE_SIZE)
|
||||||
|
} else {
|
||||||
|
(in_offset + x_start)..(in_offset + width)
|
||||||
|
};
|
||||||
|
let in_chunk = in_b.get(in_bounds).unwrap_hard();
|
||||||
|
for (x, in_p) in in_chunk.iter().enumerate() {
|
||||||
|
let new_x = y;
|
||||||
|
let new_y = new_height - 1 - (x_start + x);
|
||||||
|
*out_b.get_mut(new_y * new_width + new_x).unwrap_hard() = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn rotate(width: usize, height: usize, rotate: usize) {
|
||||||
|
match rotate {
|
||||||
|
0 => rotate_0(width, height),
|
||||||
|
90 => rotate_90(width, height),
|
||||||
|
180 => rotate_180(width, height),
|
||||||
|
270 => rotate_270(width, height),
|
||||||
|
_ => std::process::abort(),
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
codecs/rotate/rotate.wasm
Executable file
BIN
codecs/rotate/rotate.wasm
Executable file
Binary file not shown.
37
codecs/webp_dec/build.sh → codecs/webp/build.sh
Executable file → Normal file
37
codecs/webp_dec/build.sh → codecs/webp/build.sh
Executable file → Normal file
@@ -2,22 +2,21 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export OPTIMIZE="-Os"
|
export EM_CACHE="${PWD}/node_modules/.em_cache"
|
||||||
|
export OPTIMIZE="-Os -flto --llvm-lto 1"
|
||||||
export LDFLAGS="${OPTIMIZE}"
|
export LDFLAGS="${OPTIMIZE}"
|
||||||
export CFLAGS="${OPTIMIZE}"
|
export CFLAGS="${OPTIMIZE}"
|
||||||
export CPPFLAGS="${OPTIMIZE}"
|
export CPPFLAGS="${OPTIMIZE}"
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -qqy autoconf libtool libpng-dev pkg-config
|
apt-get install -qqy autoconf libtool pkg-config
|
||||||
|
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling libwebp"
|
echo "Compiling libwebp"
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
test -n "$SKIP_LIBWEBP" || (
|
test -n "$SKIP_LIBWEBP" || (
|
||||||
cd node_modules/libwebp
|
cd node_modules/libwebp
|
||||||
autoreconf -fiv
|
autoreconf -iv
|
||||||
rm -rf build || true
|
emconfigure ./configure -C \
|
||||||
mkdir -p build && cd build
|
|
||||||
emconfigure ../configure \
|
|
||||||
--disable-libwebpdemux \
|
--disable-libwebpdemux \
|
||||||
--disable-wic \
|
--disable-wic \
|
||||||
--disable-gif \
|
--disable-gif \
|
||||||
@@ -31,7 +30,7 @@ test -n "$SKIP_LIBWEBP" || (
|
|||||||
--disable-neon \
|
--disable-neon \
|
||||||
--disable-sse2 \
|
--disable-sse2 \
|
||||||
--disable-sse4.1
|
--disable-sse4.1
|
||||||
emmake make
|
emmake make -j`nproc`
|
||||||
)
|
)
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling wasm bindings"
|
echo "Compiling wasm bindings"
|
||||||
@@ -39,16 +38,28 @@ echo "============================================="
|
|||||||
(
|
(
|
||||||
emcc \
|
emcc \
|
||||||
${OPTIMIZE} \
|
${OPTIMIZE} \
|
||||||
|
--closure 1 \
|
||||||
--bind \
|
--bind \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s 'EXPORT_NAME="webp_dec"' \
|
-s 'EXPORT_NAME="webp_dec"' \
|
||||||
--std=c++11 \
|
|
||||||
-I node_modules/libwebp \
|
-I node_modules/libwebp \
|
||||||
-o ./webp_dec.js \
|
-o dec/webp_dec.js \
|
||||||
-x c++ \
|
dec/webp_dec.cpp \
|
||||||
webp_dec.cpp \
|
node_modules/libwebp/src/.libs/libwebp.a
|
||||||
node_modules/libwebp/build/src/.libs/libwebp.a
|
)
|
||||||
|
(
|
||||||
|
emcc \
|
||||||
|
${OPTIMIZE} \
|
||||||
|
--closure 1 \
|
||||||
|
--bind \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s 'EXPORT_NAME="webp_enc"' \
|
||||||
|
-I node_modules/libwebp \
|
||||||
|
-o enc/webp_enc.js \
|
||||||
|
enc/webp_enc.cpp \
|
||||||
|
node_modules/libwebp/src/.libs/libwebp.a
|
||||||
)
|
)
|
||||||
echo "============================================="
|
echo "============================================="
|
||||||
echo "Compiling wasm bindings done"
|
echo "Compiling wasm bindings done"
|
||||||
@@ -56,5 +67,5 @@ echo "============================================="
|
|||||||
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
echo "Did you update your docker image?"
|
echo "Did you update your docker image?"
|
||||||
echo "Run \`docker pull trzeci/emscripten\`"
|
echo "Run \`docker pull trzeci/emscripten-upstream\`"
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
Module.onRuntimeInitialized = async _ => {
|
Module.onRuntimeInitialized = async _ => {
|
||||||
console.log('Version:', Module.version().toString(16));
|
console.log('Version:', Module.version().toString(16));
|
||||||
const image = await loadFile('../example.webp');
|
const image = await loadFile('../../example.webp');
|
||||||
const result = Module.decode(image);
|
const result = Module.decode(image);
|
||||||
const imageData = new ImageData(new Uint8ClampedArray(result.buffer), result.width, result.height);
|
const imageData = new ImageData(new Uint8ClampedArray(result.buffer), result.width, result.height);
|
||||||
Module.free_result();
|
Module.free_result();
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
|
#include <string>
|
||||||
#include "emscripten/bind.h"
|
#include "emscripten/bind.h"
|
||||||
#include "emscripten/val.h"
|
#include "emscripten/val.h"
|
||||||
#include "src/webp/decode.h"
|
#include "src/webp/decode.h"
|
||||||
#include "src/webp/demux.h"
|
#include "src/webp/demux.h"
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
@@ -11,24 +11,19 @@ int version() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RawImage {
|
class RawImage {
|
||||||
public:
|
public:
|
||||||
val buffer;
|
val buffer;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
RawImage(val b, int w, int h)
|
RawImage(val b, int w, int h) : buffer(b), width(w), height(h) {}
|
||||||
: buffer(b), width(w), height(h) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t* last_result;
|
uint8_t* last_result;
|
||||||
RawImage decode(std::string buffer) {
|
RawImage decode(std::string buffer) {
|
||||||
int width, height;
|
int width, height;
|
||||||
last_result = WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height);
|
last_result = WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height);
|
||||||
return RawImage(
|
return RawImage(val(typed_memory_view(width * height * 4, last_result)), width, height);
|
||||||
val(typed_memory_view(width*height*4, last_result)),
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_result() {
|
void free_result() {
|
||||||
@@ -37,9 +32,9 @@ void free_result() {
|
|||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
class_<RawImage>("RawImage")
|
class_<RawImage>("RawImage")
|
||||||
.property("buffer", &RawImage::buffer)
|
.property("buffer", &RawImage::buffer)
|
||||||
.property("width", &RawImage::width)
|
.property("width", &RawImage::width)
|
||||||
.property("height", &RawImage::height);
|
.property("height", &RawImage::height);
|
||||||
|
|
||||||
function("decode", &decode);
|
function("decode", &decode);
|
||||||
function("version", &version);
|
function("version", &version);
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user