Files
photocraft/crates/psd/src/image_data.rs
T
Brandon ThomasandClaude Opus 5.5 f7eb6ea9e7 Format: adopt the craft-family rustfmt.toml and format the workspace
CI's `cargo fmt --all -- --check` has failed on every run because the
repo had no rustfmt config and was never formatted. Use the same settings
as EffectCraft/FilmCraft (max_width 160, use_small_heuristics Max), which
also keeps the churn small. Formatting only; no code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:31:17 -04:00

58 lines
2.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Merged (composite) image data section.
use crate::compression::{Compression, PlaneLayout, decode_planes, encode_planes, validate_planes};
use crate::error::Result;
use crate::header::Header;
use crate::io::Reader;
/// The merged image: compression plus the encoded bytes of all channels
/// (to the end of the file), kept verbatim.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImageData {
/// Compression method for the whole image.
pub compression: Compression,
/// Encoded data. For RLE: the byte-count table for every row of every
/// channel followed by the rows.
pub data: Vec<u8>,
}
impl ImageData {
/// Plane layout for the merged image described by `header`.
pub fn layout(header: &Header) -> PlaneLayout {
PlaneLayout {
planes: usize::from(header.channels),
width: header.width as usize,
height: header.height as usize,
depth: header.depth,
version: header.version,
}
}
/// Encodes planar data (`channels × height × row_bytes`).
pub fn encode(compression: Compression, decoded: &[u8], header: &Header) -> Result<Self> {
Ok(ImageData { compression, data: encode_planes(compression, decoded, &Self::layout(header))? })
}
/// Decodes all channels into planar big-endian samples.
pub fn decode(&self, header: &Header) -> Result<Vec<u8>> {
decode_planes(self.compression, &self.data, &Self::layout(header))
}
/// Decodes and returns a single channel plane.
pub fn decode_channel(&self, header: &Header, index: usize) -> Result<Vec<u8>> {
let all = self.decode(header)?;
let plane = header.row_bytes() * header.height as usize;
all.get(index * plane..(index + 1) * plane).map(<[u8]>::to_vec).ok_or_else(|| crate::error::PsdError::invalid(format!("no merged channel {index}")))
}
pub(crate) fn read(r: &mut Reader<'_>, header: &Header) -> Result<Self> {
let compression = Compression::from_u16(r.u16()?);
let data = r.peek_rest();
validate_planes(compression, data, &Self::layout(header))?;
let data = data.to_vec();
r.skip(data.len())?;
Ok(ImageData { compression, data })
}
}