main
//! Fixed preview geometry. These are deliberately constants instead of config:
//! the preview is a product decision (what a list view loads), not a per-host
//! tuning knob, and every deployment must produce identical derivatives for the
//! same upload.
/// Longest-edge ceiling for full-content images (chat pictures, banners).
pub const CONTENT_MAX_EDGE: u32 = 1920;
/// Longest-edge ceiling for avatar-shaped images.
pub const AVATAR_MAX_EDGE: u32 = 512;
/// JPEG quality for the opaque preview encoding.
pub const JPEG_QUALITY: u8 = 82;
/// Sources above this size are served as-is instead of being decoded.
pub const MAX_SOURCE_BYTES: u64 = 32 * 1024 * 1024;
/// Decoded pixel ceiling; guards against decompression bombs.
pub const MAX_DECODE_PIXELS: u64 = 40_000_000;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PreviewPreset {
/// Small, square-ish target for avatars and space avatars.
Avatar,
/// General picture target for chat attachments and space banners.
Content,
}
impl PreviewPreset {
#[must_use]
pub fn max_edge(self) -> u32 {
match self {
Self::Avatar => AVATAR_MAX_EDGE,
Self::Content => CONTENT_MAX_EDGE,
}
}
#[must_use]
pub fn jpeg_quality(self) -> u8 {
JPEG_QUALITY
}
#[must_use]
pub fn max_source_bytes(self) -> u64 {
MAX_SOURCE_BYTES
}
#[must_use]
pub fn max_decode_pixels(self) -> u64 {
MAX_DECODE_PIXELS
}
/// Whether a source alpha channel must survive into the preview. Avatars and
/// pictures can both be cut-outs, so both keep it.
#[must_use]
pub fn keep_alpha(self) -> bool {
true
}
}