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

📄 ibmcam.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	sprintf(tmp, "%8lx", ibmcam->scratch_ovf_count);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8lx", ibmcam->iso_skip_count);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8lx", ibmcam->iso_err_count);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8x", ibmcam->vpic.colour);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8x", ibmcam->vpic.hue);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8x", ibmcam->vpic.brightness >> 8);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8x", ibmcam->vpic.contrast >> 12);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;	sprintf(tmp, "%8d", ibmcam->vpic.whiteness >> 8);	usb_ibmcam_overlaystring(ibmcam, frame, x, y, tmp);	y += y_diff;}/* * usb_ibmcam_testpattern() * * Procedure forms a test pattern (yellow grid on blue background). * * Parameters: * fullframe:   if TRUE then entire frame is filled, otherwise the procedure *	      continues from the current scanline. * pmode	0: fill the frame with solid blue color (like on VCR or TV) *	      1: Draw a colored grid * * History: * 1/2/00   Created. */void usb_ibmcam_testpattern(struct usb_ibmcam *ibmcam, int fullframe, int pmode){	static const char proc[] = "usb_ibmcam_testpattern";	struct ibmcam_frame *frame;	unsigned char *f;	int num_cell = 0;	int scan_length = 0;	static int num_pass = 0;	if (ibmcam == NULL) {		printk(KERN_ERR "%s: ibmcam == NULL\n", proc);		return;	}	if ((ibmcam->curframe < 0) || (ibmcam->curframe >= IBMCAM_NUMFRAMES)) {		printk(KERN_ERR "%s: ibmcam->curframe=%d.\n", proc, ibmcam->curframe);		return;	}	/* Grab the current frame */	frame = &ibmcam->frame[ibmcam->curframe];	/* Optionally start at the beginning */	if (fullframe) {		frame->curline = 0;		frame->scanlength = 0;	}	/* Form every scan line */	for (; frame->curline < imgheight; frame->curline++) {		int i;		f = frame->data + (imgwidth * 3 * frame->curline);		for (i=0; i < imgwidth; i++) {			unsigned char cb=0x80;			unsigned char cg = 0;			unsigned char cr = 0;			if (pmode == 1) {				if (frame->curline % 32 == 0)					cb = 0, cg = cr = 0xFF;				else if (i % 32 == 0) {					if (frame->curline % 32 == 1)						num_cell++;					cb = 0, cg = cr = 0xFF;				} else {					cb = ((num_cell*7) + num_pass) & 0xFF;					cg = ((num_cell*5) + num_pass*2) & 0xFF;					cr = ((num_cell*3) + num_pass*3) & 0xFF;				}			} else {				/* Just the blue screen */			}							*f++ = cb;			*f++ = cg;			*f++ = cr;			scan_length += 3;		}	}	frame->grabstate = FRAME_DONE;	frame->scanlength += scan_length;	++num_pass;	/* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */	usb_ibmcam_overlaystats(ibmcam, frame);}static unsigned char *ibmcam_model1_find_header(unsigned char hdr_sig, unsigned char *data, int len){	while (len >= 4)	{		if ((data[0] == 0x00) && (data[1] == 0xFF) && (data[2] == 0x00))		{#if 0			/* This code helps to detect new frame markers */			printk(KERN_DEBUG "Header sig: 00 FF 00 %02X\n", data[3]);#endif			if (data[3] == hdr_sig) {				if (debug > 2)					printk(KERN_DEBUG "Header found.\n");				return data+4;			}		}		++data;		--len;	}	return NULL;}static unsigned char *ibmcam_model2_find_header(unsigned char hdr_sig, unsigned char *data, int len){	int marker_len = 0;	switch (videosize) {	case VIDEOSIZE_176x144:		marker_len = 10;		break;	default:		marker_len = 2;		break;	}	while (len >= marker_len)	{		if ((data[0] == 0x00) && (data[1] == 0xFF))		{#if 0			/* This code helps to detect new frame markers */			static int pass = 0;			if (pass++ == 0)				ibmcam_hexdump(data, (len > 16) ? 16 : len);#endif			if (debug > 2)				printk(KERN_DEBUG "Header found.\n");			return data+marker_len;		}		++data;		--len;	}	return NULL;}/* How much data is left in the scratch buf? */#define scratch_left(x)	(ibmcam->scratchlen - (int)((char *)x - (char *)ibmcam->scratch))/* Grab the remaining */static void usb_ibmcam_align_scratch(struct usb_ibmcam *ibmcam, unsigned char *data){	unsigned long left;	left = scratch_left(data);	memmove(ibmcam->scratch, data, left);	ibmcam->scratchlen = left;}/* * usb_ibmcam_find_header() * * Locate one of supported header markers in the scratch buffer. * Once found, remove all preceding bytes AND the marker (4 bytes) * from the scratch buffer. Whatever follows must be video lines. * * History: * 1/21/00  Created. */static scan_state_t usb_ibmcam_find_header(struct usb_ibmcam *ibmcam){	struct ibmcam_frame *frame;	unsigned char *data, *tmp;	data = ibmcam->scratch;	frame = &ibmcam->frame[ibmcam->curframe];	if (ibmcam->camera_model == IBMCAM_MODEL_1)		tmp = ibmcam_model1_find_header(frame->hdr_sig, data, scratch_left(data));	else if (ibmcam->camera_model == IBMCAM_MODEL_2)		tmp = ibmcam_model2_find_header(frame->hdr_sig, data, scratch_left(data));	else		tmp = NULL;	if (tmp == NULL) {		/* No header - entire scratch buffer is useless! */		if (debug > 2)			printk(KERN_DEBUG "Skipping frame, no header\n");		ibmcam->scratchlen = 0;		return scan_EndParse;	}	/* Header found */	data = tmp;	ibmcam->has_hdr = 1;	ibmcam->header_count++;	frame->scanstate = STATE_LINES;	frame->curline = 0;	if (flags & FLAGS_FORCE_TESTPATTERN) {		usb_ibmcam_testpattern(ibmcam, 1, 1);		return scan_NextFrame;	}	usb_ibmcam_align_scratch(ibmcam, data);	return scan_Continue;}/* * usb_ibmcam_parse_lines() * * Parse one line (TODO: more than one!) from the scratch buffer, put * decoded RGB value into the current frame buffer and add the written * number of bytes (RGB) to the *pcopylen. * * History: * 1/21/00  Created. */static scan_state_t usb_ibmcam_parse_lines(struct usb_ibmcam *ibmcam, long *pcopylen){	struct ibmcam_frame *frame;	unsigned char *data, *f, *chromaLine;	unsigned int len;	const int v4l_linesize = imgwidth * V4L_BYTES_PER_PIXEL;	/* V4L line offset */	const int hue_corr  = (ibmcam->vpic.hue - 0x8000) >> 10;	/* -32..+31 */	const int hue2_corr = (hue_correction - 128) / 4;		/* -32..+31 */	const int ccm = 128; /* Color correction median - see below */	int y, u, v, i, frame_done=0, mono_plane, color_corr;	color_corr = (ibmcam->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/	RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1);	data = ibmcam->scratch;	frame = &ibmcam->frame[ibmcam->curframe];	len = frame->frmwidth * 3; /* 1 line of mono + 1 line of color */	/*printk(KERN_DEBUG "len=%d. left=%d.\n",len,scratch_left(data));*/	mono_plane = ((frame->curline & 1) == 0);	/*	 * Lines are organized this way (or are they?)	 *	 * I420:	 * ~~~~	 * ___________________________________	 * |-----Y-----|---UVUVUV...UVUV-----| \	 * |-----------+---------------------|  \	 * |<-- 176 -->|<------ 176*2 ------>|  Total 72. pairs of lines	 * |...	   ...	     ...|  /	 * |___________|_____________________| /	 *  - odd line- ------- even line ---	 *	 * another format:	 * ~~~~~~~~~~~~~~	 * ___________________________________	 * |-----Y-----|---UVUVUV...UVUV-----| \	 * |-----------+---------------------|  \	 * |<-- 352 -->|<------ 352*2 ------>|  Total 144. pairs of lines	 * |...	   ...	     ...|  /	 * |___________|_____________________| /	 *  - odd line- ------- even line ---	 */	/* Make sure there's enough data for the entire line */	if (scratch_left(data) < (len+1024)) {		/*printk(KERN_DEBUG "out of data, need %u.\n", len);*/		return scan_Out;	}#if 0	{	/* This code prints beginning of the source frame */		static int pass = 0;		if ((pass++ % 3000) == 0)			ibmcam_hexdump(data, 16);	}#endif#if 0	if (frame->curline == 10 || frame->curline == 11) {		/* This code prints beginning of 10th (mono), 11th (chroma) line */		static int pass = 0;		if ((pass % 100) == 0)			ibmcam_hexdump(data, 16);		if (frame->curline == 11)			pass++;	}#endif	/*	 * Make sure that our writing into output buffer	 * will not exceed the buffer. Mind that we may write	 * not into current output scanline but in several after	 * it as well (if we enlarge image vertically.)	 */	if ((frame->curline + 1) >= V4L_FRAME_HEIGHT)		return scan_NextFrame;	/*	 * Now we are sure that entire line (representing all 'frame->frmwidth'	 * pixels from the camera) is available in the scratch buffer. We	 * start copying the line left-aligned to the V4L buffer (which	 * might be larger - not smaller, hopefully). If the camera	 * line is shorter then we should pad the V4L buffer with something	 * (black in this case) to complete the line.	 */	f = frame->data + (v4l_linesize * frame->curline);	/*	 * chromaLine points to 1st pixel of the line with chrominance.	 * If current line is monochrome then chromaLine points to next	 * line after monochrome one. If current line has chrominance	 * then chromaLine points to this very line. Such method allows	 * to access chrominance data uniformly.	 *	 * To obtain chrominance data from the 'chromaLine' use this:	 *   v = chromaLine[0]; // 0-1:[0], 2-3:[4], 4-5:[8]...	 *   u = chromaLine[2]; // 0-1:[2], 2-3:[6], 4-5:[10]...	 *	 * Indices must be calculated this way:	 * v_index = (i >> 1) << 2;	 * u_index = (i >> 1) << 2 + 2;	 *	 * where 'i' is the column number [0..frame->frmwidth-1]	 */	chromaLine = data;	if (mono_plane)		chromaLine += frame->frmwidth;	for (i = 0; i < frame->frmwidth; i++, data += (mono_plane ? 1 : 2))	{		unsigned char rv, gv, bv;	/* RGB components */		/*		 * Search for potential Start-Of-Frame marker. It should		 * not be here, of course, but if your formats don't match		 * you might exceed the frame. We must match the marker to		 * each byte of multi-byte data element if it is multi-byte.		 */#if 1		if ((ibmcam->camera_model == IBMCAM_MODEL_1) && (scratch_left(data) >= (4+2))) {			unsigned char *dp;			int j;			for (j=0, dp=data; j < 2; j++, dp++) {				if ((dp[0] == 0x00) && (dp[1] == 0xFF) &&				    (dp[2] == 0x00) && (dp[3] == frame->hdr_sig)) {					ibmcam->has_hdr = 2;					frame_done++;					break;				}			}		}#endif		/* Check for various visual debugging hints (colorized pixels) */		if ((flags & FLAGS_DISPLAY_HINTS) && (ibmcam->has_hdr)) {			/*			 * This is bad and should not happen. This means that			 * we somehow overshoot the line and encountered new			 * frame! Obviously our camera/V4L frame size is out			 * of whack. This cyan dot will help you to figure			 * out where exactly the new frame arrived.			 */			if (ibmcam->has_hdr == 1) {				bv = 0; /* Yellow marker */				gv = 0xFF;				rv = 0xFF;			} else {				bv = 0xFF; /* Cyan marker */				gv = 0xFF;				rv = 0;			}			ibmcam->has_hdr = 0;			goto make_pixel;		}		if (mono_plane || frame->order_yc)			y = data[0];		else			y = data[1];		if (flags & FLAGS_MONOCHROME) /* Use monochrome for debugging */			rv = gv = bv = y;		else {			int off_0, off_2;			off_0 = (i >> 1) << 2;			off_2 = off_0 + 2;			if (frame->order_yc) {				off_0++;				off_2++;			}			if (!frame->order_uv) {				off_0 += 2;				off_2 -= 2;			}			u = chromaLine[off_0] + hue_corr;			v = chromaLine[off_2] + hue2_corr;			/* Apply color correction */			if (color_corr != 0) {				/* Magnify up to 2 times, reduce down to zero saturation */				u = 128 + ((ccm + color_corr) * (u - 128)) / ccm;				v = 128 + ((ccm + color_corr) * (v - 128)) / ccm;			}			YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv);		}	make_pixel:

⌨️ 快捷键说明

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