JPEG解码程序(带中文注释)

JPEG解码,困扰了我好长一段时间,网上的教程有很多问题,首先解码过程基本没有,都是理论;而且细节部分很多错误,容易误导大家;另外教程就那两三个,其余的都是转载。
可用VS建立控制台程序,并把这个程序输入,即可直接运行

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <windows.h>
using namespace std;


//公共数据定义区-------------------------------------//
double PI=3.14159265358979;
DWORD t1=0,t2=0,t3=0,t4=0;
//CbCr拓扑表
int CrCb[64]={0,0,1,1,2,2,3,3,
              0,0,1,1,2,2,3,3,
              8,8,9,9,10,10,11,11,
              8,8,9,9,10,10,11,11,
              16,16,17,17,18,18,19,19,
              16,16,17,17,18,18,19,19,
              24,24,25,25,26,26,27,27,
              24,24,25,25,26,26,27,27
             };
int crcb(int i,int s)
{
    int h=0;
    if(s==0)h=0;
    else if(s==1)h=4;
    else if(s==2)h=32;
    else if(s==3)h=36;
    return CrCb[i]+h;
}

//反z型编码表
int FZig[64]={0,1,5,6,14,15,27,28,
            2,4,7,13,16,26,29,42,
            3,8,12,17,25,30,41,43,
            9,11,18,24,31,40,44,53,
            10,19,23,32,39,45,52,54,
            20,22,33,38,46,51,55,60,
            21,34,37,47,50,56,59,61,
            35,36,48,49,57,58,62,63};


//反DCT表,快速DCT表
double fast_IDCT[8][8]={
0.35355339059327001, 0.49039264020161527, 0.46193976625564348, 0.41573480615127278, 0.35355339059327406, 0.27778511650980153, 0.19134171618254542, 0.097545161008064818,
0.35355339059327001, 0.41573480615127278, 0.19134171618254542, -0.097545161008063236, -0.35355339059327295, -0.49039264020161494, -0.46193976625564409, -0.27778511650980292,
0.35355339059327001, 0.27778511650980153, -0.19134171618254392, -0.49039264020161494, -0.35355339059327523, 0.097545161008061529, 0.4619397662556422, 0.41573480615127451,
0.35355339059327001, 0.097545161008064818, -0.46193976625564287, -0.27778511650980292, 0.35355339059327179, 0.41573480615127451, -0.19134171618254084, -0.49039264020161621,
0.35355339059327001, -0.097545161008063236, -0.46193976625564409, 0.2777851165097987, 0.3535533905932764, -0.41573480615127012, -0.19134171618255019, 0.49039264020161405,
0.35355339059327001, -0.27778511650980026, -0.19134171618254681, 0.49039264020161583, -0.35355339059327084, -0.097545161008069245, 0.46193976625564576, -0.41573480615126807,
0.35355339059327001, -0.4157348061512719, 0.19134171618254253, 0.097545161008067871, -0.35355339059327734, 0.49039264020161655, -0.46193976625564048, 0.27778511650979337,
0.35355339059327001, -0.49039264020161494, 0.4619397662556422, -0.41573480615127012, 0.35355339059326951, -0.27778511650979487, 0.19134171618253656, -0.097545161008053827};




class JPEG{

    //数据区
public:
    ifstream myjpg; //图片文件对象
    long int jpg_size;//图片文件字节数
    long data_start;//数据开始点

    //double fandct[8][8];//反DCT表

    bool JM;//解码结果
    int** rgb_r;    //图形解码结果存放处
    int** rgb_g;    //
    int** rgb_b;    //
    long mcu_w,mcu_h;//补全边角的宽和高

    //SOFO  0XFFC0
    int data_precision;//颜色数据精度:8/12/16:  8/12/16(bit)
    int jpg_hight;//图片高度(像素)
    int jpg_width;//图片宽度(像素)
    int colors;//颜色分量数(1灰度,3YCrCb,4CMYK)
    int color_infor[3][5];//各颜色分量信息:[n][0]=ID,[n][1]=水平/垂直采样因子(高低4位),[n][2]=当前颜色分量使用的量化表,[n][3]/[4]=当前颜色分量使用的直流/交流哈夫曼树表编号
    int YCbCr_BIZHI;//采样比
    int ACjzbl[3];//Y Cr Cb 三个直流矫正变量;

    unsigned char* data_buf;//数据缓存区
    long data_lp;//数据指针
    long datasize;//数据总长

    //DQT 0XFFDB
    unsigned short QT[4][64];//量化表

    //DHT 0XFFC4
    int HT_bit[4][17];//哈夫曼表不同位数的码字数量(16),码字数量之和(1)
    int* sp_HT_value[4];//哈夫曼权值表指针
    int* sp_HT_tree[4];//哈夫曼树指针

    //DRI 0XFFDD
    unsigned short DRI_val;//差分编码累计复位值

    //Getbit()所需数据
    int s_bit;
    unsigned char bittemp;

    //Decode_Photo()相关参数
    int mcu_x,mcu_y;

    //函数区
public:
    JPEG(char* filename)
    {
        //打开图像文件
        myjpg.open(filename,ios::binary|ios::in);
        if(myjpg.good()==false)
            cout<<"文件打开失败!"<<endl;

        //验证文件是否为JPEG图片
        unsigned short temp=0;
        temp=myjpg.get();
        temp=(temp<<8)+myjpg.get();
        if(temp!=0xFFD8)
            cout<<"图片打开失败!"<<endl;
        else
            cout<<"图片打开成功!"<<endl;

        //获取文件大小
        myjpg.seekg(0,ios::end);
        this->jpg_size=(long)myjpg.tellg();

        //数据初始化

        s_bit=0;//关于Getbit()函数
        bittemp=0;//关于Getbit()函数

        ACjzbl[0]=0xabcdef;//关于直流系数的差分编码校正
        ACjzbl[1]=0xabcdef;
        ACjzbl[2]=0xabcdef;

        mcu_x=0;//关于Decode_Photo()函数
        mcu_y=0;

        DRI_val=0;//差分编码累计复位的间隔

        JM=false;//解码结果

        //反DCT变换表
        //for(int q1=0;q1<8;q1++)
        //{
        //  for(int qq=0;qq<8;qq++)
        //  {
        //      fandct[q1][qq]=Cu(qq)*cos((2*q1+1)*qq*PI/16);
        //  }
        //}



        //量化表初始化
        for(int n=0;n<4;n++)
        {
            for(int i=0;i<8;i++)
            {
                for(int j=0;j<8;j++)
                {
                    QT[n][i*8+j]=0;
                }
            }
        }


        //图片初始化:图片信息提取

        //1.SOFO
        //颜色精度
        //图像高度和宽度
        //颜色分量数
        //颜色分量信息(分量ID,水平/垂直采样因子,对应量化表ID)
        Read_SOFO();

        //2.DQT
        //量化表ID,精度,个数,表数据
        Read_DQT();

        //3.DHT
        //哈夫曼表信息读取
        //哈夫曼树建立
        Read_DHT();

        //DRI
        Read_DRI();

        //4.SOS
        //颜色分量信息:ID以及对应的DC/AC哈夫曼树
        Read_SOS();

        //5.建立霍夫曼树
        Build_Htree();

        //6.建立图片缓存区
        if(YCbCr_BIZHI==0x111)
        {
            int w=0,h=0;
            w=jpg_width/8;
            if((jpg_width%8)>0)w++;
            h=jpg_hight/8;
            if((jpg_hight%8)>0)h++;

            mcu_w=w*8;
            mcu_h=h*8;
            rgb_r=new int*[mcu_h];
            rgb_g=new int*[mcu_h];
            rgb_b=new int*[mcu_h];
            for(long i=0;i<mcu_h;i++)
            {
                rgb_r[i]=new int[mcu_w];
                rgb_g[i]=new int[mcu_w];
                rgb_b[i]=new int[mcu_w];
            }
        }
        else if(YCbCr_BIZHI==0x411)
        {
            int w=0,h=0;
            w=jpg_width/16;
            if((jpg_width%16)>0)w++;
            h=jpg_hight/16;
            if((jpg_hight%16)>0)h++;

            mcu_w=w*16;
            mcu_h=h*16;
            rgb_r=new int*[mcu_h];
            rgb_g=new int*[mcu_h];
            rgb_b=new int*[mcu_h];
            for(long i=0;i<mcu_h;i++)
            {
                rgb_r[i]=new int[mcu_w];
                rgb_g[i]=new int[mcu_w];
                rgb_b[i]=new int[mcu_w];
            }
        }
        //建立图片原始数据缓存区
        myjpg.seekg(data_start,ios::beg);
        datasize=jpg_size-data_start;
        data_buf=new unsigned char[jpg_size];
        myjpg.read((char*)data_buf,datasize);
        if(myjpg.gcount()==datasize)cout<<"读取完整"<<endl;
        else{cout<<dec<<myjpg.gcount()<<'-'<<datasize<<endl;}
        data_lp=0;//缓存区数据指针
        myjpg.close();
    }
    bool Read_SOFO(void)
    {
        unsigned short temp=0;
        myjpg.seekg(0,ios::beg);

        while( ((temp=(temp<<8)|myjpg.get())!=0xFFC0) && (temp!=0xFFD9) );
        if(temp==0xFFC0)
        {
            temp=myjpg.get();
            temp=(temp<<8)+myjpg.get();
            if(temp==17)
            {
                this->data_precision=myjpg.get();
                this->jpg_hight=(myjpg.get()<<8)+myjpg.get();
                this->jpg_width=(myjpg.get()<<8)+myjpg.get();
                this->colors=myjpg.get();
                for(int i=0;i<3;i++)
                    for(int j=0;j<3;j++)
                        this->color_infor[i][j]=myjpg.get();
                YCbCr_BIZHI=((color_infor[0][1]&0xf0)>>4) * (color_infor[0][1]&0x0f);
                YCbCr_BIZHI=(YCbCr_BIZHI<<4)|(((color_infor[1][1]&0xf0)>>4) * (color_infor[1][1]&0x0f));
                YCbCr_BIZHI=(YCbCr_BIZHI<<4)|(((color_infor[2][1]&0xf0)>>4) * (color_infor[2][1]&0x0f));
            }
            else
                return false;

        }
        else
            return false;
        return true;
    }
    bool Read_DQT(void)
    {
        unsigned short temp=0,S=0;
        myjpg.seekg(0,ios::beg);
        while(!myjpg.eof())
        {
        temp=0;
        while( ((temp=(temp<<8)+myjpg.get())!=0xFFDB) && (temp!=0xFFC0) );
        if(temp==0xFFDB)
        {
            myjpg.seekg(2,ios::cur);
            S=myjpg.get();
            if((S&0xF0)==0)
            {
                S=S&0x0F;
                for(int i=0;i<64;i++)
                {
                    this->QT[S][i]=myjpg.get();
                }
            }
            else
            {
                S=S&0x0F;
                for(int i=0;i<64;i++)
                {
                    this->QT[S][i]=(myjpg.get()<<8)|(myjpg.get());
                }
            }
        }
        else
        {
            return true;
        }
        }
        return false;
    }
    bool Read_DHT(void)
    {
        unsigned short temp=0,size=0,ID=0,u=0;;
        long ts=0;
        myjpg.seekg(0,ios::beg);

        while(1)
        {
            temp=0;
            ts=0;
            size=0;
            ID=0;
            while( ((temp=(temp<<8)+myjpg.get())!=0xFFC4) && (temp!=0xFFDA) );
            if(temp==0xFFC4)
            {
                size=(myjpg.get()<<8)|myjpg.get();

                while(1)
                {
                    ts=(long)myjpg.tellg();
                    ID=myjpg.get();
                    ID=((ID&0x10)>>3)|(ID&0x01);

                    HT_bit[ID][16]=0;
                    for(int i=0;i<16;i++)
                    {
                        this->HT_bit[ID][i]=myjpg.get();
                        HT_bit[ID][16]+=HT_bit[ID][i];
                    }



                    sp_HT_value[ID]=new int[(HT_bit[ID][16])];

                    for(int i=0;i<(HT_bit[ID][16]);i++)
                    {
                        this->sp_HT_value[ID][i]=myjpg.get();
                    }
                    if((size-myjpg.tellg()+ts)<16)break;
                }
            }
            else
                return true;
        }
        return 0;
    }
    bool Read_SOS(void)
    {
        unsigned short temp=0,s=0;
        myjpg.seekg(0,ios::beg);

        while( ((temp=(temp<<8)|myjpg.get())!=0xFFDA) && (temp!=0xFFD9) );
        if(temp==0xFFDA)
        {
            myjpg.seekg(2,ios::cur);
            s=myjpg.get();
            for(int i=0;i<s;i++)
            {
                myjpg.seekg(1,ios::cur);
                temp=myjpg.get();
                this->color_infor[i][3]=temp>>4;
                this->color_infor[i][4]=temp&0x0F;
            }
            myjpg.seekg(3,ios::cur);
            data_start=(long)myjpg.tellg();
        }
        else
            return false;
        return true;
    }
    void print_infor(void)
    {
        cout<<"图片文件大小:"<<(double)jpg_size/1024<<"kb"<<endl;
        cout<<"高*宽:"<<jpg_hight<<"*"<<jpg_width<<endl;
        cout<<"颜色精度:"<<data_precision<<endl;
        cout<<"颜色分量数:"<<colors<<endl;
        cout<<"YCbCr采样比:"<<hex<<YCbCr_BIZHI<<endl<<endl;

        for(int n=0;n<4;n++)
        {
            cout<<"量表"<<n<<':'<<endl;
            for(int i=0;i<8;i++)
            {
                for(int j=0;j<8;j++)
                {
                    cout<<dec<<QT[n][i*8+j]<<'\t';
                }
                cout<<endl;
            }
        }
        cout<<endl;


        for(int n=0;n<4;n++)
        {
            for(int ui=0;ui<16;ui++)
            {
                cout<<dec<<HT_bit[n][ui]<<' ';
            }
            cout<<endl;
            cout<<"哈夫曼树"<<dec<<n+1<<endl;
            int temp=0;
            for(int i=0;i<HT_bit[n][16];i++)
            {
                cout<<hex<<setw(2)<<sp_HT_value[n][i]<<"--->";
                temp=sp_HT_tree[n][i];
                cout<<dec<<setw(2)<<((temp&0xf0000)>>16)<<"  ";
                for(int x=0;x<16;x++)
                {
                    if((temp&0x8000)==0)
                        cout<<'0';
                    else
                        cout<<'1';
                    temp<<=1;
                }
                cout<<endl;
            }
            cout<<endl;
        }

        for(int i=0;i<3;i++)
        {
            for(int j=0;j<5;j++)
            {
                cout<<hex<<color_infor[i][j]<<'\t';
            }
            cout<<endl;
        }

    }
    bool Build_Htree(void)//建立霍夫曼树
    {
        unsigned int temp=0;
        int t1=0;
        int lp=0;

        for(int i=0;i<4;i++)
        {
            sp_HT_tree[i]=new int[HT_bit[i][16]];
            temp=0;
            lp=0;
            for(int ss=0;ss<16;ss++)
            {
                for(int ww=0;ww<HT_bit[i][ss];ww++)
                {
                    sp_HT_tree[i][lp++]=ss+1;
                }
            }
        }

        for(int i=0;i<4;i++)
        {
            temp=0;
            for(int j=0;j<HT_bit[i][16];j++)
            {
                if(j==0)
                {
                    if(sp_HT_tree[i][0]!=1)
                    {
                    t1=sp_HT_tree[i][0];
                    sp_HT_tree[i][0]<<=16;
                    temp=0;
                    }
                    else
                    {
                        t1=sp_HT_tree[i][0];
                        temp=0;
                        sp_HT_tree[i][0]<<=16;
                        temp=0;
                    }
                }
                else
                {
                    if(sp_HT_tree[i][j]>t1)
                    {
                        temp++;
                        temp<<=(sp_HT_tree[i][j]-t1);
                        t1=sp_HT_tree[i][j];
                        sp_HT_tree[i][j]<<=16;
                        sp_HT_tree[i][j]|=temp;
                    }
                    else
                    {
                        temp++;
                        sp_HT_tree[i][j]<<=16;
                        sp_HT_tree[i][j]|=temp;
                    }
                }
            }
        }
        return true;
    }
    bool Read_DRI(void)
    {
        unsigned short temp=0;
        myjpg.seekg(0,ios::beg);

        while(1)
        {
            temp=0;
            while( ((temp=(temp<<8)+myjpg.get())!=0xFFDD) && (temp!=0xFFDA) );
            if(temp==0xFFDD)
            {
                myjpg.seekg(2,ios::cur);
                temp=myjpg.get();
                temp=(temp<<8)+myjpg.get();
                DRI_val=temp;
                return true;
            }
            else
                return false;
        }
    }

    unsigned Getbit(void)//获取一BIT数据
    {
        int x=0,ee=0;

        if(s_bit==0)
        {
            s_bit=8;
            if(data_lp>=(datasize-2))return 0x0f;
            bittemp=data_buf[data_lp++];
            if(bittemp==0xff)
            {
                ee=data_buf[data_lp++];

                if(ee==0x00)
                {
                    ;//data_lp++;
                }
                else if(ee==0xD9)
                {
                    data_lp-=2;
                    cout<<"over! "<<hex<<0xffd9<<endl;
                    return 0x0f;
                }
                else
                {
                    cout<<"erro:"<<hex<<ee<<endl;
                    return 0x0f;
                }
            }
        }

        if(0==(bittemp&0x80))
            x=0;
        else
            x=1;
        bittemp<<=1;
        s_bit--;
        //cout<<dec<<x;
        return x;
    }
    int Found_Tree(unsigned int temp,int tree)//查霍夫曼树
    {
        for(int i=0;i<HT_bit[tree][16];i++)
        {
            if(temp==sp_HT_tree[tree][i])
            {
                return sp_HT_value[tree][i];
            }
        }
        return 0xffffffff;
    }
    double Cu(int u)//DCT用函数
    {
        if(u==0)
            return 0.35355339059327;
        else
            return 0.5;
    }
    int Foune_table(unsigned short temp,char s)//译码表
    {
        if(pow((double)2,s-1)>temp)
        {
            return (int)(temp-pow((double)2,s)+1);
        }
        else
            return temp;
    }
    bool ReadPart(double* OUT_buf,int YCbCr)//8*8数据块解码YCrCb(1=Y,2=Cb,3=Cr)
    {
        //1.利用霍夫曼树解码
        //描述:把二进制文件解码成游程编码:(前面0的个数,实际值)
        //结果存在zs_val[64][2]
        int zs_val[64][2]={0};
        unsigned short temp=0;
        int c=0,x=0,sss=0;
        int df=0,ww=1,sp=0;

        t3=GetTickCount();
        for(int x1=0;x1<16;x1++)
        {
            if(0x0f==(df=Getbit()))
                return false;
            temp=(temp<<1)+df;
            c=Found_Tree(temp|((x1+1)<<16),color_infor[YCbCr-1][3]);
            if(c!=0xffffffff)
            {
                temp=x=0;
                for(int i=0;i<c;i++)
                {
                    if(0x0f==(df=Getbit()))
                        return false;
                    temp=(temp<<1)+df;
                    x++;
                }
                zs_val[sp++][1]=this->Foune_table(temp,x);
                sss++;
                break;
            }
        }
        while(ww)
        {
            temp=x=0;
            for(int x1=0;x1<16;x1++)
            {
                if(0x0f==(df=Getbit()))
                    return false;
                temp=(temp<<1)+df;
                c=Found_Tree(temp|((x1+1)<<16),color_infor[YCbCr-1][4]+2);

                if((c!=0xffffffff)&&(c!=0))
                {
                    temp=0;
                    zs_val[sp][0]=(c&0xf0)>>4;
                    sss+=zs_val[sp][0];
                    c=c&0x0f;
                    if(c!=0)
                    {
                        for(int i=0;i<c;i++)
                        {
                            if(0x0f==(df=Getbit()))
                                return false;
                            temp=(temp<<1)+df;
                            x++;
                        }
                        zs_val[sp++][1]=this->Foune_table(temp,x);
                        sss++;
                        if((sss==64)||(sp>63))
                            ww=0;
                        break;
                    }
                    else if(c==0)
                    {
                        zs_val[sp++][1]=0;
                        sss++;
                        if((sss==64)||(sp>63))
                            ww=0;
                        break;
                    }
                }
                else if(c==0)
                {
                    ww=0;
                    break;
                }

                if(x1==15)
                    return false;
            }
        }

        //2.直流系数的差分编码校正
        int a[64]={0};

        if(ACjzbl[YCbCr-1]==0xabcdef)
        {
            a[0]=zs_val[0][1];
            ACjzbl[YCbCr-1]=a[0];
        }
        else
        {
            a[0]=zs_val[0][1]+ACjzbl[YCbCr-1];
            ACjzbl[YCbCr-1]=a[0];
        }

        //3.游程编码恢复成8*8矩阵
        int sum=1;

        for(int i=1;i<64;i++)
        {
            if((zs_val[i][0]==0)&&(zs_val[i][1]==0))
                break;

            for(int j=0;j<zs_val[i][0];j++)
            {
                a[sum++]=0;         
            }
            if(sum>63)
                    return false;

            a[sum++]=zs_val[i][1];
            if(sum>63)
                    break;
        }

        //4.反Z型编码+反量化
        int FZ[64]={0};
        int qtx=0;

        qtx=color_infor[YCbCr-1][2];
        for(int s=0;s<64;s++)
        {
            FZ[s]=a[FZig[s]]*QT[qtx][s];
        }

        //5.反余弦变换IDCT
        double FG[64]={0};
        double Fend[64]={0};

        //行IDCT
        for(int yy=0;yy<8;yy++)//行递增
        {
            for(int xx=0;xx<8;xx++)//列递增
            {
                //求单一元素值
                for(int t=0;t<8;t++)
                {
                    FG[yy*8+xx]+=fast_IDCT[xx][t]*FZ[yy*8+t];//Cu(t)*FZ[yy*8+t]*cos((2*xx+1)*t*PI/16);//
                }
            }
        }

        //列IDCT
        for(int xx=0;xx<8;xx++)//列递增
        {
            for(int yy=0;yy<8;yy++)//行递增
            {
                OUT_buf[yy*8+xx]=0;
                //求单一元素值
                for(int t=0;t<8;t++)
                {
                    OUT_buf[yy*8+xx]+=fast_IDCT[yy][t]*FG[t*8+xx];//Cu(t)*FG[t*8+xx]*cos((2*yy+1)*t*PI/16);//
                }
            }
        }

        t4+=GetTickCount()-t3;
        //程序结束
        return true;
    }
    bool Decode_Photo(void)//图片解码
    {
        if(DRI_val!=0)
        {
            cout<<"DRI值不为0,无法解码"<<endl;
            return false;
        }
        if(YCbCr_BIZHI==0x111)//采用比为1:1:1时
        {
            double y[64]={0};
            double cb[64]={0};
            double cr[64]={0};
            int r[64]={0};
            int g[64]={0};
            int b[64]={0};
            data_lp=0;

            while(data_lp<datasize)
            {
                if(true==ReadPart(y,1))//y
                    if(true==ReadPart(cb,2))//b
                        if(true==ReadPart(cr,3))//r顺序一定不要反了
                        {
                            for(int i=0;i<64;i++)
                            {
                                r[i]=y[i]+1.402*(cr[i])+128;
                                g[i]=y[i]-0.34414*(cb[i])-0.71414*(cr[i])+128;
                                b[i]=y[i]+1.772*(cb[i])+128;
                                if(r[i]>255)r[i]=255;
                                if(g[i]>255)g[i]=255;
                                if(b[i]>255)b[i]=255;
                                if(r[i]<0)r[i]=0;
                                if(g[i]<0)g[i]=0;
                                if(b[i]<0)b[i]=0;
                            }

                            for(int y=0;y<8;y++)
                            {
                                for(int x=0;x<8;x++)
                                {
                                    this->rgb_r[mcu_y+y][mcu_x+x]=r[y*8+x];
                                    this->rgb_g[mcu_y+y][mcu_x+x]=g[y*8+x];
                                    this->rgb_b[mcu_y+y][mcu_x+x]=b[y*8+x];
                                }
                            }

                            mcu_x+=8;
                            if(mcu_x>=(mcu_w-1))
                            {
                                    mcu_x=0;
                                    mcu_y+=8;
                                    if(mcu_y>=(mcu_h-1))
                                    {
                                        JM=true;
                                        return true;
                                    }
                            }
                        }
                        else
                            return false;
                    else
                        return false;
                else
                    return false;
            }
            return false;
        }
        else if(YCbCr_BIZHI==0x411)//采用比为4:1:1时
        {
            double y[4][64]={0};

            double cb[64]={0};
            double cr[64]={0};
            int r[4][64]={0};
            int g[4][64]={0};
            int b[4][64]={0};
            int uu=0;
            data_lp=0;

            while(data_lp<datasize)
            {
                if(true==ReadPart(y[0],1))//y1
                    if(true==ReadPart(y[1],1))//y2
                        if(true==ReadPart(y[2],1))//y3
                            if(true==ReadPart(y[3],1))//y4
                                if(true==ReadPart(cb,2))//b
                                    if(true==ReadPart(cr,3))//r
                                    {
                                        for(int n=0;n<4;n++)
                                        {
                                            for(int i=0;i<64;i++)
                                            {
                                                uu=crcb(i,n);
                                                r[n][i]=y[n][i]+1.402*(cr[uu])+128;
                                                g[n][i]=y[n][i]-0.34414*(cb[uu])-0.71414*(cr[uu])+128;
                                                b[n][i]=y[n][i]+1.772*(cb[uu])+128;
                                                if(r[n][i]>255)r[n][i]=255;
                                                if(g[n][i]>255)g[n][i]=255;
                                                if(b[n][i]>255)b[n][i]=255;
                                                if(r[n][i]<0)r[n][i]=0;
                                                if(g[n][i]<0)g[n][i]=0;
                                                if(b[n][i]<0)b[n][i]=0;
                                            }
                                        }

                                        for(int y=0;y<8;y++)
                                        {
                                            for(int x=0;x<8;x++)
                                            {
                                                this->rgb_r[mcu_y+y][mcu_x+x]=r[0][y*8+x];
                                                this->rgb_g[mcu_y+y][mcu_x+x]=g[0][y*8+x];
                                                this->rgb_b[mcu_y+y][mcu_x+x]=b[0][y*8+x];
                                                this->rgb_r[mcu_y+y][mcu_x+8+x]=r[1][y*8+x];
                                                this->rgb_g[mcu_y+y][mcu_x+8+x]=g[1][y*8+x];
                                                this->rgb_b[mcu_y+y][mcu_x+8+x]=b[1][y*8+x];
                                                this->rgb_r[mcu_y+8+y][mcu_x+x]=r[2][y*8+x];
                                                this->rgb_g[mcu_y+8+y][mcu_x+x]=g[2][y*8+x];
                                                this->rgb_b[mcu_y+8+y][mcu_x+x]=b[2][y*8+x];
                                                this->rgb_r[mcu_y+8+y][mcu_x+8+x]=r[3][y*8+x];
                                                this->rgb_g[mcu_y+8+y][mcu_x+8+x]=g[3][y*8+x];
                                                this->rgb_b[mcu_y+8+y][mcu_x+8+x]=b[3][y*8+x];
                                            }
                                        }
                                        mcu_x+=16;
                                        if(mcu_x>=(mcu_w-1))
                                        {
                                                mcu_x=0;
                                                mcu_y+=16;
                                                if(mcu_y>=(mcu_h-1))
                                                {
                                                    JM=true;
                                                    return true;
                                                }
                                        }
                                }
                        else
                            return false;
                    else
                        return false;
                else
                    return false;
        }
        return false;
        }
    }
    bool Show_photo(int w_x,int w_y)
    {
        if(JM==false)
        {
            cout<<"解码未成功,图片显示失败!"<<endl;
            return false;
        }
         HDC hdc = GetWindowDC( GetDesktopWindow() );

         for(int y=0;y<jpg_hight;y++)
         {
             for(int x=0;x<jpg_width;x++)
             {
                 SetPixel( hdc, w_x+x, w_y+y, RGB(rgb_r[y][x],rgb_g[y][x],rgb_b[y][x]) );
             }
         }
         return true;
    }
    unsigned char get(void)
    {
        if(data_lp<datasize)
            return data_buf[data_lp++];
    }
};
int main()
{   

    JPEG jpg1("jpg02.jpg");

    //jpg1.print_infor(); //图片信息显示

    t1 = GetTickCount();//
    if(jpg1.Decode_Photo())
    {
        t2 = GetTickCount();
        jpg1.Show_photo(0,0);
        cout<<dec<<"解码用时:"<<t2-t1<<" ms"<<endl;
        cout<<dec<<"Read_part用时:"<<t4<<" ms"<<endl;
    }
    else
    {
        t2 = GetTickCount();
        cout<<"解码失败!"<<endl;
        cout<<dec<<(int)jpg1.myjpg.tellg()<<endl;
        jpg1.Show_photo(0,0);
    }

    while(1);
    return 0;
}`
  • 10
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值