caco 0.5.33

library for dealing with doom [et al] wad files
Documentation
//! Palette-related lump formats. The main format of interest
//! here is [`Playpal`].

use crate::{agnostic::ClumpFormat, error::Error as CacoError};

use anyhow::{Error, Result};
use image::{Pixel, Rgb};
use itertools::Itertools;

/// A set of 256 colors, making up one palette inside of
/// a [`Playpal`]. These are used with 256-color indexed-color
/// graphics.
pub struct PaletteTint {
    pub colors: [Rgb<u8>; 256]
}

/// A `PLAYPAL`, from Doom, for example.
/// 
/// It's a series of [`PaletteTint`]s. Doom has 14 of them,
/// to cycle through for the pain and item pickup effects,
/// and the radsuit.
pub struct Playpal {
    pub tints: Vec<PaletteTint>
}

impl ClumpFormat for Playpal {
    fn try_decode_bytes(data: &[u8]) -> Result<Self> {
        if data.len() % 768 != 0 { return Err(Error::new(CacoError::FormatError)) }

        let mut tints = vec!();

        for t in data.chunks(768) {
            let colors = *t.iter()
                .tuples()
                .map(|(r, g, b)| Rgb([*r, *g, *b]))
                .collect::<Vec<Rgb<u8>>>()
                .as_array()
                .ok_or(CacoError::FormatError)?;

            tints.push(PaletteTint { colors });
        }

        Ok(Playpal { tints })
    }

    fn try_encode_bytes(&self) -> Result<Box<[u8]>> {
        Ok(self.tints.iter()
            .map(|t| t.colors.iter()
                .map(|c| c.channels())
                .flatten()
                .map(|n| *n) //???????????????????????????????????????????????????????????????????????????
            )
            .flatten()
            .collect::<Vec<u8>>()
            .into_boxed_slice())
    }
}