gspcadecoder.c

来自「Linux下很强大的万能USB摄像头驱动。解压后」· C语言 代码 · 共 2,167 行 · 第 1/5 页

C
2,167
字号
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255, 255, 255, 255, 255,	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,	255    };    // abs_clamp15[19 + i] = min(abs(i), 15)    const static int abs_clamp15[] =	{ 15, 15, 15, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,	2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15,	15    };    // diff_encoding[256 + i] = ...    const static int diff_encoding[] =	{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7,	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5,	5, 5, 5, 5, 5, 3, 3,	3, 3, 1, 1, 0, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,	6, 6, 6, 6, 6, 6    };    int block;    int bitfill = 0;    int xwidth = width + 6;    int off_up_right = 2 - 2 * xwidth;    int off_up_left = -2 - 2 * xwidth;    int pixel_U = 0, saved_pixel_UR = 0;    int pixel_x = 0, pixel_y = 2;    unsigned char *output_ptr = outbuf;    memset(i_hits, 0, sizeof(i_hits));    memset(accum, 0, sizeof(accum));    memcpy(outbuf + xwidth * 2 + 3, inbuf + 0x14, width);    memcpy(outbuf + xwidth * 3 + 3, inbuf + 0x14 + width, width);    input_ptr = inbuf + 0x14 + width * 2;    output_ptr = outbuf + (xwidth) * 4 + 3;    bit_bucket = 0;    for (block = 0; block < ((height - 2) * width) / 32; ++block) {	int b_it, var_7 = 0;	int cur_byte;	refill(&bitfill);	cur_byte = (bit_bucket >> (bitfill & 7)) & 0xff;	if ((cur_byte & 0x80) == 0) {	    var_7 = 0;	    bitfill--;	} else if ((cur_byte & 0xC0) == 0x80) {	    var_7 = 1;	    bitfill -= 2;	} else if ((cur_byte & 0xc0) == 0xc0) {	    var_7 = 2;	    bitfill -= 2;	}	for (b_it = 0; b_it < 32; b_it++) {	    int index;	    int pixel_L, pixel_UR, pixel_UL;	    int multiplier;	    int dL, dC, dR;	    int gkw;		// God knows what	    refill(&bitfill);	    cur_byte = bit_bucket >> (bitfill & 7) & 0xff;	    pixel_L = output_ptr[-2];	    pixel_UR = output_ptr[off_up_right];	    pixel_UL = output_ptr[off_up_left];	    dL = diff_encoding[0x100 + pixel_UL - pixel_L];	    dC = diff_encoding[0x100 + pixel_U - pixel_UL];	    dR = diff_encoding[0x100 + pixel_UR - pixel_U];	    if (pixel_x < 2) {		pixel_L = pixel_UL = pixel_U = output_ptr[-xwidth * 2];		pixel_UR = output_ptr[off_up_right];		dL = dC = 0;		dR = diff_encoding[0x100 + pixel_UR - pixel_U];	    } else if (pixel_x > width - 3)		dR = 0;	    multiplier = 4;	    index = dR + dC * 8 + dL * 64;	    if (pixel_L + pixel_U * 2 <= 144		&& (pixel_y & 1) == 0		&& (b_it & 3) == 0 && (dR < 5) && (dC < 5) && (dL < 5)) {		multiplier = 1;	    } else if (pixel_L <= 48		       && dL <= 4 && dC <= 4 && dL >= 1 && dC >= 1) {		multiplier = 2;	    } else if (var_7 == 1) {		multiplier = 2;	    } else if (dC + dL >= 11 || var_7 == 2) {		multiplier = 8;	    }	    if (i_hits[index] < 7) {		bitfill -= nbits_A[cur_byte];		gkw = tab_A[cur_byte];		if (gkw == 0xfe)		    gkw = fun_A(&bitfill);	    } else if (i_hits[index] >= accum[index]) {		bitfill -= nbits_B[cur_byte];		gkw = tab_B[cur_byte];		if (cur_byte == 0)		    gkw = fun_B(&bitfill);	    } else if (i_hits[index] * 2 >= accum[index]) {		bitfill -= nbits_C[cur_byte];		gkw = tab_C[cur_byte];		if (cur_byte < 2)		    gkw = fun_C(&bitfill, gkw);	    } else if (i_hits[index] * 4 >= accum[index]) {		bitfill -= nbits_D[cur_byte];		gkw = tab_D[cur_byte];		if (cur_byte < 4)		    gkw = fun_D(&bitfill, gkw);	    } else if (i_hits[index] * 8 >= accum[index]) {		gkw = fun_E(cur_byte, &bitfill);	    } else {		gkw = fun_F(cur_byte, &bitfill);	    }	    if (gkw == 0xff)		return -3;	    {		int tmp1, tmp2;		tmp1 = (pixel_U + pixel_L) * 3 - pixel_UL * 2;		tmp1 += (tmp1 < 0) ? 3 : 0;		tmp2 = a_curve[19 + gkw] * multiplier;		tmp2 += (tmp2 < 0) ? 1 : 0;		*(output_ptr++) =		    clamp0_255[0x100 + (tmp1 >> 2) - (tmp2 >> 1)];	    }	    pixel_U = saved_pixel_UR;	    saved_pixel_UR = pixel_UR;	    if (++pixel_x == width) {		output_ptr += 6;		pixel_x = 0;		pixel_y++;	    }	    accum[index] += abs_clamp15[19 + gkw];	    if (i_hits[index]++ == 15) {		i_hits[index] = 8;		accum[index] /= 2;	    }	}    }    return 0;}staticvoid decode_spca561(unsigned char *inbuf, char *outbuf, int width,		    int height){    int i;    static char tmpbuf[650 * 490];    if (internal_spca561_decode(width, height, inbuf, tmpbuf) == 0) {	for (i = 0; i < height; i++)	    memcpy(outbuf + i * width,		   tmpbuf + (i + 2) * (width + 6) + 3, width);    }}/****************************************************************//**************       huffman decoder             ***************//****************************************************************//*need to be on init jpeg */static struct comp comp_template[MAXCOMP] = {    {0x01, 0x22, 0x00},    {0x02, 0x11, 0x01},    {0x03, 0x11, 0x01},    {0x00, 0x00, 0x00}};/* deprecated set by webcam now in spca50x *///static struct scan dscans[MAXCOMP];//static unsigned char quant[3][64];//static struct in in;//int dquant[3][64];//static struct jpginfo info;/* table de Huffman global for all */static struct dec_hufftbl dhuff[4];#define dec_huffdc (dhuff + 0)#define dec_huffac (dhuff + 2)#define M_RST0	0xd0static int fillbits(struct in *, int, unsigned int);static int dec_rec2(struct in *, struct dec_hufftbl *, int *, int, int);static int fillbits(struct in *in, int le, unsigned int bi){    int b;    int m;    if (in->marker) {	if (le <= 16)	    in->bits = bi << 16, le += 16;	return le;    }    while (le <= 24) {	b = *in->p++;	if (in->omitescape) {	    if (b == 0xff && (m = *in->p++) != 0) {		in->marker = m;		if (le <= 16)		    bi = bi << 16, le += 16;		break;	    }	}	bi = bi << 8 | b;	le += 8;    }    in->bits = bi;		/* tmp... 2 return values needed */    return le;}#define LEBI_GET(in)	(le = in->left, bi = in->bits)#define LEBI_PUT(in)	(in->left = le, in->bits = bi)#define GETBITS(in, n) (					\  (le < (n) ? le = fillbits(in, le, bi), bi = in->bits : 0),	\  (le -= (n)),							\  bi >> le & ((1 << (n)) - 1)					\)#define UNGETBITS(in, n) (	\  le += (n)			\)static void dec_initscans(struct dec_data *decode){    struct jpginfo *info = &decode->info;    struct scan *dscans = decode->dscans;    int i;    info->ns = 3;		// HARDCODED  here    info->nm = info->dri + 1;	// macroblock count    info->rm = M_RST0;    for (i = 0; i < info->ns; i++)	dscans[i].dc = 0;}static int dec_readmarker(struct in *in){    int m;    in->left = fillbits(in, in->left, in->bits);    if ((m = in->marker) == 0)	return 0;    in->left = 0;    in->marker = 0;    return m;}static int dec_checkmarker(struct dec_data *decode){    struct jpginfo *info = &decode->info;    struct scan *dscans = decode->dscans;    struct in *in = &decode->in;    int i;    if (dec_readmarker(in) != info->rm)	return -1;    info->nm = info->dri;    info->rm = (info->rm + 1) & ~0x08;    for (i = 0; i < info->ns; i++)	dscans[i].dc = 0;    return 0;}staticvoidjpeg_reset_input_context(struct dec_data *decode, unsigned char *buf,			 int oescap){    /* set input context */    struct in *in = &decode->in;    in->p = buf;    in->omitescape = oescap;    in->left = 0;    in->bits = 0;    in->marker = 0;}static intdec_rec2(struct in *in, struct dec_hufftbl *hu, int *runp, int c, int i){    int le, bi;    le = in->left;    bi = in->bits;    if (i) {	UNGETBITS(in, i & 127);	*runp = i >> 8 & 15;	i >>= 16;    } else {	for (i = DECBITS;	     (c = ((c << 1) | GETBITS(in, 1))) >= (hu->maxcode[i]); i++);	if (i >= 16) {	    in->marker = M_BADHUFF;	    return 0;	}	i = hu->vals[hu->valptr[i] + c - hu->maxcode[i - 1] * 2];	*runp = i >> 4;	i &= 15;    }    if (i == 0) {		/* sigh, 0xf0 is 11 bit */	LEBI_PUT(in);	return 0;    }    /* receive part */    c = GETBITS(in, i);    if (c < (1 << (i - 1)))	c += (-1 << i) + 1;    LEBI_PUT(in);    return c;}#define DEC_REC(in, hu, r, i)	 (	\  r = GETBITS(in, DECBITS),		\  i = hu->llvals[r],			\  i & 128 ?				\    (					\      UNGETBITS(in, i & 127),		\      r = i >> 8 & 15,			\      i >> 16				\    )					\  :					\    (					\      LEBI_PUT(in),			\      i = dec_rec2(in, hu, &r, r, i),	\      LEBI_GET(in),			\      i					\    )					\)inline static voiddecode_mcus(struct in *in, int *dct, int n, struct scan *sc, int *maxp){    struct dec_hufftbl *hu;    int i, r, t;    int le, bi;    memset(dct, 0, n * 64 * sizeof(*dct));    le = in->left;    bi = in->bits;    while (n-- > 0) {	hu = sc->hudc.dhuff;	*dct++ = (sc->dc += DEC_REC(in, hu, r, t));	hu = sc->huac.dhuff;	i = 63;	while (i > 0) {	    t = DEC_REC(in, hu, r, t);	    if (t == 0 && r == 0) {		dct += i;		break;	    }	    dct += r;	    *dct++ = t;	    i -= r + 1;

⌨️ 快捷键说明

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