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

📄 spcadecoder.c

📁 spca5xx video for linux (v4l) driver
💻 C
📖 第 1 页 / 共 5 页
字号:
	t1 = tmp[j + 1];	t2 = tmp[j + 2];	t3 = tmp[j + 3];	t4 = tmp[j + 4];	t5 = tmp[j + 5];	t6 = tmp[j + 6];	t7 = tmp[j + 7];	if ((t1 | t2 | t3 | t4 | t5 | t6 | t7) == 0) {	    te = ITOINT(t0);	    out[j + 0] = te;	    out[j + 1] = te;	    out[j + 2] = te;	    out[j + 3] = te;	    out[j + 4] = te;	    out[j + 5] = te;	    out[j + 6] = te;	    out[j + 7] = te;	    j += 8;	    continue;	}	//IDCT;	tmp0 = t0 + t1;	t1 = t0 - t1;	tmp2 = t2 - t3;	t3 = t2 + t3;	tmp2 = IMULT(tmp2, IC4) - t3;	tmp3 = tmp0 + t3;	t3 = tmp0 - t3;	tmp1 = t1 + tmp2;	tmp2 = t1 - tmp2;	tmp4 = t4 - t7;	t7 = t4 + t7;	tmp5 = t5 + t6;	t6 = t5 - t6;	tmp6 = tmp5 - t7;	t7 = tmp5 + t7;	tmp5 = IMULT(tmp6, IC4);	tmp6 = IMULT((tmp4 + t6), S22);	tmp4 = IMULT(tmp4, (C22 - S22)) + tmp6;	t6 = IMULT(t6, (C22 + S22)) - tmp6;	t6 = t6 - t7;	t5 = tmp5 - t6;	t4 = tmp4 - t5;	out[j + 0] = ITOINT(tmp3 + t7);	out[j + 1] = ITOINT(tmp1 + t6);	out[j + 2] = ITOINT(tmp2 + t5);	out[j + 3] = ITOINT(t3 + t4);	out[j + 4] = ITOINT(t3 - t4);	out[j + 5] = ITOINT(tmp2 - t5);	out[j + 6] = ITOINT(tmp1 - t6);	out[j + 7] = ITOINT(tmp3 - t7);	j += 8;    }}static unsigned char zig[64] = {    0, 1, 5, 6, 14, 15, 27, 28,    2, 4, 7, 13, 16, 26, 29, 42,    3, 8, 12, 17, 25, 30, 41, 43,    9, 11, 18, 24, 31, 40, 44, 53,    10, 19, 23, 32, 39, 45, 52, 54,    20, 22, 33, 38, 46, 51, 55, 60,    21, 34, 37, 47, 50, 56, 59, 61,    35, 36, 48, 49, 57, 58, 62, 63};static int aaidct[8] = {    IFIX(0.3535533906), IFIX(0.4903926402),    IFIX(0.4619397663), IFIX(0.4157348062),    IFIX(0.3535533906), IFIX(0.2777851165),    IFIX(0.1913417162), IFIX(0.0975451610)};inline static void idctqtab(unsigned char *qin, int *qout){    int i, j;    for (i = 0; i < 8; i++)	for (j = 0; j < 8; j++)	    qout[zig[i * 8 + j]] = qin[zig[i * 8 + j]] *		IMULT(aaidct[i], aaidct[j]);}inline static void scaleidctqtab(int *q, int sc){    int i;    for (i = 0; i < 64; i++)	q[i] = IMULT(q[i], sc);}/* Reduce to the necessary minimum. FIXME */void init_qTable(struct usb_spca50x *spca50x, unsigned int qIndex){    int i, j;    /* set up a quantization table */    for (i = 0; i < 2; i++) {	for (j = 0; j < 64; j++) {	    spca50x->maindecode.quant[i][j] =		GsmartQTable[qIndex * 2 + i][j];	}    }    idctqtab(spca50x->maindecode.	     quant[spca50x->maindecode.dscans[0].tq],	     spca50x->maindecode.dquant[0]);    idctqtab(spca50x->maindecode.	     quant[spca50x->maindecode.dscans[1].tq],	     spca50x->maindecode.dquant[1]);    idctqtab(spca50x->maindecode.	     quant[spca50x->maindecode.dscans[2].tq],	     spca50x->maindecode.dquant[2]);    /* rescale qtab */    //scaleidctqtab (spca50x->maindecode.dquant[0], IFIX (0.7));    //scaleidctqtab (spca50x->maindecode.dquant[1], IFIX (0.7));    //scaleidctqtab (spca50x->maindecode.dquant[2], IFIX (0.7));    }void init_jpeg_decoder(struct usb_spca50x *spca50x){    unsigned int i, j, k, l;    int tc, th, tt, tac, tdc;    unsigned char *ptr;    unsigned int qIndex = spca50x->qindex;    memcpy(spca50x->maindecode.comps, comp_template,	   MAXCOMP * sizeof(struct comp));    /* set up the huffman table */    ptr = (unsigned char *) GsmartJPEGHuffmanTable;    l = GSMART_JPG_HUFFMAN_TABLE_LENGTH;    while (l > 0) {	int hufflen[16];	unsigned char huffvals[256];	tc = *ptr++;	th = tc & 15;	tc >>= 4;	tt = tc * 2 + th;	if (tc > 1 || th > 1) {	    //printf("died whilst setting up huffman table.\n");	    //abort();	}	for (i = 0; i < 16; i++)	    hufflen[i] = *ptr++;	l -= 1 + 16;	k = 0;	for (i = 0; i < 16; i++) {	    for (j = 0; j < (unsigned int) hufflen[i]; j++)		huffvals[k++] = *ptr++;	    l -= hufflen[i];	}	dec_makehuff(dhuff + tt, hufflen, huffvals);    }    /* set up the scan table */    ptr = (unsigned char *) GsmartJPEGScanTable;    for (i = 0; i < 3; i++) {	spca50x->maindecode.dscans[i].cid = *ptr++;	tdc = *ptr++;	tac = tdc & 15;	tdc >>= 4;	if (tdc > 1 || tac > 1) {	    //printf("died whilst setting up scan table.\n");	    //abort();	}	/* for each component */	for (j = 0; j < 3; j++)	    if (spca50x->maindecode.comps[j].cid ==		spca50x->maindecode.dscans[i].cid)		break;	spca50x->maindecode.dscans[i].hv = spca50x->maindecode.comps[j].hv;	spca50x->maindecode.dscans[i].tq = spca50x->maindecode.comps[j].tq;	spca50x->maindecode.dscans[i].hudc.dhuff = dec_huffdc + tdc;	spca50x->maindecode.dscans[i].huac.dhuff = dec_huffac + tac;    }    if (spca50x->maindecode.dscans[0].cid != 1 ||	spca50x->maindecode.dscans[1].cid != 2 ||	spca50x->maindecode.dscans[2].cid != 3) {	//printf("invalid cid found.\n");	//abort();    }    if (spca50x->maindecode.dscans[0].hv != 0x22 ||	spca50x->maindecode.dscans[1].hv != 0x11 ||	spca50x->maindecode.dscans[2].hv != 0x11) {	//printf("invalid hv found.\n");	//abort();    }    spca50x->maindecode.dscans[0].next = 6 - 4;    spca50x->maindecode.dscans[1].next = 6 - 4 - 1;    spca50x->maindecode.dscans[2].next = 6 - 4 - 1 - 1;	/* 411 encoding */    /* set up a quantization table */    init_qTable(spca50x, qIndex);}static int bgr = 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 */    struct pictparam *gCorrect = &myframe->pictsetting;    unsigned char *red = myframe->decoder->Red;    unsigned char *green = myframe->decoder->Green;    unsigned char *blue = myframe->decoder->Blue;    int width = 0;    int height = 0;    int done = 0;    int i;    if (gCorrect->change) {	if (gCorrect->change == 0x01) {	    /* Gamma setting change compute all case */	    memcpy(red, &GTable[gCorrect->gamma], 256);	    memcpy(green, &GTable[gCorrect->gamma], 256);	    memcpy(blue, &GTable[gCorrect->gamma], 256);	    for (i = 0; i < 256; i++) {		red[i] =		    CLIP(((red[i] +			   gCorrect->OffRed) * gCorrect->GRed) >> 8);		green[i] =		    CLIP(((green[i] +			   gCorrect->OffGreen) * gCorrect->GGreen) >> 8);		blue[i] =		    CLIP(((blue[i] +			   gCorrect->OffBlue) * gCorrect->GBlue) >> 8);	    }	    bgr = gCorrect->force_rgb;	    gCorrect->change = 0x00;	}	if (gCorrect->change == 0x02) {	    /* Red setting change compute Red Value */	    memcpy(red, &GTable[gCorrect->gamma], 256);	    for (i = 0; i < 256; i++) {		red[i] =		    CLIP(((red[i] +			   gCorrect->OffRed) * gCorrect->GRed) >> 8);	    }	    gCorrect->change &= ~0x02;	}	if (gCorrect->change == 0x04) {	    /* Green setting change compute Green Value */	    memcpy(green, &GTable[gCorrect->gamma], 256);	    for (i = 0; i < 256; i++) {		green[i] =		    CLIP(((green[i] +			   gCorrect->OffGreen) * gCorrect->GGreen) >> 8);	    }	    gCorrect->change &= ~0x04;	}	if (gCorrect->change == 0x08) {	    /* Blue setting change compute Blue Value */	    memcpy(blue, &GTable[gCorrect->gamma], 256);	    for (i = 0; i < 256; i++) {		blue[i] =		    CLIP(((blue[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	    myframe->decoder->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	    myframe->decoder->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 JPGM:    case JPGS:	// reset info.dri	myframe->decoder->info.dri = 0;	memcpy(myframe->tmpbuffer, myframe->data, myframe->scanlength);	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 PGBRG:	done = pixart_decompress(myframe);	if (done < 0)	    break;	done = bayer_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 S561:	if (myframe->data[1] & 0x10)	    decode_spca561(myframe->data, myframe->tmpbuffer,			   myframe->width, myframe->height);	else	    memcpy(myframe->tmpbuffer, myframe->data + 20,		   myframe->scanlength);	done = bayer_decode(myframe, bgr);	break;    case SN9C:	sonix_decompress(myframe);	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;    unsigned char *red = myframe->decoder->Red;    unsigned char *green = myframe->decoder->Green;    unsigned char *blue = myframe->decoder->Blue;    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;		   /********* in

⌨️ 快捷键说明

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