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

📄 dst_arith_encoder.c

📁 关于视频压缩的jpeg2000压缩算法,C编写
💻 C
📖 第 1 页 / 共 2 页
字号:
      state->word = 0;      dst_arith_coder__output_word(state,state->word);    }  state->mqe.num_preceding_bytes =    (state->saved_words << 2) + ((32-state->current_lsb)>>3);    /* Set active flags. */  assert(!state->mqe.active);  state->mqe.active = 1;}/*****************************************************************************//* EXTERN                dst_arith_coder__output_word                        *//*****************************************************************************/void  dst_arith_coder__output_word(dst_arith_state_ptr state, std_int word) /* Outputs a word to the code word heap. */{  int pos;    pos = state->next_heap_pos;  state->heap->words[pos++] = word;  state->saved_words++;  if (pos == DST_HEAP_WORDS)    {      dst_heap_unit_ptr elt;      pos = 0;      elt = state->code_heap_mgr->get_unit(state->code_heap_mgr);      elt->next = NULL;      state->heap = state->heap->next = elt;    }  state->next_heap_pos = pos;}/*****************************************************************************//* EXTERN                    dst_arith_coder__byteout                        *//*****************************************************************************/std_int  dst_arith_coder__byteout(std_int creg, std_short *ct,                            dst_arith_state_ptr state){  assert(state->mqe.active);  if (state->mqe.have_unsent_ff)    {      put_byte(state,LONG_FF);      state->mqe.have_unsent_ff = 0;    }  if(state->mqe.buffer != LONG_FF)    {      if( !(creg & M_CR_C) )        { /* No Carry */          put_byte(state,state->mqe.buffer);          state->mqe.buffer = (creg >> S_CR_B_NML);          creg &= M_CR_SX_NML;          *ct = NEXTBITS_NML;        }      else        { /* Carry */          state->mqe.buffer++; /* Carry propagation */          if(state->mqe.buffer != LONG_FF)            {              put_byte(state,state->mqe.buffer);              state->mqe.buffer = ((creg >> S_CR_B_NML) & M_CR_BUF8);              creg  &= M_CR_SX_NML;              *ct = NEXTBITS_NML;            }          else            {              state->mqe.have_unsent_ff = 1;              state->mqe.buffer = ((creg >> S_CR_B_BS) & M_CR_BUF7);              creg  &= M_CR_SX_BS;              *ct = NEXTBITS_BS;            }        }    }  else    { /* buffer == BYTE_FF */      state->mqe.have_unsent_ff = 1;      state->mqe.buffer = (creg >> S_CR_B_BS);      creg  &= M_CR_SX_BS;      *ct   = NEXTBITS_BS;    }  return(creg);}/*****************************************************************************//* EXTERN                  dst_arith_coder__deactivate                       *//*****************************************************************************/int  dst_arith_coder__deactivate(dst_arith_state_ptr state,                              int easy){  int num_bytes;  if (!state->mqe.active)    num_bytes = perform_raw_terminating_flush(state);  else    {      assert((state->current_lsb & 7) == 0);      if (state->error_resilient_termination)        num_bytes = perform_error_resilient_flush(state);      else if (easy)        num_bytes = perform_easy_terminating_flush(state);      else        num_bytes = perform_best_terminating_flush(state);      init_enc(&(state->mqe));    }  return(num_bytes);}/*****************************************************************************//* EXTERN                   dst_arith_coder__flush                           *//*****************************************************************************/void  dst_arith_coder__flush(dst_arith_state_ptr state){  assert(!state->mqe.active); /* Encoder must already have been deactivated */  if (state->current_lsb < 32)    dst_arith_coder__output_word(state,state->word);}/*****************************************************************************//* EXTERN              dst_arith_coder__get_minimum_bytes                    *//*****************************************************************************/int  dst_arith_coder__get_minimum_bytes(dst_arith_state_ptr state,                                     dst_heap_unit_ptr heap, int heap_pos,                                     int min_bytes, int max_bytes) /* Determines the minimum number of whole bytes which are required to    correctly decode all coded symbols up to and including the last symbol    whose coding resulted in the state recorded in the supplied `state'    structure.  The `heap' and `heap_pos' arguments identify the heap unit    structure and the word index within this structure, of the first word    saved by the arithmetic coding engine.  The function indexes into the    saved bit-stream to determine the effect of premature termination on    successful decoding up to the point associated with `state'.  The    function depends intimately on the assumption that the decoder will    stuff 1's onto the end of the bit-stream as necessary and then    replace consecutive FF's by the pattern FF,7F,FF,...  Consequently,    the `dst_arith_coder__input_word' function and the `bytein' function    in "dst_arith_decoder.c" must not be carelessly modified.        The original version of this function (for the original EBCOT arithmetic    coder) was bit oriented and never overestimated the required code length;    however, the bit-stuffing policy in the MQ coder is byte oriented, which    makes estimation of the minimum number of whole bytes directly somewhat    simpler; this is sufficient, since the block coder represents truncation    points in bytes, not bits.        The `min_bytes' and `max_bytes' fields are provided to account for the    fact that there may be multiple arithmetic code-word segments in the    code stream where we are wanting to compute a termination point inside    one of those segments.  The `min_bytes' field identifies the number of    bytes in the code stream preceding the relevant segment, whereas the    `max_bytes' field identifies the number of bytes in the code stream up    until the end of the segment. */{  std_int upper_C, upper_buf, lower_C, lower_buf;  std_int word, last_byte_is_ff, next_byte;  std_short ct;  std_int n, in_word_idx, tmp;  int num_bytes;  word = 0; /* Suppress compiler warnings. */  next_byte = 0; /* Suppress compiler warnings. */  if (!state->mqe.active)    { /* Computing the length of a raw bit-stream segment -> easy! */      int current_lsb;      current_lsb = state->current_lsb & ~7;      num_bytes = (state->saved_words << 2) + ((32-current_lsb)>>3);      return(num_bytes);    }  assert((state->current_lsb & 7) == 0);  num_bytes = (state->saved_words << 2) + ((32-state->current_lsb)>>3);  if (state->mqe.io_enable)    num_bytes++;  num_bytes--;  if (state->mqe.have_unsent_ff)    num_bytes++;  if (num_bytes > max_bytes)    return(max_bytes);  assert(num_bytes >= (min_bytes-1));    /* `num_bytes' represents the number of bytes which have been pushed       out to the heap by this stage, not including any value sent to       the byte buffer in the `state->mqe' structure.  This value might       be less than `min_bytes'.  For example, if no symbols have been coded       at all, this value will be equal to `min_bytes'-1.  The interpretation       of a value of `min_bytes'-1 is that the byte buffer in the `state->mqe'       structure is itself empty. */  ct = state->mqe.ct;  lower_C = state->mqe.creg;  upper_C = lower_C + state->mqe.areg;  lower_C <<= ct;  upper_C <<= ct;  upper_buf = lower_buf = state->mqe.buffer;  if (upper_C & M_CR_C)    {      upper_C -= M_CR_C;      upper_buf++;    }  if (lower_C & M_CR_C)    {      lower_C -= M_CR_C;      lower_buf++;    }  /* At this point, `upper_buf' holds the buffer value and     `upper_C' the C-register value corresponding to an upper bound;     Similarly, `lower_C' and `lower_buf' represent the lower bound on     the arithmetic code-word.  After padding (due to truncation), the     code-word must be strictly less than the upper bound and no less than     the lower bound in order to ensure correct decoding.  We would normally     only need to consider the upper bound, but the bit-stuffing policy used     by the MQ coder renders this insufficient. */  /* Now for the loop to find the minimum number of bytes required.     We start by checking whether or not we need any more than the     `num_bytes' value, i.e. whether or not we need the byte whose     position corresponds to that of the byte in `state->mqe.buffer'. */  in_word_idx = -1; /* Illegal value. */  last_byte_is_ff = state->mqe.have_unsent_ff;  while (1)    {      if (last_byte_is_ff)        { /* If we stop immediately before here, the decoder will pad             with 0x7F, 0xFF, 0x7F, 0xFF, ..., which is equivalent to a             number strictly less than 128, but larger than any number less             than 128. */          if ((upper_buf >= 128) && (lower_buf < 128))            {              num_bytes--; /* Do not need the preceding byte either since                              the decoder will substitute the 0xFF                              automatically as the first byte after the                              end of the string. */              break;            }        }      else        { /* If we stop immediately before here, the decoder will pad             with 0xFF, 0x7F, 0xFF, 0x7F, ..., which is equivalent to a             number strictly less than 256, but larger than any number less             than 256. */          if ((upper_buf >= 256) && (lower_buf < 256))            {              break; /* We are done. */            }        }      /* Retrieve next actual byte in codeword segment. */      if (in_word_idx < 0)        { /* First access to heap. */          word = 0; in_word_idx = 3;          if (num_bytes >= 0)            {              n = num_bytes>>2; /* Number of whole words in heap to skip. */              in_word_idx = num_bytes - (n<<2); /* Index of byte in word. */              while (n)                {                  tmp = DST_HEAP_WORDS - heap_pos;                  if (tmp > n)                    {                      heap_pos += n;                      n = 0;                    }                  else                    {                      n -= tmp;                      heap_pos = 0;                      heap = heap->next;                    }                }              word = heap->words[heap_pos++];              word <<= (in_word_idx << 3);              next_byte = (word>>24) & 0x00FF;            }        }      else if (num_bytes >= 0)        {          in_word_idx++; word <<= 8;          if (in_word_idx == 4)            {              if (heap_pos >= DST_HEAP_WORDS)                { heap = heap->next; heap_pos = 0; }              word = heap->words[heap_pos++];              in_word_idx = 0;            }          next_byte = (word >> 24) & 0x00FF;        }      if (num_bytes < min_bytes)        next_byte = 0;      /* Advance to the next byte position. */      upper_buf -= next_byte;      lower_buf -= next_byte;      num_bytes++;      assert(num_bytes <= max_bytes);      if (next_byte != 0x00FF)        { /* move left-most 8 bits of C into buffer. */          upper_buf <<= 8; lower_buf <<= 8;          upper_buf |= (upper_C >> (16+SPACER)) & 0x00FF;          lower_buf |= (lower_C >> (16+SPACER)) & 0x00FF;          upper_C <<= 8; lower_C <<= 8;          last_byte_is_ff = 0;        }      else        { /* move left-most 7 bits of C into buffer. */          upper_buf <<= 7; lower_buf <<= 7;          upper_buf |= (upper_C >> (16+SPACER+1)) & 0x007F;          lower_buf |= (lower_C >> (16+SPACER+1)) & 0x007F;          upper_C <<= 7; lower_C <<= 7;          last_byte_is_ff = 1;        }      upper_C &= M_CR_BSX;      lower_C &= M_CR_BSX;    }  if (num_bytes < min_bytes)    num_bytes = min_bytes;  return(num_bytes);}/*****************************************************************************//* EXTERN                  dst_arith_coder__log_symbol                       *//*****************************************************************************/#ifdef DST_LOG_SYMBOLSvoid  dst_arith_coder__log_symbol(dst_arith_state_ptr state,                              dst_context_state_ptr ctxt,                              std_int symbol) /* David T mod */{  int val;   if(state->symbol_log == NULL)    return;  if (ctxt == NULL)    val = 255;  else    val = ctxt - state->contexts;  putc(val,state->symbol_log);  val = (symbol)?1:0;  putc(val,state->symbol_log);}#endif /* DST_LOG_SYMBOLS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -