mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-12 08:47:31 +00:00
Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f72c2ed74 | ||
|
|
19beb1a7ab | ||
|
|
e2514df601 | ||
|
|
9db572e446 | ||
|
|
42ef430cee | ||
|
|
df7b622413 | ||
|
|
5649427670 | ||
|
|
1b24d2f3fa | ||
|
|
e4322bcbc3 | ||
|
|
e217740e53 | ||
|
|
d87eff7645 | ||
|
|
f374068fb2 | ||
|
|
ecc715fe55 | ||
|
|
82caed4277 | ||
|
|
a7dff9475d | ||
|
|
d168f7a447 | ||
|
|
edf9cb755e | ||
|
|
a7503e69a2 | ||
|
|
5a9733563e | ||
|
|
2000e16ba2 | ||
|
|
7dbe0a7714 | ||
|
|
25bc43e409 | ||
|
|
cee51bf355 | ||
|
|
8d6daf0fc4 | ||
|
|
61209d0b62 | ||
|
|
d0b4855022 | ||
|
|
6cb64a59ca | ||
|
|
979fba0af1 | ||
|
|
b1df3e1d54 | ||
|
|
4f6138d97d | ||
|
|
6b6e3724d2 | ||
|
|
8ac5e6f678 | ||
|
|
a930e8d928 | ||
|
|
c814700cd2 | ||
|
|
dfdf2a7f71 | ||
|
|
cd336909fc | ||
|
|
a8bc48f94c | ||
|
|
583117697e | ||
|
|
13a185def2 | ||
|
|
918c596cba | ||
|
|
42594277fd | ||
|
|
97d13de273 | ||
|
|
a1c3304c56 | ||
|
|
7a2fc917c1 | ||
|
|
1c4233b5ae | ||
|
|
4d67ec5a7b | ||
|
|
c24505230d | ||
|
|
2238d1abaf | ||
|
|
65ea02627b | ||
|
|
18b53e2b8a | ||
|
|
66ec763667 | ||
|
|
029eda7b37 | ||
|
|
e6810059ef | ||
|
|
4eba015009 | ||
|
|
dd49a1f23d | ||
|
|
5ecb99992c | ||
|
|
d9c6ebe0a2 | ||
|
|
fba67a7a18 | ||
|
|
129b925098 | ||
|
|
e23bc4d2e5 | ||
|
|
f523a07f01 | ||
|
|
e3f840c6da | ||
|
|
cad09160b6 | ||
|
|
9663c23489 | ||
|
|
95a1b35c91 | ||
|
|
914cdea41d | ||
|
|
6bfce29af6 | ||
|
|
64cad1cc23 | ||
|
|
87f25d909b | ||
|
|
bdfdaf53af | ||
|
|
1ab9e8b3ab | ||
|
|
2718077d3d | ||
|
|
255dfa434a | ||
|
|
0bef05bcd4 | ||
|
|
c4bc369c6b | ||
|
|
68ce8f420d | ||
|
|
27f103fee5 | ||
|
|
c21d3714a8 | ||
|
|
3ea0d88c4f | ||
|
|
00cfdafdf3 | ||
|
|
92f52319da | ||
|
|
023304803f | ||
|
|
6b08cd2355 | ||
|
|
db1a5138e6 | ||
|
|
202d0bc088 | ||
|
|
bdb5b16372 | ||
|
|
30140c2b7a | ||
|
|
10996cdbca | ||
|
|
e5806507d4 | ||
|
|
1c5b44f9a1 |
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -1,2 +1,2 @@
|
||||
/codecs/**/*.js linguist-generated=true
|
||||
/codecs/*/pkg*/*.d.ts linguist-generated=true
|
||||
/codecs/**/*.js linguist-generated -diff
|
||||
/codecs/*/pkg*/*.d.ts linguist-generated
|
||||
|
||||
1
.husky/pre-commit
Executable file
1
.husky/pre-commit
Executable file
@@ -0,0 +1 @@
|
||||
npx lint-staged
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
[Squoosh] is an image compression web app that reduces image sizes through numerous formats.
|
||||
|
||||
# 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
|
||||
|
||||
Squoosh does not send your image to a server. All image compression processes locally.
|
||||
|
||||
3
cli/.gitignore
vendored
3
cli/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
build
|
||||
.DS_Store
|
||||
@@ -1 +0,0 @@
|
||||
node_modules
|
||||
@@ -1,59 +0,0 @@
|
||||
# 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
613
cli/package-lock.json
generated
@@ -1,613 +0,0 @@
|
||||
{
|
||||
"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=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"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
234
cli/src/index.js
@@ -1,234 +0,0 @@
|
||||
#!/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);
|
||||
@@ -14,6 +14,7 @@
|
||||
// for comlink
|
||||
"src/features/**/worker/**/*",
|
||||
"src/features-worker/**/*",
|
||||
"src/features/worker-utils/**/*"
|
||||
"src/features/worker-utils/**/*",
|
||||
"src/worker-shared/**/*"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# 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
|
||||
# using libavif from https://github.com/AOMediaCodec/libavif
|
||||
LIBAVIF_URL = https://github.com/AOMediaCodec/libavif/archive/refs/tags/v1.0.1.tar.gz
|
||||
LIBAVIF_PACKAGE = node_modules/libavif.tar.gz
|
||||
|
||||
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.1.0.tar.gz
|
||||
# using libaom from https://aomedia.googlesource.com/aom
|
||||
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.7.0.tar.gz
|
||||
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
||||
|
||||
export CODEC_DIR = node_modules/libavif
|
||||
@@ -11,7 +11,14 @@ export BUILD_DIR = node_modules/build
|
||||
export LIBAOM_DIR = node_modules/libaom
|
||||
|
||||
override CFLAGS += "-Wno-unused-macros"
|
||||
export
|
||||
|
||||
# We must build libsharpyuv from a specific libwebp commit
|
||||
# See libavif/ext/libsharpyuv.cmd for more detail
|
||||
LIBWEBP_URL_WITH_SHARPYUV = https://chromium.googlesource.com/webm/libwebp/+archive/e2c85878f6a33f29948b43d3492d9cdaf801aa54.tar.gz
|
||||
LIBWEBP_DIR := $(CODEC_DIR)/ext/libwebp
|
||||
LIBSHARPYUV_ST := $(LIBWEBP_DIR)/build_st/libsharpyuv.a
|
||||
LIBSHARPYUV_MT := $(LIBWEBP_DIR)/build_mt/libsharpyuv.a
|
||||
export LIBSHARPYUV := $(LIBWEBP_DIR)/build/libsharpyuv.a
|
||||
|
||||
OUT_ENC_JS = enc/avif_enc.js
|
||||
OUT_NODE_ENC_JS = enc/avif_node_enc.js
|
||||
@@ -28,10 +35,11 @@ HELPER_MAKEFLAGS := -f helper.Makefile
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS) $(OUT_NODE_DEC_JS)
|
||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
||||
|
||||
$(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
|
||||
# ST-Encoding
|
||||
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV_ST)
|
||||
mkdir -p $(LIBWEBP_DIR)/build && cp $(LIBSHARPYUV_ST) $(LIBSHARPYUV)
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
OUT_JS=$@ \
|
||||
@@ -42,9 +50,12 @@ $(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
|
||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||
" \
|
||||
ENVIRONMENT=$(ENVIRONMENT) \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON"
|
||||
|
||||
$(OUT_ENC_MT_JS) $(OUT_NODE_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||
# MT-Encoding
|
||||
# We need to run the ST and MT tasks sequentially to avoid conflicts with the copy of libsharpyuv in the build directory
|
||||
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV_MT) | $(OUT_ENC_JS)
|
||||
mkdir -p $(LIBWEBP_DIR)/build && cp $(LIBSHARPYUV_MT) $(LIBSHARPYUV)
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
OUT_JS=$@ \
|
||||
@@ -54,11 +65,11 @@ $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.t
|
||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||
" \
|
||||
ENVIRONMENT=$(ENVIRONMENT) \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON" \
|
||||
OUT_FLAGS="-pthread"
|
||||
|
||||
$(OUT_NODE_DEC_JS): ENVIRONMENT=node
|
||||
$(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||
# Decoding
|
||||
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
OUT_JS=$@ \
|
||||
@@ -70,22 +81,77 @@ $(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
|
||||
ENVIRONMENT=$(ENVIRONMENT) \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
||||
|
||||
$(CODEC_PACKAGE):
|
||||
mkdir -p $(@D)
|
||||
curl -sL $(CODEC_URL) -o $@
|
||||
# LIBAOM EXTRACTION SECTION
|
||||
|
||||
# Download the libaom tarball
|
||||
$(LIBAOM_PACKAGE):
|
||||
mkdir -p $(@D)
|
||||
curl -sL $(LIBAOM_URL) -o $@
|
||||
|
||||
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_PACKAGE)
|
||||
mkdir -p $(@D)
|
||||
tar xzm --strip 1 -C $(@D) -f $(CODEC_PACKAGE)
|
||||
|
||||
# Extract libaom from the tarball
|
||||
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
|
||||
mkdir -p $(@D)
|
||||
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)
|
||||
|
||||
# LIBAVIF EXTRACTION SECTION
|
||||
|
||||
# Download the libavif tarball
|
||||
$(LIBAVIF_PACKAGE):
|
||||
mkdir -p $(@D)
|
||||
curl -sL $(LIBAVIF_URL) -o $@
|
||||
|
||||
# Extract libavif from the tarball
|
||||
$(CODEC_DIR)/CMakeLists.txt: $(LIBAVIF_PACKAGE)
|
||||
mkdir -p $(@D)
|
||||
tar xzm --strip 1 -C $(@D) -f $(LIBAVIF_PACKAGE)
|
||||
|
||||
# Create libavif/ext/libwebp
|
||||
$(LIBWEBP_DIR)/CMakeLists.txt: $(CODEC_DIR)/CMakeLists.txt
|
||||
mkdir -p $(LIBWEBP_DIR)
|
||||
curl -sL $(LIBWEBP_URL_WITH_SHARPYUV) \
|
||||
| tar xzm -C $(LIBWEBP_DIR)
|
||||
|
||||
# Make libsharpyuv.a for ST-Encoding
|
||||
$(LIBSHARPYUV_ST): $(LIBWEBP_DIR)/CMakeLists.txt
|
||||
mkdir -p $(@D)
|
||||
emcmake cmake \
|
||||
-DWEBP_USE_THREAD=OFF \
|
||||
-DWEBP_BUILD_ANIM_UTILS=OFF \
|
||||
-DWEBP_BUILD_CWEBP=OFF \
|
||||
-DWEBP_BUILD_DWEBP=OFF \
|
||||
-DWEBP_BUILD_GIF2WEBP=OFF \
|
||||
-DWEBP_BUILD_IMG2WEBP=OFF \
|
||||
-DWEBP_BUILD_VWEBP=OFF \
|
||||
-DWEBP_BUILD_WEBPINFO=OFF \
|
||||
-DWEBP_BUILD_LIBWEBPMUX=OFF \
|
||||
-DWEBP_BUILD_WEBPMUX=OFF \
|
||||
-DWEBP_BUILD_EXTRAS=OFF \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-S $(LIBWEBP_DIR) \
|
||||
-B $(@D)
|
||||
$(MAKE) -C $(@D) sharpyuv
|
||||
|
||||
# Make libsharpyuv.a for MT-Encoding
|
||||
$(LIBSHARPYUV_MT): $(LIBWEBP_DIR)/CMakeLists.txt
|
||||
mkdir -p $(@D)
|
||||
emcmake cmake \
|
||||
-DWEBP_BUILD_ANIM_UTILS=OFF \
|
||||
-DWEBP_BUILD_CWEBP=OFF \
|
||||
-DWEBP_BUILD_DWEBP=OFF \
|
||||
-DWEBP_BUILD_GIF2WEBP=OFF \
|
||||
-DWEBP_BUILD_IMG2WEBP=OFF \
|
||||
-DWEBP_BUILD_VWEBP=OFF \
|
||||
-DWEBP_BUILD_WEBPINFO=OFF \
|
||||
-DWEBP_BUILD_LIBWEBPMUX=OFF \
|
||||
-DWEBP_BUILD_WEBPMUX=OFF \
|
||||
-DWEBP_BUILD_EXTRAS=OFF \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-S $(LIBWEBP_DIR) \
|
||||
-B $(@D)
|
||||
$(MAKE) -C $(@D) sharpyuv
|
||||
|
||||
clean:
|
||||
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_JS) clean
|
||||
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_MT_JS) clean
|
||||
|
||||
2
codecs/avif/dec/avif_dec.js
generated
2
codecs/avif/dec/avif_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/avif/dec/avif_node_dec.js
generated
2
codecs/avif/dec/avif_node_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -3,15 +3,27 @@
|
||||
#include <emscripten/val.h>
|
||||
#include "avif/avif.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#define RETURN_NULL_IF(expression) \
|
||||
do { \
|
||||
if (expression) \
|
||||
return val::null(); \
|
||||
} while (false)
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
using AvifImagePtr = std::unique_ptr<avifImage, decltype(&avifImageDestroy)>;
|
||||
using AvifEncoderPtr = std::unique_ptr<avifEncoder, decltype(&avifEncoderDestroy)>;
|
||||
|
||||
struct AvifOptions {
|
||||
// [0 - 63]
|
||||
// 0 = lossless
|
||||
// 63 = worst quality
|
||||
int cqLevel;
|
||||
// As above, but -1 means 'use cqLevel'
|
||||
int cqAlphaLevel;
|
||||
// [0 - 100]
|
||||
// 0 = worst quality
|
||||
// 100 = lossless
|
||||
int quality;
|
||||
// As above, but -1 means 'use quality'
|
||||
int qualityAlpha;
|
||||
// [0 - 6]
|
||||
// Creates 2^n tiles in that dimension
|
||||
int tileRowsLog2;
|
||||
@@ -35,12 +47,15 @@ struct AvifOptions {
|
||||
int tune;
|
||||
// 0-50
|
||||
int denoiseLevel;
|
||||
// toggles AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV
|
||||
bool enableSharpYUV;
|
||||
};
|
||||
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
val encode(std::string buffer, int width, int height, AvifOptions options) {
|
||||
avifRWData output = AVIF_DATA_EMPTY;
|
||||
avifResult status; // To check the return status for avif API's
|
||||
|
||||
int depth = 8;
|
||||
avifPixelFormat format;
|
||||
switch (options.subsample) {
|
||||
@@ -58,11 +73,13 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool lossless = options.cqLevel == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.cqAlphaLevel <= AVIF_QUANTIZER_LOSSLESS &&
|
||||
bool lossless = options.quality == AVIF_QUALITY_LOSSLESS &&
|
||||
(options.qualityAlpha == -1 || options.qualityAlpha == AVIF_QUALITY_LOSSLESS) &&
|
||||
format == AVIF_PIXEL_FORMAT_YUV444;
|
||||
|
||||
avifImage* image = avifImageCreate(width, height, depth, format);
|
||||
// Smart pointer for the input image in YUV format
|
||||
AvifImagePtr image(avifImageCreate(width, height, depth, format), avifImageDestroy);
|
||||
RETURN_NULL_IF(image == nullptr);
|
||||
|
||||
if (lossless) {
|
||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
||||
@@ -73,43 +90,49 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
||||
uint8_t* rgba = reinterpret_cast<uint8_t*>(const_cast<char*>(buffer.data()));
|
||||
|
||||
avifRGBImage srcRGB;
|
||||
avifRGBImageSetDefaults(&srcRGB, image);
|
||||
avifRGBImageSetDefaults(&srcRGB, image.get());
|
||||
srcRGB.pixels = rgba;
|
||||
srcRGB.rowBytes = width * 4;
|
||||
avifImageRGBToYUV(image, &srcRGB);
|
||||
if (options.enableSharpYUV) {
|
||||
srcRGB.chromaDownsampling = AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV;
|
||||
}
|
||||
status = avifImageRGBToYUV(image.get(), &srcRGB);
|
||||
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||
|
||||
avifEncoder* encoder = avifEncoderCreate();
|
||||
// Create a smart pointer for the encoder
|
||||
AvifEncoderPtr encoder(avifEncoderCreate(), avifEncoderDestroy);
|
||||
RETURN_NULL_IF(encoder == nullptr);
|
||||
|
||||
if (lossless) {
|
||||
encoder->minQuantizer = AVIF_QUANTIZER_LOSSLESS;
|
||||
encoder->maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
|
||||
encoder->minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
||||
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
||||
encoder->quality = AVIF_QUALITY_LOSSLESS;
|
||||
encoder->qualityAlpha = AVIF_QUALITY_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());
|
||||
status = avifEncoderSetCodecSpecificOption(encoder.get(), "sharpness",
|
||||
std::to_string(options.sharpness).c_str());
|
||||
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||
|
||||
if (options.cqAlphaLevel != -1) {
|
||||
avifEncoderSetCodecSpecificOption(encoder, "alpha:cq-level",
|
||||
std::to_string(options.cqAlphaLevel).c_str());
|
||||
// Set base quality
|
||||
encoder->quality = options.quality;
|
||||
// Conditionally set alpha quality
|
||||
if (options.qualityAlpha == -1) {
|
||||
encoder->qualityAlpha = options.quality;
|
||||
} else {
|
||||
encoder->qualityAlpha = options.qualityAlpha;
|
||||
}
|
||||
|
||||
if (options.tune == 2 || (options.tune == 0 && options.cqLevel <= 32)) {
|
||||
avifEncoderSetCodecSpecificOption(encoder, "tune", "ssim");
|
||||
if (options.tune == 2 || (options.tune == 0 && options.quality >= 50)) {
|
||||
status = avifEncoderSetCodecSpecificOption(encoder.get(), "tune", "ssim");
|
||||
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||
}
|
||||
|
||||
if (options.chromaDeltaQ) {
|
||||
avifEncoderSetCodecSpecificOption(encoder, "enable-chroma-deltaq", "1");
|
||||
status = avifEncoderSetCodecSpecificOption(encoder.get(), "color:enable-chroma-deltaq", "1");
|
||||
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||
}
|
||||
|
||||
avifEncoderSetCodecSpecificOption(encoder, "color:denoise-noise-level",
|
||||
std::to_string(options.denoiseLevel).c_str());
|
||||
status = avifEncoderSetCodecSpecificOption(encoder.get(), "color:denoise-noise-level",
|
||||
std::to_string(options.denoiseLevel).c_str());
|
||||
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||
}
|
||||
|
||||
encoder->maxThreads = emscripten_num_logical_cores();
|
||||
@@ -117,22 +140,21 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
||||
encoder->tileColsLog2 = options.tileColsLog2;
|
||||
encoder->speed = options.speed;
|
||||
|
||||
avifResult encodeResult = avifEncoderWrite(encoder, image, &output);
|
||||
avifRWData output = AVIF_DATA_EMPTY;
|
||||
avifResult encodeResult = avifEncoderWrite(encoder.get(), image.get(), &output);
|
||||
auto js_result = val::null();
|
||||
if (encodeResult == AVIF_RESULT_OK) {
|
||||
js_result = Uint8Array.new_(typed_memory_view(output.size, output.data));
|
||||
}
|
||||
|
||||
avifImageDestroy(image);
|
||||
avifEncoderDestroy(encoder);
|
||||
avifRWDataFree(&output);
|
||||
return js_result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<AvifOptions>("AvifOptions")
|
||||
.field("cqLevel", &AvifOptions::cqLevel)
|
||||
.field("cqAlphaLevel", &AvifOptions::cqAlphaLevel)
|
||||
.field("quality", &AvifOptions::quality)
|
||||
.field("qualityAlpha", &AvifOptions::qualityAlpha)
|
||||
.field("tileRowsLog2", &AvifOptions::tileRowsLog2)
|
||||
.field("tileColsLog2", &AvifOptions::tileColsLog2)
|
||||
.field("speed", &AvifOptions::speed)
|
||||
@@ -140,7 +162,8 @@ EMSCRIPTEN_BINDINGS(my_module) {
|
||||
.field("sharpness", &AvifOptions::sharpness)
|
||||
.field("tune", &AvifOptions::tune)
|
||||
.field("denoiseLevel", &AvifOptions::denoiseLevel)
|
||||
.field("subsample", &AvifOptions::subsample);
|
||||
.field("subsample", &AvifOptions::subsample)
|
||||
.field("enableSharpYUV", &AvifOptions::enableSharpYUV);
|
||||
|
||||
function("encode", &encode);
|
||||
}
|
||||
|
||||
5
codecs/avif/enc/avif_enc.d.ts
vendored
5
codecs/avif/enc/avif_enc.d.ts
vendored
@@ -5,15 +5,16 @@ export const enum AVIFTune {
|
||||
}
|
||||
|
||||
export interface EncodeOptions {
|
||||
cqLevel: number;
|
||||
quality: number;
|
||||
qualityAlpha: number;
|
||||
denoiseLevel: number;
|
||||
cqAlphaLevel: number;
|
||||
tileRowsLog2: number;
|
||||
tileColsLog2: number;
|
||||
speed: number;
|
||||
subsample: number;
|
||||
chromaDeltaQ: boolean;
|
||||
sharpness: number;
|
||||
enableSharpYUV: boolean;
|
||||
tune: AVIFTune;
|
||||
}
|
||||
|
||||
|
||||
2
codecs/avif/enc/avif_enc.js
generated
2
codecs/avif/enc/avif_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/avif/enc/avif_enc_mt.js
generated
2
codecs/avif/enc/avif_enc_mt.js
generated
File diff suppressed because one or more lines are too long
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 @@
|
||||
"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}};
|
||||
"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};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})}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["__emscripten_thread_exit"](result)}}catch(ex){if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["__emscripten_thread_exit"](ex.status)}}else{throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}postMessage({"cmd":"cancelDone"})}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}};
|
||||
|
||||
2
codecs/avif/enc/avif_node_enc.js
generated
2
codecs/avif/enc/avif_node_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/avif/enc/avif_node_enc_mt.js
generated
2
codecs/avif/enc/avif_node_enc_mt.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -10,8 +10,11 @@
|
||||
# $(LIBAVIF_FLAGS)
|
||||
# $(ENVIRONMENT)
|
||||
|
||||
# $(OUT_JS) is something like "enc/avif_enc.js" or "enc/avif_enc_mt.js"
|
||||
# so $(OUT_BUILD_DIR) will be "node_modules/build/enc/avif_enc[_mt]"
|
||||
OUT_BUILD_DIR := $(BUILD_DIR)/$(basename $(OUT_JS))
|
||||
|
||||
# We're making libavif and libaom for every node_modules/[enc|dec]/
|
||||
CODEC_BUILD_DIR := $(OUT_BUILD_DIR)/libavif
|
||||
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
||||
|
||||
@@ -25,6 +28,13 @@ OUT_WORKER=$(OUT_JS:.js=.worker.js)
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
# Only add libsharpyuv as a dependency for encoders.
|
||||
# Yes, that if statement is true for encoders.
|
||||
ifneq (,$(findstring enc/, $(OUT_JS)))
|
||||
$(OUT_JS): $(LIBSHARPYUV)
|
||||
$(CODEC_OUT): $(LIBSHARPYUV)
|
||||
endif
|
||||
|
||||
$(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR)/include \
|
||||
@@ -32,6 +42,7 @@ $(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
||||
$(LDFLAGS) \
|
||||
$(OUT_FLAGS) \
|
||||
--bind \
|
||||
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
|
||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||
-s EXPORT_ES6=1 \
|
||||
-o $@ \
|
||||
@@ -39,6 +50,7 @@ $(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
||||
|
||||
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_OUT)
|
||||
emcmake cmake \
|
||||
-DCMAKE_LIBRARY_PATH=$(LIBSHARPYUV_BUILD_DIR) \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=0 \
|
||||
-DAVIF_CODEC_AOM=1 \
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
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.
|
||||
@@ -1,83 +0,0 @@
|
||||
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)
|
||||
@@ -1,46 +0,0 @@
|
||||
#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
7
codecs/basis/dec/basis_dec.d.ts
vendored
@@ -1,7 +0,0 @@
|
||||
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
56
codecs/basis/dec/basis_dec.js
generated
@@ -1,56 +0,0 @@
|
||||
|
||||
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;
|
||||
Binary file not shown.
@@ -1,96 +0,0 @@
|
||||
#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
24
codecs/basis/enc/basis_enc.d.ts
vendored
@@ -1,24 +0,0 @@
|
||||
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
62
codecs/basis/enc/basis_enc.js
generated
@@ -1,62 +0,0 @@
|
||||
|
||||
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;
|
||||
Binary file not shown.
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "../build-cpp.sh"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM emscripten/emsdk:2.0.23
|
||||
FROM emscripten/emsdk:2.0.34
|
||||
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
||||
ENV CFLAGS "-O3 -flto"
|
||||
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
CODEC_URL = https://github.com/libjxl/libjxl.git
|
||||
CODEC_VERSION = v0.5
|
||||
CODEC_VERSION = 9f544641ec83f6abd9da598bdd08178ee8a003e0
|
||||
CODEC_DIR = node_modules/jxl
|
||||
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
|
||||
CODEC_MT_BUILD_DIR := $(CODEC_BUILD_ROOT)/mt
|
||||
@@ -75,6 +75,9 @@ $(CODEC_MT_SIMD_BUILD_DIR)/Makefile: CXXFLAGS+=-msimd128
|
||||
-DCMAKE_CROSSCOMPILING_EMULATOR=node \
|
||||
-B $(@D) \
|
||||
$(<D)
|
||||
emcc -Wall -O3 -o $(CODEC_DIR)/third_party/skcms/skcms.cc.o -I$(CODEC_DIR)/third_party/skcms -c $(CODEC_DIR)/third_party/skcms/skcms.cc
|
||||
llvm-ar rc $(CODEC_BUILD_DIR)/third_party/libskcms.a $(CODEC_DIR)/third_party/skcms/skcms.cc.o
|
||||
rm $(CODEC_DIR)/third_party/skcms/skcms.cc.o
|
||||
|
||||
$(CODEC_DIR)/CMakeLists.txt:
|
||||
$(RM) -r $(@D)
|
||||
|
||||
2
codecs/jxl/dec/jxl_dec.js
generated
2
codecs/jxl/dec/jxl_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/jxl/dec/jxl_node_dec.js
generated
2
codecs/jxl/dec/jxl_node_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -4,21 +4,21 @@
|
||||
#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_color_management.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
struct JXLOptions {
|
||||
// 1 = slowest
|
||||
// 7 = fastest
|
||||
int speed;
|
||||
int effort;
|
||||
float quality;
|
||||
bool progressive;
|
||||
int epf;
|
||||
int nearLossless;
|
||||
bool lossyPalette;
|
||||
size_t decodingSpeedTier;
|
||||
float photonNoiseIso;
|
||||
bool lossyModular;
|
||||
};
|
||||
|
||||
val encode(std::string image, int width, int height, JXLOptions options) {
|
||||
@@ -33,11 +33,14 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
||||
pool_ptr = &pool;
|
||||
#endif
|
||||
|
||||
cparams.epf = options.epf;
|
||||
cparams.speed_tier = static_cast<jxl::SpeedTier>(options.speed);
|
||||
cparams.decoding_speed_tier = options.decodingSpeedTier;
|
||||
size_t st = 10 - options.effort;
|
||||
cparams.speed_tier = jxl::SpeedTier(st);
|
||||
|
||||
if (options.lossyPalette || options.nearLossless) {
|
||||
cparams.epf = options.epf;
|
||||
cparams.decoding_speed_tier = options.decodingSpeedTier;
|
||||
cparams.photon_noise_iso = options.photonNoiseIso;
|
||||
|
||||
if (options.lossyPalette) {
|
||||
cparams.lossy_palette = true;
|
||||
cparams.palette_colors = 0;
|
||||
cparams.options.predictor = jxl::Predictor::Zero;
|
||||
@@ -49,11 +52,16 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
||||
float quality = options.quality;
|
||||
|
||||
// Quality settings roughly match libjpeg qualities.
|
||||
if (quality < 7 || quality == 100) {
|
||||
if (options.lossyModular || 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);
|
||||
if (quality < 7) {
|
||||
cparams.quality_pair.first = cparams.quality_pair.second =
|
||||
std::min(35 + (quality - 7) * 3.0f, 100.0f);
|
||||
} else {
|
||||
cparams.quality_pair.first = cparams.quality_pair.second =
|
||||
std::min(35 + (quality - 7) * 65.f / 93.f, 100.0f);
|
||||
}
|
||||
} else {
|
||||
cparams.modular_mode = false;
|
||||
if (quality >= 30) {
|
||||
@@ -90,14 +98,14 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
||||
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,
|
||||
/*alpha_is_premultiplied=*/false, /*bits_per_sample=*/8, /*endiannes=*/JXL_LITTLE_ENDIAN,
|
||||
/*flipped_y=*/false, pool_ptr, main);
|
||||
/*flipped_y=*/false, pool_ptr, main, /*(only true if bits_per_sample==32) float_in=*/false);
|
||||
|
||||
if (!result) {
|
||||
return val::null();
|
||||
}
|
||||
|
||||
auto js_result = val::null();
|
||||
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, /*aux=*/nullptr, pool_ptr)) {
|
||||
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, jxl::GetJxlCms(), /*aux=*/nullptr, pool_ptr)) {
|
||||
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
|
||||
}
|
||||
|
||||
@@ -106,12 +114,13 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<JXLOptions>("JXLOptions")
|
||||
.field("speed", &JXLOptions::speed)
|
||||
.field("effort", &JXLOptions::effort)
|
||||
.field("quality", &JXLOptions::quality)
|
||||
.field("progressive", &JXLOptions::progressive)
|
||||
.field("nearLossless", &JXLOptions::nearLossless)
|
||||
.field("lossyPalette", &JXLOptions::lossyPalette)
|
||||
.field("decodingSpeedTier", &JXLOptions::decodingSpeedTier)
|
||||
.field("photonNoiseIso", &JXLOptions::photonNoiseIso)
|
||||
.field("lossyModular", &JXLOptions::lossyModular)
|
||||
.field("epf", &JXLOptions::epf);
|
||||
|
||||
function("encode", &encode);
|
||||
|
||||
5
codecs/jxl/enc/jxl_enc.d.ts
vendored
5
codecs/jxl/enc/jxl_enc.d.ts
vendored
@@ -1,11 +1,12 @@
|
||||
export interface EncodeOptions {
|
||||
speed: number;
|
||||
effort: number;
|
||||
quality: number;
|
||||
progressive: boolean;
|
||||
epf: number;
|
||||
nearLossless: number;
|
||||
lossyPalette: boolean;
|
||||
decodingSpeedTier: number;
|
||||
photonNoiseIso: number;
|
||||
lossyModular: boolean;
|
||||
}
|
||||
|
||||
export interface JXLModule extends EmscriptenWasm.Module {
|
||||
|
||||
2
codecs/jxl/enc/jxl_enc.js
generated
2
codecs/jxl/enc/jxl_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/jxl/enc/jxl_enc_mt.js
generated
2
codecs/jxl/enc/jxl_enc_mt.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/jxl/enc/jxl_enc_mt_simd.js
generated
2
codecs/jxl/enc/jxl_enc_mt_simd.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/jxl/enc/jxl_node_enc.js
generated
2
codecs/jxl/enc/jxl_node_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
407
codecs/oxipng/Cargo.lock
generated
407
codecs/oxipng/Cargo.lock
generated
@@ -2,18 +2,6 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
@@ -21,22 +9,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "build_const"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
@@ -46,15 +28,9 @@ checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.4.1"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
@@ -62,120 +38,51 @@ version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
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]]
|
||||
name = "cloudflare-zlib"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5ed63a019d55bacd15cadcbcb96bf41b16281417fff393bdb55fa84255fe4b9"
|
||||
dependencies = [
|
||||
"cloudflare-zlib-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudflare-zlib-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e195cb274a0d6ee87e718838a09baecd7cbc9f6075dac256a84cb5842739c06"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||
dependencies = [
|
||||
"build_const",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.0"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
||||
checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.0"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.1"
|
||||
version = "0.9.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
|
||||
checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"const_fn",
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.1"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||
checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -184,56 +91,35 @@ version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ce04077ead78e39ae8610ad26216aed811996b043d47beed5090db674f9e9b5"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.6.1"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.48"
|
||||
@@ -249,161 +135,47 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||
|
||||
[[package]]
|
||||
name = "libdeflate-sys"
|
||||
version = "0.7.1"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a95fa4be7085dd06a8296dcc3f399f12ab8b0309c157dcaa90669130b175b97"
|
||||
checksum = "67921a7f85100c1559efc3d1c7c472091b7da05f304b4bbd5356f075e97f1cc2"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libdeflater"
|
||||
version = "0.7.1"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccc147465654929bf7b56518cc46d11701ba290f4ff94398ae3f89f1663cf60f"
|
||||
checksum = "3a31b22f662350ec294b13859f935aea772ba7b2bc8776269f4a5627308eab7d"
|
||||
dependencies = [
|
||||
"libdeflate-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "oxipng"
|
||||
version = "4.0.3"
|
||||
version = "9.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d0b53912a666fe2970f8ab254e283531c816aed16551ab66c52485eadb44e6"
|
||||
checksum = "28e5c341ef78a228e47a551bfd15ff885d8c501af49f953358763a538c01f14d"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
"byteorder",
|
||||
"cloudflare-zlib",
|
||||
"crc",
|
||||
"bitvec",
|
||||
"crossbeam-channel",
|
||||
"image",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"libdeflater",
|
||||
"log",
|
||||
"miniz_oxide 0.4.3",
|
||||
"rayon",
|
||||
"rgb",
|
||||
"rustc-hash",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.16.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate",
|
||||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.26"
|
||||
@@ -423,71 +195,60 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.0"
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.0"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
||||
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.25"
|
||||
version = "0.8.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "287f3c3f8236abb92d8b7e36797f19159df4b58f0a658cc3fb6dd3004b1f3bd3"
|
||||
checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.0"
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65c94201b44764d6d1f7e37c15a8289ed55e546c1762c7f1d57f616966e0c181"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
||||
|
||||
[[package]]
|
||||
name = "spmc"
|
||||
@@ -499,7 +260,6 @@ checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5"
|
||||
name = "squoosh-oxipng"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libdeflater",
|
||||
"log",
|
||||
"oxipng",
|
||||
"wasm-bindgen",
|
||||
@@ -518,10 +278,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
@@ -535,7 +295,7 @@ version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
@@ -594,3 +354,12 @@ name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
@@ -12,8 +12,7 @@ wasm-opt = ["-O", "--no-validation"]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
oxipng = { version = "4.0.3", default-features = false, features = ["libdeflater"] }
|
||||
libdeflater = { version = "0.7.1", features = ["freestanding"] }
|
||||
oxipng = { version = "9.0", default-features = false, features = ["freestanding"] }
|
||||
wasm-bindgen = "0.2.73"
|
||||
log = { version = "0.4.11", features = ["release_max_level_off"] }
|
||||
wasm-bindgen-rayon = { version = "1.0", optional = true }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# OxiPNG
|
||||
|
||||
- Source: <https://github.com/shssoichiro/oxipng>
|
||||
- Version: v3.0.0
|
||||
- Version: v9.0.0
|
||||
- License: MIT
|
||||
|
||||
@@ -5,5 +5,5 @@ set -e
|
||||
rm -rf pkg,{-parallel}
|
||||
export CFLAGS="${CFLAGS} -DUNALIGNED_ACCESS_IS_FAST=1"
|
||||
wasm-pack build -t web
|
||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel . -- -Z build-std=panic_abort,std --features=parallel
|
||||
rm pkg{,-parallel}/.gitignore
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "oxipng",
|
||||
"scripts": {
|
||||
"build": "RUST_IMG=rustlang/rust@sha256:744aeea5a38f95aa7a96ec37269a65f0c6197a1cdd87d6534e12bb869141d807 ../build-rust.sh ./build.sh"
|
||||
"build": "RUST_IMG=rustlang/rust@sha256:5fd16a5576c22c8fdd5d659247755999e426c04de8dcf18a41ea446c5f253309 ../build-rust.sh ./build.sh"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# OxiPNG
|
||||
|
||||
- Source: <https://github.com/shssoichiro/oxipng>
|
||||
- Version: v3.0.0
|
||||
- Version: v9.0.0
|
||||
- License: MIT
|
||||
|
||||
@@ -11,5 +11,7 @@
|
||||
],
|
||||
"module": "squoosh_oxipng.js",
|
||||
"types": "squoosh_oxipng.d.ts",
|
||||
"sideEffects": false
|
||||
"sideEffects": [
|
||||
"./snippets/*"
|
||||
]
|
||||
}
|
||||
9
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
9
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
@@ -1,12 +1,14 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {Uint8ClampedArray} data
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number} level
|
||||
* @param {boolean} interlace
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data: Uint8Array, level: number, interlace: boolean): Uint8Array;
|
||||
export function optimise(data: Uint8ClampedArray, width: number, height: number, level: number, interlace: boolean): Uint8Array;
|
||||
/**
|
||||
* @param {number} num_threads
|
||||
* @returns {Promise<any>}
|
||||
@@ -36,8 +38,7 @@ export class wbg_rayon_PoolBuilder {
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly __wasm_init_memory: () => void;
|
||||
readonly optimise: (a: number, b: number, c: number, d: number, e: number) => void;
|
||||
readonly optimise: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
|
||||
readonly __wbg_wbg_rayon_poolbuilder_free: (a: number) => void;
|
||||
readonly wbg_rayon_poolbuilder_numThreads: (a: number) => number;
|
||||
readonly wbg_rayon_poolbuilder_receiver: (a: number) => number;
|
||||
|
||||
8
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
8
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
@@ -54,17 +54,19 @@ function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {Uint8ClampedArray} data
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number} level
|
||||
* @param {boolean} interlace
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data, level, interlace) {
|
||||
export function optimise(data, width, height, level, interlace) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(retptr, ptr0, len0, level, interlace);
|
||||
wasm.optimise(retptr, ptr0, len0, width, height, level, interlace);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
|
||||
Binary file not shown.
3
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
3
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
@@ -1,7 +1,6 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function __wasm_init_memory(): void;
|
||||
export function optimise(a: number, b: number, c: number, d: number, e: number): void;
|
||||
export function optimise(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
|
||||
export function __wbg_wbg_rayon_poolbuilder_free(a: number): void;
|
||||
export function wbg_rayon_poolbuilder_numThreads(a: number): number;
|
||||
export function wbg_rayon_poolbuilder_receiver(a: number): number;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# OxiPNG
|
||||
|
||||
- Source: <https://github.com/shssoichiro/oxipng>
|
||||
- Version: v3.0.0
|
||||
- Version: v9.0.0
|
||||
- License: MIT
|
||||
|
||||
@@ -11,5 +11,7 @@
|
||||
],
|
||||
"module": "squoosh_oxipng.js",
|
||||
"types": "squoosh_oxipng.d.ts",
|
||||
"sideEffects": false
|
||||
"sideEffects": [
|
||||
"./snippets/*"
|
||||
]
|
||||
}
|
||||
8
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
8
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
@@ -1,18 +1,20 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {Uint8ClampedArray} data
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number} level
|
||||
* @param {boolean} interlace
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data: Uint8Array, level: number, interlace: boolean): Uint8Array;
|
||||
export function optimise(data: Uint8ClampedArray, width: number, height: number, level: number, interlace: boolean): Uint8Array;
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly optimise: (a: number, b: number, c: number, d: number, e: number) => void;
|
||||
readonly optimise: (a: number, b: number, c: number, d: number, e: number, f: number, g: 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;
|
||||
|
||||
8
codecs/oxipng/pkg/squoosh_oxipng.js
generated
8
codecs/oxipng/pkg/squoosh_oxipng.js
generated
@@ -38,17 +38,19 @@ function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {Uint8ClampedArray} data
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number} level
|
||||
* @param {boolean} interlace
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data, level, interlace) {
|
||||
export function optimise(data, width, height, level, interlace) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(retptr, ptr0, len0, level, interlace);
|
||||
wasm.optimise(retptr, ptr0, len0, width, height, level, interlace);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
|
||||
Binary file not shown.
2
codecs/oxipng/pkg/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
2
codecs/oxipng/pkg/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
@@ -1,7 +1,7 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export function optimise(a: number, b: number, c: number, d: number, e: number): void;
|
||||
export function optimise(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
|
||||
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||
export function __wbindgen_malloc(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number): void;
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
#[cfg(feature = "parallel")]
|
||||
pub use wasm_bindgen_rayon::init_thread_pool;
|
||||
|
||||
use oxipng::AlphaOptim;
|
||||
use oxipng::{BitDepth, ColorType, Interlacing};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::Clamped;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn optimise(data: &[u8], level: u8, interlace: bool) -> Vec<u8> {
|
||||
pub fn optimise(
|
||||
data: Clamped<Vec<u8>>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
level: u8,
|
||||
interlace: bool,
|
||||
) -> Vec<u8> {
|
||||
let mut options = oxipng::Options::from_preset(level);
|
||||
options.alphas.insert(AlphaOptim::Black);
|
||||
options.alphas.insert(AlphaOptim::White);
|
||||
options.alphas.insert(AlphaOptim::Up);
|
||||
options.alphas.insert(AlphaOptim::Down);
|
||||
options.alphas.insert(AlphaOptim::Left);
|
||||
options.alphas.insert(AlphaOptim::Right);
|
||||
options.interlace = Some(if interlace { 1 } else { 0 });
|
||||
options.optimize_alpha = true;
|
||||
options.interlace = Some(if interlace {
|
||||
Interlacing::Adam7
|
||||
} else {
|
||||
Interlacing::None
|
||||
});
|
||||
|
||||
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||
let raw = oxipng::RawImage::new(width, height, ColorType::RGBA, BitDepth::Eight, data.0)
|
||||
.unwrap_throw();
|
||||
raw.create_optimized_png(&options).unwrap_throw()
|
||||
}
|
||||
|
||||
42
codecs/qoi/Makefile
Normal file
42
codecs/qoi/Makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
CODEC_URL = https://github.com/phoboslab/qoi/archive/8d35d93cdca85d2868246c2a8a80a1e2c16ba2a8.tar.gz
|
||||
|
||||
CODEC_DIR = node_modules/qoi
|
||||
CODEC_BUILD_DIR:= $(CODEC_DIR)/build
|
||||
ENVIRONMENT = worker
|
||||
|
||||
OUT_JS = enc/qoi_enc.js dec/qoi_dec.js
|
||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
$(filter enc/%,$(OUT_JS)): enc/qoi_enc.o
|
||||
$(filter dec/%,$(OUT_JS)): dec/qoi_dec.o
|
||||
|
||||
# ALL .js FILES
|
||||
$(OUT_JS):
|
||||
$(LD) \
|
||||
$(LDFLAGS) \
|
||||
--bind \
|
||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||
-s EXPORT_ES6=1 \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
# ALL .o FILES
|
||||
%.o: %.cpp $(CODEC_DIR)
|
||||
$(CXX) -c \
|
||||
$(CXXFLAGS) \
|
||||
-I $(CODEC_DIR) \
|
||||
-o $@ \
|
||||
$<
|
||||
|
||||
# CREATE DIRECTORY
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $(CODEC_DIR)
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $(CODEC_DIR)
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_DIR) clean
|
||||
30
codecs/qoi/dec/qoi_dec.cpp
Normal file
30
codecs/qoi/dec/qoi_dec.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
|
||||
#define QOI_IMPLEMENTATION
|
||||
#include "qoi.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||
thread_local const val ImageData = val::global("ImageData");
|
||||
|
||||
val decode(std::string qoiimage) {
|
||||
qoi_desc desc;
|
||||
uint8_t* rgba = (uint8_t*)qoi_decode(qoiimage.c_str(), qoiimage.length(), &desc, 4);
|
||||
|
||||
// Resultant width and height stored in descriptor
|
||||
int decodedWidth = desc.width;
|
||||
int decodedHeight = desc.height;
|
||||
|
||||
val result = ImageData.new_(
|
||||
Uint8ClampedArray.new_(typed_memory_view(4 * decodedWidth * decodedHeight, rgba)),
|
||||
decodedWidth, decodedHeight);
|
||||
free(rgba);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
function("decode", &decode);
|
||||
}
|
||||
7
codecs/qoi/dec/qoi_dec.d.ts
vendored
Normal file
7
codecs/qoi/dec/qoi_dec.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface QOIModule extends EmscriptenWasm.Module {
|
||||
decode(data: BufferSource): ImageData | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QOIModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
16
codecs/qoi/dec/qoi_dec.js
generated
Normal file
16
codecs/qoi/dec/qoi_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/qoi/dec/qoi_dec.wasm
Normal file
BIN
codecs/qoi/dec/qoi_dec.wasm
Normal file
Binary file not shown.
36
codecs/qoi/enc/qoi_enc.cpp
Normal file
36
codecs/qoi/enc/qoi_enc.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
|
||||
#define QOI_IMPLEMENTATION
|
||||
#include "qoi.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
struct QoiOptions {};
|
||||
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
val encode(std::string buffer, int width, int height, QoiOptions options) {
|
||||
int compressedSizeInBytes;
|
||||
qoi_desc desc;
|
||||
desc.width = width;
|
||||
desc.height = height;
|
||||
desc.channels = 4;
|
||||
desc.colorspace = QOI_SRGB;
|
||||
|
||||
uint8_t* encodedData = (uint8_t*)qoi_encode(buffer.c_str(), &desc, &compressedSizeInBytes);
|
||||
if (encodedData == NULL)
|
||||
return val::null();
|
||||
|
||||
auto js_result =
|
||||
Uint8Array.new_(typed_memory_view(compressedSizeInBytes, (const uint8_t*)encodedData));
|
||||
free(encodedData);
|
||||
|
||||
return js_result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<QoiOptions>("QoiOptions");
|
||||
|
||||
function("encode", &encode);
|
||||
}
|
||||
14
codecs/qoi/enc/qoi_enc.d.ts
vendored
Normal file
14
codecs/qoi/enc/qoi_enc.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
export interface EncodeOptions {}
|
||||
|
||||
export interface QoiModule extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QoiModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
16
codecs/qoi/enc/qoi_enc.js
generated
Normal file
16
codecs/qoi/enc/qoi_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/qoi/enc/qoi_enc.wasm
Normal file
BIN
codecs/qoi/enc/qoi_enc.wasm
Normal file
Binary file not shown.
7
codecs/qoi/package.json
Normal file
7
codecs/qoi/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "qoi",
|
||||
"scripts": {
|
||||
"build": "../build-cpp.sh"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ ARG RUST_IMG=rust:1.47
|
||||
|
||||
FROM emscripten/emsdk:2.0.8 AS wasm-tools
|
||||
WORKDIR /opt/wasm-tools
|
||||
RUN wget -qO- https://github.com/rustwasm/wasm-pack/releases/download/v0.9.1/wasm-pack-v0.9.1-x86_64-unknown-linux-musl.tar.gz | tar -xzf - --strip 1
|
||||
RUN wget -qO- https://github.com/rustwasm/wasm-pack/releases/download/v0.12.1/wasm-pack-v0.12.1-x86_64-unknown-linux-musl.tar.gz | tar -xzf - --strip 1
|
||||
|
||||
FROM $RUST_IMG AS rust
|
||||
ARG RUST_IMG
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
"static-build/*": ["src/static-build/*"],
|
||||
"client/*": ["src/client/*"],
|
||||
"shared/*": ["src/shared/*"],
|
||||
"features/*": ["src/features/*"]
|
||||
"features/*": ["src/features/*"],
|
||||
"worker-shared/*": ["src/worker-shared/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,28 +14,40 @@ import { promises as fs } from 'fs';
|
||||
|
||||
import { lookup as lookupMime } from 'mime-types';
|
||||
|
||||
const prefix = 'data-url:';
|
||||
const prefix = /^data-url(-text)?:/;
|
||||
|
||||
export default function dataURLPlugin() {
|
||||
return {
|
||||
name: 'data-url-plugin',
|
||||
async resolveId(id, importer) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const match = prefix.exec(id);
|
||||
if (!match) return;
|
||||
return (
|
||||
prefix + (await this.resolve(id.slice(prefix.length), importer)).id
|
||||
match[0] + (await this.resolve(id.slice(match[0].length), importer)).id
|
||||
);
|
||||
},
|
||||
async load(id) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length);
|
||||
const match = prefix.exec(id);
|
||||
if (!match) return;
|
||||
|
||||
const isText = !!match[1];
|
||||
const realId = id.slice(match[0].length);
|
||||
this.addWatchFile(realId);
|
||||
|
||||
const source = await fs.readFile(realId);
|
||||
const type = lookupMime(realId) || 'text/plain';
|
||||
|
||||
return `export default 'data:${type};base64,${source.toString(
|
||||
'base64',
|
||||
)}';`;
|
||||
if (isText) {
|
||||
const encodedBody = encodeURIComponent(source.toString('utf8'));
|
||||
|
||||
return `export default ${JSON.stringify(
|
||||
`data:${type};charset=utf-8,${encodedBody}`,
|
||||
)};`;
|
||||
}
|
||||
|
||||
return `export default ${JSON.stringify(
|
||||
`data:${type};base64,${source.toString('base64')}`,
|
||||
)};`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
15
lib/omt.ejs
15
lib/omt.ejs
@@ -28,10 +28,17 @@ if (!self.<%- amdFunctionName %>) {
|
||||
<% } else { %>
|
||||
new Promise(resolve => {
|
||||
if ("document" in self) {
|
||||
const script = document.createElement("script");
|
||||
script.src = uri;
|
||||
script.onload = resolve;
|
||||
document.head.appendChild(script);
|
||||
const link = document.createElement("link");
|
||||
link.rel = "preload";
|
||||
link.as = "script";
|
||||
link.href = uri;
|
||||
link.onload = () => {
|
||||
const script = document.createElement("script");
|
||||
script.src = uri;
|
||||
script.onload = resolve;
|
||||
document.head.appendChild(script);
|
||||
};
|
||||
document.head.appendChild(link);
|
||||
} else {
|
||||
self.nextDefineUri = uri;
|
||||
importScripts(uri);
|
||||
|
||||
3
libsquoosh/.gitignore
vendored
3
libsquoosh/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
build
|
||||
.DS_Store
|
||||
@@ -1 +0,0 @@
|
||||
node_modules
|
||||
@@ -1,171 +0,0 @@
|
||||
# libSquoosh
|
||||
|
||||
libSquoosh is an _experimental_ way to run all the codecs you know from the [Squoosh] web app directly inside your own JavaScript program. libSquoosh uses a worker pool to parallelize processing images. This way you can apply the same codec to many images at once.
|
||||
|
||||
libSquoosh 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
|
||||
|
||||
libSquoosh can be installed to your local project with the following command:
|
||||
|
||||
```
|
||||
$ npm install @squoosh/lib
|
||||
```
|
||||
|
||||
You can start using the libSquoosh by adding these lines to the top of your JS program:
|
||||
|
||||
```js
|
||||
import { ImagePool } from '@squoosh/lib';
|
||||
const imagePool = new ImagePool();
|
||||
```
|
||||
|
||||
This will create an image pool with an underlying processing pipeline that you can use to ingest and encode images. The ImagePool constructor takes one argument that defines how many parallel operations it is allowed to run at any given time. By default, this number is set to the amount of CPU cores available in the system it is running on.
|
||||
|
||||
## Ingesting images
|
||||
|
||||
You can ingest a new image like so:
|
||||
|
||||
```js
|
||||
const imagePath = 'path/to/image.png';
|
||||
const image = imagePool.ingestImage(imagePath);
|
||||
```
|
||||
|
||||
The `ingestImage` function can take anything the node [`readFile`][readfile] function can take, including a buffer and `FileHandle`.
|
||||
|
||||
The returned `image` object is a representation of the original image, that you can now preprocess, encode, and extract information about.
|
||||
|
||||
## Preprocessing and encoding images
|
||||
|
||||
When an image has been ingested, you can start preprocessing it and encoding it to other formats. This example will resize the image and then encode it to a `.jpg` and `.jxl` image:
|
||||
|
||||
```js
|
||||
await image.decoded; //Wait until the image is decoded before running preprocessors.
|
||||
|
||||
const preprocessOptions = {
|
||||
//When both width and height are specified, the image resized to specified size.
|
||||
resize: {
|
||||
enabled: true,
|
||||
width: 100,
|
||||
height: 50,
|
||||
}
|
||||
/*
|
||||
//When either width or height is specified, the image resized to specified size keeping aspect ratio.
|
||||
resize: {
|
||||
enabled: true,
|
||||
width: 100,
|
||||
}
|
||||
*/
|
||||
}
|
||||
await image.preprocess(preprocessOptions);
|
||||
|
||||
const encodeOptions = {
|
||||
mozjpeg: {}, //an empty object means 'use default settings'
|
||||
jxl: {
|
||||
quality: 90,
|
||||
},
|
||||
}
|
||||
await image.encode(encodeOptions);
|
||||
|
||||
```
|
||||
|
||||
The default values for each option can be found in the [`codecs.ts`][codecs.ts] file under `defaultEncoderOptions`. Every unspecified value will use the default value specified there. _Better documentation is needed here._
|
||||
|
||||
You can run your own code inbetween the different steps, if, for example, you want to change how much the image should be resized based on its original height. (See [Extracting image information](#extracting-image-information) to learn how to get the image dimensions).
|
||||
|
||||
## Closing the ImagePool
|
||||
|
||||
When you have encoded everything you need, it is recommended to close the processing pipeline in the ImagePool. This will not delete the images you have already encoded, but it will prevent you from ingesting and encoding new images.
|
||||
|
||||
Close the ImagePool pipeline with this line:
|
||||
|
||||
```js
|
||||
await imagePool.close();
|
||||
```
|
||||
|
||||
## Writing encoded images to the file system
|
||||
|
||||
When you have encoded an image, you normally want to write it to a file.
|
||||
|
||||
This example takes an image that has been encoded as a `jpg` and writes it to a file:
|
||||
|
||||
```js
|
||||
const rawEncodedImage = (await image.encodedWith.mozjpeg).binary;
|
||||
|
||||
fs.writeFile('/path/to/new/image.jpg', rawEncodedImage);
|
||||
```
|
||||
|
||||
This example iterates through all encoded versions of the image and writes them to a specific path:
|
||||
|
||||
```js
|
||||
const newImagePath = '/path/to/image.'; //extension is added automatically
|
||||
|
||||
for (const encodedImage of Object.values(image.encodedWith)) {
|
||||
fs.writeFile(
|
||||
newImagePath + (await encodedImage).extension,
|
||||
(await encodedImage).binary,
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Extracting image information
|
||||
|
||||
Information about a decoded image is available at `Image.decoded`. It looks something like this:
|
||||
|
||||
```js
|
||||
console.log(await image.decoded);
|
||||
// Returns:
|
||||
{
|
||||
bitmap: {
|
||||
data: Uint8ClampedArray(47736584) [
|
||||
225, 228, 237, 255, 225, 228, 237, 255, 225, 228, 237, 255,
|
||||
225, 228, 237, 255, 225, 228, 237, 255, 225, 228, 237, 255,
|
||||
225, 228, 237, 255,
|
||||
... //the entire raw image
|
||||
],
|
||||
width: 4606, //pixels
|
||||
height: 2591 //pixels
|
||||
},
|
||||
size: 2467795 //bytes
|
||||
}
|
||||
```
|
||||
|
||||
Information about an encoded image can be found at `Image.encodedWith[encoderName]`. It looks something like this:
|
||||
|
||||
```js
|
||||
console.log(await image.encodedWith.jxl);
|
||||
// Returns:
|
||||
{
|
||||
optionsUsed: {
|
||||
quality: 75,
|
||||
baseline: false,
|
||||
arithmetic: false,
|
||||
progressive: true,
|
||||
... //all the possible options for this encoder
|
||||
},
|
||||
binary: Uint8Array(1266975) [
|
||||
1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 132,
|
||||
113, 119, 156, 156, 209, 1, 8, 8, 8, 8, 9, 8,
|
||||
9, 10, 10, 9,
|
||||
... //the entire raw encoded image
|
||||
],
|
||||
extension: 'jxl',
|
||||
size: 1266975 //bytes
|
||||
}
|
||||
```
|
||||
|
||||
## Auto optimizer
|
||||
|
||||
libSquoosh 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.
|
||||
|
||||
```js
|
||||
const encodeOptions: {
|
||||
mozjpeg: 'auto',
|
||||
}
|
||||
```
|
||||
|
||||
[squoosh]: https://squoosh.app
|
||||
[codecs.ts]: https://github.com/GoogleChromeLabs/squoosh/blob/dev/libsquoosh/src/codecs.ts
|
||||
[butteraugli]: https://github.com/google/butteraugli
|
||||
[readfile]: https://nodejs.org/api/fs.html#fs_fspromises_readfile_path_options
|
||||
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
||||
* 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.
|
||||
*/
|
||||
import { promises as fs } from 'fs';
|
||||
import { basename } from 'path';
|
||||
|
||||
const defaultOpts = {
|
||||
prefix: 'asset-url',
|
||||
};
|
||||
|
||||
export default function assetPlugin(opts) {
|
||||
opts = { ...defaultOpts, ...opts };
|
||||
|
||||
/** @type {Map<string, Buffer>} */
|
||||
let assetIdToSourceBuffer;
|
||||
|
||||
const prefix = opts.prefix + ':';
|
||||
return {
|
||||
name: 'asset-plugin',
|
||||
buildStart() {
|
||||
assetIdToSourceBuffer = new Map();
|
||||
},
|
||||
augmentChunkHash(info) {
|
||||
// Get the sources for all assets imported by this chunk.
|
||||
const buffers = Object.keys(info.modules)
|
||||
.map((moduleId) => assetIdToSourceBuffer.get(moduleId))
|
||||
.filter(Boolean);
|
||||
|
||||
if (buffers.length === 0) return;
|
||||
|
||||
for (const moduleId of Object.keys(info.modules)) {
|
||||
const buffer = assetIdToSourceBuffer.get(moduleId);
|
||||
if (buffer) buffers.push(buffer);
|
||||
}
|
||||
|
||||
const combinedBuffer =
|
||||
buffers.length === 1 ? buffers[0] : Buffer.concat(buffers);
|
||||
|
||||
return combinedBuffer;
|
||||
},
|
||||
async resolveId(id, importer) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length);
|
||||
const resolveResult = await this.resolve(realId, importer);
|
||||
|
||||
if (!resolveResult) {
|
||||
throw Error(`Cannot find ${realId}`);
|
||||
}
|
||||
// Add an additional .js to the end so it ends up with .js at the end in the _virtual folder.
|
||||
return prefix + resolveResult.id + '.js';
|
||||
},
|
||||
async load(id) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length, -'.js'.length);
|
||||
const source = await fs.readFile(realId);
|
||||
assetIdToSourceBuffer.set(id, source);
|
||||
this.addWatchFile(realId);
|
||||
|
||||
return `export default import.meta.ROLLUP_FILE_URL_${this.emitFile({
|
||||
type: 'asset',
|
||||
source,
|
||||
name: basename(realId),
|
||||
})}`;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { promises as fsp } from 'fs';
|
||||
|
||||
export default function autojsonPlugin() {
|
||||
return {
|
||||
name: 'autojson-plugin',
|
||||
async load(id) {
|
||||
if (id.endsWith('.json') && !id.startsWith('json:')) {
|
||||
return 'export default ' + (await fsp.readFile(id, 'utf8'));
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
||||
* 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.
|
||||
*/
|
||||
import { promises as fs } from 'fs';
|
||||
import { basename } from 'path';
|
||||
|
||||
const defaultOpts = {
|
||||
prefix: 'chunk-url',
|
||||
};
|
||||
|
||||
export default function chunkPlugin(opts) {
|
||||
opts = { ...defaultOpts, ...opts };
|
||||
|
||||
const prefix = opts.prefix + ':';
|
||||
return {
|
||||
name: 'chunk-plugin',
|
||||
async resolveId(id, importer) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length);
|
||||
const resolveResult = await this.resolve(realId, importer);
|
||||
|
||||
if (!resolveResult) {
|
||||
throw Error(`Cannot find ${realId}`);
|
||||
}
|
||||
return prefix + resolveResult.id;
|
||||
},
|
||||
async load(id) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length);
|
||||
const source = await fs.readFile(realId);
|
||||
this.addWatchFile(realId);
|
||||
|
||||
return `export default import.meta.ROLLUP_FILE_URL_${this.emitFile({
|
||||
type: 'chunk',
|
||||
source,
|
||||
id: realId,
|
||||
})}`;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { promises as fsp } from 'fs';
|
||||
|
||||
const prefix = 'json:';
|
||||
|
||||
const reservedKeys = ['public'];
|
||||
|
||||
export default function jsonPlugin() {
|
||||
return {
|
||||
name: 'json-plugin',
|
||||
async resolveId(id, importer) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length);
|
||||
const resolveResult = await this.resolve(realId, importer);
|
||||
|
||||
if (!resolveResult) {
|
||||
throw Error(`Cannot find ${realId}`);
|
||||
}
|
||||
// Add an additional .js to the end so it ends up with .js at the end in the _virtual folder.
|
||||
return prefix + resolveResult.id;
|
||||
},
|
||||
async load(id) {
|
||||
if (!id.startsWith(prefix)) return;
|
||||
const realId = id.slice(prefix.length);
|
||||
const source = await fsp.readFile(realId, 'utf8');
|
||||
|
||||
let code = '';
|
||||
for (const [key, value] of Object.entries(JSON.parse(source))) {
|
||||
if (reservedKeys.includes(key)) {
|
||||
continue;
|
||||
}
|
||||
code += `
|
||||
export const ${key} = ${JSON.stringify(value)};
|
||||
`;
|
||||
}
|
||||
return code;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/**
|
||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
||||
* 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.
|
||||
*/
|
||||
import { spawn } from 'child_process';
|
||||
import { relative, join } from 'path';
|
||||
import { promises as fsp } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import glob from 'glob';
|
||||
import { sync as whichSync } from 'which';
|
||||
|
||||
const globP = promisify(glob);
|
||||
|
||||
const tscPath = whichSync('tsc');
|
||||
|
||||
const extRe = /\.tsx?$/;
|
||||
|
||||
function loadConfig(mainPath) {
|
||||
const fileName = ts.findConfigFile(mainPath, ts.sys.fileExists);
|
||||
if (!fileName) throw Error('tsconfig not found');
|
||||
const text = ts.sys.readFile(fileName);
|
||||
const loadedConfig = ts.parseConfigFileTextToJson(fileName, text).config;
|
||||
const parsedTsConfig = ts.parseJsonConfigFileContent(
|
||||
loadedConfig,
|
||||
ts.sys,
|
||||
process.cwd(),
|
||||
undefined,
|
||||
fileName,
|
||||
);
|
||||
return parsedTsConfig;
|
||||
}
|
||||
|
||||
export default function simpleTS(mainPath, { noBuild, watch } = {}) {
|
||||
const config = loadConfig(mainPath);
|
||||
const args = ['-b', mainPath];
|
||||
|
||||
let tsBuildDone;
|
||||
|
||||
async function watchBuiltFiles(rollupContext) {
|
||||
const matches = await globP(config.options.outDir + '/**/*.js');
|
||||
for (const match of matches) rollupContext.addWatchFile(match);
|
||||
}
|
||||
|
||||
async function tsBuild(rollupContext) {
|
||||
if (tsBuildDone) {
|
||||
// Watch lists are cleared on each build, so we need to rewatch all the JS files.
|
||||
await watchBuiltFiles(rollupContext);
|
||||
return tsBuildDone;
|
||||
}
|
||||
if (noBuild) {
|
||||
return (tsBuildDone = Promise.resolve());
|
||||
}
|
||||
tsBuildDone = Promise.resolve().then(async () => {
|
||||
await new Promise((resolve) => {
|
||||
const proc = spawn(tscPath, args, {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
proc.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
throw Error('TypeScript build failed');
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
await watchBuiltFiles(rollupContext);
|
||||
|
||||
if (watch) {
|
||||
tsBuildDone.then(() => {
|
||||
spawn(tscPath, [...args, '--watch', '--preserveWatchOutput'], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return tsBuildDone;
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'simple-ts',
|
||||
resolveId(id, importer) {
|
||||
// If there isn't an importer, it's an entry point, so we don't need to resolve it relative
|
||||
// to something.
|
||||
if (!importer) return null;
|
||||
|
||||
const tsResolve = ts.resolveModuleName(
|
||||
id,
|
||||
importer,
|
||||
config.options,
|
||||
ts.sys,
|
||||
);
|
||||
|
||||
if (
|
||||
// It didn't find anything
|
||||
!tsResolve.resolvedModule ||
|
||||
// Or if it's linking to a definition file, it's something in node_modules,
|
||||
// or something local like css.d.ts
|
||||
tsResolve.resolvedModule.extension === '.d.ts'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return tsResolve.resolvedModule.resolvedFileName;
|
||||
},
|
||||
async load(id) {
|
||||
if (!extRe.test(id)) return null;
|
||||
|
||||
// TypeScript building is deferred until the first TS file load.
|
||||
// This allows prerequisites to happen first,
|
||||
// such as css.d.ts generation in css-plugin.
|
||||
await tsBuild(this);
|
||||
|
||||
// Look for the JS equivalent in the tmp folder
|
||||
const newId = join(
|
||||
config.options.outDir,
|
||||
relative(config.options.rootDir, id),
|
||||
).replace(extRe, '.js');
|
||||
|
||||
return fsp.readFile(newId, { encoding: 'utf8' });
|
||||
},
|
||||
};
|
||||
}
|
||||
3986
libsquoosh/package-lock.json
generated
3986
libsquoosh/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "@squoosh/lib",
|
||||
"version": "0.4.0",
|
||||
"description": "A Node library for Squoosh",
|
||||
"public": true,
|
||||
"main": "./build/index.js",
|
||||
"files": [
|
||||
"/build/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rollup -c"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Google Chrome Developers <chromium-dev@google.com>",
|
||||
"homepage": "https://github.com/GoogleChromeLabs/squoosh",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/GoogleChromeLabs/squoosh.git"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": " ^12.5.0 || ^14.0.0 || ^16.0.0 "
|
||||
},
|
||||
"dependencies": {
|
||||
"wasm-feature-detect": "^1.2.11",
|
||||
"web-streams-polyfill": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.0",
|
||||
"@babel/preset-env": "^7.14.0",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-commonjs": "^18.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@types/node": "^15.6.1",
|
||||
"rollup": "^2.46.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"typescript": "^4.1.3",
|
||||
"which": "^2.0.2"
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import cjs from '@rollup/plugin-commonjs';
|
||||
import simpleTS from './lib/simple-ts';
|
||||
import asset from './lib/asset-plugin.js';
|
||||
import chunk from './lib/chunk-plugin.js';
|
||||
import json from './lib/json-plugin.js';
|
||||
import autojson from './lib/autojson-plugin.js';
|
||||
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
|
||||
import { builtinModules } from 'module';
|
||||
|
||||
/** @type {import('rollup').RollupOptions} */
|
||||
export default {
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
dir: 'build',
|
||||
format: 'cjs',
|
||||
assetFileNames: '[name]-[hash][extname]',
|
||||
},
|
||||
plugins: [
|
||||
resolve(),
|
||||
cjs(),
|
||||
chunk(),
|
||||
asset(),
|
||||
autojson(),
|
||||
json(),
|
||||
simpleTS('.'),
|
||||
getBabelOutputPlugin({
|
||||
babelrc: false,
|
||||
configFile: false,
|
||||
minified: process.env.DEBUG != '',
|
||||
comments: true,
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: 12,
|
||||
},
|
||||
loose: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
],
|
||||
external: [...builtinModules, 'web-streams-polyfill'],
|
||||
};
|
||||
132
libsquoosh/src/WebAssembly.d.ts
vendored
132
libsquoosh/src/WebAssembly.d.ts
vendored
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* WebAssembly definitions are not available in `@types/node` yet,
|
||||
* so these are copied from `lib.dom.d.ts`
|
||||
*/
|
||||
declare namespace WebAssembly {
|
||||
interface CompileError {}
|
||||
|
||||
var CompileError: {
|
||||
prototype: CompileError;
|
||||
new (): CompileError;
|
||||
};
|
||||
|
||||
interface Global {
|
||||
value: any;
|
||||
valueOf(): any;
|
||||
}
|
||||
|
||||
var Global: {
|
||||
prototype: Global;
|
||||
new (descriptor: GlobalDescriptor, v?: any): Global;
|
||||
};
|
||||
|
||||
interface Instance {
|
||||
readonly exports: Exports;
|
||||
}
|
||||
|
||||
var Instance: {
|
||||
prototype: Instance;
|
||||
new (module: Module, importObject?: Imports): Instance;
|
||||
};
|
||||
|
||||
interface LinkError {}
|
||||
|
||||
var LinkError: {
|
||||
prototype: LinkError;
|
||||
new (): LinkError;
|
||||
};
|
||||
|
||||
interface Memory {
|
||||
readonly buffer: ArrayBuffer;
|
||||
grow(delta: number): number;
|
||||
}
|
||||
|
||||
var Memory: {
|
||||
prototype: Memory;
|
||||
new (descriptor: MemoryDescriptor): Memory;
|
||||
};
|
||||
|
||||
interface Module {}
|
||||
|
||||
var Module: {
|
||||
prototype: Module;
|
||||
new (bytes: BufferSource): Module;
|
||||
customSections(moduleObject: Module, sectionName: string): ArrayBuffer[];
|
||||
exports(moduleObject: Module): ModuleExportDescriptor[];
|
||||
imports(moduleObject: Module): ModuleImportDescriptor[];
|
||||
};
|
||||
|
||||
interface RuntimeError {}
|
||||
|
||||
var RuntimeError: {
|
||||
prototype: RuntimeError;
|
||||
new (): RuntimeError;
|
||||
};
|
||||
|
||||
interface Table {
|
||||
readonly length: number;
|
||||
get(index: number): Function | null;
|
||||
grow(delta: number): number;
|
||||
set(index: number, value: Function | null): void;
|
||||
}
|
||||
|
||||
var Table: {
|
||||
prototype: Table;
|
||||
new (descriptor: TableDescriptor): Table;
|
||||
};
|
||||
|
||||
interface GlobalDescriptor {
|
||||
mutable?: boolean;
|
||||
value: ValueType;
|
||||
}
|
||||
|
||||
interface MemoryDescriptor {
|
||||
initial: number;
|
||||
maximum?: number;
|
||||
}
|
||||
|
||||
interface ModuleExportDescriptor {
|
||||
kind: ImportExportKind;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface ModuleImportDescriptor {
|
||||
kind: ImportExportKind;
|
||||
module: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface TableDescriptor {
|
||||
element: TableKind;
|
||||
initial: number;
|
||||
maximum?: number;
|
||||
}
|
||||
|
||||
interface WebAssemblyInstantiatedSource {
|
||||
instance: Instance;
|
||||
module: Module;
|
||||
}
|
||||
|
||||
type ImportExportKind = 'function' | 'global' | 'memory' | 'table';
|
||||
type TableKind = 'anyfunc';
|
||||
type ValueType = 'f32' | 'f64' | 'i32' | 'i64';
|
||||
type ExportValue = Function | Global | Memory | Table;
|
||||
type Exports = Record<string, ExportValue>;
|
||||
type ImportValue = ExportValue | number;
|
||||
type ModuleImports = Record<string, ImportValue>;
|
||||
type Imports = Record<string, ModuleImports>;
|
||||
function compile(bytes: BufferSource): Promise<Module>;
|
||||
// `compileStreaming` does not exist in NodeJS
|
||||
// function compileStreaming(source: Response | Promise<Response>): Promise<Module>;
|
||||
function instantiate(
|
||||
bytes: BufferSource,
|
||||
importObject?: Imports,
|
||||
): Promise<WebAssemblyInstantiatedSource>;
|
||||
function instantiate(
|
||||
moduleObject: Module,
|
||||
importObject?: Imports,
|
||||
): Promise<Instance>;
|
||||
// `instantiateStreaming` does not exist in NodeJS
|
||||
// function instantiateStreaming(response: Response | PromiseLike<Response>, importObject?: Imports): Promise<WebAssemblyInstantiatedSource>;
|
||||
function validate(bytes: BufferSource): boolean;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user