forked from external-repos/squoosh
Compare commits
434 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ce7bcea5f | ||
|
|
a547491146 | ||
|
|
6e427f9208 | ||
|
|
0d35fbd349 | ||
|
|
4e901c714c | ||
|
|
b74788e036 | ||
|
|
14c3d190e9 | ||
|
|
eeaa19589e | ||
|
|
35b8c56f1a | ||
|
|
816d1f92fd | ||
|
|
4091f2efec | ||
|
|
821d14c6ab | ||
|
|
a72ca46531 | ||
|
|
fafcf97f0c | ||
|
|
d526877147 | ||
|
|
0ed7ef842f | ||
|
|
de4eb9c8f7 | ||
|
|
16a53caa48 | ||
|
|
3d4c62fede | ||
|
|
ce7be359c0 | ||
|
|
3f2dd66726 | ||
|
|
9198f748b8 | ||
|
|
a726adf0e8 | ||
|
|
04580b0bcb | ||
|
|
a040c47047 | ||
|
|
2427763a14 | ||
|
|
c582c54922 | ||
|
|
9ae27c1887 | ||
|
|
bf95eb39c2 | ||
|
|
011c0346c1 | ||
|
|
9b36c3f9af | ||
|
|
490fe2aace | ||
|
|
48efb4ddeb | ||
|
|
0977bd94d3 | ||
|
|
d5f12a8c61 | ||
|
|
fb867dcdaa | ||
|
|
f038c1bd7d | ||
|
|
b37cc0784f | ||
|
|
ff40000473 | ||
|
|
7232524f4d | ||
|
|
bf683cdf59 | ||
|
|
f848a9384e | ||
|
|
d4d0db6c49 | ||
|
|
0719abff27 | ||
|
|
2c561687af | ||
|
|
cd20082e5d | ||
|
|
8262c79bb6 | ||
|
|
ef176d7565 | ||
|
|
3b0b7dbdb1 | ||
|
|
cc9a887386 | ||
|
|
71ca1ab0ca | ||
|
|
f5d9535fd2 | ||
|
|
cea6a61366 | ||
|
|
192cfc62ee | ||
|
|
fe21322b2b | ||
|
|
d953822d19 | ||
|
|
021b082884 | ||
|
|
ad5002c79c | ||
|
|
883bb92e48 | ||
|
|
79efd0d32e | ||
|
|
99741d665d | ||
|
|
b38765b4e6 | ||
|
|
a11ac15008 | ||
|
|
4f6d21199c | ||
|
|
fb7e00067f | ||
|
|
a2121ec47b | ||
|
|
d4056026fb | ||
|
|
d12b040bd3 | ||
|
|
149ebf5a67 | ||
|
|
d8297aad10 | ||
|
|
0e84a5b5f7 | ||
|
|
187a5bed01 | ||
|
|
07a288398e | ||
|
|
dbb31a1add | ||
|
|
6e58e8edb0 | ||
|
|
955079b18f | ||
|
|
f6f70c590e | ||
|
|
55c4aa51ac | ||
|
|
aea316c604 | ||
|
|
d604e94ad2 | ||
|
|
61de471e52 | ||
|
|
955b2ac1ba | ||
|
|
3d225966c5 | ||
|
|
851da25302 | ||
|
|
32e3528666 | ||
|
|
1e52837931 | ||
|
|
5bc80e66ec | ||
|
|
b1f50cd27c | ||
|
|
3d136016e2 | ||
|
|
14a715e952 | ||
|
|
324b04d398 | ||
|
|
eb76fbc4bc | ||
|
|
1d292468b0 | ||
|
|
828f9a5eeb | ||
|
|
5595525c8a | ||
|
|
5e14444b13 | ||
|
|
3d58c616af | ||
|
|
d7090042a6 | ||
|
|
be3249bf2f | ||
|
|
1b59c3f47a | ||
|
|
9a37cc7959 | ||
|
|
ffb9135a7a | ||
|
|
5707eeff41 | ||
|
|
a18ed360eb | ||
|
|
011d0c2099 | ||
|
|
89105bbb22 | ||
|
|
5f7c619413 | ||
|
|
3ec7d4db16 | ||
|
|
8ef8cef522 | ||
|
|
f6431d8147 | ||
|
|
be037754ce | ||
|
|
32107124e6 | ||
|
|
1af5d1fa7b | ||
|
|
1ec3b36858 | ||
|
|
0cb454295b | ||
|
|
2d4c1906e1 | ||
|
|
08adfba8be | ||
|
|
c036866478 | ||
|
|
5df04f6419 | ||
|
|
cf570a4d3f | ||
|
|
2aa691339c | ||
|
|
9fcb4a4c55 | ||
|
|
18e3d77aef | ||
|
|
6a4982bf4c | ||
|
|
c7b998a877 | ||
|
|
e5b2030666 | ||
|
|
0e09d0b33f | ||
|
|
ed03a37fb8 | ||
|
|
2bc4ab8fd6 | ||
|
|
2037fe8964 | ||
|
|
d07c57ecaa | ||
|
|
e7d55bf903 | ||
|
|
687cf5aae2 | ||
|
|
d63823d196 | ||
|
|
7d111b6a43 | ||
|
|
426f31e548 | ||
|
|
dd0adba6b1 | ||
|
|
30445927ea | ||
|
|
31b263fc27 | ||
|
|
fc590918ed | ||
|
|
8dc532eb09 | ||
|
|
41f4f7778f | ||
|
|
9278b8a1ab | ||
|
|
dc86b33634 | ||
|
|
e4832644f2 | ||
|
|
c4783b03df | ||
|
|
8f9c0ff0e7 | ||
|
|
40c81ef782 | ||
|
|
397193a5f5 | ||
|
|
f91c7a267d | ||
|
|
99f2286a73 | ||
|
|
f414092ea9 | ||
|
|
c683dfaaed | ||
|
|
12fb647fde | ||
|
|
2ee1dfa867 | ||
|
|
fa331586d7 | ||
|
|
4192c607f1 | ||
|
|
128096afd9 | ||
|
|
58661078e2 | ||
|
|
cbfa503fcb | ||
|
|
96b6dc8e6e | ||
|
|
4033d1c965 | ||
|
|
f779e13bc8 | ||
|
|
2f00fe2b1b | ||
|
|
118885cd26 | ||
|
|
1dc24a5c36 | ||
|
|
8eb29bd792 | ||
|
|
83db97856c | ||
|
|
925e549466 | ||
|
|
e0895ca074 | ||
|
|
af80643809 | ||
|
|
a6f3bb596a | ||
|
|
c9bc01b111 | ||
|
|
1aba7b51ee | ||
|
|
c5bbce6a1d | ||
|
|
b0a7b21b0b | ||
|
|
8dfe35aa77 | ||
|
|
1a891072c0 | ||
|
|
720cb98872 | ||
|
|
e8b1db5da6 | ||
|
|
be41088fb8 | ||
|
|
558ee0e5ba | ||
|
|
114d6869ea | ||
|
|
4e1dcb819c | ||
|
|
c36f4bebb8 | ||
|
|
c04bb54f0d | ||
|
|
4890c56abb | ||
|
|
392aced394 | ||
|
|
8bcaeb2f78 | ||
|
|
c417bd0a7a | ||
|
|
eb8204d69b | ||
|
|
c9b83a8716 | ||
|
|
bdbb8b81ac | ||
|
|
ba5640835f | ||
|
|
88106a09f5 | ||
|
|
52ca417d3a | ||
|
|
1527b1431c | ||
|
|
189d196b2b | ||
|
|
cf66f2a69d | ||
|
|
d3c1877e76 | ||
|
|
bb036df1fc | ||
|
|
2e3361af79 | ||
|
|
4dd2296eaf | ||
|
|
25754b91b7 | ||
|
|
875c24525b | ||
|
|
50ed5febd3 | ||
|
|
10c5082499 | ||
|
|
f0fb891498 | ||
|
|
b9b6e57581 | ||
|
|
ff9dea465f | ||
|
|
912c1fac08 | ||
|
|
ad0d46de3e | ||
|
|
efc89efba5 | ||
|
|
8ed50d8f0c | ||
|
|
b50402e3b3 | ||
|
|
df65f1a112 | ||
|
|
58c09ff740 | ||
|
|
33c0c3b034 | ||
|
|
e900d33092 | ||
|
|
650c662ffa | ||
|
|
2bf0b904cd | ||
|
|
9d890a8fd6 | ||
|
|
914bff41c6 | ||
|
|
86c4271844 | ||
|
|
56beb6786a | ||
|
|
ef77da9e96 | ||
|
|
42cfbe11a1 | ||
|
|
0874a3ba52 | ||
|
|
7f6ee3204f | ||
|
|
37d778e4da | ||
|
|
8f24c9b5ce | ||
|
|
9d3401762e | ||
|
|
a783de618d | ||
|
|
659d2b8277 | ||
|
|
934ab9065a | ||
|
|
029c2ebb83 | ||
|
|
dc40f84a65 | ||
|
|
2c0dd363d4 | ||
|
|
e6916575b7 | ||
|
|
1c7486056d | ||
|
|
8e8b75684d | ||
|
|
92ade727aa | ||
|
|
6117c9dd26 | ||
|
|
a3be343959 | ||
|
|
39c6be41df | ||
|
|
5603f2d6e7 | ||
|
|
0d72f652c5 | ||
|
|
7ce0c8a4fc | ||
|
|
30528c2330 | ||
|
|
b4329c5bed | ||
|
|
5845e566da | ||
|
|
5d0c856fa0 | ||
|
|
ff25dd81f8 | ||
|
|
c7d156e8d7 | ||
|
|
02532b5a31 | ||
|
|
c5c95254f0 | ||
|
|
dfa7695a97 | ||
|
|
7095ed2f7a | ||
|
|
61a66c4ed4 | ||
|
|
c6188c8846 | ||
|
|
ae583f7581 | ||
|
|
22a948267c | ||
|
|
35f5ad6e2b | ||
|
|
34d3c13b5d | ||
|
|
dba8f097d3 | ||
|
|
36293d756b | ||
|
|
ad07584730 | ||
|
|
e260994600 | ||
|
|
f55e4cf9a8 | ||
|
|
a1ea6223ac | ||
|
|
e7e205c326 | ||
|
|
990a43b733 | ||
|
|
1a40c57876 | ||
|
|
e8afe408f1 | ||
|
|
9352569852 | ||
|
|
10d648c28d | ||
|
|
1e64e52298 | ||
|
|
733b470f1f | ||
|
|
e72dcd6c6e | ||
|
|
62b4d39128 | ||
|
|
d338e8a048 | ||
|
|
f2a947df9e | ||
|
|
3ec55b0a03 | ||
|
|
3338808f17 | ||
|
|
5bdba43b33 | ||
|
|
c63120d4ce | ||
|
|
405dd1cdfa | ||
|
|
b958d46086 | ||
|
|
c3d05e0e2d | ||
|
|
0c848a33ad | ||
|
|
57357f5c8d | ||
|
|
6bfd1f2c29 | ||
|
|
8b20aa5f14 | ||
|
|
81e171e684 | ||
|
|
7b4dbbfe2d | ||
|
|
a972dfdeed | ||
|
|
f190ca6069 | ||
|
|
adb2f7ed50 | ||
|
|
d6de741ddc | ||
|
|
b5f708a1e6 | ||
|
|
15248bf85a | ||
|
|
5d691af8a1 | ||
|
|
722f1c806c | ||
|
|
522449adc1 | ||
|
|
07b4e53718 | ||
|
|
c6e6042726 | ||
|
|
94b9d08719 | ||
|
|
064b152e2a | ||
|
|
9de95f74fe | ||
|
|
21a8f62dcc | ||
|
|
9062a75541 | ||
|
|
fec826b106 | ||
|
|
12889d9d50 | ||
|
|
a19e97b2ed | ||
|
|
5765ea5aa4 | ||
|
|
c11e99c811 | ||
|
|
76d8a636af | ||
|
|
5758e5db9a | ||
|
|
4e4778397f | ||
|
|
aff137218d | ||
|
|
fa5bd3d1c6 | ||
|
|
d1533d66a2 | ||
|
|
83b52cabc1 | ||
|
|
c832287fa6 | ||
|
|
ed55660c88 | ||
|
|
33d60658cd | ||
|
|
5af8810e0b | ||
|
|
33c3fd3278 | ||
|
|
f5be882b10 | ||
|
|
2a8a2f2952 | ||
|
|
200e01132c | ||
|
|
fe6cc5c503 | ||
|
|
d25d01c705 | ||
|
|
7699f75b45 | ||
|
|
4976ad8481 | ||
|
|
60cef4cb3a | ||
|
|
6b8d2e058c | ||
|
|
004e18036b | ||
|
|
f051dcb07c | ||
|
|
4e5bb64565 | ||
|
|
89508c9385 | ||
|
|
951e0dc93a | ||
|
|
c35c285273 | ||
|
|
45fe4d2917 | ||
|
|
ef31e5cbd1 | ||
|
|
d8bd12fc6a | ||
|
|
3abc770053 | ||
|
|
a3b341f813 | ||
|
|
58a6abffbb | ||
|
|
869d3f7732 | ||
|
|
618a4d777b | ||
|
|
7266c94f52 | ||
|
|
d15dba7d20 | ||
|
|
0ded493489 | ||
|
|
990018f758 | ||
|
|
4f4eaf01b7 | ||
|
|
19fab33d3c | ||
|
|
6f19d027b4 | ||
|
|
73499d4a27 | ||
|
|
8581785869 | ||
|
|
198ad0fb1b | ||
|
|
f0d341aefa | ||
|
|
69e62339e6 | ||
|
|
195762f64f | ||
|
|
a951096aaa | ||
|
|
24d241564e | ||
|
|
3d1ecc1215 | ||
|
|
25fb1a9c80 | ||
|
|
3ae1cf86f5 | ||
|
|
a699a5c4dc | ||
|
|
613401c541 | ||
|
|
f450373e3f | ||
|
|
750872aca6 | ||
|
|
beaabe47dc | ||
|
|
8f7369068c | ||
|
|
10bfd60e20 | ||
|
|
7f08348509 | ||
|
|
f77ddac652 | ||
|
|
13631f1cfc | ||
|
|
f11e692d58 | ||
|
|
f0221b626d | ||
|
|
10c5ed0495 | ||
|
|
d945c79796 | ||
|
|
30b628c1b9 | ||
|
|
6ebf94d1b6 | ||
|
|
a229662bed | ||
|
|
e995b445ef | ||
|
|
6da590c7d0 | ||
|
|
56e10b3aa2 | ||
|
|
67df305594 | ||
|
|
106d733fec | ||
|
|
67c64d4df3 | ||
|
|
75d571cb6c | ||
|
|
af954bd9e0 | ||
|
|
612cee0011 | ||
|
|
911ca32c35 | ||
|
|
49cb8b268c | ||
|
|
4946268ae2 | ||
|
|
4487da9e9e | ||
|
|
09f65d0cd7 | ||
|
|
261b3ad013 | ||
|
|
1b886aa4e2 | ||
|
|
1d5fd98a3e | ||
|
|
588d5ad44e | ||
|
|
139b635eed | ||
|
|
516c0aa8e7 | ||
|
|
273b4211c9 | ||
|
|
ef920ac6ba | ||
|
|
f445a5dcbe | ||
|
|
c8dc88f8a1 | ||
|
|
1d7b6ab13e | ||
|
|
1e700cd7c3 | ||
|
|
01c04d4a72 | ||
|
|
df45b996d1 | ||
|
|
c9a271f57a | ||
|
|
c37f798565 | ||
|
|
e9b9993189 | ||
|
|
96b1ec2356 | ||
|
|
e5d254ad80 | ||
|
|
b1b3c8c461 | ||
|
|
1f2f5d1c61 | ||
|
|
12a719f05a | ||
|
|
28c7b7aa94 | ||
|
|
6e3e6af70e | ||
|
|
31118daa18 | ||
|
|
47fb7f9f71 | ||
|
|
3b07862efb | ||
|
|
f0eb79f2f1 | ||
|
|
ebdb00f50d | ||
|
|
4b6334a212 | ||
|
|
483daa0493 | ||
|
|
0b4a673b13 | ||
|
|
8c56d16aea | ||
|
|
773208d76e |
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/codecs/**/*.js linguist-generated=true
|
||||||
|
/codecs/*/pkg*/*.d.ts linguist-generated=true
|
||||||
22
.github/workflows/node.js.yml
vendored
Normal file
22
.github/workflows/node.js.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Node.js CI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- id: nvmrc
|
||||||
|
uses: browniebroke/read-nvmrc-action@v1
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: '${{ steps.nvmrc.outputs.node_version }}'
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build
|
||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,6 +1,12 @@
|
|||||||
|
.tmp
|
||||||
node_modules
|
node_modules
|
||||||
/build
|
|
||||||
/*.log
|
|
||||||
*.scss.d.ts
|
*.scss.d.ts
|
||||||
*.css.d.ts
|
*.css.d.ts
|
||||||
|
build
|
||||||
*.o
|
*.o
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Auto-generated by lib/feature-plugin.js
|
||||||
|
src/features-worker/index.ts
|
||||||
|
src/client/lazy-app/worker-bridge/meta.ts
|
||||||
|
src/client/lazy-app/feature-meta/index.ts
|
||||||
|
|||||||
12
.prettierignore
Normal file
12
.prettierignore
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
codecs
|
||||||
|
.tmp
|
||||||
|
node_modules
|
||||||
|
*.scss.d.ts
|
||||||
|
*.css.d.ts
|
||||||
|
build
|
||||||
|
*.o
|
||||||
|
|
||||||
|
# Auto-generated by lib/feature-plugin.js
|
||||||
|
src/features-worker/index.ts
|
||||||
|
src/client/lazy-app/worker-bridge/meta.ts
|
||||||
|
src/client/lazy-app/feature-meta/index.ts
|
||||||
4
.prettierrc.json
Normal file
4
.prettierrc.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all"
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
language: node_js
|
|
||||||
cache: npm
|
|
||||||
script: npm run build
|
|
||||||
after_success: npm run sizereport
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- windows
|
|
||||||
40
README.md
40
README.md
@@ -1,32 +1,42 @@
|
|||||||
# [Squoosh]!
|
# [Squoosh]!
|
||||||
|
|
||||||
[Squoosh] is an image compression web app that allows you to dive into the advanced options provided
|
[Squoosh] is an image compression web app that reduces image sizes through numerous formats.
|
||||||
by various image compressors.
|
|
||||||
|
# API & CLI
|
||||||
|
|
||||||
|
Squoosh has [an API](https://github.com/GoogleChromeLabs/squoosh/tree/dev/libsquoosh) and [a CLI](https://github.com/GoogleChromeLabs/squoosh/tree/dev/cli) to compress many images at once.
|
||||||
|
|
||||||
# Privacy
|
# Privacy
|
||||||
|
|
||||||
Google Analytics is used to record the following:
|
Squoosh does not send your image to a server. All image compression processes locally.
|
||||||
|
|
||||||
* [Basic visit data](https://support.google.com/analytics/answer/6004245?ref_topic=2919631).
|
However, Squoosh utilizes Google Analytics to collect the following:
|
||||||
* Before and after image size once an image is downloaded. These values are rounded to the nearest
|
|
||||||
kilobyte.
|
|
||||||
* If install is available, when Squoosh is installed, and what method was used to install Squoosh.
|
|
||||||
|
|
||||||
Image compression is handled locally; no additional data is sent to the server.
|
- [Basic visitor data](https://support.google.com/analytics/answer/6004245?ref_topic=2919631).
|
||||||
|
- The before and after image size value.
|
||||||
|
- If Squoosh PWA, the type of Squoosh installation.
|
||||||
|
- If Squoosh PWA, the installation time and date.
|
||||||
|
|
||||||
# Building locally
|
# Developing
|
||||||
|
|
||||||
Clone the repo, and:
|
To develop for Squoosh:
|
||||||
|
|
||||||
|
1. Clone the repository
|
||||||
|
1. To install node packages, run:
|
||||||
```sh
|
```sh
|
||||||
npm install
|
npm install
|
||||||
|
```
|
||||||
|
1. Then build the app by running:
|
||||||
|
```sh
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
1. After building, start the development server by running:
|
||||||
You can run the development server with:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm start
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
[Squoosh]: https://squoosh.app
|
# Contributing
|
||||||
|
|
||||||
|
Squoosh is an open-source project that appreciates all community involvement. To contribute to the project, follow the [contribute guide](/CONTRIBUTING.md).
|
||||||
|
|
||||||
|
[squoosh]: https://squoosh.app
|
||||||
|
|||||||
23
_headers.ejs
23
_headers.ejs
@@ -1,23 +0,0 @@
|
|||||||
# 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
|
|
||||||
|
|
||||||
# COOP+COEP for WebAssembly threads.
|
|
||||||
/*
|
|
||||||
Cross-Origin-Embedder-Policy: require-corp
|
|
||||||
Cross-Origin-Opener-Policy: same-origin
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/index.html / 301
|
|
||||||
/* /index.html 301
|
|
||||||
3
cli/.gitignore
vendored
Normal file
3
cli/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
build
|
||||||
|
.DS_Store
|
||||||
1
cli/.npmignore
Normal file
1
cli/.npmignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules
|
||||||
0
cli/.npmrc
Normal file
0
cli/.npmrc
Normal file
59
cli/README.md
Normal file
59
cli/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Squoosh CLI
|
||||||
|
|
||||||
|
Squoosh CLI is an _experimental_ way to run all the codecs you know from the [Squoosh] web app on your command line using WebAssembly. The Squoosh CLI uses a worker pool to parallelize processing images. This way you can apply the same codec to many images at once.
|
||||||
|
|
||||||
|
Squoosh CLI is currently not the fastest image compression tool in town and doesn’t aim to be. It is, however, fast enough to compress many images sufficiently quick at once.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The Squoosh CLI can be used straight from the command line without installing using `npx`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npx @squoosh/cli <options...>
|
||||||
|
```
|
||||||
|
|
||||||
|
Of course, you can also install the Squoosh CLI:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm i -g @squoosh/cli
|
||||||
|
$ squoosh-cli <options...>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage: squoosh-cli [options] <files...>
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-V, --version output the version number
|
||||||
|
-d, --output-dir <dir> Output directory (default: ".")
|
||||||
|
-s, --suffix <suffix> Append suffix to output files (default: "")
|
||||||
|
--max-optimizer-rounds <rounds> Maximum number of compressions to use for auto optimizations (default: "6")
|
||||||
|
--optimizer-butteraugli-target <butteraugli distance> Target Butteraugli distance for auto optimizer (default: "1.4")
|
||||||
|
--resize [config] Resize the image before compressing
|
||||||
|
--quant [config] Reduce the number of colors used (aka. paletting)
|
||||||
|
--rotate [config] Rotate image
|
||||||
|
--mozjpeg [config] Use MozJPEG to generate a .jpg file with the given configuration
|
||||||
|
--webp [config] Use WebP to generate a .webp file with the given configuration
|
||||||
|
--avif [config] Use AVIF to generate a .avif file with the given configuration
|
||||||
|
--jxl [config] Use JPEG-XL to generate a .jxl file with the given configuration
|
||||||
|
--wp2 [config] Use WebP2 to generate a .wp2 file with the given configuration
|
||||||
|
--oxipng [config] Use OxiPNG to generate a .png file with the given configuration
|
||||||
|
-h, --help display help for command
|
||||||
|
```
|
||||||
|
|
||||||
|
The default values for each `config` option can be found in the [`codecs.ts`][codecs.ts] file under `defaultEncoderOptions`. Every unspecified value will use the default value specified here. _Better documentation is needed here._
|
||||||
|
|
||||||
|
## Auto optimizer
|
||||||
|
|
||||||
|
Squoosh CLI has an _experimental_ auto optimizer that compresses an image as much as possible, trying to hit a specific [Butteraugli] target value. The higher the Butteraugli target value, the more artifacts can be introduced.
|
||||||
|
|
||||||
|
You can make use of the auto optimizer by using “auto” as the config object.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npx @squoosh/cli --wp2 auto test.png
|
||||||
|
```
|
||||||
|
|
||||||
|
[squoosh]: https://squoosh.app
|
||||||
|
[codecs.ts]: https://github.com/GoogleChromeLabs/squoosh/blob/dev/libsquoosh/src/codecs.ts
|
||||||
|
[butteraugli]: https://github.com/google/butteraugli
|
||||||
613
cli/package-lock.json
generated
Normal file
613
cli/package-lock.json
generated
Normal file
@@ -0,0 +1,613 @@
|
|||||||
|
{
|
||||||
|
"name": "@squoosh/cli",
|
||||||
|
"version": "0.7.2",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "@squoosh/cli",
|
||||||
|
"version": "0.7.2",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@squoosh/lib": "^0.4.0",
|
||||||
|
"commander": "^7.2.0",
|
||||||
|
"json5": "^2.2.0",
|
||||||
|
"kleur": "^4.1.4",
|
||||||
|
"ora": "^5.4.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cli": "src/index.js",
|
||||||
|
"squoosh-cli": "src/index.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": " ^12.20.2 || ^14.13.1 || ^16.0.0 "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@squoosh/lib": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@squoosh/lib/-/lib-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-O1LyugWLZjMI4JZeZMA5vzfhfPjfMZXH5/HmVkRagP8B70wH3uoR7tjxfGNdSavey357MwL8YJDxbGwBBdHp7Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"wasm-feature-detect": "^1.2.11",
|
||||||
|
"web-streams-polyfill": "^3.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": " ^12.5.0 || ^14.0.0 || ^16.0.0 "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||||
|
},
|
||||||
|
"node_modules/bl": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer": "^5.5.0",
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"readable-stream": "^3.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/buffer": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.1.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cli-cursor": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||||
|
"dependencies": {
|
||||||
|
"restore-cursor": "^3.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cli-spinners": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/clone": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/defaults": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
|
||||||
|
"dependencies": {
|
||||||
|
"clone": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ieee754": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/is-interactive": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-unicode-supported": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/json5": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"json5": "lib/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/kleur": {
|
||||||
|
"version": "4.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
|
||||||
|
"integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/log-symbols": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"is-unicode-supported": "^0.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mimic-fn": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||||
|
},
|
||||||
|
"node_modules/onetime": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
|
"dependencies": {
|
||||||
|
"mimic-fn": "^2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ora": {
|
||||||
|
"version": "5.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.0.tgz",
|
||||||
|
"integrity": "sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg==",
|
||||||
|
"dependencies": {
|
||||||
|
"bl": "^4.1.0",
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"cli-cursor": "^3.1.0",
|
||||||
|
"cli-spinners": "^2.5.0",
|
||||||
|
"is-interactive": "^1.0.0",
|
||||||
|
"is-unicode-supported": "^0.1.0",
|
||||||
|
"log-symbols": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0",
|
||||||
|
"wcwidth": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/restore-cursor": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||||
|
"dependencies": {
|
||||||
|
"onetime": "^5.1.0",
|
||||||
|
"signal-exit": "^3.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"node_modules/signal-exit": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||||
|
},
|
||||||
|
"node_modules/string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
|
},
|
||||||
|
"node_modules/wasm-feature-detect": {
|
||||||
|
"version": "1.2.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.2.11.tgz",
|
||||||
|
"integrity": "sha512-HUqwaodrQGaZgz1lZaNioIkog9tkeEJjrM3eq4aUL04whXOVDRc/o2EGb/8kV0QX411iAYWEqq7fMBmJ6dKS6w=="
|
||||||
|
},
|
||||||
|
"node_modules/wcwidth": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
|
||||||
|
"dependencies": {
|
||||||
|
"defaults": "^1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/web-streams-polyfill": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@squoosh/lib": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@squoosh/lib/-/lib-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-O1LyugWLZjMI4JZeZMA5vzfhfPjfMZXH5/HmVkRagP8B70wH3uoR7tjxfGNdSavey357MwL8YJDxbGwBBdHp7Q==",
|
||||||
|
"requires": {
|
||||||
|
"wasm-feature-detect": "^1.2.11",
|
||||||
|
"web-streams-polyfill": "^3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||||
|
},
|
||||||
|
"bl": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||||
|
"requires": {
|
||||||
|
"buffer": "^5.5.0",
|
||||||
|
"inherits": "^2.0.4",
|
||||||
|
"readable-stream": "^3.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer": {
|
||||||
|
"version": "5.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||||
|
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||||
|
"requires": {
|
||||||
|
"base64-js": "^1.3.1",
|
||||||
|
"ieee754": "^1.1.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^4.1.0",
|
||||||
|
"supports-color": "^7.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cli-cursor": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||||
|
"requires": {
|
||||||
|
"restore-cursor": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cli-spinners": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q=="
|
||||||
|
},
|
||||||
|
"clone": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
|
||||||
|
},
|
||||||
|
"defaults": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
|
||||||
|
"requires": {
|
||||||
|
"clone": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||||
|
},
|
||||||
|
"ieee754": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"is-interactive": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="
|
||||||
|
},
|
||||||
|
"is-unicode-supported": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="
|
||||||
|
},
|
||||||
|
"json5": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kleur": {
|
||||||
|
"version": "4.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
|
||||||
|
"integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA=="
|
||||||
|
},
|
||||||
|
"log-symbols": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
||||||
|
"requires": {
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"is-unicode-supported": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mimic-fn": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||||
|
},
|
||||||
|
"onetime": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
|
"requires": {
|
||||||
|
"mimic-fn": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ora": {
|
||||||
|
"version": "5.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.0.tgz",
|
||||||
|
"integrity": "sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg==",
|
||||||
|
"requires": {
|
||||||
|
"bl": "^4.1.0",
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"cli-cursor": "^3.1.0",
|
||||||
|
"cli-spinners": "^2.5.0",
|
||||||
|
"is-interactive": "^1.0.0",
|
||||||
|
"is-unicode-supported": "^0.1.0",
|
||||||
|
"log-symbols": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0",
|
||||||
|
"wcwidth": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"restore-cursor": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||||
|
"requires": {
|
||||||
|
"onetime": "^5.1.0",
|
||||||
|
"signal-exit": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"signal-exit": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
|
},
|
||||||
|
"wasm-feature-detect": {
|
||||||
|
"version": "1.2.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.2.11.tgz",
|
||||||
|
"integrity": "sha512-HUqwaodrQGaZgz1lZaNioIkog9tkeEJjrM3eq4aUL04whXOVDRc/o2EGb/8kV0QX411iAYWEqq7fMBmJ6dKS6w=="
|
||||||
|
},
|
||||||
|
"wcwidth": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
|
||||||
|
"requires": {
|
||||||
|
"defaults": "^1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web-streams-polyfill": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
cli/package.json
Normal file
32
cli/package.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "@squoosh/cli",
|
||||||
|
"version": "0.7.2",
|
||||||
|
"description": "A CLI for Squoosh",
|
||||||
|
"public": true,
|
||||||
|
"type": "module",
|
||||||
|
"homepage": "https://github.com/GoogleChromeLabs/squoosh",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/GoogleChromeLabs/squoosh.git"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"squoosh-cli": "src/index.js",
|
||||||
|
"@squoosh/cli": "src/index.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"/src/index.js"
|
||||||
|
],
|
||||||
|
"keywords": [],
|
||||||
|
"author": "Google Chrome Developers <chromium-dev@google.com>",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": " ^12.20.2 || ^14.13.1 || ^16.0.0 "
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@squoosh/lib": "^0.4.0",
|
||||||
|
"commander": "^7.2.0",
|
||||||
|
"json5": "^2.2.0",
|
||||||
|
"kleur": "^4.1.4",
|
||||||
|
"ora": "^5.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
234
cli/src/index.js
Executable file
234
cli/src/index.js
Executable file
@@ -0,0 +1,234 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { program } from 'commander/esm.mjs';
|
||||||
|
import JSON5 from 'json5';
|
||||||
|
import path from 'path';
|
||||||
|
import { promises as fsp } from 'fs';
|
||||||
|
import ora from 'ora';
|
||||||
|
import kleur from 'kleur';
|
||||||
|
|
||||||
|
import { ImagePool, preprocessors, encoders } from '@squoosh/lib';
|
||||||
|
|
||||||
|
function clamp(v, min, max) {
|
||||||
|
if (v < min) return min;
|
||||||
|
if (v > max) return max;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
const suffix = ['B', 'KB', 'MB'];
|
||||||
|
function prettyPrintSize(size) {
|
||||||
|
const base = Math.floor(Math.log2(size) / 10);
|
||||||
|
const index = clamp(base, 0, 2);
|
||||||
|
return (size / 2 ** (10 * index)).toFixed(2) + suffix[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
function progressTracker(results) {
|
||||||
|
const spinner = ora();
|
||||||
|
const tracker = {};
|
||||||
|
tracker.spinner = spinner;
|
||||||
|
tracker.progressOffset = 0;
|
||||||
|
tracker.totalOffset = 0;
|
||||||
|
let status = '';
|
||||||
|
tracker.setStatus = (text) => {
|
||||||
|
status = text || '';
|
||||||
|
update();
|
||||||
|
};
|
||||||
|
let progress = '';
|
||||||
|
tracker.setProgress = (done, total) => {
|
||||||
|
spinner.prefixText = kleur.dim(`${done}/${total}`);
|
||||||
|
const completeness =
|
||||||
|
(tracker.progressOffset + done) / (tracker.totalOffset + total);
|
||||||
|
progress = kleur.cyan(
|
||||||
|
`▐${'▨'.repeat((completeness * 10) | 0).padEnd(10, '╌')}▌ `,
|
||||||
|
);
|
||||||
|
update();
|
||||||
|
};
|
||||||
|
function update() {
|
||||||
|
spinner.text = progress + kleur.bold(status) + getResultsText();
|
||||||
|
}
|
||||||
|
tracker.finish = (text) => {
|
||||||
|
spinner.succeed(kleur.bold(text) + getResultsText());
|
||||||
|
};
|
||||||
|
function getResultsText() {
|
||||||
|
let out = '';
|
||||||
|
for (const result of results.values()) {
|
||||||
|
out += `\n ${kleur.cyan(result.file)}: ${prettyPrintSize(result.size)}`;
|
||||||
|
for (const { outputFile, size: outputSize, infoText } of result.outputs) {
|
||||||
|
out += `\n ${kleur.dim('└')} ${kleur.cyan(
|
||||||
|
outputFile.padEnd(5),
|
||||||
|
)} → ${prettyPrintSize(outputSize)}`;
|
||||||
|
const percent = ((outputSize / result.size) * 100).toPrecision(3);
|
||||||
|
out += ` (${kleur[outputSize > result.size ? 'red' : 'green'](
|
||||||
|
percent + '%',
|
||||||
|
)})`;
|
||||||
|
if (infoText) out += kleur.yellow(infoText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out || '\n';
|
||||||
|
}
|
||||||
|
spinner.start();
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getInputFiles(paths) {
|
||||||
|
const validFiles = [];
|
||||||
|
|
||||||
|
for (const inputPath of paths) {
|
||||||
|
const files = (await fsp.lstat(inputPath)).isDirectory()
|
||||||
|
? (await fsp.readdir(inputPath, { withFileTypes: true }))
|
||||||
|
.filter((dirent) => dirent.isFile())
|
||||||
|
.map((dirent) => path.join(inputPath, dirent.name))
|
||||||
|
: [inputPath];
|
||||||
|
for (const file of files) {
|
||||||
|
try {
|
||||||
|
await fsp.stat(file);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
console.warn(
|
||||||
|
`Warning: Input file does not exist: ${path.resolve(file)}`,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validFiles.push(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return validFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processFiles(files) {
|
||||||
|
files = await getInputFiles(files);
|
||||||
|
|
||||||
|
const imagePool = new ImagePool();
|
||||||
|
|
||||||
|
const results = new Map();
|
||||||
|
const progress = progressTracker(results);
|
||||||
|
|
||||||
|
progress.setStatus('Decoding...');
|
||||||
|
progress.totalOffset = files.length;
|
||||||
|
progress.setProgress(0, files.length);
|
||||||
|
|
||||||
|
// Create output directory
|
||||||
|
await fsp.mkdir(program.opts().outputDir, { recursive: true });
|
||||||
|
|
||||||
|
let decoded = 0;
|
||||||
|
let decodedFiles = await Promise.all(
|
||||||
|
files.map(async (file) => {
|
||||||
|
const image = imagePool.ingestImage(file);
|
||||||
|
await image.decoded;
|
||||||
|
results.set(image, {
|
||||||
|
file,
|
||||||
|
size: (await image.decoded).size,
|
||||||
|
outputs: [],
|
||||||
|
});
|
||||||
|
progress.setProgress(++decoded, files.length);
|
||||||
|
return image;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const preprocessOptions = {};
|
||||||
|
|
||||||
|
for (const preprocessorName of Object.keys(preprocessors)) {
|
||||||
|
if (!program.opts()[preprocessorName]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
preprocessOptions[preprocessorName] = JSON5.parse(
|
||||||
|
program.opts()[preprocessorName],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const image of decodedFiles) {
|
||||||
|
image.preprocess(preprocessOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(decodedFiles.map((image) => image.decoded));
|
||||||
|
|
||||||
|
progress.progressOffset = decoded;
|
||||||
|
progress.setStatus(
|
||||||
|
'Encoding ' + kleur.dim(`(${imagePool.workerPool.numWorkers} threads)`),
|
||||||
|
);
|
||||||
|
progress.setProgress(0, files.length);
|
||||||
|
|
||||||
|
const jobs = [];
|
||||||
|
let jobsStarted = 0;
|
||||||
|
let jobsFinished = 0;
|
||||||
|
for (const image of decodedFiles) {
|
||||||
|
const originalFile = results.get(image).file;
|
||||||
|
|
||||||
|
const encodeOptions = {
|
||||||
|
optimizerButteraugliTarget: Number(
|
||||||
|
program.opts().optimizerButteraugliTarget,
|
||||||
|
),
|
||||||
|
maxOptimizerRounds: Number(program.opts().maxOptimizerRounds),
|
||||||
|
};
|
||||||
|
for (const encName of Object.keys(encoders)) {
|
||||||
|
if (!program.opts()[encName]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const encParam = program.opts()[encName];
|
||||||
|
const encConfig =
|
||||||
|
encParam.toLowerCase() === 'auto' ? 'auto' : JSON5.parse(encParam);
|
||||||
|
encodeOptions[encName] = encConfig;
|
||||||
|
}
|
||||||
|
jobsStarted++;
|
||||||
|
const job = image.encode(encodeOptions).then(async () => {
|
||||||
|
jobsFinished++;
|
||||||
|
const outputPath = path.join(
|
||||||
|
program.opts().outputDir,
|
||||||
|
path.basename(originalFile, path.extname(originalFile)) +
|
||||||
|
program.opts().suffix
|
||||||
|
);
|
||||||
|
for (const output of Object.values(image.encodedWith)) {
|
||||||
|
const outputFile = `${outputPath}.${(await output).extension}`;
|
||||||
|
await fsp.writeFile(outputFile, (await output).binary);
|
||||||
|
results
|
||||||
|
.get(image)
|
||||||
|
.outputs.push(Object.assign(await output, { outputFile }));
|
||||||
|
}
|
||||||
|
progress.setProgress(jobsFinished, jobsStarted);
|
||||||
|
});
|
||||||
|
jobs.push(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the progress to account for multi-format
|
||||||
|
progress.setProgress(jobsFinished, jobsStarted);
|
||||||
|
// Wait for all jobs to finish
|
||||||
|
await Promise.all(jobs);
|
||||||
|
await imagePool.close();
|
||||||
|
progress.finish('Squoosh results:');
|
||||||
|
}
|
||||||
|
|
||||||
|
program
|
||||||
|
.name('squoosh-cli')
|
||||||
|
.arguments('<files...>')
|
||||||
|
.option('-d, --output-dir <dir>', 'Output directory', '.')
|
||||||
|
.option('-s, --suffix <suffix>', 'Append suffix to output files', '')
|
||||||
|
.option(
|
||||||
|
'--max-optimizer-rounds <rounds>',
|
||||||
|
'Maximum number of compressions to use for auto optimizations',
|
||||||
|
'6',
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
'--optimizer-butteraugli-target <butteraugli distance>',
|
||||||
|
'Target Butteraugli distance for auto optimizer',
|
||||||
|
'1.4',
|
||||||
|
)
|
||||||
|
.action(processFiles);
|
||||||
|
|
||||||
|
// Create a CLI option for each supported preprocessor
|
||||||
|
for (const [key, value] of Object.entries(preprocessors)) {
|
||||||
|
program.option(`--${key} [config]`, value.description);
|
||||||
|
}
|
||||||
|
// Create a CLI option for each supported encoder
|
||||||
|
for (const [key, value] of Object.entries(encoders)) {
|
||||||
|
program.option(
|
||||||
|
`--${key} [config]`,
|
||||||
|
`Use ${value.name} to generate a .${value.extension} file with the given configuration`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
program.parse(process.argv);
|
||||||
19
client-tsconfig.json
Normal file
19
client-tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "./generic-tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["esnext", "dom", "dom.iterable"],
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/features/**/client/**/*",
|
||||||
|
"src/features/**/shared/**/*",
|
||||||
|
"src/features/client-utils/**/*",
|
||||||
|
"src/shared/**/*",
|
||||||
|
"src/client/**/*",
|
||||||
|
// Not really clean, but we need these to access the type of the functions
|
||||||
|
// for comlink
|
||||||
|
"src/features/**/worker/**/*",
|
||||||
|
"src/features-worker/**/*",
|
||||||
|
"src/features/worker-utils/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,33 +1,39 @@
|
|||||||
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/31d7c6d1e32cf467ac24fb8c7a76c4902a4c00db.tar.gz
|
# libavif and libaom versions are from
|
||||||
|
# https://docs.google.com/document/d/1wEEA5rRU7wT54k41u3qyZIZHDCJArIMzLuzsrLAwaK8/edit
|
||||||
|
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/1c39e772c2c0d687691dd4b589a12c323f5f767d.tar.gz
|
||||||
CODEC_PACKAGE = node_modules/libavif.tar.gz
|
CODEC_PACKAGE = node_modules/libavif.tar.gz
|
||||||
|
|
||||||
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v2.0.0.tar.gz
|
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.1.0.tar.gz
|
||||||
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
||||||
|
|
||||||
export CODEC_DIR = node_modules/libavif
|
export CODEC_DIR = node_modules/libavif
|
||||||
BUILD_DIR := node_modules/build
|
export BUILD_DIR = node_modules/build
|
||||||
ENC_BUILD_DIR := $(BUILD_DIR)/enc
|
|
||||||
ENC_MT_BUILD_DIR := $(BUILD_DIR)/enc-mt
|
|
||||||
DEC_BUILD_DIR := $(BUILD_DIR)/dec
|
|
||||||
export LIBAOM_DIR = node_modules/libaom
|
export LIBAOM_DIR = node_modules/libaom
|
||||||
|
|
||||||
|
override CFLAGS += "-Wno-unused-macros"
|
||||||
|
export
|
||||||
|
|
||||||
OUT_ENC_JS = enc/avif_enc.js
|
OUT_ENC_JS = enc/avif_enc.js
|
||||||
|
OUT_NODE_ENC_JS = enc/avif_node_enc.js
|
||||||
OUT_ENC_MT_JS = enc/avif_enc_mt.js
|
OUT_ENC_MT_JS = enc/avif_enc_mt.js
|
||||||
|
OUT_NODE_ENC_MT_JS = enc/avif_node_enc_mt.js
|
||||||
OUT_DEC_JS = dec/avif_dec.js
|
OUT_DEC_JS = dec/avif_dec.js
|
||||||
|
OUT_NODE_DEC_JS = dec/avif_node_dec.js
|
||||||
|
|
||||||
OUT_ENC_CPP = enc/avif_enc.cpp
|
OUT_ENC_CPP = enc/avif_enc.cpp
|
||||||
OUT_DEC_CPP = dec/avif_dec.cpp
|
OUT_DEC_CPP = dec/avif_dec.cpp
|
||||||
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
HELPER_MAKEFLAGS := -f helper.Makefile
|
HELPER_MAKEFLAGS := -f helper.Makefile
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS) $(OUT_NODE_DEC_JS)
|
||||||
|
|
||||||
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
$(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS): ENVIRONMENT=node
|
||||||
|
$(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
BUILD_DIR=$(ENC_BUILD_DIR) \
|
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
OUT_CPP=$< \
|
OUT_CPP=$< \
|
||||||
LIBAOM_FLAGS="\
|
LIBAOM_FLAGS="\
|
||||||
@@ -35,31 +41,33 @@ $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLis
|
|||||||
-DCONFIG_MULTITHREAD=0 \
|
-DCONFIG_MULTITHREAD=0 \
|
||||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||||
" \
|
" \
|
||||||
|
ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
|
||||||
|
|
||||||
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
$(OUT_ENC_MT_JS) $(OUT_NODE_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
BUILD_DIR=$(ENC_MT_BUILD_DIR) \
|
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
OUT_CPP=$< \
|
OUT_CPP=$< \
|
||||||
LIBAOM_FLAGS="\
|
LIBAOM_FLAGS="\
|
||||||
-DCONFIG_AV1_DECODER=0 \
|
-DCONFIG_AV1_DECODER=0 \
|
||||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||||
" \
|
" \
|
||||||
|
ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
|
||||||
OUT_FLAGS="-pthread"
|
OUT_FLAGS="-pthread"
|
||||||
|
|
||||||
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
$(OUT_NODE_DEC_JS): ENVIRONMENT=node
|
||||||
|
$(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
BUILD_DIR=$(DEC_BUILD_DIR) \
|
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
OUT_CPP=$< \
|
OUT_CPP=$< \
|
||||||
LIBAOM_FLAGS="\
|
LIBAOM_FLAGS="\
|
||||||
-DCONFIG_AV1_ENCODER=0 \
|
-DCONFIG_AV1_ENCODER=0 \
|
||||||
-DCONFIG_MULTITHREAD=0 \
|
-DCONFIG_MULTITHREAD=0 \
|
||||||
" \
|
" \
|
||||||
|
ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
||||||
|
|
||||||
$(CODEC_PACKAGE):
|
$(CODEC_PACKAGE):
|
||||||
@@ -79,6 +87,9 @@ $(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
|
|||||||
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)
|
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(ENC_BUILD_DIR) OUT_JS=$(OUT_ENC_JS) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_JS) clean
|
||||||
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(ENC_MT_BUILD_DIR) OUT_JS=$(OUT_ENC_MT_JS) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_MT_JS) clean
|
||||||
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(DEC_BUILD_DIR) OUT_JS=$(OUT_DEC_JS) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_NODE_JS) clean
|
||||||
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_NODE_MT_JS) clean
|
||||||
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEC_JS) clean
|
||||||
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEV_NODE_JS) clean
|
||||||
|
|||||||
5
codecs/avif/dec/avif_dec.d.ts
vendored
5
codecs/avif/dec/avif_dec.d.ts
vendored
@@ -1,6 +1,7 @@
|
|||||||
interface AVIFModule extends EmscriptenWasm.Module {
|
export interface AVIFModule extends EmscriptenWasm.Module {
|
||||||
decode(data: BufferSource): ImageData | null;
|
decode(data: BufferSource): ImageData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<AVIFModule>;
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<AVIFModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
73
codecs/avif/dec/avif_dec.js
generated
73
codecs/avif/dec/avif_dec.js
generated
File diff suppressed because one or more lines are too long
BIN
codecs/avif/dec/avif_dec.wasm
Normal file → Executable file
BIN
codecs/avif/dec/avif_dec.wasm
Normal file → Executable file
Binary file not shown.
16
codecs/avif/dec/avif_node_dec.js
generated
Normal file
16
codecs/avif/dec/avif_node_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/avif/dec/avif_node_dec.wasm
Executable file
BIN
codecs/avif/dec/avif_node_dec.wasm
Executable file
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
#include <emscripten/val.h>
|
|
||||||
#include <emscripten/threading.h>
|
#include <emscripten/threading.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
#include "avif/avif.h"
|
#include "avif/avif.h"
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
@@ -9,10 +9,9 @@ struct AvifOptions {
|
|||||||
// [0 - 63]
|
// [0 - 63]
|
||||||
// 0 = lossless
|
// 0 = lossless
|
||||||
// 63 = worst quality
|
// 63 = worst quality
|
||||||
int minQuantizer;
|
int cqLevel;
|
||||||
int maxQuantizer;
|
// As above, but -1 means 'use cqLevel'
|
||||||
int minQuantizerAlpha;
|
int cqAlphaLevel;
|
||||||
int maxQuantizerAlpha;
|
|
||||||
// [0 - 6]
|
// [0 - 6]
|
||||||
// Creates 2^n tiles in that dimension
|
// Creates 2^n tiles in that dimension
|
||||||
int tileRowsLog2;
|
int tileRowsLog2;
|
||||||
@@ -26,6 +25,16 @@ struct AvifOptions {
|
|||||||
// 2 = 4:2:2
|
// 2 = 4:2:2
|
||||||
// 3 = 4:4:4
|
// 3 = 4:4:4
|
||||||
int subsample;
|
int subsample;
|
||||||
|
// Extra chroma compression
|
||||||
|
bool chromaDeltaQ;
|
||||||
|
// 0-7
|
||||||
|
int sharpness;
|
||||||
|
// 0 = auto
|
||||||
|
// 1 = PSNR
|
||||||
|
// 2 = SSIM
|
||||||
|
int tune;
|
||||||
|
// 0-50
|
||||||
|
int denoiseLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||||
@@ -49,21 +58,19 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lossless = options.cqLevel == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
|
options.cqAlphaLevel <= AVIF_QUANTIZER_LOSSLESS &&
|
||||||
|
format == AVIF_PIXEL_FORMAT_YUV444;
|
||||||
|
|
||||||
avifImage* image = avifImageCreate(width, height, depth, format);
|
avifImage* image = avifImageCreate(width, height, depth, format);
|
||||||
|
|
||||||
if (
|
if (lossless) {
|
||||||
options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
|
||||||
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
|
||||||
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
|
||||||
options.maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
|
||||||
format == AVIF_PIXEL_FORMAT_YUV444
|
|
||||||
) {
|
|
||||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
||||||
} else {
|
} else {
|
||||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT709;
|
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* rgba = (uint8_t*)buffer.c_str();
|
uint8_t* rgba = reinterpret_cast<uint8_t*>(const_cast<char*>(buffer.data()));
|
||||||
|
|
||||||
avifRGBImage srcRGB;
|
avifRGBImage srcRGB;
|
||||||
avifRGBImageSetDefaults(&srcRGB, image);
|
avifRGBImageSetDefaults(&srcRGB, image);
|
||||||
@@ -72,14 +79,44 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
|||||||
avifImageRGBToYUV(image, &srcRGB);
|
avifImageRGBToYUV(image, &srcRGB);
|
||||||
|
|
||||||
avifEncoder* encoder = avifEncoderCreate();
|
avifEncoder* encoder = avifEncoderCreate();
|
||||||
|
|
||||||
|
if (lossless) {
|
||||||
|
encoder->minQuantizer = AVIF_QUANTIZER_LOSSLESS;
|
||||||
|
encoder->maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
|
||||||
|
encoder->minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
||||||
|
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
||||||
|
} else {
|
||||||
|
encoder->minQuantizer = AVIF_QUANTIZER_BEST_QUALITY;
|
||||||
|
encoder->maxQuantizer = AVIF_QUANTIZER_WORST_QUALITY;
|
||||||
|
encoder->minQuantizerAlpha = AVIF_QUANTIZER_BEST_QUALITY;
|
||||||
|
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_WORST_QUALITY;
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "end-usage", "q");
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "cq-level", std::to_string(options.cqLevel).c_str());
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "sharpness",
|
||||||
|
std::to_string(options.sharpness).c_str());
|
||||||
|
|
||||||
|
if (options.cqAlphaLevel != -1) {
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "alpha:cq-level",
|
||||||
|
std::to_string(options.cqAlphaLevel).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.tune == 2 || (options.tune == 0 && options.cqLevel <= 32)) {
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "tune", "ssim");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.chromaDeltaQ) {
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "enable-chroma-deltaq", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
avifEncoderSetCodecSpecificOption(encoder, "color:denoise-noise-level",
|
||||||
|
std::to_string(options.denoiseLevel).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
encoder->maxThreads = emscripten_num_logical_cores();
|
encoder->maxThreads = emscripten_num_logical_cores();
|
||||||
encoder->minQuantizer = options.minQuantizer;
|
|
||||||
encoder->maxQuantizer = options.maxQuantizer;
|
|
||||||
encoder->minQuantizerAlpha = options.minQuantizerAlpha;
|
|
||||||
encoder->maxQuantizerAlpha = options.maxQuantizerAlpha;
|
|
||||||
encoder->tileRowsLog2 = options.tileRowsLog2;
|
encoder->tileRowsLog2 = options.tileRowsLog2;
|
||||||
encoder->tileColsLog2 = options.tileColsLog2;
|
encoder->tileColsLog2 = options.tileColsLog2;
|
||||||
encoder->speed = options.speed;
|
encoder->speed = options.speed;
|
||||||
|
|
||||||
avifResult encodeResult = avifEncoderWrite(encoder, image, &output);
|
avifResult encodeResult = avifEncoderWrite(encoder, image, &output);
|
||||||
auto js_result = val::null();
|
auto js_result = val::null();
|
||||||
if (encodeResult == AVIF_RESULT_OK) {
|
if (encodeResult == AVIF_RESULT_OK) {
|
||||||
@@ -94,13 +131,15 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
|||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<AvifOptions>("AvifOptions")
|
value_object<AvifOptions>("AvifOptions")
|
||||||
.field("minQuantizer", &AvifOptions::minQuantizer)
|
.field("cqLevel", &AvifOptions::cqLevel)
|
||||||
.field("maxQuantizer", &AvifOptions::maxQuantizer)
|
.field("cqAlphaLevel", &AvifOptions::cqAlphaLevel)
|
||||||
.field("minQuantizerAlpha", &AvifOptions::minQuantizerAlpha)
|
|
||||||
.field("maxQuantizerAlpha", &AvifOptions::maxQuantizerAlpha)
|
|
||||||
.field("tileRowsLog2", &AvifOptions::tileRowsLog2)
|
.field("tileRowsLog2", &AvifOptions::tileRowsLog2)
|
||||||
.field("tileColsLog2", &AvifOptions::tileColsLog2)
|
.field("tileColsLog2", &AvifOptions::tileColsLog2)
|
||||||
.field("speed", &AvifOptions::speed)
|
.field("speed", &AvifOptions::speed)
|
||||||
|
.field("chromaDeltaQ", &AvifOptions::chromaDeltaQ)
|
||||||
|
.field("sharpness", &AvifOptions::sharpness)
|
||||||
|
.field("tune", &AvifOptions::tune)
|
||||||
|
.field("denoiseLevel", &AvifOptions::denoiseLevel)
|
||||||
.field("subsample", &AvifOptions::subsample);
|
.field("subsample", &AvifOptions::subsample);
|
||||||
|
|
||||||
function("encode", &encode);
|
function("encode", &encode);
|
||||||
|
|||||||
34
codecs/avif/enc/avif_enc.d.ts
vendored
34
codecs/avif/enc/avif_enc.d.ts
vendored
@@ -1,7 +1,31 @@
|
|||||||
import { EncodeOptions } from '../../../src/codecs/avif/encoder-meta';
|
export const enum AVIFTune {
|
||||||
|
auto,
|
||||||
interface AVIFModule extends EmscriptenWasm.Module {
|
psnr,
|
||||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
ssim,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<AVIFModule>;
|
export interface EncodeOptions {
|
||||||
|
cqLevel: number;
|
||||||
|
denoiseLevel: number;
|
||||||
|
cqAlphaLevel: number;
|
||||||
|
tileRowsLog2: number;
|
||||||
|
tileColsLog2: number;
|
||||||
|
speed: number;
|
||||||
|
subsample: number;
|
||||||
|
chromaDeltaQ: boolean;
|
||||||
|
sharpness: number;
|
||||||
|
tune: AVIFTune;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AVIFModule extends EmscriptenWasm.Module {
|
||||||
|
encode(
|
||||||
|
data: BufferSource,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
options: EncodeOptions,
|
||||||
|
): Uint8Array | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<AVIFModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
115
codecs/avif/enc/avif_enc.js
generated
115
codecs/avif/enc/avif_enc.js
generated
File diff suppressed because one or more lines are too long
BIN
codecs/avif/enc/avif_enc.wasm
Normal file → Executable file
BIN
codecs/avif/enc/avif_enc.wasm
Normal file → Executable file
Binary file not shown.
1
codecs/avif/enc/avif_enc_mt.d.ts
vendored
Normal file
1
codecs/avif/enc/avif_enc_mt.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './avif_enc';
|
||||||
157
codecs/avif/enc/avif_enc_mt.js
generated
157
codecs/avif/enc/avif_enc_mt.js
generated
File diff suppressed because one or more lines are too long
BIN
codecs/avif/enc/avif_enc_mt.wasm
Normal file → Executable file
BIN
codecs/avif/enc/avif_enc_mt.wasm
Normal file → Executable file
Binary file not shown.
2
codecs/avif/enc/avif_enc_mt.worker.js
generated
2
codecs/avif/enc/avif_enc_mt.worker.js
generated
@@ -1 +1 @@
|
|||||||
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:selfThreadId})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["DYNAMIC_BASE"]=e.data.DYNAMIC_BASE;Module["DYNAMICTOP_PTR"]=e.data.DYNAMICTOP_PTR;Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}avif_enc_mt(Module).then(function(instance){Module=instance;postMessage({"cmd":"loaded"})})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;threadInfoStruct=e.data.threadInfoStruct;Module["registerPthreadPtr"](threadInfoStruct,/*isMainBrowserThread=*/0,/*isMainRuntimeThread=*/0);selfThreadId=e.data.selfThreadId;parentThreadId=e.data.parentThreadId;var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);/*EM_THREAD_STATUS_RUNNING*/try{var result=Module["dynCall_ii"](e.data.start_routine,e.data.arg);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){Atomics.store(Module["HEAPU32"],(threadInfoStruct+4)>>/*C_STRUCTS.pthread.threadExitCode*/2,(ex instanceof Module["ExitStatus"])?ex.status:-2);/*A custom entry specific to Emscripten denoting that the thread crashed.*/Atomics.store(Module["HEAPU32"],(threadInfoStruct+0)>>/*C_STRUCTS.pthread.threadStatus*/2,1);Module["_emscripten_futex_wake"](threadInfoStruct+0,/*C_STRUCTS.pthread.threadStatus*/2147483647);if(!(ex instanceof Module["ExitStatus"]))throw ex}}}else if(e.data.cmd==="cancel"){if(threadInfoStruct){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(threadInfoStruct){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}
|
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./avif_enc_mt.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
|
|||||||
16
codecs/avif/enc/avif_node_enc.js
generated
Normal file
16
codecs/avif/enc/avif_node_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/avif/enc/avif_node_enc.wasm
Executable file
BIN
codecs/avif/enc/avif_node_enc.wasm
Executable file
Binary file not shown.
16
codecs/avif/enc/avif_node_enc_mt.js
generated
Normal file
16
codecs/avif/enc/avif_node_enc_mt.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/avif/enc/avif_node_enc_mt.wasm
Executable file
BIN
codecs/avif/enc/avif_node_enc_mt.wasm
Executable file
Binary file not shown.
1
codecs/avif/enc/avif_node_enc_mt.worker.js
generated
Normal file
1
codecs/avif/enc/avif_node_enc_mt.worker.js
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"use strict";var Module={};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:function(f){(0,eval)(nodeFS.readFileSync(f,"utf8"))},postMessage:function(msg){parentPort.postMessage(msg)},performance:global.performance||{now:function(){return Date.now()}}})}var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./avif_node_enc_mt.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
@@ -8,11 +8,14 @@
|
|||||||
# $(OUT_CPP)
|
# $(OUT_CPP)
|
||||||
# $(LIBAOM_FLAGS)
|
# $(LIBAOM_FLAGS)
|
||||||
# $(LIBAVIF_FLAGS)
|
# $(LIBAVIF_FLAGS)
|
||||||
|
# $(ENVIRONMENT)
|
||||||
|
|
||||||
CODEC_BUILD_DIR := $(BUILD_DIR)/libavif
|
OUT_BUILD_DIR := $(BUILD_DIR)/$(basename $(OUT_JS))
|
||||||
|
|
||||||
|
CODEC_BUILD_DIR := $(OUT_BUILD_DIR)/libavif
|
||||||
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
||||||
|
|
||||||
LIBAOM_BUILD_DIR := $(BUILD_DIR)/libaom
|
LIBAOM_BUILD_DIR := $(OUT_BUILD_DIR)/libaom
|
||||||
LIBAOM_OUT := $(LIBAOM_BUILD_DIR)/libaom.a
|
LIBAOM_OUT := $(LIBAOM_BUILD_DIR)/libaom.a
|
||||||
|
|
||||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||||
@@ -29,10 +32,8 @@ $(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
|||||||
$(LDFLAGS) \
|
$(LDFLAGS) \
|
||||||
$(OUT_FLAGS) \
|
$(OUT_FLAGS) \
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
201
codecs/basis/LICENSE.codec.md
Normal file
201
codecs/basis/LICENSE.codec.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
83
codecs/basis/Makefile
Normal file
83
codecs/basis/Makefile
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
CODEC_URL := https://github.com/BinomialLLC/basis_universal/archive/refs/tags/v1.15_rel2.tar.gz
|
||||||
|
CODEC_DIR := node_modules/basis
|
||||||
|
CODEC_BUILD_DIR := $(CODEC_DIR)/build
|
||||||
|
CODEC_LIB := $(CODEC_BUILD_DIR)/basis.a
|
||||||
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
|
OUT_JS := enc/basis_enc.js dec/basis_dec.js
|
||||||
|
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||||
|
|
||||||
|
COMMON_FLAGS := -O3 -fno-strict-aliasing
|
||||||
|
|
||||||
|
override CXXFLAGS += $(COMMON_FLAGS)
|
||||||
|
override CFLAGS += $(COMMAN_FLAGS)
|
||||||
|
|
||||||
|
CODEC_CPP_SOURCE_FILES := \
|
||||||
|
encoder/basisu_comp.cpp \
|
||||||
|
encoder/basisu_enc.cpp \
|
||||||
|
encoder/basisu_backend.cpp \
|
||||||
|
encoder/basisu_basis_file.cpp \
|
||||||
|
encoder/basisu_etc.cpp \
|
||||||
|
encoder/basisu_uastc_enc.cpp \
|
||||||
|
encoder/basisu_gpu_texture.cpp \
|
||||||
|
encoder/basisu_frontend.cpp \
|
||||||
|
encoder/basisu_bc7enc.cpp \
|
||||||
|
encoder/basisu_pvrtc1_4.cpp \
|
||||||
|
encoder/basisu_astc_decomp.cpp \
|
||||||
|
encoder/basisu_global_selector_palette_helpers.cpp \
|
||||||
|
encoder/basisu_resampler.cpp \
|
||||||
|
encoder/basisu_kernels_sse.cpp \
|
||||||
|
encoder/basisu_resample_filters.cpp \
|
||||||
|
encoder/jpgd.cpp \
|
||||||
|
encoder/lodepng.cpp \
|
||||||
|
transcoder/basisu_transcoder.cpp
|
||||||
|
|
||||||
|
CODEC_C_SOURCE_FILES := \
|
||||||
|
encoder/apg_bmp.c \
|
||||||
|
zstd/zstd.c
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(CODEC_DIR) $(OUT_JS)
|
||||||
|
|
||||||
|
# Define dependencies for all variations of build artifacts.
|
||||||
|
$(filter enc/%,$(OUT_JS)): enc/basis_enc.cpp
|
||||||
|
$(filter dec/%,$(OUT_JS)): dec/basis_dec.cpp
|
||||||
|
|
||||||
|
# TODO: Make it build for node
|
||||||
|
# enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js: ENVIRONMENT = node
|
||||||
|
|
||||||
|
%.js: $(CODEC_LIB)
|
||||||
|
$(CXX) \
|
||||||
|
-I $(CODEC_DIR)/encoder \
|
||||||
|
-I $(CODEC_DIR)/transcoder \
|
||||||
|
${CXXFLAGS} \
|
||||||
|
${LDFLAGS} \
|
||||||
|
--closure 1 \
|
||||||
|
--bind \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s MODULARIZE=1 \
|
||||||
|
-s TEXTDECODER=2 \
|
||||||
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
|
-s EXPORT_ES6=1 \
|
||||||
|
-o $@ \
|
||||||
|
$+
|
||||||
|
|
||||||
|
$(CODEC_LIB): $(CODEC_DIR)
|
||||||
|
mkdir -p $(CODEC_BUILD_DIR)
|
||||||
|
cd $(CODEC_BUILD_DIR) && \
|
||||||
|
$(CXX) \
|
||||||
|
${CXXFLAGS} \
|
||||||
|
-c $(addprefix ../, $(CODEC_CPP_SOURCE_FILES))
|
||||||
|
cd $(CODEC_BUILD_DIR) && \
|
||||||
|
$(CC) \
|
||||||
|
${CFLAGS} \
|
||||||
|
-c $(addprefix ../, $(CODEC_C_SOURCE_FILES))
|
||||||
|
$(AR) rc $(CODEC_LIB) $(CODEC_BUILD_DIR)/*.o
|
||||||
|
|
||||||
|
$(CODEC_DIR):
|
||||||
|
mkdir -p $@
|
||||||
|
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) -r $(OUT_JS) $(OUT_WASM) $(CODEC_BUILD_DIR)
|
||||||
46
codecs/basis/dec/basis_dec.cpp
Normal file
46
codecs/basis/dec/basis_dec.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string>
|
||||||
|
#include "basisu_global_selector_palette.h"
|
||||||
|
#include "basisu_transcoder.h"
|
||||||
|
|
||||||
|
using namespace emscripten;
|
||||||
|
using namespace basisu;
|
||||||
|
|
||||||
|
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||||
|
thread_local const val ImageData = val::global("ImageData");
|
||||||
|
|
||||||
|
val decode(std::string data) {
|
||||||
|
basist::basisu_transcoder_init();
|
||||||
|
|
||||||
|
basist::etc1_global_selector_codebook sel_codebook = basist::etc1_global_selector_codebook(
|
||||||
|
basist::g_global_selector_cb_size, basist::g_global_selector_cb);
|
||||||
|
basist::ktx2_transcoder transcoder = basist::ktx2_transcoder(&sel_codebook);
|
||||||
|
|
||||||
|
const void* dataPtr = reinterpret_cast<const void*>(data.c_str());
|
||||||
|
auto dataSize = data.size();
|
||||||
|
transcoder.init(dataPtr, dataSize);
|
||||||
|
|
||||||
|
auto header = transcoder.get_header();
|
||||||
|
auto image_width = static_cast<uint32_t>(header.m_pixel_width);
|
||||||
|
auto image_height = static_cast<uint32_t>(header.m_pixel_height);
|
||||||
|
|
||||||
|
transcoder.start_transcoding();
|
||||||
|
auto buffer = std::vector<uint8_t>(image_width * image_height * 4);
|
||||||
|
auto ok = transcoder.transcode_image_level(
|
||||||
|
0 /* level_index */, 0 /* layer_index */, 0 /* face_index */, buffer.data(),
|
||||||
|
buffer.size() / 4, basist::transcoder_texture_format::cTFRGBA32, 0 /* decode_flags */,
|
||||||
|
image_width /* output_row_pitch_in_blocks_or_pixels */);
|
||||||
|
if (!ok) {
|
||||||
|
return val(std::string("Could not decode"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto img_data_data = Uint8ClampedArray.new_(typed_memory_view(buffer.size(), buffer.data()));
|
||||||
|
auto imgData = ImageData.new_(img_data_data, image_width, image_height);
|
||||||
|
return imgData;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
function("decode", &decode);
|
||||||
|
}
|
||||||
7
codecs/basis/dec/basis_dec.d.ts
vendored
Normal file
7
codecs/basis/dec/basis_dec.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export interface BasisModule extends EmscriptenWasm.Module {
|
||||||
|
decode(data: BufferSource): ImageData | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<BasisModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
56
codecs/basis/dec/basis_dec.js
generated
Normal file
56
codecs/basis/dec/basis_dec.js
generated
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
var Module = (function() {
|
||||||
|
var _scriptDir = import.meta.url;
|
||||||
|
|
||||||
|
return (
|
||||||
|
function(Module) {
|
||||||
|
Module = Module || {};
|
||||||
|
|
||||||
|
|
||||||
|
var e;e||(e=typeof Module !== 'undefined' ? Module : {});var aa,r;e.ready=new Promise(function(a,b){aa=a;r=b});var t={},u;for(u in e)e.hasOwnProperty(u)&&(t[u]=e[u]);var v="",w;v=self.location.href;_scriptDir&&(v=_scriptDir);0!==v.indexOf("blob:")?v=v.substr(0,v.lastIndexOf("/")+1):v="";w=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)};var ba=e.print||console.log.bind(console),y=e.printErr||console.warn.bind(console);
|
||||||
|
for(u in t)t.hasOwnProperty(u)&&(e[u]=t[u]);t=null;var z;e.wasmBinary&&(z=e.wasmBinary);var noExitRuntime=e.noExitRuntime||!0;"object"!==typeof WebAssembly&&A("no native wasm support detected");var C,ca=!1,da=new TextDecoder("utf8");function D(a,b){if(!a)return"";b=a+b;for(var c=a;!(c>=b)&&E[c];)++c;return da.decode(E.subarray(a,c))}
|
||||||
|
function ea(a,b,c){var d=E;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;d[b++]=g}else{if(2047>=g){if(b+1>=c)break;d[b++]=192|g>>6}else{if(65535>=g){if(b+2>=c)break;d[b++]=224|g>>12}else{if(b+3>=c)break;d[b++]=240|g>>18;d[b++]=128|g>>12&63}d[b++]=128|g>>6&63}d[b++]=128|g&63}}d[b]=0}}var fa=new TextDecoder("utf-16le");
|
||||||
|
function ha(a,b){var c=a>>1;for(b=c+b/2;!(c>=b)&&F[c];)++c;return fa.decode(E.subarray(a,c<<1))}function ia(a,b,c){void 0===c&&(c=2147483647);if(2>c)return 0;c-=2;var d=b;c=c<2*a.length?c/2:a.length;for(var f=0;f<c;++f)G[b>>1]=a.charCodeAt(f),b+=2;G[b>>1]=0;return b-d}function ja(a){return 2*a.length}function ka(a,b){for(var c=0,d="";!(c>=b/4);){var f=I[a+4*c>>2];if(0==f)break;++c;65536<=f?(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023)):d+=String.fromCharCode(f)}return d}
|
||||||
|
function la(a,b,c){void 0===c&&(c=2147483647);if(4>c)return 0;var d=b;c=d+c-4;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}I[b>>2]=g;b+=4;if(b+4>c)break}I[b>>2]=0;return b-d}function ma(a){for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);55296<=d&&57343>=d&&++c;b+=4}return b}var na,oa,E,G,F,I,J,pa,qa;
|
||||||
|
function ra(){var a=C.buffer;na=a;e.HEAP8=oa=new Int8Array(a);e.HEAP16=G=new Int16Array(a);e.HEAP32=I=new Int32Array(a);e.HEAPU8=E=new Uint8Array(a);e.HEAPU16=F=new Uint16Array(a);e.HEAPU32=J=new Uint32Array(a);e.HEAPF32=pa=new Float32Array(a);e.HEAPF64=qa=new Float64Array(a)}var L,sa=[],ta=[],ua=[];function va(){var a=e.preRun.shift();sa.unshift(a)}var M=0,wa=null,N=null;e.preloadedImages={};e.preloadedAudios={};
|
||||||
|
function A(a){if(e.onAbort)e.onAbort(a);y(a);ca=!0;a=new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");r(a);throw a;}var O=(new URL("basis_dec.wasm",import.meta.url)).toString();function xa(){try{if(O==O&&z)return new Uint8Array(z);if(w)return w(O);throw"both async and sync fetching of the wasm failed";}catch(a){A(a)}}
|
||||||
|
function ya(){return z||"function"!==typeof fetch?Promise.resolve().then(function(){return xa()}):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 xa()})}function za(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b(e);else{var c=b.M;"number"===typeof c?void 0===b.I?L.get(c)():L.get(c)(b.I):c(void 0===b.I?null:b.I)}}}
|
||||||
|
function Aa(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 Ba=void 0;function P(a){for(var b="";E[a];)b+=Ba[E[a++]];return b}var Q={},R={},S={};function Ca(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 Da(a,b){a=Ca(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}function Ea(a){var b=Error,c=Da(a,function(d){this.name=a;this.message=d;d=Error(d).stack;void 0!==d&&(this.stack=this.toString()+"\n"+d.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 Fa=void 0;function T(a){throw new Fa(a);}var Ga=void 0;function Ha(a,b){function c(h){h=b(h);if(h.length!==d.length)throw new Ga("Mismatched type converter count");for(var m=0;m<d.length;++m)U(d[m],h[m])}var d=[];d.forEach(function(h){S[h]=a});var f=Array(a.length),g=[],k=0;a.forEach(function(h,m){R.hasOwnProperty(h)?f[m]=R[h]:(g.push(h),Q.hasOwnProperty(h)||(Q[h]=[]),Q[h].push(function(){f[m]=R[h];++k;k===g.length&&c(f)}))});0===g.length&&c(f)}
|
||||||
|
function U(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||T('type "'+d+'" must have a positive integer typeid pointer');if(R.hasOwnProperty(a)){if(c.L)return;T("Cannot register type '"+d+"' twice")}R[a]=b;delete S[a];Q.hasOwnProperty(a)&&(b=Q[a],delete Q[a],b.forEach(function(f){f()}))}var Ia=[],V=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
||||||
|
function La(a){4<a&&0===--V[a].J&&(V[a]=void 0,Ia.push(a))}function W(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Ia.length?Ia.pop():V.length;V[b]={J:1,value:a};return b}}function Ma(a){return this.fromWireType(J[a>>2])}function Na(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}
|
||||||
|
function Oa(a,b){switch(b){case 2:return function(c){return this.fromWireType(pa[c>>2])};case 3:return function(c){return this.fromWireType(qa[c>>3])};default:throw new TypeError("Unknown float type: "+a);}}function Pa(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=Da(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}
|
||||||
|
function Qa(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function Ra(a,b){var c=e;if(void 0===c[a].G){var d=c[a];c[a]=function(){c[a].G.hasOwnProperty(arguments.length)||T("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].G+")!");return c[a].G[arguments.length].apply(this,arguments)};c[a].G=[];c[a].G[d.K]=d}}
|
||||||
|
function Sa(a,b,c){e.hasOwnProperty(a)?((void 0===c||void 0!==e[a].G&&void 0!==e[a].G[c])&&T("Cannot register public name '"+a+"' twice"),Ra(a,a),e.hasOwnProperty(c)&&T("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),e[a].G[c]=b):(e[a]=b,void 0!==c&&(e[a].O=c))}function Ta(a,b){for(var c=[],d=0;d<a;d++)c.push(I[(b>>2)+d]);return c}
|
||||||
|
function Ua(a,b){var c=[];return function(){c.length=arguments.length;for(var d=0;d<arguments.length;d++)c[d]=arguments[d];a.includes("j")?(d=e["dynCall_"+a],d=c&&c.length?d.apply(null,[b].concat(c)):d.call(null,b)):d=L.get(b).apply(null,c);return d}}function Va(a,b){a=P(a);var c=a.includes("j")?Ua(a,b):L.get(b);"function"!==typeof c&&T("unknown function pointer with signature "+a+": "+b);return c}var Wa=void 0;function Xa(a){a=Ya(a);var b=P(a);X(a);return b}
|
||||||
|
function Za(a,b){function c(g){f[g]||R[g]||(S[g]?S[g].forEach(c):(d.push(g),f[g]=!0))}var d=[],f={};b.forEach(c);throw new Wa(a+": "+d.map(Xa).join([", "]));}function $a(a,b,c){switch(b){case 0:return c?function(d){return oa[d]}:function(d){return E[d]};case 1:return c?function(d){return G[d>>1]}:function(d){return F[d>>1]};case 2:return c?function(d){return I[d>>2]}:function(d){return J[d>>2]};default:throw new TypeError("Unknown integer type: "+a);}}var ab={};
|
||||||
|
function bb(){return"object"===typeof globalThis?globalThis:Function("return this")()}function cb(a,b){var c=R[a];void 0===c&&T(b+" has unknown type "+Xa(a));return c}for(var db={},eb=[null,[],[]],fb=Array(256),Y=0;256>Y;++Y)fb[Y]=String.fromCharCode(Y);Ba=fb;Fa=e.BindingError=Ea("BindingError");Ga=e.InternalError=Ea("InternalError");e.count_emval_handles=function(){for(var a=0,b=5;b<V.length;++b)void 0!==V[b]&&++a;return a};
|
||||||
|
e.get_first_emval=function(){for(var a=5;a<V.length;++a)if(void 0!==V[a])return V[a];return null};Wa=e.UnboundTypeError=Ea("UnboundTypeError");
|
||||||
|
var hb={a:function(a,b,c,d){A("Assertion failed: "+D(a)+", at: "+[b?D(b):"unknown filename",c,d?D(d):"unknown function"])},g:function(){},r:function(){},x:function(a,b,c,d,f){var g=Aa(c);b=P(b);U(a,{name:b,fromWireType:function(k){return!!k},toWireType:function(k,h){return h?d:f},argPackAdvance:8,readValueFromPointer:function(k){if(1===c)var h=oa;else if(2===c)h=G;else if(4===c)h=I;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(h[k>>g])},H:null})},w:function(a,
|
||||||
|
b){b=P(b);U(a,{name:b,fromWireType:function(c){var d=V[c].value;La(c);return d},toWireType:function(c,d){return W(d)},argPackAdvance:8,readValueFromPointer:Ma,H:null})},l:function(a,b,c){c=Aa(c);b=P(b);U(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,f){if("number"!==typeof f&&"boolean"!==typeof f)throw new TypeError('Cannot convert "'+Na(f)+'" to '+this.name);return f},argPackAdvance:8,readValueFromPointer:Oa(b,c),H:null})},o:function(a,b,c,d,f,g){var k=Ta(b,c);a=P(a);f=Va(d,
|
||||||
|
f);Sa(a,function(){Za("Cannot call "+a+" due to unbound types",k)},b-1);Ha(k,function(h){var m=a,l=a;h=[h[0],null].concat(h.slice(1));var p=f,q=h.length;2>q&&T("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var x=null!==h[1]&&!1,B=!1,n=1;n<h.length;++n)if(null!==h[n]&&void 0===h[n].H){B=!0;break}var Ja="void"!==h[0].name,H="",K="";for(n=0;n<q-2;++n)H+=(0!==n?", ":"")+"arg"+n,K+=(0!==n?", ":"")+"arg"+n+"Wired";l="return function "+Ca(l)+"("+H+") {\nif (arguments.length !== "+
|
||||||
|
(q-2)+") {\nthrowBindingError('function "+l+" called with ' + arguments.length + ' arguments, expected "+(q-2)+" args!');\n}\n";B&&(l+="var destructors = [];\n");var Ka=B?"destructors":"null";H="throwBindingError invoker fn runDestructors retType classParam".split(" ");p=[T,p,g,Qa,h[0],h[1]];x&&(l+="var thisWired = classParam.toWireType("+Ka+", this);\n");for(n=0;n<q-2;++n)l+="var arg"+n+"Wired = argType"+n+".toWireType("+Ka+", arg"+n+"); // "+h[n+2].name+"\n",H.push("argType"+n),p.push(h[n+2]);x&&
|
||||||
|
(K="thisWired"+(0<K.length?", ":"")+K);l+=(Ja?"var rv = ":"")+"invoker(fn"+(0<K.length?", ":"")+K+");\n";if(B)l+="runDestructors(destructors);\n";else for(n=x?1:2;n<h.length;++n)q=1===n?"thisWired":"arg"+(n-2)+"Wired",null!==h[n].H&&(l+=q+"_dtor("+q+"); // "+h[n].name+"\n",H.push(q+"_dtor"),p.push(h[n].H));Ja&&(l+="var ret = retType.fromWireType(rv);\nreturn ret;\n");H.push(l+"}\n");h=Pa(H).apply(null,p);n=b-1;if(!e.hasOwnProperty(m))throw new Ga("Replacing nonexistant public symbol");void 0!==e[m].G&&
|
||||||
|
void 0!==n?e[m].G[n]=h:(e[m]=h,e[m].K=n);return[]})},c:function(a,b,c,d,f){function g(l){return l}b=P(b);-1===f&&(f=4294967295);var k=Aa(c);if(0===d){var h=32-8*c;g=function(l){return l<<h>>>h}}var m=b.includes("unsigned");U(a,{name:b,fromWireType:g,toWireType:function(l,p){if("number"!==typeof p&&"boolean"!==typeof p)throw new TypeError('Cannot convert "'+Na(p)+'" to '+this.name);if(p<d||p>f)throw new TypeError('Passing a number "'+Na(p)+'" from JS side to C/C++ side to an argument of type "'+b+
|
||||||
|
'", which is outside the valid range ['+d+", "+f+"]!");return m?p>>>0:p|0},argPackAdvance:8,readValueFromPointer:$a(b,k,0!==d),H:null})},b:function(a,b,c){function d(g){g>>=2;var k=J;return new f(na,k[g+1],k[g])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=P(c);U(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{L:!0})},m:function(a,b){b=P(b);var c="std::string"===b;U(a,{name:b,fromWireType:function(d){var f=J[d>>2];if(c)for(var g=
|
||||||
|
d+4,k=0;k<=f;++k){var h=d+4+k;if(k==f||0==E[h]){g=D(g,h-g);if(void 0===m)var m=g;else m+=String.fromCharCode(0),m+=g;g=h+1}}else{m=Array(f);for(k=0;k<f;++k)m[k]=String.fromCharCode(E[d+4+k]);m=m.join("")}X(d);return m},toWireType:function(d,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var g="string"===typeof f;g||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array||T("Cannot pass non-string to std::string");var k=(c&&g?function(){for(var l=0,p=0;p<f.length;++p){var q=
|
||||||
|
f.charCodeAt(p);55296<=q&&57343>=q&&(q=65536+((q&1023)<<10)|f.charCodeAt(++p)&1023);127>=q?++l:l=2047>=q?l+2:65535>=q?l+3:l+4}return l}:function(){return f.length})(),h=gb(4+k+1);J[h>>2]=k;if(c&&g)ea(f,h+4,k+1);else if(g)for(g=0;g<k;++g){var m=f.charCodeAt(g);255<m&&(X(h),T("String has UTF-16 code units that do not fit in 8 bits"));E[h+4+g]=m}else for(g=0;g<k;++g)E[h+4+g]=f[g];null!==d&&d.push(X,h);return h},argPackAdvance:8,readValueFromPointer:Ma,H:function(d){X(d)}})},i:function(a,b,c){c=P(c);
|
||||||
|
if(2===b){var d=ha;var f=ia;var g=ja;var k=function(){return F};var h=1}else 4===b&&(d=ka,f=la,g=ma,k=function(){return J},h=2);U(a,{name:c,fromWireType:function(m){for(var l=J[m>>2],p=k(),q,x=m+4,B=0;B<=l;++B){var n=m+4+B*b;if(B==l||0==p[n>>h])x=d(x,n-x),void 0===q?q=x:(q+=String.fromCharCode(0),q+=x),x=n+b}X(m);return q},toWireType:function(m,l){"string"!==typeof l&&T("Cannot pass non-string to C++ string type "+c);var p=g(l),q=gb(4+p+b);J[q>>2]=p>>h;f(l,q+4,p+b);null!==m&&m.push(X,q);return q},
|
||||||
|
argPackAdvance:8,readValueFromPointer:Ma,H:function(m){X(m)}})},n:function(a,b){b=P(b);U(a,{N:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},e:La,f:function(a){if(0===a)return W(bb());var b=ab[a];a=void 0===b?P(a):b;return W(bb()[a])},j:function(a){4<a&&(V[a].J+=1)},k:function(a,b,c,d){a||T("Cannot use deleted val. handle = "+a);a=V[a].value;var f=db[b];if(!f){f="";for(var g=0;g<b;++g)f+=(0!==g?", ":"")+"arg"+g;var k="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";
|
||||||
|
for(g=0;g<b;++g)k+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";f=(new Function("requireRegisteredType","Module","__emval_register",k+("var obj = new constructor("+f+");\nreturn __emval_register(obj);\n}\n")))(cb,e,W);db[b]=f}return f(a,c,d)},p:function(a,b){a=cb(a,"_emval_take_value");a=a.readValueFromPointer(b);return W(a)},d:function(){A()},
|
||||||
|
t:function(a,b,c){E.copyWithin(a,b,b+c)},h:function(a){var b=E.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(a,d);0<d%65536&&(d+=65536-d%65536);a:{try{C.grow(Math.min(2147483648,d)-na.byteLength+65535>>>16);ra();var f=1;break a}catch(g){}f=void 0}if(f)return!0}return!1},v:function(){return 0},q:function(){},u:function(a,b,c,d){for(var f=0,g=0;g<c;g++){for(var k=I[b+8*g>>2],h=I[b+(8*g+4)>>2],m=0;m<h;m++){var l=E[k+m],p=eb[a];if(0===
|
||||||
|
l||10===l){for(l=0;p[l]&&!(NaN<=l);)++l;l=da.decode(p.subarray?p.subarray(0,l):new Uint8Array(p.slice(0,l)));(1===a?ba:y)(l);p.length=0}else p.push(l)}f+=h}I[d>>2]=f;return 0},s:function(){}};
|
||||||
|
(function(){function a(f){e.asm=f.exports;C=e.asm.y;ra();L=e.asm.E;ta.unshift(e.asm.z);M--;e.monitorRunDependencies&&e.monitorRunDependencies(M);0==M&&(null!==wa&&(clearInterval(wa),wa=null),N&&(f=N,N=null,f()))}function b(f){a(f.instance)}function c(f){return ya().then(function(g){return WebAssembly.instantiate(g,d)}).then(f,function(g){y("failed to asynchronously prepare wasm: "+g);A(g)})}var d={a:hb};M++;e.monitorRunDependencies&&e.monitorRunDependencies(M);if(e.instantiateWasm)try{return e.instantiateWasm(d,
|
||||||
|
a)}catch(f){return y("Module.instantiateWasm callback failed with error: "+f),!1}(function(){return z||"function"!==typeof WebAssembly.instantiateStreaming||O.startsWith("data:application/octet-stream;base64,")||"function"!==typeof fetch?c(b):fetch(O,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,d).then(b,function(g){y("wasm streaming compile failed: "+g);y("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(r);return{}})();
|
||||||
|
e.___wasm_call_ctors=function(){return(e.___wasm_call_ctors=e.asm.z).apply(null,arguments)};var gb=e._malloc=function(){return(gb=e._malloc=e.asm.A).apply(null,arguments)},X=e._free=function(){return(X=e._free=e.asm.B).apply(null,arguments)},Ya=e.___getTypeName=function(){return(Ya=e.___getTypeName=e.asm.C).apply(null,arguments)};e.___embind_register_native_and_builtin_types=function(){return(e.___embind_register_native_and_builtin_types=e.asm.D).apply(null,arguments)};
|
||||||
|
e.dynCall_jiji=function(){return(e.dynCall_jiji=e.asm.F).apply(null,arguments)};var Z;N=function ib(){Z||jb();Z||(N=ib)};
|
||||||
|
function jb(){function a(){if(!Z&&(Z=!0,e.calledRun=!0,!ca)){za(ta);aa(e);if(e.onRuntimeInitialized)e.onRuntimeInitialized();if(e.postRun)for("function"==typeof e.postRun&&(e.postRun=[e.postRun]);e.postRun.length;){var b=e.postRun.shift();ua.unshift(b)}za(ua)}}if(!(0<M)){if(e.preRun)for("function"==typeof e.preRun&&(e.preRun=[e.preRun]);e.preRun.length;)va();za(sa);0<M||(e.setStatus?(e.setStatus("Running..."),setTimeout(function(){setTimeout(function(){e.setStatus("")},1);a()},1)):a())}}e.run=jb;
|
||||||
|
if(e.preInit)for("function"==typeof e.preInit&&(e.preInit=[e.preInit]);0<e.preInit.length;)e.preInit.pop()();jb();
|
||||||
|
|
||||||
|
|
||||||
|
return Module.ready
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
export default Module;
|
||||||
BIN
codecs/basis/dec/basis_dec.wasm
Executable file
BIN
codecs/basis/dec/basis_dec.wasm
Executable file
Binary file not shown.
96
codecs/basis/enc/basis_enc.cpp
Normal file
96
codecs/basis/enc/basis_enc.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "basisu_comp.h"
|
||||||
|
#include "basisu_enc.h"
|
||||||
|
|
||||||
|
using namespace emscripten;
|
||||||
|
using namespace basisu;
|
||||||
|
|
||||||
|
struct BasisOptions {
|
||||||
|
float quality;
|
||||||
|
uint8_t compression;
|
||||||
|
bool uastc;
|
||||||
|
bool mipmap;
|
||||||
|
bool srgb_mipmap;
|
||||||
|
std::string mipmap_filter;
|
||||||
|
bool perceptual;
|
||||||
|
bool y_flip;
|
||||||
|
uint32_t mipmap_min_dimension;
|
||||||
|
};
|
||||||
|
|
||||||
|
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||||
|
|
||||||
|
val encode(std::string image_in, int image_width, int image_height, BasisOptions opts) {
|
||||||
|
basisu_encoder_init();
|
||||||
|
|
||||||
|
basist::etc1_global_selector_codebook sel_codebook(basist::g_global_selector_cb_size,
|
||||||
|
basist::g_global_selector_cb);
|
||||||
|
basis_compressor_params params;
|
||||||
|
basis_compressor compressor;
|
||||||
|
image img =
|
||||||
|
image(reinterpret_cast<const uint8_t*>(image_in.c_str()), image_width, image_height, 4);
|
||||||
|
// We don’t need the encoder to read/decode files from the filesystem
|
||||||
|
params.m_read_source_images = false;
|
||||||
|
// Writing is unnecessary, too
|
||||||
|
params.m_write_output_basis_files = false;
|
||||||
|
// No printf pls
|
||||||
|
params.m_status_output = false;
|
||||||
|
// True => UASTC, False => ETC1S
|
||||||
|
params.m_uastc = opts.uastc;
|
||||||
|
// Use the standardized KTX2 format
|
||||||
|
params.m_create_ktx2_file = true;
|
||||||
|
// Codebook, whatever this exactly is or does.
|
||||||
|
params.m_pSel_codebook = &sel_codebook;
|
||||||
|
// No multithreading. It apparently doesn’t work well in Wasm.
|
||||||
|
// But we still need to provide a job pool.
|
||||||
|
params.m_multithreading = false;
|
||||||
|
job_pool jpool(1);
|
||||||
|
params.m_pJob_pool = &jpool;
|
||||||
|
|
||||||
|
params.m_ktx2_uastc_supercompression = basist::KTX2_SS_ZSTANDARD;
|
||||||
|
|
||||||
|
params.m_perceptual = opts.perceptual;
|
||||||
|
params.m_y_flip = opts.y_flip;
|
||||||
|
params.m_mip_gen = opts.mipmap;
|
||||||
|
params.m_mip_srgb = opts.srgb_mipmap;
|
||||||
|
params.m_mip_filter = opts.mipmap_filter;
|
||||||
|
params.m_mip_smallest_dimension = opts.mipmap_min_dimension;
|
||||||
|
params.m_compression_level = opts.compression;
|
||||||
|
params.m_source_images.push_back(img);
|
||||||
|
|
||||||
|
if (opts.uastc) {
|
||||||
|
params.m_rdo_uastc_quality_scalar = opts.quality;
|
||||||
|
params.m_rdo_uastc = opts.quality != 0;
|
||||||
|
} else {
|
||||||
|
params.m_quality_level = static_cast<int>(opts.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compressor.init(params)) {
|
||||||
|
return val(std::string("Well something went wrong during init"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compressor.process() != 0) {
|
||||||
|
return val(std::string("Well something went wrong during processing"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto comp_data = compressor.get_output_ktx2_file();
|
||||||
|
auto js_result = Uint8Array.new_(typed_memory_view(comp_data.size(), &comp_data[0]));
|
||||||
|
// Not sure if there is anything to free here
|
||||||
|
return js_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
value_object<BasisOptions>("BasisOptions")
|
||||||
|
.field("quality", &BasisOptions::quality)
|
||||||
|
.field("compression", &BasisOptions::compression)
|
||||||
|
.field("uastc", &BasisOptions::uastc)
|
||||||
|
.field("perceptual", &BasisOptions::perceptual)
|
||||||
|
.field("y_flip", &BasisOptions::y_flip)
|
||||||
|
.field("mipmap", &BasisOptions::mipmap)
|
||||||
|
.field("srgb_mipmap", &BasisOptions::srgb_mipmap)
|
||||||
|
.field("mipmap_filter", &BasisOptions::mipmap_filter)
|
||||||
|
.field("mipmap_min_dimension", &BasisOptions::mipmap_min_dimension);
|
||||||
|
|
||||||
|
function("encode", &encode);
|
||||||
|
}
|
||||||
24
codecs/basis/enc/basis_enc.d.ts
vendored
Normal file
24
codecs/basis/enc/basis_enc.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
export interface EncodeOptions {
|
||||||
|
quality: number;
|
||||||
|
compression: number;
|
||||||
|
uastc: boolean;
|
||||||
|
y_flip: boolean;
|
||||||
|
mipmap: boolean;
|
||||||
|
srgb_mipmap: boolean;
|
||||||
|
perceptual: boolean;
|
||||||
|
mipmap_filter: string;
|
||||||
|
mipmap_min_dimension: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BasisModule extends EmscriptenWasm.Module {
|
||||||
|
encode(
|
||||||
|
data: BufferSource,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
options: EncodeOptions,
|
||||||
|
): Uint8Array | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<BasisModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
62
codecs/basis/enc/basis_enc.js
generated
Normal file
62
codecs/basis/enc/basis_enc.js
generated
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
var Module = (function() {
|
||||||
|
var _scriptDir = import.meta.url;
|
||||||
|
|
||||||
|
return (
|
||||||
|
function(Module) {
|
||||||
|
Module = Module || {};
|
||||||
|
|
||||||
|
|
||||||
|
var f;f||(f=typeof Module !== 'undefined' ? Module : {});var aa,ba;f.ready=new Promise(function(a,b){aa=a;ba=b});var r={},t;for(t in f)f.hasOwnProperty(t)&&(r[t]=f[t]);var u="",ca;u=self.location.href;_scriptDir&&(u=_scriptDir);0!==u.indexOf("blob:")?u=u.substr(0,u.lastIndexOf("/")+1):u="";ca=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)};var da=f.print||console.log.bind(console),v=f.printErr||console.warn.bind(console);
|
||||||
|
for(t in r)r.hasOwnProperty(t)&&(f[t]=r[t]);r=null;var ea=0,w;f.wasmBinary&&(w=f.wasmBinary);var noExitRuntime=f.noExitRuntime||!0;"object"!==typeof WebAssembly&&x("no native wasm support detected");var ha,ia=!1,ja=new TextDecoder("utf8");function B(a,b){if(!a)return"";b=a+b;for(var c=a;!(c>=b)&&C[c];)++c;return ja.decode(C.subarray(a,c))}
|
||||||
|
function ka(a,b,c){var d=C;if(0<c){c=b+c-1;for(var e=0;e<a.length;++e){var g=a.charCodeAt(e);if(55296<=g&&57343>=g){var k=a.charCodeAt(++e);g=65536+((g&1023)<<10)|k&1023}if(127>=g){if(b>=c)break;d[b++]=g}else{if(2047>=g){if(b+1>=c)break;d[b++]=192|g>>6}else{if(65535>=g){if(b+2>=c)break;d[b++]=224|g>>12}else{if(b+3>=c)break;d[b++]=240|g>>18;d[b++]=128|g>>12&63}d[b++]=128|g>>6&63}d[b++]=128|g&63}}d[b]=0}}var la=new TextDecoder("utf-16le");
|
||||||
|
function ma(a,b){var c=a>>1;for(b=c+b/2;!(c>=b)&&D[c];)++c;return la.decode(C.subarray(a,c<<1))}function na(a,b,c){void 0===c&&(c=2147483647);if(2>c)return 0;c-=2;var d=b;c=c<2*a.length?c/2:a.length;for(var e=0;e<c;++e)E[b>>1]=a.charCodeAt(e),b+=2;E[b>>1]=0;return b-d}function oa(a){return 2*a.length}function pa(a,b){for(var c=0,d="";!(c>=b/4);){var e=F[a+4*c>>2];if(0==e)break;++c;65536<=e?(e-=65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023)):d+=String.fromCharCode(e)}return d}
|
||||||
|
function qa(a,b,c){void 0===c&&(c=2147483647);if(4>c)return 0;var d=b;c=d+c-4;for(var e=0;e<a.length;++e){var g=a.charCodeAt(e);if(55296<=g&&57343>=g){var k=a.charCodeAt(++e);g=65536+((g&1023)<<10)|k&1023}F[b>>2]=g;b+=4;if(b+4>c)break}F[b>>2]=0;return b-d}function ra(a){for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);55296<=d&&57343>=d&&++c;b+=4}return b}var sa,H,C,E,D,F,I,ta,ua;
|
||||||
|
function va(){var a=ha.buffer;sa=a;f.HEAP8=H=new Int8Array(a);f.HEAP16=E=new Int16Array(a);f.HEAP32=F=new Int32Array(a);f.HEAPU8=C=new Uint8Array(a);f.HEAPU16=D=new Uint16Array(a);f.HEAPU32=I=new Uint32Array(a);f.HEAPF32=ta=new Float32Array(a);f.HEAPF64=ua=new Float64Array(a)}var J,wa=[],xa=[],ya=[];function za(){var a=f.preRun.shift();wa.unshift(a)}var K=0,Aa=null,L=null;f.preloadedImages={};f.preloadedAudios={};
|
||||||
|
function x(a){if(f.onAbort)f.onAbort(a);v(a);ia=!0;a=new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");ba(a);throw a;}var M=(new URL("basis_enc.wasm",import.meta.url)).toString();function Ba(){try{if(M==M&&w)return new Uint8Array(w);if(ca)return ca(M);throw"both async and sync fetching of the wasm failed";}catch(a){x(a)}}
|
||||||
|
function Ca(){return w||"function"!==typeof fetch?Promise.resolve().then(function(){return Ba()}):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 Ba()})}function Da(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b(f);else{var c=b.Aa;"number"===typeof c?void 0===b.fa?J.get(c)():J.get(c)(b.fa):c(void 0===b.fa?null:b.fa)}}}
|
||||||
|
function Ea(a){this.ea=a-16;this.va=function(b){F[this.ea+8>>2]=b};this.sa=function(b){F[this.ea+0>>2]=b};this.ta=function(){F[this.ea+4>>2]=0};this.ra=function(){H[this.ea+12>>0]=0};this.ua=function(){H[this.ea+13>>0]=0};this.oa=function(b,c){this.va(b);this.sa(c);this.ta();this.ra();this.ua()}}var Fa=0,Ga=[null,[],[]],Ha={},Ia={};function Ja(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function Ka(a){return this.fromWireType(I[a>>2])}var N={},O={},La={};
|
||||||
|
function Ma(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 Na(a,b){a=Ma(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}
|
||||||
|
function Oa(a){var b=Error,c=Na(a,function(d){this.name=a;this.message=d;d=Error(d).stack;void 0!==d&&(this.stack=this.toString()+"\n"+d.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 Pa=void 0;
|
||||||
|
function Qa(a,b,c){function d(h){h=c(h);if(h.length!==a.length)throw new Pa("Mismatched type converter count");for(var l=0;l<a.length;++l)P(a[l],h[l])}a.forEach(function(h){La[h]=b});var e=Array(b.length),g=[],k=0;b.forEach(function(h,l){O.hasOwnProperty(h)?e[l]=O[h]:(g.push(h),N.hasOwnProperty(h)||(N[h]=[]),N[h].push(function(){e[l]=O[h];++k;k===g.length&&d(e)}))});0===g.length&&d(e)}
|
||||||
|
function Ra(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 Sa=void 0;function Q(a){for(var b="";C[a];)b+=Sa[C[a++]];return b}var Ta=void 0;function R(a){throw new Ta(a);}
|
||||||
|
function P(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||R('type "'+d+'" must have a positive integer typeid pointer');if(O.hasOwnProperty(a)){if(c.na)return;R("Cannot register type '"+d+"' twice")}O[a]=b;delete La[a];N.hasOwnProperty(a)&&(b=N[a],delete N[a],b.forEach(function(e){e()}))}var Ua=[],S=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
||||||
|
function Va(a){4<a&&0===--S[a].ga&&(S[a]=void 0,Ua.push(a))}function T(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Ua.length?Ua.pop():S.length;S[b]={ga:1,value:a};return b}}function Wa(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}
|
||||||
|
function Xa(a,b){switch(b){case 2:return function(c){return this.fromWireType(ta[c>>2])};case 3:return function(c){return this.fromWireType(ua[c>>3])};default:throw new TypeError("Unknown float type: "+a);}}function Ya(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=Na(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}
|
||||||
|
function Za(a,b){var c=f;if(void 0===c[a].ca){var d=c[a];c[a]=function(){c[a].ca.hasOwnProperty(arguments.length)||R("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].ca+")!");return c[a].ca[arguments.length].apply(this,arguments)};c[a].ca=[];c[a].ca[d.ia]=d}}
|
||||||
|
function $a(a,b,c){f.hasOwnProperty(a)?((void 0===c||void 0!==f[a].ca&&void 0!==f[a].ca[c])&&R("Cannot register public name '"+a+"' twice"),Za(a,a),f.hasOwnProperty(c)&&R("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),f[a].ca[c]=b):(f[a]=b,void 0!==c&&(f[a].Da=c))}function ab(a,b){for(var c=[],d=0;d<a;d++)c.push(F[(b>>2)+d]);return c}
|
||||||
|
function bb(a,b){var c=[];return function(){c.length=arguments.length;for(var d=0;d<arguments.length;d++)c[d]=arguments[d];a.includes("j")?(d=f["dynCall_"+a],d=c&&c.length?d.apply(null,[b].concat(c)):d.call(null,b)):d=J.get(b).apply(null,c);return d}}function U(a,b){a=Q(a);var c=a.includes("j")?bb(a,b):J.get(b);"function"!==typeof c&&R("unknown function pointer with signature "+a+": "+b);return c}var cb=void 0;function db(a){a=eb(a);var b=Q(a);V(a);return b}
|
||||||
|
function fb(a,b){function c(g){e[g]||O[g]||(La[g]?La[g].forEach(c):(d.push(g),e[g]=!0))}var d=[],e={};b.forEach(c);throw new cb(a+": "+d.map(db).join([", "]));}function gb(a,b,c){switch(b){case 0:return c?function(d){return H[d]}:function(d){return C[d]};case 1:return c?function(d){return E[d>>1]}:function(d){return D[d>>1]};case 2:return c?function(d){return F[d>>2]}:function(d){return I[d>>2]};default:throw new TypeError("Unknown integer type: "+a);}}var hb={};
|
||||||
|
function ib(){return"object"===typeof globalThis?globalThis:Function("return this")()}function jb(a,b){var c=O[a];void 0===c&&R(b+" has unknown type "+db(a));return c}var kb={};Pa=f.InternalError=Oa("InternalError");for(var lb=Array(256),mb=0;256>mb;++mb)lb[mb]=String.fromCharCode(mb);Sa=lb;Ta=f.BindingError=Oa("BindingError");f.count_emval_handles=function(){for(var a=0,b=5;b<S.length;++b)void 0!==S[b]&&++a;return a};
|
||||||
|
f.get_first_emval=function(){for(var a=5;a<S.length;++a)if(void 0!==S[a])return S[a];return null};cb=f.UnboundTypeError=Oa("UnboundTypeError");
|
||||||
|
var vb={a:function(a,b,c,d){x("Assertion failed: "+B(a)+", at: "+[b?B(b):"unknown filename",c,d?B(d):"unknown function"])},D:function(a){return nb(a+16)+16},R:function(){},z:function(a,b,c){(new Ea(a)).oa(b,c);Fa++;throw a;},s:function(){return 0},H:function(){return 0},I:function(){},P:function(a){var b=Ia[a];delete Ia[a];var c=b.pa,d=b.qa,e=b.ha,g=e.map(function(k){return k.ma}).concat(e.map(function(k){return k.xa}));Qa([a],g,function(k){var h={};e.forEach(function(l,m){var n=k[m],q=l.ka,y=l.la,
|
||||||
|
z=k[m+e.length],p=l.wa,fa=l.ya;h[l.ja]={read:function(A){return n.fromWireType(q(y,A))},write:function(A,G){var X=[];p(fa,A,z.toWireType(X,G));Ja(X)}}});return[{name:b.name,fromWireType:function(l){var m={},n;for(n in h)m[n]=h[n].read(l);d(l);return m},toWireType:function(l,m){for(var n in h)if(!(n in m))throw new TypeError('Missing field: "'+n+'"');var q=c();for(n in h)h[n].write(q,m[n]);null!==l&&l.push(d,q);return q},argPackAdvance:8,readValueFromPointer:Ka,da:d}]})},B:function(){},L:function(a,
|
||||||
|
b,c,d,e){var g=Ra(c);b=Q(b);P(a,{name:b,fromWireType:function(k){return!!k},toWireType:function(k,h){return h?d:e},argPackAdvance:8,readValueFromPointer:function(k){if(1===c)var h=H;else if(2===c)h=E;else if(4===c)h=F;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(h[k>>g])},da:null})},K:function(a,b){b=Q(b);P(a,{name:b,fromWireType:function(c){var d=S[c].value;Va(c);return d},toWireType:function(c,d){return T(d)},argPackAdvance:8,readValueFromPointer:Ka,da:null})},
|
||||||
|
u:function(a,b,c){c=Ra(c);b=Q(b);P(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,e){if("number"!==typeof e&&"boolean"!==typeof e)throw new TypeError('Cannot convert "'+Wa(e)+'" to '+this.name);return e},argPackAdvance:8,readValueFromPointer:Xa(b,c),da:null})},O:function(a,b,c,d,e,g){var k=ab(b,c);a=Q(a);e=U(d,e);$a(a,function(){fb("Cannot call "+a+" due to unbound types",k)},b-1);Qa([],k,function(h){var l=a,m=a;h=[h[0],null].concat(h.slice(1));var n=e,q=h.length;2>q&&R("argTypes array size mismatch! Must at least get return value and 'this' types!");
|
||||||
|
for(var y=null!==h[1]&&!1,z=!1,p=1;p<h.length;++p)if(null!==h[p]&&void 0===h[p].da){z=!0;break}var fa="void"!==h[0].name,A="",G="";for(p=0;p<q-2;++p)A+=(0!==p?", ":"")+"arg"+p,G+=(0!==p?", ":"")+"arg"+p+"Wired";m="return function "+Ma(m)+"("+A+") {\nif (arguments.length !== "+(q-2)+") {\nthrowBindingError('function "+m+" called with ' + arguments.length + ' arguments, expected "+(q-2)+" args!');\n}\n";z&&(m+="var destructors = [];\n");var X=z?"destructors":"null";A="throwBindingError invoker fn runDestructors retType classParam".split(" ");
|
||||||
|
n=[R,n,g,Ja,h[0],h[1]];y&&(m+="var thisWired = classParam.toWireType("+X+", this);\n");for(p=0;p<q-2;++p)m+="var arg"+p+"Wired = argType"+p+".toWireType("+X+", arg"+p+"); // "+h[p+2].name+"\n",A.push("argType"+p),n.push(h[p+2]);y&&(G="thisWired"+(0<G.length?", ":"")+G);m+=(fa?"var rv = ":"")+"invoker(fn"+(0<G.length?", ":"")+G+");\n";if(z)m+="runDestructors(destructors);\n";else for(p=y?1:2;p<h.length;++p)q=1===p?"thisWired":"arg"+(p-2)+"Wired",null!==h[p].da&&(m+=q+"_dtor("+q+"); // "+h[p].name+
|
||||||
|
"\n",A.push(q+"_dtor"),n.push(h[p].da));fa&&(m+="var ret = retType.fromWireType(rv);\nreturn ret;\n");A.push(m+"}\n");h=Ya(A).apply(null,n);p=b-1;if(!f.hasOwnProperty(l))throw new Pa("Replacing nonexistant public symbol");void 0!==f[l].ca&&void 0!==p?f[l].ca[p]=h:(f[l]=h,f[l].ia=p);return[]})},j:function(a,b,c,d,e){function g(m){return m}b=Q(b);-1===e&&(e=4294967295);var k=Ra(c);if(0===d){var h=32-8*c;g=function(m){return m<<h>>>h}}var l=b.includes("unsigned");P(a,{name:b,fromWireType:g,toWireType:function(m,
|
||||||
|
n){if("number"!==typeof n&&"boolean"!==typeof n)throw new TypeError('Cannot convert "'+Wa(n)+'" to '+this.name);if(n<d||n>e)throw new TypeError('Passing a number "'+Wa(n)+'" from JS side to C/C++ side to an argument of type "'+b+'", which is outside the valid range ['+d+", "+e+"]!");return l?n>>>0:n|0},argPackAdvance:8,readValueFromPointer:gb(b,k,0!==d),da:null})},i:function(a,b,c){function d(g){g>>=2;var k=I;return new e(sa,k[g+1],k[g])}var e=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,
|
||||||
|
Uint32Array,Float32Array,Float64Array][b];c=Q(c);P(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{na:!0})},v:function(a,b){b=Q(b);var c="std::string"===b;P(a,{name:b,fromWireType:function(d){var e=I[d>>2];if(c)for(var g=d+4,k=0;k<=e;++k){var h=d+4+k;if(k==e||0==C[h]){g=B(g,h-g);if(void 0===l)var l=g;else l+=String.fromCharCode(0),l+=g;g=h+1}}else{l=Array(e);for(k=0;k<e;++k)l[k]=String.fromCharCode(C[d+4+k]);l=l.join("")}V(d);return l},toWireType:function(d,e){e instanceof ArrayBuffer&&
|
||||||
|
(e=new Uint8Array(e));var g="string"===typeof e;g||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Int8Array||R("Cannot pass non-string to std::string");var k=(c&&g?function(){for(var m=0,n=0;n<e.length;++n){var q=e.charCodeAt(n);55296<=q&&57343>=q&&(q=65536+((q&1023)<<10)|e.charCodeAt(++n)&1023);127>=q?++m:m=2047>=q?m+2:65535>=q?m+3:m+4}return m}:function(){return e.length})(),h=nb(4+k+1);I[h>>2]=k;if(c&&g)ka(e,h+4,k+1);else if(g)for(g=0;g<k;++g){var l=e.charCodeAt(g);255<l&&
|
||||||
|
(V(h),R("String has UTF-16 code units that do not fit in 8 bits"));C[h+4+g]=l}else for(g=0;g<k;++g)C[h+4+g]=e[g];null!==d&&d.push(V,h);return h},argPackAdvance:8,readValueFromPointer:Ka,da:function(d){V(d)}})},p:function(a,b,c){c=Q(c);if(2===b){var d=ma;var e=na;var g=oa;var k=function(){return D};var h=1}else 4===b&&(d=pa,e=qa,g=ra,k=function(){return I},h=2);P(a,{name:c,fromWireType:function(l){for(var m=I[l>>2],n=k(),q,y=l+4,z=0;z<=m;++z){var p=l+4+z*b;if(z==m||0==n[p>>h])y=d(y,p-y),void 0===q?
|
||||||
|
q=y:(q+=String.fromCharCode(0),q+=y),y=p+b}V(l);return q},toWireType:function(l,m){"string"!==typeof m&&R("Cannot pass non-string to C++ string type "+c);var n=g(m),q=nb(4+n+b);I[q>>2]=n>>h;e(m,q+4,n+b);null!==l&&l.push(V,q);return q},argPackAdvance:8,readValueFromPointer:Ka,da:function(l){V(l)}})},Q:function(a,b,c,d,e,g){Ia[a]={name:Q(b),pa:U(c,d),qa:U(e,g),ha:[]}},k:function(a,b,c,d,e,g,k,h,l,m){Ia[a].ha.push({ja:Q(b),ma:c,ka:U(d,e),la:g,xa:k,wa:U(h,l),ya:m})},M:function(a,b){b=Q(b);P(a,{Ca:!0,
|
||||||
|
name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},m:Va,y:function(a){if(0===a)return T(ib());var b=hb[a];a=void 0===b?Q(a):b;return T(ib()[a])},N:function(a){4<a&&(S[a].ga+=1)},w:function(a,b,c,d){a||R("Cannot use deleted val. handle = "+a);a=S[a].value;var e=kb[b];if(!e){e="";for(var g=0;g<b;++g)e+=(0!==g?", ":"")+"arg"+g;var k="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";for(g=0;g<b;++g)k+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+
|
||||||
|
g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";e=(new Function("requireRegisteredType","Module","__emval_register",k+("var obj = new constructor("+e+");\nreturn __emval_register(obj);\n}\n")))(jb,f,T);kb[b]=e}return e(a,c,d)},x:function(a,b){a=jb(a,"_emval_take_value");a=a.readValueFromPointer(b);return T(a)},e:function(){x()},h:function(a,b){W(a,b||1);throw"longjmp";},E:function(a,b,c){C.copyWithin(a,b,b+c)},o:function(a){var b=
|
||||||
|
C.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(a,d);0<d%65536&&(d+=65536-d%65536);a:{try{ha.grow(Math.min(2147483648,d)-sa.byteLength+65535>>>16);va();var e=1;break a}catch(g){}e=void 0}if(e)return!0}return!1},t:function(){return 0},G:function(a,b,c,d){a=Ha.Ba(a);b=Ha.za(a,b,c);F[d>>2]=b;return 0},A:function(){},J:function(a,b,c,d){for(var e=0,g=0;g<c;g++){for(var k=F[b+8*g>>2],h=F[b+(8*g+4)>>2],l=0;l<h;l++){var m=C[k+l],n=Ga[a];
|
||||||
|
if(0===m||10===m){for(m=0;n[m]&&!(NaN<=m);)++m;m=ja.decode(n.subarray?n.subarray(0,m):new Uint8Array(n.slice(0,m)));(1===a?da:v)(m);n.length=0}else n.push(m)}e+=h}F[d>>2]=e;return 0},c:function(){return ea},g:function(a){var b=Date.now();F[a>>2]=b/1E3|0;F[a+4>>2]=b%1E3*1E3|0;return 0},l:ob,f:pb,r:qb,q:rb,n:sb,d:tb,C:ub,F:function(){return 28},b:function(a){ea=a}};
|
||||||
|
(function(){function a(e){f.asm=e.exports;ha=f.asm.S;va();J=f.asm.$;xa.unshift(f.asm.T);K--;f.monitorRunDependencies&&f.monitorRunDependencies(K);0==K&&(null!==Aa&&(clearInterval(Aa),Aa=null),L&&(e=L,L=null,e()))}function b(e){a(e.instance)}function c(e){return Ca().then(function(g){return WebAssembly.instantiate(g,d)}).then(e,function(g){v("failed to asynchronously prepare wasm: "+g);x(g)})}var d={a:vb};K++;f.monitorRunDependencies&&f.monitorRunDependencies(K);if(f.instantiateWasm)try{return f.instantiateWasm(d,
|
||||||
|
a)}catch(e){return v("Module.instantiateWasm callback failed with error: "+e),!1}(function(){return w||"function"!==typeof WebAssembly.instantiateStreaming||M.startsWith("data:application/octet-stream;base64,")||"function"!==typeof fetch?c(b):fetch(M,{credentials:"same-origin"}).then(function(e){return WebAssembly.instantiateStreaming(e,d).then(b,function(g){v("wasm streaming compile failed: "+g);v("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ba);return{}})();
|
||||||
|
f.___wasm_call_ctors=function(){return(f.___wasm_call_ctors=f.asm.T).apply(null,arguments)};var nb=f._malloc=function(){return(nb=f._malloc=f.asm.U).apply(null,arguments)},V=f._free=function(){return(V=f._free=f.asm.V).apply(null,arguments)},eb=f.___getTypeName=function(){return(eb=f.___getTypeName=f.asm.W).apply(null,arguments)};f.___embind_register_native_and_builtin_types=function(){return(f.___embind_register_native_and_builtin_types=f.asm.X).apply(null,arguments)};
|
||||||
|
var Y=f.stackSave=function(){return(Y=f.stackSave=f.asm.Y).apply(null,arguments)},Z=f.stackRestore=function(){return(Z=f.stackRestore=f.asm.Z).apply(null,arguments)},W=f._setThrew=function(){return(W=f._setThrew=f.asm._).apply(null,arguments)};f.dynCall_jiiii=function(){return(f.dynCall_jiiii=f.asm.aa).apply(null,arguments)};f.dynCall_jiji=function(){return(f.dynCall_jiji=f.asm.ba).apply(null,arguments)};
|
||||||
|
function tb(a,b,c){var d=Y();try{J.get(a)(b,c)}catch(e){Z(d);if(e!==e+0&&"longjmp"!==e)throw e;W(1,0)}}function sb(a,b){var c=Y();try{J.get(a)(b)}catch(d){Z(c);if(d!==d+0&&"longjmp"!==d)throw d;W(1,0)}}function qb(a,b,c,d){var e=Y();try{return J.get(a)(b,c,d)}catch(g){Z(e);if(g!==g+0&&"longjmp"!==g)throw g;W(1,0)}}function pb(a,b,c){var d=Y();try{return J.get(a)(b,c)}catch(e){Z(d);if(e!==e+0&&"longjmp"!==e)throw e;W(1,0)}}
|
||||||
|
function ob(a,b){var c=Y();try{return J.get(a)(b)}catch(d){Z(c);if(d!==d+0&&"longjmp"!==d)throw d;W(1,0)}}function rb(a,b,c,d,e,g){var k=Y();try{return J.get(a)(b,c,d,e,g)}catch(h){Z(k);if(h!==h+0&&"longjmp"!==h)throw h;W(1,0)}}function ub(a,b,c,d,e){var g=Y();try{J.get(a)(b,c,d,e)}catch(k){Z(g);if(k!==k+0&&"longjmp"!==k)throw k;W(1,0)}}var wb;L=function xb(){wb||yb();wb||(L=xb)};
|
||||||
|
function yb(){function a(){if(!wb&&(wb=!0,f.calledRun=!0,!ia)){Da(xa);aa(f);if(f.onRuntimeInitialized)f.onRuntimeInitialized();if(f.postRun)for("function"==typeof f.postRun&&(f.postRun=[f.postRun]);f.postRun.length;){var b=f.postRun.shift();ya.unshift(b)}Da(ya)}}if(!(0<K)){if(f.preRun)for("function"==typeof f.preRun&&(f.preRun=[f.preRun]);f.preRun.length;)za();Da(wa);0<K||(f.setStatus?(f.setStatus("Running..."),setTimeout(function(){setTimeout(function(){f.setStatus("")},1);a()},1)):a())}}f.run=yb;
|
||||||
|
if(f.preInit)for("function"==typeof f.preInit&&(f.preInit=[f.preInit]);0<f.preInit.length;)f.preInit.pop()();yb();
|
||||||
|
|
||||||
|
|
||||||
|
return Module.ready
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
export default Module;
|
||||||
BIN
codecs/basis/enc/basis_enc.wasm
Executable file
BIN
codecs/basis/enc/basis_enc.wasm
Executable file
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "mozjpeg_enc",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../build-cpp.sh"
|
"build": "../build-cpp.sh"
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
docker build -t squoosh-cpp - < ../cpp.Dockerfile
|
docker build -t squoosh-cpp - < ../cpp.Dockerfile
|
||||||
docker run --rm -v $PWD:/src squoosh-cpp
|
docker run -it --rm -v $PWD:/src squoosh-cpp "$@"
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
set -e
|
|
||||||
|
|
||||||
docker build -t squoosh-rust-nightly --build-arg RUST_IMG=rustlang/rust:nightly - < ../rust.Dockerfile
|
|
||||||
docker run --rm -v $PWD:/src squoosh-rust-nightly "$@"
|
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
docker build -t squoosh-rust - < ../rust.Dockerfile
|
if [ ! -z "$RUST_IMG" ]
|
||||||
docker run --rm -v $PWD:/src squoosh-rust "$@"
|
then
|
||||||
|
# Get part after ":" (https://stackoverflow.com/a/15149278/439965).
|
||||||
|
IMG_SUFFIX=-${RUST_IMG#*:}
|
||||||
|
fi
|
||||||
|
IMG_NAME=squoosh-rust$IMG_SUFFIX
|
||||||
|
docker build -t $IMG_NAME --build-arg RUST_IMG - < ../rust.Dockerfile
|
||||||
|
docker run -it --rm -v $PWD:/src $IMG_NAME "$@"
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
FROM emscripten/emsdk:1.40.0
|
FROM emscripten/emsdk:2.0.23
|
||||||
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
||||||
ENV CFLAGS "-O3 -flto"
|
ENV CFLAGS "-O3 -flto"
|
||||||
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
||||||
ENV LDFLAGS "${CFLAGS} -s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency"
|
ENV LDFLAGS "${CFLAGS} \
|
||||||
# Build and cache standard libraries with these flags
|
-s FILESYSTEM=0 \
|
||||||
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
|
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s TEXTDECODER=2 \
|
||||||
|
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
||||||
|
"
|
||||||
|
# Build and cache standard libraries with these flags + Embind.
|
||||||
|
RUN emcc ${CXXFLAGS} ${LDFLAGS} --bind -xc++ /dev/null -o /dev/null
|
||||||
|
# And another set for the pthread variant.
|
||||||
|
RUN emcc ${CXXFLAGS} ${LDFLAGS} --bind -pthread -xc++ /dev/null -o /dev/null
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
CMD ["sh", "-c", "emmake make -j`nproc`"]
|
CMD ["sh", "-c", "emmake make -j`nproc`"]
|
||||||
|
|||||||
197
codecs/hqx/Cargo.lock
generated
197
codecs/hqx/Cargo.lock
generated
@@ -4,286 +4,289 @@
|
|||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console_error_panic_hook"
|
name = "console_error_panic_hook"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.10",
|
||||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.1.29"
|
version = "0.1.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hqx"
|
name = "hqx"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.2#5f19cda24191ccc7c0c4920b6b246b4e242f377c"
|
source = "git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.3#d7cbae67906796928c8e451b186f3c653924beb8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.42"
|
version = "0.3.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.73"
|
version = "0.2.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.11"
|
version = "0.4.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memory_units"
|
name = "memory_units"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.30"
|
version = "0.4.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.19"
|
version = "1.0.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.13"
|
version = "0.6.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.30",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped-tls"
|
name = "scoped-tls"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "squooshhqx"
|
name = "squooshhqx"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.10",
|
||||||
"console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"console_error_panic_hook",
|
||||||
"hqx 0.1.0 (git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.2)",
|
"hqx",
|
||||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-test 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-test",
|
||||||
"wee_alloc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wee_alloc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.35"
|
version = "1.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.27",
|
||||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.7",
|
||||||
"unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 1.0.0",
|
||||||
"wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bumpalo",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static",
|
||||||
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log",
|
||||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.27",
|
||||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.7",
|
||||||
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn",
|
||||||
"wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-futures"
|
name = "wasm-bindgen-futures"
|
||||||
version = "0.3.27"
|
version = "0.3.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.10",
|
||||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures",
|
||||||
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"js-sys",
|
||||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen",
|
||||||
"web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.7",
|
||||||
"wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-macro-support",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.27",
|
||||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.7",
|
||||||
"syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn",
|
||||||
"wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-test"
|
name = "wasm-bindgen-test"
|
||||||
version = "0.2.50"
|
version = "0.2.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"console_error_panic_hook",
|
||||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures",
|
||||||
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"js-sys",
|
||||||
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scoped-tls",
|
||||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-futures",
|
||||||
"wasm-bindgen-test-macro 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen-test-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-test-macro"
|
name = "wasm-bindgen-test-macro"
|
||||||
version = "0.2.50"
|
version = "0.2.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.30",
|
||||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.6.13",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.42"
|
version = "0.3.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"js-sys",
|
||||||
"wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wee_alloc"
|
name = "wee_alloc"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.10",
|
||||||
"libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc",
|
||||||
"memory_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memory_units",
|
||||||
"winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-i686-pc-windows-gnu",
|
||||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
[metadata]
|
|
||||||
"checksum bumpalo 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
|
||||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|
||||||
"checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
|
||||||
"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
|
||||||
"checksum hqx 0.1.0 (git+https://github.com/CryZe/wasmboy-rs?tag=v0.1.2)" = "<none>"
|
|
||||||
"checksum js-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
|
|
||||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
"checksum libc 0.2.73 (registry+https://github.com/rust-lang/crates.io-index)" = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
|
|
||||||
"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
|
||||||
"checksum memory_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
|
||||||
"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
|
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
|
||||||
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
|
||||||
"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
|
||||||
"checksum syn 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
|
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
|
||||||
"checksum wasm-bindgen 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
|
|
||||||
"checksum wasm-bindgen-backend 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
|
|
||||||
"checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
|
||||||
"checksum wasm-bindgen-macro 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
|
|
||||||
"checksum wasm-bindgen-macro-support 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
|
|
||||||
"checksum wasm-bindgen-shared 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
|
|
||||||
"checksum wasm-bindgen-test 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "a2d9693b63a742d481c7f80587e057920e568317b2806988c59cd71618bc26c1"
|
|
||||||
"checksum wasm-bindgen-test-macro 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "0789dac148a8840bbcf9efe13905463b733fa96543bfbf263790535c11af7ba5"
|
|
||||||
"checksum web-sys 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
|
|
||||||
"checksum wee_alloc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
|
||||||
"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ default = ["console_error_panic_hook", "wee_alloc"]
|
|||||||
cfg-if = "0.1.2"
|
cfg-if = "0.1.2"
|
||||||
wasm-bindgen = "0.2.38"
|
wasm-bindgen = "0.2.38"
|
||||||
# lazy_static = "1.0.0"
|
# lazy_static = "1.0.0"
|
||||||
hqx = {git = "https://github.com/CryZe/wasmboy-rs", tag="v0.1.2"}
|
hqx = {git = "https://github.com/CryZe/wasmboy-rs", tag="v0.1.3"}
|
||||||
|
|
||||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
# logging them with `console.error`. This is great for development, but requires
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
# This is intentionally an old version of Rust. Newer versions
|
|
||||||
# generate _significantly_ bigger Wasm binaries.
|
|
||||||
FROM rust:1.37
|
|
||||||
RUN rustup target add wasm32-unknown-unknown
|
|
||||||
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
|
||||||
|
|
||||||
RUN mkdir /opt/binaryen && \
|
|
||||||
curl -L https://github.com/WebAssembly/binaryen/releases/download/1.38.32/binaryen-1.38.32-x86-linux.tar.gz | tar -xzf - -C /opt/binaryen --strip 1
|
|
||||||
|
|
||||||
ENV PATH="/opt/binaryen:${PATH}"
|
|
||||||
WORKDIR /src
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling wasm"
|
|
||||||
echo "============================================="
|
|
||||||
(
|
|
||||||
wasm-pack build -- --verbose --locked
|
|
||||||
rm pkg/.gitignore
|
|
||||||
)
|
|
||||||
echo "============================================="
|
|
||||||
echo "Compiling wasm done"
|
|
||||||
echo "============================================="
|
|
||||||
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
||||||
echo "Did you update your docker image?"
|
|
||||||
echo "Run \`docker pull ubuntu\`"
|
|
||||||
echo "Run \`docker pull rust\`"
|
|
||||||
echo "Run \`docker build -t squoosh-hqx .\`"
|
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hqx",
|
"name": "hqx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:image": "docker build -t squoosh-hqx - < Dockerfile",
|
"build": "../build-rust.sh"
|
||||||
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.sh"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
codecs/hqx/pkg/README.md
Normal file
5
codecs/hqx/pkg/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# HQX
|
||||||
|
|
||||||
|
- Source: <https://github.com/CryZe/wasmboy-rs>
|
||||||
|
- Version: v0.1.2
|
||||||
|
- License: Apache 2.0
|
||||||
20
codecs/hqx/pkg/squooshhqx.d.ts
generated
vendored
20
codecs/hqx/pkg/squooshhqx.d.ts
generated
vendored
@@ -8,3 +8,23 @@
|
|||||||
* @returns {Uint32Array}
|
* @returns {Uint32Array}
|
||||||
*/
|
*/
|
||||||
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array;
|
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array;
|
||||||
|
|
||||||
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
|
|
||||||
|
export interface InitOutput {
|
||||||
|
readonly memory: WebAssembly.Memory;
|
||||||
|
readonly resize: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
||||||
|
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||||
|
readonly __wbindgen_malloc: (a: number) => number;
|
||||||
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||||
|
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||||
|
*
|
||||||
|
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||||
|
*
|
||||||
|
* @returns {Promise<InitOutput>}
|
||||||
|
*/
|
||||||
|
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||||
|
|||||||
110
codecs/hqx/pkg/squooshhqx.js
generated
110
codecs/hqx/pkg/squooshhqx.js
generated
@@ -1,2 +1,108 @@
|
|||||||
import * as wasm from "./squooshhqx_bg.wasm";
|
|
||||||
export * from "./squooshhqx_bg.js";
|
let wasm;
|
||||||
|
|
||||||
|
let cachegetUint32Memory0 = null;
|
||||||
|
function getUint32Memory0() {
|
||||||
|
if (cachegetUint32Memory0 === null || cachegetUint32Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint32Memory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
|
function passArray32ToWasm0(arg, malloc) {
|
||||||
|
const ptr = malloc(arg.length * 4);
|
||||||
|
getUint32Memory0().set(arg, ptr / 4);
|
||||||
|
WASM_VECTOR_LEN = arg.length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetInt32Memory0 = null;
|
||||||
|
function getInt32Memory0() {
|
||||||
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getArrayU32FromWasm0(ptr, len) {
|
||||||
|
return getUint32Memory0().subarray(ptr / 4, ptr / 4 + len);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Uint32Array} input_image
|
||||||
|
* @param {number} input_width
|
||||||
|
* @param {number} input_height
|
||||||
|
* @param {number} factor
|
||||||
|
* @returns {Uint32Array}
|
||||||
|
*/
|
||||||
|
export function resize(input_image, input_width, input_height, factor) {
|
||||||
|
try {
|
||||||
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||||
|
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
wasm.resize(retptr, ptr0, len0, input_width, input_height, factor);
|
||||||
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
|
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
||||||
|
wasm.__wbindgen_free(r0, r1 * 4);
|
||||||
|
return v1;
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function load(module, imports) {
|
||||||
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
|
try {
|
||||||
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||||
|
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = await module.arrayBuffer();
|
||||||
|
return await WebAssembly.instantiate(bytes, imports);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const instance = await WebAssembly.instantiate(module, imports);
|
||||||
|
|
||||||
|
if (instance instanceof WebAssembly.Instance) {
|
||||||
|
return { instance, module };
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init(input) {
|
||||||
|
if (typeof input === 'undefined') {
|
||||||
|
input = new URL('squooshhqx_bg.wasm', import.meta.url);
|
||||||
|
}
|
||||||
|
const imports = {};
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||||
|
input = fetch(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const { instance, module } = await load(await input, imports);
|
||||||
|
|
||||||
|
wasm = instance.exports;
|
||||||
|
init.__wbindgen_wasm_module = module;
|
||||||
|
|
||||||
|
return wasm;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default init;
|
||||||
|
|
||||||
|
|||||||
6
codecs/hqx/pkg/squooshhqx_bg.d.ts
generated
vendored
6
codecs/hqx/pkg/squooshhqx_bg.d.ts
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
export const memory: WebAssembly.Memory;
|
|
||||||
export function resize(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
||||||
export function __wbindgen_malloc(a: number): number;
|
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
|
||||||
48
codecs/hqx/pkg/squooshhqx_bg.js
generated
48
codecs/hqx/pkg/squooshhqx_bg.js
generated
@@ -1,48 +0,0 @@
|
|||||||
import * as wasm from './squooshhqx_bg.wasm';
|
|
||||||
|
|
||||||
let cachegetUint32Memory0 = null;
|
|
||||||
function getUint32Memory0() {
|
|
||||||
if (cachegetUint32Memory0 === null || cachegetUint32Memory0.buffer !== wasm.memory.buffer) {
|
|
||||||
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
|
|
||||||
}
|
|
||||||
return cachegetUint32Memory0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
|
||||||
|
|
||||||
function passArray32ToWasm0(arg, malloc) {
|
|
||||||
const ptr = malloc(arg.length * 4);
|
|
||||||
getUint32Memory0().set(arg, ptr / 4);
|
|
||||||
WASM_VECTOR_LEN = arg.length;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachegetInt32Memory0 = null;
|
|
||||||
function getInt32Memory0() {
|
|
||||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
|
||||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
|
||||||
}
|
|
||||||
return cachegetInt32Memory0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getArrayU32FromWasm0(ptr, len) {
|
|
||||||
return getUint32Memory0().subarray(ptr / 4, ptr / 4 + len);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param {Uint32Array} input_image
|
|
||||||
* @param {number} input_width
|
|
||||||
* @param {number} input_height
|
|
||||||
* @param {number} factor
|
|
||||||
* @returns {Uint32Array}
|
|
||||||
*/
|
|
||||||
export function resize(input_image, input_width, input_height, factor) {
|
|
||||||
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
|
|
||||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
|
||||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
|
||||||
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
|
||||||
wasm.__wbindgen_free(r0, r1 * 4);
|
|
||||||
return v1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -2,25 +2,26 @@ CODEC_URL := https://github.com/ImageOptim/libimagequant/archive/2.12.1.tar.gz
|
|||||||
CODEC_DIR := node_modules/libimagequant
|
CODEC_DIR := node_modules/libimagequant
|
||||||
CODEC_OUT_RELATIVE := libimagequant.a
|
CODEC_OUT_RELATIVE := libimagequant.a
|
||||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||||
OUT_JS := imagequant.js
|
OUT_JS := imagequant.js imagequant_node.js
|
||||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||||
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_JS)
|
all: $(OUT_JS)
|
||||||
|
|
||||||
%.js: %.cpp $(CODEC_OUT)
|
imagequant_node.js: ENVIRONMENT=node
|
||||||
|
$(OUT_JS): $(CODEC_OUT)
|
||||||
$(CXX) \
|
$(CXX) \
|
||||||
-I $(CODEC_DIR) \
|
-I $(CODEC_DIR) \
|
||||||
${CXXFLAGS} \
|
${CXXFLAGS} \
|
||||||
${LDFLAGS} \
|
${LDFLAGS} \
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+ \
|
||||||
|
imagequant.cpp
|
||||||
|
|
||||||
$(CODEC_OUT): $(CODEC_DIR)/config.mk
|
$(CODEC_OUT): $(CODEC_DIR)/config.mk
|
||||||
$(MAKE) -C $(CODEC_DIR) $(CODEC_OUT_RELATIVE)
|
$(MAKE) -C $(CODEC_DIR) $(CODEC_OUT_RELATIVE)
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<style>
|
<style>
|
||||||
canvas {
|
canvas {
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src='imagequant.js'></script>
|
<script type="module">
|
||||||
<script>
|
import imagequant from './imagequant.js';
|
||||||
const Module = imagequant();
|
|
||||||
|
|
||||||
async function loadImage(src) {
|
async function loadImage(src) {
|
||||||
// Load image
|
// Load image
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = src;
|
img.src = src;
|
||||||
await new Promise(resolve => img.onload = resolve);
|
await new Promise((resolve) => (img.onload = resolve));
|
||||||
// Make canvas same size as image
|
// Make canvas same size as image
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
[canvas.width, canvas.height] = [img.width, img.height];
|
[canvas.width, canvas.height] = [img.width, img.height];
|
||||||
@@ -22,19 +21,32 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
return ctx.getImageData(0, 0, img.width, img.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Module.onRuntimeInitialized = async _ => {
|
async function main() {
|
||||||
console.log('Version:', Module.version().toString(16));
|
const module = await imagequant();
|
||||||
|
|
||||||
|
console.log('Version:', module.version().toString(16));
|
||||||
const image = await loadImage('../example.png');
|
const image = await loadImage('../example.png');
|
||||||
// const rawImage = Module.quantize(image.data, image.width, image.height, 256, 1.0);
|
const rawImage = module.quantize(
|
||||||
const rawImage = Module.zx_quantize(image.data, image.width, image.height, 1.0);
|
image.data,
|
||||||
|
image.width,
|
||||||
|
image.height,
|
||||||
|
256,
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
console.log('done');
|
console.log('done');
|
||||||
|
|
||||||
const imageData = new ImageData(new Uint8ClampedArray(rawImage.buffer), image.width, image.height);
|
const imageData = new ImageData(
|
||||||
|
new Uint8ClampedArray(rawImage.buffer),
|
||||||
|
image.width,
|
||||||
|
image.height,
|
||||||
|
);
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = image.width;
|
canvas.width = image.width;
|
||||||
canvas.height = image.height;
|
canvas.height = image.height;
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.putImageData(imageData, 0, 0);
|
ctx.putImageData(imageData, 0, 0);
|
||||||
document.body.appendChild(canvas);
|
document.body.appendChild(canvas);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
21
codecs/imagequant/imagequant.d.ts
vendored
21
codecs/imagequant/imagequant.d.ts
vendored
@@ -1,6 +1,19 @@
|
|||||||
interface QuantizerModule extends EmscriptenWasm.Module {
|
export interface QuantizerModule extends EmscriptenWasm.Module {
|
||||||
quantize(data: BufferSource, width: number, height: number, numColors: number, dither: number): Uint8ClampedArray;
|
quantize(
|
||||||
zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray;
|
data: BufferSource,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
numColors: number,
|
||||||
|
dither: number,
|
||||||
|
): Uint8ClampedArray;
|
||||||
|
zx_quantize(
|
||||||
|
data: BufferSource,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
dither: number,
|
||||||
|
): Uint8ClampedArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<QuantizerModule>;
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QuantizerModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
70
codecs/imagequant/imagequant.js
generated
70
codecs/imagequant/imagequant.js
generated
File diff suppressed because one or more lines are too long
BIN
codecs/imagequant/imagequant.wasm
Normal file → Executable file
BIN
codecs/imagequant/imagequant.wasm
Normal file → Executable file
Binary file not shown.
16
codecs/imagequant/imagequant_node.js
generated
Normal file
16
codecs/imagequant/imagequant_node.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/imagequant/imagequant_node.wasm
Executable file
BIN
codecs/imagequant/imagequant_node.wasm
Executable file
Binary file not shown.
@@ -1,66 +1,90 @@
|
|||||||
CODEC_URL = https://gitlab.com/wg1/jpeg-xl.git
|
CODEC_URL = https://github.com/libjxl/libjxl.git
|
||||||
CODEC_VERSION = 4d70bd58fbcb758b61446aba447fedd9177a00c9
|
CODEC_VERSION = v0.5
|
||||||
CODEC_DIR = node_modules/jxl
|
CODEC_DIR = node_modules/jxl
|
||||||
CODEC_BUILD_DIR := $(CODEC_DIR)/build
|
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
|
||||||
CODEC_OUT := $(CODEC_BUILD_DIR)/lib/libjxl.a
|
CODEC_MT_BUILD_DIR := $(CODEC_BUILD_ROOT)/mt
|
||||||
|
CODEC_MT_SIMD_BUILD_DIR := $(CODEC_BUILD_ROOT)/mt-simd
|
||||||
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
OUT_JS = enc/jxl_enc.js dec/jxl_dec.js
|
OUT_JS = enc/jxl_enc.js enc/jxl_enc_mt.js enc/jxl_enc_mt_simd.js dec/jxl_dec.js enc/jxl_node_enc.js dec/jxl_node_dec.js
|
||||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||||
|
OUT_WORKER = $(OUT_JS:.js=.worker.js)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_JS)
|
all: $(OUT_JS)
|
||||||
|
|
||||||
%.js: %.cpp $(LIBAOM_OUT) $(CODEC_OUT)
|
# Define dependencies for all variations of build artifacts.
|
||||||
|
$(filter enc/%,$(OUT_JS)): enc/jxl_enc.cpp
|
||||||
|
$(filter dec/%,$(OUT_JS)): dec/jxl_dec.cpp
|
||||||
|
|
||||||
|
enc/jxl_node_enc.js dec/jxl_node_dec.js: ENVIRONMENT = node
|
||||||
|
|
||||||
|
# For single-threaded build, we compile with threads enabled, but then just don't use them nor link them in.
|
||||||
|
enc/jxl_enc.js enc/jxl_node_enc.js enc/jxl_enc_mt.js dec/jxl_dec.js dec/jxl_node_dec.js: CODEC_BUILD_DIR:=$(CODEC_MT_BUILD_DIR)
|
||||||
|
enc/jxl_enc_mt_simd.js: CODEC_BUILD_DIR:=$(CODEC_MT_SIMD_BUILD_DIR)
|
||||||
|
|
||||||
|
enc/jxl_node_enc.js dec/jxl_node_dec.js enc/jxl_enc.js dec/jxl_dec.js: $(CODEC_MT_BUILD_DIR)/lib/libjxl.a
|
||||||
|
enc/jxl_enc_mt.js: $(CODEC_MT_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_BUILD_DIR)/lib/libjxl_threads.a
|
||||||
|
enc/jxl_enc_mt_simd.js: $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl_threads.a
|
||||||
|
|
||||||
|
# Disable errors on deprecated SIMD intrinsics.
|
||||||
|
# JPEG-XL & Highway need to catch up, once they do, we can remove this suppression.
|
||||||
|
export CXXFLAGS += -Wno-deprecated-declarations
|
||||||
|
|
||||||
|
# Compile multithreaded wrappers with -pthread.
|
||||||
|
enc/jxl_enc_mt.js enc/jxl_enc_mt_simd.js: CXXFLAGS+=-pthread
|
||||||
|
|
||||||
|
$(OUT_JS):
|
||||||
$(CXX) \
|
$(CXX) \
|
||||||
|
$(CXXFLAGS) \
|
||||||
|
$(LDFLAGS) \
|
||||||
-I $(CODEC_DIR) \
|
-I $(CODEC_DIR) \
|
||||||
-I $(CODEC_DIR)/lib \
|
-I $(CODEC_DIR)/lib \
|
||||||
-I $(CODEC_DIR)/lib/include \
|
-I $(CODEC_DIR)/lib/include \
|
||||||
-I $(CODEC_BUILD_DIR)/lib/include \
|
-I $(CODEC_BUILD_DIR)/lib/include \
|
||||||
-I $(CODEC_DIR)/third_party/highway \
|
-I $(CODEC_DIR)/third_party/highway \
|
||||||
-I $(CODEC_DIR)/third_party/skcms \
|
-I $(CODEC_DIR)/third_party/skcms \
|
||||||
-I $(CODEC_DIR)/third_party/brunsli \
|
|
||||||
-I $(CODEC_DIR)/third_party/brunsli/c/include \
|
|
||||||
${CXXFLAGS} \
|
|
||||||
${LDFLAGS} \
|
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+ \
|
$+ \
|
||||||
$(CODEC_BUILD_DIR)/artifacts/libbrunslienc-static.bc \
|
|
||||||
$(CODEC_BUILD_DIR)/artifacts/libbrunslicommon-static.bc \
|
|
||||||
$(CODEC_BUILD_DIR)/artifacts/libbrunslidec-static.bc \
|
|
||||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlidec-static.a \
|
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlidec-static.a \
|
||||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlienc-static.a \
|
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlienc-static.a \
|
||||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlicommon-static.a \
|
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlicommon-static.a \
|
||||||
$(CODEC_BUILD_DIR)/third_party/libskcms.a \
|
$(CODEC_BUILD_DIR)/third_party/libskcms.a \
|
||||||
$(CODEC_BUILD_DIR)/third_party/highway/libhwy.a
|
$(CODEC_BUILD_DIR)/third_party/highway/libhwy.a
|
||||||
|
|
||||||
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt
|
%/lib/libjxl.a: %/Makefile
|
||||||
mkdir -p $(CODEC_BUILD_DIR)
|
$(MAKE) -C $(<D) jxl-static
|
||||||
cd $(CODEC_BUILD_DIR) && \
|
|
||||||
emcmake cmake ../ && \
|
|
||||||
$(MAKE) jxl-static
|
|
||||||
|
|
||||||
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_DIR)
|
%/lib/libjxl_threads.a: %/Makefile
|
||||||
|
$(MAKE) -C $(<D) jxl_threads-static
|
||||||
|
|
||||||
$(CODEC_DIR):
|
# Enable SIMD on a SIMD build.
|
||||||
# The JXL repository doesn’t have version tags or anything yet,
|
$(CODEC_MT_SIMD_BUILD_DIR)/Makefile: CXXFLAGS+=-msimd128
|
||||||
# so we have to pin to a specific commit for now. This implies we
|
|
||||||
# can’t use --recursive, as we will change commit after checkout (it
|
%/Makefile: $(CODEC_DIR)/CMakeLists.txt
|
||||||
# seems you can’t clone a specific commit directly), and it also means
|
emcmake cmake \
|
||||||
# we can’t use --depth 1 because we want to change commits.
|
$(CMAKE_FLAGS) \
|
||||||
# The JXL code base also relies on submodules so we can’t just download
|
-DBUILD_SHARED_LIBS=0 \
|
||||||
# a .tar.gz from GitLab.
|
-DJPEGXL_ENABLE_BENCHMARK=0 \
|
||||||
mkdir -p $@
|
-DJPEGXL_ENABLE_EXAMPLES=0 \
|
||||||
git clone $(CODEC_URL) $@
|
-DBUILD_TESTING=0 \
|
||||||
cd $@ && \
|
-DCMAKE_CROSSCOMPILING_EMULATOR=node \
|
||||||
git reset --hard $(CODEC_VERSION) && \
|
-B $(@D) \
|
||||||
git submodule update --init --recursive
|
$(<D)
|
||||||
|
|
||||||
|
$(CODEC_DIR)/CMakeLists.txt:
|
||||||
|
$(RM) -r $(@D)
|
||||||
|
git init $(@D)
|
||||||
|
git -C $(@D) fetch $(CODEC_URL) $(CODEC_VERSION) --depth 1
|
||||||
|
git -C $(@D) checkout FETCH_HEAD
|
||||||
|
git -C $(@D) submodule update --init --depth 1 --recursive --jobs `nproc`
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
$(RM) $(OUT_JS) $(OUT_WASM) $(OUT_WORKER)
|
||||||
$(MAKE) -C $(CODEC_BUILD_DIR) clean
|
$(MAKE) -C $(CODEC_BUILD_DIR) clean
|
||||||
|
$(MAKE) -C $(CODEC_MT_BUILD_DIR) clean
|
||||||
|
$(MAKE) -C $(CODEC_MT_SIMD_BUILD_DIR) clean
|
||||||
|
|||||||
@@ -14,11 +14,33 @@ thread_local const val ImageData = val::global("ImageData");
|
|||||||
// R, G, B, A
|
// R, G, B, A
|
||||||
#define COMPONENTS_PER_PIXEL 4
|
#define COMPONENTS_PER_PIXEL 4
|
||||||
|
|
||||||
|
#ifndef JXL_DEBUG_ON_ALL_ERROR
|
||||||
|
#define JXL_DEBUG_ON_ALL_ERROR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if JXL_DEBUG_ON_ALL_ERROR
|
||||||
#define EXPECT_TRUE(a) \
|
#define EXPECT_TRUE(a) \
|
||||||
if (!(a)) \
|
if (!(a)) { \
|
||||||
return val::null();
|
fprintf(stderr, "Assertion failure (%d): %s\n", __LINE__, #a); \
|
||||||
|
return val::null(); \
|
||||||
|
}
|
||||||
|
#define EXPECT_EQ(a, b) \
|
||||||
|
{ \
|
||||||
|
int a_ = a; \
|
||||||
|
int b_ = b; \
|
||||||
|
if (a_ != b_) { \
|
||||||
|
fprintf(stderr, "Assertion failure (%d): %s (%d) != %s (%d)\n", __LINE__, #a, a_, #b, b_); \
|
||||||
|
return val::null(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define EXPECT_TRUE(a) \
|
||||||
|
if (!(a)) { \
|
||||||
|
return val::null(); \
|
||||||
|
}
|
||||||
|
|
||||||
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b));
|
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b));
|
||||||
|
#endif
|
||||||
|
|
||||||
val decode(std::string data) {
|
val decode(std::string data) {
|
||||||
std::unique_ptr<JxlDecoder,
|
std::unique_ptr<JxlDecoder,
|
||||||
@@ -30,40 +52,37 @@ val decode(std::string data) {
|
|||||||
|
|
||||||
auto next_in = (const uint8_t*)data.c_str();
|
auto next_in = (const uint8_t*)data.c_str();
|
||||||
auto avail_in = data.size();
|
auto avail_in = data.size();
|
||||||
EXPECT_EQ(JXL_DEC_BASIC_INFO, JxlDecoderProcessInput(dec.get(), &next_in, &avail_in));
|
JxlDecoderSetInput(dec.get(), next_in, avail_in);
|
||||||
|
EXPECT_EQ(JXL_DEC_BASIC_INFO, JxlDecoderProcessInput(dec.get()));
|
||||||
JxlBasicInfo info;
|
JxlBasicInfo info;
|
||||||
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetBasicInfo(dec.get(), &info));
|
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetBasicInfo(dec.get(), &info));
|
||||||
size_t pixel_count = info.xsize * info.ysize;
|
size_t pixel_count = info.xsize * info.ysize;
|
||||||
size_t component_count = pixel_count * COMPONENTS_PER_PIXEL;
|
size_t component_count = pixel_count * COMPONENTS_PER_PIXEL;
|
||||||
|
|
||||||
EXPECT_EQ(JXL_DEC_COLOR_ENCODING, JxlDecoderProcessInput(dec.get(), &next_in, &avail_in));
|
EXPECT_EQ(JXL_DEC_COLOR_ENCODING, JxlDecoderProcessInput(dec.get()));
|
||||||
|
static const JxlPixelFormat format = {COMPONENTS_PER_PIXEL, JXL_TYPE_FLOAT, JXL_LITTLE_ENDIAN, 0};
|
||||||
size_t icc_size;
|
size_t icc_size;
|
||||||
EXPECT_EQ(JXL_DEC_SUCCESS,
|
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetICCProfileSize(dec.get(), &format,
|
||||||
JxlDecoderGetICCProfileSize(dec.get(), JXL_COLOR_PROFILE_TARGET_DATA, &icc_size));
|
JXL_COLOR_PROFILE_TARGET_DATA, &icc_size));
|
||||||
std::vector<uint8_t> icc_profile(icc_size);
|
std::vector<uint8_t> icc_profile(icc_size);
|
||||||
EXPECT_EQ(JXL_DEC_SUCCESS,
|
EXPECT_EQ(JXL_DEC_SUCCESS,
|
||||||
JxlDecoderGetColorAsICCProfile(dec.get(), JXL_COLOR_PROFILE_TARGET_DATA,
|
JxlDecoderGetColorAsICCProfile(dec.get(), &format, JXL_COLOR_PROFILE_TARGET_DATA,
|
||||||
icc_profile.data(), icc_profile.size()));
|
icc_profile.data(), icc_profile.size()));
|
||||||
|
|
||||||
|
EXPECT_EQ(JXL_DEC_NEED_IMAGE_OUT_BUFFER, JxlDecoderProcessInput(dec.get()));
|
||||||
|
size_t buffer_size;
|
||||||
|
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size));
|
||||||
|
EXPECT_EQ(buffer_size, component_count * sizeof(float));
|
||||||
|
|
||||||
auto float_pixels = std::make_unique<float[]>(component_count);
|
auto float_pixels = std::make_unique<float[]>(component_count);
|
||||||
static const JxlPixelFormat format = {COMPONENTS_PER_PIXEL, JXL_LITTLE_ENDIAN, JXL_TYPE_FLOAT};
|
|
||||||
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderSetImageOutBuffer(dec.get(), &format, float_pixels.get(),
|
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderSetImageOutBuffer(dec.get(), &format, float_pixels.get(),
|
||||||
component_count * sizeof(float)));
|
component_count * sizeof(float)));
|
||||||
EXPECT_EQ(JXL_DEC_FULL_IMAGE, JxlDecoderProcessInput(dec.get(), &next_in, &avail_in));
|
EXPECT_EQ(JXL_DEC_FULL_IMAGE, JxlDecoderProcessInput(dec.get()));
|
||||||
|
|
||||||
auto byte_pixels = std::make_unique<uint8_t[]>(component_count);
|
auto byte_pixels = std::make_unique<uint8_t[]>(component_count);
|
||||||
// Convert to sRGB.
|
// Convert to sRGB.
|
||||||
skcms_ICCProfile jxl_profile;
|
skcms_ICCProfile jxl_profile;
|
||||||
// If the image is encoded in its original color space, the decoded data will be in the color
|
|
||||||
// space defined by the decoded ICC profile. Otherwise, it is in Linear sRGB. TODO: the decoded
|
|
||||||
// color profile should also be Linear sRGB if !uses_original_profile.
|
|
||||||
if (info.uses_original_profile) {
|
|
||||||
EXPECT_TRUE(skcms_Parse(icc_profile.data(), icc_profile.size(), &jxl_profile));
|
EXPECT_TRUE(skcms_Parse(icc_profile.data(), icc_profile.size(), &jxl_profile));
|
||||||
} else {
|
|
||||||
auto s = jxl::ColorEncoding::LinearSRGB(/*gray=*/false);
|
|
||||||
EXPECT_TRUE(s.CreateICC());
|
|
||||||
EXPECT_TRUE(skcms_Parse(s.ICC().data(), s.ICC().size(), &jxl_profile));
|
|
||||||
}
|
|
||||||
EXPECT_TRUE(skcms_Transform(
|
EXPECT_TRUE(skcms_Transform(
|
||||||
float_pixels.get(), skcms_PixelFormat_RGBA_ffff,
|
float_pixels.get(), skcms_PixelFormat_RGBA_ffff,
|
||||||
info.alpha_premultiplied ? skcms_AlphaFormat_PremulAsEncoded : skcms_AlphaFormat_Unpremul,
|
info.alpha_premultiplied ? skcms_AlphaFormat_PremulAsEncoded : skcms_AlphaFormat_Unpremul,
|
||||||
|
|||||||
6
codecs/jxl/dec/jxl_dec.d.ts
vendored
6
codecs/jxl/dec/jxl_dec.d.ts
vendored
@@ -1,5 +1,7 @@
|
|||||||
interface JXLModule extends EmscriptenWasm.Module {
|
export interface JXLModule extends EmscriptenWasm.Module {
|
||||||
decode(data: BufferSource): ImageData | null;
|
decode(data: BufferSource): ImageData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<JXLModule>;
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<JXLModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
71
codecs/jxl/dec/jxl_dec.js
generated
71
codecs/jxl/dec/jxl_dec.js
generated
File diff suppressed because one or more lines are too long
BIN
codecs/jxl/dec/jxl_dec.wasm
Normal file → Executable file
BIN
codecs/jxl/dec/jxl_dec.wasm
Normal file → Executable file
Binary file not shown.
16
codecs/jxl/dec/jxl_node_dec.js
generated
Normal file
16
codecs/jxl/dec/jxl_node_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/jxl/dec/jxl_node_dec.wasm
Executable file
BIN
codecs/jxl/dec/jxl_node_dec.wasm
Executable file
Binary file not shown.
@@ -1,8 +1,9 @@
|
|||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
|
|
||||||
|
#include "lib/jxl/base/thread_pool_internal.h"
|
||||||
|
#include "lib/jxl/enc_external_image.h"
|
||||||
#include "lib/jxl/enc_file.h"
|
#include "lib/jxl/enc_file.h"
|
||||||
#include "lib/jxl/external_image.h"
|
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
@@ -13,6 +14,11 @@ struct JXLOptions {
|
|||||||
// 7 = fastest
|
// 7 = fastest
|
||||||
int speed;
|
int speed;
|
||||||
float quality;
|
float quality;
|
||||||
|
bool progressive;
|
||||||
|
int epf;
|
||||||
|
int nearLossless;
|
||||||
|
bool lossyPalette;
|
||||||
|
size_t decodingSpeedTier;
|
||||||
};
|
};
|
||||||
|
|
||||||
val encode(std::string image, int width, int height, JXLOptions options) {
|
val encode(std::string image, int width, int height, JXLOptions options) {
|
||||||
@@ -21,26 +27,77 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
jxl::CodecInOut io;
|
jxl::CodecInOut io;
|
||||||
jxl::PaddedBytes bytes;
|
jxl::PaddedBytes bytes;
|
||||||
jxl::ImageBundle* main = &io.Main();
|
jxl::ImageBundle* main = &io.Main();
|
||||||
|
jxl::ThreadPoolInternal* pool_ptr = nullptr;
|
||||||
|
#ifdef __EMSCRIPTEN_PTHREADS__
|
||||||
|
jxl::ThreadPoolInternal pool;
|
||||||
|
pool_ptr = &pool;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cparams.epf = options.epf;
|
||||||
cparams.speed_tier = static_cast<jxl::SpeedTier>(options.speed);
|
cparams.speed_tier = static_cast<jxl::SpeedTier>(options.speed);
|
||||||
cparams.butteraugli_distance = options.quality;
|
cparams.decoding_speed_tier = options.decodingSpeedTier;
|
||||||
|
|
||||||
io.metadata.SetAlphaBits(8);
|
if (options.lossyPalette || options.nearLossless) {
|
||||||
|
cparams.lossy_palette = true;
|
||||||
|
cparams.palette_colors = 0;
|
||||||
|
cparams.options.predictor = jxl::Predictor::Zero;
|
||||||
|
// Near-lossless assumes -R 0
|
||||||
|
cparams.responsive = 0;
|
||||||
|
cparams.modular_mode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float quality = options.quality;
|
||||||
|
|
||||||
|
// Quality settings roughly match libjpeg qualities.
|
||||||
|
if (quality < 7 || quality == 100) {
|
||||||
|
cparams.modular_mode = true;
|
||||||
|
// Internal modular quality to roughly match VarDCT size.
|
||||||
|
cparams.quality_pair.first = cparams.quality_pair.second =
|
||||||
|
std::min(35 + (quality - 7) * 3.0f, 100.0f);
|
||||||
|
} else {
|
||||||
|
cparams.modular_mode = false;
|
||||||
|
if (quality >= 30) {
|
||||||
|
cparams.butteraugli_distance = 0.1 + (100 - quality) * 0.09;
|
||||||
|
} else {
|
||||||
|
cparams.butteraugli_distance = 6.4 + pow(2.5, (30 - quality) / 5.0f) / 6.25f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.progressive) {
|
||||||
|
cparams.qprogressive_mode = true;
|
||||||
|
cparams.responsive = 1;
|
||||||
|
if (!cparams.modular_mode) {
|
||||||
|
cparams.progressive_dc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cparams.modular_mode) {
|
||||||
|
if (cparams.quality_pair.first != 100 || cparams.quality_pair.second != 100) {
|
||||||
|
cparams.color_transform = jxl::ColorTransform::kXYB;
|
||||||
|
} else {
|
||||||
|
cparams.color_transform = jxl::ColorTransform::kNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io.metadata.m.SetAlphaBits(8);
|
||||||
|
if (!io.metadata.size.Set(width, height)) {
|
||||||
|
return val::null();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* inBuffer = (uint8_t*)image.c_str();
|
uint8_t* inBuffer = (uint8_t*)image.c_str();
|
||||||
|
|
||||||
auto result = jxl::ConvertImage(
|
auto result = jxl::ConvertFromExternal(
|
||||||
jxl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(image.data()), image.size()), width,
|
jxl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(image.data()), image.size()), width,
|
||||||
height, jxl::ColorEncoding::SRGB(/*is_gray=*/false), /*has_alpha=*/true,
|
height, jxl::ColorEncoding::SRGB(/*is_gray=*/false), /*has_alpha=*/true,
|
||||||
/*alpha_is_premultiplied=*/false, /*bits_per_alpha=*/8, /*bits_per_sample=*/8,
|
/*alpha_is_premultiplied=*/false, /*bits_per_sample=*/8, /*endiannes=*/JXL_LITTLE_ENDIAN,
|
||||||
/*big_endian=*/false, /*flipped_y=*/false, /*pool=*/nullptr, main);
|
/*flipped_y=*/false, pool_ptr, main);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return val::null();
|
return val::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto js_result = val::null();
|
auto js_result = val::null();
|
||||||
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes)) {
|
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, /*aux=*/nullptr, pool_ptr)) {
|
||||||
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
|
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +107,12 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<JXLOptions>("JXLOptions")
|
value_object<JXLOptions>("JXLOptions")
|
||||||
.field("speed", &JXLOptions::speed)
|
.field("speed", &JXLOptions::speed)
|
||||||
.field("quality", &JXLOptions::quality);
|
.field("quality", &JXLOptions::quality)
|
||||||
|
.field("progressive", &JXLOptions::progressive)
|
||||||
|
.field("nearLossless", &JXLOptions::nearLossless)
|
||||||
|
.field("lossyPalette", &JXLOptions::lossyPalette)
|
||||||
|
.field("decodingSpeedTier", &JXLOptions::decodingSpeedTier)
|
||||||
|
.field("epf", &JXLOptions::epf);
|
||||||
|
|
||||||
function("encode", &encode);
|
function("encode", &encode);
|
||||||
}
|
}
|
||||||
|
|||||||
25
codecs/jxl/enc/jxl_enc.d.ts
vendored
25
codecs/jxl/enc/jxl_enc.d.ts
vendored
@@ -1,7 +1,22 @@
|
|||||||
import { EncodeOptions } from '../../../src/codecs/jxl/encoder-meta';
|
export interface EncodeOptions {
|
||||||
|
speed: number;
|
||||||
interface JXLModule extends EmscriptenWasm.Module {
|
quality: number;
|
||||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
progressive: boolean;
|
||||||
|
epf: number;
|
||||||
|
nearLossless: number;
|
||||||
|
lossyPalette: boolean;
|
||||||
|
decodingSpeedTier: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<JXLModule>;
|
export interface JXLModule extends EmscriptenWasm.Module {
|
||||||
|
encode(
|
||||||
|
data: BufferSource,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
options: EncodeOptions,
|
||||||
|
): Uint8Array | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<JXLModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
117
codecs/jxl/enc/jxl_enc.js
generated
117
codecs/jxl/enc/jxl_enc.js
generated
File diff suppressed because one or more lines are too long
BIN
codecs/jxl/enc/jxl_enc.wasm
Normal file → Executable file
BIN
codecs/jxl/enc/jxl_enc.wasm
Normal file → Executable file
Binary file not shown.
1
codecs/jxl/enc/jxl_enc_mt.d.ts
vendored
Normal file
1
codecs/jxl/enc/jxl_enc_mt.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './jxl_enc';
|
||||||
16
codecs/jxl/enc/jxl_enc_mt.js
generated
Normal file
16
codecs/jxl/enc/jxl_enc_mt.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/jxl/enc/jxl_enc_mt.wasm
Executable file
BIN
codecs/jxl/enc/jxl_enc_mt.wasm
Executable file
Binary file not shown.
1
codecs/jxl/enc/jxl_enc_mt.worker.js
generated
Normal file
1
codecs/jxl/enc/jxl_enc_mt.worker.js
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./jxl_enc_mt.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
1
codecs/jxl/enc/jxl_enc_mt_simd.d.ts
vendored
Normal file
1
codecs/jxl/enc/jxl_enc_mt_simd.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from './jxl_enc';
|
||||||
16
codecs/jxl/enc/jxl_enc_mt_simd.js
generated
Normal file
16
codecs/jxl/enc/jxl_enc_mt_simd.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/jxl/enc/jxl_enc_mt_simd.wasm
Executable file
BIN
codecs/jxl/enc/jxl_enc_mt_simd.wasm
Executable file
Binary file not shown.
1
codecs/jxl/enc/jxl_enc_mt_simd.worker.js
generated
Normal file
1
codecs/jxl/enc/jxl_enc_mt_simd.worker.js
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./jxl_enc_mt_simd.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
16
codecs/jxl/enc/jxl_node_enc.js
generated
Normal file
16
codecs/jxl/enc/jxl_node_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/jxl/enc/jxl_node_enc.wasm
Executable file
BIN
codecs/jxl/enc/jxl_node_enc.wasm
Executable file
Binary file not shown.
@@ -2,23 +2,29 @@ CODEC_URL := https://github.com/mozilla/mozjpeg/archive/v3.3.1.tar.gz
|
|||||||
CODEC_DIR := node_modules/mozjpeg
|
CODEC_DIR := node_modules/mozjpeg
|
||||||
CODEC_OUT_RELATIVE := .libs/libjpeg.a rdswitch.o
|
CODEC_OUT_RELATIVE := .libs/libjpeg.a rdswitch.o
|
||||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||||
OUT_JS := mozjpeg_enc.js
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
|
OUT_JS := enc/mozjpeg_enc.js enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js
|
||||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_JS)
|
all: $(OUT_JS)
|
||||||
|
|
||||||
%.js: %.cpp $(CODEC_OUT)
|
# Define dependencies for all variations of build artifacts.
|
||||||
|
$(filter enc/%,$(OUT_JS)): enc/mozjpeg_enc.cpp
|
||||||
|
$(filter dec/%,$(OUT_JS)): dec/mozjpeg_dec.cpp
|
||||||
|
|
||||||
|
enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js: ENVIRONMENT = node
|
||||||
|
|
||||||
|
%.js: $(CODEC_OUT)
|
||||||
$(CXX) \
|
$(CXX) \
|
||||||
-I $(CODEC_DIR) \
|
-I $(CODEC_DIR) \
|
||||||
${CXXFLAGS} \
|
${CXXFLAGS} \
|
||||||
${LDFLAGS} \
|
${LDFLAGS} \
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
@@ -36,7 +42,10 @@ $(CODEC_DIR)/Makefile: $(CODEC_DIR)/configure
|
|||||||
--without-turbojpeg \
|
--without-turbojpeg \
|
||||||
--without-simd \
|
--without-simd \
|
||||||
--without-arith-enc \
|
--without-arith-enc \
|
||||||
--without-arith-dec
|
--without-arith-dec \
|
||||||
|
--with-build-date=squoosh
|
||||||
|
# ^ If not provided with a dummy value, MozJPEG includes a build date in the
|
||||||
|
# binary as part of the version string, making binaries different each time.
|
||||||
|
|
||||||
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
|
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
|
||||||
cd $(CODEC_DIR) && autoreconf -iv
|
cd $(CODEC_DIR) && autoreconf -iv
|
||||||
57
codecs/mozjpeg/dec/mozjpeg_dec.cpp
Normal file
57
codecs/mozjpeg/dec/mozjpeg_dec.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "jpeglib.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "cdjpeg.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace emscripten;
|
||||||
|
|
||||||
|
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||||
|
thread_local const val ImageData = val::global("ImageData");
|
||||||
|
|
||||||
|
val decode(std::string image_in) {
|
||||||
|
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||||
|
|
||||||
|
jpeg_decompress_struct cinfo;
|
||||||
|
jpeg_error_mgr jerr;
|
||||||
|
// Initialize the JPEG decompression object with default error handling.
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
|
jpeg_mem_src(&cinfo, image_buffer, image_in.length());
|
||||||
|
// Read file header, set default decompression parameters
|
||||||
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
// Force RGBA decoding, even for grayscale images
|
||||||
|
cinfo.out_color_space = JCS_EXT_RGBA;
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
|
// Prepare output buffer
|
||||||
|
size_t output_size = cinfo.output_width * cinfo.output_height * 4;
|
||||||
|
std::vector<uint8_t> output_buffer(output_size);
|
||||||
|
auto stride = cinfo.output_width * 4;
|
||||||
|
|
||||||
|
// Process data
|
||||||
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
|
uint8_t* ptr = &output_buffer[stride * cinfo.output_scanline];
|
||||||
|
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||||
|
}
|
||||||
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
|
||||||
|
// Step 7: release JPEG compression object
|
||||||
|
|
||||||
|
auto data = Uint8ClampedArray.new_(typed_memory_view(output_size, &output_buffer[0]));
|
||||||
|
auto js_result = ImageData.new_(data, cinfo.output_width, cinfo.output_height);
|
||||||
|
|
||||||
|
// This is an important step since it will release a good deal of memory.
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
|
// And we're done!
|
||||||
|
return js_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
function("decode", &decode);
|
||||||
|
}
|
||||||
16
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
Normal file
16
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/mozjpeg/dec/mozjpeg_node_dec.wasm
Executable file
BIN
codecs/mozjpeg/dec/mozjpeg_node_dec.wasm
Executable file
Binary file not shown.
@@ -141,6 +141,7 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
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_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 0);
|
||||||
|
|
||||||
// A little hacky to build a string for this, but it means we can use
|
// A little hacky to build a string for this, but it means we can use
|
||||||
// set_quality_ratings which does some useful heuristic stuff.
|
// set_quality_ratings which does some useful heuristic stuff.
|
||||||
@@ -157,6 +158,11 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
||||||
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
||||||
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
||||||
|
|
||||||
|
if (opts.chroma_subsample > 2) {
|
||||||
|
// Otherwise encoding fails.
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.baseline && opts.progressive) {
|
if (!opts.baseline && opts.progressive) {
|
||||||
37
codecs/mozjpeg/enc/mozjpeg_enc.d.ts
vendored
Normal file
37
codecs/mozjpeg/enc/mozjpeg_enc.d.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
export const enum MozJpegColorSpace {
|
||||||
|
GRAYSCALE = 1,
|
||||||
|
RGB,
|
||||||
|
YCbCr,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EncodeOptions {
|
||||||
|
quality: number;
|
||||||
|
baseline: boolean;
|
||||||
|
arithmetic: boolean;
|
||||||
|
progressive: boolean;
|
||||||
|
optimize_coding: boolean;
|
||||||
|
smoothing: number;
|
||||||
|
color_space: MozJpegColorSpace;
|
||||||
|
quant_table: number;
|
||||||
|
trellis_multipass: boolean;
|
||||||
|
trellis_opt_zero: boolean;
|
||||||
|
trellis_opt_table: boolean;
|
||||||
|
trellis_loops: number;
|
||||||
|
auto_subsample: boolean;
|
||||||
|
chroma_subsample: number;
|
||||||
|
separate_chroma_quality: boolean;
|
||||||
|
chroma_quality: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||||
|
encode(
|
||||||
|
data: BufferSource,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
options: EncodeOptions,
|
||||||
|
): Uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<MozJPEGModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
16
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
Normal file
16
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user