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;
}`