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

📄 jpeg.c

📁 jpeg解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
typedef enum {			/* JPEG marker codes */
  M_SOF0  = 0xc0,
  M_SOF1  = 0xc1,
  M_SOF2  = 0xc2,
  M_SOF3  = 0xc3,  
  M_SOF5  = 0xc5,
  M_SOF6  = 0xc6,
  M_SOF7  = 0xc7,  
  M_JPG   = 0xc8,
  M_SOF9  = 0xc9,
  M_SOF10 = 0xca,
  M_SOF11 = 0xcb,  
  M_SOF13 = 0xcd,
  M_SOF14 = 0xce,
  M_SOF15 = 0xcf,  
  M_DHT   = 0xc4,  
  M_DAC   = 0xcc,  
  M_RST0  = 0xd0,
  M_RST1  = 0xd1,
  M_RST2  = 0xd2,
  M_RST3  = 0xd3,
  M_RST4  = 0xd4,
  M_RST5  = 0xd5,
  M_RST6  = 0xd6,
  M_RST7  = 0xd7,  
  M_SOI   = 0xd8,
  M_EOI   = 0xd9,
  M_SOS   = 0xda,
  M_DQT   = 0xdb,
  M_DNL   = 0xdc,
  M_DRI   = 0xdd,
  M_DHP   = 0xde,
  M_EXP   = 0xdf,  
  M_APP0  = 0xe0,
  M_APP1  = 0xe1,
  M_APP2  = 0xe2,
  M_APP3  = 0xe3,
  M_APP4  = 0xe4,
  M_APP5  = 0xe5,
  M_APP6  = 0xe6,
  M_APP7  = 0xe7,
  M_APP8  = 0xe8,
  M_APP9  = 0xe9,
  M_APP10 = 0xea,
  M_APP11 = 0xeb,
  M_APP12 = 0xec,
  M_APP13 = 0xed,
  M_APP14 = 0xee,
  M_APP15 = 0xef,  
  M_JPG0  = 0xf0,
  M_JPG13 = 0xfd,
  M_COM   = 0xfe,  
  M_TEM   = 0x01,  
  M_ERROR = 0x100
} JPEG_MARKER;

static int Zig_Zag[8][8]={{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,37,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}
};

#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565  /* 2048*sqrt(2)*cos(7*pi/16) */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>


int  InitTag(void);
int Decode(void); 
int DecodeMCUBlock(void);
int DecodeElement(void);
void StoreBuffer(void);
unsigned char  ReadByte(void);
void Initialize_Fast_IDCT(void); 


int *RateTable = NULL;  
U16  RateTable_len;
/////////////////////////////////////////////////////////////////
void InitTable(void)
{
	short i,j;
	sizei=sizej=0;
	ImgWidth=ImgHeight=0;
	rrun=vvalue=0;
	BitPos=0;
	CurByte=0;
	IntervalFlag=FALSE;
	restart_jpg=0;
	for(i=0;i<3;i++)
		for(j=0;j<64;j++)
			qt_table[i][j]=0;
	comp_num=0;
	HufTabIndex=0;
	for(i=0;i<3;i++)
		comp_index[i]=0;
	for(i=0;i<4;i++)
		for(j=0;j<16;j++){
			code_len_table[i][j]=0;
			code_pos_table[i][j]=0;
			huf_max_value[i][j]=0;
			huf_min_value[i][j]=0;
		}
	for(i=0;i<4;i++)
		for(j=0;j<256;j++)
			code_value_table[i][j]=0;
	
	for(i=0;i<10*64;i++){
		MCUBuffer[i]=0;
		QtZzMCUBuffer[i]=0;
	}
	for(i=0;i<64;i++){
		Y[i]=0;
		U[i]=0;
		V[i]=0;
		BlockBuffer[i]=0;
	}
	ycoef=ucoef=vcoef=0;
}
BOOL LoadJpeg (const unsigned char* JpegData, int s_x,int s_y, int max_w, int max_h,BOOL bMenSelBack/*, unsigned long size*/)
{
	void*			   hJpegBuf=NULL;
	int				   funcret;
	BOOL bSaveData = FALSE;
	needzoom=0;
	rate=1.0;
	
	MmiTrace("  loadjpg");
       lpJpegBuf=(unsigned char*)(JpegData);   
	memset(G_JpgDecData,0,sizeof(G_JpgDecData));
	InitTable();// :table初始化

	if((funcret=InitTag())!=FUNC_OK) //初始化Tag
	{
		return FALSE;
	}

	lpPtr=(char *)(&G_JpgDecData[2]);//  add

	if((SampRate_Y_H==0)||(SampRate_Y_V==0))  // :根据inittag的结果来判断
	{	   
		return FALSE ;
	}
	//  add to avoid overflow
	if(0==max_w || 0== max_h)  // : no input size limitation, use MAX_WIDTH and MAX_HEIGHT
	{
		if((ImgWidth>MAX_WIDTH)||(ImgHeight>MAX_HEIGHT))
		{
		       double factor_w = 1.0, factor_h=1.0;
			char tmp[100];
			
			factor_w=MAX_WIDTH/(double)ImgWidth;
			factor_h=MAX_HEIGHT/(double)ImgHeight;
			if((factor_w-factor_h)>0.0000)
				factor_w=factor_h;
			rate=factor_w;
			needzoom=1;
		}
		else
		{
			rate	=1.0;	
			needzoom=0;
	        }  
	}
	else if((ImgWidth>max_w)||(ImgHeight>max_h))
	{
		       double factor_w = 1.0, factor_h=1.0;
			char tmp[100];
			
			factor_w=max_w/(double)ImgWidth;
			factor_h=max_h/(double)ImgHeight;
			if((factor_w-factor_h)>0.0000)
				factor_w=factor_h;
			rate=factor_w;
			needzoom=1;
	}
	else
	{
                     rate=1.0;
			needzoom=0;	
	}
	if(needzoom)
	{
	       int i;
		int former=0;
		int cur=0;
		double temp=0.0;
	       
	       G_JpgDecData[0]=(unsigned char)(ImgWidth*rate);
		G_JpgDecData[1]=(unsigned char)(ImgHeight*rate);//  add,the 1st 2 for height and width

		RateTable_len = (ImgWidth>ImgHeight)?ImgWidth:ImgHeight;
		RateTable = (int*)Alloc(RateTable_len*sizeof(int));
		if(RateTable == NULL)
		{
			return FALSE;
		}
		for(i=0; i<RateTable_len; i++)
		{
                 	temp=i*rate+0.5005;
			cur=(int)(temp);
			former=(int)(temp+rate);
			if(cur==former) //discard this line;
			    RateTable[i] = -1;
			else
			    RateTable[i]= cur;
		}
		
	}
	else
	{
	       G_JpgDecData[0]=(unsigned char)ImgWidth;
		G_JpgDecData[1]=(unsigned char)ImgHeight;//  add,the 1st 2 for height and width
	}

	LineBytes=(unsigned short)G_JpgDecData[0]*2;//  changed this ,is it right?
	
	funcret=Decode();
	if(funcret==FUNC_OK)
	{
	    //display here				
		if(RateTable != NULL)
		{
			Free(RateTable, (U16)(sizeof(int)*RateTable_len));
			RateTable = NULL;
			RateTable_len = 0;
		}
		return TRUE;
	}
	else 
	{
		if(RateTable != NULL)
		{
			Free(RateTable, (U16)(sizeof(int)*RateTable_len));
			RateTable = NULL;
			RateTable_len = 0;
		}
		return FALSE;
	}
}

BOOL WbmpDecode(UBYTE *oldImage, U8* pBuf, UINT16 oldWidth, UINT16 oldHeight,
	UINT16 newWidth, UINT16 newHeight)
{
	USHORT	byteWidth;
	USHORT	scrByteWidth;
	int i, j, k, w = 0;
       UBYTE *pOld = oldImage;
       USHORT *pNew = (USHORT *)pBuf;
	   	
	/* Work out the width of the original image in bytes */
	byteWidth = oldWidth/8;
	if (oldWidth % 8)
		byteWidth++;

	/* Work out the width of the scaled image in bytes */
	scrByteWidth = newWidth/8;
	if (newWidth % 8)
		scrByteWidth++;


	/* If there's no scaling to do, copy the image and that's it! */
	if(NULL == pBuf)
	{
		return FALSE;
	}

	if(NULL == oldImage)
	{
		return FALSE;
	}

	if (newWidth == oldWidth && newHeight == oldHeight)
	{
	       for(j = 0; j < oldHeight; j++)
	       {
		       for(i = 0; i < byteWidth; i++)
		       {
                           for(k = 0; k < 8; k++)
                           {
                                if(0 != ((*pOld) & (1 << (7-k))))
                                {
                                      *pNew = 0xFFFF;
				    }
				    else
				    {
                                      *pNew = 0;
				    }
				    pNew++;
				    w++;
				    if(w == oldWidth)
				    {
                                    w = 0;
					 break;
				    }
			      }
			      pOld++;
			}
	       }
	}
	else
	{
              return FALSE;
	}
	
	return TRUE;
}


BOOL showWbmpInWebPage (const unsigned char* WbmpData, U8* pBuf,int width,int height, int max_w, int max_h)
{
       UINT16 index = 0;
	UINT16 shift;
	UINT16 origWidth;	/* Original width of image (from image data) */
	UINT16 origHeight;	/* Original width of image (from image data) */
  
	if((0 != WbmpData[0]) || (0 != WbmpData[1]))
	{
               return FALSE;
	}

	/*overleap WBMP type, Fixed header , width, and height*/
       index++;       

	origWidth = 0;
	shift = 1;

	do
	{
		index++;
		origWidth |= ((WbmpData[index] & 0x7F)*shift);
		shift *= 0x80;
	}
	while (WbmpData[index] & 0x80);
	
	origHeight = 0;
	shift = 1;

	do
	{
		index++;
		origHeight |= ((WbmpData[index] & 0x7F)*shift);
		shift *= 0x80;
	}
       while (WbmpData[index] & 0x80);

	if((0 == origWidth) || (0 == origHeight))
	{
             return FALSE;
	}

	if((origWidth > max_w) || (origHeight > max_h))
	{
             return FALSE;
	}	
  	
	index++;

	return WbmpDecode(
		(UBYTE *)&WbmpData[index],
		pBuf,
		origWidth,
		origHeight,
		(UINT16)width,
		(UINT16)height);
	
}

BOOL showJpgInWebPage (const unsigned char* JpegData, U8* pBuf,int width,int height, int max_w, int max_h)
{
	void*			   hJpegBuf=NULL;
	int				   funcret;
	needzoom=0;
	rate=1.0;
	
       lpJpegBuf=(unsigned char*)(JpegData);   
	memset(G_JpgDecData,0,sizeof(G_JpgDecData));
	InitTable();// :table初始化

	if((funcret=InitTag())!=FUNC_OK) //初始化Tag
	{
		return FALSE;
	}
	lpPtr=(char *)(&G_JpgDecData[2]);//  add

	if((SampRate_Y_H==0)||(SampRate_Y_V==0))  // :根据inittag的结果来判断
	{	   
		//TM_EnableWatchdog();//   in order to remove rvf_delay in long time consumed jpg decode
		return FALSE ;
	}
	//  add to avoid overflow
	if(0==max_w || 0== max_h)  // : no input size limitation, use MAX_WIDTH and MAX_HEIGHT
	{
		if((ImgWidth>MAX_WIDTH)||(ImgHeight>MAX_HEIGHT))
		{
		       double factor_w = 1.0, factor_h=1.0;
			char tmp[100];
			
			factor_w=MAX_WIDTH/(double)ImgWidth;
			factor_h=MAX_HEIGHT/(double)ImgHeight;
			if((factor_w-factor_h)>0.0000)
				factor_w=factor_h;
			rate=factor_w;
			needzoom=1;
		}
		else
		{
			rate	=1.0;	
			needzoom=0;
	        }  
	}
	else if((ImgWidth>max_w)||(ImgHeight>max_h))
	{
		       double factor_w = 1.0, factor_h=1.0;
			char tmp[100];
			
			factor_w=max_w/(double)ImgWidth;
			factor_h=max_h/(double)ImgHeight;
			if((factor_w-factor_h)>0.0000)
				factor_w=factor_h;
			rate=factor_w;
			needzoom=1;
	}
	else
	{
                     rate=1.0;
			needzoom=0;	
	}
	if(needzoom)
	{
	       int i;
		int former=0;
		int cur=0;
		double temp=0.0;
	       
	       G_JpgDecData[0]=(unsigned char)(ImgWidth*rate);
		G_JpgDecData[1]=(unsigned char)(ImgHeight*rate);//  add,the 1st 2 for height and width

		RateTable_len = (ImgWidth>ImgHeight)?ImgWidth:ImgHeight;
		RateTable = (int*)Alloc(RateTable_len*sizeof(int));
		if(RateTable == NULL)
		{
			return FALSE;
		}
		for(i=0; i<RateTable_len; i++)
		{
                 	temp=i*rate+0.5005;
			cur=(int)(temp);
			former=(int)(temp+rate);
			if(cur==former) //discard this line;
			    RateTable[i] = -1;
			else
			    RateTable[i]= cur;
		}
		
	}
	else
	{
	       G_JpgDecData[0]=(unsigned char)ImgWidth;
		G_JpgDecData[1]=(unsigned char)ImgHeight;//  add,the 1st 2 for height and width
	}

	LineBytes=(unsigned short)G_JpgDecData[0]*2;//  changed this ,is it right?
	
	funcret=Decode();
	if(funcret==FUNC_OK)
	{
		memcpy(pBuf , (U8*)&G_JpgDecData[2], G_JpgDecData[0] * G_JpgDecData[1] * sizeof(USHORT));
		if(RateTable != NULL)
		{
			Free(RateTable, (U16)(sizeof(int)*RateTable_len));
			RateTable = NULL;
			RateTable_len = 0;
		}
		return TRUE;
	}
	else 
	{
		if(RateTable != NULL)
		{
			Free(RateTable, (U16)(sizeof(int)*RateTable_len));
			RateTable = NULL;
			RateTable_len = 0;
		}
		return FALSE;
	}
}
/////////////////////////////////////////////////////////////////////////
int Decode(void)
{
	int funcret;
	static int count=0;//  add to protect from crash 20040804

	Y_in_MCU=SampRate_Y_H*SampRate_Y_V;
	U_in_MCU=SampRate_U_H*SampRate_U_V;
	V_in_MCU=SampRate_V_H*SampRate_V_V;
	H_YtoU=SampRate_Y_H/SampRate_U_H;
	V_YtoU=SampRate_Y_V/SampRate_U_V;
	H_YtoV=SampRate_Y_H/SampRate_V_H;
	V_YtoV=SampRate_Y_V/SampRate_V_V;
	Initialize_Fast_IDCT();
	while((funcret=DecodeMCUBlock())==FUNC_OK){
		interval++;
		if((restart_jpg)&&(interval % restart_jpg==0))
			 IntervalFlag=TRUE;
		else
			IntervalFlag=FALSE;
		IQtIZzMCUComponent(0);
		IQtIZzMCUComponent(1);
		IQtIZzMCUComponent(2);
		GetYUV(0);
		GetYUV(1);
		GetYUV(2);
		StoreBuffer();
		count++;
		if(count==10)
		{
			rvf_delay(3);
			count=0;
		}
		sizej+=SampRate_Y_H*8;
		if(sizej>=ImgWidth){
			sizej=0;
			sizei+=SampRate_Y_V*8;
		}
		if ((sizej==0)&&(sizei>=ImgHeight))
			break;
		}
	count=0;
	return funcret;
}
/////////////////////////////////////////////////////////////////////////////////////////
void  GetYUV(short flag)
{
	short	H,VV;
	short	i,j,k,h;
	int		*buf;
	int		*pQtZzMCU;

	switch(flag){
	case 0:
		H=SampRate_Y_H;
		VV=SampRate_Y_V;
		buf=Y;
		pQtZzMCU=QtZzMCUBuffer;
		break;
	case 1:
		H=SampRate_U_H;
		VV=SampRate_U_V;
		buf=U;
		pQtZzMCU=QtZzMCUBuffer+Y_in_MCU*64;
		break;
	case 2:
		H=SampRate_V_H;
		VV=SampRate_V_V;
		buf=V;
		pQtZzMCU=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;
		break;
	}
	for (i=0;i<VV;i++)
		for(j=0;j<H;j++)
			for(k=0;k<8;k++)
				for(h=0;h<8;h++)
					buf[(i*8+k)*SampRate_Y_H*8+j*8+h]=*pQtZzMCU++;
}
///////////////////////////////////////////////////////////////////////////////
/*目前的缩放算法由重复,实际上一个象素的保存进行了多次最后一次起作用*/
void StoreBuffer(void)// :只有该函数需要存储数据的buffer的指针,存储数据前偏移头信息的长度,lpPtr,lpImgData
{                     //可以在该处作一定的改动,然后用到手机中
	short i,j;
	unsigned char  *lpbmp;
	unsigned char R,G,B;
	int y,u,v,rr,gg,bb;

	int h_former=0;
	int h_cur=0;
	int w_former=0;
	int w_cur=0;
	double temp=0.0;
	unsigned long     pixel_pos=(unsigned long)sizej*2;
	if(needzoom)
	{
		pixel_pos=(unsigned long)(sizej*rate+0.5005)*2;
		for(i=0;i<SampRate_Y_V*8;i++)
		{		
		       if((sizei+i)<ImgHeight)
			{
	                     	{
	                     	    	if(RateTable[sizei+i] == -1 && ((sizei+i+1)<ImgHeight))
					    continue;
					if(RateTable[sizei+i] >= G_JpgDecData[1])
					    return;
	                     	}
				lpbmp=(unsigned char *)lpPtr+(unsigned long)(RateTable[sizei+i]*LineBytes)+pixel_pos;
				for(j=0;j<SampRate_Y_H*8;j++)
					{
						if((sizej+j)<ImgWidth)
						{
							//  revise zoom out 20040510
				                     //if((sizej+j)!=0)
			                     	{
				                     	#if 0
				                     	temp=(sizej+j)*rate+0.5005;
								w_cur=(int)(temp);
								w_former=(int)(temp+rate);
								if((w_cur==w_former) && ((sizej+j+1)<ImgWidth) ) //discard this line;
								    continue;
								if(w_cur >= G_JpgDecData[0])
							           break;
							        #else
							    if((RateTable[sizej+j] == -1) && ((sizej+j+1)<ImgWidth))
							    	continue;
							    if(RateTable[sizej+j] >= G_JpgDecData[0])
							    	break;
							        #endif
			                     	}
							//end
							y=Y[i*8*SampRate_Y_H+j];
							u=U[(i/V_YtoU)*8*SampRate_Y_H+j/H_YtoU];

⌨️ 快捷键说明

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