1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
//! # webpx
//!
//! Complete WebP encoding and decoding with ICC profiles, streaming, and animation support.
//!
//! `webpx` provides ergonomic Rust bindings to Google's libwebp library
//! (FFI to the upstream C codebase).
//!
//! **For new projects, use [`zenwebp`](https://github.com/imazen/zenwebp)
//! instead.** `zenwebp` is a pure-Rust port of libwebp — equally or
//! more capable than webpx on every axis (full feature parity: lossy /
//! lossless, animation, alpha, ICC / EXIF / XMP, streaming, presets,
//! limits), with native `wasm32-unknown-unknown` support that webpx
//! cannot offer (libwebp requires emscripten), and
//! `#![forbid(unsafe_code)]` so the whole class of FFI / memory-safety
//! bug is structurally impossible.
//!
//! Performance and compression are essentially a wash: libwebp can be
//! up to ~35 % faster on specific photos but up to ~2.5× slower on
//! others; encoded-size difference is at most ~0.02 % — noise.
//!
//! The security argument is concrete: libwebp has a documented history
//! of high-severity vulnerabilities (most notably CVE-2023-4863, an
//! actively-exploited 0-click heap overflow patched out of band in
//! every major browser), and every libwebp wrapper that has been
//! audited — webpx included — has shipped soundness bugs (versions
//! 0.1.0–0.1.4 are yanked; 0.2.0 + 0.2.1 fixed multiple FFI issues
//! found across two parallel audits). `zenwebp`'s pure-safe-Rust
//! implementation does not have that exposure.
//!
//! `webpx` is maintained for users whose application already links
//! libwebp through another path (existing C / C++ code, system
//! package), who specifically need libwebp's MIPS DSP code paths, or
//! who have benchmarked their content and confirmed libwebp wins.
//!
//! webpx offers:
//!
//! - **Static Images**: Encode/decode RGB, RGBA, and YUV formats with lossy or lossless compression
//! - **Animations**: Create and decode animated WebP files frame-by-frame or in batch
//! - **Metadata**: Embed and extract ICC color profiles, EXIF, and XMP data
//! - **Streaming**: Incremental decoding for large files or network streams
//! - **Presets**: Content-aware optimization (Photo, Picture, Drawing, Icon, Text)
//! - **Advanced Config**: Full control over compression parameters, alpha handling, and more
//!
//! ## Quick Start
//!
//! ```rust
//! use webpx::{Encoder, Unstoppable};
//!
//! // Create a small 2x2 RGBA image (red, green, blue, white)
//! let rgba_data: Vec<u8> = vec![
//! 255, 0, 0, 255, // red
//! 0, 255, 0, 255, // green
//! 0, 0, 255, 255, // blue
//! 255, 255, 255, 255 // white
//! ];
//!
//! // Encode to WebP (lossy, quality 85)
//! let webp_bytes = Encoder::new_rgba(&rgba_data, 2, 2)
//! .quality(85.0)
//! .encode(Unstoppable)?;
//!
//! // Decode back to RGBA
//! let (pixels, width, height) = webpx::decode_rgba(&webp_bytes)?;
//! assert_eq!((width, height), (2, 2));
//! # Ok::<(), webpx::At<webpx::Error>>(())
//! ```
//!
//! ## Decoding untrusted input
//!
//! [`Limits::default()`] applies opinionated production caps (64 MP per
//! frame, 256 MP cumulative, 16383×16383, 64 MiB input, 4096 frames,
//! 5 min animation, 4 MiB metadata, 256 MiB output), so the default
//! `DecoderConfig` and `AnimationDecoder` paths are already bounded.
//! Override individual fields via the `with_*` builders on top of
//! `Limits::default()`, or use [`Limits::none()`] to opt out entirely
//! (only when the input source is fully trusted).
//!
//! ```rust,no_run
//! use webpx::{Decoder, DecoderConfig, Limits};
//!
//! // Tighter than default: 16 MP per frame for a thumbnail decoder.
//! let limits = Limits::default().with_max_pixels(16 * 1024 * 1024);
//!
//! let webp_data: &[u8] = &[];
//! let img = Decoder::new(webp_data)?
//! .config(DecoderConfig::new().limits(limits))
//! .decode_rgba()?;
//! # Ok::<(), webpx::At<webpx::Error>>(())
//! ```
//!
//! See the [`Limits`] type for the per-field enforcement matrix and the
//! `decode_with_limits` example for end-to-end usage across the static
//! decoder, animation decoder, and metadata extraction paths.
//!
//! ## Builder API
//!
//! For more control, use the builder pattern:
//!
//! ```rust,no_run
//! use webpx::{Encoder, Preset, Unstoppable};
//!
//! let rgba_data: &[u8] = &[0u8; 640 * 480 * 4]; // placeholder
//! let webp_bytes = Encoder::new_rgba(rgba_data, 640, 480)
//! .preset(Preset::Photo) // Optimize for photos
//! .quality(85.0) // 0-100, higher = better quality
//! .method(4) // 0-6, higher = slower but smaller
//! .encode(Unstoppable)?;
//! # Ok::<(), webpx::At<webpx::Error>>(())
//! ```
//!
//! ## Feature Flags
//!
//! | Feature | Default | Description |
//! |---------|---------|-------------|
//! | `decode` | Yes | Decoding support |
//! | `encode` | Yes | Encoding support |
//! | `std` | Yes | Standard library (disable for no_std) |
//! | `animation` | No | Animated WebP support |
//! | `icc` | No | ICC/EXIF/XMP metadata |
//! | `streaming` | No | Incremental processing |
//!
//! ## no_std Support
//!
//! This crate supports `no_std` with `alloc`. Disable the `std` feature:
//!
//! ```toml
//! webpx = { version = "0.1", default-features = false, features = ["decode", "encode"] }
//! ```
//!
//! ## Compatibility Shims
//!
//! For easy migration from other WebP crates, see [`compat::webp`] and [`compat::webp_animation`].
//!
//! ## Error Handling
//!
//! All functions return `Result<T, At<Error>>` where [`At`] provides lightweight error
//! location tracking. See the [error module](crate::error) documentation for how to:
//! - Propagate traces with `.at()`
//! - Add your crate's info to traces with `at_crate!`
//! - Convert to plain errors with `.into_inner()`
extern crate alloc;
// Define crate info for whereat traces (enables GitHub links)
define_at_crate_info!;
/// `zencodec` trait implementations.
///
/// Mirror of [`zenwebp::zencodec`](https://docs.rs/zenwebp/latest/zenwebp/zencodec/index.html);
/// use either crate interchangeably under the same call shape.
// Re-exports
pub use ;
pub use ;
pub use ;
pub use ;
// Re-export enough crate types for cooperative cancellation
pub use ;
// Re-export whereat types for error location tracking
pub use ;
pub use ;
// DecodePixel trait is intentionally not exported - it's a sealed implementation detail.
// Users use concrete types (RGBA8, RGB8, etc.) with decode functions.
pub use Encoder;
pub use ;
pub use DecodeStatus;
pub use StreamingDecoder;
pub use StreamingEncoder;
pub use AnimationDecoder;
pub use AnimationEncoder;
pub use ;
/// Library version information.