Compare commits
646 Commits
extract-pi
...
jpeg-simd
Author | SHA1 | Date | |
---|---|---|---|
173d1ea1e5 | |||
0e90f805a4 | |||
d0f5d5a644 | |||
37f09245a6 | |||
c43f75f1f2 | |||
227d32be7b | |||
87955ab9a0 | |||
ecb0b15cdc | |||
ed451e4dfa | |||
1a26057452 | |||
98b930abde | |||
ddbeaa0870 | |||
b69dc4c7f4 | |||
ed6b8b89c6 | |||
2580f1e292 | |||
2ac684f98f | |||
b8d921ec16 | |||
9c0a375f01 | |||
d1cff7d84e | |||
9c2b582986 | |||
e342766cbf | |||
f1cd6a87da | |||
39e5741cb2 | |||
93cbe557cd | |||
97931bad22 | |||
1f35c40d3f | |||
c39383333f | |||
4fc18de5f9 | |||
aac30e6fd3 | |||
45785bcca3 | |||
f36cb5d3ef | |||
b7f7a5ac0a | |||
dd895f026b | |||
548c126521 | |||
ca00a22303 | |||
1ce6dd73d8 | |||
ff7dc2c4cf | |||
117b87132e | |||
42e7a7e165 | |||
796324ad71 | |||
cf1a718534 | |||
718427badb | |||
c5c520a71d | |||
17ffa57a8b | |||
005d5180b4 | |||
ce9b96994c | |||
a1fb445b06 | |||
8a516131ea | |||
9816be83ab | |||
63f607a3ea | |||
57418034c4 | |||
3892490023 | |||
5bedff583b | |||
d94835402f | |||
b7e45ab843 | |||
8313246fd1 | |||
2b3cafb1f4 | |||
d52698f005 | |||
6ad28c0b5c | |||
c76dabf063 | |||
e6d8bac9c5 | |||
42e43730c8 | |||
5c17fba349 | |||
85eb94b725 | |||
4fa73be842 | |||
7c89d09139 | |||
079e56f1e1 | |||
6065ceabfe | |||
265e6db2bd | |||
3a5c0aa30c | |||
f0c3ec9d51 | |||
1ae93b527c | |||
a95cb740bf | |||
de543b3206 | |||
1542bfb7fd | |||
f95954a9f1 | |||
bc8d75128f | |||
d3252bb1bb | |||
83d9d2c764 | |||
476268fe19 | |||
74492af675 | |||
bd4179aff2 | |||
27ae47117e | |||
7da3f07333 | |||
eeb3d3562a | |||
2d73c24e09 | |||
ed666dd381 | |||
6f18f08a8e | |||
eae808cb6f | |||
0ae99c9228 | |||
f4a16022ef | |||
12153c72dc | |||
ae7782031d | |||
7cd6487a28 | |||
62c53c9fed | |||
53a38b2ba1 | |||
f3dfcae3f0 | |||
3f7274a6ac | |||
f5bc715bc0 | |||
22b7e36c01 | |||
a0e6a377cd | |||
22b04c159d | |||
5b496ad85f | |||
92249ac711 | |||
629d64326d | |||
4621cbcae9 | |||
164191d746 | |||
b22adc9957 | |||
6b0a675469 | |||
d7fb0d9b40 | |||
bc1bf8542c | |||
309947a08f | |||
6aeaae6160 | |||
71b3c7dda2 | |||
48c06e86fa | |||
e8f4e82cf8 | |||
1b7d3fa394 | |||
650db99818 | |||
7638bb795e | |||
570e604be0 | |||
a056d1c363 | |||
fce61c8c89 | |||
d60d0ae47d | |||
9a838f1d55 | |||
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 | |||
cb16fb5437 | |||
36f5fa2c47 | |||
51ad22e72c | |||
1a355c0c16 | |||
fe5ba08963 | |||
7fc994d4af | |||
a0a8285e02 | |||
da2e35f613 | |||
09bdc25352 | |||
ad263a9c36 | |||
c8d8d4e43d | |||
94249b8a93 | |||
edd2c51eb6 | |||
1d24e9399f | |||
3a0062276d | |||
1993cf3f6c | |||
c97aac31c6 | |||
507921cbe8 | |||
887db675c8 | |||
3917618e4e | |||
3c42d2e6a4 | |||
db8777b7f7 | |||
18c2cddee2 | |||
3ff9d3a1fa | |||
6503667c78 | |||
0fa95f84d4 | |||
cf91a90270 | |||
690052f989 | |||
b3e935f7e4 | |||
17314ebd29 | |||
adc437cd51 | |||
0e97b74510 | |||
9ffb475cac | |||
faa2b030c5 | |||
e3b3b10e2a | |||
b569cf268c | |||
b154b77556 | |||
84c0f30a7c | |||
16463ff76d | |||
8314e9e24b | |||
a33c557818 | |||
6fbdc65ad0 | |||
9c9b6c4711 | |||
46278d04c3 | |||
c1c16508b5 | |||
ed1b983711 | |||
ec23e28eda | |||
d48b49e8e4 | |||
14308970c6 | |||
38e86e1012 | |||
e9a33af831 | |||
6a63e5dbb2 | |||
1e1892a3d5 | |||
8bff9a2973 | |||
cbe753dd29 | |||
b047845b43 | |||
1bebc75381 | |||
93c46bfc8d | |||
a3d0f5963e | |||
006b82bf05 | |||
c36e37ac6b | |||
3cf6d7385a | |||
9045b2fa97 | |||
be6f3b9c6d | |||
5a699b7ce9 | |||
f366a78e87 | |||
c63c7ead51 | |||
ecfa5902cd | |||
444027b496 | |||
9c5dcb93c7 | |||
9594221271 | |||
01823d3b75 | |||
db07a90139 | |||
962d0928d3 | |||
e67d50c8e6 | |||
f9b2f17852 | |||
9746a9f5ed | |||
be0877ecb0 | |||
d2fcdfae43 | |||
2c9eb46941 | |||
d30a85fd48 | |||
9260bed1b1 | |||
f6d12985a9 | |||
10c9b1db7c | |||
4fb17be8de | |||
b592b1a088 | |||
0544a6507e | |||
1e20ff15ed | |||
04a0ec0645 | |||
f355292fe3 | |||
32e4d813de | |||
f960f5ea87 | |||
aa6f83e2fa | |||
c09e1f1895 | |||
7c311928dd | |||
5f1c8bcb6b | |||
93bc20f014 | |||
d29d9571c6 | |||
3d47dfc820 | |||
d7846c9add | |||
4d6fe9d641 | |||
205feba75d | |||
ca7663b94a | |||
83e45f054b | |||
783e893a67 | |||
0a941866a9 | |||
04edfe0085 | |||
6cae634eca | |||
8c7bf278dc | |||
f6106650b5 | |||
166e606034 | |||
c997e6a3e4 | |||
2a1b6dc9da | |||
129c33fa12 | |||
3245987113 | |||
593ad62cbb | |||
a625a76e9e | |||
c2a305304b | |||
7389c507fb | |||
68f0f23016 | |||
dc809dde30 | |||
80dfa03b94 | |||
fca7a5350d | |||
1b693fb57a | |||
7723bd3b5f | |||
723fc142ec | |||
06d4d946d9 | |||
428b7d976d | |||
32f2b4e573 | |||
b3ab983f02 | |||
e011724af4 | |||
f11a6cb38a | |||
adf6d3c60d | |||
bb8f35ce09 | |||
ae9ae31ddc | |||
67893817b5 | |||
f8da5b153d | |||
e2a956a088 | |||
5c5b001fc7 | |||
e4beafed97 | |||
553a504140 | |||
44dd2ee808 | |||
b36c851b2a | |||
0502d70cdf | |||
86546574bb | |||
f351712130 | |||
c7f2ae2234 | |||
436f689115 | |||
951c7af724 | |||
53b46f879f | |||
cbe82112ab | |||
7f5562ccfe | |||
76ec946616 | |||
68bb2edb39 | |||
9c85618aff | |||
aebeff8b4c | |||
8d63125b13 | |||
2ca97ef586 | |||
a1a00f0bfb | |||
6870b135b7 |
13
.babelrc
13
.babelrc
@ -1,13 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
"transform-class-properties",
|
||||
"transform-react-constant-elements",
|
||||
"transform-react-remove-prop-types",
|
||||
[
|
||||
"transform-react-jsx",
|
||||
{
|
||||
"pragma": "h"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
2
.clang-format
Normal file
2
.clang-format
Normal file
@ -0,0 +1,2 @@
|
||||
BasedOnStyle: Chromium
|
||||
ColumnLimit: 100
|
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Something is not working as expected
|
||||
labels:
|
||||
|
||||
---
|
||||
|
||||
**Before you start**
|
||||
Please take a look at the [FAQ](https://github.com/GoogleChromeLabs/squoosh/wiki/FAQ) as well as the already opened issues! If nothing fits your problem, go ahead and fill out the following template:
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Version:**
|
||||
- OS w/ version: [e.g. iOS 12]
|
||||
- Browser w/ version [e.g. Chrome 70]
|
||||
- Node version: [e.g. 10.11.0]
|
||||
- npm version: [e.g. 6.4.1]
|
||||
|
||||
**Is your issue related to the quality of image compression?**
|
||||
Please attach original and output images (you can drag & drop to attach).
|
||||
- Original image
|
||||
- Output image from Squoosh
|
||||
|
||||
**Additional context, screenshots, screencasts**
|
||||
Add any other context about the problem here.
|
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels:
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Does other service/app have this feature?**
|
||||
Add any service you know/use that has this feature (We want to know for research)
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
@ -1,5 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- node
|
||||
cache: npm
|
||||
script: npm run build || npm run build # scss ts definitions need to be generated before an actual build
|
||||
script: npm run build
|
||||
after_success: npm run sizereport
|
||||
os:
|
||||
- linux
|
||||
- windows
|
||||
|
33
README.md
33
README.md
@ -1,5 +1,32 @@
|
||||
# Squoosh!
|
||||
# [Squoosh]!
|
||||
|
||||
Squoosh will be an image compression web app that allows you to dive into the
|
||||
advanced options provided by various image compressors.
|
||||
[Squoosh] is an image compression web app that allows you to dive into the advanced options provided
|
||||
by various image compressors.
|
||||
|
||||
# Privacy
|
||||
|
||||
Google Analytics is used to record the following:
|
||||
|
||||
* [Basic visit data](https://support.google.com/analytics/answer/6004245?ref_topic=2919631).
|
||||
* Before and after image size once an image is downloaded. These values are rounded to the nearest
|
||||
kilobyte.
|
||||
* If install is available, when Squoosh is installed, and what method was used to install Squoosh.
|
||||
|
||||
Image compression is handled locally; no additional data is sent to the server.
|
||||
|
||||
# Building locally
|
||||
|
||||
Clone the repo, and:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can run the development server with:
|
||||
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
||||
[Squoosh]: https://squoosh.app
|
||||
|
2
_redirects.ejs
Normal file
2
_redirects.ejs
Normal file
@ -0,0 +1,2 @@
|
||||
/index.html / 301
|
||||
/* /index.html 301
|
@ -11,6 +11,6 @@ $ npm install
|
||||
$ npm run build
|
||||
```
|
||||
|
||||
This will build two files: `<codec name>_<enc or dec>.js` and `<codec name>_<enc or dec>.wasm`. It will most likely be necessary to set [`Module["locateFile"]`](https://kripken.github.io/emscripten-site/docs/api_reference/module.html#affecting-execution) to sucessfully load the `.wasm` file. When the `.js` file is loaded, a global `<codec name>_<enc or dec>` is created with the same API as an [Emscripten `Module`](https://kripken.github.io/emscripten-site/docs/api_reference/module.html).
|
||||
This will build two files: `<codec name>_<enc or dec>.js` and `<codec name>_<enc or dec>.wasm`. It will most likely be necessary to set [`Module["locateFile"]`](https://kripken.github.io/emscripten-site/docs/api_reference/module.html#affecting-execution) to successfully load the `.wasm` file. When the `.js` file is loaded, a global `<codec name>_<enc or dec>` is created with the same API as an [Emscripten `Module`](https://kripken.github.io/emscripten-site/docs/api_reference/module.html).
|
||||
|
||||
Each codec will document its API in its README.
|
||||
|
3
codecs/build-cpp.sh
Executable file
3
codecs/build-cpp.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh -e
|
||||
docker build -t squoosh-cpp - < ../cpp.Dockerfile
|
||||
docker run --rm -v $PWD:/src squoosh-cpp
|
4
codecs/build-rust.sh
Executable file
4
codecs/build-rust.sh
Executable file
@ -0,0 +1,4 @@
|
||||
set -e
|
||||
|
||||
docker build -t squoosh-rust - < ../rust.Dockerfile
|
||||
docker run --rm -v $PWD:/src squoosh-rust "$@"
|
11
codecs/cpp.Dockerfile
Normal file
11
codecs/cpp.Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM emscripten/emsdk:1.39.19
|
||||
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
||||
ENV CFLAGS "-Os -flto"
|
||||
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
||||
ENV LDFLAGS "${CFLAGS}"
|
||||
# Build and cache standard libraries with these flags
|
||||
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
|
||||
RUN /bin/bash -ic 'nvm install 14.7.0'
|
||||
WORKDIR /src
|
||||
CMD ["sh", "-c", "emmake make -j`nproc`"]
|
1
codecs/hqx/.gitignore
vendored
Normal file
1
codecs/hqx/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
289
codecs/hqx/Cargo.lock
generated
Normal file
289
codecs/hqx/Cargo.lock
generated
Normal file
@ -0,0 +1,289 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
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 = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
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 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hqx"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.2#5f19cda24191ccc7c0c4920b6b246b4e242f377c"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"wasm-bindgen 0.2.65 (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.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
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 = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "squooshhqx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hqx 0.1.0 (git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.2)",
|
||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-test 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wee_alloc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.65"
|
||||
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.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bumpalo 3.4.0 (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.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.3.27"
|
||||
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)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-test-macro 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
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)",
|
||||
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
||||
"checksum hqx 0.1.0 (git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.2)" = "<none>"
|
||||
"checksum js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
|
||||
"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||
"checksum memory_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
"checksum syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
"checksum wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
|
||||
"checksum wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
|
||||
"checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||
"checksum wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
|
||||
"checksum wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
|
||||
"checksum wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
|
||||
"checksum wasm-bindgen-test 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
||||
"checksum wasm-bindgen-test-macro 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
||||
"checksum web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
|
||||
"checksum wee_alloc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
37
codecs/hqx/Cargo.toml
Normal file
37
codecs/hqx/Cargo.toml
Normal file
@ -0,0 +1,37 @@
|
||||
[package]
|
||||
name = "squooshhqx"
|
||||
version = "0.1.0"
|
||||
authors = ["Surma <surma@surma.link>"]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook", "wee_alloc"]
|
||||
|
||||
[dependencies]
|
||||
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
|
||||
# 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]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
opt-level = "s"
|
||||
lto = true
|
11
codecs/hqx/Dockerfile
Normal file
11
codecs/hqx/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
# This is intentionally an old version of Rust. Newer versions
|
||||
# generate _significantly_ bigger Wasm binaries.
|
||||
FROM rust:1.37
|
||||
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
|
||||
|
||||
ENV PATH="/opt/binaryen:${PATH}"
|
||||
WORKDIR /src
|
21
codecs/hqx/build.sh
Executable file
21
codecs/hqx/build.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling wasm"
|
||||
echo "============================================="
|
||||
(
|
||||
wasm-pack build -- --verbose --locked
|
||||
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 - < Dockerfile",
|
||||
"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
|
||||
}
|
10
codecs/hqx/pkg/squooshhqx.d.ts
vendored
Normal file
10
codecs/hqx/pkg/squooshhqx.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-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;
|
2
codecs/hqx/pkg/squooshhqx.js
Normal file
2
codecs/hqx/pkg/squooshhqx.js
Normal file
@ -0,0 +1,2 @@
|
||||
import * as wasm from "./squooshhqx_bg.wasm";
|
||||
export * from "./squooshhqx_bg.js";
|
6
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
Normal file
6
codecs/hqx/pkg/squooshhqx_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): void;
|
||||
export function __wbindgen_malloc(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number): void;
|
48
codecs/hqx/pkg/squooshhqx_bg.js
Normal file
48
codecs/hqx/pkg/squooshhqx_bg.js
Normal file
@ -0,0 +1,48 @@
|
||||
import * as wasm from './squooshhqx_bg.wasm';
|
||||
|
||||
let cachegetUint32Memory0 = null;
|
||||
function getUint32Memory0() {
|
||||
if (cachegetUint32Memory0 === null || cachegetUint32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint32Memory0;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray32ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 4);
|
||||
getUint32Memory0().set(arg, ptr / 4);
|
||||
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 getArrayU32FromWasm0(ptr, len) {
|
||||
return getUint32Memory0().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) {
|
||||
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
|
||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 4);
|
||||
return v1;
|
||||
}
|
||||
|
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;
|
||||
}
|
17
codecs/hqx/src/utils.rs
Normal file
17
codecs/hqx/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() {}
|
||||
}
|
||||
}
|
40
codecs/imagequant/Makefile
Normal file
40
codecs/imagequant/Makefile
Normal file
@ -0,0 +1,40 @@
|
||||
CODEC_URL := https://github.com/ImageOptim/libimagequant/archive/2.12.1.tar.gz
|
||||
CODEC_DIR := node_modules/libimagequant
|
||||
CODEC_OUT_RELATIVE := libimagequant.a
|
||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||
OUT_JS := imagequant.js
|
||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
%.js: %.cpp $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR) \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
$(CODEC_OUT): $(CODEC_DIR)/config.mk
|
||||
$(MAKE) -C $(CODEC_DIR) $(CODEC_OUT_RELATIVE)
|
||||
|
||||
$(CODEC_DIR)/config.mk: $(CODEC_DIR)/configure
|
||||
cd $(CODEC_DIR) && ./configure \
|
||||
--disable-sse
|
||||
|
||||
$(CODEC_DIR)/configure: $(CODEC_DIR)
|
||||
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $@
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_DIR) clean
|
@ -24,7 +24,3 @@ Quantizes the given images, using at most `numColors`, a value between 2 and 256
|
||||
### `RawImage zx_quantize(std::string buffer, int image_width, int image_height, float dithering)`
|
||||
|
||||
???
|
||||
|
||||
### `void free_result()`
|
||||
|
||||
Frees the result created by `quantize()`.
|
||||
|
@ -1,48 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export OPTIMIZE="-Os"
|
||||
export LDFLAGS="${OPTIMIZE}"
|
||||
export CFLAGS="${OPTIMIZE}"
|
||||
export CPPFLAGS="${OPTIMIZE}"
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling libimagequant"
|
||||
echo "============================================="
|
||||
(
|
||||
emcc \
|
||||
--bind \
|
||||
${OPTIMIZE} \
|
||||
-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 "Compiling wasm module"
|
||||
echo "============================================="
|
||||
(
|
||||
emcc \
|
||||
--bind \
|
||||
${OPTIMIZE} \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="imagequant"' \
|
||||
-I node_modules/libimagequant \
|
||||
-o ./imagequant.js \
|
||||
--std=c++11 *.o \
|
||||
-x c++ \
|
||||
imagequant.cpp
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling wasm module done"
|
||||
echo "============================================="
|
||||
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo "Did you update your docker image?"
|
||||
echo "Run \`docker pull trzeci/emscripten\`"
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
@ -28,7 +28,6 @@
|
||||
// const rawImage = Module.quantize(image.data, image.width, image.height, 256, 1.0);
|
||||
const rawImage = Module.zx_quantize(image.data, image.width, image.height, 1.0);
|
||||
console.log('done');
|
||||
Module.free_result();
|
||||
|
||||
const imageData = new ImageData(new Uint8ClampedArray(rawImage.buffer), rawImage.width, rawImage.height);
|
||||
const canvas = document.createElement('canvas');
|
||||
|
@ -1,95 +1,87 @@
|
||||
#include "emscripten/bind.h"
|
||||
#include "emscripten/val.h"
|
||||
#include <stdlib.h>
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libimagequant.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
int version() {
|
||||
return (((LIQ_VERSION/10000) % 100) << 16) |
|
||||
(((LIQ_VERSION/100 ) % 100) << 8) |
|
||||
(((LIQ_VERSION/1 ) % 100) << 0);
|
||||
return (((LIQ_VERSION / 10000) % 100) << 16) | (((LIQ_VERSION / 100) % 100) << 8) |
|
||||
(((LIQ_VERSION / 1) % 100) << 0);
|
||||
}
|
||||
|
||||
class RawImage {
|
||||
public:
|
||||
val buffer;
|
||||
int width;
|
||||
int height;
|
||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||
|
||||
RawImage(val b, int w, int h)
|
||||
: buffer(b), width(w), height(h) {}
|
||||
};
|
||||
#define liq_ptr(T) std::unique_ptr<T, std::integral_constant<decltype(&T##_destroy), T##_destroy>>
|
||||
|
||||
using liq_attr_ptr = liq_ptr(liq_attr);
|
||||
using liq_image_ptr = liq_ptr(liq_image);
|
||||
using liq_result_ptr = liq_ptr(liq_result);
|
||||
|
||||
liq_attr *attr;
|
||||
liq_image *image;
|
||||
liq_result *res;
|
||||
uint8_t* result;
|
||||
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();
|
||||
int size = image_width * image_height;
|
||||
attr = liq_attr_create();
|
||||
image = liq_image_create_rgba(attr, image_buffer, image_width, image_height, 0);
|
||||
liq_set_max_colors(attr, num_colors);
|
||||
liq_result_ptr liq_image_quantize(liq_image* image, liq_attr* attr) {
|
||||
liq_result* res = nullptr;
|
||||
liq_image_quantize(image, attr, &res);
|
||||
liq_set_dithering_level(res, dithering);
|
||||
uint8_t* image8bit = (uint8_t*) malloc(size);
|
||||
result = (uint8_t*) malloc(size * 4);
|
||||
liq_write_remapped_image(res, image, image8bit, size);
|
||||
const liq_palette *pal = liq_get_palette(res);
|
||||
return liq_result_ptr(res);
|
||||
}
|
||||
|
||||
val quantize(std::string rawimage,
|
||||
int image_width,
|
||||
int image_height,
|
||||
int num_colors,
|
||||
float dithering) {
|
||||
auto image_buffer = (const liq_color*)rawimage.c_str();
|
||||
int size = image_width * image_height;
|
||||
liq_attr_ptr attr(liq_attr_create());
|
||||
liq_image_ptr image(
|
||||
liq_image_create_rgba(attr.get(), image_buffer, image_width, image_height, 0));
|
||||
liq_set_max_colors(attr.get(), num_colors);
|
||||
auto res = liq_image_quantize(image.get(), attr.get());
|
||||
liq_set_dithering_level(res.get(), dithering);
|
||||
std::vector<uint8_t> image8bit(size);
|
||||
std::vector<liq_color> result(size);
|
||||
liq_write_remapped_image(res.get(), image.get(), image8bit.data(), image8bit.size());
|
||||
auto pal = liq_get_palette(res.get());
|
||||
// Turn palletted image back into an RGBA image
|
||||
for(int i = 0; i < size; i++) {
|
||||
result[i * 4 + 0] = pal->entries[image8bit[i]].r;
|
||||
result[i * 4 + 1] = pal->entries[image8bit[i]].g;
|
||||
result[i * 4 + 2] = pal->entries[image8bit[i]].b;
|
||||
result[i * 4 + 3] = pal->entries[image8bit[i]].a;
|
||||
for (int i = 0; i < size; i++) {
|
||||
result[i] = pal->entries[image8bit[i]];
|
||||
}
|
||||
free(image8bit);
|
||||
liq_result_destroy(res);
|
||||
liq_image_destroy(image);
|
||||
liq_attr_destroy(attr);
|
||||
return {
|
||||
val(typed_memory_view(image_width*image_height*4, result)),
|
||||
image_width,
|
||||
image_height
|
||||
};
|
||||
return Uint8ClampedArray.new_(
|
||||
typed_memory_view(result.size() * sizeof(liq_color), (const uint8_t*)result.data()));
|
||||
}
|
||||
|
||||
const liq_color zx_colors[] = {
|
||||
{.a = 255, .r = 0, .g = 0, .b = 0}, // regular black
|
||||
{.a = 255, .r = 0, .g = 0, .b = 215}, // regular blue
|
||||
{.a = 255, .r = 215, .g = 0, .b = 0}, // regular red
|
||||
{.a = 255, .r = 215, .g = 0, .b = 215}, // regular magenta
|
||||
{.a = 255, .r = 0, .g = 215, .b = 0}, // regular green
|
||||
{.a = 255, .r = 0, .g = 215, .b = 215}, // regular cyan
|
||||
{.a = 255, .r = 215, .g = 215, .b = 0}, // regular yellow
|
||||
{.a = 255, .r = 215, .g = 215, .b = 215}, // regular white
|
||||
{.a = 255, .r = 0, .g = 0, .b = 255}, // bright blue
|
||||
{.a = 255, .r = 255, .g = 0, .b = 0}, // bright red
|
||||
{.a = 255, .r = 255, .g = 0, .b = 255}, // bright magenta
|
||||
{.a = 255, .r = 0, .g = 255, .b = 0}, // bright green
|
||||
{.a = 255, .r = 0, .g = 255, .b = 255}, // bright cyan
|
||||
{.a = 255, .r = 255, .g = 255, .b = 0}, // bright yellow
|
||||
{.a = 255, .r = 255, .g = 255, .b = 255} // bright white
|
||||
{.r = 0, .g = 0, .b = 0, .a = 255}, // regular black
|
||||
{.r = 0, .g = 0, .b = 215, .a = 255}, // regular blue
|
||||
{.r = 215, .g = 0, .b = 0, .a = 255}, // regular red
|
||||
{.r = 215, .g = 0, .b = 215, .a = 255}, // regular magenta
|
||||
{.r = 0, .g = 215, .b = 0, .a = 255}, // regular green
|
||||
{.r = 0, .g = 215, .b = 215, .a = 255}, // regular cyan
|
||||
{.r = 215, .g = 215, .b = 0, .a = 255}, // regular yellow
|
||||
{.r = 215, .g = 215, .b = 215, .a = 255}, // regular white
|
||||
{.r = 0, .g = 0, .b = 255, .a = 255}, // bright blue
|
||||
{.r = 255, .g = 0, .b = 0, .a = 255}, // bright red
|
||||
{.r = 255, .g = 0, .b = 255, .a = 255}, // bright magenta
|
||||
{.r = 0, .g = 255, .b = 0, .a = 255}, // bright green
|
||||
{.r = 0, .g = 255, .b = 255, .a = 255}, // bright cyan
|
||||
{.r = 255, .g = 255, .b = 0, .a = 255}, // bright yellow
|
||||
{.r = 255, .g = 255, .b = 255, .a = 255} // bright white
|
||||
};
|
||||
|
||||
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
|
||||
* both be 'regular' or 'bright'. Black exists as both regular and bright.
|
||||
* The ZX has one bit per pixel, but can assign two colours to an 8x8 block. The
|
||||
* 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) {
|
||||
const uint8_t* image_buffer = (uint8_t*) rawimage.c_str();
|
||||
val zx_quantize(std::string rawimage, int image_width, int image_height, float dithering) {
|
||||
auto image_buffer = (const liq_color*)rawimage.c_str();
|
||||
int size = image_width * image_height;
|
||||
int bytes_per_pixel = 4;
|
||||
result = (uint8_t*) malloc(size * bytes_per_pixel);
|
||||
uint8_t* image8bit = (uint8_t*) malloc(8 * 8);
|
||||
liq_color block[8 * 8];
|
||||
uint8_t image8bit[8 * 8];
|
||||
std::vector<liq_color> result(size);
|
||||
|
||||
// For each 8x8 grid
|
||||
for (int block_start_y = 0; block_start_y < image_height; block_start_y += 8) {
|
||||
@ -99,7 +91,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
||||
int block_width = 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) {
|
||||
block_height = image_height - block_start_y;
|
||||
}
|
||||
@ -111,26 +104,22 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
||||
// For each pixel in that block:
|
||||
for (int y = block_start_y; y < block_start_y + block_height; y++) {
|
||||
for (int x = block_start_x; x < block_start_x + block_width; x++) {
|
||||
int pixel_start = (y * image_width * bytes_per_pixel) + (x * bytes_per_pixel);
|
||||
int pixel_start = (y * image_width) + x;
|
||||
int smallest_distance = INT_MAX;
|
||||
int winning_index = -1;
|
||||
|
||||
// Copy pixel data for quantizing later
|
||||
block[block_index++] = image_buffer[pixel_start];
|
||||
block[block_index++] = image_buffer[pixel_start + 1];
|
||||
block[block_index++] = image_buffer[pixel_start + 2];
|
||||
block[block_index++] = image_buffer[pixel_start + 3];
|
||||
|
||||
// Which zx color is this pixel closest to?
|
||||
for (int color_index = 0; color_index < 15; color_index++) {
|
||||
liq_color color = zx_colors[color_index];
|
||||
liq_color pixel = image_buffer[pixel_start];
|
||||
|
||||
// Using Euclidean distance. LibQuant has better methods, but it requires conversion to
|
||||
// LAB, so I don't think it's worth it.
|
||||
// Using Euclidean distance. LibQuant has better methods, but it
|
||||
// requires conversion to LAB, so I don't think it's worth it.
|
||||
int distance =
|
||||
pow(color.r - image_buffer[pixel_start + 0], 2) +
|
||||
pow(color.g - image_buffer[pixel_start + 1], 2) +
|
||||
pow(color.b - image_buffer[pixel_start + 2], 2);
|
||||
pow(color.r - pixel.r, 2) + pow(color.g - pixel.g, 2) + pow(color.b - pixel.b, 2);
|
||||
|
||||
if (distance < smallest_distance) {
|
||||
winning_index = color_index;
|
||||
@ -151,7 +140,8 @@ RawImage zx_quantize(std::string rawimage, int image_width, int image_height, fl
|
||||
|
||||
for (int color_index = 0; color_index < 15; color_index++) {
|
||||
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_highest_popularity = second_highest_popularity;
|
||||
second_color_index = first_color_index;
|
||||
@ -169,8 +159,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.
|
||||
// Resolve any conflict:
|
||||
// ZX images can't mix bright and regular colours, except black which
|
||||
// appears in both. Resolve any conflict:
|
||||
while (1) {
|
||||
// If either colour is black, there's no conflict to resolve.
|
||||
if (first_color_index != 0 && second_color_index != 0) {
|
||||
@ -183,63 +173,44 @@ 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
|
||||
// selected the bright & regular version of the same colour), retry again with the third
|
||||
// most popular colour.
|
||||
// If, during conflict resolving, we now have two of the same colour
|
||||
// (because we initially selected the bright & regular version of the
|
||||
// same colour), retry again with the third most popular colour.
|
||||
if (first_color_index == second_color_index) {
|
||||
second_color_index = third_color_index;
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
// Quantize
|
||||
attr = liq_attr_create();
|
||||
image = liq_image_create_rgba(attr, block, block_width, block_height, 0);
|
||||
liq_set_max_colors(attr, 2);
|
||||
liq_image_add_fixed_color(image, zx_colors[first_color_index]);
|
||||
liq_image_add_fixed_color(image, zx_colors[second_color_index]);
|
||||
liq_image_quantize(image, attr, &res);
|
||||
liq_set_dithering_level(res, dithering);
|
||||
liq_write_remapped_image(res, image, image8bit, size);
|
||||
const liq_palette *pal = liq_get_palette(res);
|
||||
liq_attr_ptr attr(liq_attr_create());
|
||||
liq_image_ptr image(liq_image_create_rgba(attr.get(), block, block_width, block_height, 0));
|
||||
liq_set_max_colors(attr.get(), 2);
|
||||
liq_image_add_fixed_color(image.get(), zx_colors[first_color_index]);
|
||||
liq_image_add_fixed_color(image.get(), zx_colors[second_color_index]);
|
||||
auto res = liq_image_quantize(image.get(), attr.get());
|
||||
liq_set_dithering_level(res.get(), dithering);
|
||||
liq_write_remapped_image(res.get(), image.get(), image8bit, size);
|
||||
auto pal = liq_get_palette(res.get());
|
||||
|
||||
// Turn palletted image back into an RGBA image, and write it into the full size result image.
|
||||
for(int y = 0; y < block_height; y++) {
|
||||
for(int x = 0; x < block_width; x++) {
|
||||
// Turn palletted image back into an RGBA image, and write it into the
|
||||
// full size result image.
|
||||
for (int y = 0; y < block_height; y++) {
|
||||
for (int x = 0; x < 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);
|
||||
result[resultStartPos + 0] = pal->entries[image8bit[image8BitPos]].r;
|
||||
result[resultStartPos + 1] = pal->entries[image8bit[image8BitPos]].g;
|
||||
result[resultStartPos + 2] = pal->entries[image8bit[image8BitPos]].b;
|
||||
result[resultStartPos + 3] = pal->entries[image8bit[image8BitPos]].a;
|
||||
int resultStartPos = ((block_start_y + y) * image_width) + (block_start_x + x);
|
||||
result[resultStartPos] = pal->entries[image8bit[image8BitPos]];
|
||||
}
|
||||
}
|
||||
|
||||
liq_result_destroy(res);
|
||||
liq_image_destroy(image);
|
||||
liq_attr_destroy(attr);
|
||||
}
|
||||
}
|
||||
|
||||
free(image8bit);
|
||||
return {
|
||||
val(typed_memory_view(image_width*image_height*4, result)),
|
||||
image_width,
|
||||
image_height
|
||||
};
|
||||
}
|
||||
|
||||
void free_result() {
|
||||
free(result);
|
||||
return Uint8ClampedArray.new_(
|
||||
typed_memory_view(result.size() * sizeof(liq_color), (const uint8_t*)result.data()));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
class_<RawImage>("RawImage")
|
||||
.property("buffer", &RawImage::buffer)
|
||||
.property("width", &RawImage::width)
|
||||
.property("height", &RawImage::height);
|
||||
|
||||
function("quantize", &quantize);
|
||||
function("zx_quantize", &zx_quantize);
|
||||
function("version", &version);
|
||||
function("free_result", &free_result);
|
||||
}
|
||||
|
13
codecs/imagequant/imagequant.d.ts
vendored
13
codecs/imagequant/imagequant.d.ts
vendored
@ -1,15 +1,6 @@
|
||||
interface RawImage {
|
||||
buffer: Uint8Array;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface QuantizerModule extends EmscriptenWasm.Module {
|
||||
quantize(data: BufferSource, width: number, height: number, numColors: number, dither: number): RawImage;
|
||||
zx_quantize(data: BufferSource, width: number, height: number, dither: number): RawImage;
|
||||
free_result(): void;
|
||||
quantize(data: BufferSource, width: number, height: number, numColors: number, dither: number): Uint8ClampedArray;
|
||||
zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): QuantizerModule;
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
1145
codecs/imagequant/package-lock.json
generated
1145
codecs/imagequant/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,6 @@
|
||||
{
|
||||
"name": "imagequant",
|
||||
"scripts": {
|
||||
"install": "napa",
|
||||
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten ./build.sh"
|
||||
},
|
||||
"napa": {
|
||||
"libimagequant": "ImageOptim/libimagequant#2.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"napa": "^3.0.0"
|
||||
"build": "../build-cpp.sh"
|
||||
}
|
||||
}
|
||||
|
13
codecs/mozjpeg_enc/.emscripten
Normal file
13
codecs/mozjpeg_enc/.emscripten
Normal file
@ -0,0 +1,13 @@
|
||||
import os
|
||||
emsdk_path = "/emsdk/"
|
||||
#NODE_JS = emsdk_path + '/node/12.18.1_64bit/bin/node'
|
||||
# We need a newer version of Node that supports the most recent iteration of Wasm SIMD
|
||||
# and need to enable that experimental support via flag so that autoconf can successfully
|
||||
# detect SIMD support.
|
||||
NODE_JS=["/root/.nvm/versions/node/v14.7.0/bin/node", "--experimental-wasm-simd"]
|
||||
LLVM_ROOT = emsdk_path + '/upstream/bin'
|
||||
BINARYEN_ROOT = emsdk_path + '/upstream'
|
||||
EMSCRIPTEN_ROOT = emsdk_path + '/upstream/emscripten'
|
||||
TEMP_DIR = emsdk_path + '/tmp'
|
||||
COMPILER_ENGINE = NODE_JS
|
||||
JS_ENGINES = [NODE_JS]
|
63
codecs/mozjpeg_enc/Makefile
Normal file
63
codecs/mozjpeg_enc/Makefile
Normal file
@ -0,0 +1,63 @@
|
||||
CODEC_URL := https://github.com/mozilla/mozjpeg/archive/v3.3.1.tar.gz
|
||||
CODEC_DIR := node_modules/mozjpeg
|
||||
CODEC_OUT_RELATIVE := .libs/libjpeg.a rdswitch.o
|
||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||
OUT_JS := mozjpeg_enc_simd.js
|
||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||
|
||||
CFLAGS += -msimd128 -msse --em-config /src/.emscripten
|
||||
CXXFLAGS += -msimd128 -msse --em-config /src/.emscripten
|
||||
|
||||
#CFLAGS += --em-config /src/.emscripten
|
||||
#CXXFLAGS += --em-config /src/.emscripten
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
%.js: %.cpp $(CODEC_OUT)
|
||||
# We just to disable the overridden NODE_JS binary because
|
||||
# `--closure 1` can’t handle arrays in `.emscripten` it seems.
|
||||
# https://github.com/emscripten-core/emsdk/issues/583
|
||||
export EM_NODE_JS='/root/.nvm/versions/node/v14.7.0/bin/node' && \
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR) \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s EXPORT_ES6=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
# This one is a bit special: there is no rule for .libs/libjpeg.a
|
||||
# so we use libjpeg.la which implicitly builds that one instead.
|
||||
$(CODEC_DIR)/.libs/libjpeg.a: $(CODEC_DIR)/Makefile
|
||||
$(MAKE) -C $(CODEC_DIR) libjpeg.la
|
||||
|
||||
$(CODEC_DIR)/rdswitch.o: $(CODEC_DIR)/Makefile
|
||||
$(MAKE) -C $(CODEC_DIR) rdswitch.o
|
||||
|
||||
$(CODEC_DIR)/Makefile: $(CODEC_DIR)/configure
|
||||
cd $(CODEC_DIR) && ./configure \
|
||||
--disable-shared \
|
||||
--without-turbojpeg \
|
||||
--without-simd \
|
||||
--without-arith-enc \
|
||||
--without-arith-dec
|
||||
|
||||
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
|
||||
cd $(CODEC_DIR) && autoreconf -iv
|
||||
|
||||
$(CODEC_DIR)/configure.ac: $(CODEC_DIR)
|
||||
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $@
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_DIR) clean
|
@ -17,10 +17,6 @@ See `example.html`
|
||||
|
||||
Returns the version of MozJPEG as a number. va.b.c is encoded as 0x0a0b0c
|
||||
|
||||
### `void free_result()`
|
||||
|
||||
Frees the result created by `encode()`.
|
||||
|
||||
### `Uint8Array encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts)`
|
||||
|
||||
Encodes the given image with given dimension to JPEG. Options looks like this:
|
||||
|
62
codecs/mozjpeg_enc/bench.d8.js
Normal file
62
codecs/mozjpeg_enc/bench.d8.js
Normal file
@ -0,0 +1,62 @@
|
||||
import mozjpeg from "./mozjpeg_enc.js";
|
||||
import mozjpegSimd from "./mozjpeg_enc_simd.js";
|
||||
|
||||
const width = 2048;
|
||||
const height = 2048;
|
||||
const size = width * height * 4;
|
||||
const data = new Uint8ClampedArray(size);
|
||||
for(let i = 0; i < size; i++) {
|
||||
data[i] = Math.random() * 256;
|
||||
}
|
||||
|
||||
mozjpeg({
|
||||
onRuntimeInitialized() {
|
||||
const start = performance.now();
|
||||
const result = this.encode(data, width, height, {
|
||||
quality: 75,
|
||||
baseline: false,
|
||||
arithmetic: false,
|
||||
progressive: true,
|
||||
optimize_coding: true,
|
||||
smoothing: 0,
|
||||
color_space: 3,
|
||||
quant_table: 3,
|
||||
trellis_multipass: false,
|
||||
trellis_opt_zero: false,
|
||||
trellis_opt_table: false,
|
||||
trellis_loops: 1,
|
||||
auto_subsample: true,
|
||||
chroma_subsample: 2,
|
||||
separate_chroma_quality: false,
|
||||
chroma_quality: 75,
|
||||
});
|
||||
const end = performance.now();
|
||||
console.log("No SIMD", end - start);
|
||||
}
|
||||
})
|
||||
|
||||
mozjpegSimd({
|
||||
onRuntimeInitialized() {
|
||||
const start = performance.now();
|
||||
const result = this.encode(data, width, height, {
|
||||
quality: 75,
|
||||
baseline: false,
|
||||
arithmetic: false,
|
||||
progressive: true,
|
||||
optimize_coding: true,
|
||||
smoothing: 0,
|
||||
color_space: 3,
|
||||
quant_table: 3,
|
||||
trellis_multipass: false,
|
||||
trellis_opt_zero: false,
|
||||
trellis_opt_table: false,
|
||||
trellis_loops: 1,
|
||||
auto_subsample: true,
|
||||
chroma_subsample: 2,
|
||||
separate_chroma_quality: false,
|
||||
chroma_quality: 75,
|
||||
});
|
||||
const end = performance.now();
|
||||
console.log("SIMD", end - start);
|
||||
}
|
||||
})
|
@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
export OPTIMIZE="-Os"
|
||||
export LDFLAGS="${OPTIMIZE}"
|
||||
export CFLAGS="${OPTIMIZE}"
|
||||
export CPPFLAGS="${OPTIMIZE}"
|
||||
|
||||
apt-get update
|
||||
apt-get install -qqy autoconf libtool libpng-dev pkg-config
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling mozjpeg"
|
||||
echo "============================================="
|
||||
(
|
||||
cd node_modules/mozjpeg
|
||||
autoreconf -fiv
|
||||
emconfigure ./configure --without-simd
|
||||
emmake make libjpeg.la
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling mozjpeg done"
|
||||
echo "============================================="
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling wasm bindings"
|
||||
echo "============================================="
|
||||
(
|
||||
emcc \
|
||||
--bind \
|
||||
${OPTIMIZE} \
|
||||
-s WASM=1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="mozjpeg_enc"' \
|
||||
-I node_modules/mozjpeg \
|
||||
-o ./mozjpeg_enc.js \
|
||||
-Wno-deprecated-register \
|
||||
-Wno-writable-strings \
|
||||
node_modules/mozjpeg/rdswitch.c \
|
||||
-x c++ -std=c++11 \
|
||||
mozjpeg_enc.cpp \
|
||||
node_modules/mozjpeg/.libs/libjpeg.a
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling wasm bindings done"
|
||||
echo "============================================="
|
||||
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo "Did you update your docker image?"
|
||||
echo "Run \`docker pull trzeci/emscripten\`"
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
@ -1,26 +1,14 @@
|
||||
<!doctype html>
|
||||
<script src='mozjpeg_enc.js'></script>
|
||||
<script>
|
||||
const module = mozjpeg_enc();
|
||||
|
||||
async function loadImage(src) {
|
||||
// Load image
|
||||
const img = document.createElement('img');
|
||||
img.src = src;
|
||||
await new Promise(resolve => img.onload = resolve);
|
||||
// Make canvas same size as image
|
||||
const canvas = document.createElement('canvas');
|
||||
[canvas.width, canvas.height] = [img.width, img.height];
|
||||
// Draw image onto canvas
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
return ctx.getImageData(0, 0, img.width, img.height);
|
||||
}
|
||||
|
||||
module.onRuntimeInitialized = async _ => {
|
||||
console.log('Version:', module.version().toString(16));
|
||||
const module = mozjpeg_enc({
|
||||
loadFile() {
|
||||
return "./mozjpeg_enc.wasm";
|
||||
},
|
||||
async onRuntimeInitialized() {
|
||||
//console.log('Version:', module.version().toString(16));
|
||||
const image = await loadImage('../example.png');
|
||||
const result = module.encode(image.data, image.width, image.height, {
|
||||
const result = this.encode(image.data, image.width, image.height, {
|
||||
quality: 75,
|
||||
baseline: false,
|
||||
arithmetic: false,
|
||||
@ -44,5 +32,21 @@
|
||||
const img = document.createElement('img');
|
||||
img.src = blobURL;
|
||||
document.body.appendChild(img);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
async function loadImage(src) {
|
||||
// Load image
|
||||
const img = document.createElement('img');
|
||||
img.src = src;
|
||||
await new Promise(resolve => img.onload = resolve);
|
||||
// Make canvas same size as image
|
||||
const canvas = document.createElement('canvas');
|
||||
[canvas.width, canvas.height] = [img.width, img.height];
|
||||
// Draw image onto canvas
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
return ctx.getImageData(0, 0, img.width, img.height);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -1,18 +1,22 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
extern "C" {
|
||||
#include "cdjpeg.h"
|
||||
}
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro hackery to turn it
|
||||
// into a string. More details here: https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro
|
||||
// hackery to turn it into a string. More details here:
|
||||
// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
@ -39,8 +43,8 @@ int version() {
|
||||
char buffer[] = xstr(MOZJPEG_VERSION);
|
||||
int version = 0;
|
||||
int last_index = 0;
|
||||
for(int i = 0; i < strlen(buffer); i++) {
|
||||
if(buffer[i] == '.') {
|
||||
for (int i = 0; i < strlen(buffer); i++) {
|
||||
if (buffer[i] == '.') {
|
||||
buffer[i] = '\0';
|
||||
version = version << 8 | atoi(&buffer[last_index]);
|
||||
buffer[i] = '.';
|
||||
@ -51,16 +55,16 @@ int version() {
|
||||
return version;
|
||||
}
|
||||
|
||||
uint8_t* last_result;
|
||||
struct jpeg_compress_struct cinfo;
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
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
|
||||
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
||||
// I just write to memory instead of a file.
|
||||
|
||||
/* Step 1: allocate and initialize JPEG compression object */
|
||||
|
||||
/* This struct contains the JPEG compression parameters and pointers to
|
||||
* working space (which is allocated as needed by the JPEG library).
|
||||
@ -68,6 +72,7 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
||||
* compression/decompression processes, in existence at once. We refer
|
||||
* to any one struct (and its associated working data) as a "JPEG object".
|
||||
*/
|
||||
jpeg_compress_struct cinfo;
|
||||
/* This struct represents a JPEG error handler. It is declared separately
|
||||
* because applications often want to supply a specialized error handler
|
||||
* (see the second half of this file for an example). But here we just
|
||||
@ -76,15 +81,7 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
struct jpeg_error_mgr jerr;
|
||||
/* More stuff */
|
||||
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
|
||||
int row_stride; /* physical row width in image buffer */
|
||||
uint8_t* output;
|
||||
unsigned long size;
|
||||
|
||||
/* Step 1: allocate and initialize JPEG compression object */
|
||||
|
||||
jpeg_error_mgr jerr;
|
||||
/* We have to set up the error handler first, in case the initialization
|
||||
* step fails. (Unlikely, but it could happen if you are out of memory.)
|
||||
* This routine fills in the contents of struct jerr, and returns jerr's
|
||||
@ -106,6 +103,8 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
||||
// fprintf(stderr, "can't open %s\n", filename);
|
||||
// exit(1);
|
||||
// }
|
||||
uint8_t* output = nullptr;
|
||||
unsigned long size = 0;
|
||||
jpeg_mem_dest(&cinfo, &output, &size);
|
||||
|
||||
/* Step 3: set parameters for compression */
|
||||
@ -113,17 +112,17 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
||||
/* First we supply a description of the input image.
|
||||
* 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.input_components = 4; /* # of color components per pixel */
|
||||
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
||||
cinfo.input_components = 4; /* # of color components per pixel */
|
||||
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
||||
/* Now use the library's routine to set default compression parameters.
|
||||
* (You must set at least cinfo.in_color_space before calling this,
|
||||
* since the defaults depend on the source color space.)
|
||||
*/
|
||||
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) {
|
||||
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
||||
@ -143,17 +142,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_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
|
||||
// does some useful heuristic stuff.
|
||||
// A little hacky to build a string for this, but it means we can use
|
||||
// set_quality_ratings which does some useful heuristic stuff.
|
||||
std::string quality_str = std::to_string(opts.quality);
|
||||
|
||||
if (opts.separate_chroma_quality && opts.color_space == JCS_YCbCr) {
|
||||
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) {
|
||||
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
||||
@ -181,54 +180,54 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
||||
* To keep things simple, we pass one scanline per call; you can pass
|
||||
* more if you wish, though.
|
||||
*/
|
||||
row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
|
||||
int row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could pass
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
|
||||
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
|
||||
JSAMPROW row_pointer =
|
||||
&image_buffer[cinfo.next_scanline * row_stride]; /* pointer to JSAMPLE row[s] */
|
||||
(void)jpeg_write_scanlines(&cinfo, &row_pointer, 1);
|
||||
}
|
||||
|
||||
/* Step 6: Finish compression */
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
/* Step 7: release JPEG compression object */
|
||||
|
||||
last_result = output;
|
||||
auto js_result = Uint8Array.new_(typed_memory_view(size, output));
|
||||
|
||||
/* And we're done! */
|
||||
return val(typed_memory_view(size, output));
|
||||
}
|
||||
|
||||
void free_result() {
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(output);
|
||||
|
||||
/* And we're done! */
|
||||
return js_result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<MozJpegOptions>("MozJpegOptions")
|
||||
.field("quality", &MozJpegOptions::quality)
|
||||
.field("baseline", &MozJpegOptions::baseline)
|
||||
.field("arithmetic", &MozJpegOptions::arithmetic)
|
||||
.field("progressive", &MozJpegOptions::progressive)
|
||||
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
||||
.field("smoothing", &MozJpegOptions::smoothing)
|
||||
.field("color_space", &MozJpegOptions::color_space)
|
||||
.field("quant_table", &MozJpegOptions::quant_table)
|
||||
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
||||
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
||||
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
||||
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
||||
.field("chroma_subsample", &MozJpegOptions::chroma_subsample)
|
||||
.field("auto_subsample", &MozJpegOptions::auto_subsample)
|
||||
.field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality)
|
||||
.field("chroma_quality", &MozJpegOptions::chroma_quality)
|
||||
;
|
||||
.field("quality", &MozJpegOptions::quality)
|
||||
.field("baseline", &MozJpegOptions::baseline)
|
||||
.field("arithmetic", &MozJpegOptions::arithmetic)
|
||||
.field("progressive", &MozJpegOptions::progressive)
|
||||
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
||||
.field("smoothing", &MozJpegOptions::smoothing)
|
||||
.field("color_space", &MozJpegOptions::color_space)
|
||||
.field("quant_table", &MozJpegOptions::quant_table)
|
||||
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
||||
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
||||
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
||||
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
||||
.field("chroma_subsample", &MozJpegOptions::chroma_subsample)
|
||||
.field("auto_subsample", &MozJpegOptions::auto_subsample)
|
||||
.field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality)
|
||||
.field("chroma_quality", &MozJpegOptions::chroma_quality);
|
||||
|
||||
function("version", &version);
|
||||
function("encode", &encode);
|
||||
function("free_result", &free_result);
|
||||
}
|
||||
|
1
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
1
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
@ -2,7 +2,6 @@ import { EncodeOptions } from '../../src/codecs/mozjpeg/encoder-meta';
|
||||
|
||||
interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array;
|
||||
free_result(): void;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): MozJPEGModule;
|
||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
1145
codecs/mozjpeg_enc/package-lock.json
generated
1145
codecs/mozjpeg_enc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,6 @@
|
||||
{
|
||||
"name": "mozjpeg_enc",
|
||||
"scripts": {
|
||||
"install": "napa",
|
||||
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten ./build.sh"
|
||||
},
|
||||
"napa": {
|
||||
"mozjpeg": "mozilla/mozjpeg#v3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"napa": "^3.0.0"
|
||||
"build": "../build-cpp.sh"
|
||||
}
|
||||
}
|
||||
|
2
codecs/optipng/.gitignore
vendored
2
codecs/optipng/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
build/
|
||||
*.o
|
@ -1,26 +0,0 @@
|
||||
# OptiPNG
|
||||
|
||||
- Source: <https://sourceforge.net/project/optipng>
|
||||
- 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"
|
||||
}
|
||||
}
|
1
codecs/oxipng/.gitignore
vendored
Normal file
1
codecs/oxipng/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
496
codecs/oxipng/Cargo.lock
generated
Normal file
496
codecs/oxipng/Cargo.lock
generated
Normal file
@ -0,0 +1,496 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "build_const"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cloudflare-zlib"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5ed63a019d55bacd15cadcbcb96bf41b16281417fff393bdb55fa84255fe4b9"
|
||||
dependencies = [
|
||||
"cloudflare-zlib-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudflare-zlib-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e195cb274a0d6ee87e718838a09baecd7cbc9f6075dac256a84cb5842739c06"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||
dependencies = [
|
||||
"build_const",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"maybe-uninit",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2397fc43bd5648b7117aabb3c5e62d0e62c194826ec77b0b4d0c41e62744635"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
|
||||
|
||||
[[package]]
|
||||
name = "libdeflater"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxipng"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fd695858078338d73862ff3755f820eff0bf4f3304e4b52f22aba53463183a"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
"byteorder",
|
||||
"cloudflare-zlib",
|
||||
"crc",
|
||||
"image",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"libdeflater",
|
||||
"log",
|
||||
"miniz_oxide",
|
||||
"rgb",
|
||||
"zopfli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.16.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c150bf7479fafe3dd8740dbe48cc33b2a3efb7b0fe3483aced8bbc39f6d0238d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ef54b45ae131327a88597e2463fee4098ad6c88ba7b6af4b3987db8aad4098"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "squoosh-oxipng"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"oxipng",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4079b79464426ade2a1b0177fb0ce8396ba6b4084267407e333573c666073964"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
"crc",
|
||||
"typed-arena",
|
||||
]
|
18
codecs/oxipng/Cargo.toml
Normal file
18
codecs/oxipng/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "squoosh-oxipng"
|
||||
version = "0.1.0"
|
||||
authors = ["Ingvar Stepanyan <me@rreverser.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
oxipng = { version = "3.0.0", default-features = false }
|
||||
wasm-bindgen = "0.2.64"
|
||||
log = { version = "0.4", features = ["release_max_level_off"] }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = "s"
|
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.17/wabt-1.0.17-ubuntu.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-11/wasi-sdk-11.0-linux.tar.gz | tar -xzf - -C /opt/wasi-sdk --strip 1
|
||||
|
||||
ENV PATH="/opt/wabt/bin:/opt/wasi-sdk/bin:${PATH}"
|
||||
WORKDIR /src
|
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
|
||||
}
|
6
codecs/oxipng/package.json
Normal file
6
codecs/oxipng/package.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "oxipng",
|
||||
"scripts": {
|
||||
"build": "../build-rust.sh"
|
||||
}
|
||||
}
|
15
codecs/oxipng/pkg/package.json
Normal file
15
codecs/oxipng/pkg/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "squoosh-oxipng",
|
||||
"collaborators": [
|
||||
"Ingvar Stepanyan <me@rreverser.com>"
|
||||
],
|
||||
"version": "0.1.0",
|
||||
"files": [
|
||||
"squoosh_oxipng_bg.wasm",
|
||||
"squoosh_oxipng.js",
|
||||
"squoosh_oxipng.d.ts"
|
||||
],
|
||||
"module": "squoosh_oxipng.js",
|
||||
"types": "squoosh_oxipng.d.ts",
|
||||
"sideEffects": false
|
||||
}
|
8
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
Normal file
8
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {number} level
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
2
codecs/oxipng/pkg/squoosh_oxipng.js
Normal file
2
codecs/oxipng/pkg/squoosh_oxipng.js
Normal file
@ -0,0 +1,2 @@
|
||||
import * as wasm from "./squoosh_oxipng_bg.wasm";
|
||||
export * from "./squoosh_oxipng_bg.js";
|
8
codecs/oxipng/pkg/squoosh_oxipng_bg.d.ts
vendored
Normal file
8
codecs/oxipng/pkg/squoosh_oxipng_bg.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export function optimise(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_free(a: number, b: number): void;
|
60
codecs/oxipng/pkg/squoosh_oxipng_bg.js
Normal file
60
codecs/oxipng/pkg/squoosh_oxipng_bg.js
Normal file
@ -0,0 +1,60 @@
|
||||
import * as wasm from './squoosh_oxipng_bg.wasm';
|
||||
|
||||
const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;
|
||||
|
||||
let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||
|
||||
cachedTextDecoder.decode();
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
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} data
|
||||
* @param {number} level
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data, level) {
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(8, ptr0, len0, level);
|
||||
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;
|
||||
}
|
||||
|
||||
export const __wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
BIN
codecs/oxipng/pkg/squoosh_oxipng_bg.wasm
Normal file
BIN
codecs/oxipng/pkg/squoosh_oxipng_bg.wasm
Normal file
Binary file not shown.
18
codecs/oxipng/src/lib.rs
Normal file
18
codecs/oxipng/src/lib.rs
Normal file
@ -0,0 +1,18 @@
|
||||
mod malloc_shim;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use oxipng::AlphaOptim;
|
||||
|
||||
#[wasm_bindgen(catch)]
|
||||
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||
let mut options = oxipng::Options::from_preset(level);
|
||||
options.alphas.insert(AlphaOptim::Black);
|
||||
options.alphas.insert(AlphaOptim::White);
|
||||
options.alphas.insert(AlphaOptim::Up);
|
||||
options.alphas.insert(AlphaOptim::Down);
|
||||
options.alphas.insert(AlphaOptim::Left);
|
||||
options.alphas.insert(AlphaOptim::Right);
|
||||
|
||||
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||
}
|
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))
|
||||
}
|
5
codecs/resize/.gitignore
vendored
Normal file
5
codecs/resize/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
**/*.rs.bk
|
||||
target
|
||||
bin/
|
||||
pkg/README.md
|
||||
lut.inc
|
284
codecs/resize/Cargo.lock
generated
Normal file
284
codecs/resize/Cargo.lock
generated
Normal file
@ -0,0 +1,284 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memory_units"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resize"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e653e390eafbfebb2b3c5fcfbc90d801bc410d0de1f44f266ffbf2151d28aa"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
|
||||
[[package]]
|
||||
name = "squoosh-resize"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"console_error_panic_hook",
|
||||
"resize",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
"wee_alloc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"unicode-xid 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
|
||||
dependencies = [
|
||||
"quote 1.0.7",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"futures",
|
||||
"js-sys",
|
||||
"scoped-tls",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-bindgen-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wee_alloc"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memory_units",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
38
codecs/resize/Cargo.toml
Normal file
38
codecs/resize/Cargo.toml
Normal file
@ -0,0 +1,38 @@
|
||||
[package]
|
||||
name = "squoosh-resize"
|
||||
version = "0.1.0"
|
||||
authors = ["Surma <surma@surma.link>"]
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
#crate-type = ["cdylib", "rlib"]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook", "wee_alloc"]
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "0.1.2"
|
||||
wasm-bindgen = "0.2.38"
|
||||
resize = "0.3.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.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]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
opt-level = "s"
|
||||
lto = true
|
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(())
|
||||
}
|
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
|
||||
}
|
6
codecs/resize/package.json
Normal file
6
codecs/resize/package.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "resize",
|
||||
"scripts": {
|
||||
"build": "../build-rust.sh"
|
||||
}
|
||||
}
|
15
codecs/resize/pkg/package.json
Normal file
15
codecs/resize/pkg/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "squoosh-resize",
|
||||
"collaborators": [
|
||||
"Surma <surma@surma.link>"
|
||||
],
|
||||
"version": "0.1.0",
|
||||
"files": [
|
||||
"squoosh_resize_bg.wasm",
|
||||
"squoosh_resize.js",
|
||||
"squoosh_resize.d.ts"
|
||||
],
|
||||
"module": "squoosh_resize.js",
|
||||
"types": "squoosh_resize.d.ts",
|
||||
"sideEffects": false
|
||||
}
|
14
codecs/resize/pkg/squoosh_resize.d.ts
vendored
Normal file
14
codecs/resize/pkg/squoosh_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/squoosh_resize.js
Normal file
2
codecs/resize/pkg/squoosh_resize.js
Normal file
@ -0,0 +1,2 @@
|
||||
import * as wasm from "./squoosh_resize_bg.wasm";
|
||||
export * from "./squoosh_resize_bg.js";
|
6
codecs/resize/pkg/squoosh_resize_bg.d.ts
vendored
Normal file
6
codecs/resize/pkg/squoosh_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/squoosh_resize_bg.js
Normal file
52
codecs/resize/pkg/squoosh_resize_bg.js
Normal file
@ -0,0 +1,52 @@
|
||||
import * as wasm from './squoosh_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/squoosh_resize_bg.wasm
Normal file
BIN
codecs/resize/pkg/squoosh_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() {}
|
||||
}
|
||||
}
|
1
codecs/rotate/.gitignore
vendored
Normal file
1
codecs/rotate/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
target
|
6
codecs/rotate/Cargo.lock
generated
Normal file
6
codecs/rotate/Cargo.lock
generated
Normal file
@ -0,0 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "squoosh-rotate"
|
||||
version = "0.1.0"
|
||||
|
15
codecs/rotate/Cargo.toml
Normal file
15
codecs/rotate/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "squoosh-rotate"
|
||||
version = "0.1.0"
|
||||
authors = ["Surma <surma@google.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[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));
|
8
codecs/rotate/build.sh
Executable file
8
codecs/rotate/build.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cargo build \
|
||||
--target wasm32-unknown-unknown \
|
||||
--release
|
||||
wasm-opt -Os --strip target/wasm32-unknown-unknown/release/rotate.wasm -o rotate.wasm
|
10
codecs/rotate/package.json
Normal file
10
codecs/rotate/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "rotate",
|
||||
"scripts": {
|
||||
"build": "../build-rust.sh ./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.
15
codecs/rust.Dockerfile
Normal file
15
codecs/rust.Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM emscripten/emsdk:1.39.19 AS wasm-tools
|
||||
WORKDIR /opt/wasm-tools
|
||||
RUN wget -qO- https://github.com/rustwasm/wasm-pack/releases/download/v0.9.1/wasm-pack-v0.9.1-x86_64-unknown-linux-musl.tar.gz | tar -xzf - --strip 1
|
||||
|
||||
FROM rust:1.44-stretch AS rust
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
COPY --from=wasm-tools /emsdk/upstream/bin/wasm-opt /emsdk/upstream/bin/clang /usr/local/bin/
|
||||
COPY --from=wasm-tools /emsdk/upstream/lib/ /usr/local/lib/
|
||||
COPY --from=wasm-tools /emsdk/upstream/emscripten/system/include/libc/ /wasm32/include/
|
||||
COPY --from=wasm-tools /emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten/bits/ /wasm32/include/bits/
|
||||
COPY --from=wasm-tools /opt/wasm-tools/wasm-pack /usr/local/cargo/bin/
|
||||
|
||||
ENV CPATH="/wasm32/include"
|
||||
WORKDIR /src
|
||||
CMD ["sh", "-c", "rm -rf pkg && wasm-pack build -- --verbose --locked && rm pkg/.gitignore"]
|
56
codecs/webp/Makefile
Normal file
56
codecs/webp/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
CODEC_URL := https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||
CODEC_DIR = node_modules/libwebp
|
||||
CODEC_OUT_RELATIVE = src/.libs/libwebp.a
|
||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||
OUT_JS = enc/webp_enc.js dec/webp_dec.js
|
||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
%.js: %.cpp $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR) \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
$(CODEC_OUT): $(CODEC_DIR)/src/Makefile
|
||||
$(MAKE) -C $(CODEC_DIR)/src
|
||||
|
||||
$(CODEC_DIR)/src/Makefile: $(CODEC_DIR)/configure
|
||||
cd $(CODEC_DIR) && ./configure \
|
||||
--disable-shared \
|
||||
--disable-libwebpdemux \
|
||||
--disable-wic \
|
||||
--disable-gif \
|
||||
--disable-tiff \
|
||||
--disable-jpeg \
|
||||
--disable-png \
|
||||
--disable-sdl \
|
||||
--disable-gl \
|
||||
--disable-threading \
|
||||
--disable-neon-rtcd \
|
||||
--disable-neon \
|
||||
--disable-sse2 \
|
||||
--disable-sse4.1
|
||||
|
||||
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
|
||||
cd $(CODEC_DIR) && autoreconf -iv
|
||||
|
||||
$(CODEC_DIR)/configure.ac: $(CODEC_DIR)
|
||||
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $@
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_DIR) clean
|
@ -1,7 +1,7 @@
|
||||
# WebP decoder
|
||||
|
||||
- Source: <https://github.com/webmproject/libwebp>
|
||||
- Version: v0.6.1
|
||||
- Version: v1.0.2
|
||||
|
||||
## Example
|
||||
|
||||
@ -16,7 +16,3 @@ Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
||||
### `RawImage decode(std::string buffer)`
|
||||
|
||||
Decodes the given webp buffer into raw RGBA. `RawImage` is a class with 3 fields: `buffer`, `width`, and `height`.
|
||||
|
||||
### `void free_result()`
|
||||
|
||||
Frees the result created by `decode()`.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user