📄 dspjpeg.c
字号:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "fdct_8x8.h"
#include "jpegfromat.h"
const int DCTSIZE = 8;
const int DCTBLOCKSIZE = 64;
const unsigned int std_Y_QT[64] =
{
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109,103,77,
24, 35, 55, 64, 81, 104,113,92,
49, 64, 78, 87, 103,121,120,101,
72, 92, 95, 98, 112,100,103,99
};
const unsigned int std_UV_QT[64] =
{
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99 ,99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
const int FZBT[64] =
{
0, 1, 5, 6, 14,15,27,28,
2, 4, 7, 13,16,26,29,42,
3, 8, 12,17,25,30,41,43,
9, 11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63
};
extern volatile unsigned int *hpiBuffer;
unsigned int buffWidth=360;
unsigned int buffHeight=288;
unsigned int* HeadBuff;
volatile BYTE* pDestJpeg;
BYTE* ppYBuff;
BYTE* ppUBuff;
BYTE* ppVBuff;
volatile unsigned int CodeLen;
extern BYTE VLI_TAB[4096];
extern BYTE* pVLITAB;
extern float YQT_DCT[64];
extern float UVQT_DCT[64];
extern HUFFCODE STD_DC_Y_HT[12];
extern HUFFCODE STD_DC_UV_HT[12];
extern HUFFCODE STD_AC_Y_HT[256];
extern HUFFCODE STD_AC_UV_HT[256];
//extern const BYTE FZBT[64];
void DivBuff(volatile BYTE* pBuf,BYTE*spBuf,int K);
void WriteHead(unsigned int* restrict lpBuf);
void ProcessData(BYTE* lpYBuf,BYTE* lpUBuf,BYTE* lpVBuf);
void ProcessDU(short int* lpBuf, const unsigned int* quantTab,HUFFCODE* dcHuffTab,HUFFCODE* acHuffTab,short int* DC);
//void FDCT(float* lpBuff);
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);
WORD Intel2Moto(WORD val);
void WriteByte(BYTE val);
void WriteEOI(void);
void Standard(short int *lpBuf,const unsigned int* quantTab);
void DspJpeg( volatile BYTE * inBuffer,int Q,int num)
{
CodeLen=0;
ppYBuff=(BYTE *)0xB06B3700;
ppUBuff=(BYTE *)0xB06CCC00;
ppVBuff=(BYTE *)0xB06E6100;
//DATAYUV111(inBuffer,pYBuff,pUBuff,pVBuff);
DivBuff(inBuffer,ppYBuff,1);
DivBuff(inBuffer,ppUBuff,0);
DivBuff(inBuffer,ppVBuff,2);
HeadBuff=(unsigned int *)(0xB0658800+num*20480);
//CodeLen=0;
WriteHead(JpegHead);
pDestJpeg=(BYTE *)(0xB0658A70+num*20480);
*pDestJpeg=0x00;
CodeLen=1;
ProcessData(ppYBuff,ppUBuff,ppVBuff);
WriteEOI();
hpiBuffer[5]=CodeLen+624;
}
/*void DATAYUV111(BYTE* pBuf, BYTE* pYBuff, BYTE* pUBuff, BYTE* pVBuff)
{
int i,j;
for(i=0;i<288;i++)
for(j=0;j<360;j++)
{
pYBuff[j+360*i]=pBuf[4+i*361*4+j*4+1];
pVBuff[j+360*i]=pBuf[4+i*361*4+j*4+2];
pUBuff[j+360*i]=pBuf[4+i*361*4+j*4];
}
}*/
void DivBuff(volatile BYTE* pBuf,BYTE*spBuf,int K)
{
int i = 0; //临时变量
int j = 0;
int m = 0;
//int n = 0;
int tempS = 0;
int tempP = 0;
for (i = 0; i <36 ; i++) //循环Y方向切割数量
{
for (j = 0; j < 45; j++) //循环X方向切割数量
{
for(m = 0; m < 8; m++) //计算单元信号块的首行偏移量
{
//spBuf[i*2880+j*64+m*8+n]=*(pBuf+4+i*11552+j*32+m*1444+4*n+K);
tempS=i*2880+j*64+m*8;
tempP=4+i*11552+j*32+m*1444+K;
spBuf[tempS]=*(pBuf+tempP);
spBuf[tempS+1]=*(pBuf+tempP+4);
spBuf[tempS+2]=*(pBuf+tempP+8);
spBuf[tempS+3]=*(pBuf+tempP+12);
spBuf[tempS+4]=*(pBuf+tempP+16);
spBuf[tempS+5]=*(pBuf+tempP+20);
spBuf[tempS+6]=*(pBuf+tempP+24);
spBuf[tempS+7]=*(pBuf+tempP+28);
}
}
}
}
void WriteHead(unsigned int* restrict lpBuf)
{
int i;
//int n=0;
for(i=0;i<156;i++)
{
//n=4*i;
*(HeadBuff+i)=JpegHead[i];
//*(HeadBuff+n+1)=JpegHead[n+1];
//*(HeadBuff+n+2)=JpegHead[n+2];
//*(HeadBuff+n+3)=JpegHead[n+3];
}
}
void ProcessData(BYTE* lpYBuf,BYTE* lpUBuf,BYTE* lpVBuf)
{
int yBufLen = buffHeight * buffWidth; //亮度Y缓冲长度
short int dctYBuf[64]; //Y信号FDCT编码临时缓冲
short int dctUBuf[64]; //U信号FDCT编码临时缓冲
short int dctVBuf[64]; //V信号FDCT编码临时缓冲
//int mcuNum = 0; //存放MCU的数量
short int yDC = 0; //Y信号的当前块的DC
short int uDC = 0; //U信号的当前块的DC
short int vDC = 0; //V信号的当前块的DC
int i = 0; //临时变量
int j = 0;
//mcuNum = (buffHeight * buffWidth )/ (64 ); //计算MCU的数量
for (i=0; i < yBufLen; i += 64)
{
for (j = 0; j < 64; j++)
{
dctYBuf[j] = lpYBuf[i + j] -128;
dctUBuf[j] = lpUBuf[i + j] -128;
dctVBuf[j] = lpVBuf[i + j] -128;
}
ProcessDU(dctYBuf,std_Y_QT,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
ProcessDU(dctUBuf,std_UV_QT,STD_DC_UV_HT,STD_AC_UV_HT,&uDC);
ProcessDU(dctVBuf,std_UV_QT,STD_DC_UV_HT,STD_AC_UV_HT,&vDC);
}
}
void ProcessDU(short int* lpBuf,const unsigned int* quantTab,HUFFCODE* dcHuffTab,HUFFCODE* acHuffTab,short int* DC)
{
int i = 0; //临时变量
int j = 0;
unsigned int K = 0;
int EndBit =0;
short int diffVal = 0; //DC差异值
BYTE acLen = 0;//熵编码后AC中间符号的数量
short int sigBuf[64]; //量化后信号缓冲
ACSYM acSym[64]; //AC中间符号缓冲
//FDCT(lpBuf); //离散余弦变换
fdct_8x8(lpBuf,1);
for (i = 0; i < 64; i++) //量化操作
{
K =FZBT[i];
sigBuf[K] = lpBuf[i]*2/quantTab[i]+0.5;
}
//Standard(sigBuf,quantTab);
//对DC信号编码,写入文件
//DPCM编码
diffVal = sigBuf[0] - *DC;
*DC = 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 FDCT(float* lpBuff)
{
float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
float tmp10, tmp11, tmp12, tmp13;
float z1, z2, z3, z4, z5, z11, z13;
float* dataptr;
int ctr;
dataptr = lpBuff;
for (ctr = 7; ctr >= 0; ctr--)
{
tmp0 = dataptr[0] + dataptr[7];
tmp7 = dataptr[0] - dataptr[7];
tmp1 = dataptr[1] + dataptr[6];
tmp6 = dataptr[1] - dataptr[6];
tmp2 = dataptr[2] + dataptr[5];
tmp5 = dataptr[2] - dataptr[5];
tmp3 = dataptr[3] + dataptr[4];
tmp4 = dataptr[3] - dataptr[4];
tmp10 = tmp0 + tmp3; // phase 2
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; // phase 3
dataptr[4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * (0.707106781); // c4
dataptr[2] = tmp13 + z1; // phase 5
dataptr[6] = tmp13 - z1;
tmp10 = tmp4 + tmp5; //phase 2
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
z5 = (tmp10 - tmp12) * ( 0.382683433); // c6
z2 = (0.541196100) * tmp10 + z5; // c2-c6
z4 = (1.306562965) * tmp12 + z5; // c2+c6
z3 = tmp11 * (0.707106781); // c4
z11 = tmp7 + z3; // phase 5
z13 = tmp7 - z3;
dataptr[5] = z13 + z2; // phase 6
dataptr[3] = z13 - z2;
dataptr[1] = z11 + z4;
dataptr[7] = z11 - z4;
dataptr += DCTSIZE; //将指针指向下一行
}
dataptr = lpBuff;
for (ctr = 7; ctr >= 0; ctr--)
{
tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
tmp10 = tmp0 + tmp3; //phase 2
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[DCTSIZE*0] = tmp10 + tmp11; // phase 3
dataptr[DCTSIZE*4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * (0.707106781); // c4
dataptr[DCTSIZE*2] = tmp13 + z1; //phase 5
dataptr[DCTSIZE*6] = tmp13 - z1;
tmp10 = tmp4 + tmp5; // phase 2
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
z5 = (tmp10 - tmp12) * (0.382683433); //c6
z2 = (0.541196100) * tmp10 + z5; //c2-c6
z4 = (1.306562965) * tmp12 + z5; //c2+c6
z3 = tmp11 * (0.707106781); //c4
z11 = tmp7 + z3; //phase 5
z13 = tmp7 - z3;
dataptr[DCTSIZE*5] = z13 + z2; // phase 6
dataptr[DCTSIZE*3] = z13 - z2;
dataptr[DCTSIZE*1] = z11 + z4;
dataptr[DCTSIZE*7] = z11 - z4;
++dataptr; // 将指针指向下一列
}
}*/
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(0);
}
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 = EOBPos; i > 0; i--) //从最后的AC信号数0的个数
{
if (lpbuf[i] == 0) //判断数据是否为0
{
--EOBPos; //向前一位
}
else //遇到非0,跳出
{
break;
}
}*/
for (i = 1; i <= EOBPos; i++) //从第二个信号,即AC信号开始编码
{
if (lpbuf[i] == 0 && zeroNum < MAXZEROLEN) //如果信号为0并连续长度小于15
{
++zeroNum;
}
else
{
lpOutBuf[j].zeroLen = zeroNum; //0行程(连续长度)
lpOutBuf[j].codeLen = pVLITAB[lpbuf[i]]; //ComputeVLI(lpbuf[i]); //幅度编码长度
lpOutBuf[j].amplitude = lpbuf[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;
}
WORD Intel2Moto(WORD val)
{
BYTE highBits;
BYTE lowBits ;
highBits = (BYTE)(val / 256);
lowBits = (BYTE)(val % 256);
return lowBits * 256 + highBits;
}
void WriteByte(BYTE val)
{
*(pDestJpeg+CodeLen)=val;
CodeLen++;
}
void WriteEOI(void)
{
*(pDestJpeg+CodeLen)=0xFF;
CodeLen++;
*(pDestJpeg+CodeLen)=0xD9;
CodeLen++;
}
void Standard(short int *lpBuf,const unsigned int* quantTab)
{
int F0, F1, F2, F3, F4, F5, F6, F7;
int i;
short int *dataBuf;
dataBuf=lpBuf;
for(i=0;i<8;i=i+8)
{
F0=dataBuf[0]*quantTab[0];
F1=dataBuf[1]*quantTab[1];
F2=dataBuf[2]*quantTab[2];
F3=dataBuf[3]*quantTab[3];
F4=dataBuf[4]*quantTab[4];
F5=dataBuf[5]*quantTab[5];
F6=dataBuf[6]*quantTab[6];
F7=dataBuf[7]*quantTab[7];
dataBuf[0]=F0 >> 15;
dataBuf[1]=F1 >> 15;
dataBuf[2]=F2 >> 15;
dataBuf[3]=F3 >> 15;
dataBuf[4]=F4 >> 15;
dataBuf[5]=F5 >> 15;
dataBuf[6]=F6 >> 15;
dataBuf[7]=F7 >> 15;
dataBuf +=8;
quantTab +=8;
}
/*for(i=0;i<64;i++)
{
F0=dataBuf[i]*quantTab[i];
dataBuf[i]=F0 >> 15;
}*/
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -