1use nom::bytes::complete::{tag, take};
2
3use super::{
4 color_depth::{parse_color_depth, ColorDepth},
5 errors::ParseResult,
6 scalars::{byte, dword, short, word, Byte, Dword, Short, Word},
7};
8
9const HEADER_MAGIC_NUMBER: [u8; 2] = 0xA5E0u16.to_le_bytes();
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq)]
13pub struct Header {
14 pub file_size: Dword,
16 pub frames: Word,
18 pub width: Word,
20 pub height: Word,
22 pub color_depth: ColorDepth,
24 pub flags: Dword,
27 #[deprecated = "You should use the frame durations instead"]
31 pub speed: Word,
32 pub transparent_index: Byte,
35 pub color_count: Word,
37 pub pixel_width: Byte,
40 pub pixel_height: Byte,
42 pub grid_x: Short,
44 pub grid_y: Short,
46 pub grid_width: Word,
49 pub grid_height: Word,
51}
52
53pub fn parse_header(input: &[u8]) -> ParseResult<'_, Header> {
54 let (rest, input) = take(128usize)(input)?;
55 let (input, file_size) = dword(input)?;
56 let (input, _) = tag(HEADER_MAGIC_NUMBER)(input)?;
57 let (input, frames) = word(input)?;
58 let (input, width) = word(input)?;
59 let (input, height) = word(input)?;
60 let (input, color_depth) = parse_color_depth(input)?;
61 let (input, flags) = dword(input)?;
62 let (input, speed) = word(input)?;
63 let (input, _) = tag([0u8; 4])(input)?;
64 let (input, _) = tag([0u8; 4])(input)?;
65 let (input, transparent_index) = byte(input)?;
66 let (input, _) = take(3usize)(input)?;
67 let (input, color_count) = word(input)?;
68 let (input, pixel_width) = byte(input)?;
69 let (input, pixel_height) = byte(input)?;
70 let (input, grid_x) = short(input)?;
71 let (input, grid_y) = short(input)?;
72 let (input, grid_width) = word(input)?;
73 let (input, grid_height) = word(input)?;
74 let (input, _) = take(84usize)(input)?;
75 assert_eq!(input.len(), 0);
77 #[allow(deprecated)]
78 Ok((
79 rest,
80 Header {
81 file_size,
82 frames,
83 width,
84 height,
85 color_depth,
86 flags,
87 speed,
88 transparent_index,
89 color_count,
90 pixel_width,
91 pixel_height,
92 grid_x,
93 grid_y,
94 grid_width,
95 grid_height,
96 },
97 ))
98}
99
100#[test]
101#[allow(deprecated)]
102fn test_parse_header() {
103 let input = std::fs::read("./tests/default.aseprite").unwrap();
104 let (_, header) = parse_header(&input).unwrap();
105 assert_eq!(
106 header,
107 Header {
108 file_size: 573,
109 frames: 1,
110 width: 32,
111 height: 32,
112 color_depth: ColorDepth::Rgba,
113 flags: 1,
114 speed: 100,
115 transparent_index: 0,
116 color_count: 32,
117 pixel_width: 1,
118 pixel_height: 1,
119 grid_x: 0,
120 grid_y: 0,
121 grid_width: 16,
122 grid_height: 16,
123 },
124 );
125}