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

📄 jpegencoder.c

📁 JPEG压缩编码在TMS320VC5509的实现代码。使用编译器为ccs2.2
💻 C
字号:
//JpegEncoder.c
#include "BasicDefinition.h"
#include "JpegTypesAndGlobals.h"

extern BYTE DDC4[0x400];
extern BYTE RMartix[0x4000];
extern BYTE GMartix[0x4000];
extern BYTE BMartix[0x4000];
extern BOOL m_bAlreadyOpen;//没有打开文件

UINT m_nErrorCode;//前面操作的错误代码
extern RGB2YUV(void);
extern DctBlockQuantize(int* InputBlock,const unsigned int* zigzag,const int* Q_table,int* OutputBlock);
extern Mem8x8Cpy(BYTE* SourceAddr,BYTE* DistAddr);
void DCEncode(int* InputBlock,const DC_ENCODE_TAB* dc_encode_tab,int* OldDc);
void ACEncode(int* InputBlock,const AC_ENCODE_TAB* ac_encode_tab,BOOL Y_or_CbCr);
extern void ACEncode2(int* InputBlock,const AC_ENCODE_TAB* ac_encode_tab,BOOL Y_or_CbCr);
#define K_Y_AC 0
#define K_CbCr_AC 1
extern FILE *fp1;


void JpegGloablValsInit(void)
{
	m_bAlreadyOpen = 0;//没有打开文件
	m_nErrorCode = K_OPERATION_SUCCESS;
	OneBlockBitstream.BitstreamLength = 0;
	OneBlockBitstream.LeftedBitLength = 0;
	OldDCY = 0;
	OldDCCb = 0;
	OldDCCr = 0;
}


BOOL JpegInfoInit(void)
{
	if(m_nErrorCode == K_OPERATION_SUCCESS)
	{
		if(DDC4[0] == 'B' && DDC4[0] == 'M' && DDC4[28] != 24)//不是24位真彩色
		{
			JpegEncodeErrorMsg(K_NOT_TRUE_COLOR_ERROR);
			return K_NOT_TRUE_COLOR_ERROR;
		}
		
		ImageWidth = (DDC4[18]&0xff) + (DDC4[19]<<8);//后面两个字节不管,不会产生这么大的图
		ImageHight = (DDC4[22]&0xff) + (DDC4[23]<<8);
		ImageBufSize = (unsigned long)(ImageWidth) * (unsigned long)(ImageHight);	
		return K_OPERATION_SUCCESS;
	}
	else
	{
		JpegEncodeErrorMsg(K_FILE_NOT_OPEN_ERROR);
		
		return K_FILE_NOT_OPEN_ERROR;
	}
}

void JpegEncodeErrorMsg(UINT ErrorCode)//方便以后与单片机通信
{
	puts(JpegErrorMessageTable[ErrorCode]);
}

BOOL JpegMainEncoder(void)
{
	UINT xpos,ypos;
	
	if(m_nErrorCode == K_OPERATION_SUCCESS)
	{
		ImageWidthFixed = (ImageWidth>>3)<<3;
		ImageHightFixed = (ImageHight>>3)<<3;
		for(ypos=0;ypos<ImageHightFixed;ypos+=8)
			for(xpos=0;xpos<ImageWidthFixed;xpos+=8)
			{
				LoadDataUnitsFromBuffer(xpos,ypos);
											
				RGB2YUV();

				IMG_sw_fdct_8x8(YDU,TmpCalBuf);
				IMG_sw_fdct_8x8(CbDU,TmpCalBuf);
				IMG_sw_fdct_8x8(CrDU,TmpCalBuf);

				DctBlockQuantize(YDU,zigzag,LuminanceScaleTab,YDCTzigzagQ);
				DctBlockQuantize(CbDU,zigzag,ChrominanceScaleTab,CbDCTzigzagQ);
				DctBlockQuantize(CrDU,zigzag,ChrominanceScaleTab,CrDCTzigzagQ);
								
				DCEncode(YDCTzigzagQ,&YDc_EncodeTab,&OldDCY);
				ACEncode(YDCTzigzagQ,&YAc_EncodeTab,K_Y_AC);
				//ACEncode2(YDCTzigzagQ,&YAc_EncodeTab,K_Y_AC);
				
												
				DCEncode(CbDCTzigzagQ,&CrCbDc_EncodeTab,&OldDCCb);
				ACEncode(CbDCTzigzagQ,&CrCbAc_EncodeTab,K_CbCr_AC);
								
				DCEncode(CrDCTzigzagQ,&CrCbDc_EncodeTab,&OldDCCr);
				ACEncode(CrDCTzigzagQ,&CrCbAc_EncodeTab,K_CbCr_AC);
			}
			
		FillOnes();
		
		JpegEncodeEnd(fp1);
		
		return K_OPERATION_SUCCESS;
	}
	else
	{
		return K_STOP_DU_TO_PREVIOUS_ERROR;
	}
}


void LoadDataUnitsFromBuffer(UINT xpos,UINT ypos)
{
	unsigned long m_nLocation,m_nLocationTmp;//存放的地址

	m_nLocation = ((unsigned long)(ImageWidth)) * ((unsigned long)(ypos)) + (unsigned long)(xpos);
	m_nLocationTmp = m_nLocation + (unsigned long)RMartix;//装载Red
	Mem8x8Cpy((BYTE*)m_nLocationTmp,Rbuf);
	

	m_nLocationTmp = m_nLocation + (unsigned long)GMartix;//装载Green
	Mem8x8Cpy((BYTE*)m_nLocationTmp,Gbuf);
	

	m_nLocationTmp = m_nLocation + (unsigned long)BMartix;//装载Blue
	Mem8x8Cpy((BYTE*)m_nLocationTmp,Bbuf);
}


void DCEncode(int* InputBlock,const DC_ENCODE_TAB* dc_encode_tab,int* OldDc)
{
	register int DiffDc,DiffDc2;//直流系数的差值
	register UINT SizeOfDiffDc;
	UINT m_nAddBitsNum;//添加的bits位数
	UINT m_nAddBitsVal;//添加的变量
	

	SizeOfDiffDc = 0;
	
	DiffDc = *InputBlock - *OldDc;
	
	DiffDc2 = abs(DiffDc);
	
	//计算直流系数的位数
	while(DiffDc2 > 0)
	{
		DiffDc2 = DiffDc2>>1;
		
		SizeOfDiffDc++;	
	}
	
	*OldDc = *InputBlock;
	
	m_nAddBitsNum = dc_encode_tab->BitStreamLengthTab[SizeOfDiffDc];//求新添加的bitstream的位数

	m_nAddBitsVal = dc_encode_tab->BitStreamTab[SizeOfDiffDc];//添加的变量

	AddBits(m_nAddBitsVal,m_nAddBitsNum);

	//if(DiffDc >= 0)
	//{
	//	DiffDc2 = DiffDc;
	//}
	//else
	if(DiffDc < 0)
	{	
		//if(SizeOfDiffDc == 16)
		//{
		//	DiffDc2 = (abs(DiffDc))^0xffff;
		//}
		//else
		//{
			//DiffDc2 = ~(0xffff<<SizeOfDiffDc);
		
			//DiffDc2 = (abs(DiffDc))^DiffDc2;
			
			DiffDc = (abs(DiffDc))^(~(0xffff<<SizeOfDiffDc));	
		//}
	}
	
	AddBits(DiffDc,SizeOfDiffDc);	
}


void AddBits(int Inputdata,UINT Length)
{
	int TmpLeftedBits;//计算的时候使用
	UINT TmpPos;
	UINT TmpShiftNum;//,TmpShiftNum2;
	UINT TmpData;
	//BYTE TmpDataLow,TmpDataHigh;
	//UINT TmpMask;
	
	if(OneBlockBitstream.BitstreamLength > 511)
	{
		AddBytes(fp1);	
	}

	TmpShiftNum = 16 - OneBlockBitstream.LeftedBitLength;//计算OneBlockBitstream.LeftedWord的移位数

	TmpLeftedBits = (int)(Length) - TmpShiftNum;//+ (int)(OneBlockBitstream.LeftedBitLength) - 16;//是否超过16位
	
	if(TmpLeftedBits >= 0)
	{		
		TmpPos = OneBlockBitstream.BitstreamLength;
		
		//TmpShiftNum = 16 - OneBlockBitstream.LeftedBitLength;//计算OneBlockBitstream.LeftedWord的移位数
		
		OneBlockBitstream.LeftedWord = (OneBlockBitstream.LeftedWord>>TmpShiftNum)<<TmpShiftNum;//清除末尾不需要的部分
		
		//TmpShiftNum2 = Length - TmpShiftNum;//计算m_nAddBitsVal的移位数
		
		//TmpMask = 1;
		
		//while(TmpShiftNum > 1)
		//{
		//	TmpMask = (TmpMask<<1) + 1;
			
		//	TmpShiftNum--;
		//}
		
		//TmpMask = (1 << TmpShiftNum) - 1;
		
		TmpData = OneBlockBitstream.LeftedWord | ((Inputdata>>TmpLeftedBits)&((1 << TmpShiftNum) - 1));//TmpMask);



		//TmpDataHigh = (BYTE)(TmpData>>8);

		OneBlockBitstream.Bitstream[TmpPos++] = (BYTE)(TmpData>>8);//TmpDataHigh;
		
		//OneBlockBitstream.BitstreamLength++;//放到后面一起加
		
		if((BYTE)(TmpData>>8) == 0xff)//(TmpDataHigh == 0xff)
		{
			OneBlockBitstream.Bitstream[TmpPos++] = 0;
			
			OneBlockBitstream.BitstreamLength++;
		}



		//TmpDataLow = (BYTE)(TmpData&0xff);

		OneBlockBitstream.Bitstream[TmpPos++] = (BYTE)(TmpData&0xff);//TmpDataLow;
		
		OneBlockBitstream.BitstreamLength += 2;
						
		if((BYTE)(TmpData&0xff) == 0xff)//(TmpDataLow == 0xff)
		{
			OneBlockBitstream.Bitstream[TmpPos++] = 0;
		
			OneBlockBitstream.BitstreamLength++;		
		}


	
		OneBlockBitstream.LeftedBitLength = TmpLeftedBits;
		
		OneBlockBitstream.LeftedWord = Inputdata<<(16-TmpLeftedBits);//(16-TmpShiftNum2);
		
	}
	else
	{
		//TmpShiftNum2 = 16 - OneBlockBitstream.LeftedBitLength;//计算移位的数量

		//TmpShiftNum = TmpShiftNum2 - Length;
		
		

		OneBlockBitstream.LeftedBitLength += Length;//更新最后bit的长度
		
		OneBlockBitstream.LeftedWord = OneBlockBitstream.LeftedWord>>TmpShiftNum;//TmpShiftNum2;//清除末尾不需要的部分

		OneBlockBitstream.LeftedWord = (OneBlockBitstream.LeftedWord<<TmpShiftNum) | (Inputdata<<abs(TmpLeftedBits));//(Inputdata<<TmpShiftNum);
	}
}

//extern UINT jpe1(int* InputBlock,UINT* m_bAllAcZero);
void ACEncode(int* InputBlock,const AC_ENCODE_TAB* ac_encode_tab,BOOL Y_or_CbCr)
{
	UINT m_bAllAcZero,EncodeAc,nrzeroes,startpos,k,nrmarker;
	register int *pInputBlock;
	register UINT Tmp,i,endpos;
	
	pInputBlock = InputBlock + 63;
	
	//m_bAllAcZero = 1;//假设所有元素都为0成立
	//endpos = 63;

//	endpos = jpe1(InputBlock,&m_bAllAcZero);
	for(i=63;i>0;i--)
	{
		if(*pInputBlock-- != 0)
		{
			//m_bAllAcZero = 0;
			break;
		}
		//endpos--;
	}
	
	if(i>0)
	{
		m_bAllAcZero = 0;
	}
	else
	{
		m_bAllAcZero = 1;//所有元素都为0成立
	}
	endpos = i;
	

	
	if(m_bAllAcZero == 1)//EOB
	{
		if(Y_or_CbCr == K_Y_AC )
		{			
			AddBits(10,4);
		}
		else
		{
			AddBits(0,2);
		}
	}
	else
	{
		i=1;
		nrzeroes = 0;//连零的数量
		pInputBlock = InputBlock + 1;
		while (i <= endpos)
		{
			startpos = i;

			while(i < endpos && *pInputBlock++ == 0)//InputBlock[i]寻找相连的零,我交换了判断的顺序
            	i++;

            nrzeroes = i - startpos;//连零的数量
            
			if(nrzeroes >= 16)//如果连零的数量大于等于16
			{
				Tmp = nrzeroes>>4;
						
            	for(nrmarker=0;nrmarker<Tmp;nrmarker++)
            	//while(Tmp-- > 0)
            	{
                	if(Y_or_CbCr == K_Y_AC )//ZRL
					{			
						AddBits(2041,11);
					}
					else
					{
						AddBits(1018,10);
					}
                	nrzeroes = nrzeroes - 16;
				}
				
				//nrzeroes -= Tmp3*16;
			}
			
			EncodeAc = 0;//AC编码的长度
			
			Tmp = abs(InputBlock[i]);//(*(pInputBlock-1));//abs(Output8x8Block(i,j));
			
            while(Tmp > 0)//计算需要的长度
            {
                Tmp = Tmp>>1;
                
                EncodeAc++;
            }
            k = nrzeroes*10 + EncodeAc - 1;//在AcMapStrTab中的位置

			AddBits(ac_encode_tab->BitStreamTab[k],ac_encode_tab->BitStreamLengthTab[k]);

			Tmp = InputBlock[i];

		//	if(InputBlock[i] >= 0)
		//	{
		//		Tmp = InputBlock[i];
		//	}
		//	else
			if(*(InputBlock + i) < 0)
			{
			//	if(EncodeAc == 16)//好象不存在EncodeAc = 16的情况
			//	{
			//		Tmp = (abs(Tmp))^0xffff;//(abs(InputBlock[i]))^0xffff;
			//	}
			//	else
			//	{
					//Tmp = ~(0xffff<<EncodeAc);
				
					//Tmp = abs(InputBlock[i])^Tmp;
					
					Tmp = abs(Tmp)^(~(0xffff<<EncodeAc));		
			//	}
			}
			
			AddBits(Tmp,EncodeAc);
			
			i++;
		}//i <= endpos
		
		if(endpos < 63)
		{
			if(Y_or_CbCr == K_Y_AC )
			{			
				AddBits(10,4);
			}
			else
			{
				AddBits(0,2);
			}
		}
	}//m_bAllAcZero == 1
}

void FillOnes(void)
{
	//UINT Tmp,Tmp2;
	
	//if(OneBlockBitstream.LeftedBitLength != 0)
	//{
		//Tmp = 16 - OneBlockBitstream.LeftedBitLength;
		
		////Tmp2 = (1 << (16 - OneBlockBitstream.LeftedBitLength)) - 1;
		
		//Tmp2 = 1;

		//while(Tmp>1)
		//{
		//	Tmp2 = (Tmp2<<1) + 1;
			
		//	Tmp--;	
		//}
		
		OneBlockBitstream.LeftedWord = OneBlockBitstream.LeftedWord | ((1 << (16 - OneBlockBitstream.LeftedBitLength)) - 1);
	//}
}


extern void ClearStReg(void);

void JpegEncodeEnd(FILE *fp)
{
	UINT TmpDataHigh;
	
	ClearStReg();
	
	fwrite(OneBlockBitstream.Bitstream,sizeof(BYTE),OneBlockBitstream.BitstreamLength,fp);

	OneBlockBitstream.BitstreamLength = 0;
	
	if(OneBlockBitstream.LeftedBitLength != 0)
	{	
		TmpDataHigh = (OneBlockBitstream.LeftedWord)>>8;
		
		fwrite(&TmpDataHigh,sizeof(BYTE),1,fp);
		
		if(OneBlockBitstream.LeftedBitLength > 8)
		{
			fwrite(&(OneBlockBitstream.LeftedWord),sizeof(BYTE),1,fp);
		}
		
		OneBlockBitstream.LeftedBitLength = 0;
	}
	
	TmpDataHigh = 0xff;
	
	fwrite(&TmpDataHigh,sizeof(BYTE),1,fp);
	
	TmpDataHigh = 0xd9;
	
	fwrite(&TmpDataHigh,sizeof(BYTE),1,fp);
	
	fclose(fp);			
}


void JpegHeadWrite(FILE *fp)
{
	BYTE TmpJpegInfo[4];
	
	ImageWidthFixed = (ImageWidth>>3)<<3;
	
	ImageHightFixed = (ImageHight>>3)<<3;
	
	TmpJpegInfo[0] = (BYTE)(ImageHightFixed>>8);//159
	
	TmpJpegInfo[1] = (BYTE)(ImageHightFixed&0xff);//160
	
	TmpJpegInfo[2] = (BYTE)(ImageWidthFixed>>8);//161
	
	TmpJpegInfo[3] = (BYTE)(ImageWidthFixed&0xff);//162

	fwrite(JpegInfo,sizeof(BYTE),159,fp);//JpegInfo 607

	fwrite(TmpJpegInfo,sizeof(BYTE),4,fp);//TmpJpegInfo
	
	fwrite((JpegInfo+163),sizeof(BYTE),444,fp);//JpegInfo		
}


void AddBytes(FILE *fp)
{
	//UINT Tmp;
	
	ClearStReg();

	fwrite(OneBlockBitstream.Bitstream,sizeof(BYTE),512,fp);
	
	OneBlockBitstream.BitstreamLength -= 512;
	
	if(OneBlockBitstream.BitstreamLength != 0)
	{
		//Tmp = OneBlockBitstream.Bitstream[512];
	
		//OneBlockBitstream.Bitstream[0] = Tmp;
		
		OneBlockBitstream.Bitstream[0] = OneBlockBitstream.Bitstream[512];
	
		//Tmp = OneBlockBitstream.Bitstream[513];
	
		//OneBlockBitstream.Bitstream[1] = Tmp;
		
		OneBlockBitstream.Bitstream[1] = OneBlockBitstream.Bitstream[513];
	}	
}

⌨️ 快捷键说明

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