87 lines
1.6 KiB
Rust
87 lines
1.6 KiB
Rust
//! QuickDraw PICT `PixMap` headers.
|
|
|
|
use crate::{bin::*, err::*, image::*};
|
|
|
|
/// Reads a `PixMap` header.
|
|
pub fn read<'a>(b: &'a [u8],
|
|
pack: bool,
|
|
clip: bool,
|
|
im: &Image8) -> ResultS<(&'a [u8], Header)>
|
|
{
|
|
read_data! {
|
|
endian: BIG, buf: b, size: 36, start: 0, data {
|
|
let pt_fl = u16[0];
|
|
let top = u16[2] usize;
|
|
let left = u16[4] usize;
|
|
let bottom = u16[6] usize;
|
|
let right = u16[8] usize;
|
|
let pack_t = u16[12] enum PackType;
|
|
let depth = u16[28] enum Depth;
|
|
}
|
|
}
|
|
|
|
if pt_fl & 0x8000 == 0 {
|
|
bail!("PICT1 not supported");
|
|
}
|
|
|
|
if right - left != im.w() || bottom - top != im.h() {
|
|
bail!("image bounds are incorrect");
|
|
}
|
|
|
|
let mut p = 46;
|
|
|
|
// get CLUT if packed
|
|
let clut = if pack {
|
|
let (clut, sz) = pict::clut::read(&b[p..])?;
|
|
p += sz;
|
|
Some(clut)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
p += 18; // srcRect, dstRect, mode
|
|
|
|
if clip {
|
|
p += usize::from(u16b(&b[p..])); // maskRgn
|
|
}
|
|
|
|
let rle = pack_t == PackType::Default ||
|
|
pack_t == PackType::Rle16 && depth == Depth::_16 ||
|
|
pack_t == PackType::Rle32 && depth == Depth::_32;
|
|
|
|
let pitch = usize::from(pt_fl & 0x3FFF);
|
|
|
|
Ok((&b[p..], Header{pitch, pack_t, depth, clut, rle}))
|
|
}
|
|
|
|
pub struct Header {
|
|
pub pitch: usize,
|
|
pub pack_t: PackType,
|
|
pub depth: Depth,
|
|
pub clut: Option<Vec<Color8>>,
|
|
pub rle: bool,
|
|
}
|
|
|
|
c_enum! {
|
|
pub enum Depth: u16 {
|
|
_1 = 1,
|
|
_2 = 2,
|
|
_4 = 4,
|
|
_8 = 8,
|
|
_16 = 16,
|
|
_32 = 32,
|
|
}
|
|
}
|
|
|
|
c_enum! {
|
|
pub enum PackType: u16 {
|
|
Default = 0,
|
|
None = 1,
|
|
NoPad = 2,
|
|
Rle16 = 3,
|
|
Rle32 = 4,
|
|
}
|
|
}
|
|
|
|
// EOF
|