📄 jpegencoder.c
字号:
//float z1, z2, z3, z4, z5, z11, z13;
SWORD z1, z2, z3, z4, z5, z11, z13;
//float *dataptr;
//float datafloat[64];
SWORD *dataptr;
//SWORD datafloat[64];
//float temp;
//SWORD temp;
SBYTE ctr;
BYTE i, j = 0;
//Pass 1: process rows.
dataptr = data;
for (ctr = 7; ctr >= 0; ctr--)
{
tmp0 = dataptr[0] + dataptr[7];
tmp7 = dataptr[0] - dataptr[7];
tmp1 = dataptr[1] + dataptr[6];
tmp6 = dataptr[1] - dataptr[6];
tmp2 = dataptr[2] + dataptr[5];
tmp5 = dataptr[2] - dataptr[5];
tmp3 = dataptr[3] + dataptr[4];
tmp4 = dataptr[3] - dataptr[4];
//Even part
tmp10 = tmp0 + tmp3; //phase 2
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; //phase 3
dataptr[4] = tmp10 - tmp11;
//z1 = (tmp12 + tmp13) * ((float) 0.707106781); //c4
z1 = ((tmp12 + tmp13) * IDCT_COEFF_1) >> IDCT_SHIFT; //c4 IDCT_COEFF_1
dataptr[2] = tmp13 + z1; //phase 5
dataptr[6] = tmp13 - z1;
//Odd part
tmp10 = tmp4 + tmp5; //phase 2
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
//The rotator is modified from fig 4-8 to avoid extra negations.
//z5 = (tmp10 - tmp12) * ((float) 0.382683433); //c6
//z2 = ((float) 0.541196100) * tmp10 + z5; //c2-c6
//z4 = ((float) 1.306562965) * tmp12 + z5; //c2+c6
//z3 = tmp11 * ((float) 0.707106781); //c4
z5 = ((tmp10 - tmp12) * IDCT_COEFF_2) >> IDCT_SHIFT; //c6
//z2 = ((IDCT_COEFF_3 * tmp10) + (z5 << IDCT_SHIFT)) >> IDCT_SHIFT; //c2-c6
z2 = ((tmp10 << 9) + (z5 << IDCT_SHIFT)) >> IDCT_SHIFT; //c2-c6
z4 = ((IDCT_COEFF_4 * tmp12) + (z5 << IDCT_SHIFT)) >> IDCT_SHIFT; //c2+c6
z3 = (tmp11 * IDCT_COEFF_1) >> IDCT_SHIFT; //c4
z11 = tmp7 + z3; //phase 5
z13 = tmp7 - z3;
dataptr[5] = z13 + z2; //phase 6
dataptr[3] = z13 - z2;
dataptr[1] = z11 + z4;
dataptr[7] = z11 - z4;
dataptr += 8; //advance pointer to next row
}
// Pass 2: process columns.
//dataptr = datafloat;
dataptr = data;
for (ctr = 7; ctr >= 0; ctr--)
{
tmp0 = dataptr[0] + dataptr[56];
tmp7 = dataptr[0] - dataptr[56];
tmp1 = dataptr[8] + dataptr[48];
tmp6 = dataptr[8] - dataptr[48];
tmp2 = dataptr[16] + dataptr[40];
tmp5 = dataptr[16] - dataptr[40];
tmp3 = dataptr[24] + dataptr[32];
tmp4 = dataptr[24] - dataptr[32];
// Even part
tmp10 = tmp0 + tmp3; //phase 2
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; //phase 3
dataptr[32] = tmp10 - tmp11;
z1 = ((tmp12 + tmp13) * IDCT_COEFF_1) >> IDCT_SHIFT; //c4
dataptr[16] = tmp13 + z1; //phase 5
dataptr[48] = tmp13 - z1;
//Odd part
tmp10 = tmp4 + tmp5; //phase 2
tmp11 = tmp5 + tmp6;
tmp12 = tmp6 + tmp7;
//The rotator is modified from fig 4-8 to avoid extra negations.
z5 = ((tmp10 - tmp12) * IDCT_COEFF_2) >> IDCT_SHIFT; //c6
//z2 = (IDCT_COEFF_3 * tmp10 + (z5 << IDCT_SHIFT)) >> IDCT_SHIFT; //c2-c6
z2 = ((tmp10 << 9) + (z5 << IDCT_SHIFT)) >> IDCT_SHIFT; //c2-c6
z4 = (IDCT_COEFF_4 * tmp12 + (z5 << IDCT_SHIFT)) >> IDCT_SHIFT; //c2+c6
z3 = (tmp11 * IDCT_COEFF_1) >> IDCT_SHIFT; //c4
z11 = tmp7 + z3; //phase 5
z13 = tmp7 - z3;
dataptr[40] = z13 + z2; //phase 6
dataptr[24] = z13 - z2;
dataptr[8] = z11 + z4;
dataptr[56] = z11 - z4;
dataptr++; //advance pointer to next column
}
//Quantize/descale the coefficients, and store into output array
for (i = 0; i < 64; i++)
{
//Apply the quantization and scaling factor
#ifdef QUANT_TABLE_DEBUG
outdata[zigzag[i]] = ((SDWORD)(data[i] * fdtbl[i] + 16384)) >> 15;
#else
outdata[zigzag[i]] = data[i] / fdtbl[i];
#endif
#ifdef QUANT_LOOP_DEBUG
if (0 == outdata[i])
{
if (j++ >= 15)
{
for (j = i; j < 64; j++)
outdata[zigzag[j]] = 0;
return;
}
}
else
j = 0;
#endif
//Round to nearest integer.
//Since C does not specify the direction of rounding for negative
//quotients, we have to force the dividend positive for portability.
//The maximum coefficient size is +-16K (for 12-bit data), so this
//code should work for either 16-bit or 32-bit ints.
//outdata[i] = (SWORD)((SWORD)(temp * 16 + 16384.5 * 16) >> 4 - 16384);
//outdata[i] = (SWORD) ((SWORD)(temp + 16384.5) - 16384);
}
}
#else
SWORD Cm_matrix[8][8] = {
16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384,
31521, 26722, 17855, 6270, -6270, -17855, -26722, -31521,
27969, 11585, -11585, -27969, -27969, -11585, 11585, 27969,
22654, -5315, -26722, -15137, 15137, 26722, 5315, -22654,
16384, -16384, -16384, 16384, 16384, -16384, -16384, 16384,
10114, -17855, 3552, 15137, -15137, -3552, 17855, -10114,
4799, -11585, 11585, -4799, -4799, 11585, -11585, 4799,
1247, -3552, 5315, -6270, 6270, -5315, 3552, -1247
};
//Q14
//ralf modify
static void fdct_and_quantization(SWORD *data, WORD *fdtbl, SWORD *outdata)
{
SWORD *dataptr, *matrixptr;
//SWORD dct_64_tmp[8][8];
SWORD dct_64_tmp[64];
SWORD i, j, k, temp;
dataptr = data;
matrixptr = Cm_matrix[0];
for(k = 0; k <= 7; k++)
{
// for (i = 0; i <= 7; i++)
// {
// temp = 0;
// for(j = 0; j <= 7; j++)
// {
// temp = temp + Cm_matrix[i][j] * dataptr[k * 8 + j];
// }
//
// dct_64_tmp[k][i] = temp >> 14;
// }
dct_64_tmp[k * 8 + 0] = (dataptr[0] + dataptr[1] + dataptr[2] + dataptr[3]
+ dataptr[4] + dataptr[5] + dataptr[6] + dataptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 1] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 2] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 3] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 4] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 5] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 6] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dct_64_tmp[k * 8 + 7] = (dataptr[0] * matrixptr[0] + dataptr[1] * matrixptr[1]
+ dataptr[2] * matrixptr[2] + dataptr[3] * matrixptr[3]
+ dataptr[4] * matrixptr[4] + dataptr[5] * matrixptr[5]
+ dataptr[6] * matrixptr[6] + dataptr[7] * matrixptr[7]) >> 14;
matrixptr += 1;
dataptr += 8;
}
dataptr = dct_64_tmp;
matrixptr = Cm_matrix[0];
/*
for(k = 0; k <= 7; k++)
{
for(i = 0; i <= 7; i++)
{
temp = 0;
for(j = 0; j <= 7; j++)
{
temp = temp + Cm_matrix[i][j] * dct_64_tmp[j][k];
}
dataptr[i * 8 + k] = temp >> 14;
}
}
*/
for (i = 0; i < 64; i++)
{
//Apply the quantization and scaling factor
//outdata[i] = data[i] / fdtbl[i]; //
//outdata[zigzag[i]] = data[i] / fdtbl[i];
//outdata[zigzag[i]] = ((SDWORD)(data[i] * fdtbl[i] + 16384)) >> 15; //16384
#ifdef QUANT_TABLE_DEBUG
outdata[zigzag[i]] = ((SDWORD)(data[i] * fdtbl[i] + 16384)) >> 15; //16384
#else
outdata[zigzag[i]] = data[i] / fdtbl[i];
#endif
#ifdef QUANT_LOOP_DEBUG
if (0 == outdata[i])
{
if (j++ >= 15)
{
for (j = i; j < 64; j++)
outdata[zigzag[j]] = 0;
//outdata[j] = 0;
return;
}
}
else
j = 0;
#endif
//Round to nearest integer.
//Since C does not specify the direction of rounding for negative
//quotients, we have to force the dividend positive for portability.
//The maximum coefficient size is +-16K (for 12-bit data), so this
//code should work for either 16-bit or 32-bit ints.
//outdata[i] = (SWORD)((SWORD)(temp * 16 + 16384.5 * 16) >> 4 - 16384);
//outdata[i] = (SWORD) ((SWORD)(temp + 16384.5) - 16384);
}
}
#endif
/*
function:
compute quantization table
DC编码:
AC编码:
中间符号RRRRSSSS:
高四位是前续0的个数
低四位是后面数字的位数
ZRL(15/0, Zero Run-Length): 连续为0的个数大于15,则用15/0来表示连续的16个0.
EOB(0/0, Enel of Block): 表示其后所剩余的AC系数皆等于0,以中间符号值作为索引值,从相应的AC编码表中
找出适当的霍夫曼码值,再于AC值相连即可。
input:
[in] *ComponentDU: 指向输入缓冲区的指针
[in] *fdtbl: 量化因子
[in, out] *DC: 指向上一个F(0, 0) DC值指针, 然后记录当前F(0, 0) DC值指针
[in] *HTDC: 指向DC Huffman表指针
[in] *HTAC: 指向AC Huffman表指针
output:
None
*/
static void process_DU(SWORD *ComponentDU, WORD *fdtbl, SWORD *DC, bitstring *HTDC, bitstring *HTAC)
{
//SWORD DU_DCT[64]; //Current DU (after DCT and quantization) which we'll zigzag
SWORD DU[64], tempDU; //zigzag reordered DU which will be Huffman coded
bitstring EOB = HTAC[0X00]; //EOB
bitstring M16zeroes = HTAC[0XF0]; //ZRL
BYTE i;
BYTE startpos;
BYTE end0pos;
BYTE nrzeroes, nrzeroes_times;
BYTE nrmarker;
SWORD diff;
//经过DCT变换后矩阵数据自然数为频率系数,这些系数以F(0,0)的值最大,称为DC
//其余的63个频率系数则多半是一些接近于0的正负浮点数,称为AC.
//获得经过FDCT 和量化后的数据(经过量化后,频率系数变为整数,便于最后的编码)
fdct_and_quantization(ComponentDU, fdtbl, DU);
diff = DU[0] - *DC; //计算当前块DC和上一块DC的差值
*DC = DU[0]; //保存当前块的DC值
//Encode DC
if (diff == 0)
writebits(HTDC[0]); //记录huffman编码,此时DC的差值位数和差值内容均为0,不必记录
else
{
get_dc_diff_bits(diff);
writebits(HTDC[DCBitCode.length]); //记录huffman编码
//reserved DCBitCode.length bits in DCBitCode.value
DCBitCode.value = DCBitCode.value & ((1 << DCBitCode.length) - 1);
writebits(DCBitCode); //记录当前的DC编码
}
//Encode ACs
for (end0pos = 63; (DU[end0pos] == 0) && (end0pos > 0); end0pos--);
#ifdef PROCESS_DU_DEBUG
process_du_buf[end0pos]++;
#endif
//end0pos = first element in reverse order !=0
if (!end0pos)
{
writebits(EOB);
return;
}
i = 1;
while (i <= end0pos)
{
startpos = i;
for (; (DU[i] == 0) && (i <= end0pos); i++);
nrzeroes = i - startpos; //连续0的个数
if (nrzeroes >= 16)
{
//printf("%d > 16\n", nrzeroes);
//连续16个0,用M16zeroes记录一次
nrzeroes_times = nrzeroes / 16;
for (nrmarker = 1; nrmarker <= nrzeroes_times; nrmarker++)
writebits(M16zeroes);
//记录连续16个0(整数倍)后,剩余0的个数
//nrzeroes = nrzeroes % 16;
nrzeroes = nrzeroes - (nrzeroes_times << 4);
}
#ifdef GET_AC_BIT_DEBUG
get_ac_bits_category(DU[i]);
//中间符号RRRR/SSSS,RRRR表示第非0的AC之前,其值为0的AC个数,SSSS表示AC所需的位数
writebits(HTAC[(nrzeroes << 4) + ACBitCode.length]); //记录huffman编码
writebits(ACBitCode); //记录当前的AC编码
#else
if (DU[i] < 0) tempDU = -DU[i];
else tempDU = DU[i];
if (tempDU <= 255)
{
writebits(HTAC[(nrzeroes << 4) + pbitcode[DU[i]].length]); //记录huffman编码 pbitcode.
writebits(pbitcode[DU[i]]); //记录当前的AC编码
}
else
{
get_ac_bits_category(DU[i]);
//中间符号RRRR/SSSS,RRRR表示第非0的AC之前,其值为0的AC个数,SSSS表示AC所需的位数
writebits(HTAC[(nrzeroes << 4) + ACBitCode.length]); //记录huffman编码
writebits(ACBitCode); //记录当前的AC编码
}
#endif
i++;
}
if (end0pos != 63)
writebits(EOB);
}
#ifdef Y_HXV_1X1_DEBUG
/*
function:
read a mcu unit from FIFO
input:
xpos: position of current RGB in width
ypos: position of current RGB in height
output:
None
*/
void load_mcu_data_from_fifo(WORD xpos, WORD ypos)
{
WORD x,y;
BYTE pos = 0;
DWORD location;
location = ypos * Ximage + xpos;
for (y = 0; y < 8; y++)
{
for (x = 0; x < 8; x++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -