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

📄 w3cam.c

📁 usb摄像头测试源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * w3cam.c * * Copyright (C) 1998 - 2001 Rasca, Berlin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <errno.h>#ifdef USE_SYSLOG#include <syslog.h>#endif#if defined __GLIBC__ && __GLIBC__ >= 2#include <libgen.h>	/* basename */#endif#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h>#include <linux/types.h>#include <linux/videodev.h>#ifdef HAVE_LIBZ#include <zlib.h>#endif#ifdef HAVE_LIBPNG#include <png.h>#endif#ifdef HAVE_LIBJPEG#include <jpeglib.h>#endif#ifdef HAVE_LIBTTF#include <freetype.h>#endif#include "w3cam.h"#include "cgi.h"#include "v4l.h"/* * some default values, change these to fit your needs * most of these could be changed at runtime with config file */#define FMT_DEFAULT		FMT_JPEG	/* FMT_PPM, FMT_JPEG, FMT_PNG */#define QUALITY_DEFAULT	65			/* JPEG default quality */#define WIDTH_DEFAULT	240			/* default width and height of the image */#define HEIGHT_DEFAULT	180#define MODE_DEFAULT	MODE_PLAIN	/* MODE_GUI or MODE_PLAIN */#define USEC_DEFAULT	20000		/* wait microseconds before capturing */#define REFRESH_DEFAULT	OFF			/* don't use refreshing */#define MIN_REFRESH		0.0			/* min refresh time, compile time option */#define FREQLIST_DEFAULT "878;9076;9844;9460"	/* default frequenzies */#define MAX_TRY_OPEN	20			/* may be the device is locked, so try max*//* end of default values * ********************* *//* */voidusage (char *pname, int width, int height, int color, int quality, int usec){	cgi_response (http_bad_request, "text/html");	printf (	"<title>w3cam - help</title><pre>W3Cam, Version %s\n\n"	"Usage: %s<?parameters>\n"	"CGI parameters (GET or POST):\n"	" help                                    show this page\n"	" size=#x#                                geometry of picture "		"[default = %dx%d]\n"	" color={0|1}                             color or grey mode "		"[default = %d]\n"	" input={tv|composite|composite2|s-video} define input source\n"	" quality={1-100}                         jpeg quality "		"[default = %d]\n"	" format={ppm|png|jpeg}                   output format\n"	" freq=#                                  define frequenzy for TV\n"	" usleep=#                                sleep # micro secs before cap. "		"[default = %d]\n"	" mode=[gui|html]                         build a page with panel or plain html\n"	" refresh=#.#                             time in sec to refresh gui\n"	" norm={pal|ntsc|secam}                   tv norm\n"	" bgr={1|0}                               swap RGB to BGR (default: no)\n",	VERSION, basename(pname), width, height, color, quality, usec);	printf (	"\nCompiled in features:\n");#ifdef HAVE_LIBPNG	printf (" PNG file format\n");#endif#ifdef HAVE_LIBJPEG	printf (" JPEG file format\n");#endif#ifdef HAVE_LIBTTF	printf ( " TTF/TimeStamp\n");#endif#ifdef USE_SYSLOG	printf ( " SYSLOG support\n");#endif	exit (0);}/* */voidlog (char *info){#ifdef USE_SYSLOG	syslog (LOG_USER, "%s\n", info);#else	fprintf (stderr, "%s\n", info);#endif}/* */voidlog2 (char *s1, char *s2){#ifdef USE_SYSLOG	syslog (LOG_USER, "%s %s\n", s1, s2);#else	fprintf (stderr, "%s %s\n", s1, s2);#endif}/* * parse comma seperated frequency list */char **parse_list (char *freqs){	char **flist = NULL;	char *p = freqs, *end = NULL;	int num = 0, i, len;	if (!freqs)		return (NULL);	while ((p = strchr(p, ';')) != NULL) {		p++;		num++;	}	num++;	flist = malloc ((num + 1) * sizeof (char *));	flist[num] = NULL;	p = freqs;	for (i = 0; i < num; i++) {		if (i == (num-1)) {			/* last element */			len = strlen (p);		} else {			end = strchr(p, ';');			len = end - p;		}		flist[i] = malloc (len+1);		strncpy (flist[i], p, len);		p = end+1;	}	return (flist);}/* * read rgb image from v4l device * return: new allocated buffer */unsigned char *get_image (int dev, int width, int height, int input, int usec,			unsigned long freq, int palette){	struct video_mbuf vid_buf;	struct video_mmap vid_mmap;	char *map;	unsigned char *buff;	int size, len, bpp;	register int i;	if (input == IN_TV) {		if (freq > 0) {			if (ioctl (dev, VIDIOCSFREQ, &freq) == -1)				log2 ("ioctl (VIDIOCSREQ):", strerror(errno));		}	}	/* it seems some cards need a little bit time to come in		sync with the new settings */	if (usec)		usleep (usec);	if (palette != VIDEO_PALETTE_GREY) {		/* RGB or YUV */		size = width * height * 3;		bpp = 3;	} else {		size = width * height * 1;		bpp = 1;	}	vid_mmap.format = palette;	if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {		/* do a normal read()		 */		struct video_window vid_win;		if (ioctl (dev, VIDIOCGWIN, &vid_win) != -1) {			vid_win.width  = width;			vid_win.height = height;			if (ioctl (dev, VIDIOCSWIN, &vid_win) == -1) {				log2 ("ioctl(VIDIOCSWIN):", strerror(errno));				return (NULL);			}		}		map = malloc (size);		if (!map)			return (NULL);				len = read (dev, map, size);		if (len <= 0) {			free (map);			return NULL;		}		if (palette == VIDEO_PALETTE_YUV420P) {			char *convmap;            convmap = malloc ( width * height * bpp );            v4l_yuv420p2rgb (convmap, map, width, height, bpp * 8);            memcpy (map, convmap, (size_t) width * height * bpp);            free (convmap);        } else if (palette == VIDEO_PALETTE_YUV422P) {			char *convmap;            convmap = malloc ( width * height * bpp );            v4l_yuv422p2rgb (convmap, map, width, height, bpp * 8);            memcpy (map, convmap, (size_t) width * height * bpp);            free (convmap);		}		return (map);	}	map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0);	if ((unsigned char *)-1 == (unsigned char *)map) {		log2 ("mmap():", strerror(errno));		return (NULL);	}	vid_mmap.frame = 0;	vid_mmap.width = width;	vid_mmap.height =height;	if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {		log2 ("ioctl(VIDIOCMCAPTURE):", strerror(errno));		munmap (map, vid_buf.size);		return (NULL);	}	if (ioctl (dev, VIDIOCSYNC, &vid_mmap.frame) == -1) {		log2 ("ioctl(VIDIOCSYNC):", strerror(errno));		munmap (map, vid_buf.size);		return (NULL);	}	buff = (unsigned char *) malloc (size);	if (buff) {		if (palette == VIDEO_PALETTE_YUV420P) {			v4l_yuv420p2rgb (buff, map, width, height, 24);        } else if (palette == VIDEO_PALETTE_YUV422P) {            v4l_yuv422p2rgb (buff, map, width, height, 24);		} else {			for (i = 0; i < size; i++)				buff[i] = map[i];		}	} else {		perror ("malloc()");	}	munmap (map, vid_buf.size);	return (buff);}/* */voidput_image_jpeg (char *image, int width, int height, int quality, int color){#ifdef HAVE_LIBJPEG	register int x, y, line_width;	JSAMPROW row_ptr[1];	struct jpeg_compress_struct cjpeg;	struct jpeg_error_mgr jerr;	char *line = NULL;	if (color) {		line_width = width * 3;		line = malloc (line_width);		if (!line)			return;	} else {		line_width = width;	}	cjpeg.err = jpeg_std_error(&jerr);	jpeg_create_compress (&cjpeg);	cjpeg.image_width = width;	cjpeg.image_height= height;	if (color) {		cjpeg.input_components = 3;		cjpeg.in_color_space = JCS_RGB;	} else {		cjpeg.input_components = 1;		cjpeg.in_color_space = JCS_GRAYSCALE;	}	jpeg_set_defaults (&cjpeg);	jpeg_simple_progression (&cjpeg);	jpeg_set_quality (&cjpeg, quality, TRUE);	cjpeg.dct_method = JDCT_FASTEST;	jpeg_stdio_dest (&cjpeg, stdout);	jpeg_start_compress (&cjpeg, TRUE);	if (color) {		row_ptr[0] = line;		for ( y = 0; y < height; y++) {			for (x = 0; x < line_width; x += 3) {				line[x]   = image[x+2];				line[x+1] = image[x+1];				line[x+2] = image[x];			}			image += line_width;			jpeg_write_scanlines (&cjpeg, row_ptr, 1);		}		free (line);	} else {		for ( y = 0; y < height; y++) {			row_ptr[0] = image;			jpeg_write_scanlines (&cjpeg, row_ptr, 1);			image += line_width;		}	}	jpeg_finish_compress (&cjpeg);	jpeg_destroy_compress (&cjpeg);#endif}/* * write png image to stdout */voidput_image_png (char *image, int width, int height, int color){#ifdef HAVE_LIBPNG	register int y;	register char *p;	png_infop info_ptr;	png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,						NULL, NULL, NULL);	if (!png_ptr)		return;	info_ptr = png_create_info_struct (png_ptr);	if (!info_ptr)		return;	png_init_io (png_ptr, stdout);	if (color) {		png_set_IHDR (png_ptr, info_ptr, width, height,					8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);		png_set_bgr (png_ptr);	} else {		png_set_IHDR (png_ptr, info_ptr, width, height,					8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);	}	png_write_info (png_ptr, info_ptr);	p = image;	if (color) {		width *= 3;		for (y = 0; y < height; y++) {			png_write_row (png_ptr, p);			p += width;		}	} else {		for (y = 0; y < height; y++) {			png_write_row (png_ptr, p);			p += width;		}	}	png_write_end (png_ptr, info_ptr);	png_destroy_write_struct (&png_ptr, &info_ptr);#endif}/* * write ppm image to stdout */voidput_image_ppm (char *image, int width, int height){	int x, y, ls=0;	unsigned char *p = (unsigned char *)image;	printf ("P3\n%d %d\n%d\n", width, height, 255);	for (x = 0; x < width; x++) {		for (y = 0; y < height; y++) {			printf ("%03d %03d %03d  ", p[2], p[1], p[0]);			p += 3;			if (ls++ > 4) {				printf ("\n");				ls = 0;			}		}	}}/* */const char *palette2string (int palette) {	if (palette == VIDEO_PALETTE_RGB24)		return "rgb24";	if (palette == VIDEO_PALETTE_YUV420P)		return "yuv420p";	if (palette == VIDEO_PALETTE_YUV422P)		return "yuv422p";	if (palette == VIDEO_PALETTE_GREY)		return "grey";	return "color";}/* * create a plain html page */voidmake_html (int width, int height, int color, int input, int fmt, int quality,			float refresh, int us, int norm, int freq, char **freqs, int pal,			int swapRGB){	cgi_response (http_ok, "text/html");	/* cgi_refresh (refresh, NULL); */	cgi_html_start ("W3Cam");	printf ("<DIV class=image><IMG width=%d height=%d src=\"%s?"		"size=%dx%d&color=%s&id=%d&refresh=%1.2f&usleep=%d&freq=%d"		"&mode=plain",		width, height,		cgi_script_name(),		width, height, palette2string(pal),(int)time(NULL), refresh, us, freq);	if (input != INPUT_DEFAULT)		printf ("&input=%s", input == IN_TV? "tv" :					input == IN_COMP1 ? "composite" :					input == IN_COMP2? "composite2" : "s-video");	if (norm != OFF)		printf ("&norm=%s", norm == NORM_PAL ? "pal":					norm == NORM_NTSC ? "ntsc" : "secam");	if (fmt != FMT_DEFAULT)		printf ("&format=%s", fmt == FMT_PNG? "png":					fmt == FMT_JPEG? "jpeg": "ppm");	if (quality)		printf ("&quality=%d", quality);	if (swapRGB)		printf ("&bgr=1");	printf ("\"></DIV>\n");}/* * create a html page with panel */voidmake_gui (int width, int height, int color, int input, int fmt, int quality,			float refresh, int us, int norm, int freq, char **freqs, int pal,			int swapRGB){	make_html (width, height, color, input, fmt, quality,			refresh, us, norm, freq, freqs, pal, swapRGB);	printf ("<P><DIV class=panel><FORM>\n");	printf ("<INPUT type=hidden name=width value=%d>", width);	printf ("<INPUT type=hidden name=height value=%d>\n", height);	printf ("<INPUT type=hidden name=mode value=gui>");	printf ("<INPUT type=hidden name=quality value=%d>\n", quality);	printf ("<INPUT type=hidden name=usleep value=%d>\n", us);	printf ("Input:<SELECT name=input>\n");	printf ("<option%s value='-1'>Default</option>",				input == INPUT_DEFAULT? " selected":"");	printf ("<option%s>TV</option>",				input == IN_TV? " selected":"");	printf ("<option%s>Composite</option>",				input == IN_COMP1 ? " selected":"");	printf ("<option%s>Composite2</option>",				input == IN_COMP2? " selected":"");	printf ("<option%s>S-Video</option></SELECT>\n",				input == IN_SVIDEO? " selected":"");	if ((norm != OFF) && (input == IN_TV)) {		printf ("Norm:<SELECT name=norm>\n");		printf ("<option%s>PAL</option>",   norm == NORM_PAL ? " selected":"");		printf ("<option%s>NTSC</option>",  norm == NORM_NTSC? " selected":"");

⌨️ 快捷键说明

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