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

📄 jpeg.c

📁 GPRS模组资料包含DEMO
💻 C
📖 第 1 页 / 共 2 页
字号:
	unsigned int i, j;
	unsigned int data[2];
	unsigned int *pointer;

	if(chrominance == 0)
		pointer = (unsigned int *)P_MPEG4_LUMOFFSET_SA;
	else
		pointer = (unsigned int *)P_MPEG4_CHROMOFFSET_SA;

	for(i=0; i<8; i++)
	{
		j = i * 2;
		data[1] = (unsigned int)cs[j + 1];
		data[0] = (unsigned int)cs[j];
		data[1] = data[1] & 0x0000000f;
		data[1] = data[1] << 4;
		data[0] = data[0] & 0x0000000f;
		*pointer++ = data[0] + data[1];
	}
}

//=============================================================
// 语法格式:	void set_jpg_huffman_dcv_reg(int chrominance, unsigned char *cv);
// 实现功能:	填充 DC Huffman值
// 参数:		chrominance,选择亮度还是色度;*cv,DC huffman值
// 返回值:		无
//=============================================================
static void set_jpg_huffman_dcv_reg(int chrominance, unsigned char *cv)
{
	unsigned int *pointer;
	unsigned int i, j;
	unsigned int data[2];

	if(chrominance == 0)
		pointer = (unsigned int *)P_MPEG4_LUMHUFFMANTABLE_START;
	else
		pointer = (unsigned int *)P_MPEG4_CHROMHUFFMANTABLE_START;

	for(i=0; i<8; i++)
	{
		j = i * 2;
		data[1] = (unsigned int)(cv[j+1] & 0x000f);
		data[0] = (unsigned int)(cv[j] & 0x000f);
		data[1] = data[1] << 4;
		*pointer++ = data[0] + data[1];
	}
}

//=============================================================
// 语法格式:	int fill_huffman_reg(unsigned char *jpg_ptr);
// 实现功能:	向SPCE3200填充Huffman表,只能直接填充读出的huffman,需要解开填充
// 参数:		jpg_ptr,指向jpeg数据的指针
// 返回值:		1: 成功;  0: 失败
//=============================================================
static int fill_huffman_reg(unsigned char *jpg_ptr)
{
	unsigned int length, counter, i, index;
	unsigned char word;
	unsigned char *pointer;
	unsigned char *temp_pointer;
	unsigned int cw[16];						// 存储huffman表
	unsigned char cs[16];						// huffman表的相对开始位置
	unsigned char cv[256];						// DC或AC数据
	
	length = get_jpg_segment_length(jpg_ptr);
	
	if(length == 0x1A2)
	{
		counter = 3;
		pointer = jpg_ptr + 3;
		
		for(index=0; index<4; index++)
		{
			for(i=0; i<16; i++)
			{
				cw[i] = 0;
				cs[i] = 0;
			}
			for(i=0; i<256; i++)
			{
				cv[i] = 0;
			}

			Get_Huffman_cs_cw(cs, cw, pointer);
			word = *(pointer - 1);						// Get Huffman table type
			temp_pointer = pointer + 16;				// Shift to the starting point of DiffDC_length or <R, V_length>

			set_Huff_sram_mode(8);						// Set TSramMode = CPU R/W TSRAM Regs and JPEG Decoding
			set_jpg_huffman_cw_reg(word, cw);

			if(word == 0x00)
			{
				length = 0x1c;
				set_jpg_huffman_dcs_reg(0, cs);
				for(i=0; i<16; i++)
				{
					cv[i] = *temp_pointer++;
				}
				set_jpg_huffman_dcv_reg(0, cv);
			}	// YDC
			else if(word == 0x01)
			{
				length = 0x1c;
				set_jpg_huffman_dcs_reg(1, cs);
				for(i=0; i<16; i++)
				{
					cv[i] = *temp_pointer++;
				}
				set_jpg_huffman_dcv_reg(1, cv);
			}	// CDC
			else if(word == 0x10)
			{
				length = 0xb2;
				set_jpg_huffman_acs_reg(0, cs);
				for(i=0; i<(0x40 * 3); i++)
				{
					cv[i] = *temp_pointer++;
				}
				set_jpg_huffman_acv_sram(0, cv);
			}	// YAC
			else if(word == 0x11)
			{
				length = 0xb2;
				set_jpg_huffman_acs_reg(1, cs);
				for(i=0; i<(0x40 * 3); i++)
				{
					cv[i] = *temp_pointer++;
				}
				set_jpg_huffman_acv_sram(1, cv);
			}	// CAC

			pointer = pointer + (length + 1);
			counter = counter + (length + 1);
		}
	}
	else if(length < 0xa0)
	{
		counter = 3;
		pointer = jpg_ptr + 3;

		for(i=0; i<16; i++)
		{
			cw[i] = 0;
			cs[i] = 0;
		}
		for(i=0; i<256; i++)
		{
			cv[i] = 0;
		}

		Get_Huffman_cs_cw(cs, cw, pointer);

		word = *(pointer - 1);							// Get Huffman table type
		temp_pointer = pointer + 16;					// Shift to the starting point of DiffDC_length or <R,V_length>
		
		set_Huff_sram_mode(8);							// Set TSramMode = CPU R/W TSRAM Regs and JPEG Decoding
		set_jpg_huffman_cw_reg(word, cw);

		if(word == 0x00)
		{
			set_jpg_huffman_dcs_reg(0, cs);
			for(i=0; i<16; i++)
			{
				word = *temp_pointer;
				cv[i] = word;
				temp_pointer++;
			}
			set_jpg_huffman_dcv_reg(0, cv);
		}	// YDC
		else if(word == 0x01)
		{
			set_jpg_huffman_dcs_reg(1, cs);
			for(i=0; i<16; i++)
			{
				word = *temp_pointer;
				cv[i] = word;
				temp_pointer++;
			}
			set_jpg_huffman_dcv_reg(1, cv);
		}	// CDC
		else if(word == 0x10)
		{
			set_jpg_huffman_acs_reg(0, cs);
			for(i=0; i<(0x40*3); i++)
			{
				word = *temp_pointer;
				cv[i] = word;
				temp_pointer++;
			}
			set_jpg_huffman_acv_sram(0, cv);
		}	// YAC
		else if(word == 0x11)
		{
			set_jpg_huffman_acs_reg(1, cs);
			for(i=0; i<(0x40*3); i++)
			{
				word = *temp_pointer;
				cv[i] = word;
				temp_pointer++;
			}
			set_jpg_huffman_acv_sram(1, cv);
		}	// CAC
		pointer = pointer + (length - 3);
		counter = counter + (length - 3);
	}
	else
		return 0;
	return 1;
}

//=============================================================
// 语法格式:	void set_mcuno_reg(unsigned char *jpg_ptr);
// 实现功能:	有反转的处理
// 参数:		*jpg_ptr,指向图片地址
// 返回值:		无
//=============================================================
static void set_mcuno_reg(unsigned char *jpg_ptr)
{
	unsigned int mcuno;
	unsigned char word;
	unsigned char* pointer;

	pointer = jpg_ptr + 2;
	word = *pointer;
	mcuno = (unsigned int)word;
	
	*P_MPEG4_RESETMCU_HIGH = mcuno;
	mcuno = mcuno << 8;
	
	pointer++;
	word = *pointer;
	
	mcuno = mcuno + (unsigned int)word;
	*P_MPEG4_RESETMCU_LOW = (unsigned int)word;
}

//=============================================================
// 语法格式:	unsigned int Extract_JPG_Header(unsigned int JPG_SA);
// 实现功能:	解jpeg图片的文件头数据
// 参数:		JPG_SA,指向jpeg数据的指针
// 返回值:		jpeg去除文件头的数据(VLC存储),失败则返回0
//=============================================================
static unsigned int Extract_JPG_Header(unsigned int JPG_SA)
{
	unsigned char *jpg_ptr;
	unsigned int vlc_sa = 0;
	unsigned char word;
	
	jpg_ptr = (unsigned char *)JPG_SA;
	jpg_ptr = find_marker(jpg_ptr);						// find marker
	word = *jpg_ptr;
	
	if(word == 0xd8)									// jpg start marker
	{
		*P_MPEG4_SRAM_EN = 0x00000001;					// turn on sram
	
		while(jpg_ptr)
		{
			jpg_ptr = find_marker(jpg_ptr);
			word = *jpg_ptr++;
			
			if((word > 0xc0) && (word <= 0xcf) && (word != 0xc4))
				return 0;								// I can't decode this JPG file

			switch(word)
			{
				case 0xd9 :								// jpg file end
							jpg_ptr = 0;
							break;
				case 0xdb :								// Quantization table
							fill_quantize_sram(jpg_ptr);
							jpg_ptr = bypass_jpg_segment(jpg_ptr);
							vlc_sa = (unsigned int)jpg_ptr;
							break;
				case 0xc4 :								// Huffman table
							if(fill_huffman_reg(jpg_ptr) == 0)
								return 0;
							jpg_ptr = bypass_jpg_segment(jpg_ptr);
							vlc_sa = (unsigned int)jpg_ptr;
							break;
				case 0xda :								// Start of scan
							jpg_ptr = bypass_jpg_segment(jpg_ptr);
							vlc_sa = (unsigned int)jpg_ptr;
							break;
				case 0xc0 :								// Start of frame
							if(set_jpg_mode(jpg_ptr) == 0)
								return 0;
							jpg_ptr = bypass_jpg_segment(jpg_ptr);
							vlc_sa = (unsigned int)jpg_ptr;
							break;
				case 0xdd :								// Restart_Interval mcu_no
							set_mcuno_reg(jpg_ptr);
							jpg_ptr = (jpg_ptr + 4);
							vlc_sa = (unsigned int)jpg_ptr;
							break;
				case 0x00 :
							jpg_ptr = 0;				// i suppose there is no segment behind the vlc
							break;
				default   :
							jpg_ptr = bypass_jpg_segment(jpg_ptr);
							vlc_sa = (unsigned int)jpg_ptr;
			}
		}
	}// if(word==0xd8) jpg start marker
	return vlc_sa;
}

//=============================================================
// 语法格式:	int JPEG_DepressPicture(void *JPG_SA, void *DestBuf)
// 实现功能:	解jpeg图片
// 参数:		*JPG_SA,要解码图片的首地址
//				*DestBuf,解码后图片的保存位置
// 返回值:		1: 成功;  0: 失败
//=============================================================
int JPEG_DepressPicture(void *JPG_SA, void *DestBuf)
{
	unsigned int vlc_sa;										// 存储去除文件头的地址
	vlc_sa = (unsigned int)JPG_SA;

	*P_MPEG4_QTABLE_CTRL = C_MPEG4_QVALUE_ORIGIN				// 设置量化表
							| C_MPEG4_QSCALE_QTABLE;
	*P_MPEG4_BUFFER_CTRL = C_MPEG4_NORMAL_MODE;
	*P_MPEG4_MODE_CTRL3 = C_MPEG4_SOPTRIG_CPU;
	*P_MPEG4_JFIF_COMPATIBLE = C_MPEG4_JFIF_MODE;				// 兼容JFIF
	*P_MPEG4_TRUNCATE_CTRL = C_MPEG4_QUANTIFY_TRUNCATE;			// 裁减

	if((vlc_sa = Extract_JPG_Header((unsigned int)JPG_SA)) == 0)
		return 0;			// 获取除去文件头的实际地址

	// Decode VLC Bit Stream Starting Offset, Low/Middle/High is Byte Boundard.
	*P_MPEG4_DECVLCOFFSET_SALOW = vlc_sa;
	vlc_sa = vlc_sa >> 8;
	*P_MPEG4_DECVLCOFFSET_SAMID = vlc_sa;
	vlc_sa = vlc_sa >> 8;
	*P_MPEG4_DECVLCOFFSET_SAHIGH = vlc_sa;
	
//	*P_MPEG4_MODE_CTRL2 = 3;

	*P_MPEG4_COMPRESS_CTRL = C_MPEG4_DECODE_START;					// Start decoding

	while((*P_MPEG4_COMPRESS_CTRL & C_MPEG4_DECODE_STATUS) != 0);	// wait for hardware decoder
	
	BLNDMA_YUV2RGB((unsigned int *)MPEG4_W_BUFFER0_SA, (unsigned int *)DestBuf);
	return 1;
}

//=============================================================
// 语法格式:	int Jpeg_Height_Width_Get(unsigned char *jpg_ptr, unsigned int *Height, unsigned int *Width);
// 实现功能:	得到Jpeg图片的高度、宽度
// 参数:		*JPG_SA,要解码图片的首地址;*Height,高度;*Width,宽度
// 返回值:		1: 成功;  0: 失败
//=============================================================
int JPEG_GetPictureSize(void *pImage, unsigned short *Width, unsigned short *Height)
{
	int Ret = 0;
	unsigned char word = 0;
	unsigned short height;
	unsigned short width;
	unsigned char *jpg_ptr;
	
	jpg_ptr = find_marker(pImage);						// find marker
	word = *jpg_ptr;
	
	if(word == 0xd8)									// jpg start marker
	{
		while(jpg_ptr)
		{
			jpg_ptr = find_marker(jpg_ptr);
			word = *jpg_ptr++;
			
			switch(word)
			{
				case 0xc0 :	
					jpg_ptr = jpg_ptr + 3;
					
					word = *jpg_ptr++;
					height = (unsigned short)word << 8;
					word = *jpg_ptr++;
					height += (unsigned short)word;
					
					word = *jpg_ptr++;
					width = (unsigned short)word << 8;
					word = *jpg_ptr++;
					width += (unsigned short)word;
					
					*Height = height;
					*Width = width;
					jpg_ptr = 0;
					Ret = 1;
					break;
				default:
					jpg_ptr = bypass_jpg_segment(jpg_ptr);
					break;
			}
		}
	}
	return Ret;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -