#pragma once #include #include "pxl8_types.h" void pxl8_bit_clear(u32* val, u8 bit); u32 pxl8_bit_count(u32 val); void pxl8_bit_set(u32* val, u8 bit); bool pxl8_bit_test(u32 val, u8 bit); void pxl8_bit_toggle(u32* val, u8 bit); void pxl8_pack_u8(u8* buf, size_t offset, u8 val); void pxl8_pack_u16_be(u8* buf, size_t offset, u16 val); void pxl8_pack_u16_le(u8* buf, size_t offset, u16 val); void pxl8_pack_u32_be(u8* buf, size_t offset, u32 val); void pxl8_pack_u32_le(u8* buf, size_t offset, u32 val); void pxl8_pack_u64_be(u8* buf, size_t offset, u64 val); void pxl8_pack_u64_le(u8* buf, size_t offset, u64 val); void pxl8_pack_i8(u8* buf, size_t offset, i8 val); void pxl8_pack_i16_be(u8* buf, size_t offset, i16 val); void pxl8_pack_i16_le(u8* buf, size_t offset, i16 val); void pxl8_pack_i32_be(u8* buf, size_t offset, i32 val); void pxl8_pack_i32_le(u8* buf, size_t offset, i32 val); void pxl8_pack_i64_be(u8* buf, size_t offset, i64 val); void pxl8_pack_i64_le(u8* buf, size_t offset, i64 val); void pxl8_pack_f32_be(u8* buf, size_t offset, f32 val); void pxl8_pack_f32_le(u8* buf, size_t offset, f32 val); void pxl8_pack_f64_be(u8* buf, size_t offset, f64 val); void pxl8_pack_f64_le(u8* buf, size_t offset, f64 val); u8 pxl8_unpack_u8(const u8* buf, size_t offset); u16 pxl8_unpack_u16_be(const u8* buf, size_t offset); u16 pxl8_unpack_u16_le(const u8* buf, size_t offset); u32 pxl8_unpack_u32_be(const u8* buf, size_t offset); u32 pxl8_unpack_u32_le(const u8* buf, size_t offset); u64 pxl8_unpack_u64_be(const u8* buf, size_t offset); u64 pxl8_unpack_u64_le(const u8* buf, size_t offset); i8 pxl8_unpack_i8(const u8* buf, size_t offset); i16 pxl8_unpack_i16_be(const u8* buf, size_t offset); i16 pxl8_unpack_i16_le(const u8* buf, size_t offset); i32 pxl8_unpack_i32_be(const u8* buf, size_t offset); i32 pxl8_unpack_i32_le(const u8* buf, size_t offset); i64 pxl8_unpack_i64_be(const u8* buf, size_t offset); i64 pxl8_unpack_i64_le(const u8* buf, size_t offset); f32 pxl8_unpack_f32_be(const u8* buf, size_t offset); f32 pxl8_unpack_f32_le(const u8* buf, size_t offset); f64 pxl8_unpack_f64_be(const u8* buf, size_t offset); f64 pxl8_unpack_f64_le(const u8* buf, size_t offset); typedef struct { const u8* bytes; u32 offset; u32 size; bool overflow; } pxl8_stream; typedef struct { u8* bytes; u32 capacity; u32 offset; bool overflow; } pxl8_write_stream; static inline pxl8_stream pxl8_stream_create(const u8* bytes, u32 size) { return (pxl8_stream){ .bytes = bytes, .offset = 0, .size = size, .overflow = false }; } static inline pxl8_write_stream pxl8_write_stream_create(u8* bytes, u32 capacity) { return (pxl8_write_stream){ .bytes = bytes, .capacity = capacity, .offset = 0, .overflow = false }; } static inline bool pxl8_stream_can_read(const pxl8_stream* s, u32 count) { return !s->overflow && s->offset + count <= s->size; } static inline bool pxl8_stream_has_overflow(const pxl8_stream* s) { return s->overflow; } static inline bool pxl8_write_stream_has_overflow(const pxl8_write_stream* s) { return s->overflow; } static inline u32 pxl8_stream_position(const pxl8_stream* s) { return s->offset; } static inline u32 pxl8_write_stream_position(const pxl8_write_stream* s) { return s->offset; } static inline void pxl8_stream_seek(pxl8_stream* s, u32 offset) { s->offset = offset; } static inline u8 pxl8_read_u8(pxl8_stream* s) { if (s->offset + 1 > s->size) { s->overflow = true; return 0; } return pxl8_unpack_u8(s->bytes, s->offset++); } static inline u16 pxl8_read_u16(pxl8_stream* s) { if (s->offset + 2 > s->size) { s->overflow = true; return 0; } u16 val = pxl8_unpack_u16_le(s->bytes, s->offset); s->offset += 2; return val; } static inline u16 pxl8_read_u16_be(pxl8_stream* s) { if (s->offset + 2 > s->size) { s->overflow = true; return 0; } u16 val = pxl8_unpack_u16_be(s->bytes, s->offset); s->offset += 2; return val; } static inline u32 pxl8_read_u32(pxl8_stream* s) { if (s->offset + 4 > s->size) { s->overflow = true; return 0; } u32 val = pxl8_unpack_u32_le(s->bytes, s->offset); s->offset += 4; return val; } static inline u32 pxl8_read_u32_be(pxl8_stream* s) { if (s->offset + 4 > s->size) { s->overflow = true; return 0; } u32 val = pxl8_unpack_u32_be(s->bytes, s->offset); s->offset += 4; return val; } static inline u64 pxl8_read_u64(pxl8_stream* s) { if (s->offset + 8 > s->size) { s->overflow = true; return 0; } u64 val = pxl8_unpack_u64_le(s->bytes, s->offset); s->offset += 8; return val; } static inline u64 pxl8_read_u64_be(pxl8_stream* s) { if (s->offset + 8 > s->size) { s->overflow = true; return 0; } u64 val = pxl8_unpack_u64_be(s->bytes, s->offset); s->offset += 8; return val; } static inline i16 pxl8_read_i16(pxl8_stream* s) { return (i16)pxl8_read_u16(s); } static inline i32 pxl8_read_i32(pxl8_stream* s) { return (i32)pxl8_read_u32(s); } static inline f32 pxl8_read_f32(pxl8_stream* s) { if (s->offset + 4 > s->size) { s->overflow = true; return 0; } f32 val = pxl8_unpack_f32_le(s->bytes, s->offset); s->offset += 4; return val; } static inline f32 pxl8_read_f32_be(pxl8_stream* s) { if (s->offset + 4 > s->size) { s->overflow = true; return 0; } f32 val = pxl8_unpack_f32_be(s->bytes, s->offset); s->offset += 4; return val; } static inline void pxl8_read_bytes(pxl8_stream* s, void* dest, u32 count) { if (s->offset + count > s->size) { s->overflow = true; return; } memcpy(dest, &s->bytes[s->offset], count); s->offset += count; } static inline void pxl8_skip_bytes(pxl8_stream* s, u32 count) { if (s->offset + count > s->size) { s->overflow = true; return; } s->offset += count; } static inline const u8* pxl8_read_ptr(pxl8_stream* s, u32 count) { if (s->offset + count > s->size) { s->overflow = true; return NULL; } const u8* ptr = &s->bytes[s->offset]; s->offset += count; return ptr; } static inline void pxl8_write_u8(pxl8_write_stream* s, u8 val) { if (s->offset + 1 > s->capacity) { s->overflow = true; return; } pxl8_pack_u8(s->bytes, s->offset++, val); } static inline void pxl8_write_u16(pxl8_write_stream* s, u16 val) { if (s->offset + 2 > s->capacity) { s->overflow = true; return; } pxl8_pack_u16_le(s->bytes, s->offset, val); s->offset += 2; } static inline void pxl8_write_u16_be(pxl8_write_stream* s, u16 val) { if (s->offset + 2 > s->capacity) { s->overflow = true; return; } pxl8_pack_u16_be(s->bytes, s->offset, val); s->offset += 2; } static inline void pxl8_write_u32(pxl8_write_stream* s, u32 val) { if (s->offset + 4 > s->capacity) { s->overflow = true; return; } pxl8_pack_u32_le(s->bytes, s->offset, val); s->offset += 4; } static inline void pxl8_write_u32_be(pxl8_write_stream* s, u32 val) { if (s->offset + 4 > s->capacity) { s->overflow = true; return; } pxl8_pack_u32_be(s->bytes, s->offset, val); s->offset += 4; } static inline void pxl8_write_u64(pxl8_write_stream* s, u64 val) { if (s->offset + 8 > s->capacity) { s->overflow = true; return; } pxl8_pack_u64_le(s->bytes, s->offset, val); s->offset += 8; } static inline void pxl8_write_u64_be(pxl8_write_stream* s, u64 val) { if (s->offset + 8 > s->capacity) { s->overflow = true; return; } pxl8_pack_u64_be(s->bytes, s->offset, val); s->offset += 8; } static inline void pxl8_write_f32(pxl8_write_stream* s, f32 val) { if (s->offset + 4 > s->capacity) { s->overflow = true; return; } pxl8_pack_f32_le(s->bytes, s->offset, val); s->offset += 4; } static inline void pxl8_write_f32_be(pxl8_write_stream* s, f32 val) { if (s->offset + 4 > s->capacity) { s->overflow = true; return; } pxl8_pack_f32_be(s->bytes, s->offset, val); s->offset += 4; } static inline void pxl8_write_bytes(pxl8_write_stream* s, const void* src, u32 count) { if (s->offset + count > s->capacity) { s->overflow = true; return; } memcpy(&s->bytes[s->offset], src, count); s->offset += count; }