📄 qcset.c
字号:
val = val*10 + c - '0'; /* Assume ASCII */ } while (1); if (!isspace(c)) error("PNM file error"); ungetc(c,pnm_file); return val;}/* }}} *//* {{{ [fold] void pnm_open(unsigned char *name, unsigned int *width, unsigned int *height) */void pnm_open(unsigned char *name, unsigned int *width, unsigned int *height) { char c1,c2,c3; unsigned int maxval; pnm_file = fopen(name, "rb"); if (!pnm_file) error("can not open file `%s'", name); /* Check signature */ c1 = getc(pnm_file); c2 = getc(pnm_file); c3 = getc(pnm_file); if (c1!='P' || c2!='6' || !isspace(c3)) error("Not raw bits PPM file"); ungetc(c3,pnm_file); /* Read dimensions */ *width = pnm_readnum(); *height = pnm_readnum(); maxval = pnm_readnum(); if (maxval>255) error("Does not support PNM files with more depth than 8 bits"); c1 = getc(pnm_file); if (!isspace(c1)) error("PNM file error");}/* }}} *//* {{{ [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) { /* 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': /* Settings read/write */ if (!argp) error("missing parameter to option `-%c'", argv[0][1]); switch (argp[0]) { case 'r': /* read */ r = ioctl(fd, VIDIOCGPICT, &vidpic); if (r!=0) error("ioctl VIDIOCGPICT"); read_settings(&vidpic); break; case 'w': /* write */ r = ioctl(fd, VIDIOCGPICT, &vidpic); if (r!=0) error("ioctl VIDIOCGPICT"); write_settings(&vidpic); /* Modify only settings which user gives */ r = ioctl(fd, VIDIOCSPICT, &vidpic); if (r!=0) error("ioctl VIDIOCSPICT"); break; default: /* unknown */ error("unknown request"); } 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; } 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 (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 + -