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

📄 dspjpeg.c

📁 DSP GEPE 压缩算法
💻 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 + -