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

📄 qcset.c

📁 Webcam Linux driver for Quickcam
💻 C
📖 第 1 页 / 共 2 页
字号:
/* }}} *//* {{{ [fold] void pnm_close(void) */void pnm_close(void){	fclose(pnm_file);	pnm_file = NULL;}/* }}} *//* {{{ [fold] void pnm_getpixel(unsigned char *r, unsigned char *g, unsigned char *b) */void pnm_getpixel(unsigned char *r, unsigned char *g, unsigned char *b){	*r = getc(pnm_file);	*g = getc(pnm_file);	*b = getc(pnm_file);}/* }}} *//* {{{ [fold] void compute_lut(unsigned int (*hist)[256], unsigned char (*lut)[256]) *//* Compute lookup-table `lut' (256 elements) for image equalization * based on given image color histogram `hist'. The LUT is also smoothed and normalized. */void compute_lut(unsigned int (*hist)[256], unsigned char *lut){	static const int len = 64;			/* Smoothing kernel length, must be less than 255 */	static const double p = 3.0 - 1;		/* Smoothing kernel order */	unsigned int sum;	double dlut[256];	double min, max;	double norm, v, r;	int i,j;	/* Compute lookup-table based on the histogram */	sum = 0;	for (i=0; i<256; i++) {		dlut[i] = sum;		sum += (*hist)[i];	}	/* Normalize lookup-table */	norm = 255.0 / dlut[255];	for (i=0; i<256; i++) {		dlut[i] *= norm;	}	/* Compute normalization factor for smoothing kernel */	norm = 0.0;	for (j=-len; j<=len; j++) {		norm += pow(j+len, p) * pow(len-j, p);	}	norm = 1.0 / norm;	/* Smooth the lookup table, handle edges with point-symmetric reflections */	min = dlut[0];	max = dlut[255];	for (i=0; i<256; i++) {		r = 0.0;		for (j=-len; j<=len; j++) {			int x = i + j;			if (x<0) {				v = min - dlut[-x];			} else if (x>255) {				v = 2*max - dlut[511-x];			} else {				v = dlut[x];			}			r += v * norm * pow(j+len, p) * pow(len-j, p);		}		lut[i] = (unsigned char)CLIP(r+0.5, 0.0, 255.0);	}}/* }}} *//* {{{ [fold] main() */int main(int argc, char *argv[]){	int fd = 0,i,j,r,l,l2,c;	char *device = "/dev/video0";		/* Default should not be /dev/video which may be subdir */	char *argp;	struct video_capability vidcap;	struct video_window vidwin;	struct video_channel vidchan;	struct video_picture vidpic;	if (argc<=1) help();	if (argv && argv[0]) progname = argv[0];	if (argv && argv[0] && argv[1] && argv[1][0]=='-' && argv[1][1]=='h')		help();	while (*++argv) {		if (argv[0][0]=='/' || argv[0][0]=='.') {			/* Device filename given */			if (fd) close(fd);			device = argv[0];			fd = 0;		} else {			if (fd==0			    && (argv[0][0]!='-' && argv[0][1]!='G')			    ) {				/* Open the device, if it wasn't yet opened.				 * Do not try to modify any settings, because if other applications have				 * already the camera open and are capturing, it might disturb them under 2.6.x */				fd = open(device,O_RDWR);	if (fd==-1) error("can not open %s",device);				r = ioctl(fd, VIDIOCGCAP, &vidcap);	if (r != 0) error("ioctl VIDIOCGCAP");				r = ioctl(fd, VIDIOCGWIN, &vidwin);	if (r != 0) error("ioctl VIDIOCGWIN");				vidchan.channel = 0;				r = ioctl(fd, VIDIOCGCHAN, &vidchan);	if (r != 0) error("ioctl VIDIOCGCHAN");				r = ioctl(fd, VIDIOCGPICT, &vidpic);	if (r != 0) error("ioctl VIDIOCGPICT");			}			if (argv[0][0]=='-') {				/* Option given */				argp = NULL;				c = 0;				if (argv[0][1] && argv[0][2]) {					argp = &argv[0][2];				} else {					if (argv[1]) {						argp = argv[1];						c = 1;					}				}				i = argp ? atoi(argp) : 0;				switch (argv[0][1]) {				case 'h':	/* Help */					help();					/* Never returns */				case 'i':	/* Information */					print_cap(&vidcap,&vidwin,&vidchan,&vidpic);					break;				case 'r':	/* Dump known chip registers */					print_regs(fd, 0);					break;				case 'a':	/* Dump all chip registers */					print_regs(fd, 1);					break;				case 'b':	/* Brightness */					if (!argp) error("missing brightness value");					vidpic.brightness = i;					r = ioctl(fd, VIDIOCSPICT, &vidpic);					if (r!=0) error("ioctl VIDIOCSPICT");					argv += c;					break;				case 'u':	/* Hue */					if (!argp) error("missing hue value");					vidpic.hue = i;					r = ioctl(fd, VIDIOCSPICT, &vidpic);					if (r!=0) error("ioctl VIDIOCSPICT");					argv += c;					break;				case 'o':	/* Color */					if (!argp) error("missing color value");					vidpic.colour = i;					r = ioctl(fd, VIDIOCSPICT, &vidpic);					if (r!=0) error("ioctl VIDIOCSPICT");					argv += c;					break;				case 'c':	/* Contrast */					if (!argp) error("missing contrast value");					vidpic.contrast = i;					r = ioctl(fd, VIDIOCSPICT, &vidpic);					if (r!=0) error("ioctl VIDIOCSPICT");					argv += c;					break;				case 'w':	/* Whiteness */					if (!argp) error("missing whiteness value");					vidpic.whiteness = i;					r = ioctl(fd, VIDIOCSPICT, &vidpic);					if (r!=0) error("ioctl VIDIOCSPICT");					argv += c;					break;				case 's':	/* Shutter */					if (!argp) error("missing shutter value");					r = ioctl(fd, VIDIOCQCSSHUTTERVAL, &i);					if (r!=0) error("ioctl VIDIOCQCSSHUTTERVAL");					argv += c;					break;				case 'g':				case 'e': {					struct qc_userlut userlut;					memset(&userlut, 0, sizeof(userlut));					if (!argp) error("missing parameter to option `-%c'", argv[0][1]);					switch (argp[0]) {					case '?':		/* Display software lut settings */						userlut.flags |= QC_USERLUT_VALUES;						r = ioctl(fd, VIDIOCQCGUSERLUT, &userlut);						if (r!=0) error("ioctl VIDIOCGUSERLUT");						printf("Software lookup-table status: %s\n", (userlut.flags & QC_USERLUT_ENABLE) ? "Enabled" : "Disabled");						printf("\tRed table:\n");						for (i=0; i<256; i++) {							printf("%i", userlut.lut[QC_LUT_RED + i]);							if (i!=255) printf(",");							if (((i+1) % 20)==0 || i==255) printf("\n");						}						printf("\tGreen table:\n");						for (i=0; i<256; i++) {							printf("%i", userlut.lut[QC_LUT_GREEN + i]);							if (i!=255) printf(",");							if (((i+1) % 20)==0 || i==255) printf("\n");						}						printf("\tBlue table:\n");						for (i=0; i<256; i++) {							printf("%i", userlut.lut[QC_LUT_BLUE + i]);							if (i!=255) printf(",");							if (((i+1) % 20)==0 || i==255) printf("\n");						}						break;					case '+':		/* Enable lookup-table */						userlut.flags |= QC_USERLUT_ENABLE;						/* Continue */					case '-':		/* Disable lookup-table */						r = ioctl(fd, VIDIOCQCSUSERLUT, &userlut);						if (r!=0) error("ioctl VIDIOCSUSERLUT");						break;					default:						switch (argv[0][1]) {						case 'g': {	/* Gamma */							double gr = 0.55;							double gg = 0.55;							double gb = 0.55;							double wr = 1.0;							double wg = 1.0;							double wb = 1.0;							r = sscanf(argp, "%lg:%lg:%lg:%lg:%lg:%lg", &gr, &gg, &gb, &wr, &wg, &wb);							if (r!=1 && r!=3 && r!=6) error("bad number of arguments for -g (must be 1, 3, or 6)");							if (r < 3) {								gg = gr;								gb = gr;							}							for (i=0; i<256; i++) {								userlut.lut[QC_LUT_RED   + i] = (unsigned char)CLIP(pow(i/256.0, gr)*256.0*wr+0.5, 0.0, 255.0);								userlut.lut[QC_LUT_GREEN + i] = (unsigned char)CLIP(pow(i/256.0, gg)*256.0*wg+0.5, 0.0, 255.0);								userlut.lut[QC_LUT_BLUE  + i] = (unsigned char)CLIP(pow(i/256.0, gb)*256.0*wb+0.5, 0.0, 255.0);							}							userlut.flags |= QC_USERLUT_ENABLE | QC_USERLUT_VALUES;							r = ioctl(fd, VIDIOCQCSUSERLUT, &userlut);							if (r!=0) error("ioctl VIDIOCSUSERLUT");						}						case 'e': {	/* Static equalization */							unsigned int width, height;							unsigned char r, g, b;							unsigned int cnt_red[256], cnt_green[256], cnt_blue[256];							memset(cnt_red,   0, sizeof(cnt_red));							memset(cnt_green, 0, sizeof(cnt_green));							memset(cnt_blue,  0, sizeof(cnt_blue));							pnm_open(argp, &width, &height);							/* Compute histograms for each color channel */							for (i=0; i<height; i++) for (j=0; j<width; j++) {								pnm_getpixel(&r, &g, &b);								cnt_red  [r]++;								cnt_green[g]++;								cnt_blue [b]++;							}							pnm_close();							/* Compute lookup tables based on the histograms */							compute_lut(&cnt_red,   &userlut.lut[QC_LUT_RED]);							compute_lut(&cnt_green, &userlut.lut[QC_LUT_GREEN]);							compute_lut(&cnt_blue,  &userlut.lut[QC_LUT_BLUE]);							/* Send the new lookup table to the driver */							userlut.flags |= QC_USERLUT_ENABLE | QC_USERLUT_VALUES;							r = ioctl(fd, VIDIOCQCSUSERLUT, &userlut);							if (r!=0) error("ioctl VIDIOCSUSERLUT");							break;						}						default:							error("this can't happen");						}					}					argv += c;					break;				}				case 'G': {				  struct qc_userlut userlut;				  double gr = 0.55;				  double gg = 0.55;				  double gb = 0.55;				  double wr = 1.0;				  double wg = 1.0;				  double wb = 1.0;				  if(!argp) error("Missing r:g:b:r:g:b options");				  				  memset(&userlut, 0, sizeof(userlut));				  r = sscanf(argp, "%lg:%lg:%lg:%lg:%lg:%lg", &gr, &gg, &gb, &wr, &wg, &wb);				  if (r!=1 && r!=3 && r!=6) error("bad number of arguments for -G (must be 1, 3, or 6)");				  if (r < 3) {				    gg = gr;				    gb = gr;				  }				  for (i=0; i<256; i++) {				    userlut.lut[QC_LUT_RED   + i] = (unsigned char)CLIP(pow(i/256.0, gr)*256.0*wr+0.5, 0.0, 255.0);				    userlut.lut[QC_LUT_GREEN + i] = (unsigned char)CLIP(pow(i/256.0, gg)*256.0*wg+0.5, 0.0, 255.0);				    userlut.lut[QC_LUT_BLUE  + i] = (unsigned char)CLIP(pow(i/256.0, gb)*256.0*wb+0.5, 0.0, 255.0);				  }				  				  printf("Software lookup-table status: %s\n", (userlut.flags & QC_USERLUT_ENABLE) ? "Enabled" : "Disabled");				  printf("static unsigned char userlut_contents[QC_LUT_SIZE] = {\n/* Red */\n");				  for (i=0; i<256; i++) {				    printf("%4i,", userlut.lut[QC_LUT_RED + i]);				    if (((i+1) % 12)==0) printf("\n");				    if (i==255) printf("\n");				  }				  printf("/* Green */\n");				  for (i=0; i<256; i++) {				    printf("%4i,", userlut.lut[QC_LUT_GREEN + i]);				    if (((i+1) % 12)==0) printf("\n");				    if (i==255) printf("\n");				  }				  printf("/* Blue */\n");				  for (i=0; i<256; i++) {				    printf("%4i", userlut.lut[QC_LUT_BLUE + i]);				    if (i!=255) printf(",");				    if (((i+1) % 12)==0) printf("\n");				    //if (i==255) printf("\n");				  }				  printf("\n};\n");				  exit(0);				}				default:					error("invalid option");				}			} else {				/* Configuration given */				for (l=0; argv[0][l]!=0 && argv[0][l]!='=' && argv[0][l]!='?'; l++);				for (i=0; i<SIZE(ioctlinfo); i++) {					if (memcmp(ioctlinfo[i].name, argv[0], MIN(l,strlen(ioctlinfo[i].name)))==0)						break;				}				if (i>=SIZE(ioctlinfo)) error("invalid configuration name");				if(!strncmp(argv[0], "reg", 3)) {				  int add, val;				  if(sscanf(argv[0], "reg%X=%X", &add, &val) == 2) {				    printf("set reg%X = %X", add, val);				    add &= 0xFFFF;				    add |= ((val & 0xFFFF) << 16);				    printf("add = %08X\n", add);				    r = ioctl(fd, VIDIOCQCSSTV, &add);				    if (r != 0) error("error\n");				    else printf("\n");				  } else if(sscanf(argv[0], "reg%X", &add) == 1) {				    printf("get reg%X = ", add);				    r = ioctl(fd, VIDIOCQCGSTV, &add);				    if (r != 0) error("error\n");				    else {				      printf(" %02X\n", add >> 16);				    }				  }				} else				if (argv[0][l]=='?') {					/* Display configuration */					r = ioctl(fd, ioctlinfo[i].get, &c);	if (r != 0) error("ioctl get %s", ioctlinfo[i].name);					r = 0;		/* Not first flag? */					if (ioctlinfo[i].flags!=NULL) {						for (j=0; ioctlinfo[i].flags[j].name!=NULL; j++) {							l2 = ioctlinfo[i].flags[j].val;							if (c==l2 || (ioctlinfo[i].bitfield && l2!=0 && (c&l2)==l2)) {								if (r!=0) printf(",");								r = 1;								printf(ioctlinfo[i].flags[j].name);								if (ioctlinfo[i].bitfield) c &= ~l2;							}						}					}					if (r==0 || (ioctlinfo[i].bitfield && c!=0)) printf("%i", c);					printf("\n");				} else				if (argv[0][l]=='=') {					/* Set configuration */					c = 0;					while (argv[0][l]!=0) {						r = 0;		/* Is it a recognized string? */						for (l2=l+1; argv[0][l2]!=0 && argv[0][l2]!=','; l2++);						if (ioctlinfo[i].flags!=NULL) {							for (j=0; ioctlinfo[i].flags[j].name!=NULL; j++) {								if (strlen(ioctlinfo[i].flags[j].name)==(l2-l-1) && memcmp(ioctlinfo[i].flags[j].name, &argv[0][l+1], l2-l-1)==0) {									c |= ioctlinfo[i].flags[j].val;									r = 1;									break;								}							}						}						if (r==0) {							if (!isdigit(argv[0][l+1])) error("unrecognized option parameter");							c |= atoi(&argv[0][l+1]);						}						l = l2;						if (!ioctlinfo[i].bitfield && argv[0][l]!=0) error("multiple flags given for a non-bitfield option");					}					r = ioctl(fd, ioctlinfo[i].set, &c);	if (r != 0) error("ioctl set %s", ioctlinfo[i].name);					printf("%i\n", c);				} else {					error("invalid configuration request type");				}			}		}	}	close(fd);	return 0;}/* }}} *//* End of file */

⌨️ 快捷键说明

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