//! QuickDraw PICT format run length encoded data. use crate::{bin::*, err::*}; /// Read run-length encoded data. pub fn read(b: &[u8], pitch: usize) -> ResultS<(Vec, usize)> where T: ReadRleData { let mut p = 0; let mut o = Vec::with_capacity(pitch); let sz = if pitch > 250 { (usize::from(u16b(b)) + 2, p += 2).0 } else { (usize::from(b[0]) + 1, p += 1).0 }; while p < sz { let szf = b[p]; let cmp = szf & 0x80 != 0; let len = usize::from(if cmp {!szf + 2} else {szf + 1}); p += 1; o.reserve(len); T::read_rle_data(b, &mut p, cmp, len, &mut o); } if o.len() == pitch { Ok((o, p)) } else { Err(err_msg("incorrect size for compressed scanline")) } } pub trait ReadRleData: Sized { // Read a sequence of packed RLE data. fn read_rle_data(b: &[u8], p: &mut usize, cmp: bool, len: usize, out: &mut Vec); } impl ReadRleData for u16 { fn read_rle_data(b: &[u8], p: &mut usize, cmp: bool, len: usize, out: &mut Vec) { 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); } } } } impl ReadRleData for u8 { fn read_rle_data(b: &[u8], p: &mut usize, cmp: bool, len: usize, out: &mut Vec) { 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); } } } } // EOF