game/axl_rle.c
2025-12-07 23:07:56 +03:00

82 lines
1.6 KiB
C

#include "axl_rle.h"
#include "axl_vlq.h"
#include "axl_memory.h"
u32 axl_rle_encode(const u8* src, u32 src_size, u8* dst, u32 dst_size)
{
if (src == NULL || dst == NULL || src_size == 0 || dst_size == 0)
{
return 0;
}
u8 vlq_buff[AXL_VLQ_MAX_LEN];
const u8* head = src;
u32 used_size = 0;
while(head < src + src_size)
{
const u8 value = *head;
u32 count = 0;
while(head < src + src_size && *head == value)
{
count++;
head++;
}
u32 vlq_len = axl_vlq_encode(count, vlq_buff);
u32 req_size = vlq_len + 1;
if(req_size + used_size > dst_size)
{
return 0;
}
axl_memcpy(dst, vlq_buff, vlq_len);
dst += vlq_len;
axl_memcpy(dst, &value, 1);
dst += 1;
used_size += req_size;
}
return used_size;
}
u32 axl_rle_decode(const u8* src, u32 src_size, u8* dst, u32 dst_size)
{
if (src == NULL || dst == NULL || src_size == 0 || dst_size == 0)
{
return 0;
}
const u8* head = src;
u32 used_size = 0;
while(head < src + src_size)
{
u32 repeat_count;
u32 vlq_len = axl_vlq_decode(head, &repeat_count);
if(vlq_len == 0 || head + vlq_len + 1 > src + src_size)
{
return 0;
}
head += vlq_len;
const u8 value = *head;
head++;
used_size += repeat_count;
if(used_size > dst_size)
{
return 0;
}
axl_memset(dst, value, repeat_count);
dst += repeat_count;
}
return used_size;
}