#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColorSpace {
Grayscale,
YCbCr,
Rgb,
Cmyk,
Ycck,
Unknown,
}
impl ColorSpace {
pub fn num_components(self) -> usize {
match self {
Self::Grayscale => 1,
Self::YCbCr | Self::Rgb => 3,
Self::Cmyk | Self::Ycck => 4,
Self::Unknown => 3,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Subsampling {
S444,
S422,
S420,
S440,
S411,
S441,
Unknown,
}
impl Subsampling {
pub fn mcu_width_blocks(self) -> usize {
match self {
Self::S444 | Self::S440 | Self::S441 | Self::Unknown => 1,
Self::S422 | Self::S420 => 2,
Self::S411 => 4,
}
}
pub fn mcu_height_blocks(self) -> usize {
match self {
Self::S444 | Self::S422 | Self::S411 | Self::Unknown => 1,
Self::S420 | Self::S440 => 2,
Self::S441 => 4,
}
}
pub fn sampling_factors(self) -> (u8, u8) {
match self {
Self::S444 | Self::Unknown => (1, 1),
Self::S422 => (2, 1),
Self::S420 => (2, 2),
Self::S440 => (1, 2),
Self::S411 => (4, 1),
Self::S441 => (1, 4),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DctMethod {
#[default]
IsLow,
IsFast,
Float,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PixelFormat {
Grayscale,
Rgb,
Rgba,
Bgr,
Bgra,
Cmyk,
Rgbx,
Bgrx,
Xrgb,
Xbgr,
Argb,
Abgr,
Rgb565,
}
impl PixelFormat {
pub fn bytes_per_pixel(self) -> usize {
match self {
Self::Grayscale => 1,
Self::Rgb565 => 2,
Self::Rgb | Self::Bgr => 3,
Self::Rgba
| Self::Bgra
| Self::Cmyk
| Self::Rgbx
| Self::Bgrx
| Self::Xrgb
| Self::Xbgr
| Self::Argb
| Self::Abgr => 4,
}
}
pub fn red_offset(self) -> Option<usize> {
match self {
Self::Rgb | Self::Rgba | Self::Rgbx => Some(0),
Self::Bgr | Self::Bgra | Self::Bgrx => Some(2),
Self::Xrgb | Self::Argb => Some(1),
Self::Xbgr | Self::Abgr => Some(3),
_ => None,
}
}
pub fn green_offset(self) -> Option<usize> {
match self {
Self::Rgb | Self::Rgba | Self::Rgbx => Some(1),
Self::Bgr | Self::Bgra | Self::Bgrx => Some(1),
Self::Xrgb | Self::Argb => Some(2),
Self::Xbgr | Self::Abgr => Some(2),
_ => None,
}
}
pub fn blue_offset(self) -> Option<usize> {
match self {
Self::Rgb | Self::Rgba | Self::Rgbx => Some(2),
Self::Bgr | Self::Bgra | Self::Bgrx => Some(0),
Self::Xrgb | Self::Argb => Some(3),
Self::Xbgr | Self::Abgr => Some(1),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ComponentInfo {
pub id: u8,
pub horizontal_sampling: u8,
pub vertical_sampling: u8,
pub quant_table_index: u8,
}
#[derive(Debug, Clone)]
pub struct FrameHeader {
pub precision: u8,
pub height: u16,
pub width: u16,
pub components: Vec<ComponentInfo>,
pub is_progressive: bool,
pub is_lossless: bool,
}
#[derive(Debug, Clone)]
pub struct ScanHeader {
pub components: Vec<ScanComponentSelector>,
pub spec_start: u8,
pub spec_end: u8,
pub succ_high: u8,
pub succ_low: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CropRegion {
pub x: usize,
pub y: usize,
pub width: usize,
pub height: usize,
}
#[derive(Debug, Clone, Copy)]
pub struct ScanComponentSelector {
pub component_id: u8,
pub dc_table_index: u8,
pub ac_table_index: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ScalingFactor {
pub num: u32,
pub denom: u32,
}
impl ScalingFactor {
pub fn new(num: u32, denom: u32) -> Self {
Self { num, denom }
}
pub fn block_size(self) -> usize {
let ratio_x8 = (self.num * 8).div_ceil(self.denom);
match ratio_x8 {
0 => 1,
1 => 1,
2 => 2,
3..=4 => 4,
_ => 8,
}
}
pub fn scale_dim(self, input_dim: usize) -> usize {
(input_dim * self.num as usize).div_ceil(self.denom as usize)
}
}
impl Default for ScalingFactor {
fn default() -> Self {
Self { num: 1, denom: 1 }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DensityInfo {
pub unit: DensityUnit,
pub x: u16,
pub y: u16,
}
impl Default for DensityInfo {
fn default() -> Self {
Self {
unit: DensityUnit::Dpi,
x: 72,
y: 72,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DensityUnit {
Unknown,
Dpi,
Dpcm,
}
#[derive(Debug, Clone)]
pub struct SavedMarker {
pub code: u8,
pub data: Vec<u8>,
}
#[derive(Debug, Clone, Default)]
pub enum MarkerSaveConfig {
#[default]
None,
All,
AppOnly,
Specific(Vec<u8>),
}
#[derive(Debug, Clone)]
pub struct ScanScript {
pub components: Vec<u8>,
pub ss: u8,
pub se: u8,
pub ah: u8,
pub al: u8,
}
#[derive(Debug, Clone)]
pub struct IccChunk {
pub seq_no: u8,
pub num_markers: u8,
pub data: Vec<u8>,
}