Skip to main content

tim2/
image.rs

1use crate::common::*;
2use crate::error::Error;
3use crate::frame::Frame;
4
5use byteorder::{ByteOrder, BigEndian, LittleEndian};
6use std::fs::File;
7use std::io::prelude::*;
8use std::path::Path;
9
10const IDENT: u32 = 0x54494d32;
11
12#[derive(Debug)]
13struct Header {
14	identifier: u32,
15	version: u16,
16	count: usize,
17}
18
19impl Header {
20	fn read(buffer: &[u8], offset: &mut usize) -> Result<Header, Error> {
21		let mut load_part = |size| { get_slice(&buffer, offset, size) };
22		let identifier = BigEndian::read_u32(load_part(4));
23		let version = LittleEndian::read_u16(load_part(2));
24		let count = LittleEndian::read_u16(load_part(2)) as usize;
25
26		load_part(8);
27		if identifier != IDENT {
28			return Err(Error::InvalidIdentifier(identifier))
29		}
30
31		Ok(Header { identifier, version, count })
32	}
33}
34
35#[derive(Debug)]
36pub struct Image {
37	header: Header,
38	frames: Vec::<Frame>,
39}
40
41impl Image {
42	fn read(buffer: &[u8], offset: &mut usize) -> Result<Image, Error> {
43		let header = Header::read(buffer, offset)?;
44		let mut frames = Vec::with_capacity(header.count);
45
46		for _ in 0..header.count {
47			frames.push(Frame::read(buffer, offset)?);
48		}
49
50		Ok(Image { header, frames })
51	}
52
53	pub fn frames(&self) -> &Vec::<Frame> {
54		&self.frames
55	}
56
57	pub fn get_frame(&self, index: usize) -> &Frame {
58		&self.frames[index]
59	}
60}
61
62/// Loads a TIM2 image file into memory from buffer.
63///
64/// # Examples
65///
66/// ```
67/// use std::fs::File;
68/// use std::io::prelude::*;
69/// 
70/// fn main() {
71///     let mut buffer = Vec::new();
72///     let mut file = File::open("../assets/test.tm2").unwrap();
73///     file.read_to_end(&mut buffer).unwrap();
74/// 
75///     let image = tim2::from_buffer(&buffer).unwrap();
76/// 
77///     /* print the header info for each frame found */
78///     for (i, frame) in image.frames().iter().enumerate() {
79///         println!("frame[{}]: <{}  {}>", i, frame.width(), frame.height());
80///     }
81/// }
82/// ```
83pub fn from_buffer(buffer: &[u8]) -> Result<Image, Error> {
84	let mut offset = 0usize;
85
86	Image::read(&buffer, &mut offset)
87}
88
89/// Loads a TIM2 image file into memory.
90///
91/// # Examples
92///
93/// ```
94/// fn main() {
95///     let image = tim2::load("../assets/test.tm2").unwrap();
96/// 
97///     /* print the header info for each frame found */
98///     for (i, frame) in image.frames().iter().enumerate() {
99///         println!("frame[{}]: <{}  {}>", i, frame.width(), frame.height());
100///     }
101/// }
102/// ```
103pub fn load<P: AsRef<Path>>(path: P) -> Result<Image, Error> {
104	let mut offset = 0usize;
105	let mut buffer = Vec::new();
106	let mut file = File::open(path)?;
107
108	file.read_to_end(&mut buffer)?;
109	Image::read(&buffer, &mut offset)
110}