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

📄 arithmetic.c

📁 spiht的压缩解压缩c编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
        {
          QccErrorAddMessage("(QccENTArithmeticEncode): Invalid context");
          return(1);
        }
      if ((symbol_stream[current_symbol] >=
           model->num_symbols[model->current_context] - 1) ||
          (symbol_stream[current_symbol] < 0))
        {
          QccErrorAddMessage("(QccENTArithmeticEncode): Invalid symbol in symbol stream");
          return(1);
        }
      symbol_index = 
        model->translate_symbol_to_index
        [model->current_context][symbol_stream[current_symbol]];
      return_value =
        QccENTArithmeticEncodeSymbol(symbol_index, model->current_context,
                                     model, output_buffer);
      if (return_value == 2)
        return(2);
      else
        if (return_value == 1)
          {
            QccErrorAddMessage("(QccENTArithmeticEncode): Error calling QccENTArithmeticEncodeSymbol()");
            return(1);
          }
      if (model->adaptive_model == QCCENT_ADAPTIVE)
        if (QccENTArithmeticUpdateModel(model,
                                        symbol_index,
                                        model->current_context))
          {
            QccErrorAddMessage("(QccENTArithmeticEncode): Error calling QccENTArithmeticUpdateModel()");
            return(1);
          }
    }

  return(0);
}

static QccENTArithmeticModel
*QccENTArithmeticCreateModel(const int *num_symbols,
                             int num_contexts,
                             QccENTArithmeticGetContext context_function)
{
  QccENTArithmeticModel *new_model = NULL;
  int symbol, context;

  if (num_symbols == NULL)
    return(NULL);

  if ((new_model = 
       (QccENTArithmeticModel *)malloc(sizeof(QccENTArithmeticModel))) == NULL)
    {
      QccErrorAddMessage("(QccENTArithmeticCreateModel): Error allocating memory");
      goto QccENTError;
    }

  QccENTArithmeticModelInitialize(new_model);

  if ((new_model->num_symbols = 
       (int *)malloc(sizeof(int)*num_contexts)) == NULL)
    {
      QccErrorAddMessage("(QccENTArithmeticCreateModel): Error allocating memory");
      goto QccENTError;
    }
  /*  Save space for EOF symbol  */
  for (context = 0; context < num_contexts; context++)
    new_model->num_symbols[context] = num_symbols[context] + 1;
  new_model->num_contexts = num_contexts;
  
  if (QccENTArithmeticAllocModelArrays(new_model))
    {
      QccErrorAddMessage("(QccENTArithmeticCreateModel): Error calling QccENTArithmeticAllocModelArrays()");
      goto QccENTError;
    }
  
  for (context = 0; context < new_model->num_contexts; context++)
    {
      for (symbol = 0; symbol < new_model->num_symbols[context]; symbol++)
        {
          new_model->translate_symbol_to_index[context][symbol] = symbol + 1;
          new_model->translate_index_to_symbol[context][symbol + 1] =
            symbol;
        }
      for (symbol = 0; symbol <= new_model->num_symbols[context]; symbol++)
        {
          new_model->frequencies[context][symbol] = 1;
          new_model->cumulative_frequencies[context][symbol] =
            new_model->num_symbols[context] - symbol;
        }
      new_model->frequencies[context][0] = 0;
    }

  new_model->low = 0;
  new_model->high = QCCENT_TOPVALUE;
  new_model->bits_to_follow = 0;

  new_model->context_function = context_function;
  new_model->current_context = 0;

  return(new_model);

 QccENTError:
  if (new_model != NULL)
    QccENTArithmeticFreeModel(new_model);
  return(NULL);
}

int QccENTArithmeticSetModelContext(QccENTArithmeticModel *model,
                                    int current_context)
{
  if ((current_context < 0) || (current_context >= model->num_contexts))
    {
      QccErrorAddMessage("(QccENTArithmeticSetModelContext): Invalid context number");
      return(1);
    }

  model->current_context = current_context;

  return(0);
}

static int QccENTArithmeticDecodeGetBit(QccENTArithmeticModel *model,
                                        QccBitBuffer *input_buffer,
                                        int *bit_value)
{
  int beyond_bounds;
  
  if (model->target_num_bits == QCCENT_ANYNUMBITS)
    beyond_bounds = QccBitBufferGetBit(input_buffer, bit_value);
  else
    if (input_buffer->bit_cnt >= model->target_num_bits)
      beyond_bounds = 1;
    else
      beyond_bounds = QccBitBufferGetBit(input_buffer, bit_value);
  
  if (beyond_bounds)
    {
      QccErrorClearMessages();
      model->garbage_bits++;
      if (model->garbage_bits > QCCENT_CODEVALUEBITS - 2)
        return(1);

      *bit_value = 0;
    }

  return(0);
}

static int QccENTArithmeticDecodeSymbol(int *symbol_index, 
                                        int context,
                                        QccENTArithmeticModel *model, 
                                        QccBitBuffer *input_buffer)
{
  long range;
  int cumulative_frequency;
  int bit_value;

  range = (long)(model->high - model->low) + 1;
  cumulative_frequency = 
    (((long)(model->current_code_value - model->low) + 1) *
     model->cumulative_frequencies[context][0] - 1) / range;

  for (*symbol_index = 1;
       model->cumulative_frequencies[context][*symbol_index] > 
         cumulative_frequency;
       *symbol_index += 1) ;

  model->high = model->low +
    (range * model->cumulative_frequencies[context][*symbol_index - 1]) /
    model->cumulative_frequencies[context][0] - 1;
  model->low = model->low +
    (range * model->cumulative_frequencies[context][*symbol_index]) /
    model->cumulative_frequencies[context][0];

  for (;;)
    {
      if (model->high < QCCENT_HALFVALUE) ;
      else if (model->low >= QCCENT_HALFVALUE)
        {
          model->current_code_value -= QCCENT_HALFVALUE;
          model->low -= QCCENT_HALFVALUE;
          model->high -= QCCENT_HALFVALUE;
        }
      else if (model->low >= QCCENT_FIRSTQUARTERVALUE &&
               model->high < QCCENT_THIRDQUARTERVALUE)
        {
          model->current_code_value -= QCCENT_FIRSTQUARTERVALUE;
          model->low -= QCCENT_FIRSTQUARTERVALUE;
          model->high -= QCCENT_FIRSTQUARTERVALUE;
        }
      else
        break;

      model->low = 2 * model->low;
      model->high = 2 * model->high + 1;

      if (QccENTArithmeticDecodeGetBit(model, input_buffer, &bit_value))
        return(1);

      model->current_code_value = 2 * (model->current_code_value) +
        bit_value;

    }

  return(0);
}

static int QccENTArithmeticSymbolIsEOF(int symbol_index,
                                       int context,
                                       QccENTArithmeticModel *model)
{
  int EOF_symbol_index;

  EOF_symbol_index = model->num_symbols[context];

  return(symbol_index == EOF_symbol_index);
}

QccENTArithmeticModel *QccENTArithmeticDecodeStart(QccBitBuffer *input_buffer,
                                                   const int *num_symbols, 
                                                   int num_contexts,
                                                   QccENTArithmeticGetContext
                                                   context_function,
                                                   int target_num_bits)
{
  int bit_index;
  int bit_value;

  QccENTArithmeticModel *new_model = NULL;

  if ((new_model = 
       QccENTArithmeticCreateModel(num_symbols, num_contexts,
                                   context_function)) == NULL)
    {
      QccErrorAddMessage("(QccENTArithmeticDecodeStart): Error calling QccENTArithmeticCreateModel()");
      return(NULL);
    }

  new_model->current_code_value = 0;
  new_model->garbage_bits = 0;
  new_model->target_num_bits = target_num_bits;
  for (bit_index = 1; bit_index <= QCCENT_CODEVALUEBITS; bit_index++)
    {
      if (QccENTArithmeticDecodeGetBit(new_model, input_buffer, &bit_value))
        {
          QccErrorAddMessage("(QccENTArithmeticDecodeStart): Error calling QccENTArithmeticDecodeGetBit()");
          QccENTArithmeticFreeModel(new_model);
          return(NULL);
        }
      new_model->current_code_value = 2*(new_model->current_code_value) + 
        bit_value;
    }

  return(new_model);
}

int QccENTArithmeticDecode(QccBitBuffer *input_buffer,
                           QccENTArithmeticModel *model,
                           int *symbol_stream,
                           int symbol_stream_length)
{
  int current_symbol;
  int symbol_index;

  if (input_buffer == NULL)
    return(0);
  if (symbol_stream == NULL)
    return(0);
  if (model == NULL)
    return(0);

  for (current_symbol = 0; current_symbol < symbol_stream_length; 
       current_symbol++)
    {
      if (model->context_function != NULL)
        model->current_context =
          (model->context_function)(symbol_stream, current_symbol);

      if (QccENTArithmeticDecodeSymbol(&symbol_index, model->current_context,
                                       model, input_buffer))
        {
          QccErrorAddMessage("(QccENTArithmeticDecode): Error calling QccENTArithmeticDecodeSymbol()");
          return(1);
        }

      if (QccENTArithmeticSymbolIsEOF(symbol_index,
                                      model->current_context, model))
        return(2);

      symbol_stream[current_symbol] =
        model->translate_index_to_symbol[model->current_context][symbol_index];

      if (model->adaptive_model == QCCENT_ADAPTIVE)
        if (QccENTArithmeticUpdateModel(model,
                                        symbol_index, model->current_context))
          {
            QccErrorAddMessage("(QccENTArithmeticDecode): Error calling QccENTArithmeticUpdateModel()");
            return(1);
          }
    }

  return(0);
}

⌨️ 快捷键说明

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