Commit 755d8704 authored by Mathis Rosenhauer's avatar Mathis Rosenhauer Committed by Thomas Jahns

Add check for short RSI handling to catch previous bug

parent 3ae7b421
lib_LTLIBRARIES = libaec.la libsz.la lib_LTLIBRARIES = libaec.la libsz.la
libaec_la_SOURCES = encode.c encode_accessors.c decode.c encode.h encode_accessors.h libaec_la_SOURCES = encode.c encode_accessors.c decode.c encode.h \
libsz_la_SOURCES = sz_compat.c libaec.la encode_accessors.h
libsz_la_SOURCES = sz_compat.c
libsz_la_LIBADD = libaec.la libsz_la_LIBADD = libaec.la
libaec_la_LDFLAGS = -version-info 0:0 libaec_la_LDFLAGS = -version-info 0:0
libsz_la_LDFLAGS = -version-info 0:0 libsz_la_LDFLAGS = -version-info 0:0
......
INCLUDES = -I$(top_srcdir)/src INCLUDES = -I$(top_srcdir)/src
TESTS = check_aec TESTS = check_code_options check_buffer_sizes
check_PROGRAMS = check_aec check_LTLIBRARIES = libcheck_aec.la
check_aec_SOURCES = check_aec.c $(top_builddir)/src/libaec.h libcheck_aec_la_SOURCES = check_aec.c check_aec.h
check_aec_LDADD = $(top_builddir)/src/libaec.la check_PROGRAMS = check_code_options check_buffer_sizes
check_code_options_SOURCES = check_code_options.c check_aec.h \
$(top_builddir)/src/libaec.h
check_buffer_sizes_SOURCES = check_buffer_sizes.c check_aec.h \
$(top_builddir)/src/libaec.h
check_code_options_LDADD = libcheck_aec.la $(top_builddir)/src/libaec.la
check_buffer_sizes_LDADD = libcheck_aec.la $(top_builddir)/src/libaec.la
...@@ -3,22 +3,7 @@ ...@@ -3,22 +3,7 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include "libaec.h" #include "libaec.h"
#include "check_aec.h"
#define BUF_SIZE 1024 * 3
struct test_state {
int id_len;
int byte_per_sample;
unsigned char *ubuf;
unsigned char *cbuf;
unsigned char *obuf;
size_t buf_len;
size_t cbuf_len;
long long int xmax;
long long int xmin;
void (*out)(unsigned char *dest, unsigned int val, int size);
struct aec_stream *strm;
};
static void out_lsb(unsigned char *dest, unsigned int val, int size) static void out_lsb(unsigned char *dest, unsigned int val, int size)
{ {
...@@ -36,7 +21,7 @@ static void out_msb(unsigned char *dest, unsigned int val, int size) ...@@ -36,7 +21,7 @@ static void out_msb(unsigned char *dest, unsigned int val, int size)
dest[i] = val >> (8 * (size - 1 - i)); dest[i] = val >> (8 * (size - 1 - i));
} }
static int update_state(struct test_state *state) int update_state(struct test_state *state)
{ {
struct aec_stream *strm = state->strm; struct aec_stream *strm = state->strm;
...@@ -78,7 +63,7 @@ int encode_decode(struct test_state *state) ...@@ -78,7 +63,7 @@ int encode_decode(struct test_state *state)
int status, i, to; int status, i, to;
struct aec_stream *strm = state->strm; struct aec_stream *strm = state->strm;
strm->avail_in = state->buf_len; strm->avail_in = state->ibuf_len;
strm->avail_out = state->cbuf_len; strm->avail_out = state->cbuf_len;
strm->next_in = state->ubuf; strm->next_in = state->ubuf;
strm->next_out = state->cbuf; strm->next_out = state->cbuf;
...@@ -115,7 +100,7 @@ int encode_decode(struct test_state *state) ...@@ -115,7 +100,7 @@ int encode_decode(struct test_state *state)
return 99; return 99;
} }
if (memcmp(state->ubuf, state->obuf, state->buf_len)) { if (memcmp(state->ubuf, state->obuf, state->ibuf_len)) {
printf("FAIL: Uncompressed output differs from input.\n"); printf("FAIL: Uncompressed output differs from input.\n");
printf("\nuncompressed buf"); printf("\nuncompressed buf");
...@@ -142,245 +127,3 @@ int encode_decode(struct test_state *state) ...@@ -142,245 +127,3 @@ int encode_decode(struct test_state *state)
aec_decode_end(strm); aec_decode_end(strm);
return 0; return 0;
} }
int check_block_sizes(struct test_state *state, int id, int id_len)
{
int bs, status;
for (bs = 8; bs <= 64; bs *= 2) {
state->strm->block_size = bs;
state->strm->rsi = state->buf_len
/ (bs * state->byte_per_sample);
status = encode_decode(state);
if (status)
return status;
if ((state->cbuf[0] >> (8 - id_len)) != id) {
printf("FAIL: Unexpected block of size %i created %x.\n",
bs, state->cbuf[0] >> (8 - id_len));
return 99;
}
}
return 0;
}
int check_zero(struct test_state *state)
{
int status;
memset(state->ubuf, 0x55, state->buf_len);
printf("Checking zero blocks ... ");
status = check_block_sizes(state, 0, state->id_len + 1);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_splitting(struct test_state *state, int k)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 4 * state->byte_per_sample) {
state->out(tmp, state->xmin + (1ULL << (k - 1)) - 1, size);
state->out(tmp + size, state->xmin, size);
state->out(tmp + 2 * size, state->xmin + (1ULL << (k + 1)) - 1, size);
state->out(tmp + 3 * size, state->xmin, size);
}
printf("Checking splitting with k=%i ... ", k);
status = check_block_sizes(state, k + 1, state->id_len);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_uncompressed(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 2 * state->byte_per_sample) {
state->out(tmp, state->xmax, size);
state->out(tmp + size, state->xmin, size);
}
printf("Checking uncompressed ... ");
status = check_block_sizes(state,
(1ULL << state->id_len) - 1,
state->id_len);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_fs(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 2 * state->byte_per_sample) {
state->out(tmp, state->xmin + 1, size);
state->out(tmp + size, state->xmin, size);
}
printf("Checking FS ... ");
status = check_block_sizes(state, 1, state->id_len);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_se(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 8 * size) {
state->out(tmp, 0, size);
state->out(tmp + size, 0, size);
state->out(tmp + 2 * size, 0, size);
state->out(tmp + 3 * size, 0, size);
state->out(tmp + 4 * size, 0, size);
state->out(tmp + 5 * size, 0, size);
state->out(tmp + 6 * size, 0, size);
state->out(tmp + 7 * size, 1, size);
}
printf("Checking Second Extension ... ");
status = check_block_sizes(state, 1, state->id_len + 1);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_bps(struct test_state *state)
{
int k, status, bps;
for (bps = 8; bps <= 32; bps += 8) {
state->strm->bit_per_sample = bps;
if (bps == 24)
state->strm->flags |= AEC_DATA_3BYTE;
else
state->strm->flags &= ~AEC_DATA_3BYTE;
update_state(state);
status = check_zero(state);
if (status)
return status;
status = check_se(state);
if (status)
return status;
status = check_uncompressed(state);
if (status)
return status;
status = check_fs(state);
if (status)
return status;
for (k = 1; k < bps - 2; k++) {
status = check_splitting(state, k);
if (status)
return status;
}
printf("All checks with %i bit per sample passed.\n\n", bps);
}
return 0;
}
int main (void)
{
int status;
struct aec_stream strm;
struct test_state state;
state.buf_len = BUF_SIZE;
state.cbuf_len = 2 * BUF_SIZE;
state.ubuf = (unsigned char *)malloc(state.buf_len);
state.cbuf = (unsigned char *)malloc(state.cbuf_len);
state.obuf = (unsigned char *)malloc(state.buf_len);
if (!state.ubuf || !state.cbuf || !state.obuf) {
printf("Not enough memory.\n");
return 99;
}
strm.flags = AEC_DATA_PREPROCESS;
state.strm = &strm;
printf("----------------------------\n");
printf("Checking LSB first, unsigned\n");
printf("----------------------------\n");
status = check_bps(&state);
if (status)
goto destruct;
printf("--------------------------\n");
printf("Checking LSB first, signed\n");
printf("--------------------------\n");
strm.flags |= AEC_DATA_SIGNED;
status = check_bps(&state);
if (status)
goto destruct;
strm.flags &= ~AEC_DATA_SIGNED;
strm.flags |= AEC_DATA_MSB;
printf("----------------------------\n");
printf("Checking MSB first, unsigned\n");
printf("----------------------------\n");
status = check_bps(&state);
if (status)
goto destruct;
printf("--------------------------\n");
printf("Checking MSB first, signed\n");
printf("--------------------------\n");
strm.flags |= AEC_DATA_SIGNED;
status = check_bps(&state);
if (status)
goto destruct;
destruct:
free(state.ubuf);
free(state.cbuf);
free(state.obuf);
return status;
}
#ifndef CHECK_AEC_H
#define CHECK_AEC_H
#include "libaec.h"
struct test_state {
int id_len;
int byte_per_sample;
unsigned char *ubuf;
unsigned char *cbuf;
unsigned char *obuf;
size_t ibuf_len; /* input buffer legth may be shorter than buf_len */
size_t buf_len;
size_t cbuf_len;
long long int xmax;
long long int xmin;
void (*out)(unsigned char *dest, unsigned int val, int size);
struct aec_stream *strm;
};
int update_state(struct test_state *state);
int encode_decode(struct test_state *state);
#endif /* CHECK_AEC_H */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "libaec.h"
#include "check_aec.h"
#define BUF_SIZE 1024 * 3
int check_block_sizes(struct test_state *state)
{
int bs, status;
for (bs = 8; bs <= 64; bs *= 2) {
state->strm->block_size = bs;
state->strm->rsi = state->buf_len / (bs * state->byte_per_sample);
status = encode_decode(state);
if (status)
return status;
}
return 0;
}
int check_block_sizes_short(struct test_state *state)
{
int bs, status;
size_t tmp;
tmp = state->ibuf_len;
for (bs = 8; bs <= 64; bs *= 2) {
state->strm->block_size = bs;
state->strm->rsi = state->buf_len / (bs * state->byte_per_sample);
state->ibuf_len = state->buf_len - 2 * bs + 4;
status = encode_decode(state);
if (status)
return status;
if (state->strm->total_out != state->buf_len) {
printf("FAIL: Unexpected buffer length. Got %i expected %i\n",
(int)state->strm->total_out,
(int)state->buf_len);
return 99;
}
}
state->ibuf_len = tmp;
return 0;
}
int check_rsi(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 2 * state->byte_per_sample) {
state->out(tmp, state->xmax, size);
state->out(tmp + size, state->xmin, size);
}
printf("Checking full rsi ... ");
status = check_block_sizes(state);
if (status)
return status;
printf ("OK\n");
printf("Checking short rsi ... ");
status = check_block_sizes_short(state);
if (status)
return status;
printf ("OK\n");
return 0;
}
int main (void)
{
int status;
struct aec_stream strm;
struct test_state state;
state.buf_len = state.ibuf_len = BUF_SIZE;
state.cbuf_len = 2 * BUF_SIZE;
state.ubuf = (unsigned char *)malloc(state.buf_len);
state.cbuf = (unsigned char *)malloc(state.cbuf_len);
state.obuf = (unsigned char *)malloc(state.buf_len);
if (!state.ubuf || !state.cbuf || !state.obuf) {
printf("Not enough memory.\n");
return 99;
}
strm.flags = AEC_DATA_PREPROCESS;
state.strm = &strm;
strm.bit_per_sample = 32;
update_state(&state);
status = check_rsi(&state);
if (status)
goto DESTRUCT;
DESTRUCT:
free(state.ubuf);
free(state.cbuf);
free(state.obuf);
return status;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "libaec.h"
#include "check_aec.h"
#define BUF_SIZE 1024 * 3
int check_block_sizes(struct test_state *state, int id, int id_len)
{
int bs, status;
for (bs = 8; bs <= 64; bs *= 2) {
state->strm->block_size = bs;
state->strm->rsi = state->buf_len
/ (bs * state->byte_per_sample);
status = encode_decode(state);
if (status)
return status;
if ((state->cbuf[0] >> (8 - id_len)) != id) {
printf("FAIL: Unexpected block of size %i created %x.\n",
bs, state->cbuf[0] >> (8 - id_len));
return 99;
}
}
return 0;
}
int check_zero(struct test_state *state)
{
int status;
memset(state->ubuf, 0x55, state->buf_len);
printf("Checking zero blocks ... ");
status = check_block_sizes(state, 0, state->id_len + 1);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_splitting(struct test_state *state, int k)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 4 * state->byte_per_sample) {
state->out(tmp, state->xmin + (1ULL << (k - 1)) - 1, size);
state->out(tmp + size, state->xmin, size);
state->out(tmp + 2 * size, state->xmin + (1ULL << (k + 1)) - 1, size);
state->out(tmp + 3 * size, state->xmin, size);
}
printf("Checking splitting with k=%i ... ", k);
status = check_block_sizes(state, k + 1, state->id_len);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_uncompressed(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 2 * state->byte_per_sample) {
state->out(tmp, state->xmax, size);
state->out(tmp + size, state->xmin, size);
}
printf("Checking uncompressed ... ");
status = check_block_sizes(state,
(1ULL << state->id_len) - 1,
state->id_len);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_fs(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 2 * state->byte_per_sample) {
state->out(tmp, state->xmin + 1, size);
state->out(tmp + size, state->xmin, size);
}
printf("Checking FS ... ");
status = check_block_sizes(state, 1, state->id_len);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_se(struct test_state *state)
{
int status, size;
unsigned char *tmp;
size = state->byte_per_sample;
for (tmp = state->ubuf;
tmp < state->ubuf + state->buf_len;
tmp += 8 * size) {
state->out(tmp, 0, size);
state->out(tmp + size, 0, size);
state->out(tmp + 2 * size, 0, size);
state->out(tmp + 3 * size, 0, size);
state->out(tmp + 4 * size, 0, size);
state->out(tmp + 5 * size, 0, size);
state->out(tmp + 6 * size, 0, size);
state->out(tmp + 7 * size, 1, size);
}
printf("Checking Second Extension ... ");
status = check_block_sizes(state, 1, state->id_len + 1);
if (status)
return status;
printf ("OK\n");
return 0;
}
int check_bps(struct test_state *state)
{
int k, status, bps;
for (bps = 8; bps <= 32; bps += 8) {
state->strm->bit_per_sample = bps;
if (bps == 24)
state->strm->flags |= AEC_DATA_3BYTE;
else
state->strm->flags &= ~AEC_DATA_3BYTE;
update_state(state);
status = check_zero(state);
if (status)
return status;
status = check_se(state);
if (status)
return status;
status = check_uncompressed(state);
if (status)
return status;
status = check_fs(state);
if (status)
return status;
for (k = 1; k < bps - 2; k++) {
status = check_splitting(state, k);
if (status)
return status;
}
printf("All checks with %i bit per sample passed.\n", bps);
}
return 0;
}
int main (void)
{
int status;
struct aec_stream strm;
struct test_state state;
state.buf_len = state.ibuf_len = BUF_SIZE;
state.cbuf_len = 2 * BUF_SIZE;
state.ubuf = (unsigned char *)malloc(state.buf_len);
state.cbuf = (unsigned char *)malloc(state.cbuf_len);
state.obuf = (unsigned char *)malloc(state.buf_len);
if (!state.ubuf || !state.cbuf || !state.obuf) {
printf("Not enough memory.\n");
return 99;
}
strm.flags = AEC_DATA_PREPROCESS;
state.strm = &strm;
printf("----------------------------\n");
printf("Checking LSB first, unsigned\n");
printf("----------------------------\n");
status = check_bps(&state);
if (status)
goto DESTRUCT;
printf("--------------------------\n");
printf("Checking LSB first, signed\n");
printf("--------------------------\n");
strm.flags |= AEC_DATA_SIGNED;
status = check_bps(&state);
if (status)
goto DESTRUCT;
strm.flags &= ~AEC_DATA_SIGNED;
strm.flags |= AEC_DATA_MSB;
printf("----------------------------\n");
printf("Checking MSB first, unsigned\n");
printf("----------------------------\n");
status = check_bps(&state);
if (status)
goto DESTRUCT;
printf("--------------------------\n");
printf("Checking MSB first, signed\n");
printf("--------------------------\n");
strm.flags |= AEC_DATA_SIGNED;
status = check_bps(&state);
if (status)
goto DESTRUCT;