www.pudn.com > jpeg_thread.rar > jpeg_thread.c


#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
//#include "jpeglib.h" 
#include "gpsserver.h" 
#include "sudp_linux.h" 
#include  
#include  
#include "main.h" 
#include  
 
 
#define GPECON 0x56000040 
#define GPE11 0xb 
 
 
#define BUF_SIZE 1024*1024 
#define IMAGE_SIZE 256*720 //YUV像素大小 
#define byte unsigned char  
static unsigned char image_buffer[256*720*2]; 
int alarmmark=0;//报警信号位,0为无报警,1为有报警(发送数据接口用) 
 
/********************************************** 
包头定义:0x42 0x4d:B M(2字节) 
	文件大小:256*720*3+54=553014=0x87036(4个字节) 
	4个字节保留,值为0// 
	4个字节表示第一个像素的偏移量(54=0x36) 
	4 个字节存放文件信息头的长度 ,其值为 40=0x28 
	4 个字节存放位图的宽度720=0x2D0 
	4 个字节存放位图的高度256=0x100 
	2 个字节存放平面的数目 ,其值为 1 
	2 个字节存放每个像素所占的位数 ,24=0x18 
	4 个字节指定位图是否压缩,0// 
	4 个字节表示位图的实际大小,文件大小-包头(54),0x87000 
	4 个字节指定目标设备的水平分辨率 ,通常不用将其设为 0。 
	4 个字节指定目标设备的垂直分辨率 ,通常不用将其设为 0。 
	4 个字节指定图像实际用到的颜色数 ,若使用所有颜色则值为 0 
	4 个字节指定图像中重要的颜色数 ,若全部重要则值为 0 
********************************************/ 
unsigned char head[54]={0x42,0x4d,0x36,0x70,0x08,0,0,0,0,0,   //10 
	0x36,0,0,0,0x28,0,0,0,0xd0,0x2,0,0,0x00,0x1,0,0,0x1,0,0x18,0,0,0,0,0,//24 
	0,0x70,0x8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //20 
 
int WriteJPEG(void); 
void InitGPIO(); 
void GetFromSram();  
void 	GetPictrue(void); 
inline byte ADJUST(double ); 
void YUV_BMP24(); 
 
int * firstthread(void *); 
int * secondthread(void *); 
 
pthread_t firstid,secondid; 
 
int main() 
{	 
	InitGPIO(); 
	 /******************创建线程***************/   
	if(pthread_create(&firstid, NULL, (void *)firstthread, NULL) != 0) //创建线程1,用于侦听服务器下行命令 
	{ 
		printf("thread creation failed\n"); 
		exit(1); 
	} 
 
	if(pthread_create(&secondid, NULL, (void *)secondthread, NULL) != 0) //创建线程2,用于每30秒发送心跳 
	{ 
		printf("thread creation failed\n"); 
		exit(1); 
	} 
	 
	pthread_exit(0);   
	printf("this is end"); 
} 
 
int * firstthread(void * arg) 
{ 
		GetPictrue();	 
} 
int * secondthread(void * arg) 
{ 
		while(1) 
		{ 
			printf("this is secondthread\n "); 
			sleep(3); 
		} 
} 
 
/************************************************************** 
函数说明:JPEG压缩,压缩当前文件夹的bmp图像,有待改进 
******************************************************************/ 
int WriteJPEG(void) 
{ 
		pid_t pid; 
		int i; 
	  char *argv[]={"cjpeg","-quality","25","-outfile","/version_w/pic.jpg","/version_w/pic.bmp",(char *)0}; 
	  if((pid=fork())==-1) 
		{ 
			printf("Error in fork\n"); 
			exit(1); 
 		} 
 	 	if(pid==0)   //子进程 
 		{ 
 			if(i=execv("/version_w/cjpeg",argv)<0) 
	  	{ 
	  		printf("\n cjpeg error. \n"); 
	  		perror("cjpeg error"); 
	  	}   
		} 
} 
/****************************************************************************************** 
函数说明:拍照函数 
ARM通过上拉GPE11通知FPGA采集图片;FPGA通过上拉GPG2(EINT9)通知ARM采集完一帧, 
ARM从SRAM中读数据,并调用压缩处理模块,GPE11复位 
*******************************************************************************************/ 
void 	GetPictrue(void) 
{ 
	unsigned long *sp; 
	unsigned long gpioaddress; 
	int memfd; 
/*	gpioaddress=0x56000000; 
	alarmmark=1;//置报警信息位 
	memfd=open ("/dev/mem",O_RDWR);	 
	sp=(unsigned long *)mmap(0,10000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,gpioaddress); 
	*(unsigned long*)(sp+rGPEDAT) |=0x0800; //拉高GPE11 
 
	munmap(sp,10000); 
	close(memfd);	 
	while(1) 
	{ 
		sleep(1); 
		memfd=open ("/dev/mem",O_RDWR);	 
	  sp=(unsigned long *)mmap(0,10000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,gpioaddress); 
		if((*(unsigned long*)(sp+rGPGDAT))&&0x2)//等待GPG1电平拉高 
		{ 
			*(unsigned long*)(sp+rGPEDAT) &=0xf7ff;     //拉低 
			munmap(sp,10000); 
			close(memfd);				 
*/    
			int t; 
	   	unsigned long  p[2]; 
/*	   	 
	   	t=open("/dev/gpio",O_RDWR | O_NOCTTY); 
	   	if (t < 0) 
	   	{ 
	      printf("can not open led!\n"); 
			  perror("open /dev/gpio "); 
	  	} 
   
		 	p[0]=GPECON;  //GPJCON 
		 	p[1]=GPE11; 
		  
		  write(t,p,0); 
		 	write(t,p,1);sleep(1); 
		 	write(t,p,0); 
		 	close(t); 
		 	printf("3333333\n"); 
	*/ 
			GetFromSram(); 
			printf("111111111\n"); 
			YUV_BMP24(); 
			printf("2222222\n"); 
	 
			WriteJPEG(); 
			printf("4444444\n"); 
	//		send_cf(man_number); 
//			alarmmark=0;//发送完就复位报警信息位 
	 
	//		send_pp(); 
	//		pthread_mutex_lock(&ftp_mutex); 
	//		FtpPic(); //图片上传 
	//		pthread_mutex_unlock(&ftp_mutex); 
//			munmap(sp,10000); 
//			close(memfd); 
//			break; 
//		} 
//	} 
 
} 
 
 
/****************************************************************************************** 
函数说明:从指定地址的SRAM中读取图像数据,存在imagebuff,低位存低字节,高位存高字节 
*******************************************************************************************/ 
void GetFromSram() 
{ 
//	int i,j,fd,bufsize; 
	int i,j,bufsize; 
	int k=0; 
	int memfd; 
	unsigned short *sp1; 
	unsigned long sramaddress; 
	size_t size; 
	 
	memset(image_buffer,0,sizeof(image_buffer)); 
	size = getpagesize(); 
	bufsize=BUF_SIZE; 
	sramaddress=0x8000000;	 
	 
	memfd=open ("/dev/mem",O_RDWR);	 
	 
	sp1=(unsigned short *)mmap(0,((bufsize/size)+1)*size,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,sramaddress); 
	 
	for(i=0;i<256;i++)// 从内存读到imagebuff 
		for(j=0;j<720;j++) 
		{ 
			*(unsigned short*)&image_buffer[k]=*(unsigned short *)(sp1+1024*i+j);	 
			k=k+2; 
		} 
	munmap(sp1,bufsize); 
	close(memfd);	 
} 
/****************************************************************************************** 
YUV422-->BMP24的数据转换,并生成BMP文件(还没添加BMP文件头56字节) 
*******************************************************************************************/ 
inline byte ADJUST(double tmp)  
{  
	return (byte)((tmp >= 0 && tmp  <= 255)?tmp:(tmp  < 0 ? 0 : 255));  
}  
 
 
void YUV_BMP24() 
{ 
	int i,j,size;  
	unsigned char temp; 
	unsigned char write_buffer[256*720*3]; 
	unsigned char file_buffer[256*720*3+54]; 
	FILE *output_file; 
	byte Y1,Y2,U,V;  
	 
	char out_file[]="/version_w/pic.bmp"; //此处应申明为宏定义或全局变量,作为输出文件的目录,与JPEG压缩对应	 
	size=256*720*2; 
	 
	memset(write_buffer,0,sizeof(write_buffer));  
	memset(file_buffer,0,sizeof(file_buffer)); 	 
	for(i=0;i<(size/4)+1;i=i+1) 
	{ 
		/***一个宏像素里4个字节,有4个Y分量,2个U分量,2个V分量,Y:U:V=4:2:2,** 
		*****Y0 U0 Y1 V0 Y2 U2 Y3 V2,4个字节-->6个字节********************/ 
		/**************RGB24在内存中的存放顺序BGR,BGR,...*********/ 
			 
		Y1=image_buffer[4*i+1]; 
		Y2=image_buffer[4*i+3]; 
		U=image_buffer[4*i]; 
		V=image_buffer[4*i+2]; 
					 
		write_buffer[6*i]   = ADJUST((Y1+ (1.772 * (U - 128))));    //B1 
		write_buffer[6*i+1] = ADJUST((Y1 - (0.34414 * (U - 128) - 0.71414 * (V - 128))));  //G1 
		write_buffer[6*i+2] = ADJUST((Y1 + (1.402 * (V - 128))));  //R1 
		 
		write_buffer[6*i+3] = ADJUST((Y2+ (1.772 * (U - 128))));	//B2 
		write_buffer[6*i+4] = ADJUST((Y2 - (0.34414 * (U - 128) - 0.71414 * (V - 128))));  //G2 
		write_buffer[6*i+5] = ADJUST((Y2 + (1.402 * (V - 128)))); //R2 
	} 
	 
	/***********BMP图像数据按逆序存储**************/ 
	for(i=0;i<128;i++) 
		for(j=0;j<720*3;j++) 
		{ 
			temp=write_buffer[j+720*3*i]; 
			write_buffer[j+720*3*i]=write_buffer[j+720*3*(256-i-1)]; 
			write_buffer[j+720*3*(256-i-1)]=temp;			 
		} 
	/*********** 连接BMP头部,并生成BMP文件**************/	 
/*********** 效率太低,怎么把两文件直接连接?**************/	 
	for(i=0;i<54;i++) 
	{ 
			file_buffer[i]=head[i]; 
	} 
	 
	for(i=0;i<256*720*3;i++)    
	{ 
		file_buffer[54+i]=write_buffer[i]; 
	} 
	 
	if((output_file = fopen(out_file,"wb"))==NULL) 
	{ 
  		fprintf(stderr, "cannot open the %s\n", out_file); 
  		exit(0); 
	}	 
//	printf("before write\n"); 
	fwrite(file_buffer,sizeof(unsigned char),(256*720*3+54),output_file); 
	fclose(output_file); 
} 
 
/****************************************************************************************** 
函数说明:配置各端口控制寄存器,初始化各数据寄存器 
*******************************************************************************************/ 
void InitGPIO() 
{ 
	int memfd; 
	unsigned long *sp,sp1;	 
	 
//	unsigned long address; 
//	address=0x56000000; 
	/****************配置BWSCON,Determine data bus width for bank 1,16bit**************/		 
	memfd=open ("/dev/mem",O_RDWR);	 
	sp1=(unsigned long *)mmap(0,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,0x48000000); 
//	printf("memory control register old %x\n",*(unsigned long *)(sp1)); 
	*(unsigned long *)(sp1)=0x2211d110; 
//	printf("memory control register new %x\n",*(unsigned long *)(sp1)); 
	munmap(sp1,0x1000); 
	close(memfd);	 
	 
/**************配置GPE端口,其中GPE11为output,FPGA要求****************/ 
	memfd=open ("/dev/mem",O_RDWR);		 
	sp=(unsigned long *)mmap(0,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,0x56000000); 
	*(unsigned long*)(sp+rGPECON) &=0xff7fffff; 
	*(unsigned long*)(sp+rGPECON) |=0x400000; 
	*(unsigned long*)(sp+rGPEDAT) &=0xf7ff;     //拉低 
	 
	 
/***************配置GPG1(EINT9)为input******************/ 
	*(unsigned long*)(sp+rGPGCON) &=0xfffffff3; 
	 
/**********************************GPH9做为系统自检成功后的亮灯标识************/ 
	*(unsigned long*)(sp+rGPHCON) &=0x37ffff; 
	*(unsigned long*)(sp+rGPHCON) |=0x40000; 
	*(unsigned long*)(sp+rGPHDAT) &=0x5ff;     //拉低点亮GPH9 
	munmap(sp,0x1000); 
	close(memfd);	 
}