118 lines
3.3 KiB
Rust
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
|