also more shapes

png-branch
an 2019-02-11 06:29:01 -05:00
parent 48b917998a
commit 9e8c6eea92
1 changed files with 111 additions and 24 deletions

View File

@ -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(),
}
}
}
@ -249,10 +327,11 @@ enum ColorShp
#[derive(Debug)]
struct ImageShp<'a>
{
w: usize,
h: usize,
cr: Vec<u8>,
clut: &'a [ColorShp],
w: usize,
h: usize,
cr: Vec<u8>,
alpha: bool,
clut: &'a [ColorShp],
}
#[derive(Debug)]
@ -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
{