📄 jpegencoder.c
字号:
{
ACBitCode.value = (127 + diffVal); return;
}
}
else if (diff <= 255)
{
ACBitCode.length = 8; //TotalNum[8]++;
if (diffVal < 0)
{
ACBitCode.value = (255 + diffVal); return;
}
}
else if (diff <= 511)
{
ACBitCode.length = 9; //TotalNum[9]++;
if (diffVal < 0)
{
ACBitCode.value = (511 + diffVal); return;
}
}
else if (diff <= 1023)
{
ACBitCode.length = 10; //TotalNum[10]++;
if (diffVal < 0)
{
ACBitCode.value = (1023 + diffVal); return;
}
}
else if (diff == 0)
{
//DC差值内容为0, AC差值内容不保存
DCBitCode.length = 0; //TotalNum[0]++;
return;
}
else if (diff <= 2047)
{
ACBitCode.length = 11; //TotalNum[11]++;
if (diffVal < 0)
{
ACBitCode.value = (2047 + diffVal); return;
}
}
else if (diff <= 4095)
{
ACBitCode.length = 12; //TotalNum[12]++;
if (diffVal < 0)
{
ACBitCode.value = (4095 + diffVal); return;
}
}
else if (diff <= 8191)
{
ACBitCode.length = 13; //TotalNum[13]++;
if (diffVal < 0)
{
ACBitCode.value = (8191 + diffVal); return;
}
}
else if (diff <= 16383)
{
ACBitCode.length = 14; //TotalNum[14]++;
if (diffVal < 0)
{
ACBitCode.value = (16383 + diffVal); return;
}
}
else
{
ACBitCode.length = 15; //TotalNum[15]++;
if (diffVal < 0)
{
ACBitCode.value = (32767 + diffVal); return;
}
}
}
#else
static void set_numbers_category_and_bitcode(void)
{
SDWORD nr;
SDWORD nrlower, nrupper;
BYTE cat;
pbitcode = bitcode + JPEGENCODER_BITCODE_LENGEH;
nrlower = 1;
nrupper = 2;
for (cat = 1; cat <= 8; cat++) //7, 8, ok
{
//Positive numbers
for (nr = nrlower; nr < nrupper; nr++)
{
//AC, AC系数范围与AC所需位数对照表
pbitcode[nr].length = cat; //AC系数
pbitcode[nr].value = (WORD)nr;//AC系数所需的位数
}
//Negative numbers
for (nr = -(nrupper - 1); nr <= -nrlower; nr++)
{
//AC, AC系数范围与AC所需位数对照表
pbitcode[nr].length = cat; //AC系数
pbitcode[nr].value = (WORD)(nrupper - 1 + nr); //AC系数所需的位数
}
nrlower <<= 1;
nrupper <<= 1;
}
}
void get_ac_bits_category(SWORD diffVal)
{
SWORD diff;
if (diffVal < 0) diff = -diffVal;
else diff = diffVal;
//AC系数所需的位数(SSSS组)
ACBitCode.value = diff;
//判断时,据统计,diff范围从1开始,依次减小
if (diff <= 511)
{
//AC, AC系数范围与AC所需位数对照表(正向)(AC实际保存值从负向0开始向正向递增)
ACBitCode.length = 9; //TotalNum[9]++;
if (diffVal < 0)
{
ACBitCode.value = (511 + diffVal); return;
}
}
else if (diff <= 1023)
{
ACBitCode.length = 10; //TotalNum[10]++;
if (diffVal < 0)
{
ACBitCode.value = (1023 + diffVal); return;
}
}
else if (diff == 0)
{
//DC差值内容为0, AC差值内容不保存
DCBitCode.length = 0; //TotalNum[0]++;
return;
}
else if (diff <= 2047)
{
ACBitCode.length = 11; //TotalNum[11]++;
if (diffVal < 0)
{
ACBitCode.value = (2047 + diffVal); return;
}
}
else if (diff <= 4095)
{
ACBitCode.length = 12; //TotalNum[12]++;
if (diffVal < 0)
{
ACBitCode.value = (4095 + diffVal); return;
}
}
else if (diff <= 8191)
{
ACBitCode.length = 13; //TotalNum[13]++;
if (diffVal < 0)
{
ACBitCode.value = (8191 + diffVal); return;
}
}
else if (diff <= 16383)
{
ACBitCode.length = 14; //TotalNum[14]++;
if (diffVal < 0)
{
ACBitCode.value = (16383 + diffVal); return;
}
}
else
{
ACBitCode.length = 15; //TotalNum[15]++;
if (diffVal < 0)
{
ACBitCode.value = (32767 + diffVal); return;
}
}
}
#endif
//Nothing to overwrite for APP0info
static void write_APP0info(void)
{
writeword(APP0info.marker);
writeword(APP0info.length);
writebyte('J');
writebyte('F');
writebyte('I');
writebyte('F');
writebyte(0X00);
writebyte(APP0info.versionhi);
writebyte(APP0info.versionlo);
writebyte(APP0info.xyunits);
writeword(APP0info.xdensity);
writeword(APP0info.ydensity);
writebyte(APP0info.thumbnwidth);
writebyte(APP0info.thumbnheight);
}
static void write_DQTinfo(void)
{
BYTE i;
writeword(DQTinfo.marker);
writeword(DQTinfo.length);
writebyte(DQTinfo.QTYinfo);
for (i = 0; i < 64; i++)
writebyte(DQTinfo.Ytable[i]);
writebyte(DQTinfo.QTCbinfo);
for (i = 0; i < 64; i++)
writebyte(DQTinfo.Cbtable[i]);
}
// We should overwrite width and height
static void write_SOF0info(void)
{
writeword(SOF0info.marker);
writeword(SOF0info.length);
writebyte(SOF0info.precision);
writeword(SOF0info.height);
writeword(SOF0info.width);
writebyte(SOF0info.nrofcomponents);
writebyte(SOF0info.IdY);
#ifdef Y_HXV_1X1_DEBUG
SOF0info.HVY = 0X11;
#endif
#ifdef Y_HXV_2X2_DEBUG
SOF0info.HVY = 0X22;
#endif
#ifdef Y_HXV_2X1_DEBUG
SOF0info.HVY = 0X21;
#endif
#ifdef Y_HXV_1X2_DEBUG
SOF0info.HVY = 0X12;
#endif
writebyte(SOF0info.HVY);
writebyte(SOF0info.QTY);
writebyte(SOF0info.IdCb);
writebyte(SOF0info.HVCb);
writebyte(SOF0info.QTCb);
writebyte(SOF0info.IdCr);
writebyte(SOF0info.HVCr);
writebyte(SOF0info.QTCr);
}
/*
function:
Set quantization table and zigzag reorder it
input:
[in] *basic_table: 指向输入缓冲区的指针
scale_factor: 压缩因数,决定压缩比
[in, out] *newtable: 指向输入、输出缓冲区的指针
output:
None
*/
static void set_quant_table(BYTE *basic_table, BYTE scale_factor, BYTE *newtable)
{
BYTE i;
WORD temp;
for (i = 0; i < 64; i++)
{
temp = (basic_table[i] * scale_factor + 50) / 100;
//limit the values to the valid range
if (temp <= 0)
temp = 1;
//limit to baseline range if requested
if (temp > 255)
temp = 255;
newtable[zigzag[i]] = (BYTE)temp;
//newtable[i] = (BYTE)temp;
}
}
//controls the visual quality of the image
//the smaller is, the better image we'll get, and the smaller
//compression we'll achieve
#define JPEGENCODER_SCALE_FACTOR 100//150//100//50
static void set_DQTinfo(void)
{
DQTinfo.marker = 0XFFDB;
DQTinfo.length = 132;
DQTinfo.QTYinfo = 0;
DQTinfo.QTCbinfo = 1;
set_quant_table(std_luminance_qt, JPEGENCODER_SCALE_FACTOR, DQTinfo.Ytable);
set_quant_table(std_chrominance_qt, JPEGENCODER_SCALE_FACTOR, DQTinfo.Cbtable);
}
static void write_DHTinfo(void)
{
BYTE i;
writeword(DHTinfo.marker);
writeword(DHTinfo.length);
writebyte(DHTinfo.HTYDCinfo);
for (i = 0; i < 16;i++)
writebyte(DHTinfo.YDC_nrcodes[i]);
for (i = 0; i <= 11; i++)
writebyte(DHTinfo.YDC_values[i]);
writebyte(DHTinfo.HTYACinfo);
for (i = 0; i < 16; i++)
writebyte(DHTinfo.YAC_nrcodes[i]);
for (i = 0; i <= 161; i++)
writebyte(DHTinfo.YAC_values[i]);
writebyte(DHTinfo.HTCbDCinfo);
for (i = 0; i < 16; i++)
writebyte(DHTinfo.CbDC_nrcodes[i]);
for (i = 0; i <= 11; i++)
writebyte(DHTinfo.CbDC_values[i]);
writebyte(DHTinfo.HTCbACinfo);
for (i = 0; i < 16; i++)
writebyte(DHTinfo.CbAC_nrcodes[i]);
for (i = 0; i <= 161; i++)
writebyte(DHTinfo.CbAC_values[i]);
}
/*
function:
Set Huffman table
input:
None
output:
None
*/
static void set_DHTinfo(void)
{
BYTE i;
DHTinfo.marker = 0xFFC4; //DHT标记,定义Huffman表
DHTinfo.length = 0x01A2; //DHT参数长度
//高四位表示DHT的使用者:0 = DC, 1 = AC
//低四位表示使用第几个Huffman表
DHTinfo.HTYDCinfo = 0X00;
for (i = 0; i < 16; i++)
DHTinfo.YDC_nrcodes[i] = std_dc_luminance_nrcodes[i + 1];
for (i = 0; i <= 11; i++)
DHTinfo.YDC_values[i] = std_dc_luminance_values[i];
DHTinfo.HTYACinfo = 0X10;
for (i = 0; i < 16; i++)
DHTinfo.YAC_nrcodes[i] = std_ac_luminance_nrcodes[i + 1];
for (i = 0; i <= 161; i++)
DHTinfo.YAC_values[i] = std_ac_luminance_values[i];
DHTinfo.HTCbDCinfo = 0X01;
for (i = 0; i < 16; i++)
DHTinfo.CbDC_nrcodes[i] = std_dc_chrominance_nrcodes[i + 1];
for (i = 0; i <= 11; i++)
DHTinfo.CbDC_values[i] = std_dc_chrominance_values[i];
DHTinfo.HTCbACinfo = 0X11;
for (i = 0; i < 16; i++)
DHTinfo.CbAC_nrcodes[i] = std_ac_chrominance_nrcodes[i + 1];
for (i = 0; i <= 161; i++)
DHTinfo.CbAC_values[i] = std_ac_chrominance_values[i];
}
//Nothing to overwrite for SOSinfo
static void write_SOSinfo(void)
{
writeword(SOSinfo.marker);
writeword(SOSinfo.length);
writebyte(SOSinfo.nrofcomponents);
writebyte(SOSinfo.IdY);
writebyte(SOSinfo.HTY);
writebyte(SOSinfo.IdCb);
writebyte(SOSinfo.HTCb);
writebyte(SOSinfo.IdCr);
writebyte(SOSinfo.HTCr);
writebyte(SOSinfo.Ss);
writebyte(SOSinfo.Se);
writebyte(SOSinfo.Bf);
}
static void write_comment(BYTE *comment)
{
WORD i, length;
writeword(0XFFFE); //The COM marker
length = strlen((const char *)comment);
writeword(length + 2);
for (i = 0; i < length; i++)
writebyte(comment[i]);
}
// A portable version; it should be done in assembler
/*
function:
compute quantization table
input:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -