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

📄 jpg2bmp.c

📁 开发平台:ADS 1.2 功能:ARM下JPG文件转成BMP文件 1、在C盘根目录下放一个JPG文件
💻 C
📖 第 1 页 / 共 2 页
字号:
// jpg2bmp.c
// Seloo luo
// seloo@tom.com
// 2008-10-10

//header file
#include <string.h>
#include <stdlib.h>
#include "math.h" 
#include "stdio.h" 
#include "DEF.H"
#include "BMP.H"
#include "JPEG.H"

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

//macro definition
#define WIDTHBYTES(i) ((i+31)/32*4)
#define PI 3.1415926535
//define return value of function
#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);
void InitTable(void);
int Decode(void);
int DecodeMCUBlock(void);
int HufBlock(BYTE dchufindex,BYTE achufindex);
int DecodeElement(void);
void IQtIZzMCUComponent(short flag);
void IQtIZzBlock(short*s,int*d,short flag);
void GetYUV(short flag);
void StoreBuffer(void);
BYTE ReadByte(void);
void Initialize_Fast_IDCT(void);
void Fast_IDCT(int*block);
void idctrow(int*blk);
void idctcol(int*blk);
//////////////////////////////////////////////////
//global variable declaration
BITMAPFILEHEADER bf ;
BITMAPINFOHEADER bi ;
char  *hImgData=NULL ;
void  *hJpegBuf=NULL ;
DWORD NumColors ;
DWORD LineBytes ;
DWORD ImgWidth=0,ImgHeight=0 ;
//////////////////////////////////////////////////
//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 ;



////////////////////////////////////////////////////////////////
BOOL LoadJpegFile(char *JpegFileName)
{
    FILE *hfjpg ;
    DWORD ImgSize ,JpegBufSize ;
    FILE *hfbmp ;
    int funcret ;
 
    //BITMAPINFOHEADER *lpImgData ;
   
    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);
    printf("Jpegfile size is %ld\n",JpegBufSize);

    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)
    {
        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("ImgWidth is %ld\n",bi.biWidth);
    printf("bi.biBitCount is %d\n",bi.biBitCount);
    LineBytes=(unsigned long)WIDTHBYTES(bi.biWidth*bi.biBitCount);
    printf("ImgHeight is %ld\n",bi.biHeight);
    ImgSize=(DWORD)LineBytes*bi.biHeight ;
    printf("Image size is %ld\n",ImgSize);
    bf.bfType=0x4d42 ;
    bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize ;
  
    printf("sizeof(BITMAPFILEHEADER) is %d\n",sizeof(BITMAPFILEHEADER));
    printf("sizeof(BITMAPINFOHEADER) is %d\n",sizeof(BITMAPINFOHEADER));
    
    bf.bfOffBits=(DWORD)(NumColors*sizeof(RGBQUAD)+(sizeof(BITMAPFILEHEADER))+sizeof(BITMAPINFOHEADER)) ;

    if((hImgData=(char*)malloc(ImgSize))==NULL)
    {
        free(hJpegBuf);
        showerror(FUNC_MEMORY_ERROR);
        return FALSE ;
    }

    if((SampRate_Y_H==0)||(SampRate_Y_V==0))
    {
        free(hJpegBuf);
        free(hImgData);
        hImgData=NULL ;
        showerror(FUNC_FORMAT_ERROR);
        return FALSE ;
    }
    
    funcret=Decode();
    if(funcret==FUNC_OK)
    {

        if((hfbmp=fopen("c:\\test.bmp","wb"))==NULL)
        {
            showerror(FUNC_FILE_ERROR);
            return FALSE ;
        }
        
        fwrite((char *)&bf,sizeof(BITMAPFILEHEADER),1,hfbmp);
        fwrite((char *)&bi,sizeof(BITMAPINFOHEADER),1,hfbmp);
        fwrite((char *)hImgData,sizeof(char),ImgSize,hfbmp);
        fclose(hfbmp);
        free(hJpegBuf);
        return TRUE ;
    }
    else 
    {
        free(hJpegBuf);
        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(void)
{
    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 ;
            default :
            if((id&0xf0)!=0xd0)
            {
                llength=MAKEWORD(*(lp+1),*lp);
                lp+=llength ;
            }
            else lp+=2 ;
            break ;
        }//switch
    }//while
    return FUNC_OK ;
}
/////////////////////////////////////////////////////////////////
void InitTable(void)
{
    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 ;
    Initialize_Fast_IDCT();
    while((funcret=DecodeMCUBlock())==FUNC_OK)
    {
        interval++;
        if((restart)&&(interval%restart==0))
        IntervalFlag=TRUE ;
        else 

⌨️ 快捷键说明

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