clean up
[platform/upstream/libaec.git] / src / encode.c
1 /**
2  * @file encode.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
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 Encoder
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 <stdlib.h>
62 #include <unistd.h>
63 #include <string.h>
64
65 #include "libaec.h"
66 #include "encode.h"
67 #include "encode_accessors.h"
68
69 /* Marker for Remainder Of Segment condition in zero block encoding */
70 #define ROS -1
71
72 static int m_get_block(struct aec_stream *strm);
73
74 static inline void emit(struct internal_state *state,
75                         uint32_t data, int bits)
76 {
77     /**
78        Emit sequence of bits.
79      */
80
81     if (bits <= state->bits) {
82         state->bits -= bits;
83         *state->cds += data << state->bits;
84     } else {
85         bits -= state->bits;
86         *state->cds++ += (uint64_t)data >> bits;
87
88         while (bits & ~7) {
89             bits -= 8;
90             *state->cds++ = data >> bits;
91         }
92
93         state->bits = 8 - bits;
94         *state->cds = data << state->bits;
95     }
96 }
97
98 static inline void emitfs(struct internal_state *state, int fs)
99 {
100     /**
101        Emits a fundamental sequence.
102
103        fs zero bits followed by one 1 bit.
104      */
105
106     for(;;) {
107         if (fs < state->bits) {
108             state->bits -= fs + 1;
109             *state->cds += 1U << state->bits;
110             break;
111         } else {
112             fs -= state->bits;
113             *++state->cds = 0;
114             state->bits = 8;
115         }
116     }
117 }
118
119 static inline void copy64(uint8_t *dst, uint64_t src)
120 {
121     dst[0] = src >> 56;
122     dst[1] = src >> 48;
123     dst[2] = src >> 40;
124     dst[3] = src >> 32;
125     dst[4] = src >> 24;
126     dst[5] = src >> 16;
127     dst[6] = src >> 8;
128     dst[7] = src;
129 }
130
131 #define EMITBLOCK_FS(ref)                                           \
132     static inline void emitblock_fs_##ref(struct aec_stream *strm,  \
133                                           int k)                    \
134     {                                                               \
135         int i;                                                      \
136         int used; /* used bits in 64 bit accumulator */             \
137         uint64_t acc; /* accumulator */                             \
138         struct internal_state *state = strm->state;                 \
139                                                                     \
140         acc = (uint64_t)*state->cds << 56;                          \
141         used = 7 - state->bits;                                     \
142                                                                     \
143         for (i = ref; i < strm->block_size; i++) {                  \
144             used += (state->block[i] >> k) + 1;                     \
145             if (used > 63) {                                        \
146                 copy64(state->cds, acc);                            \
147                 state->cds += 8;                                    \
148                 acc = 0;                                            \
149                 used &= 0x3f;                                       \
150             }                                                       \
151             acc |= 1ULL << (63 - used);                             \
152         }                                                           \
153                                                                     \
154         copy64(state->cds, acc);                                    \
155         state->cds += used >> 3;                                    \
156         state->bits = 7 - (used & 7);                               \
157     }
158
159 EMITBLOCK_FS(0);
160 EMITBLOCK_FS(1);
161
162 #define EMITBLOCK(ref)                                              \
163     static inline void emitblock_##ref(struct aec_stream *strm,     \
164                                        int k)                       \
165     {                                                               \
166         /**                                                         \
167            Emit the k LSB of a whole block of input data.           \
168         */                                                          \
169                                                                     \
170         int b;                                                      \
171         uint64_t a;                                                 \
172         struct internal_state *state = strm->state;                 \
173         uint32_t *in = state->block + ref;                          \
174         uint32_t *in_end = state->block + strm->block_size;         \
175         uint64_t mask = (1ULL << k) - 1;                            \
176         uint8_t *o = state->cds;                                    \
177         int p = state->bits;                                        \
178                                                                     \
179         a = *o;                                                     \
180                                                                     \
181         while(in < in_end) {                                        \
182             a <<= 56;                                               \
183             p = (p % 8) + 56;                                       \
184                                                                     \
185             while (p > k && in < in_end) {                          \
186                 p -= k;                                             \
187                 a += ((uint64_t)(*in++) & mask) << p;               \
188             }                                                       \
189                                                                     \
190             for (b = 56; b > (p & ~7); b -= 8)                      \
191                 *o++ = a >> b;                                      \
192             a >>= b;                                                \
193         }                                                           \
194                                                                     \
195         *o = a;                                                     \
196         state->cds = o;                                             \
197         state->bits = p % 8;                                        \
198     }
199
200 EMITBLOCK(0);
201 EMITBLOCK(1);
202
203 static void preprocess_unsigned(struct aec_stream *strm)
204 {
205     /**
206        Preprocess RSI of unsigned samples.
207
208        Combining preprocessing and converting to uint32_t in one loop
209        is slower due to the data dependance on x_i-1.
210     */
211
212     uint32_t D;
213     struct internal_state *state = strm->state;
214     const uint32_t *x = state->data_raw;
215     uint32_t *d = state->data_pp;
216     uint32_t xmax = state->xmax;
217     uint32_t rsi = strm->rsi * strm->block_size - 1;
218
219     *d++ = x[0];
220     while (rsi--) {
221         if (x[1] >= x[0]) {
222             D = x[1] - x[0];
223             if (D <= x[0])
224                 *d = 2 * D;
225             else
226                 *d = x[1];
227         } else {
228             D = x[0] - x[1];
229             if (D <= xmax - x[0])
230                 *d = 2 * D - 1;
231             else
232                 *d = xmax - x[1];
233         }
234         d++;
235         x++;
236     }
237     state->ref = 1;
238 }
239
240 static void preprocess_signed(struct aec_stream *strm)
241 {
242     /**
243        Preprocess RSI of signed samples.
244     */
245
246     int64_t D;
247     struct internal_state *state = strm->state;
248     uint32_t *d = state->data_pp;
249     int32_t *x = (int32_t *)state->data_raw;
250     uint64_t m = 1ULL << (strm->bits_per_sample - 1);
251     int64_t xmax = state->xmax;
252     int64_t xmin = state->xmin;
253     uint32_t rsi = strm->rsi * strm->block_size - 1;
254
255     *d++ = (uint32_t)x[0];
256     x[0] = (x[0] ^ m) - m;
257
258     while (rsi--) {
259         x[1] = (x[1] ^ m) - m;
260         if (x[1] < x[0]) {
261             D = (int64_t)x[0] - x[1];
262             if (D <= xmax - x[0])
263                 *d = 2 * D - 1;
264             else
265                 *d = xmax - x[1];
266         } else {
267             D = (int64_t)x[1] - x[0];
268             if (D <= x[0] - xmin)
269                 *d = 2 * D;
270             else
271                 *d = x[1] - xmin;
272         }
273         x++;
274         d++;
275     }
276     state->ref = 1;
277 }
278
279 static uint64_t block_fs(struct aec_stream *strm, int k)
280 {
281     /**
282        Sum FS of all samples in block for given splitting position.
283     */
284
285     int j;
286     uint64_t fs;
287     struct internal_state *state = strm->state;
288
289     fs = (uint64_t)(state->block[1] >> k)
290         + (uint64_t)(state->block[2] >> k)
291         + (uint64_t)(state->block[3] >> k)
292         + (uint64_t)(state->block[4] >> k)
293         + (uint64_t)(state->block[5] >> k)
294         + (uint64_t)(state->block[6] >> k)
295         + (uint64_t)(state->block[7] >> k);
296
297     if (strm->block_size > 8)
298         for (j = 8; j < strm->block_size; j += 8)
299             fs +=
300                 (uint64_t)(state->block[j + 0] >> k)
301                 + (uint64_t)(state->block[j + 1] >> k)
302                 + (uint64_t)(state->block[j + 2] >> k)
303                 + (uint64_t)(state->block[j + 3] >> k)
304                 + (uint64_t)(state->block[j + 4] >> k)
305                 + (uint64_t)(state->block[j + 5] >> k)
306                 + (uint64_t)(state->block[j + 6] >> k)
307                 + (uint64_t)(state->block[j + 7] >> k);
308
309     if (!state->ref)
310         fs += (uint64_t)(state->block[0] >> k);
311
312     return fs;
313 }
314
315 static int assess_splitting_option(struct aec_stream *strm)
316 {
317     /**
318        Length of CDS encoded with splitting option and optimal k.
319
320        In Rice coding each sample in a block of samples is split at
321        the same position into k LSB and bits_per_sample - k MSB. The
322        LSB part is left binary and the MSB part is coded as a
323        fundamental sequence a.k.a. unary (see CCSDS 121.0-B-2). The
324        function of the length of the Coded Data Set (CDS) depending on
325        k has exactly one minimum (see A. Kiely, IPN Progress Report
326        42-159).
327
328        To find that minimum with only a few costly evaluations of the
329        CDS length, we start with the k of the previous CDS. K is
330        increased and the CDS length evaluated. If the CDS length gets
331        smaller, then we are moving towards the minimum. If the length
332        increases, then the minimum will be found with smaller k.
333
334        For increasing k we know that we will gain block_size bits in
335        length through the larger binary part. If the FS lenth is less
336        than the block size then a reduced FS part can't compensate the
337        larger binary part. So we know that the CDS for k+1 will be
338        larger than for k without actually computing the length. An
339        analogue check can be done for decreasing k.
340      */
341
342     int k;
343     int k_min;
344     int this_bs; /* Block size of current block */
345     int no_turn; /* 1 if we shouldn't reverse */
346     int dir; /* Direction, 1 means increasing k, 0 decreasing k */
347     uint64_t len; /* CDS length for current k */
348     uint64_t len_min; /* CDS length minimum so far */
349     uint64_t fs_len; /* Length of FS part (not including 1s) */
350
351     struct internal_state *state = strm->state;
352
353     this_bs = strm->block_size - state->ref;
354     len_min = UINT64_MAX;
355     k = k_min = state->k;
356     no_turn = (k == 0) ? 1 : 0;
357     dir = 1;
358
359     for (;;) {
360         fs_len = block_fs(strm, k);
361         len = fs_len + this_bs * (k + 1);
362
363         if (len < len_min) {
364             if (len_min < UINT64_MAX)
365                 no_turn = 1;
366
367             len_min = len;
368             k_min = k;
369
370             if (dir) {
371                 if (fs_len < this_bs || k >= state->kmax) {
372                     if (no_turn)
373                         break;
374                     k = state->k - 1;
375                     dir = 0;
376                     no_turn = 1;
377                 } else {
378                     k++;
379                 }
380             } else {
381                 if (fs_len >= this_bs || k == 0)
382                     break;
383                 k--;
384             }
385         } else {
386             if (no_turn)
387                 break;
388             k = state->k - 1;
389             dir = 0;
390             no_turn = 1;
391         }
392     }
393     state->k = k_min;
394
395     return len_min;
396 }
397
398 static int assess_se_option(uint64_t limit, struct aec_stream *strm)
399 {
400     /**
401        Length of CDS encoded with Second Extension option.
402
403        If length is above limit just return UINT64_MAX.
404     */
405
406     int i;
407     uint64_t d;
408     uint64_t len;
409     struct internal_state *state = strm->state;
410
411     len = 1;
412
413     for (i = 0; i < strm->block_size; i+= 2) {
414         d = (uint64_t)state->block[i]
415             + (uint64_t)state->block[i + 1];
416         /* we have to worry about overflow here */
417         if (d > limit) {
418             len = UINT64_MAX;
419             break;
420         } else {
421             len += d * (d + 1) / 2
422                 + (uint64_t)state->block[i + 1];
423         }
424     }
425     return len;
426 }
427
428 /*
429  *
430  * FSM functions
431  *
432  */
433
434 static int m_flush_block_resumable(struct aec_stream *strm)
435 {
436     /**
437        Slow and restartable flushing
438     */
439     struct internal_state *state = strm->state;
440
441     while(state->cds_buf + state->i < state->cds) {
442         if (strm->avail_out == 0)
443             return M_EXIT;
444
445         *strm->next_out++ = state->cds_buf[state->i];
446         strm->avail_out--;
447         strm->total_out++;
448         state->i++;
449     }
450     state->mode = m_get_block;
451     return M_CONTINUE;
452 }
453
454 static int m_flush_block(struct aec_stream *strm)
455 {
456     /**
457        Flush block in direct_out mode by updating counters.
458
459        Fall back to slow flushing if in buffered mode.
460     */
461     int n;
462     struct internal_state *state = strm->state;
463
464     if (state->direct_out) {
465         n = state->cds - strm->next_out;
466         strm->next_out += n;
467         strm->avail_out -= n;
468         strm->total_out += n;
469         state->mode = m_get_block;
470         return M_CONTINUE;
471     }
472
473     state->i = 0;
474     state->mode = m_flush_block_resumable;
475     return M_CONTINUE;
476 }
477
478 static int m_encode_splitting(struct aec_stream *strm)
479 {
480     struct internal_state *state = strm->state;
481     int k = state->k;
482
483     emit(state, k + 1, state->id_len);
484
485     if (state->ref)
486     {
487         emit(state, state->block[0], strm->bits_per_sample);
488         emitblock_fs_1(strm, k);
489         if (k)
490             emitblock_1(strm, k);
491     }
492     else
493     {
494         emitblock_fs_0(strm, k);
495         if (k)
496             emitblock_0(strm, k);
497     }
498
499     return m_flush_block(strm);
500 }
501
502 static int m_encode_uncomp(struct aec_stream *strm)
503 {
504     struct internal_state *state = strm->state;
505
506     emit(state, (1U << state->id_len) - 1, state->id_len);
507     emitblock_0(strm, strm->bits_per_sample);
508
509     return m_flush_block(strm);
510 }
511
512 static int m_encode_se(struct aec_stream *strm)
513 {
514     int i;
515     uint32_t d;
516     struct internal_state *state = strm->state;
517
518     emit(state, 1, state->id_len + 1);
519     if (state->ref)
520         emit(state, state->block[0], strm->bits_per_sample);
521
522     for (i = 0; i < strm->block_size; i+= 2) {
523         d = state->block[i] + state->block[i + 1];
524         emitfs(state, d * (d + 1) / 2 + state->block[i + 1]);
525     }
526
527     return m_flush_block(strm);
528 }
529
530 static int m_encode_zero(struct aec_stream *strm)
531 {
532     struct internal_state *state = strm->state;
533
534     emit(state, 0, state->id_len + 1);
535
536     if (state->zero_ref)
537         emit(state, state->zero_ref_sample, strm->bits_per_sample);
538
539     if (state->zero_blocks == ROS)
540         emitfs(state, 4);
541     else if (state->zero_blocks >= 5)
542         emitfs(state, state->zero_blocks);
543     else
544         emitfs(state, state->zero_blocks - 1);
545
546     state->zero_blocks = 0;
547     return m_flush_block(strm);
548 }
549
550 static int m_select_code_option(struct aec_stream *strm)
551 {
552     /**
553        Decide which code option to use.
554     */
555
556     uint64_t uncomp_len;
557     uint64_t split_len;
558     uint64_t se_len;
559     struct internal_state *state = strm->state;
560
561     uncomp_len = (strm->block_size - state->ref)
562         * strm->bits_per_sample;
563     split_len = assess_splitting_option(strm);
564     se_len = assess_se_option(split_len, strm);
565
566     if (split_len < uncomp_len) {
567         if (split_len < se_len)
568             return m_encode_splitting(strm);
569         else
570             return m_encode_se(strm);
571     } else {
572         if (uncomp_len <= se_len)
573             return m_encode_uncomp(strm);
574         else
575             return m_encode_se(strm);
576     }
577 }
578
579 static int m_check_zero_block(struct aec_stream *strm)
580 {
581     /**
582        Check if input block is all zero.
583
584        Aggregate consecutive zero blocks until we find !0 or reach the
585        end of a segment or RSI.
586     */
587
588     struct internal_state *state = strm->state;
589     uint32_t *p = state->block + state->ref;
590     uint32_t *end = state->block + strm->block_size;
591
592     while(p < end && *p == 0)
593         p++;
594
595     if (p < end) {
596         if (state->zero_blocks) {
597             /* The current block isn't zero but we have to emit a
598              * previous zero block first. The current block will be
599              * handled later.
600              */
601             state->block -= strm->block_size;
602             state->blocks_avail++;
603             state->mode = m_encode_zero;
604             return M_CONTINUE;
605         }
606         state->mode = m_select_code_option;
607         return M_CONTINUE;
608     } else {
609         state->zero_blocks++;
610         if (state->zero_blocks == 1) {
611             state->zero_ref = state->ref;
612             state->zero_ref_sample = state->block[0];
613         }
614         if (state->blocks_avail == 0
615             || (strm->rsi - state->blocks_avail) % 64 == 0) {
616             if (state->zero_blocks > 4)
617                 state->zero_blocks = ROS;
618             state->mode = m_encode_zero;
619             return M_CONTINUE;
620         }
621         state->mode = m_get_block;
622         return M_CONTINUE;
623     }
624 }
625
626 static int m_get_rsi_resumable(struct aec_stream *strm)
627 {
628     /**
629        Get RSI while input buffer is short.
630
631        Let user provide more input. Once we got all input pad buffer
632        to full RSI.
633     */
634
635     int j;
636     struct internal_state *state = strm->state;
637
638     do {
639         if (strm->avail_in > 0) {
640             state->data_raw[state->i] = state->get_sample(strm);
641         } else {
642             if (state->flush == AEC_FLUSH) {
643                 if (state->i > 0) {
644                     for (j = state->i; j < strm->rsi * strm->block_size; j++)
645                         state->data_raw[j] = state->data_raw[state->i - 1];
646                     state->i = strm->rsi * strm->block_size;
647                 } else {
648                     if (state->zero_blocks) {
649                         state->mode = m_encode_zero;
650                         return M_CONTINUE;
651                     }
652
653                     emit(state, 0, state->bits);
654                     if (strm->avail_out > 0) {
655                         if (!state->direct_out)
656                             *strm->next_out++ = *state->cds;
657                         strm->avail_out--;
658                         strm->total_out++;
659                     }
660                     return M_EXIT;
661                 }
662             } else {
663                 return M_EXIT;
664             }
665         }
666     } while (++state->i < strm->rsi * strm->block_size);
667
668     if (strm->flags & AEC_DATA_PREPROCESS)
669         state->preprocess(strm);
670
671     return m_check_zero_block(strm);
672 }
673
674 static int m_get_block(struct aec_stream *strm)
675 {
676     /**
677        Provide the next block of preprocessed input data.
678
679        Pull in a whole Reference Sample Interval (RSI) of data if
680        block buffer is empty.
681     */
682
683     struct internal_state *state = strm->state;
684
685     if (strm->avail_out > state->cds_len) {
686         if (!state->direct_out) {
687             state->direct_out = 1;
688             *strm->next_out = *state->cds;
689             state->cds = strm->next_out;
690         }
691     } else {
692         if (state->zero_blocks == 0 || state->direct_out) {
693             /* copy leftover from last block */
694             *state->cds_buf = *state->cds;
695             state->cds = state->cds_buf;
696         }
697         state->direct_out = 0;
698     }
699
700     if (state->blocks_avail == 0) {
701         state->blocks_avail = strm->rsi - 1;
702         state->block = state->data_pp;
703
704         if (strm->avail_in >= state->rsi_len) {
705             state->get_rsi(strm);
706             if (strm->flags & AEC_DATA_PREPROCESS)
707                 state->preprocess(strm);
708
709             return m_check_zero_block(strm);
710         } else {
711             state->i = 0;
712             state->mode = m_get_rsi_resumable;
713         }
714     } else {
715         state->ref = 0;
716         state->block += strm->block_size;
717         state->blocks_avail--;
718         return m_check_zero_block(strm);
719     }
720     return M_CONTINUE;
721 }
722
723 /*
724  *
725  * API functions
726  *
727  */
728
729 int aec_encode_init(struct aec_stream *strm)
730 {
731     struct internal_state *state;
732
733     if (strm->bits_per_sample > 32 || strm->bits_per_sample == 0)
734         return AEC_CONF_ERROR;
735
736     if (strm->block_size != 8
737         && strm->block_size != 16
738         && strm->block_size != 32
739         && strm->block_size != 64)
740         return AEC_CONF_ERROR;
741
742     if (strm->rsi > 4096)
743         return AEC_CONF_ERROR;
744
745     state = malloc(sizeof(struct internal_state));
746     if (state == NULL)
747         return AEC_MEM_ERROR;
748
749     memset(state, 0, sizeof(struct internal_state));
750     strm->state = state;
751
752     if (strm->bits_per_sample > 16) {
753         /* 24/32 input bit settings */
754         state->id_len = 5;
755
756         if (strm->bits_per_sample <= 24
757             && strm->flags & AEC_DATA_3BYTE) {
758             state->rsi_len = 3;
759             if (strm->flags & AEC_DATA_MSB) {
760                 state->get_sample = aec_get_msb_24;
761                 state->get_rsi = aec_get_rsi_msb_24;
762             } else {
763                 state->get_sample = aec_get_lsb_24;
764                 state->get_rsi = aec_get_rsi_lsb_24;
765             }
766         } else {
767             state->rsi_len = 4;
768             if (strm->flags & AEC_DATA_MSB) {
769                 state->get_sample = aec_get_msb_32;
770                 state->get_rsi = aec_get_rsi_msb_32;
771             } else {
772                 state->get_sample = aec_get_lsb_32;
773                 state->get_rsi = aec_get_rsi_lsb_32;
774             }
775         }
776     }
777     else if (strm->bits_per_sample > 8) {
778         /* 16 bit settings */
779         state->id_len = 4;
780         state->rsi_len = 2;
781
782         if (strm->flags & AEC_DATA_MSB) {
783             state->get_sample = aec_get_msb_16;
784             state->get_rsi = aec_get_rsi_msb_16;
785         } else {
786             state->get_sample = aec_get_lsb_16;
787             state->get_rsi = aec_get_rsi_lsb_16;
788         }
789     } else {
790         /* 8 bit settings */
791         state->id_len = 3;
792         state->rsi_len = 1;
793
794         state->get_sample = aec_get_8;
795         state->get_rsi = aec_get_rsi_8;
796     }
797     state->rsi_len *= strm->rsi * strm->block_size;
798
799     if (strm->flags & AEC_DATA_SIGNED) {
800         state->xmin = -(1ULL << (strm->bits_per_sample - 1));
801         state->xmax = (1ULL << (strm->bits_per_sample - 1)) - 1;
802         state->preprocess = preprocess_signed;
803     } else {
804         state->xmin = 0;
805         state->xmax = (1ULL << strm->bits_per_sample) - 1;
806         state->preprocess = preprocess_unsigned;
807     }
808
809     state->kmax = (1U << state->id_len) - 3;
810
811     state->data_pp = malloc(strm->rsi
812                             * strm->block_size
813                             * sizeof(uint32_t));
814     if (state->data_pp == NULL)
815         return AEC_MEM_ERROR;
816
817     if (strm->flags & AEC_DATA_PREPROCESS) {
818         state->data_raw = malloc(strm->rsi
819                                  * strm->block_size
820                                  * sizeof(uint32_t));
821         if (state->data_raw == NULL)
822             return AEC_MEM_ERROR;
823     } else {
824         state->data_raw = state->data_pp;
825     }
826
827     state->block = state->data_pp;
828
829     /* Largest possible CDS according to specs */
830     state->cds_len = (5 + 64 * 32) / 8 + 3;
831     state->cds_buf = malloc(state->cds_len);
832     if (state->cds_buf == NULL)
833         return AEC_MEM_ERROR;
834
835     strm->total_in = 0;
836     strm->total_out = 0;
837
838     state->cds = state->cds_buf;
839     *state->cds = 0;
840     state->bits = 8;
841     state->mode = m_get_block;
842
843     return AEC_OK;
844 }
845
846 int aec_encode(struct aec_stream *strm, int flush)
847 {
848     /**
849        Finite-state machine implementation of the adaptive entropy
850        encoder.
851     */
852     int n;
853     struct internal_state *state = strm->state;
854
855     state->flush = flush;
856
857     while (state->mode(strm) == M_CONTINUE);
858
859     if (state->direct_out) {
860         n = state->cds - strm->next_out;
861         strm->next_out += n;
862         strm->avail_out -= n;
863         strm->total_out += n;
864
865         *state->cds_buf = *state->cds;
866         state->cds = state->cds_buf;
867         state->direct_out = 0;
868     }
869     return AEC_OK;
870 }
871
872 int aec_encode_end(struct aec_stream *strm)
873 {
874     struct internal_state *state = strm->state;
875
876     if (strm->flags & AEC_DATA_PREPROCESS)
877         free(state->data_raw);
878     free(state->data_pp);
879     free(state->cds_buf);
880     free(state);
881     return AEC_OK;
882 }
883
884 int aec_buffer_encode(struct aec_stream *strm)
885 {
886     int status;
887
888     status = aec_encode_init(strm);
889     if (status != AEC_OK)
890         return status;
891     status = aec_encode(strm, AEC_FLUSH);
892     if (strm->avail_in > 0 || strm->avail_out == 0)
893         status = AEC_DATA_ERROR;
894
895     aec_encode_end(strm);
896     return status;
897 }