@mutables.app/image-optimizer 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -4
- package/dist/optimizer.wasm +0 -0
- package/package.json +1 -1
- package/licenses/libaom-LICENSE +0 -26
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Standalone image optimizer
|
|
2
2
|
|
|
3
|
-
Rust/Emscripten JPEG, PNG,
|
|
3
|
+
Rust/Emscripten JPEG, non-interlaced PNG, and tiled/grid HEIC/HEIF decoding, scanline Lanczos3 resizing with WASM SIMD128, and WebP/JPEG output. Adam7/interlaced PNG, non-grid HEIC/HEIF, and AVIF input are rejected. HEIC/HEIF grid decoding uses libde265. No Cloudflare Computer dependency.
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
6
|
import { image } from '@mutables.app/image-optimizer';
|
|
@@ -14,13 +14,45 @@ const jpeg = await image(inputBytes).resize(800).jpeg({quality: 80}).bytes();
|
|
|
14
14
|
|
|
15
15
|
Input: Blob, ArrayBuffer, or typed array. `.bytes()` returns a Uint8Array; `.blob()` returns an image/webp or image/jpeg Blob. Width-only resizing preserves aspect ratio. Two dimensions default to stretch; `fit: 'inside'` preserves aspect ratio.
|
|
16
16
|
|
|
17
|
-
**Scanline resizing applies with and without `speed: 'fast'`.** Baseline JPEG and non-interlaced PNG inputs are read row by row.
|
|
17
|
+
**Scanline resizing applies with and without `speed: 'fast'`.** Baseline JPEG and non-interlaced PNG inputs are read row by row. Tiled/grid HEIF/HEIC inputs decode one tile row at a time and support up to 48 million pixels. Adam7/interlaced PNG and non-grid HEIF/HEIC inputs are rejected; AVIF input is also unsupported. WebP retains the complete resized image for encoding. JPEG encodes resized rows directly, uses baseline 4:2:0 output and composites transparency onto white. Input and encoded output bytes remain buffered: this API does not stream HTTP input/output.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Only Lowzag-compatible progressive JPEGs use reduced coefficient storage and decode to a power-of-two scale before row resizing. Other progressive/multi-scan variants, including CMYK and YCCK, are rejected before coefficient buffering. No fixed whole-Worker memory guarantee is made.
|
|
20
20
|
|
|
21
21
|
For WebP, `speed: 'fast'` selects a faster internal encoder setting and enables scaled JPEG decoding where beneficial. The fast encoder can produce larger files. For JPEG output, `speed: 'fast'` enables scaled JPEG decoding; the JPEG encoder uses the same settings in both modes. Omit speed for full-resolution decoding and the default WebP encoder. `.webp({lossless: true})` uses lossless WebP encoding and disables scaled decoding; resizing still changes pixels.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## Input and output limits
|
|
24
|
+
|
|
25
|
+
| Input type | Maximum source pixels | Decode path | WASM linear-memory capacity | Cloudflare isolate memory (max sampled) |
|
|
26
|
+
| --- | ---: | --- | ---: | ---: |
|
|
27
|
+
| Baseline JPEG | 48 MP | Sequential scanline decode; eligible resized JPEGs can use scaled decode with `speed: 'fast'`. | 16 MiB | 36.14 MiB |
|
|
28
|
+
| Non-interlaced PNG | 48 MP | Sequential scanline decode. | 16 MiB | 21.17 MiB |
|
|
29
|
+
| Lowzag-compatible progressive JPEG | 48 MP | Reduced coefficient decode when resizing; coefficient planes are checked before any full-resolution fallback. | 27.75 MiB | 43.23 MiB |
|
|
30
|
+
| Tiled/grid HEIC/HEIF | 48 MP | libde265 (HEVC); decodes one tile row at a time. | 49 MiB | 54.97 MiB |
|
|
31
|
+
|
|
32
|
+
### Worker response time and CPU
|
|
33
|
+
|
|
34
|
+
These end-to-end samples convert supported synthetic inputs to 800×600 WebP. Each fixture ran in its own temporary Worker with one warm-up request followed by three measured requests. Response time is client-observed p50 and includes network and transfer time; CPU is the median per-invocation `cpuTime` reported by Wrangler tail. Wrangler captured one to three CPU samples per fixture; the sample count appears beside each CPU median. The temporary Workers used a 30-second CPU limit.
|
|
35
|
+
|
|
36
|
+
| Input path and source size | Result | Response p50 | Worker CPU median | WASM capacity after last request |
|
|
37
|
+
| --- | --- | ---: | ---: | ---: |
|
|
38
|
+
| Baseline JPEG, 12 MP | Converted | 234 ms | 111 ms (1 sample) | 16 MiB |
|
|
39
|
+
| Baseline JPEG, 24 MP | Converted | 367 ms | 198 ms (1 sample) | 16 MiB |
|
|
40
|
+
| Baseline JPEG, 48 MP | Converted | 630 ms | 346 ms (3 samples) | 16 MiB |
|
|
41
|
+
| Non-interlaced PNG, 12 MP | Converted | 469 ms | 381 ms (3 samples) | 16 MiB |
|
|
42
|
+
| Non-interlaced PNG, 24 MP | Converted | 547 ms | 426 ms (3 samples) | 16 MiB |
|
|
43
|
+
| Non-interlaced PNG, 48 MP | Converted | 1,047 ms | 932 ms (3 samples) | 16 MiB |
|
|
44
|
+
| Lowzag progressive JPEG, 12 MP | Converted | 671 ms | 438 ms (3 samples) | 16 MiB |
|
|
45
|
+
| Lowzag progressive JPEG, 24 MP | Converted | 708 ms | 498 ms (3 samples) | 27.75 MiB |
|
|
46
|
+
| Lowzag progressive JPEG, 48 MP | Converted | 1,359 ms | 1,032 ms (3 samples) | 27.75 MiB |
|
|
47
|
+
| Tiled/grid HEIC/HEIF, 12 MP | Converted | 962 ms | 710 ms (3 samples) | 16 MiB |
|
|
48
|
+
| Tiled/grid HEIC/HEIF, 24 MP | Converted | 885 ms | 734 ms (3 samples) | 36.88 MiB |
|
|
49
|
+
| Tiled/grid HEIC/HEIF, 48 MP | Converted | 1,570 ms | 1,417 ms (3 samples) | 48.63 MiB |
|
|
50
|
+
|
|
51
|
+
See the [raw Worker performance results](../../benchmarks/decoder-performance-worker.json). Adam7 PNG, non-grid HEIC/HEIF, and non-Lowzag progressive JPEG measurements are retained under `historicalUnsupportedResults` and do not describe current support. These small synthetic-fixture samples show this test run, not guaranteed production latency.
|
|
52
|
+
|
|
53
|
+
All formats share a 20 MiB input limit and a 16,383-pixel dimension limit. `image(input,{maxPixels: ...})` bounds output pixels: 8 MP by default, maximum 16 MP. Adam7/interlaced PNG and non-grid HEIC/HEIF are unsupported. Only Lowzag-compatible progressive JPEGs are accepted; all other progressive/multi-scan variants, including CMYK and YCCK, are rejected. WASM capacity is not total Worker memory. Cloudflare's per-invocation isolate-memory metric includes shared JavaScript and WebAssembly memory, but is sampled at invocation time rather than measuring exact peak memory. Cloudflare's isolate limit is 128 MiB. Image processing runs synchronously inside the terminal method's promise.
|
|
54
|
+
|
|
55
|
+
Worker measurements used synthetic fixtures and 800×600 WebP output. A fresh Worker handled each fixture with a 30-second CPU ceiling; the normal experiment Worker uses 1,000 ms and may time out on large inputs. Cloudflare `memoryUsageBytesP99` samples are observed isolate-memory measurements, not exact peaks. Historical measurements for now-unsupported progressive JPEG variants remain under `historicalUnsupportedResults` in the [full Worker measurement report](../../benchmarks/decoder-memory-worker.json).
|
|
24
56
|
|
|
25
57
|
Node uses a file-based WASM loader; Workers use a static `.wasm` import. Configure your bundler to treat that file as a WebAssembly module. Requires WebAssembly SIMD and modern WASM exception handling. Workers tested with compatibility date 2026-09-02 and `new_module_registry`.
|
|
26
58
|
|
package/dist/optimizer.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/licenses/libaom-LICENSE
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2016, Alliance for Open Media. All rights reserved.
|
|
2
|
-
|
|
3
|
-
Redistribution and use in source and binary forms, with or without
|
|
4
|
-
modification, are permitted provided that the following conditions
|
|
5
|
-
are met:
|
|
6
|
-
|
|
7
|
-
1. Redistributions of source code must retain the above copyright
|
|
8
|
-
notice, this list of conditions and the following disclaimer.
|
|
9
|
-
|
|
10
|
-
2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
-
notice, this list of conditions and the following disclaimer in
|
|
12
|
-
the documentation and/or other materials provided with the
|
|
13
|
-
distribution.
|
|
14
|
-
|
|
15
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
16
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
17
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
18
|
-
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
19
|
-
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
20
|
-
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
21
|
-
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
22
|
-
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
23
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
24
|
-
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
25
|
-
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
26
|
-
POSSIBILITY OF SUCH DAMAGE.
|