int id; /* option ID */
int id_len; /* bit length of code option identification key */
int *id_table; /* table maps IDs to states */
- void (*put_sample)(aec_streamp, int64_t);
+ void (*put_sample)(struct aec_stream *, int64_t);
int ref_int; /* reference sample is every ref_int samples */
int64_t last_out; /* previous output for post-processing */
int64_t xmin; /* minimum integer for post-processing */
} decode_state;
/* decoding table for the second-extension option */
-static const int second_extension[92][2] =
-{
+static const int second_extension[92][2] = {
{0, 0},
{1, 1}, {1, 1},
{2, 3}, {2, 3}, {2, 3},
{12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}, {12, 78}
};
-enum
-{
+enum {
M_ID = 0,
M_SPLIT,
M_SPLIT_FS,
M_UNCOMP_COPY,
};
-static void put_msb_32(aec_streamp strm, int64_t data)
+static void put_msb_32(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data >> 24;
*strm->next_out++ = data >> 16;
strm->total_out += 4;
}
-static void put_msb_24(aec_streamp strm, int64_t data)
+static void put_msb_24(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data >> 16;
*strm->next_out++ = data >> 8;
strm->total_out += 3;
}
-static void put_msb_16(aec_streamp strm, int64_t data)
+static void put_msb_16(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data >> 8;
*strm->next_out++ = data;
strm->total_out += 2;
}
-static void put_lsb_32(aec_streamp strm, int64_t data)
+static void put_lsb_32(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data;
*strm->next_out++ = data >> 8;
strm->total_out += 4;
}
-static void put_lsb_24(aec_streamp strm, int64_t data)
+static void put_lsb_24(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data;
*strm->next_out++ = data >> 8;
strm->total_out += 3;
}
-static void put_lsb_16(aec_streamp strm, int64_t data)
+static void put_lsb_16(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data;
*strm->next_out++ = data >> 8;
strm->total_out += 2;
}
-static void put_8(aec_streamp strm, int64_t data)
+static void put_8(struct aec_stream *strm, int64_t data)
{
*strm->next_out++ = data;
strm->avail_out--;
strm->total_out++;
}
-static inline void u_put(aec_streamp strm, int64_t sample)
+static inline void u_put(struct aec_stream *strm, int64_t sample)
{
int64_t x, d, th, D, lower;
decode_state *state = strm->state;
- if (state->pp && (state->samples_out % state->ref_int != 0))
- {
+ if (state->pp && (state->samples_out % state->ref_int != 0)) {
d = sample;
x = state->last_out;
lower = x - state->xmin;
th = MIN(lower, state->xmax - x);
- if (d <= 2 * th)
- {
+ if (d <= 2 * th) {
if (d & 1)
D = - (d + 1) / 2;
else
D = th - d;
}
sample = x + D;
- }
- else
- {
- if (strm->flags & AEC_DATA_SIGNED)
- {
+ } else {
+ if (strm->flags & AEC_DATA_SIGNED) {
int m = 64 - strm->bit_per_sample;
/* Reference samples have to be sign extended */
sample = (sample << m) >> m;
state->samples_out++;
}
-static inline int64_t u_get(aec_streamp strm, unsigned int n)
+static inline int64_t u_get(struct aec_stream *strm, unsigned int n)
{
/**
Unsafe get n bit from input stream
decode_state *state;
state = strm->state;
- while (state->bitp < n)
- {
+ while (state->bitp < n) {
strm->avail_in--;
strm->total_in++;
state->acc = (state->acc << 8) | *strm->next_in++;
return (state->acc >> state->bitp) & ((1ULL << n) - 1);
}
-static inline int64_t u_get_fs(aec_streamp strm)
+static inline int64_t u_get_fs(struct aec_stream *strm)
{
/**
Interpret a Fundamental Sequence from the input buffer.
return fs;
}
-static inline void fast_split(aec_streamp strm)
+static inline void fast_split(struct aec_stream *strm)
{
int i, k;
decode_state *state;
for (i = state->ref; i < strm->block_size; i++)
state->block[i] = u_get_fs(strm) << k;
- for (i = state->ref; i < strm->block_size; i++)
- {
+ for (i = state->ref; i < strm->block_size; i++) {
state->block[i] += u_get(strm, k);
u_put(strm, state->block[i]);
}
}
-static inline void fast_zero(aec_streamp strm)
+static inline void fast_zero(struct aec_stream *strm)
{
int i = strm->state->i;
u_put(strm, 0);
}
-static inline void fast_se(aec_streamp strm)
+static inline void fast_se(struct aec_stream *strm)
{
int i;
int64_t gamma, beta, ms, delta1;
i = strm->state->ref;
- while (i < strm->block_size)
- {
+ while (i < strm->block_size) {
gamma = u_get_fs(strm);
beta = second_extension[gamma][0];
ms = second_extension[gamma][1];
delta1 = gamma - ms;
- if ((i & 1) == 0)
- {
+ if ((i & 1) == 0) {
u_put(strm, beta - delta1);
i++;
}
}
}
-static inline void fast_uncomp(aec_streamp strm)
+static inline void fast_uncomp(struct aec_stream *strm)
{
int i;
u_put(strm, u_get(strm, strm->bit_per_sample));
}
-int aec_decode_init(aec_streamp strm)
+int aec_decode_init(struct aec_stream *strm)
{
int i, modi;
decode_state *state;
- /* Some sanity checks */
if (strm->bit_per_sample > 32 || strm->bit_per_sample == 0)
- {
return AEC_CONF_ERROR;
- }
- /* Internal state for decoder */
state = (decode_state *) malloc(sizeof(decode_state));
if (state == NULL)
- {
return AEC_MEM_ERROR;
- }
+
strm->state = state;
- if (strm->bit_per_sample > 16)
- {
+ if (strm->bit_per_sample > 16) {
state->id_len = 5;
- if (strm->bit_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE)
- {
+ if (strm->bit_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE) {
state->byte_per_sample = 3;
if (strm->flags & AEC_DATA_MSB)
state->put_sample = put_msb_24;
else
state->put_sample = put_lsb_24;
- }
- else
- {
+ } else {
state->byte_per_sample = 4;
if (strm->flags & AEC_DATA_MSB)
state->put_sample = put_msb_32;
state->out_blklen = strm->block_size
* state->byte_per_sample;
}
- else if (strm->bit_per_sample > 8)
- {
+ else if (strm->bit_per_sample > 8) {
state->byte_per_sample = 2;
state->id_len = 4;
state->out_blklen = strm->block_size * 2;
state->put_sample = put_msb_16;
else
state->put_sample = put_lsb_16;
- }
- else
- {
+ } else {
state->byte_per_sample = 1;
state->id_len = 3;
state->out_blklen = strm->block_size;
state->put_sample = put_8;
}
- if (strm->flags & AEC_DATA_SIGNED)
- {
+ if (strm->flags & AEC_DATA_SIGNED) {
state->xmin = -(1ULL << (strm->bit_per_sample - 1));
state->xmax = (1ULL << (strm->bit_per_sample - 1)) - 1;
- }
- else
- {
+ } else {
state->xmin = 0;
state->xmax = (1ULL << strm->bit_per_sample) - 1;
}
modi = 1UL << state->id_len;
state->id_table = (int *)malloc(modi * sizeof(int));
if (state->id_table == NULL)
- {
return AEC_MEM_ERROR;
- }
+
state->id_table[0] = M_LOW_ENTROPY;
- for (i = 1; i < modi - 1; i++)
- {
+ for (i = 1; i < modi - 1; i++) {
state->id_table[i] = M_SPLIT;
}
state->id_table[modi - 1] = M_UNCOMP;
state->block = (int64_t *)malloc(strm->block_size * sizeof(int64_t));
if (state->block == NULL)
- {
return AEC_MEM_ERROR;
- }
+
strm->total_in = 0;
strm->total_out = 0;
return AEC_OK;
}
-int aec_decode_end(aec_streamp strm)
+int aec_decode_end(struct aec_stream *strm)
{
decode_state *state;
#define ASK(n) \
do { \
- while (state->bitp < (unsigned)(n)) \
- { \
- if (strm->avail_in == 0) goto req_buffer; \
+ while (state->bitp < (unsigned)(n)) { \
+ if (strm->avail_in == 0) \
+ goto req_buffer; \
strm->avail_in--; \
strm->total_in++; \
state->acc <<= 8; \
#define DROP(n) state->bitp -= (unsigned)(n)
-#define ASKFS() \
- do { \
- ASK(1); \
- while ((state->acc & (1ULL << (state->bitp - 1))) == 0) \
- { \
- if (state->bitp == 1) \
- { \
- if (strm->avail_in == 0) goto req_buffer; \
- strm->avail_in--; \
- strm->total_in++; \
- state->acc <<= 8; \
- state->acc |= *strm->next_in++; \
- state->bitp += 8; \
- } \
- state->fs++; \
- state->bitp--; \
- } \
+#define ASKFS() \
+ do { \
+ ASK(1); \
+ while ((state->acc & (1ULL << (state->bitp - 1))) == 0) { \
+ if (state->bitp == 1) { \
+ if (strm->avail_in == 0) \
+ goto req_buffer; \
+ strm->avail_in--; \
+ strm->total_in++; \
+ state->acc <<= 8; \
+ state->acc |= *strm->next_in++; \
+ state->bitp += 8; \
+ } \
+ state->fs++; \
+ state->bitp--; \
+ } \
} while (0)
#define GETFS() state->fs
#define PUT(sample) \
do { \
- if (strm->avail_out == 0) goto req_buffer; \
+ if (strm->avail_out == 0) \
+ goto req_buffer; \
u_put(strm, (sample)); \
} while (0)
} while (0)
-int aec_decode(aec_streamp strm, int flush)
+int aec_decode(struct aec_stream *strm, int flush)
{
/**
Finite-state machine implementation of the adaptive entropy
state = strm->state;
- for (;;)
- {
- switch(state->mode)
- {
+ for (;;) {
+ switch(state->mode) {
case M_ID:
if (state->pp
&& (state->samples_out / strm->block_size) % strm->rsi == 0)
break;
case M_SPLIT:
- if (SAFE)
- {
+ if (SAFE) {
fast_split(strm);
state->mode = M_ID;
break;
}
- if (state->ref)
- {
+ if (state->ref) {
COPYSAMPLE();
state->n = strm->block_size - 1;
- }
- else
- {
+ } else {
state->n = strm->block_size;
}
state->mode = M_SPLIT_FS;
case M_SPLIT_FS:
- do
- {
+ do {
ASKFS();
state->block[state->i] = GETFS();
DROPFS();
- }
- while(state->i--);
+ } while(state->i--);
state->i = state->n - 1;
state->mode = M_SPLIT_OUTPUT;
case M_SPLIT_OUTPUT:
k = state->id - 1;
- do
- {
+ do {
ASK(k);
PUT((state->block[state->i] << k) + GET(k));
DROP(k);
- }
- while(state->i--);
+ } while(state->i--);
state->mode = M_ID;
break;
if (state->ref)
COPYSAMPLE();
- if(state->id == 1)
- {
+ if(state->id == 1) {
state->mode = M_SE;
break;
}
zero_blocks = GETFS() + 1;
DROPFS();
- if (zero_blocks == ROS)
- {
+ if (zero_blocks == ROS) {
zero_blocks = 64 - (
(state->samples_out / strm->block_size)
% strm->rsi % 64);
- }
- else if (zero_blocks > ROS)
- {
+ } else if (zero_blocks > ROS) {
zero_blocks--;
}
else
state->i = zero_blocks * strm->block_size;
- if (strm->avail_out >= state->i * state->byte_per_sample)
- {
+ if (strm->avail_out >= state->i * state->byte_per_sample) {
fast_zero(strm);
state->mode = M_ID;
break;
break;
case M_SE:
- if (SAFE)
- {
+ if (SAFE) {
fast_se(strm);
state->mode = M_ID;
break;
state->i = state->ref;
case M_SE_DECODE:
- while(state->i < strm->block_size)
- {
+ while(state->i < strm->block_size) {
ASKFS();
gamma = GETFS();
beta = second_extension[gamma][0];
ms = second_extension[gamma][1];
delta1 = gamma - ms;
- if ((state->i & 1) == 0)
- {
+ if ((state->i & 1) == 0) {
PUT(beta - delta1);
state->i++;
}
break;
case M_UNCOMP:
- if (SAFE)
- {
+ if (SAFE) {
fast_uncomp(strm);
state->mode = M_ID;
break;
#define MIN(a, b) (((a) < (b))? (a): (b))
-static int m_get_block(aec_streamp strm);
-static int m_get_block_cautious(aec_streamp strm);
-static int m_check_zero_block(aec_streamp strm);
-static int m_select_code_option(aec_streamp strm);
-static int m_flush_block(aec_streamp strm);
-static int m_flush_block_cautious(aec_streamp strm);
-static int m_encode_splitting(aec_streamp strm);
-static int m_encode_uncomp(aec_streamp strm);
-static int m_encode_se(aec_streamp strm);
-static int m_encode_zero(aec_streamp strm);
-
-/*
- *
- * Bit emitters
- *
- */
-
-static inline void emit(encode_state *state, uint32_t data, int bits)
+static int m_get_block(struct aec_stream *strm);
+static int m_get_block_cautious(struct aec_stream *strm);
+static int m_check_zero_block(struct aec_stream *strm);
+static int m_select_code_option(struct aec_stream *strm);
+static int m_flush_block(struct aec_stream *strm);
+static int m_flush_block_cautious(struct aec_stream *strm);
+static int m_encode_splitting(struct aec_stream *strm);
+static int m_encode_uncomp(struct aec_stream *strm);
+static int m_encode_se(struct aec_stream *strm);
+static int m_encode_zero(struct aec_stream *strm);
+
+static inline void emit(struct internal_state *state,
+ uint32_t data, int bits)
{
- if (bits <= state->bit_p)
- {
+ /**
+ Emit sequence of bits.
+ */
+
+ if (bits <= state->bit_p) {
state->bit_p -= bits;
*state->cds_p += data << state->bit_p;
- }
- else
- {
+ } else {
bits -= state->bit_p;
*state->cds_p++ += (uint64_t)data >> bits;
- while (bits & ~7)
- {
+ while (bits & ~7) {
bits -= 8;
*state->cds_p++ = data >> bits;
}
}
}
-static inline void emitfs(encode_state *state, int fs)
+static inline void emitfs(struct internal_state *state, int fs)
{
/**
Emits a fundamental sequence.
fs zero bits followed by one 1 bit.
*/
- for(;;)
- {
- if (fs < state->bit_p)
- {
+ for(;;) {
+ if (fs < state->bit_p) {
state->bit_p -= fs + 1;
*state->cds_p += 1 << state->bit_p;
break;
- }
- else
- {
+ } else {
fs -= state->bit_p;
*++state->cds_p = 0;
state->bit_p = 8;
}
#define EMITBLOCK(ref) \
- static inline void emitblock_##ref(aec_streamp strm, int k) \
+ static inline void emitblock_##ref(struct aec_stream *strm, \
+ int k) \
{ \
int b; \
uint64_t a; \
- encode_state *state = strm->state; \
+ struct internal_state *state = strm->state; \
uint32_t *in = state->block_p + ref; \
uint32_t *in_end = state->block_p + strm->block_size; \
uint64_t mask = (1ULL << k) - 1; \
\
a = *o; \
\
- while(in < in_end) \
- { \
+ while(in < in_end) { \
a <<= 56; \
p = (p % 8) + 56; \
\
- while (p > k && in < in_end) \
- { \
+ while (p > k && in < in_end) { \
p -= k; \
a += ((uint64_t)(*in++) & mask) << p; \
} \
EMITBLOCK(0);
EMITBLOCK(1);
-static void preprocess_unsigned(aec_streamp strm)
+static void preprocess_unsigned(struct aec_stream *strm)
{
int i;
int64_t theta, Delta, prev;
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
- /* Insert reference samples into first block of Reference Sample
- * Interval.
- */
prev = state->block_buf[0];
- for (i = 1; i < strm->rsi * strm->block_size; i++)
- {
+ for (i = 1; i < strm->rsi * strm->block_size; i++) {
theta = MIN(prev, state->xmax - prev);
Delta = (int64_t)state->block_buf[i] - prev;
prev = state->block_buf[i];
- if (0 <= Delta && Delta <= theta)
- {
+ if (0 <= Delta && Delta <= theta) {
state->block_buf[i] = 2 * Delta;
- }
- else if (-theta <= Delta && Delta < 0)
- {
+ } else if (-theta <= Delta && Delta < 0) {
state->block_buf[i] = 2
* (Delta < 0 ? -(uint64_t)Delta : Delta) - 1;
- }
- else
- {
+ } else {
state->block_buf[i] = theta
+ (Delta < 0 ? -(uint64_t)Delta : Delta);
}
}
}
-static void preprocess_signed(aec_streamp strm)
+static void preprocess_signed(struct aec_stream *strm)
{
int i, m;
int64_t theta, Delta, prev, sample;
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
- /* Insert reference samples into first block of Reference Sample
- * Interval.
- */
m = 64 - strm->bit_per_sample;
prev = ((int64_t)state->block_buf[0] << m) >> m;
- for (i = 1; i < strm->rsi * strm->block_size; i++)
- {
+ for (i = 1; i < strm->rsi * strm->block_size; i++) {
theta = MIN(prev - state->xmin, state->xmax - prev);
sample = ((int64_t)state->block_buf[i] << m) >> m;
Delta = sample - prev;
prev = sample;
- if (0 <= Delta && Delta <= theta)
- {
+ if (0 <= Delta && Delta <= theta) {
state->block_buf[i] = 2 * Delta;
- }
- else if (-theta <= Delta && Delta < 0)
- {
+ } else if (-theta <= Delta && Delta < 0) {
state->block_buf[i] = 2
* (Delta < 0 ? -(uint64_t)Delta : Delta) - 1;
- }
- else
- {
+ } else {
state->block_buf[i] = theta
+ (Delta < 0 ? -(uint64_t)Delta : Delta);
}
*
*/
-static int m_get_block(aec_streamp strm)
+static int m_get_block(struct aec_stream *strm)
{
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
- if (strm->avail_out > state->cds_len)
- {
- if (!state->direct_out)
- {
+ if (strm->avail_out > state->cds_len) {
+ if (!state->direct_out) {
state->direct_out = 1;
*strm->next_out = *state->cds_p;
state->cds_p = strm->next_out;
}
- }
- else
- {
- if (state->zero_blocks == 0 || state->direct_out)
- {
+ } else {
+ if (state->zero_blocks == 0 || state->direct_out) {
/* copy leftover from last block */
*state->cds_buf = *state->cds_p;
state->cds_p = state->cds_buf;
state->direct_out = 0;
}
- if (state->blocks_avail == 0)
- {
+ if (state->blocks_avail == 0) {
state->ref = 1;
state->blocks_avail = strm->rsi - 1;
state->block_p = state->block_buf;
- if (strm->avail_in >= state->block_len * strm->rsi)
- {
+ if (strm->avail_in >= state->block_len * strm->rsi) {
state->get_block(strm);
if (strm->flags & AEC_DATA_PREPROCESS)
state->preprocess(strm);
return m_check_zero_block(strm);
- }
- else
- {
+ } else {
state->i = 0;
state->mode = m_get_block_cautious;
}
- }
- else
- {
+ } else {
state->ref = 0;
state->block_p += strm->block_size;
state->blocks_avail--;
return M_CONTINUE;
}
-static int m_get_block_cautious(aec_streamp strm)
+static int input_empty(struct aec_stream *strm)
{
int j;
- encode_state *state = strm->state;
-
- do
- {
- if (strm->avail_in > 0)
- {
- state->block_buf[state->i] = state->get_sample(strm);
- }
- else
- {
- if (state->flush == AEC_FLUSH)
- {
- if (state->i > 0)
- {
- /* Pad block with last sample if we have a partial
- * block.
- */
- for (j = state->i; j < strm->rsi * strm->block_size; j++)
- state->block_buf[j] = state->block_buf[state->i - 1];
- state->i = strm->rsi * strm->block_size;
- }
- else
- {
- if (state->zero_blocks)
- {
- /* Output any remaining zero blocks */
- state->mode = m_encode_zero;
- return M_CONTINUE;
- }
+ struct internal_state *state = strm->state;
+
+ if (state->flush == AEC_FLUSH) {
+ if (state->i > 0) {
+ for (j = state->i; j < strm->rsi * strm->block_size; j++)
+ state->block_buf[j] = state->block_buf[state->i - 1];
+ state->i = strm->rsi * strm->block_size;
+ } else {
+ if (state->zero_blocks) {
+ state->mode = m_encode_zero;
+ return M_CONTINUE;
+ }
- /* Pad last output byte with 0 bits if user wants
- * to flush, i.e. we got all input there is.
- */
- emit(state, 0, state->bit_p);
- if (state->direct_out == 0)
- *strm->next_out++ = *state->cds_p;
- strm->avail_out--;
- strm->total_out++;
+ emit(state, 0, state->bit_p);
+ if (state->direct_out == 0)
+ *strm->next_out++ = *state->cds_p;
+ strm->avail_out--;
+ strm->total_out++;
- return M_EXIT;
- }
- }
- else
- {
- return M_EXIT;
- }
+ return M_EXIT;
}
}
- while (++state->i < strm->rsi * strm->block_size);
+
+ return M_EXIT;
+}
+
+static int m_get_block_cautious(struct aec_stream *strm)
+{
+ struct internal_state *state = strm->state;
+
+ do {
+ if (strm->avail_in > 0)
+ state->block_buf[state->i] = state->get_sample(strm);
+ else
+ return input_empty(strm);
+ } while (++state->i < strm->rsi * strm->block_size);
if (strm->flags & AEC_DATA_PREPROCESS)
state->preprocess(strm);
return m_check_zero_block(strm);
}
-static inline int m_check_zero_block(aec_streamp strm)
+static int m_check_zero_block(struct aec_stream *strm)
{
int i;
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
i = state->ref;
while(i < strm->block_size && state->block_p[i] == 0)
i++;
- if (i == strm->block_size)
- {
- /* remember ref on first zero block */
- if (state->zero_blocks == 0)
- {
+ if (i == strm->block_size) {
+ if (state->zero_blocks == 0) {
state->zero_ref = state->ref;
state->zero_ref_sample = state->block_p[0];
}
state->zero_blocks++;
- if ((strm->rsi - state->blocks_avail) % 64 == 0)
- {
+ if ((strm->rsi - state->blocks_avail) % 64 == 0) {
if (state->zero_blocks > 4)
state->zero_blocks = ROS;
state->mode = m_encode_zero;
}
state->mode = m_get_block;
return M_CONTINUE;
- }
- else if (state->zero_blocks)
- {
+ } else if (state->zero_blocks) {
/* The current block isn't zero but we have to emit a previous
* zero block first. The current block will be handled
* later.
return M_CONTINUE;
}
-static inline int m_select_code_option(aec_streamp strm)
+static uint64_t block_fs(struct aec_stream *strm, int k)
{
- int i, j, k, this_bs, looked_bothways, direction;
- uint64_t split_len, uncomp_len;
- uint64_t split_len_min, fs_len;
- uint64_t d, se_len;
- encode_state *state = strm->state;
+ int j;
+ uint64_t fs;
+ struct internal_state *state = strm->state;
+
+ fs = (uint64_t)(state->block_p[1] >> k)
+ + (uint64_t)(state->block_p[2] >> k)
+ + (uint64_t)(state->block_p[3] >> k)
+ + (uint64_t)(state->block_p[4] >> k)
+ + (uint64_t)(state->block_p[5] >> k)
+ + (uint64_t)(state->block_p[6] >> k)
+ + (uint64_t)(state->block_p[7] >> k);
+
+ if (strm->block_size > 8)
+ for (j = 1; j < strm->block_size / 8; j++)
+ fs +=
+ (uint64_t)(state->block_p[j * 8 + 0] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 1] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 2] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 3] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 4] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 5] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 6] >> k)
+ + (uint64_t)(state->block_p[j * 8 + 7] >> k);
+
+ if (state->ref == 0)
+ fs += (uint64_t)(state->block_p[0] >> k);
+
+ return fs;
+}
- /* Length of this block minus reference sample (if present) */
- this_bs = strm->block_size - state->ref;
+static int count_splitting_option(struct aec_stream *strm)
+{
+ int i, k, this_bs, looked_bothways, direction;
+ uint64_t len, len_min, fs_len;
+ struct internal_state *state = strm->state;
- split_len_min = UINT64_MAX;
+ this_bs = strm->block_size - state->ref;
+ len_min = UINT64_MAX;
i = k = state->k;
direction = 1;
looked_bothways = 0;
/* Starting with splitting position of last block. Look left and
* possibly right to find new minimum.
*/
- for (;;)
- {
- fs_len = (uint64_t)(state->block_p[1] >> i)
- + (uint64_t)(state->block_p[2] >> i)
- + (uint64_t)(state->block_p[3] >> i)
- + (uint64_t)(state->block_p[4] >> i)
- + (uint64_t)(state->block_p[5] >> i)
- + (uint64_t)(state->block_p[6] >> i)
- + (uint64_t)(state->block_p[7] >> i);
-
- if (strm->block_size > 8)
- for (j = 1; j < strm->block_size / 8; j++)
- fs_len +=
- (uint64_t)(state->block_p[j * 8 + 0] >> i)
- + (uint64_t)(state->block_p[j * 8 + 1] >> i)
- + (uint64_t)(state->block_p[j * 8 + 2] >> i)
- + (uint64_t)(state->block_p[j * 8 + 3] >> i)
- + (uint64_t)(state->block_p[j * 8 + 4] >> i)
- + (uint64_t)(state->block_p[j * 8 + 5] >> i)
- + (uint64_t)(state->block_p[j * 8 + 6] >> i)
- + (uint64_t)(state->block_p[j * 8 + 7] >> i);
-
- if (state->ref == 0)
- fs_len += (uint64_t)(state->block_p[0] >> i);
-
- split_len = fs_len + this_bs * (i + 1);
-
- if (split_len < split_len_min)
- {
- if (split_len_min < UINT64_MAX)
- {
+ for (;;) {
+ fs_len = block_fs(strm, i);
+ len = fs_len + this_bs * (i + 1);
+
+ if (len < len_min) {
+ if (len_min < UINT64_MAX) {
/* We are moving towards the minimum so it cant be in
* the other direction.
*/
looked_bothways = 1;
}
- split_len_min = split_len;
+ len_min = len;
k = i;
- if (direction == 1)
- {
- if (fs_len < this_bs)
- {
+ if (direction == 1) {
+ if (fs_len < this_bs) {
/* Next can't get better because what we lose by
* additional uncompressed bits isn't compensated
* by a smaller FS part. Vice versa if we are
* coming from the other direction.
*/
- if (looked_bothways)
- {
+ if (looked_bothways) {
break;
- }
- else
- {
+ } else {
direction = -direction;
looked_bothways = 1;
i = state->k;
}
- }
- else
- {
- while (fs_len > 5 * this_bs)
- {
+ } else {
+ while (fs_len > 5 * this_bs) {
i++;
fs_len /= 5;
}
}
- }
- else if (fs_len > this_bs)
- {
+ } else if (fs_len > this_bs) {
/* Since we started looking the other way there is no
* need to turn back.
*/
break;
}
- }
- else
- {
+ } else {
/* Stop looking for better option if we don't see any
* improvement.
*/
- if (looked_bothways)
- {
- break;
- }
- else
- {
- direction = -direction;
- looked_bothways = 1;
- i = state->k;
- }
+ if (looked_bothways) {
+ break;
+ } else {
+ direction = -direction;
+ looked_bothways = 1;
+ i = state->k;
+ }
}
if (i + direction < 0
- || i + direction >= strm->bit_per_sample - 2)
- {
+ || i + direction >= strm->bit_per_sample - 2) {
if (looked_bothways)
break;
looked_bothways = 1;
i = state->k;
}
-
i += direction;
}
state->k = k;
- /* Count bits for 2nd extension */
- se_len = 1;
- for (i = 0; i < strm->block_size; i+= 2)
- {
+ return len_min;
+}
+
+static int count_se_option(uint64_t limit, struct aec_stream *strm)
+{
+ int i;
+ uint64_t d, len;
+ struct internal_state *state = strm->state;
+
+ len = 1;
+
+ for (i = 0; i < strm->block_size; i+= 2) {
d = (uint64_t)state->block_p[i]
+ (uint64_t)state->block_p[i + 1];
/* we have to worry about overflow here */
- if (d > split_len_min)
- {
- se_len = UINT64_MAX;
+ if (d > limit) {
+ len = UINT64_MAX;
break;
- }
- else
- {
- se_len += d * (d + 1) / 2 + (uint64_t)state->block_p[i + 1];
+ } else {
+ len += d * (d + 1) / 2
+ + (uint64_t)state->block_p[i + 1];
}
}
+ return len;
+}
+
+static int m_select_code_option(struct aec_stream *strm)
+{
+ uint64_t uncomp_len, split_len, se_len;
+ struct internal_state *state = strm->state;
- /* Length of uncompressed block */
- uncomp_len = this_bs * strm->bit_per_sample;
+ uncomp_len = (strm->block_size - state->ref)
+ * strm->bit_per_sample;
+ split_len = count_splitting_option(strm);
+ se_len = count_se_option(split_len, strm);
- /* Decide which option to use */
- if (split_len_min < uncomp_len)
- {
- if (split_len_min < se_len)
- {
- /* Splitting won - the most common case. */
+ if (split_len < uncomp_len) {
+ if (split_len < se_len)
return m_encode_splitting(strm);
- }
else
- {
return m_encode_se(strm);
- }
- }
- else
- {
+ } else {
if (uncomp_len <= se_len)
- {
return m_encode_uncomp(strm);
- }
else
- {
return m_encode_se(strm);
- }
}
}
-static inline int m_encode_splitting(aec_streamp strm)
+static int m_encode_splitting(struct aec_stream *strm)
{
int i;
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
int k = state->k;
emit(state, k + 1, state->id_len);
return m_flush_block(strm);
}
-static inline int m_encode_uncomp(aec_streamp strm)
+static int m_encode_uncomp(struct aec_stream *strm)
{
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
emit(state, (1 << state->id_len) - 1, state->id_len);
emitblock_0(strm, strm->bit_per_sample);
return m_flush_block(strm);
}
-static inline int m_encode_se(aec_streamp strm)
+static int m_encode_se(struct aec_stream *strm)
{
int i;
uint32_t d;
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
emit(state, 1, state->id_len + 1);
if (state->ref)
emit(state, state->block_p[0], strm->bit_per_sample);
- for (i = 0; i < strm->block_size; i+= 2)
- {
+ for (i = 0; i < strm->block_size; i+= 2) {
d = state->block_p[i] + state->block_p[i + 1];
emitfs(state, d * (d + 1) / 2 + state->block_p[i + 1]);
}
return m_flush_block(strm);
}
-static inline int m_encode_zero(aec_streamp strm)
+static int m_encode_zero(struct aec_stream *strm)
{
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
emit(state, 0, state->id_len + 1);
return m_flush_block(strm);
}
-static inline int m_flush_block(aec_streamp strm)
+static int m_flush_block(struct aec_stream *strm)
{
+ /**
+ Flush block in direct_out mode by updating counters.
+
+ Fall back to slow flushing if in buffered mode.
+ */
int n;
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
- if (state->direct_out)
- {
+ if (state->direct_out) {
n = state->cds_p - strm->next_out;
strm->next_out += n;
strm->avail_out -= n;
return M_CONTINUE;
}
-static inline int m_flush_block_cautious(aec_streamp strm)
+static int m_flush_block_cautious(struct aec_stream *strm)
{
- encode_state *state = strm->state;
+ /**
+ Slow and restartable flushing
+ */
+ struct internal_state *state = strm->state;
- /* Slow restartable flushing */
- while(state->cds_buf + state->i < state->cds_p)
- {
+ while(state->cds_buf + state->i < state->cds_p) {
if (strm->avail_out == 0)
return M_EXIT;
*
*/
-int aec_encode_init(aec_streamp strm)
+int aec_encode_init(struct aec_stream *strm)
{
int bs, bsi;
- encode_state *state;
+ struct internal_state *state;
- /* Some sanity checks */
if (strm->bit_per_sample > 32 || strm->bit_per_sample == 0)
return AEC_CONF_ERROR;
if (strm->rsi > 4096)
return AEC_CONF_ERROR;
- /* Internal state for encoder */
- state = (encode_state *) malloc(sizeof(encode_state));
+ state = (struct internal_state *)malloc(sizeof(struct internal_state));
if (state == NULL)
- {
return AEC_MEM_ERROR;
- }
- memset(state, 0, sizeof(encode_state));
+
+ memset(state, 0, sizeof(struct internal_state));
strm->state = state;
bs = strm->block_size >> 3;
while (bs >>= 1)
bsi++;
- if (strm->bit_per_sample > 16)
- {
+ if (strm->bit_per_sample > 16) {
/* 24/32 input bit settings */
state->id_len = 5;
- if (strm->bit_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE)
- {
+ if (strm->bit_per_sample <= 24
+ && strm->flags & AEC_DATA_3BYTE) {
state->block_len = 3 * strm->block_size;
- if (strm->flags & AEC_DATA_MSB)
- {
+ if (strm->flags & AEC_DATA_MSB) {
state->get_sample = get_msb_24;
state->get_block = get_block_funcs_msb_24[bsi];
- }
- else
- {
+ } else {
state->get_sample = get_lsb_24;
state->get_block = get_block_funcs_lsb_24[bsi];
}
- }
- else
- {
+ } else {
state->block_len = 4 * strm->block_size;
- if (strm->flags & AEC_DATA_MSB)
- {
+ if (strm->flags & AEC_DATA_MSB) {
state->get_sample = get_msb_32;
state->get_block = get_block_funcs_msb_32[bsi];
- }
- else
- {
+ } else {
state->get_sample = get_lsb_32;
state->get_block = get_block_funcs_lsb_32[bsi];
}
}
}
- else if (strm->bit_per_sample > 8)
- {
+ else if (strm->bit_per_sample > 8) {
/* 16 bit settings */
state->id_len = 4;
state->block_len = 2 * strm->block_size;
- if (strm->flags & AEC_DATA_MSB)
- {
+ if (strm->flags & AEC_DATA_MSB) {
state->get_sample = get_msb_16;
state->get_block = get_block_funcs_msb_16[bsi];
- }
- else
- {
+ } else {
state->get_sample = get_lsb_16;
state->get_block = get_block_funcs_lsb_16[bsi];
}
- }
- else
- {
+ } else {
/* 8 bit settings */
state->id_len = 3;
state->block_len = strm->block_size;
state->get_block = get_block_funcs_8[bsi];
}
- if (strm->flags & AEC_DATA_SIGNED)
- {
+ if (strm->flags & AEC_DATA_SIGNED) {
state->xmin = -(1ULL << (strm->bit_per_sample - 1));
state->xmax = (1ULL << (strm->bit_per_sample - 1)) - 1;
state->preprocess = preprocess_signed;
- }
- else
- {
+ } else {
state->xmin = 0;
state->xmax = (1ULL << strm->bit_per_sample) - 1;
state->preprocess = preprocess_unsigned;
* strm->block_size
* sizeof(uint32_t));
if (state->block_buf == NULL)
- {
return AEC_MEM_ERROR;
- }
+
state->block_p = state->block_buf;
- /* Largest possible block according to specs */
+ /* Largest possible CDS according to specs */
state->cds_len = (5 + 64 * 32) / 8 + 3;
state->cds_buf = (uint8_t *)malloc(state->cds_len);
if (state->cds_buf == NULL)
- {
return AEC_MEM_ERROR;
- }
strm->total_in = 0;
strm->total_out = 0;
return AEC_OK;
}
-int aec_encode(aec_streamp strm, int flush)
+int aec_encode(struct aec_stream *strm, int flush)
{
/**
Finite-state machine implementation of the adaptive entropy
encoder.
*/
int n;
- encode_state *state;
+ struct internal_state *state;
state = strm->state;
state->flush = flush;
while (state->mode(strm) == M_CONTINUE);
- if (state->direct_out)
- {
+ if (state->direct_out) {
n = state->cds_p - strm->next_out;
strm->next_out += n;
strm->avail_out -= n;
return AEC_OK;
}
-int aec_encode_end(aec_streamp strm)
+int aec_encode_end(struct aec_stream *strm)
{
- encode_state *state = strm->state;
+ struct internal_state *state = strm->state;
free(state->block_buf);
free(state->cds_buf);