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

📄 j2b.c

📁 JPEG图像解码并转换成BMP图像:大概包括IDCT、反量化、反编码等过程
💻 C
字号:
#include <stdio.h>
#include <math.h>
#include <string.h>//初始化标志符函数InitTag()里的常量表达式 
#define M_SOF0  0xc0
#define M_DHT   0xc4
#define M_EOI   0xd9
#define M_SOS   0xda
#define M_DQT   0xdb
#define M_DRI   0xdd
#define M_APP0  0xe0
//函数 idct(short * const block)中使用的宏定义
#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) */
//宏定义功能值
#define FUNC_OK           0
#define FUNC_MEMORY_ERROR 1
#define FUNC_FILE_ERROR   2
#define FUNC_FORMAT_ERROR 3
//+++++++++++++++++++++++++++++++
#define WIDTH   640
#define HEIGHT  480 
//+++++++++++++++++++++++++++++++
#define WIDTHBYTES(i) (((i+31)&~31)>>3)

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,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 void idct(short * const block);
extern void idct_init();
extern void idct_mmx_c(short *block);//??????????

//Jpeg 功能函数
void    showerror(int funcret);
int     InitTag();
void    InitTable();
int     Decode();
int     DecodeMCUBlock();
int     HufBlock(unsigned char dchufindex,unsigned char achufindex);
int     DecodeElement();
void    IQtIZzMCUComponent(short flag);
void    IQtIZzBlock(short  *s ,int * d,short flag);
void    GetYUV(short flag);
void    StoreBuffer();//+++++++++++++++++++++++++++++++++++++++++
// main函数中主要函数模块int     maindecoder(int funcret);void    preparebmpheader(unsigned long ImgSize);void    writetobmpfile(FILE *hfbmp);
//+++++++++++++++++++++++++++++++++++++++++
////////////////////////////////////////////////////////////////////////
//定义全局变量

struct  BITMAPFILEHEADER {
//unsigned short bfType; 
unsigned int   bfSize; 
unsigned short bfReserved1; 
unsigned short bfReserved2; 
unsigned int   bfOffBits; 
} bf; 

unsigned char  bfType[2];

struct         BITMAPINFOHEADER{ 
unsigned int   biSize; 
int            biWidth; 
int            biHeight; 
unsigned short biPlanes; 
unsigned short biBitCount;
unsigned int   biCompression; 
unsigned int   biSizeImage; 
int            biXPelsPerMeter; 
int            biYPelsPerMeter; 
unsigned int   biClrUsed; 
unsigned int   biClrImportant; 
} bi;

//BITMAPFILEHEADER   bf;
//BITMAPINFOHEADER   bi;
//HPALETTE           hPalette=NULL;
//HGLOBAL            hImgData=NULL;
unsigned long  NumColors;
unsigned long  LineBytes;
unsigned long  ImgWidth=0 , ImgHeight=0;
unsigned char  *lpPtr;

///////////////////////////////////////////////////////////////////////
//variables used in jpeg function
short			SampRate_Y_H,SampRate_Y_V;
short			SampRate_U_H,SampRate_U_V;
short			SampRate_V_H,SampRate_V_V;
short			H_YtoU,V_YtoU,H_YtoV,V_YtoV;
short			Y_in_MCU,U_in_MCU,V_in_MCU;
unsigned char      *lpJpegBuf;
unsigned char      *lpYBuf;
unsigned char      *lpUBuf;
unsigned char      *lpVBuf;

unsigned char      *lp;
short			qt_table[3][64];
short			comp_num;
unsigned char	comp_index[3];
unsigned char   YDcIndex,YAcIndex,UVDcIndex,UVAcIndex;
unsigned char	HufTabIndex;
short		    *YQtTable,*UQtTable,*VQtTable;
unsigned char	And[9]={0,1,3,7,0xf,0x1f,0x3f,0x7f,0xff};
short		    code_pos_table[4][16],code_len_table[4][16];    
unsigned short	code_value_table[4][256];                       
unsigned short	huf_max_value[4][16],huf_min_value[4][16];     short			BitPos,CurByte;
short			rrun,vvalue;
short			MCUBuffer[10*64];
int			    QtZzMCUBuffer[10*64];
short			BlockBuffer[64];
short			ycoef,ucoef,vcoef;int		    	IntervalFlag;
short			interval=0;
int			Y[4*64],U[4*64],V[4*64];
unsigned long      sizei,sizej;short 		    	restart;unsigned char      bmpbuf[WIDTH*HEIGHT*3];
/* private data */
static short       iclip[1024]; /* clipping table */
static short       *iclp;
////////////////////////////////////////////////////////////////////////////////////
int MAKEWORD(a, b)
{
    return (int) (((unsigned char) (a)) | ((int) ((unsigned char) (b))) << 8);
}
////////////////////////////////////////////////////////////////////////////////////

void idct(short * const block)
{
  // idct_int32_init() must be called before the first call to this function!
  // changed by David to enable multi-threading.
  short  *blk;
  int    i;
  int    X0, X1, X2, X3, X4, X5, X6, X7, X8;

  for (i=0; i<8; i++)	// idct rows
  {
	blk = block+(i<<3);
	if (!((X1 = blk[4]<<11) | (X2 = blk[6]) | (X3 = blk[2]) |
        (X4 = blk[1]) | (X5 = blk[7]) | (X6 = blk[5]) | (X7 = blk[3])))
	{
		blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
		continue;
	}

	X0 = (blk[0]<<11) + 128; // for proper rounding in the fourth stage 

	// first stage 
	X8 = W7*(X4+X5);
	X4 = X8 + (W1-W7)*X4;
	X5 = X8 - (W1+W7)*X5;
	X8 = W3*(X6+X7);
	X6 = X8 - (W3-W5)*X6;
	X7 = X8 - (W3+W5)*X7;
  
	// second stage 
	X8 = X0 + X1;
	X0 -= X1;
	X1 = W6*(X3+X2);
	X2 = X1 - (W2+W6)*X2;
	X3 = X1 + (W2-W6)*X3;
	X1 = X4 + X6;
	X4 -= X6;
	X6 = X5 + X7;
	X5 -= X7;
  
	// third stage 
	X7 = X8 + X3;
	X8 -= X3;
	X3 = X0 + X2;
	X0 -= X2;
	X2 = (181*(X4+X5)+128)>>8;
	X4 = (181*(X4-X5)+128)>>8;
  
	// fourth stage 
	
	blk[0] = (short)((X7+X1)>>8);
	blk[1] = (short)((X3+X2)>>8);
	blk[2] = (short)((X0+X4)>>8);
	blk[3] = (short)((X8+X6)>>8);
	blk[4] = (short)((X8-X6)>>8);
	blk[5] = (short)((X0-X4)>>8);
	blk[6] = (short)((X3-X2)>>8);
	blk[7] = (short)((X7-X1)>>8);

  } // end for ( i = 0; i < 8; ++i ) IDCT-rows
  for (i=0; i<8; i++)	// idct columns
  {
	blk = block + i;
    // shortcut 
	if (!((X1 = (blk[8*4]<<8)) | (X2 = blk[8*6]) | (X3 = blk[8*2]) |
        (X4 = blk[8*1]) | (X5 = blk[8*7]) | (X6 = blk[8*5]) | (X7 = blk[8*3])))
	{
		blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=
			blk[8*5]=blk[8*6]=blk[8*7]=iclp[(blk[8*0]+32)>>6];
		continue;
	}

	X0 = (blk[8*0]<<8) + 8192;

	// first stage 
	X8 = W7*(X4+X5) + 4;
	X4 = (X8+(W1-W7)*X4)>>3;
	X5 = (X8-(W1+W7)*X5)>>3;
	X8 = W3*(X6+X7) + 4;
	X6 = (X8-(W3-W5)*X6)>>3;
	X7 = (X8-(W3+W5)*X7)>>3;
  
	// second stage 
	X8 = X0 + X1;
	X0 -= X1;
	X1 = W6*(X3+X2) + 4;
	X2 = (X1-(W2+W6)*X2)>>3;
	X3 = (X1+(W2-W6)*X3)>>3;
	X1 = X4 + X6;
	X4 -= X6;
	X6 = X5 + X7;
	X5 -= X7;
  
	// third stage 
	X7 = X8 + X3;
	X8 -= X3;
	X3 = X0 + X2;
	X0 -= X2;
	X2 = (181*(X4+X5)+128)>>8;
	X4 = (181*(X4-X5)+128)>>8;
  
	// fourth stage 
	blk[8*0] = iclp[(X7+X1)>>14];
	blk[8*1] = iclp[(X3+X2)>>14];
	blk[8*2] = iclp[(X0+X4)>>14];
	blk[8*3] = iclp[(X8+X6)>>14];
	blk[8*4] = iclp[(X8-X6)>>14];
	blk[8*5] = iclp[(X0-X4)>>14];
	blk[8*6] = iclp[(X3-X2)>>14];
	blk[8*7] = iclp[(X7-X1)>>14]; 
  }
 
} // end function idct_int32(block)
////////////////////////////////////////////////////////////////////////////////////////
//void idct_int32_init()
void idct_init()
{
  int i;

  iclp = iclip+512;
  for (i= -512; i<512; i++)
    iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
}
//////////////////////////////////////////////////////////////////////////////////////////
int main()
{

	FILE		                *hfjpg;
	FILE                        *hfbmp;
	unsigned long 		       ImgSize;
	unsigned long                JpegBufSize;//, BufSize,fb,fe;      unsigned char              hJpegBuf[2*1024*16];
	int				             funcret;
//	int                          start;//,end;
//	int                          j;

	  printf("000\n");
	  if((hfjpg=fopen("capture.jpg","r"))==NULL)//带回空指针
	   {
             printf("open error!\n");                
		    
	    }	
	  
	  //get jpg file length
         //+++++++++++++++++++++++++++++++++++++++++++++=            fseek(hfjpg,0L,SEEK_END);        JpegBufSize=ftell(hfjpg);        fseek(hfjpg,0L,SEEK_SET);         //+++++++++++++++++++++++++++++++++++++++++++ ++        printf("jsize=%d\n",JpegBufSize);        lpJpegBuf=hJpegBuf;
        
	  fread((unsigned char  *)lpJpegBuf,JpegBufSize,1,hfjpg);       
	  fclose(hfjpg);                                                         //+++++++++++++++++++++++++++++++++++++++++++++++++=
          funcret=maindecoder(funcret);          preparebmpheader(ImgSize);          //+++++++++++++++++++++++++++++++++++++++++++++++++
	if(funcret==FUNC_OK)
	{
	  writetobmpfile(hfbmp);	
	}
	else
	{	 printf("jpeg to bmp failed!\n");
	  return 0;
	}
}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++int maindecoder(int funcret){ 	   InitTable();                                         	   printf("111\n");
	   idct_init();
	   printf("222\n");
	   funcret=Decode();
	   printf("333\n");         return funcret;}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++void preparebmpheader(unsigned long ImgSize){       bi.biSize=(unsigned int)40;//sizeof(bi);
	   bi.biWidth=(int)(ImgWidth);
	   bi.biHeight=(int)(ImgHeight);
	   bi.biPlanes=1;
	   bi.biBitCount=24;
	   bi.biClrUsed=0;
	   bi.biClrImportant=0;
	   bi.biCompression=0;
	   bi.biSizeImage=ImgWidth*ImgHeight*3;
	   NumColors=0;
		
	   LineBytes=(unsigned int)(bi.biWidth*3);
	   ImgSize=(unsigned int)LineBytes*bi.biHeight;

	     bfType[0]=0x42;//??????????????
         bfType[1]=0x4d;
                
	   bf.bfSize=(unsigned int)(14+40+ImgSize);//sizeof(bf)+sizeof(bi)+ImgSize;
	   bf.bfOffBits=(unsigned int)(14+40);//(sizeof(bi)+sizeof(bf));         //BufSize=bf.bfSize-sizeof(bf); }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++void writetobmpfile(FILE *hfbmp){
      hfbmp=fopen("capture.bmp","w+");
	  fwrite(&bfType,2,1,hfbmp);
	  fwrite(&bf,/*sizeof(bf)*/12,1,hfbmp); 
	  fwrite(&bi,/*sizeof(bi)*/40,1,hfbmp);
	  //fwrite(bmpbuf,0x120*0x160*3,1,hfbmp);      fwrite(bmpbuf,WIDTH*HEIGHT*3,1,hfbmp);
	  fclose(hfbmp);      printf("jpeg to bmp successful!\n");

}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void showerror(int funcret)
{
/*	switch(funcret)
	{
	case FUNC_MEMORY_ERROR:
		MessageBox(NULL,"Error alloc memory!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);
		break;
	case FUNC_FILE_ERROR:
		MessageBox(NULL,"File not found!","ErrorMessage",MB_OK|MB_ICONEXCLAMATION);
		break;
	case FUNC_FORMAT_ERROR:
		MessageBox(NULL,"File format error!","Error Message",MB_OK|MB_ICONEXCLAMATION);
		break;
	default:
		break;
	}
	*/
}
///////////////////////////////////////////////////////////////////////////////////////
void InitTable()
{
	short i,j;
	sizei=sizej=0;
	ImgWidth=ImgHeight=0;
	rrun=vvalue=0;
	BitPos=0;
	CurByte=0;
	IntervalFlag=0;
	restart=0;
	comp_num=0;
	HufTabIndex=0;
	
	for(i=0;i<3;i++)
		for(j=0;j<64;j++)
			qt_table[i][j]=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;
}
//////////////////////////////////////////////////////////////////////////////////
int InitTag()
{
	int           finish=0;
	unsigned char id;
	short         llength;
	short         i,j,k;
	short         huftab1,huftab2;
	short         huftabindex;
	unsigned char hf_table_index;
	unsigned char qt_table_index;
	unsigned char comnum;

	unsigned char *lptemp;
	short         ccount;

	lp=lpJpegBuf+2;
	printf("++++%c\n",lp);

	while (finish!=1)
	{
		id=*(lp+1);
		lp+=2;
		switch (id)
		{
		  case M_APP0:
			 llength=MAKEWORD(*(lp+1),*lp);    //鐢熸垚涓

⌨️ 快捷键说明

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