#![forbid(unsafe_code)]
#![allow(dead_code)]
#![allow(clippy::doc_markdown)]
mod context;
mod dc;
mod directional;
mod filter;
mod modes;
mod paeth;
mod palette;
mod smooth;
pub use context::{IntraPredContext, LeftSamples, NeighborAvailability, TopSamples};
pub use dc::{DcMode, DcPredictor};
pub use directional::{
D113Predictor, D117Predictor, D135Predictor, D153Predictor, D157Predictor, D203Predictor,
D207Predictor, D45Predictor, D63Predictor, D67Predictor, DirectionalPredictor,
HorizontalPredictor, VerticalPredictor,
};
pub use filter::{apply_intra_filter, FilterStrength, IntraEdgeFilter};
pub use modes::{AngleDelta, DirectionalMode, IntraMode, IntraPredictor, NonDirectionalMode};
pub use paeth::{paeth_predictor, PaethPredictor};
pub use palette::{ColorCache, PaletteInfo, PalettePredictor};
pub use smooth::{SmoothHPredictor, SmoothPredictor, SmoothVPredictor};
pub const MAX_BLOCK_SIZE: usize = 128;
pub const MAX_NEIGHBOR_SAMPLES: usize = 2 * MAX_BLOCK_SIZE + 1;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum BitDepth {
#[default]
Bits8 = 8,
Bits10 = 10,
Bits12 = 12,
}
impl BitDepth {
#[must_use]
pub const fn max_value(self) -> u16 {
match self {
Self::Bits8 => 255,
Self::Bits10 => 1023,
Self::Bits12 => 4095,
}
}
#[must_use]
pub const fn midpoint(self) -> u16 {
match self {
Self::Bits8 => 128,
Self::Bits10 => 512,
Self::Bits12 => 2048,
}
}
#[must_use]
pub const fn bits(self) -> u8 {
match self {
Self::Bits8 => 8,
Self::Bits10 => 10,
Self::Bits12 => 12,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BlockDimensions {
pub width: usize,
pub height: usize,
}
impl BlockDimensions {
#[must_use]
pub const fn new(width: usize, height: usize) -> Self {
Self { width, height }
}
#[must_use]
pub const fn num_samples(self) -> usize {
self.width * self.height
}
#[must_use]
pub const fn is_square(self) -> bool {
self.width == self.height
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bit_depth_values() {
assert_eq!(BitDepth::Bits8.max_value(), 255);
assert_eq!(BitDepth::Bits10.max_value(), 1023);
assert_eq!(BitDepth::Bits12.max_value(), 4095);
assert_eq!(BitDepth::Bits8.midpoint(), 128);
assert_eq!(BitDepth::Bits10.midpoint(), 512);
assert_eq!(BitDepth::Bits12.midpoint(), 2048);
assert_eq!(BitDepth::Bits8.bits(), 8);
assert_eq!(BitDepth::Bits10.bits(), 10);
assert_eq!(BitDepth::Bits12.bits(), 12);
}
#[test]
fn test_block_dimensions() {
let dim = BlockDimensions::new(8, 8);
assert_eq!(dim.num_samples(), 64);
assert!(dim.is_square());
let rect = BlockDimensions::new(16, 8);
assert_eq!(rect.num_samples(), 128);
assert!(!rect.is_square());
}
}