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

📄 spiht.c

📁 该源码是SPIHT即分层树集合划分算法的c代码,希望对搞压缩编码的朋友们有用.
💻 C
📖 第 1 页 / 共 3 页
字号:
	QccSPIHTGetCoefficientBlockFromNode(current_list_node);

      if (current_coefficient_block->type == QCCSPIHT_TYPE_A)
	{
	  if ((return_value =
	       QccSPIHTTypeA(subband_pyramid,
			     sign_array,
			     buffer,
			     current_coefficient_block,
			     current_list_node,
			     threshold,
			     LSP, LIP, LIS,
			     method,
			     model,
			     target_bit_cnt,
			     block_size)))
	    {
	      QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTTypeA()");
	      return(return_value);
	    }
	}      
      else
	if ((return_value =
	     QccSPIHTTypeB(subband_pyramid,
			   sign_array,
			   buffer,
			   current_coefficient_block,
			   current_list_node,
			   threshold,
			   LIS,
			   method,
			   model,
			   target_bit_cnt,
			   block_size)))
	  {
	    QccErrorAddMessage("(QccSPIHTSortingPass): Error calling QccSPIHTTypeB()");
	    return(return_value);
	  }
      
      current_list_node = next_list_node;
    }
  
  return(0);
}


static int QccSPIHTRefinementPass(QccWAVSubbandPyramid
				  *subband_pyramid,
				  QccBitBuffer *buffer,
				  double threshold,
				  QccList *LSP,
				  QccListNode *stop,
				  int method,
				  QccENTArithmeticModel *model,
				  int target_bit_cnt)
{
  QccListNode *current_node;
  QccSPIHTCoefficientBlock *current_coefficient;
  
  current_node = LSP->start;
  
  if ((current_node == NULL) || (stop == NULL))
    return(0);
  
  stop = stop->next;
  
  while (current_node != stop)
    {
      current_coefficient = QccSPIHTGetCoefficientBlockFromNode(current_node);
      
      if (QccSPIHTInputOutputRefinementBit(subband_pyramid,
					   buffer,
					   threshold,
					   current_coefficient,
					   method,
					   model,
					   target_bit_cnt))
	{
	  QccErrorAddMessage("(QccSPIHTRefinementPass): Error calling QccSPIHTInputOutputRefinementBit()");
	  return(2);
	}
      
      current_node = current_node->next;
    }
  
  return(0);
}


int QccSPIHTEncode(const QccIMGImageComponent *image,
		   const QccIMGImageComponent *mask,
		   QccBitBuffer *buffer,
		   int num_levels,
		   const QccWAVWavelet *wavelet,
		   const QccWAVPerceptualWeights *perceptual_weights,
		   int target_bit_cnt,
		   int arithmetic_coded)
{
  int return_value;
  QccENTArithmeticModel *model = NULL;
  QccWAVSubbandPyramid image_subband_pyramid;
  QccWAVSubbandPyramid mask_subband_pyramid;
  int **sign_array = NULL;
  double image_mean;
  int max_coefficient_bits;
  QccList LSP;
  QccList LIP;
  QccList LIS;
  QccListNode *stop;
  double threshold;
  int row;
  int block_size;

  if (image == NULL)
    return(0);
  if (buffer == NULL)
    return(0);
  if (wavelet == NULL)
    return(0);
  
  QccWAVSubbandPyramidInitialize(&image_subband_pyramid);
  QccWAVSubbandPyramidInitialize(&mask_subband_pyramid);
  QccListInitialize(&LSP);
  QccListInitialize(&LIP);
  QccListInitialize(&LIS);
  
  image_subband_pyramid.num_levels = 0;
  image_subband_pyramid.num_rows = image->num_rows;
  image_subband_pyramid.num_cols = image->num_cols;
  if (QccWAVSubbandPyramidAlloc(&image_subband_pyramid))
    {
      QccErrorAddMessage("(QccSPIHTEncode): Error calling QccWAVSubbandPyramidAlloc()");
      goto QccError;
    }
  
  if (mask != NULL)
    {
      if ((mask->num_rows != image->num_rows) ||
	  (mask->num_cols != image->num_cols))
	{
	  QccErrorAddMessage("(QccSPIHTEncode): Mask and image must be same size");
	  goto QccError;
	}

      mask_subband_pyramid.num_levels = 0;
      mask_subband_pyramid.num_rows = mask->num_rows;
      mask_subband_pyramid.num_cols = mask->num_cols;
      if (QccWAVSubbandPyramidAlloc(&mask_subband_pyramid))
	{
	  QccErrorAddMessage("(QccSPIHTEncode): Error calling QccWAVSubbandPyramidAlloc()");
	  goto QccError;
	}
    }
  
  if ((sign_array = (int **)malloc(sizeof(int *) * image->num_rows)) == NULL)
    {
      QccErrorAddMessage("(QccSPIHTEncode): Error allocating memory");
      goto QccError;
    }
  for (row = 0; row < image->num_rows; row++)
    if ((sign_array[row] =
	 (int *)malloc(sizeof(int) * image->num_cols)) == NULL)
      {
	QccErrorAddMessage("(QccSPIHTEncode): Error allocating memory");
	goto QccError;
      }
  
  if (QccSPIHTEncodeDWT(&image_subband_pyramid,
			sign_array,
			image,
			num_levels,
			&image_mean,
			&max_coefficient_bits,
			&mask_subband_pyramid,
			mask,
			wavelet,
			perceptual_weights))
    {
      QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTEncodeDWT()");
      goto QccError;
    }
  
  if (QccSPIHTEncodeHeader(buffer,
			   num_levels,
			   image->num_rows, image->num_cols, 
			   image_mean,
			   max_coefficient_bits,
			   arithmetic_coded))
    {
      QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTEncodeHeader()");
      goto QccError;
    }
  
  if (arithmetic_coded)
    {
      if ((model =
	   QccENTArithmeticEncodeStart(QccSPIHTArithmeticContexts,
				       QCCSPIHT_NUM_CONTEXTS,
				       NULL,
				       QCCENT_ANYNUMBITS))
	  == NULL)
	{
	  QccErrorAddMessage("(QccSPIHTEncode): Error calling QccENTArithmeticEncodeStart()");
	  goto QccError;
	}
      block_size = 2;
    }
  else
    block_size = 1;

  if (QccSPIHTAlgorithmInitialize(&image_subband_pyramid,
				  &LIP,
				  &LIS,
				  block_size))
    {
      QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTAlgorithmInitialize()");
      goto QccError;
    }
  
  threshold = pow((double)2, (double)max_coefficient_bits);
  
  while (1)
    {
      stop = LSP.end;
      
      return_value = 
	QccSPIHTSortingPass(&image_subband_pyramid,
			    sign_array,
			    buffer,
			    threshold,
			    &LSP,
			    &LIP,
			    &LIS,
			    QCCSPIHT_ENCODE,
			    model,
			    target_bit_cnt,
			    block_size);
      if (return_value == 1)
	{
	  QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTSortingPass()");
	  goto QccError;
	}
      else
	if (return_value == 2)
	  break;
      
      return_value =
	QccSPIHTRefinementPass(&image_subband_pyramid,
			       buffer,
			       threshold,
			       &LSP,
			       stop,
			       QCCSPIHT_ENCODE,
			       model,
			       target_bit_cnt);
      if (return_value == 1)
	{
	  QccErrorAddMessage("(QccSPIHTEncode): Error calling QccSPIHTRefinementPass()");
	  goto QccError;
	}
      else
	if (return_value == 2)
	  break;
      
      threshold /= 2.0;
    }
  
  return_value = 0;
  QccErrorClearMessages();
  goto QccReturn;
 QccError:
  return_value = 1;
 QccReturn:
  QccWAVSubbandPyramidFree(&image_subband_pyramid);
  QccWAVSubbandPyramidFree(&mask_subband_pyramid);
  if (sign_array != NULL)
    {
      for (row = 0; row < image->num_rows; row++)
	if (sign_array[row] != NULL)
	  free(sign_array[row]);
      free(sign_array);
    }
  QccListFree(&LSP);
  QccListFree(&LIP);
  QccListFree(&LIS);
  QccENTArithmeticFreeModel(model);
  return(return_value);
}


int QccSPIHTDecodeHeader(QccBitBuffer *buffer, 
			 int *num_levels, 
			 int *num_rows, int *num_cols,
			 double *image_mean,
			 int *max_coefficient_bits,
			 int *arithmetic_coded)
{
  int return_value;
  unsigned char ch;
  
  if (QccBitBufferGetChar(buffer, &ch))
    {
      QccErrorAddMessage("(QccSPIHTEncodeHeader): Error calling QccBitBufferPuChar()");
      goto QccError;
    }
  *num_levels = (int)ch;
  
  if (QccBitBufferGetInt(buffer, num_rows))
    {
      QccErrorAddMessage("(QccSPIHTEncodeHeader): Error calling QccBitBufferGetInt()");
      goto QccError;
    }
  
  if (QccBitBufferGetInt(buffer, num_cols))
    {
      QccErrorAddMessage("(QccSPIHTEncodeHeader): Error calling QccBitBufferGetInt()");
      goto QccError;
    }
  
  if (QccBitBufferGetDouble(buffer, image_mean))
    {
      QccErrorAddMessage("(QccSPIHTEncodeHeader): Error calling QccBitBufferGetDouble()");
      goto QccError;
    }
  
  if (QccBitBufferGetChar(buffer, &ch))
    {
      QccErrorAddMessage("(QccSPIHTEncodeHeader): Error calling QccBitBufferGetChar()");
      goto QccError;
    }
  *max_coefficient_bits = (int)ch;
  
  if (QccBitBufferGetBit(buffer, arithmetic_coded))
    {
      QccErrorAddMessage("(QccSPIHTEncodeHeader): Error calling QccBitBufferGetBit()");
      goto QccError;
    }
  
  return_value = 0;
  goto QccReturn;
 QccError:
  return_value = 1;
 QccReturn:
  return(return_value);
}


int QccSPIHTDecode(QccBitBuffer *buffer,
		   QccIMGImageComponent *image,
		   const QccIMGImageComponent *mask,
		   int num_levels,
		   const QccWAVWavelet *wavelet,
		   const QccWAVPerceptualWeights *perceptual_weights,
		   double image_mean,
		   int max_coefficient_bits,
		   int arithmetic_coded)
{
  int return_value;
  QccENTArithmeticModel *model = NULL;
  QccWAVSubbandPyramid image_subband_pyramid;
  QccWAVSubbandPyramid mask_subband_pyramid;
  int **sign_array = NULL;
  QccList LSP;
  QccList LIP;
  QccList LIS;
  QccListNode *stop;
  double threshold;
  int row, col;
  QccWAVWavelet lazy_wavelet_transform;
  int block_size;

  if (image == NULL)
    return(0);
  if (buffer == NULL)
    return(0);
  if (wavelet == NULL)
    return(0);
  
  QccWAVSubbandPyramidInitialize(&image_subband_pyramid);
  QccWAVSubbandPyramidInitialize(&mask_subband_pyramid);
  QccListInitialize(&LSP);
  QccListInitialize(&LIP);
  QccListInitialize(&LIS);
  QccWAVWaveletInitialize(&lazy_wavelet_transform);
  
  image_subband_pyramid.num_levels = num_levels;
  image_subband_pyramid.num_rows = image->num_rows;
  image_subband_pyramid.num_cols = image->num_cols;
  if (QccWAVSubbandPyramidAlloc(&image_subband_pyramid))
    {
      QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVSubbandPyramidAlloc()");
      goto QccError;
    }
  
  if (mask != NULL)
    {
      if ((mask->num_rows != image->num_rows) ||
	  (mask->num_cols != image->num_cols))
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Mask and image must be same size");
	  goto QccError;
	}

      if (QccWAVWaveletCreate(&lazy_wavelet_transform, "LWT.lft", "symmetric"))
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVWaveletCreate()");
	  goto QccError;
	}

      mask_subband_pyramid.num_levels = 0;
      mask_subband_pyramid.num_rows = mask->num_rows;
      mask_subband_pyramid.num_cols = mask->num_cols;
      if (QccWAVSubbandPyramidAlloc(&mask_subband_pyramid))
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVSubbandPyramidAlloc()");
	  goto QccError;
	}

      if (QccMatrixCopy(mask_subband_pyramid.matrix,
			mask->image,
			mask->num_rows,
			mask->num_cols))
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Error calling QccMatrixCopy()");
	  goto QccError;
	}

      if (QccWAVSubbandPyramidDWT(&mask_subband_pyramid,
				  num_levels,
				  &lazy_wavelet_transform))
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Error calling QccWAVSubbandPyramidDWT()");
	  goto QccError;
	}
    }
  
  if ((sign_array = (int **)malloc(sizeof(int *) * image->num_rows)) == NULL)
    {
      QccErrorAddMessage("(QccSPIHTDecode): Error allocating memory");
      goto QccError;
    }
  for (row = 0; row < image->num_rows; row++)
    if ((sign_array[row] =
	 (int *)malloc(sizeof(int) * image->num_cols)) == NULL)
      {
	QccErrorAddMessage("(QccSPIHTDecode): Error allocating memory");
	goto QccError;
      }
  
  for (row = 0; row < image->num_rows; row++)
    for (col = 0; col < image->num_cols; col++)
      {
	image_subband_pyramid.matrix[row][col] = 0.0;
	sign_array[row][col] = 0;
      }
  
  if (arithmetic_coded)
    {
      if ((model =
	   QccENTArithmeticDecodeStart(buffer,
				       QccSPIHTArithmeticContexts,
				       QCCSPIHT_NUM_CONTEXTS,
				       NULL,
				       QCCENT_ANYNUMBITS))
	  == NULL)
	{
	  QccErrorAddMessage("(QccSPIHTEncode): Error calling QccENTArithmeticDecodeStart()");
	  goto QccError;
	}
      block_size = 2;
    }
  else
    block_size = 1;

  if (QccSPIHTAlgorithmInitialize(&image_subband_pyramid,
				  &LIP,
				  &LIS,
				  block_size))
    {
      QccErrorAddMessage("(QccSPIHTDecode): Error calling QccSPIHTAlgorithmInitialize()");
      goto QccError;
    }
  
  threshold = pow((double)2, (double)max_coefficient_bits);
  
  while (1)
    {
      stop = LSP.end;
      
      return_value =
	QccSPIHTSortingPass(&image_subband_pyramid,
			    sign_array,
			    buffer,
			    threshold,
			    &LSP,
			    &LIP,
			    &LIS,
			    QCCSPIHT_DECODE,
			    model,
			    0,
			    block_size);
      if (return_value == 1)
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Error calling QccSPIHTSortingPass()");
	  goto QccError;
	}
      else
	if (return_value == 2)
	  break;
      
      return_value =
	QccSPIHTRefinementPass(&image_subband_pyramid,
			       buffer,
			       threshold,
			       &LSP,
			       stop,
			       QCCSPIHT_DECODE,
			       model,
			       0);
      if (return_value == 1)
	{
	  QccErrorAddMessage("(QccSPIHTDecode): Error calling QccSPIHTRefinementPass()");
	  goto QccError;
	}
      else
	if (return_value == 2)
	  break;
      
      threshold /= 2.0;
    }
  
  if (QccSPIHTDecodeInverseDWT(&image_subband_pyramid,
			       ((mask != NULL) ? &mask_subband_pyramid : NULL),
			       sign_array,
			       image,
			       image_mean,
			       wavelet,
			       perceptual_weights))
    {
      QccErrorAddMessage("(QccSPIHTDecode): Error calling QccSPIHTDecodeInverseDWT()");
      goto QccError;
    }
  
  return_value = 0;
  QccErrorClearMessages();
  goto QccReturn;
 QccError:
  return_value = 1;
 QccReturn:
  QccWAVSubbandPyramidFree(&image_subband_pyramid);
  QccWAVSubbandPyramidFree(&mask_subband_pyramid);
  QccWAVWaveletFree(&lazy_wavelet_transform);
  if (sign_array != NULL)
    {
      for (row = 0; row < image->num_rows; row++)
	if (sign_array[row] != NULL)
	  free(sign_array[row]);
      free(sign_array);
    }
  QccListFree(&LSP);
  QccListFree(&LIP);
  QccListFree(&LIS);
  QccENTArithmeticFreeModel(model);
  return(return_value);
}

⌨️ 快捷键说明

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