⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dst_arith_decoder.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ------------------------- 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_SYMBOLS
void
  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 + -