Compare commits
729 Commits
prerenderi
...
v1.10.1
Author | SHA1 | Date | |
---|---|---|---|
62c53c9fed | |||
53a38b2ba1 | |||
f3dfcae3f0 | |||
3f7274a6ac | |||
f5bc715bc0 | |||
22b7e36c01 | |||
a0e6a377cd | |||
22b04c159d | |||
92249ac711 | |||
629d64326d | |||
4621cbcae9 | |||
164191d746 | |||
b22adc9957 | |||
6b0a675469 | |||
d7fb0d9b40 | |||
309947a08f | |||
6aeaae6160 | |||
71b3c7dda2 | |||
48c06e86fa | |||
1b7d3fa394 | |||
650db99818 | |||
7638bb795e | |||
570e604be0 | |||
a056d1c363 | |||
fce61c8c89 | |||
d60d0ae47d | |||
8bf741ed4e | |||
9f660e5178 | |||
ef2318bcc1 | |||
364a5db5d5 | |||
4a01d0d548 | |||
4a9c28f89f | |||
3aed873467 | |||
2b7f059b8f | |||
33726e9c68 | |||
3d29f486e7 | |||
79e8a26f06 | |||
e8efd54766 | |||
edcc774c16 | |||
746b33a590 | |||
8a264efc67 | |||
f0af6e97a0 | |||
043107c101 | |||
e9e3b923e0 | |||
aea6e91b1d | |||
9c4717a13d | |||
559cabce9e | |||
7f6a3de7ca | |||
f3adc87f52 | |||
6499e9f63d | |||
ac1f104e49 | |||
87f89e6b2f | |||
7f6404d5a8 | |||
8e857cd393 | |||
b8f801333d | |||
499956e216 | |||
3932ee2c00 | |||
68177b7590 | |||
0a2a4122dc | |||
e6299569d0 | |||
578ad8c291 | |||
eaa294b689 | |||
6e97cfb8d5 | |||
80a68c48b2 | |||
98865f8141 | |||
78da9fd144 | |||
94c50a989b | |||
3e525e767c | |||
dfcc1e24e4 | |||
f3aa8edfca | |||
ffd7ee6013 | |||
64bb09dbc5 | |||
35fcbc40ed | |||
1b55a48680 | |||
88fbb19d29 | |||
3dc1501ff7 | |||
b7576c559a | |||
69ed2e1d56 | |||
55f7f3d72a | |||
055d0b4ea1 | |||
7735346ed0 | |||
2a06fdbbe0 | |||
19169199e9 | |||
76f3c39b78 | |||
8da52acc4c | |||
9253522a3a | |||
cf39a3e5a5 | |||
a08877f0ac | |||
2f0dc1c067 | |||
535d8c9142 | |||
6dc2ba3bef | |||
93cfdc8f98 | |||
671544349e | |||
d3c1939692 | |||
99642aef96 | |||
ac4942b640 | |||
23cb004a86 | |||
4b6de60978 | |||
de204aa56a | |||
976f811b36 | |||
855fc9e602 | |||
a8848e717c | |||
90b99faf8b | |||
d3cfffbbcf | |||
fade7f9be8 | |||
b10dd055d3 | |||
7532f01222 | |||
2df09efdee | |||
bed4f49a12 | |||
2b7fefff8b | |||
bdcf2519ce | |||
3f8afb72a6 | |||
2f834db224 | |||
3541ce7492 | |||
b6fae0eb4c | |||
fbaa282f07 | |||
6136ae7411 | |||
f024747299 | |||
66feffcc49 | |||
24254df7db | |||
cae73f1f1b | |||
073a52213e | |||
0d34485a00 | |||
65519d539e | |||
ec44a8e817 | |||
920f225cb0 | |||
d5d4bd61ff | |||
5656d10b67 | |||
adb4b6468b | |||
0a293d7f63 | |||
27cb5afd5b | |||
5e58fc6b04 | |||
e820adfc96 | |||
5a8a114dcb | |||
a1c685e820 | |||
377dcfcc1b | |||
913e67ca93 | |||
fb1a97c7d4 | |||
42eef6945d | |||
d04b08d640 | |||
c547dd10d3 | |||
f4579da9c9 | |||
37dc585d80 | |||
bc0a425a0f | |||
b696f246a1 | |||
e6e197e140 | |||
1c0e8a1fd3 | |||
e3e154fa1a | |||
73b7c437f9 | |||
719168be77 | |||
a2021b175c | |||
9a388fbd13 | |||
1ba0452540 | |||
73df9f18f0 | |||
0e7521877b | |||
120b37c192 | |||
5f3502b838 | |||
33f99432c5 | |||
85756ff5df | |||
84e567ad6a | |||
39281331fa | |||
438ce2ce63 | |||
a13e17e256 | |||
cd6db2d776 | |||
a08662b617 | |||
003ec9de35 | |||
e7f76ca0b8 | |||
21111e2927 | |||
445c3ef32c | |||
9df5542ee1 | |||
fffc4a0cd1 | |||
50a8743be3 | |||
8480bc7dbd | |||
72e4546922 | |||
11be5babca | |||
17e5db2427 | |||
465093eb07 | |||
b430ac1041 | |||
ea96847c1e | |||
3b5106a61d | |||
9f611b0b52 | |||
18a6b3c3e5 | |||
d9ed4e18ea | |||
9e757aa896 | |||
89b58bb446 | |||
e80ca583cc | |||
2ecc81b34f | |||
60e98ee34f | |||
538ea89ea9 | |||
3990e11e0a | |||
0251f88fe5 | |||
bbcb959b11 | |||
b5e928bac9 | |||
6592dee4a9 | |||
9b3d72191e | |||
a92e5b48ff | |||
e355764ab0 | |||
c5efd5a8bf | |||
385461944b | |||
8385ba3274 | |||
6ca6a77595 | |||
14c837e894 | |||
33346d7cb6 | |||
05d4f531e2 | |||
ede2c49b12 | |||
16acd32c68 | |||
cc90192860 | |||
3607005fa8 | |||
7646a64f94 | |||
c8ce6ce27b | |||
1240474c4b | |||
f5e84441c0 | |||
6bc19d78bc | |||
a4437d2873 | |||
cd19650748 | |||
253315b3b1 | |||
4203ad9a13 | |||
6958202f9d | |||
386fef063f | |||
d7246ca427 | |||
fd024853b6 | |||
bd53d17876 | |||
3f87f571f4 | |||
1c69a6f1b7 | |||
82419cbb6e | |||
db65630c8d | |||
b8e54b947f | |||
f23897108d | |||
1efe5b21f0 | |||
fc71b4d249 | |||
dc81d46556 | |||
56c2080f43 | |||
4cc50fcaa5 | |||
2d67562576 | |||
76f2d7afa7 | |||
80fa9c4f21 | |||
8f215a5b4b | |||
bffd9cb52a | |||
74b1ff5b10 | |||
3c0079fea0 | |||
c0a9723d20 | |||
a4f0a76200 | |||
eb57b0130b | |||
f8c37c7abc | |||
72373f8812 | |||
b285e99e7d | |||
f9a6b88bb6 | |||
4a65d506f2 | |||
3bc03c90fd | |||
c35dfa4ac5 | |||
1d2a9a9dde | |||
925220bb13 | |||
16d088bfe3 | |||
b8e22ee435 | |||
60dea4b932 | |||
8ae1a42e4b | |||
cfdc7a46e6 | |||
afb23adcbf | |||
3b84a474b8 | |||
e96bb04e88 | |||
2e3b8507b2 | |||
e12c69f1a6 | |||
d049a23469 | |||
2633f427c8 | |||
ff920f1d7b | |||
fd69560025 | |||
ba51e47e05 | |||
409f552274 | |||
69a7c184bd | |||
3039c84738 | |||
bfa5cd085d | |||
7c282b30b1 | |||
06fa3c541e | |||
c9e31ac1f7 | |||
e248486d3d | |||
b32a52d236 | |||
a24b4d6d4d | |||
b831aa0075 | |||
bf4d4b78cb | |||
496896e36e | |||
6b88ec1f8a | |||
3af5f3a96d | |||
ddc5564515 | |||
bc5da7ef06 | |||
45221c0b03 | |||
d29cf2ffa7 | |||
f6c0b89d1f | |||
ecd9e06665 | |||
9e5b66d5f4 | |||
8c35c3cdaa | |||
828a6240fe | |||
eaad0eaee0 | |||
db76d4417c | |||
7a6c6ec210 | |||
8e034f183b | |||
5a01b34cce | |||
1399a9bffe | |||
653c6ed85a | |||
ebbb7b58cb | |||
7164e4e315 | |||
23398d07f9 | |||
ec2bc3efa2 | |||
86d78763c1 | |||
fb5ae36d7e | |||
51f812625b | |||
479bfee647 | |||
a3501a56cd | |||
c353e286b0 | |||
8ed01e8a87 | |||
36ed21b9f4 | |||
cca41bb449 | |||
8f787ad0e6 | |||
9c1170f100 | |||
5432be4a3f | |||
7cae821db5 | |||
19ebb24f03 | |||
d07512566e | |||
61929666f3 | |||
792ffbfcd7 | |||
9685271bb4 | |||
5b1a6cc95e | |||
bf34075e6a | |||
f1859eeef2 | |||
fa12b37e53 | |||
520a5dc9f2 | |||
7af949b5a5 | |||
300612b09b | |||
6f00e9825c | |||
6ca9c5300e | |||
cdeb31051b | |||
ba90517ad7 | |||
7aff949f47 | |||
0e8c0da3dd | |||
3132a207e1 | |||
88dd0e06c5 | |||
f507a2464f | |||
14baa6ebf8 | |||
5d32126565 | |||
484ff7ab4c | |||
36f86385a2 | |||
436faa17af | |||
d205ae206f | |||
6baa5900fc | |||
fadb53f075 | |||
1a63387408 | |||
a316120b69 | |||
0d1e5ef119 | |||
b49cfca39d | |||
ab58df4c2c | |||
db20f10bd2 | |||
444cc5a193 | |||
6c253bc9b4 | |||
2fd28e174e | |||
a188692c88 | |||
b263419e08 | |||
826e06c727 | |||
dfcdfb105f | |||
0508bbb16f | |||
dfbfa85fd3 | |||
b99ad4bdc3 | |||
e801170496 | |||
91e7c9c5ad | |||
ca5162ed32 | |||
0bf87d0c87 | |||
ce91eb5bae | |||
8d68056bca | |||
d0de8e444a | |||
dfef1f21cc | |||
2440ac4e87 | |||
e90db78697 | |||
5ae15d429c | |||
89d6b46f3e | |||
e086f64779 | |||
9ed3b4f11e | |||
ece3fa12b4 | |||
9a35224535 | |||
ef3faa58bc | |||
b6a8f7eeba | |||
d1203d9c42 | |||
a834b6ae38 | |||
e7982a73ad | |||
717342c80c | |||
075f0e62fd | |||
bcca31fbed | |||
007891fc11 | |||
f8e41952d1 | |||
e4d64f8a79 | |||
1654f69ec1 | |||
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 | |||
a0f1379feb | |||
9b17322478 | |||
f562bad286 | |||
6994cc3d15 | |||
9b572f9541 | |||
71f893cb44 | |||
6b76ea0a6f | |||
7616d33883 | |||
3c757bb2b2 | |||
a502df80ba | |||
921268ec58 | |||
7d42d4f973 | |||
e4e130c5d6 | |||
bcf7a63118 | |||
66aac12db7 | |||
59cd1f8930 | |||
150e704d20 | |||
b2d47f0fb8 | |||
bd3d33296d | |||
f4c82ced97 | |||
76188df0d3 | |||
9a58e4d339 | |||
f396a5b784 | |||
e572b853e2 | |||
726c2f195a | |||
4599e51b1e | |||
d93169cc5a | |||
bdd3c11f1a | |||
0cec90c7ca | |||
43def798e1 | |||
02b0c022ca | |||
c82d0d1b88 | |||
e24d7865ce | |||
a79f95b305 | |||
49b40b1c3e | |||
11ee74e224 | |||
f335246673 | |||
ccb734aec6 | |||
568b9e9459 | |||
a43ea761f5 | |||
577c77cc30 | |||
d2f60baef9 | |||
64acc08cd7 | |||
a1f0b81dff | |||
48bb58dc89 | |||
765cc213d2 | |||
37f5c0dd76 | |||
b25d1eaf86 | |||
248676aa31 | |||
059c80c05d | |||
cfd42818b7 | |||
5e66e0acc4 | |||
c9fe5ffbcf | |||
1b630a092f | |||
09e60284cb | |||
76b34c62db | |||
9d7212bc1d | |||
1b69c9231d | |||
bcd88f6356 | |||
2a47f67214 | |||
5e8dc1b26c | |||
c591f1f37d | |||
4db43ccd4e | |||
ea5d3c2d78 | |||
700b1f15cd | |||
485ba174e3 | |||
32f6f8b941 | |||
54ad30a7ed | |||
170d75482e | |||
a8db2b30f2 | |||
e3b1b08424 | |||
8006a1a5e7 | |||
1ae65dd4a1 | |||
bff515b63f | |||
65c3ea826f | |||
602d5140f9 | |||
44f0700332 | |||
c90db020b0 | |||
ef4094885e | |||
b52d9d9194 | |||
d3f2836f48 | |||
27722f77f9 | |||
3a0db14c40 | |||
e0dc1b48ec | |||
009327c2c4 | |||
b16d60b52b | |||
c550fe9283 | |||
dce4fc70ac | |||
b3f3ecbf28 | |||
e8c0ddfc7f | |||
a002b376af | |||
2165383da4 | |||
5fbf6b297f | |||
9d5ad83ff8 | |||
07f17dece2 | |||
f2f467ecb8 | |||
2ea9e22b52 | |||
4ee5572d2f | |||
df7e112d22 | |||
13ac3ed5b2 | |||
b7c223bc0d | |||
0f08121596 | |||
b15545402a | |||
b310c97044 | |||
307c6b05ae | |||
77a6d21924 | |||
d22a343378 | |||
790a5b580d | |||
6e8f8bbe41 | |||
cc9d01a9ab | |||
526520c399 | |||
acbc31bc35 | |||
e8e151a926 | |||
835a537c55 | |||
23ea9fad49 | |||
491280935a | |||
900eda9a8e | |||
38d0057833 | |||
3867448aad | |||
807a76d443 | |||
3e26a0a3cc | |||
68729979e3 | |||
a09ec269b8 | |||
3f18c927f1 | |||
9add650b75 | |||
cc3ed168d8 | |||
3b9b1e9f2e | |||
7c220b1a92 | |||
3035a68b90 | |||
65847c0ed7 | |||
5303afe9ad | |||
579b8a494a | |||
56faf619d0 | |||
85e3a12c84 | |||
cab8d3f13c | |||
5c651a1716 | |||
ba0ad81646 | |||
695bbed12b | |||
6a6d478f77 | |||
d75a3aca9b | |||
91945da5ae | |||
00e73daabd | |||
60543dd0a5 | |||
850a019212 | |||
9c0e0b683e | |||
79dfe39978 | |||
96a61eb0b2 | |||
e62fc26dfd | |||
638c57b6fe | |||
7ff18e6ae1 | |||
9d8f885556 | |||
5245c5ca6e | |||
19342208d2 | |||
a9e1c38971 | |||
1533728f59 | |||
d4a616713a | |||
a7598b6602 | |||
e38e7154a6 | |||
7a5c8f5d6b | |||
49db0de05f | |||
8daaea5768 | |||
c2e2a1a0b6 | |||
7edb7f0de8 | |||
634dfe3717 | |||
1b4526ca1e | |||
5e2c4be0c6 | |||
e9eaf227bc | |||
6249ca8ac8 | |||
03a6716745 | |||
ddf8409127 | |||
bcf71f4702 | |||
31db4b9719 | |||
953a0c9124 | |||
444e59c69c | |||
b619427237 | |||
5f7f9e32a8 | |||
1196d4f54f | |||
da53b5fedc | |||
c5e3f9e737 | |||
3b47ee6fe5 | |||
aa02cf2157 |
31
.babelrc
31
.babelrc
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
[
|
|
||||||
"env",
|
|
||||||
{
|
|
||||||
"loose": true,
|
|
||||||
"uglify": false,
|
|
||||||
"modules": false,
|
|
||||||
"targets": {
|
|
||||||
"browsers": "last 2 versions"
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"transform-regenerator",
|
|
||||||
"transform-es2015-typeof-symbol"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"transform-decorators-legacy",
|
|
||||||
"transform-class-properties",
|
|
||||||
"transform-react-constant-elements",
|
|
||||||
"transform-react-remove-prop-types",
|
|
||||||
[
|
|
||||||
"transform-react-jsx",
|
|
||||||
{
|
|
||||||
"pragma": "h"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
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.
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,6 @@
|
|||||||
node_modules
|
node_modules
|
||||||
/build
|
/build
|
||||||
/*.log
|
/*.log
|
||||||
|
*.scss.d.ts
|
||||||
|
*.css.d.ts
|
||||||
|
*.o
|
||||||
|
4
.travis.yml
Normal file
4
.travis.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
language: node_js
|
||||||
|
cache: npm
|
||||||
|
script: npm run build
|
||||||
|
after_success: npm run sizereport
|
32
README.md
32
README.md
@ -1,5 +1,31 @@
|
|||||||
# Squoosh!
|
# [Squoosh]!
|
||||||
|
|
||||||
Squoosh will be an image compression web app that allows you to dive into the
|
[Squoosh] is an image compression web app that allows you to dive into the advanced options provided
|
||||||
advanced options provided by various image compressors.
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
18
_headers.ejs
Normal file
18
_headers.ejs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Long-term cache by default.
|
||||||
|
/*
|
||||||
|
Cache-Control: max-age=31536000
|
||||||
|
|
||||||
|
# And here are the exceptions:
|
||||||
|
/
|
||||||
|
Cache-Control: no-cache
|
||||||
|
|
||||||
|
/serviceworker.js
|
||||||
|
Cache-Control: no-cache
|
||||||
|
|
||||||
|
/manifest.json
|
||||||
|
Cache-Control: must-revalidate, max-age=3600
|
||||||
|
|
||||||
|
# URLs in /assets do not include a hash and are mutable.
|
||||||
|
# But it isn't a big deal if the user gets an old version.
|
||||||
|
/assets/*
|
||||||
|
Cache-Control: must-revalidate, max-age=3600
|
2
_redirects.ejs
Normal file
2
_redirects.ejs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/index.html / 301
|
||||||
|
/* /index.html 301
|
16
codecs/README.md
Normal file
16
codecs/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Codecs
|
||||||
|
|
||||||
|
This folder contains a self-contained sub-project for each encoder and decoder that squoosh supplies.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Each subproject can be built using [Docker](https://www.docker.com/) the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ 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 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.
|
BIN
codecs/example.png
Normal file
BIN
codecs/example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 MiB |
BIN
codecs/example.webp
Normal file
BIN
codecs/example.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
BIN
codecs/example_palette.png
Normal file
BIN
codecs/example_palette.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 239 KiB |
5
codecs/hqx/.gitignore
vendored
Normal file
5
codecs/hqx/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
**/*.rs.bk
|
||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/README.md
|
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
|
12
codecs/hqx/Dockerfile
Normal file
12
codecs/hqx/Dockerfile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
RUN mkdir /opt/binaryen && \
|
||||||
|
curl -L https://github.com/WebAssembly/binaryen/releases/download/1.38.32/binaryen-1.38.32-x86-linux.tar.gz | tar -xzf - -C /opt/binaryen --strip 1
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/binaryen:/opt/wabt:${PATH}"
|
||||||
|
WORKDIR /src
|
25
codecs/hqx/build.sh
Executable file
25
codecs/hqx/build.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
wasm-pack build
|
||||||
|
wasm-strip pkg/squooshhqx_bg.wasm
|
||||||
|
echo "Optimising Wasm so it doesn't break Chrome (this takes like 10-15mins. get a cup of tea)"
|
||||||
|
echo "Once https://crbug.com/974804 is fixed, we can remove this step"
|
||||||
|
wasm-opt -Os --no-validation -o pkg/squooshhqx_bg.wasm pkg/squooshhqx_bg.wasm
|
||||||
|
rm pkg/.gitignore
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-hqx .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
4
codecs/hqx/package-lock.json
generated
Normal file
4
codecs/hqx/package-lock.json
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "hqx",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
7
codecs/hqx/package.json
Normal file
7
codecs/hqx/package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "hqx",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-hqx .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.sh"
|
||||||
|
}
|
||||||
|
}
|
15
codecs/hqx/pkg/package.json
Normal file
15
codecs/hqx/pkg/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "squooshhqx",
|
||||||
|
"collaborators": [
|
||||||
|
"Surma <surma@surma.link>"
|
||||||
|
],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"files": [
|
||||||
|
"squooshhqx_bg.wasm",
|
||||||
|
"squooshhqx.js",
|
||||||
|
"squooshhqx.d.ts"
|
||||||
|
],
|
||||||
|
"module": "squooshhqx.js",
|
||||||
|
"types": "squooshhqx.d.ts",
|
||||||
|
"sideEffects": "false"
|
||||||
|
}
|
9
codecs/hqx/pkg/squooshhqx.d.ts
vendored
Normal file
9
codecs/hqx/pkg/squooshhqx.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/**
|
||||||
|
* @param {Uint32Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} factor
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array;
|
46
codecs/hqx/pkg/squooshhqx.js
Normal file
46
codecs/hqx/pkg/squooshhqx.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import * as wasm from './squooshhqx_bg.wasm';
|
||||||
|
|
||||||
|
let cachegetUint32Memory = null;
|
||||||
|
function getUint32Memory() {
|
||||||
|
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint32Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
|
function passArray32ToWasm(arg) {
|
||||||
|
const ptr = wasm.__wbindgen_malloc(arg.length * 4);
|
||||||
|
getUint32Memory().set(arg, ptr / 4);
|
||||||
|
WASM_VECTOR_LEN = arg.length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetInt32Memory = null;
|
||||||
|
function getInt32Memory() {
|
||||||
|
if (cachegetInt32Memory === null || cachegetInt32Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU32FromWasm(ptr, len) {
|
||||||
|
return getUint32Memory().subarray(ptr / 4, ptr / 4 + len);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Uint32Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} factor
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image, input_width, input_height, factor) {
|
||||||
|
const retptr = 8;
|
||||||
|
const ret = wasm.resize(retptr, passArray32ToWasm(input_image), WASM_VECTOR_LEN, input_width, input_height, factor);
|
||||||
|
const memi32 = getInt32Memory();
|
||||||
|
const v0 = getArrayU32FromWasm(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1]).slice();
|
||||||
|
wasm.__wbindgen_free(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1] * 4);
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
5
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
Normal file
5
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
|
export function resize(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
BIN
codecs/hqx/pkg/squooshhqx_bg.wasm
Normal file
BIN
codecs/hqx/pkg/squooshhqx_bg.wasm
Normal file
Binary file not shown.
55
codecs/hqx/src/lib.rs
Normal file
55
codecs/hqx/src/lib.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
extern crate cfg_if;
|
||||||
|
extern crate hqx;
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
|
// allocator.
|
||||||
|
if #[cfg(feature = "wee_alloc")] {
|
||||||
|
extern crate wee_alloc;
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn resize(
|
||||||
|
input_image: Vec<u32>,
|
||||||
|
input_width: usize,
|
||||||
|
input_height: usize,
|
||||||
|
factor: usize,
|
||||||
|
) -> Vec<u32> {
|
||||||
|
let num_output_pixels = input_width * input_height * factor * factor;
|
||||||
|
let mut output_image = Vec::<u32>::with_capacity(num_output_pixels * 4);
|
||||||
|
output_image.resize(num_output_pixels, 0);
|
||||||
|
|
||||||
|
match factor {
|
||||||
|
2 => hqx::hq2x(
|
||||||
|
input_image.as_slice(),
|
||||||
|
output_image.as_mut_slice(),
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
),
|
||||||
|
3 => hqx::hq3x(
|
||||||
|
input_image.as_slice(),
|
||||||
|
output_image.as_mut_slice(),
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
),
|
||||||
|
4 => hqx::hq4x(
|
||||||
|
input_image.as_slice(),
|
||||||
|
output_image.as_mut_slice(),
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return output_image;
|
||||||
|
}
|
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() {}
|
||||||
|
}
|
||||||
|
}
|
30
codecs/imagequant/README.md
Normal file
30
codecs/imagequant/README.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# ImageQuant
|
||||||
|
|
||||||
|
- Source: <https://github.com/ImageOptim/libimagequant>
|
||||||
|
- Version: v2.12.1
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Docker
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See `example.html`
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `int version()`
|
||||||
|
|
||||||
|
Returns the version of libimagequant as a number. va.b.c is encoded as 0x0a0b0c
|
||||||
|
|
||||||
|
### `RawImage quantize(std::string buffer, int image_width, int image_height, int numColors, float dithering)`
|
||||||
|
|
||||||
|
Quantizes the given images, using at most `numColors`, a value between 2 and 256. `dithering` is a value between 0 and 1 controlling the amount of dithering. `RawImage` is a class with 3 fields: `buffer`, `width`, and `height`.
|
||||||
|
|
||||||
|
### `RawImage zx_quantize(std::string buffer, int image_width, int image_height, float dithering)`
|
||||||
|
|
||||||
|
???
|
||||||
|
|
||||||
|
### `void free_result()`
|
||||||
|
|
||||||
|
Frees the result created by `quantize()`.
|
45
codecs/imagequant/build.sh
Executable file
45
codecs/imagequant/build.sh
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export OPTIMIZE="-Os"
|
||||||
|
export LDFLAGS="${OPTIMIZE}"
|
||||||
|
export CFLAGS="${OPTIMIZE}"
|
||||||
|
export CPPFLAGS="${OPTIMIZE}"
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling libimagequant"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
emcc \
|
||||||
|
${OPTIMIZE} \
|
||||||
|
-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} \
|
||||||
|
--closure 1 \
|
||||||
|
-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 "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
41
codecs/imagequant/example.html
Normal file
41
codecs/imagequant/example.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<style>
|
||||||
|
canvas {
|
||||||
|
image-rendering: pixelated;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src='imagequant.js'></script>
|
||||||
|
<script>
|
||||||
|
const Module = imagequant();
|
||||||
|
|
||||||
|
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 image = await loadImage('../example.png');
|
||||||
|
// 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');
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.height = image.height;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.putImageData(imageData, 0, 0);
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
};
|
||||||
|
</script>
|
245
codecs/imagequant/imagequant.cpp
Normal file
245
codecs/imagequant/imagequant.cpp
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
#include "emscripten/bind.h"
|
||||||
|
#include "emscripten/val.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RawImage {
|
||||||
|
public:
|
||||||
|
val buffer;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
RawImage(val b, int w, int h)
|
||||||
|
: buffer(b), width(w), height(h) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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_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);
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
RawImage zx_quantize(std::string rawimage, int image_width, int image_height, float dithering) {
|
||||||
|
const uint8_t* image_buffer = (uint8_t*) 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);
|
||||||
|
|
||||||
|
// For each 8x8 grid
|
||||||
|
for (int block_start_y = 0; block_start_y < image_height; block_start_y += 8) {
|
||||||
|
for (int block_start_x = 0; block_start_x < image_width; block_start_x += 8) {
|
||||||
|
int color_popularity[15] = {0};
|
||||||
|
int block_index = 0;
|
||||||
|
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 (block_start_y + block_height > image_height) {
|
||||||
|
block_height = image_height - block_start_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block_start_x + block_width > image_width) {
|
||||||
|
block_width = image_width - block_start_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 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];
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
if (distance < smallest_distance) {
|
||||||
|
winning_index = color_index;
|
||||||
|
smallest_distance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color_popularity[winning_index]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the three most popular colours for the block.
|
||||||
|
int first_color_index = 0;
|
||||||
|
int second_color_index = 0;
|
||||||
|
int third_color_index = 0;
|
||||||
|
int highest_popularity = -1;
|
||||||
|
int second_highest_popularity = -1;
|
||||||
|
int third_highest_popularity = -1;
|
||||||
|
|
||||||
|
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:
|
||||||
|
third_color_index = second_color_index;
|
||||||
|
third_highest_popularity = second_highest_popularity;
|
||||||
|
second_color_index = first_color_index;
|
||||||
|
second_highest_popularity = highest_popularity;
|
||||||
|
first_color_index = color_index;
|
||||||
|
highest_popularity = color_popularity[color_index];
|
||||||
|
} else if (color_popularity[color_index] > second_highest_popularity) {
|
||||||
|
third_color_index = second_color_index;
|
||||||
|
third_highest_popularity = second_highest_popularity;
|
||||||
|
second_color_index = color_index;
|
||||||
|
second_highest_popularity = color_popularity[color_index];
|
||||||
|
} else if (color_popularity[color_index] > third_highest_popularity) {
|
||||||
|
third_color_index = color_index;
|
||||||
|
third_highest_popularity = color_popularity[color_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
if (first_color_index >= 8 && second_color_index < 8) {
|
||||||
|
// Make the second color bright
|
||||||
|
second_color_index = second_color_index + 7;
|
||||||
|
} else if (first_color_index < 8 && second_color_index >= 8) {
|
||||||
|
// Make the second color regular
|
||||||
|
second_color_index = second_color_index - 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
15
codecs/imagequant/imagequant.d.ts
vendored
Normal file
15
codecs/imagequant/imagequant.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function(opts: EmscriptenWasm.ModuleOpts): QuantizerModule;
|
||||||
|
|
||||||
|
|
81
codecs/imagequant/imagequant.js
Normal file
81
codecs/imagequant/imagequant.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
var imagequant = (function() {
|
||||||
|
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
|
||||||
|
if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
|
||||||
|
return (
|
||||||
|
function(imagequant) {
|
||||||
|
imagequant = imagequant || {};
|
||||||
|
|
||||||
|
var e;e||(e=typeof imagequant !== 'undefined' ? imagequant : {});var m={},r;for(r in e)e.hasOwnProperty(r)&&(m[r]=e[r]);var u=!1,v=!1,aa=!1,ba=!1,ca=!1;u="object"===typeof window;v="function"===typeof importScripts;aa=(ba="object"===typeof process&&"object"===typeof process.versions&&"string"===typeof process.versions.node)&&!u&&!v;ca=!u&&!aa&&!v;var w="",da,x,ea,fa;
|
||||||
|
if(aa)w=__dirname+"/",da=function(a,b){ea||(ea=require("fs"));fa||(fa=require("path"));a=fa.normalize(a);return ea.readFileSync(a,b?null:"utf8")},x=function(a){a=da(a,!0);a.buffer||(a=new Uint8Array(a));a.buffer||y("Assertion failed: undefined");return a},1<process.argv.length&&process.argv[1].replace(/\\/g,"/"),process.argv.slice(2),process.on("uncaughtException",function(a){throw a;}),process.on("unhandledRejection",y),e.inspect=function(){return"[Emscripten Module object]"};else if(ca)"undefined"!=
|
||||||
|
typeof read&&(da=function(a){return read(a)}),x=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");"object"===typeof a||y("Assertion failed: undefined");return a},"undefined"!==typeof print&&("undefined"===typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!==typeof printErr?printErr:print);else if(u||v)v?w=self.location.href:document.currentScript&&(w=document.currentScript.src),_scriptDir&&(w=_scriptDir),0!==w.indexOf("blob:")?
|
||||||
|
w=w.substr(0,w.lastIndexOf("/")+1):w="",da=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},v&&(x=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)});var ha=e.print||console.log.bind(console),z=e.printErr||console.warn.bind(console);for(r in m)m.hasOwnProperty(r)&&(e[r]=m[r]);m=null;var ia={"f64-rem":function(a,b){return a%b},"debugger":function(){}},A;e.wasmBinary&&(A=e.wasmBinary);
|
||||||
|
"object"!==typeof WebAssembly&&z("no native wasm support detected");var B,ja=new WebAssembly.Table({initial:79,maximum:79,element:"anyfunc"}),ka=!1,la="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0;
|
||||||
|
function ma(a,b,c){var d=b+c;for(c=b;a[c]&&!(c>=d);)++c;if(16<c-b&&a.subarray&&la)return la.decode(a.subarray(b,c));for(d="";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))d+=String.fromCharCode((f&31)<<6|h);else{var g=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|g:(f&7)<<18|h<<12|g<<6|a[b++]&63;65536>f?d+=String.fromCharCode(f):(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else d+=String.fromCharCode(f)}return d}function na(a){return a?ma(C,a,void 0):""}
|
||||||
|
function oa(a,b,c){var d=C;if(0<c){c=b+c-1;for(var f=0;f<a.length;++f){var h=a.charCodeAt(f);if(55296<=h&&57343>=h){var g=a.charCodeAt(++f);h=65536+((h&1023)<<10)|g&1023}if(127>=h){if(b>=c)break;d[b++]=h}else{if(2047>=h){if(b+1>=c)break;d[b++]=192|h>>6}else{if(65535>=h){if(b+2>=c)break;d[b++]=224|h>>12}else{if(b+3>=c)break;d[b++]=240|h>>18;d[b++]=128|h>>12&63}d[b++]=128|h>>6&63}d[b++]=128|h&63}}d[b]=0}}"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");
|
||||||
|
function pa(a){0<a%65536&&(a+=65536-a%65536);return a}var buffer,qa,C,ra,sa,D,E,ta,ua;function va(a){buffer=a;e.HEAP8=qa=new Int8Array(a);e.HEAP16=ra=new Int16Array(a);e.HEAP32=D=new Int32Array(a);e.HEAPU8=C=new Uint8Array(a);e.HEAPU16=sa=new Uint16Array(a);e.HEAPU32=E=new Uint32Array(a);e.HEAPF32=ta=new Float32Array(a);e.HEAPF64=ua=new Float64Array(a)}var wa=e.TOTAL_MEMORY||16777216;e.wasmMemory?B=e.wasmMemory:B=new WebAssembly.Memory({initial:wa/65536});B&&(buffer=B.buffer);wa=buffer.byteLength;
|
||||||
|
va(buffer);D[2092]=5251440;function xa(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b();else{var c=b.Aa;"number"===typeof c?void 0===b.ra?e.dynCall_v(c):e.dynCall_vi(c,b.ra):c(void 0===b.ra?null:b.ra)}}}var ya=[],za=[],Aa=[],Ba=[];function Ca(){var a=e.preRun.shift();ya.unshift(a)}var G=0,Da=null,H=null;e.preloadedImages={};e.preloadedAudios={};
|
||||||
|
function y(a){if(e.onAbort)e.onAbort(a);ha(a);z(a);ka=!0;throw new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");}function Ea(){var a=I;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var I="imagequant.wasm";if(!Ea()){var Fa=I;I=e.locateFile?e.locateFile(Fa,w):w+Fa}
|
||||||
|
function Ga(){try{if(A)return new Uint8Array(A);if(x)return x(I);throw"both async and sync fetching of the wasm failed";}catch(a){y(a)}}function Ha(){return A||!u&&!v||"function"!==typeof fetch?new Promise(function(a){a(Ga())}):fetch(I,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+I+"'";return a.arrayBuffer()}).catch(function(){return Ga()})}
|
||||||
|
e.asm=function(){function a(a){e.asm=a.exports;G--;e.monitorRunDependencies&&e.monitorRunDependencies(G);0==G&&(null!==Da&&(clearInterval(Da),Da=null),H&&(a=H,H=null,a()))}function b(b){a(b.instance)}function c(a){return Ha().then(function(a){return WebAssembly.instantiate(a,d)}).then(a,function(a){z("failed to asynchronously prepare wasm: "+a);y(a)})}var d={env:Ia,wasi_unstable:Ia,global:{NaN:NaN,Infinity:Infinity},"global.Math":Math,asm2wasm:ia};G++;e.monitorRunDependencies&&e.monitorRunDependencies(G);
|
||||||
|
if(e.instantiateWasm)try{return e.instantiateWasm(d,a)}catch(f){return z("Module.instantiateWasm callback failed with error: "+f),!1}(function(){if(A||"function"!==typeof WebAssembly.instantiateStreaming||Ea()||"function"!==typeof fetch)return c(b);fetch(I,{credentials:"same-origin"}).then(function(a){return WebAssembly.instantiateStreaming(a,d).then(b,function(a){z("wasm streaming compile failed: "+a);z("falling back to ArrayBuffer instantiation");c(b)})})})();return{}};za.push({Aa:function(){Ja()}});
|
||||||
|
var Ka=[null,[],[]];function La(){return 0}function Ma(){return 0}function Na(a,b,c,d){try{for(var f=0,h=0;h<c;h++){for(var g=D[b+8*h>>2],k=D[b+(8*h+4)>>2],p=0;p<k;p++){var q=C[g+p],l=Ka[a];0===q||10===q?((1===a?ha:z)(ma(l,0)),l.length=0):l.push(q)}f+=k}D[d>>2]=f;return 0}catch(t){return"undefined"!==typeof FS&&t instanceof FS.Ia||y(t),t.Ja}}function Oa(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var Pa=void 0;
|
||||||
|
function J(a){for(var b="";C[a];)b+=Pa[C[a++]];return b}var K={},L={},Qa={};function Ra(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}function Sa(a,b){a=Ra(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}
|
||||||
|
function Ta(a){var b=Error,c=Sa(a,function(b){this.name=a;this.message=b;b=Error(b).stack;void 0!==b&&(this.stack=this.toString()+"\n"+b.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}var M=void 0;function N(a){throw new M(a);}var Ua=void 0;function Va(a){throw new Ua(a);}
|
||||||
|
function Wa(a,b,c){function d(b){b=c(b);b.length!==a.length&&Va("Mismatched type converter count");for(var d=0;d<a.length;++d)Q(a[d],b[d])}a.forEach(function(a){Qa[a]=b});var f=Array(b.length),h=[],g=0;b.forEach(function(a,b){L.hasOwnProperty(a)?f[b]=L[a]:(h.push(a),K.hasOwnProperty(a)||(K[a]=[]),K[a].push(function(){f[b]=L[a];++g;g===h.length&&d(f)}))});0===h.length&&d(f)}
|
||||||
|
function Q(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||N('type "'+d+'" must have a positive integer typeid pointer');if(L.hasOwnProperty(a)){if(c.Da)return;N("Cannot register type '"+d+"' twice")}L[a]=b;delete Qa[a];K.hasOwnProperty(a)&&(b=K[a],delete K[a],b.forEach(function(a){a()}))}function Xa(a){return{count:a.count,la:a.la,na:a.na,aa:a.aa,da:a.da,ea:a.ea,fa:a.fa}}
|
||||||
|
function Ya(a){N(a.$.da.ba.name+" instance already deleted")}var Za=!1;function $a(){}function ab(a){--a.count.value;0===a.count.value&&(a.ea?a.fa.ka(a.ea):a.da.ba.ka(a.aa))}
|
||||||
|
function R(a){if("undefined"===typeof FinalizationGroup)return R=function(a){return a},a;Za=new FinalizationGroup(function(a){for(var b=a.next();!b.done;b=a.next())b=b.value,b.aa?ab(b):console.warn("object already deleted: "+b.aa)});R=function(a){Za.register(a,a.$,a.$);return a};$a=function(a){Za.unregister(a.$)};return R(a)}var bb=void 0,cb=[];function db(){for(;cb.length;){var a=cb.pop();a.$.la=!1;a["delete"]()}}function T(){}var eb={};
|
||||||
|
function fb(a,b){var c=e;if(void 0===c[a].ha){var d=c[a];c[a]=function(){c[a].ha.hasOwnProperty(arguments.length)||N("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].ha+")!");return c[a].ha[arguments.length].apply(this,arguments)};c[a].ha=[];c[a].ha[d.xa]=d}}
|
||||||
|
function gb(a,b,c){e.hasOwnProperty(a)?((void 0===c||void 0!==e[a].ha&&void 0!==e[a].ha[c])&&N("Cannot register public name '"+a+"' twice"),fb(a,a),e.hasOwnProperty(c)&&N("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),e[a].ha[c]=b):(e[a]=b,void 0!==c&&(e[a].La=c))}function hb(a,b,c,d,f,h,g,k){this.name=a;this.constructor=b;this.ja=c;this.ka=d;this.ga=f;this.Ba=h;this.oa=g;this.za=k}
|
||||||
|
function ib(a,b,c){for(;b!==c;)b.oa||N("Expected null or instance of "+c.name+", got an instance of "+b.name),a=b.oa(a),b=b.ga;return a}function jb(a,b){if(null===b)return this.sa&&N("null is not a valid "+this.name),0;b.$||N('Cannot pass "'+U(b)+'" as a '+this.name);b.$.aa||N("Cannot pass deleted object as a pointer of type "+this.name);return ib(b.$.aa,b.$.da.ba,this.ba)}
|
||||||
|
function kb(a,b){if(null===b){this.sa&&N("null is not a valid "+this.name);if(this.qa){var c=this.Fa();null!==a&&a.push(this.ka,c);return c}return 0}b.$||N('Cannot pass "'+U(b)+'" as a '+this.name);b.$.aa||N("Cannot pass deleted object as a pointer of type "+this.name);!this.pa&&b.$.da.pa&&N("Cannot convert argument of type "+(b.$.fa?b.$.fa.name:b.$.da.name)+" to parameter type "+this.name);c=ib(b.$.aa,b.$.da.ba,this.ba);if(this.qa)switch(void 0===b.$.ea&&N("Passing raw pointer to smart pointer is illegal"),
|
||||||
|
this.Ha){case 0:b.$.fa===this?c=b.$.ea:N("Cannot convert argument of type "+(b.$.fa?b.$.fa.name:b.$.da.name)+" to parameter type "+this.name);break;case 1:c=b.$.ea;break;case 2:if(b.$.fa===this)c=b.$.ea;else{var d=b.clone();c=this.Ga(c,lb(function(){d["delete"]()}));null!==a&&a.push(this.ka,c)}break;default:N("Unsupporting sharing policy")}return c}
|
||||||
|
function ob(a,b){if(null===b)return this.sa&&N("null is not a valid "+this.name),0;b.$||N('Cannot pass "'+U(b)+'" as a '+this.name);b.$.aa||N("Cannot pass deleted object as a pointer of type "+this.name);b.$.da.pa&&N("Cannot convert argument of type "+b.$.da.name+" to parameter type "+this.name);return ib(b.$.aa,b.$.da.ba,this.ba)}function pb(a){return this.fromWireType(E[a>>2])}function qb(a,b,c){if(b===c)return a;if(void 0===c.ga)return null;a=qb(a,b,c.ga);return null===a?null:c.za(a)}var rb={};
|
||||||
|
function sb(a,b){for(void 0===b&&N("ptr should not be undefined");a.ga;)b=a.oa(b),a=a.ga;return rb[b]}function tb(a,b){b.da&&b.aa||Va("makeClassHandle requires ptr and ptrType");!!b.fa!==!!b.ea&&Va("Both smartPtrType and smartPtr must be specified");b.count={value:1};return R(Object.create(a,{$:{value:b}}))}
|
||||||
|
function V(a,b,c,d){this.name=a;this.ba=b;this.sa=c;this.pa=d;this.qa=!1;this.ka=this.Ga=this.Fa=this.wa=this.Ha=this.Ea=void 0;void 0!==b.ga?this.toWireType=kb:(this.toWireType=d?jb:ob,this.ia=null)}function ub(a,b,c){e.hasOwnProperty(a)||Va("Replacing nonexistant public symbol");void 0!==e[a].ha&&void 0!==c?e[a].ha[c]=b:(e[a]=b,e[a].xa=c)}
|
||||||
|
function W(a,b){a=J(a);if(void 0!==e["FUNCTION_TABLE_"+a])var c=e["FUNCTION_TABLE_"+a][b];else if("undefined"!==typeof FUNCTION_TABLE)c=FUNCTION_TABLE[b];else{c=e["dynCall_"+a];void 0===c&&(c=e["dynCall_"+a.replace(/f/g,"d")],void 0===c&&N("No dynCall invoker for signature: "+a));for(var d=[],f=1;f<a.length;++f)d.push("a"+f);f="return function "+("dynCall_"+a+"_"+b)+"("+d.join(", ")+") {\n";f+=" return dynCall(rawFunction"+(d.length?", ":"")+d.join(", ")+");\n";c=(new Function("dynCall","rawFunction",
|
||||||
|
f+"};\n"))(c,b)}"function"!==typeof c&&N("unknown function pointer with signature "+a+": "+b);return c}var vb=void 0;function wb(a){a=xb(a);var b=J(a);X(a);return b}function yb(a,b){function c(a){f[a]||L[a]||(Qa[a]?Qa[a].forEach(c):(d.push(a),f[a]=!0))}var d=[],f={};b.forEach(c);throw new vb(a+": "+d.map(wb).join([", "]));}function zb(a){for(;a.length;){var b=a.pop();a.pop()(b)}}
|
||||||
|
function Ab(a,b,c){a instanceof Object||N(c+' with invalid "this": '+a);a instanceof b.ba.constructor||N(c+' incompatible with "this" of type '+a.constructor.name);a.$.aa||N("cannot call emscripten binding method "+c+" on deleted object");return ib(a.$.aa,a.$.da.ba,b.ba)}var Bb=[],Y=[{},{value:void 0},{value:null},{value:!0},{value:!1}];function Cb(a){4<a&&0===--Y[a].ta&&(Y[a]=void 0,Bb.push(a))}
|
||||||
|
function lb(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Bb.length?Bb.pop():Y.length;Y[b]={ta:1,value:a};return b}}function U(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}function Db(a,b){switch(b){case 2:return function(a){return this.fromWireType(ta[a>>2])};case 3:return function(a){return this.fromWireType(ua[a>>3])};default:throw new TypeError("Unknown float type: "+a);}}
|
||||||
|
function Eb(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=Sa(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}function Fb(a,b){for(var c=[],d=0;d<a;d++)c.push(D[(b>>2)+d]);return c}
|
||||||
|
function Gb(a,b,c){switch(b){case 0:return c?function(a){return qa[a]}:function(a){return C[a]};case 1:return c?function(a){return ra[a>>1]}:function(a){return sa[a>>1]};case 2:return c?function(a){return D[a>>2]}:function(a){return E[a>>2]};default:throw new TypeError("Unknown integer type: "+a);}}function Hb(){return qa.length}function Z(){Z.ma||(Z.ma=[]);Z.ma.push(Ib());return Z.ma.length-1}for(var Jb=Array(256),Kb=0;256>Kb;++Kb)Jb[Kb]=String.fromCharCode(Kb);Pa=Jb;M=e.BindingError=Ta("BindingError");
|
||||||
|
Ua=e.InternalError=Ta("InternalError");T.prototype.isAliasOf=function(a){if(!(this instanceof T&&a instanceof T))return!1;var b=this.$.da.ba,c=this.$.aa,d=a.$.da.ba;for(a=a.$.aa;b.ga;)c=b.oa(c),b=b.ga;for(;d.ga;)a=d.oa(a),d=d.ga;return b===d&&c===a};T.prototype.clone=function(){this.$.aa||Ya(this);if(this.$.na)return this.$.count.value+=1,this;var a=R(Object.create(Object.getPrototypeOf(this),{$:{value:Xa(this.$)}}));a.$.count.value+=1;a.$.la=!1;return a};
|
||||||
|
T.prototype["delete"]=function(){this.$.aa||Ya(this);this.$.la&&!this.$.na&&N("Object already scheduled for deletion");$a(this);ab(this.$);this.$.na||(this.$.ea=void 0,this.$.aa=void 0)};T.prototype.isDeleted=function(){return!this.$.aa};T.prototype.deleteLater=function(){this.$.aa||Ya(this);this.$.la&&!this.$.na&&N("Object already scheduled for deletion");cb.push(this);1===cb.length&&bb&&bb(db);this.$.la=!0;return this};V.prototype.Ca=function(a){this.wa&&(a=this.wa(a));return a};
|
||||||
|
V.prototype.va=function(a){this.ka&&this.ka(a)};V.prototype.argPackAdvance=8;V.prototype.readValueFromPointer=pb;V.prototype.deleteObject=function(a){if(null!==a)a["delete"]()};
|
||||||
|
V.prototype.fromWireType=function(a){function b(){return this.qa?tb(this.ba.ja,{da:this.Ea,aa:c,fa:this,ea:a}):tb(this.ba.ja,{da:this,aa:a})}var c=this.Ca(a);if(!c)return this.va(a),null;var d=sb(this.ba,c);if(void 0!==d){if(0===d.$.count.value)return d.$.aa=c,d.$.ea=a,d.clone();d=d.clone();this.va(a);return d}d=this.ba.Ba(c);d=eb[d];if(!d)return b.call(this);d=this.pa?d.ya:d.pointerType;var f=qb(c,this.ba,d.ba);return null===f?b.call(this):this.qa?tb(d.ba.ja,{da:d,aa:f,fa:this,ea:a}):tb(d.ba.ja,
|
||||||
|
{da:d,aa:f})};e.getInheritedInstanceCount=function(){return Object.keys(rb).length};e.getLiveInheritedInstances=function(){var a=[],b;for(b in rb)rb.hasOwnProperty(b)&&a.push(rb[b]);return a};e.flushPendingDeletes=db;e.setDelayFunction=function(a){bb=a;cb.length&&bb&&bb(db)};vb=e.UnboundTypeError=Ta("UnboundTypeError");e.count_emval_handles=function(){for(var a=0,b=5;b<Y.length;++b)void 0!==Y[b]&&++a;return a};e.get_first_emval=function(){for(var a=5;a<Y.length;++a)if(void 0!==Y[a])return Y[a];return null};
|
||||||
|
var Ia={c:function(a,b,c,d){y("Assertion failed: "+na(a)+", at: "+[b?na(b):"unknown filename",c,d?na(d):"unknown function"])},v:function(){return La.apply(null,arguments)},r:function(){return Ma.apply(null,arguments)},q:function(){return Na.apply(null,arguments)},p:function(a,b,c,d,f){var h=Oa(c);b=J(b);Q(a,{name:b,fromWireType:function(a){return!!a},toWireType:function(a,b){return b?d:f},argPackAdvance:8,readValueFromPointer:function(a){if(1===c)var d=qa;else if(2===c)d=ra;else if(4===c)d=D;else throw new TypeError("Unknown boolean type size: "+
|
||||||
|
b);return this.fromWireType(d[a>>h])},ia:null})},o:function(a,b,c,d,f,h,g,k,p,q,l,t,O){l=J(l);h=W(f,h);k&&(k=W(g,k));q&&(q=W(p,q));O=W(t,O);var F=Ra(l);gb(F,function(){yb("Cannot construct "+l+" due to unbound types",[d])});Wa([a,b,c],d?[d]:[],function(b){b=b[0];if(d){var c=b.ba;var f=c.ja}else f=T.prototype;b=Sa(F,function(){if(Object.getPrototypeOf(this)!==p)throw new M("Use 'new' to construct "+l);if(void 0===g.ua)throw new M(l+" has no accessible constructor");var a=g.ua[arguments.length];if(void 0===
|
||||||
|
a)throw new M("Tried to invoke ctor of "+l+" with invalid number of parameters ("+arguments.length+") - expected ("+Object.keys(g.ua).toString()+") parameters instead!");return a.apply(this,arguments)});var p=Object.create(f,{constructor:{value:b}});b.prototype=p;var g=new hb(l,b,p,O,c,h,k,q);c=new V(l,g,!0,!1);f=new V(l+"*",g,!1,!1);var t=new V(l+" const*",g,!1,!0);eb[a]={pointerType:f,ya:t};ub(F,b);return[c,f,t]})},h:function(a,b,c,d,f,h,g,k,p,q){b=J(b);f=W(d,f);Wa([],[a],function(a){a=a[0];var d=
|
||||||
|
a.name+"."+b,l={get:function(){yb("Cannot access "+d+" due to unbound types",[c,g])},enumerable:!0,configurable:!0};p?l.set=function(){yb("Cannot access "+d+" due to unbound types",[c,g])}:l.set=function(){N(d+" is a read-only property")};Object.defineProperty(a.ba.ja,b,l);Wa([],p?[c,g]:[c],function(c){var g=c[0],l={get:function(){var b=Ab(this,a,d+" getter");return g.fromWireType(f(h,b))},enumerable:!0};if(p){p=W(k,p);var t=c[1];l.set=function(b){var c=Ab(this,a,d+" setter"),f=[];p(q,c,t.toWireType(f,
|
||||||
|
b));zb(f)}}Object.defineProperty(a.ba.ja,b,l);return[]});return[]})},n:function(a,b){b=J(b);Q(a,{name:b,fromWireType:function(a){var b=Y[a].value;Cb(a);return b},toWireType:function(a,b){return lb(b)},argPackAdvance:8,readValueFromPointer:pb,ia:null})},j:function(a,b,c){c=Oa(c);b=J(b);Q(a,{name:b,fromWireType:function(a){return a},toWireType:function(a,b){if("number"!==typeof b&&"boolean"!==typeof b)throw new TypeError('Cannot convert "'+U(b)+'" to '+this.name);return b},argPackAdvance:8,readValueFromPointer:Db(b,
|
||||||
|
c),ia:null})},e:function(a,b,c,d,f,h){var g=Fb(b,c);a=J(a);f=W(d,f);gb(a,function(){yb("Cannot call "+a+" due to unbound types",g)},b-1);Wa([],g,function(c){var d=[c[0],null].concat(c.slice(1)),g=c=a,l=f,k=d.length;2>k&&N("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var O=null!==d[1]&&!1,F=!1,n=1;n<d.length;++n)if(null!==d[n]&&void 0===d[n].ia){F=!0;break}var mb="void"!==d[0].name,P="",S="";for(n=0;n<k-2;++n)P+=(0!==n?", ":"")+"arg"+n,S+=(0!==n?", ":"")+"arg"+
|
||||||
|
n+"Wired";g="return function "+Ra(g)+"("+P+") {\nif (arguments.length !== "+(k-2)+") {\nthrowBindingError('function "+g+" called with ' + arguments.length + ' arguments, expected "+(k-2)+" args!');\n}\n";F&&(g+="var destructors = [];\n");var nb=F?"destructors":"null";P="throwBindingError invoker fn runDestructors retType classParam".split(" ");l=[N,l,h,zb,d[0],d[1]];O&&(g+="var thisWired = classParam.toWireType("+nb+", this);\n");for(n=0;n<k-2;++n)g+="var arg"+n+"Wired = argType"+n+".toWireType("+
|
||||||
|
nb+", arg"+n+"); // "+d[n+2].name+"\n",P.push("argType"+n),l.push(d[n+2]);O&&(S="thisWired"+(0<S.length?", ":"")+S);g+=(mb?"var rv = ":"")+"invoker(fn"+(0<S.length?", ":"")+S+");\n";if(F)g+="runDestructors(destructors);\n";else for(n=O?1:2;n<d.length;++n)k=1===n?"thisWired":"arg"+(n-2)+"Wired",null!==d[n].ia&&(g+=k+"_dtor("+k+"); // "+d[n].name+"\n",P.push(k+"_dtor"),l.push(d[n].ia));mb&&(g+="var ret = retType.fromWireType(rv);\nreturn ret;\n");P.push(g+"}\n");d=Eb(P).apply(null,l);ub(c,d,b-1);return[]})},
|
||||||
|
d:function(a,b,c,d,f){function h(a){return a}b=J(b);-1===f&&(f=4294967295);var g=Oa(c);if(0===d){var k=32-8*c;h=function(a){return a<<k>>>k}}var p=-1!=b.indexOf("unsigned");Q(a,{name:b,fromWireType:h,toWireType:function(a,c){if("number"!==typeof c&&"boolean"!==typeof c)throw new TypeError('Cannot convert "'+U(c)+'" to '+this.name);if(c<d||c>f)throw new TypeError('Passing a number "'+U(c)+'" from JS side to C/C++ side to an argument of type "'+b+'", which is outside the valid range ['+d+", "+f+"]!");
|
||||||
|
return p?c>>>0:c|0},argPackAdvance:8,readValueFromPointer:Gb(b,g,0!==d),ia:null})},b:function(a,b,c){function d(a){a>>=2;var b=E;return new f(b.buffer,b[a+1],b[a])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=J(c);Q(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{Da:!0})},m:function(a,b){b=J(b);var c="std::string"===b;Q(a,{name:b,fromWireType:function(a){var b=E[a>>2];if(c){var d=C[a+4+b],g=0;0!=d&&(g=d,C[a+4+b]=0);var k=
|
||||||
|
a+4;for(d=0;d<=b;++d){var p=a+4+d;if(0==C[p]){k=na(k);if(void 0===q)var q=k;else q+=String.fromCharCode(0),q+=k;k=p+1}}0!=g&&(C[a+4+b]=g)}else{q=Array(b);for(d=0;d<b;++d)q[d]=String.fromCharCode(C[a+4+d]);q=q.join("")}X(a);return q},toWireType:function(a,b){b instanceof ArrayBuffer&&(b=new Uint8Array(b));var d="string"===typeof b;d||b instanceof Uint8Array||b instanceof Uint8ClampedArray||b instanceof Int8Array||N("Cannot pass non-string to std::string");var f=(c&&d?function(){for(var a=0,c=0;c<b.length;++c){var d=
|
||||||
|
b.charCodeAt(c);55296<=d&&57343>=d&&(d=65536+((d&1023)<<10)|b.charCodeAt(++c)&1023);127>=d?++a:a=2047>=d?a+2:65535>=d?a+3:a+4}return a}:function(){return b.length})(),k=Lb(4+f+1);E[k>>2]=f;if(c&&d)oa(b,k+4,f+1);else if(d)for(d=0;d<f;++d){var p=b.charCodeAt(d);255<p&&(X(k),N("String has UTF-16 code units that do not fit in 8 bits"));C[k+4+d]=p}else for(d=0;d<f;++d)C[k+4+d]=b[d];null!==a&&a.push(X,k);return k},argPackAdvance:8,readValueFromPointer:pb,ia:function(a){X(a)}})},z:function(a,b,c){c=J(c);
|
||||||
|
if(2===b){var d=function(){return sa};var f=1}else 4===b&&(d=function(){return E},f=2);Q(a,{name:c,fromWireType:function(a){for(var b=d(),c=E[a>>2],h=Array(c),q=a+4>>f,l=0;l<c;++l)h[l]=String.fromCharCode(b[q+l]);X(a);return h.join("")},toWireType:function(a,c){var h=c.length,g=Lb(4+h*b),q=d();E[g>>2]=h;for(var l=g+4>>f,t=0;t<h;++t)q[l+t]=c.charCodeAt(t);null!==a&&a.push(X,g);return g},argPackAdvance:8,readValueFromPointer:pb,ia:function(a){X(a)}})},y:function(a,b){b=J(b);Q(a,{Ka:!0,name:b,argPackAdvance:0,
|
||||||
|
fromWireType:function(){},toWireType:function(){}})},l:Cb,x:function(a){4<a&&(Y[a].ta+=1)},k:function(a,b){var c=L[a];void 0===c&&N("_emval_take_value has unknown type "+wb(a));a=c.readValueFromPointer(b);return lb(a)},__memory_base:1024,__table_base:0,i:function(){y()},w:Hb,u:function(a,b,c){C.set(C.subarray(b,b+c),a)},t:function(a){if(2147418112<a)return!1;for(var b=Math.max(Hb(),16777216);b<a;)536870912>=b?b=pa(2*b):b=Math.min(pa((3*b+2147483648)/4),2147418112);a:{try{B.grow(b-buffer.byteLength+
|
||||||
|
65535>>16);va(B.buffer);var c=1;break a}catch(d){}c=void 0}return c?!0:!1},g:function(a){var b=Z.ma[a];Z.ma.splice(a,1);Mb(b)},f:Z,a:y,memory:B,s:function(){},table:ja},Nb=e.asm({},Ia,buffer);e.asm=Nb;e.___embind_register_native_and_builtin_types=function(){return e.asm.A.apply(null,arguments)};
|
||||||
|
var xb=e.___getTypeName=function(){return e.asm.B.apply(null,arguments)},X=e._free=function(){return e.asm.C.apply(null,arguments)},Lb=e._malloc=function(){return e.asm.D.apply(null,arguments)},Ja=e.globalCtors=function(){return e.asm.X.apply(null,arguments)},Mb=e.stackRestore=function(){return e.asm.Y.apply(null,arguments)},Ib=e.stackSave=function(){return e.asm.Z.apply(null,arguments)};e.dynCall_i=function(){return e.asm.E.apply(null,arguments)};
|
||||||
|
e.dynCall_ifi=function(){return e.asm.F.apply(null,arguments)};e.dynCall_ii=function(){return e.asm.G.apply(null,arguments)};e.dynCall_iidiiii=function(){return e.asm.H.apply(null,arguments)};e.dynCall_iii=function(){return e.asm.I.apply(null,arguments)};e.dynCall_iiii=function(){return e.asm.J.apply(null,arguments)};e.dynCall_iiiiif=function(){return e.asm.K.apply(null,arguments)};e.dynCall_iiiiiif=function(){return e.asm.L.apply(null,arguments)};
|
||||||
|
e.dynCall_jiji=function(){return e.asm.M.apply(null,arguments)};e.dynCall_v=function(){return e.asm.N.apply(null,arguments)};e.dynCall_vi=function(){return e.asm.O.apply(null,arguments)};e.dynCall_vif=function(){return e.asm.P.apply(null,arguments)};e.dynCall_vii=function(){return e.asm.Q.apply(null,arguments)};e.dynCall_viii=function(){return e.asm.R.apply(null,arguments)};e.dynCall_viiii=function(){return e.asm.S.apply(null,arguments)};e.dynCall_viiiif=function(){return e.asm.T.apply(null,arguments)};
|
||||||
|
e.dynCall_viiiii=function(){return e.asm.U.apply(null,arguments)};e.dynCall_viiiiif=function(){return e.asm.V.apply(null,arguments)};e.dynCall_viiiiii=function(){return e.asm.W.apply(null,arguments)};e.asm=Nb;var Ob;e.then=function(a){if(Ob)a(e);else{var b=e.onRuntimeInitialized;e.onRuntimeInitialized=function(){b&&b();a(e)}}return e};H=function Pb(){Ob||Qb();Ob||(H=Pb)};
|
||||||
|
function Qb(){function a(){if(!Ob&&(Ob=!0,!ka)){xa(za);xa(Aa);if(e.onRuntimeInitialized)e.onRuntimeInitialized();if(e.postRun)for("function"==typeof e.postRun&&(e.postRun=[e.postRun]);e.postRun.length;){var a=e.postRun.shift();Ba.unshift(a)}xa(Ba)}}if(!(0<G)){if(e.preRun)for("function"==typeof e.preRun&&(e.preRun=[e.preRun]);e.preRun.length;)Ca();xa(ya);0<G||(e.setStatus?(e.setStatus("Running..."),setTimeout(function(){setTimeout(function(){e.setStatus("")},1);a()},1)):a())}}e.run=Qb;
|
||||||
|
if(e.preInit)for("function"==typeof e.preInit&&(e.preInit=[e.preInit]);0<e.preInit.length;)e.preInit.pop()();Qb();
|
||||||
|
|
||||||
|
|
||||||
|
return imagequant
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
if (typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = imagequant;
|
||||||
|
else if (typeof define === 'function' && define['amd'])
|
||||||
|
define([], function() { return imagequant; });
|
||||||
|
else if (typeof exports === 'object')
|
||||||
|
exports["imagequant"] = imagequant;
|
||||||
|
|
BIN
codecs/imagequant/imagequant.wasm
Normal file
BIN
codecs/imagequant/imagequant.wasm
Normal file
Binary file not shown.
1147
codecs/imagequant/package-lock.json
generated
Normal file
1147
codecs/imagequant/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
codecs/imagequant/package.json
Normal file
13
codecs/imagequant/package.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
47
codecs/mozjpeg_enc/README.md
Normal file
47
codecs/mozjpeg_enc/README.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# MozJPEG encoder
|
||||||
|
|
||||||
|
- Source: <https://github.com/mozilla/mozjpeg>
|
||||||
|
- Version: v3.3.1
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Docker
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See `example.html`
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `int version()`
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
struct MozJpegOptions {
|
||||||
|
int quality;
|
||||||
|
bool baseline;
|
||||||
|
bool arithmetic;
|
||||||
|
bool progressive;
|
||||||
|
bool optimize_coding;
|
||||||
|
int smoothing;
|
||||||
|
int color_space;
|
||||||
|
int quant_table;
|
||||||
|
bool trellis_multipass;
|
||||||
|
bool trellis_opt_zero;
|
||||||
|
bool trellis_opt_table;
|
||||||
|
int trellis_loops;
|
||||||
|
bool auto_subsample;
|
||||||
|
int chroma_subsample;
|
||||||
|
bool separate_chroma_quality;
|
||||||
|
int chroma_quality;
|
||||||
|
};
|
||||||
|
```
|
54
codecs/mozjpeg_enc/build.sh
Executable file
54
codecs/mozjpeg_enc/build.sh
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
#!/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} \
|
||||||
|
--closure 1 \
|
||||||
|
-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 "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
48
codecs/mozjpeg_enc/example.html
Normal file
48
codecs/mozjpeg_enc/example.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!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 image = await loadImage('../example.png');
|
||||||
|
const result = module.encode(image.data, image.width, image.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 blob = new Blob([result], {type: 'image/jpeg'});
|
||||||
|
const blobURL = URL.createObjectURL(blob);
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = blobURL;
|
||||||
|
document.body.appendChild(img);
|
||||||
|
};
|
||||||
|
</script>
|
234
codecs/mozjpeg_enc/mozjpeg_enc.cpp
Normal file
234
codecs/mozjpeg_enc/mozjpeg_enc.cpp
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "jpeglib.h"
|
||||||
|
#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
|
||||||
|
#define xstr(s) str(s)
|
||||||
|
#define str(s) #s
|
||||||
|
|
||||||
|
struct MozJpegOptions {
|
||||||
|
int quality;
|
||||||
|
bool baseline;
|
||||||
|
bool arithmetic;
|
||||||
|
bool progressive;
|
||||||
|
bool optimize_coding;
|
||||||
|
int smoothing;
|
||||||
|
int color_space;
|
||||||
|
int quant_table;
|
||||||
|
bool trellis_multipass;
|
||||||
|
bool trellis_opt_zero;
|
||||||
|
bool trellis_opt_table;
|
||||||
|
int trellis_loops;
|
||||||
|
bool auto_subsample;
|
||||||
|
int chroma_subsample;
|
||||||
|
bool separate_chroma_quality;
|
||||||
|
int chroma_quality;
|
||||||
|
};
|
||||||
|
|
||||||
|
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] == '.') {
|
||||||
|
buffer[i] = '\0';
|
||||||
|
version = version << 8 | atoi(&buffer[last_index]);
|
||||||
|
buffer[i] = '.';
|
||||||
|
last_index = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version = version << 8 | atoi(&buffer[last_index]);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* last_result;
|
||||||
|
struct jpeg_compress_struct cinfo;
|
||||||
|
|
||||||
|
val encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts) {
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
/* This struct contains the JPEG compression parameters and pointers to
|
||||||
|
* working space (which is allocated as needed by the JPEG library).
|
||||||
|
* It is possible to have several such structures, representing multiple
|
||||||
|
* compression/decompression processes, in existence at once. We refer
|
||||||
|
* to any one struct (and its associated working data) as a "JPEG object".
|
||||||
|
*/
|
||||||
|
/* 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
|
||||||
|
* take the easy way out and use the standard error handler, which will
|
||||||
|
* print a message on stderr and call exit() if compression fails.
|
||||||
|
* 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 */
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* address which we place into the link field in cinfo.
|
||||||
|
*/
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
/* Now we can initialize the JPEG compression object. */
|
||||||
|
jpeg_create_compress(&cinfo);
|
||||||
|
|
||||||
|
/* Step 2: specify data destination (eg, a file) */
|
||||||
|
/* Note: steps 2 and 3 can be done in either order. */
|
||||||
|
|
||||||
|
/* Here we use the library-supplied code to send compressed data to a
|
||||||
|
* stdio stream. You can also write your own code to do something else.
|
||||||
|
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
||||||
|
* requires it in order to write binary files.
|
||||||
|
*/
|
||||||
|
// if ((outfile = fopen(filename, "wb")) == NULL) {
|
||||||
|
// fprintf(stderr, "can't open %s\n", filename);
|
||||||
|
// exit(1);
|
||||||
|
// }
|
||||||
|
jpeg_mem_dest(&cinfo, &output, &size);
|
||||||
|
|
||||||
|
/* Step 3: set parameters for compression */
|
||||||
|
|
||||||
|
/* 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_height = image_height;
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (opts.quant_table != -1) {
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfo.optimize_coding = opts.optimize_coding;
|
||||||
|
|
||||||
|
if (opts.arithmetic) {
|
||||||
|
cinfo.arith_code = TRUE;
|
||||||
|
cinfo.optimize_coding = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfo.smoothing_factor = opts.smoothing;
|
||||||
|
|
||||||
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_SCANS_IN_TRELLIS, opts.trellis_multipass);
|
||||||
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
||||||
|
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.
|
||||||
|
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();
|
||||||
|
|
||||||
|
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;
|
||||||
|
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opts.baseline && opts.progressive) {
|
||||||
|
jpeg_simple_progression(&cinfo);
|
||||||
|
} else {
|
||||||
|
cinfo.num_scans = 0;
|
||||||
|
cinfo.scan_info = NULL;
|
||||||
|
}
|
||||||
|
/* Step 4: Start compressor */
|
||||||
|
|
||||||
|
/* TRUE ensures that we will write a complete interchange-JPEG file.
|
||||||
|
* Pass TRUE unless you are very sure of what you're doing.
|
||||||
|
*/
|
||||||
|
jpeg_start_compress(&cinfo, TRUE);
|
||||||
|
|
||||||
|
/* Step 5: while (scan lines remain to be written) */
|
||||||
|
/* jpeg_write_scanlines(...); */
|
||||||
|
|
||||||
|
/* Here we use the library's state variable cinfo.next_scanline as the
|
||||||
|
* loop counter, so that we don't have to keep track ourselves.
|
||||||
|
* 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 */
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 6: Finish compression */
|
||||||
|
|
||||||
|
jpeg_finish_compress(&cinfo);
|
||||||
|
/* Step 7: release JPEG compression object */
|
||||||
|
|
||||||
|
last_result = 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
;
|
||||||
|
|
||||||
|
function("version", &version);
|
||||||
|
function("encode", &encode);
|
||||||
|
function("free_result", &free_result);
|
||||||
|
}
|
8
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
Normal file
8
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
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;
|
70
codecs/mozjpeg_enc/mozjpeg_enc.js
Normal file
70
codecs/mozjpeg_enc/mozjpeg_enc.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
var mozjpeg_enc = (function() {
|
||||||
|
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
|
||||||
|
if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
|
||||||
|
return (
|
||||||
|
function(mozjpeg_enc) {
|
||||||
|
mozjpeg_enc = mozjpeg_enc || {};
|
||||||
|
|
||||||
|
var d;d||(d=typeof mozjpeg_enc !== 'undefined' ? mozjpeg_enc : {});var p={},q;for(q in d)d.hasOwnProperty(q)&&(p[q]=d[q]);var aa="./this.program";function t(a,b){throw b;}var u=!1,v=!1,ba=!1,ca=!1,da=!1;u="object"===typeof window;v="function"===typeof importScripts;ba=(ca="object"===typeof process&&"object"===typeof process.versions&&"string"===typeof process.versions.node)&&!u&&!v;da=!u&&!ba&&!v;var w="",x,z,ha,ia;
|
||||||
|
if(ba)w=__dirname+"/",x=function(a,b){ha||(ha=require("fs"));ia||(ia=require("path"));a=ia.normalize(a);return ha.readFileSync(a,b?null:"utf8")},z=function(a){a=x(a,!0);a.buffer||(a=new Uint8Array(a));a.buffer||A("Assertion failed: undefined");return a},1<process.argv.length&&(aa=process.argv[1].replace(/\\/g,"/")),process.argv.slice(2),process.on("uncaughtException",function(a){if(!(a instanceof ja))throw a;}),process.on("unhandledRejection",A),t=function(a){process.exit(a)},d.inspect=function(){return"[Emscripten Module object]"};
|
||||||
|
else if(da)"undefined"!=typeof read&&(x=function(a){return read(a)}),z=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");"object"===typeof a||A("Assertion failed: undefined");return a},"function"===typeof quit&&(t=function(a){quit(a)}),"undefined"!==typeof print&&("undefined"===typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!==typeof printErr?printErr:print);else if(u||v)v?w=self.location.href:document.currentScript&&
|
||||||
|
(w=document.currentScript.src),_scriptDir&&(w=_scriptDir),0!==w.indexOf("blob:")?w=w.substr(0,w.lastIndexOf("/")+1):w="",x=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},v&&(z=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)});var ka=d.print||console.log.bind(console),B=d.printErr||console.warn.bind(console);for(q in p)p.hasOwnProperty(q)&&(d[q]=p[q]);p=null;
|
||||||
|
d.thisProgram&&(aa=d.thisProgram);d.quit&&(t=d.quit);function la(a){var b=C[ma>>2];a=b+a+15&-16;a>na()&&A();C[ma>>2]=a;return b}var oa={"f64-rem":function(a,b){return a%b},"debugger":function(){}},D;d.wasmBinary&&(D=d.wasmBinary);var pa;d.noExitRuntime&&(pa=d.noExitRuntime);"object"!==typeof WebAssembly&&B("no native wasm support detected");var E,qa=new WebAssembly.Table({initial:208,maximum:208,element:"anyfunc"}),ra=!1,sa="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0;
|
||||||
|
function ta(a,b,c){var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.subarray&&sa)return sa.decode(a.subarray(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var g=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|g);else{var h=a[b++]&63;f=224==(f&240)?(f&15)<<12|g<<6|h:(f&7)<<18|g<<12|h<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e}
|
||||||
|
function ua(a,b,c,e){if(0<e){e=c+e-1;for(var f=0;f<a.length;++f){var g=a.charCodeAt(f);if(55296<=g&&57343>=g){var h=a.charCodeAt(++f);g=65536+((g&1023)<<10)|h&1023}if(127>=g){if(c>=e)break;b[c++]=g}else{if(2047>=g){if(c+1>=e)break;b[c++]=192|g>>6}else{if(65535>=g){if(c+2>=e)break;b[c++]=224|g>>12}else{if(c+3>=e)break;b[c++]=240|g>>18;b[c++]=128|g>>12&63}b[c++]=128|g>>6&63}b[c++]=128|g&63}}b[c]=0}}
|
||||||
|
function va(a){for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);55296<=e&&57343>=e&&(e=65536+((e&1023)<<10)|a.charCodeAt(++c)&1023);127>=e?++b:b=2047>=e?b+2:65535>=e?b+3:b+4}return b}"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");function wa(a){0<a%65536&&(a+=65536-a%65536);return a}var buffer,F,G,xa,ya,C,H,za,Aa;
|
||||||
|
function Ca(a){buffer=a;d.HEAP8=F=new Int8Array(a);d.HEAP16=xa=new Int16Array(a);d.HEAP32=C=new Int32Array(a);d.HEAPU8=G=new Uint8Array(a);d.HEAPU16=ya=new Uint16Array(a);d.HEAPU32=H=new Uint32Array(a);d.HEAPF32=za=new Float32Array(a);d.HEAPF64=Aa=new Float64Array(a)}var ma=89296,Da=d.TOTAL_MEMORY||16777216;d.wasmMemory?E=d.wasmMemory:E=new WebAssembly.Memory({initial:Da/65536});E&&(buffer=E.buffer);Da=buffer.byteLength;Ca(buffer);C[ma>>2]=5332368;
|
||||||
|
function I(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b();else{var c=b.ha;"number"===typeof c?void 0===b.ba?d.dynCall_v(c):d.dynCall_vi(c,b.ba):c(void 0===b.ba?null:b.ba)}}}var Ea=[],Fa=[],Ga=[],Ha=[],Ia=!1;function Ja(){var a=d.preRun.shift();Ea.unshift(a)}var J=0,Ka=null,K=null;d.preloadedImages={};d.preloadedAudios={};function A(a){if(d.onAbort)d.onAbort(a);ka(a);B(a);ra=!0;throw new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");}
|
||||||
|
function La(){var a=M;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var M="mozjpeg_enc.wasm";if(!La()){var Ma=M;M=d.locateFile?d.locateFile(Ma,w):w+Ma}function Na(){try{if(D)return new Uint8Array(D);if(z)return z(M);throw"both async and sync fetching of the wasm failed";}catch(a){A(a)}}
|
||||||
|
function Oa(){return D||!u&&!v||"function"!==typeof fetch?new Promise(function(a){a(Na())}):fetch(M,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+M+"'";return a.arrayBuffer()}).catch(function(){return Na()})}
|
||||||
|
d.asm=function(){function a(a){d.asm=a.exports;J--;d.monitorRunDependencies&&d.monitorRunDependencies(J);0==J&&(null!==Ka&&(clearInterval(Ka),Ka=null),K&&(a=K,K=null,a()))}function b(b){a(b.instance)}function c(a){return Oa().then(function(a){return WebAssembly.instantiate(a,e)}).then(a,function(a){B("failed to asynchronously prepare wasm: "+a);A(a)})}var e={env:Pa,wasi_unstable:Pa,global:{NaN:NaN,Infinity:Infinity},"global.Math":Math,asm2wasm:oa};J++;d.monitorRunDependencies&&d.monitorRunDependencies(J);
|
||||||
|
if(d.instantiateWasm)try{return d.instantiateWasm(e,a)}catch(f){return B("Module.instantiateWasm callback failed with error: "+f),!1}(function(){if(D||"function"!==typeof WebAssembly.instantiateStreaming||La()||"function"!==typeof fetch)return c(b);fetch(M,{credentials:"same-origin"}).then(function(a){return WebAssembly.instantiateStreaming(a,e).then(b,function(a){B("wasm streaming compile failed: "+a);B("falling back to ArrayBuffer instantiation");c(b)})})})();return{}};Fa.push({ha:function(){Qa()}});
|
||||||
|
var O={};
|
||||||
|
function Ra(a){if(Ra.aa){var b=C[a>>2];var c=C[b>>2]}else Ra.aa=!0,O.USER="web_user",O.LOGNAME="web_user",O.PATH="/",O.PWD="/",O.HOME="/home/web_user",O.LANG=("object"===typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",O._=aa,c=Ia?P(1024):la(1024),b=Ia?P(256):la(256),C[b>>2]=c,C[a>>2]=b;a=[];var e=0,f;for(f in O)if("string"===typeof O[f]){var g=f+"="+O[f];a.push(g);e+=g.length}if(1024<e)throw Error("Environment size exceeded TOTAL_ENV_SIZE!");for(f=0;f<
|
||||||
|
a.length;f++){e=g=a[f];for(var h=c,k=0;k<e.length;++k)F[h++>>0]=e.charCodeAt(k);F[h>>0]=0;C[b+4*f>>2]=c;c+=g.length+1}C[b+4*a.length>>2]=0}var Sa=[null,[],[]];function Ta(){return 0}function Ua(){return 0}function Va(a,b,c,e){try{for(var f=0,g=0;g<c;g++){for(var h=C[b+8*g>>2],k=C[b+(8*g+4)>>2],r=0;r<k;r++){var m=G[h+r],y=Sa[a];0===m||10===m?((1===a?ka:B)(ta(y,0)),y.length=0):y.push(m)}f+=k}C[e>>2]=f;return 0}catch(n){return"undefined"!==typeof FS&&n instanceof FS.ra||A(n),n.sa}}var Wa={};
|
||||||
|
function Xa(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function Ya(a){return this.fromWireType(H[a>>2])}var Q={},R={},Za={};function $a(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}function ab(a,b){a=$a(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}
|
||||||
|
function bb(a){var b=Error,c=ab(a,function(b){this.name=a;this.message=b;b=Error(b).stack;void 0!==b&&(this.stack=this.toString()+"\n"+b.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}var cb=void 0;
|
||||||
|
function db(a,b,c){function e(b){b=c(b);if(b.length!==a.length)throw new cb("Mismatched type converter count");for(var e=0;e<a.length;++e)S(a[e],b[e])}a.forEach(function(a){Za[a]=b});var f=Array(b.length),g=[],h=0;b.forEach(function(a,b){R.hasOwnProperty(a)?f[b]=R[a]:(g.push(a),Q.hasOwnProperty(a)||(Q[a]=[]),Q[a].push(function(){f[b]=R[a];++h;h===g.length&&e(f)}))});0===g.length&&e(f)}
|
||||||
|
function eb(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var gb=void 0;function T(a){for(var b="";G[a];)b+=gb[G[a++]];return b}var hb=void 0;function U(a){throw new hb(a);}
|
||||||
|
function S(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var e=b.name;a||U('type "'+e+'" must have a positive integer typeid pointer');if(R.hasOwnProperty(a)){if(c.la)return;U("Cannot register type '"+e+"' twice")}R[a]=b;delete Za[a];Q.hasOwnProperty(a)&&(b=Q[a],delete Q[a],b.forEach(function(a){a()}))}var ib=[],V=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
||||||
|
function jb(a){4<a&&0===--V[a].da&&(V[a]=void 0,ib.push(a))}function kb(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=ib.length?ib.pop():V.length;V[b]={da:1,value:a};return b}}function lb(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}
|
||||||
|
function mb(a,b){switch(b){case 2:return function(a){return this.fromWireType(za[a>>2])};case 3:return function(a){return this.fromWireType(Aa[a>>3])};default:throw new TypeError("Unknown float type: "+a);}}function nb(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=ab(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}
|
||||||
|
function ob(a,b){var c=d;if(void 0===c[a].Z){var e=c[a];c[a]=function(){c[a].Z.hasOwnProperty(arguments.length)||U("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].Z+")!");return c[a].Z[arguments.length].apply(this,arguments)};c[a].Z=[];c[a].Z[e.fa]=e}}
|
||||||
|
function pb(a,b,c){d.hasOwnProperty(a)?((void 0===c||void 0!==d[a].Z&&void 0!==d[a].Z[c])&&U("Cannot register public name '"+a+"' twice"),ob(a,a),d.hasOwnProperty(c)&&U("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),d[a].Z[c]=b):(d[a]=b,void 0!==c&&(d[a].ua=c))}function qb(a,b){for(var c=[],e=0;e<a;e++)c.push(C[(b>>2)+e]);return c}
|
||||||
|
function W(a,b){a=T(a);if(void 0!==d["FUNCTION_TABLE_"+a])var c=d["FUNCTION_TABLE_"+a][b];else if("undefined"!==typeof FUNCTION_TABLE)c=FUNCTION_TABLE[b];else{c=d["dynCall_"+a];void 0===c&&(c=d["dynCall_"+a.replace(/f/g,"d")],void 0===c&&U("No dynCall invoker for signature: "+a));for(var e=[],f=1;f<a.length;++f)e.push("a"+f);f="return function "+("dynCall_"+a+"_"+b)+"("+e.join(", ")+") {\n";f+=" return dynCall(rawFunction"+(e.length?", ":"")+e.join(", ")+");\n";c=(new Function("dynCall","rawFunction",
|
||||||
|
f+"};\n"))(c,b)}"function"!==typeof c&&U("unknown function pointer with signature "+a+": "+b);return c}var rb=void 0;function sb(a){a=tb(a);var b=T(a);X(a);return b}function ub(a,b){function c(a){f[a]||R[a]||(Za[a]?Za[a].forEach(c):(e.push(a),f[a]=!0))}var e=[],f={};b.forEach(c);throw new rb(a+": "+e.map(sb).join([", "]));}
|
||||||
|
function vb(a,b,c){switch(b){case 0:return c?function(a){return F[a]}:function(a){return G[a]};case 1:return c?function(a){return xa[a>>1]}:function(a){return ya[a>>1]};case 2:return c?function(a){return C[a>>2]}:function(a){return H[a>>2]};default:throw new TypeError("Unknown integer type: "+a);}}function na(){return F.length}function Y(a){if(0===a)return 0;a=a?ta(G,a,void 0):"";if(!O.hasOwnProperty(a))return 0;Y.aa&&X(Y.aa);a=O[a];var b=va(a)+1,c=P(b);c&&ua(a,F,c,b);Y.aa=c;return Y.aa}
|
||||||
|
cb=d.InternalError=bb("InternalError");for(var wb=Array(256),xb=0;256>xb;++xb)wb[xb]=String.fromCharCode(xb);gb=wb;hb=d.BindingError=bb("BindingError");d.count_emval_handles=function(){for(var a=0,b=5;b<V.length;++b)void 0!==V[b]&&++a;return a};d.get_first_emval=function(){for(var a=5;a<V.length;++a)if(void 0!==V[a])return V[a];return null};rb=d.UnboundTypeError=bb("UnboundTypeError");
|
||||||
|
var Pa={B:Ra,u:function(){return Ta.apply(null,arguments)},n:function(){return Ua.apply(null,arguments)},m:function(){return Va.apply(null,arguments)},l:function(a){var b=Wa[a];delete Wa[a];var c=b.ma,e=b.na,f=b.ea,g=f.map(function(a){return a.ka}).concat(f.map(function(a){return a.pa}));db([a],g,function(a){var g={};f.forEach(function(b,c){var e=a[c],k=b.ia,r=b.ja,h=a[c+f.length],m=b.oa,fa=b.qa;g[b.ga]={read:function(a){return e.fromWireType(k(r,a))},write:function(a,b){var c=[];m(fa,a,h.toWireType(c,
|
||||||
|
b));Xa(c)}}});return[{name:b.name,fromWireType:function(a){var b={},c;for(c in g)b[c]=g[c].read(a);e(a);return b},toWireType:function(a,b){for(var f in g)if(!(f in b))throw new TypeError("Missing field");var k=c();for(f in g)g[f].write(k,b[f]);null!==a&&a.push(e,k);return k},argPackAdvance:8,readValueFromPointer:Ya,$:e}]})},k:function(a,b,c,e,f){var g=eb(c);b=T(b);S(a,{name:b,fromWireType:function(a){return!!a},toWireType:function(a,b){return b?e:f},argPackAdvance:8,readValueFromPointer:function(a){if(1===
|
||||||
|
c)var e=F;else if(2===c)e=xa;else if(4===c)e=C;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(e[a>>g])},$:null})},j:function(a,b){b=T(b);S(a,{name:b,fromWireType:function(a){var b=V[a].value;jb(a);return b},toWireType:function(a,b){return kb(b)},argPackAdvance:8,readValueFromPointer:Ya,$:null})},g:function(a,b,c){c=eb(c);b=T(b);S(a,{name:b,fromWireType:function(a){return a},toWireType:function(a,b){if("number"!==typeof b&&"boolean"!==typeof b)throw new TypeError('Cannot convert "'+
|
||||||
|
lb(b)+'" to '+this.name);return b},argPackAdvance:8,readValueFromPointer:mb(b,c),$:null})},f:function(a,b,c,e,f,g){var h=qb(b,c);a=T(a);f=W(e,f);pb(a,function(){ub("Cannot call "+a+" due to unbound types",h)},b-1);db([],h,function(c){var e=[c[0],null].concat(c.slice(1)),h=c=a,k=f,n=e.length;2>n&&U("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var Ba=null!==e[1]&&!1,ea=!1,l=1;l<e.length;++l)if(null!==e[l]&&void 0===e[l].$){ea=!0;break}var fa="void"!==e[0].name,
|
||||||
|
L="",N="";for(l=0;l<n-2;++l)L+=(0!==l?", ":"")+"arg"+l,N+=(0!==l?", ":"")+"arg"+l+"Wired";h="return function "+$a(h)+"("+L+") {\nif (arguments.length !== "+(n-2)+") {\nthrowBindingError('function "+h+" called with ' + arguments.length + ' arguments, expected "+(n-2)+" args!');\n}\n";ea&&(h+="var destructors = [];\n");var fb=ea?"destructors":"null";L="throwBindingError invoker fn runDestructors retType classParam".split(" ");k=[U,k,g,Xa,e[0],e[1]];Ba&&(h+="var thisWired = classParam.toWireType("+fb+
|
||||||
|
", this);\n");for(l=0;l<n-2;++l)h+="var arg"+l+"Wired = argType"+l+".toWireType("+fb+", arg"+l+"); // "+e[l+2].name+"\n",L.push("argType"+l),k.push(e[l+2]);Ba&&(N="thisWired"+(0<N.length?", ":"")+N);h+=(fa?"var rv = ":"")+"invoker(fn"+(0<N.length?", ":"")+N+");\n";if(ea)h+="runDestructors(destructors);\n";else for(l=Ba?1:2;l<e.length;++l)n=1===l?"thisWired":"arg"+(l-2)+"Wired",null!==e[l].$&&(h+=n+"_dtor("+n+"); // "+e[l].name+"\n",L.push(n+"_dtor"),k.push(e[l].$));fa&&(h+="var ret = retType.fromWireType(rv);\nreturn ret;\n");
|
||||||
|
L.push(h+"}\n");e=nb(L).apply(null,k);l=b-1;if(!d.hasOwnProperty(c))throw new cb("Replacing nonexistant public symbol");void 0!==d[c].Z&&void 0!==l?d[c].Z[l]=e:(d[c]=e,d[c].fa=l);return[]})},c:function(a,b,c,e,f){function g(a){return a}b=T(b);-1===f&&(f=4294967295);var h=eb(c);if(0===e){var k=32-8*c;g=function(a){return a<<k>>>k}}var r=-1!=b.indexOf("unsigned");S(a,{name:b,fromWireType:g,toWireType:function(a,c){if("number"!==typeof c&&"boolean"!==typeof c)throw new TypeError('Cannot convert "'+lb(c)+
|
||||||
|
'" to '+this.name);if(c<e||c>f)throw new TypeError('Passing a number "'+lb(c)+'" from JS side to C/C++ side to an argument of type "'+b+'", which is outside the valid range ['+e+", "+f+"]!");return r?c>>>0:c|0},argPackAdvance:8,readValueFromPointer:vb(b,h,0!==e),$:null})},b:function(a,b,c){function e(a){a>>=2;var b=H;return new f(b.buffer,b[a+1],b[a])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=T(c);S(a,{name:c,fromWireType:e,argPackAdvance:8,
|
||||||
|
readValueFromPointer:e},{la:!0})},i:function(a,b){b=T(b);var c="std::string"===b;S(a,{name:b,fromWireType:function(a){var b=H[a>>2];if(c){var e=G[a+4+b],h=0;0!=e&&(h=e,G[a+4+b]=0);var k=a+4;for(e=0;e<=b;++e){var r=a+4+e;if(0==G[r]){k=k?ta(G,k,void 0):"";if(void 0===m)var m=k;else m+=String.fromCharCode(0),m+=k;k=r+1}}0!=h&&(G[a+4+b]=h)}else{m=Array(b);for(e=0;e<b;++e)m[e]=String.fromCharCode(G[a+4+e]);m=m.join("")}X(a);return m},toWireType:function(a,b){b instanceof ArrayBuffer&&(b=new Uint8Array(b));
|
||||||
|
var e="string"===typeof b;e||b instanceof Uint8Array||b instanceof Uint8ClampedArray||b instanceof Int8Array||U("Cannot pass non-string to std::string");var f=(c&&e?function(){return va(b)}:function(){return b.length})(),k=P(4+f+1);H[k>>2]=f;if(c&&e)ua(b,G,k+4,f+1);else if(e)for(e=0;e<f;++e){var r=b.charCodeAt(e);255<r&&(X(k),U("String has UTF-16 code units that do not fit in 8 bits"));G[k+4+e]=r}else for(e=0;e<f;++e)G[k+4+e]=b[e];null!==a&&a.push(X,k);return k},argPackAdvance:8,readValueFromPointer:Ya,
|
||||||
|
$:function(a){X(a)}})},A:function(a,b,c){c=T(c);if(2===b){var e=function(){return ya};var f=1}else 4===b&&(e=function(){return H},f=2);S(a,{name:c,fromWireType:function(a){for(var b=e(),c=H[a>>2],g=Array(c),m=a+4>>f,y=0;y<c;++y)g[y]=String.fromCharCode(b[m+y]);X(a);return g.join("")},toWireType:function(a,c){var g=c.length,h=P(4+g*b),m=e();H[h>>2]=g;for(var y=h+4>>f,n=0;n<g;++n)m[y+n]=c.charCodeAt(n);null!==a&&a.push(X,h);return h},argPackAdvance:8,readValueFromPointer:Ya,$:function(a){X(a)}})},z:function(a,
|
||||||
|
b,c,e,f,g){Wa[a]={name:T(b),ma:W(c,e),na:W(f,g),ea:[]}},h:function(a,b,c,e,f,g,h,k,r,m){Wa[a].ea.push({ga:T(b),ka:c,ia:W(e,f),ja:g,pa:h,oa:W(k,r),qa:m})},y:function(a,b){b=T(b);S(a,{ta:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},x:jb,w:function(a){4<a&&(V[a].da+=1)},v:function(a,b){var c=R[a];void 0===c&&U("_emval_take_value has unknown type "+sb(a));a=c.readValueFromPointer(b);return kb(a)},__memory_base:1024,__table_base:0,e:function(){A()},t:na,s:function(a,
|
||||||
|
b,c){G.set(G.subarray(b,b+c),a)},r:function(a){if(2147418112<a)return!1;for(var b=Math.max(na(),16777216);b<a;)536870912>=b?b=wa(2*b):b=Math.min(wa((3*b+2147483648)/4),2147418112);a:{try{E.grow(b-buffer.byteLength+65535>>16);Ca(E.buffer);var c=1;break a}catch(e){}c=void 0}return c?!0:!1},q:function(a){if(!pa&&(ra=!0,d.onExit))d.onExit(a);t(a,new ja(a))},p:Y,d:function(a){return Math.pow(2,a)},a:A,memory:E,o:function(){},table:qa},yb=d.asm({},Pa,buffer);d.asm=yb;
|
||||||
|
d.___embind_register_native_and_builtin_types=function(){return d.asm.C.apply(null,arguments)};var tb=d.___getTypeName=function(){return d.asm.D.apply(null,arguments)},X=d._free=function(){return d.asm.E.apply(null,arguments)},P=d._malloc=function(){return d.asm.F.apply(null,arguments)},Qa=d.globalCtors=function(){return d.asm.Y.apply(null,arguments)};d.dynCall_i=function(){return d.asm.G.apply(null,arguments)};d.dynCall_ii=function(){return d.asm.H.apply(null,arguments)};
|
||||||
|
d.dynCall_iidiiii=function(){return d.asm.I.apply(null,arguments)};d.dynCall_iii=function(){return d.asm.J.apply(null,arguments)};d.dynCall_iiii=function(){return d.asm.K.apply(null,arguments)};d.dynCall_iiiii=function(){return d.asm.L.apply(null,arguments)};d.dynCall_iiiiii=function(){return d.asm.M.apply(null,arguments)};d.dynCall_iiiiiii=function(){return d.asm.N.apply(null,arguments)};d.dynCall_jiji=function(){return d.asm.O.apply(null,arguments)};
|
||||||
|
d.dynCall_v=function(){return d.asm.P.apply(null,arguments)};d.dynCall_vi=function(){return d.asm.Q.apply(null,arguments)};d.dynCall_vii=function(){return d.asm.R.apply(null,arguments)};d.dynCall_viii=function(){return d.asm.S.apply(null,arguments)};d.dynCall_viiii=function(){return d.asm.T.apply(null,arguments)};d.dynCall_viiiii=function(){return d.asm.U.apply(null,arguments)};d.dynCall_viiiiii=function(){return d.asm.V.apply(null,arguments)};
|
||||||
|
d.dynCall_viiiiiii=function(){return d.asm.W.apply(null,arguments)};d.dynCall_viiiiiiii=function(){return d.asm.X.apply(null,arguments)};d.asm=yb;var Z;d.then=function(a){if(Z)a(d);else{var b=d.onRuntimeInitialized;d.onRuntimeInitialized=function(){b&&b();a(d)}}return d};function ja(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}K=function zb(){Z||Ab();Z||(K=zb)};
|
||||||
|
function Ab(){function a(){if(!Z&&(Z=!0,!ra)){Ia=!0;I(Fa);I(Ga);if(d.onRuntimeInitialized)d.onRuntimeInitialized();if(d.postRun)for("function"==typeof d.postRun&&(d.postRun=[d.postRun]);d.postRun.length;){var a=d.postRun.shift();Ha.unshift(a)}I(Ha)}}if(!(0<J)){if(d.preRun)for("function"==typeof d.preRun&&(d.preRun=[d.preRun]);d.preRun.length;)Ja();I(Ea);0<J||(d.setStatus?(d.setStatus("Running..."),setTimeout(function(){setTimeout(function(){d.setStatus("")},1);a()},1)):a())}}d.run=Ab;
|
||||||
|
if(d.preInit)for("function"==typeof d.preInit&&(d.preInit=[d.preInit]);0<d.preInit.length;)d.preInit.pop()();pa=!0;Ab();
|
||||||
|
|
||||||
|
|
||||||
|
return mozjpeg_enc
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
if (typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = mozjpeg_enc;
|
||||||
|
else if (typeof define === 'function' && define['amd'])
|
||||||
|
define([], function() { return mozjpeg_enc; });
|
||||||
|
else if (typeof exports === 'object')
|
||||||
|
exports["mozjpeg_enc"] = mozjpeg_enc;
|
||||||
|
|
BIN
codecs/mozjpeg_enc/mozjpeg_enc.wasm
Normal file
BIN
codecs/mozjpeg_enc/mozjpeg_enc.wasm
Normal file
Binary file not shown.
1147
codecs/mozjpeg_enc/package-lock.json
generated
Normal file
1147
codecs/mozjpeg_enc/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
codecs/mozjpeg_enc/package.json
Normal file
13
codecs/mozjpeg_enc/package.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
1
codecs/oxipng/.gitignore
vendored
Normal file
1
codecs/oxipng/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
501
codecs/oxipng/Cargo.lock
generated
Normal file
501
codecs/oxipng/Cargo.lock
generated
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "adler32"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-vec"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "build_const"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudflare-zlib"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cloudflare-zlib-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudflare-zlib-sys"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deflate"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "image"
|
||||||
|
version = "0.23.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-iter 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-rational 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"png 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inflate"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.68"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libdeflater"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "maybe-uninit"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-iter"
|
||||||
|
version = "0.1.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxipng"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"oxipng 2.3.0 (git+https://github.com/shssoichiro/oxipng.git)",
|
||||||
|
"wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxipng"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "git+https://github.com/shssoichiro/oxipng.git#f74726915131ec7ff1df0514436aac34bc603cff"
|
||||||
|
dependencies = [
|
||||||
|
"bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cloudflare-zlib 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"image 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libdeflater 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rgb 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "png"
|
||||||
|
version = "0.16.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"deflate 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rgb"
|
||||||
|
version = "0.8.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typed-arena"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zopfli"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typed-arena 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
||||||
|
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||||
|
"checksum bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4523a10839ffae575fb08aa3423026c8cb4687eef43952afb956229d4f246f7"
|
||||||
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||||
|
"checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
|
||||||
|
"checksum bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
|
||||||
|
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||||
|
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||||
|
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
"checksum cloudflare-zlib 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed63a019d55bacd15cadcbcb96bf41b16281417fff393bdb55fa84255fe4b9"
|
||||||
|
"checksum cloudflare-zlib-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e195cb274a0d6ee87e718838a09baecd7cbc9f6075dac256a84cb5842739c06"
|
||||||
|
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||||
|
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||||
|
"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||||
|
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||||
|
"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
|
||||||
|
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||||
|
"checksum deflate 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "050ef6de42a33903b30a7497b76b40d3d58691d4d3eec355348c122444a388f0"
|
||||||
|
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||||
|
"checksum hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
|
||||||
|
"checksum image 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9062b90712d25bc6bb165d110aa59c6b47c849246e341e7b86a98daff9d49f60"
|
||||||
|
"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
|
||||||
|
"checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||||
|
"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||||
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
"checksum libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
|
||||||
|
"checksum libdeflater 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246"
|
||||||
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
|
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||||
|
"checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
|
||||||
|
"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
|
||||||
|
"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
|
||||||
|
"checksum num-iter 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
|
||||||
|
"checksum num-rational 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||||
|
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
|
||||||
|
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
|
||||||
|
"checksum oxipng 2.3.0 (git+https://github.com/shssoichiro/oxipng.git)" = "<none>"
|
||||||
|
"checksum png 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46060468187c21c00ffa2a920690b29997d7fd543f5a4d400461e4a7d4fccde8"
|
||||||
|
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||||
|
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||||
|
"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
|
||||||
|
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
||||||
|
"checksum rgb 0.8.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5ec4ab2cf0b27e111e266e161cf7f9efd20125a161190da1c0945c4a4408fef3"
|
||||||
|
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||||
|
"checksum typed-arena 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
||||||
|
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
"checksum wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
|
||||||
|
"checksum wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
|
||||||
|
"checksum wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
|
||||||
|
"checksum wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
|
||||||
|
"checksum wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
|
||||||
|
"checksum zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4079b79464426ade2a1b0177fb0ce8396ba6b4084267407e333573c666073964"
|
20
codecs/oxipng/Cargo.toml
Normal file
20
codecs/oxipng/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "oxipng"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Ingvar Stepanyan <me@rreverser.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
oxipng = { version = "2.3.0", default-features = false }
|
||||||
|
wasm-bindgen = "0.2.48"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
oxipng = { git = "https://github.com/shssoichiro/oxipng.git", branch = "master" }
|
12
codecs/oxipng/Dockerfile
Normal file
12
codecs/oxipng/Dockerfile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
RUN mkdir /opt/wasi-sdk && \
|
||||||
|
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-8/wasi-sdk-8.0-linux.tar.gz | tar -xzf - -C /opt/wasi-sdk --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/wabt:/opt/wasi-sdk/bin:${PATH}"
|
||||||
|
WORKDIR /src
|
22
codecs/oxipng/build.sh
Normal file
22
codecs/oxipng/build.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
wasm-pack build
|
||||||
|
wasm-strip pkg/oxipng_bg.wasm
|
||||||
|
rm pkg/.gitignore
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-oxipng .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
4
codecs/oxipng/package-lock.json
generated
Normal file
4
codecs/oxipng/package-lock.json
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "oxipng",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
7
codecs/oxipng/package.json
Normal file
7
codecs/oxipng/package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "oxipng",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-oxipng .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-oxipng ./build.sh"
|
||||||
|
}
|
||||||
|
}
|
8
codecs/oxipng/pkg/oxipng.d.ts
vendored
Normal file
8
codecs/oxipng/pkg/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;
|
60
codecs/oxipng/pkg/oxipng.js
Normal file
60
codecs/oxipng/pkg/oxipng.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import * as wasm from './oxipng_bg.wasm';
|
||||||
|
|
||||||
|
const lTextDecoder = typeof TextDecoder === 'undefined' ? 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));
|
||||||
|
};
|
||||||
|
|
8
codecs/oxipng/pkg/oxipng_bg.d.ts
vendored
Normal file
8
codecs/oxipng/pkg/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;
|
BIN
codecs/oxipng/pkg/oxipng_bg.wasm
Normal file
BIN
codecs/oxipng/pkg/oxipng_bg.wasm
Normal file
Binary file not shown.
15
codecs/oxipng/pkg/package.json
Normal file
15
codecs/oxipng/pkg/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "oxipng",
|
||||||
|
"collaborators": [
|
||||||
|
"Ingvar Stepanyan <me@rreverser.com>"
|
||||||
|
],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"files": [
|
||||||
|
"oxipng_bg.wasm",
|
||||||
|
"oxipng.js",
|
||||||
|
"oxipng.d.ts"
|
||||||
|
],
|
||||||
|
"module": "oxipng.js",
|
||||||
|
"types": "oxipng.d.ts",
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
10
codecs/oxipng/src/lib.rs
Normal file
10
codecs/oxipng/src/lib.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
mod malloc_shim;
|
||||||
|
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen(catch)]
|
||||||
|
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||||
|
let mut options = oxipng::Options::from_preset(level);
|
||||||
|
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||||
|
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||||
|
}
|
27
codecs/oxipng/src/malloc_shim.rs
Normal file
27
codecs/oxipng/src/malloc_shim.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//! 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.
|
||||||
|
//!
|
||||||
|
//! 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(ptr: *mut u8) {
|
||||||
|
let size_and_data_ptr = ptr.sub(size_of::<usize>());
|
||||||
|
let size = *(size_and_data_ptr as *const usize);
|
||||||
|
dealloc(ptr, layout_for(size))
|
||||||
|
}
|
6
codecs/resize/.gitignore
vendored
Normal file
6
codecs/resize/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
**/*.rs.bk
|
||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
|
bin/
|
||||||
|
pkg/README.md
|
||||||
|
lut.inc
|
37
codecs/resize/Cargo.toml
Normal file
37
codecs/resize/Cargo.toml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
[package]
|
||||||
|
name = "resize"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Surma <surma@surma.link>"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
#crate-type = ["cdylib", "rlib"]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["console_error_panic_hook", "wee_alloc"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cfg-if = "0.1.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
|
9
codecs/resize/Dockerfile
Normal file
9
codecs/resize/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/wabt:${PATH}"
|
||||||
|
WORKDIR /src
|
23
codecs/resize/build.rs
Normal file
23
codecs/resize/build.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
include!("./src/srgb.rs");
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let mut srgb_to_linear_lut = String::from("static SRGB_TO_LINEAR_LUT: [f32; 256] = [");
|
||||||
|
let mut linear_to_srgb_lut = String::from("static LINEAR_TO_SRGB_LUT: [f32; 256] = [");
|
||||||
|
for i in 0..256 {
|
||||||
|
srgb_to_linear_lut.push_str(&format!("{0:.7}", srgb_to_linear((i as f32) / 255.0)));
|
||||||
|
srgb_to_linear_lut.push_str(",");
|
||||||
|
linear_to_srgb_lut.push_str(&format!("{0:.7}", linear_to_srgb((i as f32) / 255.0)));
|
||||||
|
linear_to_srgb_lut.push_str(",");
|
||||||
|
}
|
||||||
|
srgb_to_linear_lut.pop().unwrap();
|
||||||
|
linear_to_srgb_lut.pop().unwrap();
|
||||||
|
srgb_to_linear_lut.push_str("];");
|
||||||
|
linear_to_srgb_lut.push_str("];");
|
||||||
|
|
||||||
|
let mut file = std::fs::File::create("src/lut.inc")?;
|
||||||
|
file.write_all(srgb_to_linear_lut.as_bytes())?;
|
||||||
|
file.write_all(linear_to_srgb_lut.as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
22
codecs/resize/build.sh
Executable file
22
codecs/resize/build.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
wasm-pack build
|
||||||
|
wasm-strip pkg/resize_bg.wasm
|
||||||
|
rm pkg/.gitignore
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-resize .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
4
codecs/resize/package-lock.json
generated
Normal file
4
codecs/resize/package-lock.json
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
7
codecs/resize/package.json
Normal file
7
codecs/resize/package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-resize .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-resize ./build.sh"
|
||||||
|
}
|
||||||
|
}
|
15
codecs/resize/pkg/package.json
Normal file
15
codecs/resize/pkg/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"collaborators": [
|
||||||
|
"Surma <surma@surma.link>"
|
||||||
|
],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"files": [
|
||||||
|
"resize_bg.wasm",
|
||||||
|
"resize.js",
|
||||||
|
"resize.d.ts"
|
||||||
|
],
|
||||||
|
"module": "resize.js",
|
||||||
|
"types": "resize.d.ts",
|
||||||
|
"sideEffects": "false"
|
||||||
|
}
|
13
codecs/resize/pkg/resize.d.ts
vendored
Normal file
13
codecs/resize/pkg/resize.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* tslint: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;
|
50
codecs/resize/pkg/resize.js
Normal file
50
codecs/resize/pkg/resize.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import * as wasm from './resize_bg.wasm';
|
||||||
|
|
||||||
|
let cachegetUint8Memory = null;
|
||||||
|
function getUint8Memory() {
|
||||||
|
if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint8Memory = new Uint8Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
|
function passArray8ToWasm(arg) {
|
||||||
|
const ptr = wasm.__wbindgen_malloc(arg.length * 1);
|
||||||
|
getUint8Memory().set(arg, ptr / 1);
|
||||||
|
WASM_VECTOR_LEN = arg.length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetInt32Memory = null;
|
||||||
|
function getInt32Memory() {
|
||||||
|
if (cachegetInt32Memory === null || cachegetInt32Memory.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU8FromWasm(ptr, len) {
|
||||||
|
return getUint8Memory().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) {
|
||||||
|
const retptr = 8;
|
||||||
|
const ret = wasm.resize(retptr, passArray8ToWasm(input_image), WASM_VECTOR_LEN, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
|
||||||
|
const memi32 = getInt32Memory();
|
||||||
|
const v0 = getArrayU8FromWasm(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1]).slice();
|
||||||
|
wasm.__wbindgen_free(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1] * 1);
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
5
codecs/resize/pkg/resize_bg.d.ts
vendored
Normal file
5
codecs/resize/pkg/resize_bg.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
|
export function resize(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number): void;
|
BIN
codecs/resize/pkg/resize_bg.wasm
Normal file
BIN
codecs/resize/pkg/resize_bg.wasm
Normal file
Binary file not shown.
121
codecs/resize/src/lib.rs
Normal file
121
codecs/resize/src/lib.rs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
extern crate cfg_if;
|
||||||
|
extern crate resize;
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use cfg_if::cfg_if;
|
||||||
|
use resize::Pixel::RGBA;
|
||||||
|
use resize::Type;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
mod srgb;
|
||||||
|
use srgb::Clamp;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
|
// allocator.
|
||||||
|
if #[cfg(feature = "wee_alloc")] {
|
||||||
|
extern crate wee_alloc;
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include!("./lut.inc");
|
||||||
|
|
||||||
|
// If `with_space_conversion` is true, this function returns 2 functions that
|
||||||
|
// convert from sRGB to linear RGB and vice versa. If `with_space_conversion` is
|
||||||
|
// false, the 2 functions returned do nothing.
|
||||||
|
fn converter_funcs(with_space_conversion: bool) -> ((fn(u8) -> f32), (fn(f32) -> u8)) {
|
||||||
|
if with_space_conversion {
|
||||||
|
(
|
||||||
|
|v| SRGB_TO_LINEAR_LUT[v as usize] * 255.0,
|
||||||
|
|v| (LINEAR_TO_SRGB_LUT[v as usize] * 255.0) as u8,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(|v| v as f32, |v| v as u8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `with_alpha_premultiplication` is true, this function returns a function
|
||||||
|
// that premultiply the alpha channel with the given channel value and another
|
||||||
|
// function that reverses that process. If `with_alpha_premultiplication` is
|
||||||
|
// false, the functions just return the channel value.
|
||||||
|
fn alpha_multiplier_funcs(
|
||||||
|
with_alpha_premultiplication: bool,
|
||||||
|
) -> ((fn(f32, u8) -> u8), (fn(u8, u8) -> f32)) {
|
||||||
|
if with_alpha_premultiplication {
|
||||||
|
(
|
||||||
|
|v, a| (v * (a as f32) / 255.0) as u8,
|
||||||
|
|v, a| (v as f32) * 255.0 / (a as f32).clamp(0.0, 255.0),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(|v, _a| v as u8, |v, _a| v as f32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn resize(
|
||||||
|
mut input_image: Vec<u8>,
|
||||||
|
input_width: usize,
|
||||||
|
input_height: usize,
|
||||||
|
output_width: usize,
|
||||||
|
output_height: usize,
|
||||||
|
typ_idx: usize,
|
||||||
|
premultiply: bool,
|
||||||
|
color_space_conversion: bool,
|
||||||
|
) -> Vec<u8> {
|
||||||
|
let typ = match typ_idx {
|
||||||
|
0 => Type::Triangle,
|
||||||
|
1 => Type::Catrom,
|
||||||
|
2 => Type::Mitchell,
|
||||||
|
3 => Type::Lanczos3,
|
||||||
|
_ => panic!("Nope"),
|
||||||
|
};
|
||||||
|
let num_input_pixels = input_width * input_height;
|
||||||
|
let num_output_pixels = output_width * output_height;
|
||||||
|
|
||||||
|
let (to_linear, to_color_space) = converter_funcs(color_space_conversion);
|
||||||
|
let (premultiplier, demultiplier) = alpha_multiplier_funcs(premultiply);
|
||||||
|
|
||||||
|
// If both options are false, there is no preprocessing on the pixel valus
|
||||||
|
// and we can skip the loop.
|
||||||
|
if premultiply || color_space_conversion {
|
||||||
|
for i in 0..num_input_pixels {
|
||||||
|
for j in 0..3 {
|
||||||
|
input_image[4 * i + j] =
|
||||||
|
premultiplier(to_linear(input_image[4 * i + j]), input_image[4 * i + 3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut resizer = resize::new(
|
||||||
|
input_width,
|
||||||
|
input_height,
|
||||||
|
output_width,
|
||||||
|
output_height,
|
||||||
|
RGBA,
|
||||||
|
typ,
|
||||||
|
);
|
||||||
|
let mut output_image = Vec::<u8>::with_capacity(num_output_pixels * 4);
|
||||||
|
output_image.resize(num_output_pixels * 4, 0);
|
||||||
|
resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
|
||||||
|
|
||||||
|
if premultiply || color_space_conversion {
|
||||||
|
for i in 0..num_output_pixels {
|
||||||
|
for j in 0..3 {
|
||||||
|
// We don’t need to worry about division by zero, as division by zero
|
||||||
|
// is well-defined on floats to return ±Inf. ±Inf is converted to 0
|
||||||
|
// when casting to integers.
|
||||||
|
output_image[4 * i + j] = to_color_space(demultiplier(
|
||||||
|
output_image[4 * i + j],
|
||||||
|
output_image[4 * i + 3],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_image;
|
||||||
|
}
|
29
codecs/resize/src/srgb.rs
Normal file
29
codecs/resize/src/srgb.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
pub trait Clamp: std::cmp::PartialOrd + Sized {
|
||||||
|
fn clamp(self, min: Self, max: Self) -> Self {
|
||||||
|
if self.lt(&min) {
|
||||||
|
min
|
||||||
|
} else if self.gt(&max) {
|
||||||
|
max
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clamp for f32 {}
|
||||||
|
|
||||||
|
pub fn srgb_to_linear(v: f32) -> f32 {
|
||||||
|
if v < 0.04045 {
|
||||||
|
v / 12.92
|
||||||
|
} else {
|
||||||
|
((v + 0.055) / 1.055).powf(2.4).clamp(0.0, 1.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn linear_to_srgb(v: f32) -> f32 {
|
||||||
|
if v < 0.0031308 {
|
||||||
|
v * 12.92
|
||||||
|
} else {
|
||||||
|
(1.055 * v.powf(1.0 / 2.4) - 0.055).clamp(0.0, 1.0)
|
||||||
|
}
|
||||||
|
}
|
17
codecs/resize/src/utils.rs
Normal file
17
codecs/resize/src/utils.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use cfg_if::cfg_if;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||||
|
// `set_panic_hook` function at least once during initialization, and then
|
||||||
|
// we will get better error messages if our code ever panics.
|
||||||
|
//
|
||||||
|
// For more details see
|
||||||
|
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||||
|
if #[cfg(feature = "console_error_panic_hook")] {
|
||||||
|
extern crate console_error_panic_hook;
|
||||||
|
pub use self::console_error_panic_hook::set_once as set_panic_hook;
|
||||||
|
} else {
|
||||||
|
#[inline]
|
||||||
|
pub fn set_panic_hook() {}
|
||||||
|
}
|
||||||
|
}
|
2
codecs/rotate/.gitignore
vendored
Normal file
2
codecs/rotate/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
target
|
||||||
|
Cargo.lock
|
14
codecs/rotate/Cargo.toml
Normal file
14
codecs/rotate/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "rotate"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Surma <surma@google.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "rotate"
|
||||||
|
path = "rotate.rs"
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
8
codecs/rotate/Dockerfile
Normal file
8
codecs/rotate/Dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
FROM rust
|
||||||
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
|
|
||||||
|
RUN mkdir /opt/wabt && \
|
||||||
|
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||||
|
|
||||||
|
ENV PATH="/opt/wabt:${PATH}"
|
||||||
|
WORKDIR /src
|
45
codecs/rotate/benchmark.js
Normal file
45
codecs/rotate/benchmark.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// THIS IS NOT A NODE SCRIPT
|
||||||
|
// This is a d8 script. Please install jsvu[1] and install v8.
|
||||||
|
// Then run `npm run --silent benchmark`.
|
||||||
|
// [1]: https://github.com/GoogleChromeLabs/jsvu
|
||||||
|
async function init() {
|
||||||
|
// Adjustable constants.
|
||||||
|
const imageDimensions = 4096;
|
||||||
|
const iterations = new Array(100);
|
||||||
|
|
||||||
|
// Constants. Don’t change.
|
||||||
|
const imageByteSize = imageDimensions * imageDimensions * 4;
|
||||||
|
const wasmPageSize = 64 * 1024;
|
||||||
|
|
||||||
|
const buffer = readbuffer("rotate.wasm");
|
||||||
|
const { instance } = await WebAssembly.instantiate(buffer);
|
||||||
|
|
||||||
|
const pagesAvailable = Math.floor(
|
||||||
|
instance.exports.memory.buffer.byteLength / wasmPageSize
|
||||||
|
);
|
||||||
|
const pagesNeeded = Math.floor((imageByteSize * 2 + 4) / wasmPageSize) + 1;
|
||||||
|
const additionalPagesNeeded = pagesNeeded - pagesAvailable;
|
||||||
|
if (additionalPagesNeeded > 0) {
|
||||||
|
instance.exports.memory.grow(additionalPagesNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
[0, 90, 180, 270].forEach(rotation => {
|
||||||
|
print(`\n${rotation} degrees`);
|
||||||
|
print(`==============================`);
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
const start = Date.now();
|
||||||
|
instance.exports.rotate(imageDimensions, imageDimensions, rotation);
|
||||||
|
iterations[i] = Date.now() - start;
|
||||||
|
}
|
||||||
|
const average = iterations.reduce((sum, c) => sum + c) / iterations.length;
|
||||||
|
const stddev = Math.sqrt(
|
||||||
|
iterations
|
||||||
|
.map(i => Math.pow(i - average, 2))
|
||||||
|
.reduce((sum, c) => sum + c) / iterations.length
|
||||||
|
);
|
||||||
|
print(`n = ${iterations.length}`);
|
||||||
|
print(`Average: ${average}`);
|
||||||
|
print(`StdDev: ${stddev}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
init().catch(e => console.error(e.stack));
|
24
codecs/rotate/build.sh
Executable file
24
codecs/rotate/build.sh
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
cargo build \
|
||||||
|
--target wasm32-unknown-unknown \
|
||||||
|
--release
|
||||||
|
cp target/wasm32-unknown-unknown/release/rotate.wasm .
|
||||||
|
wasm-strip rotate.wasm
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull ubuntu\`"
|
||||||
|
echo "Run \`docker pull rust\`"
|
||||||
|
echo "Run \`docker build -t squoosh-rotate .\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
11
codecs/rotate/package.json
Normal file
11
codecs/rotate/package.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "rotate",
|
||||||
|
"scripts": {
|
||||||
|
"build:image": "docker build -t squoosh-rotate .",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-rotate ./build.sh",
|
||||||
|
"benchmark": "echo File size after gzip && npm run benchmark:filesize && echo Optimizing && npm run -s benchmark:optimizing",
|
||||||
|
"benchmark:baseline": "v8 --liftoff --no-wasm-tier-up --no-opt ./benchmark.js",
|
||||||
|
"benchmark:optimizing": "v8 --no-liftoff --no-wasm-tier-up ./benchmark.js",
|
||||||
|
"benchmark:filesize": "cat rotate.wasm | gzip -c9n | wc -c"
|
||||||
|
}
|
||||||
|
}
|
113
codecs/rotate/rotate.rs
Normal file
113
codecs/rotate/rotate.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
|
|
||||||
|
// This function is taken from Zachary Dremann
|
||||||
|
// https://github.com/GoogleChromeLabs/squoosh/pull/462
|
||||||
|
trait HardUnwrap<T> {
|
||||||
|
fn unwrap_hard(self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> HardUnwrap<T> for Option<T> {
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
#[inline]
|
||||||
|
fn unwrap_hard(self) -> T {
|
||||||
|
match self {
|
||||||
|
Some(t) => t,
|
||||||
|
None => std::process::abort(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
fn unwrap_hard(self) -> T {
|
||||||
|
self.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TILE_SIZE: usize = 16;
|
||||||
|
|
||||||
|
fn get_buffers<'a>(width: usize, height: usize) -> (&'a [u32], &'a mut [u32]) {
|
||||||
|
let num_pixels = width * height;
|
||||||
|
let in_b: &[u32];
|
||||||
|
let out_b: &mut [u32];
|
||||||
|
unsafe {
|
||||||
|
in_b = from_raw_parts::<u32>(8 as *const u32, num_pixels);
|
||||||
|
out_b = from_raw_parts_mut::<u32>((num_pixels * 4 + 8) as *mut u32, num_pixels);
|
||||||
|
}
|
||||||
|
return (in_b, out_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_0(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
for (in_p, out_p) in in_b.iter().zip(out_b.iter_mut()) {
|
||||||
|
*out_p = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_90(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
let new_width = height;
|
||||||
|
let _new_height = width;
|
||||||
|
for y_start in (0..height).step_by(TILE_SIZE) {
|
||||||
|
for x_start in (0..width).step_by(TILE_SIZE) {
|
||||||
|
for y in y_start..(y_start + TILE_SIZE).min(height) {
|
||||||
|
let in_offset = y * width;
|
||||||
|
let in_bounds = if x_start + TILE_SIZE < width {
|
||||||
|
(in_offset + x_start)..(in_offset + x_start + TILE_SIZE)
|
||||||
|
} else {
|
||||||
|
(in_offset + x_start)..(in_offset + width)
|
||||||
|
};
|
||||||
|
let in_chunk = in_b.get(in_bounds).unwrap_hard();
|
||||||
|
for (x, in_p) in in_chunk.iter().enumerate() {
|
||||||
|
let new_x = (new_width - 1) - y;
|
||||||
|
let new_y = x + x_start;
|
||||||
|
*out_b.get_mut(new_y * new_width + new_x).unwrap_hard() = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_180(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
for (in_p, out_p) in in_b.iter().zip(out_b.iter_mut().rev()) {
|
||||||
|
*out_p = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn rotate_270(width: usize, height: usize) {
|
||||||
|
let (in_b, out_b) = get_buffers(width, height);
|
||||||
|
let new_width = height;
|
||||||
|
let new_height = width;
|
||||||
|
for y_start in (0..height).step_by(TILE_SIZE) {
|
||||||
|
for x_start in (0..width).step_by(TILE_SIZE) {
|
||||||
|
for y in y_start..(y_start + TILE_SIZE).min(height) {
|
||||||
|
let in_offset = y * width;
|
||||||
|
let in_bounds = if x_start + TILE_SIZE < width {
|
||||||
|
(in_offset + x_start)..(in_offset + x_start + TILE_SIZE)
|
||||||
|
} else {
|
||||||
|
(in_offset + x_start)..(in_offset + width)
|
||||||
|
};
|
||||||
|
let in_chunk = in_b.get(in_bounds).unwrap_hard();
|
||||||
|
for (x, in_p) in in_chunk.iter().enumerate() {
|
||||||
|
let new_x = y;
|
||||||
|
let new_y = new_height - 1 - (x_start + x);
|
||||||
|
*out_b.get_mut(new_y * new_width + new_x).unwrap_hard() = *in_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn rotate(width: usize, height: usize, rotate: usize) {
|
||||||
|
match rotate {
|
||||||
|
0 => rotate_0(width, height),
|
||||||
|
90 => rotate_90(width, height),
|
||||||
|
180 => rotate_180(width, height),
|
||||||
|
270 => rotate_270(width, height),
|
||||||
|
_ => std::process::abort(),
|
||||||
|
}
|
||||||
|
}
|
BIN
codecs/rotate/rotate.wasm
Executable file
BIN
codecs/rotate/rotate.wasm
Executable file
Binary file not shown.
22
codecs/webp_dec/README.md
Normal file
22
codecs/webp_dec/README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# WebP decoder
|
||||||
|
|
||||||
|
- Source: <https://github.com/webmproject/libwebp>
|
||||||
|
- Version: v1.0.2
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See `example.html`
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `int version()`
|
||||||
|
|
||||||
|
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()`.
|
61
codecs/webp_dec/build.sh
Executable file
61
codecs/webp_dec/build.sh
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/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 libwebp"
|
||||||
|
echo "============================================="
|
||||||
|
test -n "$SKIP_LIBWEBP" || (
|
||||||
|
cd node_modules/libwebp
|
||||||
|
autoreconf -fiv
|
||||||
|
rm -rf build || true
|
||||||
|
mkdir -p build && cd build
|
||||||
|
emconfigure ../configure \
|
||||||
|
--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
|
||||||
|
emmake make
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm bindings"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
emcc \
|
||||||
|
${OPTIMIZE} \
|
||||||
|
--closure 1 \
|
||||||
|
--bind \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s 'EXPORT_NAME="webp_dec"' \
|
||||||
|
--std=c++11 \
|
||||||
|
-I node_modules/libwebp \
|
||||||
|
-o ./webp_dec.js \
|
||||||
|
-x c++ \
|
||||||
|
webp_dec.cpp \
|
||||||
|
node_modules/libwebp/build/src/.libs/libwebp.a
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm bindings done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull trzeci/emscripten\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
24
codecs/webp_dec/example.html
Normal file
24
codecs/webp_dec/example.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<script src='webp_dec.js'></script>
|
||||||
|
<script>
|
||||||
|
const Module = webp_dec();
|
||||||
|
|
||||||
|
async function loadFile(src) {
|
||||||
|
const resp = await fetch(src);
|
||||||
|
return await resp.arrayBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Module.onRuntimeInitialized = async _ => {
|
||||||
|
console.log('Version:', Module.version().toString(16));
|
||||||
|
const image = await loadFile('../example.webp');
|
||||||
|
const result = Module.decode(image);
|
||||||
|
const imageData = new ImageData(new Uint8ClampedArray(result.buffer), result.width, result.height);
|
||||||
|
Module.free_result();
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = result.width;
|
||||||
|
canvas.height = result.height;
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.putImageData(imageData, 0, 0);
|
||||||
|
};
|
||||||
|
</script>
|
1147
codecs/webp_dec/package-lock.json
generated
Normal file
1147
codecs/webp_dec/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
codecs/webp_dec/package.json
Normal file
13
codecs/webp_dec/package.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "webp_dec",
|
||||||
|
"scripts": {
|
||||||
|
"install": "napa",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten ./build.sh"
|
||||||
|
},
|
||||||
|
"napa": {
|
||||||
|
"libwebp": "webmproject/libwebp#v1.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"napa": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
47
codecs/webp_dec/webp_dec.cpp
Normal file
47
codecs/webp_dec/webp_dec.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "emscripten/bind.h"
|
||||||
|
#include "emscripten/val.h"
|
||||||
|
#include "src/webp/decode.h"
|
||||||
|
#include "src/webp/demux.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace emscripten;
|
||||||
|
|
||||||
|
int version() {
|
||||||
|
return WebPGetDecoderVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
class RawImage {
|
||||||
|
public:
|
||||||
|
val buffer;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
RawImage(val b, int w, int h)
|
||||||
|
: buffer(b), width(w), height(h) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t* last_result;
|
||||||
|
RawImage decode(std::string buffer) {
|
||||||
|
int width, height;
|
||||||
|
last_result = WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height);
|
||||||
|
return RawImage(
|
||||||
|
val(typed_memory_view(width*height*4, last_result)),
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_result() {
|
||||||
|
free(last_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
class_<RawImage>("RawImage")
|
||||||
|
.property("buffer", &RawImage::buffer)
|
||||||
|
.property("width", &RawImage::width)
|
||||||
|
.property("height", &RawImage::height);
|
||||||
|
|
||||||
|
function("decode", &decode);
|
||||||
|
function("version", &version);
|
||||||
|
function("free_result", &free_result);
|
||||||
|
}
|
13
codecs/webp_dec/webp_dec.d.ts
vendored
Normal file
13
codecs/webp_dec/webp_dec.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
interface RawImage {
|
||||||
|
buffer: Uint8Array;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WebPModule extends EmscriptenWasm.Module {
|
||||||
|
decode(data: BufferSource): RawImage;
|
||||||
|
free_result(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule;
|
||||||
|
|
79
codecs/webp_dec/webp_dec.js
Normal file
79
codecs/webp_dec/webp_dec.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
var webp_dec = (function() {
|
||||||
|
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
|
||||||
|
if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
|
||||||
|
return (
|
||||||
|
function(webp_dec) {
|
||||||
|
webp_dec = webp_dec || {};
|
||||||
|
|
||||||
|
var e;e||(e=typeof webp_dec !== 'undefined' ? webp_dec : {});var m={},r;for(r in e)e.hasOwnProperty(r)&&(m[r]=e[r]);var u=!1,v=!1,aa=!1,ba=!1,ca=!1;u="object"===typeof window;v="function"===typeof importScripts;aa=(ba="object"===typeof process&&"object"===typeof process.versions&&"string"===typeof process.versions.node)&&!u&&!v;ca=!u&&!aa&&!v;var w="",da,x,ea,fa;
|
||||||
|
if(aa)w=__dirname+"/",da=function(a,b){ea||(ea=require("fs"));fa||(fa=require("path"));a=fa.normalize(a);return ea.readFileSync(a,b?null:"utf8")},x=function(a){a=da(a,!0);a.buffer||(a=new Uint8Array(a));a.buffer||y("Assertion failed: undefined");return a},1<process.argv.length&&process.argv[1].replace(/\\/g,"/"),process.argv.slice(2),process.on("uncaughtException",function(a){throw a;}),process.on("unhandledRejection",y),e.inspect=function(){return"[Emscripten Module object]"};else if(ca)"undefined"!=
|
||||||
|
typeof read&&(da=function(a){return read(a)}),x=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");"object"===typeof a||y("Assertion failed: undefined");return a},"undefined"!==typeof print&&("undefined"===typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!==typeof printErr?printErr:print);else if(u||v)v?w=self.location.href:document.currentScript&&(w=document.currentScript.src),_scriptDir&&(w=_scriptDir),0!==w.indexOf("blob:")?
|
||||||
|
w=w.substr(0,w.lastIndexOf("/")+1):w="",da=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},v&&(x=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)});var ha=e.print||console.log.bind(console),z=e.printErr||console.warn.bind(console);for(r in m)m.hasOwnProperty(r)&&(e[r]=m[r]);m=null;var ia={"f64-rem":function(a,b){return a%b},"debugger":function(){}},A;e.wasmBinary&&(A=e.wasmBinary);
|
||||||
|
"object"!==typeof WebAssembly&&z("no native wasm support detected");var B,ja=new WebAssembly.Table({initial:230,maximum:230,element:"anyfunc"}),ka=!1,la="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0;
|
||||||
|
function ma(a,b,c){var d=b+c;for(c=b;a[c]&&!(c>=d);)++c;if(16<c-b&&a.subarray&&la)return la.decode(a.subarray(b,c));for(d="";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))d+=String.fromCharCode((f&31)<<6|h);else{var g=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|g:(f&7)<<18|h<<12|g<<6|a[b++]&63;65536>f?d+=String.fromCharCode(f):(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else d+=String.fromCharCode(f)}return d}
|
||||||
|
function na(a,b,c){var d=C;if(0<c){c=b+c-1;for(var f=0;f<a.length;++f){var h=a.charCodeAt(f);if(55296<=h&&57343>=h){var g=a.charCodeAt(++f);h=65536+((h&1023)<<10)|g&1023}if(127>=h){if(b>=c)break;d[b++]=h}else{if(2047>=h){if(b+1>=c)break;d[b++]=192|h>>6}else{if(65535>=h){if(b+2>=c)break;d[b++]=224|h>>12}else{if(b+3>=c)break;d[b++]=240|h>>18;d[b++]=128|h>>12&63}d[b++]=128|h>>6&63}d[b++]=128|h&63}}d[b]=0}}"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");
|
||||||
|
function oa(a){0<a%65536&&(a+=65536-a%65536);return a}var buffer,pa,C,qa,ra,D,E,sa,ta;function ua(a){buffer=a;e.HEAP8=pa=new Int8Array(a);e.HEAP16=qa=new Int16Array(a);e.HEAP32=D=new Int32Array(a);e.HEAPU8=C=new Uint8Array(a);e.HEAPU16=ra=new Uint16Array(a);e.HEAPU32=E=new Uint32Array(a);e.HEAPF32=sa=new Float32Array(a);e.HEAPF64=ta=new Float64Array(a)}var va=e.TOTAL_MEMORY||16777216;e.wasmMemory?B=e.wasmMemory:B=new WebAssembly.Memory({initial:va/65536});B&&(buffer=B.buffer);va=buffer.byteLength;
|
||||||
|
ua(buffer);D[3824]=5258368;function wa(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b();else{var c=b.ra;"number"===typeof c?void 0===b.ia?e.dynCall_v(c):e.dynCall_vi(c,b.ia):c(void 0===b.ia?null:b.ia)}}}var xa=[],ya=[],za=[],Aa=[];function Ba(){var a=e.preRun.shift();xa.unshift(a)}var G=0,Ca=null,H=null;e.preloadedImages={};e.preloadedAudios={};
|
||||||
|
function y(a){if(e.onAbort)e.onAbort(a);ha(a);z(a);ka=!0;throw new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");}function Da(){var a=I;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var I="webp_dec.wasm";if(!Da()){var Ea=I;I=e.locateFile?e.locateFile(Ea,w):w+Ea}
|
||||||
|
function Fa(){try{if(A)return new Uint8Array(A);if(x)return x(I);throw"both async and sync fetching of the wasm failed";}catch(a){y(a)}}function Ga(){return A||!u&&!v||"function"!==typeof fetch?new Promise(function(a){a(Fa())}):fetch(I,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+I+"'";return a.arrayBuffer()}).catch(function(){return Fa()})}
|
||||||
|
e.asm=function(){function a(a){e.asm=a.exports;G--;e.monitorRunDependencies&&e.monitorRunDependencies(G);0==G&&(null!==Ca&&(clearInterval(Ca),Ca=null),H&&(a=H,H=null,a()))}function b(b){a(b.instance)}function c(a){return Ga().then(function(a){return WebAssembly.instantiate(a,d)}).then(a,function(a){z("failed to asynchronously prepare wasm: "+a);y(a)})}var d={env:Ha,wasi_unstable:Ha,global:{NaN:NaN,Infinity:Infinity},"global.Math":Math,asm2wasm:ia};G++;e.monitorRunDependencies&&e.monitorRunDependencies(G);
|
||||||
|
if(e.instantiateWasm)try{return e.instantiateWasm(d,a)}catch(f){return z("Module.instantiateWasm callback failed with error: "+f),!1}(function(){if(A||"function"!==typeof WebAssembly.instantiateStreaming||Da()||"function"!==typeof fetch)return c(b);fetch(I,{credentials:"same-origin"}).then(function(a){return WebAssembly.instantiateStreaming(a,d).then(b,function(a){z("wasm streaming compile failed: "+a);z("falling back to ArrayBuffer instantiation");c(b)})})})();return{}};ya.push({ra:function(){Ia()}});
|
||||||
|
var Ja=[null,[],[]];function Ka(){return 0}function La(){return 0}function Ma(a,b,c,d){try{for(var f=0,h=0;h<c;h++){for(var g=D[b+8*h>>2],k=D[b+(8*h+4)>>2],p=0;p<k;p++){var q=C[g+p],l=Ja[a];0===q||10===q?((1===a?ha:z)(ma(l,0)),l.length=0):l.push(q)}f+=k}D[d>>2]=f;return 0}catch(t){return"undefined"!==typeof FS&&t instanceof FS.za||y(t),t.Aa}}function Na(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var Oa=void 0;
|
||||||
|
function J(a){for(var b="";C[a];)b+=Oa[C[a++]];return b}var K={},L={},Pa={};function Qa(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}function Ra(a,b){a=Qa(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}
|
||||||
|
function Sa(a){var b=Error,c=Ra(a,function(b){this.name=a;this.message=b;b=Error(b).stack;void 0!==b&&(this.stack=this.toString()+"\n"+b.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}var M=void 0;function P(a){throw new M(a);}var Ta=void 0;function Ua(a){throw new Ta(a);}
|
||||||
|
function Va(a,b,c){function d(b){b=c(b);b.length!==a.length&&Ua("Mismatched type converter count");for(var d=0;d<a.length;++d)Q(a[d],b[d])}a.forEach(function(a){Pa[a]=b});var f=Array(b.length),h=[],g=0;b.forEach(function(a,b){L.hasOwnProperty(a)?f[b]=L[a]:(h.push(a),K.hasOwnProperty(a)||(K[a]=[]),K[a].push(function(){f[b]=L[a];++g;g===h.length&&d(f)}))});0===h.length&&d(f)}
|
||||||
|
function Q(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||P('type "'+d+'" must have a positive integer typeid pointer');if(L.hasOwnProperty(a)){if(c.ua)return;P("Cannot register type '"+d+"' twice")}L[a]=b;delete Pa[a];K.hasOwnProperty(a)&&(b=K[a],delete K[a],b.forEach(function(a){a()}))}function Wa(a){return{count:a.count,da:a.da,ea:a.ea,T:a.T,V:a.V,W:a.W,X:a.X}}
|
||||||
|
function Xa(a){P(a.S.V.U.name+" instance already deleted")}var Ya=!1;function Za(){}function $a(a){--a.count.value;0===a.count.value&&(a.W?a.X.ba(a.W):a.V.U.ba(a.T))}function S(a){if("undefined"===typeof FinalizationGroup)return S=function(a){return a},a;Ya=new FinalizationGroup(function(a){for(var b=a.next();!b.done;b=a.next())b=b.value,b.T?$a(b):console.warn("object already deleted: "+b.T)});S=function(a){Ya.register(a,a.S,a.S);return a};Za=function(a){Ya.unregister(a.S)};return S(a)}
|
||||||
|
var T=void 0,ab=[];function bb(){for(;ab.length;){var a=ab.pop();a.S.da=!1;a["delete"]()}}function U(){}var cb={};function db(a,b){var c=e;if(void 0===c[a].Z){var d=c[a];c[a]=function(){c[a].Z.hasOwnProperty(arguments.length)||P("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].Z+")!");return c[a].Z[arguments.length].apply(this,arguments)};c[a].Z=[];c[a].Z[d.oa]=d}}
|
||||||
|
function eb(a,b,c){e.hasOwnProperty(a)?((void 0===c||void 0!==e[a].Z&&void 0!==e[a].Z[c])&&P("Cannot register public name '"+a+"' twice"),db(a,a),e.hasOwnProperty(c)&&P("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),e[a].Z[c]=b):(e[a]=b,void 0!==c&&(e[a].Ca=c))}function fb(a,b,c,d,f,h,g,k){this.name=a;this.constructor=b;this.aa=c;this.ba=d;this.Y=f;this.sa=h;this.fa=g;this.qa=k}
|
||||||
|
function gb(a,b,c){for(;b!==c;)b.fa||P("Expected null or instance of "+c.name+", got an instance of "+b.name),a=b.fa(a),b=b.Y;return a}function hb(a,b){if(null===b)return this.ja&&P("null is not a valid "+this.name),0;b.S||P('Cannot pass "'+V(b)+'" as a '+this.name);b.S.T||P("Cannot pass deleted object as a pointer of type "+this.name);return gb(b.S.T,b.S.V.U,this.U)}
|
||||||
|
function ib(a,b){if(null===b){this.ja&&P("null is not a valid "+this.name);if(this.ha){var c=this.wa();null!==a&&a.push(this.ba,c);return c}return 0}b.S||P('Cannot pass "'+V(b)+'" as a '+this.name);b.S.T||P("Cannot pass deleted object as a pointer of type "+this.name);!this.ga&&b.S.V.ga&&P("Cannot convert argument of type "+(b.S.X?b.S.X.name:b.S.V.name)+" to parameter type "+this.name);c=gb(b.S.T,b.S.V.U,this.U);if(this.ha)switch(void 0===b.S.W&&P("Passing raw pointer to smart pointer is illegal"),
|
||||||
|
this.ya){case 0:b.S.X===this?c=b.S.W:P("Cannot convert argument of type "+(b.S.X?b.S.X.name:b.S.V.name)+" to parameter type "+this.name);break;case 1:c=b.S.W;break;case 2:if(b.S.X===this)c=b.S.W;else{var d=b.clone();c=this.xa(c,jb(function(){d["delete"]()}));null!==a&&a.push(this.ba,c)}break;default:P("Unsupporting sharing policy")}return c}
|
||||||
|
function mb(a,b){if(null===b)return this.ja&&P("null is not a valid "+this.name),0;b.S||P('Cannot pass "'+V(b)+'" as a '+this.name);b.S.T||P("Cannot pass deleted object as a pointer of type "+this.name);b.S.V.ga&&P("Cannot convert argument of type "+b.S.V.name+" to parameter type "+this.name);return gb(b.S.T,b.S.V.U,this.U)}function nb(a){return this.fromWireType(E[a>>2])}function ob(a,b,c){if(b===c)return a;if(void 0===c.Y)return null;a=ob(a,b,c.Y);return null===a?null:c.qa(a)}var pb={};
|
||||||
|
function qb(a,b){for(void 0===b&&P("ptr should not be undefined");a.Y;)b=a.fa(b),a=a.Y;return pb[b]}function rb(a,b){b.V&&b.T||Ua("makeClassHandle requires ptr and ptrType");!!b.X!==!!b.W&&Ua("Both smartPtrType and smartPtr must be specified");b.count={value:1};return S(Object.create(a,{S:{value:b}}))}function W(a,b,c,d){this.name=a;this.U=b;this.ja=c;this.ga=d;this.ha=!1;this.ba=this.xa=this.wa=this.na=this.ya=this.va=void 0;void 0!==b.Y?this.toWireType=ib:(this.toWireType=d?hb:mb,this.$=null)}
|
||||||
|
function sb(a,b,c){e.hasOwnProperty(a)||Ua("Replacing nonexistant public symbol");void 0!==e[a].Z&&void 0!==c?e[a].Z[c]=b:(e[a]=b,e[a].oa=c)}
|
||||||
|
function X(a,b){a=J(a);if(void 0!==e["FUNCTION_TABLE_"+a])var c=e["FUNCTION_TABLE_"+a][b];else if("undefined"!==typeof FUNCTION_TABLE)c=FUNCTION_TABLE[b];else{c=e["dynCall_"+a];void 0===c&&(c=e["dynCall_"+a.replace(/f/g,"d")],void 0===c&&P("No dynCall invoker for signature: "+a));for(var d=[],f=1;f<a.length;++f)d.push("a"+f);f="return function "+("dynCall_"+a+"_"+b)+"("+d.join(", ")+") {\n";f+=" return dynCall(rawFunction"+(d.length?", ":"")+d.join(", ")+");\n";c=(new Function("dynCall","rawFunction",
|
||||||
|
f+"};\n"))(c,b)}"function"!==typeof c&&P("unknown function pointer with signature "+a+": "+b);return c}var tb=void 0;function ub(a){a=vb(a);var b=J(a);Y(a);return b}function wb(a,b){function c(a){f[a]||L[a]||(Pa[a]?Pa[a].forEach(c):(d.push(a),f[a]=!0))}var d=[],f={};b.forEach(c);throw new tb(a+": "+d.map(ub).join([", "]));}function xb(a){for(;a.length;){var b=a.pop();a.pop()(b)}}
|
||||||
|
function yb(a,b,c){a instanceof Object||P(c+' with invalid "this": '+a);a instanceof b.U.constructor||P(c+' incompatible with "this" of type '+a.constructor.name);a.S.T||P("cannot call emscripten binding method "+c+" on deleted object");return gb(a.S.T,a.S.V.U,b.U)}var zb=[],Z=[{},{value:void 0},{value:null},{value:!0},{value:!1}];function Ab(a){4<a&&0===--Z[a].ka&&(Z[a]=void 0,zb.push(a))}
|
||||||
|
function jb(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=zb.length?zb.pop():Z.length;Z[b]={ka:1,value:a};return b}}function V(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}function Bb(a,b){switch(b){case 2:return function(a){return this.fromWireType(sa[a>>2])};case 3:return function(a){return this.fromWireType(ta[a>>3])};default:throw new TypeError("Unknown float type: "+a);}}
|
||||||
|
function Cb(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=Ra(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}function Db(a,b){for(var c=[],d=0;d<a;d++)c.push(D[(b>>2)+d]);return c}
|
||||||
|
function Eb(a,b,c){switch(b){case 0:return c?function(a){return pa[a]}:function(a){return C[a]};case 1:return c?function(a){return qa[a>>1]}:function(a){return ra[a>>1]};case 2:return c?function(a){return D[a>>2]}:function(a){return E[a>>2]};default:throw new TypeError("Unknown integer type: "+a);}}function Fb(){return pa.length}for(var Gb=Array(256),Hb=0;256>Hb;++Hb)Gb[Hb]=String.fromCharCode(Hb);Oa=Gb;M=e.BindingError=Sa("BindingError");Ta=e.InternalError=Sa("InternalError");
|
||||||
|
U.prototype.isAliasOf=function(a){if(!(this instanceof U&&a instanceof U))return!1;var b=this.S.V.U,c=this.S.T,d=a.S.V.U;for(a=a.S.T;b.Y;)c=b.fa(c),b=b.Y;for(;d.Y;)a=d.fa(a),d=d.Y;return b===d&&c===a};U.prototype.clone=function(){this.S.T||Xa(this);if(this.S.ea)return this.S.count.value+=1,this;var a=S(Object.create(Object.getPrototypeOf(this),{S:{value:Wa(this.S)}}));a.S.count.value+=1;a.S.da=!1;return a};
|
||||||
|
U.prototype["delete"]=function(){this.S.T||Xa(this);this.S.da&&!this.S.ea&&P("Object already scheduled for deletion");Za(this);$a(this.S);this.S.ea||(this.S.W=void 0,this.S.T=void 0)};U.prototype.isDeleted=function(){return!this.S.T};U.prototype.deleteLater=function(){this.S.T||Xa(this);this.S.da&&!this.S.ea&&P("Object already scheduled for deletion");ab.push(this);1===ab.length&&T&&T(bb);this.S.da=!0;return this};W.prototype.ta=function(a){this.na&&(a=this.na(a));return a};
|
||||||
|
W.prototype.ma=function(a){this.ba&&this.ba(a)};W.prototype.argPackAdvance=8;W.prototype.readValueFromPointer=nb;W.prototype.deleteObject=function(a){if(null!==a)a["delete"]()};
|
||||||
|
W.prototype.fromWireType=function(a){function b(){return this.ha?rb(this.U.aa,{V:this.va,T:c,X:this,W:a}):rb(this.U.aa,{V:this,T:a})}var c=this.ta(a);if(!c)return this.ma(a),null;var d=qb(this.U,c);if(void 0!==d){if(0===d.S.count.value)return d.S.T=c,d.S.W=a,d.clone();d=d.clone();this.ma(a);return d}d=this.U.sa(c);d=cb[d];if(!d)return b.call(this);d=this.ga?d.pa:d.pointerType;var f=ob(c,this.U,d.U);return null===f?b.call(this):this.ha?rb(d.U.aa,{V:d,T:f,X:this,W:a}):rb(d.U.aa,{V:d,T:f})};
|
||||||
|
e.getInheritedInstanceCount=function(){return Object.keys(pb).length};e.getLiveInheritedInstances=function(){var a=[],b;for(b in pb)pb.hasOwnProperty(b)&&a.push(pb[b]);return a};e.flushPendingDeletes=bb;e.setDelayFunction=function(a){T=a;ab.length&&T&&T(bb)};tb=e.UnboundTypeError=Sa("UnboundTypeError");e.count_emval_handles=function(){for(var a=0,b=5;b<Z.length;++b)void 0!==Z[b]&&++a;return a};e.get_first_emval=function(){for(var a=5;a<Z.length;++a)if(void 0!==Z[a])return Z[a];return null};
|
||||||
|
var Ha={w:function(){return Ka.apply(null,arguments)},o:function(){return La.apply(null,arguments)},q:function(){return Ma.apply(null,arguments)},n:function(a,b,c,d,f){var h=Na(c);b=J(b);Q(a,{name:b,fromWireType:function(a){return!!a},toWireType:function(a,b){return b?d:f},argPackAdvance:8,readValueFromPointer:function(a){if(1===c)var d=pa;else if(2===c)d=qa;else if(4===c)d=D;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(d[a>>h])},$:null})},m:function(a,b,c,d,
|
||||||
|
f,h,g,k,p,q,l,t,N){l=J(l);h=X(f,h);k&&(k=X(g,k));q&&(q=X(p,q));N=X(t,N);var F=Qa(l);eb(F,function(){wb("Cannot construct "+l+" due to unbound types",[d])});Va([a,b,c],d?[d]:[],function(b){b=b[0];if(d){var c=b.U;var f=c.aa}else f=U.prototype;b=Ra(F,function(){if(Object.getPrototypeOf(this)!==p)throw new M("Use 'new' to construct "+l);if(void 0===g.la)throw new M(l+" has no accessible constructor");var a=g.la[arguments.length];if(void 0===a)throw new M("Tried to invoke ctor of "+l+" with invalid number of parameters ("+
|
||||||
|
arguments.length+") - expected ("+Object.keys(g.la).toString()+") parameters instead!");return a.apply(this,arguments)});var p=Object.create(f,{constructor:{value:b}});b.prototype=p;var g=new fb(l,b,p,N,c,h,k,q);c=new W(l,g,!0,!1);f=new W(l+"*",g,!1,!1);var t=new W(l+" const*",g,!1,!0);cb[a]={pointerType:f,pa:t};sb(F,b);return[c,f,t]})},e:function(a,b,c,d,f,h,g,k,p,q){b=J(b);f=X(d,f);Va([],[a],function(a){a=a[0];var d=a.name+"."+b,l={get:function(){wb("Cannot access "+d+" due to unbound types",[c,
|
||||||
|
g])},enumerable:!0,configurable:!0};p?l.set=function(){wb("Cannot access "+d+" due to unbound types",[c,g])}:l.set=function(){P(d+" is a read-only property")};Object.defineProperty(a.U.aa,b,l);Va([],p?[c,g]:[c],function(c){var g=c[0],l={get:function(){var b=yb(this,a,d+" getter");return g.fromWireType(f(h,b))},enumerable:!0};if(p){p=X(k,p);var t=c[1];l.set=function(b){var c=yb(this,a,d+" setter"),f=[];p(q,c,t.toWireType(f,b));xb(f)}}Object.defineProperty(a.U.aa,b,l);return[]});return[]})},l:function(a,
|
||||||
|
b){b=J(b);Q(a,{name:b,fromWireType:function(a){var b=Z[a].value;Ab(a);return b},toWireType:function(a,b){return jb(b)},argPackAdvance:8,readValueFromPointer:nb,$:null})},f:function(a,b,c){c=Na(c);b=J(b);Q(a,{name:b,fromWireType:function(a){return a},toWireType:function(a,b){if("number"!==typeof b&&"boolean"!==typeof b)throw new TypeError('Cannot convert "'+V(b)+'" to '+this.name);return b},argPackAdvance:8,readValueFromPointer:Bb(b,c),$:null})},d:function(a,b,c,d,f,h){var g=Db(b,c);a=J(a);f=X(d,f);
|
||||||
|
eb(a,function(){wb("Cannot call "+a+" due to unbound types",g)},b-1);Va([],g,function(c){var d=[c[0],null].concat(c.slice(1)),g=c=a,l=f,k=d.length;2>k&&P("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var N=null!==d[1]&&!1,F=!1,n=1;n<d.length;++n)if(null!==d[n]&&void 0===d[n].$){F=!0;break}var kb="void"!==d[0].name,O="",R="";for(n=0;n<k-2;++n)O+=(0!==n?", ":"")+"arg"+n,R+=(0!==n?", ":"")+"arg"+n+"Wired";g="return function "+Qa(g)+"("+O+") {\nif (arguments.length !== "+
|
||||||
|
(k-2)+") {\nthrowBindingError('function "+g+" called with ' + arguments.length + ' arguments, expected "+(k-2)+" args!');\n}\n";F&&(g+="var destructors = [];\n");var lb=F?"destructors":"null";O="throwBindingError invoker fn runDestructors retType classParam".split(" ");l=[P,l,h,xb,d[0],d[1]];N&&(g+="var thisWired = classParam.toWireType("+lb+", this);\n");for(n=0;n<k-2;++n)g+="var arg"+n+"Wired = argType"+n+".toWireType("+lb+", arg"+n+"); // "+d[n+2].name+"\n",O.push("argType"+n),l.push(d[n+2]);N&&
|
||||||
|
(R="thisWired"+(0<R.length?", ":"")+R);g+=(kb?"var rv = ":"")+"invoker(fn"+(0<R.length?", ":"")+R+");\n";if(F)g+="runDestructors(destructors);\n";else for(n=N?1:2;n<d.length;++n)k=1===n?"thisWired":"arg"+(n-2)+"Wired",null!==d[n].$&&(g+=k+"_dtor("+k+"); // "+d[n].name+"\n",O.push(k+"_dtor"),l.push(d[n].$));kb&&(g+="var ret = retType.fromWireType(rv);\nreturn ret;\n");O.push(g+"}\n");d=Cb(O).apply(null,l);sb(c,d,b-1);return[]})},c:function(a,b,c,d,f){function h(a){return a}b=J(b);-1===f&&(f=4294967295);
|
||||||
|
var g=Na(c);if(0===d){var k=32-8*c;h=function(a){return a<<k>>>k}}var p=-1!=b.indexOf("unsigned");Q(a,{name:b,fromWireType:h,toWireType:function(a,c){if("number"!==typeof c&&"boolean"!==typeof c)throw new TypeError('Cannot convert "'+V(c)+'" to '+this.name);if(c<d||c>f)throw new TypeError('Passing a number "'+V(c)+'" from JS side to C/C++ side to an argument of type "'+b+'", which is outside the valid range ['+d+", "+f+"]!");return p?c>>>0:c|0},argPackAdvance:8,readValueFromPointer:Eb(b,g,0!==d),
|
||||||
|
$:null})},b:function(a,b,c){function d(a){a>>=2;var b=E;return new f(b.buffer,b[a+1],b[a])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=J(c);Q(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{ua:!0})},k:function(a,b){b=J(b);var c="std::string"===b;Q(a,{name:b,fromWireType:function(a){var b=E[a>>2];if(c){var d=C[a+4+b],g=0;0!=d&&(g=d,C[a+4+b]=0);var k=a+4;for(d=0;d<=b;++d){var p=a+4+d;if(0==C[p]){k=k?ma(C,k,void 0):"";if(void 0===
|
||||||
|
q)var q=k;else q+=String.fromCharCode(0),q+=k;k=p+1}}0!=g&&(C[a+4+b]=g)}else{q=Array(b);for(d=0;d<b;++d)q[d]=String.fromCharCode(C[a+4+d]);q=q.join("")}Y(a);return q},toWireType:function(a,b){b instanceof ArrayBuffer&&(b=new Uint8Array(b));var d="string"===typeof b;d||b instanceof Uint8Array||b instanceof Uint8ClampedArray||b instanceof Int8Array||P("Cannot pass non-string to std::string");var f=(c&&d?function(){for(var a=0,c=0;c<b.length;++c){var d=b.charCodeAt(c);55296<=d&&57343>=d&&(d=65536+((d&
|
||||||
|
1023)<<10)|b.charCodeAt(++c)&1023);127>=d?++a:a=2047>=d?a+2:65535>=d?a+3:a+4}return a}:function(){return b.length})(),k=Ib(4+f+1);E[k>>2]=f;if(c&&d)na(b,k+4,f+1);else if(d)for(d=0;d<f;++d){var p=b.charCodeAt(d);255<p&&(Y(k),P("String has UTF-16 code units that do not fit in 8 bits"));C[k+4+d]=p}else for(d=0;d<f;++d)C[k+4+d]=b[d];null!==a&&a.push(Y,k);return k},argPackAdvance:8,readValueFromPointer:nb,$:function(a){Y(a)}})},v:function(a,b,c){c=J(c);if(2===b){var d=function(){return ra};var f=1}else 4===
|
||||||
|
b&&(d=function(){return E},f=2);Q(a,{name:c,fromWireType:function(a){for(var b=d(),c=E[a>>2],h=Array(c),q=a+4>>f,l=0;l<c;++l)h[l]=String.fromCharCode(b[q+l]);Y(a);return h.join("")},toWireType:function(a,c){var h=c.length,g=Ib(4+h*b),q=d();E[g>>2]=h;for(var l=g+4>>f,t=0;t<h;++t)q[l+t]=c.charCodeAt(t);null!==a&&a.push(Y,g);return g},argPackAdvance:8,readValueFromPointer:nb,$:function(a){Y(a)}})},u:function(a,b){b=J(b);Q(a,{Ba:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},
|
||||||
|
j:Ab,t:function(a){4<a&&(Z[a].ka+=1)},i:function(a,b){var c=L[a];void 0===c&&P("_emval_take_value has unknown type "+ub(a));a=c.readValueFromPointer(b);return jb(a)},__memory_base:1024,__table_base:0,h:function(){y()},s:Fb,r:function(a,b,c){C.set(C.subarray(b,b+c),a)},p:function(a){if(2147418112<a)return!1;for(var b=Math.max(Fb(),16777216);b<a;)536870912>=b?b=oa(2*b):b=Math.min(oa((3*b+2147483648)/4),2147418112);a:{try{B.grow(b-buffer.byteLength+65535>>16);ua(B.buffer);var c=1;break a}catch(d){}c=
|
||||||
|
void 0}return c?!0:!1},a:y,memory:B,g:function(){},table:ja},Jb=e.asm({},Ha,buffer);e.asm=Jb;e.___embind_register_native_and_builtin_types=function(){return e.asm.x.apply(null,arguments)};var vb=e.___getTypeName=function(){return e.asm.y.apply(null,arguments)},Y=e._free=function(){return e.asm.z.apply(null,arguments)},Ib=e._malloc=function(){return e.asm.A.apply(null,arguments)},Ia=e.globalCtors=function(){return e.asm.R.apply(null,arguments)};e.dynCall_i=function(){return e.asm.B.apply(null,arguments)};
|
||||||
|
e.dynCall_ii=function(){return e.asm.C.apply(null,arguments)};e.dynCall_iidiiii=function(){return e.asm.D.apply(null,arguments)};e.dynCall_iii=function(){return e.asm.E.apply(null,arguments)};e.dynCall_iiii=function(){return e.asm.F.apply(null,arguments)};e.dynCall_iiiiiii=function(){return e.asm.G.apply(null,arguments)};e.dynCall_jiiii=function(){return e.asm.H.apply(null,arguments)};e.dynCall_jiji=function(){return e.asm.I.apply(null,arguments)};
|
||||||
|
e.dynCall_v=function(){return e.asm.J.apply(null,arguments)};e.dynCall_vi=function(){return e.asm.K.apply(null,arguments)};e.dynCall_vii=function(){return e.asm.L.apply(null,arguments)};e.dynCall_viii=function(){return e.asm.M.apply(null,arguments)};e.dynCall_viiii=function(){return e.asm.N.apply(null,arguments)};e.dynCall_viiiii=function(){return e.asm.O.apply(null,arguments)};e.dynCall_viiiiii=function(){return e.asm.P.apply(null,arguments)};
|
||||||
|
e.dynCall_viiiiiiiii=function(){return e.asm.Q.apply(null,arguments)};e.asm=Jb;var Kb;e.then=function(a){if(Kb)a(e);else{var b=e.onRuntimeInitialized;e.onRuntimeInitialized=function(){b&&b();a(e)}}return e};H=function Lb(){Kb||Mb();Kb||(H=Lb)};
|
||||||
|
function Mb(){function a(){if(!Kb&&(Kb=!0,!ka)){wa(ya);wa(za);if(e.onRuntimeInitialized)e.onRuntimeInitialized();if(e.postRun)for("function"==typeof e.postRun&&(e.postRun=[e.postRun]);e.postRun.length;){var a=e.postRun.shift();Aa.unshift(a)}wa(Aa)}}if(!(0<G)){if(e.preRun)for("function"==typeof e.preRun&&(e.preRun=[e.preRun]);e.preRun.length;)Ba();wa(xa);0<G||(e.setStatus?(e.setStatus("Running..."),setTimeout(function(){setTimeout(function(){e.setStatus("")},1);a()},1)):a())}}e.run=Mb;
|
||||||
|
if(e.preInit)for("function"==typeof e.preInit&&(e.preInit=[e.preInit]);0<e.preInit.length;)e.preInit.pop()();Mb();
|
||||||
|
|
||||||
|
|
||||||
|
return webp_dec
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
if (typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = webp_dec;
|
||||||
|
else if (typeof define === 'function' && define['amd'])
|
||||||
|
define([], function() { return webp_dec; });
|
||||||
|
else if (typeof exports === 'object')
|
||||||
|
exports["webp_dec"] = webp_dec;
|
||||||
|
|
BIN
codecs/webp_dec/webp_dec.wasm
Normal file
BIN
codecs/webp_dec/webp_dec.wasm
Normal file
Binary file not shown.
26
codecs/webp_enc/README.md
Normal file
26
codecs/webp_enc/README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# WebP encoder
|
||||||
|
|
||||||
|
- Source: <https://github.com/webmproject/libwebp>
|
||||||
|
- Version: v1.0.2
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Docker
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See `example.html`
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `int version()`
|
||||||
|
|
||||||
|
Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
||||||
|
|
||||||
|
### `UInt8Array encode(uint8_t* image_buffer, int image_width, int image_height, WebPConfig config)`
|
||||||
|
|
||||||
|
Encodes the given image with given dimension to WebP.
|
||||||
|
|
||||||
|
### `void free_result()`
|
||||||
|
|
||||||
|
Frees the last result created by `encode()`.
|
62
codecs/webp_enc/build.sh
Executable file
62
codecs/webp_enc/build.sh
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/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 libwebp"
|
||||||
|
echo "============================================="
|
||||||
|
test -n "$SKIP_LIBWEBP" || (
|
||||||
|
cd node_modules/libwebp
|
||||||
|
autoreconf -fiv
|
||||||
|
rm -rf build || true
|
||||||
|
mkdir -p build && cd build
|
||||||
|
emconfigure ../configure \
|
||||||
|
--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
|
||||||
|
emmake make
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm bindings"
|
||||||
|
echo "============================================="
|
||||||
|
(
|
||||||
|
emcc \
|
||||||
|
${OPTIMIZE} \
|
||||||
|
--closure 1 \
|
||||||
|
--bind \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s 'EXPORT_NAME="webp_enc"' \
|
||||||
|
--std=c++11 \
|
||||||
|
-I node_modules/libwebp \
|
||||||
|
-o ./webp_enc.js \
|
||||||
|
-x c++ \
|
||||||
|
webp_enc.cpp \
|
||||||
|
node_modules/libwebp/build/src/.libs/libwebp.a
|
||||||
|
)
|
||||||
|
echo "============================================="
|
||||||
|
echo "Compiling wasm bindings done"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||||
|
echo "Did you update your docker image?"
|
||||||
|
echo "Run \`docker pull trzeci/emscripten\`"
|
||||||
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
62
codecs/webp_enc/example.html
Normal file
62
codecs/webp_enc/example.html
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<script src='webp_enc.js'></script>
|
||||||
|
<script>
|
||||||
|
const module = webp_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 image = await loadImage('../example.png');
|
||||||
|
const result = module.encode(image.data, image.width, image.height, {
|
||||||
|
quality: 75,
|
||||||
|
target_size: 0,
|
||||||
|
target_PSNR: 0,
|
||||||
|
method: 4,
|
||||||
|
sns_strength: 50,
|
||||||
|
filter_strength: 60,
|
||||||
|
filter_sharpness: 0,
|
||||||
|
filter_type: 1,
|
||||||
|
partitions: 0,
|
||||||
|
segments: 4,
|
||||||
|
pass: 1,
|
||||||
|
show_compressed: 0,
|
||||||
|
preprocessing: 0,
|
||||||
|
autofilter: 0,
|
||||||
|
partition_limit: 0,
|
||||||
|
alpha_compression: 1,
|
||||||
|
alpha_filtering: 1,
|
||||||
|
alpha_quality: 100,
|
||||||
|
lossless: 0,
|
||||||
|
exact: 0,
|
||||||
|
image_hint: 0,
|
||||||
|
emulate_jpeg_size: 0,
|
||||||
|
thread_level: 0,
|
||||||
|
low_memory: 0,
|
||||||
|
near_lossless: 100,
|
||||||
|
use_delta_palette: 0,
|
||||||
|
use_sharp_yuv: 0,
|
||||||
|
});
|
||||||
|
console.log('size', result.length);
|
||||||
|
const blob = new Blob([result], {type: 'image/webp'});
|
||||||
|
|
||||||
|
module.free_result();
|
||||||
|
|
||||||
|
const blobURL = URL.createObjectURL(blob);
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.src = blobURL;
|
||||||
|
document.body.appendChild(img);
|
||||||
|
};
|
||||||
|
</script>
|
1147
codecs/webp_enc/package-lock.json
generated
Normal file
1147
codecs/webp_enc/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
codecs/webp_enc/package.json
Normal file
13
codecs/webp_enc/package.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "webp_enc",
|
||||||
|
"scripts": {
|
||||||
|
"install": "napa",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten ./build.sh"
|
||||||
|
},
|
||||||
|
"napa": {
|
||||||
|
"libwebp": "webmproject/libwebp#v1.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"napa": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
96
codecs/webp_enc/webp_enc.cpp
Normal file
96
codecs/webp_enc/webp_enc.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
#include "src/webp/encode.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
using namespace emscripten;
|
||||||
|
|
||||||
|
int version() {
|
||||||
|
return WebPGetEncoderVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* last_result;
|
||||||
|
|
||||||
|
val encode(std::string img, int width, int height, WebPConfig config) {
|
||||||
|
uint8_t* img_in = (uint8_t*) img.c_str();
|
||||||
|
|
||||||
|
// A lot of this is duplicated from Encode in picture_enc.c
|
||||||
|
WebPPicture pic;
|
||||||
|
WebPMemoryWriter wrt;
|
||||||
|
int ok;
|
||||||
|
|
||||||
|
if (!WebPPictureInit(&pic)) {
|
||||||
|
// shouldn't happen, except if system installation is broken
|
||||||
|
throw std::runtime_error("Unexpected error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only use use_argb if we really need it, as it's slower.
|
||||||
|
pic.use_argb = config.lossless || config.use_sharp_yuv || config.preprocessing > 0;
|
||||||
|
pic.width = width;
|
||||||
|
pic.height = height;
|
||||||
|
pic.writer = WebPMemoryWrite;
|
||||||
|
pic.custom_ptr = &wrt;
|
||||||
|
|
||||||
|
WebPMemoryWriterInit(&wrt);
|
||||||
|
|
||||||
|
ok = WebPPictureImportRGBA(&pic, (uint8_t*) img_in, width * 4) && WebPEncode(&config, &pic);
|
||||||
|
WebPPictureFree(&pic);
|
||||||
|
if (!ok) {
|
||||||
|
WebPMemoryWriterClear(&wrt);
|
||||||
|
throw std::runtime_error("Encode failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
last_result = wrt.mem;
|
||||||
|
|
||||||
|
return val(typed_memory_view(wrt.size, wrt.mem));
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_result() {
|
||||||
|
WebPFree(last_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
enum_<WebPImageHint>("WebPImageHint")
|
||||||
|
.value("WEBP_HINT_DEFAULT", WebPImageHint::WEBP_HINT_DEFAULT)
|
||||||
|
.value("WEBP_HINT_PICTURE", WebPImageHint::WEBP_HINT_PICTURE)
|
||||||
|
.value("WEBP_HINT_PHOTO", WebPImageHint::WEBP_HINT_PHOTO)
|
||||||
|
.value("WEBP_HINT_GRAPH", WebPImageHint::WEBP_HINT_GRAPH)
|
||||||
|
;
|
||||||
|
|
||||||
|
value_object<WebPConfig>("WebPConfig")
|
||||||
|
.field("lossless", &WebPConfig::lossless)
|
||||||
|
.field("quality", &WebPConfig::quality)
|
||||||
|
.field("method", &WebPConfig::method)
|
||||||
|
.field("image_hint", &WebPConfig::image_hint)
|
||||||
|
.field("target_size", &WebPConfig::target_size)
|
||||||
|
.field("target_PSNR", &WebPConfig::target_PSNR)
|
||||||
|
.field("segments", &WebPConfig::segments)
|
||||||
|
.field("sns_strength", &WebPConfig::sns_strength)
|
||||||
|
.field("filter_strength", &WebPConfig::filter_strength)
|
||||||
|
.field("filter_sharpness", &WebPConfig::filter_sharpness)
|
||||||
|
.field("filter_type", &WebPConfig::filter_type)
|
||||||
|
.field("autofilter", &WebPConfig::autofilter)
|
||||||
|
.field("alpha_compression", &WebPConfig::alpha_compression)
|
||||||
|
.field("alpha_filtering", &WebPConfig::alpha_filtering)
|
||||||
|
.field("alpha_quality", &WebPConfig::alpha_quality)
|
||||||
|
.field("pass", &WebPConfig::pass)
|
||||||
|
.field("show_compressed", &WebPConfig::show_compressed)
|
||||||
|
.field("preprocessing", &WebPConfig::preprocessing)
|
||||||
|
.field("partitions", &WebPConfig::partitions)
|
||||||
|
.field("partition_limit", &WebPConfig::partition_limit)
|
||||||
|
.field("emulate_jpeg_size", &WebPConfig::emulate_jpeg_size)
|
||||||
|
.field("thread_level", &WebPConfig::thread_level)
|
||||||
|
.field("low_memory", &WebPConfig::low_memory)
|
||||||
|
.field("near_lossless", &WebPConfig::near_lossless)
|
||||||
|
.field("exact", &WebPConfig::exact)
|
||||||
|
.field("use_delta_palette", &WebPConfig::use_delta_palette)
|
||||||
|
.field("use_sharp_yuv", &WebPConfig::use_sharp_yuv)
|
||||||
|
;
|
||||||
|
|
||||||
|
function("version", &version);
|
||||||
|
function("encode", &encode);
|
||||||
|
function("free_result", &free_result);
|
||||||
|
}
|
9
codecs/webp_enc/webp_enc.d.ts
vendored
Normal file
9
codecs/webp_enc/webp_enc.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { EncodeOptions } from '../../src/codecs/webp/encoder-meta';
|
||||||
|
|
||||||
|
interface WebPModule extends EmscriptenWasm.Module {
|
||||||
|
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array;
|
||||||
|
free_result(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule;
|
70
codecs/webp_enc/webp_enc.js
Normal file
70
codecs/webp_enc/webp_enc.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
var webp_enc = (function() {
|
||||||
|
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
|
||||||
|
if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
|
||||||
|
return (
|
||||||
|
function(webp_enc) {
|
||||||
|
webp_enc = webp_enc || {};
|
||||||
|
|
||||||
|
var d;d||(d=typeof webp_enc !== 'undefined' ? webp_enc : {});var n={},q;for(q in d)d.hasOwnProperty(q)&&(n[q]=d[q]);var r=!1,t=!1,aa=!1,ba=!1,ca=!1;r="object"===typeof window;t="function"===typeof importScripts;aa=(ba="object"===typeof process&&"object"===typeof process.versions&&"string"===typeof process.versions.node)&&!r&&!t;ca=!r&&!aa&&!t;var u="",v,x,fa,ha;
|
||||||
|
if(aa)u=__dirname+"/",v=function(a,b){fa||(fa=require("fs"));ha||(ha=require("path"));a=ha.normalize(a);return fa.readFileSync(a,b?null:"utf8")},x=function(a){a=v(a,!0);a.buffer||(a=new Uint8Array(a));a.buffer||y("Assertion failed: undefined");return a},1<process.argv.length&&process.argv[1].replace(/\\/g,"/"),process.argv.slice(2),process.on("uncaughtException",function(a){throw a;}),process.on("unhandledRejection",y),d.inspect=function(){return"[Emscripten Module object]"};else if(ca)"undefined"!=
|
||||||
|
typeof read&&(v=function(a){return read(a)}),x=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");"object"===typeof a||y("Assertion failed: undefined");return a},"undefined"!==typeof print&&("undefined"===typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!==typeof printErr?printErr:print);else if(r||t)t?u=self.location.href:document.currentScript&&(u=document.currentScript.src),_scriptDir&&(u=_scriptDir),0!==u.indexOf("blob:")?
|
||||||
|
u=u.substr(0,u.lastIndexOf("/")+1):u="",v=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},t&&(x=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)});var ia=d.print||console.log.bind(console),z=d.printErr||console.warn.bind(console);for(q in n)n.hasOwnProperty(q)&&(d[q]=n[q]);n=null;var ja={"f64-rem":function(a,b){return a%b},"debugger":function(){}},A;d.wasmBinary&&(A=d.wasmBinary);
|
||||||
|
"object"!==typeof WebAssembly&&z("no native wasm support detected");var C,ka=new WebAssembly.Table({initial:256,maximum:256,element:"anyfunc"}),la=!1,ma="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0;
|
||||||
|
function na(a,b,c){var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.subarray&&ma)return ma.decode(a.subarray(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var g=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|g);else{var k=a[b++]&63;f=224==(f&240)?(f&15)<<12|g<<6|k:(f&7)<<18|g<<12|k<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e}
|
||||||
|
function oa(a,b,c){var e=D;if(0<c){c=b+c-1;for(var f=0;f<a.length;++f){var g=a.charCodeAt(f);if(55296<=g&&57343>=g){var k=a.charCodeAt(++f);g=65536+((g&1023)<<10)|k&1023}if(127>=g){if(b>=c)break;e[b++]=g}else{if(2047>=g){if(b+1>=c)break;e[b++]=192|g>>6}else{if(65535>=g){if(b+2>=c)break;e[b++]=224|g>>12}else{if(b+3>=c)break;e[b++]=240|g>>18;e[b++]=128|g>>12&63}e[b++]=128|g>>6&63}e[b++]=128|g&63}}e[b]=0}}"undefined"!==typeof TextDecoder&&new TextDecoder("utf-16le");
|
||||||
|
function pa(a){0<a%65536&&(a+=65536-a%65536);return a}var buffer,E,D,F,G,H,I,qa,ra;function ta(a){buffer=a;d.HEAP8=E=new Int8Array(a);d.HEAP16=F=new Int16Array(a);d.HEAP32=H=new Int32Array(a);d.HEAPU8=D=new Uint8Array(a);d.HEAPU16=G=new Uint16Array(a);d.HEAPU32=I=new Uint32Array(a);d.HEAPF32=qa=new Float32Array(a);d.HEAPF64=ra=new Float64Array(a)}var ua=d.TOTAL_MEMORY||16777216;d.wasmMemory?C=d.wasmMemory:C=new WebAssembly.Memory({initial:ua/65536});C&&(buffer=C.buffer);ua=buffer.byteLength;ta(buffer);
|
||||||
|
H[9180]=5279792;function K(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b();else{var c=b.ja;"number"===typeof c?void 0===b.da?d.dynCall_v(c):d.dynCall_vi(c,b.da):c(void 0===b.da?null:b.da)}}}var va=[],wa=[],xa=[],ya=[];function za(){var a=d.preRun.shift();va.unshift(a)}var M=0,Aa=null,N=null;d.preloadedImages={};d.preloadedAudios={};
|
||||||
|
function y(a){if(d.onAbort)d.onAbort(a);ia(a);z(a);la=!0;throw new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");}function Ba(){var a=O;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var O="webp_enc.wasm";if(!Ba()){var Ca=O;O=d.locateFile?d.locateFile(Ca,u):u+Ca}
|
||||||
|
function Da(){try{if(A)return new Uint8Array(A);if(x)return x(O);throw"both async and sync fetching of the wasm failed";}catch(a){y(a)}}function Ea(){return A||!r&&!t||"function"!==typeof fetch?new Promise(function(a){a(Da())}):fetch(O,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+O+"'";return a.arrayBuffer()}).catch(function(){return Da()})}
|
||||||
|
d.asm=function(){function a(a){d.asm=a.exports;M--;d.monitorRunDependencies&&d.monitorRunDependencies(M);0==M&&(null!==Aa&&(clearInterval(Aa),Aa=null),N&&(a=N,N=null,a()))}function b(b){a(b.instance)}function c(a){return Ea().then(function(a){return WebAssembly.instantiate(a,e)}).then(a,function(a){z("failed to asynchronously prepare wasm: "+a);y(a)})}var e={env:Fa,wasi_unstable:Fa,global:{NaN:NaN,Infinity:Infinity},"global.Math":Math,asm2wasm:ja};M++;d.monitorRunDependencies&&d.monitorRunDependencies(M);
|
||||||
|
if(d.instantiateWasm)try{return d.instantiateWasm(e,a)}catch(f){return z("Module.instantiateWasm callback failed with error: "+f),!1}(function(){if(A||"function"!==typeof WebAssembly.instantiateStreaming||Ba()||"function"!==typeof fetch)return c(b);fetch(O,{credentials:"same-origin"}).then(function(a){return WebAssembly.instantiateStreaming(a,e).then(b,function(a){z("wasm streaming compile failed: "+a);z("falling back to ArrayBuffer instantiation");c(b)})})})();return{}};wa.push({ja:function(){Ga()}});
|
||||||
|
var Ha=[null,[],[]];function Ia(){return 0}function Ja(){return 0}function Ka(a,b,c,e){try{for(var f=0,g=0;g<c;g++){for(var k=H[b+8*g>>2],h=H[b+(8*g+4)>>2],p=0;p<h;p++){var l=D[k+p],w=Ha[a];0===l||10===l?((1===a?ia:z)(na(w,0)),w.length=0):w.push(l)}f+=h}H[e>>2]=f;return 0}catch(B){return"undefined"!==typeof FS&&B instanceof FS.ta||y(B),B.ua}}var P={};function La(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function Q(a){return this.fromWireType(I[a>>2])}var R={},S={},Ma={};
|
||||||
|
function Na(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}function Oa(a,b){a=Na(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}
|
||||||
|
function Pa(a){var b=Error,c=Oa(a,function(b){this.name=a;this.message=b;b=Error(b).stack;void 0!==b&&(this.stack=this.toString()+"\n"+b.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}var Qa=void 0;
|
||||||
|
function Ra(a,b,c){function e(b){b=c(b);if(b.length!==a.length)throw new Qa("Mismatched type converter count");for(var e=0;e<a.length;++e)T(a[e],b[e])}a.forEach(function(a){Ma[a]=b});var f=Array(b.length),g=[],k=0;b.forEach(function(a,b){S.hasOwnProperty(a)?f[b]=S[a]:(g.push(a),R.hasOwnProperty(a)||(R[a]=[]),R[a].push(function(){f[b]=S[a];++k;k===g.length&&e(f)}))});0===g.length&&e(f)}
|
||||||
|
function Sa(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var Ta=void 0;function U(a){for(var b="";D[a];)b+=Ta[D[a++]];return b}var Ua=void 0;function V(a){throw new Ua(a);}
|
||||||
|
function T(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var e=b.name;a||V('type "'+e+'" must have a positive integer typeid pointer');if(S.hasOwnProperty(a)){if(c.na)return;V("Cannot register type '"+e+"' twice")}S[a]=b;delete Ma[a];R.hasOwnProperty(a)&&(b=R[a],delete R[a],b.forEach(function(a){a()}))}var Va=[],W=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
||||||
|
function Wa(a){4<a&&0===--W[a].ea&&(W[a]=void 0,Va.push(a))}function Ya(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Va.length?Va.pop():W.length;W[b]={ea:1,value:a};return b}}
|
||||||
|
function Za(a,b){var c=d;if(void 0===c[a].ba){var e=c[a];c[a]=function(){c[a].ba.hasOwnProperty(arguments.length)||V("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].ba+")!");return c[a].ba[arguments.length].apply(this,arguments)};c[a].ba=[];c[a].ba[e.ha]=e}}
|
||||||
|
function $a(a,b,c){d.hasOwnProperty(a)?((void 0===c||void 0!==d[a].ba&&void 0!==d[a].ba[c])&&V("Cannot register public name '"+a+"' twice"),Za(a,a),d.hasOwnProperty(c)&&V("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),d[a].ba[c]=b):(d[a]=b,void 0!==c&&(d[a].wa=c))}
|
||||||
|
function ab(a,b,c){switch(b){case 0:return function(a){return this.fromWireType((c?E:D)[a])};case 1:return function(a){return this.fromWireType((c?F:G)[a>>1])};case 2:return function(a){return this.fromWireType((c?H:I)[a>>2])};default:throw new TypeError("Unknown integer type: "+a);}}function bb(a){a=cb(a);var b=U(a);X(a);return b}function db(a,b){var c=S[a];void 0===c&&V(b+" has unknown type "+bb(a));return c}
|
||||||
|
function eb(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}function fb(a,b){switch(b){case 2:return function(a){return this.fromWireType(qa[a>>2])};case 3:return function(a){return this.fromWireType(ra[a>>3])};default:throw new TypeError("Unknown float type: "+a);}}
|
||||||
|
function gb(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=Oa(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}function hb(a,b){for(var c=[],e=0;e<a;e++)c.push(H[(b>>2)+e]);return c}
|
||||||
|
function Y(a,b){a=U(a);if(void 0!==d["FUNCTION_TABLE_"+a])var c=d["FUNCTION_TABLE_"+a][b];else if("undefined"!==typeof FUNCTION_TABLE)c=FUNCTION_TABLE[b];else{c=d["dynCall_"+a];void 0===c&&(c=d["dynCall_"+a.replace(/f/g,"d")],void 0===c&&V("No dynCall invoker for signature: "+a));for(var e=[],f=1;f<a.length;++f)e.push("a"+f);f="return function "+("dynCall_"+a+"_"+b)+"("+e.join(", ")+") {\n";f+=" return dynCall(rawFunction"+(e.length?", ":"")+e.join(", ")+");\n";c=(new Function("dynCall","rawFunction",
|
||||||
|
f+"};\n"))(c,b)}"function"!==typeof c&&V("unknown function pointer with signature "+a+": "+b);return c}var ib=void 0;function jb(a,b){function c(a){f[a]||S[a]||(Ma[a]?Ma[a].forEach(c):(e.push(a),f[a]=!0))}var e=[],f={};b.forEach(c);throw new ib(a+": "+e.map(bb).join([", "]));}
|
||||||
|
function kb(a,b,c){switch(b){case 0:return c?function(a){return E[a]}:function(a){return D[a]};case 1:return c?function(a){return F[a>>1]}:function(a){return G[a>>1]};case 2:return c?function(a){return H[a>>2]}:function(a){return I[a>>2]};default:throw new TypeError("Unknown integer type: "+a);}}function lb(){return E.length}Qa=d.InternalError=Pa("InternalError");for(var mb=Array(256),nb=0;256>nb;++nb)mb[nb]=String.fromCharCode(nb);Ta=mb;Ua=d.BindingError=Pa("BindingError");
|
||||||
|
d.count_emval_handles=function(){for(var a=0,b=5;b<W.length;++b)void 0!==W[b]&&++a;return a};d.get_first_emval=function(){for(var a=5;a<W.length;++a)if(void 0!==W[a])return W[a];return null};ib=d.UnboundTypeError=Pa("UnboundTypeError");
|
||||||
|
var Fa={j:function(a){return ob(a)},g:function(a){"uncaught_exception"in pb?pb.ga++:pb.ga=1;throw a;},q:function(){return Ia.apply(null,arguments)},r:function(){return Ja.apply(null,arguments)},p:function(){return Ka.apply(null,arguments)},o:function(a){var b=P[a];delete P[a];var c=b.oa,e=b.pa,f=b.fa,g=f.map(function(a){return a.ma}).concat(f.map(function(a){return a.ra}));Ra([a],g,function(a){var g={};f.forEach(function(b,c){var e=a[c],l=b.ka,p=b.la,h=a[c+f.length],k=b.qa,ea=b.sa;g[b.ia]={read:function(a){return e.fromWireType(l(p,
|
||||||
|
a))},write:function(a,b){var c=[];k(ea,a,h.toWireType(c,b));La(c)}}});return[{name:b.name,fromWireType:function(a){var b={},c;for(c in g)b[c]=g[c].read(a);e(a);return b},toWireType:function(a,b){for(var f in g)if(!(f in b))throw new TypeError("Missing field");var h=c();for(f in g)g[f].write(h,b[f]);null!==a&&a.push(e,h);return h},argPackAdvance:8,readValueFromPointer:Q,aa:e}]})},n:function(a,b,c,e,f){var g=Sa(c);b=U(b);T(a,{name:b,fromWireType:function(a){return!!a},toWireType:function(a,b){return b?
|
||||||
|
e:f},argPackAdvance:8,readValueFromPointer:function(a){if(1===c)var e=E;else if(2===c)e=F;else if(4===c)e=H;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(e[a>>g])},aa:null})},m:function(a,b){b=U(b);T(a,{name:b,fromWireType:function(a){var b=W[a].value;Wa(a);return b},toWireType:function(a,b){return Ya(b)},argPackAdvance:8,readValueFromPointer:Q,aa:null})},l:function(a,b,c,e){function f(){}c=Sa(c);b=U(b);f.values={};T(a,{name:b,constructor:f,fromWireType:function(a){return this.constructor.values[a]},
|
||||||
|
toWireType:function(a,b){return b.value},argPackAdvance:8,readValueFromPointer:ab(b,c,e),aa:null});$a(b,f)},k:function(a,b,c){var e=db(a,"enum");b=U(b);a=e.constructor;e=Object.create(e.constructor.prototype,{value:{value:c},constructor:{value:Oa(e.name+"_"+b,function(){})}});a.values[c]=e;a[b]=e},i:function(a,b,c){c=Sa(c);b=U(b);T(a,{name:b,fromWireType:function(a){return a},toWireType:function(a,b){if("number"!==typeof b&&"boolean"!==typeof b)throw new TypeError('Cannot convert "'+eb(b)+'" to '+
|
||||||
|
this.name);return b},argPackAdvance:8,readValueFromPointer:fb(b,c),aa:null})},e:function(a,b,c,e,f,g){var k=hb(b,c);a=U(a);f=Y(e,f);$a(a,function(){jb("Cannot call "+a+" due to unbound types",k)},b-1);Ra([],k,function(c){var e=[c[0],null].concat(c.slice(1)),l=c=a,k=f,h=e.length;2>h&&V("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var sa=null!==e[1]&&!1,da=!1,m=1;m<e.length;++m)if(null!==e[m]&&void 0===e[m].aa){da=!0;break}var ea="void"!==e[0].name,J="",L="";
|
||||||
|
for(m=0;m<h-2;++m)J+=(0!==m?", ":"")+"arg"+m,L+=(0!==m?", ":"")+"arg"+m+"Wired";l="return function "+Na(l)+"("+J+") {\nif (arguments.length !== "+(h-2)+") {\nthrowBindingError('function "+l+" called with ' + arguments.length + ' arguments, expected "+(h-2)+" args!');\n}\n";da&&(l+="var destructors = [];\n");var Xa=da?"destructors":"null";J="throwBindingError invoker fn runDestructors retType classParam".split(" ");k=[V,k,g,La,e[0],e[1]];sa&&(l+="var thisWired = classParam.toWireType("+Xa+", this);\n");
|
||||||
|
for(m=0;m<h-2;++m)l+="var arg"+m+"Wired = argType"+m+".toWireType("+Xa+", arg"+m+"); // "+e[m+2].name+"\n",J.push("argType"+m),k.push(e[m+2]);sa&&(L="thisWired"+(0<L.length?", ":"")+L);l+=(ea?"var rv = ":"")+"invoker(fn"+(0<L.length?", ":"")+L+");\n";if(da)l+="runDestructors(destructors);\n";else for(m=sa?1:2;m<e.length;++m)h=1===m?"thisWired":"arg"+(m-2)+"Wired",null!==e[m].aa&&(l+=h+"_dtor("+h+"); // "+e[m].name+"\n",J.push(h+"_dtor"),k.push(e[m].aa));ea&&(l+="var ret = retType.fromWireType(rv);\nreturn ret;\n");
|
||||||
|
J.push(l+"}\n");e=gb(J).apply(null,k);m=b-1;if(!d.hasOwnProperty(c))throw new Qa("Replacing nonexistant public symbol");void 0!==d[c].ba&&void 0!==m?d[c].ba[m]=e:(d[c]=e,d[c].ha=m);return[]})},c:function(a,b,c,e,f){function g(a){return a}b=U(b);-1===f&&(f=4294967295);var k=Sa(c);if(0===e){var h=32-8*c;g=function(a){return a<<h>>>h}}var p=-1!=b.indexOf("unsigned");T(a,{name:b,fromWireType:g,toWireType:function(a,c){if("number"!==typeof c&&"boolean"!==typeof c)throw new TypeError('Cannot convert "'+
|
||||||
|
eb(c)+'" to '+this.name);if(c<e||c>f)throw new TypeError('Passing a number "'+eb(c)+'" from JS side to C/C++ side to an argument of type "'+b+'", which is outside the valid range ['+e+", "+f+"]!");return p?c>>>0:c|0},argPackAdvance:8,readValueFromPointer:kb(b,k,0!==e),aa:null})},b:function(a,b,c){function e(a){a>>=2;var b=I;return new f(b.buffer,b[a+1],b[a])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=U(c);T(a,{name:c,fromWireType:e,argPackAdvance:8,
|
||||||
|
readValueFromPointer:e},{na:!0})},h:function(a,b){b=U(b);var c="std::string"===b;T(a,{name:b,fromWireType:function(a){var b=I[a>>2];if(c){var e=D[a+4+b],k=0;0!=e&&(k=e,D[a+4+b]=0);var h=a+4;for(e=0;e<=b;++e){var p=a+4+e;if(0==D[p]){h=h?na(D,h,void 0):"";if(void 0===l)var l=h;else l+=String.fromCharCode(0),l+=h;h=p+1}}0!=k&&(D[a+4+b]=k)}else{l=Array(b);for(e=0;e<b;++e)l[e]=String.fromCharCode(D[a+4+e]);l=l.join("")}X(a);return l},toWireType:function(a,b){b instanceof ArrayBuffer&&(b=new Uint8Array(b));
|
||||||
|
var e="string"===typeof b;e||b instanceof Uint8Array||b instanceof Uint8ClampedArray||b instanceof Int8Array||V("Cannot pass non-string to std::string");var f=(c&&e?function(){for(var a=0,c=0;c<b.length;++c){var e=b.charCodeAt(c);55296<=e&&57343>=e&&(e=65536+((e&1023)<<10)|b.charCodeAt(++c)&1023);127>=e?++a:a=2047>=e?a+2:65535>=e?a+3:a+4}return a}:function(){return b.length})(),h=ob(4+f+1);I[h>>2]=f;if(c&&e)oa(b,h+4,f+1);else if(e)for(e=0;e<f;++e){var p=b.charCodeAt(e);255<p&&(X(h),V("String has UTF-16 code units that do not fit in 8 bits"));
|
||||||
|
D[h+4+e]=p}else for(e=0;e<f;++e)D[h+4+e]=b[e];null!==a&&a.push(X,h);return h},argPackAdvance:8,readValueFromPointer:Q,aa:function(a){X(a)}})},C:function(a,b,c){c=U(c);if(2===b){var e=function(){return G};var f=1}else 4===b&&(e=function(){return I},f=2);T(a,{name:c,fromWireType:function(a){for(var b=e(),c=I[a>>2],g=Array(c),l=a+4>>f,w=0;w<c;++w)g[w]=String.fromCharCode(b[l+w]);X(a);return g.join("")},toWireType:function(a,c){var g=c.length,k=ob(4+g*b),l=e();I[k>>2]=g;for(var w=k+4>>f,B=0;B<g;++B)l[w+
|
||||||
|
B]=c.charCodeAt(B);null!==a&&a.push(X,k);return k},argPackAdvance:8,readValueFromPointer:Q,aa:function(a){X(a)}})},B:function(a,b,c,e,f,g){P[a]={name:U(b),oa:Y(c,e),pa:Y(f,g),fa:[]}},d:function(a,b,c,e,f,g,k,h,p,l){P[a].fa.push({ia:U(b),ma:c,ka:Y(e,f),la:g,ra:k,qa:Y(h,p),sa:l})},A:function(a,b){b=U(b);T(a,{va:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},z:Wa,y:function(a){4<a&&(W[a].ea+=1)},x:function(a,b){a=db(a,"_emval_take_value");a=a.readValueFromPointer(b);
|
||||||
|
return Ya(a)},__memory_base:1024,__table_base:0,f:function(){y()},w:lb,v:function(a,b,c){D.set(D.subarray(b,b+c),a)},u:function(a){if(2147418112<a)return!1;for(var b=Math.max(lb(),16777216);b<a;)536870912>=b?b=pa(2*b):b=Math.min(pa((3*b+2147483648)/4),2147418112);a:{try{C.grow(b-buffer.byteLength+65535>>16);ta(C.buffer);var c=1;break a}catch(e){}c=void 0}return c?!0:!1},t:function(a){return Math.log(a)/Math.LN10},a:y,memory:C,s:function(){},table:ka},qb=d.asm({},Fa,buffer);d.asm=qb;
|
||||||
|
var pb=d.__ZSt18uncaught_exceptionv=function(){return d.asm.D.apply(null,arguments)};d.___embind_register_native_and_builtin_types=function(){return d.asm.E.apply(null,arguments)};var cb=d.___getTypeName=function(){return d.asm.F.apply(null,arguments)},X=d._free=function(){return d.asm.G.apply(null,arguments)},ob=d._malloc=function(){return d.asm.H.apply(null,arguments)},Ga=d.globalCtors=function(){return d.asm.$.apply(null,arguments)};d.dynCall_diiii=function(){return d.asm.I.apply(null,arguments)};
|
||||||
|
d.dynCall_fii=function(){return d.asm.J.apply(null,arguments)};d.dynCall_i=function(){return d.asm.K.apply(null,arguments)};d.dynCall_ii=function(){return d.asm.L.apply(null,arguments)};d.dynCall_iidiiii=function(){return d.asm.M.apply(null,arguments)};d.dynCall_iii=function(){return d.asm.N.apply(null,arguments)};d.dynCall_iiii=function(){return d.asm.O.apply(null,arguments)};d.dynCall_iiiiii=function(){return d.asm.P.apply(null,arguments)};
|
||||||
|
d.dynCall_iiiiiii=function(){return d.asm.Q.apply(null,arguments)};d.dynCall_jiji=function(){return d.asm.R.apply(null,arguments)};d.dynCall_v=function(){return d.asm.S.apply(null,arguments)};d.dynCall_vi=function(){return d.asm.T.apply(null,arguments)};d.dynCall_vii=function(){return d.asm.U.apply(null,arguments)};d.dynCall_viif=function(){return d.asm.V.apply(null,arguments)};d.dynCall_viii=function(){return d.asm.W.apply(null,arguments)};d.dynCall_viiii=function(){return d.asm.X.apply(null,arguments)};
|
||||||
|
d.dynCall_viiiii=function(){return d.asm.Y.apply(null,arguments)};d.dynCall_viiiiii=function(){return d.asm.Z.apply(null,arguments)};d.dynCall_viiiiiiiii=function(){return d.asm._.apply(null,arguments)};d.asm=qb;var Z;d.then=function(a){if(Z)a(d);else{var b=d.onRuntimeInitialized;d.onRuntimeInitialized=function(){b&&b();a(d)}}return d};N=function rb(){Z||sb();Z||(N=rb)};
|
||||||
|
function sb(){function a(){if(!Z&&(Z=!0,!la)){K(wa);K(xa);if(d.onRuntimeInitialized)d.onRuntimeInitialized();if(d.postRun)for("function"==typeof d.postRun&&(d.postRun=[d.postRun]);d.postRun.length;){var a=d.postRun.shift();ya.unshift(a)}K(ya)}}if(!(0<M)){if(d.preRun)for("function"==typeof d.preRun&&(d.preRun=[d.preRun]);d.preRun.length;)za();K(va);0<M||(d.setStatus?(d.setStatus("Running..."),setTimeout(function(){setTimeout(function(){d.setStatus("")},1);a()},1)):a())}}d.run=sb;
|
||||||
|
if(d.preInit)for("function"==typeof d.preInit&&(d.preInit=[d.preInit]);0<d.preInit.length;)d.preInit.pop()();sb();
|
||||||
|
|
||||||
|
|
||||||
|
return webp_enc
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
if (typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = webp_enc;
|
||||||
|
else if (typeof define === 'function' && define['amd'])
|
||||||
|
define([], function() { return webp_enc; });
|
||||||
|
else if (typeof exports === 'object')
|
||||||
|
exports["webp_enc"] = webp_enc;
|
||||||
|
|
BIN
codecs/webp_enc/webp_enc.wasm
Normal file
BIN
codecs/webp_enc/webp_enc.wasm
Normal file
Binary file not shown.
74
config/add-css-types.js
Normal file
74
config/add-css-types.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
const DtsCreator = require('typed-css-modules');
|
||||||
|
const chokidar = require('chokidar');
|
||||||
|
const util = require('util');
|
||||||
|
const sass = require('node-sass');
|
||||||
|
|
||||||
|
const sassRender = util.promisify(sass.render);
|
||||||
|
|
||||||
|
async function sassToCss(path) {
|
||||||
|
const result = await sassRender({ file: path });
|
||||||
|
return result.css;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Opts
|
||||||
|
* @property {boolean} watch Watch for changes
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Create typing files for CSS & SCSS.
|
||||||
|
*
|
||||||
|
* @param {string[]} rootPaths Paths to search within
|
||||||
|
* @param {Opts} [opts={}] Options.
|
||||||
|
*/
|
||||||
|
function addCssTypes(rootPaths, opts = {}) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const { watch = false } = opts;
|
||||||
|
|
||||||
|
const paths = [];
|
||||||
|
const preReadyPromises = [];
|
||||||
|
let ready = false;
|
||||||
|
|
||||||
|
for (const rootPath of rootPaths) {
|
||||||
|
// Look for scss & css in each path.
|
||||||
|
paths.push(rootPath + '/**/*.scss');
|
||||||
|
paths.push(rootPath + '/**/*.css');
|
||||||
|
}
|
||||||
|
|
||||||
|
// For simplicity, the watcher is used even if we're not watching.
|
||||||
|
// If we're not watching, we stop the watcher after the initial files are found.
|
||||||
|
const watcher = chokidar.watch(paths, {
|
||||||
|
// Avoid processing already-processed files.
|
||||||
|
ignored: '*.d.*',
|
||||||
|
// Without this, travis and netlify builds never complete. I'm not sure why, but it might be
|
||||||
|
// related to https://github.com/paulmillr/chokidar/pull/758
|
||||||
|
persistent: watch,
|
||||||
|
});
|
||||||
|
|
||||||
|
function change(path) {
|
||||||
|
const promise = (async function() {
|
||||||
|
const creator = new DtsCreator({ camelCase: true });
|
||||||
|
const result = path.endsWith('.scss') ?
|
||||||
|
await creator.create(path, await sassToCss(path)) :
|
||||||
|
await creator.create(path);
|
||||||
|
|
||||||
|
await result.writeFile();
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (!ready) preReadyPromises.push(promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
watcher.on('change', change);
|
||||||
|
watcher.on('add', change);
|
||||||
|
|
||||||
|
// 'ready' is when events have been fired for file discovery.
|
||||||
|
watcher.on('ready', () => {
|
||||||
|
ready = true;
|
||||||
|
// Wait for the current set of processing to finish.
|
||||||
|
Promise.all(preReadyPromises).then(resolve);
|
||||||
|
// And if we're not watching, close the watcher.
|
||||||
|
if (!watch) watcher.close();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = addCssTypes;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user