📄 dst_arith_decoder.c
字号:
/* ------------------------- External Functions ---------------------------- *//* ========================================================================= *//*****************************************************************************//* EXTERN dst_arith_coder__initialize *//*****************************************************************************/void dst_arith_coder__initialize(dst_arith_state_ptr state, int num_contexts, dst_context_state_ptr contexts, dst_heap_unit_ptr heap, int total_bytes, int error_resilient_termination){ state->word = state->save_word = 0; state->current_lsb = 0; /* `word' unloaded. */ state->bytes_in_word = 0; state->num_contexts = num_contexts; assert(num_contexts <= DST_ARITH_MAX_CTXTS); /* Fast implementation depends on this. */ state->contexts = contexts; state->total_bytes_available = total_bytes; state->total_bytes_consumed = 0; state->final_segment_word_consumed = 0; state->current_segment_bytes = 0; state->bytes_left_in_segment = state->total_bytes_available - state->total_bytes_consumed; /* When the coder is not activated, we assume that all bytes in the code stream are available, since we have no way of knowing anything different. Of course, this means that erroneous consumption of raw bits, say in the lazy mode, may eat into the portion of the code-stream belonging to the next arithmetically coded segment, which will cause a lot of errors. Some error resilience might be offered by providing all the information which is known about segment lengths including the lengths of raw bit-stream segments, but we do not complicate the implementation with this for the moment, especially since in many cases only the lengths of arithmetically coded segments will actually be known. */ state->heap_head = state->heap_ptr = heap; state->next_heap_pos = 0; state->error_resilient_termination = error_resilient_termination; init_dec(&(state->mqd));}/*****************************************************************************//* EXTERN dst_arith_coder__model_init *//*****************************************************************************/void dst_arith_coder__model_init(dst_arith_state_ptr state, dst_context_state_ptr init){ dst_context_state_ptr csp1, csp2; int n; csp1 = state->contexts; csp2 = csp1 + DST_ARITH_MAX_CTXTS; for (n=state->num_contexts; n > 0; n--, csp1++, csp2++, init++) { *csp1 = *init; *csp2 = dst_arith_state_to_delta[*csp1]; }}/*****************************************************************************//* EXTERN dst_arith_coder__input_word *//*****************************************************************************/std_int dst_arith_coder__input_word(dst_arith_state_ptr state){ std_int result; if (!state->final_segment_word_consumed) { int bytes_in_word; bytes_in_word = state->bytes_in_word; if (bytes_in_word > state->bytes_left_in_segment) bytes_in_word = state->bytes_left_in_segment; state->total_bytes_consumed += bytes_in_word; state->bytes_left_in_segment -= bytes_in_word; } if (state->bytes_left_in_segment == 0) { /* Do not consume anything. Just pad with a full word of FF's. */ state->total_bytes_consumed += state->bytes_left_in_segment; state->bytes_left_in_segment = 0; state->final_segment_word_consumed = 1; state->bytes_in_word = 0; return((std_int)(-1)); } result = state->save_word = state->heap_ptr->words[state->next_heap_pos++]; if (state->next_heap_pos == DST_HEAP_WORDS) { state->heap_ptr = state->heap_ptr->next; state->next_heap_pos = 0; } state->bytes_in_word = 4; if (state->bytes_left_in_segment < state->bytes_in_word) { std_int trailing_ffs; trailing_ffs = state->bytes_in_word - state->bytes_left_in_segment; trailing_ffs <<= 3; trailing_ffs = ~(((std_int)(-1)) << trailing_ffs); result |= trailing_ffs; } return(result);}/*****************************************************************************//* EXTERN dst_arith_coder__set_segment_size *//*****************************************************************************/void dst_arith_coder__set_segment_size(dst_arith_state_ptr state, int terminating_byte_count){ assert((!state->mqd.active) && ((state->current_lsb & 7) == 0)); assert(state->total_bytes_consumed <= terminating_byte_count); assert(terminating_byte_count <= state->total_bytes_available); /* Now set the new segment size and load the various state variables accordingly. */ state->bytes_left_in_segment = state->current_segment_bytes = terminating_byte_count - state->total_bytes_consumed; if (state->bytes_left_in_segment < state->bytes_in_word) { std_int trailing_ffs; trailing_ffs = state->bytes_in_word - state->bytes_left_in_segment; trailing_ffs <<= 3; trailing_ffs = ~(((std_int)(-1)) << trailing_ffs); state->word |= trailing_ffs; } state->final_segment_word_consumed = 0;}/*****************************************************************************//* EXTERN dst_arith_coder__activate *//*****************************************************************************/void dst_arith_coder__activate(dst_arith_state_ptr state){ state->current_lsb &= ~7; /* Byte align code stream. */ state->mqd.active = 1; dec_preload(state,&(state->mqd));}/*****************************************************************************//* EXTERN dst_arith_coder__deactivate *//*****************************************************************************/int dst_arith_coder__deactivate(dst_arith_state_ptr state){ int num_er_bits; num_er_bits = 0; if (!state->mqd.active) { if (state->error_resilient_termination) num_er_bits = check_raw_erterm_bits(state); state->current_lsb &= ~7; } while (state->bytes_left_in_segment > 0) dst_arith_coder__input_word(state); /* Correct `total_bytes_consumed' and `bytes_left_in_segment' values and also restore the `word' state variable in preparation for further consumption. */ assert((state->current_lsb & 7) == 0); if (!state->final_segment_word_consumed) { int bytes_in_word; bytes_in_word = state->bytes_in_word; bytes_in_word -= state->current_lsb >> 3; if (bytes_in_word > state->bytes_left_in_segment) bytes_in_word = state->bytes_left_in_segment; state->total_bytes_consumed += bytes_in_word; state->bytes_left_in_segment -= bytes_in_word; } assert(state->bytes_left_in_segment == 0); state->word = state->save_word; state->bytes_in_word = (4-state->total_bytes_consumed) & 3; state->current_lsb = state->bytes_in_word << 3; /* Reset the arithmetic coder state and set a default segment length for further raw or arithmetic decoding operations in which the segment length is not explicitly signalled. */ if (state->mqd.active) { if (state->error_resilient_termination) { std_int last_byte; last_byte = (state->word >> (state->bytes_in_word<<3)) & 0x00FF; num_er_bits = check_mq_erterm_bits(state,last_byte); } state->mqd.active = 0; init_dec(&(state->mqd)); } dst_arith_coder__set_segment_size(state,state->total_bytes_available); if (num_er_bits < 0) num_er_bits = -1000; return(num_er_bits);}/*****************************************************************************//* EXTERN dst_arith_coder__bytein *//*****************************************************************************/unsigned long dst_arith_coder__bytein(unsigned long creg, int *ct, dst_arith_state_ptr state){ assert(state->mqd.active); if(state->mqd.buffer != (LONG_FF << S_DR_B_NML)) { creg += state->mqd.buffer; get_byte(state); *ct = state->mqd.nextct; state->mqd.nextct = NEXTBITS_NML; state->mqd.buffer <<= S_DR_B_NML; } else { /* FF */ get_byte(state); creg += LONG_FF << S_DR_B_NML; *ct = state->mqd.nextct; /*NEXTBITS_NML*/ state->mqd.nextct = NEXTBITS_BS; if (state->mqd.buffer == 0x00FF) { state->mqd.converted_doublets++; state->mqd.buffer = 0x007F; /* General marker detection method will have same effect in practice. */ } state->mqd.buffer <<= S_DR_B_BS; } return(creg);}/*****************************************************************************//* EXTERN dst_arith_coder__terminate (Mitsubishi) *//*****************************************************************************/void dst_arith_coder__terminate(dst_arith_state_ptr state){ state->mqd.active = 0;}/*****************************************************************************//* EXTERN dst_arith_coder__check_logged_symbol *//*****************************************************************************/#ifdef DST_LOG_SYMBOLSvoid dst_arith_coder__check_logged_symbol(dst_arith_state_ptr state, dst_context_state_ptr ctxt, std_int symbol) /* David T mod */{ int val, check_val; if(state->symbol_log == NULL) return; if (ctxt == NULL) val = 255; else val = ctxt - state->contexts; check_val = getc(state->symbol_log); if (val != check_val) assert(val == check_val); val = (symbol)?1:0; check_val = getc(state->symbol_log); if (val != check_val) assert(val == check_val);}#endif /* DST_LOG_SYMBOLS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -