Encoder

Struct Encoder 

Source
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:

§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

Source

pub fn new(preset: Preset) -> Self

Create an encoder with the specified preset.

§Arguments
§Preset Comparison
PresetTimeSizeBest For
BaselineFastest~2msbaselineReal-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();
Source

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
SettingValueNotes
quality75Good balance of size/quality
progressivefalseSequential baseline JPEG
optimize_scansfalseN/A for baseline mode
subsampling4:2:0Standard chroma subsampling
trellisenabledAC + DC trellis quantization
optimize_huffmantrue2-pass for optimal Huffman tables
overshoot_deringingtrueReduces ringing on hard edges
quant_tablesImageMagickSame as C mozjpeg default
force_baselinefalseAllows 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.

Settingbaseline_optimized()C mozjpeg default
progressivefalsetrue
optimize_scansfalsetrue
trellistruetrue
deringingtruetrue

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();
Source

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)
SettingValueNotes
quality75Same as new()
progressivetrueMulti-scan progressive JPEG
optimize_scanstrueTries multiple scan configs
subsampling4:2:0Same as new()
trellisenabledSame as new()
optimize_huffmantrueSame as new()
overshoot_deringingtrueSame 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();
Source

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
SettingValueNotes
progressivetrueMulti-scan progressive JPEG
optimize_scansfalseUses fixed 9-scan config
trellisenabledAC + DC trellis quantization
optimize_huffmantrue2-pass for optimal tables
overshoot_deringingtrueReduces 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();
Source

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)
SettingValueNotes
quality75Same as new()
progressivefalseSame as new()
trellisdisabledNo trellis quantization
optimize_huffmanfalseUses default Huffman tables
overshoot_deringingfalseNo deringing filter
force_baselinetrue8-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();
Source

pub fn quality(self, quality: u8) -> Self

Set quality level (1-100).

Higher values produce larger, higher-quality images.

Source

pub fn progressive(self, enable: bool) -> Self

Enable or disable progressive mode.

Source

pub fn subsampling(self, mode: Subsampling) -> Self

Set chroma subsampling mode.

Source

pub fn quant_tables(self, idx: QuantTableIdx) -> Self

Set quantization table variant.

Source

pub fn trellis(self, config: TrellisConfig) -> Self

Configure trellis quantization.

Source

pub fn force_baseline(self, enable: bool) -> Self

Force baseline-compatible output.

Source

pub fn optimize_huffman(self, enable: bool) -> Self

Enable Huffman table optimization.

Source

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.

Source

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.

Source

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);
Source

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.

Source

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.

Source

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 DPI
Source

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
Source

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.

Source

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)
Source

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)
Source

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);
Source

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);
Source

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.

Source

pub fn chroma_subsampling(self, mode: Subsampling) -> Self

Set chroma subsampling mode.

Alias for subsampling().

Source

pub fn qtable(self, idx: QuantTableIdx) -> Self

Set quantization table variant.

Alias for quant_tables().

Source

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 pixels
  • height - 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);
Source

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.

Source

pub fn encode_rgb( &self, rgb_data: &[u8], width: u32, height: u32, ) -> Result<Vec<u8>>

Encode RGB image data to JPEG.

§Arguments
  • rgb_data - RGB pixel data (3 bytes per pixel, row-major)
  • width - Image width in pixels
  • height - Image height in pixels
§Returns

JPEG-encoded data as a Vec<u8>.

Source

pub fn encode_gray( &self, gray_data: &[u8], width: u32, height: u32, ) -> Result<Vec<u8>>

Encode grayscale image data to JPEG.

§Arguments
  • gray_data - Grayscale pixel data (1 byte per pixel, row-major)
  • width - Image width in pixels
  • height - Image height in pixels
§Returns

JPEG-encoded data as a Vec<u8>.

Source

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 pixels
  • height - Image height in pixels
  • cancel - Optional cancellation flag. Set to true to abort encoding.
  • timeout - Optional maximum encoding duration.
§Returns
  • Ok(Vec<u8>) - JPEG-encoded data
  • Err(Error::Cancelled) - If cancelled via the flag
  • Err(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)),
);
Source

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 pixels
  • height - Image height in pixels
  • cancel - Optional cancellation flag. Set to true to abort encoding.
  • timeout - Optional maximum encoding duration.
§Returns
  • Ok(Vec<u8>) - JPEG-encoded data
  • Err(Error::Cancelled) - If cancelled via the flag
  • Err(Error::TimedOut) - If the timeout was exceeded
Source

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.

Source

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 pixels
  • height - 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.

Source

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.

Source

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:

  1. Converted from RGB to YCbCr color space
  2. 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 data
  • y_stride - Bytes per row in luma plane (must be >= width)
  • cb - Cb chroma plane data
  • cb_stride - Bytes per row in Cb plane (must be >= chroma_width)
  • cr - Cr chroma plane data
  • cr_stride - Bytes per row in Cr plane (must be >= chroma_width)
  • width - Image width in pixels
  • height - 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
Source

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

pub fn encode_rgb_to_writer<W: Write>( &self, rgb_data: &[u8], width: u32, height: u32, output: W, ) -> Result<()>

Encode RGB image data to a writer.

Source§

impl Encoder

Source

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()?;

Trait Implementations§

Source§

impl Clone for Encoder

Source§

fn clone(&self) -> Encoder

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Encoder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Encoder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Encode for Encoder

Source§

fn encode_rgb( &self, rgb_data: &[u8], width: u32, height: u32, ) -> Result<Vec<u8>>

Encode RGB image data to JPEG. Read more
Source§

fn encode_gray( &self, gray_data: &[u8], width: u32, height: u32, ) -> Result<Vec<u8>>

Encode grayscale image data to JPEG. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.