use std::io::Write;
use ::{FlicError,FlicResult,Raster,RasterMut};
use super::LinScale;
pub const FLI_COPY: u16 = 16;
pub const FPS_COPY: u16 = FLI_COPY;
pub fn decode_fli_copy(src: &[u8], dst: &mut RasterMut)
-> FlicResult<()> {
if (dst.w <= 0) || (src.len() % dst.w != 0) {
return Err(FlicError::WrongResolution);
}
let start = dst.stride * dst.y;
let end = dst.stride * (dst.y + dst.h);
let src_rows = src.chunks(dst.w);
let dst_rows = dst.buf[start..end].chunks_mut(dst.stride);
for (src_row, dst_row) in src_rows.zip(dst_rows) {
let start = dst.x;
let end = start + dst.w;
dst_row[start..end].copy_from_slice(src_row);
}
Ok(())
}
pub fn decode_fps_copy(
src: &[u8], src_w: usize, src_h: usize, dst: &mut RasterMut)
-> FlicResult<()> {
if src_w <= 0 || src_h <= 0
|| src_w.checked_mul(src_h).expect("overflow") > src.len() {
return Err(FlicError::WrongResolution);
}
for (sy, dy) in LinScale::new(src_h, dst.h) {
let src_start = src_w * sy;
let src_end = src_start + src_w;
let dst_start = dst.stride * (dst.y + dy) + dst.x;
let dst_end = dst_start + dst.w;
let src_row = &src[src_start..src_end];
let dst_row = &mut dst.buf[dst_start..dst_end];
for (sx, dx) in LinScale::new(src_w, dst.w) {
dst_row[dx] = src_row[sx];
}
}
Ok(())
}
pub fn encode_fli_copy<W: Write>(
next: &Raster, w: &mut W)
-> FlicResult<usize> {
let start = next.stride * next.y;
let end = next.stride * (next.y + next.h);
for row in next.buf[start..end].chunks(next.stride) {
let start = next.x;
let end = start + next.w;
w.write_all(&row[start..end])?;
}
Ok(next.w * next.h)
}
#[cfg(test)]
mod tests {
use ::RasterMut;
use super::decode_fps_copy;
#[test]
fn test_decode_fps_copy() {
let src = [
11, 12, 13,
21, 22, 23,
31, 32, 33 ];
let expected = [
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 11, 11, 12, 12, 13, 13,
0, 0, 11, 11, 12, 12, 13, 13,
0, 0, 21, 21, 22, 22, 23, 23,
0, 0, 21, 21, 22, 22, 23, 23,
0, 0, 31, 31, 32, 32, 33, 33,
0, 0, 31, 31, 32, 32, 33, 33,
0, 0, 0, 0, 0, 0, 0, 0 ];
const SCREEN_W: usize = 8;
const SCREEN_H: usize = 8;
let mut buf = [0; SCREEN_W * SCREEN_H];
let mut pal = [0; 3 * 256];
let res = decode_fps_copy(&src, 3, 3,
&mut RasterMut::with_offset(2, 1, 6, 6, SCREEN_W, &mut buf, &mut pal));
assert!(res.is_ok());
assert_eq!(&buf[..], &expected[..]);
}
}