@standardagents/sip 0.10.0-dev
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 +170 -0
- package/dist/index.d.ts +615 -0
- package/dist/index.js +1272 -0
- package/dist/index.js.map +1 -0
- package/dist/sip.js +2 -0
- package/dist/sip.wasm +0 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# @standardagents/sip
|
|
2
|
+
|
|
3
|
+
**S**mall **I**mage **P**rocessor - Ultra memory-efficient image processing for Cloudflare Workers.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Format Detection**: Probe images for format and dimensions without decoding
|
|
8
|
+
- **Scanline Resize**: Memory-efficient bilinear interpolation using only 2 rows at a time
|
|
9
|
+
- **Multi-format Input**: JPEG, PNG, WebP, AVIF
|
|
10
|
+
- **JPEG Output**: Always outputs JPEG with configurable quality
|
|
11
|
+
- **Size Control**: Resize to target dimensions and/or file size
|
|
12
|
+
- **Streaming WASM** (optional): DCT-scaled JPEG decoding for <1MB peak memory on any image size
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @standardagents/sip
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { sip } from '@standardagents/sip';
|
|
24
|
+
|
|
25
|
+
// Process an image
|
|
26
|
+
const result = await sip.process(imageBuffer, {
|
|
27
|
+
maxWidth: 2048,
|
|
28
|
+
maxHeight: 2048,
|
|
29
|
+
maxBytes: 1.5 * 1024 * 1024, // 1.5MB target
|
|
30
|
+
quality: 85,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
console.log(result.width, result.height); // Output dimensions
|
|
34
|
+
console.log(result.mimeType); // 'image/jpeg'
|
|
35
|
+
console.log(result.originalFormat); // 'png', 'jpeg', etc.
|
|
36
|
+
|
|
37
|
+
// Get the output
|
|
38
|
+
const jpegBlob = new Blob([result.data], { type: 'image/jpeg' });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Probe Only
|
|
42
|
+
|
|
43
|
+
Get image info without decoding:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { sip } from '@standardagents/sip';
|
|
47
|
+
|
|
48
|
+
const info = sip.probe(imageBuffer);
|
|
49
|
+
console.log(info.format); // 'jpeg' | 'png' | 'webp' | 'avif'
|
|
50
|
+
console.log(info.width, info.height);
|
|
51
|
+
console.log(info.hasAlpha);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### `sip.process(input, options)`
|
|
57
|
+
|
|
58
|
+
Process an image: decode, resize, and encode to JPEG.
|
|
59
|
+
|
|
60
|
+
**Parameters:**
|
|
61
|
+
- `input: ArrayBuffer` - Input image data
|
|
62
|
+
- `options: ProcessOptions` - Processing options
|
|
63
|
+
|
|
64
|
+
**Options:**
|
|
65
|
+
- `maxWidth?: number` - Maximum output width (default: 4096)
|
|
66
|
+
- `maxHeight?: number` - Maximum output height (default: 4096)
|
|
67
|
+
- `maxBytes?: number` - Target output size in bytes (default: 1.5MB)
|
|
68
|
+
- `quality?: number` - JPEG quality 1-100 (default: 85)
|
|
69
|
+
|
|
70
|
+
**Returns:** `ProcessResult`
|
|
71
|
+
- `data: ArrayBuffer` - JPEG image data
|
|
72
|
+
- `width: number` - Output width
|
|
73
|
+
- `height: number` - Output height
|
|
74
|
+
- `mimeType: 'image/jpeg'` - Always JPEG
|
|
75
|
+
- `originalFormat: ImageFormat` - Original input format
|
|
76
|
+
|
|
77
|
+
### `sip.probe(input)`
|
|
78
|
+
|
|
79
|
+
Get format and dimensions without decoding.
|
|
80
|
+
|
|
81
|
+
**Parameters:**
|
|
82
|
+
- `input: ArrayBuffer | Uint8Array` - Image data
|
|
83
|
+
|
|
84
|
+
**Returns:** `ProbeResult`
|
|
85
|
+
- `format: 'jpeg' | 'png' | 'webp' | 'avif' | 'unknown'`
|
|
86
|
+
- `width: number`
|
|
87
|
+
- `height: number`
|
|
88
|
+
- `hasAlpha: boolean`
|
|
89
|
+
|
|
90
|
+
## Memory Efficiency
|
|
91
|
+
|
|
92
|
+
The library has two processing modes:
|
|
93
|
+
|
|
94
|
+
### Standard Mode (Default)
|
|
95
|
+
|
|
96
|
+
Uses `@jsquash/*` packages for decode/encode with scanline-based resize:
|
|
97
|
+
- Only 2 rows in memory during resize
|
|
98
|
+
- Full image decoded to memory first
|
|
99
|
+
- Works for images that fit in Worker memory (~128MB limit)
|
|
100
|
+
|
|
101
|
+
### Streaming WASM Mode (Optional)
|
|
102
|
+
|
|
103
|
+
For JPEG images when WASM is built, uses ultra-efficient streaming:
|
|
104
|
+
- **DCT Scaling**: Decode JPEG at 1/2, 1/4, or 1/8 scale directly during decompression
|
|
105
|
+
- **Scanline Processing**: Never holds the full image in memory
|
|
106
|
+
- **Peak Memory**: ~50KB for any image size
|
|
107
|
+
|
|
108
|
+
Memory comparison for a 25MP (6800x3900) image:
|
|
109
|
+
|
|
110
|
+
| Mode | Peak Memory |
|
|
111
|
+
|------|-------------|
|
|
112
|
+
| Standard (@jsquash) | ~107MB |
|
|
113
|
+
| Streaming WASM (1/4 scale) | ~50KB |
|
|
114
|
+
|
|
115
|
+
## Building WASM Module
|
|
116
|
+
|
|
117
|
+
The WASM module is optional. Without it, sip falls back to standard processing.
|
|
118
|
+
|
|
119
|
+
### Prerequisites
|
|
120
|
+
|
|
121
|
+
- [Emscripten](https://emscripten.org/docs/getting_started/downloads.html)
|
|
122
|
+
- CMake
|
|
123
|
+
- Make
|
|
124
|
+
|
|
125
|
+
### Build
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Install Emscripten (if not already)
|
|
129
|
+
git clone https://github.com/emscripten-core/emsdk.git
|
|
130
|
+
cd emsdk && ./emsdk install latest && ./emsdk activate latest
|
|
131
|
+
source ./emsdk_env.sh
|
|
132
|
+
|
|
133
|
+
# Build WASM
|
|
134
|
+
cd packages/sip
|
|
135
|
+
pnpm build:wasm
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
This downloads libjpeg-turbo, compiles it to WASM, and generates:
|
|
139
|
+
- `dist/sip.js` - Emscripten loader
|
|
140
|
+
- `dist/sip.wasm` - WebAssembly binary
|
|
141
|
+
|
|
142
|
+
### Using WASM
|
|
143
|
+
|
|
144
|
+
To enable streaming mode, register the WASM loader before processing:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { sip } from '@standardagents/sip';
|
|
148
|
+
import createSipModule from '@standardagents/sip/dist/sip.js';
|
|
149
|
+
|
|
150
|
+
// Register WASM loader (once at startup)
|
|
151
|
+
globalThis.__SIP_WASM_LOADER__ = async () => createSipModule();
|
|
152
|
+
|
|
153
|
+
// Now sip.process() will use streaming for JPEG
|
|
154
|
+
const result = await sip.process(jpegBuffer, { maxWidth: 2048 });
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Architecture
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
Input → [Probe] → [Decode*] → [Resize] → [Encode*] → Output
|
|
161
|
+
↓ ↓ ↓
|
|
162
|
+
WASM: DCT Scanline WASM: Scanline
|
|
163
|
+
Scaling Bilinear JPEG Encode
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
*When WASM is available, decode and encode process one row at a time.
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
UNLICENSED - Proprietary
|