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

📄 pwc-dec23.c

📁 webcam device driver
💻 C
📖 第 1 页 / 共 2 页
字号:
 *   . G . G . G . G . G . G . G *   . . . . . . . . . . . . . . *   . G . G . G . G . G . G . G *   . . . . . . . . . . . . . . *   or *   . . . . . . . . . . . . . . *   G . G . G . G . G . G . G . *   . . . . . . . . . . . . . . *   G . G . G . G . G . G . G .*/static void copy_image_block_Green(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits){#if UNROLL_LOOP_FOR_COPY	/* Unroll all loops */	const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;	unsigned char *d = dst;	const int *c = src;	d[0] = cm[c[0] >> scalebits];	d[2] = cm[c[1] >> scalebits];	d[4] = cm[c[2] >> scalebits];	d[6] = cm[c[3] >> scalebits];	d[8] = cm[c[4] >> scalebits];	d[10] = cm[c[5] >> scalebits];	d[12] = cm[c[6] >> scalebits];	d[14] = cm[c[7] >> scalebits];	d = dst + bytes_per_line;	d[0] = cm[c[8] >> scalebits];	d[2] = cm[c[9] >> scalebits];	d[4] = cm[c[10] >> scalebits];	d[6] = cm[c[11] >> scalebits];	d[8] = cm[c[12] >> scalebits];	d[10] = cm[c[13] >> scalebits];	d[12] = cm[c[14] >> scalebits];	d[14] = cm[c[15] >> scalebits];#else	int i;	unsigned char *d;	const int *c = src;	d = dst;	for (i = 0; i < 8; i++, c++)		d[i*2] = CLAMP((*c) >> scalebits);	d = dst + bytes_per_line;	for (i = 0; i < 8; i++, c++)		d[i*2] = CLAMP((*c) >> scalebits);#endif}#endif#if ENABLE_BAYER_DECODER/* * Format: 4x4 pixels *   R . R . R . R *   . B . B . B . *   R . R . R . R *   . B . B . B . */static void copy_image_block_RedBlue(const int *src, unsigned char *dst, unsigned int bytes_per_line, unsigned int scalebits){#if UNROLL_LOOP_FOR_COPY	/* Unroll all loops */	const unsigned char *cm = pwc_crop_table+MAX_OUTER_CROP_VALUE;	unsigned char *d = dst;	const int *c = src;	d[0] = cm[c[0] >> scalebits];	d[2] = cm[c[1] >> scalebits];	d[4] = cm[c[2] >> scalebits];	d[6] = cm[c[3] >> scalebits];	d = dst + bytes_per_line;	d[1] = cm[c[4] >> scalebits];	d[3] = cm[c[5] >> scalebits];	d[5] = cm[c[6] >> scalebits];	d[7] = cm[c[7] >> scalebits];	d = dst + bytes_per_line*2;	d[0] = cm[c[8] >> scalebits];	d[2] = cm[c[9] >> scalebits];	d[4] = cm[c[10] >> scalebits];	d[6] = cm[c[11] >> scalebits];	d = dst + bytes_per_line*3;	d[1] = cm[c[12] >> scalebits];	d[3] = cm[c[13] >> scalebits];	d[5] = cm[c[14] >> scalebits];	d[7] = cm[c[15] >> scalebits];#else	int i;	unsigned char *d;	const int *c = src;	d = dst;	for (i = 0; i < 4; i++, c++)		d[i*2] = CLAMP((*c) >> scalebits);	d = dst + bytes_per_line;	for (i = 0; i < 4; i++, c++)		d[i*2+1] = CLAMP((*c) >> scalebits);	d = dst + bytes_per_line*2;	for (i = 0; i < 4; i++, c++)		d[i*2] = CLAMP((*c) >> scalebits);	d = dst + bytes_per_line*3;	for (i = 0; i < 4; i++, c++)		d[i*2+1] = CLAMP((*c) >> scalebits);#endif}#endif/* * To manage the stream, we keep bits in a 32 bits register. * fill_nbits(n): fill the reservoir with at least n bits * skip_bits(n): discard n bits from the reservoir * get_bits(n): fill the reservoir, returns the first n bits and discard the *              bits from the reservoir. * __get_nbits(n): faster version of get_bits(n), but asumes that the reservoir *                 contains at least n bits. bits returned is discarded. */#define fill_nbits(pdec, nbits_wanted) do { \   while (pdec->nbits_in_reservoir<(nbits_wanted)) \    { \      pdec->reservoir |= (*(pdec->stream)++) << (pdec->nbits_in_reservoir); \      pdec->nbits_in_reservoir += 8; \    } \}  while(0);#define skip_nbits(pdec, nbits_to_skip) do { \   pdec->reservoir >>= (nbits_to_skip); \   pdec->nbits_in_reservoir -= (nbits_to_skip); \}  while(0);#define get_nbits(pdec, nbits_wanted, result) do { \   fill_nbits(pdec, nbits_wanted); \   result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \   skip_nbits(pdec, nbits_wanted); \}  while(0);#define __get_nbits(pdec, nbits_wanted, result) do { \   result = (pdec->reservoir) & ((1U<<(nbits_wanted))-1); \   skip_nbits(pdec, nbits_wanted); \}  while(0);#define look_nbits(pdec, nbits_wanted) \   ((pdec->reservoir) & ((1U<<(nbits_wanted))-1))/* * Decode a 4x4 pixel block */static void decode_block(struct pwc_dec23_private *pdec,			 const unsigned char *ptable0004,			 const unsigned char *ptable8004){	unsigned int primary_color;	unsigned int channel_v, offset1, op;	int i;	fill_nbits(pdec, 16);	__get_nbits(pdec, pdec->nbits, primary_color);	if (look_nbits(pdec,2) == 0) {		skip_nbits(pdec, 2);		/* Very simple, the color is the same for all pixels of the square */		for (i = 0; i < 16; i++)			pdec->temp_colors[i] = pdec->table_dc00[primary_color];		return;	}	/* This block is encoded with small pattern */	for (i = 0; i < 16; i++)		pdec->temp_colors[i] = pdec->table_d800[primary_color];	__get_nbits(pdec, 3, channel_v);	channel_v = ((channel_v & 1) << 2) | (channel_v & 2) | ((channel_v & 4) >> 2);	ptable0004 += (channel_v * 128);	ptable8004 += (channel_v * 32);	offset1 = 0;	do	{		unsigned int htable_idx, rows = 0;		const unsigned int *block;		/* [  zzzz y x x ]		 *     xx == 00 :=> end of the block def, remove the two bits from the stream		 *    yxx == 111		 *    yxx == any other value		 *    		 */		fill_nbits(pdec, 16);		htable_idx = look_nbits(pdec, 6);		op = hash_table_ops[htable_idx * 4];		if (op == 2) {			skip_nbits(pdec, 2);		} else if (op == 1) {			/* 15bits [ xxxx xxxx yyyy 111 ]			 * yyy => offset in the table8004			 * xxx => offset in the tabled004 (tree)			 */			unsigned int mask, shift;			unsigned int nbits, col1;			unsigned int yyyy;			skip_nbits(pdec, 3);			/* offset1 += yyyy */			__get_nbits(pdec, 4, yyyy);			offset1 += 1 + yyyy;			offset1 &= 0x0F;			nbits = ptable8004[offset1 * 2];			/* col1 = xxxx xxxx */			__get_nbits(pdec, nbits+1, col1);			/* Bit mask table */			mask = pdec->table_bitpowermask[nbits][col1];			shift = ptable8004[offset1 * 2 + 1];			rows = ((mask << shift) + 0x80) & 0xFF;			block = pdec->table_subblock[rows];			for (i = 0; i < 16; i++)				pdec->temp_colors[i] += block[MulIdx[offset1][i]];		} else {			/* op == 0			 * offset1 is coded on 3 bits			 */    			unsigned int shift;			offset1 += hash_table_ops [htable_idx * 4 + 2];			offset1 &= 0x0F;			rows = ptable0004[offset1 + hash_table_ops [htable_idx * 4 + 3]];			block = pdec->table_subblock[rows];			for (i = 0; i < 16; i++)				pdec->temp_colors[i] += block[MulIdx[offset1][i]];			shift = hash_table_ops[htable_idx * 4 + 1];			skip_nbits(pdec, shift);		}	} while (op != 2);}static void DecompressBand23(struct pwc_dec23_private *pdec,			     const unsigned char *rawyuv,			     unsigned char *planar_y,			     unsigned char *planar_u,			     unsigned char *planar_v,			     unsigned int   compressed_image_width,			     unsigned int   real_image_width){	int compression_index, nblocks;	const unsigned char *ptable0004;	const unsigned char *ptable8004;	pdec->reservoir = 0;	pdec->nbits_in_reservoir = 0;	pdec->stream = rawyuv + 1;	/* The first byte of the stream is skipped */	get_nbits(pdec, 4, compression_index);	/* pass 1: uncompress Y component */	nblocks = compressed_image_width / 4;	ptable0004 = pdec->table_0004_pass1[compression_index];	ptable8004 = pdec->table_8004_pass1[compression_index];	/* Each block decode a square of 4x4 */	while (nblocks) {		decode_block(pdec, ptable0004, ptable8004);		copy_image_block_Y(pdec->temp_colors, planar_y, real_image_width, pdec->scalebits);		planar_y += 4;		nblocks--;	}	/* pass 2: uncompress UV component */	nblocks = compressed_image_width / 8;	ptable0004 = pdec->table_0004_pass2[compression_index];	ptable8004 = pdec->table_8004_pass2[compression_index];	/* Each block decode a square of 4x4 */	while (nblocks) {		decode_block(pdec, ptable0004, ptable8004);		copy_image_block_CrCb(pdec->temp_colors, planar_u, real_image_width/2, pdec->scalebits);		decode_block(pdec, ptable0004, ptable8004);		copy_image_block_CrCb(pdec->temp_colors, planar_v, real_image_width/2, pdec->scalebits);		planar_v += 8;		planar_u += 8;		nblocks -= 2;	}}#if ENABLE_BAYER_DECODER/* * Size need to be a multiple of 8 in width * * Return a block of four line encoded like this: * *   G R G R G R G R G R G R G R G R *   B G B G B G B G B G B G B G B G *   G R G R G R G R G R G R G R G R *   B G B G B G B G B G B G B G B G *  */static void DecompressBandBayer(struct pwc_dec23_private *pdec,    				const unsigned char *rawyuv,				unsigned char *rgbbayer,				unsigned int   compressed_image_width,				unsigned int   real_image_width){	int compression_index, nblocks;	const unsigned char *ptable0004;	const unsigned char *ptable8004;	unsigned char *dest;	pdec->reservoir = 0;	pdec->nbits_in_reservoir = 0;	pdec->stream = rawyuv + 1;	/* The first byte of the stream is skipped */	get_nbits(pdec, 4, compression_index);	/* pass 1: uncompress RB component */	nblocks = compressed_image_width / 4;	ptable0004 = pdec->table_0004_pass1[compression_index];	ptable8004 = pdec->table_8004_pass1[compression_index];	dest = rgbbayer;	/* Each block decode a square of 4x4 */	while (nblocks) {		decode_block(pdec, ptable0004, ptable8004);		copy_image_block_RedBlue(pdec->temp_colors, rgbbayer, real_image_width, pdec->scalebits);		dest += 8;		nblocks--;	}	/* pass 2: uncompress G component */	nblocks = compressed_image_width / 8;	ptable0004 = pdec->table_0004_pass2[compression_index];	ptable8004 = pdec->table_8004_pass2[compression_index];	/* Each block decode a square of 4x4 */	while (nblocks) {		decode_block(pdec, ptable0004, ptable8004);		copy_image_block_Green(pdec->temp_colors, rgbbayer+1, real_image_width, pdec->scalebits);		decode_block(pdec, ptable0004, ptable8004);		copy_image_block_Green(pdec->temp_colors, rgbbayer+real_image_width, real_image_width, pdec->scalebits);		rgbbayer += 16;		nblocks -= 2;	}}#endif/** * * Uncompress a pwc23 buffer. * * pwc.view: size of the image wanted * pwc.image: size of the image returned by the camera * pwc.offset: (x,y) to displayer image in the view * * src: raw data * dst: image output * flags: PWCX_FLAG_PLANAR or PWCX_FLAG_BAYER */void pwc_dec23_decompress(const struct pwc_device *pwc,			  const void *src,			  void *dst,			  int flags){	int bandlines_left, stride, bytes_per_block;	bandlines_left = pwc->image.y / 4;	bytes_per_block = pwc->view.x * 4;	if (flags & PWCX_FLAG_BAYER) {#if ENABLE_BAYER_DECODER		/* RGB Bayer format */		unsigned char *rgbout;		stride = pwc->view.x * pwc->offset.y;		rgbout = dst + stride + pwc->offset.x;		while (bandlines_left--) {			DecompressBandBayer(pwc->decompress_data,					    src,					    rgbout,					    pwc->image.x, pwc->view.x);			src += pwc->vbandlength;			rgbout += bytes_per_block;		}	#else		memcpy(dst, 0, pwc->view.x * pwc->view.y);#endif	} else {		/* YUV420P image format */		unsigned char *pout_planar_y;		unsigned char *pout_planar_u;		unsigned char *pout_planar_v;		unsigned int   plane_size;		plane_size = pwc->view.x * pwc->view.y;		/* offset in Y plane */		stride = pwc->view.x * pwc->offset.y;		pout_planar_y = dst + stride + pwc->offset.x;		/* offsets in U/V planes */		stride = (pwc->view.x * pwc->offset.y) / 4 + pwc->offset.x / 2;		pout_planar_u = dst + plane_size + stride;		pout_planar_v = dst + plane_size + plane_size / 4 + stride;		while (bandlines_left--) {			DecompressBand23(pwc->decompress_data,				         src,					 pout_planar_y, pout_planar_u, pout_planar_v,					 pwc->image.x, pwc->view.x);			src += pwc->vbandlength;			pout_planar_y += bytes_per_block;			pout_planar_u += pwc->view.x;			pout_planar_v += pwc->view.x;		}		}}void pwc_dec23_exit(void){	/* Do nothing */}/** * Allocate a private structure used by lookup table. * You must call kfree() to free the memory allocated. */int pwc_dec23_alloc(struct pwc_device *pwc){	pwc->decompress_data = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL);	if (pwc->decompress_data == NULL)		return -ENOMEM;	return 0;}/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */

⌨️ 快捷键说明

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