mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
87 lines
1.8 KiB
C
87 lines
1.8 KiB
C
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "crunch.h"
|
|
|
|
void crunch(crunch_state_t* state)
|
|
{
|
|
while (state->inputlen && state->outputlen)
|
|
{
|
|
uint8_t data = *state->inputptr++;
|
|
state->inputlen--;
|
|
|
|
if (data & 0x80)
|
|
{
|
|
state->fifo = (state->fifo << 2) | 2 | (data & 1);
|
|
state->fifolen += 2;
|
|
}
|
|
else
|
|
{
|
|
state->fifo = (state->fifo << 8) | data;
|
|
state->fifolen += 8;
|
|
}
|
|
|
|
if (state->fifolen >= 8)
|
|
{
|
|
data = state->fifo >> (state->fifolen - 8);
|
|
*state->outputptr++ = data;
|
|
state->outputlen--;
|
|
state->fifolen -= 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
void donecrunch(crunch_state_t* state)
|
|
{
|
|
if (state->fifolen > 0)
|
|
{
|
|
uint8_t b = 0;
|
|
state->inputptr = &b;
|
|
state->inputlen = 1;
|
|
crunch(state);
|
|
}
|
|
}
|
|
|
|
void uncrunch(crunch_state_t* state)
|
|
{
|
|
while (state->inputlen && state->outputlen)
|
|
{
|
|
if (state->fifolen < 8)
|
|
{
|
|
if (state->inputlen)
|
|
{
|
|
state->fifo = (state->fifo << 8) | *state->inputptr++;
|
|
state->inputlen--;
|
|
state->fifolen += 8;
|
|
}
|
|
else
|
|
state->fifo <<= 8;
|
|
}
|
|
|
|
uint8_t data = state->fifo >> (state->fifolen - 8);
|
|
if (data & 0x80)
|
|
{
|
|
data = ((data >> 6) & 0x01) | 0x80;
|
|
state->fifolen -= 2;
|
|
}
|
|
else
|
|
state->fifolen -= 8;
|
|
|
|
if (data)
|
|
{
|
|
*state->outputptr++ = data;
|
|
state->outputlen--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void doneuncrunch(crunch_state_t* state)
|
|
{
|
|
if (state->fifolen > 0)
|
|
{
|
|
uint8_t b = 0;
|
|
state->inputptr = &b;
|
|
state->inputlen = 1;
|
|
uncrunch(state);
|
|
}
|
|
}
|