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

传真(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 "memfile.h"
  19. #include "FaxAPI.h"
  20. // static functions
  21. CMemFile* mf_open();
  22. unsigned int mf_lseek (thandle_t fd, unsigned int offset, int whence);
  23. int mf_read (thandle_t fd, void *buf, int size);
  24. int mf_write (thandle_t fd, void *buf, int size);
  25. unsigned int mf_size (thandle_t fd);
  26. int mf_map (thandle_t fd, void **addr, size_t *len);
  27. void mf_unmap (thandle_t fd, void *addr, size_t len);
  28. int mf_close (thandle_t fd);
  29. // CMemFile - unnamed memory mapped file implementation
  30. CMemFile::CMemFile() : m_buf(NULL), m_off(0), m_size(0), m_dataPtr(0), m_dataLen(0), m_dataMark(false)
  31. {
  32. m_hMapping = ::CreateFileMapping( INVALID_HANDLE_VALUE, // handle to file
  33. NULL,   // security
  34. PAGE_READWRITE,   // protection
  35. 0,   // high-order DWORD of size
  36. MaxSize,   // low-order DWORD of size
  37. NULL);   // object name
  38. if( m_hMapping != NULL )
  39. {
  40. m_buf = (unsigned char*) 
  41.      MapViewOfFile( m_hMapping, // handle to file-mapping object
  42. FILE_MAP_WRITE, // access mode
  43. 0, // high-order DWORD of offset
  44. 0, // low-order DWORD of offset
  45. 0); // number of bytes to map
  46. }
  47. }
  48. CMemFile::~CMemFile()
  49. {
  50. // free the data pointer
  51. if (m_buf != NULL)
  52. {
  53. UnmapViewOfFile(m_buf);
  54. m_buf = NULL;
  55. }
  56. // remove the file mapping
  57. if (m_hMapping != NULL)
  58. {
  59. CloseHandle(m_hMapping);
  60. m_hMapping = NULL;
  61. }
  62. }
  63. #define CopyField(tag, v) 
  64.     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
  65. int CMemFile::ReadPage( TIFF* in, int nEncodeType )
  66. {
  67. uint32 g4opts = 0, g3opts = 0;
  68. uint16 compression = COMPRESSION_NONE;
  69. bool bDecode = true;
  70. int n;
  71. uint16 fillorder = 1;
  72. m_off = 0;
  73. m_size = 0;
  74. if( TIFFGetField(in, TIFFTAG_COMPRESSION, &compression) == 0 )
  75. return 1;
  76. if( compression == COMPRESSION_CCITTFAX3 )
  77. {
  78. TIFFGetField(in, TIFFTAG_GROUP3OPTIONS, &g3opts );
  79. }
  80. else if( compression == COMPRESSION_CCITTFAX4 )
  81. {
  82. TIFFGetField(in, TIFFTAG_GROUP4OPTIONS, &g4opts );
  83. }
  84. switch( nEncodeType )
  85. {
  86. case FAXAPI_ENC_CCITT_1D:
  87. if( ( compression == COMPRESSION_CCITTFAX3 ) && (g3opts == 0) )
  88. {
  89. bDecode = false;
  90. }
  91. break;
  92. case FAXAPI_ENC_CCITT_2D:
  93. if( (compression == COMPRESSION_CCITTFAX3 ) && (g3opts == GROUP3OPT_2DENCODING) )
  94. {
  95. bDecode = false;
  96. }
  97. break;
  98. case FAXAPI_ENC_CCITT_UNC:
  99. if( compression == COMPRESSION_NONE ) 
  100. {
  101. bDecode = false;
  102. }
  103. break;
  104. case FAXAPI_ENC_CCITT_T6:
  105. if( (compression == COMPRESSION_CCITTFAX4 ) && (g4opts == 0) )
  106. {
  107. bDecode = false;
  108. }
  109. break;
  110. }
  111. if( TIFFGetField( in, TIFFTAG_FILLORDER, &fillorder) && fillorder != 1 )
  112. {
  113. bDecode = true;
  114. }
  115. if( bDecode )
  116. {
  117. TIFF* out = TIFFClientOpen( "memory file", "w", (thandle_t)this, mf_read, mf_write, 
  118.    mf_lseek, mf_close, mf_size, mf_map, mf_unmap );
  119. uint16 bitspersample;
  120. uint32 width, length, rowsperstrip;
  121. uint16 photometric;
  122. uint16 config = PLANARCONFIG_CONTIG;
  123. uint16 resunit = RESUNIT_INCH;
  124. float xres = 204.0f, yres = 196.0f;
  125. CopyField(TIFFTAG_IMAGEWIDTH, width);
  126. CopyField(TIFFTAG_IMAGELENGTH, length);
  127. CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
  128. CopyField(TIFFTAG_PHOTOMETRIC, photometric);
  129. TIFFSetField( out, TIFFTAG_FILLORDER, 1 );
  130. CopyField(TIFFTAG_PLANARCONFIG, config);
  131. CopyField(TIFFTAG_XRESOLUTION, xres );
  132. CopyField(TIFFTAG_YRESOLUTION, yres );
  133. CopyField(TIFFTAG_RESOLUTIONUNIT, resunit );
  134. CopyField( TIFFTAG_ROWSPERSTRIP, rowsperstrip );
  135. TIFFGetField(in, TIFFTAG_COMPRESSION, &compression);
  136. if( compression == COMPRESSION_CCITTFAX3 )
  137. {
  138. n = TIFFGetField(in, TIFFTAG_GROUP3OPTIONS, &g3opts );
  139. }
  140. else if( compression == COMPRESSION_CCITTFAX4 )
  141. {
  142. TIFFGetField(in, TIFFTAG_GROUP4OPTIONS, &g4opts );
  143. }
  144. switch( nEncodeType )
  145. {
  146. case FAXAPI_ENC_CCITT_1D:
  147. if( ( compression == COMPRESSION_CCITTFAX3 ) && (g3opts == 0) )
  148. {
  149. bDecode = false;
  150. }
  151. TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3);
  152. TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, 0 );  // 0 = 1D, 1 = 2D No byte-aligned EOLs 
  153. break;
  154. case FAXAPI_ENC_CCITT_2D:
  155. if( (compression == COMPRESSION_CCITTFAX3 ) && (g3opts == GROUP3OPT_2DENCODING) )
  156. {
  157. bDecode = false;
  158. }
  159. TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3);
  160. TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING );  // No byte-aligned EOLs 
  161. break;
  162. case FAXAPI_ENC_CCITT_UNC:
  163. if( compression == COMPRESSION_NONE ) 
  164. {
  165. bDecode = false;
  166. }
  167. TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
  168. break;
  169. case FAXAPI_ENC_CCITT_T6:
  170. if( (compression == COMPRESSION_CCITTFAX4 ) && (g4opts == 0) )
  171. {
  172. bDecode = false;
  173. }
  174. TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
  175. TIFFSetField(out, TIFFTAG_GROUP4OPTIONS, 0 );  // 0 = data compressed 
  176. break;
  177. }
  178. tstrip_t s = 0;
  179. tsize_t stripsize  = TIFFStripSize(in);
  180. tdata_t buf = _TIFFmalloc(stripsize);
  181. if( TIFFReadEncodedStrip(in, s, buf, stripsize) == -1 )
  182. {
  183. _TIFFfree(buf);
  184. TIFFClose( out );
  185. return 2;
  186. }
  187. MarkDataPtr( true );
  188. if( TIFFWriteEncodedStrip(out, s, buf, stripsize) == -1 )
  189. {
  190. _TIFFfree(buf);
  191. TIFFClose( out );
  192. return 3;
  193. }
  194. MarkDataPtr( false );
  195. _TIFFfree(buf);
  196. // n = TIFFWriteDirectory(out);
  197. TIFFClose( out );
  198. }
  199. else
  200. {
  201. tstrip_t s = 0;
  202. tsize_t stripsize  = TIFFRawStripSize(in, s);
  203. m_off = 0;
  204. m_size = stripsize;
  205. m_dataPtr = 0;
  206. m_dataLen = stripsize;
  207. if( TIFFReadRawStrip(in, s, m_buf, stripsize) == -1 )
  208. return 4;
  209. }
  210. return 0;
  211. }
  212. CMemFile* mf_open(void)
  213. {
  214. return new CMemFile();
  215. }
  216. CMemFile* CheckHandle( thandle_t fd )
  217. {
  218. if( fd == 0 )
  219. {
  220. return NULL;
  221. }
  222. CMemFile* pFile = (CMemFile*)fd;
  223. if( pFile->GetData(0) )
  224. {
  225. return pFile;
  226. }
  227. else
  228. {
  229. return NULL;
  230. }
  231. }
  232. unsigned int mf_lseek (thandle_t fd, unsigned int offset, int whence)
  233. {
  234. CMemFile* pFile = CheckHandle( fd );
  235. if( pFile == NULL )
  236. return -1;
  237. return pFile->Seek( offset, whence );
  238. }
  239. unsigned int CMemFile::Seek( unsigned int offset, int whence )
  240. {
  241. unsigned int ret = -1;
  242. unsigned int test_off;
  243. switch (whence)
  244. {
  245. case SEEK_SET:
  246. if (offset > CMemFile::MaxSize)
  247. {
  248. ret = -1;
  249. }
  250. else
  251. {
  252. m_off = offset;
  253. if( offset > m_size )
  254. {
  255. m_size = offset;
  256. }
  257. ret = offset;
  258. }
  259. break;
  260. case SEEK_CUR:
  261. test_off = m_off + offset;
  262. if (test_off < 0)
  263. {
  264. ret = -1;
  265. }
  266. else
  267. {
  268. if (test_off > CMemFile::MaxSize)
  269. {
  270. ret = -1;
  271. }
  272. else
  273. {
  274. m_off = test_off;
  275. ret = test_off;
  276. }
  277. }
  278. break;
  279. case SEEK_END:
  280. test_off = m_size + offset;
  281. if (test_off < 0)
  282. {
  283. ret = -1;
  284. }
  285. else
  286. {
  287. if (test_off > CMemFile::MaxSize)
  288. {
  289. ret = -1;
  290. }
  291. else
  292. {
  293. m_off = test_off;
  294. ret = test_off;
  295. }
  296. }
  297. break;
  298. default:
  299. ret = -1;
  300. break;
  301. }
  302. return ret;
  303. }
  304. int mf_read (thandle_t fd, void *buf, int size)
  305. {
  306. CMemFile* pFile = CheckHandle( fd );
  307. if( pFile == NULL )
  308. return -1;
  309. return pFile->Read( buf, size );
  310. }
  311. int CMemFile::Read( void* buf, int size )
  312. {
  313. if( m_off + size > m_size )
  314. {
  315. return -1;
  316. }
  317. memcpy( buf, m_buf + m_off, size );
  318. m_off += size;
  319. return size;
  320. }
  321. int mf_write (thandle_t fd, void *buf, int size)
  322. {
  323. CMemFile* pFile = CheckHandle( fd );
  324. if( pFile == NULL )
  325. return -1;
  326. return pFile->Write( buf, size );
  327. }
  328. int CMemFile::Write( void* buf, int size )
  329. {
  330. if( m_off + size > CMemFile::MaxSize )
  331. {
  332. return -1;
  333. }
  334. if( m_dataMark )
  335. {
  336. if( m_dataPtr == 0 )
  337. {
  338. m_dataPtr = m_off;
  339. }
  340. m_dataLen += size;
  341. }
  342. memcpy( m_buf + m_off, buf, size );
  343. if( m_off + size > m_size )
  344. {
  345. m_size = m_off + size;
  346. }
  347. m_off += size;
  348. return size;
  349. }
  350. void CMemFile::AddDataByte( unsigned char b) 
  351. if( m_off < MaxSize) 
  352. m_buf[m_off] = b;
  353. m_off++; 
  354. if( m_off > m_size )
  355. {
  356. m_size = m_off;
  357. }
  358. }
  359. unsigned int mf_size (thandle_t fd)
  360. {
  361. CMemFile* pFile = CheckHandle( fd );
  362. if( pFile == NULL )
  363. return -1;
  364. return pFile->Size();
  365. }
  366. int mf_map (thandle_t fd, void **addr, size_t *len)
  367. {
  368. // CMemFile* pFile = CheckHandle( fd );
  369. // if( pFile == NULL )
  370. // return -1;
  371. return 0;
  372. }
  373. void mf_unmap (thandle_t fd, void *addr, size_t len)
  374. {
  375. // CMemFile* pFile = CheckHandle( fd );
  376. // if( pFile == NULL )
  377. // return;
  378. }
  379. int mf_close (thandle_t fd)
  380. {
  381. CMemFile* pFile = CheckHandle( fd );
  382. if( pFile == NULL )
  383. return -1;
  384. return 0;
  385. }
  386. /*
  387. void DebugOut( CMemFile* pFile, char* szOut )
  388. {
  389. FILE* fp = fopen( szOut, "wb" );
  390. fwrite( pFile->m_buf, 1, pFile->m_size, fp );
  391. fclose( fp );
  392. }
  393. */