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

📄 cc.cpp

📁 ati driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************//	File:			CC.cpp//	Description:	Closed caption module.//	Copyright 2001, Carlos Hasan/*******************************************************************************/#include <stdio.h>#include <Debug.h>#include "CC.h"CCaption::CCaption(CCapture & capture)	:	fCapture(capture),		fChannel(C_RADEON_CC1),		fRow(0),		fColumn(0),		fColor(0),		fLastControlCode(0){	for (int row = 0; row < C_RADEON_CC_ROWS; row++) {		for (int column = 0; column < C_RADEON_CC_COLUMNS; column++) {			fText[row][column] = fDisplayText[row][column] = 0x0000;		}	}}CCaption::~CCaption(){}status_t CCaption::InitCheck() const{	return fCapture.InitCheck();}void CCaption::SetMode(cc_mode mode){	fChannel = mode;	fLastControlCode = 0;}bool CCaption::DecodeBits(const unsigned char * buffer, int & data){	// assume the buffer is long enough (at least VBI line width bytes)	if (buffer == NULL)		return false;	// compute low/high levels	int low = 0xff, high = 0x00;	for (int offset = C_RADEON_CC_BLANK_START; offset < C_RADEON_CC_BLANK_START + 4 * C_RADEON_CC_BIT_DURATION; offset++) {		if (low > buffer[offset])			low = buffer[offset];		if (high < buffer[offset])			high = buffer[offset];	}	if (low + C_RADEON_CC_LEVEL_THRESHOLD >= high)		return false;	const int middle = (low + high) >> 1;		// find position of the first pulse	int start = C_RADEON_CC_BLANK_START + C_RADEON_CC_BIT_DURATION;	while (start <= C_RADEON_CC_BLANK_START + 4 * C_RADEON_CC_BIT_DURATION) {		if (buffer[start + 0] < middle && buffer[start + 1] < middle &&			buffer[start + 3] > middle && buffer[start + 4] > middle)			break;		start++;	}	if (start >= C_RADEON_CC_BLANK_START + 4 * C_RADEON_CC_BIT_DURATION)		return false;	// compute position of the last pulse	int end = start + 17 * C_RADEON_CC_BIT_DURATION;	// start in middle of first pulse	int bit = 0;	bool one = true;	for (int offset = start + C_RADEON_CC_BIT_DURATION / 2; offset < end; offset++) {		int width = 1;				// search the next pulse front		while (offset < end) {			if (one) {				if (buffer[offset + 0] > middle && buffer[offset + 1] > middle &&					buffer[offset + 3] < middle && buffer[offset + 4] < middle)					break;			}			else {				if (buffer[offset + 0] < middle && buffer[offset + 1] < middle &&					buffer[offset + 3] > middle && buffer[offset + 4] > middle)					break;			}			offset++;			width++;		}		// compute pulse width in bits		const int nbits = (width + (bit == 0 ? 0 : bit == 15 ? C_RADEON_CC_BIT_DURATION :			C_RADEON_CC_BIT_DURATION / 2)) / C_RADEON_CC_BIT_DURATION;		data >>= nbits;		if (one)			data |= (0xffff << (16 - nbits)) & 0xffff;				if ((bit += nbits) >= C_RADEON_CC_BITS_PER_FIELD)			break;				one = !one;	}		if (bit != C_RADEON_CC_BITS_PER_FIELD)		return false;	return true;}bool CCaption::Decode(const unsigned char * buffer0,							const unsigned char * buffer1){	enum caption_code {		/* channel */		C_CC1		= 0x0000,		C_CC2		= 0x0800,				/* address */		C_ROW_1		= 0x0100,		C_ROW_2		= 0x0120,		C_ROW_3		= 0x0200,		C_ROW_4		= 0x0220,		C_ROW_5		= 0x0500,		C_ROW_6		= 0x0520,		C_ROW_7		= 0x0600,		C_ROW_8		= 0x0620,		C_ROW_9		= 0x0700,		C_ROW_10	= 0x0720,		C_ROW_11	= 0x0000,		C_ROW_12	= 0x0300,		C_ROW_13	= 0x0320,		C_ROW_14	= 0x0400,		C_ROW_15	= 0x0420,						/* color */		C_WHITE		= 0x0000,		C_GREEN		= 0x0002,		C_BLUE		= 0x0004,		C_CYAN		= 0x0006,		C_RED		= 0x0008,		C_YELLOW	= 0x000a,		C_MAGENTA	= 0x000c,		C_ITALICS	= 0x000e,				/* underline */		C_NORMAL	= 0x0000,		C_UNDERLINE	= 0x0001,				/* control */		C_RCL		= 0x0000,	// resume caption loading		C_BS		= 0x0001,	// backspace		C_AOF		= 0x0002,	// alarm off		C_AON		= 0x0003,	// alarm on		C_DER		= 0x0004,	// delete to end of row		C_RU2		= 0x0005,	// roll-up captions (2 rows)		C_RU3		= 0x0006,	// roll-up captions (3 rows)		C_RU4		= 0x0007,	// roll-up captions (4 rows)		C_FON		= 0x0008,	// flash on		C_RDC		= 0x0009,	// resume direct captioning		C_TR		= 0x000a,	// text restart		C_RTD		= 0x000b,	// resume text display		C_EDM		= 0x000c,	// erase displayed memory		C_CR		= 0x000d,	// carriage return		C_ENM		= 0x000e,	// erase non-displayed memory		C_EOC		= 0x000f,	// end of caption				/* special character */		C_reg		= 0x0000,	// registered		C_deg		= 0x0001,	// degree		C_frac12	= 0x0002,	// fraction 1/2		C_iquest	= 0x0003,	// invert question		C_trademark	= 0x0004,	// trademark		C_cent		= 0x0005,	// cent		C_pound		= 0x0006,	// pound		C_music		= 0x0007,	// music note		C_agrave	= 0x0008,	// agrave		C_tspace	= 0x0009,	// transparent space		C_egrave	= 0x000a,	// egrave		C_acirc		= 0x000b,	// a circ		C_ecirc		= 0x000c,	// e circ		C_icirc		= 0x000d,	// i circ		C_ocirc		= 0x000e,	// o circ		C_ucirc		= 0x000f,	// u circ				/* standard character (ASCII) */		C_aacute	= 0x002a,	// a acute accent		C_eacute	= 0x005c,	// e acute accent		C_iacute	= 0x005e,	// i acute accent		C_oacute	= 0x005f,	// o acute accent		C_uacute	= 0x0060,	// u acute accent		C_ccedil	= 0x007b,	// c cedilla		C_division	= 0x007c,	// division sign		C_Ntilde	= 0x007d,	// N tilde		C_ntilde	= 0x007e,	// n tilde		C_block		= 0x007f	// solid block	};		int code, channel, character;		/* decode next pair of bytes from the odd or even field buffer */	if (!DecodeBits(fChannel == C_RADEON_CC1 || fChannel == C_RADEON_CC2 ? buffer0 : buffer1, code))		return false;		/* swap decoded bytes */	code = ((code << 8) & 0xff00) | ((code >> 8) & 0x00ff);	/* check parity */	for (int bit = 0; bit < 7; bit++) {		if ((code & (0x0001 << bit)) != 0)			code ^= 0x0080;		if ((code & (0x0100 << bit)) != 0)			code ^= 0x8000;	}	if ((code & 0x8080) != 0x8080) {		PRINT(("CCaption::Decode() - parity error (%04X)\n", code));		return false;	}			/* check channel number */	channel = (code & 0x0800) >> 12;	if (channel == 0) {		if (fChannel != C_RADEON_CC1 && fChannel != C_RADEON_CC3) {			PRINT(("CCaption::Decode() - ignore channel (%02X)\n", code & 0x7f7f));			return false;		}	}	else {		if (fChannel != C_RADEON_CC2 && fChannel != C_RADEON_CC4) {			PRINT(("CCaption::Decode() - ignore channel (%02X)\n", code & 0x7f7f));			return false;		}	}	if ((code & 0x7000) == 0x0000) {		/* one-byte standard character (0?XX) */		character = code & 0x007f;				if (character >= 0x20) {					PRINT(("%c", character));						fText[fRow][fColumn] = (fColor << 8) + character;			if (fColumn < C_RADEON_CC_COLUMNS - 1)				fColumn++;		}		else if (character != 0x00) {			PRINT(("<%04X>", code & 0x7f7f));		}	}	else if ((code & 0x7770) == 0x1120) {		/* middle row code (112X) */		fColor = code & 0x000f;				fText[fRow][fColumn] = (fColor << 8) + ' ';		if (fColumn < C_RADEON_CC_COLUMNS - 1)			fColumn++;				switch (fColor & 0x000e) {		case C_WHITE:			PRINT(("<white"));			break;		case C_GREEN:			PRINT(("<green"));			break;		case C_BLUE:			PRINT(("<blue"));			break;		case C_CYAN:			PRINT(("<cyan"));			break;		case C_RED:			PRINT(("<red"));			break;		case C_YELLOW:			PRINT(("<yellow"));			break;		case C_MAGENTA:			PRINT(("<magenta"));			break;		case C_ITALICS:			PRINT(("<italics"));			break;		}		if ((fColor & 0x0001) != 0)			PRINT((",underline>"));		else			PRINT((">"));	}	else if ((code & 0x7770) == 0x1130) {		/* two-byte special character (113X) */		character = (code & 0x000f);		fText[fRow][fColumn] = (fColor << 8) + character + 0x0080;		if (fColumn < C_RADEON_CC_COLUMNS - 1)			fColumn++;				switch (character) {		case C_reg:			PRINT(("&reg;"));			break;		case C_deg:			PRINT(("&deg;"));			break;		case C_frac12:			PRINT(("&frac12;"));			break;		case C_iquest:			PRINT(("&iquest;"));			break;		case C_trademark:			PRINT(("&trademark;"));			break;		case C_cent:			PRINT(("&cent;"));			break;		case C_pound:			PRINT(("&pound;"));			break;		case C_music:			PRINT(("&music;"));			break;		case C_agrave:			PRINT(("&agrave;"));			break;		case C_tspace:			PRINT(("&tspace;"));			break;		case C_egrave:			PRINT(("&egrave;"));			break;		case C_acirc:			PRINT(("&acirc;"));			break;		case C_ecirc:			PRINT(("&ecirc;"));			break;		case C_icirc:			PRINT(("&icirc;"));			break;		case C_ocirc:			PRINT(("&ocirc;"));			break;		case C_ucirc:			PRINT(("&ucirc;"));			break;		default:			PRINT(("<special=%04X>", code & 0x7f7f));			break;		}	}	else if ((code & 0x7770) == 0x1420) {			if (code == fLastControlCode)			return false;		fLastControlCode = code;				/* miscellaneous control code (142X) */		switch (code & 0x000f) {		case C_RCL:			// resume caption loading			PRINT(("<rcl>"));			break;					case C_BS:			// backspace			PRINT(("<bs>"));			if (fColumn > 0)				fText[fRow][--fColumn] = 0x0000;			break;					case C_AOF:			// alarm off			PRINT(("<aof>"));			break;					case C_AON:			// alarm on			PRINT(("<aon>"));			break;					case C_DER:			// delete to end of row			PRINT(("<der>"));			for (int column = fColumn; column < C_RADEON_CC_COLUMNS; column++)				fText[fRow][column] = 0x0000;			break;					case C_RU2:			// rollup captions (2 rows)			PRINT(("<ru2>"));			for (int row = 0; row < C_RADEON_CC_ROWS - 2; row++) {				for (int column = 0; column < C_RADEON_CC_COLUMNS; column++)					fText[row][column] = fText[row + 2][column];			}			for (int row = C_RADEON_CC_ROWS - 2; row < C_RADEON_CC_ROWS; row++) {				for (int column = 0; column < C_RADEON_CC_COLUMNS; column++)					fText[row][column] = 0x0000;			}			break;		case C_RU3:			// rollup captions (3 rows)			PRINT(("<ru3>"));			for (int row = 0; row < C_RADEON_CC_ROWS - 3; row++) {				for (int column = 0; column < C_RADEON_CC_COLUMNS; column++)					fText[row][column] = fText[row + 2][column];

⌨️ 快捷键说明

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