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)
47 data &= ((1ULL << bits) - 1);
48 if (bits <= state->bitp)
51 *state->out_bp += data << state->bitp;
57 *state->out_bp += data >> bits;
64 static inline void emitfs(encode_state *state, int fs)
67 Emits a fundamental sequence.
69 fs zero bits followed by one 1 bit.
75 if (fs <= state->bitp)
78 *state->out_bp += 1 << state->bitp;
90 static inline void preprocess(ae_streamp strm)
93 int64_t theta, d, Delta;
94 encode_state *state = strm->state;
96 /* Insert reference samples into first block of Reference Sample
99 if(state->in_total_blocks % strm->rsi == 0)
102 state->last_in = state->in_block[0];
109 for (i = state->ref; i < strm->block_size; i++)
111 theta = MIN(state->last_in - state->xmin,
112 state->xmax - state->last_in);
113 Delta = state->in_block[i] - state->last_in;
114 state->last_in = state->in_block[i];
115 if (0 <= Delta && Delta <= theta)
117 state->in_block[i] = 2 * Delta;
119 else if (-theta <= Delta && Delta < 0)
121 d = Delta < 0 ? -(uint64_t)Delta : Delta;
122 state->in_block[i] = 2 * d - 1;
126 state->in_block[i] = theta +
127 (Delta < 0 ? -(uint64_t)Delta : Delta);
138 static int m_get_block(ae_streamp strm)
140 encode_state *state = strm->state;
142 if (strm->avail_out > state->out_blklen)
144 if (!state->out_direct)
146 state->out_direct = 1;
147 *strm->next_out = *state->out_bp;
148 state->out_bp = strm->next_out;
153 if (state->zero_blocks == 0 || state->out_direct)
155 /* copy leftover from last block */
156 *state->out_block = *state->out_bp;
157 state->out_bp = state->out_block;
159 state->out_direct = 0;
162 if(state->block_deferred)
164 state->block_deferred = 0;
165 state->mode = m_select_code_option;
169 if (strm->avail_in >= state->in_blklen)
171 state->get_block(strm);
173 if (strm->flags & AE_DATA_PREPROCESS)
176 state->in_total_blocks++;
177 return m_check_zero_block(strm);
182 state->mode = m_get_block_cautious;
187 static int m_get_block_cautious(ae_streamp strm)
190 encode_state *state = strm->state;
194 if (strm->avail_in == 0)
196 if (state->flush == AE_FLUSH)
200 /* Pad block with last sample if we have a partial
203 state->in_block[state->i] = state->in_block[state->i - 1];
207 if (state->zero_blocks)
209 /* Output any remaining zero blocks */
210 state->mode = m_encode_zero;
214 if ((strm->flags & AE_DATA_SZ_COMPAT)
215 && (state->in_total_blocks % strm->rsi != 0))
217 /* If user wants szip copatibility then we
218 * have to pad until but not including the
219 * next reference sample.
221 pad = 64 - (state->in_total_blocks % strm->rsi % 64);
222 state->in_total_blocks += pad;
223 state->zero_blocks = (pad > 4)? ROS: pad;
224 state->mode = m_encode_zero;
228 /* Pad last output byte with 0 bits if user wants
229 * to flush, i.e. we got all input there is.
231 emit(state, 0, state->bitp);
232 if (state->out_direct == 0)
233 *strm->next_out++ = *state->out_bp;
247 state->in_block[state->i] = state->get_sample(strm);
250 while (++state->i < strm->block_size);
252 if (strm->flags & AE_DATA_PREPROCESS)
255 state->in_total_blocks++;
256 return m_check_zero_block(strm);
259 static inline int m_check_zero_block(ae_streamp strm)
262 encode_state *state = strm->state;
265 while(i < strm->block_size && state->in_block[i] == 0)
268 if (i == strm->block_size)
270 /* remember ref on first zero block */
271 if (state->zero_blocks == 0)
273 state->zero_ref = state->ref;
274 state->zero_ref_sample = state->in_block[0];
277 state->zero_blocks++;
279 if (state->in_total_blocks % strm->rsi % 64 == 0)
281 if (state->zero_blocks > 4)
282 state->zero_blocks = ROS;
283 state->mode = m_encode_zero;
286 state->mode = m_get_block;
289 else if (state->zero_blocks)
291 /* The current block isn't zero but we have to emit a previous
292 * zero block first. The current block will be handled
295 state->block_deferred = 1;
296 state->mode = m_encode_zero;
299 state->mode = m_select_code_option;
303 static inline int m_select_code_option(ae_streamp strm)
305 int i, k, this_bs, looked_bothways, direction;
306 int64_t d, split_len, uncomp_len;
307 int64_t split_len_min, se_len, fs_len;
308 encode_state *state = strm->state;
310 /* Length of this block minus reference sample (if present) */
311 this_bs = strm->block_size - state->ref;
313 split_len_min = INT64_MAX;
318 /* Starting with splitting position of last block look left and
319 * possibly right to find new minimum.
323 fs_len = (state->in_block[1] >> i)
324 + (state->in_block[2] >> i)
325 + (state->in_block[3] >> i)
326 + (state->in_block[4] >> i)
327 + (state->in_block[5] >> i)
328 + (state->in_block[6] >> i)
329 + (state->in_block[7] >> i);
332 fs_len += (state->in_block[0] >> i);
334 if (strm->block_size == 16)
335 fs_len += (state->in_block[8] >> i)
336 + (state->in_block[9] >> i)
337 + (state->in_block[10] >> i)
338 + (state->in_block[11] >> i)
339 + (state->in_block[12] >> i)
340 + (state->in_block[13] >> i)
341 + (state->in_block[14] >> i)
342 + (state->in_block[15] >> i);
344 split_len = fs_len + this_bs * (i + 1);
346 if (split_len < split_len_min)
348 if (split_len_min < INT64_MAX)
350 /* We are moving towards the minimum so it cant be in
351 * the other direction.
355 split_len_min = split_len;
360 if (fs_len < this_bs)
362 /* Next can't get better because what we lose by
363 * additional uncompressed bits isn't compensated
364 * by a smaller FS part. Vice versa if we are
365 * coming from the other direction.
373 direction = -direction;
380 while (fs_len > 5 * this_bs)
387 else if (fs_len > this_bs)
389 /* Since we started looking the other way there is no
397 /* Stop looking for better option if we don't see any
406 direction = -direction;
411 if (i + direction < 0
412 || i + direction >= strm->bit_per_sample - 2)
417 direction = -direction;
426 /* Count bits for 2nd extension */
428 for (i = 0; i < strm->block_size; i+= 2)
430 d = state->in_block[i] + state->in_block[i + 1];
431 /* we have to worry about overflow here */
432 if (d > split_len_min)
439 se_len += d * (d + 1) / 2 + state->in_block[i + 1];
443 /* Length of uncompressed block */
444 uncomp_len = this_bs * strm->bit_per_sample;
446 /* Decide which option to use */
447 if (split_len_min < uncomp_len)
449 if (split_len_min <= se_len)
451 /* Splitting won - the most common case. */
452 return m_encode_splitting(strm);
456 return m_encode_se(strm);
461 if (uncomp_len <= se_len)
463 return m_encode_uncomp(strm);
467 return m_encode_se(strm);
472 static inline int m_encode_splitting(ae_streamp strm)
475 encode_state *state = strm->state;
478 emit(state, k + 1, state->id_len);
480 emit(state, state->in_block[0], strm->bit_per_sample);
482 for (i = state->ref; i < strm->block_size; i++)
483 emitfs(state, state->in_block[i] >> k);
485 for (i = state->ref; i < strm->block_size; i++)
486 emit(state, state->in_block[i], k);
488 return m_flush_block(strm);
491 static inline int m_encode_uncomp(ae_streamp strm)
494 encode_state *state = strm->state;
496 emit(state, 0x1f, state->id_len);
497 for (i = 0; i < strm->block_size; i++)
498 emit(state, state->in_block[i], strm->bit_per_sample);
500 return m_flush_block(strm);
503 static inline int m_encode_se(ae_streamp strm)
507 encode_state *state = strm->state;
509 emit(state, 1, state->id_len + 1);
511 emit(state, state->in_block[0], strm->bit_per_sample);
513 for (i = 0; i < strm->block_size; i+= 2)
515 d = state->in_block[i] + state->in_block[i + 1];
516 emitfs(state, d * (d + 1) / 2 + state->in_block[i + 1]);
519 return m_flush_block(strm);
522 static inline int m_encode_zero(ae_streamp strm)
524 encode_state *state = strm->state;
526 emit(state, 0, state->id_len + 1);
529 emit(state, state->zero_ref_sample, strm->bit_per_sample);
531 if (state->zero_blocks == ROS)
533 else if (state->zero_blocks >= 5)
534 emitfs(state, state->zero_blocks);
536 emitfs(state, state->zero_blocks - 1);
538 state->zero_blocks = 0;
539 return m_flush_block(strm);
542 static inline int m_flush_block(ae_streamp strm)
545 encode_state *state = strm->state;
547 if (state->out_direct)
549 n = state->out_bp - strm->next_out;
551 strm->avail_out -= n;
552 strm->total_out += n;
553 state->mode = m_get_block;
558 state->mode = m_flush_block_cautious;
562 static inline int m_flush_block_cautious(ae_streamp strm)
564 encode_state *state = strm->state;
566 /* Slow restartable flushing */
567 while(state->out_block + state->i < state->out_bp)
569 if (strm->avail_out == 0)
572 *strm->next_out++ = state->out_block[state->i];
577 state->mode = m_get_block;
587 int ae_encode_init(ae_streamp strm)
591 /* Some sanity checks */
592 if (strm->bit_per_sample > 32 || strm->bit_per_sample == 0)
597 /* Internal state for encoder */
598 state = (encode_state *) malloc(sizeof(encode_state));
603 memset(state, 0, sizeof(encode_state));
606 if (strm->bit_per_sample > 16)
608 /* 32 bit settings */
610 state->in_blklen = 4 * strm->block_size;
612 if (strm->flags & AE_DATA_MSB)
613 state->get_sample = get_msb_32;
615 state->get_sample = get_lsb_32;
617 else if (strm->bit_per_sample > 8)
619 /* 16 bit settings */
621 state->in_blklen = 2 * strm->block_size;
623 if (strm->flags & AE_DATA_MSB)
625 state->get_sample = get_msb_16;
627 if (strm->block_size == 8)
628 state->get_block = get_block_msb_16_bs_8;
630 state->get_block = get_block_msb_16_bs_16;
633 state->get_sample = get_lsb_16;
638 state->in_blklen = strm->block_size;
641 state->get_sample = get_8;
643 if (strm->block_size == 8)
644 state->get_block = get_block_8_bs_8;
646 state->get_block = get_block_8_bs_16;
649 if (strm->flags & AE_DATA_SIGNED)
651 state->xmin = -(1ULL << (strm->bit_per_sample - 1));
652 state->xmax = (1ULL << (strm->bit_per_sample - 1)) - 1;
657 state->xmax = (1ULL << strm->bit_per_sample) - 1;
660 state->in_block = (int64_t *)malloc(strm->block_size * sizeof(int64_t));
661 if (state->in_block == NULL)
666 /* Largest possible block according to specs */
667 state->out_blklen = (5 + 16 * 32) / 8 + 3;
668 state->out_block = (uint8_t *)malloc(state->out_blklen);
669 if (state->out_block == NULL)
677 state->out_bp = state->out_block;
680 state->mode = m_get_block;
685 int ae_encode(ae_streamp strm, int flush)
688 Finite-state machine implementation of the adaptive entropy
694 state->flush = flush;
696 while (state->mode(strm) == M_CONTINUE);
698 if (state->out_direct)
701 *state->out_block = *state->out_bp;
702 state->out_bp = state->out_block;
703 state->out_direct = 0;
708 int ae_encode_end(ae_streamp strm)
710 encode_state *state = strm->state;
712 free(state->in_block);
713 free(state->out_block);