Maraiah/maraiah/shp/clut.rs

115 lines
2.3 KiB
Rust

//! Shapes file color lookup tables.
use crate::{err::*, image::Color};
/// Reads a color from a color table into `clut`.
pub fn read_color(b: &[u8], clut: &mut [ColorShp]) -> ResultS<()>
{
read_data! {
endian: BIG, buf: b, size: 8, start: 0, data {
let flag = u8[0];
let ind = u8[1];
let r = u16[2];
let g = u16[4];
let b = u16[6];
}
}
let cr = ok!(clut.get_mut(usize::from(ind)), "bad index")?;
*cr = match flag {
128 => ColorShp::Lit {r, g, b},
0 => ColorShp::Opaque{r, g, b},
_ => {
return Err(err_msg("invalid flag in color"));
}
};
Ok(())
}
/// Reads color tables from `b`.
pub fn read(b: &[u8],
tab_ofs: usize,
tab_num: usize,
clr_num: usize) -> ResultS<Vec<Clut>>
{
let end = tab_num * clr_num * 8;
let b = ok!(b.get(tab_ofs..tab_ofs + end), "bad offset")?;
let mut v = vec![vec![ColorShp::Translucent; clr_num]; tab_num];
let mut p = 0;
for clut in v.iter_mut().take(tab_num) {
for _ in 0..clr_num {
read_color(ok!(b.get(p..p + 8), "not enough data")?, clut)?;
p += 8;
}
}
Ok(v)
}
impl Color for ColorShp
{
fn r(&self) -> u16
{
match *self {
ColorShp::Translucent => 0,
ColorShp::Opaque{r, ..} |
ColorShp::Lit {r, ..} => r,
}
}
fn g(&self) -> u16
{
match *self {
ColorShp::Translucent => 0,
ColorShp::Opaque{g, ..} |
ColorShp::Lit {g, ..} => g,
}
}
fn b(&self) -> u16
{
match *self {
ColorShp::Translucent => 0,
ColorShp::Opaque{b, ..} |
ColorShp::Lit {b, ..} => b,
}
}
fn a(&self) -> u16
{
match *self {
ColorShp::Translucent => 0,
ColorShp::Opaque{..} |
ColorShp::Lit {..} => u16::max_value(),
}
}
}
/// A color in a `Clut`.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ColorShp {
/// A completely translucent color.
Translucent,
/// An opaque color which may be shaded.
Opaque{/** The red component. */ r: u16,
/** The green component. */ g: u16,
/** The blue component. */ b: u16},
/// An opaque color which may not be shaded.
Lit{/** The red component. */ r: u16,
/** The green component. */ g: u16,
/** The blue component. */ b: u16},
}
/// A color collection.
pub type Clut = Vec<ColorShp>;
// EOF