Make RSI padding for encoding compile time option as it affects performance
[platform/upstream/libaec.git] / src / decode.c
1 /**
2  * @file decode.c
3  *
4  * @author Mathis Rosenhauer, Deutsches Klimarechenzentrum
5  * @author Moritz Hanke, Deutsches Klimarechenzentrum
6  * @author Joerg Behrens, Deutsches Klimarechenzentrum
7  * @author Luis Kornblueh, Max-Planck-Institut fuer Meteorologie
8  *
9  * @section LICENSE
10  * Copyright 2012 - 2014
11  *
12  * Mathis Rosenhauer,                 Luis Kornblueh
13  * Moritz Hanke,
14  * Joerg Behrens
15  *
16  * Deutsches Klimarechenzentrum GmbH  Max-Planck-Institut fuer Meteorologie
17  * Bundesstr. 45a                     Bundesstr. 53
18  * 20146 Hamburg                      20146 Hamburg
19  * Germany                            Germany
20  *
21  * All rights reserved.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  *
27  * 1. Redistributions of source code must retain the above copyright
28  *    notice, this list of conditions and the following disclaimer.
29  * 2. Redistributions in binary form must reproduce the above
30  *    copyright notice, this list of conditions and the following
31  *    disclaimer in the documentation and/or other materials provided
32  *    with the distribution.
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
37  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
38  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
39  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
43  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
45  * OF THE POSSIBILITY OF SUCH DAMAGE.
46  *
47  * @section DESCRIPTION
48  *
49  * Adaptive Entropy Decoder
50  * Based on CCSDS documents 121.0-B-2 and 120.0-G-2
51  *
52  */
53
54 #include <config.h>
55
56 #if HAVE_STDINT_H
57 # include <stdint.h>
58 #endif
59
60 #include <stdio.h>
61 #include <unistd.h>
62 #include <stdlib.h>
63 #include <string.h>
64
65 #include "libaec.h"
66 #include "decode.h"
67
68 #define ROS 5
69
70 #define BUFFERSPACE(strm) (strm->avail_in >= strm->state->in_blklen     \
71                            && strm->avail_out >= strm->state->out_blklen)
72
73 #define FLUSH(KIND)                                                     \
74     static void flush_##KIND(struct aec_stream *strm)                   \
75     {                                                                   \
76         uint32_t *bp, *flush_end;                                       \
77         int64_t d, m;                                                   \
78         int64_t data, med, half_d, xmin, xmax;                          \
79         struct internal_state *state = strm->state;                     \
80                                                                         \
81         flush_end = state->rsip;                                        \
82         if (state->pp) {                                                \
83             if (state->flush_start == state->rsi_buffer                 \
84                 && state->rsip > state->rsi_buffer) {                   \
85                 state->last_out = *state->rsi_buffer;                   \
86                                                                         \
87                 if (strm->flags & AEC_DATA_SIGNED) {                    \
88                     m = 1ULL << (strm->bits_per_sample - 1);            \
89                     /* Reference samples have to be sign extended */    \
90                     state->last_out = (state->last_out ^ m) - m;        \
91                 }                                                       \
92                 put_##KIND(strm, state->last_out);                      \
93                 state->flush_start++;                                   \
94             }                                                           \
95                                                                         \
96             data = state->last_out;                                     \
97             if (strm->flags & AEC_DATA_SIGNED)                          \
98                 med = 0;                                                \
99             else                                                        \
100                 med = (state->xmax - state->xmin) / 2 + 1;              \
101                                                                         \
102             xmin = state->xmin;                                         \
103             xmax = state->xmax;                                         \
104                                                                         \
105             for (bp = state->flush_start; bp < flush_end; bp++) {       \
106                 d = *bp;                                                \
107                 half_d = (d + 1) >> 1;                                  \
108                                                                         \
109                 if (data < med) {                                       \
110                     if (half_d <= data - xmin) {                        \
111                         if (d & 1)                                      \
112                             data -= half_d;                             \
113                         else                                            \
114                             data += half_d;                             \
115                     } else {                                            \
116                         data = xmin + d;                                \
117                     }                                                   \
118                 } else {                                                \
119                     if (half_d <= xmax - data) {                        \
120                         if (d & 1)                                      \
121                             data -= half_d;                             \
122                         else                                            \
123                             data += half_d;                             \
124                     } else {                                            \
125                         data = xmax - d;                                \
126                     }                                                   \
127                 }                                                       \
128                 put_##KIND(strm, data);                                 \
129             }                                                           \
130             state->last_out = data;                                     \
131         } else {                                                        \
132             for (bp = state->flush_start; bp < flush_end; bp++)         \
133                 put_##KIND(strm, *bp);                                  \
134         }                                                               \
135         state->flush_start = state->rsip;                               \
136     }
137
138
139 static inline void put_msb_32(struct aec_stream *strm, uint32_t data)
140 {
141     *strm->next_out++ = data >> 24;
142     *strm->next_out++ = data >> 16;
143     *strm->next_out++ = data >> 8;
144     *strm->next_out++ = data;
145 }
146
147 static inline void put_msb_24(struct aec_stream *strm, uint32_t data)
148 {
149     *strm->next_out++ = data >> 16;
150     *strm->next_out++ = data >> 8;
151     *strm->next_out++ = data;
152 }
153
154 static inline void put_msb_16(struct aec_stream *strm, uint32_t data)
155 {
156     *strm->next_out++ = data >> 8;
157     *strm->next_out++ = data;
158 }
159
160 static inline void put_lsb_32(struct aec_stream *strm, uint32_t data)
161 {
162     *strm->next_out++ = data;
163     *strm->next_out++ = data >> 8;
164     *strm->next_out++ = data >> 16;
165     *strm->next_out++ = data >> 24;
166 }
167
168 static inline void put_lsb_24(struct aec_stream *strm, uint32_t data)
169 {
170     *strm->next_out++ = data;
171     *strm->next_out++ = data >> 8;
172     *strm->next_out++ = data >> 16;
173 }
174
175 static inline void put_lsb_16(struct aec_stream *strm, uint32_t data)
176 {
177     *strm->next_out++ = data;
178     *strm->next_out++ = data >> 8;
179 }
180
181 static inline void put_8(struct aec_stream *strm, uint32_t data)
182 {
183     *strm->next_out++ = data;
184 }
185
186 FLUSH(msb_32);
187 FLUSH(msb_24);
188 FLUSH(msb_16);
189 FLUSH(lsb_32);
190 FLUSH(lsb_24);
191 FLUSH(lsb_16);
192 FLUSH(8);
193
194 static inline void check_rsi_end(struct aec_stream *strm)
195 {
196     /**
197        Flush output if end of RSI reached
198      */
199     struct internal_state *state = strm->state;
200
201     if (state->rsip - state->rsi_buffer == state->rsi_size) {
202         state->flush_output(strm);
203         state->flush_start = state->rsi_buffer;
204         state->rsip = state->rsi_buffer;
205     }
206 }
207
208 static inline void put_sample(struct aec_stream *strm, uint32_t s)
209 {
210     struct internal_state *state = strm->state;
211
212     *state->rsip++ = s;
213     strm->avail_out -= state->bytes_per_sample;
214     check_rsi_end(strm);
215 }
216
217 static inline void fill_acc(struct aec_stream *strm)
218 {
219     int b = (63 - strm->state->bitp) >> 3;
220
221     strm->avail_in -= b;
222     strm->state->bitp += b << 3;
223
224     switch (b) {
225       case (7):
226         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
227       case (6):
228         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
229       case (5):
230         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
231       case (4):
232         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
233       case (3):
234         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
235       case (2):
236         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
237       case (1):
238         strm->state->acc = (strm->state->acc << 8) | *strm->next_in++;
239     };
240
241 }
242
243 static inline uint32_t direct_get(struct aec_stream *strm, unsigned int n)
244 {
245     /**
246        Get n bit from input stream
247
248        No checking whatsoever. Read bits are dumped.
249      */
250
251     struct internal_state *state = strm->state;
252
253     if (state->bitp < n)
254         fill_acc(strm);
255
256     state->bitp -= n;
257     return (state->acc >> state->bitp) & ((1ULL << n) - 1);
258 }
259
260 static inline uint32_t direct_get_fs(struct aec_stream *strm)
261 {
262     /**
263        Interpret a Fundamental Sequence from the input buffer.
264
265        Essentially counts the number of 0 bits until a 1 is
266        encountered.
267      */
268
269     uint32_t fs = 0;
270 #ifdef HAVE_DECL___BUILTIN_CLZLL
271     uint32_t lz;
272 #endif
273     struct internal_state *state = strm->state;
274
275     state->acc &= ((1ULL << state->bitp) - 1);
276
277     while (state->acc == 0) {
278         fs += state->bitp;
279         state->bitp = 0;
280         fill_acc(strm);
281     }
282
283 #ifdef HAVE_DECL___BUILTIN_CLZLL
284     lz = __builtin_clzll(state->acc);
285     fs += lz + state->bitp - 64;
286     state->bitp = 63 - lz;
287 #else
288     state->bitp--;
289     while ((state->acc & (1ULL << state->bitp)) == 0) {
290         state->bitp--;
291         fs++;
292     }
293 #endif
294     return fs;
295 }
296
297 static inline uint32_t bits_ask(struct aec_stream *strm, int n)
298 {
299     while (strm->state->bitp < n) {
300         if (strm->avail_in == 0)
301             return 0;
302         strm->avail_in--;
303         strm->state->acc <<= 8;
304         strm->state->acc |= *strm->next_in++;
305         strm->state->bitp += 8;
306     }
307     return 1;
308 }
309
310 static inline uint32_t bits_get(struct aec_stream *strm, int n)
311 {
312     return (strm->state->acc >> (strm->state->bitp - n))
313         & ((1ULL << n) - 1);
314 }
315
316 static inline void bits_drop(struct aec_stream *strm, int n)
317 {
318     strm->state->bitp -= n;
319 }
320
321 static inline uint32_t fs_ask(struct aec_stream *strm)
322 {
323     if (bits_ask(strm, 1) == 0)
324         return 0;
325     while ((strm->state->acc & (1ULL << (strm->state->bitp - 1))) == 0) {
326         if (strm->state->bitp == 1) {
327             if (strm->avail_in == 0)
328                 return 0;
329             strm->avail_in--;
330             strm->state->acc <<= 8;
331             strm->state->acc |= *strm->next_in++;
332             strm->state->bitp += 8;
333         }
334         strm->state->fs++;
335         strm->state->bitp--;
336     }
337     return 1;
338 }
339
340 static inline void fs_drop(struct aec_stream *strm)
341 {
342     strm->state->fs = 0;
343     strm->state->bitp--;
344 }
345
346 static inline uint32_t copysample(struct aec_stream *strm)
347 {
348     if (bits_ask(strm, strm->bits_per_sample) == 0
349         || strm->avail_out == 0)
350         return 0;
351
352     put_sample(strm, bits_get(strm, strm->bits_per_sample));
353     bits_drop(strm, strm->bits_per_sample);
354     return 1;
355 }
356
357 static int m_id(struct aec_stream *strm)
358 {
359     struct internal_state *state = strm->state;
360
361     if (state->rsip == state->rsi_buffer) {
362         if(strm->flags & AEC_PAD_RSI)
363             state->bitp -= state->bitp % 8;
364         if (state->pp)
365             state->ref = 1;
366     } else {
367         state->ref = 0;
368     }
369     if (bits_ask(strm, state->id_len) == 0)
370         return M_EXIT;
371     state->id = bits_get(strm, state->id_len);
372     bits_drop(strm, state->id_len);
373     state->mode = state->id_table[state->id];
374
375     return M_CONTINUE;
376 }
377
378 static int m_split_output(struct aec_stream *strm)
379 {
380     struct internal_state *state = strm->state;
381     int k = state->id - 1;
382
383     do {
384         if (bits_ask(strm, k) == 0 || strm->avail_out == 0)
385             return M_EXIT;
386         *state->rsip++ += bits_get(strm, k);
387         strm->avail_out -= state->bytes_per_sample;
388         bits_drop(strm, k);
389     } while(++state->i < state->n);
390
391     check_rsi_end(strm);
392     state->mode = m_id;
393     return M_CONTINUE;
394 }
395
396 static int m_split_fs(struct aec_stream *strm)
397 {
398     struct internal_state *state = strm->state;
399     int k = state->id - 1;
400
401     do {
402         if (fs_ask(strm) == 0)
403             return M_EXIT;
404         state->rsip[state->i] = state->fs << k;
405         fs_drop(strm);
406     } while(++state->i < state->n);
407
408     state->i = 0;
409     state->mode = m_split_output;
410     return M_CONTINUE;
411 }
412
413 static int m_split(struct aec_stream *strm)
414 {
415     int i, k;
416     struct internal_state *state = strm->state;
417
418     if (BUFFERSPACE(strm)) {
419         k = state->id - 1;
420
421         if (state->ref)
422             *state->rsip++ = direct_get(strm, strm->bits_per_sample);
423
424         for (i = 0; i < strm->block_size - state->ref; i++)
425             state->rsip[i] = direct_get_fs(strm) << k;
426
427         for (i = state->ref; i < strm->block_size; i++)
428             *state->rsip++ += direct_get(strm, k);
429
430         strm->avail_out -= state->out_blklen;
431         check_rsi_end(strm);
432
433         state->mode = m_id;
434         return M_CONTINUE;
435     }
436
437     if (state->ref) {
438         if (copysample(strm) == 0)
439             return M_EXIT;
440         state->n = strm->block_size - 1;
441     } else {
442         state->n = strm->block_size;
443     }
444
445     state->i = 0;
446     state->mode = m_split_fs;
447     return M_CONTINUE;
448 }
449
450 static int m_zero_output(struct aec_stream *strm)
451 {
452     struct internal_state *state = strm->state;
453
454     do {
455         if (strm->avail_out == 0)
456             return M_EXIT;
457         put_sample(strm, 0);
458     } while(--state->i);
459
460     state->mode = m_id;
461     return M_CONTINUE;
462 }
463
464 static int m_zero_block(struct aec_stream *strm)
465 {
466     int i, zero_blocks, b, zero_bytes;
467     struct internal_state *state = strm->state;
468
469     if (fs_ask(strm) == 0)
470         return M_EXIT;
471     zero_blocks = state->fs + 1;
472     fs_drop(strm);
473
474     if (zero_blocks == ROS) {
475         b = (state->rsip - state->rsi_buffer) / strm->block_size;
476         zero_blocks = MIN(strm->rsi - b, 64 - (b % 64));
477     } else if (zero_blocks > ROS) {
478         zero_blocks--;
479     }
480
481     if (state->ref)
482         i = zero_blocks * strm->block_size - 1;
483     else
484         i = zero_blocks * strm->block_size;
485
486     zero_bytes = i * state->bytes_per_sample;
487
488     if (strm->avail_out >= zero_bytes) {
489         if (state->rsi_size - (state->rsip - state->rsi_buffer) < i)
490             return M_ERROR;
491
492         memset(state->rsip, 0, i * sizeof(uint32_t));
493         state->rsip += i;
494         strm->avail_out -= zero_bytes;
495         check_rsi_end(strm);
496
497         state->mode = m_id;
498         return M_CONTINUE;
499     }
500
501     state->i = i;
502     state->mode = m_zero_output;
503     return M_CONTINUE;
504 }
505
506 static int m_se_decode(struct aec_stream *strm)
507 {
508     int32_t m, d1;
509     struct internal_state *state = strm->state;
510
511     while(state->i < strm->block_size) {
512         if (fs_ask(strm) == 0)
513             return M_EXIT;
514         m = state->fs;
515         d1 = m - state->se_table[2 * m + 1];
516
517         if ((state->i & 1) == 0) {
518             if (strm->avail_out == 0)
519                 return M_EXIT;
520             put_sample(strm, state->se_table[2 * m] - d1);
521             state->i++;
522         }
523
524         if (strm->avail_out == 0)
525             return M_EXIT;
526         put_sample(strm, d1);
527         state->i++;
528         fs_drop(strm);
529     }
530
531     state->mode = m_id;
532     return M_CONTINUE;
533 }
534
535 static int m_se(struct aec_stream *strm)
536 {
537     int i;
538     int32_t m, d1;
539     struct internal_state *state = strm->state;
540
541     if (BUFFERSPACE(strm)) {
542         i = state->ref;
543
544         while (i < strm->block_size) {
545             m = direct_get_fs(strm);
546             d1 = m - state->se_table[2 * m + 1];
547
548             if ((i & 1) == 0) {
549                 put_sample(strm, state->se_table[2 * m] - d1);
550                 i++;
551             }
552             put_sample(strm, d1);
553             i++;
554         }
555         state->mode = m_id;
556         return M_CONTINUE;
557     }
558
559     state->mode = m_se_decode;
560     state->i = state->ref;
561     return M_CONTINUE;
562 }
563
564 static int m_low_entropy_ref(struct aec_stream *strm)
565 {
566     struct internal_state *state = strm->state;
567
568     if (state->ref && copysample(strm) == 0)
569         return M_EXIT;
570
571     if(state->id == 1) {
572         state->mode = m_se;
573         return M_CONTINUE;
574     }
575
576     state->mode = m_zero_block;
577     return M_CONTINUE;
578 }
579
580 static int m_low_entropy(struct aec_stream *strm)
581 {
582     struct internal_state *state = strm->state;
583
584     if (bits_ask(strm, 1) == 0)
585         return M_EXIT;
586     state->id = bits_get(strm, 1);
587     bits_drop(strm, 1);
588     state->mode = m_low_entropy_ref;
589     return M_CONTINUE;
590 }
591
592 static int m_uncomp_copy(struct aec_stream *strm)
593 {
594     struct internal_state *state = strm->state;
595
596     do {
597         if (copysample(strm) == 0)
598             return M_EXIT;
599     } while(--state->i);
600
601     state->mode = m_id;
602     return M_CONTINUE;
603 }
604
605 static int m_uncomp(struct aec_stream *strm)
606 {
607     int i;
608     struct internal_state *state = strm->state;
609
610     if (BUFFERSPACE(strm)) {
611         for (i = 0; i < strm->block_size; i++)
612             *state->rsip++ = direct_get(strm, strm->bits_per_sample);
613         strm->avail_out -= state->out_blklen;
614         check_rsi_end(strm);
615
616         state->mode = m_id;
617         return M_CONTINUE;
618     }
619
620     state->i = strm->block_size;
621     state->mode = m_uncomp_copy;
622     return M_CONTINUE;
623 }
624
625 static void create_se_table(int *table)
626 {
627     int i, j, k, ms;
628
629     k = 0;
630     for (i = 0; i < 13; i++) {
631         ms = k;
632         for (j = 0; j <= i; j++) {
633             table[2 * k] = i;
634             table[2 * k + 1] = ms;
635             k++;
636         }
637     }
638 }
639
640 int aec_decode_init(struct aec_stream *strm)
641 {
642     int i, modi;
643     struct internal_state *state;
644
645     if (strm->bits_per_sample > 32 || strm->bits_per_sample == 0)
646         return AEC_CONF_ERROR;
647
648     state = malloc(sizeof(struct internal_state));
649     if (state == NULL)
650         return AEC_MEM_ERROR;
651
652     create_se_table(state->se_table);
653
654     strm->state = state;
655
656     if (strm->bits_per_sample > 16) {
657         state->id_len = 5;
658
659         if (strm->bits_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE) {
660             state->bytes_per_sample = 3;
661             if (strm->flags & AEC_DATA_MSB)
662                 state->flush_output = flush_msb_24;
663             else
664                 state->flush_output = flush_lsb_24;
665         } else {
666             state->bytes_per_sample = 4;
667             if (strm->flags & AEC_DATA_MSB)
668                 state->flush_output = flush_msb_32;
669             else
670                 state->flush_output = flush_lsb_32;
671         }
672         state->out_blklen = strm->block_size
673             * state->bytes_per_sample;
674     }
675     else if (strm->bits_per_sample > 8) {
676         state->bytes_per_sample = 2;
677         state->id_len = 4;
678         state->out_blklen = strm->block_size * 2;
679         if (strm->flags & AEC_DATA_MSB)
680             state->flush_output = flush_msb_16;
681         else
682             state->flush_output = flush_lsb_16;
683     } else {
684         if (strm->flags & AEC_RESTRICTED) {
685             if (strm->bits_per_sample <= 4) {
686                 if (strm->bits_per_sample <= 2)
687                     state->id_len = 1;
688                 else
689                     state->id_len = 2;
690             } else {
691                 return AEC_CONF_ERROR;
692             }
693         } else {
694             state->id_len = 3;
695         }
696
697         state->bytes_per_sample = 1;
698         state->out_blklen = strm->block_size;
699         state->flush_output = flush_8;
700     }
701
702     if (strm->flags & AEC_DATA_SIGNED) {
703         state->xmin = -(1ULL << (strm->bits_per_sample - 1));
704         state->xmax = (1ULL << (strm->bits_per_sample - 1)) - 1;
705     } else {
706         state->xmin = 0;
707         state->xmax = (1ULL << strm->bits_per_sample) - 1;
708     }
709
710     state->in_blklen = (strm->block_size * strm->bits_per_sample
711                         + state->id_len) / 8 + 9;
712
713     modi = 1UL << state->id_len;
714     state->id_table = malloc(modi * sizeof(int (*)(struct aec_stream *)));
715     if (state->id_table == NULL)
716         return AEC_MEM_ERROR;
717
718     state->id_table[0] = m_low_entropy;
719     for (i = 1; i < modi - 1; i++) {
720         state->id_table[i] = m_split;
721     }
722     state->id_table[modi - 1] = m_uncomp;
723
724     state->rsi_size = strm->rsi * strm->block_size;
725     state->rsi_buffer = malloc(state->rsi_size * sizeof(uint32_t));
726     if (state->rsi_buffer == NULL)
727         return AEC_MEM_ERROR;
728
729     strm->total_in = 0;
730     strm->total_out = 0;
731
732     state->rsip = state->rsi_buffer;
733     state->flush_start = state->rsi_buffer;
734     state->bitp = 0;
735     state->fs = 0;
736     state->pp = strm->flags & AEC_DATA_PREPROCESS;
737     state->mode = m_id;
738     return AEC_OK;
739 }
740
741 int aec_decode(struct aec_stream *strm, int flush)
742 {
743     /**
744        Finite-state machine implementation of the adaptive entropy
745        decoder.
746
747        Can work with one byte input und one sample output buffers. If
748        enough buffer space is available, then faster implementations
749        of the states are called. Inspired by zlib.
750     */
751
752     struct internal_state *state = strm->state;
753     int status;
754
755     strm->total_in += strm->avail_in;
756     strm->total_out += strm->avail_out;
757
758     do {
759         status = state->mode(strm);
760     } while (status == M_CONTINUE);
761
762     if (status == M_ERROR)
763         return AEC_DATA_ERROR;
764
765     state->flush_output(strm);
766
767     strm->total_in -= strm->avail_in;
768     strm->total_out -= strm->avail_out;
769
770     return AEC_OK;
771 }
772
773 int aec_decode_end(struct aec_stream *strm)
774 {
775     struct internal_state *state = strm->state;
776
777     free(state->id_table);
778     free(state->rsi_buffer);
779     free(state);
780     return AEC_OK;
781 }
782
783 int aec_buffer_decode(struct aec_stream *strm)
784 {
785     int status;
786
787     status = aec_decode_init(strm);
788     if (status != AEC_OK)
789         return status;
790
791     status = aec_decode(strm, AEC_FLUSH);
792     aec_decode_end(strm);
793     return status;
794 }