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

📄 spiht.c

📁 spiht的压缩解压缩c编写的
💻 C
📖 第 1 页 / 共 4 页
字号:
  base_col = coefficient_block->col;

  if (QccSPIHTDescendantsOutsideMask(subband_pyramid,
                                     mask,
                                     base_row, base_col,
                                     block_size))
    return(0);

  if (method == QCCSPIHT_ENCODE)
    {
      bit = QccSPIHTDescendantsSignificance(subband_pyramid,
                                            base_row, base_col,
                                            threshold,
                                            block_size);
      
      if (bit == -1)
        return(0);
    }
  
  if (model != NULL)
    if (QccENTArithmeticSetModelContext(model,
                                        QCCSPIHT_LIS_TYPEA_CONTEXT +
                                        coefficient_block->state))
      {
        QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccENTArithmeticSetModelContext()");
        return(2);
      }
  
  if (QccSPIHTInputOutput(buffer, &bit, method, model, target_bit_cnt))
    {
      QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccSPIHTInputOutput()");
      return(2);
    }
  
  if (!bit)
    return(0);
  
  num_offspring = 
    QccSPIHTGetOffspring(subband_pyramid,
                         base_row, base_col,
                         offspring_row,
                         offspring_col,
                         block_size);
  
  for (offspring = 0; offspring < num_offspring; offspring++)
    {
      new_coefficient_block.row = 
        offspring_row[offspring];
      new_coefficient_block.col = 
        offspring_col[offspring];
      new_coefficient_block.type = 
        QCCSPIHT_TYPE_A;
      new_coefficient_block.state = 0;

      if (model != NULL)
        if (QccENTArithmeticSetModelContext(model,
                                            QCCSPIHT_LIS_TYPEA_OFFSPRING_CONTEXT +
                                            coefficient_block->state))
          {
            QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccENTArithmeticSetModelContext()");
            return(2);
          }

      if (QccSPIHTInputOutputSignificanceBits(subband_pyramid,
                                              buffer,
                                              &new_coefficient_block,
                                              threshold,
                                              method,
                                              model,
                                              target_bit_cnt,
                                              block_size))
        {
          QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccSPIHTInputOutputSignificanceBits()");
          return(2);
        }

      new_state = new_coefficient_block.state;

      cnt = 0;
      for (row = 0; row < block_size; row++)
        for (col = 0; col < block_size; col++)
          if (QccSPIHTIsSignificant(new_state, row, col, block_size))
            {
              cnt++;
              if ((return_value =
                   QccSPIHTAddNodeToLSP(LSP,
                                        offspring_row[offspring] + row,
                                        offspring_col[offspring] + col,
                                        subband_pyramid,
                                        threshold,
                                        sign_array,
                                        buffer,
                                        method,
                                        model,
                                        target_bit_cnt,
                                        distortion_trace)))
                {
                  QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccSPIHTAddNodeToLSP()");
                  return(return_value);
                }
            }

      if (cnt != block_size * block_size)
        {
          if ((new_node =
               QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
                                 (void *)(&new_coefficient_block))) == NULL)
            {
              QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListCreateNode()");
              return(1);
            }

          if (QccListAppendNode(LIP, new_node))
            {
              QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListAppendNode()");
              return(1);
            }
        }
    }
  
  if (QccSPIHTGetOffspring(subband_pyramid,
                           offspring_row[0], offspring_col[0],
                           offspring_row, offspring_col,
                           block_size))
    {
      coefficient_block->type = QCCSPIHT_TYPE_B;
      
      if ((new_node =
           QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
                             (void *)(coefficient_block))) == NULL)
        {
          QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListCreateNode()");
          return(1);
        }

      if (QccListAppendNode(LIS, new_node))
        {
          QccErrorAddMessage("(QccSPIHTTypeA): Error calling QccListAppendNode()");
          return(1);
        }
    }
  
  coefficient_block->type = QCCSPIHT_TYPE_DELETE;
  
  return(0);
}

static int QccSPIHTTypeB(QccWAVSubbandPyramid *subband_pyramid,
                         QccWAVSubbandPyramid *mask,
                         int **sign_array,
                         QccBitBuffer *buffer,
                         QccSPIHTCoefficientBlock *coefficient_block,
                         QccListNode *current_list_node,
                         double threshold,
                         QccList *LIS,
                         int method,
                         QccENTArithmeticModel *model,
                         int target_bit_cnt,
                         int block_size)
{
  int bit;
  int offspring_row[4];
  int offspring_col[4];
  int num_offspring;
  int offspring;
  QccSPIHTCoefficientBlock new_coefficient_block;
  QccListNode *new_node;
  int base_row, base_col;

  base_row = coefficient_block->row;
  base_col = coefficient_block->col;

  if (QccSPIHTDescendantsOutsideMask(subband_pyramid,
                                     mask,
                                     base_row, base_col,
                                     block_size))
    return(0);

  if (method == QCCSPIHT_ENCODE)
    {
      bit = QccSPIHTLSignificance(subband_pyramid,
                                  coefficient_block->row,
                                  coefficient_block->col,
                                  threshold,
                                  block_size);
      
      if (bit == -1)
        return(0);
    }      

  if (model != NULL)
    if (QccENTArithmeticSetModelContext(model,
                                        QCCSPIHT_LIS_TYPEB_CONTEXT +
                                        coefficient_block->state))
      {
        QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccENTArithmeticSetModelContext()");
        return(2);
      }

  if (QccSPIHTInputOutput(buffer, &bit, method, model, target_bit_cnt))
    {
      QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccSPIHTInputOutput()");
      return(2);
    }
  
  if (!bit)
    return(0);
  
  num_offspring = QccSPIHTGetOffspring(subband_pyramid,
                                       coefficient_block->row,
                                       coefficient_block->col,
                                       offspring_row,
                                       offspring_col,
                                       block_size);
  
  for (offspring = 0; offspring < num_offspring; offspring++)
    {
      new_coefficient_block.row = 
        offspring_row[offspring];
      new_coefficient_block.col = 
        offspring_col[offspring];
      new_coefficient_block.type = 
        QCCSPIHT_TYPE_A;
      new_coefficient_block.state = 0;

      if ((new_node =
           QccListCreateNode(sizeof(QccSPIHTCoefficientBlock),
                             (void *)(&new_coefficient_block))) == NULL)
        {
          QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccListCreateNode()");
          return(1);
        }
      if (QccListAppendNode(LIS, new_node))
        {
          QccErrorAddMessage("(QccSPIHTTypeB): Error calling QccListAppendNode()");
          return(1);
        }
    }

  QccSPIHTGetCoefficientBlockFromNode(current_list_node)->type =
    QCCSPIHT_TYPE_DELETE;

  return(0);
}

static int QccSPIHTSortingPass(QccWAVSubbandPyramid *subband_pyramid,
                               QccWAVSubbandPyramid *mask,
                               int **sign_array,
                               QccBitBuffer *buffer,
                               double threshold,
                               QccList *LSP,
                               QccList *LIP,
                               QccList *LIS,
                               int method,
                               QccENTArithmeticModel *model,
                               int target_bit_cnt,
                               int block_size,
                               QccSPIHTDistortionTrace *distortion_trace)
{
  int return_value;
  int old_state;
  int new_state;
  int row, col;
  int cnt;
  int base_row, base_col;
  QccSPIHTCoefficientBlock *current_coefficient_block;
  QccListNode *current_list_node;
  
  current_list_node = LIP->start;
  while (current_list_node != NULL)
    {
      current_coefficient_block =
        QccSPIHTGetCoefficientBlockFromNode(current_list_node);

      if (current_coefficient_block->type != QCCSPIHT_TYPE_DELETE)
        {
          old_state = current_coefficient_block->state;
          
          if (model != NULL)
            if (QccENTArithmeticSetModelContext(model, 
                                                QCCSPIHT_LIP_CONTEXT +
                                                old_state))
              {
                QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccENTArithmeticSetModelContext()");
                goto Finished;
              }
          
          if (QccSPIHTInputOutputSignificanceBits(subband_pyramid,
                                                  buffer,
                                                  current_coefficient_block,
                                                  threshold,
                                                  method,
                                                  model,
                                                  target_bit_cnt,
                                                  block_size))
            {
              QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTInputOutputSignificanceBits()");
              goto Finished;
            }
          
          new_state = current_coefficient_block->state;
          
          base_row = current_coefficient_block->row;
          base_col = current_coefficient_block->col;
          cnt = 0;
          for (row = 0; row < block_size; row++)
            for (col = 0; col < block_size; col++)
              if (QccSPIHTIsSignificant(new_state, row, col, block_size))
                {
                  cnt++;
                  if (!QccSPIHTIsSignificant(old_state, row, col, block_size))
                    {
                      return_value =
                        QccSPIHTAddNodeToLSP(LSP,
                                             base_row + row,
                                             base_col + col,
                                             subband_pyramid,
                                             threshold,
                                             sign_array,
                                             buffer,
                                             method,
                                             model,
                                             target_bit_cnt,
                                             distortion_trace);
                      if (return_value == 2)
                        goto Finished;
                      else
                        if (return_value == 1)
                          {
                            QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTAddNodeToLSP()");
                            goto Error;
                          }
                    }
                }
          
          if (cnt == block_size * block_size)
            current_coefficient_block->type = QCCSPIHT_TYPE_DELETE;
        }
      
      current_list_node = current_list_node->next;
    }

  current_list_node = LIS->start;
  while (current_list_node != NULL)
    {
      current_coefficient_block =
        QccSPIHTGetCoefficientBlockFromNode(current_list_node);

      switch (current_coefficient_block->type)
        {
        case QCCSPIHT_TYPE_A:
          return_value =
            QccSPIHTTypeA(subband_pyramid,
                          mask,
                          sign_array,
                          buffer,
                          current_coefficient_block,
                          current_list_node,
                          threshold,
                          LSP, LIP, LIS,
                          method,
                          model,
                          target_bit_cnt,
                          block_size,
                          distortion_trace);
          if (return_value == 2)
            goto Finished;
          else
            if (return_value == 1)
              {
                QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTTypeA()");
                goto Error;
              }
          break;

        case QCCSPIHT_TYPE_B:
          return_value =
            QccSPIHTTypeB(subband_pyramid,
                          mask,
                          sign_array,
                          buffer,
                          current_coefficient_block,
                          current_list_node,
                          threshold,
                          LIS,
                          method,
                          model,
                          target_bit_cnt,
                          block_size);
          if (return_value == 2)
            goto Finished;
          else
            if (return_value == 1)

⌨️ 快捷键说明

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