Jpeg文件格式转换成bmp文件格式

为了简单,我将jpg图片原文件和转换后的bmp文件都直接存到内存的数组,这样不会涉及文件操作。

将jpg文件转换成数组,并将数组存到文件中方便编译调用,我用的是C库文件操作接口,也可以用其他文件系统。

//读文件

int FILE_Read(FILE*fd, const void*buf, int len)

{

         #define READ_MAX_LEN         1024

         int cnt,leftLen;

         int hasread=0;

        

         cnt = len/READ_MAX_LEN;

         leftLen = len%READ_MAX_LEN;     

         if(cnt>0)

                   hasread += READ_MAX_LEN*fread((char*)buf+hasread, READ_MAX_LEN, cnt, fd);  

         if(leftLen>0)

         {

                   while(!feof(fd)&&(len-hasread)>0)

                   {

                            hasread += fread((char*)buf+hasread, 1, len-hasread, fd);

                            if(ferror(fd))

                            {

                                     break;

                            }

                   }

         }

        

         return hasread;

}



//将jpg文件保存到数组

void SaveJpgFile2Arry(const char * jpgFileName ,unsigned char *jpgFileBuf, DWORD len)

{

         FILE *fd;

    DWORD i = 0;

         char *s2 = "};";

         char buf[50]={0};

         char rollEnd[]={0x0d,0x0a};

  FILE *fd;

  DWORD FileSize;

  unsigned char * pFile;

 



         //将文件读到缓冲区

  fd = fopen(jpgFileName,"rb");

  fseek(fd,0,SEEK_END);

  FileSize = ftell(fd);

  pFile = malloc(FileSize);

   fseek(fd,0,SEEK_SET);

  FILE_Read(fd,pFile,FileSize);

fclose(fd);

       

         //生成jpg数据对应的数组文件,我的路径是:

//      "E:\\UCGUI390_sim\\Start\\Application\\jpg_data.c",你需要改成你自己的存储路劲

// fuck! 注意文件打开模式必须是2进制的,否则图片可能失真,其他文件系统不知道会不//会出问题

         fd = fopen("E:\\UCGUI390_sim\\Start\\Application\\jpg_data.c","wb+");

//数组名:const unsigned char jpgData[]

         sprintf(buf,"const unsigned char jpgData[%d] = {",len);

         fwrite(buf,strlen(buf),1,fd);



    for (i =0; i<len; i++)

    {

                   if(i%16 == 0)

                   {

                            fwrite(rollEnd,2,1,fd);      //换行符,最好不要直接使用字符串“\n”,有些编辑//器不识别

                   }

                   sprintf(buf,"0X%02X,", jpgFileBuf[i]);//十六进制格式

                   fwrite(buf,strlen(buf),1,fd);  

         }

         fwrite(rollEnd,2,1,fd);     

         fwrite(s2,strlen(s2),1,fd);

         fclose(fd);

}



数组const unsigned char jpgData[]就是我们要转换的jpg文件数据。





有了jpg数据文件,下一步就开始转换了。



先生成一个头文件jpeg.h,头文件中声明一些数据类型以及定义相关数据结构和宏

头文件源码如下:

#ifndef JPG_H_

#define JPG_H_



#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



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) */

#define BI_RGB        0L



#ifndef FALSE                      /* in case these macros already exist */

#define FALSE  0                /* values of boolean */

#endif

#ifndef TRUE

#define TRUE   1

#endif



typedef unsigned long       DWORD;

typedef int                 BOOL;

typedef unsigned char       BYTE;

typedef unsigned short      WORD;

typedef long LONG;



#define MAKEWORD(a, b)      ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8))





typedef struct tagRGBQUAD {

        BYTE    rgbBlue;

        BYTE    rgbGreen;

        BYTE    rgbRed;

        BYTE    rgbReserved;

} RGBQUAD;



// fuck! 2字节对齐,否则编译器默认4字节对齐,导致文件头长度错误

#pragma pack (2)

typedef struct tagBITMAPFILEHEADER {

        WORD    bfType;

        DWORD   bfSize;

        WORD    bfReserved1;

        WORD    bfReserved2;

        DWORD   bfOffBits;

} BITMAPFILEHEADER;

#pragma pack()



typedef struct tagBITMAPINFOHEADER{

        DWORD      biSize;

        LONG       biWidth;

        LONG       biHeight;

        WORD       biPlanes;

        WORD       biBitCount;

        DWORD      biCompression;

        DWORD      biSizeImage;

        LONG       biXPelsPerMeter;

        LONG       biYPelsPerMeter;

        DWORD      biClrUsed;

        DWORD      biClrImportant;

} BITMAPINFOHEADER;



#endif



下面是转换文件源码jpg2bmp.c,这里声明下:源码来源于网上,我同学下的,其实也是昨天我同学问了我jpg文件显示相关问题,我今天才写了这篇博客。至于出处我也不知道,请作者见谅。我将其中文件操作去掉了,转换后的bmp文件数据直接存到内存,同时涉及vc的内容也去掉了,这样可以更独立的使用。

/*start of file*/

#include "jpeg.h"

#include "stdio.h"

#include "string.h"

#include "stdlib.h"



#define WIDTHBYTES(i)    ((i+31)/32*4)

#define PI 3.1415926535

#define FUNC_OK 0

#define FUNC_MEMORY_ERROR 1

#define FUNC_FILE_ERROR 2

#define FUNC_FORMAT_ERROR 3

//

//Jpeg functions

BOOL LoadJpegFile(char *BmpFileName);

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();

BYTE ReadByte();

void Initialize_Fast_IDCT();

void Fast_IDCT(int * block);

void idctrow(int * blk);

void idctcol(int * blk);

//

//global variable declaration

BITMAPFILEHEADER   bf;

BITMAPINFOHEADER   bi;

char*            hBitmap=NULL;

char*            hImgData=NULL;

DWORD              NumColors;

DWORD              LineBytes;

DWORD              ImgWidth=0 , ImgHeight=0;

unsigned int       PcxBytesPerLine;

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   *lp;

short                           qt_table[3][64];

short                           comp_num;

BYTE                            comp_index[3];

BYTE                      YDcIndex,YAcIndex,UVDcIndex,UVAcIndex;

BYTE                            HufTabIndex;

short                      *YQtTable,*UQtTable,*VQtTable;

BYTE                            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;

BOOL                           IntervalFlag;

short                           interval=0;

int                                Y[4*64],U[4*64],V[4*64];

DWORD                sizei,sizej;

short                          restart;

static  long     iclip[1024];

static  long     *iclp;



char*   myBmpData;





//jpg数据声明,这个就是我们之前生成的数组

extern unsigned char jpgData[];



int LoadJpegFile (void)

{

         DWORD                  ImgSize;

         int                                   funcret;

         FILE *fd;

         int bitmapFileHeaderLen,bitmapInfoHeaderLen;

         char *p;

         lpJpegBuf = jpgData;



         InitTable();

        

         if((funcret=InitTag())!=FUNC_OK)

         {

                   return 0;

         }



         bitmapFileHeaderLen = sizeof(BITMAPFILEHEADER);

         bitmapInfoHeaderLen = sizeof(BITMAPINFOHEADER);

        

         //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;

         LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);

         ImgSize=(DWORD)LineBytes*bi.biHeight;



         bf.bfType=0x4d42;

         bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;

         bf.bfOffBits=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));



         if((hImgData=malloc(ImgSize))==NULL)

         {

                   return 0;

         }

         lpPtr=(char *)hImgData;



         if((SampRate_Y_H==0)||(SampRate_Y_V==0))

         {

                   return 0 ;

         }



         funcret=Decode();

        

         if(funcret==FUNC_OK)

         {

                   /*用文件存储转换后的bmp数据,主要是为了在vc下验证数据转换是否正确

在应用中可以去掉

*/

                   fd=fopen("E:\\UCGUI390_sim\\Start\\jpgFile\\test_my.bmp","wb+");

                   fwrite(&bf,sizeof(BITMAPFILEHEADER),1,fd); //写BMP文件头

                   fwrite(&bi,sizeof(BITMAPINFOHEADER),1,fd); //写BMP文件信息

                  

                   fwrite(hImgData,ImgSize,1,fd);            //写BMP位图数据

                   fclose(fd);

        

                   //直接将转换后的bmp数据存到内存数组中

                   //申请内存

                   if((myBmpData=malloc(bf.bfSize))==NULL)

                   {

                            return 0;

                   }

                   p = myBmpData;

                   memcpy(p,&bf,sizeof(BITMAPFILEHEADER));//存储bmp文件头

                   p += sizeof(BITMAPFILEHEADER);

                   memcpy(p,&bi,sizeof(BITMAPINFOHEADER)); //存储bmp信息头

                   p += sizeof(BITMAPINFOHEADER);

                   memcpy(p,hImgData,ImgSize); //存储bmp显示数据

                   free(hImgData);  //释放直接存储图片数据申请的内存

                   return 1;

         }

         else

         {

                   return 0;

         }

}

/



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<4*64;i++)

         {

                   Y[i]=0;

                   U[i]=0;

                   V[i]=0;               

         }

         for(i=0;i<64;i++)

                   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;

         Initialize_Fast_IDCT();

         while((funcret=DecodeMCUBlock())==FUNC_OK)

         {

                   interval++;

                   if((restart)&&(interval % restart==0))

                             IntervalFlag=TRUE;

                   else

                            IntervalFlag=FALSE;

                   IQtIZzMCUComponent(0);

                   IQtIZzMCUComponent(1);

                   IQtIZzMCUComponent(2);

                   GetYUV(0);

                   GetYUV(1);

                   GetYUV(2);

                   StoreBuffer();

                   sizej+=SampRate_Y_H*8;

                   if(sizej>=ImgWidth)

                   {

                            sizej=0;

                            sizei+=SampRate_Y_V*8;

                   }

                   if ((sizej==0)&&(sizei>=ImgHeight))

                            break;

         }

         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()

{

         short i,j;

         unsigned char  *lpbmp;

         unsigned char R,G,B;

         int y,u,v,rr,gg,bb;



         for(i=0;i<SampRate_Y_V*8;i++)

         {

                   if((sizei+i)<ImgHeight)

                   {

                            lpbmp=((unsigned char *)lpPtr+(DWORD)(ImgHeight-sizei-i-1)*LineBytes+sizej*3);

                            for(j=0;j<SampRate_Y_H*8;j++)

                            {

                                     if((sizej+j)<ImgWidth)

                                     {

                                               y=Y[i*8*SampRate_Y_H+j];

                                               u=U[(i/V_YtoU)*8*SampRate_Y_H+j/H_YtoU];

                                               v=V[(i/V_YtoV)*8*SampRate_Y_H+j/H_YtoV];

                                               rr=((y<<8)+18*u+367*v)>>8;

                                               gg=((y<<8)-159*u-220*v)>>8;

                                               bb=((y<<8)+411*u-29*v)>>8;

                                               R=(unsigned char)rr;

                                               G=(unsigned char)gg;

                                               B=(unsigned char)bb;

                                               if (rr&0xffffff00) if (rr>255) R=255; else if (rr<0) R=0;

                                               if (gg&0xffffff00) if (gg>255) G=255; else if (gg<0) G=0;

                                               if (bb&0xffffff00) if (bb>255) B=255; else if (bb<0) B=0;

                                               *lpbmp++=B;

                                               *lpbmp++=G;

                                               *lpbmp++=R;

                                     }

                                     else  break;

                            }

                   }

                   else break;

         }

}

///

int DecodeMCUBlock()

{

         short *lpMCUBuffer;

         short i,j;

         int funcret;



         if (IntervalFlag)

         {

                   lp+=2;

                   ycoef=ucoef=vcoef=0;

                   BitPos=0;

                   CurByte=0;

         }

         switch(comp_num)

         {

         case 3:

                   lpMCUBuffer=MCUBuffer;

                   for (i=0;i<SampRate_Y_H*SampRate_Y_V;i++)  //Y

                   {

                            funcret=HufBlock(YDcIndex,YAcIndex);

                            if (funcret!=FUNC_OK)

                                     return funcret;

                            BlockBuffer[0]=BlockBuffer[0]+ycoef;

                            ycoef=BlockBuffer[0];

                            for (j=0;j<64;j++)

                                     *lpMCUBuffer++=BlockBuffer[j];

                   }

                   for (i=0;i<SampRate_U_H*SampRate_U_V;i++)  //U

                   {

                            funcret=HufBlock(UVDcIndex,UVAcIndex);

                            if (funcret!=FUNC_OK)

                                     return funcret;

                            BlockBuffer[0]=BlockBuffer[0]+ucoef;

                            ucoef=BlockBuffer[0];

                            for (j=0;j<64;j++)

                                     *lpMCUBuffer++=BlockBuffer[j];

                   }

                   for (i=0;i<SampRate_V_H*SampRate_V_V;i++)  //V

                   {

                            funcret=HufBlock(UVDcIndex,UVAcIndex);

                            if (funcret!=FUNC_OK)

                                     return funcret;

                            BlockBuffer[0]=BlockBuffer[0]+vcoef;

                            vcoef=BlockBuffer[0];

                            for (j=0;j<64;j++)

                                     *lpMCUBuffer++=BlockBuffer[j];

                   }

                   break;

         case 1:

                   lpMCUBuffer=MCUBuffer;

                   funcret=HufBlock(YDcIndex,YAcIndex);

                   if (funcret!=FUNC_OK)

                            return funcret;

                   BlockBuffer[0]=BlockBuffer[0]+ycoef;

                   ycoef=BlockBuffer[0];

                   for (j=0;j<64;j++)

                            *lpMCUBuffer++=BlockBuffer[j];

                   for (i=0;i<128;i++)

                            *lpMCUBuffer++=0;

                   break;

         default:

                   return FUNC_FORMAT_ERROR;

         }

         return FUNC_OK;

}

//

int HufBlock(BYTE dchufindex,BYTE achufindex)

{

         short count=0;

         short i;

         int funcret;



         //dc

         HufTabIndex=dchufindex;

         funcret=DecodeElement();

         if(funcret!=FUNC_OK)

                   return funcret;



         BlockBuffer[count++]=vvalue;

         //ac

         HufTabIndex=achufindex;

         while (count<64)

         {

                   funcret=DecodeElement();

                   if(funcret!=FUNC_OK)

                            return funcret;

                   if ((rrun==0)&&(vvalue==0))

                   {

                            for (i=count;i<64;i++)

                                     BlockBuffer[i]=0;

                            count=64;

                   }

                   else

                   {

                            for (i=0;i<rrun;i++)

                                     BlockBuffer[count++]=0;

                            BlockBuffer[count++]=vvalue;

                   }

         }

         return FUNC_OK;

}

//

int DecodeElement()

{

         int thiscode,tempcode;

         unsigned short temp,valueex;

         short codelen;

         BYTE hufexbyte,runsize,tempsize,sign;

         BYTE newbyte,lastbyte;



         if(BitPos>=1)

         {

                   BitPos--;

                   thiscode=(BYTE)CurByte>>BitPos;

                   CurByte=CurByte&And[BitPos];

         }

         else

         {

                   lastbyte=ReadByte();

                   BitPos--;

                   newbyte=CurByte&And[BitPos];

                   thiscode=lastbyte>>7;

                   CurByte=newbyte;

         }

         codelen=1;

         while ((thiscode<huf_min_value[HufTabIndex][codelen-1])||

                     (code_len_table[HufTabIndex][codelen-1]==0)||

                     (thiscode>huf_max_value[HufTabIndex][codelen-1]))

         {

                   if(BitPos>=1)

                   {

                            BitPos--;

                            tempcode=(BYTE)CurByte>>BitPos;

                            CurByte=CurByte&And[BitPos];

                   }

                   else

                   {

                            lastbyte=ReadByte();

                            BitPos--;

                            newbyte=CurByte&And[BitPos];

                            tempcode=(BYTE)lastbyte>>7;

                            CurByte=newbyte;

                   }

                   thiscode=(thiscode<<1)+tempcode;

                   codelen++;

                   if(codelen>16)

                            return FUNC_FORMAT_ERROR;

         }  //while

         temp=thiscode-huf_min_value[HufTabIndex][codelen-1]+code_pos_table[HufTabIndex][codelen-1];

         hufexbyte=(BYTE)code_value_table[HufTabIndex][temp];

         rrun=(short)(hufexbyte>>4);

         runsize=hufexbyte&0x0f;

         if(runsize==0)

         {

                   vvalue=0;

                   return FUNC_OK;

         }

         tempsize=runsize;

         if(BitPos>=runsize)

         {

                   BitPos-=runsize;

                   valueex=(BYTE)CurByte>>BitPos;

                   CurByte=CurByte&And[BitPos];

         }

         else

         {

                   valueex=CurByte;

                   tempsize-=BitPos;

                   while(tempsize>8)

                   {

                            lastbyte=ReadByte();

                            valueex=(valueex<<8)+(BYTE)lastbyte;

                            tempsize-=8;

                   }  //while

                   lastbyte=ReadByte();

                   BitPos-=tempsize;

                   valueex=(valueex<<tempsize)+(lastbyte>>BitPos);

                   CurByte=lastbyte&And[BitPos];

         }  //else

         sign=valueex>>(runsize-1);

         if(sign)

                   vvalue=valueex;

         else

         {

                   valueex=valueex^0xffff;

                   temp=0xffff<<runsize;

                   vvalue=-(short)(valueex^temp);

         }

         return FUNC_OK;

}

/

void IQtIZzMCUComponent(short flag)

{

         short H,VV;

         short i,j;

         int *pQtZzMCUBuffer;

         short  *pMCUBuffer;



         switch(flag)

         {

         case 0:

                   H=SampRate_Y_H;

                   VV=SampRate_Y_V;

                   pMCUBuffer=MCUBuffer;

                   pQtZzMCUBuffer=QtZzMCUBuffer;

                   break;

         case 1:

                   H=SampRate_U_H;

                   VV=SampRate_U_V;

                   pMCUBuffer=MCUBuffer+Y_in_MCU*64;

                   pQtZzMCUBuffer=QtZzMCUBuffer+Y_in_MCU*64;

                   break;

         case 2:

                   H=SampRate_V_H;

                   VV=SampRate_V_V;

                   pMCUBuffer=MCUBuffer+(Y_in_MCU+U_in_MCU)*64;

                   pQtZzMCUBuffer=QtZzMCUBuffer+(Y_in_MCU+U_in_MCU)*64;

                   break;

         }

         for(i=0;i<VV;i++)

                   for (j=0;j<H;j++)

                            IQtIZzBlock(pMCUBuffer+(i*H+j)*64,pQtZzMCUBuffer+(i*H+j)*64,flag);

}

//

void IQtIZzBlock(short  *s ,int * d,short flag)

{

         short i,j;

         short tag;

         short *pQt;

         int buffer2[8][8];

         int *buffer1;

         short offset;



         switch(flag)

         {

         case 0:

                   pQt=YQtTable;

                   offset=128;

                   break;

         case 1:

                   pQt=UQtTable;

                   offset=0;

                   break;

         case 2:

                   pQt=VQtTable;

                   offset=0;

                   break;

         }



         for(i=0;i<8;i++)

                   for(j=0;j<8;j++)

                   {

                            tag=Zig_Zag[i][j];

                            buffer2[i][j]=(int)s[tag]*(int)pQt[tag];

                   }

         buffer1=(int *)buffer2;

         Fast_IDCT(buffer1);

         for(i=0;i<8;i++)

                   for(j=0;j<8;j++)

                            d[i*8+j]=buffer2[i][j]+offset;

}

///

void Fast_IDCT(int * block)

{

         short i;



         for (i=0; i<8; i++)

                   idctrow(block+8*i);



         for (i=0; i<8; i++)

                   idctcol(block+i);

}

///

BYTE  ReadByte()

{

         BYTE  i;



         i=*(lp++);

         if(i==0xff)

                   lp++;

         BitPos=8;

         CurByte=i;

         return i;

}

///

void Initialize_Fast_IDCT()

{

         short i;



         iclp = iclip+512;

         for (i= -512; i<512; i++)

                   iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);

}



void idctrow(int * blk)

{

         int x0, x1, x2, x3, x4, x5, x6, x7, x8;

         //intcut

         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;

                   return;

         }

         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] = (x7+x1)>>8;

         blk[1] = (x3+x2)>>8;

         blk[2] = (x0+x4)>>8;

         blk[3] = (x8+x6)>>8;

         blk[4] = (x8-x6)>>8;

         blk[5] = (x0-x4)>>8;

         blk[6] = (x3-x2)>>8;

         blk[7] = (x7-x1)>>8;

}

//

void idctcol(int * blk)

{

         int x0, x1, x2, x3, x4, x5, x6, x7, x8;

         //intcut

         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];

                   return;

         }

         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];

}

/*endof file*/

调用int LoadJpegFile (void)这个函数后,转换后的bmp数据文件会存到myBmpData所指的内存中,我们可以调用Gui的bmp图片显示借口显示,也可转换成文件在pc上验证数据是否准确。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缥缈孤鸿_jason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值