Skip to main content

Encoder

Struct Encoder 

Source
pub struct Encoder { /* private fields */ }
Expand description

Builds a .lumen file.

Implementations§

Source§

impl Encoder

Source

pub fn new(head: Head, meta: Meta) -> Encoder

Start a file with the given HEAD and META.

head.total_layers must equal the number of layers pushed.

Source

pub fn set_profile(&mut self, profile: Profile)

Attach a reusable print profile.

Source

pub fn set_sectors(&mut self, sectors: Vec<Sector>)

Declare the non-zero sectors this print uses, as META.sectors.

Sector 0 is implicit and must not appear; a sector carries no material until its entry names one.

Source

pub fn set_overrides(&mut self, overrides: Vec<Override>) -> Result<()>

Attach the per-(layer, sector) timing deltas.

Each pair’s matching LTBL entry points at an LROV chunk, and pairs whose deltas are equal share one: a delta set on a range - or on any set of pairs - costs one chunk, and every entry that names it applies it. A layer emitted here also gets a table entry for that sector even when the layer holds no data for it, which is how an override reaches a sector a layer does not print.

Source

pub fn add_preview(&mut self, role: PreviewRole, png: Vec<u8>)

Add a PNG preview.

Source

pub fn add_extension(&mut self, extension: Extension)

Add a vendor or standard extension.

Source

pub fn set_voxl(&mut self, voxl: Vec<u8>)

Embed the scene that produced this print, verbatim.

Source

pub fn set_layers_per_chunk(&mut self, layers: u32)

How many layers one LAYR chunk spans.

Source

pub fn set_tag_probe(&mut self, enabled: bool)

Whether to encode each layer group both ways and keep the smaller.

On by default. A group’s layers are encoded with the tag EncodeMode::Auto chooses and with EncodeMode::Attached, both are compressed exactly as the file will frame them, and the smaller result is kept. The comparison is what makes the attached form a gain rather than a gamble: its raw size is not a guide to its compressed size, so an encoder that picked it by bytes alone would lose on a print whose layers barely change.

The probe costs one extra encoding and one extra compression of every layer group, and it measures without the ZDIC dictionary, which is only trained once the whole print has been pushed. Turning it off means every layer is stored with the tag EncodeMode::Auto picks.

Source

pub fn set_zstd_level(&mut self, level: i32)

zstd compression level for the layer chunks.

Source

pub fn set_dictionary(&mut self, enabled: bool)

Whether to train and emit a ZDIC dictionary (section 6.2).

Enabled, the writer samples the print, trains a dictionary and writes it if the data says it pays - see [dictionary_pays]. Disabled, it compresses every frame without one, which is a smaller file than a dictionary that does not fit the print.

Source

pub fn set_layer_hashes(&mut self, enabled: bool)

Whether to emit an LHAS integrity tree.

Source

pub fn set_worker_threads(&mut self, threads: usize)

How many threads finish may frame chunks and hash layers on.

0, what a fresh encoder starts with, means one per available core, and a request above that is capped by it: this is CPU-bound work on data already in memory, so a thread beyond the cores available would take time from another rather than spend a wait. 1 is the serial path, and it writes the same bytes any other count does - the output of this encoder is a function of its input and settings alone, as section 5.7 intends.

Source

pub fn set_encryption(&mut self, options: EncryptOptions)

Encrypt the file.

Source

pub fn session_key(&self) -> Option<SessionKey>

The session key this encoder uses, for a caller that wants to keep it.

Source

pub fn push_layer(&mut self, pixels: &[u8]) -> Result<()>

Push one layer’s mask, choosing its encoding per EncodeMode::Auto.

The mask is sector 0’s: it is what a single-material reader prints.

Source

pub fn push_layer_with_mode( &mut self, pixels: &[u8], mode: EncodeMode, ) -> Result<()>

Push one layer’s mask with an explicit encoding.

Source

pub fn push_layer_sectors(&mut self, sectors: &[(u32, Vec<u8>)]) -> Result<()>

Push one layer as a set of sectors, each with its own mask.

Sector 0 is implicit, so a layer whose only content is sector 0 is pushed with Encoder::push_layer instead. A sector with no exposed pixel is omitted, and a layer whose every sector is empty is stored as the empty-layer form. The pairs are sorted by sector, which is the order the layer table requires.

Source

pub fn push_layer_runs(&mut self, runs: &[Run], mode: EncodeMode) -> Result<()>

Push one layer given as runs instead of pixels, as sector 0.

Equivalent to Encoder::push_layer on the mask the runs describe, except that the mask is never built: a slicer’s run-length rasterizer output goes straight to the encoder. The runs must be canonical and cover the layer, as ree::encode_runs requires.

Source

pub fn push_encoded_layer(&mut self, layer: EncodedLayer) -> Result<()>

Push a layer that is already encoded.

This is the parallel path: workers turn one layer’s runs into bytes with ree::encode_runs, and the writer stores each result in layer order without ever seeing pixel data. The streams are checked to carry a layer encoding tag, the sectors are sorted by id as the layer table requires, and a layer with no sector data becomes the empty-layer form.

Source

pub fn push_encoded_layer_pair( &mut self, layer: EncodedLayer, alternative: Option<EncodedLayer>, ) -> Result<()>

Push a layer that is already encoded, with the other encoding the tag probe should weigh it against.

Encoder::push_encoded_layer is this with no alternative. A caller that encodes layers on its own threads - the slicer adapter does, one worker per layer - can hand over the tag 0x03 stream of the same layer as well, and the probe then has two candidates to compress when the group closes. Both must describe the same pixels: the probe’s choice is a choice of encoding, and nothing checks that they agree.

The alternative is stored as it is when the probe is off, which costs the caller nothing but the encoding it computed.

Source

pub fn finish(self) -> Result<Vec<u8>>

Assemble the container.

Fails if the number of pushed layers disagrees with head.total_layers.

Trait Implementations§

Source§

impl Debug for Encoder

Source§

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

Formats the value using the given formatter. 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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V