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

📄 dc_endecoding.c

📁 CCSDS空间图像图像压缩标准c源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
Implementation of CCSDS 122.0-B-1 Recommended Standard
Please note:
(1)	Before you download and use the program, you must read and agree the license agreement carefully. 
(2)	We supply the source code and program WITHOUT ANY WARRANTIES. The users will be responsible 
        for any loses or damages caused by the use of the source code and the program. 

Author: 
Hongqiang Wang
Department of Electrical Engineering
University of Nebraska-Lincoln
Email: hqwang@bigred.unl.edu, hqwang@eecomm.unl.edu

Your comment and suggestions are welcome. Please report bugs to me via email and I would greatly appreciate it. 
Jan. 21, 2007
*/ 
#include <math.h>
#include <stdlib.h>
#include "global.h"


long DeConvTwosComp(DWORD32 complement, 
					short leftmost);

extern void HeaderOutput(StructCodingPara *PtrCoding);
 
long DeConvTwosComp(DWORD32 complement, 
					short leftmost)
{
/*	To determine the integer value of a 2's complement code
Case #1            If the leftmost bit is 0:
      1.            Write down the integer value of the pure binary code
Case #2            If the leftmost bit is 1:
      1.            Complement the bits.
	  2.            Add 1.
	  3.            Determine the integer value of the pure binary code from step 2.
	  4.            Negate
	  E.g.            32-bit 2's complement code 1111 1111 1111 1111 1111 1111 1111 1011
		1.            0000 0000 0000 0000 0000 0000 0000 0100            Complement the bits.
		2.            0000 0000 0000 0000 0000 0000 0000 0101     Add 1.
        3.            5                      Determine the integer value of the pure binary code from step 2.
		4.            -5                                                                     Negate*/

	DWORD32 temp = 0; 
	long Original;
	short  i = 0;
	if((leftmost >= sizeof(DWORD32) * 8) ||
		(leftmost == 0) || (leftmost == 1))
		ErrorMsg(BPE_DATA_ERROR);
	if (((1 << (leftmost-1)) & complement) == 0)
		return (long)complement;
	else
	{
		temp = 0;
		for( i = 0; i < leftmost; i ++)
		{
			temp <<= 1;
			temp ++;
		}
		Original = -(long)(((~complement) & temp) + 1);
		return Original;
	}
}





DWORD32 ConvTwosComp(long Original, 
				   short leftmost);


DWORD32 ConvTwosComp(long Original, 
				   short leftmost)
{
/*		To determine the 2's complement code for a number.
		Case #1            If the number is >= 0:
			1.            Write down the number's pure binary code
		Case #2            If the number is < 0:
	    	1.            Write down the pure binary code for the integer without its sign
	    	2.            Complement the bits
			3.            Add 1
			
		E.g.            32-bit 2's complement of -5
			1.            0000 0000 0000 0000 0000 0000 0000 0101  32-bit pure binary of 5
			2.            1111 1111 1111 1111 1111 1111 1111 1010      complement
			3.            1111 1111 1111 1111 1111 1111 1111 1011  add 1*/

	DWORD32 temp;
	DWORD32 complement;
	short i = 0;

	if(leftmost == 1)
	 return 0;

	if((leftmost >= sizeof(DWORD32) * 8) || (leftmost == 0))
	{
		ErrorMsg(BPE_DATA_ERROR);
	}

	if (Original >= 0)
		return (DWORD32) Original;
	else
	{
		complement = ~(DWORD32) (-Original);
		temp = 0;
		for ( i = 0; i < leftmost; i ++)
		{
			temp <<= 1;
			temp ++;
		}
		complement &= temp;
		complement ++;
		return complement;
	}
}



void DCEncoder(StructCodingPara *PtrCoding, 
						   BitPlaneBits *BlockInfo, 
						   int StartIndex,
						   int gaggles, 
						   int Max_k, 
						   int ID_Length)
{
	int i = 0; 
	int k = 0; 
	int min_k = 0;
	int temp_DC = 0;
		
	DWORD32 min_bits = 0xFFFF; 
	DWORD32 total_bits = 0; 

	if (gaggles == 0)
		return;
	

	if(PtrCoding->PtrHeader->Header.Part3.OptDCSelect == TRUE)
	{
		//calculate  the uncoded:
		WORD16 uncoded_bits = PtrCoding->N * gaggles;
		for ( k = 0; k <= Max_k; k ++)
		{
			total_bits = k * gaggles;

			for (i = StartIndex; i < StartIndex + gaggles; i ++)
				total_bits += ((BlockInfo[i].MappedDC >> k ) + 1);			
			
			if( total_bits < min_bits)
			{
				min_bits = total_bits;
				min_k = k;
			}
		}

		if (min_bits < uncoded_bits)
		{
			// Get the one that gives the minimum number of bits. 
			BitsOutput(PtrCoding, min_k, ID_Length);
			if(StartIndex == 1)
				BitsOutput(PtrCoding, BlockInfo[0].MappedDC, PtrCoding->N);
			for (i = StartIndex; i < StartIndex + gaggles; i ++)
			{
				temp_DC = BlockInfo[i].MappedDC;
				temp_DC >>= min_k;	
				temp_DC++;
				// determine the length of the symbol
				BitsOutput(PtrCoding, 1, temp_DC);	
			}
			
			for (i = StartIndex; i < StartIndex + gaggles; i ++)
				BitsOutput(PtrCoding, BlockInfo[i].MappedDC, min_k);
		}
		else
		{		
			UCHAR8 ones = ~0;			
			BitsOutput(PtrCoding, ones, ID_Length);			
			if(StartIndex == 1)
				BitsOutput(PtrCoding, BlockInfo[0].MappedDC, PtrCoding->N);
			for (i = StartIndex; i < StartIndex + gaggles; i ++)
				BitsOutput(PtrCoding, BlockInfo[i].MappedDC, PtrCoding->N);
			return;
		}
	}
	else
	{
		// Using so called Heuristic procedure. 
		int delta = 0;
		for (i = StartIndex; i < StartIndex + gaggles; i ++)
			delta += BlockInfo[i].MappedDC;
		if (64 *  delta >= 23 * gaggles * PtrCoding->N)
		{
			// uncoded/
			UCHAR8 ones = ~0;			
			BitsOutput(PtrCoding, ones, ID_Length);
			for (i = StartIndex; i < StartIndex + gaggles; i ++)
				BitsOutput(PtrCoding, BlockInfo[i].MappedDC, PtrCoding->N);
			return;
		}
		else if (207 * gaggles > 128 * delta)
		{
			k = 0;
		}
		else if (gaggles * (1<<(PtrCoding->N - 5)) <= 128 * delta + 49 * gaggles)
		{
			k = PtrCoding->N - 2;
		}
		else
		{
			long sum = 128 * delta + 49 * gaggles; 
			k = 0;
			while (gaggles * (1 << (k + 7)) <= sum)
				k++;
			k--;
		}	
		min_k = k; 
		BitsOutput(PtrCoding, min_k, ID_Length);

		if(StartIndex == 1)
			BitsOutput(PtrCoding, BlockInfo[0].MappedDC, PtrCoding->N);

		for (i = StartIndex; i < StartIndex + gaggles; i ++)
		{
			temp_DC = BlockInfo[i].MappedDC;
			temp_DC >>= min_k;	
			temp_DC++;
			// determine the length of the symbol
			BitsOutput(PtrCoding, 1, temp_DC);	
		}	
		for (i = StartIndex; i < StartIndex + gaggles; i ++)
			BitsOutput(PtrCoding, BlockInfo[i].MappedDC, min_k);
	}	
}


void DCEntropyEncoder(StructCodingPara* PtrCoding, 
					  BitPlaneBits *BlockInfo)
{
	int Max_k = 0; 
	int ID_Length = 0;
	int index = 0;
	int bit_num= 0;
	int counter = 0 ; // initial value is 15.
	UINT32 GaggleStartIndex = 0;
	UINT32 gaggles = 0;

	if (PtrCoding->N  == 2) 
	{
		Max_k = 0;
		ID_Length = 1;
	}
	else if (PtrCoding->N <=4)
	{
		Max_k = 2;
		ID_Length = 2;	
	}
	else if (PtrCoding->N <=8)
	{
		Max_k = 6;
		ID_Length = 3;	
	}
	else if (PtrCoding->N <=10)
	{
		Max_k = 8;
		ID_Length = 4;	
	}

	// determine which one results in the minimum bits used. 
	// adaptive entropy coder. We will select the one results in
	// the minimum number of bits. 
	// determine the first 15 DC coefficient. 
	
	gaggles = GAGGLE_SIZE - 1;
	if (PtrCoding->PtrHeader->Header.Part3.S_20Bits < gaggles)
		gaggles = PtrCoding->PtrHeader->Header.Part3.S_20Bits - 1;
	// output the first reference symbol:
	GaggleStartIndex = 1;
	DCEncoder(PtrCoding, BlockInfo, GaggleStartIndex,
		gaggles, Max_k, ID_Length);

	GaggleStartIndex += gaggles;
	gaggles = GAGGLE_SIZE;	

	while(PtrCoding->PtrHeader->Header.Part3.S_20Bits - GaggleStartIndex >= gaggles)
	{		 
		DCEncoder(PtrCoding, BlockInfo, GaggleStartIndex,
			gaggles, Max_k, ID_Length);
		GaggleStartIndex += gaggles;	
	}	

	gaggles = PtrCoding->PtrHeader->Header.Part3.S_20Bits - GaggleStartIndex;		
	DCEncoder(PtrCoding, BlockInfo, GaggleStartIndex,
			gaggles, Max_k, ID_Length);

	if(PtrCoding->PtrHeader->Header.Part1.BitDepthAC_5Bits < 
		PtrCoding->QuantizationFactorQ)
	{
		UINT32 i;
		UINT32 k;
		if (PtrCoding->PtrHeader->Header.Part4.DWTType == INTEGER_WAVELET)
		{ // considering the scaling effect. 

			int Valid_DC_Length = 0; 
			Valid_DC_Length = PtrCoding->QuantizationFactorQ
				- (1 <<PtrCoding->PtrHeader->Header.Part4.CustomWtLL3_2bits);
			if (Valid_DC_Length == 0)
				return;

			if (PtrCoding->PtrHeader->Header.Part1.BitDepthAC_5Bits >
				(1 <<PtrCoding->PtrHeader->Header.Part4.CustomWtLL3_2bits))
			{
				for (i = 0; i < (UINT32)(PtrCoding->QuantizationFactorQ
					- PtrCoding->PtrHeader->Header.Part1.BitDepthAC_5Bits); i ++)
				{
					for( k = 0; k < PtrCoding->PtrHeader->Header.Part3.S_20Bits; k++)
						BitsOutput(PtrCoding, BlockInfo[k].DCRemainder >>(PtrCoding->QuantizationFactorQ - i + 1), 1);
				}
			}
			else 
			{
				for (i = 0; i < (UINT32) (PtrCoding->QuantizationFactorQ -	PtrCoding->PtrHeader->Header.Part4.CustomWtLL3_2bits) ; i ++)
				{
					for( k = 0; k < PtrCoding->PtrHeader->Header.Part3.S_20Bits; k++)
						BitsOutput(PtrCoding, BlockInfo[k].DCRemainder >>(PtrCoding->QuantizationFactorQ - i - 1), 1);
						//BitsOutput(PtrCoding, BlockInfo[k].DCRemainder >>(PtrCoding->QuantizationFactorQ - i ), 1);
				}
			}
		}
		else  // floating wavelet does not have scaling problem. 
			// output the bit directly. 
			for ( i = 0; i < (UINT32) (PtrCoding->QuantizationFactorQ - PtrCoding->PtrHeader->Header.Part1.BitDepthAC_5Bits); i ++)
			{
				for( k = 0; k < PtrCoding->PtrHeader->Header.Part3.S_20Bits; k++)
				BitsOutput(PtrCoding, BlockInfo[k].DCRemainder>>(PtrCoding->QuantizationFactorQ - i - 1), 1);

			}
	}		
	return;
}

void DCGaggleDecoding(StructCodingPara *PtrCoding,						   
						   BitPlaneBits *BlockInfo,  
						   int StartIndex,
						   int gaggles, 
						   int Max_k, 
						   short ID_Length)
{
	short i = 0; 
	short j = 0; 
	int counter = 0;
	UCHAR8 ones = ~0;
	UCHAR8 temp_bit = 0;
	UCHAR8 min_k;
	DWORD32 TempWord =0;
	BOOL uncoded = FALSE;
	if (gaggles == 0)
		return;

	ones = ((ones << (8-ID_Length)) >>((8-ID_Length)));  
	
	// makes the least ID_Length bits to ones.
	BitsRead(PtrCoding, &TempWord, ID_Length);
	min_k = (UCHAR8) TempWord;
	
	if(ID_Length == 1 && min_k == 1)
		uncoded = TRUE;	
	else if(ID_Length == 2 && min_k == 3)
		uncoded = TRUE;
	else if(ID_Length == 3 && min_k == 7)
		uncoded = TRUE;
	else if(ID_Length == 4 && min_k == 15)
		uncoded = TRUE;	

	if(StartIndex == 1)
		// first read the reference 
	{
		BitsRead(PtrCoding, &TempWord, PtrCoding->N);
		BlockInfo[0].MappedDC = TempWord;
	}

// if uncoded. read the symbols directly. 
	if(uncoded == TRUE)
	{	
		for (i = StartIndex; i < StartIndex + gaggles; i ++)
		{
			BitsRead(PtrCoding, &TempWord, PtrCoding->N);
			BlockInfo[i].MappedDC = TempWord;
		}
		return;
	}

// If coded. read the first part of each DC first,
	
	for( i = StartIndex; i < StartIndex + gaggles; i ++)
	{		
		counter = 0;
		// rice decoding. determined 0s
		for(;;)
		{
			BitsRead(PtrCoding, &TempWord, 1);
			if(TempWord == 0)
			{
				counter ++;
				if (PtrCoding->RateReached == TRUE)
					break;
			}
			else
				break;
		}
		if (PtrCoding->RateReached == TRUE)
			break;
		BlockInfo[i].MappedDC = counter;
		BlockInfo[i].MappedDC <<= min_k;
	}

	if (PtrCoding->RateReached == TRUE)
		return;
// then the second part. 
	for( i = StartIndex; i < StartIndex + gaggles; i ++)
	{	
		j = BitsRead(PtrCoding, &TempWord, min_k);		
		BlockInfo[i].MappedDC += TempWord;
		if (PtrCoding->RateReached == TRUE)
			break;
	}
	return;
}



short DCEntropyDecoder(StructCodingPara *PtrCoding, 
					   BitPlaneBits *BlockInfo)
{
	int Max_k = 0;
	int gaggles = 15;
	int GaggleStartIndex = 0;

⌨️ 快捷键说明

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