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

📄 jpegencoder.c

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