All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- RGBX8 descriptor in zencodec dispatch —
RGBX8_SRGBadded toENCODE_DESCRIPTORSalongsideRGBA8_SRGB, routing throughencode_rgba_with_stopsince mozjpeg reads 4 bytes per pixel and ignores byte 3 regardless of whether it's alpha or padding (ed47868)- Handled in both the one-shot encode path and the
push_rows/finishstreaming path - Tests confirm RGBX produces byte-identical output to RGBA and to RGB when colour bytes match
- Handled in both the one-shot encode path and the
- Routed all README badges through shields.io with
?style=flat-squarefor consistent sizing (9f10ab2) - Bump zencodec to 0.1.19
fast_colordoctest insrc/encode.rsnow passesPreset::default()toEncoder::new()to match the current API signature (9f10ab2)
0.9.1 - 2026-04-14
- RGBA8 encoding — Native 4-channel input support without intermediate RGB buffer (7a55b85, 6f0ffcc)
Encoder::encode_rgba(),encode_rgba_with_stop(),encode_rgba_to_writer()color::convert_rgba_to_ycbcr_c_compat()— direct RGBA→YCbCr, alpha ignored- For BGRA input, swizzle to RGBA first with
garb::bytes::bgra_to_rgba_inplace
- zencodec RGBA8 support —
RGBA8_SRGBadded to supported encode descriptors (d5d60ab, 06c5e4b)encode()routes to native RGBA path based on pixel descriptorencode_srgba8()uses native RGBA path for contiguous data,garb::rgba_to_rgb_stridedfor stridedpush_rows()/finish()handle RGB8, RGBA8, and GRAY8
- garb dependency (optional, via
zencodecfeature) for SIMD-optimized pixel format conversions
- Swapped
yuvcrate forzenyuvin thefast-yuvpath (2667a98) — internal Imazen crate, same 15-bit fixed-point BT.601 output, enables future Sharp YUV opt-in - Refactored
encode_rgb_to_writerto share downsample+MCU+encode pipeline viaencode_ycbcr_planes_to_writerhelper (6f0ffcc)
- ARM NEON SIMD support — Safe SIMD implementation for aarch64 using archmage
- Automatic runtime detection and dispatch
- Byte-identical output to scalar implementation
- Zero unsafe code
- 100% safe Rust — Achieved
#![forbid(unsafe_code)]with no exceptions- Uses archmage 0.5 for safe SIMD intrinsics
- Uses safe_unaligned_simd 0.2.4 for safe load/store operations
- CI coverage for ARM platforms — Tests on native arm64 runners plus QEMU for aarch64, armv7, and i686
- WASM support — Builds successfully for wasm32-wasip1 with SIMD128
- Updated to archmage 0.5 (from 0.4)
- Updated to safe_unaligned_simd 0.2.4 (from 0.2.3)
- Trellis encoding is now 6% faster than C mozjpeg (was 7%, updated measurements)
- CI now tests 15 platform configurations including ARM and WASM
- Conditional compilation for forbid(unsafe_code) when mozjpeg-sys-config feature is enabled
- wasm32 unused import warnings
fast_color(bool)- Ergonomic API for color conversion modefast_color(true)— ~40% faster RGB→YCbCr usingyuvcrate (±1 rounding vs C)fast_color(false)— exact C mozjpeg parity, bytewise identical output (default)
- Byte-exact C mozjpeg parity — Baseline and Progressive modes now produce identical output to C mozjpeg (0.00% file size delta)
- AVX2-accelerated C-compatible color conversion — 3.6 Gpix/s, exact match to C mozjpeg's
jccolor.c
- Default color conversion now produces byte-exact output matching C mozjpeg
kodak_dir()now returns the actual Kodak corpus directory (was aliasingcid22_dir())- With trellis enabled, Rust produces smaller files than C mozjpeg (-0.05% to -0.47%)
- Trellis encoding is now 7% faster than C mozjpeg
c_compat_color(bool)— usefast_color(bool)instead (clearer semantics)
0.6.0 - 2026-02-02
imgreffeature (default) - Type-safe encoding withencode_imgref()acceptingImgRef<P>directly- Supports
RGB<u8>,RGBA<u8>(alpha discarded),Gray<u8>,[u8; 3],[u8; 4],u8 - Automatic stride handling for subimages
- No dimension mix-ups (width/height baked into type)
- Supports
- Strided encoding -
encode_rgb_strided()andencode_gray_strided()for:- Memory-aligned buffers (e.g., 64-byte aligned rows)
- Cropping without copy (point into larger buffer)
- GPU texture formats with padding
EncodeablePixeltrait - Implement for custom pixel typesError::InvalidStride- New error variant for stride validation
imgrefandrgbcrates are now default dependencies (can be disabled withdefault-features = false)
0.5.5 - 2026-02-01
- Recommend
mozjpegcrate for users who need both encoding and decoding
0.5.4 - 2026-01-13
- Clippy warnings in benchmarks and examples
- Removed all unsafe from SIMD modules (now uses safe wrappers)
0.5.3 - 2026-01-10
- Migrated from archmage 0.1 to 0.4 with safe_unaligned_simd
0.5.1 - 2026-01-08
- Scan optimizer parity improvements with C mozjpeg
0.5.0 - 2026-01-05
- Improved scan optimization algorithm
- Better progressive scan selection
- optimize_scans parity with C mozjpeg (now within ±0.4%)
0.4.1 - 2025-01-03
encode_ycbcr_planar_strided()- Encode strided YCbCr data without extra copies. Accepts separate stride for each plane.
0.4.0 - 2025-01-03
encode_ycbcr_planar()- Encode pre-converted planar YCbCr data directly, bypassing RGB-to-YCbCr conversion. Supports all subsampling modes (4:4:4, 4:2:2, 4:2:0).CMozjpeg::encode_ycbcr_planar()- Same capability for C mozjpeg wrapper- Decoder round-trip validation - CI now validates encoded JPEGs against multiple decoders
configure_sys()renamed toto_c_mozjpeg()- Clearer naming for C mozjpeg interopsys-localis now an optional dev dependency gated by feature flag
0.3.0 - 2025-01-02
Encoder::new()now requires aPresetargument - Explicit preset selection replaces the previous boolean progressive parameter- Crate renamed from
mozjpeg-oxidetomozjpeg-rs
- Preset enum with four encoding modes:
BaselineFastest- No optimizations, maximum speedBaselineBalanced- Baseline with trellis + Huffman optimizationProgressiveBalanced- Progressive with optimizations (default)ProgressiveSmallest- Maximum compression with optimize_scans
mozjpeg-sys-configfeature - Configure a C mozjpeg encoder from RustEncodersettings viaEncoder::configure_sys()- Smoothing filter -
.smoothing(0-100)for noise reduction on dithered images - Robidoux quant table alias -
QuantTableIdx::Robidoux(alias for MssimTuned) - CLI-style method names -
.quant_method(),.dct_method()aliases - Grayscale progressive JPEG support
- Trellis speed optimization - Adaptive search limiting for high-entropy blocks
- EOB cross-block optimization - Opt-in via
TrellisConfig::eob_optimization(true)
- AC refinement ZRL encoding - Fixed decoder errors on 8/24 test corpus images with successive approximation
- Progressive encoding now works correctly for all image sizes including non-MCU-aligned dimensions
- Public API cleanup: internal modules now hidden with
#[doc(hidden)] - SIMD:
multiversionis now the default (safe autovectorization) - SIMD: Hand-written AVX2 intrinsics available via
simd-intrinsicsfeature - Encoder settings matrix added to README
0.2.5 - 2024-12-30
- Example
test_refine.rsused wrong crate name
0.2.4 - 2024-12-29
- Grayscale progressive JPEG support
- Trellis speed optimization (
speed_level)
0.2.3 - 2024-12-28
- AC refinement ZRL loop must run for both
temp>1andtemp==1cases - Bytewise parity analysis documentation
0.2.2 - 2024-12-27
- Match C mozjpeg progressive encoding defaults exactly
- Per-scan Huffman tables for all progressive modes
0.1.0 - 2024-12-27
- Initial release of mozjpeg-rs
- Pure Rust JPEG encoder based on Mozilla's mozjpeg
- Trellis quantization - Rate-distortion optimized AC and DC coefficient selection
- Progressive JPEG encoding - Multi-scan with DC-first, AC-band progression
- Huffman optimization - 2-pass encoding for optimal entropy coding
- Overshoot deringing - Reduces ringing artifacts near hard edges
- Chroma subsampling - 4:4:4, 4:2:2, 4:2:0, 4:4:0 modes
- Quality presets -
Encoder::new(),Encoder::max_compression(),Encoder::fastest() - Optimize scans - Tries multiple scan configurations for progressive mode
- SIMD acceleration via
multiversioncrate (AVX2, SSE4.1, NEON) - Runtime CPU feature detection and dispatch
- Comprehensive test suite (177+ tests)
- FFI validation against C mozjpeg
- Multi-platform CI (Linux, macOS, Windows on x64 and ARM64)
- Trellis mode: Rust is ~10% faster than C mozjpeg
- With matching settings, produces files 2% smaller than C mozjpeg
- AVX2 intrinsics provide additional ~15% DCT speedup (opt-in feature)
- MSRV: Rust 1.89.0
- Platforms: Linux, macOS, Windows (x64 and ARM64)
- Output compatible with all standard JPEG decoders