jpeg转bmp实现c代码

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

    #include <stdio.h>  
    #include <stdlib.h>  
    #include <time.h>  
      
    #pragma pack(1)  
    #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) */  
      
    //*************************************************************************************  
    typedef char CHAR;  
    typedef short SHORT;  
    typedef long LONG;  
      
    typedef unsigned long       DWORD;  
    typedef int                 BOOL;  
    typedef unsigned char       BYTE;  
    typedef unsigned short      WORD;  
      
    typedef int HFILE;  
    typedef CHAR *LPSTR, *PSTR;  
      
    #define FALSE 0  
    #define TRUE 1  
      
    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, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;  
      
    typedef struct tagBITMAPFILEHEADER {  
        WORD    bfType;  
        DWORD   bfSize;  
        WORD    bfReserved1;  
        WORD    bfReserved2;  
        DWORD   bfOffBits;  
    }  BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;  
      
    /* constants for the biCompression field */  
    #define BI_RGB        0L  
    #define BI_RLE8       1L  
    #define BI_RLE4       2L  
    #define BI_BITFIELDS  3L  
      
    typedef struct tagRGBQUAD {  
        BYTE    rgbBlue;  
        BYTE    rgbGreen;  
        BYTE    rgbRed;  
        BYTE    rgbReserved;  
    } RGBQUAD;  
    typedef RGBQUAD * LPRGBQUAD;  
      
    #define MAKEWORD(a, b)      ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8))  
    #define MAKELONG(a, b)      ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))  
    #define LOWORD(l)           ((WORD)(l))  
    #define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))  
    #define LOBYTE(w)           ((BYTE)(w))  
    #define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))  
      
    //---yk--- add  
    #include "memory.h"  
    #include "math.h"  
    #include "stdio.h"  
    //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 InitTable();  
    int  Decode();  
    int  DecodeMCUBlock();  
    int  HufBlock(BYTE dchufindex, BYTE 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;  
    //HPALETTE           hPalette=NULL;  
    //HBITMAP            hBitmap=NULL;  
    char *            hImgData = NULL;  
    DWORD              NumColors;  
    DWORD              LineBytes;  
    DWORD              ImgWidth = 0, ImgHeight = 0;  
    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;  
      
    ////////////////////////////////////////////////////////////////  
    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;  
        fopen_s(&hfjpg, JpegFileName, "rb");  
      
        //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);  
      
        bf.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;  
        bf.bfOffBits = 54;//(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));  
        BufSize = bf.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)  
        {  
            fopen_s(&hfbmp, "jpeg2-bmp.bmp", "wb");  
            fwrite((LPSTR)&bf, sizeof(BITMAPFILEHEADER), 1, hfbmp);  
            fwrite((LPSTR)lpImgData, sizeof(char), BufSize, hfbmp);  
            fopen_s(&IMGdata, "111.txt", "wb");  
      
            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);  
            fclose(IMGdata);  
      
            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()  
    {  
        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;  
        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;  
        buf = Y;  
        pQtZzMCU = QtZzMCUBuffer;  
        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;  
        pMCUBuffer = MCUBuffer;  
        pQtZzMCUBuffer = QtZzMCUBuffer;  
        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;  
        pQt = YQtTable;  
        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];  
    }  
      
    int main()  
    {  
        long time = clock();  
        LoadJpegFile("0.jpg");  
        printf("%d\n", clock() - time);  
        return 0;  
    }