这是我的转换代码。。。。请斑竹指点下。。。
long B2J()
{
if(type==24)
{
JPG a;
long i,j,c,k;
long m,n,tp;
long u,v,x,y;//用于二维DCT变换
float cv,cu,pi;
unsigned char count;
double sum[6]={0};
unsigned char R,G,B;
signed char *Y,*U,*V;
signed char MCU[6][64]={0};
signed char Q_DCT[6][64]={0};
float DCT[6][64]={0};
short sgn;
signed char Z[64]={0};
signed char transt[317]={0};
signed char PreDC[3]={0};
//int location=0,run=0;
unsigned char run=0;
int
r_tp=0;
long r_len=0;
bit *buff;
//unsigned char y,u,v;
unsigned char ZigZag[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
};
pi=(float)11.25;
c=h;
k=w;
while(c%16!=0) c++;
while(k%16!=0) k++;
Y=new signed char[c*k];//获取BMP主要图像信息
U=new signed char[c*k];
V=new signed char[c*k];
memset(Y,0,c*k);
memset(U,0,c*k);
memset(V,0,c*k);
p_temp=new unsigned char[c*k*3>>1];//4:1:1比例最大为一半,记录最后的编码
memset(p_temp,0,c*k*3>>1);
buff=new bit[c*k*12];
for(i=0;i<c*k*12;i++)
buff[i].a =1;
//YUV
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
R=p_data[i*wf+3*j+2];//Y
G=p_data[i*wf+3*j+1];//U
B=p_data[i*wf+3*j];//V
Y[i*w+j]=0.2990*R+0.5870*G+0.1140*B;
U[i*w+j]=-0.1687*R-0.3313*G+0.5000*B;
V[i*w+j]=0.5000*R-0.4187*G-0.0813*B;
}
}
//4:1:1 sample
for(i=0;i<c>>4;i++)
for(j=0;j<k>>4;j++)
{
for(n=i*8;n<i*8+8;n++)
for(m=j*8;m<j*8+8;m++)
{
tp=(n-i*8)*8+(m-j*8);
MCU[0][tp]=Y[n*k+m]-128;
MCU[1][tp]=Y[n*k+m+8]-128;
MCU[2][tp]=Y[(n+8)*k+m]-128;
MCU[3][tp]=Y[(n+8)*k+m+8]-128;
MCU[4][tp]=U[2*n*k+2*m];
MCU[5][tp]=V[2*n*k+2*m];
}
/*
printf("************************MCU\n*****************");
for(count=0;count<6;count++)
{
printf("MCU编号%d\n",count);
for(y=0;y<64;y++)
{
if(1) printf("%d ",MCU[count][y]);
if((y+1)%8==0) printf("\n");
}
}
getch();
printf("\n");
*/
//DCT
for(v=0;v<8;v++)
{
if(v==0) cv=1/sqrt(2);
else
cv=1;
for(u=0;u<8;u++)
{
if(u==0)
cu=1/sqrt(2);
else
cu=1;
for(count=0;count<6;count++)
sum[count]=0;
for(y=0;y<8;y++)
for(x=0;x<8;x++)
{
for(count=0;count<6;count++)
sum[count]=sum[count]+MCU[count][y*8+x]*cos((2*x+1)*u*pi)*cos((2*y+1)*v*pi);
}
for(count=0;count<6;count++)
{
DCT[count][v*8+u]=sum[count]*cu*cv/4;
}
}
}
//Q
for(count=0;count<6;count++)
{
for(y=0;y<64;y++)
{
if(DCT[count][y]>0) sgn=1; else sgn=-1;
if(count<4)
Q_DCT[count][y]=(DCT[count][y]+sgn*a.dqt0.QT[y]/2)/a.dqt0.QT[y];
if(count>3)
Q_DCT[count][y]=(DCT[count][y]+sgn*a.dqt1.QT[y]/2)/a.dqt1.QT[y];
//if(1) printf("%d ",Q_DCT[count][y]);
//if((y+1)%8==0) printf("\n");
//getch();
//printf("\n");
}
//printf("************\n");
}
//ZigZag
for(count=0;count<6;count++)
{
for(y=0;y<64;y++)
{
Z[ZigZag[y]]=Q_DCT[count][y];
}
//Z字编码显示
/*
printf("原Q块\n");
for(y=0;y<64;y++)
{
printf("%5d",Q_DCT[count][y]);
if((y+1)%8==0) printf("\n");
}
printf("编码块\n");
for(y=0;y<64;y++)
{
printf("%5d",Z[y]);
if((y+1)%8==0) printf("\n");
}
getch();*/
memcpy(Q_DCT[count],Z,64);
}
//HuffmanEncoder
for(count=0;count<6;count++)
{
run=0;//记录一个8*8像素块的过渡段行程
//过渡DC
if(count<4)
{
transt[run+1]=Q_DCT[count][0]-PreDC[0];
x=0;
while(abs(transt[run+1])>>x!=0) x++;
transt[run]=x;
PreDC[0]=Q_DCT[count][0];//记录当前DC为下一次差分做准备
}
if(count==4)
{
transt[run+1]=Q_DCT[count][0]-PreDC[1];
x=0;
while(abs(transt[run+1])>>x!=0) x++;
transt[run]=x;
PreDC[1]=Q_DCT[count][0];//记录当前DC为下一次差分做准备
}
if(count==5)
{
transt[run+1]=Q_DCT[count][0]-PreDC[2];
x=0;
while(abs(transt[run+1])>>x!=0) x++;
transt[run]=x;
PreDC[2]=Q_DCT[count][0];//记录当前DC为下一次差分做准备
}
run=run+2;
x=0;
//过渡AC
for(y=1;y<64;y++)
{
if(Q_DCT[count][y]==0)
{
x++;
if(x>15)//x=16
{
r_tp=y+1;
while(Q_DCT[count][r_tp]==0 && r_tp<64)
r_tp++;
if(r_tp==64)
{
transt[run]=transt[run+1]=0;//00标记结尾
run=run+2;
y=64;
goto transt_end;//标记结束编码
}
else
{
transt[run]=15;
transt[run+1]=0;
transt[run+2]=0;
run=run+3;
x=0;//重新计0
}
}
}
else
{
transt[run]=x;//记录0个数
x=0;
while(abs(Q_DCT[count][y])>>x!=0) x++;
transt[run+1]=x;//记录区间
transt[run+2]=Q_DCT[count][y];
x=0;//记录下一个行程
run=run+3;
}
}
if(Q_DCT[count][63]==0)
{
transt[run]=transt[run+1]=0;//00标记结尾
run=run+2;
}
transt_end:;
/*
//过渡块显示输出
for(y=0;y<64;y++)
{
if(1) printf("%d ",Q_DCT[count][y]);
if((y+1)%8==0) printf("\n");
}
if(count<4) printf("亮度块");
if(count==4)
printf("色度块");
if(count==5)
printf("深度块");
printf("****************************\n");
for(y=0;y<run;y++)
if(1) printf("%d ",transt[y]);
printf("\n对应中间编码,共%d个\n",run);
getch();
*/
//过渡段编码
//p_temp,buff,transt,x,y,r_tp,r_len
unsigned char b_cmp=0;
unsigned short *DCtable,*ACtable;
unsigned char *DCL;//,*ACL;
//unsigned char *DCtable,*ACtable;
if(count<4)
{
DCtable=a.DCTY.C ;
DCL=a.DCTY.L;
ACtable=a.ACTY.C ;
//ACL=a.dhtac0.sum;
}
else
{
DCtable=a.DCTC.C ;
DCL=a.DCTC.L;
ACtable=a.ACTC.C ;
//ACL=a.dhtac0.sum;
}
//DC
//r_len=0;
x=DCL[transt[0]];
while(x!=0)
{
x--;
buff[r_len++].a=DCtable[transt[0]]>>x;
}
x=transt[0];
if(transt[1]<0)
b_cmp=((unsigned char)0x01 <<x)-1-abs(transt[1]);
else b_cmp=transt[1];
while(x!=0)
{
x--;
buff[r_len++].a=b_cmp>>x;
}
//AC
for(y=2;y<run-2;y=y+3)
{
x=0;
r_tp=transt[y]*16+transt[y+1];//RRRRSSSS
if(r_tp==1 || (r_tp==0 && count>3) ||(r_tp==2 && count<4)) x=2;
else
while(ACtable[r_tp]>>x!=0) x++;
//x=ACL[r_tp];
while(x!=0)
{
x--;
buff[r_len++].a=ACtable[r_tp]>>x;
}
x=transt[y+1];
if(transt[y+2]<0)
b_cmp=((unsigned char)0x01 <<x)-1-abs(transt[y+2]);
else b_cmp=transt[y+2];
while(x!=0)
{
x--;
buff[r_len++].a=b_cmp>>x;
}
}
//结尾
x=0;
r_tp=0;//RRRRSSSS
if(count>3)
x=2;
else
x=4;
while(x!=0)
{
x--;
buff[r_len++].a=ACtable[r_tp]>>x;
}
}
}
//开始转换字节
r_tp=0;
while(r_len%8==0)
{
r_len++;
r_tp=1;
}
y=0;
for(x=0;x<r_len;x=x+8)
{
p_temp[y]=((unsigned char)buff[x].a<<7)+((unsigned char)buff[x+1].a<<6)+((unsigned char)buff[x+2].a<<5)+((unsigned char)buff[x+3].a<<4)+((unsigned char)buff[x+4].a<<3)+((unsigned char)buff[x+5].a<<2)+((unsigned char)buff[x+6].a<<1)+(unsigned char)buff[x+7].a;
if(p_temp[y]==0xFF)
{
p_temp[y+1]=0x00;
y=y+2;
}
else
y=y+1;
}
if(r_tp==1) //如果有位填充需要补FF
{
p_temp[y++]=0xFF;
p_temp[y++]=0x00;
}
printf("\n转换长度%ld",y);
//delete []p_temp;p_temp=0;//由于不是正常处理图像,所以需要清空指针
delete []buff;
return y;
//exit(0);
}
else
return -1;
}