📄 membitmap.cpp
字号:
Scale=table[CurBl];
}
float memBitmap::GetScale()
{
return Scale;
}
void memBitmap::Release()
{
if(flag==1)delete bData;
flag=0;
}
BOOL memBitmap::JpegToBmp(BYTE *buf,long int lenth)
{
BitData JpegData(buf,lenth);
BYTE tag[2];
JpegData.GetBit(8,tag[0]);
JpegData.GetBit(8,tag[1]);
if(tag[0]!=0xff||tag[1]!=0xD8) //0xFFD8为jpg标志
{
AfxMessageBox("不是合法的Jpeg文件");
return FALSE;
}
TagFlag=FALSE;
ImageHeight=0;
while(1)
{
if(!JpegData.GetBit(8,tag[0]))return FALSE;
switch(tag[0])
{
case 0xff:
TagFlag=TRUE; //如为0xFF,则可能为交换格式
break;
case 0xc0: //SOF0
if(TagFlag==TRUE)
{
BYTE temp;
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
if(temp!=0x08) //是否baseline
{
AfxMessageBox("不是合法的Jpeg文件");
return FALSE;
}
JpegData.GetBit(8,temp); //图象高度
ImageHeight=temp;
ImageHeight<<=8;
JpegData.GetBit(8,temp);
ImageHeight|=temp;
JpegData.GetBit(8,temp); //图象宽度
ImageWidth=temp;
ImageWidth<<=8;
JpegData.GetBit(8,temp);
ImageWidth|=temp;
JpegData.GetBit(8,CnNum);//成分数
for(int i=0;i<CnNum;i++)
{
JpegData.GetBit(8,CnTable[i]); //成分编号
JpegData.GetBit(4,CnHSample[i]);//成分水平采样比例
JpegData.GetBit(4,CnVSample[i]);//成分垂直采样比例
JpegData.GetBit(8,QuanNum[i]);//成分所用量化表
}
TagFlag=FALSE;
}break;
case 0xDB: //DQT,量化表数据
if(TagFlag==TRUE)
{
BYTE temp;
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
JpegData.GetBit(4,temp);
if(temp!=0) //是否baseline
{
AfxMessageBox("本系统只支持DCT-baseline格式");
return FALSE;
}
JpegData.GetBit(4,temp);
for(int i=0;i<64;i++)
{
JpegData.GetBit(8,QuanTable[temp][i]); //成分编号
}
TagFlag=FALSE;
}break;
case 0xE0:
if(TagFlag==TRUE)
{
BYTE temp,flag[4];
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
for(int i=0;i<4;i++)
JpegData.GetBit(8,flag[i]);
if(flag[0]!='J'&&flag[1]!='F'&&\
flag[2]!='I'&&flag[3]!='F') //是否JFIF
{
AfxMessageBox("本系统只支持JFIF格式");
return FALSE;
}
TagFlag=FALSE;
}break;
case 0xDC:
if(TagFlag==TRUE)
{
if(ImageHeight==0)
//如在SOF中未定义图象高度,则在此处赋值
{
BYTE temp;
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
ImageHeight=temp;
ImageHeight<<=8;
JpegData.GetBit(8,temp);
ImageHeight|=temp;
}
TagFlag=FALSE;
}break;
case 0xDD:
if(TagFlag==TRUE) //定义重入间隔
{
BYTE temp;
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
ReEnterInterval=temp;
ReEnterInterval<<=8;
JpegData.GetBit(8,temp);
ReEnterInterval|=temp;
TagFlag=FALSE;
}break;
case 0xc4:
if(TagFlag==TRUE)
{
BYTE temp;
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
BYTE DcAc,TableNum;
JpegData.GetBit(4,DcAc);
JpegData.GetBit(4,TableNum);
if(DcAc==0) //为DC系数所使用的霍夫曼数据
{
BYTE num=0;
for(int i=0;i<16;i++)
{
JpegData.GetBit(8,HuffDCBits[TableNum][i]);
HuffDCPtr[TableNum][i]=num;
num+=HuffDCBits[TableNum][i];
}
for(i=0;i<num;i++)
{
JpegData.GetBit(8,HuffDCVar[TableNum][i]);
}
int code=0; num=0;
for(i=0;i<16;i++)
{
if(HuffDCBits[TableNum][i]==0)
{
HuffDCMinCode[TableNum][i]=0;
HuffDCMaxCode[TableNum][i]=-1;
code<<=1;
}
else
{
HuffDCMinCode[TableNum][i]=code;
for(int j=0;j<HuffDCBits[TableNum][i];j++)
{
HuffDCTable[TableNum][num]=code;
code++;
num++;
}
//code--;
HuffDCMaxCode[TableNum][i]=code-1;
code<<=1;
}
}
}
else //AC系数所用霍夫曼数据
{
BYTE num=0;
for(int i=0;i<16;i++)
{
JpegData.GetBit(8,HuffACBits[TableNum][i]);
HuffACPtr[TableNum][i]=num;
num+=HuffACBits[TableNum][i];
}
for(i=0;i<num;i++)
{
JpegData.GetBit(8,HuffACVar[TableNum][i]);
}
int code=0; num=0;
for(i=0;i<16;i++)
{
if(HuffACBits[TableNum][i]==0)
{
HuffACMinCode[TableNum][i]=0;
HuffACMaxCode[TableNum][i]=-1;
code<<=1;
}
else
{
HuffACMinCode[TableNum][i]=code;
for(int j=0;j<HuffACBits[TableNum][i];j++)
{
HuffACTable[TableNum][num]=code;
code++;
num++;
}
//code--;
HuffACMaxCode[TableNum][i]=code-1;
code<<=1;
}
}
}
}break;
case 0xDA:
if(TagFlag==TRUE)
{
if(ImageHeight==0)
{
AfxMessageBox("不是合法的Jpeg文件");
return FALSE;
}
//分配相应的bmp数据
if(!CreateDirect(ImageWidth,ImageHeight))
return FALSE;
for(int k=0;k<ImageWidth;k++)
for(int j=0;j<ImageHeight;j++)
SetPixel(k,j,RGB(0,0,0));
BYTE temp;
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
if(temp!=CnNum)
{
AfxMessageBox("成分(Components)个数不一致");
return FALSE;
}
for(int i=0;i<CnNum;i++)
{
JpegData.GetBit(8,temp);
BYTE CurPtr;
for(int j=0;j<CnNum;j++)
{
if(temp==CnTable[j])CurPtr=j;
}
JpegData.GetBit(4,CnDCHuffNum[CurPtr]);
JpegData.GetBit(4,CnACHuffNum[CurPtr]);
}
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
JpegData.GetBit(8,temp);
if(!EnCode(JpegData))
return FALSE;
else
return TRUE;
//JpegData.BitPtr=0;
//TagFlag=FALSE;
}//break;
case 0xD9:
if(TagFlag==TRUE)
{
return TRUE;
}
default:
TagFlag=FALSE;
}
}
return TRUE;
}
BOOL memBitmap::EnCode(BitData &JpegData)
{
int i,j;
MCUnumber=0;
xRes=0;
yRes=0;
for(i=0;i<CnNum;i++)
{
if(CnHSample[i]>xRes)xRes=CnHSample[i];
if(CnVSample[i]>yRes)yRes=CnVSample[i];
}
xRes*=8;yRes*=8;
int xf,yf;
if(ImageWidth%xRes!=0)xf=(ImageWidth+xRes)/xRes;
else xf=ImageWidth/xRes;
if(ImageHeight%yRes!=0)yf=(ImageHeight+yRes)/yRes;
else yf=ImageHeight/yRes;
MCUnumber=xf*yf;
MCUcount=0;
for(i=0;i<CnNum;i++)//将成分所需数据按成分编号重新排序
{
for(j=i;j<CnNum;j++)
{
if(CnTable[j]<CnTable[i])
{
BYTE temp;
temp=CnHSample[j];
CnHSample[j]=CnHSample[i];
CnHSample[i]=temp;
temp=CnVSample[j];
CnVSample[j]=CnVSample[i];
CnVSample[i]=temp;
temp=QuanNum[j];
QuanNum[j]=QuanNum[i];
QuanNum[i]=temp;
temp=CnDCHuffNum[j];
CnDCHuffNum[j]=CnDCHuffNum[i];
CnDCHuffNum[i]=temp;
temp=CnACHuffNum[j];
CnACHuffNum[j]=CnACHuffNum[i];
CnACHuffNum[i]=temp;
temp=CnTable[j];
CnTable[j]=CnTable[i];
CnTable[i]=temp;
}
}
}
for(i=0;i<3;i++)Pred[i]=0;
/* for(i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
DctVar[i][j]=(float)cos((2*j+1)*i*PIE/16);
if(i==0)DctVar[i][j]/=(float)sqrt(2.0);
}
}
*/
for(i=0;i<8;i++)
{
DctVar1[0][i]=sqrt(2)/4;
DctVar2[i][0]=DctVar1[0][i];
}
for(i=1;i<8;i++)
for(j=0;j<8;j++)
{
DctVar1[i][j]=0.5*cos((2*j+1)*i*PIE/16);
DctVar2[j][i]=DctVar1[i][j];
}
int PixelX[10],PixelY[10];
int DotX[10],DotY[10];
for(i=0;i<CnNum;i++)
{
PixelX[i]=xRes/CnHSample[i];
PixelY[i]=yRes/CnVSample[i];
DotX[i]=(xRes/8)/CnHSample[i];
DotY[i]=(yRes/8)/CnVSample[i];
}
int PieceOriX=0;
int PieceOldX=0;
while(MCUcount<MCUnumber)
{
int i,j,k;
int CurX=(MCUcount*xRes-PieceOriX)%ImageWidth;
int CurY=(MCUcount*xRes-PieceOriX)/ImageWidth*yRes;
for(i=0;i<CnNum;i++)
{
for(j=0;j<CnVSample[i];j++)
{
for(k=0;k<CnHSample[i];k++)
{
if(!EnCodeMCU(JpegData,i,k+CnVSample[i]*j))
return FALSE;
}
}
}
for(i=0;i<yRes;i++)
{
for(j=0;j<xRes;j++)
{
if( (CurX+j<ImageWidth)&&(CurY+i<ImageHeight) )
{
double Y,Cb,Cr;
int Seg=(i/PixelY[0])*CnVSample[0]+j/PixelX[0];
int xOff=(j/DotX[0])%8;
int yOff=(i/DotY[0])%8;
Y=IDct[0][Seg][yOff][xOff];
Seg=(i/PixelY[1])*CnVSample[1]+j/PixelX[1];
xOff=(j/DotX[1])%8;
yOff=(i/DotY[1])%8;
Cb=IDct[1][Seg][yOff][xOff];
Seg=(i/PixelY[2])*CnVSample[2]+j/PixelX[2];
xOff=(j/DotX[2])%8;
yOff=(i/DotY[2])%8;
Cr=IDct[2][Seg][yOff][xOff];
BYTE r,g,b;
double r1=Y+1.402*(Cr-128);
double g1=Y-0.34414*(Cb-128)-0.71414*(Cr-128);
double b1=Y+1.772*(Cb-128);
if(r1<0)r=0;
else if(r1>255)r=255;
else r=(BYTE)r1;
if(g1<0)g=0;
else if(g1>255)g=255;
else g=(BYTE)g1;
if(b1<0)b=0;
else if(b1>255)b=255;
else b=(BYTE)b1;
SetPixel(CurX+j,CurY+i,RGB(r,g,b));
}
else if( CurX+j>=ImageWidth )
{
PieceOldX=xRes-(ImageWidth-CurX-PieceOriX);
}
}
}
PieceOriX=PieceOldX;
MCUcount++;
}
return TRUE;
}
BOOL memBitmap::EnCodeMCU(BitData &JpegData,BYTE Num,BYTE MCUnum)
{
BYTE HuffDC,HuffAC,Quan;//当前表
int DotCount=0;
int iVal=0; //读出的码值
BYTE temp,CodeLenth=0;//码长-1
HuffDC=CnDCHuffNum[Num];
HuffAC=CnACHuffNum[Num];
Quan=QuanNum[Num];
int MCU[64]; //存放霍夫曼解码后的数据
int MCUQuan[64]; //存放量化后的数据
int i,j;
static BYTE DctPosition[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,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}
};
while(1)
{
JpegData.GetBit(temp);
iVal|=temp;
if(iVal<=HuffDCMaxCode[HuffDC][CodeLenth])break;
iVal<<=1;
CodeLenth++;
if(CodeLenth>8)
{
AfxMessageBox("直流数据错");
return FALSE;
}
}
iVal-=HuffDCMinCode[HuffDC][CodeLenth];
iVal+=HuffDCPtr[HuffDC][CodeLenth];
int value=0;
if(HuffDCVar[HuffDC][iVal]!=0)
{
for(i=0;i<HuffDCVar[HuffDC][iVal];i++)
{
JpegData.GetBit(temp);
value<<=1;
value|=temp;
}
if(value>>(HuffDCVar[HuffDC][iVal]-1)==0)//为负值
{
value=~value;
int x=0xffff>>(16-HuffDCVar[HuffDC][iVal]);
value&=x;
value=-value;
}
}
Pred[Num]+=value;
MCU[0]=Pred[Num];
DotCount=1;
while(DotCount<64)
{
iVal=0;
CodeLenth=0;
while(1)
{
JpegData.GetBit(temp);
iVal|=temp;
if(iVal<=HuffACMaxCode[HuffAC][CodeLenth])break;
iVal<<=1;
CodeLenth++;
if(CodeLenth>=16)
{
AfxMessageBox("交流数据错");
return FALSE;
}
}
iVal-=HuffACMinCode[HuffAC][CodeLenth];
iVal+=HuffACPtr[HuffAC][CodeLenth];
BYTE RRRRSSSS=HuffACVar[HuffAC][iVal];
BYTE RRRR=(RRRRSSSS>>4)&0xf;
BYTE SSSS=RRRRSSSS&0xf;
if(RRRRSSSS==0xf0)
{
for(int i=0;i<16;i++)
{
MCU[DotCount]=0;
DotCount++;
}
continue;
}
else if(RRRRSSSS==0)
{
for(int i=DotCount;i<64;i++)
{
MCU[DotCount]=0;
DotCount++;
}
continue;
}
if(SSSS==0)
{
AfxMessageBox("不合法的AC系数");
return FALSE;
}
value=0;
for(i=0;i<SSSS;i++)
{
JpegData.GetBit(temp);
value<<=1;
value|=temp;
}
if((value>>(SSSS-1)==0))//为负值
{
value=~value;
int x=0xffff>>(16-SSSS);
value&=x;
value=-value;
}
for(int i=0;i<RRRR;i++)
{
MCU[DotCount]=0;
DotCount++;
}
MCU[DotCount]=value;
DotCount++;
}
for(i=0;i<64;i++)
{
MCUQuan[i]=MCU[i]*QuanTable[Quan][i];
}
int DctValue[8][8];
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
DctValue[i][j]=MCUQuan[DctPosition[i][j]];
}
}
/* for(int x=0;x<8;x++)
{
for(int y=0;y<8;y++)
{
double temp=0.0;
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
temp+=DctVar[i][x]*DctVar[j][y]*DctValue[i][j];
}
}
temp/=4;
IDct[Num][MCUnum][x][y]=temp+128;
}
}*/
double TempMatrix[8][8];
for(int x=0;x<8;x++)
{
for(int y=0;y<8;y++)
{
TempMatrix[x][y]=0;
for(int k=0;k<8;k++)
TempMatrix[x][y]+=DctVar2[x][k]*DctValue[k][y];
}
}
for(x=0;x<8;x++)
{
for(int y=0;y<8;y++)
{
IDct[Num][MCUnum][x][y]=0;
for(int k=0;k<8;k++)
IDct[Num][MCUnum][x][y]+=TempMatrix[x][k]*DctVar1[k][y];
IDct[Num][MCUnum][x][y]+=128;
}
}
return TRUE;
}
void memBitmap::DataToView(class memBitmap &bmp1)
//生成显示用的其他比例文件
//采用双线性插值技术
{
int width=GetWidth();
int height=GetHeight();
int i,j;
if(Scale==(double)1)
{
bmp1.Release();
bmp1.CreateDirect(width,height);
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
{
COLORREF color=GetPixel(i,j);
bmp1.SetPixel(i,j,color);
}
}
return;
}
int NewWidth=int((double)width*Scale);
int NewHeight=int((double)height*Scale);
bmp1.Release();
bmp1.CreateDirect(NewWidth,NewHeight);
for(i=0;i<NewWidth;i++)
{
for(j=0;j<NewHeight;j++)
{
double x,y;
x=(double)i/Scale;
y=(double)j/Scale;
if(x<=0)x=0;
if(x>=width-1)x=width-1;
if(y<=0)y=0;
if(y>=height-1)y=height-1;
if( ((int)x==0)||((int)x==width-1)||((int)y==0)||((int)y==height-1) )
{
COLORREF color=GetPixel((int)x,(int)y);
bmp1.SetPixel(i,j,color);
}
else
{
double r1,r2,r3,r4;
double g1,g2,g3,g4;
double b1,b2,b3,b4;
COLORREF c1,c2,c3,c4;
c1=GetPixel((int)x,(int)y);
c2=GetPixel((int)x+1,(int)y);
c3=GetPixel((int)x,(int)y+1);
c4=GetPixel((int)x+1,(int)y+1);
double dis1=x-(int)x;
double dis2=1-x+(int)x;
double dis3=y-(int)y;
double dis4=1-y+(int)y;
r1=GetRValue(c1);
g1=GetGValue(c1);
b1=GetBValue(c1);
r2=GetRValue(c2);
g2=GetGValue(c2);
b2=GetBValue(c2);
r3=GetRValue(c3);
g3=GetGValue(c3);
b3=GetBValue(c3);
r4=GetRValue(c4);
g4=GetGValue(c4);
b4=GetBValue(c4);
int r=int(dis4*(r1*dis2+r2*dis1)+dis3*(r3*dis2+r4*dis1));
if(r>255)r=255;
int g=int(dis4*(g1*dis2+g2*dis1)+dis3*(g3*dis2+g4*dis1));
if(g>255)g=255;
int b=int(dis4*(b1*dis2+b2*dis1)+dis3*(b3*dis2+b4*dis1));
if(b>255)b=255;
bmp1.SetPixel(i,j,RGB((BYTE)r,(BYTE)g,(BYTE)b));
// COLORREF color=GetPixel(int(x+0.5),int(y+0.5));
// bmp1.SetPixel(i,j,color);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -