forked from external-repos/squoosh
Compare commits
76 Commits
dependabot
...
nix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13ff0d5934 | ||
|
|
2287e4517e | ||
|
|
16b75e7919 | ||
|
|
8a1c95b7dc | ||
|
|
d895e0a6b6 | ||
|
|
63441ef371 | ||
|
|
dfc9b36b6e | ||
|
|
aa7b284e65 | ||
|
|
24e63eafc6 | ||
|
|
00082becab | ||
|
|
fae5959392 | ||
|
|
53fc922870 | ||
|
|
4f93abb105 | ||
|
|
738d07d98a | ||
|
|
7e564e240a | ||
|
|
c1be464503 | ||
|
|
ee61b9fb18 | ||
|
|
6d061d8fa2 | ||
|
|
d278efb148 | ||
|
|
e4cec57fe3 | ||
|
|
a9c16df263 | ||
|
|
15df976a8c | ||
|
|
9bbfac62e8 | ||
|
|
13cbf8ddb1 | ||
|
|
b5bd766a4e | ||
|
|
a0f9fea679 | ||
|
|
dd290accc1 | ||
|
|
b19064702e | ||
|
|
3237a7e0ee | ||
|
|
c4cfc1d884 | ||
|
|
ba01d36c20 | ||
|
|
8c76d43a68 | ||
|
|
c308108279 | ||
|
|
2bd1eeceb8 | ||
|
|
95a16e3919 | ||
|
|
ec2a05ec33 | ||
|
|
11cd02c87b | ||
|
|
9ce5da7531 | ||
|
|
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 |
26
README.md
26
README.md
@@ -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.
|
||||
@@ -19,6 +15,8 @@ However, Squoosh utilizes Google Analytics to collect the following:
|
||||
|
||||
# Developing
|
||||
|
||||
## Web App
|
||||
|
||||
To develop for Squoosh:
|
||||
|
||||
1. Clone the repository
|
||||
@@ -35,8 +33,28 @@ To develop for Squoosh:
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Codecs
|
||||
|
||||
All build instructions for codecs are written using [Nix]. If you have Nix installed, you can rebuild the WebAssembly binaries by running:
|
||||
|
||||
```sh
|
||||
# Build the codec
|
||||
cd codec/<codec>
|
||||
nix run '.#updateRepoBinaries'
|
||||
```
|
||||
|
||||
If you do not have Nix installed, you can use the provided Docker image to create a shell with nix available:
|
||||
|
||||
```sh
|
||||
# Build the image (only needs to be done once).
|
||||
docker build -t squoosh-nix ./nix
|
||||
docker run --name squoosh-nix -ti -v $PWD:/app squoosh-nix /bin/sh
|
||||
# ... continue with the steps above
|
||||
```
|
||||
|
||||
# Contributing
|
||||
|
||||
Squoosh is an open-source project that appreciates all community involvement. To contribute to the project, follow the [contribute guide](/CONTRIBUTING.md).
|
||||
|
||||
[squoosh]: https://squoosh.app
|
||||
[nix]: https://nixos.org
|
||||
|
||||
3
cli/.gitignore
vendored
3
cli/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
build
|
||||
.DS_Store
|
||||
@@ -1 +0,0 @@
|
||||
node_modules
|
||||
@@ -1,63 +0,0 @@
|
||||
# Project no longer maintained
|
||||
|
||||
Unfortunately, due to a few people leaving the team, and staffing issues resulting from the current economic climate (ugh), this package is no longer actively maintained. I know that sucks, but there simply isn't the time & people to work on this. If anyone from the community wants to fork it, you have my blessing. The [squoosh.app](https://squoosh.app) will continue to be supported and improved.
|
||||
|
||||
# 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.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@squoosh/cli",
|
||||
"version": "0.7.3",
|
||||
"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.3",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
236
cli/src/index.js
236
cli/src/index.js
@@ -1,236 +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 { cpus } from 'os';
|
||||
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(cpus().length);
|
||||
|
||||
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 buffer = await fsp.readFile(file);
|
||||
const image = imagePool.ingestImage(buffer);
|
||||
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
codecs/.gitignore
vendored
Normal file
1
codecs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
!wasm_build
|
||||
@@ -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,12 @@ 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
|
||||
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 +33,10 @@ 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)
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
OUT_JS=$@ \
|
||||
@@ -42,9 +47,10 @@ $(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
|
||||
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV)
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
OUT_JS=$@ \
|
||||
@@ -54,11 +60,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 +76,56 @@ $(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
|
||||
$(LIBSHARPYUV): $(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,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,61 +1,31 @@
|
||||
CODEC_URL := https://github.com/mozilla/mozjpeg/archive/v3.3.1.tar.gz
|
||||
CODEC_DIR := node_modules/mozjpeg
|
||||
CODEC_OUT_RELATIVE := .libs/libjpeg.a rdswitch.o
|
||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||
ENVIRONMENT = worker
|
||||
|
||||
OUT_JS := enc/mozjpeg_enc.js enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js
|
||||
OUT_JS := enc/mozjpeg_enc.js
|
||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
# Define dependencies for all variations of build artifacts.
|
||||
$(filter enc/%,$(OUT_JS)): enc/mozjpeg_enc.cpp
|
||||
$(filter dec/%,$(OUT_JS)): dec/mozjpeg_dec.cpp
|
||||
|
||||
enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js: ENVIRONMENT = node
|
||||
|
||||
%.js: $(CODEC_OUT)
|
||||
%.js:
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR) \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
-O3 \
|
||||
-flto \
|
||||
-s FILESYSTEM=0 \
|
||||
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s TEXTDECODER=2 \
|
||||
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||
-s EXPORT_ES6=1 \
|
||||
-lembind \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
-o $@ \
|
||||
-I ${MOZJPEG}/include \
|
||||
-L ${MOZJPEG}/lib \
|
||||
-ljpeg \
|
||||
${MOZJPEG}/lib/rdswitch.o \
|
||||
$+
|
||||
|
||||
# This one is a bit special: there is no rule for .libs/libjpeg.a
|
||||
# so we use libjpeg.la which implicitly builds that one instead.
|
||||
$(CODEC_DIR)/.libs/libjpeg.a: $(CODEC_DIR)/Makefile
|
||||
$(MAKE) -C $(CODEC_DIR) libjpeg.la
|
||||
|
||||
$(CODEC_DIR)/rdswitch.o: $(CODEC_DIR)/Makefile
|
||||
$(MAKE) -C $(CODEC_DIR) rdswitch.o
|
||||
|
||||
$(CODEC_DIR)/Makefile: $(CODEC_DIR)/configure
|
||||
cd $(CODEC_DIR) && ./configure \
|
||||
--disable-shared \
|
||||
--without-turbojpeg \
|
||||
--without-simd \
|
||||
--without-arith-enc \
|
||||
--without-arith-dec \
|
||||
--with-build-date=squoosh
|
||||
# ^ If not provided with a dummy value, MozJPEG includes a build date in the
|
||||
# binary as part of the version string, making binaries different each time.
|
||||
|
||||
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
|
||||
cd $(CODEC_DIR) && autoreconf -iv
|
||||
|
||||
$(CODEC_DIR)/configure.ac: $(CODEC_DIR)
|
||||
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $@
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_DIR) clean
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
#include "config.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
extern "C" {
|
||||
#include "cdjpeg.h"
|
||||
}
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||
thread_local const val ImageData = val::global("ImageData");
|
||||
|
||||
val decode(std::string image_in) {
|
||||
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||
|
||||
jpeg_decompress_struct cinfo;
|
||||
jpeg_error_mgr jerr;
|
||||
// Initialize the JPEG decompression object with default error handling.
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_mem_src(&cinfo, image_buffer, image_in.length());
|
||||
// Read file header, set default decompression parameters
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
// Force RGBA decoding, even for grayscale images
|
||||
cinfo.out_color_space = JCS_EXT_RGBA;
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
// Prepare output buffer
|
||||
size_t output_size = cinfo.output_width * cinfo.output_height * 4;
|
||||
std::vector<uint8_t> output_buffer(output_size);
|
||||
auto stride = cinfo.output_width * 4;
|
||||
|
||||
// Process data
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
uint8_t* ptr = &output_buffer[stride * cinfo.output_scanline];
|
||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||
}
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
// Step 7: release JPEG compression object
|
||||
|
||||
auto data = Uint8ClampedArray.new_(typed_memory_view(output_size, &output_buffer[0]));
|
||||
auto js_result = ImageData.new_(data, cinfo.output_width, cinfo.output_height);
|
||||
|
||||
// This is an important step since it will release a good deal of memory.
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
|
||||
// And we're done!
|
||||
return js_result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
function("decode", &decode);
|
||||
}
|
||||
16
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
16
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -5,7 +5,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "jconfig.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
16
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
16
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
16
codecs/mozjpeg/enc/mozjpeg_node_enc.js
generated
16
codecs/mozjpeg/enc/mozjpeg_node_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
79
codecs/mozjpeg/flake.lock
generated
Normal file
79
codecs/mozjpeg/flake.lock
generated
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"mozjpeg-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1499684294,
|
||||
"narHash": "sha256-frpQdkk7bJE5qbV70fdL1FsC4eI0Fm8FWshqBQxCRtk=",
|
||||
"owner": "mozilla",
|
||||
"repo": "mozjpeg",
|
||||
"rev": "f154ccc091cbc22141cdfd531e5ad1fdc5bc53c7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "mozilla",
|
||||
"ref": "v3.3.1",
|
||||
"repo": "mozjpeg",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1717179513,
|
||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"mozjpeg-src": "mozjpeg-src",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
92
codecs/mozjpeg/flake.nix
Normal file
92
codecs/mozjpeg/flake.nix
Normal file
@@ -0,0 +1,92 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
mozjpeg-src = {
|
||||
url = "github:mozilla/mozjpeg/v3.3.1";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
mozjpeg-src,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) callPackage stdenv lib;
|
||||
|
||||
buildSquooshCppCodec = callPackage (import ../../nix/squoosh-cxx-builder) { };
|
||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
||||
inherit (squooshHelpers) forAllVariants mkRepoBinaryUpdater;
|
||||
|
||||
variants = {
|
||||
base = { };
|
||||
};
|
||||
|
||||
src = lib.sources.sourceByRegex ./. [
|
||||
"Makefile"
|
||||
"enc(/.+)?"
|
||||
];
|
||||
|
||||
builder = variantName: opts: {
|
||||
mozjpeg-squoosh = buildSquooshCppCodec {
|
||||
name = "mozjpeg-squoosh";
|
||||
inherit src;
|
||||
MOZJPEG = self.packages.${system}."mozjpeg-${variantName}";
|
||||
|
||||
dontConfigure = true;
|
||||
decoder = null;
|
||||
};
|
||||
|
||||
mozjpeg = stdenv.mkDerivation {
|
||||
name = "mozjpeg";
|
||||
src = mozjpeg-src;
|
||||
nativeBuildInputs = [
|
||||
pkgs.autoconf
|
||||
pkgs.automake
|
||||
pkgs.libtool
|
||||
pkgs.emscripten
|
||||
pkgs.pkg-config
|
||||
];
|
||||
configurePhase = ''
|
||||
# $HOME is required for Emscripten to work.
|
||||
# See: https://nixos.org/manual/nixpkgs/stable/#emscripten
|
||||
export HOME=$TMPDIR
|
||||
autoreconf -ifv
|
||||
emconfigure ./configure \
|
||||
--disable-shared \
|
||||
--without-turbojpeg \
|
||||
--without-simd \
|
||||
--without-arith-enc \
|
||||
--without-arith-dec \
|
||||
--with-build-date=squoosh \
|
||||
--prefix=$out
|
||||
'';
|
||||
buildPhase = ''
|
||||
export HOME=$TMPDIR
|
||||
emmake make V=1 -j$(nproc) --trace
|
||||
'';
|
||||
installPhase = ''
|
||||
make install
|
||||
cp *.h $out/include
|
||||
cp rdswitch.o $out/lib
|
||||
'';
|
||||
dontFixup = true;
|
||||
};
|
||||
};
|
||||
|
||||
packageVariants = forAllVariants { inherit builder variants; };
|
||||
in
|
||||
|
||||
mkRepoBinaryUpdater {
|
||||
packages = packageVariants // {
|
||||
default = packageVariants."mozjpeg-squoosh-base";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
4
codecs/mozjpeg/package-lock.json
generated
4
codecs/mozjpeg/package-lock.json
generated
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "mozjpeg_enc",
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "../build-cpp.sh"
|
||||
}
|
||||
}
|
||||
239
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.cpp
Normal file
239
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <inttypes.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jconfig.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
extern "C" {
|
||||
#include "cdjpeg.h"
|
||||
}
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro
|
||||
// hackery to turn it into a string. More details here:
|
||||
// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
struct MozJpegOptions {
|
||||
int quality;
|
||||
bool baseline;
|
||||
bool arithmetic;
|
||||
bool progressive;
|
||||
bool optimize_coding;
|
||||
int smoothing;
|
||||
int color_space;
|
||||
int quant_table;
|
||||
bool trellis_multipass;
|
||||
bool trellis_opt_zero;
|
||||
bool trellis_opt_table;
|
||||
int trellis_loops;
|
||||
bool auto_subsample;
|
||||
int chroma_subsample;
|
||||
bool separate_chroma_quality;
|
||||
int chroma_quality;
|
||||
};
|
||||
|
||||
int version() {
|
||||
char buffer[] = xstr(MOZJPEG_VERSION);
|
||||
int version = 0;
|
||||
int last_index = 0;
|
||||
for (int i = 0; i < strlen(buffer); i++) {
|
||||
if (buffer[i] == '.') {
|
||||
buffer[i] = '\0';
|
||||
version = version << 8 | atoi(&buffer[last_index]);
|
||||
buffer[i] = '.';
|
||||
last_index = i + 1;
|
||||
}
|
||||
}
|
||||
version = version << 8 | atoi(&buffer[last_index]);
|
||||
return version;
|
||||
}
|
||||
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
val encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts) {
|
||||
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||
|
||||
// The code below is basically the `write_JPEG_file` function from
|
||||
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
||||
// I just write to memory instead of a file.
|
||||
|
||||
/* Step 1: allocate and initialize JPEG compression object */
|
||||
|
||||
/* This struct contains the JPEG compression parameters and pointers to
|
||||
* working space (which is allocated as needed by the JPEG library).
|
||||
* It is possible to have several such structures, representing multiple
|
||||
* compression/decompression processes, in existence at once. We refer
|
||||
* to any one struct (and its associated working data) as a "JPEG object".
|
||||
*/
|
||||
jpeg_compress_struct cinfo;
|
||||
/* This struct represents a JPEG error handler. It is declared separately
|
||||
* because applications often want to supply a specialized error handler
|
||||
* (see the second half of this file for an example). But here we just
|
||||
* take the easy way out and use the standard error handler, which will
|
||||
* print a message on stderr and call exit() if compression fails.
|
||||
* Note that this struct must live as long as the main JPEG parameter
|
||||
* struct, to avoid dangling-pointer problems.
|
||||
*/
|
||||
jpeg_error_mgr jerr;
|
||||
/* We have to set up the error handler first, in case the initialization
|
||||
* step fails. (Unlikely, but it could happen if you are out of memory.)
|
||||
* This routine fills in the contents of struct jerr, and returns jerr's
|
||||
* address which we place into the link field in cinfo.
|
||||
*/
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
/* Now we can initialize the JPEG compression object. */
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
/* Step 2: specify data destination (eg, a file) */
|
||||
/* Note: steps 2 and 3 can be done in either order. */
|
||||
|
||||
/* Here we use the library-supplied code to send compressed data to a
|
||||
* stdio stream. You can also write your own code to do something else.
|
||||
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
||||
* requires it in order to write binary files.
|
||||
*/
|
||||
// if ((outfile = fopen(filename, "wb")) == NULL) {
|
||||
// fprintf(stderr, "can't open %s\n", filename);
|
||||
// exit(1);
|
||||
// }
|
||||
uint8_t* output = nullptr;
|
||||
unsigned long size = 0;
|
||||
jpeg_mem_dest(&cinfo, &output, &size);
|
||||
|
||||
/* Step 3: set parameters for compression */
|
||||
|
||||
/* First we supply a description of the input image.
|
||||
* Four fields of the cinfo struct must be filled in:
|
||||
*/
|
||||
cinfo.image_width = image_width; /* image width and height, in pixels */
|
||||
cinfo.image_height = image_height;
|
||||
cinfo.input_components = 4; /* # of color components per pixel */
|
||||
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
||||
/* Now use the library's routine to set default compression parameters.
|
||||
* (You must set at least cinfo.in_color_space before calling this,
|
||||
* since the defaults depend on the source color space.)
|
||||
*/
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
jpeg_set_colorspace(&cinfo, (J_COLOR_SPACE)opts.color_space);
|
||||
|
||||
if (opts.quant_table != -1) {
|
||||
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
||||
}
|
||||
|
||||
cinfo.optimize_coding = opts.optimize_coding;
|
||||
|
||||
if (opts.arithmetic) {
|
||||
cinfo.arith_code = TRUE;
|
||||
cinfo.optimize_coding = FALSE;
|
||||
}
|
||||
|
||||
cinfo.smoothing_factor = opts.smoothing;
|
||||
|
||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_SCANS_IN_TRELLIS, opts.trellis_multipass);
|
||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
||||
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
||||
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 0);
|
||||
|
||||
// A little hacky to build a string for this, but it means we can use
|
||||
// set_quality_ratings which does some useful heuristic stuff.
|
||||
std::string quality_str = std::to_string(opts.quality);
|
||||
|
||||
if (opts.separate_chroma_quality && opts.color_space == JCS_YCbCr) {
|
||||
quality_str += "," + std::to_string(opts.chroma_quality);
|
||||
}
|
||||
|
||||
char const* pqual = quality_str.c_str();
|
||||
|
||||
set_quality_ratings(&cinfo, (char*)pqual, opts.baseline);
|
||||
|
||||
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
||||
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
||||
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
||||
|
||||
if (opts.chroma_subsample > 2) {
|
||||
// Otherwise encoding fails.
|
||||
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts.baseline && opts.progressive) {
|
||||
jpeg_simple_progression(&cinfo);
|
||||
} else {
|
||||
cinfo.num_scans = 0;
|
||||
cinfo.scan_info = NULL;
|
||||
}
|
||||
/* Step 4: Start compressor */
|
||||
|
||||
/* TRUE ensures that we will write a complete interchange-JPEG file.
|
||||
* Pass TRUE unless you are very sure of what you're doing.
|
||||
*/
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
/* Step 5: while (scan lines remain to be written) */
|
||||
/* jpeg_write_scanlines(...); */
|
||||
|
||||
/* Here we use the library's state variable cinfo.next_scanline as the
|
||||
* loop counter, so that we don't have to keep track ourselves.
|
||||
* To keep things simple, we pass one scanline per call; you can pass
|
||||
* more if you wish, though.
|
||||
*/
|
||||
int row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height) {
|
||||
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
||||
* Here the array is only one element long, but you could pass
|
||||
* more than one scanline at a time if that's more convenient.
|
||||
*/
|
||||
|
||||
JSAMPROW row_pointer =
|
||||
&image_buffer[cinfo.next_scanline * row_stride]; /* pointer to JSAMPLE row[s] */
|
||||
(void)jpeg_write_scanlines(&cinfo, &row_pointer, 1);
|
||||
}
|
||||
|
||||
/* Step 6: Finish compression */
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
/* Step 7: release JPEG compression object */
|
||||
|
||||
auto js_result = Uint8Array.new_(typed_memory_view(size, output));
|
||||
|
||||
/* This is an important step since it will release a good deal of memory. */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(output);
|
||||
|
||||
/* And we're done! */
|
||||
return js_result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<MozJpegOptions>("MozJpegOptions")
|
||||
.field("quality", &MozJpegOptions::quality)
|
||||
.field("baseline", &MozJpegOptions::baseline)
|
||||
.field("arithmetic", &MozJpegOptions::arithmetic)
|
||||
.field("progressive", &MozJpegOptions::progressive)
|
||||
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
||||
.field("smoothing", &MozJpegOptions::smoothing)
|
||||
.field("color_space", &MozJpegOptions::color_space)
|
||||
.field("quant_table", &MozJpegOptions::quant_table)
|
||||
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
||||
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
||||
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
||||
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
||||
.field("chroma_subsample", &MozJpegOptions::chroma_subsample)
|
||||
.field("auto_subsample", &MozJpegOptions::auto_subsample)
|
||||
.field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality)
|
||||
.field("chroma_quality", &MozJpegOptions::chroma_quality);
|
||||
|
||||
function("version", &version);
|
||||
function("encode", &encode);
|
||||
}
|
||||
37
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.d.ts
vendored
Normal file
37
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.d.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
export const enum MozJpegColorSpace {
|
||||
GRAYSCALE = 1,
|
||||
RGB,
|
||||
YCbCr,
|
||||
}
|
||||
|
||||
export interface EncodeOptions {
|
||||
quality: number;
|
||||
baseline: boolean;
|
||||
arithmetic: boolean;
|
||||
progressive: boolean;
|
||||
optimize_coding: boolean;
|
||||
smoothing: number;
|
||||
color_space: MozJpegColorSpace;
|
||||
quant_table: number;
|
||||
trellis_multipass: boolean;
|
||||
trellis_opt_zero: boolean;
|
||||
trellis_opt_table: boolean;
|
||||
trellis_loops: number;
|
||||
auto_subsample: boolean;
|
||||
chroma_subsample: number;
|
||||
separate_chroma_quality: boolean;
|
||||
chroma_quality: number;
|
||||
}
|
||||
|
||||
export interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<MozJPEGModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
16
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.js
generated
Normal file
16
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.wasm
Executable file
BIN
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.wasm
Executable file
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"
|
||||
}
|
||||
}
|
||||
|
||||
115
codecs/resize/flake.lock
generated
Normal file
115
codecs/resize/flake.lock
generated
Normal file
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1723616992,
|
||||
"narHash": "sha256-jDHYfEECzFwZm4huz7AbPjlH3jJ4/2ns9PddtFA5XMY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1725432240,
|
||||
"narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ad416d066ca1222956472ab7d0555a6946746a80",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1717179513,
|
||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1725548942,
|
||||
"narHash": "sha256-ZnF5MaOAeiiKIATYN4rrqNsnhSQOQ+Hvfg0mHLvN04Y=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "124c7482167ff6eea4f7663c0be87ea568ccd8c6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
57
codecs/resize/flake.nix
Normal file
57
codecs/resize/flake.nix
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
fenix.url = "github:nix-community/fenix/7bad6c7ff73b784a9c7de9147626c8d5d5072809";
|
||||
};
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
fenix,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) callPackage lib;
|
||||
|
||||
buildSquooshRustCodec = callPackage (import ../../nix/squoosh-rust-builder) {
|
||||
fenix = fenix.packages.${system};
|
||||
};
|
||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
||||
inherit (squooshHelpers) mkRepoBinaryUpdater forAllVariants;
|
||||
|
||||
variants = {
|
||||
base = { };
|
||||
};
|
||||
|
||||
src = lib.sources.sourceByRegex ./. [
|
||||
"Cargo.*"
|
||||
"build\.rs"
|
||||
"src(/.+)?"
|
||||
];
|
||||
|
||||
builder = variantName: opts: {
|
||||
resize-squoosh = buildSquooshRustCodec {
|
||||
name = "resize-squoosh";
|
||||
inherit src;
|
||||
cargoLock = {
|
||||
lockFile = "${src}/Cargo.lock";
|
||||
};
|
||||
wasmBindgen = {
|
||||
sha256 = "sha256-HTElSB76gqCpDu8S0ZJlfd/S4ftMrbwxFgJM9OXBRz8=";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
packageVariants = forAllVariants { inherit builder variants; };
|
||||
in
|
||||
mkRepoBinaryUpdater {
|
||||
packages = packageVariants // {
|
||||
default = packageVariants."resize-squoosh-base";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
4
codecs/resize/package-lock.json
generated
4
codecs/resize/package-lock.json
generated
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "resize",
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "resize",
|
||||
"scripts": {
|
||||
"build": "../build-rust.sh"
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "squoosh-resize",
|
||||
"collaborators": [
|
||||
"Surma <surma@surma.link>"
|
||||
],
|
||||
"version": "0.1.0",
|
||||
"files": [
|
||||
"squoosh_resize_bg.wasm",
|
||||
"squoosh_resize.js",
|
||||
"squoosh_resize.d.ts"
|
||||
],
|
||||
"module": "squoosh_resize.js",
|
||||
"types": "squoosh_resize.d.ts",
|
||||
"sideEffects": false
|
||||
}
|
||||
Binary file not shown.
BIN
codecs/resize/wasm_build/squoosh_resize_bg.wasm
Normal file
BIN
codecs/resize/wasm_build/squoosh_resize_bg.wasm
Normal file
Binary file not shown.
115
codecs/rotate/flake.lock
generated
Normal file
115
codecs/rotate/flake.lock
generated
Normal file
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1723616992,
|
||||
"narHash": "sha256-jDHYfEECzFwZm4huz7AbPjlH3jJ4/2ns9PddtFA5XMY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1723362943,
|
||||
"narHash": "sha256-dFZRVSgmJkyM0bkPpaYRtG/kRMRTorUIDj8BxoOt1T4=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a58bc8ad779655e790115244571758e8de055e3d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1717179513,
|
||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1723561310,
|
||||
"narHash": "sha256-a3KMMsIDvdo+ClLabh5wfJoa17YTSvy2wDLb8yZCXvc=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "78c2bdce860dbd996a8083224d01a96660dd6a15",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
54
codecs/rotate/flake.nix
Normal file
54
codecs/rotate/flake.nix
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
fenix.url = "github:nix-community/fenix/7bad6c7ff73b784a9c7de9147626c8d5d5072809";
|
||||
};
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
fenix,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
inherit (pkgs) callPackage lib;
|
||||
|
||||
buildSquooshRustCodec = callPackage (import ../../nix/squoosh-rust-builder) {
|
||||
fenix = fenix.packages.${system};
|
||||
};
|
||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
||||
inherit (squooshHelpers) mkRepoBinaryUpdater forAllVariants;
|
||||
|
||||
variants = {
|
||||
base = { };
|
||||
};
|
||||
|
||||
src = lib.sources.sourceByRegex ./. [
|
||||
"Cargo\.*"
|
||||
".*\.rs"
|
||||
];
|
||||
|
||||
builder = variantName: opts: {
|
||||
rotate-squoosh = buildSquooshRustCodec {
|
||||
name = "rotate-squoosh";
|
||||
inherit src;
|
||||
cargoLock = {
|
||||
lockFile = "${src}/Cargo.lock";
|
||||
};
|
||||
wasmBindgen = null;
|
||||
};
|
||||
};
|
||||
|
||||
packageVariants = forAllVariants { inherit builder variants; };
|
||||
in
|
||||
mkRepoBinaryUpdater {
|
||||
packages = packageVariants // {
|
||||
default = packageVariants."rotate-squoosh-base";
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
Binary file not shown.
BIN
codecs/rotate/wasm_build/optimized.wasm
Normal file
BIN
codecs/rotate/wasm_build/optimized.wasm
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
CODEC_URL = https://github.com/webmproject/libwebp/archive/d2e245ea9e959a5a79e1db0ed2085206947e98f2.tar.gz
|
||||
CODEC_DIR = node_modules/libwebp
|
||||
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
|
||||
CODEC_BASELINE_BUILD_DIR := $(CODEC_BUILD_ROOT)/baseline
|
||||
CODEC_SIMD_BUILD_DIR := $(CODEC_BUILD_ROOT)/simd
|
||||
ENVIRONMENT = worker
|
||||
|
||||
OUT_JS = enc/webp_enc.js enc/webp_enc_simd.js dec/webp_dec.js enc/webp_node_enc.js dec/webp_node_dec.js
|
||||
# OUT_JS = enc/webp_enc.js enc/webp_enc_simd.js dec/webp_dec.js
|
||||
OUT_JS = enc/webp_enc.js dec/webp_dec.js
|
||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
@@ -15,54 +11,41 @@ all: $(OUT_JS)
|
||||
# Define dependencies for all variations of build artifacts.
|
||||
$(filter enc/%,$(OUT_JS)): enc/webp_enc.o
|
||||
$(filter dec/%,$(OUT_JS)): dec/webp_dec.o
|
||||
enc/webp_node_enc.js dec/webp_node_dec.js: ENVIRONMENT = node
|
||||
enc/webp_node_enc.js dec/webp_node_dec.js: $(CODEC_BASELINE_BUILD_DIR)/libwebp.a
|
||||
enc/webp_enc.js dec/webp_dec.js: $(CODEC_BASELINE_BUILD_DIR)/libwebp.a
|
||||
enc/webp_enc_simd.js: $(CODEC_SIMD_BUILD_DIR)/libwebp.a
|
||||
# enc/webp_enc.js dec/webp_dec.js: $(CODEC_BASELINE_BUILD_DIR)/libwebp.a
|
||||
# enc/webp_enc_simd.js: $(CODEC_SIMD_BUILD_DIR)/libwebp.a
|
||||
|
||||
LIBWEBP_FLAGS = -I${WEBP}/include -L${WEBP}/lib -lwebp
|
||||
|
||||
$(OUT_JS):
|
||||
$(LD) \
|
||||
-O3 \
|
||||
-flto \
|
||||
-std=c++17 \
|
||||
-s FILESYSTEM=0 \
|
||||
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s TEXTDECODER=2 \
|
||||
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
||||
$(LIBWEBP_FLAGS) \
|
||||
$(LDFLAGS) \
|
||||
--bind \
|
||||
-lembind \
|
||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||
-s EXPORT_ES6=1 \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
%.o: %.cpp $(CODEC_DIR)/CMakeLists.txt
|
||||
%.o: %.cpp
|
||||
$(CXX) -c \
|
||||
-O3 \
|
||||
-flto \
|
||||
-std=c++17 \
|
||||
-s FILESYSTEM=0 \
|
||||
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s TEXTDECODER=2 \
|
||||
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
||||
$(LIBWEBP_FLAGS) \
|
||||
$(CXXFLAGS) \
|
||||
-I $(CODEC_DIR) \
|
||||
-o $@ \
|
||||
$<
|
||||
|
||||
%/libwebp.a: %/Makefile
|
||||
$(MAKE) -C $(@D)
|
||||
|
||||
# Enable SIMD on a SIMD build.
|
||||
$(CODEC_SIMD_BUILD_DIR)/Makefile: CMAKE_FLAGS+=-DWEBP_ENABLE_SIMD=1
|
||||
|
||||
%/Makefile: $(CODEC_DIR)/CMakeLists.txt
|
||||
emcmake cmake \
|
||||
$(CMAKE_FLAGS) \
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_Threads=1 \
|
||||
-DWEBP_BUILD_ANIM_UTILS=0 \
|
||||
-DWEBP_BUILD_CWEBP=0 \
|
||||
-DWEBP_BUILD_DWEBP=0 \
|
||||
-DWEBP_BUILD_GIF2WEBP=0 \
|
||||
-DWEBP_BUILD_IMG2WEBP=0 \
|
||||
-DWEBP_BUILD_VWEBP=0 \
|
||||
-DWEBP_BUILD_WEBPINFO=0 \
|
||||
-DWEBP_BUILD_WEBPMUX=0 \
|
||||
-DWEBP_BUILD_EXTRAS=0 \
|
||||
-B $(@D) \
|
||||
$(<D)
|
||||
|
||||
$(CODEC_DIR)/CMakeLists.txt:
|
||||
mkdir -p $(CODEC_DIR)
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $(CODEC_DIR)
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_BASELINE_BUILD_DIR) clean
|
||||
$(MAKE) -C $(CODEC_SIMD_BUILD_DIR) clean
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <string>
|
||||
#include "emscripten/bind.h"
|
||||
#include "emscripten/val.h"
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/demux.h"
|
||||
#include "webp/decode.h"
|
||||
#include "webp/demux.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
|
||||
16
codecs/webp/dec/webp_dec.js
generated
16
codecs/webp/dec/webp_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
16
codecs/webp/dec/webp_node_dec.js
generated
16
codecs/webp/dec/webp_node_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdexcept>
|
||||
#include "src/webp/encode.h"
|
||||
#include "webp/encode.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
|
||||
16
codecs/webp/enc/webp_enc.js
generated
16
codecs/webp/enc/webp_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
16
codecs/webp/enc/webp_enc_simd.js
generated
16
codecs/webp/enc/webp_enc_simd.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user