📄 user_huffman.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 + -