📄 jpegencoder.c
字号:
//JpegEncoder.c
#include "BasicDefinition.h"
#include "JpegTypesAndGlobals.h"
extern BYTE DDC4[0x400];
extern BYTE RMartix[0x4000];
extern BYTE GMartix[0x4000];
extern BYTE BMartix[0x4000];
extern BOOL m_bAlreadyOpen;//没有打开文件
UINT m_nErrorCode;//前面操作的错误代码
extern RGB2YUV(void);
extern DctBlockQuantize(int* InputBlock,const unsigned int* zigzag,const int* Q_table,int* OutputBlock);
extern Mem8x8Cpy(BYTE* SourceAddr,BYTE* DistAddr);
void DCEncode(int* InputBlock,const DC_ENCODE_TAB* dc_encode_tab,int* OldDc);
void ACEncode(int* InputBlock,const AC_ENCODE_TAB* ac_encode_tab,BOOL Y_or_CbCr);
extern void ACEncode2(int* InputBlock,const AC_ENCODE_TAB* ac_encode_tab,BOOL Y_or_CbCr);
#define K_Y_AC 0
#define K_CbCr_AC 1
extern FILE *fp1;
void JpegGloablValsInit(void)
{
m_bAlreadyOpen = 0;//没有打开文件
m_nErrorCode = K_OPERATION_SUCCESS;
OneBlockBitstream.BitstreamLength = 0;
OneBlockBitstream.LeftedBitLength = 0;
OldDCY = 0;
OldDCCb = 0;
OldDCCr = 0;
}
BOOL JpegInfoInit(void)
{
if(m_nErrorCode == K_OPERATION_SUCCESS)
{
if(DDC4[0] == 'B' && DDC4[0] == 'M' && DDC4[28] != 24)//不是24位真彩色
{
JpegEncodeErrorMsg(K_NOT_TRUE_COLOR_ERROR);
return K_NOT_TRUE_COLOR_ERROR;
}
ImageWidth = (DDC4[18]&0xff) + (DDC4[19]<<8);//后面两个字节不管,不会产生这么大的图
ImageHight = (DDC4[22]&0xff) + (DDC4[23]<<8);
ImageBufSize = (unsigned long)(ImageWidth) * (unsigned long)(ImageHight);
return K_OPERATION_SUCCESS;
}
else
{
JpegEncodeErrorMsg(K_FILE_NOT_OPEN_ERROR);
return K_FILE_NOT_OPEN_ERROR;
}
}
void JpegEncodeErrorMsg(UINT ErrorCode)//方便以后与单片机通信
{
puts(JpegErrorMessageTable[ErrorCode]);
}
BOOL JpegMainEncoder(void)
{
UINT xpos,ypos;
if(m_nErrorCode == K_OPERATION_SUCCESS)
{
ImageWidthFixed = (ImageWidth>>3)<<3;
ImageHightFixed = (ImageHight>>3)<<3;
for(ypos=0;ypos<ImageHightFixed;ypos+=8)
for(xpos=0;xpos<ImageWidthFixed;xpos+=8)
{
LoadDataUnitsFromBuffer(xpos,ypos);
RGB2YUV();
IMG_sw_fdct_8x8(YDU,TmpCalBuf);
IMG_sw_fdct_8x8(CbDU,TmpCalBuf);
IMG_sw_fdct_8x8(CrDU,TmpCalBuf);
DctBlockQuantize(YDU,zigzag,LuminanceScaleTab,YDCTzigzagQ);
DctBlockQuantize(CbDU,zigzag,ChrominanceScaleTab,CbDCTzigzagQ);
DctBlockQuantize(CrDU,zigzag,ChrominanceScaleTab,CrDCTzigzagQ);
DCEncode(YDCTzigzagQ,&YDc_EncodeTab,&OldDCY);
ACEncode(YDCTzigzagQ,&YAc_EncodeTab,K_Y_AC);
//ACEncode2(YDCTzigzagQ,&YAc_EncodeTab,K_Y_AC);
DCEncode(CbDCTzigzagQ,&CrCbDc_EncodeTab,&OldDCCb);
ACEncode(CbDCTzigzagQ,&CrCbAc_EncodeTab,K_CbCr_AC);
DCEncode(CrDCTzigzagQ,&CrCbDc_EncodeTab,&OldDCCr);
ACEncode(CrDCTzigzagQ,&CrCbAc_EncodeTab,K_CbCr_AC);
}
FillOnes();
JpegEncodeEnd(fp1);
return K_OPERATION_SUCCESS;
}
else
{
return K_STOP_DU_TO_PREVIOUS_ERROR;
}
}
void LoadDataUnitsFromBuffer(UINT xpos,UINT ypos)
{
unsigned long m_nLocation,m_nLocationTmp;//存放的地址
m_nLocation = ((unsigned long)(ImageWidth)) * ((unsigned long)(ypos)) + (unsigned long)(xpos);
m_nLocationTmp = m_nLocation + (unsigned long)RMartix;//装载Red
Mem8x8Cpy((BYTE*)m_nLocationTmp,Rbuf);
m_nLocationTmp = m_nLocation + (unsigned long)GMartix;//装载Green
Mem8x8Cpy((BYTE*)m_nLocationTmp,Gbuf);
m_nLocationTmp = m_nLocation + (unsigned long)BMartix;//装载Blue
Mem8x8Cpy((BYTE*)m_nLocationTmp,Bbuf);
}
void DCEncode(int* InputBlock,const DC_ENCODE_TAB* dc_encode_tab,int* OldDc)
{
register int DiffDc,DiffDc2;//直流系数的差值
register UINT SizeOfDiffDc;
UINT m_nAddBitsNum;//添加的bits位数
UINT m_nAddBitsVal;//添加的变量
SizeOfDiffDc = 0;
DiffDc = *InputBlock - *OldDc;
DiffDc2 = abs(DiffDc);
//计算直流系数的位数
while(DiffDc2 > 0)
{
DiffDc2 = DiffDc2>>1;
SizeOfDiffDc++;
}
*OldDc = *InputBlock;
m_nAddBitsNum = dc_encode_tab->BitStreamLengthTab[SizeOfDiffDc];//求新添加的bitstream的位数
m_nAddBitsVal = dc_encode_tab->BitStreamTab[SizeOfDiffDc];//添加的变量
AddBits(m_nAddBitsVal,m_nAddBitsNum);
//if(DiffDc >= 0)
//{
// DiffDc2 = DiffDc;
//}
//else
if(DiffDc < 0)
{
//if(SizeOfDiffDc == 16)
//{
// DiffDc2 = (abs(DiffDc))^0xffff;
//}
//else
//{
//DiffDc2 = ~(0xffff<<SizeOfDiffDc);
//DiffDc2 = (abs(DiffDc))^DiffDc2;
DiffDc = (abs(DiffDc))^(~(0xffff<<SizeOfDiffDc));
//}
}
AddBits(DiffDc,SizeOfDiffDc);
}
void AddBits(int Inputdata,UINT Length)
{
int TmpLeftedBits;//计算的时候使用
UINT TmpPos;
UINT TmpShiftNum;//,TmpShiftNum2;
UINT TmpData;
//BYTE TmpDataLow,TmpDataHigh;
//UINT TmpMask;
if(OneBlockBitstream.BitstreamLength > 511)
{
AddBytes(fp1);
}
TmpShiftNum = 16 - OneBlockBitstream.LeftedBitLength;//计算OneBlockBitstream.LeftedWord的移位数
TmpLeftedBits = (int)(Length) - TmpShiftNum;//+ (int)(OneBlockBitstream.LeftedBitLength) - 16;//是否超过16位
if(TmpLeftedBits >= 0)
{
TmpPos = OneBlockBitstream.BitstreamLength;
//TmpShiftNum = 16 - OneBlockBitstream.LeftedBitLength;//计算OneBlockBitstream.LeftedWord的移位数
OneBlockBitstream.LeftedWord = (OneBlockBitstream.LeftedWord>>TmpShiftNum)<<TmpShiftNum;//清除末尾不需要的部分
//TmpShiftNum2 = Length - TmpShiftNum;//计算m_nAddBitsVal的移位数
//TmpMask = 1;
//while(TmpShiftNum > 1)
//{
// TmpMask = (TmpMask<<1) + 1;
// TmpShiftNum--;
//}
//TmpMask = (1 << TmpShiftNum) - 1;
TmpData = OneBlockBitstream.LeftedWord | ((Inputdata>>TmpLeftedBits)&((1 << TmpShiftNum) - 1));//TmpMask);
//TmpDataHigh = (BYTE)(TmpData>>8);
OneBlockBitstream.Bitstream[TmpPos++] = (BYTE)(TmpData>>8);//TmpDataHigh;
//OneBlockBitstream.BitstreamLength++;//放到后面一起加
if((BYTE)(TmpData>>8) == 0xff)//(TmpDataHigh == 0xff)
{
OneBlockBitstream.Bitstream[TmpPos++] = 0;
OneBlockBitstream.BitstreamLength++;
}
//TmpDataLow = (BYTE)(TmpData&0xff);
OneBlockBitstream.Bitstream[TmpPos++] = (BYTE)(TmpData&0xff);//TmpDataLow;
OneBlockBitstream.BitstreamLength += 2;
if((BYTE)(TmpData&0xff) == 0xff)//(TmpDataLow == 0xff)
{
OneBlockBitstream.Bitstream[TmpPos++] = 0;
OneBlockBitstream.BitstreamLength++;
}
OneBlockBitstream.LeftedBitLength = TmpLeftedBits;
OneBlockBitstream.LeftedWord = Inputdata<<(16-TmpLeftedBits);//(16-TmpShiftNum2);
}
else
{
//TmpShiftNum2 = 16 - OneBlockBitstream.LeftedBitLength;//计算移位的数量
//TmpShiftNum = TmpShiftNum2 - Length;
OneBlockBitstream.LeftedBitLength += Length;//更新最后bit的长度
OneBlockBitstream.LeftedWord = OneBlockBitstream.LeftedWord>>TmpShiftNum;//TmpShiftNum2;//清除末尾不需要的部分
OneBlockBitstream.LeftedWord = (OneBlockBitstream.LeftedWord<<TmpShiftNum) | (Inputdata<<abs(TmpLeftedBits));//(Inputdata<<TmpShiftNum);
}
}
//extern UINT jpe1(int* InputBlock,UINT* m_bAllAcZero);
void ACEncode(int* InputBlock,const AC_ENCODE_TAB* ac_encode_tab,BOOL Y_or_CbCr)
{
UINT m_bAllAcZero,EncodeAc,nrzeroes,startpos,k,nrmarker;
register int *pInputBlock;
register UINT Tmp,i,endpos;
pInputBlock = InputBlock + 63;
//m_bAllAcZero = 1;//假设所有元素都为0成立
//endpos = 63;
// endpos = jpe1(InputBlock,&m_bAllAcZero);
for(i=63;i>0;i--)
{
if(*pInputBlock-- != 0)
{
//m_bAllAcZero = 0;
break;
}
//endpos--;
}
if(i>0)
{
m_bAllAcZero = 0;
}
else
{
m_bAllAcZero = 1;//所有元素都为0成立
}
endpos = i;
if(m_bAllAcZero == 1)//EOB
{
if(Y_or_CbCr == K_Y_AC )
{
AddBits(10,4);
}
else
{
AddBits(0,2);
}
}
else
{
i=1;
nrzeroes = 0;//连零的数量
pInputBlock = InputBlock + 1;
while (i <= endpos)
{
startpos = i;
while(i < endpos && *pInputBlock++ == 0)//InputBlock[i]寻找相连的零,我交换了判断的顺序
i++;
nrzeroes = i - startpos;//连零的数量
if(nrzeroes >= 16)//如果连零的数量大于等于16
{
Tmp = nrzeroes>>4;
for(nrmarker=0;nrmarker<Tmp;nrmarker++)
//while(Tmp-- > 0)
{
if(Y_or_CbCr == K_Y_AC )//ZRL
{
AddBits(2041,11);
}
else
{
AddBits(1018,10);
}
nrzeroes = nrzeroes - 16;
}
//nrzeroes -= Tmp3*16;
}
EncodeAc = 0;//AC编码的长度
Tmp = abs(InputBlock[i]);//(*(pInputBlock-1));//abs(Output8x8Block(i,j));
while(Tmp > 0)//计算需要的长度
{
Tmp = Tmp>>1;
EncodeAc++;
}
k = nrzeroes*10 + EncodeAc - 1;//在AcMapStrTab中的位置
AddBits(ac_encode_tab->BitStreamTab[k],ac_encode_tab->BitStreamLengthTab[k]);
Tmp = InputBlock[i];
// if(InputBlock[i] >= 0)
// {
// Tmp = InputBlock[i];
// }
// else
if(*(InputBlock + i) < 0)
{
// if(EncodeAc == 16)//好象不存在EncodeAc = 16的情况
// {
// Tmp = (abs(Tmp))^0xffff;//(abs(InputBlock[i]))^0xffff;
// }
// else
// {
//Tmp = ~(0xffff<<EncodeAc);
//Tmp = abs(InputBlock[i])^Tmp;
Tmp = abs(Tmp)^(~(0xffff<<EncodeAc));
// }
}
AddBits(Tmp,EncodeAc);
i++;
}//i <= endpos
if(endpos < 63)
{
if(Y_or_CbCr == K_Y_AC )
{
AddBits(10,4);
}
else
{
AddBits(0,2);
}
}
}//m_bAllAcZero == 1
}
void FillOnes(void)
{
//UINT Tmp,Tmp2;
//if(OneBlockBitstream.LeftedBitLength != 0)
//{
//Tmp = 16 - OneBlockBitstream.LeftedBitLength;
////Tmp2 = (1 << (16 - OneBlockBitstream.LeftedBitLength)) - 1;
//Tmp2 = 1;
//while(Tmp>1)
//{
// Tmp2 = (Tmp2<<1) + 1;
// Tmp--;
//}
OneBlockBitstream.LeftedWord = OneBlockBitstream.LeftedWord | ((1 << (16 - OneBlockBitstream.LeftedBitLength)) - 1);
//}
}
extern void ClearStReg(void);
void JpegEncodeEnd(FILE *fp)
{
UINT TmpDataHigh;
ClearStReg();
fwrite(OneBlockBitstream.Bitstream,sizeof(BYTE),OneBlockBitstream.BitstreamLength,fp);
OneBlockBitstream.BitstreamLength = 0;
if(OneBlockBitstream.LeftedBitLength != 0)
{
TmpDataHigh = (OneBlockBitstream.LeftedWord)>>8;
fwrite(&TmpDataHigh,sizeof(BYTE),1,fp);
if(OneBlockBitstream.LeftedBitLength > 8)
{
fwrite(&(OneBlockBitstream.LeftedWord),sizeof(BYTE),1,fp);
}
OneBlockBitstream.LeftedBitLength = 0;
}
TmpDataHigh = 0xff;
fwrite(&TmpDataHigh,sizeof(BYTE),1,fp);
TmpDataHigh = 0xd9;
fwrite(&TmpDataHigh,sizeof(BYTE),1,fp);
fclose(fp);
}
void JpegHeadWrite(FILE *fp)
{
BYTE TmpJpegInfo[4];
ImageWidthFixed = (ImageWidth>>3)<<3;
ImageHightFixed = (ImageHight>>3)<<3;
TmpJpegInfo[0] = (BYTE)(ImageHightFixed>>8);//159
TmpJpegInfo[1] = (BYTE)(ImageHightFixed&0xff);//160
TmpJpegInfo[2] = (BYTE)(ImageWidthFixed>>8);//161
TmpJpegInfo[3] = (BYTE)(ImageWidthFixed&0xff);//162
fwrite(JpegInfo,sizeof(BYTE),159,fp);//JpegInfo 607
fwrite(TmpJpegInfo,sizeof(BYTE),4,fp);//TmpJpegInfo
fwrite((JpegInfo+163),sizeof(BYTE),444,fp);//JpegInfo
}
void AddBytes(FILE *fp)
{
//UINT Tmp;
ClearStReg();
fwrite(OneBlockBitstream.Bitstream,sizeof(BYTE),512,fp);
OneBlockBitstream.BitstreamLength -= 512;
if(OneBlockBitstream.BitstreamLength != 0)
{
//Tmp = OneBlockBitstream.Bitstream[512];
//OneBlockBitstream.Bitstream[0] = Tmp;
OneBlockBitstream.Bitstream[0] = OneBlockBitstream.Bitstream[512];
//Tmp = OneBlockBitstream.Bitstream[513];
//OneBlockBitstream.Bitstream[1] = Tmp;
OneBlockBitstream.Bitstream[1] = OneBlockBitstream.Bitstream[513];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -