最近在編寫PDF的解析器,正好需要用的jepg的解碼,順便就寫下了此文。
我參考:http://wenku.baidu.com/view/9c9d8ed333d4b14e85246813.html
這個文檔裡面介紹了jepg的大體格式,我的代碼也是參照這個大體結構來完成的:
buffer:jpg檔案的byte資料
length:檔案長度
int Jpeg::GetSize(char * buffer,long length)
{
if(!buffer)
return -1;
char * temp=buffer+length,*temp1=buffer;
unsigned char ff,type=0xff;
int m_ret=-1,m_pos=0,m_hpx=0,m_wpx=0,uits=0;
if((unsigned char)*buffer++!=0xff||(unsigned char)*buffer++!=0xd8)
{
printf("此非jepg圖檔\n");
return -1;
}
while(temp>buffer&&type!=0xDA)
{
do
{
ff=*buffer++;
} while (ff!=0xff);
do
{
type=*buffer++;
} while (type==0xff);
switch(type)
{
case 0x00:
case 0x01:
case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
break;
case 0xC0://SOF0段
temp1=buffer;
m_pos=((*buffer++)&0xff)<<8;
m_pos+=(*buffer++)&0xff;
buffer++; //舍棄精度值
height=((*buffer++)&0xff)<<8;
height+=(*buffer++)&0xff;
weidth=((*buffer++)&0xff)<<8;
weidth+=(*buffer)&0xff;
m_ret++;
break;
case 0xE0: //APP0段
temp1=buffer;
m_pos=((*buffer++)&0xff)<<8;
m_pos+=(*buffer++)&0xff;
buffer=buffer+7; //丢棄APP0标記(5bytes)以及主版本号(1bytes)及次版本号(1bytes)
uits=(*buffer++)&0xff; //0: 無機關,units=1:點數/英寸,units=2:點數/厘米
m_wpx=((*buffer++)&0xff)<<8;
m_wpx+=(*buffer++)&0xff;
m_hpx=((*buffer++)&0xff)<<8;
m_hpx+=(*buffer++)&0xff;
hpx=m_hpx*JepgSize(uits);
wpx=m_wpx*JepgSize(uits);
m_ret++;
break;
default:
temp1=buffer;
m_pos=((*buffer++)&0xff)<<8;
m_pos+=(*buffer++)&0xff;
break;
}
buffer=temp1+m_pos;
}
return m_ret;
}
float inline JepgSize(int x)
{
return x!=2?1:2.56;
}