splitting test
authorMathis Rosenhauer <rosenhauer@dkrz.de>
Fri, 21 Sep 2012 12:58:48 +0000 (14:58 +0200)
committerThomas Jahns <jahns@dkrz.de>
Tue, 19 Feb 2013 10:32:59 +0000 (11:32 +0100)
tests/check_aec.c

index dab1930..2f9877e 100644 (file)
@@ -5,20 +5,70 @@
 #include <string.h>
 #include "libaec.h"
 
-#define BUF_SIZE 1024
+#define BUF_SIZE 1024 * 3
+
+struct test_state {
+    int id_len;
+    int byte_per_sample;
+    uint8_t *ubuf;
+    uint8_t *cbuf;
+    uint8_t *obuf;
+    size_t buf_len;
+    size_t cbuf_len;
+    void (*out)(uint8_t *dest, uint32_t val, int size);
+};
+
+static void out_lsb(uint8_t *dest, uint32_t val, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++)
+        dest[i] = val >> (8 * i);
+}
+
+static void out_msb(uint8_t *dest, uint32_t val, int size)
+{
+    int i;
+
+    for (i = 0; i < size; i++)
+        dest[i] = val >> (8 * (size - 1 - i));
+}
+
+static int update_state(struct aec_stream *strm, struct test_state *state)
+{
+    if (strm->bit_per_sample > 16) {
+        state->id_len = 5;
+
+        if (strm->bit_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE) {
+            state->byte_per_sample = 3;
+        } else {
+            state->byte_per_sample = 4;
+        }
+    }
+    else if (strm->bit_per_sample > 8) {
+        state->id_len = 4;
+        state->byte_per_sample = 2;
+    } else {
+        state->id_len = 3;
+        state->byte_per_sample = 1;
+    }
+
+    if (strm->flags & AEC_DATA_MSB)
+        state->out = out_msb;
+    else
+        state->out = out_lsb;
+
+    return 0;
+}
 
-int encode_decode(struct aec_stream *strm,
-                  uint8_t *ubuf,
-                  uint8_t *cbuf,
-                  uint8_t *obuf,
-                  size_t n)
+int encode_decode(struct aec_stream *strm, struct test_state *state)
 {
-    int status;
+    int status, i, to;
 
-    strm->avail_in = n;
-    strm->avail_out = n;
-    strm->next_in = ubuf;
-    strm->next_out = cbuf;
+    strm->avail_in = state->buf_len;
+    strm->avail_out = state->cbuf_len;
+    strm->next_in = state->ubuf;
+    strm->next_out = state->cbuf;
 
     status = aec_encode_init(strm);
     if (status != AEC_OK) {
@@ -35,9 +85,10 @@ int encode_decode(struct aec_stream *strm,
     aec_encode_end(strm);
 
     strm->avail_in = strm->total_out;
-    strm->avail_out = n;
-    strm->next_in = cbuf;
-    strm->next_out = obuf;
+    strm->avail_out = state->buf_len;
+    strm->next_in = state->cbuf;
+    strm->next_out = state->obuf;
+    to = strm->total_out;
 
     status = aec_decode_init(strm);
     if (status != AEC_OK) {
@@ -51,66 +102,137 @@ int encode_decode(struct aec_stream *strm,
         return 99;
     }
 
-    if (memcmp(ubuf, obuf, n)) {
+    if (memcmp(state->ubuf, state->obuf, state->buf_len)) {
         printf("FAIL: Uncompressed output differs from input.\n");
+
+        printf("\nuncompressed buf");
+        for (i = 0; i < 80; i++) {
+            if (i % 8 == 0)
+                printf("\n");
+            printf("%02x ", state->ubuf[i]);
+        }
+        printf("\n\ncompressed buf len %i", to);
+        for (i = 0; i < 80; i++) {
+            if (i % 8 == 0)
+                printf("\n");
+            printf("%02x ", state->cbuf[i]);
+        }
+        printf("\n\ndecompressed buf");
+        for (i = 0; i < 80; i++) {
+            if (i % 8 == 0)
+                printf("\n");
+            printf("%02x ", state->obuf[i]);
+        }
+        printf("\n");
         return 99;
     }
     aec_decode_end(strm);
     return 0;
 }
 
-int check_zero(struct aec_stream *strm,
-               uint8_t *ubuf,
-               uint8_t *cbuf,
-               uint8_t *obuf,
-               size_t n)
+int check_zero(struct aec_stream *strm, struct test_state *state)
 {
     int bs, status;
 
+    printf("Checking zero blocks with bit per sample %i ... ",
+           strm->bit_per_sample);
+
     for (bs = 8; bs <= 64; bs *= 2) {
-        memset(ubuf, 0x55, n);
-        strm->bit_per_sample = 8;
+        memset(state->ubuf, 0x55, state->buf_len);
         strm->block_size = bs;
-        strm->rsi = n / bs;
-        strm->flags = AEC_DATA_PREPROCESS;
-
-        printf("Checking zero blocks with block size %i ... ", bs);
+        strm->rsi = state->buf_len / (bs * state->byte_per_sample);
 
-        status = encode_decode(strm, ubuf, cbuf, obuf, n);
+        status = encode_decode(strm, state);
         if (status)
             return status;
 
-        if ((cbuf[0] & 0xf0) != 0) {
+        if ((state->cbuf[0] >> (8 - state->id_len)) != 0) {
             printf("FAIL: Unexpected block created.\n");
             return 99;
         }
-        printf ("OK\n");
     }
+    printf ("OK\n");
+    return 0;
+}
+
+int check_splitting(struct aec_stream *strm, struct test_state *state, int k)
+{
+    int bs, status;
+    uint8_t *tmp;
+    size_t size;
+
+    size = state->byte_per_sample;
+
+    for (tmp = state->ubuf;
+         tmp < state->ubuf + state->buf_len;
+         tmp += 4 * state->byte_per_sample) {
+        state->out(tmp, (1ULL << (k - 1)) - 1, size);
+        state->out(tmp + size, 0, size);
+        state->out(tmp + 2 * size, (1ULL << (k + 1)) - 1, size);
+        state->out(tmp + 3 * size, 0, size);
+    }
+
+    printf("Checking splitting with k=%i, bit per sample %i ... ",
+           k, strm->bit_per_sample);
+
+    for (bs = 8; bs <= 64; bs *= 2) {
+        strm->block_size = bs;
+        strm->rsi = state->buf_len / (bs * state->byte_per_sample);
+
+        status = encode_decode(strm, state);
+        if (status)
+            return status;
+
+        if ((state->cbuf[0] >> (8 - state->id_len)) != k + 1) {
+            printf("FAIL: Unexpected block of size %i created %i.\n",
+                   bs, state->cbuf[0] >> 5);
+            return 99;
+        }
+    }
+    printf ("OK\n");
     return 0;
 }
 
 int main (void)
 {
-    int status;
-    uint8_t *ubuf, *cbuf, *obuf;
+    int k, status, bps;
     struct aec_stream strm;
+    struct test_state state;
+
+    state.buf_len = BUF_SIZE;
+    state.cbuf_len = 2 * BUF_SIZE;
 
-    ubuf = (uint8_t *)malloc(BUF_SIZE);
-    cbuf = (uint8_t *)malloc(BUF_SIZE);
-    obuf = (uint8_t *)malloc(BUF_SIZE);
+    state.ubuf = (uint8_t *)malloc(state.buf_len);
+    state.cbuf = (uint8_t *)malloc(state.cbuf_len);
+    state.obuf = (uint8_t *)malloc(state.buf_len);
 
-    if (!ubuf || !cbuf || !obuf) {
+    if (!state.ubuf || !state.cbuf || !state.obuf) {
         printf("Not enough memory.\n");
         return 99;
     }
 
-    status = check_zero(&strm, ubuf, cbuf, obuf, BUF_SIZE);
-    if (status)
-        return status;
+    for (bps = 8; bps <= 32; bps += 8) {
+        strm.bit_per_sample = bps;
+        strm.flags = AEC_DATA_PREPROCESS;
+        if (bps == 24)
+            strm.flags |= AEC_DATA_3BYTE;
+
+        update_state(&strm, &state);
+
+        status = check_zero(&strm, &state);
+        if (status)
+            return status;
+
+        for (k = 1; k < bps - 2; k++) {
+            status = check_splitting(&strm, &state, k);
+            if (status)
+                return status;
+        }
+    }
 
-    free(ubuf);
-    free(cbuf);
-    free(obuf);
+    free(state.ubuf);
+    free(state.cbuf);
+    free(state.obuf);
 
     return 0;
 }