📄 jpg2bmp.c
字号:
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 ;
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(void)
{
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*)hImgData+(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(void)
{
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 ;
//Y
for(i=0;i<SampRate_Y_H*SampRate_Y_V;i++)
{
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];
}
//U
for(i=0;i<SampRate_U_H*SampRate_U_V;i++)
{
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];
}
//V
for(i=0;i<SampRate_V_H*SampRate_V_V;i++)
{
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(void)
{
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 ;
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 ;
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(void)
{
BYTE i ;
i=*(lp++);
if(i==0xff)
lp++;
BitPos=8 ;
CurByte=i ;
return i ;
}
///////////////////////////////////////////////////////////////////////
void Initialize_Fast_IDCT(void)
{
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(void)
{
LoadJpegFile("c:\\test.jpg");
printf("OK");
return 0 ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -