power_play/src/ase/ase_core.h
2025-07-30 16:44:49 -05:00

249 lines
4.6 KiB
C

////////////////////////////////
//~ 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;
};
////////////////////////////////
//~ Error types
Struct(Ase_Error)
{
String msg;
Ase_Error *next;
};
Struct(Ase_ErrorList)
{
u64 count;
Ase_Error *first;
Ase_Error *last;
};
////////////////////////////////
//~ Sheet types
Struct(Ase_Slice)
{
u32 start;
i32 x1;
i32 y1;
i32 x2;
i32 y2;
Ase_Slice *next;
};
Struct(Ase_SliceKey)
{
String name;
u32 num_slices;
Ase_Slice *slice_head;
Ase_SliceKey *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;
};
////////////////////////////////
//~ Decoder result types
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;
};
////////////////////////////////
//~ 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
void Ase_PushError(Arena *arena, Ase_ErrorList *list, String msg_src);
////////////////////////////////
//~ Decoder operations
//- Helpers
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);