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

📄 spcadecoder.c

📁 用于LINUX摄像头的相关程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************#	 	spcadecoder: Generic decoder for various input stream yyuv  ## yuyv yuvy jpeg bayer rggb with gamma correct                              ## and various output palette rgb16 rgb24 rgb32 yuv420p                      ## various output size with crop feature                                     ## 		Copyright (C) 2003 Michel Xhaard   mxhaard@magic.fr         ##                                                                           ## 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA ##                                                                           #****************************************************************************/#ifndef __KERNEL__#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <stdint.h>#include <sys/types.h>#else /* __KERNEL__ */#include <linux/string.h>#endif /* __KERNEL__ *//* FIXME */#define __u8 uint8_t#define __u16 uint16_t#define __u32 uint32_t#include "spcadecoder.h"#include "jpeg_header.h"#include "spcagamma.h"#include "spca50x.h"//int spca50x_outpicture (struct spca50x_frame *myframe, int force_rgb, int gCorrect);int spca50x_outpicture (struct spca50x_frame *myframe,int force_rgb,struct pictparam *gCorrect);static int jpeg_decode(struct spca50x_frame *myframe, int force_rgb);static int yuv_decode(struct spca50x_frame *myframe, int force_rgb);static int bayer_decode(struct spca50x_frame *myframe, int force_rgb);inline static void idct (int *, int *, int *, long, int);inline static void decode_mcus (struct in *, int *, int, struct scan *, int *);static void dec_makehuff (struct dec_hufftbl *, int *, unsigned char *);static void idctqtab (unsigned char *, int *);static void scaleidctqtab (int *, int);/*	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	Gtable[7][n] -> Red conponent after Correction	Gtable[8][n] -> Green conponent after Correction	Gtable[9][n] -> Blue conponent after Correction*///static int gCor = 2; static struct comp comps[MAXCOMP] = {	{0x01, 0x22, 0x00},	{0x02, 0x11, 0x01},	{0x03, 0x11, 0x01},	{0x00, 0x00, 0x00}};static struct scan dscans[MAXCOMP];static unsigned char quant[4][64];static struct dec_hufftbl dhuff[4];#define dec_huffdc (dhuff + 0)#define dec_huffac (dhuff + 2)static struct in in;int dquant[3][64];voidjpeg_reset_input_context (unsigned char *buf){	/* set input context */	in.p = buf;	in.left = 0;	in.bits = 0;	in.marker = 0;}#define CLIP(color) (unsigned char)((color>0xFF)?0xff:((color<0)?0:color))int spca50x_outpicture (struct spca50x_frame *myframe, int force_rgb,struct pictparam *gCorrect){	/* 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;	// gCor = gCorrect;	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);	}	} else 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);	}	} else 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);		}	} else 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 = 0 ;	switch(myframe->cameratype){		case JPEG: done = jpeg_decode( myframe, force_rgb);		break;		case YUVY: 		case YUYV: 		case YYUV: done = yuv_decode( myframe, force_rgb);		break;		case GBRG: done = bayer_decode( myframe, force_rgb);		break;	default : done = -1;	break;	}return done;	}static int yuv_decode(struct spca50x_frame *myframe, int force_rgb ){	int cropx1,cropx2,cropy1,cropy2;	int r_offset, g_offset, b_offset;	int my , mx; /* scan input surface */	unsigned char *pic, *pic1; /* output surface */	__u16 *pix1,*pix2; /* same for 16 bits output */	unsigned char *buf; /* input surface */	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;	int width; 	int height;	int softwidth;	int softheight;	int method;	int format;	int bpp;	int framesize, frameUsize;	/* init usefull data */	pic = myframe->data;	buf = myframe->tmpbuffer;	width = myframe->hdrwidth;	height = myframe->hdrheight;	softwidth = myframe->width;	softheight = myframe->height;	method = myframe->method;	format = myframe->format;	cropx1 = myframe->cropx1;	cropx2 = myframe->cropx2;	cropy1 = myframe->cropy1;	cropy2 = myframe->cropy2;	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						}			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			}			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											}			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  *    For more details about idct look at : *    http://rnvs.informatik.tu-chemnitz.de/~jan/MPEG/HTML/IDCT.html  *    12/12/2003 mxhaard@magic.fr        */static intjpeg_decode (struct spca50x_frame *myframe, int force_rgb){	int mcusx, mcusy, mx, my;	int dcts[6 * 64 + 16];	int out[64 * 6];	int max[6];	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;	int cropx1,cropx2,cropy1,cropy2;	unsigned char *pic;	unsigned char *buf;	int width; 	int height;	int softwidth;	int softheight;	int method;	int format;	/* init usefull data */	pic = myframe->data;	buf = myframe->tmpbuffer;	width = myframe->hdrwidth;	height = myframe->hdrheight;	softwidth = myframe->width;	softheight = myframe->height;	method = myframe->method;	format = myframe->format;	cropx1 = myframe->cropx1;	cropx2 = myframe->cropx2;	cropy1 = myframe->cropy1;	cropy2 = myframe->cropy2;	if ((height & 15) || (width & 15))		return 1;	if (width < softwidth || height < softheight)		return 1;		mcusx = width >> 4;	mcusy = height >> 4;	framesize = softwidth * softheight;	frameUsize = framesize >> 2;	jpeg_reset_input_context (buf);	/* for each component. Reset dc values. */	for (i = 0; i < 3; i++)		dscans[i].dc = 0;	/* 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;	}	/* Decode to the correct format. */	switch (format) {		case VIDEO_PALETTE_RGB565:			{	bpp = 2;				nextline = ((softwidth << 1) - 16);// *bpp;				nextblk = bpp * (softwidth << 4);				nextnewline = softwidth ; // *bpp;				for (my = 0, picy = 0; my < mcusy; my++) {					for (mx = 0, picx = 0; mx < mcusx; mx++) {						decode_mcus (&in, dcts, 6,							     dscans, max);						if ((my >= cropy1)						    && (my < mcusy - cropy2)						    && (mx >= cropx1)						    && (mx < mcusx - cropx2)) {							idct (dcts, out,							      dquant[0],							      IFIX (128.5),

⌨️ 快捷键说明

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