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

📄 ov511_decomp.c

📁 0v511摄像头linux最新驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:

	/*****************
	 **** IDCT 1D ****
	 *****************/

#define IDCT_1D(c0, c1, c2, c3, in)					\
	do {								\
		tmp1=((c0)*DeZigZag[in])+((c2)*DeZigZag[(in)+2]);	\
		tmp2=(c1)*DeZigZag[(in)+1];				\
		tmp3=(c3)*DeZigZag[(in)+3];				\
	} while (0)

#define COMPOSE_1(out1, out2)		\
	do {				\
		tmp=tmp1+tmp2+tmp3;	\
		temp[out1] = tmp>>15;	\
		tmp=tmp1-tmp2-tmp3;	\
		temp[out2] = tmp>>15;	\
	} while (0)

#define COMPOSE_2(out1, out2)		\
	do {				\
		tmp=tmp1+tmp2-tmp3;	\
		temp[out1] = tmp>>15;	\
		tmp=tmp1-tmp2+tmp3;	\
		temp[out2] = tmp>>15;	\
	} while (0)

	/* j = 0 */
	IDCT_1D(a, b,  c, d,  0); COMPOSE_1( 0, 56);
	IDCT_1D(a, b,  c, d,  8); COMPOSE_1( 1, 57);
	IDCT_1D(a, b,  c, d, 16); COMPOSE_1( 2, 58);
	IDCT_1D(a, b,  c, d, 24); COMPOSE_1( 3, 59);

	/* j = 1 */
	IDCT_1D(a, d,  f, g,  0); COMPOSE_2( 8, 48);
	IDCT_1D(a, d,  f, g,  8); COMPOSE_2( 9, 49);
	IDCT_1D(a, d,  f, g, 16); COMPOSE_2(10, 50);
	IDCT_1D(a, d,  f, g, 24); COMPOSE_2(11, 51);

	/* j = 2 */
	IDCT_1D(a, e, -f, b,  0); COMPOSE_2(16, 40);
	IDCT_1D(a, e, -f, b,  8); COMPOSE_2(17, 41);
	IDCT_1D(a, e, -f, b, 16); COMPOSE_2(18, 42);
	IDCT_1D(a, e, -f, b, 24); COMPOSE_2(19, 43);

	/* j = 3 */
	IDCT_1D(a, g, -c, e,  0); COMPOSE_2(24, 32);
	IDCT_1D(a, g, -c, e,  8); COMPOSE_2(25, 33);
	IDCT_1D(a, g, -c, e, 16); COMPOSE_2(26, 34);
	IDCT_1D(a, g, -c, e, 24); COMPOSE_2(27, 35);

#undef IDCT_1D
#undef COMPOSE_1
#undef COMPOSE_2

	/*****************
	 **** IDCT 2D ****
	 *****************/

#define IDCT_2D(c0, c1, c2, c3, in)				\
	do {							\
		tmp = temp[in]*(c0) + temp[(in)+1]*(c1)		\
		    + temp[(in)+2]*(c2) + temp[(in)+3]*(c3);	\
	} while (0)

#define STORE(i)				\
	do {					\
		tmp = tmp >> 15;		\
		tmp = tmp + 128;		\
		if (tmp > 255) tmp = 255;	\
		if (tmp < 0)   tmp = 0;		\
		pOut[i] = (unsigned char) tmp;	\
	} while (0)

#define IDCT_2D_ROW(in)						\
	do {							\
		IDCT_2D(a,  b,  c,  d, in); STORE(0+out_idx);	\
		IDCT_2D(a,  d,  f, -g, in); STORE(1+out_idx);	\
		IDCT_2D(a,  e, -f, -b, in); STORE(2+out_idx);	\
		IDCT_2D(a,  g, -c, -e, in); STORE(3+out_idx);	\
		IDCT_2D(a, -g, -c,  e, in); STORE(4+out_idx);	\
		IDCT_2D(a, -e, -f,  b, in); STORE(5+out_idx);	\
		IDCT_2D(a, -d,  f,  g, in); STORE(6+out_idx);	\
		IDCT_2D(a, -b,  c, -d, in); STORE(7+out_idx);	\
	} while (0)


#define IDCT_2D_FAST(c0, c1, c2, c3, in)			\
	do {							\
		tmp1=((c0)*temp[in])+((c2)*temp[(in)+2]);	\
		tmp2=(c1)*temp[(in)+1];				\
		tmp3=(c3)*temp[(in)+3];				\
	} while (0)

#define STORE_FAST_1(out1, out2)				\
	do {							\
		tmp=tmp1+tmp2+tmp3;				\
		STORE((out1)+out_idx);				\
		tmp=tmp1-tmp2-tmp3;				\
		STORE((out2)+out_idx);				\
	} while (0)

#define STORE_FAST_2(out1, out2)				\
	do {							\
		tmp=tmp1+tmp2-tmp3;				\
		STORE((out1)+out_idx);				\
		tmp=tmp1-tmp2+tmp3;				\
		STORE((out2)+out_idx);				\
	} while (0)

#define IDCT_2D_FAST_ROW(in)						\
	do {								\
		IDCT_2D_FAST(a, b,  c, d, in);	STORE_FAST_1(0, 7);	\
		IDCT_2D_FAST(a, d,  f, g, in);	STORE_FAST_2(1, 6);	\
		IDCT_2D_FAST(a, e, -f, b, in);	STORE_FAST_2(2, 5);	\
		IDCT_2D_FAST(a, g, -c, e, in);	STORE_FAST_2(3, 4);	\
	} while (0)

	out_idx = out_pos;

	IDCT_2D_ROW(0);		out_idx += w;
	IDCT_2D_ROW(8);		out_idx += w;
	IDCT_2D_ROW(16);	out_idx += w;
	IDCT_2D_ROW(24);	out_idx += w;
	IDCT_2D_ROW(32);	out_idx += w;
	IDCT_2D_ROW(40);	out_idx += w;
	IDCT_2D_FAST_ROW(48);	out_idx += w;
	IDCT_2D_FAST_ROW(56);

	*iIn = in_pos;
	*iOut = out_pos + 8;
}

#define DECOMP_Y() DecompressYHI(pIn, pY, &iIn, &iY, w, 1)

#define DECOMP_U() DecompressYHI(pIn, pU, &iIn, &iU, w/2, 2)

#define DECOMP_V() DecompressYHI(pIn, pV, &iIn, &iV, w/2, 2)

inline static int
Decompress400HiNoMMX(unsigned char *pIn,
		     unsigned char *pOut,
		     const int      w,
		     const int      h,
		     const int      inSize)
{
	unsigned char *pY = pOut;
	int x, y, iIn, iY;

	iIn = 0;
	for (y = 0; y < h; y += 8) {
		iY = w*y;

		for (x = 0; x < w; x += 8)
			DECOMP_Y();
	}

	return 0;
}

inline static int
Decompress420HiNoMMX(unsigned char *pIn,
		     unsigned char *pOut,
		     const int      w,
		     const int      h,
		     const int      inSize)
{
	unsigned char *pY = pOut;
	unsigned char *pU = pY + w*h;
	unsigned char *pV = pU + w*h/4;
	int xY, xUV, iY, iU, iV, iIn, count;
	const int nBlocks = (w*h) / (32*8);

	iIn = 0;
	iY = iU = iV = 0;
	xY = xUV = 0;

	for (count = 0; count < nBlocks; count++) {
			DECOMP_U();
			DECOMP_V(); xUV += 16;
			if (xUV >= w) {
				iU += (w*7)/2;
				iV += (w*7)/2;
				xUV = 0;
			}

			DECOMP_Y();	xY += 8;
			DECOMP_Y();	xY += 8;
			if (xY >= w) {
				iY += w*7;
				xY = 0;
			}
			DECOMP_Y();	xY += 8;
			DECOMP_Y();	xY += 8;
			if (xY >= w) {
				iY += w*7;
				xY = 0;
			}
	}

	return 0;
}

/* Input format is raw isoc. data (with header and packet
 * number stripped, and all-zero blocks removed).
 * Output format is YUV400
 * Returns uncompressed data length if success, or zero if error
 */
static int
Decompress400(unsigned char *pIn,
	      unsigned char *pOut,
	      unsigned char *pTmp,
	      int	     w,
	      int	     h,
	      int	     inSize)
{
	int numpix = w * h;
	int rc;

	PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize);

	rc = Decompress400HiNoMMX(pIn, pOut, w, h, inSize);

	if (rc)
		return 0;

	return numpix;
}

/* Input format is raw isoc. data (with header and packet
 * number stripped, and all-zero blocks removed).
 * Output format is planar YUV420
 * Returns uncompressed data length if success, or zero if error
 */
static int
Decompress420(unsigned char *pIn,
	      unsigned char *pOut,
	      unsigned char *pTmp,
	      int	     w,
	      int	     h,
	      int	     inSize)
{
	int numpix = w * h;
	int rc;

	PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize);

	rc = Decompress420HiNoMMX(pIn, pOut, w, h, inSize);

	if (rc)
		return 0;

/* Disabled by Mark */
#if 0
	/* For color saturation 8/22/00 */
	{
		long u , v;
		unsigned char *pU = pOut + numpix;
		unsigned char *pV = pU + numpix/4;
		for (int i = 0; i < numpix/4; i++) {
			u = (long)*pU;
			v = (long)*pV;
			u -= 128;
			v -= 128;
			u = (u * 577) >> 10;
			v = (v * 730) >> 10;
			u += 128;
			v += 128;
			*pU++ = (unsigned char)u;
			*pV++ = (unsigned char)v;
/*   u=0.564 */
/*   v=0.713 */
		}
	}
#endif

	return (numpix * 3 / 2);
}

/******************************************************************************
 * Module Functions
 ******************************************************************************/

static struct ov51x_decomp_ops decomp_ops = {
	.decomp_400 =	Decompress400,
	.decomp_420 =	Decompress420,
	.owner =	THIS_MODULE,
};

static int __init
decomp_init(void)
{
	int rc;

	EXPORT_NO_SYMBOLS;

	rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops,
					  ov518, mmx);
	if (rc) {
		err("Could not register with ov511 (rc=%d)", rc);
		return -1;
	}

	info(DRIVER_VERSION " : " DRIVER_DESC);

	return 0;
}

static void __exit
decomp_exit(void)
{
	ov511_deregister_decomp_module(ov518, mmx);
	info("deregistered\n");
}

module_init(decomp_init);
module_exit(decomp_exit);

⌨️ 快捷键说明

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