1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use std::io::{self, Read, Seek};

mod header;
pub use self::header::*;

mod frame;
pub use self::frame::*;

mod chunk;
pub use self::chunk::*;

pub mod color;
mod helpers;

/*
https://github.com/aseprite/aseprite/blob/master/docs/ase-file-specs.md

ASE files use Intel (little-endian) byte order.

BYTE (u8): An 8-bit unsigned integer value
WORD (u16): A 16-bit unsigned integer value
SHORT (i16): A 16-bit signed integer value
DWORD (u32): A 32-bit unsigned integer value
LONG (i32): A 32-bit signed integer value
FIXED (f32): A 32-bit fixed point (16.16) value
BYTE[n] ([u8; n]): "n" bytes.
STRING:
	WORD: string length (number of bytes)
	BYTE[length]: characters (in UTF-8) The '\0' character is not included.
PIXEL: One pixel, depending on the image pixel format:
	RGBA: BYTE[4], each pixel have 4 bytes in this order Red, Green, Blue, Alpha.
	Grayscale: BYTE[2], each pixel have 2 bytes in the order Value, Alpha.
	Indexed: BYTE, Each pixel uses 1 byte (the index).
*/

pub struct Aseprite {
	pub header: Header,
	pub frames: Vec<Frame>,
}

impl Aseprite {
	pub fn from_read<R>(read: &mut R) -> io::Result<Aseprite>
	where
		R: Read + Seek,
	{
		let header = Header::from_read(read)?;
		let mut frames = Vec::with_capacity(header.frames as usize);
		for _ in 0..header.frames {
			frames.push(Frame::from_read(read, &header)?);
		}

		Ok(Self { header, frames })
	}
}