3 * @author Mathis Rosenhauer, Deutsches Klimarechenzentrum
6 * Adaptive Entropy Encoder
7 * Based on CCSDS documents 121.0-B-1 and 120.0-G-2
19 #include "aee_mutators.h"
21 /* Marker for Remainder Of Segment condition in zero block encoding */
24 #define MIN(a, b) (((a) < (b))? (a): (b))
26 static int m_get_block(ae_streamp strm);
27 static int m_get_block_cautious(ae_streamp strm);
28 static int m_check_zero_block(ae_streamp strm);
29 static int m_select_code_option(ae_streamp strm);
30 static int m_flush_block(ae_streamp strm);
31 static int m_flush_block_cautious(ae_streamp strm);
32 static int m_encode_splitting(ae_streamp strm);
33 static int m_encode_uncomp(ae_streamp strm);
34 static int m_encode_se(ae_streamp strm);
35 static int m_encode_zero(ae_streamp strm);
43 static inline void emit(encode_state *state, uint64_t data, int bits)
45 if (bits <= state->bitp)
48 *state->out_bp += data << state->bitp;
53 *state->out_bp++ += data >> bits;
58 *state->out_bp++ = data >> bits;
61 state->bitp = 8 - bits;
62 *state->out_bp = data << state->bitp;
66 static inline void emitfs(encode_state *state, int fs)
69 Emits a fundamental sequence.
71 fs zero bits followed by one 1 bit.
78 state->bitp -= fs + 1;
79 *state->out_bp += 1 << state->bitp;
91 static inline void emitblock(ae_streamp strm, int k, int skip)
95 encode_state *state = strm->state;
96 int64_t *in = state->in_block + skip;
97 int64_t *in_end = state->in_block + strm->block_size;
98 int64_t mask = (1ULL << k) - 1;
99 uint8_t *out = state->out_bp;
106 state->bitp = (state->bitp % 8) + 56;
108 while (state->bitp > k && in < in_end)
111 acc += (*in++ & mask) << state->bitp;
114 for (i = 56; i > (state->bitp & ~7); i -= 8)
124 static inline void preprocess(ae_streamp strm)
127 int64_t theta, d, Delta;
128 encode_state *state = strm->state;
130 /* Insert reference samples into first block of Reference Sample
133 if(state->in_total_blocks % strm->rsi == 0)
136 state->last_in = state->in_block[0];
143 for (i = state->ref; i < strm->block_size; i++)
145 theta = MIN(state->last_in - state->xmin,
146 state->xmax - state->last_in);
147 Delta = state->in_block[i] - state->last_in;
148 state->last_in = state->in_block[i];
149 if (0 <= Delta && Delta <= theta)
151 state->in_block[i] = 2 * Delta;
153 else if (-theta <= Delta && Delta < 0)
155 d = Delta < 0 ? -(uint64_t)Delta : Delta;
156 state->in_block[i] = 2 * d - 1;
160 state->in_block[i] = theta +
161 (Delta < 0 ? -(uint64_t)Delta : Delta);
172 static int m_get_block(ae_streamp strm)
174 encode_state *state = strm->state;
176 if (strm->avail_out > state->out_blklen)
178 if (!state->out_direct)
180 state->out_direct = 1;
181 *strm->next_out = *state->out_bp;
182 state->out_bp = strm->next_out;
187 if (state->zero_blocks == 0 || state->out_direct)
189 /* copy leftover from last block */
190 *state->out_block = *state->out_bp;
191 state->out_bp = state->out_block;
193 state->out_direct = 0;
196 if(state->block_deferred)
198 state->block_deferred = 0;
199 state->mode = m_select_code_option;
203 if (strm->avail_in >= state->in_blklen)
205 state->get_block(strm);
207 if (strm->flags & AE_DATA_PREPROCESS)
210 state->in_total_blocks++;
211 return m_check_zero_block(strm);
216 state->mode = m_get_block_cautious;
221 static int m_get_block_cautious(ae_streamp strm)
224 encode_state *state = strm->state;
228 if (strm->avail_in == 0)
230 if (state->flush == AE_FLUSH)
234 /* Pad block with last sample if we have a partial
237 state->in_block[state->i] = state->in_block[state->i - 1];
241 if (state->zero_blocks)
243 /* Output any remaining zero blocks */
244 state->mode = m_encode_zero;
248 if ((strm->flags & AE_DATA_SZ_COMPAT)
249 && (state->in_total_blocks % strm->rsi != 0))
251 /* If user wants szip copatibility then we
252 * have to pad until but not including the
253 * next reference sample.
255 pad = 64 - (state->in_total_blocks % strm->rsi % 64);
256 state->in_total_blocks += pad;
257 state->zero_blocks = (pad > 4)? ROS: pad;
258 state->mode = m_encode_zero;
262 /* Pad last output byte with 0 bits if user wants
263 * to flush, i.e. we got all input there is.
265 emit(state, 0, state->bitp);
266 if (state->out_direct == 0)
267 *strm->next_out++ = *state->out_bp;
281 state->in_block[state->i] = state->get_sample(strm);
284 while (++state->i < strm->block_size);
286 if (strm->flags & AE_DATA_PREPROCESS)
289 state->in_total_blocks++;
290 return m_check_zero_block(strm);
293 static inline int m_check_zero_block(ae_streamp strm)
296 encode_state *state = strm->state;
299 while(i < strm->block_size && state->in_block[i] == 0)
302 if (i == strm->block_size)
304 /* remember ref on first zero block */
305 if (state->zero_blocks == 0)
307 state->zero_ref = state->ref;
308 state->zero_ref_sample = state->in_block[0];
311 state->zero_blocks++;
313 if (state->in_total_blocks % strm->rsi % 64 == 0)
315 if (state->zero_blocks > 4)
316 state->zero_blocks = ROS;
317 state->mode = m_encode_zero;
320 state->mode = m_get_block;
323 else if (state->zero_blocks)
325 /* The current block isn't zero but we have to emit a previous
326 * zero block first. The current block will be handled
329 state->block_deferred = 1;
330 state->mode = m_encode_zero;
333 state->mode = m_select_code_option;
337 static inline int m_select_code_option(ae_streamp strm)
339 int i, k, this_bs, looked_bothways, direction;
340 int64_t d, split_len, uncomp_len;
341 int64_t split_len_min, se_len, fs_len;
342 encode_state *state = strm->state;
344 /* Length of this block minus reference sample (if present) */
345 this_bs = strm->block_size - state->ref;
347 split_len_min = INT64_MAX;
352 /* Starting with splitting position of last block look left and
353 * possibly right to find new minimum.
357 fs_len = (state->in_block[1] >> i)
358 + (state->in_block[2] >> i)
359 + (state->in_block[3] >> i)
360 + (state->in_block[4] >> i)
361 + (state->in_block[5] >> i)
362 + (state->in_block[6] >> i)
363 + (state->in_block[7] >> i);
366 fs_len += (state->in_block[0] >> i);
368 if (strm->block_size == 16)
369 fs_len += (state->in_block[8] >> i)
370 + (state->in_block[9] >> i)
371 + (state->in_block[10] >> i)
372 + (state->in_block[11] >> i)
373 + (state->in_block[12] >> i)
374 + (state->in_block[13] >> i)
375 + (state->in_block[14] >> i)
376 + (state->in_block[15] >> i);
378 split_len = fs_len + this_bs * (i + 1);
380 if (split_len < split_len_min)
382 if (split_len_min < INT64_MAX)
384 /* We are moving towards the minimum so it cant be in
385 * the other direction.
389 split_len_min = split_len;
394 if (fs_len < this_bs)
396 /* Next can't get better because what we lose by
397 * additional uncompressed bits isn't compensated
398 * by a smaller FS part. Vice versa if we are
399 * coming from the other direction.
407 direction = -direction;
414 while (fs_len > 5 * this_bs)
421 else if (fs_len > this_bs)
423 /* Since we started looking the other way there is no
431 /* Stop looking for better option if we don't see any
440 direction = -direction;
445 if (i + direction < 0
446 || i + direction >= strm->bit_per_sample - 2)
451 direction = -direction;
460 /* Count bits for 2nd extension */
462 for (i = 0; i < strm->block_size; i+= 2)
464 d = state->in_block[i] + state->in_block[i + 1];
465 /* we have to worry about overflow here */
466 if (d > split_len_min)
473 se_len += d * (d + 1) / 2 + state->in_block[i + 1];
477 /* Length of uncompressed block */
478 uncomp_len = this_bs * strm->bit_per_sample;
480 /* Decide which option to use */
481 if (split_len_min < uncomp_len)
483 if (split_len_min <= se_len)
485 /* Splitting won - the most common case. */
486 return m_encode_splitting(strm);
490 return m_encode_se(strm);
495 if (uncomp_len <= se_len)
497 return m_encode_uncomp(strm);
501 return m_encode_se(strm);
506 static inline int m_encode_splitting(ae_streamp strm)
509 encode_state *state = strm->state;
512 emit(state, k + 1, state->id_len);
514 emit(state, state->in_block[0], strm->bit_per_sample);
516 for (i = state->ref; i < strm->block_size; i++)
517 emitfs(state, state->in_block[i] >> k);
520 emitblock(strm, k, state->ref);
522 return m_flush_block(strm);
525 static inline int m_encode_uncomp(ae_streamp strm)
527 encode_state *state = strm->state;
529 emit(state, (1 << state->id_len) - 1, state->id_len);
530 emitblock(strm, strm->bit_per_sample, 0);
532 return m_flush_block(strm);
535 static inline int m_encode_se(ae_streamp strm)
539 encode_state *state = strm->state;
541 emit(state, 1, state->id_len + 1);
543 emit(state, state->in_block[0], strm->bit_per_sample);
545 for (i = 0; i < strm->block_size; i+= 2)
547 d = state->in_block[i] + state->in_block[i + 1];
548 emitfs(state, d * (d + 1) / 2 + state->in_block[i + 1]);
551 return m_flush_block(strm);
554 static inline int m_encode_zero(ae_streamp strm)
556 encode_state *state = strm->state;
558 emit(state, 0, state->id_len + 1);
561 emit(state, state->zero_ref_sample, strm->bit_per_sample);
563 if (state->zero_blocks == ROS)
565 else if (state->zero_blocks >= 5)
566 emitfs(state, state->zero_blocks);
568 emitfs(state, state->zero_blocks - 1);
570 state->zero_blocks = 0;
571 return m_flush_block(strm);
574 static inline int m_flush_block(ae_streamp strm)
577 encode_state *state = strm->state;
579 if (state->out_direct)
581 n = state->out_bp - strm->next_out;
583 strm->avail_out -= n;
584 strm->total_out += n;
585 state->mode = m_get_block;
590 state->mode = m_flush_block_cautious;
594 static inline int m_flush_block_cautious(ae_streamp strm)
596 encode_state *state = strm->state;
598 /* Slow restartable flushing */
599 while(state->out_block + state->i < state->out_bp)
601 if (strm->avail_out == 0)
604 *strm->next_out++ = state->out_block[state->i];
609 state->mode = m_get_block;
619 int ae_encode_init(ae_streamp strm)
623 /* Some sanity checks */
624 if (strm->bit_per_sample > 32 || strm->bit_per_sample == 0)
629 /* Internal state for encoder */
630 state = (encode_state *) malloc(sizeof(encode_state));
635 memset(state, 0, sizeof(encode_state));
638 if (strm->bit_per_sample > 16)
640 /* 32 bit settings */
642 state->in_blklen = 4 * strm->block_size;
644 if (strm->flags & AE_DATA_MSB)
645 state->get_sample = get_msb_32;
647 state->get_sample = get_lsb_32;
649 else if (strm->bit_per_sample > 8)
651 /* 16 bit settings */
653 state->in_blklen = 2 * strm->block_size;
655 if (strm->flags & AE_DATA_MSB)
657 state->get_sample = get_msb_16;
659 if (strm->block_size == 8)
660 state->get_block = get_block_msb_16_bs_8;
662 state->get_block = get_block_msb_16_bs_16;
665 state->get_sample = get_lsb_16;
670 state->in_blklen = strm->block_size;
673 state->get_sample = get_8;
675 if (strm->block_size == 8)
676 state->get_block = get_block_8_bs_8;
678 state->get_block = get_block_8_bs_16;
681 if (strm->flags & AE_DATA_SIGNED)
683 state->xmin = -(1ULL << (strm->bit_per_sample - 1));
684 state->xmax = (1ULL << (strm->bit_per_sample - 1)) - 1;
689 state->xmax = (1ULL << strm->bit_per_sample) - 1;
692 state->in_block = (int64_t *)malloc(strm->block_size * sizeof(int64_t));
693 if (state->in_block == NULL)
698 /* Largest possible block according to specs */
699 state->out_blklen = (5 + 16 * 32) / 8 + 3;
700 state->out_block = (uint8_t *)malloc(state->out_blklen);
701 if (state->out_block == NULL)
709 state->out_bp = state->out_block;
712 state->mode = m_get_block;
717 int ae_encode(ae_streamp strm, int flush)
720 Finite-state machine implementation of the adaptive entropy
726 state->flush = flush;
728 while (state->mode(strm) == M_CONTINUE);
730 if (state->out_direct)
733 *state->out_block = *state->out_bp;
734 state->out_bp = state->out_block;
735 state->out_direct = 0;
740 int ae_encode_end(ae_streamp strm)
742 encode_state *state = strm->state;
744 free(state->in_block);
745 free(state->out_block);