Compare commits

..

227 Commits

Author SHA1 Message Date
d87eff7645 Adding the Quite OK Image (QOI) Codec (#1384) 2023-10-20 09:28:59 +01:00
f374068fb2 check support and upgrade colors (#1356) 2023-09-29 14:03:28 +01:00
ecc715fe55 Merge pull request #1362 from Frank-Mayer/593
added snack bar inside noscript element
2023-04-12 14:31:49 -07:00
82caed4277 Merge branch 'dev' into 593 2023-04-12 23:13:11 +02:00
a7dff9475d Merge pull request #1348 from aryanpingle/keyboard-a11y
Better Keyboard A11y + Navigation
2023-04-12 09:11:16 -07:00
d168f7a447 Add focus animation to back button 2023-04-12 13:52:36 +05:30
edf9cb755e Add styles to save-import buttons 2023-04-12 13:52:36 +05:30
a7503e69a2 better wording wor error message 2023-04-11 11:17:19 +02:00
5a9733563e more information in the error message 2023-04-11 11:12:04 +02:00
2000e16ba2 Make text-fields match the dark theme 2023-04-08 22:35:55 +05:30
7dbe0a7714 Add focus effects to inputs
Provides better keyboard accessibility for:
* Checkboxes
* Range Inputs
* Copy-over Buttons
* Option-reveal Elements
Along with some minor design improvements
2023-04-08 22:35:55 +05:30
25bc43e409 added snack bar inside noscript element 2023-04-08 18:27:29 +02:00
cee51bf355 Merge pull request #1359 from harsh26shah03/save-and-import-side-settings
Feat : Save and import side settings
2023-04-04 15:41:45 -07:00
8d6daf0fc4 Merge branch 'dev' into save-and-import-side-settings 2023-04-04 15:39:09 -07:00
61209d0b62 Merge pull request #1358 from harsh26shah03/file-size-update-sample-data
Fix : Sample File Size Unit
2023-04-04 15:38:10 -07:00
d0b4855022 Merge branch 'dev' into file-size-update-sample-data 2023-04-04 15:36:38 -07:00
6cb64a59ca Merge pull request #1355 from harsh26shah03/sample-image-data-styles
Feat : added hover animation to sample data
2023-04-04 15:32:50 -07:00
979fba0af1 Feat : Save and import side settings
There were requests from multiple users that
they use squoosh for compression but for each
iteration side settings resets to default
causing issues and there is no way to save and
import side settings.

There will be two buttons adjacent to copy-over

save side settings : This will save side encoder
and latest settings to localstorage of browser

import side settings : This will import side encoder
and latest settings from localstorage of browser and
replace the existing settings

Also if there are saved settings in locaStorage then
whenever user loads the app it will take that settings
and populate the side so user do not have to repeatedly
enter same settings for similar compression operation
subject to user has saved side settings

Update:1

Import settings button remains disabled if there
is nothing to import

Whenever the side setting is saved there will be
event fired and eventually listened to enable import
button

All 2 operations show notifications now

Import notification has undo option

Update : 2

Changed Icon SVGs
2023-04-04 22:35:09 +05:30
b1df3e1d54 Feat : Save and import side settings
There were requests from multiple users that
they use squoosh for compression but for each
iteration side settings resets to default
causing issues and there is no way to save and
import side settings.

There will be two buttons adjacent to copy-over

save side settings : This will save side encoder
and latest settings to localstorage of browser

import side settings : This will import side encoder
and latest settings from localstorage of browser and
replace the existing settings

Also if there are saved settings in locaStorage then
whenever user loads the app it will take that settings
and populate the side so user do not have to repeatedly
enter same settings for similar compression operation
subject to user has saved side settings

Update:1

Import settings button remains disabled if there
is nothing to import

Whenever the side setting is saved there will be
event fired and eventually listened to enable import
button

All 2 operations show notifications now

Import notification has undo option
2023-04-04 15:20:06 +05:30
4f6138d97d Fix : Sample File Size Unit
Sample data had size label showing wrong memory units

13k instead of 13KB
2.8mb instead of 2.8MB

small b corresponds to bits and this would change entire
meaning of file so fixed it
2023-04-04 11:39:57 +05:30
6b6e3724d2 Undoing this as separate PR is raised 2023-04-04 11:34:40 +05:30
8ac5e6f678 Merge branch 'GoogleChromeLabs:dev' into sample-image-data-styles 2023-04-04 11:30:38 +05:30
a930e8d928 Merge pull request #1353 from harsh26shah03/filename-in-result-dropdowns
Feat : Original image name (file name)
2023-04-03 09:08:57 -07:00
c814700cd2 Feat : changed unit of sample data and added hover animation 2023-04-03 15:00:19 +05:30
dfdf2a7f71 Feat : Original image name (file name)
Inside Compress tab Original image string
will be appended by file name.

In mobile view due to space constrain there
will be only <file name>
2023-04-02 23:11:17 +05:30
cd336909fc Update libavif (v0.12-main) and AOM (3.6) for improved compression and speed (#1334)
* Update libavif and AOM (3.6) for improved compression and speed

* Minor fixes to package-lock done by NPM, also trigger new build

* Update AVIF version

---------

Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
2023-03-10 10:24:15 +00:00
a8bc48f94c Rotate copy-over-buttons correctly (#1335) 2023-03-02 11:42:52 +00:00
583117697e Ensure browser supports workers-in-workers (#1325)
Fixes #1324
2023-01-09 10:42:14 +00:00
13a185def2 Remove CLI / libsquoosh (#1321)
Unfortunately, due to a few people leaving the team, and staffing issues resulting from the current economic climate (ugh), I'm deprecating the CLI and libsquoosh parts of Squoosh. The web app will continue to be supported and improved. I know that sucks, but there simply isn't the time & people to work on this. If anyone from the community wants to fork it, you have my blessing.
2023-01-03 14:44:54 +00:00
918c596cba Add no-longer-maintained message to cli and libsquoosh 2023-01-03 13:55:36 +00:00
42594277fd Remove web codecs usage
It was decoding transparency incorrectly (multiplication wrong?), and I'd rather not have a different code path there for the sake of it
2022-12-15 14:56:51 +00:00
97d13de273 Add desktop screenshots to web app manifest (#1283)
Co-authored-by: jakearchibald <jaffathecake@gmail.com>
2022-09-18 03:22:10 +01:00
a1c3304c56 Fix issue with Chrome 105 and flexbox. Fixes #1281
https://bugs.chromium.org/p/chromium/issues/detail?id=1358807
2022-09-01 08:50:43 +01:00
7a2fc917c1 Remove margin in Safari between buttons in button group (#1275) 2022-08-18 12:45:10 +01:00
1c4233b5ae Add uniform spacing vertically and horizontally (#1277) 2022-08-18 12:44:11 +01:00
4d67ec5a7b Fix misplaced border (#1273) 2022-08-15 08:38:36 +01:00
c24505230d Bump version due to breaking changes 2022-02-18 15:36:31 +00:00
2238d1abaf Update version 2022-02-16 16:23:33 +00:00
65ea02627b Expose Typescript types in libSquoosh (#1142)
* Expose type declarations in libSquoosh npm package

* Add comment on why we remove the tsbuildinfo

* Fix PreprocessOptions type

Resize should require at least one of the width, height.
The other options are optional for all preprocessors

* Update libSquoosh README to reflect encode changes

I also removed requiring `await image.decoded` call before calling
preprocess or encode since they decode the image before the operation
2022-02-16 16:19:42 +00:00
18b53e2b8a JPEG XL: Add lossy Modular option (#1136)
* Improve .gitattributes

* Add disabled checkbox style

* Update Makefile

* Update jxl_enc.cpp

* add -O3 flag to skia compilation for optimization's sake

* Bump libjxl revision to 9f544641ec83f6abd9da598bdd08178ee8a003e0

Change use of EncodeFile from `EncodeFile(cparams, &io, &passes_enc_state, &bytes, /*aux=*/nullptr, pool_ptr)` to `EncodeFile(cparams, &io, &passes_enc_state, &bytes, /*cms=*/nullptr, /*aux=*/jxl::GetJxlCms(), pool_ptr)`

* JPEG XL: Add lossy Modular option

Co-authored-by: CanadianBaconBoi <beamconnor@gmail.com>
Co-authored-by: CanadianBaconBoi <bc.bacon.bits@gmail.com>
2022-01-21 12:42:27 +00:00
66ec763667 Merge pull request #1171 from TimvdLippe/fix-webassembly-instantiate 2021-10-20 15:42:50 +01:00
029eda7b37 Merge branch 'dev' into fix-webassembly-instantiate 2021-10-20 15:36:48 +01:00
e6810059ef Add warning for using multiple image pools
Instantiating and using multiple image pools is not intended and can
lead to memory problems. Instead, users should use a single pool and
reuse that pool across all image processing. Therefore, let's add
a warning in the README to specify call this out and avoid users
of running into issues.

Relates to #1065
2021-10-20 14:56:34 +01:00
4eba015009 Merge pull request #1165 from TimvdLippe/update-typescript 2021-10-20 13:25:54 +01:00
dd49a1f23d Merge branch 'dev' into update-typescript 2021-10-20 13:15:39 +01:00
5ecb99992c Merge pull request #1169 from TimvdLippe/update-prettier 2021-10-20 13:15:32 +01:00
d9c6ebe0a2 Merge branch 'dev' into update-prettier 2021-10-20 12:48:59 +01:00
fba67a7a18 Merge pull request #1170 from TimvdLippe/fix-husky 2021-10-20 12:47:01 +01:00
129b925098 Fix Husky pre-commit
By upgrading to version 7, we now ensure that NPM/Yarn will run
the `prepare` script and appropriately install Husky. This also
migrates us to the `pre-commit` hook as a separate file, rather
than as part of the `package.json` definition.
2021-10-20 12:44:12 +01:00
e23bc4d2e5 Update Prettier
Also manually run prettier on `src/` and `lib/` to ensure
consistent formatting.
2021-10-20 12:28:45 +01:00
f523a07f01 Update TypeScript and types packages
This pulls in TypeScript 4.4, which ships ResizeObserver in the DOM
types, as well as sets caught errors to `unknown`, requiring explicit
checks for `AbortError`.
2021-10-20 11:36:27 +01:00
e3f840c6da Added Apple touch Icon for PWA (#1160) 2021-10-15 11:52:13 +01:00
cad09160b6 Reducing browser spinner time (#1157) 2021-09-20 13:49:53 +01:00
9663c23489 Merge pull request #1151 from ergunsh/improve-encode-types
Improve `encode` API and its types
2021-09-17 13:50:29 +01:00
95a1b35c91 Update encodedWith to contain resolved values
We already await the promises that we set on the `encodedWith` instead of setting already
resolved promises to `encodedWith` we can set the resolved values

So, the users can use like
`const { mozjpeg: { binary } } = await image.encode({ mozjpeg })` or
they can first run
`await image.encode({ mozjpeg })` and then
`image.encodedWith.mozjpeg.binary`
2021-09-10 15:18:14 +02:00
914cdea41d Return encode result from Image.encode calls
Before this, there were one way to use the API:
call `await image.encode({ mozjpeg: {} })`
then use `encodedWith` by asserting that `mozjpeg` property exists on it

After adding return value to encode, people
will be able to use it like
`const { mozjpeg } = await image.encode({ mozjpeg: {} });`
which provides better type safety
2021-09-10 14:45:20 +02:00
6bfce29af6 Improve typing of Image.encode
Instead of returning `any` we're now returning the whole object.

Still from typing perspective, the API is not that
great since we don't have any type relation
between `encode` calls and `encodedWith` property. Maybe we can think about
returning directly from `encode` call
with the returned object having properties
that is supplied in `encode` calls
2021-09-10 14:08:21 +02:00
64cad1cc23 Merge pull request #1123 from styfle/load-file-async
Reduce `@squoosh/lib` Node.js API usage (make it run on the web)
2021-09-08 22:30:53 +01:00
87f25d909b Merge branch 'dev' into load-file-async 2021-09-08 17:04:50 -04:00
bdfdaf53af Remove unused readme link per atjn
Co-authored-by: Anton <dev@atjn.dk>
2021-09-08 17:04:46 -04:00
1ab9e8b3ab Merge pull request #1141 from ergunsh/improve-exposed-types 2021-09-08 17:57:46 +01:00
2718077d3d Merge branch 'dev' into improve-exposed-types 2021-09-08 19:48:01 +03:00
255dfa434a Update pointer-tracker (#1147) 2021-09-07 14:43:19 +01:00
0bef05bcd4 Remove origin trial header 2021-09-06 15:00:48 +01:00
c4bc369c6b Fix typo in triangle 2021-09-03 15:03:28 +03:00
68ce8f420d Improve encode parameter typing 2021-09-03 14:54:08 +03:00
27f103fee5 Improve preprocess parameter type 2021-09-03 11:53:52 +03:00
c21d3714a8 Fix link in readme 2021-09-02 16:38:22 -04:00
3ea0d88c4f Apply suggestions from atjn
Co-authored-by: Anton <dev@atjn.dk>
2021-09-02 16:36:37 -04:00
00cfdafdf3 Merge pull request #1138 from jcao219/fix-windows-path
Use pathify to calculate absolute paths for cross-platform compatibility
2021-08-31 13:34:28 +01:00
92f52319da Use pathify to calculate absolute paths for cross-platform compatibility 2021-08-31 00:18:21 -07:00
023304803f JPEG-XL: Better 'effort' and adding noise synth (#1039) 2021-08-27 14:18:54 +01:00
6b08cd2355 Aliasing toggle button (#1132) 2021-08-26 16:44:20 +01:00
db1a5138e6 Fix pinch zoom on iOS (#1133) 2021-08-26 15:59:42 +01:00
a547491146 Maintain DC_SCAN_OPT_MODE if subsampling is > 2. Fixes #1129 (#1130) 2021-08-26 14:29:13 +01:00
6e427f9208 The observer is null if user prefers reduced motion
Turns out TypeScript is there for a reason and shouldn't be bypassed. Fixes #1135
2021-08-25 14:10:57 +01:00
0d35fbd349 Fix horizontal scroll on option elements on mobile (#1134) 2021-08-25 09:25:09 +01:00
4e901c714c [RFC] Add Three Homepage Sections (#1112) 2021-08-25 09:08:22 +01:00
b74788e036 Stable mousewheel scrolling, one wheel up + one wheel down = no change (#1131) 2021-08-24 14:52:25 +01:00
14c3d190e9 Max cap on scale #905 (#1128) 2021-08-23 13:27:17 +01:00
202d0bc088 Generalize file to ArrayLike<number> 2021-08-20 18:48:30 -04:00
bdb5b16372 Remove Buffer from decodeFile() 2021-08-20 18:36:23 -04:00
30140c2b7a Fix CLI bug 2021-08-20 18:35:29 -04:00
10996cdbca Add missing import 2021-08-20 16:08:01 -04:00
e5806507d4 Remove Node.js API surface in libsquoosh 2021-08-20 15:11:14 -04:00
1c5b44f9a1 Add loadFile parameter to ImagePool 2021-08-16 16:51:23 -04:00
eeaa19589e Merge pull request #1120 from veluca93/jxl_05
Bump JPEG XL to v0.5.
2021-08-14 09:23:04 +01:00
35b8c56f1a Bump JPEG XL to v0.5. 2021-08-13 23:27:44 +02:00
816d1f92fd Merge pull request #1110 from styfle/libsquoosh-ts-remaining 2021-08-10 12:38:11 +01:00
4091f2efec Remove unused export 2021-08-06 13:20:14 -04:00
821d14c6ab Merge branch 'dev' into libsquoosh-ts-remaining 2021-08-06 13:02:46 -04:00
a72ca46531 Move as to input param instead of return type 2021-08-06 12:49:17 -04:00
fafcf97f0c Update code for the review comments
* Make decode module return value `ImageData`
* Fix global definition of ImageData
* Use concrete Encoder types for encode functions
* Use ArrayBufferView in FileLike instead of using a similar type
* Throw error when the `encode` functions
return null
* Use generic types for WorkerPool
* Fix `encode` function typing
in `index.ts`
* Remove ts-ignore for web-streams-polyfill
and handle nulls for TransformStream
* Fix rollup entry point (now we need to have
`index.ts` instead of `index.js`)
2021-08-06 16:05:14 +03:00
d526877147 Merge pull request #1099 from mikedelgaudio/add-meta-info 2021-07-27 11:48:04 +01:00
0ed7ef842f Include site origin in build 2021-07-27 11:30:58 +01:00
de4eb9c8f7 Add encode() and decode() types 2021-07-26 23:22:28 -04:00
16a53caa48 Convert remaining JS to TS in libSquoosh 2021-07-26 22:37:00 -04:00
3d4c62fede Merge branch 'dev' into add-meta-info 2021-07-26 12:23:06 -04:00
ce7be359c0 remove keywords
Co-authored-by: Anton <dev@atjn.dk>
2021-07-26 12:23:00 -04:00
3f2dd66726 Merge pull request #1030 from veluca93/jxl_github 2021-07-23 13:49:46 +01:00
9198f748b8 Merge branch 'dev' into jxl_github 2021-07-23 13:37:37 +01:00
a726adf0e8 Merge pull request #1107 from styfle/patch-1
Fix typo uncluding => including
2021-07-23 13:15:21 +01:00
04580b0bcb Fix typo uncluding => including 2021-07-22 13:48:19 -04:00
a040c47047 Update JPEG XL to latest version.
Also update repositories.
2021-07-21 18:55:52 +02:00
2427763a14 Squoosh CLI v0.7.2 2021-07-21 17:19:19 +01:00
c582c54922 libsquoosh v0.4.0 2021-07-21 17:15:59 +01:00
9ae27c1887 Merge pull request #1106 from GoogleChromeLabs/issue-1102 2021-07-21 17:03:21 +01:00
bf95eb39c2 Fix handling of PNGs that are not 8 bit 2021-07-21 16:16:44 +01:00
011c0346c1 Merge pull request #1100 from MaxGraey/opt-visdif-codec 2021-07-20 19:17:23 +01:00
9b36c3f9af Merge remote-tracking branch 'origin/dev' into opt-visdif-codec 2021-07-20 19:14:54 +01:00
490fe2aace Add build instructions 2021-07-20 19:14:23 +01:00
48efb4ddeb remove twitter image 2021-07-20 10:55:47 -04:00
0977bd94d3 Merge pull request #1074 from GoogleChromeLabs/avif-node-mt 2021-07-20 12:01:47 +01:00
d5f12a8c61 Merge remote-tracking branch 'origin/dev' into avif-node-mt 2021-07-20 11:51:10 +01:00
fb867dcdaa Review by rreverser 2021-07-20 11:50:48 +01:00
f038c1bd7d Update src/static-build/pages/index/index.tsx 2021-07-20 11:26:19 +01:00
b37cc0784f typo fix for secure 2021-07-19 20:31:58 -04:00
ff40000473 adding secure 2021-07-19 20:28:23 -04:00
7232524f4d add twitter 2021-07-19 20:20:03 -04:00
bf683cdf59 Merge pull request #1093 from mikedelgaudio/update-readme
[DOCS] Update README, Remove Passive Voice
2021-07-19 17:27:54 +01:00
f848a9384e Merge branch 'dev' into update-readme 2021-07-19 11:48:13 -04:00
d4d0db6c49 update header statement 2021-07-19 11:47:52 -04:00
0719abff27 Merge pull request #1081 from atjn/unused-code
Remove unused variable
2021-07-19 12:42:01 +01:00
2c561687af Merge branch 'dev' into unused-code 2021-07-19 12:39:51 +01:00
cd20082e5d Build wasm 2021-07-19 12:36:43 +01:00
8262c79bb6 fix 2021-07-13 22:38:30 +03:00
ef176d7565 optimize more 2021-07-13 22:38:10 +03:00
3b0b7dbdb1 fix 2021-07-13 19:00:26 +03:00
cc9a887386 optimize srgb -> linear preparation by using lookup table 2021-07-13 18:33:15 +03:00
71ca1ab0ca Update src/static-build/pages/index/index.tsx
Co-authored-by: Joan León <joan.leon@gmail.com>
2021-07-12 14:40:37 -04:00
f5d9535fd2 adding meta tags for better SEO 2021-07-12 11:13:51 -04:00
cea6a61366 Modify meta data 2021-07-09 15:53:18 -04:00
192cfc62ee Update README.md 2021-07-07 09:57:44 -04:00
fe21322b2b [DOCS] Update list of develop steps 2021-07-06 14:34:04 -04:00
d953822d19 [DOCS] Remove passive voice, simplify README 2021-07-05 22:37:04 -04:00
021b082884 [DOCS] Remove passive voice, simplify README 2021-07-05 22:24:20 -04:00
ad5002c79c Merge pull request #1078 from ergunsh/auto-optimizer-to-ts
Typescriptify auto optimizer in libSquoosh
2021-07-01 15:53:06 +01:00
883bb92e48 Merge branch 'dev' into auto-optimizer-to-ts 2021-07-01 15:45:38 +01:00
79efd0d32e Merge pull request #1080 from pekeq/doc-resize-with-aspect
libsquoosh/README: Add code example to resize with aspect ratio preserved.
2021-07-01 15:45:32 +01:00
99741d665d Merge branch 'dev' into auto-optimizer-to-ts 2021-07-01 15:22:23 +01:00
b38765b4e6 Merge branch 'dev' into doc-resize-with-aspect 2021-07-01 15:22:13 +01:00
a11ac15008 fix: Don't overwrite value while typing (#1082)
Fixes #316
2021-07-01 11:11:00 +01:00
4f6d21199c Remove unused variable 2021-07-01 00:08:58 +02:00
fb7e00067f Update libsquoosh/README.md code example
Add code example to resize with aspect ratio preserved.
2021-06-30 22:43:20 +09:00
a2121ec47b Typescriptify auto optimizer in libSquoosh 2021-06-27 22:27:43 +02:00
d4056026fb Add AVIF thread support 2021-06-25 00:11:25 +01:00
d12b040bd3 Add threaded AVIF encoder for node 2021-06-24 17:07:57 +01:00
149ebf5a67 Merge pull request #1073 from atjn/patch-1
Fix codecs link
2021-06-24 16:35:31 +01:00
d8297aad10 Fix codecs link 2021-06-24 17:03:17 +02:00
0e84a5b5f7 Merge pull request #1071 from simon04/patch-1 2021-06-24 10:56:26 +01:00
187a5bed01 cli/README: linkfix src/codecs.ts 2021-06-24 09:34:09 +02:00
07a288398e Spotted another leak (#1069) 2021-06-23 10:39:27 +01:00
dbb31a1add Merge remote-tracking branch 'origin/dev' into dev 2021-06-21 12:58:41 +01:00
6e58e8edb0 Merge pull request #1061 from atjn/engines
Specify supported node versions
2021-06-21 12:58:28 +01:00
955079b18f Merge branch 'dev' into engines 2021-06-21 12:53:32 +01:00
f6f70c590e Add repo info in package.json so that people can backtrack from npm site (#1066) 2021-06-21 11:59:21 +01:00
55c4aa51ac Merge pull request #1063 from SimonGolms/patch-1
fix(cli): append suffix option at the end
2021-06-19 14:25:55 +01:00
aea316c604 fix(cli): append suffix option at the end
- close #1062
2021-06-19 11:40:52 +02:00
d604e94ad2 Specify supported node versions 2021-06-18 21:18:37 +02:00
61de471e52 Merge pull request #1058 from atjn/fix-detectors
Fix WebP sniffing some more
2021-06-18 15:58:03 +01:00
955b2ac1ba Fix WebP sniffing some more 2021-06-18 15:51:20 +02:00
3d225966c5 CLI v0.7.1 2021-06-16 17:13:59 +01:00
851da25302 Update CLI dependency 2021-06-16 17:13:37 +01:00
32e3528666 libsquoosh v0.3.1 2021-06-16 17:11:15 +01:00
1e52837931 Oooops. Old files 2021-06-16 17:02:54 +01:00
5bc80e66ec Merge remote-tracking branch 'origin/dev' into visdif-error 2021-06-16 13:54:49 +01:00
b1f50cd27c Fix AVIF auto optimizer options 2021-06-16 13:54:17 +01:00
3d136016e2 Provide optimizer default value 2021-06-16 13:44:24 +01:00
14a715e952 Add test files for now 2021-06-16 12:56:37 +01:00
324b04d398 Merge pull request #1044 from ergunsh/libsquoosh-codecs-to-ts
Typescriptify libsquoosh's codecs.js and emscripten-utils.js
2021-06-16 11:47:21 +01:00
eb76fbc4bc Merge branch 'dev' into libsquoosh-codecs-to-ts 2021-06-16 11:43:35 +01:00
1d292468b0 Everything supports ResizeObserver now 2021-06-16 10:13:46 +01:00
828f9a5eeb Fix memory leaks (#1054) 2021-06-15 10:45:53 +01:00
5595525c8a Merge pull request #1053 from alex-drocks/patch-1
Update README.md @libSquoosh code example
2021-06-11 16:25:23 +01:00
5e14444b13 Update README.md
To close typo in example code as reported in issue #1051
2021-06-11 09:36:30 -04:00
3d58c616af Merge branch 'dev' into libsquoosh-codecs-to-ts 2021-06-10 18:31:02 +02:00
d7090042a6 Fix alignment issue 2021-06-10 12:25:58 -04:00
be3249bf2f Add test case 2021-06-10 11:31:59 -04:00
1b59c3f47a Keep js extension while importing module & types 2021-06-09 18:11:30 +02:00
9a37cc7959 Merge pull request #1042 from GoogleChromeLabs/issue-1022 2021-06-09 12:17:00 +01:00
ffb9135a7a Merge remote-tracking branch 'origin/dev' into issue-1022 2021-06-09 06:35:00 -04:00
5707eeff41 Return Uint8ClampedArray in resize operation 2021-06-08 20:28:22 +02:00
a18ed360eb Address review comments
* Updated import to contain file extension `js`
* Separated WebAssembly definitions from missing-types
* Converted resizer.resize result to Uint8ClampedArray
* Moved ResizeInstantiateOptions to an interface
2021-06-08 20:09:37 +02:00
011d0c2099 Update AVIF 2021-06-08 16:51:08 +01:00
89105bbb22 Update wp2 2021-06-08 11:07:32 -04:00
5f7c619413 Update webp 2021-06-08 11:02:43 -04:00
3ec7d4db16 Update visdif 2021-06-08 10:59:47 -04:00
8ef8cef522 Update MozJPEG 2021-06-08 10:58:10 -04:00
f6431d8147 Update JXL 2021-06-08 10:54:16 -04:00
be037754ce Update imagequant 2021-06-08 10:43:33 -04:00
32107124e6 Update Emscripten version 2021-06-08 10:43:11 -04:00
1af5d1fa7b Typescriptify libsquoosh's codecs and emscripten-utils 2021-06-04 19:12:31 +02:00
08adfba8be Merge pull request #1037 from ergunsh/libsquoosh-ts-setup
Add initial ts setup for libsquoosh
2021-06-04 15:46:23 +01:00
5df04f6419 Update wp2 2021-06-04 09:51:10 -04:00
cf570a4d3f Update webp 2021-06-04 09:29:16 -04:00
2aa691339c Update visdif 2021-06-04 09:25:57 -04:00
9fcb4a4c55 Update mozjpeg 2021-06-04 09:23:23 -04:00
18e3d77aef Update jxl 2021-06-04 09:18:27 -04:00
6a4982bf4c Update imagequant 2021-06-04 08:52:46 -04:00
c7b998a877 Add flags 2021-06-04 08:33:57 -04:00
e5b2030666 Merge branch 'dev' into libsquoosh-ts-setup 2021-06-03 18:54:36 +02:00
0e09d0b33f Remove unnecessary missing-typed.d.ts for now
We don't need it for ImageData module
2021-06-03 18:50:44 +02:00
ed03a37fb8 Merge pull request #1041 from alexander-akait/issue-1034
fix: `main` filed
2021-06-03 11:18:41 +01:00
2bc4ab8fd6 fix: main filed 2021-06-03 12:36:49 +03:00
2037fe8964 Add an error for unsupported usage of new URL 2021-06-02 17:03:14 +01:00
d07c57ecaa Update lib/client-bundle-plugin.js 2021-06-02 17:03:14 +01:00
e7d55bf903 Update lib/entry-data-plugin.js
Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
2021-06-02 17:03:14 +01:00
687cf5aae2 Bundle URL assets as dependencies
I've added support for `new URL(..., import.meta.url)` pattern accepted by many bundlers to wasm-bindgen and Emscripten, both for Wasm files as well as for side Workers autogenerated to support multithreading.

On the apps side like Squoosh this means we no longer have to manually specify URLs to be passed to wasm-bindgen or Emscripten init functions. In this PR I'm primarily doing just that - removing all the manual Wasm URL locators, as well as the associated logic.

One notable change on the build system side is that, in order for Wasm and multithreading-related Workers to be detected as dependencies, I'm now walking over `referencedFiles` in addition to `imports` when collecting list of dependencies in `getDependencies` function (client-bundle-plugin.js).

As a side effect, it also included other linked assets - images and CSS - which simplified quite a few caching lists in to-cache.ts as well. Instead of having to manually specify each asset that needs to be included, the logic is inverted and only few extra assets had to be excluded to keep the list of in items cached on the first load as low as it was before the change.

All in all, I think this simplification is worth it and even helped to accidentally uncover & fix one caching bug where WP2 regular JS was cached in addition to WP2 multithreaded JS simultaneously.
2021-06-02 17:03:14 +01:00
d63823d196 Add @web/rollup-plugin-import-meta-assets 2021-06-02 17:03:14 +01:00
7d111b6a43 Update wasm-bindgen 2021-06-02 17:03:14 +01:00
426f31e548 Upgrade Emscripten to 2.0.21
Few notes:
 - Lots of deprecated SIMD intrinsic warnings & errors in JPEG-XL -> Highway; had to suppress erorrs to make project build.
 - Moved couple of common link flags to cpp.Dockerfile (note: can't move `EXPORT_ES6` otherwise `configure` will fail).
 - MODULARIZE=1 is no longer necessary and implied by EXPORT_ES6.
 - EXPORT_NAME=... is no longer necessary in EXPORT_ES6.
 - Changed visdif to also use EXPORT_ES6 and ENVIRONMENT=node instead of generic JS.
2021-06-02 17:03:14 +01:00
dd0adba6b1 Revert "Remove SIMD for now (#1025)"
This reverts commit f779e13bc8.
2021-06-02 17:03:14 +01:00
30445927ea Add initial ts setup for libsquoosh
Convert `image_data` to typescript as an example
2021-05-31 21:45:28 +02:00
31b263fc27 Merge pull request #1035 from JustTestCode/patch-1
Update README.md
2021-05-30 10:06:01 +01:00
fc590918ed Update README.md
I check 2 hours, why can't run...
2021-05-30 12:16:58 +08:00
c4783b03df Merge pull request #1031 from GoogleChromeLabs/defensive-web-codec 2021-05-27 10:30:38 +01:00
8f9c0ff0e7 More defensive use of isTypeSupported 2021-05-27 09:14:13 +01:00
40c81ef782 Remove circular dependency 2021-05-27 09:13:17 +01:00
397193a5f5 <title> to indicate progress/error (#1023)
Fixes #644
2021-05-25 14:29:42 +01:00
f91c7a267d libsquoosh v0.2.3 2021-05-25 11:49:54 +01:00
99f2286a73 Better error handling for libSquoosh 2021-05-25 11:46:30 +01:00
f414092ea9 libsquoosh v0.2.2 2021-05-24 23:58:15 +01:00
c683dfaaed Merge branch 'libsquoosh-kinks' into dev 2021-05-24 23:57:33 +01:00
12fb647fde Fix JXL in libsquoosh 2021-05-24 23:57:24 +01:00
2ee1dfa867 Fix AVIF in libsquoosh 2021-05-24 23:54:26 +01:00
fa331586d7 Handle more input types gracefully 2021-05-24 17:56:53 +01:00
4192c607f1 Merge pull request #1018 from GoogleChromeLabs/web-codecs
Add a call-out to Web Codecs API during decoding
2021-05-24 17:08:54 +01:00
223 changed files with 10855 additions and 6689 deletions

4
.gitattributes vendored
View File

@ -1,2 +1,2 @@
/codecs/**/*.js linguist-generated=true
/codecs/*/pkg*/*.d.ts linguist-generated=true
/codecs/**/*.js linguist-generated -diff
/codecs/*/pkg*/*.d.ts linguist-generated

1
.husky/pre-commit Executable file
View File

@ -0,0 +1 @@
npx lint-staged

View File

@ -1,36 +1,38 @@
# [Squoosh]!
[Squoosh] is an image compression web app that allows you to dive into the advanced options provided
by various image compressors.
# API & CLI
Squoosh now has [an API](https://github.com/GoogleChromeLabs/squoosh/tree/dev/libsquoosh) and [a CLI](https://github.com/GoogleChromeLabs/squoosh/tree/dev/cli) that allows you to compress many images at once.
[Squoosh] is an image compression web app that reduces image sizes through numerous formats.
# 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).
- 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.
However, Squoosh utilizes Google Analytics to collect the following:
Image compression is handled locally; no additional data is sent to the server.
- [Basic visitor data](https://support.google.com/analytics/answer/6004245?ref_topic=2919631).
- The before and after image size value.
- If Squoosh PWA, the type of Squoosh installation.
- If Squoosh PWA, the installation time and date.
# Building locally
# Developing
Clone the repo, and:
To develop for Squoosh:
```sh
npm install
npm run build
```
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
```
You can run the development server with:
# Contributing
```sh
npm run dev
```
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

3
cli/.gitignore vendored
View File

@ -1,3 +0,0 @@
node_modules
build
.DS_Store

View File

@ -1 +0,0 @@
node_modules

View File

View File

@ -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 doesnt 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/libsquoosh/src/codecs.js
[butteraugli]: https://github.com/google/butteraugli

595
cli/package-lock.json generated
View File

@ -1,595 +0,0 @@
{
"name": "@squoosh/cli",
"version": "0.7.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@squoosh/cli",
"version": "0.7.0",
"license": "Apache-2.0",
"dependencies": {
"@squoosh/lib": "^0.2.0",
"commander": "^7.2.0",
"json5": "^2.2.0",
"kleur": "^4.1.4",
"ora": "^5.4.0"
},
"bin": {
"cli": "src/index.js",
"squoosh-cli": "src/index.js"
}
},
"node_modules/@squoosh/lib": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@squoosh/lib/-/lib-0.2.0.tgz",
"integrity": "sha512-zKId9h/LzEnCdoOGnIgjzvqbk5g2aHgfEqgKQ+S+r5K3TasgD/DAsT6r7v6gXft1ao0f/00CTcwIp1KviWTQbw==",
"dependencies": {
"web-streams-polyfill": "^3.0.3"
}
},
"node_modules/ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"dependencies": {
"restore-cursor": "^3.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cli-spinners": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz",
"integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==",
"engines": {
"node": ">=6"
}
},
"node_modules/clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"engines": {
"node": ">=0.8"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"engines": {
"node": ">= 10"
}
},
"node_modules/defaults": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
"dependencies": {
"clone": "^1.0.2"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
"engines": {
"node": ">=8"
}
},
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"engines": {
"node": ">=10"
}
},
"node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/kleur": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
"integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
"engines": {
"node": ">=6"
}
},
"node_modules/log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dependencies": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"engines": {
"node": ">=6"
}
},
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dependencies": {
"mimic-fn": "^2.1.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/ora": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.0.tgz",
"integrity": "sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg==",
"dependencies": {
"bl": "^4.1.0",
"chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
"cli-spinners": "^2.5.0",
"is-interactive": "^1.0.0",
"is-unicode-supported": "^0.1.0",
"log-symbols": "^4.1.0",
"strip-ansi": "^6.0.0",
"wcwidth": "^1.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"node_modules/signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dependencies": {
"ansi-regex": "^5.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
"dependencies": {
"defaults": "^1.0.3"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz",
"integrity": "sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA==",
"engines": {
"node": ">= 8"
}
}
},
"dependencies": {
"@squoosh/lib": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@squoosh/lib/-/lib-0.2.0.tgz",
"integrity": "sha512-zKId9h/LzEnCdoOGnIgjzvqbk5g2aHgfEqgKQ+S+r5K3TasgD/DAsT6r7v6gXft1ao0f/00CTcwIp1KviWTQbw==",
"requires": {
"web-streams-polyfill": "^3.0.3"
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"requires": {
"restore-cursor": "^3.1.0"
}
},
"cli-spinners": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz",
"integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q=="
},
"clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
},
"defaults": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
"requires": {
"clone": "^1.0.2"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="
},
"is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="
},
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"requires": {
"minimist": "^1.2.5"
}
},
"kleur": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
"integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA=="
},
"log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"requires": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
}
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"requires": {
"mimic-fn": "^2.1.0"
}
},
"ora": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.0.tgz",
"integrity": "sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg==",
"requires": {
"bl": "^4.1.0",
"chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
"cli-spinners": "^2.5.0",
"is-interactive": "^1.0.0",
"is-unicode-supported": "^0.1.0",
"log-symbols": "^4.1.0",
"strip-ansi": "^6.0.0",
"wcwidth": "^1.0.1"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"requires": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"requires": {
"ansi-regex": "^5.0.0"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
"requires": {
"defaults": "^1.0.3"
}
},
"web-streams-polyfill": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz",
"integrity": "sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA=="
}
}
}

View File

@ -1,24 +0,0 @@
{
"name": "@squoosh/cli",
"version": "0.7.0",
"description": "A CLI for Squoosh",
"public": true,
"type": "module",
"bin": {
"squoosh-cli": "src/index.js",
"@squoosh/cli": "src/index.js"
},
"files": [
"/src/index.js"
],
"keywords": [],
"author": "Google Chrome Developers <chromium-dev@google.com>",
"license": "Apache-2.0",
"dependencies": {
"@squoosh/lib": "^0.2.0",
"commander": "^7.2.0",
"json5": "^2.2.0",
"kleur": "^4.1.4",
"ora": "^5.4.0"
}
}

View File

@ -1,232 +0,0 @@
#!/usr/bin/env node
import { program } from 'commander/esm.mjs';
import JSON5 from 'json5';
import path from 'path';
import { promises as fsp } from 'fs';
import ora from 'ora';
import kleur from 'kleur';
import { ImagePool, preprocessors, encoders } from '@squoosh/lib';
function clamp(v, min, max) {
if (v < min) return min;
if (v > max) return max;
return v;
}
const suffix = ['B', 'KB', 'MB'];
function prettyPrintSize(size) {
const base = Math.floor(Math.log2(size) / 10);
const index = clamp(base, 0, 2);
return (size / 2 ** (10 * index)).toFixed(2) + suffix[index];
}
function progressTracker(results) {
const spinner = ora();
const tracker = {};
tracker.spinner = spinner;
tracker.progressOffset = 0;
tracker.totalOffset = 0;
let status = '';
tracker.setStatus = (text) => {
status = text || '';
update();
};
let progress = '';
tracker.setProgress = (done, total) => {
spinner.prefixText = kleur.dim(`${done}/${total}`);
const completeness =
(tracker.progressOffset + done) / (tracker.totalOffset + total);
progress = kleur.cyan(
`${'▨'.repeat((completeness * 10) | 0).padEnd(10, '╌')}`,
);
update();
};
function update() {
spinner.text = progress + kleur.bold(status) + getResultsText();
}
tracker.finish = (text) => {
spinner.succeed(kleur.bold(text) + getResultsText());
};
function getResultsText() {
let out = '';
for (const result of results.values()) {
out += `\n ${kleur.cyan(result.file)}: ${prettyPrintSize(result.size)}`;
for (const { outputFile, size: outputSize, infoText } of result.outputs) {
out += `\n ${kleur.dim('└')} ${kleur.cyan(
outputFile.padEnd(5),
)}${prettyPrintSize(outputSize)}`;
const percent = ((outputSize / result.size) * 100).toPrecision(3);
out += ` (${kleur[outputSize > result.size ? 'red' : 'green'](
percent + '%',
)})`;
if (infoText) out += kleur.yellow(infoText);
}
}
return out || '\n';
}
spinner.start();
return tracker;
}
async function getInputFiles(paths) {
const validFiles = [];
for (const inputPath of paths) {
const files = (await fsp.lstat(inputPath)).isDirectory()
? (await fsp.readdir(inputPath, {withFileTypes: true})).filter(dirent => dirent.isFile()).map(dirent => path.join(inputPath, dirent.name))
: [inputPath];
for (const file of files) {
try {
await fsp.stat(file);
} catch (err) {
if (err.code === 'ENOENT') {
console.warn(
`Warning: Input file does not exist: ${path.resolve(file)}`,
);
continue;
} else {
throw err;
}
}
validFiles.push(file);
}
}
return validFiles;
}
async function processFiles(files) {
files = await getInputFiles(files);
const imagePool = new ImagePool();
const results = new Map();
const progress = progressTracker(results);
progress.setStatus('Decoding...');
progress.totalOffset = files.length;
progress.setProgress(0, files.length);
// Create output directory
await fsp.mkdir(program.opts().outputDir, { recursive: true });
let decoded = 0;
let decodedFiles = await Promise.all(
files.map(async (file) => {
const image = imagePool.ingestImage(file);
await image.decoded;
results.set(image, {
file,
size: (await image.decoded).size,
outputs: [],
});
progress.setProgress(++decoded, files.length);
return image;
}),
);
const preprocessOptions = {};
for (const preprocessorName of Object.keys(preprocessors)) {
if (!program.opts()[preprocessorName]) {
continue;
}
preprocessOptions[preprocessorName] = JSON5.parse(
program.opts()[preprocessorName],
);
}
for (const image of decodedFiles) {
image.preprocess(preprocessOptions);
}
await Promise.all(decodedFiles.map((image) => image.decoded));
progress.progressOffset = decoded;
progress.setStatus(
'Encoding ' + kleur.dim(`(${imagePool.workerPool.numWorkers} threads)`),
);
progress.setProgress(0, files.length);
const jobs = [];
let jobsStarted = 0;
let jobsFinished = 0;
for (const image of decodedFiles) {
const originalFile = results.get(image).file;
const encodeOptions = {
optimizerButteraugliTarget: Number(
program.opts().optimizerButteraugliTarget,
),
maxOptimizerRounds: Number(program.opts().maxOptimizerRounds),
};
for (const encName of Object.keys(encoders)) {
if (!program.opts()[encName]) {
continue;
}
const encParam = program.opts()[encName];
const encConfig =
encParam.toLowerCase() === 'auto' ? 'auto' : JSON5.parse(encParam);
encodeOptions[encName] = encConfig;
}
jobsStarted++;
const job = image.encode(encodeOptions).then(async () => {
jobsFinished++;
const outputPath = path.join(
program.opts().outputDir,
program.opts().suffix +
path.basename(originalFile, path.extname(originalFile)),
);
for (const output of Object.values(image.encodedWith)) {
const outputFile = `${outputPath}.${(await output).extension}`;
await fsp.writeFile(outputFile, (await output).binary);
results
.get(image)
.outputs.push(Object.assign(await output, { outputFile }));
}
progress.setProgress(jobsFinished, jobsStarted);
});
jobs.push(job);
}
// update the progress to account for multi-format
progress.setProgress(jobsFinished, jobsStarted);
// Wait for all jobs to finish
await Promise.all(jobs);
await imagePool.close();
progress.finish('Squoosh results:');
}
program
.name('squoosh-cli')
.arguments('<files...>')
.option('-d, --output-dir <dir>', 'Output directory', '.')
.option('-s, --suffix <suffix>', 'Append suffix to output files', '')
.option(
'--max-optimizer-rounds <rounds>',
'Maximum number of compressions to use for auto optimizations',
'6',
)
.option(
'--optimizer-butteraugli-target <butteraugli distance>',
'Target Butteraugli distance for auto optimizer',
'1.4',
)
.action(processFiles);
// Create a CLI option for each supported preprocessor
for (const [key, value] of Object.entries(preprocessors)) {
program.option(`--${key} [config]`, value.description);
}
// Create a CLI option for each supported encoder
for (const [key, value] of Object.entries(encoders)) {
program.option(
`--${key} [config]`,
`Use ${value.name} to generate a .${value.extension} file with the given configuration`,
);
}
program.parse(process.argv);

View File

@ -14,6 +14,7 @@
// for comlink
"src/features/**/worker/**/*",
"src/features-worker/**/*",
"src/features/worker-utils/**/*"
"src/features/worker-utils/**/*",
"src/worker-shared/**/*"
]
}

View File

@ -1,22 +1,25 @@
# libavif and libaom versions are from
# https://docs.google.com/document/d/1wEEA5rRU7wT54k41u3qyZIZHDCJArIMzLuzsrLAwaK8/edit
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/1c39e772c2c0d687691dd4b589a12c323f5f767d.tar.gz
# google3/third_party/libavif/METADATA
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/647c3c208cf152395d777c1bf7240d2ecf7df5a9.tar.gz
CODEC_PACKAGE = node_modules/libavif.tar.gz
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.1.0.tar.gz
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v3.6.0.tar.gz
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
export CODEC_DIR = node_modules/libavif
export BUILD_DIR = node_modules/build
export LIBAOM_DIR = node_modules/libaom
override CFLAGS += "-Wno-unused-macros"
export
OUT_ENC_JS = enc/avif_enc.js
OUT_NODE_ENC_JS = enc/avif_node_enc.js
OUT_ENC_MT_JS = enc/avif_enc_mt.js
OUT_NODE_ENC_MT_JS = enc/avif_node_enc_mt.js
OUT_DEC_JS = dec/avif_dec.js
OUT_NODE_DEC_JS = dec/avif_node_dec.js
OUT_ENC_CPP = enc/avif_enc.cpp
OUT_ENC_CPP = enc/avif_enc.cpp
OUT_DEC_CPP = dec/avif_dec.cpp
ENVIRONMENT = worker
@ -25,9 +28,9 @@ HELPER_MAKEFLAGS := -f helper.Makefile
.PHONY: all clean
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_JS) $(OUT_NODE_DEC_JS)
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS) $(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS) $(OUT_NODE_DEC_JS)
$(OUT_NODE_ENC_JS): ENVIRONMENT=node
$(OUT_NODE_ENC_JS) $(OUT_NODE_ENC_MT_JS): ENVIRONMENT=node
$(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
$(MAKE) \
$(HELPER_MAKEFLAGS) \
@ -41,7 +44,7 @@ $(OUT_NODE_ENC_JS) $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(L
ENVIRONMENT=$(ENVIRONMENT) \
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
$(OUT_ENC_MT_JS) $(OUT_NODE_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
$(MAKE) \
$(HELPER_MAKEFLAGS) \
OUT_JS=$@ \
@ -86,4 +89,7 @@ $(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
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_NODE_JS) clean
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_ENC_NODE_MT_JS) clean
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEC_JS) clean
$(MAKE) $(HELPER_MAKEFLAGS) OUT_JS=$(OUT_DEV_NODE_JS) clean

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -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};function moduleLoaded(){}self.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;(e.data.urlOrBlob?import(e.data.urlOrBlob):import("./avif_enc_mt.js")).then(function(exports){return exports.default(Module)}).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInit();if(!initializedJS){Module["___embind_register_native_and_builtin_types"]();initializedJS=true}try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(Module["keepRuntimeAlive"]()){Module["PThread"].setExitStatus(result)}else{Module["PThread"].threadExit(result)}}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["keepRuntimeAlive"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};

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

File diff suppressed because one or more lines are too long

Binary file not shown.

View 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}};

View File

@ -32,13 +32,8 @@ $(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
$(LDFLAGS) \
$(OUT_FLAGS) \
--bind \
--closure 1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s TEXTDECODER=2 \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-s EXPORT_NAME="$(basename $(@F))" \
-o $@ \
$+

View File

@ -1,9 +1,17 @@
FROM emscripten/emsdk:2.0.8
FROM emscripten/emsdk:2.0.23
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 LDFLAGS "${CFLAGS} -s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency"
# Build and cache standard libraries with these flags
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
ENV LDFLAGS "${CFLAGS} \
-s FILESYSTEM=0 \
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
-s ALLOW_MEMORY_GROWTH=1 \
-s TEXTDECODER=2 \
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
"
# 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
CMD ["sh", "-c", "emmake make -j`nproc`"]

54
codecs/hqx/Cargo.lock generated
View File

@ -12,13 +12,19 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "console_error_panic_hook"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"wasm-bindgen",
]
@ -63,7 +69,7 @@ version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -83,9 +89,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.19"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [
"unicode-xid 0.2.1",
]
@ -105,7 +111,7 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2 1.0.19",
"proc-macro2 1.0.27",
]
[[package]]
@ -118,7 +124,7 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
name = "squooshhqx"
version = "0.1.0"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"console_error_panic_hook",
"hqx",
"wasm-bindgen",
@ -128,11 +134,11 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.35"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
dependencies = [
"proc-macro2 1.0.19",
"proc-macro2 1.0.27",
"quote 1.0.7",
"unicode-xid 0.2.1",
]
@ -151,24 +157,24 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasm-bindgen"
version = "0.2.65"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.65"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2 1.0.19",
"proc-macro2 1.0.27",
"quote 1.0.7",
"syn",
"wasm-bindgen-shared",
@ -180,7 +186,7 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"futures",
"js-sys",
"wasm-bindgen",
@ -189,9 +195,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.65"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [
"quote 1.0.7",
"wasm-bindgen-macro-support",
@ -199,11 +205,11 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.65"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [
"proc-macro2 1.0.19",
"proc-macro2 1.0.27",
"quote 1.0.7",
"syn",
"wasm-bindgen-backend",
@ -212,9 +218,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.65"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
[[package]]
name = "wasm-bindgen-test"
@ -257,7 +263,7 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"memory_units",
"winapi",

2
codecs/hqx/pkg/squooshhqx.d.ts generated vendored
View File

@ -14,6 +14,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly resize: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_malloc: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number) => void;
}
@ -27,4 +28,3 @@ export interface InitOutput {
* @returns {Promise<InitOutput>}
*/
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;

View File

@ -37,19 +37,23 @@ function getArrayU32FromWasm0(ptr, len) {
* @returns {Uint32Array}
*/
export function resize(input_image, input_width, input_height, factor) {
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
var r0 = getInt32Memory0()[8 / 4 + 0];
var r1 = getInt32Memory0()[8 / 4 + 1];
var v1 = getArrayU32FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 4);
return v1;
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.resize(retptr, ptr0, len0, input_width, input_height, factor);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
var v1 = getArrayU32FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 4);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
async function load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
@ -68,7 +72,6 @@ async function load(module, imports) {
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
@ -82,7 +85,7 @@ async function load(module, imports) {
async function init(input) {
if (typeof input === 'undefined') {
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
input = new URL('squooshhqx_bg.wasm', import.meta.url);
}
const imports = {};
@ -91,6 +94,8 @@ async function init(input) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
wasm = instance.exports;

6
codecs/hqx/pkg/squooshhqx_bg.d.ts generated vendored
View File

@ -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.

View File

@ -17,10 +17,6 @@ $(OUT_JS): $(CODEC_OUT)
${CXXFLAGS} \
${LDFLAGS} \
--bind \
--closure 1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s TEXTDECODER=2 \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-o $@ \

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
CODEC_URL = https://gitlab.com/wg1/jpeg-xl.git
CODEC_VERSION = ab7c5e9b6795134377aa4846ceaae2c5bc504f76
CODEC_URL = https://github.com/libjxl/libjxl.git
CODEC_VERSION = 9f544641ec83f6abd9da598bdd08178ee8a003e0
CODEC_DIR = node_modules/jxl
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
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_simd.js: $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl.a $(CODEC_MT_SIMD_BUILD_DIR)/lib/libjxl_threads.a
# Disable errors on deprecated SIMD intrinsics.
# JPEG-XL & Highway need to catch up, once they do, we can remove this suppression.
export CXXFLAGS += -Wno-deprecated-declarations
# Compile multithreaded wrappers with -pthread.
enc/jxl_enc_mt.js enc/jxl_enc_mt_simd.js: CXXFLAGS+=-pthread
@ -42,13 +46,8 @@ $(OUT_JS):
-I $(CODEC_DIR)/third_party/highway \
-I $(CODEC_DIR)/third_party/skcms \
--bind \
--closure 1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s TEXTDECODER=2 \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-s EXPORT_NAME="$(basename $(@F))" \
-o $@ \
$+ \
$(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_EXAMPLES=0 \
-DBUILD_TESTING=0 \
-DCMAKE_CROSSCOMPILING_EMULATOR=node \
-B $(@D) \
$(<D)
emcc -Wall -O3 -o $(CODEC_DIR)/third_party/skcms/skcms.cc.o -I$(CODEC_DIR)/third_party/skcms -c $(CODEC_DIR)/third_party/skcms/skcms.cc
llvm-ar rc $(CODEC_BUILD_DIR)/third_party/libskcms.a $(CODEC_DIR)/third_party/skcms/skcms.cc.o
rm $(CODEC_DIR)/third_party/skcms/skcms.cc.o
$(CODEC_DIR)/CMakeLists.txt:
$(CODEC_DIR)/CMakeLists.txt:
$(RM) -r $(@D)
git init $(@D)
git -C $(@D) fetch $(CODEC_URL) $(CODEC_VERSION) --depth 1

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -4,21 +4,21 @@
#include "lib/jxl/base/thread_pool_internal.h"
#include "lib/jxl/enc_external_image.h"
#include "lib/jxl/enc_file.h"
#include "lib/jxl/enc_color_management.h"
using namespace emscripten;
thread_local const val Uint8Array = val::global("Uint8Array");
struct JXLOptions {
// 1 = slowest
// 7 = fastest
int speed;
int effort;
float quality;
bool progressive;
int epf;
int nearLossless;
bool lossyPalette;
size_t decodingSpeedTier;
float photonNoiseIso;
bool lossyModular;
};
val encode(std::string image, int width, int height, JXLOptions options) {
@ -33,25 +33,35 @@ val encode(std::string image, int width, int height, JXLOptions options) {
pool_ptr = &pool;
#endif
size_t st = 10 - options.effort;
cparams.speed_tier = jxl::SpeedTier(st);
cparams.epf = options.epf;
cparams.speed_tier = static_cast<jxl::SpeedTier>(options.speed);
cparams.near_lossless = options.nearLossless;
cparams.decoding_speed_tier = options.decodingSpeedTier;
cparams.photon_noise_iso = options.photonNoiseIso;
if (options.lossyPalette) {
cparams.lossy_palette = true;
cparams.palette_colors = 0;
cparams.options.predictor = jxl::Predictor::Zero;
// Near-lossless assumes -R 0
cparams.responsive = 0;
cparams.modular_mode = true;
}
float quality = options.quality;
// Quality settings roughly match libjpeg qualities.
if (quality < 7 || quality == 100) {
if (options.lossyModular || quality == 100) {
cparams.modular_mode = true;
// Internal modular quality to roughly match VarDCT size.
cparams.quality_pair.first = cparams.quality_pair.second =
std::min(35 + (quality - 7) * 3.0f, 100.0f);
if (quality < 7) {
cparams.quality_pair.first = cparams.quality_pair.second =
std::min(35 + (quality - 7) * 3.0f, 100.0f);
} else {
cparams.quality_pair.first = cparams.quality_pair.second =
std::min(35 + (quality - 7) * 65.f / 93.f, 100.0f);
}
} else {
cparams.modular_mode = false;
if (quality >= 30) {
@ -77,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);
if (!io.metadata.size.Set(width, height)) {
return val::null();
@ -94,14 +98,14 @@ val encode(std::string image, int width, int height, JXLOptions options) {
jxl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(image.data()), image.size()), width,
height, jxl::ColorEncoding::SRGB(/*is_gray=*/false), /*has_alpha=*/true,
/*alpha_is_premultiplied=*/false, /*bits_per_sample=*/8, /*endiannes=*/JXL_LITTLE_ENDIAN,
/*flipped_y=*/false, pool_ptr, main);
/*flipped_y=*/false, pool_ptr, main, /*(only true if bits_per_sample==32) float_in=*/false);
if (!result) {
return val::null();
}
auto js_result = val::null();
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, /*aux=*/nullptr, pool_ptr)) {
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes, jxl::GetJxlCms(), /*aux=*/nullptr, pool_ptr)) {
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
}
@ -110,12 +114,13 @@ val encode(std::string image, int width, int height, JXLOptions options) {
EMSCRIPTEN_BINDINGS(my_module) {
value_object<JXLOptions>("JXLOptions")
.field("speed", &JXLOptions::speed)
.field("effort", &JXLOptions::effort)
.field("quality", &JXLOptions::quality)
.field("progressive", &JXLOptions::progressive)
.field("nearLossless", &JXLOptions::nearLossless)
.field("lossyPalette", &JXLOptions::lossyPalette)
.field("decodingSpeedTier", &JXLOptions::decodingSpeedTier)
.field("photonNoiseIso", &JXLOptions::photonNoiseIso)
.field("lossyModular", &JXLOptions::lossyModular)
.field("epf", &JXLOptions::epf);
function("encode", &encode);

View File

@ -1,11 +1,12 @@
export interface EncodeOptions {
speed: number;
effort: number;
quality: number;
progressive: boolean;
epf: number;
nearLossless: number;
lossyPalette: boolean;
decodingSpeedTier: number;
photonNoiseIso: number;
lossyModular: boolean;
}
export interface JXLModule extends EmscriptenWasm.Module {

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -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}};

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -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}};

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -22,11 +22,7 @@ enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js: ENVIRONMENT = node
-I $(CODEC_DIR) \
${CXXFLAGS} \
${LDFLAGS} \
--closure 1 \
--bind \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s TEXTDECODER=2 \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-o $@ \

File diff suppressed because one or more lines are too long

View File

@ -158,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) {
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) {

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -531,9 +531,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasm-bindgen"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@ -541,9 +541,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [
"bumpalo",
"lazy_static",
@ -556,9 +556,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -566,9 +566,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [
"proc-macro2",
"quote",
@ -591,6 +591,6 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.73"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"

View File

@ -36,6 +36,7 @@ export class wbg_rayon_PoolBuilder {
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly __wasm_init_memory: () => void;
readonly optimise: (a: number, b: number, c: number, d: number, e: number) => void;
readonly __wbg_wbg_rayon_poolbuilder_free: (a: number) => void;
readonly wbg_rayon_poolbuilder_numThreads: (a: number) => number;

View File

@ -1,5 +1,6 @@
/* tslint:disable */
/* eslint-disable */
export function __wasm_init_memory(): void;
export function optimise(a: number, b: number, c: number, d: number, e: number): void;
export function __wbg_wbg_rayon_poolbuilder_free(a: number): void;
export function wbg_rayon_poolbuilder_numThreads(a: number): number;

40
codecs/png/Cargo.lock generated
View File

@ -36,13 +36,19 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crc32fast"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -76,7 +82,7 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -102,9 +108,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.18"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [
"unicode-xid",
]
@ -139,9 +145,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.34"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
dependencies = [
"proc-macro2",
"quote",
@ -156,19 +162,19 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasm-bindgen"
version = "0.2.68"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.68"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [
"bumpalo",
"lazy_static",
@ -181,9 +187,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.68"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -191,9 +197,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.68"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [
"proc-macro2",
"quote",
@ -204,9 +210,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.68"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
[[package]]
name = "web-sys"

2
codecs/png/pkg/squoosh_png.d.ts generated vendored
View File

@ -20,6 +20,7 @@ export interface InitOutput {
readonly encode: (a: number, b: number, c: number, d: number, e: number) => void;
readonly decode: (a: number, b: number) => number;
readonly __wbindgen_free: (a: number, b: number) => void;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_malloc: (a: number) => number;
}
@ -32,4 +33,3 @@ export interface InitOutput {
* @returns {Promise<InitOutput>}
*/
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;

View File

@ -72,8 +72,7 @@ function getArrayU8FromWasm0(ptr, len) {
*/
export function encode(data, width, height) {
try {
const retptr = wasm.__wbindgen_export_1.value - 16;
wasm.__wbindgen_export_1.value = retptr;
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.encode(retptr, ptr0, len0, width, height);
@ -83,7 +82,7 @@ export function encode(data, width, height) {
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
} finally {
wasm.__wbindgen_export_1.value += 16;
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
@ -113,7 +112,6 @@ export function decode(data) {
async function load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
@ -132,7 +130,6 @@ async function load(module, imports) {
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
@ -146,7 +143,7 @@ async function load(module, imports) {
async function init(input) {
if (typeof input === 'undefined') {
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
input = new URL('squoosh_png_bg.wasm', import.meta.url);
}
const imports = {};
imports.wbg = {};
@ -164,6 +161,8 @@ async function init(input) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
wasm = instance.exports;

Binary file not shown.

View File

@ -4,4 +4,5 @@ export const memory: WebAssembly.Memory;
export function encode(a: number, b: number, c: number, d: number, e: number): void;
export function decode(a: number, b: number): number;
export function __wbindgen_free(a: number, b: number): void;
export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_malloc(a: number): number;

View File

@ -53,7 +53,11 @@ where
#[wasm_bindgen]
pub fn decode(mut data: &[u8]) -> ImageData {
let mut decoder = png::Decoder::new(&mut data);
decoder.set_transformations(png::Transformations::EXPAND);
decoder.set_transformations(
png::Transformations::EXPAND | // Turn paletted images into RGB
png::Transformations::PACKING | // Turn images <8bit to 8bit
png::Transformations::STRIP_16, // Turn 16bit into 8 bit
);
let (info, mut reader) = decoder.read_info().unwrap_throw();
let num_pixels = (info.width * info.height) as usize;
let mut buf = vec![0; num_pixels * 4];

42
codecs/qoi/Makefile Normal file
View File

@ -0,0 +1,42 @@
CODEC_URL = https://github.com/phoboslab/qoi/archive/8d35d93cdca85d2868246c2a8a80a1e2c16ba2a8.tar.gz
CODEC_DIR = node_modules/qoi
CODEC_BUILD_DIR:= $(CODEC_DIR)/build
ENVIRONMENT = worker
OUT_JS = enc/qoi_enc.js dec/qoi_dec.js
OUT_WASM := $(OUT_JS:.js=.wasm)
.PHONY: all clean
all: $(OUT_JS)
$(filter enc/%,$(OUT_JS)): enc/qoi_enc.o
$(filter dec/%,$(OUT_JS)): dec/qoi_dec.o
# ALL .js FILES
$(OUT_JS):
$(LD) \
$(LDFLAGS) \
--bind \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-o $@ \
$+
# ALL .o FILES
%.o: %.cpp $(CODEC_DIR)
$(CXX) -c \
$(CXXFLAGS) \
-I $(CODEC_DIR) \
-o $@ \
$<
# CREATE DIRECTORY
$(CODEC_DIR):
mkdir -p $(CODEC_DIR)
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $(CODEC_DIR)
clean:
$(RM) $(OUT_JS) $(OUT_WASM)
$(MAKE) -C $(CODEC_DIR) clean

View File

@ -0,0 +1,30 @@
#include <emscripten/bind.h>
#include <emscripten/val.h>
#define QOI_IMPLEMENTATION
#include "qoi.h"
using namespace emscripten;
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
thread_local const val ImageData = val::global("ImageData");
val decode(std::string qoiimage) {
qoi_desc desc;
uint8_t* rgba = (uint8_t*)qoi_decode(qoiimage.c_str(), qoiimage.length(), &desc, 4);
// Resultant width and height stored in descriptor
int decodedWidth = desc.width;
int decodedHeight = desc.height;
val result = ImageData.new_(
Uint8ClampedArray.new_(typed_memory_view(4 * decodedWidth * decodedHeight, rgba)),
decodedWidth, decodedHeight);
free(rgba);
return result;
}
EMSCRIPTEN_BINDINGS(my_module) {
function("decode", &decode);
}

7
codecs/qoi/dec/qoi_dec.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
export interface QOIModule extends EmscriptenWasm.Module {
decode(data: BufferSource): ImageData | null;
}
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QOIModule>;
export default moduleFactory;

16
codecs/qoi/dec/qoi_dec.js generated Normal file

File diff suppressed because one or more lines are too long

BIN
codecs/qoi/dec/qoi_dec.wasm Normal file

Binary file not shown.

View File

@ -0,0 +1,36 @@
#include <emscripten/bind.h>
#include <emscripten/val.h>
#define QOI_IMPLEMENTATION
#include "qoi.h"
using namespace emscripten;
struct QoiOptions {};
thread_local const val Uint8Array = val::global("Uint8Array");
val encode(std::string buffer, int width, int height, QoiOptions options) {
int compressedSizeInBytes;
qoi_desc desc;
desc.width = width;
desc.height = height;
desc.channels = 4;
desc.colorspace = QOI_SRGB;
uint8_t* encodedData = (uint8_t*)qoi_encode(buffer.c_str(), &desc, &compressedSizeInBytes);
if (encodedData == NULL)
return val::null();
auto js_result =
Uint8Array.new_(typed_memory_view(compressedSizeInBytes, (const uint8_t*)encodedData));
free(encodedData);
return js_result;
}
EMSCRIPTEN_BINDINGS(my_module) {
value_object<QoiOptions>("QoiOptions");
function("encode", &encode);
}

14
codecs/qoi/enc/qoi_enc.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
export interface EncodeOptions {}
export interface QoiModule extends EmscriptenWasm.Module {
encode(
data: BufferSource,
width: number,
height: number,
options: EncodeOptions,
): Uint8Array;
}
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QoiModule>;
export default moduleFactory;

16
codecs/qoi/enc/qoi_enc.js generated Normal file

File diff suppressed because one or more lines are too long

BIN
codecs/qoi/enc/qoi_enc.wasm Normal file

Binary file not shown.

7
codecs/qoi/package.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "qoi",
"scripts": {
"build": "../build-cpp.sh"
}
}

View File

@ -18,13 +18,19 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "console_error_panic_hook"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"wasm-bindgen",
]
@ -61,7 +67,7 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
]
[[package]]
@ -81,9 +87,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.18"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
dependencies = [
"unicode-xid 0.2.1",
]
@ -103,7 +109,7 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2 1.0.18",
"proc-macro2 1.0.27",
]
[[package]]
@ -134,7 +140,7 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
name = "squoosh-resize"
version = "0.1.0"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"console_error_panic_hook",
"resize",
"wasm-bindgen",
@ -144,11 +150,11 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.34"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
dependencies = [
"proc-macro2 1.0.18",
"proc-macro2 1.0.27",
"quote 1.0.7",
"unicode-xid 0.2.1",
]
@ -167,24 +173,24 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasm-bindgen"
version = "0.2.64"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.64"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2 1.0.18",
"proc-macro2 1.0.27",
"quote 1.0.7",
"syn",
"wasm-bindgen-shared",
@ -196,7 +202,7 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"futures",
"js-sys",
"wasm-bindgen",
@ -205,9 +211,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.64"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
dependencies = [
"quote 1.0.7",
"wasm-bindgen-macro-support",
@ -215,11 +221,11 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.64"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
dependencies = [
"proc-macro2 1.0.18",
"proc-macro2 1.0.27",
"quote 1.0.7",
"syn",
"wasm-bindgen-backend",
@ -228,9 +234,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.64"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
[[package]]
name = "wasm-bindgen-test"
@ -273,7 +279,7 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"memory_units",
"winapi",

View File

@ -9,15 +9,16 @@
* @param {number} typ_idx
* @param {boolean} premultiply
* @param {boolean} color_space_conversion
* @returns {Uint8Array}
* @returns {Uint8ClampedArray}
*/
export function resize(input_image: Uint8Array, input_width: number, input_height: number, output_width: number, output_height: number, typ_idx: number, premultiply: boolean, color_space_conversion: boolean): Uint8Array;
export function resize(input_image: Uint8Array, input_width: number, input_height: number, output_width: number, output_height: number, typ_idx: number, premultiply: boolean, color_space_conversion: boolean): Uint8ClampedArray;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly resize: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_malloc: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number) => void;
}
@ -31,4 +32,3 @@ export interface InitOutput {
* @returns {Promise<InitOutput>}
*/
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;

View File

@ -26,8 +26,16 @@ function getInt32Memory0() {
return cachegetInt32Memory0;
}
function getArrayU8FromWasm0(ptr, len) {
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
let cachegetUint8ClampedMemory0 = null;
function getUint8ClampedMemory0() {
if (cachegetUint8ClampedMemory0 === null || cachegetUint8ClampedMemory0.buffer !== wasm.memory.buffer) {
cachegetUint8ClampedMemory0 = new Uint8ClampedArray(wasm.memory.buffer);
}
return cachegetUint8ClampedMemory0;
}
function getClampedArrayU8FromWasm0(ptr, len) {
return getUint8ClampedMemory0().subarray(ptr / 1, ptr / 1 + len);
}
/**
* @param {Uint8Array} input_image
@ -38,22 +46,26 @@ function getArrayU8FromWasm0(ptr, len) {
* @param {number} typ_idx
* @param {boolean} premultiply
* @param {boolean} color_space_conversion
* @returns {Uint8Array}
* @returns {Uint8ClampedArray}
*/
export function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
var ptr0 = passArray8ToWasm0(input_image, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.resize(8, ptr0, len0, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
var r0 = getInt32Memory0()[8 / 4 + 0];
var r1 = getInt32Memory0()[8 / 4 + 1];
var v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
var ptr0 = passArray8ToWasm0(input_image, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.resize(retptr, ptr0, len0, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
var v1 = getClampedArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
async function load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
@ -72,7 +84,6 @@ async function load(module, imports) {
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
@ -86,7 +97,7 @@ async function load(module, imports) {
async function init(input) {
if (typeof input === 'undefined') {
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
input = new URL('squoosh_resize_bg.wasm', import.meta.url);
}
const imports = {};
@ -95,6 +106,8 @@ async function init(input) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
wasm = instance.exports;

View File

@ -2,5 +2,6 @@
/* eslint-disable */
export const memory: WebAssembly.Memory;
export function resize(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number): void;
export function __wbindgen_add_to_stack_pointer(a: number): number;
export function __wbindgen_malloc(a: number): number;
export function __wbindgen_free(a: number, b: number): void;

View File

@ -8,6 +8,7 @@ use cfg_if::cfg_if;
use resize::Pixel;
use resize::Type;
use wasm_bindgen::prelude::*;
use wasm_bindgen::Clamped;
mod srgb;
use srgb::{linear_to_srgb, Clamp};
@ -66,7 +67,7 @@ pub fn resize(
typ_idx: usize,
premultiply: bool,
color_space_conversion: bool,
) -> Vec<u8> {
) -> Clamped<Vec<u8>> {
let typ = match typ_idx {
0 => Type::Triangle,
1 => Type::Catrom,
@ -91,7 +92,7 @@ pub fn resize(
typ,
);
resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
return output_image;
return Clamped(output_image);
}
// Otherwise, we convert to f32 images to keep the
@ -138,5 +139,5 @@ pub fn resize(
.clamp(0.0, 255.0) as u8;
}
return output_image;
return Clamped(output_image);
}

14
codecs/visdif/BUILD.md Normal file
View File

@ -0,0 +1,14 @@
This codec currently needs monkey-patching of Emscripten
```
$ docker run --rm -it -v $(PWD):/src squoosh-cpp "/bin/bash"
# cat << EOF | patch /emsdk/upstream/emscripten/system/lib/dlmalloc.c
659c659
< #define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
---
> #define MALLOC_ALIGNMENT ((size_t)(16U))
EOF
# emcc --clear-cache
# /emsdk/upstream/emscripten/embuilder build libdlmalloc --force
# emmake make
```

View File

@ -1,5 +1,6 @@
CODEC_URL = https://github.com/google/butteraugli/archive/71b18b636b9c7d1ae0c1d3730b85b3c127eb4511.tar.gz
CODEC_DIR = node_modules/butteraugli
ENVIRONMENT = node
OUT_JS = visdif.js
OUT_WASM = $(OUT_JS:.js=.wasm)
@ -8,19 +9,18 @@ OUT_WASM = $(OUT_JS:.js=.wasm)
all: $(OUT_JS)
%.js: $(CODEC_DIR)
%.js: visdif.cpp $(CODEC_DIR)/butteraugli/butteraugli.cc
$(CXX) \
-I $(CODEC_DIR) \
${CXXFLAGS} \
${LDFLAGS} \
--bind \
--closure 1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s 'EXPORT_NAME="$(basename $(@F))"' \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-o $@ \
visdif.cpp \
$(CODEC_DIR)/butteraugli/butteraugli.cc
$+
$(CODEC_DIR)/butteraugli/butteraugli.cc: $(CODEC_DIR)
$(CODEC_DIR):
mkdir -p $@

View File

@ -1,5 +1,6 @@
{
"name": "avif",
"type": "module",
"scripts": {
"build": "../build-cpp.sh"
}

View File

@ -5,12 +5,19 @@
using namespace emscripten;
using namespace butteraugli;
#define GAMMA 2.2
static float SrgbToLinear[256];
inline void gammaLookupTable() {
SrgbToLinear[0] = 0;
for (int i = 1; i < 256; ++i) {
SrgbToLinear[i] = static_cast<float>(255.0 * pow(i / 255.0, GAMMA));
}
}
// Turns an interleaved RGBA buffer into 4 planes for each color channel
void planarize(std::vector<ImageF>& img,
const uint8_t* rgba,
int width,
int height,
float gamma = 2.2) {
void planarize(std::vector<ImageF>& img, const uint8_t* rgba, int width, int height) {
assert(img.size() == 0);
img.push_back(ImageF(width, height));
img.push_back(ImageF(width, height));
@ -22,10 +29,10 @@ void planarize(std::vector<ImageF>& img,
float* const row_b = img[2].Row(y);
float* const row_a = img[3].Row(y);
for (int x = 0; x < width; x++) {
row_r[x] = 255.0 * pow(rgba[(y * width + x) * 4 + 0] / 255.0, gamma);
row_g[x] = 255.0 * pow(rgba[(y * width + x) * 4 + 1] / 255.0, gamma);
row_b[x] = 255.0 * pow(rgba[(y * width + x) * 4 + 2] / 255.0, gamma);
row_a[x] = 255.0 * pow(rgba[(y * width + x) * 4 + 3] / 255.0, gamma);
row_r[x] = SrgbToLinear[rgba[(y * width + x) * 4 + 0]];
row_g[x] = SrgbToLinear[rgba[(y * width + x) * 4 + 1]];
row_b[x] = SrgbToLinear[rgba[(y * width + x) * 4 + 2]];
row_a[x] = SrgbToLinear[rgba[(y * width + x) * 4 + 3]];
}
}
}
@ -37,6 +44,7 @@ class VisDiff {
public:
VisDiff(std::string ref_img, int width, int height) {
gammaLookupTable();
planarize(this->ref_img, (uint8_t*)ref_img.c_str(), width, height);
this->width = width;
this->height = height;

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -24,10 +24,6 @@ $(OUT_JS):
$(LD) \
$(LDFLAGS) \
--bind \
--closure 1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MODULARIZE=1 \
-s TEXTDECODER=2 \
-s ENVIRONMENT=$(ENVIRONMENT) \
-s EXPORT_ES6=1 \
-o $@ \

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More