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

📄 saa7113h_api.c

📁 S3C2440 摄像头linux2.4.18的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			return -EIO;		}#endif	} else {		ret = read(cam_fd, cam_buf, cam_buf_size);		if(ret<0) {			fprintf(stderr, "read camera fail!%d\n", ret);			return -EIO;		}		//fprintf(stdout, "read %d bytes\n", i);	}	rgb24 = (format&RGB_FMT_MSK)==RGB24_FLAG;	format &= ~RGB_FMT_MSK;	if(format>=SUB_WIN_NUMBER)		return -EINVAL;	*win = sub_win_pos[format];	if(rgb24)		convert_rgb24_image(buf, format, win);	else		convert_rgb16_image(buf, format, win);	return 0;}#define	YCbCrtoR(Y,Cb,Cr)	(1000*Y + 1371*(Cr-128))/1000#define	YCbCrtoG(Y,Cb,Cr)	(1000*Y - 336*(Cb-128) - 698*(Cr-128))/1000#define	YCbCrtoB(Y,Cb,Cr)	(1000*Y + 1732*(Cb-128))/1000#define	min(x1, x2)			(((x1)<(x2))?(x1):(x2))/*static __inline __u32 Conv_YCbCr_Rgb(__u8 y0, __u8 y1, __u8 cb0, __u8 cr0){	// bit order is	// YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0].	int r0, g0, b0, r1, g1, b1;	__u16 rgb0, rgb1;	__u32 rgb;	#if 1	r0 = YCbCrtoR(y0, cb0, cr0);	g0 = YCbCrtoG(y0, cb0, cr0);	b0 = YCbCrtoB(y0, cb0, cr0);	r1 = YCbCrtoR(y1, cb0, cr0);	g1 = YCbCrtoG(y1, cb0, cr0);	b1 = YCbCrtoB(y1, cb0, cr0);	#endif	if (r0>255 ) r0 = 255;	if (r0<0) r0 = 0;	if (g0>255 ) g0 = 255;	if (g0<0) g0 = 0;	if (b0>255 ) b0 = 255;	if (b0<0) b0 = 0;	if (r1>255 ) r1 = 255;	if (r1<0) r1 = 0;	if (g1>255 ) g1 = 255;	if (g1<0) g1 = 0;	if (b1>255 ) b1 = 255;	if (b1<0) b1 = 0;	// 5:6:5 16bit format	rgb0 = (((__u16)r0>>3)<<11) | (((__u16)g0>>2)<<5) | (((__u16)b0>>3)<<0);	//RGB565.	rgb1 = (((__u16)r1>>3)<<11) | (((__u16)g1>>2)<<5) | (((__u16)b1>>3)<<0);	//RGB565.	rgb = (rgb1<<16) | rgb0;	return(rgb);}*/static __inline __u32 Conv_YCbCr_Rgb16(__u8 y0, __u8 cb0, __u8 cr0, __u8 y1, __u8 cb1, __u8 cr1){	// bit order is	// YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0].	int r0, g0, b0, r1, g1, b1;	__u16 rgb0, rgb1;	__u32 rgb;	r0 = YCbCrtoR(y0, cb0, cr0);	g0 = YCbCrtoG(y0, cb0, cr0);	b0 = YCbCrtoB(y0, cb0, cr0);	r1 = YCbCrtoR(y1, cb1, cr1);	g1 = YCbCrtoG(y1, cb1, cr1);	b1 = YCbCrtoB(y1, cb1, cr1);	if (r0>255 ) r0 = 255;	if (r0<0) r0 = 0;	if (g0>255 ) g0 = 255;	if (g0<0) g0 = 0;	if (b0>255 ) b0 = 255;	if (b0<0) b0 = 0;	if (r1>255 ) r1 = 255;	if (r1<0) r1 = 0;	if (g1>255 ) g1 = 255;	if (g1<0) g1 = 0;	if (b1>255 ) b1 = 255;	if (b1<0) b1 = 0;	// 5:6:5 16bit format	rgb0 = (((__u16)r0>>3)<<11) | (((__u16)g0>>2)<<5) | (((__u16)b0>>3)<<0);	//RGB565.	rgb1 = (((__u16)r1>>3)<<11) | (((__u16)g1>>2)<<5) | (((__u16)b1>>3)<<0);	//RGB565.	rgb = (rgb1<<16) | rgb0;	return(rgb);}static __inline __u32 Conv_YCbCr_Rgb24(__u8 y, __u8 cb, __u8 cr){	int r, g, b;	r = YCbCrtoR(y, cb, cr);	g = YCbCrtoG(y, cb, cr);	b = YCbCrtoB(y, cb, cr);	if (r>255 ) r = 255;	if (r<0) r = 0;	if (g>255 ) g = 255;	if (g<0) g = 0;	if (b>255 ) b = 255;	if (b<0) b = 0;		return (r<<16) | (g<<8) | b;	//RGB888.}static __inline void convert_rgb16_image(void *buf, int format, cam_window_t *win){	__u32 rgb_data;	__u16 x, y, w, h, i, j;	__u32 **buf32 = buf;	__u16 x_skip = win->x_ratio;	__u16 y_skip = win->y_ratio;	w = win->width;	h = win->height;	for(y=win->y0, j=0; j<h; ) {		for(x=win->x0, i=0; i<w; ) {			rgb_data = Conv_YCbCr_Rgb16(line_y[y][x], line_cb[y][x/2], line_cr[y][x/2], 						line_y[y][x+x_skip], line_cb[y][(x+x_skip)/2], line_cr[y][(x+x_skip)/2]);			buf32[j][i/2] = rgb_data;			x += 2 * x_skip;			i += 2;		}		y += y_skip;		j += 1;	}}static __inline void convert_rgb24_image(void *buf, int format, cam_window_t *win){	__u32 rgb_data;	__u16 x, y, w, h, i, j;//	char *buf8 = ((void **)buf)[0];	char **buf8 = buf;	__u16 x_skip = win->x_ratio;	__u16 y_skip = win->y_ratio;	w = win->width;	h = win->height;	for(y=win->y0, j=0; j<h; ) {		for(x=win->x0, i=0; i<w; ) {			rgb_data = Conv_YCbCr_Rgb24(line_y[y][x], line_cb[y][x/2], line_cr[y][x/2]);			buf8[j][i*3]   = rgb_data>>16;			buf8[j][i*3+1] = rgb_data>>8;			buf8[j][i*3+2] = rgb_data;			x += x_skip;			i += 1;			rgb_data = Conv_YCbCr_Rgb24(line_y[y][x], line_cb[y][x/2], line_cr[y][x/2]);			buf8[j][i*3]   = rgb_data>>16;			buf8[j][i*3+1] = rgb_data>>8;			buf8[j][i*3+2] = rgb_data;			x += x_skip;			i += 1;		}		y += y_skip;		j += 1;	}}#ifndef GLOBAL#define	GLOBAL	//defined in jmorecfg.h#endifGLOBAL(void)write_JPEG_file (char *filename, int quality, unsigned short width, unsigned short height){	struct jpeg_compress_struct cinfo; 	struct jpeg_error_mgr jerr;  	/* More stuff */  	FILE * outfile;		/* target file */  	JSAMPROW row_pointer[1];	/* pointer to JSAMPLE row[s] */  	int row_stride;		/* physical row width in image buffer */ 	cinfo.err = jpeg_std_error(&jerr);  	/* Now we can initialize the JPEG compression object. */  	jpeg_create_compress(&cinfo); 	if ((outfile = fopen(filename, "wb")) == NULL)       	{    		fprintf(stderr, "can't open %s\n", filename);    		exit(1);  	} 	jpeg_stdio_dest(&cinfo, outfile); 	cinfo.image_width = width; 	/* image width and height, in pixels */  	cinfo.image_height = height;  	cinfo.input_components = 3;		/* # of color components per pixel */  	cinfo.in_color_space = JCS_RGB; 	/* colorspace of input image */ 	jpeg_set_defaults(&cinfo); 	jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); 	jpeg_start_compress(&cinfo, TRUE); 	row_stride = width * 3;	/* JSAMPLEs per row in image_buffer */  	while (cinfo.next_scanline < cinfo.image_height)       	{   		row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];    		(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);  	}  	/* Step 6: Finish compression */  	jpeg_finish_compress(&cinfo);  	/* After finish_compress, we can close the output file. */ 	fclose(outfile); 	jpeg_destroy_compress(&cinfo);  	/* And we're done! */}int camera_save_picture(int win_idx, char *name, int quality){	int ret;	cam_window_t cam_win;	if(cam_win_p!=(sub_win_pos + win_idx)) {		int i;		if(win_idx>=SUB_WIN_NUMBER) {			return -EINVAL;		}		cam_win_p = sub_win_pos + win_idx;		for(i=0; i<cam_win_p->width; i++)			image_line[i] = image_buffer + 3 * i * cam_win_p->width;		fprintf(stdout, "set image width %d, height %d\n", cam_win_p->width, cam_win_p->height);	}	ret = camera_output_lines(image_line, win_idx | RGB24_FLAG, &cam_win);	if(ret==0) {		write_JPEG_file(name, quality, cam_win_p->width, cam_win_p->height);	}	return ret;}/*************************************************************/int capture_img_init(void){	int rdfd;	rdfd = camera_open(S3C2440A);	if(rdfd>=0) {/*		cam_window_t cam_win;		// user defined window		cam_win.x0      = 40;		cam_win.y0      = 72;		cam_win.x1      = 680;		cam_win.y1      = 552;		cam_win.x_ratio = 2;		cam_win.y_ratio = 2;		camera_set_window(&cam_win);*/				camera_start(CAMERA_VIDEO);	//video	}	return rdfd;}int capture_img_destroy(void){	camera_stop();	camera_close();	return 0;}int capture_img_bymode(int win_idx, int *w, int *h){	int ret;	fd_set rfds;	cam_window_t cam_win;	struct timeval tv;	if(cam_fd<0)		return -ENODEV;	ret = camera_get_window(win_idx, &cam_win);	if(ret)		return ret;	*w = cam_win.width;	*h = cam_win.height;	FD_ZERO(&rfds);	//FD_SET(0, &rfds);	FD_SET(cam_fd, &rfds);	if(camera_capture()<0)		return -EIO;	tv.tv_sec = 3;	tv.tv_usec = 0;	select(cam_fd+1, &rfds, NULL,  NULL, &tv);	if(FD_ISSET(cam_fd, &rfds)) {		fprintf(stdout, "camera input\n");		if(camera_save_picture(win_idx, "jpgfile.jpg", 75)<0) {			fprintf(stderr, "capture fail!\n");			return -EIO;		}	} else {		fprintf(stderr, "wait timeout, break...\n");		return -EIO;	}	return 0;}/*************************************************************/static int   fb_fd  = -1;static int   fb_xres;static int   fb_yres;static int   fb_bpp;static char *fb_buf = NULL;static int   fb_buf_size;static char *fb_line[1024];static int open_fb(void);static int close_fb(void);static void fill_screen(int color){	int x, y;		for(y=0; y<fb_yres; y++)		for(x=0; x<fb_xres; x++)			((__u16 *)fb_buf)[y*fb_xres+x] = color;//	memset(fb_buf, 0, fb_buf_size);}static int open_fb(void){	int i;	struct fb_var_screeninfo vinfo;	struct fb_fix_screeninfo finfo;	fb_fd = open("/dev/fb0", O_RDWR);	if (fb_fd < 0) {		fb_fd = open("/dev/fb/0", O_RDWR);		if(fb_fd<0) {			fprintf(stderr, "fail to open framebuffer device!\n");		        return -ENODEV;		}	}	// Get fixed screen information	if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo)) {		fprintf(stderr, "fail to get framebuffer device fixed information!\n");		close_fb();		return -EIO;	}	// Get variable screen information	if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo)) {		fprintf(stderr, "fail to get variable information!\n");		close_fb();		return -EIO;	}	fprintf(stdout, "w:%4d, h:%4d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );	fb_xres = vinfo.xres;	fb_yres = vinfo.yres;	fb_bpp  = vinfo.bits_per_pixel;	fb_buf_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;	fb_buf      = (char *)mmap(0, fb_buf_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);	if ((int)fb_buf==-1) {		fprintf(stderr, "fail to map framebuffer device!\n");		fb_buf = NULL;		close_fb();		return -ENOMEM;	}	for(i=0; i<vinfo.yres; i++)		fb_line[i] = fb_buf + i * vinfo.xres * vinfo.bits_per_pixel / 8;//	printf("fb base %08x\n", fb_line[0]);	fill_screen(0);	return fb_fd;}static int close_fb(void){	if(fb_fd>=0) {		if(fb_buf!=NULL)			munmap(fb_buf, fb_buf_size);		fb_buf = NULL;		close(fb_fd);		fb_fd = -1;	}	return 0;}/*************************************************************/#ifdef MAIN_TEST#if 1static int change_window(int win_fmt, cam_window_t *win){	if(camera_get_window(win_fmt, win))		return 0;	fprintf(stdout, "set window format %d:\n", win_fmt);	fprintf(stdout, "x0=%d, y0=%d, x1=%d, y1=%d, real width=%d, height=%d\n", 			win->x0, win->y0, win->x1, win->y1,	win->width, win->height);	fill_screen(0x001f);	return win->width<=fb_xres && win->height<=fb_yres;}int main(int argc, char *argv[]){	int rdfd;	fd_set rfds;	cam_window_t cam_win;	struct timeval tv;	struct termios tio;	int c_lflag;	int show, cnt, win_fmt;	if(open_fb()<0) {		return -1;	}	rdfd = camera_open(S3C2440A);	if(rdfd<0) {		close_fb();		return -1;	}	//puts("press enter to start...\n");	//getchar();		if(tcgetattr(0, &tio)<0) {		fprintf(stderr, "tcgetattr fail!\n");		goto fail;	} else {		c_lflag = tio.c_lflag;		tio.c_lflag &= ~(ICANON | ECHO);		if(tcsetattr(0, TCSAFLUSH, &tio)<0) {			fprintf(stderr, "tcsetattr fail!\n");			goto fail;		}	}/*	// user defined window	cam_win.x0      = 40;	cam_win.y0      = 72;	cam_win.x1      = 680;	cam_win.y1      = 552;	cam_win.x_ratio = 2;	cam_win.y_ratio = 2;	camera_set_window(&cam_win);*/		win_fmt = SUBWIN_M;	if(argc>1)		win_fmt = atoi(argv[1]);	show = change_window(win_fmt, &cam_win);	cnt = 0;		fprintf(stdout, "now start capture...\n");	fprintf(stdout, "press Esc key to exit, 'c' to save picture, '+'/'-' to switch window\n");	FD_ZERO(&rfds);	//FD_SET(0, &rfds);	//FD_SET(rdfd, &rfds);	camera_start(CAMERA_VIDEO);	//video	while(1) {		if(camera_capture()<0)			break;		//FD_ZERO(&rfds);		FD_SET(0, &rfds);		FD_SET(rdfd, &rfds);		tv.tv_sec = 3;		tv.tv_usec = 0;		select(rdfd+1, &rfds, NULL,  NULL, &tv);		if(FD_ISSET(0, &rfds)) {			char cmd;			//fprintf(stdout, "stdin input\n");			if(read(0, &cmd, 1)<0) {				fprintf(stderr, "read stdin fail!\n");				break;			}			//fprintf(stdout, "0x%4x\n", cmd);			if(cmd=='+') {				win_fmt++;				if(win_fmt>WINDOW_INDEX_LAST)					win_fmt = 0;				show = change_window(win_fmt, &cam_win);			} else if(cmd=='-') {				win_fmt--;				if(win_fmt<0)					win_fmt = WINDOW_INDEX_LAST;				show = change_window(win_fmt, &cam_win);			} else if(cmd=='i'||cmd=='I') {			} else if(cmd=='j'||cmd=='J') {				if(win_fmt==SUBWIN_USER) {					camera_get_window(SUBWIN_USER, &cam_win);					if(cam_win.x0>=2){						cam_win.x0 -= 2;						cam_win.x1 -= 2;						camera_set_window(&cam_win);						show = change_window(win_fmt, &cam_win);					}				}			} else if(cmd=='k'||cmd=='K') {			} else if(cmd=='l'||cmd=='L') {				if(win_fmt==SUBWIN_USER) {					camera_get_window(SUBWIN_USER, &cam_win);					if(cam_win.x1<=718){						cam_win.x0 += 2;						cam_win.x1 += 2;						camera_set_window(&cam_win);						show = change_window(win_fmt, &cam_win);					}				}			} else if(cmd=='d'||cmd=='D') {			//	show = !show;			//	fprintf(stdout, "%s display\n", show?"enable":"disable");			} else if(cmd=='c'||cmd=='C') {				fprintf(stdout, "save picture...\n");				if(camera_save_picture(win_fmt, "image.jpg", 75)<0)					fprintf(stdout, "fail!\n");			} else if(cmd==0x1b)	//Esc				break;		} else if(FD_ISSET(rdfd, &rfds)) {			//fprintf(stdout, "camera input\n");			if(show) {				if(camera_output_lines(fb_line, win_fmt, &cam_win)<0)					break;				cnt++;			}		} else {			fprintf(stdout, "wait timeout, break...\n");			break;		}	}	camera_stop();	tio.c_lflag = c_lflag;	tcsetattr(0, TCSAFLUSH, &tio);fail:	camera_close();	close_fb();	return 0;}#elseint main(int argc, char *argv[]){	int ch, w, h, m;	if(capture_img_init()<0) {		puts("innitialize camera fail!");		return -1;	}		m = WINDOW_SCALE2;	while(1) {		puts("Press Esc to exit, 'm' to switch window mode, 'c' to capture image...");		ch = getchar();		if(ch==0x1b) {			puts("exit...");			break;		}		if(ch=='c'||ch=='C') {			if(capture_img_bymode(m, &w, &h)) {				puts("save picture fail!");				break;			}			printf("get image w:%d, h:%d.\n", w, h);		} else if(ch=='m'||ch=='M') {			if(m==WINDOW_SCALE2)				m = WINDOW_FULL;			else				m = WINDOW_SCALE2;			printf("switch to %s window mode.\n", (m==SUBWIN_M)?"small":"large");		}	}	capture_img_destroy();	return 0;}#endif#endif	/* MAIN_TEST */

⌨️ 快捷键说明

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