check_aec.c 8.24 KB
Newer Older
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
1 2 3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
4
#include "check_aec.h"
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
5

6
static void out_lsb(unsigned char *dest, unsigned long long int val, int size)
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
7
{
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
8
    for (int i = 0; i < size; i++)
9
        dest[i] = (unsigned char)(val >> (8 * i));
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
10 11
}

12
static void out_msb(unsigned char *dest, unsigned long long int val, int size)
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
13
{
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
14
    for (int i = 0; i < size; i++)
15
        dest[i] = (unsigned char)(val >> (8 * (size - 1 - i)));
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
16 17
}

18
int update_state(struct test_state *state)
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
19
{
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
20 21
    struct aec_stream *strm = state->strm;

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
22
    if (strm->bits_per_sample > 16) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
23 24
        state->id_len = 5;

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
25 26
        if (strm->bits_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE) {
            state->bytes_per_sample = 3;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
27
        } else {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
28
            state->bytes_per_sample = 4;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
29 30
        }
    }
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
31
    else if (strm->bits_per_sample > 8) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
32
        state->id_len = 4;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
33
        state->bytes_per_sample = 2;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
34 35
    } else {
        state->id_len = 3;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
36
        state->bytes_per_sample = 1;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
37 38 39 40 41 42 43
    }

    if (strm->flags & AEC_DATA_MSB)
        state->out = out_msb;
    else
        state->out = out_lsb;

44
    if (strm->flags & AEC_DATA_SIGNED) {
45
        state->xmin = -(1LL << (strm->bits_per_sample - 1));
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
46
        state->xmax = (1ULL << (strm->bits_per_sample - 1)) - 1;
47 48
    } else {
        state->xmin = 0;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
49
        state->xmax = (1ULL << strm->bits_per_sample) - 1;
50 51
    }

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
52 53
    return 0;
}
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
54

55 56
int encode_decode_small(struct test_state *state)
{
57 58
    size_t compressed_size;
    size_t n_in, avail_in, avail_out, total_out;
59 60
    struct aec_stream *strm = state->strm;

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
61
    int status = aec_encode_init(strm);
62 63 64 65 66
    if (status != AEC_OK) {
        printf("Init failed.\n");
        return 99;
    }

67 68 69 70 71
    n_in = 0;
    avail_in = 1;
    avail_out = 1;
    total_out = 0;
    strm->next_in = state->ubuf;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
72
    strm->avail_in = state->bytes_per_sample;
73 74 75 76 77
    strm->avail_out = 1;
    strm->next_out = state->cbuf;

    while ((avail_in || avail_out) && total_out < state->cbuf_len) {
        if (strm->avail_in == 0 && avail_in) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
78
            n_in += state->bytes_per_sample;
79
            if (n_in < state->buf_len) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
80
                strm->avail_in = state->bytes_per_sample;
81 82 83 84 85 86
                strm->next_in = state->ubuf + n_in;
            } else {
                avail_in = 0;
            }
        }

87 88
        status = aec_encode(strm, AEC_NO_FLUSH);
        if (status != AEC_OK) {
89
            printf("Decode failed.\n");
90 91
            return 99;
        }
92 93 94 95 96 97 98 99 100 101

        if (strm->total_out - total_out > 0
            && total_out < state->cbuf_len) {
            total_out = strm->total_out;
            strm->avail_out = 1;
            strm->next_out = state->cbuf + total_out;
            avail_out = 1;
        } else {
            avail_out = 0;
        }
102 103 104 105 106 107 108 109 110 111
    }

    status = aec_encode(strm, AEC_FLUSH);
    if (status != AEC_OK) {
        printf("Encode failed.\n");
        return 99;
    }

    aec_encode_end(strm);

112 113 114 115 116
    compressed_size = strm->total_out;

    strm->avail_in = 1;
    strm->next_in = state->cbuf;

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
117
    strm->avail_out = state->bytes_per_sample;
118 119 120 121 122 123 124 125
    strm->next_out = state->obuf;

    status = aec_decode_init(strm);
    if (status != AEC_OK) {
        printf("Init failed.\n");
        return 99;
    }

126 127 128 129 130 131
    n_in = 0;
    avail_in = 1;
    avail_out = 1;
    total_out = 0;
    strm->next_in = state->cbuf;
    strm->avail_in = 1;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
132
    strm->avail_out = state->bytes_per_sample;
133 134 135 136 137 138 139 140 141 142 143 144 145
    strm->next_out = state->obuf;

    while ((avail_in || avail_out) && total_out < state->buf_len) {
        if (strm->avail_in == 0 && avail_in) {
            n_in++;
            if (n_in < compressed_size) {
                strm->avail_in = 1;
                strm->next_in = state->cbuf + n_in;
            } else {
                avail_in = 0;
            }
        }

146 147 148 149 150
        status = aec_decode(strm, AEC_NO_FLUSH);
        if (status != AEC_OK) {
            printf("Decode failed.\n");
            return 99;
        }
151 152 153 154

        if (strm->total_out - total_out > 0
            && total_out < state->buf_len) {
            total_out = strm->total_out;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
155
            strm->avail_out = state->bytes_per_sample;
156 157 158 159 160
            strm->next_out = state->obuf + total_out;
            avail_out = 1;
        } else {
            avail_out = 0;
        }
161 162 163 164 165 166 167 168 169
    }

    status = aec_decode(strm, AEC_FLUSH);
    if (status != AEC_OK) {
        printf("Decode failed.\n");
        return 99;
    }

    if (memcmp(state->ubuf, state->obuf, state->ibuf_len)) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
170
        printf("\n%s: Uncompressed output differs from input.\n", CHECK_FAIL);
171 172

        printf("\nuncompressed buf");
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
173
        for (int i = 0; i < 80; i++) {
174 175 176 177
            if (i % 8 == 0)
                printf("\n");
            printf("%02x ", state->ubuf[i]);
        }
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
178
        printf("\n\ncompressed buf len %zu", compressed_size);
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
179
        for (int i = 0; i < 80; i++) {
180 181 182 183 184
            if (i % 8 == 0)
                printf("\n");
            printf("%02x ", state->cbuf[i]);
        }
        printf("\n\ndecompressed buf");
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
185
        for (int i = 0; i < 80; i++) {
186
            if (i % 8 == 0)
187
                printf("\n%04i ", i);
188 189 190 191 192 193 194 195 196
            printf("%02x ", state->obuf[i]);
        }
        printf("\n");
        return 99;
    }
    aec_decode_end(strm);
    return 0;
}

197
int encode_decode_large(struct test_state *state)
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
198
{
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
199
    int status;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
200
    int bflags = 0;
201
    size_t to;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
202
    char fbase[1024];
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
203
    struct aec_stream *strm = state->strm;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
204

205
    strm->avail_in = state->ibuf_len;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
206 207 208
    strm->avail_out = state->cbuf_len;
    strm->next_in = state->ubuf;
    strm->next_out = state->cbuf;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
209 210 211 212 213 214

    status = aec_encode_init(strm);
    if (status != AEC_OK) {
        printf("Init failed.\n");
        return 99;
    }
215
    if (state->dump) {
216
        char fname[1024 + 4];
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
217
        FILE *fp;
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
        snprintf(fbase, sizeof(fbase), "BPS%02iID%iBS%02iRSI%04iFLG%04i",
                 strm->bits_per_sample,
                 state->id,
                 strm->block_size,
                 strm->rsi,
                 strm->flags);
        snprintf(fname, sizeof(fname), "%s.dat", fbase);
        if ((fp = fopen(fname, "wb")) == NULL) {
            fprintf(stderr, "ERROR: cannot open dump file %s\n", fname);
            return 99;
        }
        fputc(strm->bits_per_sample, fp);
        bflags = strm->block_size >> 8;
        if (strm->flags | AEC_DATA_MSB)
            bflags |= 0x80;
        if (strm->flags | AEC_DATA_SIGNED)
            bflags |= 0x40;
        if (strm->flags | AEC_DATA_3BYTE)
            bflags |= 0x10;
        bflags |= 0x20; /* encode */
        fputc(bflags, fp);
        fwrite(strm->next_in, strm->avail_in, 1, fp);
        fclose(fp);
    }
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
242 243 244 245 246 247 248 249 250

    status = aec_encode(strm, AEC_FLUSH);
    if (status != AEC_OK) {
        printf("Encode failed.\n");
        return 99;
    }

    aec_encode_end(strm);

251
    if (state->dump) {
252
        char fname[1024 + 3];
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
253
        FILE *fp;
254 255 256 257 258 259 260 261 262 263 264 265
        snprintf(fname, sizeof(fname), "%s.rz", fbase);
        if ((fp = fopen(fname, "wb")) == NULL) {
            fprintf(stderr, "ERROR: cannot open dump file %s\n", fname);
            return 99;
        }
        fputc(strm->bits_per_sample, fp);
        bflags &= ~0x20;
        fputc(bflags, fp);
        fwrite(state->cbuf, strm->total_out, 1, fp);
        fclose(fp);
    }

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
266
    strm->avail_in = strm->total_out;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
267 268 269 270
    strm->avail_out = state->buf_len;
    strm->next_in = state->cbuf;
    strm->next_out = state->obuf;
    to = strm->total_out;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
271 272 273 274 275 276 277 278 279 280 281 282 283

    status = aec_decode_init(strm);
    if (status != AEC_OK) {
        printf("Init failed.\n");
        return 99;
    }

    status = aec_decode(strm, AEC_FLUSH);
    if (status != AEC_OK) {
        printf("Decode failed.\n");
        return 99;
    }

284
    if (memcmp(state->ubuf, state->obuf, state->ibuf_len)) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
285
        printf("\n%s: Uncompressed output differs from input.\n", CHECK_FAIL);
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
286 287

        printf("\nuncompressed buf");
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
288
        for (int i = 0; i < 80; i++) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
289 290 291 292
            if (i % 8 == 0)
                printf("\n");
            printf("%02x ", state->ubuf[i]);
        }
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
293
        printf("\n\ncompressed buf len %zu", to);
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
294
        for (int i = 0; i < 80; i++) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
295 296 297 298 299
            if (i % 8 == 0)
                printf("\n");
            printf("%02x ", state->cbuf[i]);
        }
        printf("\n\ndecompressed buf");
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
300
        for (int i = 0; i < 80; i++) {
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
301 302 303 304 305
            if (i % 8 == 0)
                printf("\n");
            printf("%02x ", state->obuf[i]);
        }
        printf("\n");
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
306 307 308 309 310
        return 99;
    }
    aec_decode_end(strm);
    return 0;
}