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

📄 jpeg_compress.c

📁 bf533平台图像采集程序
💻 C
字号:
#include "jcodestruct.h"
#include "jpegstuct.h"
#include "jcfunction.h"
#include "bitstream.h"
#include "tr8x8dct.h"


extern void fdct_int32(short *const block);

//********************************************************************
// 方法名称:ProcessDU
//
// 方法说明:数据处理的最小单位,真正实现了FDCT,QUANTIZATION,HUFFMAN
//
// 参数说明:
// lpBuf:8x8信号输入缓冲
// quantTab:量化表
// dcHuffTab:DC huffman表
// acHuffTab:AC huffman表
// DC:前一数据块的DC值
//********************************************************************
#ifdef 0

void ProcessDU(short* lpBuf,unsigned char* quantTab,HUFFCODE* dcHuffTab,HUFFCODE* acHuffTab,short* DC)
{
	unsigned char i    = 0;             
	unsigned int j    = 0;
	short diffVal = 0;                             //DC差异值  
//	unsigned char acLen  = 0;                               //熵编码后AC中间符号的数量
	
	#pragma align 4 
	short sigBuf[DCTBLOCKSIZE];                    //量化后信号缓冲
	
//	ACSYM acSym[DCTBLOCKSIZE];                     //AC中间符号缓冲 
	SYM2 sym2;
	HUFFCODE * huff;

//	fdct_int32(lpBuf);
	_r8x8dct(lpBuf, coeff, temp);

	quantize(sigBuf, lpBuf, quantTab);
/*	
	for (i = 0; i < DCTBLOCKSIZE; i++)             //量化操作
	{          
//		sigBuf[FZBT[i]] = (short)( (lpBuf[i] * quantTab[i] + 16384.5) - 16384 );  
		short temp;
		unsigned short qval;
		temp = lpBuf[i];
		//qval = quantTab[FZBT[i]];
		qval = quantTab[i];
		 
//		qval <<= 3;
//#ifdef FAST_DIVIDE
//#define DIVIDE_BY(a,b)	a /= b
//#else
//#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
//#endif
		if (temp < 0) {
		  temp = -temp;
		  temp += qval>>1;	// for rounding 
//		  DIVIDE_BY(temp, qval);
			if(temp > qval)
				temp /= qval;
			else
				temp = 0;
		  temp = -temp;
		} else {
		  temp += qval>>1;	// for rounding
//		  DIVIDE_BY(temp, qval);
			if(temp > qval)
				temp /= qval;
			else
				temp = 0;
		}
		sigBuf[FZBT[i]] = temp;

	}
*/
	
/*	FDCT(lpBuf);                                   //离散余弦变换

	for (i = 0; i < DCTBLOCKSIZE; i++)             //量化操作
	{          
		sigBuf[FZBT[i]] = (short)( (lpBuf[i] * quantTab[i] + 16384.5) - 16384 );  
	}
*/
	
	//-----------------------------------------------------
	//对DC信号编码,写入文件,DPCM编码  
	DCComp(sigBuf, DC, dcHuffTab);	
/*		
	diffVal = sigBuf[0] - *DC;
	*DC = sigBuf[0];

	//搜索Huffman表,写入相应的码字
	if (diffVal == 0)
	{  
		huff = &dcHuffTab[0];
		WriteBitsStream(huff->code, huff->length);                      //{0,2,0},写进零长度
	}
	else
	{   
		huff = &dcHuffTab[pVLITAB[diffVal]];
		sym2 = BuildSym2(diffVal);
		WriteBitsStream(huff->code, huff->length);       //写进长度 
		WriteBitsStream(sym2.amplitude, sym2.codeLen);                //写进幅度  
	}
*/	
	RLEComp(sigBuf, acHuffTab);
	//-------------------------------------------------------
	//对AC信号编码并写入文件
/*
	for (i = 63; (i > 0) && (sigBuf[i] == 0); i--) //判断ac信号是否为0
	{
												 //注意,空循环
	}
*/
//	i = get_nonzero_ac_index(sigBuf);
	
//	if (i == 0)                                    //如果ac信号全为0
//	{
//		huff = &acHuffTab[0x00];
//		WriteBitsStream(huff->code, huff->length);                   //写入块结束标记  
//	}
//	else
//	{ 
//		RLEComp(sigBuf, acHuffTab, i);              //对AC进行长度编码 
/*		for (j = 0; j < acLen; j++)                   //依次对AC中间符号Huffman编码
		{   
			if (acSym[j].codeLen == 0)                   //是否有连续16个0
			{   
				huff = &acHuffTab[0xF0];
				WriteBitsStream(huff->code, huff->length);                   //写入块结束标记  
			}
			else
			{
				huff = &acHuffTab[acSym[j].zeroLen * 16 + acSym[j].codeLen];
				WriteBitsStream(huff->code, huff->length);                   //写入块结束标记  
				sym2 = BuildSym2(acSym[j].amplitude);
				WriteBitsStream(sym2.amplitude, sym2.codeLen);                //写进幅度  
			}   
		}
*/
//	if (i != 63)                                  //如果最后位以0结束就写入EOB
//		{
//			huff = &acHuffTab[0x00];
//			WriteBitsStream(huff->code, huff->length);                   //写入块结束标记  
//		}
//	}
}

#endif //0

/*
copy8to16(short* d, unsigned char* s, int stride)
{
	int i, j;
	
	for(i = 0; i < 8; i++)
	{
		for(j = 0; j < 8; j++)
		{
			d[i*8+j] = (short)(s[i*stride+j]-128);
		}
	}
}
*/


void ProcessData(unsigned char* y,unsigned char* u,unsigned char* v, int w, int h)
{
	int i, j, mcux = w>>4, mcuy = h>>4;
	
	#pragma align 4 
	short d[DCTBLOCKSIZE];
	
	short yDC   = 0;                             //Y信号的当前块的DC
	short uDC   = 0;                             //U信号的当前块的DC
	short vDC   = 0;                             //V信号的当前块的DC 
	
	unsigned char* source;
	
	for(i = 0; i < mcuy; i++)
	{
		for(j = 0; j < mcux; j++)	
		{
			source = y + w*i*16 + j*16;
			pre_fetch(source, w);
			copy8to16(d, source, w);
			ProcessDU(d, YQT,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
			
			source += 8;
			pre_fetch(source, w);
			copy8to16(d, source, w);
			ProcessDU(d, YQT,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
			
			source += -8 + w*8;
			pre_fetch(source, w);
			copy8to16(d, y + w*(i*16+8) + j*16, w);
			ProcessDU(d, YQT,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);
			
			source += 8;
			pre_fetch(source, w);
			copy8to16(d, y + w*(i*16+8) + j*16 + 8, w);
			ProcessDU(d, YQT,STD_DC_Y_HT,STD_AC_Y_HT,&yDC);

			source = u + (w>>1)*i*8 + j*8;
			pre_fetch(source, w>>1);
			copy8to16(d, source, (w>>1));						
			ProcessDU(d, UVQT,STD_DC_UV_HT,STD_AC_UV_HT,&uDC);
			
			source += v - u;
			pre_fetch(source, w>>1);
			copy8to16(d, source, (w>>1));						
			ProcessDU(d, UVQT,STD_DC_UV_HT,STD_AC_UV_HT,&vDC);  
		}
	}
}

int jpeg_compress(unsigned char* image, unsigned char* code_stream, int w, int h, int Q)
{
	unsigned char *y, *u, *v;
	
	bitstream_init(code_stream);

	y = image;
	u = y + w*h;
	v = u + w*h/4;

	SetQuantTable(std_Y_QT,YQT, Q);                     // 设置Y量化表
	SetQuantTable(std_UV_QT,UVQT, Q);                   // 设置UV量化表  
	pVLITAB=VLI_TAB + 2047;                             // 设置VLI_TAB的别名
	BuildVLITable();                                    // 计算VLI表   


	// 写入文件标记结构
	WriteSOI();              
	WriteAPP0();
	WriteDQT();
	WriteSOF(w, h);
	WriteDHT();
	WriteSOS();

	// 计算Y/UV信号的交直分量的huffman表,这里使用标准的huffman表,并不是计算得出,缺点是文件略长,但是速度快
	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);

	
	ProcessData(y, u, v, w, h);                 // 处理单元数据

	bitstream_pad2byte();
	WriteEOI();

	return bitstream_getlen();
}

⌨️ 快捷键说明

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