forked from external-repos/squoosh
Compare commits
309 Commits
mozjpeg-wa
...
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 | ||
|
|
918c596cba | ||
|
|
42594277fd | ||
|
|
97d13de273 | ||
|
|
a1c3304c56 | ||
|
|
7a2fc917c1 | ||
|
|
1c4233b5ae | ||
|
|
4d67ec5a7b | ||
|
|
c24505230d | ||
|
|
2238d1abaf | ||
|
|
65ea02627b | ||
|
|
18b53e2b8a | ||
|
|
66ec763667 | ||
|
|
029eda7b37 | ||
|
|
e6810059ef | ||
|
|
4eba015009 | ||
|
|
dd49a1f23d | ||
|
|
5ecb99992c | ||
|
|
d9c6ebe0a2 | ||
|
|
fba67a7a18 | ||
|
|
129b925098 | ||
|
|
e23bc4d2e5 | ||
|
|
f523a07f01 | ||
|
|
e3f840c6da | ||
|
|
cad09160b6 | ||
|
|
9663c23489 | ||
|
|
95a1b35c91 | ||
|
|
914cdea41d | ||
|
|
6bfce29af6 | ||
|
|
64cad1cc23 | ||
|
|
87f25d909b | ||
|
|
bdfdaf53af | ||
|
|
1ab9e8b3ab | ||
|
|
2718077d3d | ||
|
|
255dfa434a | ||
|
|
0bef05bcd4 | ||
|
|
c4bc369c6b | ||
|
|
68ce8f420d | ||
|
|
27f103fee5 | ||
|
|
c21d3714a8 | ||
|
|
3ea0d88c4f | ||
|
|
00cfdafdf3 | ||
|
|
92f52319da | ||
|
|
023304803f | ||
|
|
6b08cd2355 | ||
|
|
db1a5138e6 | ||
|
|
a547491146 | ||
|
|
6e427f9208 | ||
|
|
0d35fbd349 | ||
|
|
4e901c714c | ||
|
|
b74788e036 | ||
|
|
14c3d190e9 | ||
|
|
202d0bc088 | ||
|
|
bdb5b16372 | ||
|
|
30140c2b7a | ||
|
|
10996cdbca | ||
|
|
e5806507d4 | ||
|
|
1c5b44f9a1 | ||
|
|
eeaa19589e | ||
|
|
35b8c56f1a | ||
|
|
816d1f92fd | ||
|
|
4091f2efec | ||
|
|
821d14c6ab | ||
|
|
a72ca46531 | ||
|
|
fafcf97f0c | ||
|
|
d526877147 | ||
|
|
0ed7ef842f | ||
|
|
de4eb9c8f7 | ||
|
|
16a53caa48 | ||
|
|
3d4c62fede | ||
|
|
ce7be359c0 | ||
|
|
3f2dd66726 | ||
|
|
9198f748b8 | ||
|
|
a726adf0e8 | ||
|
|
04580b0bcb | ||
|
|
a040c47047 | ||
|
|
2427763a14 | ||
|
|
c582c54922 | ||
|
|
9ae27c1887 | ||
|
|
bf95eb39c2 | ||
|
|
011c0346c1 | ||
|
|
9b36c3f9af | ||
|
|
490fe2aace | ||
|
|
48efb4ddeb | ||
|
|
0977bd94d3 | ||
|
|
d5f12a8c61 | ||
|
|
fb867dcdaa | ||
|
|
f038c1bd7d | ||
|
|
b37cc0784f | ||
|
|
ff40000473 | ||
|
|
7232524f4d | ||
|
|
bf683cdf59 | ||
|
|
f848a9384e | ||
|
|
d4d0db6c49 | ||
|
|
0719abff27 | ||
|
|
2c561687af | ||
|
|
cd20082e5d | ||
|
|
8262c79bb6 | ||
|
|
ef176d7565 | ||
|
|
3b0b7dbdb1 | ||
|
|
cc9a887386 | ||
|
|
71ca1ab0ca | ||
|
|
f5d9535fd2 | ||
|
|
cea6a61366 | ||
|
|
192cfc62ee | ||
|
|
fe21322b2b | ||
|
|
d953822d19 | ||
|
|
021b082884 | ||
|
|
ad5002c79c | ||
|
|
883bb92e48 | ||
|
|
79efd0d32e | ||
|
|
99741d665d | ||
|
|
b38765b4e6 | ||
|
|
a11ac15008 | ||
|
|
4f6d21199c | ||
|
|
fb7e00067f | ||
|
|
a2121ec47b | ||
|
|
d4056026fb | ||
|
|
d12b040bd3 | ||
|
|
149ebf5a67 | ||
|
|
d8297aad10 | ||
|
|
0e84a5b5f7 | ||
|
|
187a5bed01 | ||
|
|
07a288398e | ||
|
|
dbb31a1add | ||
|
|
6e58e8edb0 | ||
|
|
955079b18f | ||
|
|
f6f70c590e | ||
|
|
55c4aa51ac | ||
|
|
aea316c604 | ||
|
|
d604e94ad2 | ||
|
|
61de471e52 | ||
|
|
955b2ac1ba | ||
|
|
3d225966c5 | ||
|
|
851da25302 | ||
|
|
32e3528666 | ||
|
|
1e52837931 | ||
|
|
5bc80e66ec | ||
|
|
b1f50cd27c | ||
|
|
3d136016e2 | ||
|
|
14a715e952 | ||
|
|
324b04d398 | ||
|
|
eb76fbc4bc | ||
|
|
1d292468b0 | ||
|
|
828f9a5eeb | ||
|
|
5595525c8a | ||
|
|
5e14444b13 | ||
|
|
3d58c616af | ||
|
|
d7090042a6 | ||
|
|
be3249bf2f | ||
|
|
1b59c3f47a | ||
|
|
9a37cc7959 | ||
|
|
ffb9135a7a | ||
|
|
5707eeff41 | ||
|
|
a18ed360eb | ||
|
|
011d0c2099 | ||
|
|
89105bbb22 | ||
|
|
5f7c619413 | ||
|
|
3ec7d4db16 | ||
|
|
8ef8cef522 | ||
|
|
f6431d8147 | ||
|
|
be037754ce | ||
|
|
32107124e6 | ||
|
|
1af5d1fa7b | ||
|
|
08adfba8be | ||
|
|
5df04f6419 | ||
|
|
cf570a4d3f | ||
|
|
2aa691339c | ||
|
|
9fcb4a4c55 | ||
|
|
18e3d77aef | ||
|
|
6a4982bf4c | ||
|
|
c7b998a877 | ||
|
|
e5b2030666 | ||
|
|
0e09d0b33f | ||
|
|
ed03a37fb8 | ||
|
|
2bc4ab8fd6 | ||
|
|
2037fe8964 | ||
|
|
d07c57ecaa | ||
|
|
e7d55bf903 | ||
|
|
687cf5aae2 | ||
|
|
d63823d196 | ||
|
|
7d111b6a43 | ||
|
|
426f31e548 | ||
|
|
dd0adba6b1 | ||
|
|
30445927ea | ||
|
|
31b263fc27 | ||
|
|
fc590918ed | ||
|
|
c4783b03df | ||
|
|
8f9c0ff0e7 | ||
|
|
40c81ef782 | ||
|
|
397193a5f5 | ||
|
|
f91c7a267d | ||
|
|
99f2286a73 | ||
|
|
f414092ea9 | ||
|
|
c683dfaaed | ||
|
|
12fb647fde | ||
|
|
2ee1dfa867 | ||
|
|
fa331586d7 | ||
|
|
4192c607f1 | ||
|
|
128096afd9 | ||
|
|
58661078e2 | ||
|
|
cbfa503fcb | ||
|
|
96b6dc8e6e | ||
|
|
4033d1c965 | ||
|
|
f779e13bc8 | ||
|
|
2f00fe2b1b | ||
|
|
118885cd26 | ||
|
|
af80643809 | ||
|
|
1aba7b51ee | ||
|
|
b0a7b21b0b | ||
|
|
8dfe35aa77 | ||
|
|
1a891072c0 | ||
|
|
720cb98872 | ||
|
|
4e1dcb819c | ||
|
|
c36f4bebb8 | ||
|
|
c04bb54f0d | ||
|
|
4890c56abb | ||
|
|
392aced394 | ||
|
|
8bcaeb2f78 | ||
|
|
c417bd0a7a | ||
|
|
eb8204d69b | ||
|
|
25754b91b7 | ||
|
|
875c24525b | ||
|
|
50ed5febd3 | ||
|
|
10c5082499 | ||
|
|
f0fb891498 | ||
|
|
b9b6e57581 | ||
|
|
ff9dea465f | ||
|
|
912c1fac08 | ||
|
|
ad0d46de3e | ||
|
|
efc89efba5 | ||
|
|
8ed50d8f0c | ||
|
|
b50402e3b3 | ||
|
|
df65f1a112 |
4
.gitattributes
vendored
4
.gitattributes
vendored
@@ -1,2 +1,2 @@
|
|||||||
/codecs/**/*.js linguist-generated=true
|
/codecs/**/*.js linguist-generated -diff
|
||||||
/codecs/*/pkg*/*.d.ts linguist-generated=true
|
/codecs/*/pkg*/*.d.ts linguist-generated
|
||||||
|
|||||||
1
.husky/pre-commit
Executable file
1
.husky/pre-commit
Executable file
@@ -0,0 +1 @@
|
|||||||
|
npx lint-staged
|
||||||
60
README.md
60
README.md
@@ -1,36 +1,60 @@
|
|||||||
# [Squoosh]!
|
# [Squoosh]!
|
||||||
|
|
||||||
[Squoosh] is an image compression web app that allows you to dive into the advanced options provided
|
[Squoosh] is an image compression web app that reduces image sizes through numerous formats.
|
||||||
by various image compressors.
|
|
||||||
|
|
||||||
# CLI
|
|
||||||
|
|
||||||
[Squoosh now has a CLI](https://github.com/GoogleChromeLabs/squoosh/tree/dev/cli) that allows you to compress many images at once.
|
|
||||||
|
|
||||||
# Privacy
|
# Privacy
|
||||||
|
|
||||||
Google Analytics is used to record the following:
|
Squoosh does not send your image to a server. All image compression processes locally.
|
||||||
|
|
||||||
- [Basic visit data](https://support.google.com/analytics/answer/6004245?ref_topic=2919631).
|
However, Squoosh utilizes Google Analytics to collect the following:
|
||||||
- Before and after image size once an image is downloaded. These values are rounded to the nearest
|
|
||||||
kilobyte.
|
|
||||||
- If install is available, when Squoosh is installed, and what method was used to install Squoosh.
|
|
||||||
|
|
||||||
Image compression is handled locally; no additional data is sent to the server.
|
- [Basic visitor data](https://support.google.com/analytics/answer/6004245?ref_topic=2919631).
|
||||||
|
- The before and after image size value.
|
||||||
|
- If Squoosh PWA, the type of Squoosh installation.
|
||||||
|
- If Squoosh PWA, the installation time and date.
|
||||||
|
|
||||||
# Building locally
|
# Developing
|
||||||
|
|
||||||
Clone the repo, and:
|
## Web App
|
||||||
|
|
||||||
|
To develop for Squoosh:
|
||||||
|
|
||||||
|
1. Clone the repository
|
||||||
|
1. To install node packages, run:
|
||||||
|
```sh
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
1. Then build the app by running:
|
||||||
|
```sh
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
1. After building, start the development server by running:
|
||||||
|
```sh
|
||||||
|
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
|
```sh
|
||||||
npm install
|
# Build the codec
|
||||||
npm run build
|
cd codec/<codec>
|
||||||
|
nix run '.#updateRepoBinaries'
|
||||||
```
|
```
|
||||||
|
|
||||||
You can run the development server with:
|
If you do not have Nix installed, you can use the provided Docker image to create a shell with nix available:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run dev
|
# 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
|
[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,59 +0,0 @@
|
|||||||
# Squoosh CLI
|
|
||||||
|
|
||||||
Squoosh CLI is an _experimental_ way to run all the codecs you know from the [Squoosh] web app on your command line using WebAssembly. The Squoosh CLI uses a worker pool to parallelize processing images. This way you can apply the same codec to many images at once.
|
|
||||||
|
|
||||||
Squoosh CLI is currently not the fastest image compression tool in town and doesn’t aim to be. It is, however, fast enough to compress many images sufficiently quick at once.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
The Squoosh CLI can be used straight from the command line without installing using `npx`:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npx @squoosh/cli <options...>
|
|
||||||
```
|
|
||||||
|
|
||||||
Of course, you can also install the Squoosh CLI:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npm i -g @squoosh/cli
|
|
||||||
$ squoosh-cli <options...>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
Usage: squoosh-cli [options] <files...>
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-V, --version output the version number
|
|
||||||
-d, --output-dir <dir> Output directory (default: ".")
|
|
||||||
-s, --suffix <suffix> Append suffix to output files (default: "")
|
|
||||||
--max-optimizer-rounds <rounds> Maximum number of compressions to use for auto optimizations (default: "6")
|
|
||||||
--optimizer-butteraugli-target <butteraugli distance> Target Butteraugli distance for auto optimizer (default: "1.4")
|
|
||||||
--resize [config] Resize the image before compressing
|
|
||||||
--quant [config] Reduce the number of colors used (aka. paletting)
|
|
||||||
--rotate [config] Rotate image
|
|
||||||
--mozjpeg [config] Use MozJPEG to generate a .jpg file with the given configuration
|
|
||||||
--webp [config] Use WebP to generate a .webp file with the given configuration
|
|
||||||
--avif [config] Use AVIF to generate a .avif file with the given configuration
|
|
||||||
--jxl [config] Use JPEG-XL to generate a .jxl file with the given configuration
|
|
||||||
--wp2 [config] Use WebP2 to generate a .wp2 file with the given configuration
|
|
||||||
--oxipng [config] Use OxiPNG to generate a .png file with the given configuration
|
|
||||||
-h, --help display help for command
|
|
||||||
```
|
|
||||||
|
|
||||||
The default values for each `config` option can be found in the [`codecs.js`][codecs.js] 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.js]: https://github.com/GoogleChromeLabs/squoosh/blob/dev/cli/src/codecs.js
|
|
||||||
[butteraugli]: https://github.com/google/butteraugli
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { promises as fs } from "fs";
|
|
||||||
import { basename } from "path";
|
|
||||||
|
|
||||||
const defaultOpts = {
|
|
||||||
prefix: "asset-url"
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function assetPlugin(opts) {
|
|
||||||
opts = { ...defaultOpts, ...opts };
|
|
||||||
|
|
||||||
/** @type {Map<string, Buffer>} */
|
|
||||||
let assetIdToSourceBuffer;
|
|
||||||
|
|
||||||
const prefix = opts.prefix + ":";
|
|
||||||
return {
|
|
||||||
name: "asset-plugin",
|
|
||||||
buildStart() {
|
|
||||||
assetIdToSourceBuffer = new Map();
|
|
||||||
},
|
|
||||||
augmentChunkHash(info) {
|
|
||||||
// Get the sources for all assets imported by this chunk.
|
|
||||||
const buffers = Object.keys(info.modules)
|
|
||||||
.map(moduleId => assetIdToSourceBuffer.get(moduleId))
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
if (buffers.length === 0) return;
|
|
||||||
|
|
||||||
for (const moduleId of Object.keys(info.modules)) {
|
|
||||||
const buffer = assetIdToSourceBuffer.get(moduleId);
|
|
||||||
if (buffer) buffers.push(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
const combinedBuffer =
|
|
||||||
buffers.length === 1 ? buffers[0] : Buffer.concat(buffers);
|
|
||||||
|
|
||||||
return combinedBuffer;
|
|
||||||
},
|
|
||||||
async resolveId(id, importer) {
|
|
||||||
if (!id.startsWith(prefix)) return;
|
|
||||||
const realId = id.slice(prefix.length);
|
|
||||||
const resolveResult = await this.resolve(realId, importer);
|
|
||||||
|
|
||||||
if (!resolveResult) {
|
|
||||||
throw Error(`Cannot find ${realId}`);
|
|
||||||
}
|
|
||||||
// Add an additional .js to the end so it ends up with .js at the end in the _virtual folder.
|
|
||||||
return prefix + resolveResult.id + ".js";
|
|
||||||
},
|
|
||||||
async load(id) {
|
|
||||||
if (!id.startsWith(prefix)) return;
|
|
||||||
const realId = id.slice(prefix.length, -".js".length);
|
|
||||||
const source = await fs.readFile(realId);
|
|
||||||
assetIdToSourceBuffer.set(id, source);
|
|
||||||
this.addWatchFile(realId);
|
|
||||||
|
|
||||||
return `export default import.meta.ROLLUP_FILE_URL_${this.emitFile({
|
|
||||||
type: "asset",
|
|
||||||
source,
|
|
||||||
name: basename(realId)
|
|
||||||
})}`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { promises as fsp } from 'fs';
|
|
||||||
|
|
||||||
export default function autojsonPlugin() {
|
|
||||||
return {
|
|
||||||
name: 'autojson-plugin',
|
|
||||||
async load(id) {
|
|
||||||
if (id.endsWith('.json') && !id.startsWith('json:')) {
|
|
||||||
return 'export default ' + await fsp.readFile(id, 'utf8');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import { promises as fsp } from 'fs';
|
|
||||||
|
|
||||||
const prefix = 'json:';
|
|
||||||
|
|
||||||
const reservedKeys = ['public'];
|
|
||||||
|
|
||||||
export default function jsonPlugin() {
|
|
||||||
return {
|
|
||||||
name: 'json-plugin',
|
|
||||||
async resolveId(id, importer) {
|
|
||||||
if (!id.startsWith(prefix)) return;
|
|
||||||
const realId = id.slice(prefix.length);
|
|
||||||
const resolveResult = await this.resolve(realId, importer);
|
|
||||||
|
|
||||||
if (!resolveResult) {
|
|
||||||
throw Error(`Cannot find ${realId}`);
|
|
||||||
}
|
|
||||||
// Add an additional .js to the end so it ends up with .js at the end in the _virtual folder.
|
|
||||||
return prefix + resolveResult.id;
|
|
||||||
},
|
|
||||||
async load(id) {
|
|
||||||
if (!id.startsWith(prefix)) return;
|
|
||||||
const realId = id.slice(prefix.length);
|
|
||||||
const source = await fsp.readFile(realId, 'utf8');
|
|
||||||
|
|
||||||
let code = '';
|
|
||||||
for (const [key, value] of Object.entries(JSON.parse(source))) {
|
|
||||||
if (reservedKeys.includes(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
code += `
|
|
||||||
export const ${key} = ${JSON.stringify(value)};
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
2168
cli/package-lock.json
generated
2168
cli/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@squoosh/cli",
|
|
||||||
"version": "0.6.0",
|
|
||||||
"description": "A CLI for Squoosh",
|
|
||||||
"public": true,
|
|
||||||
"bin": {
|
|
||||||
"squoosh-cli": "build/index.js",
|
|
||||||
"@squoosh/cli": "build/index.js"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "rollup -c"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "Google Chrome Developers <chromium-dev@google.com>",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"web-streams-polyfill": "^3.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/core": "^7.11.6",
|
|
||||||
"@babel/preset-env": "^7.11.5",
|
|
||||||
"@rollup/plugin-babel": "^5.2.1",
|
|
||||||
"@rollup/plugin-commonjs": "^15.0.0",
|
|
||||||
"@rollup/plugin-node-resolve": "^9.0.0",
|
|
||||||
"commander": "^6.0.0",
|
|
||||||
"json5": "^2.1.3",
|
|
||||||
"kleur": "^4.1.3",
|
|
||||||
"ora": "^5.1.0",
|
|
||||||
"rollup": "^2.26.11",
|
|
||||||
"rollup-plugin-terser": "^7.0.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import resolve from '@rollup/plugin-node-resolve';
|
|
||||||
import cjs from '@rollup/plugin-commonjs';
|
|
||||||
import asset from './lib/asset-plugin.js';
|
|
||||||
import json from './lib/json-plugin.js';
|
|
||||||
import autojson from './lib/autojson-plugin.js';
|
|
||||||
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
|
|
||||||
import { builtinModules } from 'module';
|
|
||||||
|
|
||||||
/** @type {import('rollup').RollupOptions} */
|
|
||||||
export default {
|
|
||||||
input: 'src/index.js',
|
|
||||||
output: {
|
|
||||||
dir: 'build',
|
|
||||||
format: 'cjs',
|
|
||||||
assetFileNames: '[name]-[hash][extname]',
|
|
||||||
// This is needed so the resulting `index.js` can be
|
|
||||||
// executed by `npx`.
|
|
||||||
banner: '#!/usr/bin/env node',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
resolve(),
|
|
||||||
cjs(),
|
|
||||||
asset(),
|
|
||||||
autojson(),
|
|
||||||
json(),
|
|
||||||
getBabelOutputPlugin({
|
|
||||||
babelrc: false,
|
|
||||||
configFile: false,
|
|
||||||
minified: process.env.DEBUG != '',
|
|
||||||
comments: false,
|
|
||||||
presets: [
|
|
||||||
[
|
|
||||||
'@babel/preset-env',
|
|
||||||
{
|
|
||||||
targets: {
|
|
||||||
node: 12,
|
|
||||||
},
|
|
||||||
loose: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
external: builtinModules,
|
|
||||||
};
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
import { instantiateEmscriptenWasm } from "./emscripten-utils.js";
|
|
||||||
|
|
||||||
import visdif from "../../codecs/visdif/visdif.js";
|
|
||||||
import visdifWasm from "asset-url:../../codecs/visdif/visdif.wasm";
|
|
||||||
|
|
||||||
// `measure` is a (async) function that takes exactly one numeric parameter and
|
|
||||||
// returns a value. The function is assumed to be monotonic (an increase in `parameter`
|
|
||||||
// will result in an increase in the return value. The function uses binary search
|
|
||||||
// to find `parameter` such that `measure` returns `measureGoal`, within an error
|
|
||||||
// of `epsilon`. It will use at most `maxRounds` attempts.
|
|
||||||
export async function binarySearch(
|
|
||||||
measureGoal,
|
|
||||||
measure,
|
|
||||||
{ min = 0, max = 100, epsilon = 0.1, maxRounds = 8 } = {}
|
|
||||||
) {
|
|
||||||
let parameter = (max - min) / 2 + min;
|
|
||||||
let delta = (max - min) / 4;
|
|
||||||
let value;
|
|
||||||
let round = 1;
|
|
||||||
while (true) {
|
|
||||||
value = await measure(parameter);
|
|
||||||
if (Math.abs(value - measureGoal) < epsilon || round >= maxRounds) {
|
|
||||||
return { parameter, round, value };
|
|
||||||
}
|
|
||||||
if (value > measureGoal) {
|
|
||||||
parameter -= delta;
|
|
||||||
} else if (value < measureGoal) {
|
|
||||||
parameter += delta;
|
|
||||||
}
|
|
||||||
delta /= 2;
|
|
||||||
round++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function autoOptimize(
|
|
||||||
bitmapIn,
|
|
||||||
encode,
|
|
||||||
decode,
|
|
||||||
{ butteraugliDistanceGoal = 1.4, ...otherOpts } = {}
|
|
||||||
) {
|
|
||||||
const { VisDiff } = await instantiateEmscriptenWasm(visdif, visdifWasm);
|
|
||||||
|
|
||||||
const comparator = new VisDiff(
|
|
||||||
bitmapIn.data,
|
|
||||||
bitmapIn.width,
|
|
||||||
bitmapIn.height
|
|
||||||
);
|
|
||||||
|
|
||||||
let bitmapOut;
|
|
||||||
let binaryOut;
|
|
||||||
// Increasing quality means _decrease_ in Butteraugli distance.
|
|
||||||
// `binarySearch` assumes that increasing `parameter` will
|
|
||||||
// increase the metric value. So multipliy Butteraugli values by -1.
|
|
||||||
const { parameter } = await binarySearch(
|
|
||||||
-1 * butteraugliDistanceGoal,
|
|
||||||
async quality => {
|
|
||||||
binaryOut = await encode(bitmapIn, quality);
|
|
||||||
bitmapOut = await decode(binaryOut);
|
|
||||||
return -1 * comparator.distance(bitmapOut.data);
|
|
||||||
},
|
|
||||||
otherOpts
|
|
||||||
);
|
|
||||||
comparator.delete();
|
|
||||||
|
|
||||||
return {
|
|
||||||
bitmap: bitmapOut,
|
|
||||||
binary: binaryOut,
|
|
||||||
quality: parameter
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,361 +0,0 @@
|
|||||||
import { promises as fsp } from 'fs';
|
|
||||||
import { instantiateEmscriptenWasm, pathify } from './emscripten-utils.js';
|
|
||||||
|
|
||||||
// MozJPEG
|
|
||||||
import mozEnc from '../../codecs/mozjpeg/enc/mozjpeg_node_enc.js';
|
|
||||||
import mozEncWasm from 'asset-url:../../codecs/mozjpeg/enc/mozjpeg_node_enc.wasm';
|
|
||||||
import mozDec from '../../codecs/mozjpeg/dec/mozjpeg_node_dec.js';
|
|
||||||
import mozDecWasm from 'asset-url:../../codecs/mozjpeg/dec/mozjpeg_node_dec.wasm';
|
|
||||||
|
|
||||||
// WebP
|
|
||||||
import webpEnc from '../../codecs/webp/enc/webp_node_enc.js';
|
|
||||||
import webpEncWasm from 'asset-url:../../codecs/webp/enc/webp_node_enc.wasm';
|
|
||||||
import webpDec from '../../codecs/webp/dec/webp_node_dec.js';
|
|
||||||
import webpDecWasm from 'asset-url:../../codecs/webp/dec/webp_node_dec.wasm';
|
|
||||||
|
|
||||||
// AVIF
|
|
||||||
import avifEnc from '../../codecs/avif/enc/avif_node_enc.js';
|
|
||||||
import avifEncWasm from 'asset-url:../../codecs/avif/enc/avif_node_enc.wasm';
|
|
||||||
import avifDec from '../../codecs/avif/dec/avif_node_dec.js';
|
|
||||||
import avifDecWasm from 'asset-url:../../codecs/avif/dec/avif_node_dec.wasm';
|
|
||||||
|
|
||||||
// JXL
|
|
||||||
import jxlEnc from '../../codecs/jxl/enc/jxl_node_enc.js';
|
|
||||||
import jxlEncWasm from 'asset-url:../../codecs/jxl/enc/jxl_node_enc.wasm';
|
|
||||||
import jxlDec from '../../codecs/jxl/dec/jxl_node_dec.js';
|
|
||||||
import jxlDecWasm from 'asset-url:../../codecs/jxl/dec/jxl_node_dec.wasm';
|
|
||||||
|
|
||||||
// WP2
|
|
||||||
import wp2Enc from '../../codecs/wp2/enc/wp2_node_enc.js';
|
|
||||||
import wp2EncWasm from 'asset-url:../../codecs/wp2/enc/wp2_node_enc.wasm';
|
|
||||||
import wp2Dec from '../../codecs/wp2/dec/wp2_node_dec.js';
|
|
||||||
import wp2DecWasm from 'asset-url:../../codecs/wp2/dec/wp2_node_dec.wasm';
|
|
||||||
|
|
||||||
// PNG
|
|
||||||
import * as pngEncDec from '../../codecs/png/pkg/squoosh_png.js';
|
|
||||||
import pngEncDecWasm from 'asset-url:../../codecs/png/pkg/squoosh_png_bg.wasm';
|
|
||||||
const pngEncDecPromise = pngEncDec.default(
|
|
||||||
fsp.readFile(pathify(pngEncDecWasm)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// OxiPNG
|
|
||||||
import * as oxipng from '../../codecs/oxipng/pkg/squoosh_oxipng.js';
|
|
||||||
import oxipngWasm from 'asset-url:../../codecs/oxipng/pkg/squoosh_oxipng_bg.wasm';
|
|
||||||
const oxipngPromise = oxipng.default(fsp.readFile(pathify(oxipngWasm)));
|
|
||||||
|
|
||||||
// Resize
|
|
||||||
import * as resize from '../../codecs/resize/pkg/squoosh_resize.js';
|
|
||||||
import resizeWasm from 'asset-url:../../codecs/resize/pkg/squoosh_resize_bg.wasm';
|
|
||||||
const resizePromise = resize.default(fsp.readFile(pathify(resizeWasm)));
|
|
||||||
|
|
||||||
// rotate
|
|
||||||
import rotateWasm from 'asset-url:../../codecs/rotate/rotate.wasm';
|
|
||||||
|
|
||||||
// ImageQuant
|
|
||||||
import imageQuant from '../../codecs/imagequant/imagequant_node.js';
|
|
||||||
import imageQuantWasm from 'asset-url:../../codecs/imagequant/imagequant_node.wasm';
|
|
||||||
const imageQuantPromise = instantiateEmscriptenWasm(imageQuant, imageQuantWasm);
|
|
||||||
|
|
||||||
// Our decoders currently rely on a `ImageData` global.
|
|
||||||
import ImageData from './image_data.js';
|
|
||||||
globalThis.ImageData = ImageData;
|
|
||||||
|
|
||||||
function resizeNameToIndex(name) {
|
|
||||||
switch (name) {
|
|
||||||
case 'triangle':
|
|
||||||
return 0;
|
|
||||||
case 'catrom':
|
|
||||||
return 1;
|
|
||||||
case 'mitchell':
|
|
||||||
return 2;
|
|
||||||
case 'lanczos3':
|
|
||||||
return 3;
|
|
||||||
default:
|
|
||||||
throw Error(`Unknown resize algorithm "${name}"`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resizeWithAspect({
|
|
||||||
input_width,
|
|
||||||
input_height,
|
|
||||||
target_width,
|
|
||||||
target_height,
|
|
||||||
}) {
|
|
||||||
if (!target_width && !target_height) {
|
|
||||||
throw Error('Need to specify at least width or height when resizing');
|
|
||||||
}
|
|
||||||
if (target_width && target_height) {
|
|
||||||
return { width: target_width, height: target_height };
|
|
||||||
}
|
|
||||||
if (!target_width) {
|
|
||||||
return {
|
|
||||||
width: Math.round((input_width / input_height) * target_height),
|
|
||||||
height: target_height,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!target_height) {
|
|
||||||
return {
|
|
||||||
width: target_width,
|
|
||||||
height: Math.round((input_height / input_width) * target_width),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const preprocessors = {
|
|
||||||
resize: {
|
|
||||||
name: 'Resize',
|
|
||||||
description: 'Resize the image before compressing',
|
|
||||||
instantiate: async () => {
|
|
||||||
await resizePromise;
|
|
||||||
return (
|
|
||||||
buffer,
|
|
||||||
input_width,
|
|
||||||
input_height,
|
|
||||||
{ width, height, method, premultiply, linearRGB },
|
|
||||||
) => {
|
|
||||||
({ width, height } = resizeWithAspect({
|
|
||||||
input_width,
|
|
||||||
input_height,
|
|
||||||
target_width: width,
|
|
||||||
target_height: height,
|
|
||||||
}));
|
|
||||||
return new ImageData(
|
|
||||||
resize.resize(
|
|
||||||
buffer,
|
|
||||||
input_width,
|
|
||||||
input_height,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
resizeNameToIndex(method),
|
|
||||||
premultiply,
|
|
||||||
linearRGB,
|
|
||||||
),
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
defaultOptions: {
|
|
||||||
method: 'lanczos3',
|
|
||||||
fitMethod: 'stretch',
|
|
||||||
premultiply: true,
|
|
||||||
linearRGB: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// // TODO: Need to handle SVGs and HQX
|
|
||||||
quant: {
|
|
||||||
name: 'ImageQuant',
|
|
||||||
description: 'Reduce the number of colors used (aka. paletting)',
|
|
||||||
instantiate: async () => {
|
|
||||||
const imageQuant = await imageQuantPromise;
|
|
||||||
return (buffer, width, height, { numColors, dither }) =>
|
|
||||||
new ImageData(
|
|
||||||
imageQuant.quantize(buffer, width, height, numColors, dither),
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
defaultOptions: {
|
|
||||||
numColors: 255,
|
|
||||||
dither: 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rotate: {
|
|
||||||
name: 'Rotate',
|
|
||||||
description: 'Rotate image',
|
|
||||||
instantiate: async () => {
|
|
||||||
return async (buffer, width, height, { numRotations }) => {
|
|
||||||
const degrees = (numRotations * 90) % 360;
|
|
||||||
const sameDimensions = degrees == 0 || degrees == 180;
|
|
||||||
const size = width * height * 4;
|
|
||||||
const { instance } = await WebAssembly.instantiate(
|
|
||||||
await fsp.readFile(pathify(rotateWasm)),
|
|
||||||
);
|
|
||||||
const { memory } = instance.exports;
|
|
||||||
const additionalPagesNeeded = Math.ceil(
|
|
||||||
(size * 2 - memory.buffer.byteLength + 8) / (64 * 1024),
|
|
||||||
);
|
|
||||||
if (additionalPagesNeeded > 0) {
|
|
||||||
memory.grow(additionalPagesNeeded);
|
|
||||||
}
|
|
||||||
const view = new Uint8ClampedArray(memory.buffer);
|
|
||||||
view.set(buffer, 8);
|
|
||||||
instance.exports.rotate(width, height, degrees);
|
|
||||||
return new ImageData(
|
|
||||||
view.slice(size + 8, size * 2 + 8),
|
|
||||||
sameDimensions ? width : height,
|
|
||||||
sameDimensions ? height : width,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
defaultOptions: {
|
|
||||||
numRotations: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const codecs = {
|
|
||||||
mozjpeg: {
|
|
||||||
name: 'MozJPEG',
|
|
||||||
extension: 'jpg',
|
|
||||||
detectors: [/^\xFF\xD8\xFF/],
|
|
||||||
dec: () => instantiateEmscriptenWasm(mozDec, mozDecWasm),
|
|
||||||
enc: () => instantiateEmscriptenWasm(mozEnc, mozEncWasm),
|
|
||||||
defaultEncoderOptions: {
|
|
||||||
quality: 75,
|
|
||||||
baseline: false,
|
|
||||||
arithmetic: false,
|
|
||||||
progressive: true,
|
|
||||||
optimize_coding: true,
|
|
||||||
smoothing: 0,
|
|
||||||
color_space: 3 /*YCbCr*/,
|
|
||||||
quant_table: 3,
|
|
||||||
trellis_multipass: false,
|
|
||||||
trellis_opt_zero: false,
|
|
||||||
trellis_opt_table: false,
|
|
||||||
trellis_loops: 1,
|
|
||||||
auto_subsample: true,
|
|
||||||
chroma_subsample: 2,
|
|
||||||
separate_chroma_quality: false,
|
|
||||||
chroma_quality: 75,
|
|
||||||
},
|
|
||||||
autoOptimize: {
|
|
||||||
option: 'quality',
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
webp: {
|
|
||||||
name: 'WebP',
|
|
||||||
extension: 'webp',
|
|
||||||
detectors: [/^RIFF....WEBPVP8[LX ]/],
|
|
||||||
dec: () => instantiateEmscriptenWasm(webpDec, webpDecWasm),
|
|
||||||
enc: () => instantiateEmscriptenWasm(webpEnc, webpEncWasm),
|
|
||||||
defaultEncoderOptions: {
|
|
||||||
quality: 75,
|
|
||||||
target_size: 0,
|
|
||||||
target_PSNR: 0,
|
|
||||||
method: 4,
|
|
||||||
sns_strength: 50,
|
|
||||||
filter_strength: 60,
|
|
||||||
filter_sharpness: 0,
|
|
||||||
filter_type: 1,
|
|
||||||
partitions: 0,
|
|
||||||
segments: 4,
|
|
||||||
pass: 1,
|
|
||||||
show_compressed: 0,
|
|
||||||
preprocessing: 0,
|
|
||||||
autofilter: 0,
|
|
||||||
partition_limit: 0,
|
|
||||||
alpha_compression: 1,
|
|
||||||
alpha_filtering: 1,
|
|
||||||
alpha_quality: 100,
|
|
||||||
lossless: 0,
|
|
||||||
exact: 0,
|
|
||||||
image_hint: 0,
|
|
||||||
emulate_jpeg_size: 0,
|
|
||||||
thread_level: 0,
|
|
||||||
low_memory: 0,
|
|
||||||
near_lossless: 100,
|
|
||||||
use_delta_palette: 0,
|
|
||||||
use_sharp_yuv: 0,
|
|
||||||
},
|
|
||||||
autoOptimize: {
|
|
||||||
option: 'quality',
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
avif: {
|
|
||||||
name: 'AVIF',
|
|
||||||
extension: 'avif',
|
|
||||||
detectors: [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/],
|
|
||||||
dec: () => instantiateEmscriptenWasm(avifDec, avifDecWasm),
|
|
||||||
enc: () => instantiateEmscriptenWasm(avifEnc, avifEncWasm),
|
|
||||||
defaultEncoderOptions: {
|
|
||||||
minQuantizer: 33,
|
|
||||||
maxQuantizer: 63,
|
|
||||||
minQuantizerAlpha: 33,
|
|
||||||
maxQuantizerAlpha: 63,
|
|
||||||
tileColsLog2: 0,
|
|
||||||
tileRowsLog2: 0,
|
|
||||||
speed: 8,
|
|
||||||
subsample: 1,
|
|
||||||
},
|
|
||||||
autoOptimize: {
|
|
||||||
option: 'maxQuantizer',
|
|
||||||
min: 0,
|
|
||||||
max: 62,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
jxl: {
|
|
||||||
name: 'JPEG-XL',
|
|
||||||
extension: 'jxl',
|
|
||||||
detectors: [/^\xff\x0a/],
|
|
||||||
dec: () => instantiateEmscriptenWasm(jxlDec, jxlDecWasm),
|
|
||||||
enc: () => instantiateEmscriptenWasm(jxlEnc, jxlEncWasm),
|
|
||||||
defaultEncoderOptions: {
|
|
||||||
speed: 4,
|
|
||||||
quality: 75,
|
|
||||||
progressive: false,
|
|
||||||
epf: -1,
|
|
||||||
nearLossless: 0,
|
|
||||||
lossyPalette: false,
|
|
||||||
},
|
|
||||||
autoOptimize: {
|
|
||||||
option: 'quality',
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wp2: {
|
|
||||||
name: 'WebP2',
|
|
||||||
extension: 'wp2',
|
|
||||||
detectors: [/^\xF4\xFF\x6F/],
|
|
||||||
dec: () => instantiateEmscriptenWasm(wp2Dec, wp2DecWasm),
|
|
||||||
enc: () => instantiateEmscriptenWasm(wp2Enc, wp2EncWasm),
|
|
||||||
defaultEncoderOptions: {
|
|
||||||
quality: 75,
|
|
||||||
alpha_quality: 75,
|
|
||||||
effort: 5,
|
|
||||||
pass: 1,
|
|
||||||
sns: 50,
|
|
||||||
uv_mode: 0 /*UVMode.UVModeAuto*/,
|
|
||||||
csp_type: 0 /*Csp.kYCoCg*/,
|
|
||||||
error_diffusion: 0,
|
|
||||||
use_random_matrix: false,
|
|
||||||
},
|
|
||||||
autoOptimize: {
|
|
||||||
option: 'quality',
|
|
||||||
min: 0,
|
|
||||||
max: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
oxipng: {
|
|
||||||
name: 'OxiPNG',
|
|
||||||
extension: 'png',
|
|
||||||
detectors: [/^\x89PNG\x0D\x0A\x1A\x0A/],
|
|
||||||
dec: async () => {
|
|
||||||
await pngEncDecPromise;
|
|
||||||
return { decode: pngEncDec.decode };
|
|
||||||
},
|
|
||||||
enc: async () => {
|
|
||||||
await pngEncDecPromise;
|
|
||||||
await oxipngPromise;
|
|
||||||
return {
|
|
||||||
encode: (buffer, width, height, opts) => {
|
|
||||||
const simplePng = pngEncDec.encode(new Uint8Array(buffer), width, height);
|
|
||||||
return oxipng.optimise(simplePng, opts.level);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
defaultEncoderOptions: {
|
|
||||||
level: 2,
|
|
||||||
},
|
|
||||||
autoOptimize: {
|
|
||||||
option: 'level',
|
|
||||||
min: 6,
|
|
||||||
max: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { fileURLToPath } from 'url';
|
|
||||||
|
|
||||||
export function pathify(path) {
|
|
||||||
if (path.startsWith('file://')) {
|
|
||||||
path = fileURLToPath(path);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function instantiateEmscriptenWasm(factory, path) {
|
|
||||||
return factory({
|
|
||||||
locateFile() {
|
|
||||||
return pathify(path);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export default class ImageData {
|
|
||||||
constructor(data, width, height) {
|
|
||||||
this.data = data;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
362
cli/src/index.js
362
cli/src/index.js
@@ -1,362 +0,0 @@
|
|||||||
import { program } from 'commander';
|
|
||||||
import JSON5 from 'json5';
|
|
||||||
import { isMainThread } from 'worker_threads';
|
|
||||||
import { cpus } from 'os';
|
|
||||||
import { extname, join, basename } from 'path';
|
|
||||||
import { promises as fsp } from 'fs';
|
|
||||||
import { resolve as resolvePath } from 'path';
|
|
||||||
import { version } from 'json:../package.json';
|
|
||||||
import ora from 'ora';
|
|
||||||
import kleur from 'kleur';
|
|
||||||
|
|
||||||
import { codecs as supportedFormats, preprocessors } from './codecs.js';
|
|
||||||
import WorkerPool from './worker_pool.js';
|
|
||||||
import { autoOptimize } from './auto-optimizer.js';
|
|
||||||
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function decodeFile(file) {
|
|
||||||
const buffer = await fsp.readFile(file);
|
|
||||||
const firstChunk = buffer.slice(0, 16);
|
|
||||||
const firstChunkString = Array.from(firstChunk)
|
|
||||||
.map((v) => String.fromCodePoint(v))
|
|
||||||
.join('');
|
|
||||||
const key = Object.entries(supportedFormats).find(([name, { detectors }]) =>
|
|
||||||
detectors.some((detector) => detector.exec(firstChunkString)),
|
|
||||||
)?.[0];
|
|
||||||
if (!key) {
|
|
||||||
throw Error(`${file} has an unsupported format`);
|
|
||||||
}
|
|
||||||
const rgba = (await supportedFormats[key].dec()).decode(
|
|
||||||
new Uint8Array(buffer),
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
file,
|
|
||||||
bitmap: rgba,
|
|
||||||
size: buffer.length,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function preprocessImage({ preprocessorName, options, file }) {
|
|
||||||
const preprocessor = await preprocessors[preprocessorName].instantiate();
|
|
||||||
file.bitmap = await preprocessor(
|
|
||||||
file.bitmap.data,
|
|
||||||
file.bitmap.width,
|
|
||||||
file.bitmap.height,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function encodeFile({
|
|
||||||
file,
|
|
||||||
size,
|
|
||||||
bitmap: bitmapIn,
|
|
||||||
outputFile,
|
|
||||||
encName,
|
|
||||||
encConfig,
|
|
||||||
optimizerButteraugliTarget,
|
|
||||||
maxOptimizerRounds,
|
|
||||||
}) {
|
|
||||||
let out, infoText;
|
|
||||||
const encoder = await supportedFormats[encName].enc();
|
|
||||||
if (encConfig === 'auto') {
|
|
||||||
const optionToOptimize = supportedFormats[encName].autoOptimize.option;
|
|
||||||
const decoder = await supportedFormats[encName].dec();
|
|
||||||
const encode = (bitmapIn, quality) =>
|
|
||||||
encoder.encode(
|
|
||||||
bitmapIn.data,
|
|
||||||
bitmapIn.width,
|
|
||||||
bitmapIn.height,
|
|
||||||
Object.assign({}, supportedFormats[encName].defaultEncoderOptions, {
|
|
||||||
[optionToOptimize]: quality,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
const decode = (binary) => decoder.decode(binary);
|
|
||||||
const { bitmap, binary, quality } = await autoOptimize(
|
|
||||||
bitmapIn,
|
|
||||||
encode,
|
|
||||||
decode,
|
|
||||||
{
|
|
||||||
min: supportedFormats[encName].autoOptimize.min,
|
|
||||||
max: supportedFormats[encName].autoOptimize.max,
|
|
||||||
butteraugliDistanceGoal: optimizerButteraugliTarget,
|
|
||||||
maxRounds: maxOptimizerRounds,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
out = binary;
|
|
||||||
const opts = {
|
|
||||||
// 5 significant digits is enough
|
|
||||||
[optionToOptimize]: Math.round(quality * 10000) / 10000,
|
|
||||||
};
|
|
||||||
infoText = ` using --${encName} '${JSON5.stringify(opts)}'`;
|
|
||||||
} else {
|
|
||||||
out = encoder.encode(
|
|
||||||
bitmapIn.data.buffer,
|
|
||||||
bitmapIn.width,
|
|
||||||
bitmapIn.height,
|
|
||||||
encConfig,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await fsp.writeFile(outputFile, out);
|
|
||||||
return {
|
|
||||||
infoText,
|
|
||||||
inputSize: size,
|
|
||||||
inputFile: file,
|
|
||||||
outputFile,
|
|
||||||
outputSize: out.length,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// both decoding and encoding go through the worker pool
|
|
||||||
function handleJob(params) {
|
|
||||||
const { operation } = params;
|
|
||||||
switch (operation) {
|
|
||||||
case 'encode':
|
|
||||||
return encodeFile(params);
|
|
||||||
case 'decode':
|
|
||||||
return decodeFile(params.file);
|
|
||||||
case 'preprocess':
|
|
||||||
return preprocessImage(params);
|
|
||||||
default:
|
|
||||||
throw Error(`Invalid job "${operation}"`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 [filename, result] of results.entries()) {
|
|
||||||
out += `\n ${kleur.cyan(filename)}: ${prettyPrintSize(result.size)}`;
|
|
||||||
for (const { outputFile, outputSize, infoText } of result.outputs) {
|
|
||||||
const name = (program.suffix + extname(outputFile)).padEnd(5);
|
|
||||||
out += `\n ${kleur.dim('└')} ${kleur.cyan(name)} → ${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 path of paths) {
|
|
||||||
const files = (await fsp.lstat(path)).isDirectory()
|
|
||||||
? (await fsp.readdir(path)).map(file => join(path, file))
|
|
||||||
: [path];
|
|
||||||
for (const file of files) {
|
|
||||||
try {
|
|
||||||
await fsp.stat(file);
|
|
||||||
} catch (err) {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
console.warn(
|
|
||||||
`Warning: Input file does not exist: ${resolvePath(file)}`,
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
validFiles.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return validFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processFiles(files) {
|
|
||||||
files = await getInputFiles(files);
|
|
||||||
|
|
||||||
const parallelism = cpus().length;
|
|
||||||
|
|
||||||
const results = new Map();
|
|
||||||
const progress = progressTracker(results);
|
|
||||||
|
|
||||||
progress.setStatus('Decoding...');
|
|
||||||
progress.totalOffset = files.length;
|
|
||||||
progress.setProgress(0, files.length);
|
|
||||||
|
|
||||||
const workerPool = new WorkerPool(parallelism, __filename);
|
|
||||||
// Create output directory
|
|
||||||
await fsp.mkdir(program.outputDir, { recursive: true });
|
|
||||||
|
|
||||||
let decoded = 0;
|
|
||||||
let decodedFiles = await Promise.all(
|
|
||||||
files.map(async (file) => {
|
|
||||||
const result = await workerPool.dispatchJob({
|
|
||||||
operation: 'decode',
|
|
||||||
file,
|
|
||||||
});
|
|
||||||
results.set(file, {
|
|
||||||
file: result.file,
|
|
||||||
size: result.size,
|
|
||||||
outputs: [],
|
|
||||||
});
|
|
||||||
progress.setProgress(++decoded, files.length);
|
|
||||||
return result;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const [preprocessorName, value] of Object.entries(preprocessors)) {
|
|
||||||
if (!program[preprocessorName]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const preprocessorParam = program[preprocessorName];
|
|
||||||
const preprocessorOptions = Object.assign(
|
|
||||||
{},
|
|
||||||
value.defaultOptions,
|
|
||||||
JSON5.parse(preprocessorParam),
|
|
||||||
);
|
|
||||||
|
|
||||||
decodedFiles = await Promise.all(
|
|
||||||
decodedFiles.map(async (file) => {
|
|
||||||
return workerPool.dispatchJob({
|
|
||||||
file,
|
|
||||||
operation: 'preprocess',
|
|
||||||
preprocessorName,
|
|
||||||
options: preprocessorOptions,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
progress.progressOffset = decoded;
|
|
||||||
progress.setStatus('Encoding ' + kleur.dim(`(${parallelism} threads)`));
|
|
||||||
progress.setProgress(0, files.length);
|
|
||||||
|
|
||||||
const jobs = [];
|
|
||||||
let jobsStarted = 0;
|
|
||||||
let jobsFinished = 0;
|
|
||||||
for (const { file, bitmap, size } of decodedFiles) {
|
|
||||||
const ext = extname(file);
|
|
||||||
const base = basename(file, ext) + program.suffix;
|
|
||||||
|
|
||||||
for (const [encName, value] of Object.entries(supportedFormats)) {
|
|
||||||
if (!program[encName]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const encParam =
|
|
||||||
typeof program[encName] === 'string' ? program[encName] : '{}';
|
|
||||||
const encConfig =
|
|
||||||
encParam.toLowerCase() === 'auto'
|
|
||||||
? 'auto'
|
|
||||||
: Object.assign(
|
|
||||||
{},
|
|
||||||
value.defaultEncoderOptions,
|
|
||||||
JSON5.parse(encParam),
|
|
||||||
);
|
|
||||||
const outputFile = join(program.outputDir, `${base}.${value.extension}`);
|
|
||||||
jobsStarted++;
|
|
||||||
const p = workerPool
|
|
||||||
.dispatchJob({
|
|
||||||
operation: 'encode',
|
|
||||||
file,
|
|
||||||
size,
|
|
||||||
bitmap,
|
|
||||||
outputFile,
|
|
||||||
encName,
|
|
||||||
encConfig,
|
|
||||||
optimizerButteraugliTarget: Number(
|
|
||||||
program.optimizerButteraugliTarget,
|
|
||||||
),
|
|
||||||
maxOptimizerRounds: Number(program.maxOptimizerRounds),
|
|
||||||
})
|
|
||||||
.then((output) => {
|
|
||||||
jobsFinished++;
|
|
||||||
results.get(file).outputs.push(output);
|
|
||||||
progress.setProgress(jobsFinished, jobsStarted);
|
|
||||||
});
|
|
||||||
jobs.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the progress to account for multi-format
|
|
||||||
progress.setProgress(jobsFinished, jobsStarted);
|
|
||||||
// Wait for all jobs to finish
|
|
||||||
await workerPool.join();
|
|
||||||
await Promise.all(jobs);
|
|
||||||
progress.finish('Squoosh results:');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isMainThread) {
|
|
||||||
program
|
|
||||||
.name('squoosh-cli')
|
|
||||||
.version(version)
|
|
||||||
.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(supportedFormats)) {
|
|
||||||
program.option(
|
|
||||||
`--${key} [config]`,
|
|
||||||
`Use ${value.name} to generate a .${value.extension} file with the given configuration`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
program.parse(process.argv);
|
|
||||||
} else {
|
|
||||||
WorkerPool.useThisThreadAsWorker(handleJob);
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
import { Worker, parentPort } from 'worker_threads';
|
|
||||||
import { TransformStream } from 'web-streams-polyfill';
|
|
||||||
|
|
||||||
function uuid() {
|
|
||||||
return Array.from({ length: 16 }, () =>
|
|
||||||
Math.floor(Math.random() * 256).toString(16),
|
|
||||||
).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
function jobPromise(worker, msg) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const id = uuid();
|
|
||||||
worker.postMessage({ msg, id });
|
|
||||||
worker.on('message', function f({ result, id: rid }) {
|
|
||||||
if (rid !== id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
worker.off('message', f);
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
worker.on('error', (error) => console.error('Worker error: ', error));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class WorkerPool {
|
|
||||||
constructor(numWorkers, workerFile) {
|
|
||||||
this.numWorkers = numWorkers;
|
|
||||||
this.jobQueue = new TransformStream();
|
|
||||||
this.workerQueue = new TransformStream();
|
|
||||||
|
|
||||||
const writer = this.workerQueue.writable.getWriter();
|
|
||||||
for (let i = 0; i < numWorkers; i++) {
|
|
||||||
writer.write(new Worker(workerFile));
|
|
||||||
}
|
|
||||||
writer.releaseLock();
|
|
||||||
|
|
||||||
this.done = this._readLoop();
|
|
||||||
}
|
|
||||||
|
|
||||||
async _readLoop() {
|
|
||||||
const reader = this.jobQueue.readable.getReader();
|
|
||||||
while (true) {
|
|
||||||
const { value, done } = await reader.read();
|
|
||||||
if (done) {
|
|
||||||
await this._terminateAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { msg, resolve } = value;
|
|
||||||
const worker = await this._nextWorker();
|
|
||||||
jobPromise(worker, msg).then((result) => {
|
|
||||||
resolve(result);
|
|
||||||
const writer = this.workerQueue.writable.getWriter();
|
|
||||||
writer.write(worker);
|
|
||||||
writer.releaseLock();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async _nextWorker() {
|
|
||||||
const reader = this.workerQueue.readable.getReader();
|
|
||||||
const { value, done } = await reader.read();
|
|
||||||
reader.releaseLock();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _terminateAll() {
|
|
||||||
for (let n = 0; n < this.numWorkers; n++) {
|
|
||||||
const worker = await this._nextWorker();
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
this.workerQueue.writable.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
async join() {
|
|
||||||
this.jobQueue.writable.getWriter().close();
|
|
||||||
await this.done;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatchJob(msg) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const writer = this.jobQueue.writable.getWriter();
|
|
||||||
writer.write({ msg, resolve });
|
|
||||||
writer.releaseLock();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static useThisThreadAsWorker(cb) {
|
|
||||||
parentPort.on('message', async (data) => {
|
|
||||||
const { msg, id } = data;
|
|
||||||
const result = await cb(msg);
|
|
||||||
parentPort.postMessage({ result, id });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
// for comlink
|
// for comlink
|
||||||
"src/features/**/worker/**/*",
|
"src/features/**/worker/**/*",
|
||||||
"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,22 +1,30 @@
|
|||||||
# libavif and libaom versions are from
|
# using libavif from https://github.com/AOMediaCodec/libavif
|
||||||
# https://docs.google.com/document/d/1wEEA5rRU7wT54k41u3qyZIZHDCJArIMzLuzsrLAwaK8/edit
|
LIBAVIF_URL = https://github.com/AOMediaCodec/libavif/archive/refs/tags/v1.0.1.tar.gz
|
||||||
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/d37ef74127986184500e571bf1f9793cc0bdef50.tar.gz
|
LIBAVIF_PACKAGE = node_modules/libavif.tar.gz
|
||||||
CODEC_PACKAGE = node_modules/libavif.tar.gz
|
|
||||||
|
|
||||||
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/0a5da45c7f942908974f5ab8e107c9fa82048ae7.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
|
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
||||||
|
|
||||||
export CODEC_DIR = node_modules/libavif
|
export CODEC_DIR = node_modules/libavif
|
||||||
export BUILD_DIR = node_modules/build
|
export BUILD_DIR = node_modules/build
|
||||||
export LIBAOM_DIR = node_modules/libaom
|
export LIBAOM_DIR = node_modules/libaom
|
||||||
|
|
||||||
|
override CFLAGS += "-Wno-unused-macros"
|
||||||
|
|
||||||
|
# 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_ENC_JS = enc/avif_enc.js
|
||||||
OUT_NODE_ENC_JS = enc/avif_node_enc.js
|
OUT_NODE_ENC_JS = enc/avif_node_enc.js
|
||||||
OUT_ENC_MT_JS = enc/avif_enc_mt.js
|
OUT_ENC_MT_JS = enc/avif_enc_mt.js
|
||||||
|
OUT_NODE_ENC_MT_JS = enc/avif_node_enc_mt.js
|
||||||
OUT_DEC_JS = dec/avif_dec.js
|
OUT_DEC_JS = dec/avif_dec.js
|
||||||
OUT_NODE_DEC_JS = dec/avif_node_dec.js
|
OUT_NODE_DEC_JS = dec/avif_node_dec.js
|
||||||
|
|
||||||
OUT_ENC_CPP = enc/avif_enc.cpp
|
|
||||||
OUT_ENC_CPP = enc/avif_enc.cpp
|
OUT_ENC_CPP = enc/avif_enc.cpp
|
||||||
OUT_DEC_CPP = dec/avif_dec.cpp
|
OUT_DEC_CPP = dec/avif_dec.cpp
|
||||||
ENVIRONMENT = worker
|
ENVIRONMENT = worker
|
||||||
@@ -25,10 +33,10 @@ HELPER_MAKEFLAGS := -f helper.Makefile
|
|||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_JS) $(OUT_NODE_DEC_JS)
|
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
||||||
|
|
||||||
$(OUT_NODE_ENC_JS): ENVIRONMENT=node
|
# ST-Encoding
|
||||||
$(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV)
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
@@ -39,9 +47,10 @@ $(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
|
|||||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||||
" \
|
" \
|
||||||
ENVIRONMENT=$(ENVIRONMENT) \
|
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_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) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
@@ -51,11 +60,11 @@ $(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMake
|
|||||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||||
" \
|
" \
|
||||||
ENVIRONMENT=$(ENVIRONMENT) \
|
ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON" \
|
||||||
OUT_FLAGS="-pthread"
|
OUT_FLAGS="-pthread"
|
||||||
|
|
||||||
$(OUT_NODE_DEC_JS): ENVIRONMENT=node
|
# Decoding
|
||||||
$(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
@@ -67,23 +76,60 @@ $(OUT_NODE_DEC_JS) $(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
|
|||||||
ENVIRONMENT=$(ENVIRONMENT) \
|
ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
||||||
|
|
||||||
$(CODEC_PACKAGE):
|
# LIBAOM EXTRACTION SECTION
|
||||||
mkdir -p $(@D)
|
|
||||||
curl -sL $(CODEC_URL) -o $@
|
|
||||||
|
|
||||||
|
# Download the libaom tarball
|
||||||
$(LIBAOM_PACKAGE):
|
$(LIBAOM_PACKAGE):
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
curl -sL $(LIBAOM_URL) -o $@
|
curl -sL $(LIBAOM_URL) -o $@
|
||||||
|
|
||||||
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_PACKAGE)
|
# Extract libaom from the tarball
|
||||||
mkdir -p $(@D)
|
|
||||||
tar xzm --strip 1 -C $(@D) -f $(CODEC_PACKAGE)
|
|
||||||
|
|
||||||
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
|
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)
|
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:
|
clean:
|
||||||
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_JS) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_JS) clean
|
||||||
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_MT_JS) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_MT_JS) clean
|
||||||
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_NODE_JS) clean
|
||||||
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_NODE_MT_JS) clean
|
||||||
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEC_JS) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEC_JS) clean
|
||||||
|
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEV_NODE_JS) clean
|
||||||
|
|||||||
57
codecs/avif/dec/avif_dec.js
generated
57
codecs/avif/dec/avif_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
56
codecs/avif/dec/avif_node_dec.js
generated
56
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 <emscripten/val.h>
|
||||||
#include "avif/avif.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 namespace emscripten;
|
||||||
|
|
||||||
|
using AvifImagePtr = std::unique_ptr<avifImage, decltype(&avifImageDestroy)>;
|
||||||
|
using AvifEncoderPtr = std::unique_ptr<avifEncoder, decltype(&avifEncoderDestroy)>;
|
||||||
|
|
||||||
struct AvifOptions {
|
struct AvifOptions {
|
||||||
// [0 - 63]
|
// [0 - 100]
|
||||||
// 0 = lossless
|
// 0 = worst quality
|
||||||
// 63 = worst quality
|
// 100 = lossless
|
||||||
int cqLevel;
|
int quality;
|
||||||
// As above, but -1 means 'use cqLevel'
|
// As above, but -1 means 'use quality'
|
||||||
int cqAlphaLevel;
|
int qualityAlpha;
|
||||||
// [0 - 6]
|
// [0 - 6]
|
||||||
// Creates 2^n tiles in that dimension
|
// Creates 2^n tiles in that dimension
|
||||||
int tileRowsLog2;
|
int tileRowsLog2;
|
||||||
@@ -29,16 +41,21 @@ struct AvifOptions {
|
|||||||
bool chromaDeltaQ;
|
bool chromaDeltaQ;
|
||||||
// 0-7
|
// 0-7
|
||||||
int sharpness;
|
int sharpness;
|
||||||
// Target ssim rather than psnr
|
// 0 = auto
|
||||||
bool targetSsim;
|
// 1 = PSNR
|
||||||
|
// 2 = SSIM
|
||||||
|
int tune;
|
||||||
// 0-50
|
// 0-50
|
||||||
int denoiseLevel;
|
int denoiseLevel;
|
||||||
|
// toggles AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV
|
||||||
|
bool enableSharpYUV;
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||||
|
|
||||||
val encode(std::string buffer, int width, int height, AvifOptions options) {
|
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;
|
int depth = 8;
|
||||||
avifPixelFormat format;
|
avifPixelFormat format;
|
||||||
switch (options.subsample) {
|
switch (options.subsample) {
|
||||||
@@ -56,11 +73,13 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lossless = options.cqLevel == AVIF_QUANTIZER_LOSSLESS &&
|
bool lossless = options.quality == AVIF_QUALITY_LOSSLESS &&
|
||||||
options.cqAlphaLevel <= AVIF_QUANTIZER_LOSSLESS &&
|
(options.qualityAlpha == -1 || options.qualityAlpha == AVIF_QUALITY_LOSSLESS) &&
|
||||||
format == AVIF_PIXEL_FORMAT_YUV444;
|
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) {
|
if (lossless) {
|
||||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
||||||
@@ -71,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()));
|
uint8_t* rgba = reinterpret_cast<uint8_t*>(const_cast<char*>(buffer.data()));
|
||||||
|
|
||||||
avifRGBImage srcRGB;
|
avifRGBImage srcRGB;
|
||||||
avifRGBImageSetDefaults(&srcRGB, image);
|
avifRGBImageSetDefaults(&srcRGB, image.get());
|
||||||
srcRGB.pixels = rgba;
|
srcRGB.pixels = rgba;
|
||||||
srcRGB.rowBytes = width * 4;
|
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) {
|
if (lossless) {
|
||||||
encoder->minQuantizer = AVIF_QUANTIZER_LOSSLESS;
|
encoder->quality = AVIF_QUALITY_LOSSLESS;
|
||||||
encoder->maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
|
encoder->qualityAlpha = AVIF_QUALITY_LOSSLESS;
|
||||||
encoder->minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
|
||||||
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
|
||||||
} else {
|
} else {
|
||||||
encoder->minQuantizer = AVIF_QUANTIZER_BEST_QUALITY;
|
status = avifEncoderSetCodecSpecificOption(encoder.get(), "sharpness",
|
||||||
encoder->maxQuantizer = AVIF_QUANTIZER_WORST_QUALITY;
|
std::to_string(options.sharpness).c_str());
|
||||||
encoder->minQuantizerAlpha = AVIF_QUANTIZER_BEST_QUALITY;
|
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||||
encoder->maxQuantizerAlpha = AVIF_QUANTIZER_WORST_QUALITY;
|
|
||||||
avifEncoderSetCodecSpecificOption(encoder, "end-usage", "q");
|
|
||||||
avifEncoderSetCodecSpecificOption(encoder, "cq-level", std::to_string(options.cqLevel).c_str());
|
|
||||||
avifEncoderSetCodecSpecificOption(encoder, "sharpness",
|
|
||||||
std::to_string(options.sharpness).c_str());
|
|
||||||
|
|
||||||
if (options.cqAlphaLevel != -1) {
|
// Set base quality
|
||||||
avifEncoderSetCodecSpecificOption(encoder, "alpha:cq-level",
|
encoder->quality = options.quality;
|
||||||
std::to_string(options.cqAlphaLevel).c_str());
|
// Conditionally set alpha quality
|
||||||
|
if (options.qualityAlpha == -1) {
|
||||||
|
encoder->qualityAlpha = options.quality;
|
||||||
|
} else {
|
||||||
|
encoder->qualityAlpha = options.qualityAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.targetSsim) {
|
if (options.tune == 2 || (options.tune == 0 && options.quality >= 50)) {
|
||||||
avifEncoderSetCodecSpecificOption(encoder, "tune", "ssim");
|
status = avifEncoderSetCodecSpecificOption(encoder.get(), "tune", "ssim");
|
||||||
|
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.chromaDeltaQ) {
|
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",
|
status = avifEncoderSetCodecSpecificOption(encoder.get(), "color:denoise-noise-level",
|
||||||
std::to_string(options.denoiseLevel).c_str());
|
std::to_string(options.denoiseLevel).c_str());
|
||||||
|
RETURN_NULL_IF(status != AVIF_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder->maxThreads = emscripten_num_logical_cores();
|
encoder->maxThreads = emscripten_num_logical_cores();
|
||||||
@@ -115,30 +140,30 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
|||||||
encoder->tileColsLog2 = options.tileColsLog2;
|
encoder->tileColsLog2 = options.tileColsLog2;
|
||||||
encoder->speed = options.speed;
|
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();
|
auto js_result = val::null();
|
||||||
if (encodeResult == AVIF_RESULT_OK) {
|
if (encodeResult == AVIF_RESULT_OK) {
|
||||||
js_result = Uint8Array.new_(typed_memory_view(output.size, output.data));
|
js_result = Uint8Array.new_(typed_memory_view(output.size, output.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
avifImageDestroy(image);
|
|
||||||
avifEncoderDestroy(encoder);
|
|
||||||
avifRWDataFree(&output);
|
avifRWDataFree(&output);
|
||||||
return js_result;
|
return js_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<AvifOptions>("AvifOptions")
|
value_object<AvifOptions>("AvifOptions")
|
||||||
.field("cqLevel", &AvifOptions::cqLevel)
|
.field("quality", &AvifOptions::quality)
|
||||||
.field("cqAlphaLevel", &AvifOptions::cqAlphaLevel)
|
.field("qualityAlpha", &AvifOptions::qualityAlpha)
|
||||||
.field("tileRowsLog2", &AvifOptions::tileRowsLog2)
|
.field("tileRowsLog2", &AvifOptions::tileRowsLog2)
|
||||||
.field("tileColsLog2", &AvifOptions::tileColsLog2)
|
.field("tileColsLog2", &AvifOptions::tileColsLog2)
|
||||||
.field("speed", &AvifOptions::speed)
|
.field("speed", &AvifOptions::speed)
|
||||||
.field("chromaDeltaQ", &AvifOptions::chromaDeltaQ)
|
.field("chromaDeltaQ", &AvifOptions::chromaDeltaQ)
|
||||||
.field("sharpness", &AvifOptions::sharpness)
|
.field("sharpness", &AvifOptions::sharpness)
|
||||||
.field("targetSsim", &AvifOptions::targetSsim)
|
.field("tune", &AvifOptions::tune)
|
||||||
.field("denoiseLevel", &AvifOptions::denoiseLevel)
|
.field("denoiseLevel", &AvifOptions::denoiseLevel)
|
||||||
.field("subsample", &AvifOptions::subsample);
|
.field("subsample", &AvifOptions::subsample)
|
||||||
|
.field("enableSharpYUV", &AvifOptions::enableSharpYUV);
|
||||||
|
|
||||||
function("encode", &encode);
|
function("encode", &encode);
|
||||||
}
|
}
|
||||||
|
|||||||
13
codecs/avif/enc/avif_enc.d.ts
vendored
13
codecs/avif/enc/avif_enc.d.ts
vendored
@@ -1,14 +1,21 @@
|
|||||||
|
export const enum AVIFTune {
|
||||||
|
auto,
|
||||||
|
psnr,
|
||||||
|
ssim,
|
||||||
|
}
|
||||||
|
|
||||||
export interface EncodeOptions {
|
export interface EncodeOptions {
|
||||||
cqLevel: number;
|
quality: number;
|
||||||
|
qualityAlpha: number;
|
||||||
denoiseLevel: number;
|
denoiseLevel: number;
|
||||||
cqAlphaLevel: number;
|
|
||||||
tileRowsLog2: number;
|
tileRowsLog2: number;
|
||||||
tileColsLog2: number;
|
tileColsLog2: number;
|
||||||
speed: number;
|
speed: number;
|
||||||
subsample: number;
|
subsample: number;
|
||||||
chromaDeltaQ: boolean;
|
chromaDeltaQ: boolean;
|
||||||
sharpness: number;
|
sharpness: number;
|
||||||
targetSsim: boolean;
|
enableSharpYUV: boolean;
|
||||||
|
tune: AVIFTune;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AVIFModule extends EmscriptenWasm.Module {
|
export interface AVIFModule extends EmscriptenWasm.Module {
|
||||||
|
|||||||
60
codecs/avif/enc/avif_enc.js
generated
60
codecs/avif/enc/avif_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
99
codecs/avif/enc/avif_enc_mt.js
generated
99
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 @@
|
|||||||
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;var initializedJS=false;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:selfThreadId})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;import(e.data.urlOrBlob).then(function(avif_enc_mt){return avif_enc_mt.default(Module)}).then(function(instance){Module=instance;postMessage({"cmd":"loaded"})})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;threadInfoStruct=e.data.threadInfoStruct;Module["registerPthreadPtr"](threadInfoStruct,/*isMainBrowserThread=*/0,/*isMainRuntimeThread=*/0);selfThreadId=e.data.selfThreadId;parentThreadId=e.data.parentThreadId;var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["dynCall"]("ii",e.data.start_routine,[e.data.arg]);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){Atomics.store(Module["HEAPU32"],(threadInfoStruct+4)>>/*C_STRUCTS.pthread.threadExitCode*/2,(ex instanceof Module["ExitStatus"])?ex.status:-2);/*A custom entry specific to Emscripten denoting that the thread crashed.*/Atomics.store(Module["HEAPU32"],(threadInfoStruct+0)>>/*C_STRUCTS.pthread.threadStatus*/2,1);Module["_emscripten_futex_wake"](threadInfoStruct+0,/*C_STRUCTS.pthread.threadStatus*/2147483647);if(!(ex instanceof Module["ExitStatus"]))throw ex}}}else if(e.data.cmd==="cancel"){if(threadInfoStruct){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(threadInfoStruct){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&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}};
|
||||||
|
|||||||
60
codecs/avif/enc/avif_node_enc.js
generated
60
codecs/avif/enc/avif_node_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
16
codecs/avif/enc/avif_node_enc_mt.js
generated
Normal file
16
codecs/avif/enc/avif_node_enc_mt.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/avif/enc/avif_node_enc_mt.wasm
Executable file
BIN
codecs/avif/enc/avif_node_enc_mt.wasm
Executable file
Binary file not shown.
1
codecs/avif/enc/avif_node_enc_mt.worker.js
generated
Normal file
1
codecs/avif/enc/avif_node_enc_mt.worker.js
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"use strict";var Module={};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:function(f){(0,eval)(nodeFS.readFileSync(f,"utf8"))},postMessage:function(msg){parentPort.postMessage(msg)},performance:global.performance||{now:function(){return Date.now()}}})}var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);receiveInstance(instance);Module["wasmModule"]=null;return instance.exports};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./avif_node_enc_mt.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
@@ -10,8 +10,11 @@
|
|||||||
# $(LIBAVIF_FLAGS)
|
# $(LIBAVIF_FLAGS)
|
||||||
# $(ENVIRONMENT)
|
# $(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))
|
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_BUILD_DIR := $(OUT_BUILD_DIR)/libavif
|
||||||
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
||||||
|
|
||||||
@@ -25,6 +28,13 @@ OUT_WORKER=$(OUT_JS:.js=.worker.js)
|
|||||||
|
|
||||||
all: $(OUT_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)
|
$(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
||||||
$(CXX) \
|
$(CXX) \
|
||||||
-I $(CODEC_DIR)/include \
|
-I $(CODEC_DIR)/include \
|
||||||
@@ -32,18 +42,15 @@ $(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
|||||||
$(LDFLAGS) \
|
$(LDFLAGS) \
|
||||||
$(OUT_FLAGS) \
|
$(OUT_FLAGS) \
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
|
||||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s EXPORT_ES6=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-s EXPORT_NAME="$(basename $(@F))" \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_OUT)
|
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_OUT)
|
||||||
emcmake cmake \
|
emcmake cmake \
|
||||||
|
-DCMAKE_LIBRARY_PATH=$(LIBSHARPYUV_BUILD_DIR) \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DBUILD_SHARED_LIBS=0 \
|
-DBUILD_SHARED_LIBS=0 \
|
||||||
-DAVIF_CODEC_AOM=1 \
|
-DAVIF_CODEC_AOM=1 \
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
FROM emscripten/emsdk:2.0.8
|
FROM emscripten/emsdk:2.0.34
|
||||||
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
||||||
ENV CFLAGS "-O3 -flto -s FILESYSTEM=0"
|
ENV CFLAGS "-O3 -flto"
|
||||||
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
||||||
ENV LDFLAGS "${CFLAGS} -s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency"
|
ENV LDFLAGS "${CFLAGS} \
|
||||||
# Build and cache standard libraries with these flags
|
-s FILESYSTEM=0 \
|
||||||
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
|
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
||||||
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
-s TEXTDECODER=2 \
|
||||||
|
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
||||||
|
"
|
||||||
|
# Build and cache standard libraries with these flags + Embind.
|
||||||
|
RUN emcc ${CXXFLAGS} ${LDFLAGS} --bind -xc++ /dev/null -o /dev/null
|
||||||
|
# And another set for the pthread variant.
|
||||||
|
RUN emcc ${CXXFLAGS} ${LDFLAGS} --bind -pthread -xc++ /dev/null -o /dev/null
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
CMD ["sh", "-c", "emmake make -j`nproc`"]
|
CMD ["sh", "-c", "emmake make -j`nproc`"]
|
||||||
|
|||||||
54
codecs/hqx/Cargo.lock
generated
54
codecs/hqx/Cargo.lock
generated
@@ -12,13 +12,19 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console_error_panic_hook"
|
name = "console_error_panic_hook"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -63,7 +69,7 @@ version = "0.4.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -83,9 +89,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.19"
|
version = "1.0.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
|
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
@@ -105,7 +111,7 @@ version = "1.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -118,7 +124,7 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
|||||||
name = "squooshhqx"
|
name = "squooshhqx"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"hqx",
|
"hqx",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -128,11 +134,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.35"
|
version = "1.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
|
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.27",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
@@ -151,24 +157,24 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
|
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
|
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.27",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn",
|
"syn",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
@@ -180,7 +186,7 @@ version = "0.3.27"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
"futures",
|
"futures",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -189,9 +195,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
|
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@@ -199,11 +205,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
|
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.19",
|
"proc-macro2 1.0.27",
|
||||||
"quote 1.0.7",
|
"quote 1.0.7",
|
||||||
"syn",
|
"syn",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
@@ -212,9 +218,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.65"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
|
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-test"
|
name = "wasm-bindgen-test"
|
||||||
@@ -257,7 +263,7 @@ version = "0.4.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
"libc",
|
"libc",
|
||||||
"memory_units",
|
"memory_units",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
|||||||
2
codecs/hqx/pkg/squooshhqx.d.ts
generated
vendored
2
codecs/hqx/pkg/squooshhqx.d.ts
generated
vendored
@@ -14,6 +14,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
readonly resize: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
readonly resize: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
||||||
|
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||||
readonly __wbindgen_malloc: (a: number) => number;
|
readonly __wbindgen_malloc: (a: number) => number;
|
||||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
}
|
}
|
||||||
@@ -27,4 +28,3 @@ export interface InitOutput {
|
|||||||
* @returns {Promise<InitOutput>}
|
* @returns {Promise<InitOutput>}
|
||||||
*/
|
*/
|
||||||
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||||
|
|
||||||
27
codecs/hqx/pkg/squooshhqx.js
generated
27
codecs/hqx/pkg/squooshhqx.js
generated
@@ -37,19 +37,23 @@ function getArrayU32FromWasm0(ptr, len) {
|
|||||||
* @returns {Uint32Array}
|
* @returns {Uint32Array}
|
||||||
*/
|
*/
|
||||||
export function resize(input_image, input_width, input_height, factor) {
|
export function resize(input_image, input_width, input_height, factor) {
|
||||||
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
try {
|
||||||
var len0 = WASM_VECTOR_LEN;
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||||
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
|
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
var len0 = WASM_VECTOR_LEN;
|
||||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
wasm.resize(retptr, ptr0, len0, input_width, input_height, factor);
|
||||||
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
wasm.__wbindgen_free(r0, r1 * 4);
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
return v1;
|
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
||||||
|
wasm.__wbindgen_free(r0, r1 * 4);
|
||||||
|
return v1;
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(module, imports) {
|
async function load(module, imports) {
|
||||||
if (typeof Response === 'function' && module instanceof Response) {
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
|
|
||||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
try {
|
try {
|
||||||
return await WebAssembly.instantiateStreaming(module, imports);
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
@@ -68,7 +72,6 @@ async function load(module, imports) {
|
|||||||
return await WebAssembly.instantiate(bytes, imports);
|
return await WebAssembly.instantiate(bytes, imports);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const instance = await WebAssembly.instantiate(module, imports);
|
const instance = await WebAssembly.instantiate(module, imports);
|
||||||
|
|
||||||
if (instance instanceof WebAssembly.Instance) {
|
if (instance instanceof WebAssembly.Instance) {
|
||||||
@@ -82,7 +85,7 @@ async function load(module, imports) {
|
|||||||
|
|
||||||
async function init(input) {
|
async function init(input) {
|
||||||
if (typeof input === 'undefined') {
|
if (typeof input === 'undefined') {
|
||||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
input = new URL('squooshhqx_bg.wasm', import.meta.url);
|
||||||
}
|
}
|
||||||
const imports = {};
|
const imports = {};
|
||||||
|
|
||||||
@@ -91,6 +94,8 @@ async function init(input) {
|
|||||||
input = fetch(input);
|
input = fetch(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { instance, module } = await load(await input, imports);
|
const { instance, module } = await load(await input, imports);
|
||||||
|
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
|
|||||||
6
codecs/hqx/pkg/squooshhqx_bg.d.ts
generated
vendored
6
codecs/hqx/pkg/squooshhqx_bg.d.ts
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
export const memory: WebAssembly.Memory;
|
|
||||||
export function resize(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
||||||
export function __wbindgen_malloc(a: number): number;
|
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
|
||||||
Binary file not shown.
@@ -17,10 +17,6 @@ $(OUT_JS): $(CODEC_OUT)
|
|||||||
${CXXFLAGS} \
|
${CXXFLAGS} \
|
||||||
${LDFLAGS} \
|
${LDFLAGS} \
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
|
||||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s EXPORT_ES6=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
|
|||||||
43
codecs/imagequant/imagequant.js
generated
43
codecs/imagequant/imagequant.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
42
codecs/imagequant/imagequant_node.js
generated
42
codecs/imagequant/imagequant_node.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
CODEC_URL = https://gitlab.com/wg1/jpeg-xl.git
|
CODEC_URL = https://github.com/libjxl/libjxl.git
|
||||||
CODEC_VERSION = v0.3.3
|
CODEC_VERSION = 9f544641ec83f6abd9da598bdd08178ee8a003e0
|
||||||
CODEC_DIR = node_modules/jxl
|
CODEC_DIR = node_modules/jxl
|
||||||
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
|
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
|
||||||
CODEC_MT_BUILD_DIR := $(CODEC_BUILD_ROOT)/mt
|
CODEC_MT_BUILD_DIR := $(CODEC_BUILD_ROOT)/mt
|
||||||
@@ -28,6 +28,10 @@ enc/jxl_node_enc.js dec/jxl_node_dec.js enc/jxl_enc.js dec/jxl_dec.js: $(CODEC_M
|
|||||||
enc/jxl_enc_mt.js: $(CODEC_MT_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_BUILD_DIR)/lib/libjxl_threads.a
|
enc/jxl_enc_mt.js: $(CODEC_MT_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_BUILD_DIR)/lib/libjxl_threads.a
|
||||||
enc/jxl_enc_mt_simd.js: $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl_threads.a
|
enc/jxl_enc_mt_simd.js: $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl_threads.a
|
||||||
|
|
||||||
|
# Disable errors on deprecated SIMD intrinsics.
|
||||||
|
# JPEG-XL & Highway need to catch up, once they do, we can remove this suppression.
|
||||||
|
export CXXFLAGS += -Wno-deprecated-declarations
|
||||||
|
|
||||||
# Compile multithreaded wrappers with -pthread.
|
# Compile multithreaded wrappers with -pthread.
|
||||||
enc/jxl_enc_mt.js enc/jxl_enc_mt_simd.js: CXXFLAGS+=-pthread
|
enc/jxl_enc_mt.js enc/jxl_enc_mt_simd.js: CXXFLAGS+=-pthread
|
||||||
|
|
||||||
@@ -42,13 +46,8 @@ $(OUT_JS):
|
|||||||
-I $(CODEC_DIR)/third_party/highway \
|
-I $(CODEC_DIR)/third_party/highway \
|
||||||
-I $(CODEC_DIR)/third_party/skcms \
|
-I $(CODEC_DIR)/third_party/skcms \
|
||||||
--bind \
|
--bind \
|
||||||
--closure 1 \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
|
||||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s EXPORT_ES6=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-s EXPORT_NAME="$(basename $(@F))" \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+ \
|
$+ \
|
||||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlidec-static.a \
|
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlidec-static.a \
|
||||||
@@ -73,10 +72,14 @@ $(CODEC_MT_SIMD_BUILD_DIR)/Makefile: CXXFLAGS+=-msimd128
|
|||||||
-DJPEGXL_ENABLE_BENCHMARK=0 \
|
-DJPEGXL_ENABLE_BENCHMARK=0 \
|
||||||
-DJPEGXL_ENABLE_EXAMPLES=0 \
|
-DJPEGXL_ENABLE_EXAMPLES=0 \
|
||||||
-DBUILD_TESTING=0 \
|
-DBUILD_TESTING=0 \
|
||||||
|
-DCMAKE_CROSSCOMPILING_EMULATOR=node \
|
||||||
-B $(@D) \
|
-B $(@D) \
|
||||||
$(<D)
|
$(<D)
|
||||||
|
emcc -Wall -O3 -o $(CODEC_DIR)/third_party/skcms/skcms.cc.o -I$(CODEC_DIR)/third_party/skcms -c $(CODEC_DIR)/third_party/skcms/skcms.cc
|
||||||
|
llvm-ar rc $(CODEC_BUILD_DIR)/third_party/libskcms.a $(CODEC_DIR)/third_party/skcms/skcms.cc.o
|
||||||
|
rm $(CODEC_DIR)/third_party/skcms/skcms.cc.o
|
||||||
|
|
||||||
$(CODEC_DIR)/CMakeLists.txt:
|
$(CODEC_DIR)/CMakeLists.txt:
|
||||||
$(RM) -r $(@D)
|
$(RM) -r $(@D)
|
||||||
git init $(@D)
|
git init $(@D)
|
||||||
git -C $(@D) fetch $(CODEC_URL) $(CODEC_VERSION) --depth 1
|
git -C $(@D) fetch $(CODEC_URL) $(CODEC_VERSION) --depth 1
|
||||||
|
|||||||
56
codecs/jxl/dec/jxl_dec.js
generated
56
codecs/jxl/dec/jxl_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
56
codecs/jxl/dec/jxl_node_dec.js
generated
56
codecs/jxl/dec/jxl_node_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -4,20 +4,21 @@
|
|||||||
#include "lib/jxl/base/thread_pool_internal.h"
|
#include "lib/jxl/base/thread_pool_internal.h"
|
||||||
#include "lib/jxl/enc_external_image.h"
|
#include "lib/jxl/enc_external_image.h"
|
||||||
#include "lib/jxl/enc_file.h"
|
#include "lib/jxl/enc_file.h"
|
||||||
|
#include "lib/jxl/enc_color_management.h"
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||||
|
|
||||||
struct JXLOptions {
|
struct JXLOptions {
|
||||||
// 1 = slowest
|
int effort;
|
||||||
// 7 = fastest
|
|
||||||
int speed;
|
|
||||||
float quality;
|
float quality;
|
||||||
bool progressive;
|
bool progressive;
|
||||||
int epf;
|
int epf;
|
||||||
int nearLossless;
|
|
||||||
bool lossyPalette;
|
bool lossyPalette;
|
||||||
|
size_t decodingSpeedTier;
|
||||||
|
float photonNoiseIso;
|
||||||
|
bool lossyModular;
|
||||||
};
|
};
|
||||||
|
|
||||||
val encode(std::string image, int width, int height, JXLOptions options) {
|
val encode(std::string image, int width, int height, JXLOptions options) {
|
||||||
@@ -32,24 +33,35 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
pool_ptr = &pool;
|
pool_ptr = &pool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
size_t st = 10 - options.effort;
|
||||||
|
cparams.speed_tier = jxl::SpeedTier(st);
|
||||||
|
|
||||||
cparams.epf = options.epf;
|
cparams.epf = options.epf;
|
||||||
cparams.speed_tier = static_cast<jxl::SpeedTier>(options.speed);
|
cparams.decoding_speed_tier = options.decodingSpeedTier;
|
||||||
cparams.near_lossless = options.nearLossless;
|
cparams.photon_noise_iso = options.photonNoiseIso;
|
||||||
|
|
||||||
if (options.lossyPalette) {
|
if (options.lossyPalette) {
|
||||||
cparams.lossy_palette = true;
|
cparams.lossy_palette = true;
|
||||||
cparams.palette_colors = 0;
|
cparams.palette_colors = 0;
|
||||||
cparams.options.predictor = jxl::Predictor::Zero;
|
cparams.options.predictor = jxl::Predictor::Zero;
|
||||||
|
// Near-lossless assumes -R 0
|
||||||
|
cparams.responsive = 0;
|
||||||
|
cparams.modular_mode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float quality = options.quality;
|
float quality = options.quality;
|
||||||
|
|
||||||
// Quality settings roughly match libjpeg qualities.
|
// Quality settings roughly match libjpeg qualities.
|
||||||
if (quality < 7 || quality == 100) {
|
if (options.lossyModular || quality == 100) {
|
||||||
cparams.modular_mode = true;
|
cparams.modular_mode = true;
|
||||||
// Internal modular quality to roughly match VarDCT size.
|
// Internal modular quality to roughly match VarDCT size.
|
||||||
cparams.quality_pair.first = cparams.quality_pair.second =
|
if (quality < 7) {
|
||||||
std::min(35 + (quality - 7) * 3.0f, 100.0f);
|
cparams.quality_pair.first = cparams.quality_pair.second =
|
||||||
|
std::min(35 + (quality - 7) * 3.0f, 100.0f);
|
||||||
|
} else {
|
||||||
|
cparams.quality_pair.first = cparams.quality_pair.second =
|
||||||
|
std::min(35 + (quality - 7) * 65.f / 93.f, 100.0f);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cparams.modular_mode = false;
|
cparams.modular_mode = false;
|
||||||
if (quality >= 30) {
|
if (quality >= 30) {
|
||||||
@@ -75,12 +87,6 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cparams.near_lossless) {
|
|
||||||
// Near-lossless assumes -R 0
|
|
||||||
cparams.responsive = 0;
|
|
||||||
cparams.modular_mode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
io.metadata.m.SetAlphaBits(8);
|
io.metadata.m.SetAlphaBits(8);
|
||||||
if (!io.metadata.size.Set(width, height)) {
|
if (!io.metadata.size.Set(width, height)) {
|
||||||
return val::null();
|
return val::null();
|
||||||
@@ -92,14 +98,14 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
jxl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(image.data()), image.size()), width,
|
jxl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(image.data()), image.size()), width,
|
||||||
height, jxl::ColorEncoding::SRGB(/*is_gray=*/false), /*has_alpha=*/true,
|
height, jxl::ColorEncoding::SRGB(/*is_gray=*/false), /*has_alpha=*/true,
|
||||||
/*alpha_is_premultiplied=*/false, /*bits_per_sample=*/8, /*endiannes=*/JXL_LITTLE_ENDIAN,
|
/*alpha_is_premultiplied=*/false, /*bits_per_sample=*/8, /*endiannes=*/JXL_LITTLE_ENDIAN,
|
||||||
/*flipped_y=*/false, pool_ptr, main);
|
/*flipped_y=*/false, pool_ptr, main, /*(only true if bits_per_sample==32) float_in=*/false);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return val::null();
|
return val::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto js_result = val::null();
|
auto js_result = val::null();
|
||||||
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, /*aux=*/nullptr, pool_ptr)) {
|
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, jxl::GetJxlCms(), /*aux=*/nullptr, pool_ptr)) {
|
||||||
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
|
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,11 +114,13 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<JXLOptions>("JXLOptions")
|
value_object<JXLOptions>("JXLOptions")
|
||||||
.field("speed", &JXLOptions::speed)
|
.field("effort", &JXLOptions::effort)
|
||||||
.field("quality", &JXLOptions::quality)
|
.field("quality", &JXLOptions::quality)
|
||||||
.field("progressive", &JXLOptions::progressive)
|
.field("progressive", &JXLOptions::progressive)
|
||||||
.field("nearLossless", &JXLOptions::nearLossless)
|
|
||||||
.field("lossyPalette", &JXLOptions::lossyPalette)
|
.field("lossyPalette", &JXLOptions::lossyPalette)
|
||||||
|
.field("decodingSpeedTier", &JXLOptions::decodingSpeedTier)
|
||||||
|
.field("photonNoiseIso", &JXLOptions::photonNoiseIso)
|
||||||
|
.field("lossyModular", &JXLOptions::lossyModular)
|
||||||
.field("epf", &JXLOptions::epf);
|
.field("epf", &JXLOptions::epf);
|
||||||
|
|
||||||
function("encode", &encode);
|
function("encode", &encode);
|
||||||
|
|||||||
6
codecs/jxl/enc/jxl_enc.d.ts
vendored
6
codecs/jxl/enc/jxl_enc.d.ts
vendored
@@ -1,10 +1,12 @@
|
|||||||
export interface EncodeOptions {
|
export interface EncodeOptions {
|
||||||
speed: number;
|
effort: number;
|
||||||
quality: number;
|
quality: number;
|
||||||
progressive: boolean;
|
progressive: boolean;
|
||||||
epf: number;
|
epf: number;
|
||||||
nearLossless: number;
|
|
||||||
lossyPalette: boolean;
|
lossyPalette: boolean;
|
||||||
|
decodingSpeedTier: number;
|
||||||
|
photonNoiseIso: number;
|
||||||
|
lossyModular: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JXLModule extends EmscriptenWasm.Module {
|
export interface JXLModule extends EmscriptenWasm.Module {
|
||||||
|
|||||||
69
codecs/jxl/enc/jxl_enc.js
generated
69
codecs/jxl/enc/jxl_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
109
codecs/jxl/enc/jxl_enc_mt.js
generated
109
codecs/jxl/enc/jxl_enc_mt.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/jxl/enc/jxl_enc_mt.worker.js
generated
2
codecs/jxl/enc/jxl_enc_mt.worker.js
generated
@@ -1 +1 @@
|
|||||||
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;var initializedJS=false;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:selfThreadId})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;import(e.data.urlOrBlob).then(function(jxl_enc_mt){return jxl_enc_mt.default(Module)}).then(function(instance){Module=instance;postMessage({"cmd":"loaded"})})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;threadInfoStruct=e.data.threadInfoStruct;Module["registerPthreadPtr"](threadInfoStruct,/*isMainBrowserThread=*/0,/*isMainRuntimeThread=*/0);selfThreadId=e.data.selfThreadId;parentThreadId=e.data.parentThreadId;var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["dynCall"]("ii",e.data.start_routine,[e.data.arg]);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){Atomics.store(Module["HEAPU32"],(threadInfoStruct+4)>>/*C_STRUCTS.pthread.threadExitCode*/2,(ex instanceof Module["ExitStatus"])?ex.status:-2);/*A custom entry specific to Emscripten denoting that the thread crashed.*/Atomics.store(Module["HEAPU32"],(threadInfoStruct+0)>>/*C_STRUCTS.pthread.threadStatus*/2,1);Module["_emscripten_futex_wake"](threadInfoStruct+0,/*C_STRUCTS.pthread.threadStatus*/2147483647);if(!(ex instanceof Module["ExitStatus"]))throw ex}}}else if(e.data.cmd==="cancel"){if(threadInfoStruct){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(threadInfoStruct){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&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};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./jxl_enc_mt.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
|
|||||||
110
codecs/jxl/enc/jxl_enc_mt_simd.js
generated
110
codecs/jxl/enc/jxl_enc_mt_simd.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
2
codecs/jxl/enc/jxl_enc_mt_simd.worker.js
generated
2
codecs/jxl/enc/jxl_enc_mt_simd.worker.js
generated
@@ -1 +1 @@
|
|||||||
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;var initializedJS=false;var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:selfThreadId})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;import(e.data.urlOrBlob).then(function(jxl_enc_mt_simd){return jxl_enc_mt_simd.default(Module)}).then(function(instance){Module=instance;postMessage({"cmd":"loaded"})})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;threadInfoStruct=e.data.threadInfoStruct;Module["registerPthreadPtr"](threadInfoStruct,/*isMainBrowserThread=*/0,/*isMainRuntimeThread=*/0);selfThreadId=e.data.selfThreadId;parentThreadId=e.data.parentThreadId;var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["dynCall"]("ii",e.data.start_routine,[e.data.arg]);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){Atomics.store(Module["HEAPU32"],(threadInfoStruct+4)>>/*C_STRUCTS.pthread.threadExitCode*/2,(ex instanceof Module["ExitStatus"])?ex.status:-2);/*A custom entry specific to Emscripten denoting that the thread crashed.*/Atomics.store(Module["HEAPU32"],(threadInfoStruct+0)>>/*C_STRUCTS.pthread.threadStatus*/2,1);Module["_emscripten_futex_wake"](threadInfoStruct+0,/*C_STRUCTS.pthread.threadStatus*/2147483647);if(!(ex instanceof Module["ExitStatus"]))throw ex}}}else if(e.data.cmd==="cancel"){if(threadInfoStruct){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(threadInfoStruct){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&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};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./jxl_enc_mt_simd.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};
|
||||||
|
|||||||
69
codecs/jxl/enc/jxl_node_enc.js
generated
69
codecs/jxl/enc/jxl_node_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,65 +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
|
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)
|
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_JS)
|
all: $(OUT_JS)
|
||||||
|
|
||||||
# Define dependencies for all variations of build artifacts.
|
|
||||||
$(filter enc/%,$(OUT_JS)): enc/mozjpeg_enc.cpp
|
$(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:
|
||||||
|
|
||||||
%.js: $(CODEC_OUT)
|
|
||||||
$(CXX) \
|
$(CXX) \
|
||||||
-I $(CODEC_DIR) \
|
-O3 \
|
||||||
${CXXFLAGS} \
|
-flto \
|
||||||
${LDFLAGS} \
|
-s FILESYSTEM=0 \
|
||||||
--closure 1 \
|
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
||||||
--bind \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
-s TEXTDECODER=2 \
|
||||||
|
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
||||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s EXPORT_ES6=1 \
|
-s EXPORT_ES6=1 \
|
||||||
|
-lembind \
|
||||||
|
${CXXFLAGS} \
|
||||||
|
${LDFLAGS} \
|
||||||
-o $@ \
|
-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);
|
|
||||||
}
|
|
||||||
58
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
58
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
@@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
var Module = (function() {
|
|
||||||
var _scriptDir = import.meta.url;
|
|
||||||
|
|
||||||
return (
|
|
||||||
function(Module) {
|
|
||||||
Module = Module || {};
|
|
||||||
|
|
||||||
|
|
||||||
var e;e||(e=typeof Module !== 'undefined' ? Module : {});var aa,r;e.ready=new Promise(function(a,b){aa=a;r=b});var t={},u;for(u in e)e.hasOwnProperty(u)&&(t[u]=e[u]);var ba="./this.program";function ca(a,b){throw b;}var da="",ea,fa,ha,ia;da=__dirname+"/";ea=function(a){ha||(ha=require("fs"));ia||(ia=require("path"));a=ia.normalize(a);return ha.readFileSync(a,null)};fa=function(a){a=ea(a);a.buffer||(a=new Uint8Array(a));a.buffer||v("Assertion failed: undefined");return a};
|
|
||||||
1<process.argv.length&&(ba=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);process.on("uncaughtException",function(a){if(!(a instanceof ja))throw a;});process.on("unhandledRejection",v);ca=function(a){process.exit(a)};e.inspect=function(){return"[Emscripten Module object]"};var ka=e.print||console.log.bind(console),w=e.printErr||console.warn.bind(console);for(u in t)t.hasOwnProperty(u)&&(e[u]=t[u]);t=null;e.thisProgram&&(ba=e.thisProgram);e.quit&&(ca=e.quit);var y;e.wasmBinary&&(y=e.wasmBinary);
|
|
||||||
var noExitRuntime;e.noExitRuntime&&(noExitRuntime=e.noExitRuntime);"object"!==typeof WebAssembly&&v("no native wasm support detected");var z,la=!1,ma=new TextDecoder("utf8");
|
|
||||||
function na(a,b,c){var d=A;if(0<c){c=b+c-1;for(var f=0;f<a.length;++f){var g=a.charCodeAt(f);if(55296<=g&&57343>=g){var l=a.charCodeAt(++f);g=65536+((g&1023)<<10)|l&1023}if(127>=g){if(b>=c)break;d[b++]=g}else{if(2047>=g){if(b+1>=c)break;d[b++]=192|g>>6}else{if(65535>=g){if(b+2>=c)break;d[b++]=224|g>>12}else{if(b+3>=c)break;d[b++]=240|g>>18;d[b++]=128|g>>12&63}d[b++]=128|g>>6&63}d[b++]=128|g&63}}d[b]=0}}var oa=new TextDecoder("utf-16le");
|
|
||||||
function pa(a,b){var c=a>>1;for(b=c+b/2;!(c>=b)&&C[c];)++c;return oa.decode(A.subarray(a,c<<1))}function qa(a,b,c){void 0===c&&(c=2147483647);if(2>c)return 0;c-=2;var d=b;c=c<2*a.length?c/2:a.length;for(var f=0;f<c;++f)D[b>>1]=a.charCodeAt(f),b+=2;D[b>>1]=0;return b-d}function ra(a){return 2*a.length}function sa(a,b){for(var c=0,d="";!(c>=b/4);){var f=E[a+4*c>>2];if(0==f)break;++c;65536<=f?(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023)):d+=String.fromCharCode(f)}return d}
|
|
||||||
function ta(a,b,c){void 0===c&&(c=2147483647);if(4>c)return 0;var d=b;c=d+c-4;for(var f=0;f<a.length;++f){var g=a.charCodeAt(f);if(55296<=g&&57343>=g){var l=a.charCodeAt(++f);g=65536+((g&1023)<<10)|l&1023}E[b>>2]=g;b+=4;if(b+4>c)break}E[b>>2]=0;return b-d}function ua(a){for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);55296<=d&&57343>=d&&++c;b+=4}return b}var F,G,A,D,C,E,I,va,wa;
|
|
||||||
function xa(a){F=a;e.HEAP8=G=new Int8Array(a);e.HEAP16=D=new Int16Array(a);e.HEAP32=E=new Int32Array(a);e.HEAPU8=A=new Uint8Array(a);e.HEAPU16=C=new Uint16Array(a);e.HEAPU32=I=new Uint32Array(a);e.HEAPF32=va=new Float32Array(a);e.HEAPF64=wa=new Float64Array(a)}var ya=e.INITIAL_MEMORY||16777216;e.wasmMemory?z=e.wasmMemory:z=new WebAssembly.Memory({initial:ya/65536,maximum:32768});z&&(F=z.buffer);ya=F.byteLength;xa(F);var J,za=[],Aa=[],Ba=[],Ca=[];
|
|
||||||
function Da(){var a=e.preRun.shift();za.unshift(a)}var K=0,Ea=null,M=null;e.preloadedImages={};e.preloadedAudios={};function v(a){if(e.onAbort)e.onAbort(a);w(a);la=!0;a=new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");r(a);throw a;}function Fa(){var a=N;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var N="mozjpeg_node_dec.wasm";
|
|
||||||
if(!Fa()){var Ga=N;N=e.locateFile?e.locateFile(Ga,da):da+Ga}function Ha(){try{if(y)return new Uint8Array(y);if(fa)return fa(N);throw"both async and sync fetching of the wasm failed";}catch(a){v(a)}}function O(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b(e);else{var c=b.L;"number"===typeof c?void 0===b.I?J.get(c)():J.get(c)(b.I):c(void 0===b.I?null:b.I)}}}
|
|
||||||
function Ia(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var Ja=void 0;function P(a){for(var b="";A[a];)b+=Ja[A[a++]];return b}var Q={},R={},S={};function Ka(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}
|
|
||||||
function La(a,b){a=Ka(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}function Ma(a){var b=Error,c=La(a,function(d){this.name=a;this.message=d;d=Error(d).stack;void 0!==d&&(this.stack=this.toString()+"\n"+d.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}
|
|
||||||
var Na=void 0;function T(a){throw new Na(a);}var Oa=void 0;function Pa(a,b){function c(h){h=b(h);if(h.length!==d.length)throw new Oa("Mismatched type converter count");for(var k=0;k<d.length;++k)U(d[k],h[k])}var d=[];d.forEach(function(h){S[h]=a});var f=Array(a.length),g=[],l=0;a.forEach(function(h,k){R.hasOwnProperty(h)?f[k]=R[h]:(g.push(h),Q.hasOwnProperty(h)||(Q[h]=[]),Q[h].push(function(){f[k]=R[h];++l;l===g.length&&c(f)}))});0===g.length&&c(f)}
|
|
||||||
function U(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||T('type "'+d+'" must have a positive integer typeid pointer');if(R.hasOwnProperty(a)){if(c.M)return;T("Cannot register type '"+d+"' twice")}R[a]=b;delete S[a];Q.hasOwnProperty(a)&&(b=Q[a],delete Q[a],b.forEach(function(f){f()}))}var Qa=[],V=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
|
||||||
function Ra(a){4<a&&0===--V[a].J&&(V[a]=void 0,Qa.push(a))}function W(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Qa.length?Qa.pop():V.length;V[b]={J:1,value:a};return b}}function Sa(a){return this.fromWireType(I[a>>2])}function Va(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}
|
|
||||||
function Wa(a,b){switch(b){case 2:return function(c){return this.fromWireType(va[c>>2])};case 3:return function(c){return this.fromWireType(wa[c>>3])};default:throw new TypeError("Unknown float type: "+a);}}function Xa(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=La(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}
|
|
||||||
function Ya(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function Za(a,b){var c=e;if(void 0===c[a].G){var d=c[a];c[a]=function(){c[a].G.hasOwnProperty(arguments.length)||T("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].G+")!");return c[a].G[arguments.length].apply(this,arguments)};c[a].G=[];c[a].G[d.K]=d}}
|
|
||||||
function $a(a,b,c){e.hasOwnProperty(a)?((void 0===c||void 0!==e[a].G&&void 0!==e[a].G[c])&&T("Cannot register public name '"+a+"' twice"),Za(a,a),e.hasOwnProperty(c)&&T("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),e[a].G[c]=b):(e[a]=b,void 0!==c&&(e[a].O=c))}function ab(a,b){for(var c=[],d=0;d<a;d++)c.push(E[(b>>2)+d]);return c}
|
|
||||||
function bb(a,b){0<=a.indexOf("j")||v("Assertion failed: getDynCaller should only be called with i64 sigs");var c=[];return function(){c.length=arguments.length;for(var d=0;d<arguments.length;d++)c[d]=arguments[d];var f;-1!=a.indexOf("j")?f=c&&c.length?e["dynCall_"+a].apply(null,[b].concat(c)):e["dynCall_"+a].call(null,b):f=J.get(b).apply(null,c);return f}}
|
|
||||||
function cb(a,b){a=P(a);var c=-1!=a.indexOf("j")?bb(a,b):J.get(b);"function"!==typeof c&&T("unknown function pointer with signature "+a+": "+b);return c}var db=void 0;function eb(a){a=fb(a);var b=P(a);X(a);return b}function gb(a,b){function c(g){f[g]||R[g]||(S[g]?S[g].forEach(c):(d.push(g),f[g]=!0))}var d=[],f={};b.forEach(c);throw new db(a+": "+d.map(eb).join([", "]));}
|
|
||||||
function hb(a,b,c){switch(b){case 0:return c?function(d){return G[d]}:function(d){return A[d]};case 1:return c?function(d){return D[d>>1]}:function(d){return C[d>>1]};case 2:return c?function(d){return E[d>>2]}:function(d){return I[d>>2]};default:throw new TypeError("Unknown integer type: "+a);}}var ib={};function jb(){return"object"===typeof globalThis?globalThis:Function("return this")()}function kb(a,b){var c=R[a];void 0===c&&T(b+" has unknown type "+eb(a));return c}var lb={},mb={};
|
|
||||||
function nb(){if(!ob){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"===typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:ba||"./this.program"},b;for(b in mb)a[b]=mb[b];var c=[];for(b in a)c.push(b+"="+a[b]);ob=c}return ob}for(var ob,pb=[null,[],[]],qb=Array(256),Y=0;256>Y;++Y)qb[Y]=String.fromCharCode(Y);Ja=qb;Na=e.BindingError=Ma("BindingError");Oa=e.InternalError=Ma("InternalError");
|
|
||||||
e.count_emval_handles=function(){for(var a=0,b=5;b<V.length;++b)void 0!==V[b]&&++a;return a};e.get_first_emval=function(){for(var a=5;a<V.length;++a)if(void 0!==V[a])return V[a];return null};db=e.UnboundTypeError=Ma("UnboundTypeError");Aa.push({L:function(){rb()}});
|
|
||||||
var tb={g:function(){},o:function(a,b,c,d,f){var g=Ia(c);b=P(b);U(a,{name:b,fromWireType:function(l){return!!l},toWireType:function(l,h){return h?d:f},argPackAdvance:8,readValueFromPointer:function(l){if(1===c)var h=G;else if(2===c)h=D;else if(4===c)h=E;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(h[l>>g])},H:null})},x:function(a,b){b=P(b);U(a,{name:b,fromWireType:function(c){var d=V[c].value;Ra(c);return d},toWireType:function(c,d){return W(d)},argPackAdvance:8,
|
|
||||||
readValueFromPointer:Sa,H:null})},n:function(a,b,c){c=Ia(c);b=P(b);U(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,f){if("number"!==typeof f&&"boolean"!==typeof f)throw new TypeError('Cannot convert "'+Va(f)+'" to '+this.name);return f},argPackAdvance:8,readValueFromPointer:Wa(b,c),H:null})},q:function(a,b,c,d,f,g){var l=ab(b,c);a=P(a);f=cb(d,f);$a(a,function(){gb("Cannot call "+a+" due to unbound types",l)},b-1);Pa(l,function(h){var k=[h[0],null].concat(h.slice(1)),m=h=a,n=f,
|
|
||||||
p=k.length;2>p&&T("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var x=null!==k[1]&&!1,B=!1,q=1;q<k.length;++q)if(null!==k[q]&&void 0===k[q].H){B=!0;break}var Ta="void"!==k[0].name,H="",L="";for(q=0;q<p-2;++q)H+=(0!==q?", ":"")+"arg"+q,L+=(0!==q?", ":"")+"arg"+q+"Wired";m="return function "+Ka(m)+"("+H+") {\nif (arguments.length !== "+(p-2)+") {\nthrowBindingError('function "+m+" called with ' + arguments.length + ' arguments, expected "+(p-2)+" args!');\n}\n";
|
|
||||||
B&&(m+="var destructors = [];\n");var Ua=B?"destructors":"null";H="throwBindingError invoker fn runDestructors retType classParam".split(" ");n=[T,n,g,Ya,k[0],k[1]];x&&(m+="var thisWired = classParam.toWireType("+Ua+", this);\n");for(q=0;q<p-2;++q)m+="var arg"+q+"Wired = argType"+q+".toWireType("+Ua+", arg"+q+"); // "+k[q+2].name+"\n",H.push("argType"+q),n.push(k[q+2]);x&&(L="thisWired"+(0<L.length?", ":"")+L);m+=(Ta?"var rv = ":"")+"invoker(fn"+(0<L.length?", ":"")+L+");\n";if(B)m+="runDestructors(destructors);\n";
|
|
||||||
else for(q=x?1:2;q<k.length;++q)p=1===q?"thisWired":"arg"+(q-2)+"Wired",null!==k[q].H&&(m+=p+"_dtor("+p+"); // "+k[q].name+"\n",H.push(p+"_dtor"),n.push(k[q].H));Ta&&(m+="var ret = retType.fromWireType(rv);\nreturn ret;\n");H.push(m+"}\n");k=Xa(H).apply(null,n);q=b-1;if(!e.hasOwnProperty(h))throw new Oa("Replacing nonexistant public symbol");void 0!==e[h].G&&void 0!==q?e[h].G[q]=k:(e[h]=k,e[h].K=q);return[]})},c:function(a,b,c,d,f){function g(m){return m}b=P(b);-1===f&&(f=4294967295);var l=Ia(c);
|
|
||||||
if(0===d){var h=32-8*c;g=function(m){return m<<h>>>h}}var k=-1!=b.indexOf("unsigned");U(a,{name:b,fromWireType:g,toWireType:function(m,n){if("number"!==typeof n&&"boolean"!==typeof n)throw new TypeError('Cannot convert "'+Va(n)+'" to '+this.name);if(n<d||n>f)throw new TypeError('Passing a number "'+Va(n)+'" from JS side to C/C++ side to an argument of type "'+b+'", which is outside the valid range ['+d+", "+f+"]!");return k?n>>>0:n|0},argPackAdvance:8,readValueFromPointer:hb(b,l,0!==d),H:null})},
|
|
||||||
b:function(a,b,c){function d(g){g>>=2;var l=I;return new f(F,l[g+1],l[g])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=P(c);U(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{M:!0})},i:function(a,b){b=P(b);var c="std::string"===b;U(a,{name:b,fromWireType:function(d){var f=I[d>>2];if(c)for(var g=d+4,l=0;l<=f;++l){var h=d+4+l;if(l==f||0==A[h]){if(g){for(var k=g+(h-g),m=g;!(m>=k)&&A[m];)++m;g=ma.decode(A.subarray(g,m))}else g=
|
|
||||||
"";if(void 0===n)var n=g;else n+=String.fromCharCode(0),n+=g;g=h+1}}else{n=Array(f);for(l=0;l<f;++l)n[l]=String.fromCharCode(A[d+4+l]);n=n.join("")}X(d);return n},toWireType:function(d,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var g="string"===typeof f;g||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array||T("Cannot pass non-string to std::string");var l=(c&&g?function(){for(var m=0,n=0;n<f.length;++n){var p=f.charCodeAt(n);55296<=p&&57343>=p&&(p=65536+((p&1023)<<
|
|
||||||
10)|f.charCodeAt(++n)&1023);127>=p?++m:m=2047>=p?m+2:65535>=p?m+3:m+4}return m}:function(){return f.length})(),h=sb(4+l+1);I[h>>2]=l;if(c&&g)na(f,h+4,l+1);else if(g)for(g=0;g<l;++g){var k=f.charCodeAt(g);255<k&&(X(h),T("String has UTF-16 code units that do not fit in 8 bits"));A[h+4+g]=k}else for(g=0;g<l;++g)A[h+4+g]=f[g];null!==d&&d.push(X,h);return h},argPackAdvance:8,readValueFromPointer:Sa,H:function(d){X(d)}})},h:function(a,b,c){c=P(c);if(2===b){var d=pa;var f=qa;var g=ra;var l=function(){return C};
|
|
||||||
var h=1}else 4===b&&(d=sa,f=ta,g=ua,l=function(){return I},h=2);U(a,{name:c,fromWireType:function(k){for(var m=I[k>>2],n=l(),p,x=k+4,B=0;B<=m;++B){var q=k+4+B*b;if(B==m||0==n[q>>h])x=d(x,q-x),void 0===p?p=x:(p+=String.fromCharCode(0),p+=x),x=q+b}X(k);return p},toWireType:function(k,m){"string"!==typeof m&&T("Cannot pass non-string to C++ string type "+c);var n=g(m),p=sb(4+n+b);I[p>>2]=n>>h;f(m,p+4,n+b);null!==k&&k.push(X,p);return p},argPackAdvance:8,readValueFromPointer:Sa,H:function(k){X(k)}})},
|
|
||||||
p:function(a,b){b=P(b);U(a,{N:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},e:Ra,f:function(a){if(0===a)return W(jb());var b=ib[a];a=void 0===b?P(a):b;return W(jb()[a])},j:function(a){4<a&&(V[a].J+=1)},k:function(a,b,c,d){a||T("Cannot use deleted val. handle = "+a);a=V[a].value;var f=lb[b];if(!f){f="";for(var g=0;g<b;++g)f+=(0!==g?", ":"")+"arg"+g;var l="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";for(g=0;g<b;++g)l+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+
|
|
||||||
g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";f=(new Function("requireRegisteredType","Module","__emval_register",l+("var obj = new constructor("+f+");\nreturn __emval_register(obj);\n}\n")))(kb,e,W);lb[b]=f}return f(a,c,d)},l:function(){v()},t:function(a,b,c){A.copyWithin(a,b,b+c)},d:function(a){a>>>=0;var b=A.length;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(16777216,
|
|
||||||
a,d);0<d%65536&&(d+=65536-d%65536);a:{try{z.grow(Math.min(2147483648,d)-F.byteLength+65535>>>16);xa(z.buffer);var f=1;break a}catch(g){}f=void 0}if(f)return!0}return!1},u:function(a,b){var c=0;nb().forEach(function(d,f){var g=b+c;f=E[a+4*f>>2]=g;for(g=0;g<d.length;++g)G[f++>>0]=d.charCodeAt(g);G[f>>0]=0;c+=d.length+1});return 0},v:function(a,b){var c=nb();E[a>>2]=c.length;var d=0;c.forEach(function(f){d+=f.length+1});E[b>>2]=d;return 0},y:function(a){if(!noExitRuntime){if(e.onExit)e.onExit(a);la=
|
|
||||||
!0}ca(a,new ja(a))},w:function(){return 0},r:function(){},m:function(a,b,c,d){for(var f=0,g=0;g<c;g++){for(var l=E[b+8*g>>2],h=E[b+(8*g+4)>>2],k=0;k<h;k++){var m=A[l+k],n=pb[a];if(0===m||10===m){m=1===a?ka:w;var p;for(p=0;n[p]&&!(NaN<=p);)++p;p=ma.decode(n.subarray?n.subarray(0,p):new Uint8Array(n.slice(0,p)));m(p);n.length=0}else n.push(m)}f+=h}E[d>>2]=f;return 0},a:z,s:function(){}};
|
|
||||||
(function(){function a(f){e.asm=f.exports;J=e.asm.z;K--;e.monitorRunDependencies&&e.monitorRunDependencies(K);0==K&&(null!==Ea&&(clearInterval(Ea),Ea=null),M&&(f=M,M=null,f()))}function b(f){a(f.instance)}function c(f){return Promise.resolve().then(Ha).then(function(g){return WebAssembly.instantiate(g,d)}).then(f,function(g){w("failed to asynchronously prepare wasm: "+g);v(g)})}var d={a:tb};K++;e.monitorRunDependencies&&e.monitorRunDependencies(K);if(e.instantiateWasm)try{return e.instantiateWasm(d,
|
|
||||||
a)}catch(f){return w("Module.instantiateWasm callback failed with error: "+f),!1}(function(){return y||"function"!==typeof WebAssembly.instantiateStreaming||Fa()||"function"!==typeof fetch?c(b):fetch(N,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,d).then(b,function(g){w("wasm streaming compile failed: "+g);w("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(r);return{}})();
|
|
||||||
var rb=e.___wasm_call_ctors=function(){return(rb=e.___wasm_call_ctors=e.asm.A).apply(null,arguments)},sb=e._malloc=function(){return(sb=e._malloc=e.asm.B).apply(null,arguments)},X=e._free=function(){return(X=e._free=e.asm.C).apply(null,arguments)},fb=e.___getTypeName=function(){return(fb=e.___getTypeName=e.asm.D).apply(null,arguments)};e.___embind_register_native_and_builtin_types=function(){return(e.___embind_register_native_and_builtin_types=e.asm.E).apply(null,arguments)};
|
|
||||||
e.dynCall_jiji=function(){return(e.dynCall_jiji=e.asm.F).apply(null,arguments)};var Z;function ja(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}M=function ub(){Z||vb();Z||(M=ub)};
|
|
||||||
function vb(){function a(){if(!Z&&(Z=!0,e.calledRun=!0,!la)){O(Aa);O(Ba);aa(e);if(e.onRuntimeInitialized)e.onRuntimeInitialized();if(e.postRun)for("function"==typeof e.postRun&&(e.postRun=[e.postRun]);e.postRun.length;){var b=e.postRun.shift();Ca.unshift(b)}O(Ca)}}if(!(0<K)){if(e.preRun)for("function"==typeof e.preRun&&(e.preRun=[e.preRun]);e.preRun.length;)Da();O(za);0<K||(e.setStatus?(e.setStatus("Running..."),setTimeout(function(){setTimeout(function(){e.setStatus("")},1);a()},1)):a())}}
|
|
||||||
e.run=vb;if(e.preInit)for("function"==typeof e.preInit&&(e.preInit=[e.preInit]);0<e.preInit.length;)e.preInit.pop()();noExitRuntime=!0;vb();
|
|
||||||
|
|
||||||
|
|
||||||
return Module.ready
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
export default Module;
|
|
||||||
Binary file not shown.
@@ -5,7 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
#include "jconfig.h"
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -141,6 +141,7 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 0);
|
||||||
|
|
||||||
// A little hacky to build a string for this, but it means we can use
|
// A little hacky to build a string for this, but it means we can use
|
||||||
// set_quality_ratings which does some useful heuristic stuff.
|
// set_quality_ratings which does some useful heuristic stuff.
|
||||||
@@ -157,6 +158,11 @@ val encode(std::string image_in, int image_width, int image_height, MozJpegOptio
|
|||||||
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
||||||
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
||||||
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
||||||
|
|
||||||
|
if (opts.chroma_subsample > 2) {
|
||||||
|
// Otherwise encoding fails.
|
||||||
|
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.baseline && opts.progressive) {
|
if (!opts.baseline && opts.progressive) {
|
||||||
|
|||||||
60
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
60
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
@@ -1,60 +0,0 @@
|
|||||||
|
|
||||||
var Module = (function() {
|
|
||||||
var _scriptDir = import.meta.url;
|
|
||||||
|
|
||||||
return (
|
|
||||||
function(Module) {
|
|
||||||
Module = Module || {};
|
|
||||||
|
|
||||||
|
|
||||||
var f;f||(f=typeof Module !== 'undefined' ? Module : {});var aa,ba;f.ready=new Promise(function(a,b){aa=a;ba=b});var r={},t;for(t in f)f.hasOwnProperty(t)&&(r[t]=f[t]);var ca="./this.program";function ea(a,b){throw b;}var u="",fa;u=self.location.href;_scriptDir&&(u=_scriptDir);0!==u.indexOf("blob:")?u=u.substr(0,u.lastIndexOf("/")+1):u="";fa=function(a){var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)};
|
|
||||||
var ha=f.print||console.log.bind(console),v=f.printErr||console.warn.bind(console);for(t in r)r.hasOwnProperty(t)&&(f[t]=r[t]);r=null;f.thisProgram&&(ca=f.thisProgram);f.quit&&(ea=f.quit);var w;f.wasmBinary&&(w=f.wasmBinary);var noExitRuntime;f.noExitRuntime&&(noExitRuntime=f.noExitRuntime);"object"!==typeof WebAssembly&&A("no native wasm support detected");var B,ia=!1,ja=new TextDecoder("utf8");
|
|
||||||
function ka(a,b,c){var d=C;if(0<c){c=b+c-1;for(var e=0;e<a.length;++e){var g=a.charCodeAt(e);if(55296<=g&&57343>=g){var m=a.charCodeAt(++e);g=65536+((g&1023)<<10)|m&1023}if(127>=g){if(b>=c)break;d[b++]=g}else{if(2047>=g){if(b+1>=c)break;d[b++]=192|g>>6}else{if(65535>=g){if(b+2>=c)break;d[b++]=224|g>>12}else{if(b+3>=c)break;d[b++]=240|g>>18;d[b++]=128|g>>12&63}d[b++]=128|g>>6&63}d[b++]=128|g&63}}d[b]=0}}var la=new TextDecoder("utf-16le");
|
|
||||||
function ma(a,b){var c=a>>1;for(b=c+b/2;!(c>=b)&&D[c];)++c;return la.decode(C.subarray(a,c<<1))}function na(a,b,c){void 0===c&&(c=2147483647);if(2>c)return 0;c-=2;var d=b;c=c<2*a.length?c/2:a.length;for(var e=0;e<c;++e)E[b>>1]=a.charCodeAt(e),b+=2;E[b>>1]=0;return b-d}function oa(a){return 2*a.length}function pa(a,b){for(var c=0,d="";!(c>=b/4);){var e=G[a+4*c>>2];if(0==e)break;++c;65536<=e?(e-=65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023)):d+=String.fromCharCode(e)}return d}
|
|
||||||
function qa(a,b,c){void 0===c&&(c=2147483647);if(4>c)return 0;var d=b;c=d+c-4;for(var e=0;e<a.length;++e){var g=a.charCodeAt(e);if(55296<=g&&57343>=g){var m=a.charCodeAt(++e);g=65536+((g&1023)<<10)|m&1023}G[b>>2]=g;b+=4;if(b+4>c)break}G[b>>2]=0;return b-d}function ra(a){for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);55296<=d&&57343>=d&&++c;b+=4}return b}var H,I,C,E,D,G,J,sa,ta;
|
|
||||||
function ua(a){H=a;f.HEAP8=I=new Int8Array(a);f.HEAP16=E=new Int16Array(a);f.HEAP32=G=new Int32Array(a);f.HEAPU8=C=new Uint8Array(a);f.HEAPU16=D=new Uint16Array(a);f.HEAPU32=J=new Uint32Array(a);f.HEAPF32=sa=new Float32Array(a);f.HEAPF64=ta=new Float64Array(a)}var va=f.INITIAL_MEMORY||16777216;f.wasmMemory?B=f.wasmMemory:B=new WebAssembly.Memory({initial:va/65536,maximum:32768});B&&(H=B.buffer);va=H.byteLength;ua(H);var K,wa=[],xa=[],ya=[],za=[];
|
|
||||||
function Aa(){var a=f.preRun.shift();wa.unshift(a)}var L=0,Ba=null,M=null;f.preloadedImages={};f.preloadedAudios={};function A(a){if(f.onAbort)f.onAbort(a);v(a);ia=!0;a=new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");ba(a);throw a;}function Ca(){var a=N;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var N="mozjpeg_enc.wasm";
|
|
||||||
if(!Ca()){var Da=N;N=f.locateFile?f.locateFile(Da,u):u+Da}function Ea(){try{if(w)return new Uint8Array(w);if(fa)return fa(N);throw"both async and sync fetching of the wasm failed";}catch(a){A(a)}}function Fa(){return w||"function"!==typeof fetch?Promise.resolve().then(Ea):fetch(N,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+N+"'";return a.arrayBuffer()}).catch(function(){return Ea()})}
|
|
||||||
function O(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b(f);else{var c=b.R;"number"===typeof c?void 0===b.L?K.get(c)():K.get(c)(b.L):c(void 0===b.L?null:b.L)}}}var P={};function Ga(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function Q(a){return this.fromWireType(J[a>>2])}var R={},S={},Ha={};function Ia(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}
|
|
||||||
function Ja(a,b){a=Ia(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}function Ka(a){var b=Error,c=Ja(a,function(d){this.name=a;this.message=d;d=Error(d).stack;void 0!==d&&(this.stack=this.toString()+"\n"+d.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}
|
|
||||||
var La=void 0;function Ma(a,b,c){function d(h){h=c(h);if(h.length!==a.length)throw new La("Mismatched type converter count");for(var n=0;n<a.length;++n)T(a[n],h[n])}a.forEach(function(h){Ha[h]=b});var e=Array(b.length),g=[],m=0;b.forEach(function(h,n){S.hasOwnProperty(h)?e[n]=S[h]:(g.push(h),R.hasOwnProperty(h)||(R[h]=[]),R[h].push(function(){e[n]=S[h];++m;m===g.length&&d(e)}))});0===g.length&&d(e)}
|
|
||||||
function Na(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var Oa=void 0;function U(a){for(var b="";C[a];)b+=Oa[C[a++]];return b}var Pa=void 0;function W(a){throw new Pa(a);}
|
|
||||||
function T(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||W('type "'+d+'" must have a positive integer typeid pointer');if(S.hasOwnProperty(a)){if(c.V)return;W("Cannot register type '"+d+"' twice")}S[a]=b;delete Ha[a];R.hasOwnProperty(a)&&(b=R[a],delete R[a],b.forEach(function(e){e()}))}var Qa=[],X=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
|
||||||
function Ra(a){4<a&&0===--X[a].M&&(X[a]=void 0,Qa.push(a))}function Sa(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Qa.length?Qa.pop():X.length;X[b]={M:1,value:a};return b}}function Ta(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}
|
|
||||||
function Ua(a,b){switch(b){case 2:return function(c){return this.fromWireType(sa[c>>2])};case 3:return function(c){return this.fromWireType(ta[c>>3])};default:throw new TypeError("Unknown float type: "+a);}}function Va(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=Ja(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}
|
|
||||||
function Wa(a,b){var c=f;if(void 0===c[a].J){var d=c[a];c[a]=function(){c[a].J.hasOwnProperty(arguments.length)||W("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].J+")!");return c[a].J[arguments.length].apply(this,arguments)};c[a].J=[];c[a].J[d.O]=d}}
|
|
||||||
function Xa(a,b,c){f.hasOwnProperty(a)?((void 0===c||void 0!==f[a].J&&void 0!==f[a].J[c])&&W("Cannot register public name '"+a+"' twice"),Wa(a,a),f.hasOwnProperty(c)&&W("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),f[a].J[c]=b):(f[a]=b,void 0!==c&&(f[a].ba=c))}function Ya(a,b){for(var c=[],d=0;d<a;d++)c.push(G[(b>>2)+d]);return c}
|
|
||||||
function Za(a,b){0<=a.indexOf("j")||A("Assertion failed: getDynCaller should only be called with i64 sigs");var c=[];return function(){c.length=arguments.length;for(var d=0;d<arguments.length;d++)c[d]=arguments[d];var e;-1!=a.indexOf("j")?e=c&&c.length?f["dynCall_"+a].apply(null,[b].concat(c)):f["dynCall_"+a].call(null,b):e=K.get(b).apply(null,c);return e}}
|
|
||||||
function Y(a,b){a=U(a);var c=-1!=a.indexOf("j")?Za(a,b):K.get(b);"function"!==typeof c&&W("unknown function pointer with signature "+a+": "+b);return c}var $a=void 0;function ab(a){a=bb(a);var b=U(a);Z(a);return b}function cb(a,b){function c(g){e[g]||S[g]||(Ha[g]?Ha[g].forEach(c):(d.push(g),e[g]=!0))}var d=[],e={};b.forEach(c);throw new $a(a+": "+d.map(ab).join([", "]));}
|
|
||||||
function db(a,b,c){switch(b){case 0:return c?function(d){return I[d]}:function(d){return C[d]};case 1:return c?function(d){return E[d>>1]}:function(d){return D[d>>1]};case 2:return c?function(d){return G[d>>2]}:function(d){return J[d>>2]};default:throw new TypeError("Unknown integer type: "+a);}}var eb={};function fb(){return"object"===typeof globalThis?globalThis:Function("return this")()}function gb(a,b){var c=S[a];void 0===c&&W(b+" has unknown type "+ab(a));return c}var hb={},ib={};
|
|
||||||
function jb(){if(!kb){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"===typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:ca||"./this.program"},b;for(b in ib)a[b]=ib[b];var c=[];for(b in a)c.push(b+"="+a[b]);kb=c}return kb}var kb,lb=[null,[],[]];La=f.InternalError=Ka("InternalError");for(var mb=Array(256),nb=0;256>nb;++nb)mb[nb]=String.fromCharCode(nb);Oa=mb;Pa=f.BindingError=Ka("BindingError");
|
|
||||||
f.count_emval_handles=function(){for(var a=0,b=5;b<X.length;++b)void 0!==X[b]&&++a;return a};f.get_first_emval=function(){for(var a=5;a<X.length;++a)if(void 0!==X[a])return X[a];return null};$a=f.UnboundTypeError=Ka("UnboundTypeError");xa.push({R:function(){ob()}});
|
|
||||||
var rb={B:function(){},n:function(a){var b=P[a];delete P[a];var c=b.W,d=b.X,e=b.N,g=e.map(function(m){return m.U}).concat(e.map(function(m){return m.Z}));Ma([a],g,function(m){var h={};e.forEach(function(n,k){var l=m[k],q=n.S,x=n.T,y=m[k+e.length],p=n.Y,da=n.$;h[n.P]={read:function(z){return l.fromWireType(q(x,z))},write:function(z,F){var V=[];p(da,z,y.toWireType(V,F));Ga(V)}}});return[{name:b.name,fromWireType:function(n){var k={},l;for(l in h)k[l]=h[l].read(n);d(n);return k},toWireType:function(n,
|
|
||||||
k){for(var l in h)if(!(l in k))throw new TypeError('Missing field: "'+l+'"');var q=c();for(l in h)h[l].write(q,k[l]);null!==n&&n.push(d,q);return q},argPackAdvance:8,readValueFromPointer:Q,K:d}]})},y:function(a,b,c,d,e){var g=Na(c);b=U(b);T(a,{name:b,fromWireType:function(m){return!!m},toWireType:function(m,h){return h?d:e},argPackAdvance:8,readValueFromPointer:function(m){if(1===c)var h=I;else if(2===c)h=E;else if(4===c)h=G;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(h[m>>
|
|
||||||
g])},K:null})},x:function(a,b){b=U(b);T(a,{name:b,fromWireType:function(c){var d=X[c].value;Ra(c);return d},toWireType:function(c,d){return Sa(d)},argPackAdvance:8,readValueFromPointer:Q,K:null})},k:function(a,b,c){c=Na(c);b=U(b);T(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,e){if("number"!==typeof e&&"boolean"!==typeof e)throw new TypeError('Cannot convert "'+Ta(e)+'" to '+this.name);return e},argPackAdvance:8,readValueFromPointer:Ua(b,c),K:null})},g:function(a,b,c,d,e,g){var m=
|
|
||||||
Ya(b,c);a=U(a);e=Y(d,e);Xa(a,function(){cb("Cannot call "+a+" due to unbound types",m)},b-1);Ma([],m,function(h){var n=a,k=a;h=[h[0],null].concat(h.slice(1));var l=e,q=h.length;2>q&&W("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var x=null!==h[1]&&!1,y=!1,p=1;p<h.length;++p)if(null!==h[p]&&void 0===h[p].K){y=!0;break}var da="void"!==h[0].name,z="",F="";for(p=0;p<q-2;++p)z+=(0!==p?", ":"")+"arg"+p,F+=(0!==p?", ":"")+"arg"+p+"Wired";k="return function "+Ia(k)+
|
|
||||||
"("+z+") {\nif (arguments.length !== "+(q-2)+") {\nthrowBindingError('function "+k+" called with ' + arguments.length + ' arguments, expected "+(q-2)+" args!');\n}\n";y&&(k+="var destructors = [];\n");var V=y?"destructors":"null";z="throwBindingError invoker fn runDestructors retType classParam".split(" ");l=[W,l,g,Ga,h[0],h[1]];x&&(k+="var thisWired = classParam.toWireType("+V+", this);\n");for(p=0;p<q-2;++p)k+="var arg"+p+"Wired = argType"+p+".toWireType("+V+", arg"+p+"); // "+h[p+2].name+"\n",
|
|
||||||
z.push("argType"+p),l.push(h[p+2]);x&&(F="thisWired"+(0<F.length?", ":"")+F);k+=(da?"var rv = ":"")+"invoker(fn"+(0<F.length?", ":"")+F+");\n";if(y)k+="runDestructors(destructors);\n";else for(p=x?1:2;p<h.length;++p)q=1===p?"thisWired":"arg"+(p-2)+"Wired",null!==h[p].K&&(k+=q+"_dtor("+q+"); // "+h[p].name+"\n",z.push(q+"_dtor"),l.push(h[p].K));da&&(k+="var ret = retType.fromWireType(rv);\nreturn ret;\n");z.push(k+"}\n");h=Va(z).apply(null,l);p=b-1;if(!f.hasOwnProperty(n))throw new La("Replacing nonexistant public symbol");
|
|
||||||
void 0!==f[n].J&&void 0!==p?f[n].J[p]=h:(f[n]=h,f[n].O=p);return[]})},d:function(a,b,c,d,e){function g(k){return k}b=U(b);-1===e&&(e=4294967295);var m=Na(c);if(0===d){var h=32-8*c;g=function(k){return k<<h>>>h}}var n=-1!=b.indexOf("unsigned");T(a,{name:b,fromWireType:g,toWireType:function(k,l){if("number"!==typeof l&&"boolean"!==typeof l)throw new TypeError('Cannot convert "'+Ta(l)+'" to '+this.name);if(l<d||l>e)throw new TypeError('Passing a number "'+Ta(l)+'" from JS side to C/C++ side to an argument of type "'+
|
|
||||||
b+'", which is outside the valid range ['+d+", "+e+"]!");return n?l>>>0:l|0},argPackAdvance:8,readValueFromPointer:db(b,m,0!==d),K:null})},c:function(a,b,c){function d(g){g>>=2;var m=J;return new e(H,m[g+1],m[g])}var e=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=U(c);T(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{V:!0})},l:function(a,b){b=U(b);var c="std::string"===b;T(a,{name:b,fromWireType:function(d){var e=J[d>>2];if(c)for(var g=
|
|
||||||
d+4,m=0;m<=e;++m){var h=d+4+m;if(m==e||0==C[h]){if(g){for(var n=g+(h-g),k=g;!(k>=n)&&C[k];)++k;g=ja.decode(C.subarray(g,k))}else g="";if(void 0===l)var l=g;else l+=String.fromCharCode(0),l+=g;g=h+1}}else{l=Array(e);for(m=0;m<e;++m)l[m]=String.fromCharCode(C[d+4+m]);l=l.join("")}Z(d);return l},toWireType:function(d,e){e instanceof ArrayBuffer&&(e=new Uint8Array(e));var g="string"===typeof e;g||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Int8Array||W("Cannot pass non-string to std::string");
|
|
||||||
var m=(c&&g?function(){for(var k=0,l=0;l<e.length;++l){var q=e.charCodeAt(l);55296<=q&&57343>=q&&(q=65536+((q&1023)<<10)|e.charCodeAt(++l)&1023);127>=q?++k:k=2047>=q?k+2:65535>=q?k+3:k+4}return k}:function(){return e.length})(),h=pb(4+m+1);J[h>>2]=m;if(c&&g)ka(e,h+4,m+1);else if(g)for(g=0;g<m;++g){var n=e.charCodeAt(g);255<n&&(Z(h),W("String has UTF-16 code units that do not fit in 8 bits"));C[h+4+g]=n}else for(g=0;g<m;++g)C[h+4+g]=e[g];null!==d&&d.push(Z,h);return h},argPackAdvance:8,readValueFromPointer:Q,
|
|
||||||
K:function(d){Z(d)}})},f:function(a,b,c){c=U(c);if(2===b){var d=ma;var e=na;var g=oa;var m=function(){return D};var h=1}else 4===b&&(d=pa,e=qa,g=ra,m=function(){return J},h=2);T(a,{name:c,fromWireType:function(n){for(var k=J[n>>2],l=m(),q,x=n+4,y=0;y<=k;++y){var p=n+4+y*b;if(y==k||0==l[p>>h])x=d(x,p-x),void 0===q?q=x:(q+=String.fromCharCode(0),q+=x),x=p+b}Z(n);return q},toWireType:function(n,k){"string"!==typeof k&&W("Cannot pass non-string to C++ string type "+c);var l=g(k),q=pb(4+l+b);J[q>>2]=l>>
|
|
||||||
h;e(k,q+4,l+b);null!==n&&n.push(Z,q);return q},argPackAdvance:8,readValueFromPointer:Q,K:function(n){Z(n)}})},o:function(a,b,c,d,e,g){P[a]={name:U(b),W:Y(c,d),X:Y(e,g),N:[]}},b:function(a,b,c,d,e,g,m,h,n,k){P[a].N.push({P:U(b),U:c,S:Y(d,e),T:g,Z:m,Y:Y(h,n),$:k})},z:function(a,b){b=U(b);T(a,{aa:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},h:Ra,v:function(a){if(0===a)return Sa(fb());var b=eb[a];a=void 0===b?U(a):b;return Sa(fb()[a])},m:function(a){4<a&&(X[a].M+=1)},
|
|
||||||
p:function(a,b,c,d){a||W("Cannot use deleted val. handle = "+a);a=X[a].value;var e=hb[b];if(!e){e="";for(var g=0;g<b;++g)e+=(0!==g?", ":"")+"arg"+g;var m="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";for(g=0;g<b;++g)m+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";e=(new Function("requireRegisteredType","Module",
|
|
||||||
"__emval_register",m+("var obj = new constructor("+e+");\nreturn __emval_register(obj);\n}\n")))(gb,f,Sa);hb[b]=e}return e(a,c,d)},i:function(){A()},s:function(a,b,c){C.copyWithin(a,b,b+c)},e:function(a){a>>>=0;var b=C.length;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(16777216,a,d);0<d%65536&&(d+=65536-d%65536);a:{try{B.grow(Math.min(2147483648,d)-H.byteLength+65535>>>16);ua(B.buffer);var e=1;break a}catch(g){}e=void 0}if(e)return!0}return!1},
|
|
||||||
t:function(a,b){var c=0;jb().forEach(function(d,e){var g=b+c;e=G[a+4*e>>2]=g;for(g=0;g<d.length;++g)I[e++>>0]=d.charCodeAt(g);I[e>>0]=0;c+=d.length+1});return 0},u:function(a,b){var c=jb();G[a>>2]=c.length;var d=0;c.forEach(function(e){d+=e.length+1});G[b>>2]=d;return 0},A:function(a){if(!noExitRuntime){if(f.onExit)f.onExit(a);ia=!0}ea(a,new qb(a))},w:function(){return 0},q:function(){},j:function(a,b,c,d){for(var e=0,g=0;g<c;g++){for(var m=G[b+8*g>>2],h=G[b+(8*g+4)>>2],n=0;n<h;n++){var k=C[m+n],
|
|
||||||
l=lb[a];if(0===k||10===k){for(k=0;l[k]&&!(NaN<=k);)++k;k=ja.decode(l.subarray?l.subarray(0,k):new Uint8Array(l.slice(0,k)));(1===a?ha:v)(k);l.length=0}else l.push(k)}e+=h}G[d>>2]=e;return 0},a:B,r:function(){}};
|
|
||||||
(function(){function a(e){f.asm=e.exports;K=f.asm.C;L--;f.monitorRunDependencies&&f.monitorRunDependencies(L);0==L&&(null!==Ba&&(clearInterval(Ba),Ba=null),M&&(e=M,M=null,e()))}function b(e){a(e.instance)}function c(e){return Fa().then(function(g){return WebAssembly.instantiate(g,d)}).then(e,function(g){v("failed to asynchronously prepare wasm: "+g);A(g)})}var d={a:rb};L++;f.monitorRunDependencies&&f.monitorRunDependencies(L);if(f.instantiateWasm)try{return f.instantiateWasm(d,a)}catch(e){return v("Module.instantiateWasm callback failed with error: "+
|
|
||||||
e),!1}(function(){return w||"function"!==typeof WebAssembly.instantiateStreaming||Ca()||"function"!==typeof fetch?c(b):fetch(N,{credentials:"same-origin"}).then(function(e){return WebAssembly.instantiateStreaming(e,d).then(b,function(g){v("wasm streaming compile failed: "+g);v("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ba);return{}})();
|
|
||||||
var ob=f.___wasm_call_ctors=function(){return(ob=f.___wasm_call_ctors=f.asm.D).apply(null,arguments)},pb=f._malloc=function(){return(pb=f._malloc=f.asm.E).apply(null,arguments)},Z=f._free=function(){return(Z=f._free=f.asm.F).apply(null,arguments)},bb=f.___getTypeName=function(){return(bb=f.___getTypeName=f.asm.G).apply(null,arguments)};f.___embind_register_native_and_builtin_types=function(){return(f.___embind_register_native_and_builtin_types=f.asm.H).apply(null,arguments)};
|
|
||||||
f.dynCall_jiji=function(){return(f.dynCall_jiji=f.asm.I).apply(null,arguments)};var sb;function qb(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}M=function tb(){sb||ub();sb||(M=tb)};
|
|
||||||
function ub(){function a(){if(!sb&&(sb=!0,f.calledRun=!0,!ia)){O(xa);O(ya);aa(f);if(f.onRuntimeInitialized)f.onRuntimeInitialized();if(f.postRun)for("function"==typeof f.postRun&&(f.postRun=[f.postRun]);f.postRun.length;){var b=f.postRun.shift();za.unshift(b)}O(za)}}if(!(0<L)){if(f.preRun)for("function"==typeof f.preRun&&(f.preRun=[f.preRun]);f.preRun.length;)Aa();O(wa);0<L||(f.setStatus?(f.setStatus("Running..."),setTimeout(function(){setTimeout(function(){f.setStatus("")},1);a()},1)):a())}}
|
|
||||||
f.run=ub;if(f.preInit)for("function"==typeof f.preInit&&(f.preInit=[f.preInit]);0<f.preInit.length;)f.preInit.pop()();noExitRuntime=!0;ub();
|
|
||||||
|
|
||||||
|
|
||||||
return Module.ready
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
export default Module;
|
|
||||||
Binary file not shown.
61
codecs/mozjpeg/enc/mozjpeg_node_enc.js
generated
61
codecs/mozjpeg/enc/mozjpeg_node_enc.js
generated
@@ -1,61 +0,0 @@
|
|||||||
|
|
||||||
var Module = (function() {
|
|
||||||
var _scriptDir = import.meta.url;
|
|
||||||
|
|
||||||
return (
|
|
||||||
function(Module) {
|
|
||||||
Module = Module || {};
|
|
||||||
|
|
||||||
|
|
||||||
var f;f||(f=typeof Module !== 'undefined' ? Module : {});var aa,ba;f.ready=new Promise(function(a,b){aa=a;ba=b});var r={},t;for(t in f)f.hasOwnProperty(t)&&(r[t]=f[t]);var da="./this.program";function ea(a,b){throw b;}var fa="",ha,ia,ja,ka;fa=__dirname+"/";ha=function(a){ja||(ja=require("fs"));ka||(ka=require("path"));a=ka.normalize(a);return ja.readFileSync(a,null)};ia=function(a){a=ha(a);a.buffer||(a=new Uint8Array(a));a.buffer||u("Assertion failed: undefined");return a};
|
|
||||||
1<process.argv.length&&(da=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);process.on("uncaughtException",function(a){if(!(a instanceof la))throw a;});process.on("unhandledRejection",u);ea=function(a){process.exit(a)};f.inspect=function(){return"[Emscripten Module object]"};var ma=f.print||console.log.bind(console),v=f.printErr||console.warn.bind(console);for(t in r)r.hasOwnProperty(t)&&(f[t]=r[t]);r=null;f.thisProgram&&(da=f.thisProgram);f.quit&&(ea=f.quit);var w;f.wasmBinary&&(w=f.wasmBinary);
|
|
||||||
var noExitRuntime;f.noExitRuntime&&(noExitRuntime=f.noExitRuntime);"object"!==typeof WebAssembly&&u("no native wasm support detected");var A,na=!1,oa=new TextDecoder("utf8");
|
|
||||||
function pa(a,b,c){var d=B;if(0<c){c=b+c-1;for(var e=0;e<a.length;++e){var g=a.charCodeAt(e);if(55296<=g&&57343>=g){var m=a.charCodeAt(++e);g=65536+((g&1023)<<10)|m&1023}if(127>=g){if(b>=c)break;d[b++]=g}else{if(2047>=g){if(b+1>=c)break;d[b++]=192|g>>6}else{if(65535>=g){if(b+2>=c)break;d[b++]=224|g>>12}else{if(b+3>=c)break;d[b++]=240|g>>18;d[b++]=128|g>>12&63}d[b++]=128|g>>6&63}d[b++]=128|g&63}}d[b]=0}}var qa=new TextDecoder("utf-16le");
|
|
||||||
function ra(a,b){var c=a>>1;for(b=c+b/2;!(c>=b)&&C[c];)++c;return qa.decode(B.subarray(a,c<<1))}function sa(a,b,c){void 0===c&&(c=2147483647);if(2>c)return 0;c-=2;var d=b;c=c<2*a.length?c/2:a.length;for(var e=0;e<c;++e)D[b>>1]=a.charCodeAt(e),b+=2;D[b>>1]=0;return b-d}function ta(a){return 2*a.length}function ua(a,b){for(var c=0,d="";!(c>=b/4);){var e=F[a+4*c>>2];if(0==e)break;++c;65536<=e?(e-=65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023)):d+=String.fromCharCode(e)}return d}
|
|
||||||
function va(a,b,c){void 0===c&&(c=2147483647);if(4>c)return 0;var d=b;c=d+c-4;for(var e=0;e<a.length;++e){var g=a.charCodeAt(e);if(55296<=g&&57343>=g){var m=a.charCodeAt(++e);g=65536+((g&1023)<<10)|m&1023}F[b>>2]=g;b+=4;if(b+4>c)break}F[b>>2]=0;return b-d}function wa(a){for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);55296<=d&&57343>=d&&++c;b+=4}return b}var G,H,B,D,C,F,I,xa,ya;
|
|
||||||
function za(a){G=a;f.HEAP8=H=new Int8Array(a);f.HEAP16=D=new Int16Array(a);f.HEAP32=F=new Int32Array(a);f.HEAPU8=B=new Uint8Array(a);f.HEAPU16=C=new Uint16Array(a);f.HEAPU32=I=new Uint32Array(a);f.HEAPF32=xa=new Float32Array(a);f.HEAPF64=ya=new Float64Array(a)}var Aa=f.INITIAL_MEMORY||16777216;f.wasmMemory?A=f.wasmMemory:A=new WebAssembly.Memory({initial:Aa/65536,maximum:32768});A&&(G=A.buffer);Aa=G.byteLength;za(G);var J,Ba=[],Ca=[],Da=[],Ea=[];
|
|
||||||
function Fa(){var a=f.preRun.shift();Ba.unshift(a)}var K=0,Ga=null,L=null;f.preloadedImages={};f.preloadedAudios={};function u(a){if(f.onAbort)f.onAbort(a);v(a);na=!0;a=new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");ba(a);throw a;}function Ha(){var a=M;return String.prototype.startsWith?a.startsWith("data:application/octet-stream;base64,"):0===a.indexOf("data:application/octet-stream;base64,")}var M="mozjpeg_node_enc.wasm";
|
|
||||||
if(!Ha()){var Ia=M;M=f.locateFile?f.locateFile(Ia,fa):fa+Ia}function Ja(){try{if(w)return new Uint8Array(w);if(ia)return ia(M);throw"both async and sync fetching of the wasm failed";}catch(a){u(a)}}function N(a){for(;0<a.length;){var b=a.shift();if("function"==typeof b)b(f);else{var c=b.R;"number"===typeof c?void 0===b.L?J.get(c)():J.get(c)(b.L):c(void 0===b.L?null:b.L)}}}var O={};function Ka(a){for(;a.length;){var b=a.pop();a.pop()(b)}}function P(a){return this.fromWireType(I[a>>2])}
|
|
||||||
var Q={},R={},S={};function La(a){if(void 0===a)return"_unknown";a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?"_"+a:a}function Ma(a,b){a=La(a);return(new Function("body","return function "+a+'() {\n "use strict"; return body.apply(this, arguments);\n};\n'))(b)}
|
|
||||||
function Na(a){var b=Error,c=Ma(a,function(d){this.name=a;this.message=d;d=Error(d).stack;void 0!==d&&(this.stack=this.toString()+"\n"+d.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(b.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:this.name+": "+this.message};return c}var Oa=void 0;
|
|
||||||
function Pa(a,b,c){function d(h){h=c(h);if(h.length!==a.length)throw new Oa("Mismatched type converter count");for(var k=0;k<a.length;++k)U(a[k],h[k])}a.forEach(function(h){S[h]=b});var e=Array(b.length),g=[],m=0;b.forEach(function(h,k){R.hasOwnProperty(h)?e[k]=R[h]:(g.push(h),Q.hasOwnProperty(h)||(Q[h]=[]),Q[h].push(function(){e[k]=R[h];++m;m===g.length&&d(e)}))});0===g.length&&d(e)}
|
|
||||||
function Qa(a){switch(a){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+a);}}var Ra=void 0;function V(a){for(var b="";B[a];)b+=Ra[B[a++]];return b}var Sa=void 0;function W(a){throw new Sa(a);}
|
|
||||||
function U(a,b,c){c=c||{};if(!("argPackAdvance"in b))throw new TypeError("registerType registeredInstance requires argPackAdvance");var d=b.name;a||W('type "'+d+'" must have a positive integer typeid pointer');if(R.hasOwnProperty(a)){if(c.V)return;W("Cannot register type '"+d+"' twice")}R[a]=b;delete S[a];Q.hasOwnProperty(a)&&(b=Q[a],delete Q[a],b.forEach(function(e){e()}))}var Ta=[],X=[{},{value:void 0},{value:null},{value:!0},{value:!1}];
|
|
||||||
function Ua(a){4<a&&0===--X[a].M&&(X[a]=void 0,Ta.push(a))}function Va(a){switch(a){case void 0:return 1;case null:return 2;case !0:return 3;case !1:return 4;default:var b=Ta.length?Ta.pop():X.length;X[b]={M:1,value:a};return b}}function Wa(a){if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a}
|
|
||||||
function Xa(a,b){switch(b){case 2:return function(c){return this.fromWireType(xa[c>>2])};case 3:return function(c){return this.fromWireType(ya[c>>3])};default:throw new TypeError("Unknown float type: "+a);}}function Ya(a){var b=Function;if(!(b instanceof Function))throw new TypeError("new_ called with constructor type "+typeof b+" which is not a function");var c=Ma(b.name||"unknownFunctionName",function(){});c.prototype=b.prototype;c=new c;a=b.apply(c,a);return a instanceof Object?a:c}
|
|
||||||
function Za(a,b){var c=f;if(void 0===c[a].J){var d=c[a];c[a]=function(){c[a].J.hasOwnProperty(arguments.length)||W("Function '"+b+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+c[a].J+")!");return c[a].J[arguments.length].apply(this,arguments)};c[a].J=[];c[a].J[d.O]=d}}
|
|
||||||
function $a(a,b,c){f.hasOwnProperty(a)?((void 0===c||void 0!==f[a].J&&void 0!==f[a].J[c])&&W("Cannot register public name '"+a+"' twice"),Za(a,a),f.hasOwnProperty(c)&&W("Cannot register multiple overloads of a function with the same number of arguments ("+c+")!"),f[a].J[c]=b):(f[a]=b,void 0!==c&&(f[a].ba=c))}function ab(a,b){for(var c=[],d=0;d<a;d++)c.push(F[(b>>2)+d]);return c}
|
|
||||||
function bb(a,b){0<=a.indexOf("j")||u("Assertion failed: getDynCaller should only be called with i64 sigs");var c=[];return function(){c.length=arguments.length;for(var d=0;d<arguments.length;d++)c[d]=arguments[d];var e;-1!=a.indexOf("j")?e=c&&c.length?f["dynCall_"+a].apply(null,[b].concat(c)):f["dynCall_"+a].call(null,b):e=J.get(b).apply(null,c);return e}}
|
|
||||||
function Y(a,b){a=V(a);var c=-1!=a.indexOf("j")?bb(a,b):J.get(b);"function"!==typeof c&&W("unknown function pointer with signature "+a+": "+b);return c}var cb=void 0;function db(a){a=eb(a);var b=V(a);Z(a);return b}function fb(a,b){function c(g){e[g]||R[g]||(S[g]?S[g].forEach(c):(d.push(g),e[g]=!0))}var d=[],e={};b.forEach(c);throw new cb(a+": "+d.map(db).join([", "]));}
|
|
||||||
function gb(a,b,c){switch(b){case 0:return c?function(d){return H[d]}:function(d){return B[d]};case 1:return c?function(d){return D[d>>1]}:function(d){return C[d>>1]};case 2:return c?function(d){return F[d>>2]}:function(d){return I[d>>2]};default:throw new TypeError("Unknown integer type: "+a);}}var hb={};function ib(){return"object"===typeof globalThis?globalThis:Function("return this")()}function jb(a,b){var c=R[a];void 0===c&&W(b+" has unknown type "+db(a));return c}var kb={},lb={};
|
|
||||||
function mb(){if(!nb){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"===typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:da||"./this.program"},b;for(b in lb)a[b]=lb[b];var c=[];for(b in a)c.push(b+"="+a[b]);nb=c}return nb}var nb,ob=[null,[],[]];Oa=f.InternalError=Na("InternalError");for(var pb=Array(256),qb=0;256>qb;++qb)pb[qb]=String.fromCharCode(qb);Ra=pb;Sa=f.BindingError=Na("BindingError");
|
|
||||||
f.count_emval_handles=function(){for(var a=0,b=5;b<X.length;++b)void 0!==X[b]&&++a;return a};f.get_first_emval=function(){for(var a=5;a<X.length;++a)if(void 0!==X[a])return X[a];return null};cb=f.UnboundTypeError=Na("UnboundTypeError");Ca.push({R:function(){rb()}});
|
|
||||||
var tb={B:function(){},n:function(a){var b=O[a];delete O[a];var c=b.W,d=b.X,e=b.N,g=e.map(function(m){return m.U}).concat(e.map(function(m){return m.Z}));Pa([a],g,function(m){var h={};e.forEach(function(k,n){var l=m[n],p=k.S,x=k.T,y=m[n+e.length],q=k.Y,ca=k.$;h[k.P]={read:function(z){return l.fromWireType(p(x,z))},write:function(z,E){var T=[];q(ca,z,y.toWireType(T,E));Ka(T)}}});return[{name:b.name,fromWireType:function(k){var n={},l;for(l in h)n[l]=h[l].read(k);d(k);return n},toWireType:function(k,
|
|
||||||
n){for(var l in h)if(!(l in n))throw new TypeError('Missing field: "'+l+'"');var p=c();for(l in h)h[l].write(p,n[l]);null!==k&&k.push(d,p);return p},argPackAdvance:8,readValueFromPointer:P,K:d}]})},y:function(a,b,c,d,e){var g=Qa(c);b=V(b);U(a,{name:b,fromWireType:function(m){return!!m},toWireType:function(m,h){return h?d:e},argPackAdvance:8,readValueFromPointer:function(m){if(1===c)var h=H;else if(2===c)h=D;else if(4===c)h=F;else throw new TypeError("Unknown boolean type size: "+b);return this.fromWireType(h[m>>
|
|
||||||
g])},K:null})},x:function(a,b){b=V(b);U(a,{name:b,fromWireType:function(c){var d=X[c].value;Ua(c);return d},toWireType:function(c,d){return Va(d)},argPackAdvance:8,readValueFromPointer:P,K:null})},k:function(a,b,c){c=Qa(c);b=V(b);U(a,{name:b,fromWireType:function(d){return d},toWireType:function(d,e){if("number"!==typeof e&&"boolean"!==typeof e)throw new TypeError('Cannot convert "'+Wa(e)+'" to '+this.name);return e},argPackAdvance:8,readValueFromPointer:Xa(b,c),K:null})},g:function(a,b,c,d,e,g){var m=
|
|
||||||
ab(b,c);a=V(a);e=Y(d,e);$a(a,function(){fb("Cannot call "+a+" due to unbound types",m)},b-1);Pa([],m,function(h){var k=[h[0],null].concat(h.slice(1)),n=h=a,l=e,p=k.length;2>p&&W("argTypes array size mismatch! Must at least get return value and 'this' types!");for(var x=null!==k[1]&&!1,y=!1,q=1;q<k.length;++q)if(null!==k[q]&&void 0===k[q].K){y=!0;break}var ca="void"!==k[0].name,z="",E="";for(q=0;q<p-2;++q)z+=(0!==q?", ":"")+"arg"+q,E+=(0!==q?", ":"")+"arg"+q+"Wired";n="return function "+La(n)+"("+
|
|
||||||
z+") {\nif (arguments.length !== "+(p-2)+") {\nthrowBindingError('function "+n+" called with ' + arguments.length + ' arguments, expected "+(p-2)+" args!');\n}\n";y&&(n+="var destructors = [];\n");var T=y?"destructors":"null";z="throwBindingError invoker fn runDestructors retType classParam".split(" ");l=[W,l,g,Ka,k[0],k[1]];x&&(n+="var thisWired = classParam.toWireType("+T+", this);\n");for(q=0;q<p-2;++q)n+="var arg"+q+"Wired = argType"+q+".toWireType("+T+", arg"+q+"); // "+k[q+2].name+"\n",z.push("argType"+
|
|
||||||
q),l.push(k[q+2]);x&&(E="thisWired"+(0<E.length?", ":"")+E);n+=(ca?"var rv = ":"")+"invoker(fn"+(0<E.length?", ":"")+E+");\n";if(y)n+="runDestructors(destructors);\n";else for(q=x?1:2;q<k.length;++q)p=1===q?"thisWired":"arg"+(q-2)+"Wired",null!==k[q].K&&(n+=p+"_dtor("+p+"); // "+k[q].name+"\n",z.push(p+"_dtor"),l.push(k[q].K));ca&&(n+="var ret = retType.fromWireType(rv);\nreturn ret;\n");z.push(n+"}\n");k=Ya(z).apply(null,l);q=b-1;if(!f.hasOwnProperty(h))throw new Oa("Replacing nonexistant public symbol");
|
|
||||||
void 0!==f[h].J&&void 0!==q?f[h].J[q]=k:(f[h]=k,f[h].O=q);return[]})},d:function(a,b,c,d,e){function g(n){return n}b=V(b);-1===e&&(e=4294967295);var m=Qa(c);if(0===d){var h=32-8*c;g=function(n){return n<<h>>>h}}var k=-1!=b.indexOf("unsigned");U(a,{name:b,fromWireType:g,toWireType:function(n,l){if("number"!==typeof l&&"boolean"!==typeof l)throw new TypeError('Cannot convert "'+Wa(l)+'" to '+this.name);if(l<d||l>e)throw new TypeError('Passing a number "'+Wa(l)+'" from JS side to C/C++ side to an argument of type "'+
|
|
||||||
b+'", which is outside the valid range ['+d+", "+e+"]!");return k?l>>>0:l|0},argPackAdvance:8,readValueFromPointer:gb(b,m,0!==d),K:null})},c:function(a,b,c){function d(g){g>>=2;var m=I;return new e(G,m[g+1],m[g])}var e=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=V(c);U(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{V:!0})},l:function(a,b){b=V(b);var c="std::string"===b;U(a,{name:b,fromWireType:function(d){var e=I[d>>2];if(c)for(var g=
|
|
||||||
d+4,m=0;m<=e;++m){var h=d+4+m;if(m==e||0==B[h]){if(g){for(var k=g+(h-g),n=g;!(n>=k)&&B[n];)++n;g=oa.decode(B.subarray(g,n))}else g="";if(void 0===l)var l=g;else l+=String.fromCharCode(0),l+=g;g=h+1}}else{l=Array(e);for(m=0;m<e;++m)l[m]=String.fromCharCode(B[d+4+m]);l=l.join("")}Z(d);return l},toWireType:function(d,e){e instanceof ArrayBuffer&&(e=new Uint8Array(e));var g="string"===typeof e;g||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Int8Array||W("Cannot pass non-string to std::string");
|
|
||||||
var m=(c&&g?function(){for(var n=0,l=0;l<e.length;++l){var p=e.charCodeAt(l);55296<=p&&57343>=p&&(p=65536+((p&1023)<<10)|e.charCodeAt(++l)&1023);127>=p?++n:n=2047>=p?n+2:65535>=p?n+3:n+4}return n}:function(){return e.length})(),h=sb(4+m+1);I[h>>2]=m;if(c&&g)pa(e,h+4,m+1);else if(g)for(g=0;g<m;++g){var k=e.charCodeAt(g);255<k&&(Z(h),W("String has UTF-16 code units that do not fit in 8 bits"));B[h+4+g]=k}else for(g=0;g<m;++g)B[h+4+g]=e[g];null!==d&&d.push(Z,h);return h},argPackAdvance:8,readValueFromPointer:P,
|
|
||||||
K:function(d){Z(d)}})},f:function(a,b,c){c=V(c);if(2===b){var d=ra;var e=sa;var g=ta;var m=function(){return C};var h=1}else 4===b&&(d=ua,e=va,g=wa,m=function(){return I},h=2);U(a,{name:c,fromWireType:function(k){for(var n=I[k>>2],l=m(),p,x=k+4,y=0;y<=n;++y){var q=k+4+y*b;if(y==n||0==l[q>>h])x=d(x,q-x),void 0===p?p=x:(p+=String.fromCharCode(0),p+=x),x=q+b}Z(k);return p},toWireType:function(k,n){"string"!==typeof n&&W("Cannot pass non-string to C++ string type "+c);var l=g(n),p=sb(4+l+b);I[p>>2]=l>>
|
|
||||||
h;e(n,p+4,l+b);null!==k&&k.push(Z,p);return p},argPackAdvance:8,readValueFromPointer:P,K:function(k){Z(k)}})},o:function(a,b,c,d,e,g){O[a]={name:V(b),W:Y(c,d),X:Y(e,g),N:[]}},b:function(a,b,c,d,e,g,m,h,k,n){O[a].N.push({P:V(b),U:c,S:Y(d,e),T:g,Z:m,Y:Y(h,k),$:n})},z:function(a,b){b=V(b);U(a,{aa:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},h:Ua,v:function(a){if(0===a)return Va(ib());var b=hb[a];a=void 0===b?V(a):b;return Va(ib()[a])},m:function(a){4<a&&(X[a].M+=1)},
|
|
||||||
p:function(a,b,c,d){a||W("Cannot use deleted val. handle = "+a);a=X[a].value;var e=kb[b];if(!e){e="";for(var g=0;g<b;++g)e+=(0!==g?", ":"")+"arg"+g;var m="return function emval_allocator_"+b+"(constructor, argTypes, args) {\n";for(g=0;g<b;++g)m+="var argType"+g+" = requireRegisteredType(Module['HEAP32'][(argTypes >>> 2) + "+g+'], "parameter '+g+'");\nvar arg'+g+" = argType"+g+".readValueFromPointer(args);\nargs += argType"+g+"['argPackAdvance'];\n";e=(new Function("requireRegisteredType","Module",
|
|
||||||
"__emval_register",m+("var obj = new constructor("+e+");\nreturn __emval_register(obj);\n}\n")))(jb,f,Va);kb[b]=e}return e(a,c,d)},i:function(){u()},s:function(a,b,c){B.copyWithin(a,b,b+c)},e:function(a){a>>>=0;var b=B.length;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,a+100663296);d=Math.max(16777216,a,d);0<d%65536&&(d+=65536-d%65536);a:{try{A.grow(Math.min(2147483648,d)-G.byteLength+65535>>>16);za(A.buffer);var e=1;break a}catch(g){}e=void 0}if(e)return!0}return!1},
|
|
||||||
t:function(a,b){var c=0;mb().forEach(function(d,e){var g=b+c;e=F[a+4*e>>2]=g;for(g=0;g<d.length;++g)H[e++>>0]=d.charCodeAt(g);H[e>>0]=0;c+=d.length+1});return 0},u:function(a,b){var c=mb();F[a>>2]=c.length;var d=0;c.forEach(function(e){d+=e.length+1});F[b>>2]=d;return 0},A:function(a){if(!noExitRuntime){if(f.onExit)f.onExit(a);na=!0}ea(a,new la(a))},w:function(){return 0},q:function(){},j:function(a,b,c,d){for(var e=0,g=0;g<c;g++){for(var m=F[b+8*g>>2],h=F[b+(8*g+4)>>2],k=0;k<h;k++){var n=B[m+k],
|
|
||||||
l=ob[a];if(0===n||10===n){n=1===a?ma:v;var p;for(p=0;l[p]&&!(NaN<=p);)++p;p=oa.decode(l.subarray?l.subarray(0,p):new Uint8Array(l.slice(0,p)));n(p);l.length=0}else l.push(n)}e+=h}F[d>>2]=e;return 0},a:A,r:function(){}};
|
|
||||||
(function(){function a(e){f.asm=e.exports;J=f.asm.C;K--;f.monitorRunDependencies&&f.monitorRunDependencies(K);0==K&&(null!==Ga&&(clearInterval(Ga),Ga=null),L&&(e=L,L=null,e()))}function b(e){a(e.instance)}function c(e){return Promise.resolve().then(Ja).then(function(g){return WebAssembly.instantiate(g,d)}).then(e,function(g){v("failed to asynchronously prepare wasm: "+g);u(g)})}var d={a:tb};K++;f.monitorRunDependencies&&f.monitorRunDependencies(K);if(f.instantiateWasm)try{return f.instantiateWasm(d,
|
|
||||||
a)}catch(e){return v("Module.instantiateWasm callback failed with error: "+e),!1}(function(){return w||"function"!==typeof WebAssembly.instantiateStreaming||Ha()||"function"!==typeof fetch?c(b):fetch(M,{credentials:"same-origin"}).then(function(e){return WebAssembly.instantiateStreaming(e,d).then(b,function(g){v("wasm streaming compile failed: "+g);v("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ba);return{}})();
|
|
||||||
var rb=f.___wasm_call_ctors=function(){return(rb=f.___wasm_call_ctors=f.asm.D).apply(null,arguments)},sb=f._malloc=function(){return(sb=f._malloc=f.asm.E).apply(null,arguments)},Z=f._free=function(){return(Z=f._free=f.asm.F).apply(null,arguments)},eb=f.___getTypeName=function(){return(eb=f.___getTypeName=f.asm.G).apply(null,arguments)};f.___embind_register_native_and_builtin_types=function(){return(f.___embind_register_native_and_builtin_types=f.asm.H).apply(null,arguments)};
|
|
||||||
f.dynCall_jiji=function(){return(f.dynCall_jiji=f.asm.I).apply(null,arguments)};var ub;function la(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}L=function vb(){ub||wb();ub||(L=vb)};
|
|
||||||
function wb(){function a(){if(!ub&&(ub=!0,f.calledRun=!0,!na)){N(Ca);N(Da);aa(f);if(f.onRuntimeInitialized)f.onRuntimeInitialized();if(f.postRun)for("function"==typeof f.postRun&&(f.postRun=[f.postRun]);f.postRun.length;){var b=f.postRun.shift();Ea.unshift(b)}N(Ea)}}if(!(0<K)){if(f.preRun)for("function"==typeof f.preRun&&(f.preRun=[f.preRun]);f.preRun.length;)Fa();N(Ba);0<K||(f.setStatus?(f.setStatus("Running..."),setTimeout(function(){setTimeout(function(){f.setStatus("")},1);a()},1)):a())}}
|
|
||||||
f.run=wb;if(f.preInit)for("function"==typeof f.preInit&&(f.preInit=[f.preInit]);0<f.preInit.length;)f.preInit.pop()();noExitRuntime=!0;wb();
|
|
||||||
|
|
||||||
|
|
||||||
return Module.ready
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
export default Module;
|
|
||||||
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.
458
codecs/oxipng/Cargo.lock
generated
458
codecs/oxipng/Cargo.lock
generated
@@ -1,16 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
version = 3
|
||||||
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]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
@@ -19,22 +9,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-vec"
|
name = "bitvec"
|
||||||
version = "0.6.3"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||||
|
dependencies = [
|
||||||
[[package]]
|
"funty",
|
||||||
name = "bitflags"
|
"radium",
|
||||||
version = "1.2.1"
|
"tap",
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
"wyz",
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "build_const"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
@@ -44,15 +28,9 @@ checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.4.1"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac"
|
checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byteorder"
|
|
||||||
version = "1.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
@@ -60,120 +38,51 @@ version = "1.0.66"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
|
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
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]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.0"
|
version = "0.5.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.0"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.1"
|
version = "0.9.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
|
checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"autocfg",
|
||||||
"const_fn",
|
"cfg-if",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"lazy_static",
|
|
||||||
"memoffset",
|
|
||||||
"scopeguard",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.1"
|
version = "0.8.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"cfg-if",
|
||||||
"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",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -182,54 +91,42 @@ version = "1.6.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
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]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.9.1"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
[[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",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.6.1"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
|
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"rayon",
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "js-sys"
|
||||||
version = "0.10.0"
|
version = "0.3.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -238,172 +135,52 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.81"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdeflate-sys"
|
name = "libdeflate-sys"
|
||||||
version = "0.7.1"
|
version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a95fa4be7085dd06a8296dcc3f399f12ab8b0309c157dcaa90669130b175b97"
|
checksum = "67921a7f85100c1559efc3d1c7c472091b7da05f304b4bbd5356f075e97f1cc2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdeflater"
|
name = "libdeflater"
|
||||||
version = "0.7.1"
|
version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccc147465654929bf7b56518cc46d11701ba290f4ff94398ae3f89f1663cf60f"
|
checksum = "3a31b22f662350ec294b13859f935aea772ba7b2bc8776269f4a5627308eab7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libdeflate-sys",
|
"libdeflate-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.11"
|
version = "0.4.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
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",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxipng"
|
name = "oxipng"
|
||||||
version = "4.0.3"
|
version = "9.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50d0b53912a666fe2970f8ab254e283531c816aed16551ab66c52485eadb44e6"
|
checksum = "28e5c341ef78a228e47a551bfd15ff885d8c501af49f953358763a538c01f14d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-vec",
|
"bitvec",
|
||||||
"byteorder",
|
|
||||||
"cloudflare-zlib",
|
|
||||||
"crc",
|
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"image",
|
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itertools",
|
|
||||||
"libdeflater",
|
"libdeflater",
|
||||||
"log",
|
"log",
|
||||||
"miniz_oxide 0.4.3",
|
|
||||||
"rayon",
|
"rayon",
|
||||||
"rgb",
|
"rgb",
|
||||||
|
"rustc-hash",
|
||||||
"rustc_version",
|
"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]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.24"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@@ -418,90 +195,82 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "radium"
|
||||||
version = "1.5.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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 = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"crossbeam-deque",
|
|
||||||
"either",
|
"either",
|
||||||
"rayon-core",
|
"rayon-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.9.0"
|
version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"lazy_static",
|
|
||||||
"num_cpus",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
version = "0.8.25"
|
version = "0.8.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "287f3c3f8236abb92d8b7e36797f19159df4b58f0a658cc3fb6dd3004b1f3bd3"
|
checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc-hash"
|
||||||
version = "0.3.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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 = [
|
dependencies = [
|
||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.11.0"
|
version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
||||||
dependencies = [
|
|
||||||
"semver-parser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver-parser"
|
name = "spmc"
|
||||||
version = "0.10.2"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5"
|
||||||
dependencies = [
|
|
||||||
"pest",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "squoosh-oxipng"
|
name = "squoosh-oxipng"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
|
||||||
"libdeflater",
|
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
|
||||||
"oxipng",
|
"oxipng",
|
||||||
"rayon",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.58"
|
version = "1.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
|
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -509,10 +278,10 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ucd-trie"
|
name = "tap"
|
||||||
version = "0.1.3"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
@@ -522,19 +291,19 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.69"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e"
|
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.69"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62"
|
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -547,9 +316,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.69"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084"
|
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@@ -557,9 +326,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.69"
|
version = "0.2.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549"
|
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -569,7 +338,28 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-rayon"
|
||||||
version = "0.2.69"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"
|
checksum = "3069d2a42e7a7e3bfde668f84adb5fbc35701ca2b39b27a064cbd5ede4e78194"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"rayon",
|
||||||
|
"spmc",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
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,17 +12,14 @@ wasm-opt = ["-O", "--no-validation"]
|
|||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
oxipng = { version = "4.0.1", default-features = false, features = ["libdeflater"] }
|
oxipng = { version = "9.0", default-features = false, features = ["freestanding"] }
|
||||||
libdeflater = { version = "0.7.1", features = ["freestanding"] }
|
wasm-bindgen = "0.2.73"
|
||||||
wasm-bindgen = "0.2.68"
|
|
||||||
log = { version = "0.4.11", features = ["release_max_level_off"] }
|
log = { version = "0.4.11", features = ["release_max_level_off"] }
|
||||||
rayon = { version = "1.5.0", optional = true }
|
wasm-bindgen-rayon = { version = "1.0", optional = true }
|
||||||
once_cell = { version = "1.5.2", optional = true }
|
|
||||||
crossbeam-channel = { version = "0.5.0", optional = true }
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
opt-level = "s"
|
opt-level = "s"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
parallel = ["oxipng/parallel", "rayon", "crossbeam-channel", "once_cell"]
|
parallel = ["oxipng/parallel", "wasm-bindgen-rayon"]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# OxiPNG
|
# OxiPNG
|
||||||
|
|
||||||
- Source: <https://github.com/shssoichiro/oxipng>
|
- Source: <https://github.com/shssoichiro/oxipng>
|
||||||
- Version: v3.0.0
|
- Version: v9.0.0
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|||||||
@@ -5,7 +5,5 @@ set -e
|
|||||||
rm -rf pkg,{-parallel}
|
rm -rf pkg,{-parallel}
|
||||||
export CFLAGS="${CFLAGS} -DUNALIGNED_ACCESS_IS_FAST=1"
|
export CFLAGS="${CFLAGS} -DUNALIGNED_ACCESS_IS_FAST=1"
|
||||||
wasm-pack build -t web
|
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
|
||||||
# Workaround https://github.com/rustwasm/wasm-bindgen/issues/2133:
|
|
||||||
sed -i "s|maybe_memory:|maybe_memory?:|" pkg-parallel/squoosh_oxipng.d.ts
|
|
||||||
rm pkg{,-parallel}/.gitignore
|
rm pkg{,-parallel}/.gitignore
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oxipng",
|
"name": "oxipng",
|
||||||
"scripts": {
|
"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
|
# OxiPNG
|
||||||
|
|
||||||
- Source: <https://github.com/shssoichiro/oxipng>
|
- Source: <https://github.com/shssoichiro/oxipng>
|
||||||
- Version: v3.0.0
|
- Version: v9.0.0
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|||||||
@@ -11,5 +11,7 @@
|
|||||||
],
|
],
|
||||||
"module": "squoosh_oxipng.js",
|
"module": "squoosh_oxipng.js",
|
||||||
"types": "squoosh_oxipng.d.ts",
|
"types": "squoosh_oxipng.d.ts",
|
||||||
"sideEffects": false
|
"sideEffects": [
|
||||||
|
"./snippets/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
98
codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js
generated
Normal file
98
codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js
generated
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google Inc. All Rights Reserved.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure
|
||||||
|
// we can handle bundling into other files, which might happen to have their
|
||||||
|
// own `postMessage`/`onmessage` communication channels.
|
||||||
|
//
|
||||||
|
// If we didn't take that into the account, we could send much simpler signals
|
||||||
|
// like just `0` or whatever, but the code would be less resilient.
|
||||||
|
|
||||||
|
function waitForMsgType(target, type) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
target.addEventListener('message', function onMsg({ data }) {
|
||||||
|
if (data == null || data.type !== type) return;
|
||||||
|
target.removeEventListener('message', onMsg);
|
||||||
|
resolve(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {
|
||||||
|
// # Note 1
|
||||||
|
// Our JS should have been generated in
|
||||||
|
// `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,
|
||||||
|
// resolve the main module via `../../..`.
|
||||||
|
//
|
||||||
|
// This might need updating if the generated structure changes on wasm-bindgen
|
||||||
|
// side ever in the future, but works well with bundlers today. The whole
|
||||||
|
// point of this crate, after all, is to abstract away unstable features
|
||||||
|
// and temporary bugs so that you don't need to deal with them in your code.
|
||||||
|
//
|
||||||
|
// # Note 2
|
||||||
|
// This could be a regular import, but then some bundlers complain about
|
||||||
|
// circular deps.
|
||||||
|
//
|
||||||
|
// Dynamic import could be cheap if this file was inlined into the parent,
|
||||||
|
// which would require us just using `../../..` in `new Worker` below,
|
||||||
|
// but that doesn't work because wasm-pack unconditionally adds
|
||||||
|
// "sideEffects":false (see below).
|
||||||
|
//
|
||||||
|
// OTOH, even though it can't be inlined, it should be still reasonably
|
||||||
|
// cheap since the requested file is already in cache (it was loaded by
|
||||||
|
// the main thread).
|
||||||
|
const pkg = await import('../../..');
|
||||||
|
await pkg.default(data.module, data.memory);
|
||||||
|
postMessage({ type: 'wasm_bindgen_worker_ready' });
|
||||||
|
pkg.wbg_rayon_start_worker(data.receiver);
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function startWorkers(module, memory, builder) {
|
||||||
|
const workerInit = {
|
||||||
|
type: 'wasm_bindgen_worker_init',
|
||||||
|
module,
|
||||||
|
memory,
|
||||||
|
receiver: builder.receiver()
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
Array.from({ length: builder.numThreads() }, () => {
|
||||||
|
// Self-spawn into a new Worker.
|
||||||
|
//
|
||||||
|
// TODO: while `new URL('...', import.meta.url) becomes a semi-standard
|
||||||
|
// way to get asset URLs relative to the module across various bundlers
|
||||||
|
// and browser, ideally we should switch to `import.meta.resolve`
|
||||||
|
// once it becomes a standard.
|
||||||
|
//
|
||||||
|
// Note: we could use `../../..` as the URL here to inline workerHelpers.js
|
||||||
|
// into the parent entry instead of creating another split point -
|
||||||
|
// this would be preferable from optimization perspective -
|
||||||
|
// however, Webpack then eliminates all message handler code
|
||||||
|
// because wasm-pack produces "sideEffects":false in package.json
|
||||||
|
// unconditionally.
|
||||||
|
//
|
||||||
|
// The only way to work around that is to have side effect code
|
||||||
|
// in an entry point such as Worker file itself.
|
||||||
|
const worker = new Worker(new URL('./workerHelpers.js', import.meta.url), {
|
||||||
|
type: 'module'
|
||||||
|
});
|
||||||
|
worker.postMessage(workerInit);
|
||||||
|
return waitForMsgType(worker, 'wasm_bindgen_worker_ready');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
builder.build();
|
||||||
|
} finally {
|
||||||
|
builder.free();
|
||||||
|
}
|
||||||
|
}
|
||||||
44
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
44
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
@@ -1,31 +1,52 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8ClampedArray} data
|
||||||
|
* @param {number} width
|
||||||
|
* @param {number} height
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
|
* @param {boolean} interlace
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
export function optimise(data: Uint8ClampedArray, width: number, height: number, level: number, interlace: boolean): Uint8Array;
|
||||||
/**
|
/**
|
||||||
* @param {number} num
|
* @param {number} num_threads
|
||||||
* @returns {any}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
export function worker_initializer(num: number): any;
|
export function initThreadPool(num_threads: number): Promise<any>;
|
||||||
|
/**
|
||||||
|
* @param {number} receiver
|
||||||
|
*/
|
||||||
|
export function wbg_rayon_start_worker(receiver: number): void;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_main_thread(): void;
|
export class wbg_rayon_PoolBuilder {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
numThreads(): number;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
receiver(): number;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_worker_thread(): void;
|
build(): void;
|
||||||
|
}
|
||||||
|
|
||||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
readonly optimise: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
|
||||||
readonly worker_initializer: (a: number) => number;
|
readonly __wbg_wbg_rayon_poolbuilder_free: (a: number) => void;
|
||||||
readonly start_main_thread: () => void;
|
readonly wbg_rayon_poolbuilder_numThreads: (a: number) => number;
|
||||||
readonly start_worker_thread: () => void;
|
readonly wbg_rayon_poolbuilder_receiver: (a: number) => number;
|
||||||
|
readonly wbg_rayon_poolbuilder_build: (a: number) => void;
|
||||||
|
readonly initThreadPool: (a: number) => number;
|
||||||
|
readonly wbg_rayon_start_worker: (a: number) => void;
|
||||||
readonly __wbindgen_export_0: WebAssembly.Memory;
|
readonly __wbindgen_export_0: WebAssembly.Memory;
|
||||||
|
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||||
readonly __wbindgen_malloc: (a: number) => number;
|
readonly __wbindgen_malloc: (a: number) => number;
|
||||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
readonly __wbindgen_start: () => void;
|
readonly __wbindgen_start: () => void;
|
||||||
@@ -41,4 +62,3 @@ export interface InitOutput {
|
|||||||
* @returns {Promise<InitOutput>}
|
* @returns {Promise<InitOutput>}
|
||||||
*/
|
*/
|
||||||
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;
|
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;
|
||||||
|
|
||||||
120
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
120
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
@@ -1,21 +1,6 @@
|
|||||||
|
import { startWorkers } from './snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js';
|
||||||
|
|
||||||
let wasm;
|
let wasm;
|
||||||
let memory;
|
|
||||||
|
|
||||||
const heap = new Array(32).fill(undefined);
|
|
||||||
|
|
||||||
heap.push(undefined, null, true, false);
|
|
||||||
|
|
||||||
let heap_next = heap.length;
|
|
||||||
|
|
||||||
function addHeapObject(obj) {
|
|
||||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|
||||||
const idx = heap_next;
|
|
||||||
heap_next = heap[idx];
|
|
||||||
|
|
||||||
heap[idx] = obj;
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
|
||||||
@@ -33,6 +18,21 @@ function getStringFromWasm0(ptr, len) {
|
|||||||
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const heap = new Array(32).fill(undefined);
|
||||||
|
|
||||||
|
heap.push(undefined, null, true, false);
|
||||||
|
|
||||||
|
let heap_next = heap.length;
|
||||||
|
|
||||||
|
function addHeapObject(obj) {
|
||||||
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
|
const idx = heap_next;
|
||||||
|
heap_next = heap[idx];
|
||||||
|
|
||||||
|
heap[idx] = obj;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
function passArray8ToWasm0(arg, malloc) {
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
@@ -54,24 +54,26 @@ function getArrayU8FromWasm0(ptr, len) {
|
|||||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + 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 {number} level
|
||||||
|
* @param {boolean} interlace
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data, level) {
|
export function optimise(data, width, height, level, interlace) {
|
||||||
try {
|
try {
|
||||||
const retptr = wasm.__wbindgen_export_1.value - 16;
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||||
wasm.__wbindgen_export_1.value = retptr;
|
|
||||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
wasm.optimise(retptr, ptr0, len0, level);
|
wasm.optimise(retptr, ptr0, len0, width, height, level, interlace);
|
||||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||||
wasm.__wbindgen_free(r0, r1 * 1);
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
return v1;
|
return v1;
|
||||||
} finally {
|
} finally {
|
||||||
wasm.__wbindgen_export_1.value += 16;
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,29 +91,66 @@ function takeObject(idx) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {number} num
|
* @param {number} num_threads
|
||||||
* @returns {any}
|
* @returns {Promise<any>}
|
||||||
*/
|
*/
|
||||||
export function worker_initializer(num) {
|
export function initThreadPool(num_threads) {
|
||||||
var ret = wasm.worker_initializer(num);
|
var ret = wasm.initThreadPool(num_threads);
|
||||||
return takeObject(ret);
|
return takeObject(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {number} receiver
|
||||||
*/
|
*/
|
||||||
export function start_main_thread() {
|
export function wbg_rayon_start_worker(receiver) {
|
||||||
wasm.start_main_thread();
|
wasm.wbg_rayon_start_worker(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_worker_thread() {
|
export class wbg_rayon_PoolBuilder {
|
||||||
wasm.start_worker_thread();
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(wbg_rayon_PoolBuilder.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
__destroy_into_raw() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.__destroy_into_raw();
|
||||||
|
wasm.__wbg_wbg_rayon_poolbuilder_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
numThreads() {
|
||||||
|
var ret = wasm.wbg_rayon_poolbuilder_numThreads(this.ptr);
|
||||||
|
return ret >>> 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
receiver() {
|
||||||
|
var ret = wasm.wbg_rayon_poolbuilder_receiver(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
build() {
|
||||||
|
wasm.wbg_rayon_poolbuilder_build(this.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(module, imports, maybe_memory) {
|
async function load(module, imports) {
|
||||||
if (typeof Response === 'function' && module instanceof Response) {
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
memory = imports.wbg.memory = new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
|
||||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
try {
|
try {
|
||||||
return await WebAssembly.instantiateStreaming(module, imports);
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
@@ -130,7 +169,6 @@ async function load(module, imports, maybe_memory) {
|
|||||||
return await WebAssembly.instantiate(bytes, imports);
|
return await WebAssembly.instantiate(bytes, imports);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
memory = imports.wbg.memory = maybe_memory;
|
|
||||||
const instance = await WebAssembly.instantiate(module, imports);
|
const instance = await WebAssembly.instantiate(module, imports);
|
||||||
|
|
||||||
if (instance instanceof WebAssembly.Instance) {
|
if (instance instanceof WebAssembly.Instance) {
|
||||||
@@ -144,10 +182,13 @@ async function load(module, imports, maybe_memory) {
|
|||||||
|
|
||||||
async function init(input, maybe_memory) {
|
async function init(input, maybe_memory) {
|
||||||
if (typeof input === 'undefined') {
|
if (typeof input === 'undefined') {
|
||||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
input = new URL('squoosh_oxipng_bg.wasm', import.meta.url);
|
||||||
}
|
}
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
|
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||||
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_module = function() {
|
imports.wbg.__wbindgen_module = function() {
|
||||||
var ret = init.__wbindgen_wasm_module;
|
var ret = init.__wbindgen_wasm_module;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
@@ -156,19 +197,18 @@ async function init(input, maybe_memory) {
|
|||||||
var ret = wasm.__wbindgen_export_0;
|
var ret = wasm.__wbindgen_export_0;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) {
|
imports.wbg.__wbg_startWorkers_914655bb4d5bb5e1 = function(arg0, arg1, arg2) {
|
||||||
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
var ret = startWorkers(takeObject(arg0), takeObject(arg1), wbg_rayon_PoolBuilder.__wrap(arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
|
||||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||||
input = fetch(input);
|
input = fetch(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { instance, module } = await load(await input, imports, maybe_memory);
|
imports.wbg.memory = maybe_memory || new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
||||||
|
|
||||||
|
const { instance, module } = await load(await input, imports);
|
||||||
|
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
init.__wbindgen_wasm_module = module;
|
init.__wbindgen_wasm_module = module;
|
||||||
|
|||||||
Binary file not shown.
12
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
12
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
@@ -1,10 +1,14 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export function optimise(a: number, b: number, c: number, d: number): void;
|
export function optimise(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
|
||||||
export function worker_initializer(a: number): number;
|
export function __wbg_wbg_rayon_poolbuilder_free(a: number): void;
|
||||||
export function start_main_thread(): void;
|
export function wbg_rayon_poolbuilder_numThreads(a: number): number;
|
||||||
export function start_worker_thread(): void;
|
export function wbg_rayon_poolbuilder_receiver(a: number): number;
|
||||||
|
export function wbg_rayon_poolbuilder_build(a: number): void;
|
||||||
|
export function initThreadPool(a: number): number;
|
||||||
|
export function wbg_rayon_start_worker(a: number): void;
|
||||||
export const __wbindgen_export_0: WebAssembly.Memory;
|
export const __wbindgen_export_0: WebAssembly.Memory;
|
||||||
|
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||||
export function __wbindgen_malloc(a: number): number;
|
export function __wbindgen_malloc(a: number): number;
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
export function __wbindgen_start(): void;
|
export function __wbindgen_start(): void;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# OxiPNG
|
# OxiPNG
|
||||||
|
|
||||||
- Source: <https://github.com/shssoichiro/oxipng>
|
- Source: <https://github.com/shssoichiro/oxipng>
|
||||||
- Version: v3.0.0
|
- Version: v9.0.0
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|||||||
@@ -11,5 +11,7 @@
|
|||||||
],
|
],
|
||||||
"module": "squoosh_oxipng.js",
|
"module": "squoosh_oxipng.js",
|
||||||
"types": "squoosh_oxipng.d.ts",
|
"types": "squoosh_oxipng.d.ts",
|
||||||
"sideEffects": false
|
"sideEffects": [
|
||||||
|
"./snippets/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
11
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
11
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
@@ -1,17 +1,21 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8ClampedArray} data
|
||||||
|
* @param {number} width
|
||||||
|
* @param {number} height
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
|
* @param {boolean} interlace
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data: Uint8Array, level: number): 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 type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
readonly optimise: (a: number, b: number, c: number, d: 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_malloc: (a: number) => number;
|
||||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
}
|
}
|
||||||
@@ -25,4 +29,3 @@ export interface InitOutput {
|
|||||||
* @returns {Promise<InitOutput>}
|
* @returns {Promise<InitOutput>}
|
||||||
*/
|
*/
|
||||||
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user