/* vfc-snap.c Joe Smith 4-Feb-1999 */ /* Requires VFC-1.0 for SunOS-4.1.x */ /* 8110 Dec 12 1990 /usr/1.0-VFC/vfc_lib/vfc_lib.h */ #include #include #include "vfc_lib.h" #include main(argc,argv) int argc; char *argv[]; { void hw_setup(); char *usage = "Port must be specified, 1, 1j, 2, 2j, 3, or 3j"; int do_jpg = 0; if (argc == 2) do_jpg = argv[1][1]; switch (argc == 2 ? argv[1][0] : 0) { case '1': hw_setup(VFC_PORT1,do_jpg); exit(0); case '2': hw_setup(VFC_PORT2,do_jpg); exit(0); case '3': hw_setup(VFC_SVIDEO,do_jpg); exit(0); } fprintf(stderr,"%s: %s\n",argv[0],usage); exit(1); } void hw_setup(port,do_jpg) int port; int do_jpg; { u_short *yuv_data, *yuv_ptr; u_int *rgb_data, xbgr; register int i; int rc, format, nbytes, v_format; VfcDev *vfc_dev; int width, height, pixel; u_char *rgb, r, g, b; FILE *cjpeg; /* * Open the hardware just use the default case * "/dev/vfc0" and test for success. * Lock the hardware to deny other programs access */ if ((vfc_dev = vfc_open(NULL, VFC_LOCKDEV)) == NULL) { fprintf(stderr,"Could not open hardware\n"); exit(1); } vfc_set_port(vfc_dev, port); rc = vfc_set_format(vfc_dev, VFC_AUTO, &format); if (rc < 0) { fprintf(stderr,"No video signal on port %d\n",port); exit(1); } if (format == NO_LOCK) { fprintf(stderr,"Warning: no video signal in detected\n"); } v_format = vfc_video_format(format); if (v_format == VFC_NTSC) { vfc_adjust_hue(vfc_dev, 0); width = VFC_NTSC_WIDTH; height = VFC_NTSC_HEIGHT; } else { width = VFC_PAL_WIDTH; height = VFC_PAL_HEIGHT; } /* * Now we know the video format, allocate space for * the YUV image. Check to see that memory was allocated. * If allocated clear the memory just to be sure. */ nbytes = vfc_format_height(v_format)*VFC_YUV_WIDTH*2; yuv_data = (u_short *)malloc(nbytes); if (yuv_data == NULL) { perror("malloc"); vfc_destroy(vfc_dev); exit(1); } yuv_ptr = yuv_data; for(i=0; i<(nbytes/2); i++) *yuv_ptr++ = 0; /* * Do a grab and read in an image */ if (vfc_grab(vfc_dev) < 0) { fprintf(stderr,"Warning, grab failed\n"); } if (vfc_yuvread_sq(vfc_dev, yuv_data, v_format) < 0) { fprintf(stderr,"Warning, vfc_yuvread failed\n"); } nbytes = width * height * 4; rgb_data = (u_int *)malloc(nbytes); if (rgb_data == NULL) { perror("malloc"); vfc_destroy(vfc_dev); exit(1); } vfc_init_lut(0); vfc_yuv2rgb_ntsc(yuv_data,rgb_data); free(yuv_data); vfc_destroy(vfc_dev); /* * Convert 32-bit XBGR data to 24-bit RGB data */ rgb = (u_char *) rgb_data; /* Update in place */ for (pixel=0; pixel<=width*height; pixel++) { xbgr = rgb_data[pixel]; r = (xbgr & 0xff); g = (xbgr & 0xff00) >> 8; b = (xbgr & 0xff0000) >> 16; *(rgb++) = r; *(rgb++) = g; *(rgb++) = b; } if (do_jpg) { cjpeg = popen("/usr/local/bin/cjpeg","w"); if (cjpeg == NULL) { perror("popen on /usr/local/bin/cjpeg"); exit(1); } } else { cjpeg = stdout; } fprintf(cjpeg,"P6 %d %d 255\n",width,height); /* ppm binary format */ fflush(cjpeg); rc = write(fileno(cjpeg),rgb_data,pixel*3); if (do_jpg) { rc = pclose(cjpeg); } else { rc = fclose(cjpeg); } if (rc < 0) { perror("pclose"); exit(1); } free(rgb_data); return; }