Commit 4ba62304 authored by Mathis Rosenhauer's avatar Mathis Rosenhauer

Accessors for all data types. Implemented with macros for all block sizes gaining slight speedup.

parent fef438b9
......@@ -3,7 +3,7 @@ CC = gcc
CFLAGS = -g -O3 -Wall -std=c99
CXXFLAGS = -O3 -Wall
OBJS = aee.o aee_mutators.o aed.o sz_compat.o
OBJS = aee.o aee_accessors.o aed.o sz_compat.o
.PHONY : all clean check
......@@ -26,8 +26,8 @@ libae.a: $(OBJS)
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
aed.o: libae.h
aee.o: aee_mutators.h aee.h libae.h
aee_mutators.o: aee.h libae.h
aee.o: aee_accessors.h aee.h libae.h
aee_accessors.o: aee.h libae.h
sz_compat.o: libae.h
install: libae.a
......
......@@ -265,7 +265,7 @@ int ae_decode_init(ae_streamp strm)
/* Some sanity checks */
if (strm->bit_per_sample > 32 || strm->bit_per_sample == 0)
{
return AE_ERRNO;
return AE_CONF_ERROR;
}
/* Internal state for decoder */
......
......@@ -4,7 +4,7 @@
* @section DESCRIPTION
*
* Adaptive Entropy Encoder
* Based on CCSDS documents 121.0-B-1 and 120.0-G-2
* Based on CCSDS documents 121.0-B-2 and 120.0-G-2
*
*/
......@@ -16,7 +16,7 @@
#include "libae.h"
#include "aee.h"
#include "aee_mutators.h"
#include "aee_accessors.h"
/* Marker for Remainder Of Segment condition in zero block encoding */
#define ROS -1
......@@ -377,7 +377,7 @@ static inline int m_select_code_option(ae_streamp strm)
direction = 1;
looked_bothways = 0;
/* Starting with splitting position of last block look left and
/* Starting with splitting position of last block. Look left and
* possibly right to find new minimum.
*/
for (;;)
......@@ -390,13 +390,21 @@ static inline int m_select_code_option(ae_streamp strm)
+ (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);
if (strm->block_size > 8)
for (j = 8; j < strm->block_size; j++)
fs_len += (uint64_t)(state->block_p[j] >> i);
split_len = fs_len + this_bs * (i + 1);
if (split_len < split_len_min)
......@@ -647,20 +655,21 @@ static inline int m_flush_block_cautious(ae_streamp strm)
int ae_encode_init(ae_streamp strm)
{
int bs, bsi;
encode_state *state;
/* Some sanity checks */
if (strm->bit_per_sample > 32 || strm->bit_per_sample == 0)
return AE_ERRNO;
return AE_CONF_ERROR;
if (strm->block_size != 8
&& strm->block_size != 16
&& strm->block_size != 32
&& strm->block_size != 64)
return AE_ERRNO;
return AE_CONF_ERROR;
if (strm->rsi > 4096)
return AE_ERRNO;
return AE_CONF_ERROR;
/* Internal state for encoder */
state = (encode_state *) malloc(sizeof(encode_state));
......@@ -671,6 +680,11 @@ int ae_encode_init(ae_streamp strm)
memset(state, 0, sizeof(encode_state));
strm->state = state;
bs = strm->block_size >> 3;
bsi = 0;
while (bs >>= 1)
bsi++;
if (strm->bit_per_sample > 16)
{
/* 32 bit settings */
......@@ -679,11 +693,32 @@ int ae_encode_init(ae_streamp strm)
if (strm->flags & AE_DATA_MSB)
{
state->get_sample = get_msb_32;
state->get_block = get_block_msb_32;
if (strm->bit_per_sample == 24
&& strm->flags & AE_DATA_3BYTE)
{
state->get_sample = get_msb_24;
state->get_block = get_block_funcs_msb_24[bsi];
}
else
{
state->get_sample = get_msb_32;
state->get_block = get_block_funcs_msb_32[bsi];
}
}
else
state->get_sample = get_lsb_32;
{
if (strm->bit_per_sample == 24
&& strm->flags & AE_DATA_3BYTE)
{
state->get_sample = get_lsb_24;
state->get_block = get_block_funcs_lsb_24[bsi];
}
else
{
state->get_sample = get_lsb_32;
state->get_block = get_block_funcs_lsb_32[bsi];
}
}
}
else if (strm->bit_per_sample > 8)
{
......@@ -694,27 +729,22 @@ int ae_encode_init(ae_streamp strm)
if (strm->flags & AE_DATA_MSB)
{
state->get_sample = get_msb_16;
if (strm->block_size == 8)
state->get_block = get_block_msb_16_bs_8;
else
state->get_block = get_block_msb_16;
state->get_block = get_block_funcs_msb_16[bsi];
}
else
{
state->get_sample = get_lsb_16;
state->get_block = get_block_funcs_lsb_16[bsi];
}
}
else
{
/* 8 bit settings */
state->block_len = strm->block_size;
state->id_len = 3;
state->block_len = strm->block_size;
state->get_sample = get_8;
if (strm->block_size == 8)
state->get_block = get_block_8_bs_8;
else
state->get_block = get_block_8;
state->get_block = get_block_funcs_8[bsi];
}
if (strm->flags & AE_DATA_SIGNED)
......
#include <inttypes.h>
#include <string.h>
#include "libae.h"
#include "aee.h"
#include "aee_accessors.h"
uint32_t get_8(ae_streamp strm)
{
strm->avail_in--;
strm->total_in++;
return *strm->next_in++;
}
uint32_t get_lsb_24(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[2] << 16)
| ((uint32_t)strm->next_in[1] << 8)
| (uint32_t)strm->next_in[0];
strm->next_in += 3;
strm->total_in += 3;
strm->avail_in -= 3;
return data;
}
uint32_t get_msb_24(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[0] << 16)
| ((uint32_t)strm->next_in[1] << 8)
| (uint32_t)strm->next_in[2];
strm->next_in += 3;
strm->total_in += 3;
strm->avail_in -= 3;
return data;
}
#ifdef WORDS_BIGENDIAN
uint32_t get_lsb_16(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[1] << 8)
| (uint32_t)strm->next_in[0];
strm->next_in += 2;
strm->total_in += 2;
strm->avail_in -= 2;
return data;
}
uint32_t get_msb_16(ae_streamp strm)
{
uint32_t data;
data = *(uint16_t *)strm->next_in;
strm->next_in += 2;
strm->total_in += 2;
strm->avail_in -= 2;
return data;
}
uint32_t get_lsb_32(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[3] << 24)
| ((uint32_t)strm->next_in[2] << 16)
| ((uint32_t)strm->next_in[1] << 8)
| (uint32_t)strm->next_in[0];
strm->next_in += 4;
strm->total_in += 4;
strm->avail_in -= 4;
return data;
}
uint32_t get_msb_32(ae_streamp strm)
{
uint32_t data;
data = *(uint32_t *)strm->next_in;
strm->next_in += 4;
strm->total_in += 4;
strm->avail_in -= 4;
return data;
}
#else /* LITTLEENDIAN */
uint32_t get_lsb_16(ae_streamp strm)
{
uint32_t data;
data = *(uint16_t *)strm->next_in;
strm->next_in += 2;
strm->total_in += 2;
strm->avail_in -= 2;
return data;
}
uint32_t get_msb_16(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[0] << 8)
| (uint32_t)strm->next_in[1];
strm->next_in += 2;
strm->total_in += 2;
strm->avail_in -= 2;
return data;
}
uint32_t get_lsb_32(ae_streamp strm)
{
uint32_t data;
data = *(uint32_t *)strm->next_in;
strm->next_in += 4;
strm->total_in += 4;
strm->avail_in -= 4;
return data;
}
uint32_t get_msb_32(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[0] << 24)
| ((uint32_t)strm->next_in[1] << 16)
| ((uint32_t)strm->next_in[2] << 8)
| (uint32_t)strm->next_in[3];
strm->next_in += 4;
strm->total_in += 4;
strm->avail_in -= 4;
return data;
}
#endif
#define GET_BLOCK_8(BS) \
static void get_block_8_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = strm->next_in[i * BS + j]; \
\
strm->next_in += BS * strm->rsi; \
strm->total_in += BS * strm->rsi; \
strm->avail_in -= BS * strm->rsi; \
}
#define GET_BLOCK_NATIVE_16(BS) \
static void get_block_native_16_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
uint16_t *next_in = (uint16_t *)strm->next_in; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = (uint32_t)next_in[i * BS + j]; \
\
strm->next_in += 2 * BS * strm->rsi; \
strm->total_in += 2 * BS * strm->rsi; \
strm->avail_in -= 2 * BS * strm->rsi; \
}
#define GET_BLOCK_LSB_16(BS) \
static void get_block_lsb_16_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = \
(uint32_t)strm->next_in[2 * (i * BS + j)] \
| ((uint32_t)strm->next_in[2 * (i * BS + j) + 1] \
<< 8); \
\
strm->next_in += 2 * BS * strm->rsi; \
strm->total_in += 2 * BS * strm->rsi; \
strm->avail_in -= 2 * BS * strm->rsi; \
}
#define GET_BLOCK_MSB_16(BS) \
static void get_block_msb_16_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = \
((uint32_t)strm->next_in[2 * (i * BS + j)] << 8) \
| (uint32_t)strm->next_in[2 * (i * BS + j) + 1]; \
\
strm->next_in += 2 * BS * strm->rsi; \
strm->total_in += 2 * BS * strm->rsi; \
strm->avail_in -= 2 * BS * strm->rsi; \
}
#define GET_BLOCK_LSB_24(BS) \
static void get_block_lsb_24_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = \
(uint32_t)strm->next_in[4 * (i * BS + j)] \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 1] \
<< 8) \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 2] \
<< 16); \
\
strm->next_in += 3 * BS * strm->rsi; \
strm->total_in += 3 * BS * strm->rsi; \
strm->avail_in -= 3 * BS * strm->rsi; \
}
#define GET_BLOCK_MSB_24(BS) \
static void get_block_msb_24_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = \
((uint32_t)strm->next_in[4 * (i * BS + j)] \
<< 16) \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 1] \
<< 8) \
| (uint32_t)strm->next_in[4 * (i * BS + j) + 2]; \
\
strm->next_in += 3 * BS * strm->rsi; \
strm->total_in += 3 * BS * strm->rsi; \
strm->avail_in -= 3 * BS * strm->rsi; \
}
#define GET_BLOCK_NATIVE_32(BS) \
static void get_block_native_32_bs_##BS(ae_streamp strm) \
{ \
memcpy(strm->state->block_buf, \
strm->next_in, \
4 * BS * strm->rsi); \
\
strm->next_in += 4 * BS * strm->rsi; \
strm->total_in += 4 * BS * strm->rsi; \
strm->avail_in -= 4 * BS * strm->rsi; \
}
#define GET_BLOCK_LSB_32(BS) \
static void get_block_lsb_32_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = \
(uint32_t)strm->next_in[4 * (i * BS + j)] \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 1] \
<< 8) \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 2] \
<< 16) \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 3] \
<< 24); \
\
strm->next_in += 4 * BS * strm->rsi; \
strm->total_in += 4 * BS * strm->rsi; \
strm->avail_in -= 4 * BS * strm->rsi; \
}
#define GET_BLOCK_MSB_32(BS) \
static void get_block_msb_32_bs_##BS(ae_streamp strm) \
{ \
int i, j; \
uint32_t *block = strm->state->block_buf; \
\
for (i = 0; i < strm->rsi; i++) \
for (j = 0; j < BS; j++) \
block[i * BS + j] = \
((uint32_t)strm->next_in[4 * (i * BS + j)] \
<< 24) \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 1] \
<< 16) \
| ((uint32_t)strm->next_in[4 * (i * BS + j) + 2] \
<< 8) \
| (uint32_t)strm->next_in[4 * (i * BS + j) + 3]; \
\
strm->next_in += 4 * BS * strm->rsi; \
strm->total_in += 4 * BS * strm->rsi; \
strm->avail_in -= 4 * BS * strm->rsi; \
}
#define GET_BLOCK_FUNCS(A, B) \
void (*get_block_funcs_##A[])(ae_streamp) = { \
get_block_##B##_bs_8, \
get_block_##B##_bs_16, \
get_block_##B##_bs_32, \
get_block_##B##_bs_64, \
}
GET_BLOCK_8(8);
GET_BLOCK_8(16);
GET_BLOCK_8(32);
GET_BLOCK_8(64);
GET_BLOCK_FUNCS(8, 8);
GET_BLOCK_LSB_24(8);
GET_BLOCK_LSB_24(16);
GET_BLOCK_LSB_24(32);
GET_BLOCK_LSB_24(64);
GET_BLOCK_FUNCS(lsb_24, lsb_24);
GET_BLOCK_MSB_24(8);
GET_BLOCK_MSB_24(16);
GET_BLOCK_MSB_24(32);
GET_BLOCK_MSB_24(64);
GET_BLOCK_FUNCS(msb_24, msb_24);
GET_BLOCK_NATIVE_16(8);
GET_BLOCK_NATIVE_16(16);
GET_BLOCK_NATIVE_16(32);
GET_BLOCK_NATIVE_16(64);
GET_BLOCK_NATIVE_32(8);
GET_BLOCK_NATIVE_32(16);
GET_BLOCK_NATIVE_32(32);
GET_BLOCK_NATIVE_32(64);
#ifdef WORDS_BIGENDIAN
GET_BLOCK_LSB_16(8);
GET_BLOCK_LSB_16(16);
GET_BLOCK_LSB_16(32);
GET_BLOCK_LSB_16(64);
GET_BLOCK_LSB_32(8);
GET_BLOCK_LSB_32(16);
GET_BLOCK_LSB_32(32);
GET_BLOCK_LSB_32(64);
GET_BLOCK_FUNCS(lsb_16, lsb_16);
GET_BLOCK_FUNCS(msb_16, native_16);
GET_BLOCK_FUNCS(lsb_32, lsb_32);
GET_BLOCK_FUNCS(msb_32, native_32);
#else /* LITTLEENDIAN */
GET_BLOCK_MSB_16(8);
GET_BLOCK_MSB_16(16);
GET_BLOCK_MSB_16(32);
GET_BLOCK_MSB_16(64);
GET_BLOCK_MSB_32(8);
GET_BLOCK_MSB_32(16);
GET_BLOCK_MSB_32(32);
GET_BLOCK_MSB_32(64);
GET_BLOCK_FUNCS(lsb_16, native_16);
GET_BLOCK_FUNCS(msb_16, msb_16);
GET_BLOCK_FUNCS(lsb_32, native_32);
GET_BLOCK_FUNCS(msb_32, msb_32);
#endif
#ifndef AEE_MUTATORS_H
#define AEE_MUTATORS_H
#ifndef AEE_ACCESSORS_H
#define AEE_ACCESSORS_H
#include <inttypes.h>
#include "libae.h"
uint32_t get_lsb_32(ae_streamp strm);
uint32_t get_8(ae_streamp strm);
uint32_t get_lsb_16(ae_streamp strm);
uint32_t get_msb_32(ae_streamp strm);
uint32_t get_msb_16(ae_streamp strm);
uint32_t get_8(ae_streamp strm);
uint32_t get_lsb_32(ae_streamp strm);
uint32_t get_msb_24(ae_streamp strm);
uint32_t get_lsb_24(ae_streamp strm);
uint32_t get_msb_32(ae_streamp strm);
void get_block_msb_32(ae_streamp strm);
void get_block_msb_16_bs_8(ae_streamp strm);
void get_block_msb_16(ae_streamp strm);
void get_block_8_bs_8(ae_streamp strm);
void get_block_8(ae_streamp strm);
extern void (*get_block_funcs_8[4])(ae_streamp);
extern void (*get_block_funcs_lsb_16[4])(ae_streamp);
extern void (*get_block_funcs_msb_16[4])(ae_streamp);
extern void (*get_block_funcs_lsb_24[4])(ae_streamp);
extern void (*get_block_funcs_msb_24[4])(ae_streamp);
extern void (*get_block_funcs_lsb_32[4])(ae_streamp);
extern void (*get_block_funcs_msb_32[4])(ae_streamp);
#endif
#include <inttypes.h>
#include "libae.h"
#include "aee.h"
#include "aee_mutators.h"
uint32_t get_lsb_32(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[3] << 24)
| ((uint32_t)strm->next_in[2] << 16)
| ((uint32_t)strm->next_in[1] << 8)
| (uint32_t)strm->next_in[0];
strm->next_in += 4;
strm->total_in += 4;
strm->avail_in -= 4;
return data;
}
uint32_t get_lsb_16(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[1] << 8)
| (uint32_t)strm->next_in[0];
strm->next_in += 2;
strm->total_in += 2;
strm->avail_in -= 2;
return data;
}
uint32_t get_msb_32(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[0] << 24)
| ((uint32_t)strm->next_in[1] << 16)
| ((uint32_t)strm->next_in[2] << 8)
| (uint32_t)strm->next_in[3];
strm->next_in += 4;
strm->total_in += 4;
strm->avail_in -= 4;
return data;
}
uint32_t get_msb_16(ae_streamp strm)
{
uint32_t data;
data = ((uint32_t)strm->next_in[0] << 8)
| (uint32_t)strm->next_in[1];
strm->next_in += 2;
strm->total_in += 2;
strm->avail_in -= 2;
return data;
}
uint32_t get_8(ae_streamp strm)
{
strm->avail_in--;
strm->total_in++;
return *strm->next_in++;
}
void get_block_msb_16_bs_8(ae_streamp strm)
{
int i;
uint32_t *block = strm->state->block_buf;
for (i = 0; i < 8 * strm->rsi; i += 8)
{
block[i + 0] = ((uint32_t)strm->next_in[0] << 8) | (uint32_t)strm->next_in[1];
block[i + 1] = ((uint32_t)strm->next_in[2] << 8) | (uint32_t)strm->next_in[3];
block[i + 2] = ((uint32_t)strm->next_in[4] << 8) | (uint32_t)strm->next_in[5];
block[i + 3] = ((uint32_t)strm->next_in[6] << 8) | (uint32_t)strm->next_in[7];
block[i + 4] = ((uint32_t)strm->next_in[8] << 8) | (uint32_t)strm->next_in[9];
block[i + 5] = ((uint32_t)strm->next_in[10] << 8) | (uint32_t)strm->next_in[11];
block[i + 6] = ((uint32_t)strm->next_in[12] << 8) | (uint32_t)strm->next_in[13];
block[i + 7] = ((uint32_t)strm->next_in[14] << 8) | (uint32_t)strm->next_in[15];
strm->next_in += 16;
}
strm->total_in += 16 * strm->rsi;
strm->avail_in -= 16 * strm->rsi;
}
void get_block_msb_16(ae_streamp strm)
{
int i;
uint32_t *block = strm->state->block_buf;
for (i = 0; i < strm->block_size * strm->rsi; i++)
{
block[i] = ((uint32_t)strm->next_in[2 * i] << 8)
| (uint32_t)strm->next_in[2 * i + 1];
}
strm->next_in += 2 * strm->block_size * strm->rsi;
strm->total_in += 2 * strm->block_size * strm->rsi;
strm->avail_in -= 2 * strm->block_size * strm->rsi;
}
void get_block_msb_32(ae_streamp strm)
{
int i;
uint32_t *block = strm->state->block_buf;
for (i = 0; i < strm->block_size * strm->rsi; i++)
{
block[i] = ((uint32_t)strm->next_in[4 * i] << 24)
| ((uint32_t)strm->next_in[4 * i + 1] << 16)
| ((uint32_t)strm->next_in[4 * i + 2] << 8)
| (uint32_t)strm->next_in[4 * i + 3];
}
strm->next_in += 4 * strm->block_size * strm->rsi;
strm->total_in += 4 * strm->block_size * strm->rsi;
strm->avail_in -= 4 * strm->block_size * strm->rsi;
}
void get_block_8_bs_8(ae_streamp strm)
{
int i;
uint32_t *block = strm->state->block_buf;
for (i = 0; i < 8 * strm->rsi; i += 8)