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

📄 faxfile.cpp

📁 fax engine 传真引擎 relay fax 的开源项目 商业软件使用 高质量 高可靠
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		for( j = 0; j < 8; j++, b >>= 1 )
		{
			bit = (b & 0x01);

			if( bit )
			{
				//char szMsg[80];
				//wsprintf( szMsg, "Resending Seq=%d\n", nSeqNum );
				//OutputDebugString( szMsg );

				unsigned int nOffset = (256 * m_nBlockCount + nSeqNum) * m_nECMFrameSize;

				memcpy( m_ECMBuffer.GetData(), m_MemFile.GetData( nOffset ), m_nECMFrameSize ); ;

				nZeroBitDeleteCntr = 0;

				m_ECMBuffer.InitFrame();
				m_ECMBuffer.SetLastSeq( nSeqNum );

				AddFCDHeader();

				for( k = 0; k < m_nECMFrameSize; k++ )
				{
					AddByte( s_FlipTable[m_ECMBuffer.GetData()[k]], true );
				}

				unsigned short wFCS = m_ECMBuffer.GetFCS();
				AddByte( wFCS & 0xff, false );
				AddByte( (wFCS >> 8) & 0xff, false );

				AddFlag(); // FLAG
			}

			nSeqNum++;

			// Ignore any sequence numbers which we didn't transmit
			if( nSeqNum > m_ECMBuffer.GetHighestSeq() )
			{
				break;
			}
		}
		if( nSeqNum > m_ECMBuffer.GetHighestSeq() )
		{
			break;
		}
	}

	AddRCPFrames();

	*m_PagePtr++ = DLE;
	*m_PagePtr++ = ETX;

	m_PageBufferSize = m_PagePtr - m_PageBuffer;

	return true;
}


//////////////////////////////////////////////////////////////////////
// AddRCPFrames
//////////////////////////////////////////////////////////////////////
void CFaxFile::AddRCPFrames(void)
{
	int i;

	for( i = 0; i < 3; i++ )
	{
		m_ECMBuffer.InitFrame();
		AddByte( 0xff, true );
		AddByte( 0x03, true );
		AddByte( RCP, true );

		unsigned short wFCS = m_ECMBuffer.GetFCS();
		AddByte( wFCS & 0xff, false );
		AddByte( (wFCS >> 8) & 0xff, false );

		AddFlag(); // FLAG
	}

	// output the last byte
	while( nBitCntr > 0 )
	{
		AddBit( 0 );
	}
}


//////////////////////////////////////////////////////////////////////
// AddFCDHeader
//////////////////////////////////////////////////////////////////////
void CFaxFile::AddFCDHeader(void)
{
	AddByte( 0xff, true );
	AddByte( 0x03, true );
	AddByte( FCD, true );
	AddByte( (unsigned char) m_ECMBuffer.GetLastSeq(), true );
	m_ECMBuffer.IncrementLastSeq();
}


//////////////////////////////////////////////////////////////////////
// AddByte
//////////////////////////////////////////////////////////////////////
void CFaxFile::AddByte( unsigned char b, bool bCalcFCS )
{
	int i;
	BYTE bit;

	if( bCalcFCS )
	{
		m_ECMBuffer.CalcFCS( b );
	}

	for( i = 0; i < 8; i++, b >>= 1 )
	{
		bit = (b & 0x01);

		AddBit( bit );

		nZeroBitDeleteCntr = (bit == 1) ? (nZeroBitDeleteCntr + 1) : 0;

		if( nZeroBitDeleteCntr == 5 )
		{
			nZeroBitDeleteCntr = 0;

			AddBit( 0 );
		}
	}
}


//////////////////////////////////////////////////////////////////////
// AddFlag
//////////////////////////////////////////////////////////////////////
void CFaxFile::AddFlag( void )
{
	BYTE b = HDLC_FLAG;
	BYTE bit;
	int i;

	nZeroBitDeleteCntr = 0;

	for( i = 0; i < 8; i++, b >>= 1 )
	{
		bit = (b & 0x01);
		AddBit( bit );
	}
}


//////////////////////////////////////////////////////////////////////
// AddBit
//////////////////////////////////////////////////////////////////////
void CFaxFile::AddBit( unsigned char bit )
{
	nOctet = (nOctet << 1) + bit;
	nBitCntr++;
	
	if( nBitCntr >= 8 )
	{
		nOctet = s_FlipTable[nOctet];

		*m_PagePtr++ = nOctet;
		
		if( nOctet == DLE )
		{
			*m_PagePtr++ = nOctet;
		}
		nOctet = 0;
		nBitCntr = 0;
	}
}

//////////////////////////////////////////////////////////////////////
// ReadNextHeader
//////////////////////////////////////////////////////////////////////
bool CFaxFile::ReadNextHeader(void)
{
	m_PageCount++;
	m_nBlockCount = 0;

	if( TIFFReadDirectory( m_tiff ) == 0 )
		return false;

	ReadIfd();

	return true;
}


//////////////////////////////////////////////////////////////////////
// Close
//////////////////////////////////////////////////////////////////////
void CFaxFile::Close(void)
{
	if( m_bGotData )
	{
		WriteIFD();
	}

	m_PageCount = 0;

	if( m_PageBuffer != NULL )
	{
		delete[] m_PageBuffer;
		m_PageBuffer = NULL;
	}

	if( m_tiff )
	{
		TIFFClose( m_tiff );
		m_tiff = NULL;
	}

	if( m_bFileHasData == false )
	{
		remove( m_sFaxFile.c_str() );
	}
}


//////////////////////////////////////////////////////////////////////
// SetImageRes
//////////////////////////////////////////////////////////////////////
void CFaxFile::SetImageRes( bool bHiRes )
{
	yres = (bHiRes) ? 196.0f : 98.0f;
}

//////////////////////////////////////////////////////////////////////
// SetImageWidth
//////////////////////////////////////////////////////////////////////
void CFaxFile::SetImageWidth( int nWidth )
{
	width = nWidth;
}

//////////////////////////////////////////////////////////////////////
// SetImageLength
//////////////////////////////////////////////////////////////////////
void CFaxFile::SetImageLength( int nLength )
{
	length = nLength;
}


//////////////////////////////////////////////////////////////////////
// IncrementImageLength
//////////////////////////////////////////////////////////////////////
void CFaxFile::IncrementImageLength( int n )
{
	length += n;
}


//////////////////////////////////////////////////////////////////////
// SetImageCompression
//////////////////////////////////////////////////////////////////////
void CFaxFile::SetImageCompression( int nCompression )
{
	compression = nCompression;

}

//////////////////////////////////////////////////////////////////////
// SetT4Options
//////////////////////////////////////////////////////////////////////
void CFaxFile::SetT4Options( int nOptions )
{
	g3opts = nOptions;
}



//////////////////////////////////////////////////////////////////////
// WriteFileHeader
//////////////////////////////////////////////////////////////////////
bool CFaxFile::WriteFileHeader(void)
{
	if( m_tiff == NULL )
	{
		m_tiff = TIFFOpen( m_sFaxFile.c_str(), "w" );

		if( m_tiff == NULL )
		{
			return false;
		}
	}

	m_bFileHasData = false;
	m_bGotData = false;
	m_bFoundStartOfPage = false;
	m_bFoundEndOfPage = false;
	m_bFoundStartOfFrame = false;
	nZcnt = 0;
	nRTCCnt = 0;
	nBitCntr = 0;
	nZeroBitDeleteCntr = 0;
	m_PageCount = 0;

	return true;
}


//////////////////////////////////////////////////////////////////////
// WriteBuffer
//////////////////////////////////////////////////////////////////////
bool CFaxFile::WriteBuffer( unsigned char* szBuffer, unsigned int nBytes, bool bFlipBytes )
{
	int nNewBytes =0 ;
	int i;
	BYTE lastByte;

	if( nBytes > 0 ) 
	{
		m_bGotData = true;
	}

	for (i = 0; i < nBytes; i++ )
	{
		BYTE b = (bFlipBytes) ? s_FlipTable[szBuffer[i]] : szBuffer[i];

		if( compression == 4 )
		{
			m_MemFile.AddDataByte( b );
		}
		else
		{
			if( !m_bFoundEndOfPage )
			{
				if (nZcnt) 
				{
					nZcnt += s_LeadZero[b];
					if (b && (nZcnt < 11)) 
					{
						nRTCCnt = 0;
						nZcnt = s_TrailZero[b];
					}
				}
				else 
				{
					nZcnt = s_TrailZero[b];
					if (!nZcnt) nRTCCnt = 0;
				}

				if( (nNewBytes > 0) && (lastByte == 0) && (nZcnt > 18) )
				{
					nNewBytes--; // skip last byte
					nZcnt -= 8;
				}

				if( (nZcnt > 10) && (b != 0) )
				{
					if( !m_bFoundStartOfPage )
					{
						m_bFoundStartOfPage = true;
						m_MemFile.AddDataByte( 0 );
						m_MemFile.AddDataByte( 0 );
						IncrementImageLength();
					}
					else
					{
						nRTCCnt++;
						if (nRTCCnt > 5) 
						{
							//OutputDebugString( "Found RTC!\n" );
							IncrementImageLength( -5 );
							m_bFoundEndOfPage = true;
							m_MemFile.AddDataByte( b );  // stuff in the last byte
						}
						else
						{
							IncrementImageLength();
						}
					}	
					nZcnt = s_TrailZero[b];
				}
			}

			if( m_bFoundStartOfPage && !m_bFoundEndOfPage )
			{
				m_MemFile.AddDataByte( b );
				lastByte = b;
			}
		}
	}		

//	char szMsg[100];
//	wsprintf( szMsg, "Writing Fax Data, nBytes=%d, nNewBytes=%d\n", nBytes, nNewBytes );
//	OutputDebugString( szMsg );

	return true;
}


//////////////////////////////////////////////////////////////////////
// WriteECMBuffer
//////////////////////////////////////////////////////////////////////
bool CFaxFile::WriteECMBuffer( unsigned char* szBuffer, unsigned int nBytes )
{
	int i,j;
	BYTE bit;

	//char szMsg[180];
	//wsprintf( szMsg, "Writing ECM Fax Data, nBytes=%d\n", nBytes );
	//OutputDebugString( szMsg );

	if( nBytes > 0 ) 
	{
		m_bGotData = true;
	}

	for (i = 0; i < nBytes; i++ )
	{
		//BYTE b = fliptable[szBuffer[i]];
		BYTE b = szBuffer[i];

		//char szMsg1[80];
		//wsprintf( szMsg1, "%04d: {%02X}\n", i, b );
		//OutputDebugString( szMsg1 );

		for( j = 0; j < 8; j++, b >>= 1 )
		{
			bit = (b & 0x01);

			// look for flags
			if( !m_bFoundStartOfPage )
			{
				if( (nBitCntr == 0) || (nBitCntr == 7) )
				{
					nBitCntr = (bit == 0) ? (nBitCntr + 1) : 0;
				}
				else
				{
					nBitCntr = (bit == 1) ? (nBitCntr + 1) : 0;
				}

				if (nBitCntr == 8 )
				{
					//wsprintf( szMsg, "Found a flag %d\n", i );
					//OutputDebugString( szMsg );
					nBitCntr = 0;
					nOctet = 0;
					nZeroBitDeleteCntr = 0;
					m_ECMBuffer.InitFrame();
					m_bFoundStartOfPage = true;
				}
			}
			else if( !m_bFoundStartOfFrame )
			{
				if( nZeroBitDeleteCntr == 5 )
				{
					nZeroBitDeleteCntr = 0;

					if( bit == 1 )
					{
						// must be another flag
						nOctet = (nOctet << 1) + bit;
						nBitCntr++;
					}
				}
				else
				{
					nOctet = (nOctet << 1) + bit;
					nBitCntr++;
					nZeroBitDeleteCntr = (bit == 1) ? (nZeroBitDeleteCntr + 1) : 0;

					if( nBitCntr == 8 )
					{
						if( nOctet == 255 )
						{
							m_bFoundStartOfFrame = true;
							//wsprintf( szMsg, "Found start of frame %d\n", i );
							//OutputDebugString( szMsg );
							m_bFlagFound = false;
							m_ECMBuffer.AddByte( nOctet );
						}
						else
						{
							if( nOctet != HDLC_FLAG )
							{
								//wsprintf( szMsg, "Unexpected octet [%02X], re-syncing %d\n", nOctet, i );
								//OutputDebugString( szMsg );
								m_bFoundStartOfPage = false;
							}

							nZeroBitDeleteCntr = 0;
						}

						nBitCntr = 0;
						nOctet = 0;
					}
					else if( nBitCntr > 8 )
					{
						//OutputDebugString( "Whoops!\n" );
						m_bFoundStartOfPage = false;
					}
				}
			}
			else // found start of frame
			{
				if( nZeroBitDeleteCntr == 5 )
				{
					nZeroBitDeleteCntr = 0;

					if( bit == 1 )
					{
						// must be another flag
						nOctet = (nOctet << 1) + bit;
						nBitCntr++;
						//wsprintf( szMsg, "Found potential flag %d\n", i );
						//OutputDebugString( szMsg );
						m_bFlagFound = true;
					}
				}
				else
				{
					nOctet = (nOctet << 1) + bit;
					nBitCntr++;
					nZeroBitDeleteCntr = (bit == 1) ? (nZeroBitDeleteCntr + 1) : 0;

					if( nBitCntr == 8 )
					{
						if( (m_bFlagFound && nOctet == HDLC_FLAG) ||
							(m_ECMBuffer.GetSize() == m_nECMFrameSize + ECM_DATA_HDR + 2) )
						{
							m_bFoundStartOfFrame = false;
							nZeroBitDeleteCntr = 0;
							//wsprintf( szMsg, "Found end of frame %d\n", i );
							//OutputDebugString( szMsg );
							if( ProcessECMFrame() == false )
							{
								// bad frame - resync
								m_bFoundStartOfPage = false;
							}
						}
						else
						{
							m_ECMBuffer.AddByte( nOctet );
						}

						nBitCntr = 0;
						nOctet = 0;

⌨️ 快捷键说明

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