Refactor allowing multiple pixel formats
This commit is contained in:
1 parent
cef82a2e14
commit
6cd059f401
3 files changed
+138
-102
No files matched your search
+64
-59
@@ -2,59 +2,8 @@ use super::*;
|
||||
|
||||
pub struct Farbfeld;
|
||||
|
||||
fn read_header<I>(input: &mut I) -> Result<Extent, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
let mut bytes: [u8; 16] = [0; 16];
|
||||
if input.read(&mut bytes)? < 16 || &bytes[0..8] != b"farbfeld" {
|
||||
Err(Error::Invalid)
|
||||
} else {
|
||||
Ok(Extent {
|
||||
x: u32::from_be_bytes(bytes[8..12].try_into().unwrap()),
|
||||
y: u32::from_be_bytes(bytes[12..16].try_into().unwrap()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn read_pixels<I>(input: &mut I, extent: Extent) -> Result<Vec<Pixel>, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
let mut pixels = Vec::with_capacity(extent.size() as usize);
|
||||
for _ in 0..extent.size() {
|
||||
pixels.push(read_pixel(input)?);
|
||||
}
|
||||
Ok(pixels)
|
||||
}
|
||||
|
||||
fn read_pixel<I>(input: &mut I) -> Result<Pixel, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
let mut bytes: [u8; 8] = [0; 8];
|
||||
if input.read(&mut bytes)? < 8 {
|
||||
Err(Error::Invalid)
|
||||
} else {
|
||||
Ok(Pixel {
|
||||
r: to_channel(bytes[0..2].try_into().unwrap()),
|
||||
g: to_channel(bytes[2..4].try_into().unwrap()),
|
||||
b: to_channel(bytes[4..6].try_into().unwrap()),
|
||||
a: to_channel(bytes[6..8].try_into().unwrap()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn to_channel(bytes: [u8; 2]) -> f32 {
|
||||
u16::from_be_bytes(bytes) as f32 / u16::MAX as f32
|
||||
}
|
||||
|
||||
fn from_channel(channel: f32) -> [u8; 2] {
|
||||
((channel * u16::MAX as f32) as u16).to_be_bytes()
|
||||
}
|
||||
|
||||
impl Format for Farbfeld {
|
||||
fn read<I>(input: &mut I) -> Result<Image, Error>
|
||||
impl Format<SRGBA> for Farbfeld {
|
||||
fn read<I>(input: &mut I) -> Result<Image<SRGBA>, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
@@ -65,13 +14,13 @@ impl Format for Farbfeld {
|
||||
})
|
||||
}
|
||||
|
||||
fn write<O>(output: &mut O, img: &Image) -> std::io::Result<()>
|
||||
fn write<O>(output: &mut O, img: &Image<SRGBA>) -> std::io::Result<()>
|
||||
where
|
||||
O: std::io::Write,
|
||||
{
|
||||
output.write_all(b"farbfeld")?;
|
||||
output.write_all(&img.extent.x.to_be_bytes())?;
|
||||
output.write_all(&img.extent.y.to_be_bytes())?;
|
||||
output.write_all(&(img.extent.x as u32).to_be_bytes())?;
|
||||
output.write_all(&(img.extent.y as u32).to_be_bytes())?;
|
||||
for pixel in &img.pixels {
|
||||
output.write_all(&from_channel(pixel.r))?;
|
||||
output.write_all(&from_channel(pixel.g))?;
|
||||
@@ -82,6 +31,62 @@ impl Format for Farbfeld {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_header<I>(input: &mut I) -> Result<Extent, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
let mut bytes: [u8; 16] = [0; 16];
|
||||
if input.read(&mut bytes)? < 16 || &bytes[0..8] != b"farbfeld" {
|
||||
Err(Error::Invalid)
|
||||
} else {
|
||||
Ok(Extent {
|
||||
x: be_u32_at(&bytes, 8) as usize,
|
||||
y: be_u32_at(&bytes, 12) as usize,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn read_pixels<I>(input: &mut I, extent: Extent) -> Result<Vec<SRGBA>, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
let mut pixels = Vec::with_capacity(extent.size() as usize);
|
||||
for _ in 0..extent.size() {
|
||||
pixels.push(read_pixel(input)?);
|
||||
}
|
||||
Ok(pixels)
|
||||
}
|
||||
|
||||
fn read_pixel<I>(input: &mut I) -> Result<SRGBA, Error>
|
||||
where
|
||||
I: std::io::Read,
|
||||
{
|
||||
let mut bytes: [u8; 8] = [0; 8];
|
||||
if input.read(&mut bytes)? < 8 {
|
||||
Err(Error::Invalid)
|
||||
} else {
|
||||
Ok(SRGBA {
|
||||
r: to_channel(bytes[0..2].try_into().unwrap()),
|
||||
g: to_channel(bytes[2..4].try_into().unwrap()),
|
||||
b: to_channel(bytes[4..6].try_into().unwrap()),
|
||||
a: to_channel(bytes[6..8].try_into().unwrap()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn be_u32_at(bytes: &[u8], start: usize) -> u32 {
|
||||
let end = start + std::mem::size_of::<u32>();
|
||||
u32::from_be_bytes(bytes[start..end].try_into().unwrap())
|
||||
}
|
||||
|
||||
fn to_channel(bytes: [u8; 2]) -> f32 {
|
||||
u16::from_be_bytes(bytes) as f32 / u16::MAX as f32
|
||||
}
|
||||
|
||||
fn from_channel(channel: f32) -> [u8; 2] {
|
||||
((channel * u16::MAX as f32) as u16).to_be_bytes()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -177,7 +182,7 @@ mod tests {
|
||||
fn write_magic() {
|
||||
let img = Image {
|
||||
extent: Extent { x: 1, y: 1 },
|
||||
pixels: vec![Pixel {
|
||||
pixels: vec![SRGBA {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
@@ -193,7 +198,7 @@ mod tests {
|
||||
fn write_extent() {
|
||||
let img = Image {
|
||||
extent: Extent { x: 1, y: 2 },
|
||||
pixels: vec![Pixel {
|
||||
pixels: vec![SRGBA {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
@@ -210,7 +215,7 @@ mod tests {
|
||||
fn write_pixel() {
|
||||
let img = Image {
|
||||
extent: Extent { x: 1, y: 1 },
|
||||
pixels: vec![Pixel {
|
||||
pixels: vec![SRGBA {
|
||||
r: 0.0,
|
||||
g: 0.25,
|
||||
b: 0.5,
|
||||
|
||||
Reference in new issue
Block a user