pub struct Encoder { /* private fields */ }Expand description
The main JPEG encoder.
Use the builder pattern to configure encoding options, then call
encode_rgb() or encode_gray()
to produce JPEG data.
§Presets
Use Encoder::new(preset) with a Preset to choose your settings:
Preset::ProgressiveBalanced- Progressive with all optimizations (default)Preset::BaselineBalanced- Baseline with all optimizationsPreset::BaselineFastest- No optimizations, maximum speedPreset::ProgressiveSmallest- Maximum compression (matches C mozjpeg)
§Example
use mozjpeg_rs::{Encoder, Preset};
let pixels: Vec<u8> = vec![0; 640 * 480 * 3];
let jpeg = Encoder::new(Preset::default())
.quality(85)
.encode_rgb(&pixels, 640, 480)?;JPEG encoder with configurable quality and features.
Implementations§
Source§impl Encoder
impl Encoder
Sourcepub fn new(preset: Preset) -> Self
pub fn new(preset: Preset) -> Self
Create an encoder with the specified preset.
§Arguments
preset- Encoding preset (seePresetfor details):BaselineFastest: No optimizations, fastest encodingBaselineBalanced: Baseline with all optimizationsProgressiveBalanced: Progressive with optimizations (default)ProgressiveSmallest: Maximum compression
§Preset Comparison
| Preset | Time | Size | Best For |
|---|---|---|---|
BaselineFastest | ~2ms | baseline | Real-time, thumbnails |
BaselineBalanced | ~7ms | -13% | Sequential playback |
ProgressiveBalanced | ~9ms | -13% | Web images (default) |
ProgressiveSmallest | ~21ms | -14% | Storage, archival |
Benchmarks: 512×512 Q75 image
§Example
use mozjpeg_rs::{Encoder, Preset};
let pixels: Vec<u8> = vec![128; 256 * 256 * 3];
// Default: progressive with good balance
let jpeg = Encoder::new(Preset::default())
.quality(85)
.encode_rgb(&pixels, 256, 256)
.unwrap();
// Fastest for real-time applications
let jpeg = Encoder::new(Preset::BaselineFastest)
.quality(80)
.encode_rgb(&pixels, 256, 256)
.unwrap();
// Maximum compression (matches C mozjpeg)
let jpeg = Encoder::new(Preset::ProgressiveSmallest)
.quality(85)
.encode_rgb(&pixels, 256, 256)
.unwrap();Sourcepub fn baseline_optimized() -> Self
pub fn baseline_optimized() -> Self
Create an encoder with the most optimized baseline (non-progressive) settings.
This is the recommended starting point for most use cases. It produces sequential (non-progressive) JPEGs with all mozjpeg optimizations enabled: trellis quantization, Huffman optimization, and overshoot deringing.
§Default Settings
| Setting | Value | Notes |
|---|---|---|
| quality | 75 | Good balance of size/quality |
| progressive | false | Sequential baseline JPEG |
| optimize_scans | false | N/A for baseline mode |
| subsampling | 4:2:0 | Standard chroma subsampling |
| trellis | enabled | AC + DC trellis quantization |
| optimize_huffman | true | 2-pass for optimal Huffman tables |
| overshoot_deringing | true | Reduces ringing on hard edges |
| quant_tables | ImageMagick | Same as C mozjpeg default |
| force_baseline | false | Allows 16-bit DQT at very low Q |
§Comparison with C mozjpeg
Important: This differs from C mozjpeg’s jpeg_set_defaults()!
C mozjpeg uses JCP_MAX_COMPRESSION profile by default, which enables
progressive mode and optimize_scans. This produces ~20% smaller files
but with slower encoding and progressive rendering.
| Setting | baseline_optimized() | C mozjpeg default |
|---|---|---|
| progressive | false | true |
| optimize_scans | false | true |
| trellis | true | true |
| deringing | true | true |
To match C mozjpeg’s default behavior, use max_compression().
§Example
use mozjpeg_rs::Encoder;
let pixels: Vec<u8> = vec![128; 256 * 256 * 3];
let jpeg = Encoder::baseline_optimized()
.quality(85)
.encode_rgb(&pixels, 256, 256)
.unwrap();Sourcepub fn max_compression() -> Self
pub fn max_compression() -> Self
Create encoder with maximum compression (matches C mozjpeg defaults).
This matches the JCP_MAX_COMPRESSION profile used by C mozjpeg’s
jpeg_set_defaults() and the mozjpeg crate.
§Settings (differences from new() in bold)
| Setting | Value | Notes |
|---|---|---|
| quality | 75 | Same as new() |
| progressive | true | Multi-scan progressive JPEG |
| optimize_scans | true | Tries multiple scan configs |
| subsampling | 4:2:0 | Same as new() |
| trellis | enabled | Same as new() |
| optimize_huffman | true | Same as new() |
| overshoot_deringing | true | Same as new() |
§File Size Comparison
Typical results at Q75 (256×256 image):
Encoder::baseline_optimized(): ~650 bytes (baseline)Encoder::max_compression(): ~520 bytes (~20% smaller)
§Example
use mozjpeg_rs::Encoder;
// Match C mozjpeg's default compression
let pixels: Vec<u8> = vec![128; 256 * 256 * 3];
let jpeg = Encoder::max_compression()
.quality(85)
.encode_rgb(&pixels, 256, 256)
.unwrap();Sourcepub fn progressive_balanced() -> Self
pub fn progressive_balanced() -> Self
Create encoder with progressive mode and all optimizations except optimize_scans.
This is the recommended default for most use cases. It provides:
- Progressive rendering (blurry-to-sharp loading)
- All mozjpeg optimizations (trellis, Huffman, deringing)
- Good balance between file size and encoding speed
§Settings
| Setting | Value | Notes |
|---|---|---|
| progressive | true | Multi-scan progressive JPEG |
| optimize_scans | false | Uses fixed 9-scan config |
| trellis | enabled | AC + DC trellis quantization |
| optimize_huffman | true | 2-pass for optimal tables |
| overshoot_deringing | true | Reduces ringing on hard edges |
§vs max_compression()
This preset omits optimize_scans which:
- Saves ~100% encoding time (9ms vs 21ms at 512×512)
- Loses only ~1% file size reduction
Use max_compression() only when file size is critical.
§Example
use mozjpeg_rs::Encoder;
let pixels: Vec<u8> = vec![128; 256 * 256 * 3];
let jpeg = Encoder::progressive_balanced()
.quality(85)
.encode_rgb(&pixels, 256, 256)
.unwrap();Sourcepub fn fastest() -> Self
pub fn fastest() -> Self
Create encoder with fastest settings (libjpeg-turbo compatible).
Disables all mozjpeg-specific optimizations for maximum encoding speed. Output is compatible with standard libjpeg/libjpeg-turbo.
§Settings (differences from new() in bold)
| Setting | Value | Notes |
|---|---|---|
| quality | 75 | Same as new() |
| progressive | false | Same as new() |
| trellis | disabled | No trellis quantization |
| optimize_huffman | false | Uses default Huffman tables |
| overshoot_deringing | false | No deringing filter |
| force_baseline | true | 8-bit DQT only |
§Performance
Encoding is ~4-10x faster than new(), but files are ~10-20% larger.
§Example
use mozjpeg_rs::Encoder;
// Fast encoding for real-time applications
let pixels: Vec<u8> = vec![128; 256 * 256 * 3];
let jpeg = Encoder::fastest()
.quality(80)
.encode_rgb(&pixels, 256, 256)
.unwrap();Sourcepub fn quality(self, quality: u8) -> Self
pub fn quality(self, quality: u8) -> Self
Set quality level (1-100).
Higher values produce larger, higher-quality images.
Sourcepub fn progressive(self, enable: bool) -> Self
pub fn progressive(self, enable: bool) -> Self
Enable or disable progressive mode.
Sourcepub fn subsampling(self, mode: Subsampling) -> Self
pub fn subsampling(self, mode: Subsampling) -> Self
Set chroma subsampling mode.
Sourcepub fn quant_tables(self, idx: QuantTableIdx) -> Self
pub fn quant_tables(self, idx: QuantTableIdx) -> Self
Set quantization table variant.
Sourcepub fn trellis(self, config: TrellisConfig) -> Self
pub fn trellis(self, config: TrellisConfig) -> Self
Configure trellis quantization.
Sourcepub fn force_baseline(self, enable: bool) -> Self
pub fn force_baseline(self, enable: bool) -> Self
Force baseline-compatible output.
Sourcepub fn optimize_huffman(self, enable: bool) -> Self
pub fn optimize_huffman(self, enable: bool) -> Self
Enable Huffman table optimization.
Sourcepub fn overshoot_deringing(self, enable: bool) -> Self
pub fn overshoot_deringing(self, enable: bool) -> Self
Enable overshoot deringing.
Reduces visible ringing artifacts near hard edges, especially on white backgrounds. Works by allowing encoded values to “overshoot” above 255 (which will clamp back to 255 when decoded) to create smoother waveforms.
This is a mozjpeg-specific feature that can improve visual quality at minimal file size cost. Enabled by default.
Sourcepub fn optimize_scans(self, enable: bool) -> Self
pub fn optimize_scans(self, enable: bool) -> Self
Enable or disable scan optimization for progressive mode.
When enabled, the encoder tries multiple scan configurations and picks the one that produces the smallest output. This can improve compression by 1-3% but increases encoding time.
Only has effect when progressive mode is enabled.
Sourcepub fn smoothing(self, factor: u8) -> Self
pub fn smoothing(self, factor: u8) -> Self
Set input smoothing factor (0-100).
Applies a weighted average filter to reduce fine-scale noise in the input image before encoding. This is particularly useful for converting dithered images (like GIFs) to JPEG.
- 0 = disabled (default)
- 10-50 = recommended for dithered images
- Higher values = more smoothing (may blur the image)
§Example
use mozjpeg_rs::Encoder;
// Convert a dithered GIF to JPEG with smoothing
let encoder = Encoder::baseline_optimized()
.quality(85)
.smoothing(30);Sourcepub fn restart_interval(self, interval: u16) -> Self
pub fn restart_interval(self, interval: u16) -> Self
Set restart interval in MCUs.
Restart markers are inserted every N MCUs, which can help with error recovery and parallel decoding. Set to 0 to disable (default).
Common values: 0 (disabled), or image width in MCUs for row-by-row restarts.
Sourcepub fn exif_data(self, data: Vec<u8>) -> Self
pub fn exif_data(self, data: Vec<u8>) -> Self
Set EXIF data to embed in the JPEG.
§Arguments
data- Raw EXIF data (TIFF structure). The “Exif\0\0” header will be added automatically.
Pass empty or call without this method to omit EXIF data.
Sourcepub fn pixel_density(self, density: PixelDensity) -> Self
pub fn pixel_density(self, density: PixelDensity) -> Self
Set pixel density for the JFIF APP0 marker.
This specifies the physical pixel density (DPI/DPC) or aspect ratio. Note that most software ignores JFIF density in favor of EXIF metadata.
§Example
use mozjpeg_rs::{Encoder, PixelDensity};
let encoder = Encoder::baseline_optimized()
.pixel_density(PixelDensity::dpi(300, 300)); // 300 DPISourcepub fn icc_profile(self, profile: Vec<u8>) -> Self
pub fn icc_profile(self, profile: Vec<u8>) -> Self
Set ICC color profile to embed.
The profile will be embedded in APP2 markers with the standard “ICC_PROFILE” identifier. Large profiles are automatically chunked.
§Arguments
profile- Raw ICC profile data
Sourcepub fn add_marker(self, app_num: u8, data: Vec<u8>) -> Self
pub fn add_marker(self, app_num: u8, data: Vec<u8>) -> Self
Add a custom APP marker.
§Arguments
app_num- APP marker number (0-15, e.g., 1 for EXIF, 2 for ICC)data- Raw marker data (including any identifier prefix)
Multiple markers with the same number are allowed. Markers are written in the order they are added.
Sourcepub fn custom_luma_qtable(self, table: [u16; 64]) -> Self
pub fn custom_luma_qtable(self, table: [u16; 64]) -> Self
Set custom luminance quantization table.
This overrides the table selected by quant_tables().
Values should be in natural (row-major) order, not zigzag.
§Arguments
table- 64 quantization values (quality scaling still applies)
Sourcepub fn custom_chroma_qtable(self, table: [u16; 64]) -> Self
pub fn custom_chroma_qtable(self, table: [u16; 64]) -> Self
Set custom chrominance quantization table.
This overrides the table selected by quant_tables().
Values should be in natural (row-major) order, not zigzag.
§Arguments
table- 64 quantization values (quality scaling still applies)
Sourcepub fn limits(self, limits: Limits) -> Self
pub fn limits(self, limits: Limits) -> Self
Set resource limits for the encoder.
Limits can restrict:
- Maximum image width and height
- Maximum pixel count (width × height)
- Maximum estimated memory allocation
- Maximum ICC profile size
§Example
use mozjpeg_rs::{Encoder, Preset, Limits};
let limits = Limits::default()
.max_width(4096)
.max_height(4096)
.max_pixel_count(16_000_000)
.max_alloc_bytes(100 * 1024 * 1024);
let encoder = Encoder::new(Preset::default())
.limits(limits);Sourcepub fn baseline(self, enable: bool) -> Self
pub fn baseline(self, enable: bool) -> Self
Set baseline mode (opposite of progressive).
When true, produces a sequential JPEG (non-progressive).
This is equivalent to progressive(false).
§Example
use mozjpeg_rs::Encoder;
// These are equivalent:
let enc1 = Encoder::baseline_optimized().baseline(true);
let enc2 = Encoder::baseline_optimized().progressive(false);Sourcepub fn optimize_coding(self, enable: bool) -> Self
pub fn optimize_coding(self, enable: bool) -> Self
Enable or disable Huffman coding optimization.
Alias for optimize_huffman().
This name matches mozjpeg’s CLI flag naming.
Sourcepub fn chroma_subsampling(self, mode: Subsampling) -> Self
pub fn chroma_subsampling(self, mode: Subsampling) -> Self
Set chroma subsampling mode.
Alias for subsampling().
Sourcepub fn qtable(self, idx: QuantTableIdx) -> Self
pub fn qtable(self, idx: QuantTableIdx) -> Self
Set quantization table variant.
Alias for quant_tables().
Sourcepub fn estimate_resources(&self, width: u32, height: u32) -> ResourceEstimate
pub fn estimate_resources(&self, width: u32, height: u32) -> ResourceEstimate
Estimate resource usage for encoding an RGB image of the given dimensions.
Returns peak memory usage (in bytes) and a relative CPU cost multiplier. Useful for scheduling, enforcing resource limits, or providing feedback.
§Arguments
width- Image width in pixelsheight- Image height in pixels
§Example
use mozjpeg_rs::{Encoder, Preset};
let encoder = Encoder::new(Preset::ProgressiveBalanced).quality(85);
let estimate = encoder.estimate_resources(1920, 1080);
println!("Peak memory: {} MB", estimate.peak_memory_bytes / 1_000_000);
println!("Relative CPU cost: {:.1}x", estimate.cpu_cost_multiplier);Sourcepub fn estimate_resources_gray(
&self,
width: u32,
height: u32,
) -> ResourceEstimate
pub fn estimate_resources_gray( &self, width: u32, height: u32, ) -> ResourceEstimate
Estimate resource usage for encoding a grayscale image.
Similar to estimate_resources but for single-channel images.
Sourcepub fn encode_rgb_cancellable(
&self,
rgb_data: &[u8],
width: u32,
height: u32,
cancel: Option<&AtomicBool>,
timeout: Option<Duration>,
) -> Result<Vec<u8>>
pub fn encode_rgb_cancellable( &self, rgb_data: &[u8], width: u32, height: u32, cancel: Option<&AtomicBool>, timeout: Option<Duration>, ) -> Result<Vec<u8>>
Encode RGB image data to JPEG with cancellation and timeout support.
This method allows encoding to be cancelled mid-operation via an atomic flag, or to automatically abort if a timeout is exceeded.
§Arguments
rgb_data- RGB pixel data (3 bytes per pixel, row-major)width- Image width in pixelsheight- Image height in pixelscancel- Optional cancellation flag. Set totrueto abort encoding.timeout- Optional maximum encoding duration.
§Returns
Ok(Vec<u8>)- JPEG-encoded dataErr(Error::Cancelled)- If cancelled via the flagErr(Error::TimedOut)- If the timeout was exceeded
§Example
use mozjpeg_rs::{Encoder, Preset};
use std::sync::atomic::AtomicBool;
use std::time::Duration;
let encoder = Encoder::new(Preset::ProgressiveBalanced);
let pixels: Vec<u8> = vec![128; 1920 * 1080 * 3];
let cancel = AtomicBool::new(false);
// Encode with 5 second timeout
let result = encoder.encode_rgb_cancellable(
&pixels, 1920, 1080,
Some(&cancel),
Some(Duration::from_secs(5)),
);Sourcepub fn encode_gray_cancellable(
&self,
gray_data: &[u8],
width: u32,
height: u32,
cancel: Option<&AtomicBool>,
timeout: Option<Duration>,
) -> Result<Vec<u8>>
pub fn encode_gray_cancellable( &self, gray_data: &[u8], width: u32, height: u32, cancel: Option<&AtomicBool>, timeout: Option<Duration>, ) -> Result<Vec<u8>>
Encode grayscale image data to JPEG with cancellation and timeout support.
This method allows encoding to be cancelled mid-operation via an atomic flag, or to automatically abort if a timeout is exceeded.
§Arguments
gray_data- Grayscale pixel data (1 byte per pixel, row-major)width- Image width in pixelsheight- Image height in pixelscancel- Optional cancellation flag. Set totrueto abort encoding.timeout- Optional maximum encoding duration.
§Returns
Ok(Vec<u8>)- JPEG-encoded dataErr(Error::Cancelled)- If cancelled via the flagErr(Error::TimedOut)- If the timeout was exceeded
Sourcepub fn encode_gray_to_writer<W: Write>(
&self,
gray_data: &[u8],
width: u32,
height: u32,
output: W,
) -> Result<()>
pub fn encode_gray_to_writer<W: Write>( &self, gray_data: &[u8], width: u32, height: u32, output: W, ) -> Result<()>
Encode grayscale image data to a writer.
Sourcepub fn encode_ycbcr_planar(
&self,
y: &[u8],
cb: &[u8],
cr: &[u8],
width: u32,
height: u32,
) -> Result<Vec<u8>>
pub fn encode_ycbcr_planar( &self, y: &[u8], cb: &[u8], cr: &[u8], width: u32, height: u32, ) -> Result<Vec<u8>>
Encode pre-converted planar YCbCr image data to JPEG.
This method accepts tightly packed YCbCr data (no row padding).
For strided data, use encode_ycbcr_planar_strided.
§Arguments
y- Luma plane (width × height bytes, tightly packed)cb- Cb chroma plane (chroma_width × chroma_height bytes)cr- Cr chroma plane (chroma_width × chroma_height bytes)width- Image width in pixelsheight- Image height in pixels
The chroma plane dimensions depend on the subsampling mode:
- 4:4:4: chroma_width = width, chroma_height = height
- 4:2:2: chroma_width = ceil(width/2), chroma_height = height
- 4:2:0: chroma_width = ceil(width/2), chroma_height = ceil(height/2)
§Returns
JPEG-encoded data as a Vec<u8>.
§Errors
Returns an error if plane sizes don’t match expected dimensions.
Sourcepub fn encode_ycbcr_planar_to_writer<W: Write>(
&self,
y: &[u8],
cb: &[u8],
cr: &[u8],
width: u32,
height: u32,
output: W,
) -> Result<()>
pub fn encode_ycbcr_planar_to_writer<W: Write>( &self, y: &[u8], cb: &[u8], cr: &[u8], width: u32, height: u32, output: W, ) -> Result<()>
Encode pre-converted planar YCbCr image data to a writer.
See encode_ycbcr_planar for details.
Sourcepub fn encode_ycbcr_planar_strided(
&self,
y: &[u8],
y_stride: usize,
cb: &[u8],
cb_stride: usize,
cr: &[u8],
cr_stride: usize,
width: u32,
height: u32,
) -> Result<Vec<u8>>
pub fn encode_ycbcr_planar_strided( &self, y: &[u8], y_stride: usize, cb: &[u8], cb_stride: usize, cr: &[u8], cr_stride: usize, width: u32, height: u32, ) -> Result<Vec<u8>>
Encode pre-converted planar YCbCr image data with arbitrary strides.
This method accepts YCbCr data that has already been:
- Converted from RGB to YCbCr color space
- Downsampled according to the encoder’s subsampling mode
Use this when you have YCbCr data from video decoders or other sources that may have row padding (stride > width).
§Arguments
y- Luma plane datay_stride- Bytes per row in luma plane (must be >= width)cb- Cb chroma plane datacb_stride- Bytes per row in Cb plane (must be >= chroma_width)cr- Cr chroma plane datacr_stride- Bytes per row in Cr plane (must be >= chroma_width)width- Image width in pixelsheight- Image height in pixels
The chroma plane dimensions depend on the subsampling mode:
- 4:4:4: chroma_width = width, chroma_height = height
- 4:2:2: chroma_width = ceil(width/2), chroma_height = height
- 4:2:0: chroma_width = ceil(width/2), chroma_height = ceil(height/2)
§Returns
JPEG-encoded data as a Vec<u8>.
§Errors
Returns an error if:
- Strides are less than the required width
- Plane sizes don’t match stride × height
Sourcepub fn encode_ycbcr_planar_strided_to_writer<W: Write>(
&self,
y: &[u8],
y_stride: usize,
cb: &[u8],
cb_stride: usize,
cr: &[u8],
cr_stride: usize,
width: u32,
height: u32,
output: W,
) -> Result<()>
pub fn encode_ycbcr_planar_strided_to_writer<W: Write>( &self, y: &[u8], y_stride: usize, cb: &[u8], cb_stride: usize, cr: &[u8], cr_stride: usize, width: u32, height: u32, output: W, ) -> Result<()>
Encode pre-converted planar YCbCr image data with arbitrary strides to a writer.
See encode_ycbcr_planar_strided for details.
Source§impl Encoder
impl Encoder
Sourcepub fn streaming() -> StreamingEncoder
pub fn streaming() -> StreamingEncoder
Create a streaming encoder.
Returns a StreamingEncoder which supports scanline-by-scanline encoding.
Note that streaming mode does NOT support trellis quantization, progressive
mode, or Huffman optimization (these require buffering the entire image).
For full-featured encoding with all mozjpeg optimizations, use [Encoder::new(Preset)]
with encode_rgb() or encode_gray().
§Example
use mozjpeg_rs::Encoder;
use std::fs::File;
let file = File::create("output.jpg")?;
let mut stream = Encoder::streaming()
.quality(85)
.start_rgb(1920, 1080, file)?;
// Write scanlines...
stream.finish()?;