use crate::config::{Config, OutputSizing};
use crate::error::ImageError;
use crate::grid::Grid;
use crate::sampling::Sampler;
pub(crate) const CHANNELS: usize = 3;
pub(crate) fn validate_and_compute_grid_size(
width: u32,
height: u32,
buf: &[u8],
config: &Config,
) -> Result<(u32, u32), ImageError> {
if width == 0 || height == 0 {
return Err(ImageError::ZeroSizedImage(width as usize, height as usize));
}
let expected_len = (width as usize) * (height as usize) * CHANNELS;
if buf.len() != expected_len {
return Err(ImageError::BufferSizeMismatch(expected_len, buf.len()));
}
let (grid_width, grid_height) = match config.output_sizing {
OutputSizing::Explicit {
width: w,
height: h,
} => (w as u32, h as u32),
OutputSizing::MaxWidth(max_w) => {
let gw = max_w as u32;
let scale = gw as f32 / width as f32;
let gh = ((height as f32) * scale * config.aspect_ratio_correction).round() as u32;
(gw, gh)
}
};
if grid_width == 0 || grid_height == 0 {
return Err(ImageError::ZeroSizedImage(
grid_width as usize,
grid_height as usize,
));
}
Ok((grid_width, grid_height))
}
pub fn convert_image(
width: u32,
height: u32,
buf: &[u8],
config: &Config,
) -> Result<Grid, ImageError> {
let (grid_width, grid_height) = validate_and_compute_grid_size(width, height, buf, config)?;
let mut grid = Grid::new(grid_width, grid_height);
let ramp_chars: Vec<char> = config.ramp.inner().as_str().chars().collect();
let sampler = Sampler::new(
buf,
width,
height,
CHANNELS,
grid_width,
grid_height,
config,
&ramp_chars,
);
for row_idx in 0..grid_height {
if let Some(row_cells) = grid.row_mut(row_idx) {
sampler.fill_row(row_idx, row_cells);
}
}
Ok(grid)
}