FaxFile.cpp
上传用户:glass0516
上传日期:2010-01-11
资源大小:104k
文件大小:38k
源码类别:

传真(Fax)编程

开发平台:

Visual C++

  1. /*****************************************************************************
  2. * RelayFax Open Source Project
  3. * Copyright 1996-2004 Alt-N Technologies, Ltd.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted only as authorized by the RelayFax Open 
  8. * Source License.  A copy of this license is available in file LICENSE 
  9. * in the top-level directory of the distribution.
  10. *
  11. * RelayFax is a registered trademark of Alt-N Technologies, Ltd.
  12. *
  13. * Individual files and/or contributed packages may be copyright by
  14. * other parties and subject to additional restrictions.
  15. *****************************************************************************/
  16. #include "stdafx.h"
  17. #include "FaxFile.h"
  18. #include "ClassOne.h"
  19. //////////////////////////////////////////////////////////////////////
  20. // Local definitions
  21. //////////////////////////////////////////////////////////////////////
  22. # define WHITE       0
  23. # define BLACK       0xff
  24. # define FAXFILE_OFFTREE    10000
  25. # define FAXFILE_EOL 11000
  26. # define FAXFILE_EOL2 11001
  27. # define FAXFILE_HORZ 11002
  28. # define FAXFILE_V_MINUS3   11003 
  29. # define FAXFILE_V_MINUS2   11004 
  30. # define FAXFILE_V_MINUS1   11005 
  31. # define FAXFILE_V_0 11006 
  32. # define FAXFILE_V_PLUS1 11007 
  33. # define FAXFILE_V_PLUS2 11008 
  34. # define FAXFILE_V_PLUS3    11009 
  35. # define FAXFILE_PASS 11010
  36. typedef int NODE [][2] ;
  37. //////////////////////////////////////////////////////////////////////
  38. // Statics
  39. //////////////////////////////////////////////////////////////////////
  40. BYTE CFaxFile::s_LeadZero[256] = {
  41. 8, 7, 6, 6, 5, 5, 5, 5,
  42. 4, 4, 4, 4, 4, 4, 4, 4,
  43. 3, 3, 3, 3, 3, 3, 3, 3,
  44. 3, 3, 3, 3, 3, 3, 3, 3,
  45. 2, 2, 2, 2, 2, 2, 2, 2,
  46. 2, 2, 2, 2, 2, 2, 2, 2,
  47. 2, 2, 2, 2, 2, 2, 2, 2,
  48. 2, 2, 2, 2, 2, 2, 2, 2,
  49. 1, 1, 1, 1, 1, 1, 1, 1,
  50. 1, 1, 1, 1, 1, 1, 1, 1,
  51. 1, 1, 1, 1, 1, 1, 1, 1,
  52. 1, 1, 1, 1, 1, 1, 1, 1,
  53. 1, 1, 1, 1, 1, 1, 1, 1,
  54. 1, 1, 1, 1, 1, 1, 1, 1,
  55. 1, 1, 1, 1, 1, 1, 1, 1,
  56. 1, 1, 1, 1, 1, 1, 1, 1,
  57. 0, 0, 0, 0, 0, 0, 0, 0,
  58. 0, 0, 0, 0, 0, 0, 0, 0,
  59. 0, 0, 0, 0, 0, 0, 0, 0,
  60. 0, 0, 0, 0, 0, 0, 0, 0,
  61. 0, 0, 0, 0, 0, 0, 0, 0,
  62. 0, 0, 0, 0, 0, 0, 0, 0,
  63. 0, 0, 0, 0, 0, 0, 0, 0,
  64. 0, 0, 0, 0, 0, 0, 0, 0,
  65. 0, 0, 0, 0, 0, 0, 0, 0,
  66. 0, 0, 0, 0, 0, 0, 0, 0,
  67. 0, 0, 0, 0, 0, 0, 0, 0,
  68. 0, 0, 0, 0, 0, 0, 0, 0,
  69. 0, 0, 0, 0, 0, 0, 0, 0,
  70. 0, 0, 0, 0, 0, 0, 0, 0,
  71. 0, 0, 0, 0, 0, 0, 0, 0,
  72. 0, 0, 0, 0, 0, 0, 0, 0,
  73. };
  74. BYTE CFaxFile::s_TrailZero[256] = {
  75. 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,
  76. 1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,
  77. 2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,
  78. 1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,
  79. 3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,
  80. 1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,
  81. 2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
  82. };
  83. unsigned char CFaxFile::s_FlipTable[] = {
  84.   0, 128,  64, 192,  32, 160,  96, 224,  16, 
  85. 144,  80, 208,  48, 176, 112, 240,   8, 
  86. 136,  72, 200,  40, 168, 104, 232,  24, 
  87. 152,  88, 216,  56, 184, 120, 248,   4, 
  88. 132,  68, 196,  36, 164, 100, 228,  20, 
  89. 148,  84, 212,  52, 180, 116, 244,  12, 
  90. 140,  76, 204,  44, 172, 108, 236,  28, 
  91. 156,  92, 220,  60, 188, 124, 252,   2, 
  92. 130,  66, 194,  34, 162,  98, 226,  18, 
  93. 146,  82, 210,  50, 178, 114, 242,  10, 
  94. 138,  74, 202,  42, 170, 106, 234,  26, 
  95. 154,  90, 218,  58, 186, 122, 250,   6, 
  96. 134,  70, 198,  38, 166, 102, 230,  22, 
  97. 150,  86, 214,  54, 182, 118, 246,  14, 
  98. 142,  78, 206,  46, 174, 110, 238,  30, 
  99. 158,  94, 222,  62, 190, 126, 254,   1, 
  100. 129,  65, 193,  33, 161,  97, 225,  17, 
  101. 145,  81, 209,  49, 177, 113, 241,   9, 
  102. 137,  73, 201,  41, 169, 105, 233,  25, 
  103. 153,  89, 217,  57, 185, 121, 249,   5, 
  104. 133,  69, 197,  37, 165, 101, 229,  21, 
  105. 149,  85, 213,  53, 181, 117, 245,  13, 
  106. 141,  77, 205,  45, 173, 109, 237,  29, 
  107. 157,  93, 221,  61, 189, 125, 253,   3, 
  108. 131,  67, 195,  35, 163,  99, 227,  19, 
  109. 147,  83, 211,  51, 179, 115, 243,  11, 
  110. 139,  75, 203,  43, 171, 107, 235,  27, 
  111. 155,  91, 219,  59, 187, 123, 251,   7, 
  112. 135,  71, 199,  39, 167, 103, 231,  23, 
  113. 151,  87, 215,  55, 183, 119, 247,  15, 
  114. 143,  79, 207,  47, 175, 111, 239,  31, 
  115. 159,  95, 223,  63, 191, 127, 255, 
  116. };
  117. const int CFaxFile::s_WTree [][2] =
  118. {
  119. {1, 80}, {40, 2}, {21, 3}, {4, -2}, {16, 5}, {10, 6}, {7, -256}, {9, 8}, {-1344, -1408},
  120. {-1216, -1280}, {11, 13}, {-576, 12}, {-832, -896}, {14, 15}, {-960, -1024}, {-1088, -1152}, {-1664, 17},
  121. {18, 19}, {-448, -512}, {20, -640}, {-704, -768}, {32, 22}, {23, 28}, {24, 26}, {-24, 25},
  122. {-49, -50}, {27, -25}, {-51, -52}, {29, -192}, {30, 31}, {-55, -56}, {-57, -58}, {-11, 33},
  123. {34, 36}, {-27, 35}, {-59, -60}, {37, -18}, {38, 39}, {-1472, -1536}, {-1600, -1728}, {59, 41},
  124. {49, 42}, {43, -10}, {47, 44}, {46, 45}, {-320, -384}, {-63, 0}, {-28, 48}, {-61, -62}, 
  125. {56, 50}, {53, 51}, {52, -21}, {-43, -44}, {55, 54}, {-41, -42}, {-39, -40}, {-12, 57},
  126. {58, -26}, {-53, -54}, {70, 60}, {64, 61}, {62, -1}, {-19, 63}, {-31, -32}, {68, 65},
  127. {67, 66}, {-37, -38}, {-35, -36}, {-20, 69}, {-33, -34}, {74, 71}, {72, -13}, {-23, 73},
  128. {-47, -48}, {77, 75}, {76, -22}, {-45, -46}, {79, 78}, {-29, -30}, {FAXFILE_EOL, FAXFILE_OFFTREE}, {86, 81},
  129. {83, 82}, {-6, -7}, {-5, 84}, {85, -64}, {-14, -15}, {90, 87}, {88, -4}, {-9, 89},
  130. {-16, -17}, {-3, 91}, {-128, -8}
  131. } ;
  132. const int CFaxFile::s_BTree [][2] =
  133. {
  134. {2, 1}, {-3, -2}, {4, 3}, {-1, -4}, {6, 5}, {-6, -5}, {9, 7}, {8, -7},  {-9, -8}, 
  135. {31, 10}, {30, 11}, {12, -12}, {23, 13}, {17, 14}, {15, 0}, {-21, 16}, {-42, -43},
  136. {21, 18}, {20, 19}, {-38, -39}, {-36, -37}, {-20, 22}, {-34, -35}, {-15, 24}, {27, 25},
  137. {26, -19}, {-28, -29}, {29, 28}, {-26, -27}, {-128, -192}, {-10, -11}, {57, 32}, {45, 33},
  138. {34, -14}, {41, 35}, {38, 36}, {37, -22}, {-40, -41}, {40, 39}, {-32, -33}, {-30, -31},
  139. {-17, 42}, {44, 43}, {-62, -63}, {-48, -49}, {-13, 46}, {51, 47}, {48, -16}, {50, 49},
  140. {-61, -256}, {-57, -58}, {55, 52}, {54, 53}, {-46, -47}, {-44, -45}, {-23, 56}, {-50, -51},
  141. {FAXFILE_EOL, 58}, {75, 59}, {67, 60}, {61, -64}, {65, 62}, {64, 63}, {-1152, -1216}, {-1024, -1088},
  142. {-54, 66}, {-896, -960}, {72, 68}, {71, 69}, {70, -53}, {-512, -576}, {-384, -448}, {-25, 73},
  143. {74, -320}, {-1664, -1728}, {85, 76}, {80, 77}, {78, -24}, {-60, 79}, {-1536, -1600}, {83, 81},
  144. {82, -59}, {-1408, -1472}, {-56, 84}, {-1280, -1344}, {-18, 86}, {89, 87}, {88, -55}, {-768, -832},
  145. {-52, 90}, {-640, -704}
  146. } ;
  147. const int CFaxFile::s_TwoTree [][2] =
  148. {
  149. {1, FAXFILE_V_0}, {2, 3}, {4, FAXFILE_HORZ}, {FAXFILE_V_MINUS1, FAXFILE_V_PLUS1},
  150. {5, FAXFILE_PASS}, {6, 7}, {8, 9}, {FAXFILE_V_MINUS2, FAXFILE_V_PLUS2},
  151. {FAXFILE_EOL, FAXFILE_OFFTREE}, {FAXFILE_V_MINUS3, FAXFILE_V_PLUS3}
  152. } ;
  153. //////////////////////////////////////////////////////////////////////
  154. // Construction/Destruction
  155. //////////////////////////////////////////////////////////////////////
  156. CFaxFile::CFaxFile()
  157. {
  158. m_PageCount = 0;
  159. m_PageBuffer = NULL;
  160. m_tiff = NULL;
  161. m_nSendEncoding = FAXAPI_ENC_CCITT_T6;
  162. m_bGotData = false;
  163. bitspersample = 1;
  164. width = 1728;
  165. length = 0;
  166. fillorder = 1;
  167. g3opts = 0;
  168. compression = COMPRESSION_CCITTFAX3;
  169. xres = 204.0f;
  170. yres = 196.0f;
  171. m_bFileHasData = false;
  172. }
  173. CFaxFile::~CFaxFile()
  174. {
  175. }
  176. //////////////////////////////////////////////////////////////////////
  177. // IsHiRes
  178. //////////////////////////////////////////////////////////////////////
  179. bool CFaxFile::IsHiRes(void) 
  180. short oures=(short)((2*xres)/yres); 
  181. if (oures<3) 
  182. return true; 
  183. return false; 
  184. }
  185. //////////////////////////////////////////////////////////////////////
  186. // ReadFirstHeader
  187. //////////////////////////////////////////////////////////////////////
  188. int CFaxFile::ReadFirstHeader(void)
  189. {
  190. m_bFileHasData = true;
  191. m_tiff = TIFFOpen( m_sFaxFile.c_str(), "r" );
  192. m_PageCount = 0;
  193. m_bPartialPage = false;
  194. m_nBlockCount = 0;
  195. if ( m_tiff == NULL ) 
  196. {
  197. return 1;
  198. }
  199. // read TIFF tags
  200. ReadIfd();
  201. if( width != 1728 )
  202. {
  203. TIFFClose( m_tiff );
  204. m_tiff = NULL;
  205. return 2;
  206. }
  207. return 0;
  208. }
  209. //////////////////////////////////////////////////////////////////////
  210. // ReadIfd
  211. //////////////////////////////////////////////////////////////////////
  212. int CFaxFile::ReadIfd (void)
  213. {
  214. TIFFGetField( m_tiff, TIFFTAG_IMAGEWIDTH, &width );
  215. TIFFGetField( m_tiff, TIFFTAG_IMAGELENGTH, &length);
  216. TIFFGetField( m_tiff, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  217. TIFFGetField( m_tiff, TIFFTAG_FILLORDER, &fillorder);
  218. TIFFGetField( m_tiff, TIFFTAG_XRESOLUTION, &xres );
  219. TIFFGetField( m_tiff, TIFFTAG_YRESOLUTION, &yres );
  220. TIFFGetField( m_tiff, TIFFTAG_ROWSPERSTRIP, &rowsperstrip );
  221. return 0;
  222. }
  223. //////////////////////////////////////////////////////////////////////
  224. // ReadPage
  225. //////////////////////////////////////////////////////////////////////
  226. bool CFaxFile::ReadPage( bool bUseECM, int nClass1Speed, WORD wMinLineChars, bool bClassTwoZero, bool bClassTwo )
  227. {
  228. unsigned int nTotalBytes;
  229. int i;
  230. int nMaxBytes;
  231. int nFlagLength = 0;
  232. unsigned int nOffset;
  233. int nDataBits = 0;
  234. bool bFoundRTC = false;
  235. if( m_bPartialPage ) 
  236. {
  237. m_nBlockCount++;
  238. nOffset = m_nPartialPagePos;
  239. }
  240. else
  241. {
  242. m_nBlockCount = 0;
  243. nOffset = 0;
  244. }
  245. if( m_MemFile.ReadPage( m_tiff, m_nSendEncoding ) != 0 )
  246. {
  247. return false;
  248. }
  249. nBitCntr = 0;
  250. nOctet = 0;
  251. if( m_PageBuffer != NULL )
  252. {
  253. delete[] m_PageBuffer;
  254. }
  255. if( bUseECM )
  256. {
  257. nFlagLength = (int)(((float)(cls1Speeds[nClass1Speed].dwSpeed / 8)) * 0.2f);
  258. nMaxBytes = nFlagLength + // initial flags  
  259.         (3 * 6) + // RCP frames
  260.         (255) * (m_nECMFrameSize + ECM_DATA_HDR + 3) +
  261. 2; // DLE ETX
  262. nMaxBytes = nMaxBytes*2; // zero/DLE insertion fudge factor
  263. }
  264. else
  265. {
  266. nZcnt = 0;
  267. nRTCCnt = 0;
  268. //m_bFoundEndOfPage = false;
  269. if( wMinLineChars > 0 )
  270. {
  271. nMaxBytes = (wMinLineChars * rowsperstrip + m_MemFile.GetDataLen()) *2 + 2;
  272. }
  273. else
  274. {
  275. nMaxBytes = m_MemFile.GetDataLen()*2 + 2;
  276. }
  277. }
  278. m_PageBuffer = new unsigned char[nMaxBytes];
  279. m_PagePtr = (unsigned char*)m_PageBuffer;
  280. // Initial flag sequence
  281. if( bUseECM )
  282. {
  283. for( i = 0; i < nFlagLength; i++ )
  284. {
  285. *m_PagePtr++ = HDLC_FLAG;
  286. }
  287. nZeroBitDeleteCntr = 0;
  288. m_ECMBuffer.InitFrame();
  289. m_ECMBuffer.SetLastSeq(0);
  290. m_ECMBuffer.SetHighestSeq(0);
  291. }
  292. if( m_bPartialPage ) 
  293. {
  294. m_bPartialPage = false;
  295. }
  296. nTotalBytes = m_MemFile.GetDataLen();
  297. unsigned char* pData = m_MemFile.GetData(nOffset);
  298. i = nOffset;
  299. while( i < nTotalBytes )
  300. {
  301. // todo: byte order?
  302. if( bUseECM )
  303. {
  304. unsigned char c = s_FlipTable[ *pData ];
  305. if( m_ECMBuffer.GetSize() == 0 )
  306. {
  307. AddFCDHeader();
  308. }
  309. AddByte( c, true );
  310. if( m_ECMBuffer.GetSize() == m_nECMFrameSize + ECM_DATA_HDR )
  311. {
  312. unsigned short wFCS = m_ECMBuffer.GetFCS();
  313. AddByte( wFCS & 0xff, false );
  314. AddByte( (wFCS >> 8) & 0xff, false );
  315. AddFlag(); // FLAG
  316. m_ECMBuffer.InitFrame();
  317. if( GetFrameCount() == 255 )
  318. {
  319. // Set Partial Page flag and save state
  320. m_bPartialPage = true;
  321. m_nPartialPagePos = i + 1;
  322. }
  323. }
  324. }
  325. else
  326. {
  327. unsigned char c = *pData;
  328. if (nZcnt) 
  329. {
  330. nZcnt += s_LeadZero[c];
  331. if (c && (nZcnt < 11)) 
  332. {
  333. nRTCCnt = 0;
  334. nZcnt = s_TrailZero[c];
  335. }
  336. }
  337. else 
  338. {
  339. nZcnt = s_TrailZero[c];
  340. if (!nZcnt) nRTCCnt = 0;
  341. }
  342. if( nZcnt > 10 && c != 0 )
  343. {
  344. nDataBits += s_LeadZero[c] + 1;
  345. if( nDataBits > 12 )
  346. {
  347. int nInsertBytes = wMinLineChars - (nDataBits/8);
  348. for( int ii = 0; ii < nInsertBytes; ii++ )
  349. {
  350. *m_PagePtr++ = 0;
  351. }
  352. }
  353. else
  354. {
  355. nRTCCnt++;
  356. }
  357. nDataBits = (7 - s_LeadZero[c]);
  358. if (nRTCCnt > 5) 
  359. {
  360. bFoundRTC = true;
  361. //char szMsg[80];
  362. //wsprintf( szMsg, "ReadPage: Found RTC at byte %dn", ftell(m_fp) - nBytesRead + i + 1 );
  363. //OutputDebugString( szMsg );
  364. //IncrementImageLength( -5 );
  365. //m_bFoundEndOfPage = true;
  366. }
  367. else
  368. {
  369. //IncrementImageLength();
  370. }
  371. nZcnt = s_TrailZero[c];
  372. }
  373. else 
  374. {
  375. nDataBits += 8;
  376. }
  377. c = s_FlipTable[c];
  378. // DLE Insertion
  379. if( c == DLE )
  380. {
  381. *m_PagePtr++ = c;
  382. }
  383. *m_PagePtr++ = c;
  384. }
  385. pData++;
  386. i++;
  387. if( m_bPartialPage )
  388. {
  389. i = nTotalBytes;
  390. }
  391. }
  392. if( bUseECM )
  393. {
  394. if( m_ECMBuffer.GetSize() > 0 )
  395. {
  396. unsigned short wFCS = m_ECMBuffer.GetFCS();
  397. AddByte( wFCS & 0xff, false );
  398. AddByte( (wFCS >> 8) & 0xff, false );
  399. AddFlag(); // FLAG
  400. }
  401. // now add RCP frames
  402. AddRCPFrames();
  403. }
  404. else
  405. {
  406. // TODO: class 1 or class 2.0 should include RTC, but not class 2
  407. if( !bFoundRTC && !bClassTwo )
  408. {
  409. // OutputDebugString( "ReadPage adding RTC!n" );
  410. *m_PagePtr++ = s_FlipTable[ 0x00 ];
  411. *m_PagePtr++ = s_FlipTable[ 0x10 ];
  412. *m_PagePtr++ = s_FlipTable[ 0x01 ];
  413. *m_PagePtr++ = s_FlipTable[ 0x00 ];
  414. *m_PagePtr++ = s_FlipTable[ 0x10 ];
  415. *m_PagePtr++ = s_FlipTable[ 0x01 ];
  416. *m_PagePtr++ = s_FlipTable[ 0x00 ];
  417. *m_PagePtr++ = s_FlipTable[ 0x10 ];
  418. *m_PagePtr++ = s_FlipTable[ 0x01 ];
  419. }
  420. }
  421. *m_PagePtr++ = DLE;
  422. if( bClassTwoZero )
  423. {
  424. *m_PagePtr++ = MorePages() ? 0x2c : 0x2e;
  425. }
  426. else
  427. {
  428. *m_PagePtr++ = ETX;
  429. }
  430. m_PageBufferSize = m_PagePtr - m_PageBuffer;
  431. return true;
  432. }
  433. //////////////////////////////////////////////////////////////////////
  434. // ReadBadFrames
  435. //////////////////////////////////////////////////////////////////////
  436. bool CFaxFile::ReadBadFrames( int nClass1Speed )
  437. {
  438. // get the bad frame numbers from SeqMap and construct frames
  439. int i,j,k;
  440. BYTE b;
  441. BYTE bit;
  442. int nSeqNum = 0;
  443. m_PagePtr = (unsigned char*)m_PageBuffer;
  444. nBitCntr = 0;
  445. nOctet = 0;
  446. int nFlagLength = (int)(((float)(cls1Speeds[nClass1Speed].dwSpeed / 8)) * 0.2f);
  447. for( i = 0; i < nFlagLength; i++ )
  448. {
  449. *m_PagePtr++ = HDLC_FLAG;
  450. }
  451. for( i = 0; i < SEQ_MAP_SIZE; i++ )
  452. {
  453. b = m_ECMBuffer.GetSeqMap()[i];
  454. for( j = 0; j < 8; j++, b >>= 1 )
  455. {
  456. bit = (b & 0x01);
  457. if( bit )
  458. {
  459. //char szMsg[80];
  460. //wsprintf( szMsg, "Resending Seq=%dn", nSeqNum );
  461. //OutputDebugString( szMsg );
  462. unsigned int nOffset = (256 * m_nBlockCount + nSeqNum) * m_nECMFrameSize;
  463. memcpy( m_ECMBuffer.GetData(), m_MemFile.GetData( nOffset ), m_nECMFrameSize ); ;
  464. nZeroBitDeleteCntr = 0;
  465. m_ECMBuffer.InitFrame();
  466. m_ECMBuffer.SetLastSeq( nSeqNum );
  467. AddFCDHeader();
  468. for( k = 0; k < m_nECMFrameSize; k++ )
  469. {
  470. AddByte( s_FlipTable[m_ECMBuffer.GetData()[k]], true );
  471. }
  472. unsigned short wFCS = m_ECMBuffer.GetFCS();
  473. AddByte( wFCS & 0xff, false );
  474. AddByte( (wFCS >> 8) & 0xff, false );
  475. AddFlag(); // FLAG
  476. }
  477. nSeqNum++;
  478. // Ignore any sequence numbers which we didn't transmit
  479. if( nSeqNum > m_ECMBuffer.GetHighestSeq() )
  480. {
  481. break;
  482. }
  483. }
  484. if( nSeqNum > m_ECMBuffer.GetHighestSeq() )
  485. {
  486. break;
  487. }
  488. }
  489. AddRCPFrames();
  490. *m_PagePtr++ = DLE;
  491. *m_PagePtr++ = ETX;
  492. m_PageBufferSize = m_PagePtr - m_PageBuffer;
  493. return true;
  494. }
  495. //////////////////////////////////////////////////////////////////////
  496. // AddRCPFrames
  497. //////////////////////////////////////////////////////////////////////
  498. void CFaxFile::AddRCPFrames(void)
  499. {
  500. int i;
  501. for( i = 0; i < 3; i++ )
  502. {
  503. m_ECMBuffer.InitFrame();
  504. AddByte( 0xff, true );
  505. AddByte( 0x03, true );
  506. AddByte( RCP, true );
  507. unsigned short wFCS = m_ECMBuffer.GetFCS();
  508. AddByte( wFCS & 0xff, false );
  509. AddByte( (wFCS >> 8) & 0xff, false );
  510. AddFlag(); // FLAG
  511. }
  512. // output the last byte
  513. while( nBitCntr > 0 )
  514. {
  515. AddBit( 0 );
  516. }
  517. }
  518. //////////////////////////////////////////////////////////////////////
  519. // AddFCDHeader
  520. //////////////////////////////////////////////////////////////////////
  521. void CFaxFile::AddFCDHeader(void)
  522. {
  523. AddByte( 0xff, true );
  524. AddByte( 0x03, true );
  525. AddByte( FCD, true );
  526. AddByte( (unsigned char) m_ECMBuffer.GetLastSeq(), true );
  527. m_ECMBuffer.IncrementLastSeq();
  528. }
  529. //////////////////////////////////////////////////////////////////////
  530. // AddByte
  531. //////////////////////////////////////////////////////////////////////
  532. void CFaxFile::AddByte( unsigned char b, bool bCalcFCS )
  533. {
  534. int i;
  535. BYTE bit;
  536. if( bCalcFCS )
  537. {
  538. m_ECMBuffer.CalcFCS( b );
  539. }
  540. for( i = 0; i < 8; i++, b >>= 1 )
  541. {
  542. bit = (b & 0x01);
  543. AddBit( bit );
  544. nZeroBitDeleteCntr = (bit == 1) ? (nZeroBitDeleteCntr + 1) : 0;
  545. if( nZeroBitDeleteCntr == 5 )
  546. {
  547. nZeroBitDeleteCntr = 0;
  548. AddBit( 0 );
  549. }
  550. }
  551. }
  552. //////////////////////////////////////////////////////////////////////
  553. // AddFlag
  554. //////////////////////////////////////////////////////////////////////
  555. void CFaxFile::AddFlag( void )
  556. {
  557. BYTE b = HDLC_FLAG;
  558. BYTE bit;
  559. int i;
  560. nZeroBitDeleteCntr = 0;
  561. for( i = 0; i < 8; i++, b >>= 1 )
  562. {
  563. bit = (b & 0x01);
  564. AddBit( bit );
  565. }
  566. }
  567. //////////////////////////////////////////////////////////////////////
  568. // AddBit
  569. //////////////////////////////////////////////////////////////////////
  570. void CFaxFile::AddBit( unsigned char bit )
  571. {
  572. nOctet = (nOctet << 1) + bit;
  573. nBitCntr++;
  574. if( nBitCntr >= 8 )
  575. {
  576. nOctet = s_FlipTable[nOctet];
  577. *m_PagePtr++ = nOctet;
  578. if( nOctet == DLE )
  579. {
  580. *m_PagePtr++ = nOctet;
  581. }
  582. nOctet = 0;
  583. nBitCntr = 0;
  584. }
  585. }
  586. //////////////////////////////////////////////////////////////////////
  587. // ReadNextHeader
  588. //////////////////////////////////////////////////////////////////////
  589. bool CFaxFile::ReadNextHeader(void)
  590. {
  591. m_PageCount++;
  592. m_nBlockCount = 0;
  593. if( TIFFReadDirectory( m_tiff ) == 0 )
  594. return false;
  595. ReadIfd();
  596. return true;
  597. }
  598. //////////////////////////////////////////////////////////////////////
  599. // Close
  600. //////////////////////////////////////////////////////////////////////
  601. void CFaxFile::Close(void)
  602. {
  603. if( m_bGotData )
  604. {
  605. WriteIFD();
  606. }
  607. m_PageCount = 0;
  608. if( m_PageBuffer != NULL )
  609. {
  610. delete[] m_PageBuffer;
  611. m_PageBuffer = NULL;
  612. }
  613. if( m_tiff )
  614. {
  615. TIFFClose( m_tiff );
  616. m_tiff = NULL;
  617. }
  618. if( m_bFileHasData == false )
  619. {
  620. remove( m_sFaxFile.c_str() );
  621. }
  622. }
  623. //////////////////////////////////////////////////////////////////////
  624. // SetImageRes
  625. //////////////////////////////////////////////////////////////////////
  626. void CFaxFile::SetImageRes( bool bHiRes )
  627. {
  628. yres = (bHiRes) ? 196.0f : 98.0f;
  629. }
  630. //////////////////////////////////////////////////////////////////////
  631. // SetImageWidth
  632. //////////////////////////////////////////////////////////////////////
  633. void CFaxFile::SetImageWidth( int nWidth )
  634. {
  635. width = nWidth;
  636. }
  637. //////////////////////////////////////////////////////////////////////
  638. // SetImageLength
  639. //////////////////////////////////////////////////////////////////////
  640. void CFaxFile::SetImageLength( int nLength )
  641. {
  642. length = nLength;
  643. }
  644. //////////////////////////////////////////////////////////////////////
  645. // IncrementImageLength
  646. //////////////////////////////////////////////////////////////////////
  647. void CFaxFile::IncrementImageLength( int n )
  648. {
  649. length += n;
  650. }
  651. //////////////////////////////////////////////////////////////////////
  652. // SetImageCompression
  653. //////////////////////////////////////////////////////////////////////
  654. void CFaxFile::SetImageCompression( int nCompression )
  655. {
  656. compression = nCompression;
  657. }
  658. //////////////////////////////////////////////////////////////////////
  659. // SetT4Options
  660. //////////////////////////////////////////////////////////////////////
  661. void CFaxFile::SetT4Options( int nOptions )
  662. {
  663. g3opts = nOptions;
  664. }
  665. //////////////////////////////////////////////////////////////////////
  666. // WriteFileHeader
  667. //////////////////////////////////////////////////////////////////////
  668. bool CFaxFile::WriteFileHeader(void)
  669. {
  670. if( m_tiff == NULL )
  671. {
  672. m_tiff = TIFFOpen( m_sFaxFile.c_str(), "w" );
  673. if( m_tiff == NULL )
  674. {
  675. return false;
  676. }
  677. }
  678. m_bFileHasData = false;
  679. m_bGotData = false;
  680. m_bFoundStartOfPage = false;
  681. m_bFoundEndOfPage = false;
  682. m_bFoundStartOfFrame = false;
  683. nZcnt = 0;
  684. nRTCCnt = 0;
  685. nBitCntr = 0;
  686. nZeroBitDeleteCntr = 0;
  687. m_PageCount = 0;
  688. return true;
  689. }
  690. //////////////////////////////////////////////////////////////////////
  691. // WriteBuffer
  692. //////////////////////////////////////////////////////////////////////
  693. bool CFaxFile::WriteBuffer( unsigned char* szBuffer, unsigned int nBytes, bool bFlipBytes )
  694. {
  695. int nNewBytes =0 ;
  696. int i;
  697. BYTE lastByte;
  698. if( nBytes > 0 ) 
  699. {
  700. m_bGotData = true;
  701. }
  702. for (i = 0; i < nBytes; i++ )
  703. {
  704. BYTE b = (bFlipBytes) ? s_FlipTable[szBuffer[i]] : szBuffer[i];
  705. if( compression == 4 )
  706. {
  707. m_MemFile.AddDataByte( b );
  708. }
  709. else
  710. {
  711. if( !m_bFoundEndOfPage )
  712. {
  713. if (nZcnt) 
  714. {
  715. nZcnt += s_LeadZero[b];
  716. if (b && (nZcnt < 11)) 
  717. {
  718. nRTCCnt = 0;
  719. nZcnt = s_TrailZero[b];
  720. }
  721. }
  722. else 
  723. {
  724. nZcnt = s_TrailZero[b];
  725. if (!nZcnt) nRTCCnt = 0;
  726. }
  727. if( (nNewBytes > 0) && (lastByte == 0) && (nZcnt > 18) )
  728. {
  729. nNewBytes--; // skip last byte
  730. nZcnt -= 8;
  731. }
  732. if( (nZcnt > 10) && (b != 0) )
  733. {
  734. if( !m_bFoundStartOfPage )
  735. {
  736. m_bFoundStartOfPage = true;
  737. m_MemFile.AddDataByte( 0 );
  738. m_MemFile.AddDataByte( 0 );
  739. IncrementImageLength();
  740. }
  741. else
  742. {
  743. nRTCCnt++;
  744. if (nRTCCnt > 5) 
  745. {
  746. //OutputDebugString( "Found RTC!n" );
  747. IncrementImageLength( -5 );
  748. m_bFoundEndOfPage = true;
  749. m_MemFile.AddDataByte( b );  // stuff in the last byte
  750. }
  751. else
  752. {
  753. IncrementImageLength();
  754. }
  755. }
  756. nZcnt = s_TrailZero[b];
  757. }
  758. }
  759. if( m_bFoundStartOfPage && !m_bFoundEndOfPage )
  760. {
  761. m_MemFile.AddDataByte( b );
  762. lastByte = b;
  763. }
  764. }
  765. }
  766. // char szMsg[100];
  767. // wsprintf( szMsg, "Writing Fax Data, nBytes=%d, nNewBytes=%dn", nBytes, nNewBytes );
  768. // OutputDebugString( szMsg );
  769. return true;
  770. }
  771. //////////////////////////////////////////////////////////////////////
  772. // WriteECMBuffer
  773. //////////////////////////////////////////////////////////////////////
  774. bool CFaxFile::WriteECMBuffer( unsigned char* szBuffer, unsigned int nBytes )
  775. {
  776. int i,j;
  777. BYTE bit;
  778. //char szMsg[180];
  779. //wsprintf( szMsg, "Writing ECM Fax Data, nBytes=%dn", nBytes );
  780. //OutputDebugString( szMsg );
  781. if( nBytes > 0 ) 
  782. {
  783. m_bGotData = true;
  784. }
  785. for (i = 0; i < nBytes; i++ )
  786. {
  787. //BYTE b = fliptable[szBuffer[i]];
  788. BYTE b = szBuffer[i];
  789. //char szMsg1[80];
  790. //wsprintf( szMsg1, "%04d: {%02X}n", i, b );
  791. //OutputDebugString( szMsg1 );
  792. for( j = 0; j < 8; j++, b >>= 1 )
  793. {
  794. bit = (b & 0x01);
  795. // look for flags
  796. if( !m_bFoundStartOfPage )
  797. {
  798. if( (nBitCntr == 0) || (nBitCntr == 7) )
  799. {
  800. nBitCntr = (bit == 0) ? (nBitCntr + 1) : 0;
  801. }
  802. else
  803. {
  804. nBitCntr = (bit == 1) ? (nBitCntr + 1) : 0;
  805. }
  806. if (nBitCntr == 8 )
  807. {
  808. //wsprintf( szMsg, "Found a flag %dn", i );
  809. //OutputDebugString( szMsg );
  810. nBitCntr = 0;
  811. nOctet = 0;
  812. nZeroBitDeleteCntr = 0;
  813. m_ECMBuffer.InitFrame();
  814. m_bFoundStartOfPage = true;
  815. }
  816. }
  817. else if( !m_bFoundStartOfFrame )
  818. {
  819. if( nZeroBitDeleteCntr == 5 )
  820. {
  821. nZeroBitDeleteCntr = 0;
  822. if( bit == 1 )
  823. {
  824. // must be another flag
  825. nOctet = (nOctet << 1) + bit;
  826. nBitCntr++;
  827. }
  828. }
  829. else
  830. {
  831. nOctet = (nOctet << 1) + bit;
  832. nBitCntr++;
  833. nZeroBitDeleteCntr = (bit == 1) ? (nZeroBitDeleteCntr + 1) : 0;
  834. if( nBitCntr == 8 )
  835. {
  836. if( nOctet == 255 )
  837. {
  838. m_bFoundStartOfFrame = true;
  839. //wsprintf( szMsg, "Found start of frame %dn", i );
  840. //OutputDebugString( szMsg );
  841. m_bFlagFound = false;
  842. m_ECMBuffer.AddByte( nOctet );
  843. }
  844. else
  845. {
  846. if( nOctet != HDLC_FLAG )
  847. {
  848. //wsprintf( szMsg, "Unexpected octet [%02X], re-syncing %dn", nOctet, i );
  849. //OutputDebugString( szMsg );
  850. m_bFoundStartOfPage = false;
  851. }
  852. nZeroBitDeleteCntr = 0;
  853. }
  854. nBitCntr = 0;
  855. nOctet = 0;
  856. }
  857. else if( nBitCntr > 8 )
  858. {
  859. //OutputDebugString( "Whoops!n" );
  860. m_bFoundStartOfPage = false;
  861. }
  862. }
  863. }
  864. else // found start of frame
  865. {
  866. if( nZeroBitDeleteCntr == 5 )
  867. {
  868. nZeroBitDeleteCntr = 0;
  869. if( bit == 1 )
  870. {
  871. // must be another flag
  872. nOctet = (nOctet << 1) + bit;
  873. nBitCntr++;
  874. //wsprintf( szMsg, "Found potential flag %dn", i );
  875. //OutputDebugString( szMsg );
  876. m_bFlagFound = true;
  877. }
  878. }
  879. else
  880. {
  881. nOctet = (nOctet << 1) + bit;
  882. nBitCntr++;
  883. nZeroBitDeleteCntr = (bit == 1) ? (nZeroBitDeleteCntr + 1) : 0;
  884. if( nBitCntr == 8 )
  885. {
  886. if( (m_bFlagFound && nOctet == HDLC_FLAG) ||
  887. (m_ECMBuffer.GetSize() == m_nECMFrameSize + ECM_DATA_HDR + 2) )
  888. {
  889. m_bFoundStartOfFrame = false;
  890. nZeroBitDeleteCntr = 0;
  891. //wsprintf( szMsg, "Found end of frame %dn", i );
  892. //OutputDebugString( szMsg );
  893. if( ProcessECMFrame() == false )
  894. {
  895. // bad frame - resync
  896. m_bFoundStartOfPage = false;
  897. }
  898. }
  899. else
  900. {
  901. m_ECMBuffer.AddByte( nOctet );
  902. }
  903. nBitCntr = 0;
  904. nOctet = 0;
  905. }
  906. else if( nBitCntr > 8 )
  907. {
  908. //OutputDebugString( "Whoops 2!n" );
  909. m_bFoundStartOfPage = false;
  910. m_bFoundStartOfFrame = false;
  911. }
  912. }
  913. }
  914. }
  915. }
  916. return true;
  917. }
  918. //////////////////////////////////////////////////////////////////////
  919. // ProcessECMFrame
  920. //////////////////////////////////////////////////////////////////////
  921. bool CFaxFile::ProcessECMFrame( void )
  922. {
  923. //char szMsg[160];
  924. bool bRet = true;
  925. if( m_ECMBuffer.CheckFCS() )
  926. {
  927. if( m_ECMBuffer.GetFCF() == FCD )
  928. {
  929. //wsprintf( szMsg, "ECM Frame %d bytes, Control=%02X FCF=%02X Seq=%d LastSeq=%d Data[0]=%02Xn", m_ECMBuffer.GetSize(), 
  930. //   m_ECMBuffer.GetControl(), m_ECMBuffer.GetFCF(), m_ECMBuffer.GetSeq(), m_ECMBuffer.GetLastSeq(), m_ECMBuffer.GetData()[0] );
  931. //OutputDebugString( szMsg );
  932. int nGap = m_ECMBuffer.GetSeq() - m_ECMBuffer.GetLastSeq();
  933. if( nGap < 1 )
  934. {
  935. //wsprintf( szMsg, "Backing up %d framesn", 1 -  nGap );
  936. //OutputDebugString( szMsg );
  937. m_MemFile.Seek( (nGap-1) * m_nECMFrameSize, SEEK_CUR );
  938. //fseek( m_fp, (nGap-1) * m_nECMFrameSize, SEEK_CUR );
  939. }
  940. else if( nGap > 1 )
  941. {
  942. char Zeros[MAX_ECM_DATA];
  943. ZeroMemory( Zeros, m_nECMFrameSize );
  944. if( m_ECMBuffer.GetHighestSeq() > m_ECMBuffer.GetLastSeq() )
  945. {
  946. int nNewGap = m_ECMBuffer.GetHighestSeq() - m_ECMBuffer.GetLastSeq();
  947. if( nNewGap > nGap )
  948. {
  949. nNewGap = nGap;
  950. }
  951. //wsprintf( szMsg, "Moving forward %d framesn", nNewGap );
  952. //OutputDebugString( szMsg );
  953. m_MemFile.Seek( (nNewGap-1) * m_nECMFrameSize, SEEK_CUR );
  954. //fseek( m_fp, (nNewGap-1) * m_nECMFrameSize, SEEK_CUR );
  955. nGap -= nNewGap;
  956. }
  957. if( nGap > 0 )
  958. {
  959. //wsprintf( szMsg, "Skipping %d framesn", nGap - 1 );
  960. //OutputDebugString( szMsg );
  961. for( int i = 1; i < nGap; i++ )
  962. {
  963. if( m_MemFile.Write( Zeros, m_nECMFrameSize ) == 0 )
  964. //if( fwrite( Zeros, 1, m_nECMFrameSize, m_fp ) != m_nECMFrameSize )
  965. {
  966. //OutputDebugString( "Error writing to filen" );
  967. }
  968. }
  969. }
  970. }
  971. m_MemFile.Write( m_ECMBuffer.GetData(), m_nECMFrameSize );
  972. //if( fwrite( m_ECMBuffer.GetData(), 1, m_nECMFrameSize, m_fp ) != m_nECMFrameSize )
  973. {
  974. //OutputDebugString( "Error writing to filen" );
  975. }
  976. m_ECMBuffer.UpdateLastSeq();
  977. }
  978. else if( m_ECMBuffer.GetFCF() == RCP )
  979. {
  980. //OutputDebugString( "Got RCPn" );
  981. }
  982. else
  983. {
  984. //OutputDebugString( "Unknown ECM Framen" );
  985. }
  986. }
  987. else
  988. {
  989. //OutputDebugString( "Bad ECM Framen" );
  990. bRet = false;
  991. }
  992. m_ECMBuffer.InitFrame();
  993. return bRet;
  994. }
  995. //////////////////////////////////////////////////////////////////////
  996. // NextBlock called between ECM blocks
  997. //////////////////////////////////////////////////////////////////////
  998. void CFaxFile::NextECMBlock(void)
  999. {
  1000. m_MemFile.Seek( 0, SEEK_END );
  1001. m_ECMBuffer.InitFrame();
  1002. m_ECMBuffer.InitBlock();
  1003. m_bFoundStartOfPage = false;
  1004. m_bFoundStartOfFrame = false;
  1005. m_bFoundEndOfPage = false;
  1006. nZcnt = 0;
  1007. nRTCCnt = 0;
  1008. nBitCntr = 0;
  1009. nZeroBitDeleteCntr = 0;
  1010. }
  1011. //////////////////////////////////////////////////////////////////////
  1012. // NextBlock called between ECM blocks
  1013. //////////////////////////////////////////////////////////////////////
  1014. void CFaxFile::RedoECMBlock(void)
  1015. {
  1016. m_ECMBuffer.InitFrame();
  1017. m_bFoundStartOfPage = false;
  1018. m_bFoundStartOfFrame = false;
  1019. m_bFoundEndOfPage = false;
  1020. nZcnt = 0;
  1021. nRTCCnt = 0;
  1022. nBitCntr = 0;
  1023. nZeroBitDeleteCntr = 0;
  1024. }
  1025. //////////////////////////////////////////////////////////////////////
  1026. // WriteIFD prepares for the next fax page
  1027. //////////////////////////////////////////////////////////////////////
  1028. bool CFaxFile::WriteIFD(void)
  1029. {
  1030. m_bGotData = false;
  1031. m_bFoundStartOfPage = false;
  1032. m_bFoundStartOfFrame = false;
  1033. m_bFoundEndOfPage = false;
  1034. nZcnt = 0;
  1035. nRTCCnt = 0;
  1036. nBitCntr = 0;
  1037. nZeroBitDeleteCntr = 0;
  1038. bool bRet = ( WriteIfd() > 0 ) ? true : false;
  1039. if( bRet )
  1040. {
  1041. m_PageCount++;
  1042. }
  1043. return bRet;
  1044. }
  1045. //////////////////////////////////////////////////////////////////////
  1046. // WriteIfd dumps the page to disk
  1047. //////////////////////////////////////////////////////////////////////
  1048. int CFaxFile::WriteIfd (void)
  1049. {
  1050. int nRet = m_MemFile.Size();
  1051. if( length == 0 )
  1052. {
  1053. if( compression == 3 )
  1054. {
  1055. CountGroup3TiffLines();
  1056. }
  1057. else
  1058. {
  1059. CountGroup4TiffLines();
  1060. }
  1061. //char szMsg[80];
  1062. //wsprintf( szMsg, "Counted %d linesn", length );
  1063. //OutputDebugString( szMsg );
  1064. }
  1065. if( (length < 10) || (nRet == 0 ) )
  1066. {
  1067. return 0;
  1068. }
  1069. TIFFSetField( m_tiff, TIFFTAG_SUBFILETYPE, 2 );
  1070. TIFFSetField( m_tiff, TIFFTAG_IMAGEWIDTH, width );
  1071. TIFFSetField( m_tiff, TIFFTAG_IMAGELENGTH, length);
  1072. TIFFSetField( m_tiff, TIFFTAG_PHOTOMETRIC, 0 );
  1073. TIFFSetField( m_tiff, TIFFTAG_ROWSPERSTRIP, length );
  1074. TIFFSetField( m_tiff, TIFFTAG_BITSPERSAMPLE, bitspersample);
  1075. TIFFSetField( m_tiff, TIFFTAG_FILLORDER, fillorder);
  1076. TIFFSetField( m_tiff, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH );
  1077. TIFFSetField( m_tiff, TIFFTAG_XRESOLUTION, xres );
  1078. TIFFSetField( m_tiff, TIFFTAG_YRESOLUTION, yres );
  1079. TIFFSetField( m_tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
  1080. TIFFSetField( m_tiff, TIFFTAG_COMPRESSION, compression );
  1081. TIFFSetField( m_tiff, TIFFTAG_PAGENUMBER, m_PageCount, 0 );
  1082. if( compression == COMPRESSION_CCITTFAX3 )
  1083. {
  1084. TIFFSetField( m_tiff, TIFFTAG_GROUP3OPTIONS, g3opts );
  1085. }
  1086. else if( compression == COMPRESSION_CCITTFAX4 )
  1087. {
  1088. TIFFSetField( m_tiff, TIFFTAG_GROUP4OPTIONS, 0 );
  1089. }
  1090. TIFFWriteRawStrip( m_tiff, 0, m_MemFile.GetData(0), m_MemFile.Size() );
  1091. TIFFWriteDirectory( m_tiff );
  1092. m_bFileHasData = true;
  1093. m_MemFile.Clear();
  1094. length = 0;
  1095. return nRet;
  1096. }
  1097. //////////////////////////////////////////////////////////////////////
  1098. // CountGroup3TiffLines
  1099. //////////////////////////////////////////////////////////////////////
  1100. void CFaxFile::CountGroup3TiffLines(void)
  1101. {
  1102. int i;
  1103. nZcnt = 0;
  1104. nRTCCnt = 0;
  1105. m_bFoundEndOfPage = false;
  1106. m_MemFile.Seek( 0, SEEK_SET );
  1107. for( i = 0; i < m_MemFile.Size(); i++ )
  1108. {
  1109. if( !m_bFoundEndOfPage )
  1110. {
  1111. BYTE b = *m_MemFile.GetData(i);
  1112. if (nZcnt) 
  1113. {
  1114. nZcnt += s_LeadZero[b];
  1115. if (b && (nZcnt < 11)) 
  1116. {
  1117. nRTCCnt = 0;
  1118. nZcnt = s_TrailZero[b];
  1119. }
  1120. }
  1121. else 
  1122. {
  1123. nZcnt = s_TrailZero[b];
  1124. if (!nZcnt) nRTCCnt = 0;
  1125. }
  1126. if( nZcnt > 10 && b != 0 )
  1127. {
  1128. nRTCCnt++;
  1129. if (nRTCCnt > 5) 
  1130. {
  1131. //OutputDebugString( "Found RTC!n" );
  1132. IncrementImageLength( -5 );
  1133. m_bFoundEndOfPage = true;
  1134. }
  1135. else
  1136. {
  1137. IncrementImageLength();
  1138. }
  1139. nZcnt = s_TrailZero[b];
  1140. }
  1141. }
  1142. }
  1143. }
  1144. //////////////////////////////////////////////////////////////////////
  1145. // ExpandLine - used by CountGroup4TiffLines
  1146. //////////////////////////////////////////////////////////////////////
  1147. void ExpandLine ( unsigned char color, char *cur_line, 
  1148.    int& bit_2D, int& i_2D, int runlength )
  1149. {
  1150. int copyrun=runlength ;
  1151. if (color==WHITE)
  1152. {
  1153. bit_2D-=(copyrun%8) ;
  1154. i_2D+=(copyrun/8) ;
  1155. if (bit_2D<0)
  1156. {
  1157. bit_2D+=8 ;
  1158. i_2D++ ;
  1159. }
  1160. }
  1161. else for (;;)
  1162. {
  1163. while (bit_2D>0)
  1164. {
  1165. cur_line[i_2D]|=(1<<(bit_2D-1)) ;
  1166. bit_2D-- ;
  1167. if (!(--copyrun)) break ;
  1168. }
  1169. if (copyrun==0) break ;
  1170. i_2D++ ;
  1171. for (; copyrun>8 ; copyrun-=8) cur_line[i_2D++]=(char)0xff ;
  1172. if (copyrun==0) break ;
  1173. bit_2D=8 ;
  1174. }
  1175. }
  1176. //////////////////////////////////////////////////////////////////////
  1177. // CountGroup4TiffLines
  1178. //////////////////////////////////////////////////////////////////////
  1179. void CFaxFile::CountGroup4TiffLines(void)
  1180. {
  1181. int i,j,k;
  1182. nZcnt = 0;
  1183. nRTCCnt = 0;
  1184. m_bFoundEndOfPage = false;
  1185. int dots_left= width;
  1186. int code= 0;
  1187. int resync, a0, b1, b2, horz_runs;
  1188. NODE *tree= (NODE *)&s_WTree ;
  1189. unsigned char octet, ref_color, this_bit, coding_scheme = 1;
  1190.     unsigned char color;      
  1191.     char *cur_line; 
  1192. int i_2D= 0; 
  1193. int bit_2D=8 ;
  1194. char twolines[(2432/8)*2];
  1195. char *ref_line;
  1196. char *tmp_line;
  1197. ref_color = WHITE;
  1198.     memset (twolines,0x00,(width/8)*2) ;
  1199. ref_line= &twolines[0] ;
  1200. cur_line= &twolines[width/8] ;
  1201. coding_scheme= 2 ;
  1202. resync= 0 ;
  1203. color= WHITE ;
  1204. dots_left= width ;
  1205. tree= (NODE *)&s_TwoTree ;
  1206. horz_runs= code= 0 ;
  1207. a0= (-1) ;
  1208. m_MemFile.Seek( 0, SEEK_SET );
  1209. for( k = 0; k < m_MemFile.Size(); k++ )
  1210. {
  1211. octet = *m_MemFile.GetData(k);
  1212. for (i= 0 ; i<8 ; i++, octet<<= 1)
  1213. {
  1214. if( !m_bFoundEndOfPage )
  1215. {
  1216. if ((horz_runs==0)&&(dots_left==0))
  1217. {
  1218. i_2D=0 ;
  1219. bit_2D=8 ;
  1220. IncrementImageLength();
  1221.         coding_scheme= 2 ;
  1222. resync= 0 ;
  1223. color= WHITE ;
  1224. dots_left= width ;
  1225.         tree= (NODE *)&s_TwoTree ;
  1226. tmp_line= ref_line ;
  1227. ref_line= cur_line ;
  1228. cur_line= tmp_line ;
  1229. memset (cur_line,0x00,width/8) ;
  1230. horz_runs= code= 0 ;
  1231. a0= (-1) ;
  1232. }
  1233. if (code== FAXFILE_EOL)
  1234. {
  1235. m_bFoundEndOfPage = true;
  1236. break;
  1237. }
  1238. if (code== FAXFILE_EOL2)
  1239. {
  1240. coding_scheme= ((octet&0x80) >> 7) ;
  1241. if (coding_scheme== 1) tree= (NODE *)&s_WTree ;
  1242. else
  1243. {
  1244. tree= (NODE *)&s_TwoTree ;
  1245. horz_runs= 0 ;
  1246. a0= (-1) ;
  1247. }
  1248. tmp_line= ref_line ;
  1249. ref_line= cur_line ;
  1250. cur_line= tmp_line ;
  1251. memset (cur_line,0x00,width/8) ;
  1252. code= 0 ;
  1253. continue ;
  1254. }
  1255. int nBit = (octet&0x80)>>7;
  1256. code= (*tree)[code][nBit]  ;
  1257. if (code<1)
  1258. {
  1259. code= (-code) ;
  1260. if (!resync) if ((dots_left-= code)<0) resync= 1 ;
  1261. if ((!resync)&&(code!= 0)) ExpandLine( color, cur_line, bit_2D, i_2D, code) ;
  1262. if (code < 64)
  1263. {
  1264. color= (~color) ;
  1265. tree= color ? (NODE *)&s_BTree: (NODE *)&s_WTree;
  1266. if ((coding_scheme!= 1)&&(--horz_runs== 0))
  1267. {
  1268. a0= 0 ;
  1269. tree= (NODE *)&s_TwoTree ;
  1270. }
  1271. code= 0 ;
  1272. continue ;
  1273. }
  1274. if (code<FAXFILE_OFFTREE) continue ;
  1275. if (code== FAXFILE_OFFTREE)
  1276. {
  1277. resync= 1 ;
  1278. continue ;
  1279. }
  1280. if (code== FAXFILE_EOL)
  1281. {
  1282. continue;
  1283. }
  1284. if (code== FAXFILE_HORZ)
  1285. {
  1286. horz_runs= 2 ;
  1287. code= 0 ;
  1288. tree= color ? (NODE *)&s_BTree: (NODE *)&s_WTree;
  1289. continue ;
  1290. }
  1291. if (a0== (-1)) ref_color= WHITE ;
  1292. else
  1293. {
  1294. a0= (width-dots_left) ;
  1295. j= (a0/8) ;
  1296. this_bit= (0x80>>(a0%8)) ;
  1297. if ((unsigned char)ref_line[j]&this_bit) ref_color= BLACK ; else ref_color= WHITE ;
  1298. }
  1299. for (b1= a0+1;b1<width;b1++)
  1300. {
  1301. j= (b1/8) ;
  1302. this_bit= (0x80>>(b1%8)) ;
  1303. if (((unsigned char)ref_line[j]&this_bit)!= (ref_color&this_bit)) break ;
  1304. }
  1305. if (ref_color!= color)
  1306. {
  1307. for (b1++;b1<width;b1++)
  1308. {
  1309. j= (b1/8) ;
  1310. this_bit= (0x80>>(b1%8)) ;
  1311. if (((unsigned char)ref_line[j]&this_bit)== (ref_color&this_bit)) break ;
  1312. }
  1313. }
  1314. if (b1>width) b1= width ;
  1315. a0= (width-dots_left) ;
  1316. if (code<FAXFILE_PASS)
  1317. {
  1318. code= ((b1-a0)+(code-FAXFILE_V_0)) ; if (code < 0) resync= 1;
  1319. if (!resync) if ((dots_left-= code)<0) resync= 1 ;
  1320. if ((!resync)&&(code!= 0)) ExpandLine( color, cur_line, bit_2D, i_2D, code);
  1321. color= (~color) ;
  1322. code= 0 ;
  1323. continue ;
  1324. }
  1325. for (b2= b1+1;b2<width;b2++)
  1326. {
  1327. j= (b2/8) ;
  1328. this_bit= (0x80>>(b2%8)) ;
  1329. if (((unsigned char)ref_line[j]&this_bit)== (color&this_bit)) break ;
  1330. }
  1331. if (b2>width) b2= width ;
  1332. if (code== FAXFILE_PASS)
  1333. {
  1334. code= (b2-a0) ; if (code < 0) resync= 1;
  1335. if (!resync) if ((dots_left-= code)<0) resync= 1 ;
  1336. if ((!resync)&&(code!= 0)) ExpandLine( color, cur_line, bit_2D, i_2D, code);
  1337. code= 0 ;
  1338. continue ;
  1339. }
  1340. m_bFoundEndOfPage = true;
  1341. break;
  1342. }
  1343. }
  1344. }
  1345. }
  1346. //////////////////////////////////////////////////////////////////////
  1347. // SelectEncoding
  1348. //////////////////////////////////////////////////////////////////////
  1349. void CFaxFile::SelectEncoding( int nEncoding )
  1350. {
  1351. m_nSendEncoding = nEncoding;
  1352. }
  1353. //////////////////////////////////////////////////////////////////////
  1354. // Clear
  1355. //////////////////////////////////////////////////////////////////////
  1356. void CFaxFile::Clear(void)
  1357. {
  1358. bitspersample = 1;
  1359. width = 1728;
  1360. length = 0;
  1361. fillorder = 1;
  1362. g3opts = 0;
  1363. compression = COMPRESSION_CCITTFAX3;
  1364. xres = 204.0f;
  1365. yres = 196.0f;
  1366. m_MemFile.Clear();
  1367. }