3c250cd6c1e764d9a200a28bcc0ec9f0aea4be27
[platform/upstream/libaec.git] / tests / check_aec.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include "libaec.h"
6
7 #define BUF_SIZE 1024 * 3
8
9 struct test_state {
10     int id_len;
11     int byte_per_sample;
12     unsigned char *ubuf;
13     unsigned char *cbuf;
14     unsigned char *obuf;
15     size_t buf_len;
16     size_t cbuf_len;
17     long long int xmax;
18     long long int xmin;
19     void (*out)(unsigned char *dest, unsigned int val, int size);
20 };
21
22 static void out_lsb(unsigned char *dest, unsigned int val, int size)
23 {
24     int i;
25
26     for (i = 0; i < size; i++)
27         dest[i] = val >> (8 * i);
28 }
29
30 static void out_msb(unsigned char *dest, unsigned int val, int size)
31 {
32     int i;
33
34     for (i = 0; i < size; i++)
35         dest[i] = val >> (8 * (size - 1 - i));
36 }
37
38 static int update_state(struct aec_stream *strm, struct test_state *state)
39 {
40     if (strm->bit_per_sample > 16) {
41         state->id_len = 5;
42
43         if (strm->bit_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE) {
44             state->byte_per_sample = 3;
45         } else {
46             state->byte_per_sample = 4;
47         }
48     }
49     else if (strm->bit_per_sample > 8) {
50         state->id_len = 4;
51         state->byte_per_sample = 2;
52     } else {
53         state->id_len = 3;
54         state->byte_per_sample = 1;
55     }
56
57     if (strm->flags & AEC_DATA_MSB)
58         state->out = out_msb;
59     else
60         state->out = out_lsb;
61
62     if (strm->flags & AEC_DATA_SIGNED) {
63         state->xmin = -(1ULL << (strm->bit_per_sample - 1));
64         state->xmax = (1ULL << (strm->bit_per_sample - 1)) - 1;
65     } else {
66         state->xmin = 0;
67         state->xmax = (1ULL << strm->bit_per_sample) - 1;
68     }
69
70     return 0;
71 }
72
73 int encode_decode(struct aec_stream *strm, struct test_state *state)
74 {
75     int status, i, to;
76
77     strm->avail_in = state->buf_len;
78     strm->avail_out = state->cbuf_len;
79     strm->next_in = state->ubuf;
80     strm->next_out = state->cbuf;
81
82     status = aec_encode_init(strm);
83     if (status != AEC_OK) {
84         printf("Init failed.\n");
85         return 99;
86     }
87
88     status = aec_encode(strm, AEC_FLUSH);
89     if (status != AEC_OK) {
90         printf("Encode failed.\n");
91         return 99;
92     }
93
94     aec_encode_end(strm);
95
96     strm->avail_in = strm->total_out;
97     strm->avail_out = state->buf_len;
98     strm->next_in = state->cbuf;
99     strm->next_out = state->obuf;
100     to = strm->total_out;
101
102     status = aec_decode_init(strm);
103     if (status != AEC_OK) {
104         printf("Init failed.\n");
105         return 99;
106     }
107
108     status = aec_decode(strm, AEC_FLUSH);
109     if (status != AEC_OK) {
110         printf("Decode failed.\n");
111         return 99;
112     }
113
114     if (memcmp(state->ubuf, state->obuf, state->buf_len)) {
115         printf("FAIL: Uncompressed output differs from input.\n");
116
117         printf("\nuncompressed buf");
118         for (i = 0; i < 80; i++) {
119             if (i % 8 == 0)
120                 printf("\n");
121             printf("%02x ", state->ubuf[i]);
122         }
123         printf("\n\ncompressed buf len %i", to);
124         for (i = 0; i < 80; i++) {
125             if (i % 8 == 0)
126                 printf("\n");
127             printf("%02x ", state->cbuf[i]);
128         }
129         printf("\n\ndecompressed buf");
130         for (i = 0; i < 80; i++) {
131             if (i % 8 == 0)
132                 printf("\n");
133             printf("%02x ", state->obuf[i]);
134         }
135         printf("\n");
136         return 99;
137     }
138     aec_decode_end(strm);
139     return 0;
140 }
141
142 int check_block_sizes(struct aec_stream *strm,
143                       struct test_state *state,
144                       int id)
145 {
146     int bs, status;
147
148     for (bs = 8; bs <= 64; bs *= 2) {
149         strm->block_size = bs;
150         strm->rsi = state->buf_len / (bs * state->byte_per_sample);
151
152         status = encode_decode(strm, state);
153         if (status)
154             return status;
155
156         if ((state->cbuf[0] >> (8 - state->id_len)) != id) {
157             printf("FAIL: Unexpected block of size %i created %x.\n",
158                    bs, state->cbuf[0] >> (8 - state->id_len));
159             return 99;
160         }
161     }
162     return 0;
163 }
164
165 int check_zero(struct aec_stream *strm, struct test_state *state)
166 {
167     int status;
168
169     memset(state->ubuf, 0x55, state->buf_len);
170
171     printf("Checking zero blocks ... ");
172     status = check_block_sizes(strm, state, 0);
173     if (status)
174         return status;
175
176     printf ("OK\n");
177     return 0;
178 }
179
180 int check_splitting(struct aec_stream *strm, struct test_state *state, int k)
181 {
182     int status, size;
183     unsigned char *tmp;
184
185     size = state->byte_per_sample;
186
187     for (tmp = state->ubuf;
188          tmp < state->ubuf + state->buf_len;
189          tmp += 4 * state->byte_per_sample) {
190         state->out(tmp, state->xmin + (1ULL << (k - 1)) - 1, size);
191         state->out(tmp + size, state->xmin, size);
192         state->out(tmp + 2 * size, state->xmin + (1ULL << (k + 1)) - 1, size);
193         state->out(tmp + 3 * size, state->xmin, size);
194     }
195
196     printf("Checking splitting with k=%i ... ", k);
197     status = check_block_sizes(strm, state, k + 1);
198     if (status)
199         return status;
200
201     printf ("OK\n");
202     return 0;
203 }
204
205 int check_uncompressed(struct aec_stream *strm, struct test_state *state)
206 {
207     int status, size;
208     unsigned char *tmp;
209
210     size = state->byte_per_sample;
211
212     for (tmp = state->ubuf;
213          tmp < state->ubuf + state->buf_len;
214          tmp += 2 * state->byte_per_sample) {
215         state->out(tmp, state->xmax, size);
216         state->out(tmp + size, state->xmin, size);
217     }
218
219     printf("Checking uncompressed ... ");
220     status = check_block_sizes(strm, state, (1ULL << state->id_len) - 1);
221     if (status)
222         return status;
223
224     printf ("OK\n");
225     return 0;
226 }
227
228 int check_fs(struct aec_stream *strm, struct test_state *state)
229 {
230     int status, size;
231     unsigned char *tmp;
232
233     size = state->byte_per_sample;
234
235     for (tmp = state->ubuf;
236          tmp < state->ubuf + state->buf_len;
237          tmp += 2 * state->byte_per_sample) {
238         state->out(tmp, state->xmin + 1, size);
239         state->out(tmp + size, state->xmin, size);
240     }
241
242     printf("Checking FS ... ");
243     status = check_block_sizes(strm, state, 1);
244     if (status)
245         return status;
246
247     printf ("OK\n");
248     return 0;
249 }
250
251 int check_se(struct aec_stream *strm, struct test_state *state)
252 {
253     int status, size;
254     unsigned char *tmp;
255
256     size = state->byte_per_sample;
257
258     for (tmp = state->ubuf;
259          tmp < state->ubuf + state->buf_len;
260          tmp += 8 * size) {
261         state->out(tmp, 0, size);
262         state->out(tmp + size, 0, size);
263         state->out(tmp + 2 * size, 0, size);
264         state->out(tmp + 3 * size, 0, size);
265         state->out(tmp + 4 * size, 0, size);
266         state->out(tmp + 5 * size, 0, size);
267         state->out(tmp + 6 * size, 0, size);
268         state->out(tmp + 7 * size, 1, size);
269     }
270
271     printf("Checking Second Extension ... ");
272     status = check_block_sizes(strm, state, 0);
273     if (status)
274         return status;
275
276     printf ("OK\n");
277     return 0;
278 }
279
280 int check_bps(struct aec_stream *strm, struct test_state *state)
281 {
282     int k, status, bps;
283
284     for (bps = 8; bps <= 32; bps += 8) {
285         strm->bit_per_sample = bps;
286         if (bps == 24)
287             strm->flags |= AEC_DATA_3BYTE;
288         else
289             strm->flags &= ~AEC_DATA_3BYTE;
290
291         update_state(strm, state);
292
293         status = check_zero(strm, state);
294         if (status)
295             return status;
296
297         status = check_se(strm, state);
298         if (status)
299             return status;
300
301         status = check_uncompressed(strm, state);
302         if (status)
303             return status;
304
305         status = check_fs(strm, state);
306         if (status)
307             return status;
308
309         for (k = 1; k < bps - 2; k++) {
310             status = check_splitting(strm, state, k);
311             if (status)
312                 return status;
313         }
314         printf("All checks with %i bit per sample passed.\n\n", bps);
315     }
316     return 0;
317 }
318
319 int main (void)
320 {
321     int status;
322     struct aec_stream strm;
323     struct test_state state;
324
325     state.buf_len = BUF_SIZE;
326     state.cbuf_len = 2 * BUF_SIZE;
327
328     state.ubuf = (unsigned char *)malloc(state.buf_len);
329     state.cbuf = (unsigned char *)malloc(state.cbuf_len);
330     state.obuf = (unsigned char *)malloc(state.buf_len);
331
332     if (!state.ubuf || !state.cbuf || !state.obuf) {
333         printf("Not enough memory.\n");
334         return 99;
335     }
336
337     strm.flags = AEC_DATA_PREPROCESS;
338
339     printf("----------------------------\n");
340     printf("Checking LSB first, unsigned\n");
341     printf("----------------------------\n");
342     status = check_bps(&strm, &state);
343     if (status)
344         goto destruct;
345
346     printf("--------------------------\n");
347     printf("Checking LSB first, signed\n");
348     printf("--------------------------\n");
349     strm.flags |= AEC_DATA_SIGNED;
350
351     status = check_bps(&strm, &state);
352     if (status)
353         goto destruct;
354
355     strm.flags &= ~AEC_DATA_SIGNED;
356     strm.flags |= AEC_DATA_MSB;
357
358     printf("----------------------------\n");
359     printf("Checking MSB first, unsigned\n");
360     printf("----------------------------\n");
361     status = check_bps(&strm, &state);
362     if (status)
363         goto destruct;
364
365     printf("--------------------------\n");
366     printf("Checking MSB first, signed\n");
367     printf("--------------------------\n");
368     strm.flags |= AEC_DATA_SIGNED;
369
370     status = check_bps(&strm, &state);
371     if (status)
372         goto destruct;
373
374 destruct:
375     free(state.ubuf);
376     free(state.cbuf);
377     free(state.obuf);
378
379     return status;
380 }