Maraiah/maraiah/image/pict.rs

118 lines
3.3 KiB
Rust

//! QuickDraw PICT format loader.
pub mod clut;
pub mod pm;
pub mod rle;
use crate::{bin::*, err::*, image::*};
/// Load a `PICT` image.
pub fn read(b: &[u8]) -> ResultS<Image8>
{
read_data! {
endian: BIG, buf: b, size: 10, start: 0, data {
let h = u16[6] usize;
let w = u16[8] usize;
}
}
if w * h > 16_000_000 {
bail!("image is too large");
}
let im = Image8::new(w, h);
let mut p = 10; // size of header
while p < b.len() {
read_data! {
endian: BIG, buf: b, size: 2, start: p, data {
let op = u16[0];
}
}
p += 2;
match op {
0x0098 => {
// PackBitsRect
return pm::area::read(im, &b[p..], true, false);
}
0x0099 => {
// PackBitsRgn
return pm::area::read(im, &b[p..], true, true);
}
0x009a => {
// DirectBitsRect
return pm::area::read(im, &b[p..], false, false);
}
0x009b => {
// DirectBitsRgn
return pm::area::read(im, &b[p..], false, true);
}
0x8200 => {
// CompressedQuickTime
unimplemented!();
}
0x00ff => {
// OpEndPic
break;
}
// help i'm trapped in an awful metafile format from the 80s
0x0000 | // NoOp
0x001c | // HiliteMode
0x001e | // DefHilite
0x0038 | // FrameSameRect
0x0039 | // PaintSameRect
0x003a | // EraseSameRect
0x003b | // InvertSameRect
0x003c | // FillSameRect
0x8000 | // Reserved
0x8100 => (), // Reserved
0x0003 | // TxFont
0x0004 | // TxFace
0x0005 | // TxMode
0x0008 | // PnMode
0x000d | // TxSize
0x0011 | // VersionOp
0x0015 | // PnLocHFrac
0x0016 | // ChExtra
0x0023 | // ShortLineFrom
0x00a0 => p += 2, // ShortComment
0x0006 | // SpExtra
0x0007 | // PnSize
0x000b | // OvSize
0x000c | // Origin
0x000e | // FgCol
0x000f | // BkCol
0x0021 => p += 4, // LineFrom
0x001a | // RGBFgCol
0x001b | // RGBBkCol
0x001d | // TxRatio
0x0022 => p += 6, // ShortLine
0x0002 | // BkPat
0x0009 | // PnPat
0x0010 | // TxRatio
0x0020 | // Line
0x002e | // GlyphState
0x0030 | // FrameRect
0x0031 | // PaintRect
0x0032 | // EraseRect
0x0033 | // InvertRect
0x0034 => p += 8, // FillRect
0x002d => p += 10, // LineJustify
0x0001 => p += usize::from(u16b(&b[p.. ]) & !1), // Clip
0x00a1 => p += usize::from(u16b(&b[p+2..]) & !1) + 2, // LongComment
0x100..=
0x7fff => p += usize::from(op >> 8) * 2, // Reserved
_ => {
bail!("invalid op in PICT");
}
}
}
Err(err_msg("no image in data"))
}
// EOF