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