📄 jpegfile.cpp
字号:
// Note! this does its stuff on buffers with a whole number of pixels
// per data row!!
BOOL JpegFile::BGRFromRGB(BYTE *buf, UINT widthPix, UINT height)
{
if (buf==NULL) return FALSE;
UINT Pitch = widthPix*3;
BYTE *red,*blue,tmp;
BYTE *TmpBuf = buf;
for (UINT row=0; row<height; row++)
{
red = TmpBuf;
blue = red + 2;
TmpBuf += Pitch;
for (UINT col=0; col<widthPix; col++)
{
tmp = *red;
*red = *blue;
*blue = tmp;
red += 3;
blue+= 3;
}
}
return TRUE;
}
// Note! this does its stuff on buffers with a whole number of pixels
// per data row!!
BOOL JpegFile::MakeGrayScale(BYTE *buf, UINT widthPix, UINT height)
{
if (buf==NULL) return FALSE;
for (UINT row=0;row<height;row++)
{
BYTE *RowAddress = buf + row * widthPix * 3;
for (UINT col=0;col<widthPix;col++)
{
LPBYTE pRed, pGrn, pBlu;
pRed = RowAddress+ col * 3;
pGrn = pRed + 1;
pBlu = pRed + 2;
// luminance
int lum = (int)(.299 * (double)(*pRed) + .587 * (double)(*pGrn) + .114 * (double)(*pBlu));
*pRed = (BYTE)lum;
*pGrn = (BYTE)lum;
*pBlu = (BYTE)lum;
}
}
return TRUE;
}
// from here
BYTE And[9]={0,1,3,7,0xf,0x1f,0x3f,0x7f,0xff};
JpegFile1::JpegFile1()
{
sizei = sizej = 0;
ImgWidth = ImgHeight =0;
rrun = vvalue = 0;
BitPos = 0;
CurByte = 0;
IntervalFlag = false;
restart = 0;
comp_num = 0;
HufTabIndex = 0;
ycoef = ucoef = vcoef = 0;
interval = 0;
memset(qt_table[0], 0, 192* sizeof(short));
memset(comp_index, 0, 3);
memset(code_len_table[0], 0, 64* sizeof(short));
memset(code_pos_table[0], 0, 64* sizeof(short));
memset(huf_max_value[0], 0, 64* sizeof(short));
memset(huf_min_value[0], 0, 64* sizeof(short));
memset(code_value_table[0], 0, 1024* sizeof(short));
memset(MCUBuffer, 0, 640* sizeof(short));
memset(QtZzMCUBuffer, 0, 640* sizeof(int));
memset(Y, 0, 256* sizeof(int));
memset(U, 0, 256* sizeof(int));
memset(V, 0, 256* sizeof(int));
iclp = iclip + 512;
for(short i= -512; i<512; i++)
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i);
for(i= 0; i<400; i++)
bClipArray[i] = 0;
for(i= 656; i<1024; i++)
bClipArray[i] = 255;
blpClip = bClipArray + 400;
for(i= 0; i<256; i++)
blpClip[i] = BYTE(i);
}
JpegFile1::~JpegFile1()
{
if( lpJpegBuf != NULL ) delete []lpJpegBuf;
}
BOOL JpegFile1::OpenJPGFile(CString FlieName)
{
CFile* pReadFile = new CFile( FlieName, CFile::modeRead | CFile::shareCompat);
//get jpg file length
JpegBufSize=pReadFile->GetLength();
lpJpegBuf = new BYTE[JpegBufSize];
pReadFile->ReadHuge(lpJpegBuf, JpegBufSize);
delete pReadFile;
BOOL bR = InitTag() == 0;
LineBytes = (ImgWidth* comp_num+ 3) & ~3 ;
ImgSize = LineBytes* ImgHeight;
return bR;
}
BOOL JpegFile1::ReadJPGData(BYTE **lpParam)
{
lpImgData = lpParam;
funcret = Decode();
return true;
}
int JpegFile1::InitTag()
{
BOOL finish = false;
short llength, ccount;
short i, j, k;
short huftab1,huftab2;
short huftabindex;
BYTE id, hf_table_index, qt_table_index, comnum, *lptemp;
lp = lpJpegBuf + 2;
while (!finish)
{
id = *(lp+ 1);
lp += 2;
switch( id )
{
case M_APP0:
llength = *(lp+1) | ( *lp<<8 );
lp += llength;
break;
case M_DQT:
llength = *(lp+1) | ( *lp<<8 );
qt_table_index = ( *(lp+ 2) ) & 0x0f;
lptemp = lp + 3;
if(llength<80)
{
for(i= 0; i< 64; i++)
qt_table[qt_table_index][i] = *(lptemp++);
}
else
{
for(i= 0; i< 64; i++)
qt_table[qt_table_index][i] = *(lptemp++);
qt_table_index = ( *(lptemp++) )&0x0f;
for(i= 0; i< 64; i++)
qt_table[qt_table_index][i] = *(lptemp++);
}
lp += llength;
break;
case M_SOF0:
llength = *(lp+1) | ( *lp<<8 );
ImgHeight = *(lp+4) | ( *(lp+3)<<8 );
ImgWidth = *(lp+6) | ( *(lp+5)<<8 );
comp_num = *(lp+ 7);
if( (comp_num!=1) && (comp_num!=3))
return 1;
if( comp_num==3 )
{
comp_index[0] = *(lp+ 8);
SampRate_Y_H = (*(lp+ 9))>>4;
SampRate_Y_V = (*(lp+ 9))&0x0f;
YQtTable = (short *)qt_table[*(lp+10)];
comp_index[1] = *(lp+ 11);
SampRate_U_H = (*(lp+ 12))>>4;
SampRate_U_V = (*(lp+ 12))&0x0f;
UQtTable = (short *)qt_table[*(lp+13)];
comp_index[2] = *(lp+14);
SampRate_V_H = (*(lp+15))>>4;
SampRate_V_V = (*(lp+15))&0x0f;
VQtTable = (short *)qt_table[*(lp+16)];
}
else
{
comp_index[0] = *(lp+ 8);
SampRate_Y_H = (*(lp+ 9))>>4;
SampRate_Y_V = (*(lp+ 9))&0x0f;
YQtTable = (short *)qt_table[*(lp+10)];
comp_index[1] = *(lp+ 8);
SampRate_U_H = 1;
SampRate_U_V = 1;
UQtTable = (short *)qt_table[*(lp+10)];
comp_index[2] = *(lp+ 8);
SampRate_V_H = 1;
SampRate_V_V = 1;
VQtTable = (short *)qt_table[*(lp+10)];
}
SampRate_Y_H8 = SampRate_Y_H << 3;
SampRate_Y_V8 = SampRate_Y_V << 3;
lp += llength;
break;
case M_DHT:
llength = *(lp+1) | ( *lp<<8 );
if (llength<0xd0)
{
huftab1 = (short)(*(lp+ 2))>>4; //huftab1=0,1
huftab2 = (short)(*(lp+ 2))&0x0f; //huftab2=0,1
huftabindex = huftab1* 2 + huftab2;
lptemp = lp + 3;
for(i=0; i<16; i++)
code_len_table[huftabindex][i] = (short)(*(lptemp++));
j = 0;
for(i=0; i<16; i++)
{
if(code_len_table[huftabindex][i]!=0)
{
k=0;
while(k<code_len_table[huftabindex][i])
{
code_value_table[huftabindex][k+j]=(short)(*(lptemp++));
k++;
}
j+=k;
}
}
i=0;
while (code_len_table[huftabindex][i]==0)
i++;
for (j=0; j<i; j++)
{
huf_min_value[huftabindex][j] = 0;
huf_max_value[huftabindex][j] = 0;
}
huf_min_value[huftabindex][i] = 0;
huf_max_value[huftabindex][i] = code_len_table[huftabindex][i] - 1;
for (j= i+ 1; j<16; j++)
{
huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j-1]+1)<<1;
huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j]+code_len_table[huftabindex][j]-1;
}
code_pos_table[huftabindex][0] = 0;
for (j= 1; j< 16; j++)
code_pos_table[huftabindex][j] = code_len_table[huftabindex][j-1] + code_pos_table[huftabindex][j-1];
lp += llength;
} //if
else
{
hf_table_index = *(lp+ 2);
lp += 2;
while (hf_table_index!=0xff)
{
huftab1 = (short)hf_table_index>>4; //huftab1=0,1
huftab2 = (short)hf_table_index&0x0f; //huftab2=0,1
huftabindex = huftab1* 2+huftab2;
lptemp = lp+1;
ccount = 0;
for(i=0; i<16; i++)
{
code_len_table[huftabindex][i] = (short)(*(lptemp++));
ccount += code_len_table[huftabindex][i];
}
ccount += 17;
j = 0;
for(i=0; i<16; i++)
if(code_len_table[huftabindex][i]!=0)
{
k=0;
while(k<code_len_table[huftabindex][i])
{
code_value_table[huftabindex][k+j] = (short)(*(lptemp++));
k++;
}
j += k;
}
i = 0;
while (code_len_table[huftabindex][i]==0)
i++;
for(j= 0; j<i; j++)
{
huf_min_value[huftabindex][j] = 0;
huf_max_value[huftabindex][j] = 0;
}
huf_min_value[huftabindex][i] = 0;
huf_max_value[huftabindex][i] = code_len_table[huftabindex][i] - 1;
for (j=i+1;j<16;j++)
{
huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j-1]+1)<<1;
huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j] + code_len_table[huftabindex][j] - 1;
}
code_pos_table[huftabindex][0] = 0;
for (j=1;j<16;j++)
code_pos_table[huftabindex][j] = code_len_table[huftabindex][j-1] + code_pos_table[huftabindex][j-1];
lp += ccount;
hf_table_index = *lp;
} //while
} //else
break;
case M_DRI:
llength = *(lp+ 1) | (*lp<<8);
restart = *(lp+ 3) | (*(lp+2)<<8);
lp += llength;
break;
case M_SOS:
llength = *(lp+ 1) | ( *lp<<8 );
comnum = *(lp+ 2);
if(comnum!=comp_num)
return 1;
lptemp = lp+ 3;
for (i= 0; i<comp_num; i++)
{
if(*lptemp==comp_index[0])
{
YDcIndex = (*(lptemp+1))>>4;//Y
YAcIndex = ((*(lptemp+1))&0x0f)+2;
}
else
{
UVDcIndex = (*(lptemp+1))>>4;//U,V
UVAcIndex = ((*(lptemp+1))&0x0f)+2;
}
lptemp += 2;
}
lp += llength;
finish = TRUE;
break;
case M_EOI:
return 1;
break;
default:
if ((id&0xf0)!=0xd0)
{
llength = *(lp+1) | ( *lp<<8 );
lp += llength;
}
else
lp += 2;
break;
}//switch
} //while
return 0;
}
int JpegFile1::Decode()
{
int funcret;
Y_in_MCU = SampRate_Y_H* SampRate_Y_V;
U_in_MCU = SampRate_U_H* SampRate_U_V;
V_in_MCU = SampRate_V_H* SampRate_V_V;
H_YtoU = SampRate_Y_H/ SampRate_U_H;
V_YtoU = SampRate_Y_V/ SampRate_U_V;
H_YtoV = SampRate_Y_H/ SampRate_V_H;
V_YtoV = SampRate_Y_V/ SampRate_V_V;
int add1 = SampRate_Y_H << 3;
int add2 = SampRate_Y_V << 3;
while((funcret=DecodeMCUBlock())==0)
{
interval++;
IntervalFlag = restart && (interval % restart==0);
IQtIZzMCUComponent(0);
IQtIZzMCUComponent(1);
IQtIZzMCUComponent(2);
GetYUV(0);
GetYUV(1);
GetYUV(2);
StoreBuffer();
sizej += add1;
if( sizej >= ImgWidth)
{
sizej = 0;
sizei += add2;
}
if( (sizej==0) && (sizei>=ImgHeight))
break;
}
return funcret;
}
/////////////////////////////////////////////////////////////////////////////////////////
void JpegFile1::GetYUV(short flag)
{
short H, VV, i, j, k, h;
int *buf, *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 << 6 );
break;
case 2:
H = SampRate_V_H;
VV = SampRate_V_V;
buf = V;
pQtZzMCU = QtZzMCUBuffer + ( (Y_in_MCU+ U_in_MCU) << 6 );
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_H8+j*8+h] = *pQtZzMCU++;//*/
int add1= 0, add2= 0, num = 8* sizeof(int), inc = SampRate_Y_H8 << 3;
for (i= 0; i< VV; i++, add1 += inc)
for(h= 0, j= 0; j< H; j++, h += 8)
for(add2= 0, k= 0; k< 8; k++, add2 += SampRate_Y_H8, pQtZzMCU += 8)
memcpy( buf+ add1+ h+ add2, pQtZzMCU, num); //*/
}
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -