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

📄 spcadecoder.c

📁 linux下的摄像头驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
static int bgr = 0; voidjpeg_reset_input_context (unsigned char *buf,int oescap){	/* set input context */	in.p = buf;	in.omitescape = oescap;	in.left = 0;	in.bits = 0;	in.marker = 0;}/* Gamma correction setting *//*	Gtable[0][n] -> 2.2*	Gtable[1][n] -> 1.7*	Gtable[2][n] -> 1.45*	Gtable[3][n] -> 1*	Gtable[4][n] -> 0.6896*	Gtable[5][n] -> 0.5882*	Gtable[6][n] -> 0.4545*	gCor coeff 0..6*/int spca50x_outpicture ( struct spca50x_frame *myframe ){	/* general idea keep a frame in the temporary buffer from the tasklet*/	/* decode with native format at input and asked format at output */	/* myframe->cameratype is the native input format */	/* myframe->format is the asked format */	int done = 0;	int i;	struct pictparam *gCorrect = &myframe->pictsetting;	int width = 0;	int height = 0;	if (gCorrect->change) {		if ( gCorrect->change == 0x01) {		/* Gamma setting change compute all case */			memcpy (&GTable[7],&GTable[gCorrect->gamma],256);			memcpy (&GTable[8],&GTable[gCorrect->gamma],256);			memcpy (&GTable[9],&GTable[gCorrect->gamma],256);			for (i =0; i < 256 ; i++){				GTable[7][i] = CLIP(((GTable[7][i] + gCorrect->OffRed) * gCorrect->GRed) >> 8);				GTable[8][i] = CLIP(((GTable[8][i] + gCorrect->OffGreen) * gCorrect->GGreen) >> 8);				GTable[9][i] = CLIP(((GTable[9][i] + gCorrect->OffBlue) * gCorrect->GBlue) >> 8);						}			bgr = gCorrect->force_rgb;			gCorrect->change = 0x00;		}		if ( gCorrect->change == 0x02) {		/* Red setting change compute Red Value */			memcpy (&GTable[7],&GTable[gCorrect->gamma],256);			for (i =0; i < 256 ; i++){				GTable[7][i] = CLIP(((GTable[7][i] + gCorrect->OffRed) * gCorrect->GRed) >> 8);			}			gCorrect->change &= ~0x02;		}		if ( gCorrect->change == 0x04) {		/* Green setting change compute Green Value */			memcpy (&GTable[8],&GTable[gCorrect->gamma],256);			for (i =0; i < 256 ; i++){					GTable[8][i] = CLIP(((GTable[8][i] + gCorrect->OffGreen) * gCorrect->GGreen) >> 8);				}			gCorrect->change &= ~0x04;		}		if ( gCorrect->change == 0x08) {		/* Blue setting change compute Blue Value */			memcpy (&GTable[9],&GTable[gCorrect->gamma],256);			for (i =0; i < 256 ; i++){				GTable[9][i] = CLIP(((GTable[9][i] + gCorrect->OffBlue) * gCorrect->GBlue) >> 8);			}			gCorrect->change &= ~0x08; 		}		if ( gCorrect->change == 0x10) {		/* force_rgb setting change   */			bgr = gCorrect->force_rgb;			gCorrect->change &= ~0x10; 		}	}	switch(myframe->cameratype){		case JPGC:						height = (myframe->data[11] << 8) | myframe->data[12];			width = (myframe->data[13] << 8) | myframe->data[14];			if (myframe->hdrheight != height || myframe->hdrwidth != width){					done = ERR_CORRUPTFRAME;			} else {			//set info.dri struct should be kmalloc with the			// instance camera			info.dri = myframe->data[5];			if (myframe->format == VIDEO_PALETTE_JPEG){				memcpy(myframe->tmpbuffer,myframe->data,myframe->scanlength);			 	done = make_jpeg_conexant ( myframe );			} else {				memcpy(myframe->tmpbuffer,myframe->data + 39,myframe->scanlength - 39);			 	done = jpeg_decode422( myframe, bgr);			}			}		break;		case JPGH:			width = (myframe->data[10] << 8) | myframe->data[11];			height = (myframe->data[12] << 8) | myframe->data[13];			/* some camera did not respond with the good height ie:Labtec Pro 240 -> 232 */			if (myframe->hdrwidth != width){					done = ERR_CORRUPTFRAME;			} else {			// reset info.dri			info.dri = 0;			memcpy(myframe->tmpbuffer,myframe->data+16,myframe->scanlength - 16);			if (myframe->format == VIDEO_PALETTE_JPEG){				done = make_jpeg ( myframe );			} else {				done = jpeg_decode422( myframe, bgr);			}			}		break;		case JPEG: 			memcpy(myframe->tmpbuffer,myframe->data,myframe->scanlength);			if (myframe->format == VIDEO_PALETTE_JPEG){			 done = make_jpeg ( myframe );			} else {			 done = jpeg_decode411( myframe, bgr);			}		break;		case YUVY: 		case YUYV: 		case YYUV: 			memcpy(myframe->tmpbuffer,myframe->data,myframe->scanlength);			done = yuv_decode( myframe, bgr);		break;		case GBGR:			/* translate the tv8532 stream into GBRG stream */			tv8532_preprocess(myframe);			done = bayer_decode( myframe, bgr);		break;		case GBRG:			memcpy(myframe->tmpbuffer,myframe->data,myframe->scanlength);			done = bayer_decode( myframe, bgr);		break;		case SN9C:			sonix_decompress(myframe->hdrwidth,myframe->hdrheight,myframe->data,myframe->tmpbuffer); 			done = bayer_decode( myframe, bgr);		break;	default : done = -1;	break;	}return done;	}static int yuv_decode(struct spca50x_frame *myframe, int force_rgb ){		int r_offset, g_offset, b_offset;	int my , mx; /* scan input surface */	unsigned char *pic1; /* output surface */	__u16 *pix1,*pix2; /* same for 16 bits output */		unsigned char *U, *V; /* chroma output pointer */	int inuv, inv, pocx; /* offset chroma input */	int iny,iny1; /* offset luma input */	int nextinline, nextoutline;	int u1,v1,rg;	unsigned char y,y1;	char u,v;	unsigned char *pic = myframe->data; /* output surface */	unsigned char *buf = myframe->tmpbuffer; /* input surface */	int width = myframe->hdrwidth; 	int height = myframe->hdrheight;	int softwidth = myframe->width;	int softheight = myframe->height;	//int method = myframe->method;	int format = myframe->format;	int cropx1 = myframe->cropx1;	int cropx2 = myframe->cropx2;	int cropy1 = myframe->cropy1;	int cropy2 = myframe->cropy2;	int bpp;	int framesize, frameUsize;		framesize = softwidth * softheight;	frameUsize = framesize >> 2;	/* rgb or bgr like U or V that's the question */	if (force_rgb) {		U = pic + framesize;		V = U + frameUsize;		r_offset = 2;		g_offset = 1;		b_offset = 0;	} else {		V = pic + framesize;		U = V + frameUsize;		r_offset = 0;		g_offset = 1;		b_offset = 2;	}	switch (myframe->cameratype) {		case YUVY: {			iny = 0;	   /********* iny **********/			inuv = width;	   /*** inuv **** inv ******/			nextinline = 3 * width;			inv = ( nextinline >> 1);			iny1 = width << 1; /********* iny1 *********/			}			break;		case YUYV: {			iny = 0;	   /********* iny **********/			inuv = width;	   /*** inuv **** iny1 *****/			nextinline = 3 * width;			iny1 = ( nextinline >> 1);			inv = iny1 + width ;/*** iny1 **** inv ******/			}			break;		case YYUV: {			iny = 0;	   /********* iny **********/			iny1 = width;	   /********* iny1 *********/			inuv = width << 1; /*** inuv **** inv ******/			inv = inuv +(width >>1);			nextinline = 3 * width;			}			break;	default:	{			iny = 0 ;	   /* make compiler happy */			iny1 = 0;			inuv = 0;			inv = 0 ;			nextinline = 0;			}		 break;	}		/* Decode to the correct format. */	switch (format) {		case VIDEO_PALETTE_RGB565:			{	bpp = 2;			/* initialize */								pix1 = (__u16*) pic;				pix2 = pix1 + softwidth;												for ( my =0; my < height; my += 2){					for ( mx = 0, pocx = 0; mx < width ; mx += 2, pocx++){					/* test if we need to decode */					  if ((my >= cropy1)						    && (my < height - cropy2)						    && (mx >= cropx1)						    && (mx < width - cropx2)) {						    /* yes decode */						    if ( force_rgb ){						    	u = buf [inuv + pocx] ;						    	v = buf [inv + pocx] ;						    } else {						    	v = buf [inuv + pocx] ;						    	u = buf [inv + pocx] ;						    }						    v1 = ((v << 10) + (v << 9)) >> 10;						    rg = ((u << 8) + (u << 7) + (v << 9) + (v << 4)) >> 10;						    u1 = ((u << 11) + (u << 4)) >> 10;						    						   						    /* top pixel Right */						    y1 = 128 +buf [iny + mx];									*pix1++ = ((GTable[7][CLIP((y1 + v1))] & 0xF8) >> 3 |								  ((GTable[8][CLIP((y1 - rg))] & 0xFC) << 3) |								  ((GTable[9][CLIP((y1 + u1))] & 0xF8) << 8)) ;								    /* top pixel Left */						    y1 = 128 +buf [iny + mx +1];							*pix1++ = ((GTable[7][CLIP((y1 + v1))] & 0xF8) >> 3 |								  ((GTable[8][CLIP((y1 - rg))] & 0xFC) << 3) |								  ((GTable[9][CLIP((y1 + u1))] & 0xF8) << 8)) ;								    /* bottom pixel Right */						    y1 = 128 + buf [iny1 + mx];							*pix2++ = ((GTable[7][CLIP((y1 + v1))] & 0xF8) >> 3 |								  ((GTable[8][CLIP((y1 - rg))] & 0xFC) << 3) |								  ((GTable[9][CLIP((y1 + u1))] & 0xF8) << 8)) ;								    /* bottom pixel Left */						    y1 = 128 + buf [iny1 + mx + 1];							*pix2++ = ((GTable[7][CLIP((y1 + v1))] & 0xF8) >> 3 |								  ((GTable[8][CLIP((y1 - rg))] & 0xFC) << 3) |								  ((GTable[9][CLIP((y1 + u1))] & 0xF8) << 8)) ;								    						    						    						    					  } // end test decode					} // end mx loop					iny += nextinline;					inuv += nextinline ;					inv += nextinline ;					iny1 += nextinline;					if (my >= cropy1){						/* are we in a decode surface move the output pointer */						pix1 += softwidth ;						pix2 += softwidth ;					}									} // end my loop						}			myframe->scanlength = (long)(softwidth*softheight*bpp);			break;		case VIDEO_PALETTE_RGB32:		case VIDEO_PALETTE_RGB24:			{	bpp = (format == VIDEO_PALETTE_RGB32) ? 4 : 3;				/* initialize */				nextoutline  = bpp * softwidth;				pic1 = pic + nextoutline;												for ( my =0; my < height; my += 2){					for ( mx = 0, pocx = 0; mx < width ; mx += 2, pocx++){					/* test if we need to decode */					  if ((my >= cropy1)						    && (my < height - cropy2)						    && (mx >= cropx1)						    && (mx < width - cropx2)) {						    /* yes decode */						    v = buf [inuv + pocx] ;						    u = buf [inv + pocx] ;						    						    v1 = ((v << 10) + (v << 9)) >> 10;						    rg = ((u << 8) + (u << 7) + (v << 9) + (v << 4)) >> 10;						    u1 = ((u << 11) + (u << 4)) >> 10;						    						    y = 128 +buf [iny + mx];						    /* top pixel Right */																		pic[r_offset] = GTable[7][CLIP ((y + v1))];									pic[g_offset] = GTable[8][CLIP ((y - rg))];									pic[b_offset] = GTable[9][CLIP ((y + u1))];									pic += bpp;						    /* top pixel Left */						    y = 128 +buf [iny + mx +1];									pic[r_offset] = GTable[7][CLIP ((y + v1))];									pic[g_offset] = GTable[8][CLIP ((y - rg))];									pic[b_offset] = GTable[9][CLIP ((y + u1))];									pic += bpp;						    /* bottom pixel Right */						    y1 = 128 + buf [iny1 + mx];									pic1[r_offset] = GTable[7][CLIP ((y1 + v1))];									pic1[g_offset] = GTable[8][CLIP ((y1 - rg))];									pic1[b_offset] = GTable[9][CLIP ((y1 + u1))];									pic1 += bpp;						    /* bottom pixel Left */						    y1 = 128 + buf [iny1 + mx + 1];									pic1[r_offset] = GTable[7][CLIP ((y1 + v1))];									pic1[g_offset] = GTable[8][CLIP ((y1 - rg))];									pic1[b_offset] = GTable[9][CLIP ((y1 + u1))];									pic1 += bpp;						    						    						    						    					  } // end test decode					} // end mx loop					iny += nextinline;					inuv += nextinline ;					inv += nextinline ;					iny1 += nextinline;					if (my >= cropy1){						/* are we in a decode surface move the output pointer */						pic += nextoutline;						pic1 += nextoutline;					}									} // end my loop			}			myframe->scanlength = (long)(softwidth*softheight*bpp);			break;		case VIDEO_PALETTE_YUV420P:			{				/* initialize */				pic1 = pic + softwidth;								for ( my =0; my < height; my += 2){					for ( mx = 0, pocx=0; mx < width ; mx +=2, pocx++){					/* test if we need to decode */					  if ((my >= cropy1)						    && (my < height - cropy2)						    && (mx >= cropx1)						    && (mx < width - cropx2)) {						    /* yes decode */						    *V++ = 128 + buf [inuv + pocx];						    *U++ = 128 + buf [inv + pocx] ;						    *pic++ = 128 +buf [iny + mx];						    *pic++ = 128 +buf [iny + mx+1];						    *pic1++ = 128 + buf [iny1 + mx];						    *pic1++ = 128 + buf [iny1 + mx +1];						    					  } // end test decode					} // end mx loop					iny += nextinline;					inuv += nextinline;					inv += nextinline;					iny1 += nextinline;									if (my >= cropy1){						/* are we in a decode surface move the output pointer */						pic += softwidth;						pic1 += softwidth;					}									} // end my loop											}			myframe->scanlength = (long)(softwidth*softheight*3)>>1;			break;		default:			break;	}// end case	return 0;}/* *    linux/drivers/video/fbcon-jpegdec.c - a tiny jpeg decoder. *       *      (w) August 2001 by Michael Schroeder, <mls@suse.de> * *    I severly gutted this beast and hardcoded it to the palette and subset *    of jpeg needed for the spca50x driver. Also converted it from K&R style *    C to a more modern form ;). Michael can't be blamed for what is left. *    All nice features are his, all bugs are mine. - till * *    Change color space converter for YUVP and RGB -   *    Rework the IDCT implementation for best speed, cut test in the loop but instead *	more copy and paste code :) *    For more details about idct look at : *    http://rnvs.informatik.tu-chemnitz.de/~jan/MPEG/HTML/IDCT.html  *    12/12/2003 mxhaard@magic.fr *	add make jpeg from header (mxhaard 20/09/2004) *	add jpeg_decode for 422 stream (mxhaard 01/10/2004)        */static intjpeg_decode411 (struct spca50x_frame *myframe, int force_rgb){	int mcusx, mcusy, mx, my;		int *dcts = myframe->dcts;		int *out =myframe->out;		int *max=myframe->max;	int i;	int bpp;	int framesize, frameUsize;	int k, j;	int nextline, nextuv, nextblk, nextnewline;	unsigned char *pic0, *pic1, *outv, *outu;	__u16 *pix1,*pix2;	int picy, picx, pocx, pocy;	unsigned char *U, *V;	int *outy, *inv, *inu;	int outy1, outy2;	int v, u, y1, v1, u1, u2;	int r_offset, g_offset, b_offset;		unsigned char *pic = myframe->data; /* output surface */	unsigned char *buf = myframe->tmpbuffer; /* input surface */	int width = myframe->hdrwidth; 

⌨️ 快捷键说明

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