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

📄 main.cpp

📁 C语言实现的JPEG解码程序 效率比较高
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "jpeg.h"
#include "bmp.h"
#include <string>
//#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>
using namespace std;
////////////////////////////////////////////////////////////////
BOOL LoadJpegFile (char *JpegFileName)
{
 FILE*      hfjpg;
 DWORD          ImgSize;
 DWORD              BufSize,JpegBufSize;
 FILE*              hfbmp;
 FILE*              IMGdata;
 void *      hJpegBuf;
 int       funcret;
 DWORD i;
 LPBITMAPINFOHEADER lpImgData;

 char * hImgData256;

 if((hfjpg=fopen(JpegFileName,"rb"))==NULL)
 {
  showerror(FUNC_FILE_ERROR);
  return FALSE;
 }
/*SEEK_CUR 
Current position of file pointer. 
SEEK_END 
End of file. 
SEEK_SET 
Beginning of file.*/


 //get jpg file length
 fseek(hfjpg,0L,SEEK_END);
 JpegBufSize=ftell(hfjpg);
 //rewind to the beginning of the file
 fseek(hfjpg,0L,SEEK_SET);

 if((hJpegBuf=malloc(JpegBufSize))==NULL)
 {
  fclose(hfjpg);
  showerror(FUNC_MEMORY_ERROR);
  
  return FALSE;
 }
 lpJpegBuf=(unsigned char  *)hJpegBuf;
 fread((unsigned char  *)hJpegBuf,sizeof( char ),JpegBufSize,hfjpg);
 fclose(hfjpg);
 
 InitTable();

 if((funcret=InitTag())!=FUNC_OK)
 {
 // GlobalUnlock(hJpegBuf);
  free(hJpegBuf);
  showerror(funcret);
  return FALSE;
 }
 //create new bitmapfileheader and bitmapinfoheader
 memset((char *)&bf,0,sizeof(BITMAPFILEHEADER)); 
 memset((char *)&bi,0,sizeof(BITMAPINFOHEADER));

 bi.biSize=(DWORD)sizeof(BITMAPINFOHEADER);
 bi.biWidth=(LONG)(ImgWidth);
 bi.biHeight=(LONG)(ImgHeight);
 bi.biPlanes=1;
 bi.biBitCount=24;
 bi.biClrUsed=0;
 bi.biClrImportant=0;
 bi.biCompression=BI_RGB;
 NumColors=0;
 printf("bi.biWidth is %ld\n",bi.biWidth);
printf("bi.biBitCount is %ld\n",bi.biBitCount);
 LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
 printf("LineBytes is %ld\n",LineBytes);
 ImgSize=(DWORD)LineBytes*bi.biHeight;//???????
 printf("size is %ld\n",ImgSize);
 bf.bfType=0x4d42;
int a= sizeof(BITMAPFILEHEADER);
int b= sizeof(BITMAPINFOHEADER);
//注意字节对齐问题!!!!!!!!!!!!!!!!!!!!!!!!1
//如果没有#pragma pack(1),a是16~~~~~~~
int c=NumColors*sizeof(RGBQUAD);
int bfSize;
 bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
 bf.bfSize_lo=(bfSize&0x0ffff);
  bf.bfSize_hi=(bfSize>>16)&0xffff;
 bf.bfOffBits_lo=54;//(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
 bf.bfOffBits_hi=0;
 BufSize=bfSize-sizeof(BITMAPFILEHEADER);
// printf("size is %ld\n",BufSize);
 if((hImgData=(char*)malloc(BufSize))==NULL)
 {
  //GlobalUnlock(hJpegBuf);
  free(hJpegBuf);
  showerror(FUNC_MEMORY_ERROR);
  showerror(FUNC_MEMORY_ERROR);
  return FALSE;
 }
// lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
 lpImgData=(LPBITMAPINFOHEADER)hImgData; 
 memcpy(lpImgData,(char *)&bi,sizeof(BITMAPINFOHEADER));
 lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);

 if((SampRate_Y_H==0)||(SampRate_Y_V==0))
 {
 // GlobalUnlock(hJpegBuf);
  free(hJpegBuf);
  //GlobalUnlock(hImgData);
  free(hImgData);
  hImgData=NULL;
  showerror(FUNC_FORMAT_ERROR);
  return FALSE ;
 }

 funcret=Decode();
 if(funcret==FUNC_OK)
 {
  //hDc=GetDC(hWnd);
/*  hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
      (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
         (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
*/
 // hfbmp=fopen("c:\\jpeg2-bmp.bmp","Wb");

  if((hfbmp=fopen("jpeg2-bmp.bmp","wb"))==NULL)
  {
   showerror(FUNC_FILE_ERROR);
   return FALSE;
  }

  // hfbmp=fopen("c:\\jpeg2-bmp.bmp","Wb");

 

  fwrite((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,hfbmp); 
  fwrite((LPSTR)lpImgData,sizeof(char),BufSize,hfbmp);

  if((IMGdata=fopen("111.txt","wb"))==NULL)
  {
   showerror(FUNC_FILE_ERROR);
   return FALSE;
  }
  DWORD xx = ImgWidth*ImgHeight;
  if(( hImgData256=(char *)malloc(xx))==NULL)
  {
   //GlobalUnlock(hJpegBuf);
   free(hImgData256);
   showerror(FUNC_MEMORY_ERROR);
   showerror(FUNC_MEMORY_ERROR);
   showerror(FUNC_MEMORY_ERROR);
   return FALSE;
  }

  char * temp=hImgData256;
  for(i=0; i < xx; i++)
  {
   i;
   char t3=*lpPtr;
   t3 &= 0xE0;
   char t1=*(lpPtr+1);
   t1 = t1>>3;
   t1 &= 0x1c;
   char t2=*(lpPtr+2);
   t2=t2>>6;
   t2 &= 0x03;
   char t4 = t3 + t1 + t2 ;
   *temp++=t4;
   lpPtr=lpPtr+ 3;
   //不能使用temp+=3;
  }
  int count=fwrite(hImgData256,sizeof(char),xx,IMGdata);
  //free((void*)hImgData256);
  fclose(IMGdata);

  fclose(hfbmp);
  
//  ReleaseDC(hWnd,hDc);
//  GlobalUnlock(hJpegBuf);
  free(hJpegBuf);
  //GlobalUnlock(hImgData);
  return TRUE;
 }
 else
 {
  //GlobalUnlock(hJpegBuf);
  free(hJpegBuf);
 // GlobalUnlock(hImgData);
  free(hImgData);
  hImgData=NULL;
  showerror(funcret);
  return FALSE;
 }
}
/////////////////////////////////////////////////
void showerror(int funcret)
{
 switch(funcret)
 {
 case FUNC_MEMORY_ERROR:
     printf("Error alloc memory\n!");
  break;
 case FUNC_FILE_ERROR:
     printf("File not found!\n");
  break;
 case FUNC_FORMAT_ERROR:
  printf("File format error!\n");
  break;
 }
}
////////////////////////////////////////////////////////////////////////////////
int InitTag()
{
 BOOL finish=FALSE;
 BYTE id;
 short  llength;
 short  i,j,k;
 short  huftab1,huftab2;
 short  huftabindex;
 BYTE hf_table_index;
 BYTE qt_table_index;
 BYTE comnum;

 unsigned char  *lptemp;
 short  ccount;

 lp=lpJpegBuf+2;

 while (!finish){
  id=*(lp+1);
  lp+=2;
  switch (id){
  case M_APP0:
   llength=MAKEWORD(*(lp+1),*lp);
   lp+=llength;
   break;
  case M_DQT:
   llength=MAKEWORD(*(lp+1),*lp);
   qt_table_index=(*(lp+2))&0x0f;
   lptemp=lp+3;
   if(llength<80){
    for(i=0;i<64;i++)
     qt_table[qt_table_index][i]=(short)*(lptemp++);
   }
   else{
    for(i=0;i<64;i++)
     qt_table[qt_table_index][i]=(short)*(lptemp++);
                qt_table_index=(*(lptemp++))&0x0f;
      for(i=0;i<64;i++)
     qt_table[qt_table_index][i]=(short)*(lptemp++);
     }
     lp+=llength;  
   break;
  case M_SOF0:
    llength=MAKEWORD(*(lp+1),*lp);
    ImgHeight=MAKEWORD(*(lp+4),*(lp+3));
    ImgWidth=MAKEWORD(*(lp+6),*(lp+5));
            comp_num=*(lp+7);
      if((comp_num!=1)&&(comp_num!=3))
      return FUNC_FORMAT_ERROR;
   if(comp_num==3){
    comp_index[0]=*(lp+8);
      SampRate_Y_H=(*(lp+9))>>4;
      SampRate_Y_V=(*(lp+9))&0x0f;
      YQtTable=(short *)qt_table[*(lp+10)];

    comp_index[1]=*(lp+11);
    SampRate_U_H=(*(lp+12))>>4;
      SampRate_U_V=(*(lp+12))&0x0f;
      UQtTable=(short *)qt_table[*(lp+13)];

      comp_index[2]=*(lp+14);
      SampRate_V_H=(*(lp+15))>>4;
      SampRate_V_V=(*(lp+15))&0x0f;
    VQtTable=(short *)qt_table[*(lp+16)];
     }
   else{
      comp_index[0]=*(lp+8);
    SampRate_Y_H=(*(lp+9))>>4;
      SampRate_Y_V=(*(lp+9))&0x0f;
      YQtTable=(short *)qt_table[*(lp+10)];

    comp_index[1]=*(lp+8);
      SampRate_U_H=1;
      SampRate_U_V=1;
      UQtTable=(short *)qt_table[*(lp+10)];

    comp_index[2]=*(lp+8);
    SampRate_V_H=1;
      SampRate_V_V=1;
      VQtTable=(short *)qt_table[*(lp+10)];
   }
     lp+=llength;          
   break;
  case M_DHT:             
   llength=MAKEWORD(*(lp+1),*lp);
   if (llength<0xd0){
    huftab1=(short)(*(lp+2))>>4;     //huftab1=0,1
     huftab2=(short)(*(lp+2))&0x0f;   //huftab2=0,1
    huftabindex=huftab1*2+huftab2;
     lptemp=lp+3;
    for (i=0; i<16; i++)
     code_len_table[huftabindex][i]=(short)(*(lptemp++));
    j=0;
    for (i=0; i<16; i++)
     if(code_len_table[huftabindex][i]!=0){
      k=0;
      while(k<code_len_table[huftabindex][i]){
       code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
       k++;
      }
      j+=k; 
     }
    i=0;
    while (code_len_table[huftabindex][i]==0)
      i++;
    for (j=0;j<i;j++){
     huf_min_value[huftabindex][j]=0;
     huf_max_value[huftabindex][j]=0;
    }
    huf_min_value[huftabindex][i]=0;
    huf_max_value[huftabindex][i]=code_len_table[huftabindex][i]-1;
    for (j=i+1;j<16;j++){
     huf_min_value[huftabindex][j]=(huf_max_value[huftabindex][j-1]+1)<<1;
     huf_max_value[huftabindex][j]=huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
    }
    code_pos_table[huftabindex][0]=0;
    for (j=1;j<16;j++)
       code_pos_table[huftabindex][j]=code_len_table[huftabindex][j-1]+code_pos_table[huftabindex][j-1];
      lp+=llength;
   }  //if
   else{
     hf_table_index=*(lp+2);
    lp+=2;
    while (hf_table_index!=0xff){
     huftab1=(short)hf_table_index>>4;     //huftab1=0,1
      huftab2=(short)hf_table_index&0x0f;   //huftab2=0,1
     huftabindex=huftab1*2+huftab2;
     lptemp=lp+1;
     ccount=0;
     for (i=0; i<16; i++){
      code_len_table[huftabindex][i]=(short)(*(lptemp++));
      ccount+=code_len_table[huftabindex][i];
     }
     ccount+=17; 
     j=0;
     for (i=0; i<16; i++)
      if(code_len_table[huftabindex][i]!=0){
       k=0;
       while(k<code_len_table[huftabindex][i])
       {
        code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
        k++;
       }
       j+=k;
      }
     i=0;
     while (code_len_table[huftabindex][i]==0)
      i++;
     for (j=0;j<i;j++){
      huf_min_value[huftabindex][j]=0;
      huf_max_value[huftabindex][j]=0;
     }
     huf_min_value[huftabindex][i]=0;
     huf_max_value[huftabindex][i]=code_len_table[huftabindex][i]-1;
     for (j=i+1;j<16;j++){
      huf_min_value[huftabindex][j]=(huf_max_value[huftabindex][j-1]+1)<<1;
      huf_max_value[huftabindex][j]=huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
     }
     code_pos_table[huftabindex][0]=0;
     for (j=1;j<16;j++)
      code_pos_table[huftabindex][j]=code_len_table[huftabindex][j-1]+code_pos_table[huftabindex][j-1];
     lp+=ccount;
     hf_table_index=*lp;
    }  //while
   }  //else
   break;
  case M_DRI:
   llength=MAKEWORD(*(lp+1),*lp);
   restart=MAKEWORD(*(lp+3),*(lp+2));
   lp+=llength;
   break;
  case M_SOS:
   llength=MAKEWORD(*(lp+1),*lp);
   comnum=*(lp+2);
   if(comnum!=comp_num)
    return FUNC_FORMAT_ERROR;
   lptemp=lp+3;
   for (i=0;i<comp_num;i++){
    if(*lptemp==comp_index[0]){
     YDcIndex=(*(lptemp+1))>>4;   //Y
     YAcIndex=((*(lptemp+1))&0x0f)+2;
    }
    else{
     UVDcIndex=(*(lptemp+1))>>4;   //U,V
     UVAcIndex=((*(lptemp+1))&0x0f)+2;
    }
    lptemp+=2;
   }
   lp+=llength;
   finish=TRUE;
   break;
  case M_EOI:    
   return FUNC_FORMAT_ERROR;
   break;
  default:
    if ((id&0xf0)!=0xd0){
    llength=MAKEWORD(*(lp+1),*lp);
     lp+=llength;
   }
   else lp+=2;
   break;
    }  //switch
 } //while
 return FUNC_OK;
}
/////////////////////////////////////////////////////////////////
void InitTable()
{
 short i,j;
 sizei=sizej=0;
 ImgWidth=ImgHeight=0;
 rrun=vvalue=0;
 BitPos=0;
 CurByte=0;
 IntervalFlag=FALSE;
 restart=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;
}
/////////////////////////////////////////////////////////////////////////
int Decode()
{
 int funcret;

 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;

⌨️ 快捷键说明

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