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

📄 user_huffman.h

📁 这是我做的毕业设计
💻 H
字号:


//////////////////////////
////////////////////////////huffman 编码后的数据存放地点
extern unsigned char JPEGHUFFMAN_DATA[MapHeight*MapWidth*2];

BYTE ComputeVLI(short int val);
void BuildSTDHuffTab(BYTE* nrcodes,BYTE* stdTab,HUFFCODE* huffCode);
void BuildVLITable();

void ProcessData(short(*YY)[8],short(*UU)[8],short(*VV)[8]);
void ProcessDU(short int* lpBuf,HUFFCODE* dcHuffTab,HUFFCODE* acHuffTab,short int* DC);
void WriteBits(HUFFCODE huffCode);
void WriteBitsYM(SYM2 sym);
void WriteBitsStream(unsigned short int value,BYTE codeLen);
void RLEComp(short int* lpbuf,ACSYM* lpOutBuf,BYTE *resultLen,int EndFlag);
SYM2 BuildSym2(short int value);

void WriteByte(BYTE val);
void WriteEOI(void);
void DE_STDHuffTab(BYTE* nrcodes,BYTE* stdTab,deHUFFCODE* dehuffCode);

void ini_jpeg_huf(){
	pVLITAB=VLI_TAB + 2047;      // 设置VLI_TAB的别名
	BuildVLITable();            // 计算VLI表   
	yDC=0;	uDC=0;	vDC=0;
	CodeLen=0;
	de_CodeLen=0;
	de_bytepos=0;
	
	BuildSTDHuffTab(STD_DC_Y_NRCODES,STD_DC_Y_VALUES,STD_DC_Y_HT);
	BuildSTDHuffTab(STD_AC_Y_NRCODES,STD_AC_Y_VALUES,STD_AC_Y_HT);
	BuildSTDHuffTab(STD_DC_UV_NRCODES,STD_DC_UV_VALUES,STD_DC_UV_HT);
	BuildSTDHuffTab(STD_AC_UV_NRCODES,STD_AC_UV_VALUES,STD_AC_UV_HT);
	//解码数据初始化////////////////////////////////////////
	DE_STDHuffTab(STD_DC_Y_NRCODES,STD_DC_Y_VALUES,deSTD_DC_Y_HT);
	DE_STDHuffTab(STD_AC_Y_NRCODES,STD_AC_Y_VALUES,deSTD_AC_Y_HT);
	DE_STDHuffTab(STD_DC_UV_NRCODES,STD_DC_UV_VALUES,deSTD_DC_UV_HT);
	DE_STDHuffTab(STD_AC_UV_NRCODES,STD_AC_UV_VALUES,deSTD_AC_UV_HT);
	/////////////////////////////////////////
	}


 void ProcessData(short(*YY)[8],short(*UU)[8],short(*VV)[8])
 { 
 
  short  *dctYBuf;            //Y信号FDCT编码临时缓冲
  short  *dctUBuf;            //U信号FDCT编码临时缓冲 
  short  *dctVBuf;            //V信号FDCT编码临时缓冲 
  //int mcuNum   = 0;             //存放MCU的数量 
 // extern short int yDC;             //Y信号的当前块的DC
 // extern short int uDC;             //U信号的当前块的DC
 // extern short int vDC;             //V信号的当前块的DC 
	dctYBuf=(short*)YY;
    dctUBuf=(short*)UU;  
  	dctVBuf=(short*)VV;
  	
    //huffman 编码
    ProcessDU(dctYBuf,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
    ProcessDU(dctYBuf+64,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
    ProcessDU(dctYBuf+128,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
    ProcessDU(dctYBuf+192,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
        
    ProcessDU(dctUBuf,STD_DC_UV_HT,STD_AC_UV_HT,&uDC); 
	ProcessDU(dctVBuf,STD_DC_UV_HT,STD_AC_UV_HT,&vDC);
}
////////////////
//哈夫曼编码函数
//* sigBuf  要编码的数组sigBuf[64],
//dcHuffTab DC huffman 表
//acHuffTab AC huffman 表
void ProcessDU(short int* sigBuf,HUFFCODE* dcHuffTab,HUFFCODE* acHuffTab,short int* DC)
 {
	int i    = 0;              //临时变量
	int j    = 0;
	int EndBit =0;
	short int diffVal = 0;                //DC差异值  
	BYTE acLen  = 0;//熵编码后AC中间符号的数量
	ACSYM acSym[64];              //AC中间符号缓冲 

	//对DC信号编码,写入文件
	//DPCM编码 
	diffVal = sigBuf[0] - *DC;
	*DC = sigBuf[0];
	//diffVal = sigBuf[0];
	//搜索Huffman表,写入相应的码字
	if (diffVal == 0)
	{  
		WriteBits(dcHuffTab[0]);  
	}
	else
	{   
		WriteBits(dcHuffTab[pVLITAB[diffVal]]);  
		WriteBitsYM(BuildSym2(diffVal));    
	}
  //对AC信号编码并写入文件
	for (i = 1; i < 64; i++) //判断ac信号是否全为0
	{
		if(sigBuf[i] !=0)
		EndBit=i;
	}
		if (EndBit == 0)                //如果全为0
		{
		WriteBits(acHuffTab[0x00]);           //写入块结束标记  
		}
		else
		{ 
		RLEComp(sigBuf,&acSym[0],&acLen,EndBit);         //对AC运行长度编码 
		#pragma MUST_ITERATE(1,63);
		for (j = 0; j < acLen; j++)           //依次对AC中间符号Huffman编码
			{   
			if (acSym[j].codeLen == 0)          //是否有连续16个0
				{   
	 			WriteBits(acHuffTab[0xF0]);         //写入(15,0)    
				}
			else
			{
				WriteBits(acHuffTab[acSym[j].zeroLen * 16 + acSym[j].codeLen]); //
				WriteBitsYM(BuildSym2(acSym[j].amplitude));    
			}   
		}
		if (EndBit != 63)              //如果最后位以0结束就写入EOB
		{
		WriteBits(acHuffTab[0x00]);          
		}
  	}
 }
////////////////////////////////////////
//写入
 void WriteBits(HUFFCODE huffCode)
	{  
		WriteBitsStream(huffCode.code,huffCode.length); 
	}
 
 void WriteBitsYM(SYM2 sym)
	{
		WriteBitsStream(sym.amplitude,sym.codeLen); 
	}
void WriteBitsStream(unsigned short int value,BYTE codeLen)
 { 
	char posval;//bit position in the bitstring we read, should be<=15 and >=0 
	posval=codeLen-1;
	while (posval>=0)
		{
		if (value & mask[posval])
			{
			bytenew|=mask[bytepos];
			}
		posval--;bytepos--;
		if (bytepos<0) 
			{ 
			if (bytenew==0xFF)
				{
				WriteByte(0xFF);
				WriteByte(0x00);
				}
				else
				{
				WriteByte(bytenew);
				}
			bytepos=7;bytenew=0;
			}
		}
 }
 
 void RLEComp(short int* lpbuf,ACSYM* lpOutBuf,BYTE *resultLen,int EndFlag)
 {  
	BYTE zeroNum     = 0;       //0行程计数器
	int EOBPos      = 0;       //EOB出现位置 
	unsigned int MAXZEROLEN = 15;          //最大0行程
	int i        = 0;      //临时变量
	int j        = 0;
	EOBPos =  EndFlag;          //设置起始位置,从最后一个信号开始
	
	for (i = 1; i <= EOBPos; i++)         //从第二个信号,即AC信号开始编码
	{
		if (lpbuf[zigzag[i]] == 0 && zeroNum < MAXZEROLEN)     //如果信号为0并连续长度小于15
		{
			++zeroNum;   
		}
		else
		{  
			lpOutBuf[j].zeroLen = zeroNum;       //0行程(连续长度)
			
			lpOutBuf[j].codeLen = pVLITAB[lpbuf[zigzag[i]]]; //ComputeVLI(lpbuf[i]);    //幅度编码长度
			lpOutBuf[j].amplitude = lpbuf[zigzag[i]];      //振幅      
			zeroNum = 0;           //0计数器复位
			(*resultLen)++;           //符号数量++
			++j;             //符号计数
		}
	} 
 }
 /////计算差异类的值
 SYM2 BuildSym2(short int value)
	{
	SYM2 Symbol;  
	
	Symbol.codeLen = pVLITAB[value];//ComputeVLI(value);              //获取编码长度
	Symbol.amplitude = 0;
	if (value >= 0)
	{
		Symbol.amplitude = value;
	}
	else
	{
		Symbol.amplitude = mask[Symbol.codeLen]+value-1;   
	  //Symbol.amplitude = (short int)(pow(2,Symbol.codeLen)-1) + value;  //计算反码
	}
	return Symbol;
	}


 //写入一个字节
 void WriteByte(BYTE val)
 {   
  //*(pDestJpeg+CodeLen)=val;
  *(JPEGHUFFMAN_DATA+CodeLen)=val;
  CodeLen++;
 }
 //写入图片数据结束 符号
 void WriteEOI(void)
 {
 	*(JPEGHUFFMAN_DATA+CodeLen)=0xFF;
 	CodeLen++;
 	*(JPEGHUFFMAN_DATA+CodeLen)=0xD9;
 	CodeLen++;
 }
 
 ////////////////////////////////////////////////////////
 //初始化函数
 
//extern BYTE VLI_TAB[4096];
//差异类取值的初始化

 void BuildVLITable()
 {
  short int i   = 0;

  for (i = 0; i < DC_MAX_QUANTED; ++i)
  {
   pVLITAB[i] = ComputeVLI(i);
  }

  for (i = DC_MIN_QUANTED; i < 0; ++i)
  {
   pVLITAB[i] = ComputeVLI(i);
  }
 }
 
 BYTE ComputeVLI(short int val)
 { 
  BYTE binStrLen = 0;
  val = _abs((int)val); 
  //获取二进制码长度   
  if(val == 1)
  {
   binStrLen = 1;  
  }
  else if(val >= 2 && val <= 3)
  {
   binStrLen = 2;
  }
  else if(val >= 4 && val <= 7)
  {
   binStrLen = 3;
  }
  else if(val >= 8 && val <= 15)
  {
   binStrLen = 4;
  }
  else if(val >= 16 && val <= 31)
  {
   binStrLen = 5;
  }
  else if(val >= 32 && val <= 63)
  {
   binStrLen = 6;
  }
  else if(val >= 64 && val <= 127)
  {
   binStrLen = 7;
  }
  else if(val >= 128 && val <= 255)
  {
   binStrLen = 8;
  }
  else if(val >= 256 && val <= 511)
  {
   binStrLen = 9;
  }
  else if(val >= 512 && val <= 1023)
  {
   binStrLen = 10;
  }
  else if(val >= 1024 && val <= 2047)
  {
   binStrLen = 11;
  }

  return binStrLen;
 }
 //////////////HUFFMAN 表 进行初始化
void BuildSTDHuffTab(BYTE* nrcodes,BYTE* stdTab,HUFFCODE* huffCode)
 {
  int i     = 0;             //临时变量
  int j     = 0;
  int k     = 0;
  unsigned short int code   = 0; 

  for (i = 1; i <= 16; i++)
  { 
   for (j = 1; j <= nrcodes[i]; j++)
   {   
    huffCode[stdTab[k]].code = code;
    huffCode[stdTab[k]].length = i;
    ++k;
    ++code;
   }
   code*=2;
  } 

  for (i = 0; i < k; i++)
  {
   huffCode[i].val = stdTab[i];  
  }
} 
 
 
 

⌨️ 快捷键说明

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