also more shapes
parent
48b917998a
commit
9e8c6eea92
|
@ -20,8 +20,8 @@ fn color(b: &[u8]) -> ResultS<(usize, ColorShp)>
|
|||
}
|
||||
|
||||
fn clut_collection(b: &[u8],
|
||||
clr_num: usize,
|
||||
clu_num: usize)
|
||||
clu_num: usize,
|
||||
clr_num: usize)
|
||||
-> ResultS<Vec<Vec<ColorShp>>>
|
||||
{
|
||||
let mut tables = vec![vec![ColorShp::Translucent; clr_num]; clu_num];
|
||||
|
@ -45,6 +45,70 @@ fn clut_collection(b: &[u8],
|
|||
Ok(tables)
|
||||
}
|
||||
|
||||
fn bitmap<'a>(b: &[u8], clut: &'a [ColorShp]) -> ResultS<ImageShp<'a>>
|
||||
{
|
||||
let width = c_u16b(b, 0)? as usize;
|
||||
let height = c_u16b(b, 2)? as usize;
|
||||
let pitch = c_u16b(b, 4)? as usize;
|
||||
let flags = c_u16b(b, 6)?;
|
||||
let bpp = c_u16b(b, 8)?;
|
||||
let flags = ok!(BmpFlags::from_bits(flags), "bad BmpFlags")?;
|
||||
let alpha = flags.contains(BmpFlags::Transparent);
|
||||
|
||||
if bpp != 8 {
|
||||
bail!("invalid bit depth (should always be 8)");
|
||||
}
|
||||
|
||||
if flags.contains(BmpFlags::ColumnMajor) {
|
||||
bail!("column major format not supported");
|
||||
}
|
||||
|
||||
if pitch == u16::max_value() as usize {
|
||||
bail!("compressed shape bitmap not supported");
|
||||
}
|
||||
|
||||
let mut im = ImageShp::new(width, height, clut, alpha);
|
||||
// let mut p = 30 + if flags.contains(BmpFlags::ColumnMajor) {
|
||||
// 4 * width
|
||||
// } else {
|
||||
// 4 * height
|
||||
// };
|
||||
let mut p = 30 + 4 * height;
|
||||
|
||||
for _ in 0..height {
|
||||
for _ in 0..width {
|
||||
im.cr.push(b[p]);
|
||||
p += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
fn bitmap_collection<'a>(b: &[u8],
|
||||
bmp_ofs: usize,
|
||||
bmp_num: usize,
|
||||
clut: &'a [ColorShp])
|
||||
-> ResultS<Vec<ImageShp<'a>>>
|
||||
{
|
||||
let mut bitmaps = Vec::with_capacity(bmp_num);
|
||||
let mut p = bmp_ofs;
|
||||
|
||||
for _ in 0..bmp_num {
|
||||
let ofs = c_u32b(b, p)? as usize;
|
||||
let bmp = bitmap(c_data(b, ofs..)?, clut)?;
|
||||
|
||||
use std::{fs, io};
|
||||
let out = fs::File::create(&format!("out/shape{}.ppm", ofs))?;
|
||||
let mut out = io::BufWriter::new(out);
|
||||
write_ppm(&mut out, &bmp)?;
|
||||
|
||||
p += 4;
|
||||
}
|
||||
|
||||
Ok(bitmaps)
|
||||
}
|
||||
|
||||
/*
|
||||
fn frame(b: &[u8]) -> ResultS<()>
|
||||
{
|
||||
|
@ -148,7 +212,8 @@ fn collection(b: &[u8]) -> ResultS<Collection>
|
|||
}
|
||||
*/
|
||||
|
||||
let tables = clut_collection(&b[clu_ofs..], clr_num, clu_num)?;
|
||||
let tables = clut_collection(&b[clu_ofs..], clu_num, clr_num)?;
|
||||
let bitmaps = bitmap_collection(b, bmp_ofs, bmp_num, &tables[0])?;
|
||||
|
||||
Ok(Collection{clr_num, tables, bitmaps: Vec::new()})
|
||||
}
|
||||
|
@ -182,6 +247,14 @@ pub fn testfn_replaceme(b: &[u8]) -> ResultS<()>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
impl ImageShp<'_>
|
||||
{
|
||||
fn new(w: usize, h: usize, clut: &[ColorShp], alpha: bool) -> ImageShp
|
||||
{
|
||||
ImageShp{w, h, clut, alpha, cr: Vec::with_capacity(w * h)}
|
||||
}
|
||||
}
|
||||
|
||||
impl Image for ImageShp<'_>
|
||||
{
|
||||
type Output = ColorShp;
|
||||
|
@ -189,46 +262,51 @@ impl Image for ImageShp<'_>
|
|||
fn w(&self) -> usize {self.w}
|
||||
fn h(&self) -> usize {self.h}
|
||||
|
||||
fn cr_at(&self, x: usize, y: usize) -> Option<&ColorShp>
|
||||
fn cr_at(&self, x: usize, y: usize) -> &Self::Output
|
||||
{
|
||||
self.clut.get(*self.cr.get(x + y * self.w)? as usize)
|
||||
static TRANSLUCENT_COLOR: ColorShp = ColorShp::Translucent;
|
||||
|
||||
let cr = self.cr[x + y * self.w] as usize;
|
||||
|
||||
if self.alpha && cr == 0 {
|
||||
&TRANSLUCENT_COLOR
|
||||
} else {
|
||||
self.clut.get(cr).unwrap_or(&TRANSLUCENT_COLOR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Color for ColorShp
|
||||
{
|
||||
type Comp = u16;
|
||||
const MAX: u32 = u16::max_value() as u32;
|
||||
|
||||
fn r(&self) -> u16
|
||||
{
|
||||
match self {
|
||||
&ColorShp::Translucent => 0,
|
||||
&ColorShp::Opaque{r, ..} => r,
|
||||
match *self {
|
||||
ColorShp::Translucent => 0,
|
||||
ColorShp::Opaque{r, ..} => r,
|
||||
}
|
||||
}
|
||||
|
||||
fn g(&self) -> u16
|
||||
{
|
||||
match self {
|
||||
&ColorShp::Translucent => 0,
|
||||
&ColorShp::Opaque{g, ..} => g,
|
||||
match *self {
|
||||
ColorShp::Translucent => 0,
|
||||
ColorShp::Opaque{g, ..} => g,
|
||||
}
|
||||
}
|
||||
|
||||
fn b(&self) -> u16
|
||||
{
|
||||
match self {
|
||||
&ColorShp::Translucent => 0,
|
||||
&ColorShp::Opaque{b, ..} => b,
|
||||
match *self {
|
||||
ColorShp::Translucent => 0,
|
||||
ColorShp::Opaque{b, ..} => b,
|
||||
}
|
||||
}
|
||||
|
||||
fn a(&self) -> u16
|
||||
{
|
||||
match self {
|
||||
&ColorShp::Translucent => 0,
|
||||
&ColorShp::Opaque{..} => 255,
|
||||
match *self {
|
||||
ColorShp::Translucent => 0,
|
||||
ColorShp::Opaque{..} => u16::max_value(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,6 +330,7 @@ struct ImageShp<'a>
|
|||
w: usize,
|
||||
h: usize,
|
||||
cr: Vec<u8>,
|
||||
alpha: bool,
|
||||
clut: &'a [ColorShp],
|
||||
}
|
||||
|
||||
|
@ -263,6 +342,14 @@ struct Collection<'a>
|
|||
bitmaps: Vec<ImageShp<'a>>,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct BmpFlags: u16
|
||||
{
|
||||
const ColumnMajor = 0x80_00;
|
||||
const Transparent = 0x40_00;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct FrameFlags: u16
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue