aseprite_loader/binary/
chunk.rs

1use nom::{bytes::complete::take, multi::count};
2
3use super::{
4    chunk_type::{parse_chunk_type, ChunkType},
5    chunks::{
6        cel::{parse_cel_chunk, CelChunk},
7        cel_extra::{parse_cel_extra_chunk, CelExtraChunk},
8        color_profile::{parse_color_profile, ColorProfileChunk},
9        external_files::{parse_external_files_chunk, ExternalFilesChunk},
10        layer::{parse_layer_chunk, LayerChunk},
11        mask::{parse_mask_chunk, MaskChunk},
12        old_palette::{parse_old_palette_chunk, OldPaletteChunk},
13        palette::{parse_palette_chunk, PaletteChunk},
14        slice::{parse_slice_chunk, SliceChunk},
15        tags::{parse_tags_chunk, TagsChunk},
16        tileset::{parse_tileset_chunk, TilesetChunk},
17        user_data::{parse_user_data_chunk, UserDataChunk},
18    },
19    errors::{ParseError, ParseResult},
20    scalars::dword_size,
21};
22
23#[derive(Debug)]
24pub enum Chunk<'a> {
25    Palette0004(OldPaletteChunk),
26    Palette0011(OldPaletteChunk),
27    Layer(LayerChunk<'a>),
28    Cel(CelChunk<'a>),
29    CelExtra(CelExtraChunk<'a>),
30    ColorProfile(ColorProfileChunk<'a>),
31    ExternalFiles(ExternalFilesChunk<'a>),
32    Mask(MaskChunk<'a>),
33    Path,
34    Tags(TagsChunk<'a>),
35    Palette(PaletteChunk<'a>),
36    UserData(UserDataChunk<'a>),
37    Slice(SliceChunk<'a>),
38    Tileset(TilesetChunk<'a>),
39    Unsupported(u16),
40}
41
42pub fn parse_chunks(input: &[u8], chunk_count: usize) -> ParseResult<'_, Vec<Chunk<'_>>> {
43    count(parse_chunk, chunk_count)(input)
44}
45
46pub fn parse_chunk(input: &[u8]) -> ParseResult<'_, Chunk<'_>> {
47    let (input, size) = dword_size(input, ParseError::InvalidFrameSize)?;
48    // FIXME handle underflows
49    let (rest, input) = take(size - 4)(input)?;
50    let (chunk_data, chunk_type) = parse_chunk_type(input)?;
51    let chunk = match chunk_type {
52        Ok(ChunkType::Palette0004) => Chunk::Palette0004(parse_old_palette_chunk(chunk_data)?.1),
53        Ok(ChunkType::Palette0011) => Chunk::Palette0011(parse_old_palette_chunk(chunk_data)?.1),
54        Ok(ChunkType::Layer) => Chunk::Layer(parse_layer_chunk(chunk_data)?.1),
55        Ok(ChunkType::Cel) => Chunk::Cel(parse_cel_chunk(chunk_data)?.1),
56        Ok(ChunkType::CelExtra) => Chunk::CelExtra(parse_cel_extra_chunk(chunk_data)?.1),
57        Ok(ChunkType::ColorProfile) => Chunk::ColorProfile(parse_color_profile(chunk_data)?.1),
58        Ok(ChunkType::ExternalFile) => {
59            Chunk::ExternalFiles(parse_external_files_chunk(chunk_data)?.1)
60        }
61        Ok(ChunkType::Mask) => Chunk::Mask(parse_mask_chunk(chunk_data)?.1),
62        Ok(ChunkType::Path) => Chunk::Path,
63        Ok(ChunkType::Tags) => Chunk::Tags(parse_tags_chunk(chunk_data)?.1),
64        Ok(ChunkType::Palette) => Chunk::Palette(parse_palette_chunk(chunk_data)?.1),
65        Ok(ChunkType::UserData) => Chunk::UserData(parse_user_data_chunk(chunk_data)?.1),
66        Ok(ChunkType::Slice) => Chunk::Slice(parse_slice_chunk(chunk_data)?.1),
67        Ok(ChunkType::Tileset) => Chunk::Tileset(parse_tileset_chunk(chunk_data)?.1),
68        Err(chunk_type) => Chunk::Unsupported(chunk_type),
69    };
70    Ok((rest, chunk))
71}