Add check for short RSI handling to catch previous bug
authorMathis Rosenhauer <rosenhauer@dkrz.de>
Tue, 25 Sep 2012 08:40:21 +0000 (10:40 +0200)
committerThomas Jahns <jahns@dkrz.de>
Tue, 19 Feb 2013 10:32:59 +0000 (11:32 +0100)
src/Makefile.am
tests/Makefile.am
tests/check_aec.c
tests/check_aec.h [new file with mode: 0644]
tests/check_buffer_sizes.c [new file with mode: 0644]
tests/check_code_options.c [new file with mode: 0644]

index 83422e8..8f1f989 100644 (file)
@@ -1,6 +1,8 @@
 lib_LTLIBRARIES = libaec.la libsz.la
-libaec_la_SOURCES = encode.c encode_accessors.c decode.c encode.h encode_accessors.h
-libsz_la_SOURCES = sz_compat.c libaec.la
+libaec_la_SOURCES = encode.c encode_accessors.c decode.c encode.h \
+encode_accessors.h
+
+libsz_la_SOURCES = sz_compat.c
 libsz_la_LIBADD = libaec.la
 libaec_la_LDFLAGS = -version-info 0:0
 libsz_la_LDFLAGS = -version-info 0:0
index b437cc4..dfb1213 100644 (file)
@@ -1,5 +1,13 @@
 INCLUDES = -I$(top_srcdir)/src
-TESTS = check_aec
-check_PROGRAMS = check_aec
-check_aec_SOURCES = check_aec.c $(top_builddir)/src/libaec.h
-check_aec_LDADD = $(top_builddir)/src/libaec.la
+TESTS = check_code_options check_buffer_sizes
+check_LTLIBRARIES = libcheck_aec.la
+libcheck_aec_la_SOURCES = check_aec.c check_aec.h
+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
index 847a6af..ac1e167 100644 (file)
@@ -3,22 +3,7 @@
 #include <unistd.h>
 #include <string.h>
 #include "libaec.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;
-};
+#include "check_aec.h"
 
 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)
         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;
 
@@ -78,7 +63,7 @@ int encode_decode(struct test_state *state)
     int status, i, to;
     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->next_in = state->ubuf;
     strm->next_out = state->cbuf;
@@ -115,7 +100,7 @@ int encode_decode(struct test_state *state)
         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("\nuncompressed buf");
@@ -142,245 +127,3 @@ int encode_decode(struct test_state *state)
     aec_decode_end(strm);
     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;
-}
diff --git a/tests/check_aec.h b/tests/check_aec.h
new file mode 100644 (file)
index 0000000..884f610
--- /dev/null
@@ -0,0 +1,24 @@
+#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 */
diff --git a/tests/check_buffer_sizes.c b/tests/check_buffer_sizes.c
new file mode 100644 (file)
index 0000000..9db3808
--- /dev/null
@@ -0,0 +1,112 @@
+#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;
+}
diff --git a/tests/check_code_options.c b/tests/check_code_options.c
new file mode 100644 (file)
index 0000000..ffd361a
--- /dev/null
@@ -0,0 +1,250 @@
+#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;
+
+DESTRUCT:
+    free(state.ubuf);
+    free(state.cbuf);
+    free(state.obuf);
+
+    return status;
+}