⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpegencoder.c

📁 这是一个JPEG程序
💻 C
📖 第 1 页 / 共 5 页
字号:
  	//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 + -