2019-05-30 18:28:35 -07:00
|
|
|
//! QuickDraw PICT format run length encoded data.
|
|
|
|
|
2019-06-13 18:09:07 -07:00
|
|
|
use crate::{bin::*, err::*};
|
2019-05-30 18:28:35 -07:00
|
|
|
|
|
|
|
/// Read run-length encoded data.
|
|
|
|
pub fn read<T>(b: &[u8], pitch: usize) -> ResultS<(Vec<T>, usize)>
|
2019-07-05 20:21:11 -07:00
|
|
|
where T: ReadRleData
|
2019-05-30 18:28:35 -07:00
|
|
|
{
|
2019-07-05 20:21:11 -07:00
|
|
|
let mut p = 0;
|
|
|
|
let mut o = Vec::with_capacity(pitch);
|
2019-05-30 18:28:35 -07:00
|
|
|
|
2019-07-05 20:21:11 -07:00
|
|
|
let sz = if pitch > 250 {
|
|
|
|
(usize::from(u16b(b)) + 2, p += 2).0
|
|
|
|
} else {
|
|
|
|
(usize::from(b[0]) + 1, p += 1).0
|
|
|
|
};
|
2019-05-30 18:28:35 -07:00
|
|
|
|
2019-07-05 20:21:11 -07:00
|
|
|
while p < sz {
|
|
|
|
let szf = b[p];
|
|
|
|
let cmp = szf & 0x80 != 0;
|
|
|
|
let len = usize::from(if cmp {!szf + 2} else {szf + 1});
|
2019-05-30 18:28:35 -07:00
|
|
|
|
2019-07-05 20:21:11 -07:00
|
|
|
p += 1;
|
|
|
|
o.reserve(len);
|
2019-05-30 18:28:35 -07:00
|
|
|
|
2019-07-05 20:21:11 -07:00
|
|
|
T::read_rle_data(b, &mut p, cmp, len, &mut o);
|
|
|
|
}
|
2019-05-30 18:28:35 -07:00
|
|
|
|
2019-07-05 20:21:11 -07:00
|
|
|
if o.len() == pitch {
|
|
|
|
Ok((o, p))
|
|
|
|
} else {
|
|
|
|
Err(err_msg("incorrect size for compressed scanline"))
|
|
|
|
}
|
2019-05-30 18:28:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait ReadRleData: Sized
|
|
|
|
{
|
2019-07-05 20:21:11 -07:00
|
|
|
// Read a sequence of packed RLE data.
|
|
|
|
fn read_rle_data(b: &[u8],
|
|
|
|
p: &mut usize,
|
|
|
|
cmp: bool,
|
|
|
|
len: usize,
|
|
|
|
out: &mut Vec<Self>);
|
2019-05-30 18:28:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ReadRleData for u16
|
|
|
|
{
|
2019-07-05 20:21:11 -07:00
|
|
|
fn read_rle_data(b: &[u8],
|
|
|
|
p: &mut usize,
|
|
|
|
cmp: bool,
|
|
|
|
len: usize,
|
|
|
|
out: &mut Vec<Self>)
|
|
|
|
{
|
|
|
|
if cmp {
|
|
|
|
let d = u16b(&b[*p..*p + 2]);
|
|
|
|
*p += 2;
|
|
|
|
for _ in 0..len {
|
|
|
|
out.push(d);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _ in 0..len {
|
|
|
|
let d = u16b(&b[*p..*p + 2]);
|
|
|
|
*p += 2;
|
|
|
|
out.push(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-30 18:28:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ReadRleData for u8
|
|
|
|
{
|
2019-07-05 20:21:11 -07:00
|
|
|
fn read_rle_data(b: &[u8],
|
|
|
|
p: &mut usize,
|
|
|
|
cmp: bool,
|
|
|
|
len: usize,
|
|
|
|
out: &mut Vec<Self>)
|
|
|
|
{
|
|
|
|
if cmp {
|
|
|
|
let d = b[*p];
|
|
|
|
*p += 1;
|
|
|
|
for _ in 0..len {
|
|
|
|
out.push(d);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _ in 0..len {
|
|
|
|
let d = b[*p];
|
|
|
|
*p += 1;
|
|
|
|
out.push(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-30 18:28:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// EOF
|