pub struct EncoderConfig { /* private fields */ }Expand description
JPEG encoder configuration. Dimension-independent, reusable across images.
Implementations§
Source§impl EncoderConfig
impl EncoderConfig
Sourcepub fn ycbcr(
quality: impl Into<Quality>,
subsampling: ChromaSubsampling,
) -> Self
pub fn ycbcr( quality: impl Into<Quality>, subsampling: ChromaSubsampling, ) -> Self
Create a YCbCr encoder configuration.
YCbCr is the standard JPEG color space, compatible with all decoders.
§Arguments
quality: Quality level (0-100 for jpegli scale, or useQuality::*variants)subsampling: Chroma subsampling modeChromaSubsampling::None(4:4:4) - best quality, larger filesChromaSubsampling::Quarter(4:2:0) - good compression, smaller filesChromaSubsampling::HalfHorizontal(4:2:2) - horizontal onlyChromaSubsampling::HalfVertical(4:4:0) - vertical only
§Example
use jpegli::encoder::{EncoderConfig, ChromaSubsampling};
let config = EncoderConfig::ycbcr(85, ChromaSubsampling::Quarter)
.progressive(true);Sourcepub fn xyb(quality: impl Into<Quality>, b_subsampling: XybSubsampling) -> Self
pub fn xyb(quality: impl Into<Quality>, b_subsampling: XybSubsampling) -> Self
Create an XYB encoder configuration.
XYB is a perceptual color space that can achieve better quality at the same file size for some images. The B (blue-yellow) channel can optionally be subsampled since it’s less perceptually important.
§Arguments
quality: Quality level (0-100 for jpegli scale, or useQuality::*variants)b_subsampling: B channel subsamplingXybSubsampling::Full- all channels at full resolutionXybSubsampling::BQuarter- B channel at quarter resolution (default, recommended)
§Notes
- Requires linear RGB input (f32 or u16 pixel formats)
- Embeds an ICC profile for proper color reproduction
- Not all decoders support XYB JPEGs correctly
§Example
use jpegli::encoder::{EncoderConfig, XybSubsampling};
let config = EncoderConfig::xyb(85, XybSubsampling::BQuarter)
.progressive(true);Sourcepub fn grayscale(quality: impl Into<Quality>) -> Self
pub fn grayscale(quality: impl Into<Quality>) -> Self
Create a grayscale encoder configuration.
Only the luminance channel is encoded. Works with any input format; color inputs are converted to grayscale.
§Arguments
quality: Quality level (0-100 for jpegli scale, or useQuality::*variants)
§Example
use jpegli::encoder::EncoderConfig;
let config = EncoderConfig::grayscale(85)
.progressive(true);Sourcepub fn quality(self, q: impl Into<Quality>) -> Self
pub fn quality(self, q: impl Into<Quality>) -> Self
Override the quality level.
Accepts any type that converts to Quality:
f32oru8for ApproxJpegli scaleQuality::ApproxMozjpeg(u8)for mozjpeg-like qualityQuality::ApproxSsim2(f32)for SSIMULACRA2 targetQuality::ApproxButteraugli(f32)for Butteraugli target
Sourcepub fn progressive(self, enable: bool) -> Self
pub fn progressive(self, enable: bool) -> Self
Enable or disable progressive encoding.
Progressive encoding produces multiple scans for incremental display. Automatically enables optimized Huffman tables (required for progressive).
Sourcepub fn optimize_huffman(self, enable: bool) -> Self
pub fn optimize_huffman(self, enable: bool) -> Self
Enable or disable Huffman table optimization.
When enabled (default), computes optimal Huffman tables from image data. When disabled, uses standard JPEG Huffman tables (faster but larger files).
Note: Progressive mode requires optimized Huffman tables.
Sourcepub fn allow_16bit_quant_tables(self, enable: bool) -> Self
pub fn allow_16bit_quant_tables(self, enable: bool) -> Self
Allow 16-bit quantization tables (extended sequential JPEG, SOF1).
When enabled (default), quantization values can exceed 255, producing extended sequential JPEGs (SOF1 marker) for better low-quality precision.
When disabled, quantization values are clamped to 255, producing baseline-compatible JPEGs (SOF0 marker) that work with all decoders.
Most modern decoders support 16-bit quant tables. Only disable this for maximum compatibility with legacy software.
Sourcepub fn separate_chroma_tables(self, enable: bool) -> Self
pub fn separate_chroma_tables(self, enable: bool) -> Self
Use separate quantization tables for Cb and Cr components.
When enabled (default), uses 3 quantization tables:
- Table 0: Y (luma)
- Table 1: Cb (blue chroma)
- Table 2: Cr (red chroma)
When disabled, uses 2 quantization tables:
- Table 0: Y (luma)
- Table 1: Cb and Cr (shared chroma)
§Compatibility
- 3 tables (default): Matches C++ jpegli’s
jpegli_set_distance()behavior - 2 tables: Matches C++ jpegli’s
jpeg_set_quality()behavior
Use 2 tables when you need exact output parity with tools that use
jpeg_set_quality() (most libjpeg-based encoders).
§Example
// Match jpeg_set_quality() behavior (2 tables)
let config = EncoderConfig::ycbcr(85, ChromaSubsampling::Quarter)
.separate_chroma_tables(false);Sourcepub fn force_baseline(self) -> Self
pub fn force_baseline(self) -> Self
Force baseline JPEG compatibility.
This is a convenience method equivalent to:
config.progressive(false).allow_16bit_quant_tables(false)Baseline JPEGs (SOF0) are the most compatible format, supported by all JPEG decoders. Use this when targeting legacy software or when maximum compatibility is required.
Sourcepub fn restart_interval(self, interval: u16) -> Self
pub fn restart_interval(self, interval: u16) -> Self
Set the restart interval (MCUs between restart markers).
Restart markers allow partial decoding and error recovery. Set to 0 to disable restart markers (default).
Sourcepub fn icc_profile(self, profile: impl Into<Vec<u8>>) -> Self
pub fn icc_profile(self, profile: impl Into<Vec<u8>>) -> Self
Attach an ICC color profile to the output JPEG.
The profile will be written as APP2 marker segments with the standard “ICC_PROFILE” signature. Large profiles are automatically chunked (max 65519 bytes per segment) as required by the ICC profile embedding spec.
Common profiles:
- sRGB IEC61966-2.1 (~3KB)
- Display P3 (~0.5KB)
- Adobe RGB 1998 (~0.5KB)
§Example
use jpegli::{EncoderConfig, ChromaSubsampling};
let srgb_profile = std::fs::read("sRGB.icc")?;
let config = EncoderConfig::ycbcr(85.0, ChromaSubsampling::Quarter)
.icc_profile(srgb_profile);Sourcepub fn exif(self, exif: impl Into<Exif>) -> Self
pub fn exif(self, exif: impl Into<Exif>) -> Self
Attach EXIF metadata to the output JPEG.
Use Exif::raw for raw EXIF bytes, or
Exif::build to construct from common fields.
The two modes are mutually exclusive at compile time - you cannot mix raw bytes with field-based building.
§Examples
Build from fields (orientation and copyright):
use jpegli::encoder::{EncoderConfig, ChromaSubsampling, Exif, Orientation};
let config = EncoderConfig::ycbcr(85, ChromaSubsampling::Quarter)
.exif(Exif::build()
.orientation(Orientation::Rotate90)
.copyright("© 2024 Example Corp"));Use raw EXIF bytes:
use jpegli::encoder::{EncoderConfig, ChromaSubsampling, Exif};
let config = EncoderConfig::ycbcr(85, ChromaSubsampling::Quarter)
.exif(Exif::raw(my_exif_bytes));§Notes
- EXIF is placed immediately after SOI, before any other markers
- Raw bytes should be TIFF data without the “Exif\0\0” prefix (added automatically)
- Maximum size: 65527 bytes (larger data will be truncated)
Sourcepub fn xmp(self, data: impl Into<Vec<u8>>) -> Self
pub fn xmp(self, data: impl Into<Vec<u8>>) -> Self
Attach XMP metadata to the output JPEG.
The data will be written as an APP1 marker segment with the standard Adobe XMP namespace signature. The provided bytes should be the raw XMP XML data without the APP1 marker or namespace prefix.
XMP is placed after EXIF (if present) but before ICC profile.
§Maximum Size
Standard XMP is limited to 65502 bytes (65535 - 2 length - 29 namespace - 2 padding). For larger XMP data, use Extended XMP (not yet supported).
Sourcepub fn color_mode(self, mode: ColorMode) -> Self
pub fn color_mode(self, mode: ColorMode) -> Self
Set the output color mode.
Sourcepub fn downsampling_method(self, method: DownsamplingMethod) -> Self
pub fn downsampling_method(self, method: DownsamplingMethod) -> Self
Set the chroma downsampling method.
Only affects RGB/RGBX input with chroma subsampling enabled. Ignored for grayscale, YCbCr input, or 4:4:4 subsampling.
Sourcepub fn tables(self, tables: Box<EncodingTables>) -> Self
pub fn tables(self, tables: Box<EncodingTables>) -> Self
Apply custom encoding tables for experimentation.
This replaces both quantization tables and zero-bias configuration
with values from the provided EncodingTables.
Takes Box<EncodingTables> since custom tables are rarely used and
the struct is ~1.5KB. This keeps EncoderConfig small by default.
§Notes
- Tables must match the color mode (YCbCr or XYB)
- When using
ScalingParams::Exact, quality scaling is bypassed - When using
ScalingParams::Scaled, tables are scaled by quality
§Example
use jpegli::encode::{EncoderConfig, ChromaSubsampling};
use jpegli::encode::tuning::EncodingTables;
let mut tables = EncodingTables::default_ycbcr();
tables.scale_quant(0, 0, 0.8); // Reduce DC quantization
let config = EncoderConfig::ycbcr(85, ChromaSubsampling::Quarter)
.tables(Box::new(tables));Sourcepub fn sharp_yuv(self, enable: bool) -> Self
pub fn sharp_yuv(self, enable: bool) -> Self
Enable or disable SharpYUV (GammaAwareIterative) downsampling.
SharpYUV produces better color preservation on edges and thin lines, at the cost of ~3x slower encoding.
Sourcepub fn deringing(self, enable: bool) -> Self
pub fn deringing(self, enable: bool) -> Self
Enable or disable overshoot deringing (enabled by default).
Deringing reduces ringing artifacts on white backgrounds by smoothing hard edges. It allows pixel values to “overshoot” beyond the displayable range. Since JPEG decoders clamp values to 0-255, the overshoot is invisible but the smoother curve compresses better with fewer artifacts.
This technique was pioneered by @kornel in mozjpeg and significantly improves quality for documents, graphics, and text without degrading photographic content.
Particularly effective for:
- Documents and screenshots with white backgrounds
- Text and graphics with hard edges
- Any image with saturated regions (pixels at 0 or 255)
There is no quality downside to leaving this enabled for photos.
Sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Validate the configuration, returning an error for invalid combinations.
Invalid combinations:
- Progressive mode with disabled Huffman optimization
Sourcepub fn encode_from_bytes(
&self,
width: u32,
height: u32,
layout: PixelLayout,
) -> Result<BytesEncoder>
pub fn encode_from_bytes( &self, width: u32, height: u32, layout: PixelLayout, ) -> Result<BytesEncoder>
Create an encoder from raw bytes with explicit pixel layout.
Use this when working with raw byte buffers and you know the pixel layout.
§Arguments
width: Image width in pixelsheight: Image height in pixelslayout: Pixel data layout (channel order, depth, color space)
§Example
use jpegli::{EncoderConfig, ChromaSubsampling, PixelLayout, Unstoppable};
let config = EncoderConfig::ycbcr(85.0, ChromaSubsampling::Quarter);
let mut enc = config.encode_from_bytes(1920, 1080, PixelLayout::Rgb8Srgb)?;
enc.push_packed(&rgb_bytes, Unstoppable)?;
let jpeg = enc.finish()?;Sourcepub fn encode_from_rgb<P: Pixel>(
&self,
width: u32,
height: u32,
) -> Result<RgbEncoder<P>>
pub fn encode_from_rgb<P: Pixel>( &self, width: u32, height: u32, ) -> Result<RgbEncoder<P>>
Create an encoder from rgb crate pixel types.
Layout is inferred from the type parameter. For RGBA/BGRA types, the 4th channel is ignored.
§Type Parameter
P: Pixel type from thergbcrate (e.g.,RGB<u8>,RGBA<f32>)
§Example
use rgb::RGB;
use jpegli::{EncoderConfig, ChromaSubsampling, Unstoppable};
let config = EncoderConfig::ycbcr(85.0, ChromaSubsampling::Quarter);
let mut enc = config.encode_from_rgb::<RGB<u8>>(1920, 1080)?;
enc.push_packed(&pixels, Unstoppable)?;
let jpeg = enc.finish()?;Sourcepub fn encode_from_ycbcr_planar(
&self,
width: u32,
height: u32,
) -> Result<YCbCrPlanarEncoder>
pub fn encode_from_ycbcr_planar( &self, width: u32, height: u32, ) -> Result<YCbCrPlanarEncoder>
Create an encoder from planar YCbCr data.
Use this when you have pre-converted YCbCr from video decoders, etc. Skips RGB->YCbCr conversion entirely.
Only valid with ColorMode::YCbCr. XYB mode requires RGB input.
§Example
use jpegli::{EncoderConfig, ChromaSubsampling, Unstoppable};
let config = EncoderConfig::ycbcr(85.0, ChromaSubsampling::Quarter);
let mut enc = config.encode_from_ycbcr_planar(1920, 1080)?;
enc.push(&planes, height, Unstoppable)?;
let jpeg = enc.finish()?;Sourcepub fn estimate_memory(&self, width: u32, height: u32) -> usize
pub fn estimate_memory(&self, width: u32, height: u32) -> usize
Estimate peak memory usage for encoding an image of the given dimensions.
Returns estimated bytes based on color mode, subsampling, and dimensions. Delegates to the streaming encoder’s estimate which accounts for all internal buffers.
Sourcepub fn estimate_memory_ceiling(&self, width: u32, height: u32) -> usize
pub fn estimate_memory_ceiling(&self, width: u32, height: u32) -> usize
Returns an absolute ceiling on memory usage.
Unlike estimate_memory, this returns a guaranteed upper bound
that actual peak memory will never exceed. Use this for resource reservation
when you need certainty rather than a close estimate.
The ceiling accounts for:
- Worst-case token counts per block (high-frequency content)
- Maximum output buffer size (incompressible images)
- Vec capacity overhead (allocator rounding)
- All intermediate buffers at their maximum sizes
§Example
use jpegli::encoder::{EncoderConfig, ChromaSubsampling};
let config = EncoderConfig::ycbcr(85.0, ChromaSubsampling::Quarter);
let ceiling = config.estimate_memory_ceiling(1920, 1080);
// Reserve this much memory - actual usage guaranteed to be less
let buffer = Vec::with_capacity(ceiling);Sourcepub fn get_quality(&self) -> Quality
pub fn get_quality(&self) -> Quality
Get the configured quality.
Sourcepub fn get_color_mode(&self) -> ColorMode
pub fn get_color_mode(&self) -> ColorMode
Get the configured color mode.
Sourcepub fn is_progressive(&self) -> bool
pub fn is_progressive(&self) -> bool
Check if progressive mode is enabled.
Sourcepub fn is_optimize_huffman(&self) -> bool
pub fn is_optimize_huffman(&self) -> bool
Check if Huffman optimization is enabled.
Sourcepub fn is_allow_16bit_quant_tables(&self) -> bool
pub fn is_allow_16bit_quant_tables(&self) -> bool
Check if 16-bit quantization tables are allowed.
Sourcepub fn is_separate_chroma_tables(&self) -> bool
pub fn is_separate_chroma_tables(&self) -> bool
Check if separate chroma tables are enabled (3 tables vs 2).
Sourcepub fn get_icc_profile(&self) -> Option<&[u8]>
pub fn get_icc_profile(&self) -> Option<&[u8]>
Get the ICC profile, if set.
Sourcepub fn with_segments(self, segments: EncoderSegments) -> Self
pub fn with_segments(self, segments: EncoderSegments) -> Self
Add prepared segments for injection into output.
Use this to preserve metadata during round-trip encoding or to inject custom metadata and MPF secondary images.
§Example
use jpegli::decoder::Decoder;
use jpegli::encoder::{EncoderConfig, ChromaSubsampling};
// Decode with metadata preservation
let decoded = Decoder::new().decode(&original)?;
let extras = decoded.extras().unwrap();
// Re-encode with same metadata
let config = EncoderConfig::ycbcr(90.0, ChromaSubsampling::Quarter)
.with_segments(extras.to_encoder_segments());Sourcepub fn add_segment(self, marker: u8, data: Vec<u8>) -> Self
pub fn add_segment(self, marker: u8, data: Vec<u8>) -> Self
Add a single segment (convenience method).
The segment type is inferred from the marker and data.
Sourcepub fn add_mpf_image(self, jpeg: Vec<u8>, typ: MpfImageType) -> Self
pub fn add_mpf_image(self, jpeg: Vec<u8>, typ: MpfImageType) -> Self
Add an MPF secondary image (gain map, depth map, etc.).
The image data must be a complete JPEG file. An MPF directory will be automatically generated during encoding.
§Example
use jpegli::encoder::{EncoderConfig, ChromaSubsampling, MpfImageType};
let config = EncoderConfig::ycbcr(90.0, ChromaSubsampling::Quarter)
.add_mpf_image(gainmap_jpeg, MpfImageType::Undefined);Sourcepub fn add_gainmap(self, jpeg: Vec<u8>) -> Self
pub fn add_gainmap(self, jpeg: Vec<u8>) -> Self
Add a gain map (convenience for MpfImageType::Undefined).
Gain maps are used by UltraHDR for HDR rendering. The image data must be a complete JPEG file (typically grayscale).
Sourcepub fn get_segments(&self) -> Option<&EncoderSegments>
pub fn get_segments(&self) -> Option<&EncoderSegments>
Get the configured segments, if any.
Trait Implementations§
Source§impl Clone for EncoderConfig
impl Clone for EncoderConfig
Source§fn clone(&self) -> EncoderConfig
fn clone(&self) -> EncoderConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more