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

📄 arcode.c

📁 基于嵌入式零树小波编码的C语言程序实现。
💻 C
📖 第 1 页 / 共 2 页
字号:
		ar->Low = (ar->Low<<1);  
		ar->High = (ar->High<<1) + 1; 
	}
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderOpenFile(AREncoder *ar, char *filename)
{
	if (!ar->Closed){
		ARCoderError("File already opened.");
	}

	ar->f = fopen(filename, "wb");
	if (ar->f == NULL){
		ARCoderError("Fail to open file");
	}
	ar->Closed = 0;
	ar->ByteCounter = 0;
  	ar->SymbolCounter = ar->Low = ar->BitsToFollow = ar->BitBuffer = 0;
	ar->BitIndex = 8;  
	ar->High = TopValue;
	
	return;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderOpenAppendFile(AREncoder *ar, char * filename)
{
	if (!ar->Closed){
		ARCoderError("File already opened.");
	}

	ar->f = fopen(filename, "a+b");
   if (ar->f == NULL){
		ARCoderError("Fail to open file");
	}

	ar->Closed = 0;
	ar->ByteCounter = 0;
	ar->SymbolCounter = ar->Low = ar->BitsToFollow = ar->BitBuffer = ar->Closed = 0;
	ar->BitIndex = 8;  
	ar->High = TopValue;

	return;
}


/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderCloseFile(AREncoder *ar)
{
	if (ar->Closed){
		return;
	}

	AREncoderFlush(ar);

	if (fclose(ar->f)==EOF){
		ARCoderError("Fail to close.");
	}

	ar->Closed = 1;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderFlush(AREncoder *ar)
{
	if (ar->Closed){
		return;
	}
	
	ar->BitsToFollow++;
	AREncoderBitPlusFollow(ar, ar->Low >= FirstQtr);

	//if (ar->BitIndex<8){
		if (putc(ar->BitBuffer >> ar->BitIndex, ar->f) == EOF){
			ARCoderError("Fail to write.");
		}
		ar->ByteCounter++;  
	//}

	return;	
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderEncodeBit(AREncoder *ar, int bit)
{
	long lm1 = ar->Low-1;
	long range = ar->High-lm1;
	if (bit){
		ar->Low += (range >> 1);
	}
	else{
		ar->High = lm1 +(range>>1);
	}

	AREncoderUpdateInterval(ar);

	return;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderEncodeSymbol(AREncoder *ar, int bit, HistoBi *h)
{
	long lm1 = ar->Low -1;
	long range = (ar->High-lm1) * h->c0 / (h->c0+h->c1);

	if (bit){
		ar->Low += range;
	}
	else{
		ar->High = lm1 + range;
	}

	HistoBiUpdate(h, bit);
	AREncoderUpdateInterval(ar);

	return;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderEncodeMSymbol(AREncoder *ar, int s, Histo *h)
{
	long range = ar->High - ar->Low + 1;
	long countLeft = HistoGetCumul(h, s-1);
	long count = HistoGetCumul(h, s);
	
	ar->High= ar->Low+(range*count)/h->TotalFreq - 1;
	ar->Low = ar->Low+(range*countLeft)/h->TotalFreq;
	
	HistoUpdate(h, 1, s);
	
	AREncoderUpdateInterval(ar);
	
	return;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderEncodeBits(AREncoder *ar, int bits, int word)
{
	int i, t;

	unsigned int mask=1<<(bits-1);
	
	for (i=bits-1; i>=0; i--){
		t = (word & mask ? 1 : 0);
		AREncoderEncodeBit(ar, (word & mask ? 1 : 0));		
		mask >>= 1;
	}
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int AREncoderBitsOutput(AREncoder *ar)
{
	return (ar->ByteCounter<<3) + 10 + ar->BitsToFollow - ar->BitIndex;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
AREncoder* AREncoderAlloc(void)
{
	AREncoder *ar;

	if ((ar=(AREncoder *)malloc(sizeof(AREncoder)))==NULL){
		return NULL;
	}
	ar->Closed = 1;
	return ar;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void AREncoderDealloc(AREncoder *ar)
{
	if (!ar->Closed){
		ARCoderWarning("File not closed.");
		AREncoderCloseFile(ar);
	}
	free(ar);
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
/* Arithmetic Decoder Functions */

void ARDecoderInputByte(ARDecoder *ar)
{
	if ((ar->BitBuffer = getc(ar->f)) == EOF){
		if (++ar->ExtraBits > CodeValueBits - 2){
			ARCoderError("End of file reached");
		}		
	}
	else{
		ar->BitIndex = 8;  	
		++ar->ByteCounter;
	}
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARDecoderUpdateInterval(ARDecoder *ar)
{
	++ar->SymbolCounter;

	for (;;){
		if (ar->High < Half){
			/* nothing */
		}
		else if (ar->Low >= Half) {
			ar->Value -= Half;
			ar->Low -= Half;  
			ar->High -= Half; 
		}
		else if ((ar->Low >= FirstQtr) && (ar->High < ThirdQtr)){
			ar->Value -= FirstQtr;  
			ar->Low -= FirstQtr;  
			ar->High -= FirstQtr; 
		}
		else{
			break;
		}
		
		ar->Low <<= 1;  
		ar->High += ar->High + 1;
		ar->Value <<= 1;

		if (!ar->BitIndex){
			ARDecoderInputByte(ar);
		}
		if (ar->BitBuffer & 1){
			ar->Value++;
		}
		ar->BitBuffer>>=1;
		ar->BitIndex--;
	}
}


/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARDecoderOpenFile(ARDecoder *ar, char* filename)
{
	int i;

	if (!ar->Closed){
		ARCoderError("File already opened.");
	}
	
	ar->f = fopen(filename, "rb");
	if (ar->f == NULL){
		ARCoderError("Fail to open file");
	}
	
	ar->Closed = 0;
	ar->ByteCounter = 0;
	ar->SymbolCounter = ar->Low = ar->Value = ar->BitIndex = ar->ExtraBits = 0;
	ar->High = TopValue;

	for (i=0; i<CodeValueBits; i++){
		if (!ar->BitIndex){
			ARDecoderInputByte(ar);
		}
		ar->Value += ar->Value + (ar->BitBuffer & 1);
		ar->BitBuffer >>=1;
		ar->BitIndex--;
	}
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARDecoderOpenFileOffset(ARDecoder *ar, char* filename, int OffsetBytes)
{
	int i;

	if (!ar->Closed){
		ARCoderError("File already opened.");
	}

	ar->f = fopen(filename, "rb");
	if (ar->f == NULL){
		ARCoderError("Fail to open file");
	}

	fseek(ar->f, OffsetBytes, SEEK_SET);
	
	ar->Closed = 0;
	ar->ByteCounter = 0;
	ar->SymbolCounter = ar->Low = ar->Value = ar->BitIndex = ar->ExtraBits = 0;
	ar->High = TopValue;

	for (i=0; i<CodeValueBits; i++){
		if (!ar->BitIndex){
			ARDecoderInputByte(ar);
		}
		ar->Value += ar->Value + (ar->BitBuffer & 1);
		ar->BitBuffer >>=1;
		ar->BitIndex--;
	}
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARDecoderCloseFile(ARDecoder *ar)
{
	if (ar->Closed){
		return;
	}

	if (fclose(ar->f)==EOF){
		ARCoderError("Fail to close.");
	}

	ar->Closed = 1;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int ARDecoderDecodeBit(ARDecoder *ar)
{
	long lm1 = ar->Low - 1;
	long range = ar->High - lm1;
	int bit = (int) (((( ar->Value - lm1) << 1) - 1) / range);
	
	if (bit){
		ar->Low += (range >> 1); 
	}
	else{
		ar->High = lm1 + (range >> 1);
	}

	ARDecoderUpdateInterval(ar);

	return bit;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int ARDecoderDecodeSymbol(ARDecoder *ar, HistoBi *h)
{
	long lm1 = ar->Low - 1;
	long range = ar->High - lm1;

	int cum = (int)(((ar->Value - lm1) * (h->c0+h->c1) - 1) / range);

	int bit = (cum >= h->c0);
	range =  range * h->c0 / (h->c0+h->c1);

	if (bit){
		ar->Low += range;
	}
	else{
		ar->High = lm1 + range;
	}
	
	HistoBiUpdate(h, bit);
	ARDecoderUpdateInterval(ar);
	
	return bit;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int ARDecoderDecodeMSymbol(ARDecoder *ar, Histo *h)
{
	long range, target, countLeft, count;
   int s;

   range = ar->High - ar->Low + 1;
   
   target = ((int)(ar->Value-ar->Low+1)*h->TotalFreq-1)/(range);
	
   s = HistoGetSymbol(h, target);
	
   countLeft = HistoGetCumul(h, s-1);
   count = HistoGetCumul(h, s);

	ar->High = ar->Low+(range*count)/h->TotalFreq-1;
	ar->Low = ar->Low+(range*countLeft)/h->TotalFreq;
   	
	HistoUpdate(h, 1, s);

	ARDecoderUpdateInterval(ar);
	
	return s;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int ARDecoderDecodeBits(ARDecoder *ar, int bits)
{
	int val=0, i;
	
	for (i=bits-1; i>=0; i--){
		val = (val<<1) + ARDecoderDecodeBit(ar);
	}

	return val;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
int ARDecoderBitsInput(ARDecoder *ar)
{
	return (ar->ByteCounter<<3) - ar->BitIndex + 8;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
ARDecoder* ARDecoderAlloc(void)
{
	ARDecoder *ar;

	if ((ar=(ARDecoder *)malloc(sizeof(ARDecoder)))==NULL){
		return NULL;
	}
	ar->Closed = 1;
	return ar;
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARDecoderDealloc(ARDecoder *ar)
{
	if (!ar->Closed){
		ARCoderWarning("File not closed.");
		ARDecoderCloseFile(ar);
	}
	free(ar);
}


/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARCoderWarning(char *fmt, ...)
{
	va_list argptr;
	
	va_start( argptr, fmt );
	printf( "ARCoderWarning: " );
	vprintf( fmt, argptr );
	va_end( argptr );
	exit( -1 );
}

/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/
void ARCoderError(char *fmt, ...)
{
	va_list argptr;
	
	va_start( argptr, fmt );
	printf( "ARCoderError: " );
	vprintf( fmt, argptr );
	va_end( argptr );
	exit( -1 );
}
/*--------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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