116 lines
2.5 KiB
Rust
116 lines
2.5 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
|