242 lines
4.5 KiB
C
242 lines
4.5 KiB
C
////////////////////////////////
|
|
//~ Sheet types
|
|
|
|
Struct(ASE_Slice)
|
|
{
|
|
u32 start;
|
|
i32 x1;
|
|
i32 y1;
|
|
i32 x2;
|
|
i32 y2;
|
|
ASE_Slice *next;
|
|
};
|
|
|
|
Struct(ASE_Span)
|
|
{
|
|
String name;
|
|
u32 start;
|
|
u32 end;
|
|
ASE_Span *next;
|
|
};
|
|
|
|
Struct(ASE_Frame)
|
|
{
|
|
u32 index;
|
|
u32 x1;
|
|
u32 y1;
|
|
u32 x2;
|
|
u32 y2;
|
|
f64 duration;
|
|
ASE_Frame *next;
|
|
};
|
|
|
|
Struct(ASE_SliceKey)
|
|
{
|
|
String name;
|
|
u32 num_slices;
|
|
ASE_Slice *slice_head;
|
|
ASE_SliceKey *next;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ Decoder result types
|
|
|
|
Struct(ASE_Error)
|
|
{
|
|
String msg;
|
|
ASE_Error *next;
|
|
};
|
|
|
|
Struct(ASE_ErrorList)
|
|
{
|
|
u64 count;
|
|
ASE_Error *first;
|
|
ASE_Error *last;
|
|
};
|
|
|
|
Struct(ASE_DecodedImage)
|
|
{
|
|
u32 width;
|
|
u32 height;
|
|
u32 *pixels; /* Array of [width * height] pixels */
|
|
ASE_ErrorList errors;
|
|
b32 success;
|
|
};
|
|
|
|
Struct(ASE_DecodedSheet)
|
|
{
|
|
Vec2 image_size;
|
|
Vec2 frame_size;
|
|
u32 num_frames;
|
|
u32 num_spans;
|
|
u32 num_slice_keys;
|
|
ASE_Frame *frame_head;
|
|
ASE_Span *span_head;
|
|
ASE_SliceKey *slice_key_head;
|
|
ASE_ErrorList errors;
|
|
b32 success;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ Inflator types
|
|
|
|
#define ASE_HuffBitCount 16
|
|
|
|
Struct(ASE_Bitbuff)
|
|
{
|
|
u8 *data;
|
|
u64 cur_bit;
|
|
};
|
|
|
|
typedef i32 ASE_BlockType; enum
|
|
{
|
|
ASE_BlockType_Uncompressed = 0,
|
|
ASE_BlockType_CompressedFixed = 1,
|
|
ASE_BlockType_CompressedDynamic = 2,
|
|
ASE_BlockType_Reserved = 3
|
|
};
|
|
|
|
Struct(ASE_HuffEntry)
|
|
{
|
|
u16 symbol;
|
|
u16 bits_used;
|
|
};
|
|
|
|
Struct(ASE_HuffDict)
|
|
{
|
|
u32 max_code_bits;
|
|
u32 entries_count;
|
|
ASE_HuffEntry *entries;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ Header types
|
|
|
|
Packed(Struct(ASE_Header)
|
|
{
|
|
u32 file_size;
|
|
u16 magic;
|
|
u16 frames;
|
|
u16 width;
|
|
u16 height;
|
|
u16 color_depth;
|
|
u32 flags;
|
|
u16 speed;
|
|
u32 _1;
|
|
u32 _2;
|
|
u8 palette_entry;
|
|
u8 _3[3];
|
|
u16 num_colors;
|
|
u8 pixel_width;
|
|
u8 pixel_height;
|
|
i16 grid_x;
|
|
i16 grid_y;
|
|
u16 grid_width;
|
|
u16 grid_height;
|
|
u8 _4[84];
|
|
});
|
|
|
|
Packed(Struct(ASE_FrameHeader)
|
|
{
|
|
u32 bytes;
|
|
u16 magic;
|
|
u16 chunks_old;
|
|
u16 frame_duration_ms;
|
|
u8 _[2];
|
|
u32 chunks_new;
|
|
});
|
|
|
|
////////////////////////////////
|
|
//~ Image decoder types
|
|
|
|
typedef i32 ASE_ChunkKind; enum
|
|
{
|
|
ASE_ChunkKind_OldPalette1 = 0x0004,
|
|
ASE_ChunkKind_OldPalette2 = 0x0011,
|
|
ASE_ChunkKind_Layer = 0x2004,
|
|
ASE_ChunkKind_Cel = 0x2005,
|
|
ASE_ChunkKind_CelExtra = 0x2006,
|
|
ASE_ChunkKind_ColorProfile = 0x2007,
|
|
ASE_ChunkKind_ExternalFiles = 0x2008,
|
|
ASE_ChunkKind_Mask = 0x2016,
|
|
ASE_ChunkKind_Path = 0x2017,
|
|
ASE_ChunkKind_Tags = 0x2018,
|
|
ASE_ChunkKind_Palette = 0x2019,
|
|
ASE_ChunkKind_Userdata = 0x2020,
|
|
ASE_ChunkKind_Slice = 0x2022,
|
|
ASE_ChunkKind_Tileset = 0x2023
|
|
};
|
|
|
|
typedef i32 ASE_CelKind; enum
|
|
{
|
|
ASE_CelKind_RawImage = 0,
|
|
ASE_CelKind_Linked = 1,
|
|
ASE_CelKind_CompressedImage = 2,
|
|
ASE_CelKind_CompressedTilemap = 3
|
|
};
|
|
|
|
Struct(ASE_Layer)
|
|
{
|
|
u16 flags;
|
|
u16 type;
|
|
u16 child_level;
|
|
u16 blend_mode;
|
|
u8 opacity;
|
|
String name;
|
|
u32 tileset_index;
|
|
|
|
u32 index;
|
|
ASE_Layer *next;
|
|
};
|
|
|
|
Struct(Ace_Cel)
|
|
{
|
|
u16 layer_index;
|
|
i16 x_pos;
|
|
i16 y_pos;
|
|
u8 opacity;
|
|
ASE_CelKind type;
|
|
i16 z_index;
|
|
|
|
/* Linked cel */
|
|
u16 frame_pos;
|
|
|
|
/* Compressed image */
|
|
u32 width;
|
|
u32 height;
|
|
u32 *pixels;
|
|
|
|
u16 frame_index;
|
|
Ace_Cel *next;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ Ase bitbuff operations
|
|
|
|
u32 ASE_PeekBits(ASE_Bitbuff *bb, u32 nbits);
|
|
u32 ASE_ConsumeBits(ASE_Bitbuff *bb, u32 nbits);
|
|
void ASE_SkipBits(ASE_Bitbuff *bb, u32 nbits);
|
|
|
|
////////////////////////////////
|
|
//~ Inflate operations
|
|
|
|
u32 ASE_ReverseBits(u32 v, u32 bit_count);
|
|
ASE_HuffDict ASE_InitHuffDict(Arena *arena, u32 max_code_bits, u32 *bl_counts, u32 bl_counts_count);
|
|
u16 ASE_DecodeHuffDict(ASE_HuffDict *huffman, ASE_Bitbuff *bb);
|
|
void ASE_Inflate(u8 *dst, u8 *encoded);
|
|
|
|
////////////////////////////////
|
|
//~ Error handling operations
|
|
|
|
//- Helpers
|
|
void ASE_PushError(Arena *arena, ASE_ErrorList *list, String msg_src);
|
|
u32 ASE_BlendMulU8(u32 a, u32 b);
|
|
u32 ASE_Blend(u32 src, u32 dst, u8 opacity);
|
|
void ASE_MakeDimensionsSquareish(ASE_Header *header, u32 *frames_x, u32 *frames_y, u64 *image_width, u64 *image_height);
|
|
|
|
//- Decode image
|
|
ASE_DecodedImage ASE_DecodeImage(Arena *arena, String encoded);
|
|
|
|
//- Decode sheet
|
|
ASE_DecodedSheet ASE_DecodeSheet(Arena *arena, String encoded);
|