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