IRWEngine.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:85k
源码类别:

图形图象

开发平台:

Visual C++

  1. /********************************************************************
  2. IRWEngine.cpp - ISee图像读写引擎实现文件
  3.     版权所有(C) VCHelp-coPathway-ISee workgroup 2000 all member's
  4.     这一程序是自由软件,你可以遵照自由软件基金会出版的GNU 通用许可证
  5. 条款来修改和重新发布这一程序。或者用许可证的第二版,或者(根据你
  6. 的选择)用任何更新的版本。
  7.     发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特定
  8. 目地的隐含的担保。更详细的情况请参阅GNU通用许可证。
  9.     你应该已经和程序一起收到一份GNU通用许可证(GPL)的副本。如果还没有,
  10. 写信给:
  11.     The Free Software Foundation, Inc.,  675  Mass Ave,  Cambridge,
  12.     MA02139,  USA
  13. 如果你在使用本软件时有什么问题或建议,用以下地址可以与我们取得联
  14. 系:
  15. http://isee.126.com
  16. http://www.vchelp.net
  17. 或:
  18. iseesoft@china.com
  19. 作  者:YZ E-mail:yzfree@sina.com
  20. Analyst E-mail:analyst@citiz.net
  21.     功能实现:图像读写插件的封装,独立的工作线程,透明的读写过程。
  22. 文件版本:
  23. Build 00009
  24. Date  2000-12-20
  25. ********************************************************************/
  26. #include "stdafx.h"
  27. #include "IRWERegTabFunction.h"
  28. #include "IRWEngineInfoList.h"
  29. #include "IRWEngine.h"
  30. #ifdef _DEBUG
  31. #define new DEBUG_NEW
  32. #undef THIS_FILE
  33. static char THIS_FILE[] = __FILE__;
  34. #endif
  35. // 图像读写引擎实体。(唯一的一个实体,不允许再定义另外的的实体)
  36. static CIRWEngine isee_img_engine;
  37. //@@@@@@@@@@@命令处理函数@@@@@@@@@@@@@@
  38. // 判断指定文件是否是能被处理的图像文件(精确型)
  39. void _fnIRWEC_IS_VALID_FILE(CReturnReceipt *lpCRRt, BOOL type = FALSE);
  40. // 获取图像文件的信息
  41. void _fnIRWEC_GET_FILE_INFO(CReturnReceipt *lpCRRt);
  42. // 将图像文件读入内存
  43. void _fnIRWEC_LOAD_FROM_FILE(CReturnReceipt *lpCRRt);
  44. // 保存图像到文件
  45. void _fnIRWEC_SAVE_TO_FILE(CReturnReceipt *lpCRRt);
  46. // 获取指定尺寸的图像
  47. void _fnIRWEC_RESIZE(CReturnReceipt *lpCRRt);
  48. // 获取拇指图
  49. void _fnIRWEC_GET_THUM_IMAGE(CReturnReceipt *lpCRRt, BOOL keepbit);
  50. //@@@@@@@@@@@命令处理函数的助手@@@@@@@@@@@
  51. int _fnIRWEC_Helper_IS_VALID_FILE(CReturnReceipt *, int);
  52. int _fnIRWEC_Helper_GET_FILE_INFO(CReturnReceipt *, int);
  53. //@@@@@@@@@@@引擎助手函数@@@@@@@@@@@
  54. // 调入指定插件
  55. int _IRWE_SureActive(int ID);
  56. // 调入所有插件
  57. int _IRWE_ActiveAll(void);
  58. // 确定指定的文件能被哪个插件处理,并返回插件的ID
  59. int _IRWE_QueryFileProcID(LPCTSTR lpFileName);
  60. // 初始化插件函数内部助手-刷新系统注册表
  61. int _IRWE_UpdateRegTab();
  62. // 建立插件信息数组
  63. int _IRWE_CreatePluginsInfoStock(void);
  64. // 销毁插件信息数组
  65. int _IRWE_DestroyPluginsInfoStock(void);
  66. // 发送命令到总命令列表
  67. int _IRWE_PostCommandToImgEngine(CReturnReceipt *lpCommand, BOOL pri=FALSE);
  68. // 从总命令队列读取命令
  69. CReturnReceipt *_IRWE_ReadCommandFromTotalList(void);
  70. // 图像读写引擎线程入口点
  71. UINT ie_ThreadEnter(LPVOID pParam);
  72. //@@@@缩放代码相关定义@@@@Add by Analyst 2000-12-19@@@@
  73. // Alpha表
  74. static QWORD s_AlphaTable[_IRWE_THUM_APLHATAB_SIZE];
  75. // Alpha表初始化
  76. void _Thum_InitAlphaTable();
  77. // 缩放接口函数
  78. void _Thum_BlitStretch(DWORD **lpDesLines, int deswidth, int desheight, 
  79. DWORD **lpSrcLines, int srcwidth, int srcheight);
  80. // 行缩放函数
  81. void _Thum_DrawScanLine(DWORD* DestAddr, DWORD* SrcAddr, 
  82. int Width, DWORD dU);
  83. void _Thum_DrawScanLineAlpha(DWORD* DestAddr, DWORD* SrcAddr, 
  84. int Width, DWORD dU, DWORD Alpha);
  85. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  86. #define ENGINE_ID 101 // 引擎线程标识
  87. #define INIT_ACTIVE_PLUGINS_NUM 3 // 初始调入插件个数
  88. // 引擎状态标志,用以表明图像读写引擎是否已建立。如果
  89. // 这个值是IRWES_DEATH,则说明引擎还未被建立,如果该
  90. // 是IRWES_EXIST,则说明引擎已经被建立起来了。
  91. // 注:引擎只能被创建一次,如果多次调用引擎的创建函数
  92. //     ,在调试版中将引发断言。
  93. static int m_IRWEState = IRWES_DEATH;
  94. static UINT m_EngineID = ENGINE_ID; // 引擎的ID
  95. static HANDLE m_EngineHandle = NULL; // 引擎句柄
  96. static _IRWEC_InfoList m_EngineData; // 图像读写模块信息表
  97. static BYTE m_ProcType[IRWE_PROCTYPE_SIZE]; // 引擎能处理的文件类型(用大写的文件扩展名标识,扩展名之间用逗号分隔)
  98. static int m_ProcID[IRWE_PROCID_SIZE]; // 能处理的文件类型与插件ID的对照表
  99. static int m_ProcCount; // 能处理的文件类型总数
  100. static CWinThread *ISee_pImgEngineThread = NULL; // 图像读写引擎线程指针
  101. static HANDLE m_EnterEvent; // 线程入口点事件
  102. static BOOL m_EngineWorkSignal = FALSE; // 引擎线程工作信号(TRUE—工作,FALSE—不工作)
  103. static CPtrList m_CommandList(256); // 命令队列实体
  104. static CRITICAL_SECTION  m_CLCriticalSection; // 命令队列访问关键段
  105. static CReturnReceipt *m_pCurrentReturnReceipt; // 当前正在处理的回执单
  106. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  107. // 图像读写引擎全局助手函数
  108. //
  109. // 获取图像读写引擎(指针类型)
  110. CIRWEngine *ISeeGetIRWEngine()
  111. {
  112. return (m_IRWEState == IRWES_DEATH) ? NULL:(CIRWEngine*)(&isee_img_engine);
  113. }
  114. // 查询图像读写引擎状态
  115. int ISeeQuestionIRWEState()
  116. {
  117. return m_IRWEState;
  118. }
  119. // 创建图像读写引擎
  120. int ISeeBeginIRWEngine()
  121. {
  122. ASSERT(ISeeQuestionIRWEState() == IRWES_DEATH); // 创建之后不能再调用此函数
  123. ASSERT(m_EngineData.GetUsedElemSize() == 0);
  124. // 建立信息库
  125. int result = _IRWE_CreatePluginsInfoStock();
  126. if (result != 0)
  127. return -1; // 引擎信息库无法创建
  128. // 创建手动、初始化状态为非信号化的事件
  129. m_EnterEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
  130. if (!m_EnterEvent)
  131. {
  132. _IRWE_DestroyPluginsInfoStock();
  133. return -2; // 无法创建同步事件
  134. }
  135. // 非信号化
  136. ::ResetEvent(m_EnterEvent);
  137. // 创建图像读写引擎
  138. if (!(ISee_pImgEngineThread = ::AfxBeginThread(ie_ThreadEnter, NULL)))
  139. {
  140. ::CloseHandle(m_EnterEvent);
  141. _IRWE_DestroyPluginsInfoStock();
  142. return -3; // 无法创建引擎线程
  143. }
  144. ISee_pImgEngineThread->m_bAutoDelete = FALSE;
  145. // 等待线程初始化完毕
  146. ::WaitForSingleObject(m_EnterEvent, 6000);
  147. ::CloseHandle(m_EnterEvent);
  148. // 初始化缩放代码所需的Alpha表
  149. _Thum_InitAlphaTable();
  150. m_EngineWorkSignal = TRUE;
  151. ASSERT(IRWES_DEATH == m_IRWEState);
  152. m_IRWEState = IRWES_EXIST;
  153. return 0; // 引擎已成功创建
  154. }
  155. // 关闭图像读写引擎
  156. void ISeeEndIRWEngine()
  157. {
  158. if (ISeeQuestionIRWEState() == IRWES_DEATH)
  159. return;
  160. isee_img_engine.Destruct();
  161. delete ISee_pImgEngineThread;
  162. }
  163. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  164. // 图像读写引擎接口函数
  165. //
  166. // 接口类初始化
  167. CIRWEngine::CIRWEngine()
  168. {
  169. VERIFY(this == (CIRWEngine*)&isee_img_engine); // 只能有一个实体
  170. int i;
  171. m_IRWEState = IRWES_DEATH;
  172. m_EngineID = ENGINE_ID;
  173. m_EngineHandle = NULL;
  174. m_EngineData.ZeroAllElement();
  175. ::ZeroMemory((PVOID)m_ProcType, IRWE_PROCTYPE_SIZE);
  176. for (i=0;i<IRWE_PROCID_SIZE;i++)
  177. m_ProcID[i] = -1;
  178. m_ProcCount = 0;
  179. }
  180. // 引擎析构
  181. CIRWEngine::~CIRWEngine()
  182. {
  183. if (m_IRWEState == IRWES_EXIST)
  184. Destruct();
  185. }
  186. // 暂停引擎的工作
  187. void CIRWEngine::Pause()
  188. {
  189. m_EngineWorkSignal = FALSE;
  190. }
  191. // 恢复引擎的工作
  192. void CIRWEngine::Restore()
  193. {
  194. m_EngineWorkSignal = TRUE;
  195. }
  196. // 获取能处理的文件的过滤串(用于FileDialog)
  197. LPTSTR CIRWEngine::GetFileFilterString()
  198. {
  199. ASSERT(ISeeQuestionIRWEState() == IRWES_EXIST);
  200. ASSERT(m_EngineData.GetUsedElemSize() > 0);
  201. CString cstmp;
  202. CString cstmp2;
  203. PBYTE lpTmp = (PBYTE)m_ProcType; // 文件类型描述串
  204. BYTE ProcBuf[8], tmp;
  205. int i, j;
  206. cstmp = (LPCTSTR)"所有被支持的图像文件 (";
  207. cstmp2.Empty();
  208. for (i=0;i<m_ProcCount;i++)
  209. {
  210. j = 0;
  211. while( ((tmp=*lpTmp++) != ',') && (tmp != 0) )
  212. ProcBuf[j++] = tmp;
  213. ProcBuf[j] = 0;
  214. ASSERT(j < 5);
  215. ::_strlwr((char*)ProcBuf); // 转换为小写
  216. cstmp2 += (LPCTSTR)"*.";
  217. cstmp2 += (LPCTSTR)ProcBuf;
  218. if ((i+1) != m_ProcCount)
  219. cstmp2 += (LPCTSTR)"; ";
  220. }
  221. ASSERT(cstmp2.GetLength() > 0); // 起码应该有一种图像被支持
  222. cstmp += cstmp2;
  223. cstmp += (LPCTSTR)")|";
  224. cstmp += cstmp2;
  225. cstmp += (LPCTSTR)"|";
  226. lpTmp = (PBYTE)m_ProcType; // 文件类型描述串
  227. for (i=0;i<m_ProcCount;i++)
  228. {
  229. j = 0;
  230. while( ((tmp=*lpTmp++) != ',') && (tmp != 0) )
  231. ProcBuf[j++] = tmp;
  232. ProcBuf[j] = 0;
  233. ASSERT(j < 5);
  234. cstmp += (LPCTSTR)ProcBuf;
  235. cstmp += (LPCTSTR)"文件 (";
  236. ::_strlwr((char*)ProcBuf); // 转换为小写
  237. cstmp += (LPCTSTR)"*.";
  238. cstmp += (LPCTSTR)ProcBuf;
  239. cstmp += (LPCTSTR)")|*.";
  240. cstmp += (LPCTSTR)ProcBuf;
  241. cstmp += (LPCTSTR)"|";
  242. }
  243. cstmp += (LPCTSTR)"所有文件 (*.*)|*.*||";
  244. LPTSTR lpResult = (LPTSTR)::GlobalAlloc(GPTR, cstmp.GetLength()+1);
  245. if (!lpResult)
  246. return NULL;
  247. // 复制过滤串
  248. ::CopyMemory((PVOID)lpResult, (PVOID)(LPCTSTR)cstmp, cstmp.GetLength()+1);
  249. return lpResult;
  250. }
  251. // 查询指定文件是否是能处理的图象文件(简版,只从扩展名判断)
  252. BOOL CIRWEngine::IsValidImageFile(LPCTSTR lpFileName)
  253. {
  254. // 确定指定的文件能被哪个插件处理,TRUE表示能被处理(只从扩展名上看)
  255. return (_IRWE_QueryFileProcID(lpFileName) == -1) ? FALSE:TRUE;
  256. }
  257. // 查询指定文件是否是能处理的图象文件(标准版,根据文件的内容判断)
  258. CReturnReceipt *CIRWEngine::IsValidImageFile(LPCTSTR lpFileName, BOOL type)
  259. {
  260. // 参数 BOOL type是指判断精度标志:TRUE-精确判断, FALSE-普通判断
  261. // 精确判断就是不以文件的扩展名为首要的判断标准,而是让
  262. // 所有的图像读写模块都判断一遍。这样做的好处是可以找出
  263. // 那些修改了扩展名的图像文件,但缺点是速度非常低。
  264. CReturnReceipt *lptmp = new CReturnReceipt;
  265. if (!lptmp)
  266. return NULL;
  267. lptmp->m_processing = IRWEPROC_INITING;
  268. if (type == FALSE) // 普通判断
  269. lptmp->m_command = IRWEC_IS_VALID_FILE_COMN;
  270. else
  271. { // 精确判断
  272. ASSERT(type == TRUE);
  273. lptmp->m_command = IRWEC_IS_VALID_FILE_NICETY;
  274. }
  275. ::lstrcpy((LPTSTR)lptmp->m_filename, (LPCTSTR)lpFileName);
  276. // 发送回执单至命令队列
  277. _IRWE_PostCommandToImgEngine(lptmp);
  278. // 等待
  279. while((lptmp->m_processing==IRWEPROC_FELL_IN)||(lptmp->m_processing==IRWEPROC_PROCESSING));
  280. return lptmp;
  281. }
  282. // 获取图像信息
  283. CReturnReceipt *CIRWEngine::GetImageFileInfo(LPCTSTR lpFileName)
  284. {
  285. CReturnReceipt *lptmp = new CReturnReceipt;
  286. if (!lptmp)
  287. return NULL;
  288. lptmp->m_processing = IRWEPROC_INITING;
  289. lptmp->m_command = IRWEC_GET_FILE_INFO;
  290. ::lstrcpy((LPTSTR)lptmp->m_filename, (LPCTSTR)lpFileName);
  291. // 发送回执单至命令队列
  292. _IRWE_PostCommandToImgEngine(lptmp);
  293. return lptmp;
  294. }
  295. // 获取图像信息
  296. void CIRWEngine::GetImageFileInfo(CReturnReceipt *pCRRt)
  297. {
  298. ASSERT(pCRRt);
  299. ASSERT(pCRRt->m_processing >= IRWEPROC_COMPLETE);
  300. // 注:不能重复发送同一个回执单到引擎中!也就是说同一个回执单
  301. // 不能同时执行两个或两个以上的命令
  302. #ifndef _DEBUG
  303. while(pCRRt->m_processing < IRWEPROC_COMPLETE); // 发布版用此语句替换,但将影响程序的灵敏度
  304. #endif
  305. pCRRt->m_processing = IRWEPROC_INITING;
  306. pCRRt->m_command = IRWEC_GET_FILE_INFO;
  307. ASSERT(::lstrlen((LPCTSTR)(pCRRt->m_filename)));
  308. ASSERT(pCRRt->m_data.state > PKST_NOTVER); // 必须已经通过校验
  309. _IRWE_PostCommandToImgEngine(pCRRt);
  310. }
  311. // 读入图象
  312. CReturnReceipt *CIRWEngine::LoadImageFromFile(
  313. LPCTSTR lpFileName, 
  314. BOOL pri/*命令的优先级,TRUE为高级命令,会被优先处理*/)
  315. {
  316. CReturnReceipt *lptmp = new CReturnReceipt;
  317. if (!lptmp)
  318. return NULL;
  319. lptmp->m_processing = IRWEPROC_INITING;
  320. lptmp->m_command = IRWEC_LOAD_FROM_FILE;
  321. ::lstrcpy((LPTSTR)lptmp->m_filename, (LPCTSTR)lpFileName);
  322. lptmp->m_data.state = PKST_NOTVER;
  323. _IRWE_PostCommandToImgEngine(lptmp, pri);
  324. return lptmp;
  325. }
  326. // 读入图象
  327. void CIRWEngine::LoadImageFromFile(
  328. CReturnReceipt *pCRRt, 
  329. BOOL pri/*命令的优先级,TRUE为高级命令,会被优先处理*/)
  330. {
  331. ASSERT(pCRRt);
  332. ASSERT(pCRRt->m_processing >= IRWEPROC_COMPLETE);
  333. // 注:不能重复发送同一个回执单到引擎中!也就是说同一个回执单
  334. // 不能同时执行两个或两个以上的命令
  335. #ifndef _DEBUG
  336. while(pCRRt->m_processing < IRWEPROC_COMPLETE); // 发布版用此语句替换,但将影响程序的灵敏度
  337. #endif
  338. pCRRt->m_processing = IRWEPROC_INITING;
  339. pCRRt->m_command = IRWEC_LOAD_FROM_FILE;
  340. ASSERT(pCRRt->m_filename);
  341. ASSERT(pCRRt->m_data.state > PKST_NOTVER);
  342. _IRWE_PostCommandToImgEngine(pCRRt, pri);
  343. }
  344. // 保存图象
  345. void CIRWEngine::SaveImageToFile(
  346. LPCTSTR lpNewFileName, // 新的文件的全路径
  347. CReturnReceipt *lpCRRt,
  348. LPBYTE lpSaveInfo, // 用户设定的保存参数
  349. DWORD dwSaveInfoSize)
  350. {
  351. ASSERT(lpCRRt);
  352. ASSERT(lpNewFileName);
  353. ASSERT(lpSaveInfo);
  354. ASSERT(dwSaveInfoSize < DPK_ANNEXINFOSIZE);
  355. ASSERT(lpCRRt->m_data.state >= PKST_INFOANDBITS);
  356. ASSERT(lpCRRt->m_processing >= IRWEPROC_COMPLETE);
  357. // 注:不能重复发送同一个回执单到引擎中!也就是说同一个回执单
  358. // 不能同时执行两个或两个以上的命令
  359. #ifndef _DEBUG
  360. while(lpCRRt->m_processing < IRWEPROC_COMPLETE); // 发布版用此语句替换,但将影响程序的灵敏度
  361. #endif
  362. lpCRRt->m_processing = IRWEPROC_INITING;
  363. lpCRRt->m_command = IRWEC_SAVE_TO_FILE;
  364. ::lstrcpy((LPTSTR)lpCRRt->m_filename, (LPCTSTR)lpNewFileName);
  365. ::CopyMemory((PVOID)lpCRRt->m_data.annexdata.siAnnData, (PVOID)lpSaveInfo, dwSaveInfoSize);
  366. _IRWE_PostCommandToImgEngine(lpCRRt);
  367. }
  368. // 按照指定的大小读入图象
  369. CReturnReceipt *CIRWEngine::LoadImageResize(LPCTSTR lpFileName, CSize& size)
  370. {
  371. CReturnReceipt *lptmp = new CReturnReceipt;
  372. if (!lptmp)
  373. return NULL;
  374. lptmp->m_command = IRWEC_RESIZE;
  375. ::lstrcpy((LPTSTR)lptmp->m_filename, (LPCTSTR)lpFileName);
  376. lptmp->m_processing = IRWEPROC_INITING;
  377. lptmp->m_data.state = PKST_NOTVER;
  378. lptmp->m_data.sDIBInfo.bmi.biWidth = size.cx;
  379. lptmp->m_data.sDIBInfo.bmi.biHeight = size.cy;
  380. _IRWE_PostCommandToImgEngine(lptmp);
  381. return lptmp;
  382. }
  383. // 获取图像文件的拇指图(以ISee格式(倒向32位DIB))
  384. CReturnReceipt *CIRWEngine::GetThumImage(
  385. LPCTSTR lpFileName, // 待读取的文件名串
  386. CRect& rect, // 可以容纳拇指图的最小矩形(拇指图是按比例缩放的)
  387. BOOL keepbit, // 是否保留图像的位数据(在获取拇指图的过程中,
  388. // 整个的图像位数据都将被调入,如果该变量设为FALSE,
  389. // 则在本函数返回前将销毁这些数据。TRUE则保留)
  390. // 如果在调用本命令之前,回执单中已经存在位数据,那
  391. // 么无论此变量设为何值,位数据均不会被删除
  392. BOOL pri) // 命令的执行优先级,TRUE为高优先级命令,会被优先执行
  393. {
  394. ASSERT((lpFileName)&&(::lstrlen(lpFileName)));
  395. ASSERT(rect.Width() == rect.Height()); // 拇指图外围矩形必须是正方形
  396. ASSERT(rect.Width() >= IRWE_THUMIMAGE_MINI_SIZE);
  397. CReturnReceipt *lptmp = new CReturnReceipt;
  398. if (!lptmp)
  399. return NULL;
  400. lptmp->m_processing = IRWEPROC_INITING;
  401. lptmp->m_command = (keepbit) ? IRWEC_GET_THUMIMAGE_A_BIT:IRWEC_GET_THUMIMAGE;
  402. ::lstrcpy((LPTSTR)lptmp->m_filename, (LPCTSTR)lpFileName);
  403. lptmp->m_data.state = PKST_NOTVER;
  404. lptmp->m_thumbnails.m_thumbound = rect;
  405. lptmp->m_thumbnails.m_thumfrom  = IRWETHUM_FROM_CREATE;
  406. _IRWE_PostCommandToImgEngine(lptmp, pri);
  407. return lptmp;
  408. }
  409. // 获取图像文件的拇指图(以ISee格式(倒向32位DIB))
  410. void CIRWEngine::GetThumImage(
  411. CReturnReceipt *pCRRt, // 待读取的文件回执单
  412. CRect& rect, // 同上,略
  413. BOOL keepbit, 
  414. BOOL pri)
  415. {
  416. ASSERT(pCRRt);
  417. ASSERT(rect.Width() == rect.Height()); // 必须是正方形
  418. ASSERT(rect.Width() >= IRWE_THUMIMAGE_MINI_SIZE);
  419. ASSERT(pCRRt->m_processing >= IRWEPROC_COMPLETE);
  420. // 注:不能重复发送同一个回执单到引擎中!也就是说同一个回执单
  421. // 不能同时执行两个或两个以上的命令
  422. #ifndef _DEBUG
  423. while(pCRRt->m_processing < IRWEPROC_COMPLETE); // 发布版用此语句替换,但将影响程序的灵敏度
  424. #endif
  425. pCRRt->m_processing = IRWEPROC_INITING;
  426. pCRRt->m_command = (keepbit) ? IRWEC_GET_THUMIMAGE_A_BIT:IRWEC_GET_THUMIMAGE;
  427. ASSERT(pCRRt->m_filename);
  428. ASSERT(pCRRt->m_data.state > PKST_NOTVER);
  429. pCRRt->m_thumbnails.m_thumbound = rect;
  430. pCRRt->m_thumbnails.m_thumfrom  = IRWETHUM_FROM_CREATE;
  431. _IRWE_PostCommandToImgEngine(pCRRt, pri);
  432. }
  433. // 销毁图像读写引擎
  434. int CIRWEngine::Destruct()
  435. {
  436. CReturnReceipt ics;
  437. HKEY hKey; // 注册表总句柄
  438. HKEY hPlugKey; // 插件句柄
  439. ics.m_command = IRWEC_IN_END;
  440. _IRWE_PostCommandToImgEngine(&ics, TRUE);
  441. VERIFY(::WaitForSingleObject(ISee_pImgEngineThread->m_hThread, INFINITE) == WAIT_OBJECT_0);
  442. m_EngineWorkSignal = FALSE;
  443. int i;
  444. LPIRWMODULEINFO lpIRWEInfo = NULL;
  445. // 打开系统注册表,用于刷新各插件PRI
  446. hKey = _IRWERTF_OpenRegTab();
  447. for (i=0;i<m_EngineData.GetUsedElemSize();i++)
  448. {
  449. lpIRWEInfo = m_EngineData.GetAt(i);
  450. ASSERT(lpIRWEInfo);
  451. if (lpIRWEInfo->m_ModuleState >= IRWEMS_CA)
  452. {
  453. // 插件已经被调入,说明可能发生过读写操作
  454. VERIFY(lpIRWEInfo->m_ModuleState == IRWEMS_CR);
  455. ASSERT(lpIRWEInfo->m_hDll);
  456. // 打开待刷新的插件句柄
  457. hPlugKey = _IRWERTF_OpenPlugins(hKey, (LPCTSTR)(lpIRWEInfo->m_ModuleName));
  458. // 刷新插件优先级值
  459. ASSERT(lpIRWEInfo->m_PRI > 10);
  460. _IRWERTF_SetPluginPRI(hPlugKey, lpIRWEInfo->m_PRI);
  461. _IRWERTF_CloseKey(hPlugKey);
  462. }
  463. }
  464. // 关闭系统注册表
  465. _IRWERTF_CloseKey(hKey);
  466. // 释放插件资源
  467. m_EngineData.Destroy();
  468. // 清理插件相关变量
  469. ::ZeroMemory((PVOID)m_ProcType, IRWE_PROCTYPE_SIZE);
  470. for (i=0;i<IRWE_PROCID_SIZE;i++)
  471. m_ProcID[i] = -1;
  472. m_ProcCount = 0;
  473. // 引擎熄火 :-D
  474. m_IRWEState = IRWES_DEATH;
  475. return 0;
  476. }
  477. // 获取插件开发者的信息
  478. int CIRWEngine::GetDeveloperInfo(LPDEVELOPERINFO *lppDevInfo)
  479. {
  480. ASSERT(ISeeQuestionIRWEState() == IRWES_EXIST);
  481. ASSERT(m_EngineData.GetUsedElemSize() > 0);
  482. LPDEVELOPERINFO lpInfo = (LPDEVELOPERINFO)::GlobalAlloc(GPTR, sizeof(DEVELOPERINFO)*(m_EngineData.GetUsedElemSize()+1));
  483. if (!lpInfo)
  484. {
  485. *lppDevInfo = NULL;
  486. return 0;
  487. }
  488. LPIRWMODULEINFO lpIRWEInfo;
  489. for (int i=0;i<m_EngineData.GetUsedElemSize();i++)
  490. {
  491. lpIRWEInfo = m_EngineData.GetAt(i);
  492. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_SN == i));
  493. // 代码名称
  494. ::CopyMemory((PVOID)(lpInfo[i].modulename), (CONST PVOID)(lpIRWEInfo->m_ModuleName), 16);
  495. // 作者名字(多人时用逗号分隔)
  496. ::CopyMemory((PVOID)(lpInfo[i].author), (CONST PVOID)(lpIRWEInfo->m_Author), 16);
  497. // 作者电邮地址(多人时用逗号分隔)
  498. ::CopyMemory((PVOID)(lpInfo[i].EMail), (CONST PVOID)(lpIRWEInfo->m_EMail), 32);
  499. // 作者的留言信息
  500. ::CopyMemory((PVOID)(lpInfo[i].messages), (CONST PVOID)(lpIRWEInfo->m_Notion), 144);
  501. }
  502. ::lstrcpy((LPTSTR)(lpInfo[i].modulename), (LPCTSTR)_T("图像读写引擎"));
  503. ::lstrcpy((LPTSTR)(lpInfo[i].author), (LPCTSTR)_T("YZ"));
  504. ::lstrcpy((LPTSTR)(lpInfo[i].EMail), (LPCTSTR)_T("yzfree@sina.com"));
  505. ::lstrcpy((LPTSTR)(lpInfo[i].messages), (LPCTSTR)_T("咦哈!做这个破东西差点让我的脑子打结!"));
  506. *lppDevInfo = lpInfo;
  507. // 插件个数加引擎信息
  508. return m_EngineData.GetUsedElemSize()+1;
  509. }
  510. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  511. // 引擎的核心---命令泵
  512. //
  513. UINT ie_ThreadEnter(LPVOID pParam)
  514. {
  515. int exitmark = 0; // 线程结束标志
  516. CReturnReceipt *lpCRRt; // 命令包临时指针
  517. ASSERT(m_CommandList.IsEmpty());// 初创引擎,不应该有信息
  518. ::InitializeCriticalSection(&m_CLCriticalSection);
  519. m_pCurrentReturnReceipt = NULL;
  520. ::SetEvent(m_EnterEvent);
  521. while(!exitmark)
  522. {
  523. // 从命令队列中获取命令
  524. // -如果工作标志为FALSE或命令队列中没有命令,则 修眠—循环
  525. if ( (m_EngineWorkSignal == FALSE)||
  526.  ((lpCRRt=_IRWE_ReadCommandFromTotalList()) == NULL) )
  527. {
  528. ::Sleep(10); // 休眠10毫秒
  529. continue;
  530. }
  531. // 设置为当前正在处理的回执单
  532. m_pCurrentReturnReceipt = lpCRRt;
  533. // 分发命令
  534. switch(lpCRRt->GetCommand())
  535. {
  536. case IRWEC_IS_VALID_FILE_COMN: // 判断指定文件是否是能被处理的图像文件(普通型)
  537. _fnIRWEC_IS_VALID_FILE(lpCRRt, FALSE);
  538. break;
  539. case IRWEC_IS_VALID_FILE_NICETY: // 判断指定文件是否是能被处理的图像文件(精确型)
  540. _fnIRWEC_IS_VALID_FILE(lpCRRt, TRUE);
  541. break;
  542. case IRWEC_GET_FILE_INFO: // 获取图像文件的信息
  543. _fnIRWEC_GET_FILE_INFO(lpCRRt);
  544. break;
  545. case IRWEC_LOAD_FROM_FILE: // 将图像文件读入内存
  546. _fnIRWEC_LOAD_FROM_FILE(lpCRRt);
  547. break;
  548. case IRWEC_SAVE_TO_FILE: // 保存图像到文件
  549. _fnIRWEC_SAVE_TO_FILE(lpCRRt);
  550. break;
  551. case IRWEC_RESIZE: // 获取指定尺寸的图像
  552. _fnIRWEC_RESIZE(lpCRRt);
  553. break;
  554. case IRWEC_IN_END: // 结束引擎线程
  555. exitmark = 1;
  556. ::EnterCriticalSection(&m_CLCriticalSection);
  557. while(m_CommandList.GetCount() > 0)
  558. {
  559. lpCRRt = (CReturnReceipt *)(m_CommandList.RemoveHead());
  560. lpCRRt->m_processing = IRWEPROC_FAIL;
  561. lpCRRt->m_errorinfo  = IRWEERR_ENGINECLOSE;
  562. }
  563. ::LeaveCriticalSection(&m_CLCriticalSection);
  564. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  565. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  566. break;
  567. case IRWEC_GET_THUMIMAGE: // 获取拇指图
  568. _fnIRWEC_GET_THUM_IMAGE(lpCRRt, FALSE);
  569. break;
  570. case IRWEC_GET_THUMIMAGE_A_BIT: // 获取拇指图并保留位数据
  571. _fnIRWEC_GET_THUM_IMAGE(lpCRRt, TRUE);
  572. break;
  573. //case IRWEC_XXX: // 新的命令在此加入
  574. default:
  575. ASSERT(FALSE);
  576. exitmark = 1;
  577. break;
  578. }
  579. m_pCurrentReturnReceipt = NULL;
  580. }
  581. ::DeleteCriticalSection(&m_CLCriticalSection);
  582. return 0;
  583. }
  584. //#######################################################################
  585. // 助手函数
  586. //
  587. int _fnIRWEC_Helper_IS_VALID_FILE(CReturnReceipt *lpCRRt, int id)
  588. {
  589. ASSERT(id >= 0);
  590. ASSERT(lpCRRt);
  591. int result;
  592. LPIRWMODULEINFO lpIRWEInfo = m_EngineData.GetAt(id);
  593. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_ModuleState==IRWEMS_CR));
  594. ASSERT(lpIRWEInfo->m_IRWPInterFace); // 此时对应的插件必须已被调入
  595. lpIRWEInfo->m_ModuleState = IRWEMS_CA; // 标志该插件进入工作状态
  596. lpCRRt->m_data.comm = CMD_IS_VALID_FILE;
  597. lpCRRt->m_data.result = ER_EMPTY;
  598. lpCRRt->m_data.annexdata.iAnnData = 0;
  599. ::lstrcpy(lpCRRt->m_data.filename, lpCRRt->m_filename);
  600. lpCRRt->m_data.state = PKST_NOTVER;
  601. result = lpIRWEInfo->m_IRWPInterFace((LPINFOSTR)lpCRRt);// 调用图像读写模块
  602. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  603. return result;
  604. }
  605. int _fnIRWEC_Helper_GET_FILE_INFO(CReturnReceipt *lpCRRt, int id)
  606. {
  607. ASSERT(id >= 0);
  608. ASSERT(lpCRRt);
  609. int result;
  610. LPIRWMODULEINFO lpIRWEInfo = m_EngineData.GetAt(id);
  611. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_ModuleState==IRWEMS_CR));
  612. ASSERT(lpIRWEInfo->m_IRWPInterFace); // 此时对应的插件必须已被调入
  613. lpIRWEInfo->m_ModuleState = IRWEMS_CA;
  614. lpCRRt->m_data.comm = CMD_GET_FILE_INFO;
  615. lpCRRt->m_data.result = ER_EMPTY;
  616. ::ZeroMemory((PVOID)&(lpCRRt->m_data.imginfo), sizeof(IMAGEINFOSTR));
  617. ::lstrcpy(lpCRRt->m_data.filename, lpCRRt->m_filename);
  618. ASSERT(lpCRRt->m_data.state == PKST_PASSVER);
  619. result = lpIRWEInfo->m_IRWPInterFace((LPINFOSTR)lpCRRt);
  620. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  621. return result;
  622. }
  623. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  624. // 命令处理函数
  625. //
  626. // 判断指定文件是否是能被处理的图像文件
  627. void _fnIRWEC_IS_VALID_FILE(CReturnReceipt *lpCRRt, BOOL type)
  628. {
  629. ASSERT(lpCRRt);
  630. ASSERT(::lstrlen((LPCTSTR)lpCRRt->m_filename));
  631. ASSERT((lpCRRt->m_command == IRWEC_IS_VALID_FILE_COMN)||(lpCRRt->m_command == IRWEC_IS_VALID_FILE_NICETY));
  632. // 调用本函数时,回执单中不能含有图像信息及位数据!
  633. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  634. ASSERT(lpCRRt->m_data._pbdata == NULL);
  635. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  636. int result;
  637. // 简单判断该文件是否能被插件处理
  638. int id = _IRWE_QueryFileProcID((LPCTSTR)(lpCRRt->m_filename));
  639. if (id >= 0) // 如果文件的扩展名已经明确的指出了图像类型
  640. {
  641. // 确保插件被调入
  642. if (_IRWE_SureActive(id) < 0)
  643. {
  644. // 调入插件失败
  645. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  646. lpCRRt->m_modelID = -1;
  647. lpCRRt->m_processing = IRWEPROC_FAIL;
  648. return;
  649. }
  650. // 执行判断操作
  651. _fnIRWEC_Helper_IS_VALID_FILE(lpCRRt, id);
  652. if (lpCRRt->m_data.result != ER_SUCCESS)
  653. {
  654. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  655. lpCRRt->m_modelID = -1;
  656. lpCRRt->m_processing = IRWEPROC_FAIL;
  657. return;
  658. }
  659. else
  660. {
  661. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  662. if (lpCRRt->m_data.annexdata.iAnnData == 1)
  663. {
  664. ASSERT(lpCRRt->m_data.state == PKST_PASSVER);
  665. lpCRRt->m_modelID = id; // 可以被处理则该变量值有效
  666. }
  667. else
  668. {
  669. ASSERT(lpCRRt->m_data.state == PKST_NOTVER);
  670. lpCRRt->m_modelID = -1;
  671. }
  672. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  673. // 判断指定的文件是否是能被处理的图像文件,应判断m_modelID
  674. // 是否为-1,如果是则表示不能被处理。大于等于0表示能被处理
  675. return;
  676. }
  677. }
  678. // 如果插件不能处理该文件,并且不要求精确判断,则返回不能处理
  679. if (type == FALSE)
  680. {
  681. lpCRRt->m_data.annexdata.iAnnData = 0;
  682. lpCRRt->m_data.state = PKST_NOTVER;
  683. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  684. lpCRRt->m_modelID = -1;
  685. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  686. return;
  687. }
  688. // 用户要求精确判定,调入所有的读写模块
  689. result = _IRWE_ActiveAll();
  690. if (result <= 0)
  691. {
  692. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  693. lpCRRt->m_modelID = -1;
  694. lpCRRt->m_processing = IRWEPROC_FAIL;
  695. return;
  696. }
  697. int i, count = result; // result=所有可用插件的个数
  698. for (i=0;i<count;i++)
  699. {
  700. // 执行判断操作
  701. _fnIRWEC_Helper_IS_VALID_FILE(lpCRRt, i);
  702. if (lpCRRt->m_data.result != ER_SUCCESS)
  703. {
  704. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  705. lpCRRt->m_modelID = -1;
  706. lpCRRt->m_processing = IRWEPROC_FAIL;
  707. return;
  708. }
  709. else
  710. {
  711. if (lpCRRt->m_data.annexdata.iAnnData == 1)
  712. {
  713. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  714. lpCRRt->m_modelID   = i;
  715. lpCRRt->m_processing= IRWEPROC_COMPLETE;
  716. return;
  717. }
  718. }
  719. }
  720. ASSERT(lpCRRt->m_data.annexdata.iAnnData == 0);
  721. ASSERT(lpCRRt->m_data.state == PKST_NOTVER);
  722. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  723. lpCRRt->m_modelID = -1;
  724. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  725. return;
  726. }
  727. // 获取图像文件的信息
  728. void _fnIRWEC_GET_FILE_INFO(CReturnReceipt *lpCRRt)
  729. {
  730. ASSERT(lpCRRt);
  731. ASSERT(::lstrlen((LPCTSTR)lpCRRt->m_filename));
  732. ASSERT(lpCRRt->m_command == IRWEC_GET_FILE_INFO);
  733. int id;
  734. switch(lpCRRt->m_data.state)
  735. {
  736. case PKST_NOTVER:
  737. {
  738. // 在当前状态下,回执单中不应含有图像信息及位数据
  739. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  740. ASSERT(lpCRRt->m_data._pbdata == NULL);
  741. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  742. // 简单判断该文件是否能被插件处理
  743. id = _IRWE_QueryFileProcID((LPCTSTR)(lpCRRt->m_filename));
  744. if (id >= 0)
  745. {
  746. // 确保插件已被调入
  747. if (_IRWE_SureActive(id) < 0)
  748. {
  749. // 调入插件失败
  750. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  751. lpCRRt->m_modelID = -1;
  752. lpCRRt->m_processing = IRWEPROC_FAIL;
  753. return;
  754. }
  755. // 执行判断操作
  756. _fnIRWEC_Helper_IS_VALID_FILE(lpCRRt, id);
  757. if (lpCRRt->m_data.result != ER_SUCCESS)
  758. {
  759. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  760. lpCRRt->m_modelID = -1;
  761. lpCRRt->m_processing = IRWEPROC_FAIL;
  762. return;
  763. }
  764. else
  765. {
  766. if (lpCRRt->m_data.annexdata.iAnnData == 0)
  767. {
  768. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  769. lpCRRt->m_modelID = -1;
  770. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  771. return;
  772. }
  773. else
  774. {
  775. // 指定的文件可以被插件处理,转到下一个CASE
  776. ASSERT(lpCRRt->m_data.state == PKST_PASSVER);
  777. lpCRRt->m_modelID = id;
  778. }
  779. }
  780. }
  781. else
  782. {
  783. // 不能被插件处理的文件
  784. lpCRRt->m_data.annexdata.iAnnData = 0;
  785. lpCRRt->m_data.state = PKST_NOTVER;
  786. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  787. lpCRRt->m_modelID = -1;
  788. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  789. return;
  790. }
  791. }
  792. case PKST_PASSVER:
  793. ASSERT(lpCRRt->m_modelID >= 0);
  794. // 在当前状态下,回执单中不应含有图像信息及位数据
  795. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  796. ASSERT(lpCRRt->m_data._pbdata == NULL);
  797. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  798. // 确保插件已被调入
  799. if (_IRWE_SureActive(lpCRRt->m_modelID) < 0)
  800. {
  801. // 调入插件失败
  802. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  803. lpCRRt->m_modelID = -1;
  804. lpCRRt->m_processing = IRWEPROC_FAIL;
  805. return;
  806. }
  807. // 执行提取操作
  808. _fnIRWEC_Helper_GET_FILE_INFO(lpCRRt, lpCRRt->m_modelID);
  809. if (lpCRRt->m_data.result != ER_SUCCESS)
  810. {
  811. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  812. lpCRRt->m_processing = IRWEPROC_FAIL;
  813. return;
  814. }
  815. else
  816. {
  817. ASSERT(lpCRRt->m_data.state == PKST_PASSINFO);
  818. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  819. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  820. return;
  821. }
  822. case PKST_PASSINFO:
  823. ASSERT(FALSE); // 程序出现了重复调用(该回执单已经有图像信息数据了)
  824. VERIFY(lpCRRt->m_modelID >= 0);
  825. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  826. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  827. return;
  828. case PKST_INFOANDBITS:
  829. default:
  830. VERIFY(FALSE); // 不允许出现这种情况
  831. ::AfxMessageBox((LPCTSTR)_T("程序发生异常,您现在最好关闭本程序,以免使系统崩溃。"));
  832. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  833. lpCRRt->m_modelID = -1;
  834. lpCRRt->m_processing = IRWEPROC_FAIL;
  835. return;
  836. }
  837. }
  838. // 将图像文件读入内存
  839. void _fnIRWEC_LOAD_FROM_FILE(CReturnReceipt *lpCRRt)
  840. {
  841. ASSERT(lpCRRt);
  842. ASSERT(::lstrlen((LPCTSTR)lpCRRt->m_filename));
  843. ASSERT(lpCRRt->m_command == IRWEC_LOAD_FROM_FILE);
  844. int result, id, y;
  845. LPIRWMODULEINFO lpIRWEInfo;
  846. switch(lpCRRt->m_data.state)
  847. {
  848. case PKST_NOTVER:
  849. {
  850. // 在当前状态下,回执单中不应含有图像信息及位数据
  851. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  852. ASSERT(lpCRRt->m_data._pbdata == NULL);
  853. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  854. // 简单判断该文件是否能被插件处理
  855. id = _IRWE_QueryFileProcID((LPCTSTR)(lpCRRt->m_filename));
  856. if (id >= 0)
  857. {
  858. if (_IRWE_SureActive(id) < 0) // 确保插件已被调入
  859. {
  860. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  861. lpCRRt->m_modelID = -1;
  862. lpCRRt->m_processing = IRWEPROC_FAIL;
  863. return;
  864. }
  865. // 执行判断操作
  866. _fnIRWEC_Helper_IS_VALID_FILE(lpCRRt, id);
  867. if (lpCRRt->m_data.result != ER_SUCCESS)
  868. {
  869. // 读写模块在执行过程中发生错误
  870. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  871. lpCRRt->m_modelID = -1;
  872. lpCRRt->m_processing = IRWEPROC_FAIL;
  873. return;
  874. }
  875. else
  876. {
  877. if (lpCRRt->m_data.annexdata.iAnnData == 0)
  878. {
  879. // 指定文件不能被处理
  880. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  881. lpCRRt->m_modelID = -1;
  882. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  883. return;
  884. }
  885. else
  886. {
  887. ASSERT(lpCRRt->m_data.state == PKST_PASSVER);
  888. lpCRRt->m_modelID = id; // 能处理
  889. }
  890. }
  891. }
  892. else
  893. {
  894. // 如果用文件的扩展名无法判断出类型,则返回
  895. lpCRRt->m_data.annexdata.iAnnData = 0;
  896. lpCRRt->m_data.state = PKST_NOTVER;
  897. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  898. lpCRRt->m_modelID = -1;
  899. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  900. return;
  901. }
  902. }
  903. case PKST_PASSVER:
  904. ASSERT(lpCRRt->m_modelID >= 0);
  905. // 在当前状态下,回执单中不应含有图像信息及位数据
  906. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  907. ASSERT(lpCRRt->m_data._pbdata == NULL);
  908. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  909. // 确保插件已被调入
  910. if (_IRWE_SureActive(lpCRRt->m_modelID) < 0)
  911. {
  912. // 调入插件失败
  913. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  914. lpCRRt->m_modelID = -1;
  915. lpCRRt->m_processing = IRWEPROC_FAIL;
  916. return;
  917. }
  918. // 执行提取操作
  919. _fnIRWEC_Helper_GET_FILE_INFO(lpCRRt, lpCRRt->m_modelID);
  920. if (lpCRRt->m_data.result != ER_SUCCESS)
  921. {
  922. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  923. lpCRRt->m_processing = IRWEPROC_FAIL;
  924. return;
  925. }
  926. ASSERT(lpCRRt->m_data.state == PKST_PASSINFO);
  927. case PKST_PASSINFO:
  928. ASSERT(lpCRRt->m_modelID >= 0);
  929. // 在当前状态下,回执单中不应含有图像信息及位数据
  930. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  931. ASSERT(lpCRRt->m_data._pbdata == NULL);
  932. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  933. lpIRWEInfo = m_EngineData.GetAt(lpCRRt->m_modelID);
  934. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_ModuleState==IRWEMS_CR));
  935. ASSERT(lpIRWEInfo->m_IRWPInterFace);
  936. lpCRRt->m_data.comm = CMD_LOAD_FROM_FILE;
  937. lpCRRt->m_data.result = ER_EMPTY;
  938. lpCRRt->m_data.pImgInfo = NULL;
  939. lpCRRt->m_data.sDIBInfo.bmi.biSize     = sizeof(BITMAPINFOHEADER);
  940. ASSERT(lpCRRt->m_data.imginfo.width  > 0);
  941. lpCRRt->m_data.sDIBInfo.bmi.biWidth    = lpCRRt->m_data.imginfo.width;
  942. ASSERT(lpCRRt->m_data.imginfo.height > 0);
  943. lpCRRt->m_data.sDIBInfo.bmi.biHeight   = lpCRRt->m_data.imginfo.height;
  944. lpCRRt->m_data.sDIBInfo.bmi.biPlanes   = 1;
  945. lpCRRt->m_data.sDIBInfo.bmi.biBitCount = ISEE_IMAGE_BITCOUNT;// 恒定为32
  946. lpCRRt->m_data.sDIBInfo.bmi.biCompression = BI_RGB;
  947. lpCRRt->m_data.sDIBInfo.bmi.biSizeImage   = 0;
  948. lpCRRt->m_data.sDIBInfo.bmi.biXPelsPerMeter = 0;
  949. lpCRRt->m_data.sDIBInfo.bmi.biYPelsPerMeter = 0;
  950. lpCRRt->m_data.sDIBInfo.bmi.biClrUsed       = 0;
  951. lpCRRt->m_data.sDIBInfo.bmi.biClrImportant  = 0;
  952. lpCRRt->m_data.sDIBInfo.rmask     = 0xff0000;
  953. lpCRRt->m_data.sDIBInfo.gmask     = 0xff00;
  954. lpCRRt->m_data.sDIBInfo.bmask     = 0xff;
  955. lpCRRt->m_data.sDIBInfo.alphaMask = 0;
  956. // 分配用于存放标准图像位数据的内存块
  957. lpCRRt->m_data._pbdata = (PBYTE)::GlobalAlloc(GMEM_FIXED, lpCRRt->m_data.sDIBInfo.bmi.biWidth*(ISEE_IMAGE_BITCOUNT/8)*lpCRRt->m_data.sDIBInfo.bmi.biHeight);
  958. if (!lpCRRt->m_data._pbdata)
  959. {
  960. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  961. lpCRRt->m_processing = IRWEPROC_FAIL;
  962. return;
  963. }
  964. // 分配用于存放每一扫描行地址的指针数组并初始化
  965. lpCRRt->m_data.pLineAddr = (DWORD**)::GlobalAlloc(GPTR, lpCRRt->m_data.sDIBInfo.bmi.biHeight*sizeof(DWORD*));
  966. if (!lpCRRt->m_data.pLineAddr)
  967. {
  968. ::GlobalFree(lpCRRt->m_data._pbdata);
  969. lpCRRt->m_data._pbdata = NULL;
  970. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  971. lpCRRt->m_processing = IRWEPROC_FAIL;
  972. return;
  973. }
  974. // 初始化行首数组
  975. for (y=0;y<lpCRRt->m_data.sDIBInfo.bmi.biHeight;y++)
  976. lpCRRt->m_data.pLineAddr[y] = (DWORD*)(lpCRRt->m_data._pbdata+((lpCRRt->m_data.sDIBInfo.bmi.biHeight-y-1)*(lpCRRt->m_data.sDIBInfo.bmi.biWidth*(ISEE_IMAGE_BITCOUNT/8))));
  977. lpIRWEInfo->m_ModuleState = IRWEMS_CA;
  978. if (lpIRWEInfo->m_PRI < 0xffffffff)
  979. lpIRWEInfo->m_PRI++; // 优先级数加一
  980. // 读取文件中的图像数据
  981. result = lpIRWEInfo->m_IRWPInterFace((LPINFOSTR)lpCRRt);
  982. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  983. if (lpCRRt->m_data.result != ER_SUCCESS)
  984. {
  985. // 读取失败
  986. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  987. lpCRRt->m_processing = IRWEPROC_FAIL;
  988. return;
  989. }
  990. else
  991. {
  992. ASSERT(lpCRRt->m_data.state == PKST_INFOANDBITS);
  993. ASSERT(lpCRRt->m_data.modify == 0);
  994. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  995. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  996. return;
  997. }
  998. case PKST_INFOANDBITS:
  999. ASSERT(FALSE); // 不能重复的读取图像
  1000. VERIFY(lpCRRt->m_modelID >= 0);
  1001. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1002. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1003. return;
  1004. default:
  1005. VERIFY(FALSE); // 不允许出现这种情况
  1006. ::AfxMessageBox((LPCTSTR)_T("程序发生异常,您现在最好关闭本程序,以免使系统崩溃。"));
  1007. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1008. lpCRRt->m_modelID = -1;
  1009. lpCRRt->m_processing = IRWEPROC_FAIL;
  1010. return;
  1011. }
  1012. }
  1013. // 保存图像到文件
  1014. void _fnIRWEC_SAVE_TO_FILE(CReturnReceipt *lpCRRt)
  1015. {
  1016. ASSERT(lpCRRt->m_data.state >= PKST_INFOANDBITS);
  1017. ASSERT(lpCRRt->m_data._pbdata);
  1018. ASSERT(lpCRRt->m_data.pLineAddr);
  1019. ASSERT(::lstrlen((LPCTSTR)(lpCRRt->m_data.filename)));
  1020. int result;
  1021. LPIRWMODULEINFO lpIRWEInfo;
  1022. ASSERT(lpCRRt->m_modelID >= 0);
  1023. lpIRWEInfo = m_EngineData.GetAt(lpCRRt->m_modelID);
  1024. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_ModuleState==IRWEMS_CR));
  1025. ASSERT(lpIRWEInfo->m_IRWPInterFace);
  1026. // 检验对应的插件是否支持保存功能
  1027. if (!(lpIRWEInfo->m_Function&0x2))
  1028. {
  1029. lpCRRt->m_errorinfo = IRWEERR_NOTSUPPORT;
  1030. lpCRRt->m_processing = IRWEPROC_FAIL;
  1031. return;
  1032. }
  1033. // 保存原始文件名
  1034. ::lstrcpy((LPTSTR)(lpCRRt->m_data.imginfo.filename), (LPCTSTR)(lpCRRt->m_data.filename));
  1035. // 设置新文件名
  1036. ::lstrcpy((LPTSTR)(lpCRRt->m_data.filename), (LPCTSTR)(lpCRRt->m_filename));
  1037. lpIRWEInfo->m_ModuleState = IRWEMS_CA;
  1038. lpCRRt->m_data.comm = CMD_SAVE_TO_FILE;
  1039. lpCRRt->m_data.result = ER_EMPTY;
  1040. ASSERT(lpCRRt->m_data._pbdata != NULL);
  1041. ASSERT(::lstrlen((LPCTSTR)(lpCRRt->m_data.filename)));
  1042. // 写文件
  1043. result = lpIRWEInfo->m_IRWPInterFace((LPINFOSTR)lpCRRt);
  1044. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  1045. if (lpCRRt->m_data.result != ER_SUCCESS)
  1046. {
  1047. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1048. lpCRRt->m_processing = IRWEPROC_FAIL;
  1049. return;
  1050. }
  1051. else
  1052. {
  1053. ASSERT(lpCRRt->m_data.modify == 0);
  1054. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1055. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1056. return;
  1057. }
  1058. }
  1059. // 获取指定尺寸的图像
  1060. void _fnIRWEC_RESIZE(CReturnReceipt *lpCRRt)
  1061. {
  1062. ASSERT(lpCRRt);
  1063. ASSERT(::lstrlen((LPCTSTR)lpCRRt->m_filename));
  1064. ASSERT(lpCRRt->m_command == IRWEC_RESIZE);
  1065. int result, id, y;
  1066. LPIRWMODULEINFO lpIRWEInfo;
  1067. switch(lpCRRt->m_data.state)
  1068. {
  1069. case PKST_NOTVER:
  1070. {
  1071. // 在当前状态下,回执单中不应含有图像信息及位数据
  1072. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  1073. ASSERT(lpCRRt->m_data._pbdata == NULL);
  1074. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  1075. // 简单判断该文件是否能被插件处理
  1076. id = _IRWE_QueryFileProcID((LPCTSTR)(lpCRRt->m_filename));
  1077. if (id >= 0)
  1078. {
  1079. if (_IRWE_SureActive(id) < 0) // 确保插件已被调入
  1080. {
  1081. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1082. lpCRRt->m_modelID = -1;
  1083. lpCRRt->m_processing = IRWEPROC_FAIL;
  1084. return;
  1085. }
  1086. // 执行判断操作
  1087. _fnIRWEC_Helper_IS_VALID_FILE(lpCRRt, id);
  1088. if (lpCRRt->m_data.result != ER_SUCCESS)
  1089. {
  1090. // 读写模块在执行过程中发生错误
  1091. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1092. lpCRRt->m_modelID = -1;
  1093. lpCRRt->m_processing = IRWEPROC_FAIL;
  1094. return;
  1095. }
  1096. else
  1097. {
  1098. if (lpCRRt->m_data.annexdata.iAnnData == 0)
  1099. {
  1100. // 指定文件不能被处理
  1101. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1102. lpCRRt->m_modelID = -1;
  1103. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1104. return;
  1105. }
  1106. else
  1107. {
  1108. ASSERT(lpCRRt->m_data.state == PKST_PASSVER);
  1109. lpCRRt->m_modelID = id; // 能处理
  1110. }
  1111. }
  1112. }
  1113. else
  1114. {
  1115. // 如果用文件的扩展名无法判断出类型,则返回
  1116. lpCRRt->m_data.annexdata.iAnnData = 0;
  1117. lpCRRt->m_data.state = PKST_NOTVER;
  1118. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1119. lpCRRt->m_modelID = -1;
  1120. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1121. return;
  1122. }
  1123. }
  1124. case PKST_PASSVER:
  1125. ASSERT(lpCRRt->m_modelID >= 0);
  1126. // 在当前状态下,回执单中不应含有图像信息及位数据
  1127. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  1128. ASSERT(lpCRRt->m_data._pbdata == NULL);
  1129. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  1130. // 确保插件已被调入
  1131. if (_IRWE_SureActive(lpCRRt->m_modelID) < 0)
  1132. {
  1133. // 调入插件失败
  1134. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1135. lpCRRt->m_modelID = -1;
  1136. lpCRRt->m_processing = IRWEPROC_FAIL;
  1137. return;
  1138. }
  1139. // 执行提取操作
  1140. _fnIRWEC_Helper_GET_FILE_INFO(lpCRRt, lpCRRt->m_modelID);
  1141. if (lpCRRt->m_data.result != ER_SUCCESS)
  1142. {
  1143. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1144. lpCRRt->m_processing = IRWEPROC_FAIL;
  1145. return;
  1146. }
  1147. ASSERT(lpCRRt->m_data.state == PKST_PASSINFO);
  1148. case PKST_PASSINFO:
  1149. ASSERT(lpCRRt->m_modelID >= 0);
  1150. // 在当前状态下,回执单中不应含有图像信息及位数据
  1151. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  1152. ASSERT(lpCRRt->m_data._pbdata == NULL);
  1153. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  1154. lpIRWEInfo = m_EngineData.GetAt(lpCRRt->m_modelID);
  1155. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_ModuleState==IRWEMS_CR));
  1156. ASSERT(lpIRWEInfo->m_IRWPInterFace);
  1157. // 检验对应的插件是否支持ReSize功能
  1158. if (!(lpIRWEInfo->m_Function&0x4))
  1159. {
  1160. lpCRRt->m_errorinfo = IRWEERR_NOTSUPPORT;
  1161. lpCRRt->m_processing = IRWEPROC_FAIL;
  1162. return;
  1163. }
  1164. lpCRRt->m_data.comm = CMD_RESIZE;
  1165. lpCRRt->m_data.result = ER_EMPTY;
  1166. lpCRRt->m_data.pImgInfo = NULL;
  1167. lpCRRt->m_data.sDIBInfo.bmi.biSize     = sizeof(BITMAPINFOHEADER);
  1168. //lpCRRt->m_data.sDIBInfo.bmi.biWidth    = lpCRRt->m_data.imginfo.width;
  1169. //lpCRRt->m_data.sDIBInfo.bmi.biHeight   = lpCRRt->m_data.imginfo.height;
  1170. // 已经在上一级函数中由用户设定了宽度、高度值
  1171. ASSERT(lpCRRt->m_data.imginfo.width  > 0);
  1172. ASSERT(lpCRRt->m_data.imginfo.height > 0);
  1173. lpCRRt->m_data.sDIBInfo.bmi.biPlanes   = 1;
  1174. lpCRRt->m_data.sDIBInfo.bmi.biBitCount = ISEE_IMAGE_BITCOUNT;// 恒定为32
  1175. lpCRRt->m_data.sDIBInfo.bmi.biCompression = BI_RGB;
  1176. lpCRRt->m_data.sDIBInfo.bmi.biSizeImage   = 0;
  1177. lpCRRt->m_data.sDIBInfo.bmi.biXPelsPerMeter = 0;
  1178. lpCRRt->m_data.sDIBInfo.bmi.biYPelsPerMeter = 0;
  1179. lpCRRt->m_data.sDIBInfo.bmi.biClrUsed       = 0;
  1180. lpCRRt->m_data.sDIBInfo.bmi.biClrImportant  = 0;
  1181. lpCRRt->m_data.sDIBInfo.rmask     = 0xff0000;
  1182. lpCRRt->m_data.sDIBInfo.gmask     = 0xff00;
  1183. lpCRRt->m_data.sDIBInfo.bmask     = 0xff;
  1184. lpCRRt->m_data.sDIBInfo.alphaMask = 0;
  1185. // 分配用于存放标准图像位数据的内存块
  1186. lpCRRt->m_data._pbdata = (PBYTE)::GlobalAlloc(GMEM_FIXED, lpCRRt->m_data.sDIBInfo.bmi.biWidth*(ISEE_IMAGE_BITCOUNT/8)*lpCRRt->m_data.sDIBInfo.bmi.biHeight);
  1187. if (!lpCRRt->m_data._pbdata)
  1188. {
  1189. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  1190. lpCRRt->m_processing = IRWEPROC_FAIL;
  1191. return;
  1192. }
  1193. // 分配用于存放每一扫描行地址的指针数组并初始化
  1194. lpCRRt->m_data.pLineAddr = (DWORD**)::GlobalAlloc(GPTR, lpCRRt->m_data.sDIBInfo.bmi.biHeight*sizeof(DWORD*));
  1195. if (!lpCRRt->m_data.pLineAddr)
  1196. {
  1197. ::GlobalFree(lpCRRt->m_data._pbdata);
  1198. lpCRRt->m_data._pbdata = NULL;
  1199. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  1200. lpCRRt->m_processing = IRWEPROC_FAIL;
  1201. return;
  1202. }
  1203. // 初始化行首数组
  1204. for (y=0;y<lpCRRt->m_data.sDIBInfo.bmi.biHeight;y++)
  1205. lpCRRt->m_data.pLineAddr[y] = (DWORD*)(lpCRRt->m_data._pbdata+((lpCRRt->m_data.sDIBInfo.bmi.biHeight-y-1)*(lpCRRt->m_data.sDIBInfo.bmi.biWidth*(ISEE_IMAGE_BITCOUNT/8))));
  1206. lpIRWEInfo->m_ModuleState = IRWEMS_CA;
  1207. if (lpIRWEInfo->m_PRI < 0xffffffff)
  1208. lpIRWEInfo->m_PRI++; // 优先级数加一
  1209. // 读取文件中的图像数据
  1210. result = lpIRWEInfo->m_IRWPInterFace((LPINFOSTR)lpCRRt);
  1211. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  1212. if (lpCRRt->m_data.result != ER_SUCCESS)
  1213. {
  1214. // 读取失败
  1215. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1216. lpCRRt->m_processing = IRWEPROC_FAIL;
  1217. return;
  1218. }
  1219. else
  1220. {
  1221. ASSERT(lpCRRt->m_data.state == PKST_INFOANDBITS);
  1222. ASSERT(lpCRRt->m_data.modify == 0);
  1223. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1224. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1225. return;
  1226. }
  1227. case PKST_INFOANDBITS:
  1228. default:
  1229. VERIFY(FALSE); // 不允许出现这种情况
  1230. ::AfxMessageBox((LPCTSTR)_T("程序发生异常,您现在最好关闭本程序,以免使系统崩溃。"));
  1231. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1232. lpCRRt->m_modelID = -1;
  1233. lpCRRt->m_processing = IRWEPROC_FAIL;
  1234. return;
  1235. }
  1236. }
  1237. // 获取拇指图
  1238. void _fnIRWEC_GET_THUM_IMAGE(CReturnReceipt *lpCRRt, BOOL keep)
  1239. {
  1240. ASSERT(lpCRRt);
  1241. ASSERT(::lstrlen((LPCTSTR)lpCRRt->m_filename));
  1242. ASSERT((lpCRRt->m_command == IRWEC_GET_THUMIMAGE)||(lpCRRt->m_command == IRWEC_GET_THUMIMAGE_A_BIT));
  1243. BOOL hait = TRUE; // 在调用本函数之前,回执单中是否存在位数据,假设有
  1244. int result, id, y;
  1245. LPIRWMODULEINFO lpIRWEInfo;
  1246. CRect rect1, rect2;
  1247. BOOL smark; // 缩小标志
  1248. float fy;
  1249. switch(lpCRRt->m_data.state)
  1250. {
  1251. case PKST_NOTVER:
  1252. {
  1253. // 在当前状态下,回执单中不应含有图像信息及位数据
  1254. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  1255. ASSERT(lpCRRt->m_data._pbdata == NULL);
  1256. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  1257. // 简单判断该文件是否能被插件处理
  1258. id = _IRWE_QueryFileProcID((LPCTSTR)(lpCRRt->m_filename));
  1259. if (id >= 0)
  1260. {
  1261. if (_IRWE_SureActive(id) < 0) // 确保插件已被调入
  1262. {
  1263. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1264. lpCRRt->m_modelID = -1;
  1265. lpCRRt->m_processing = IRWEPROC_FAIL;
  1266. return;
  1267. }
  1268. // 执行判断操作
  1269. _fnIRWEC_Helper_IS_VALID_FILE(lpCRRt, id);
  1270. if (lpCRRt->m_data.result != ER_SUCCESS)
  1271. {
  1272. // 读写模块在执行过程中发生错误
  1273. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1274. lpCRRt->m_modelID = -1;
  1275. lpCRRt->m_processing = IRWEPROC_FAIL;
  1276. return;
  1277. }
  1278. else
  1279. {
  1280. if (lpCRRt->m_data.annexdata.iAnnData == 0)
  1281. {
  1282. // 指定文件不能被处理
  1283. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1284. lpCRRt->m_modelID = -1;
  1285. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1286. return;
  1287. }
  1288. else
  1289. {
  1290. ASSERT(lpCRRt->m_data.state == PKST_PASSVER);
  1291. lpCRRt->m_modelID = id; // 能处理
  1292. }
  1293. }
  1294. }
  1295. else
  1296. {
  1297. // 如果用文件的扩展名无法判断出类型,则返回
  1298. lpCRRt->m_data.annexdata.iAnnData = 0;
  1299. lpCRRt->m_data.state = PKST_NOTVER;
  1300. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1301. lpCRRt->m_modelID = -1;
  1302. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1303. return;
  1304. }
  1305. }
  1306. case PKST_PASSVER:
  1307. ASSERT(lpCRRt->m_modelID >= 0);
  1308. // 在当前状态下,回执单中不应含有图像信息及位数据
  1309. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  1310. ASSERT(lpCRRt->m_data._pbdata == NULL);
  1311. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  1312. // 确保插件已被调入
  1313. if (_IRWE_SureActive(lpCRRt->m_modelID) < 0)
  1314. {
  1315. // 调入插件失败
  1316. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1317. lpCRRt->m_modelID = -1;
  1318. lpCRRt->m_processing = IRWEPROC_FAIL;
  1319. return;
  1320. }
  1321. // 执行提取操作
  1322. _fnIRWEC_Helper_GET_FILE_INFO(lpCRRt, lpCRRt->m_modelID);
  1323. if (lpCRRt->m_data.result != ER_SUCCESS)
  1324. {
  1325. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1326. lpCRRt->m_processing = IRWEPROC_FAIL;
  1327. return;
  1328. }
  1329. ASSERT(lpCRRt->m_data.state == PKST_PASSINFO);
  1330. case PKST_PASSINFO:
  1331. ASSERT(lpCRRt->m_modelID >= 0);
  1332. // 在当前状态下,回执单中不应含有图像信息及位数据
  1333. ASSERT(lpCRRt->m_data.pLineAddr == NULL);
  1334. ASSERT(lpCRRt->m_data._pbdata == NULL);
  1335. ASSERT(lpCRRt->m_data.pImgInfo == NULL);
  1336. lpIRWEInfo = m_EngineData.GetAt(lpCRRt->m_modelID);
  1337. ASSERT((lpIRWEInfo)&&(lpIRWEInfo->m_ModuleState==IRWEMS_CR));
  1338. ASSERT(lpIRWEInfo->m_IRWPInterFace);
  1339. lpCRRt->m_data.comm = CMD_LOAD_FROM_FILE;
  1340. lpCRRt->m_data.result = ER_EMPTY;
  1341. lpCRRt->m_data.pImgInfo = NULL;
  1342. lpCRRt->m_data.sDIBInfo.bmi.biSize     = sizeof(BITMAPINFOHEADER);
  1343. ASSERT(lpCRRt->m_data.imginfo.width  > 0);
  1344. lpCRRt->m_data.sDIBInfo.bmi.biWidth    = lpCRRt->m_data.imginfo.width;
  1345. ASSERT(lpCRRt->m_data.imginfo.height > 0);
  1346. lpCRRt->m_data.sDIBInfo.bmi.biHeight   = lpCRRt->m_data.imginfo.height;
  1347. lpCRRt->m_data.sDIBInfo.bmi.biPlanes   = 1;
  1348. lpCRRt->m_data.sDIBInfo.bmi.biBitCount = ISEE_IMAGE_BITCOUNT;// 恒定为32
  1349. lpCRRt->m_data.sDIBInfo.bmi.biCompression = BI_RGB;
  1350. lpCRRt->m_data.sDIBInfo.bmi.biSizeImage   = 0;
  1351. lpCRRt->m_data.sDIBInfo.bmi.biXPelsPerMeter = 0;
  1352. lpCRRt->m_data.sDIBInfo.bmi.biYPelsPerMeter = 0;
  1353. lpCRRt->m_data.sDIBInfo.bmi.biClrUsed       = 0;
  1354. lpCRRt->m_data.sDIBInfo.bmi.biClrImportant  = 0;
  1355. lpCRRt->m_data.sDIBInfo.rmask     = 0xff0000;
  1356. lpCRRt->m_data.sDIBInfo.gmask     = 0xff00;
  1357. lpCRRt->m_data.sDIBInfo.bmask     = 0xff;
  1358. lpCRRt->m_data.sDIBInfo.alphaMask = 0;
  1359. // 分配用于存放标准图像位数据的内存块
  1360. lpCRRt->m_data._pbdata = (PBYTE)::GlobalAlloc(GMEM_FIXED, lpCRRt->m_data.sDIBInfo.bmi.biWidth*(ISEE_IMAGE_BITCOUNT/8)*lpCRRt->m_data.sDIBInfo.bmi.biHeight);
  1361. if (!lpCRRt->m_data._pbdata)
  1362. {
  1363. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  1364. lpCRRt->m_processing = IRWEPROC_FAIL;
  1365. return;
  1366. }
  1367. // 分配用于存放每一扫描行地址的指针数组并初始化
  1368. lpCRRt->m_data.pLineAddr = (DWORD**)::GlobalAlloc(GPTR, lpCRRt->m_data.sDIBInfo.bmi.biHeight*sizeof(DWORD*));
  1369. if (!lpCRRt->m_data.pLineAddr)
  1370. {
  1371. ::GlobalFree(lpCRRt->m_data._pbdata);
  1372. lpCRRt->m_data._pbdata = NULL;
  1373. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  1374. lpCRRt->m_processing = IRWEPROC_FAIL;
  1375. return;
  1376. }
  1377. // 初始化行首数组
  1378. for (y=0;y<lpCRRt->m_data.sDIBInfo.bmi.biHeight;y++)
  1379. lpCRRt->m_data.pLineAddr[y] = (DWORD*)(lpCRRt->m_data._pbdata+((lpCRRt->m_data.sDIBInfo.bmi.biHeight-y-1)*(lpCRRt->m_data.sDIBInfo.bmi.biWidth*(ISEE_IMAGE_BITCOUNT/8))));
  1380. lpIRWEInfo->m_ModuleState = IRWEMS_CA;
  1381. if (lpIRWEInfo->m_PRI < 0xffffffff)
  1382. lpIRWEInfo->m_PRI++; // 优先级数加一
  1383. // 读取文件中的图像数据
  1384. result = lpIRWEInfo->m_IRWPInterFace((LPINFOSTR)lpCRRt);
  1385. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  1386. if (lpCRRt->m_data.result != ER_SUCCESS)
  1387. {
  1388. // 读取失败
  1389. lpCRRt->m_errorinfo = (IRWE_ERROR)(int)(lpCRRt->m_data.result);
  1390. lpCRRt->m_processing = IRWEPROC_FAIL;
  1391. return;
  1392. }
  1393. ASSERT(lpCRRt->m_data.state == PKST_INFOANDBITS);
  1394. ASSERT(lpCRRt->m_data.modify == 0);
  1395. hait = FALSE; // 说明回执单以前没有位数据
  1396. case PKST_INFOANDBITS:
  1397. {
  1398. ASSERT(lpCRRt->m_data._pbdata);
  1399. VERIFY(lpCRRt->m_modelID >= 0);
  1400. // 图像的原始尺寸
  1401. rect1.SetRect(0, 0, lpCRRt->m_data.imginfo.width, lpCRRt->m_data.imginfo.height);
  1402. smark = FALSE;
  1403. if ((rect1.Width() > lpCRRt->m_thumbnails.m_thumbound.Width())||
  1404. (rect1.Height() > lpCRRt->m_thumbnails.m_thumbound.Height()))
  1405. { // 缩小图像
  1406. rect2.SetRect(0, 0, lpCRRt->m_thumbnails.m_thumbound.Width(),
  1407. lpCRRt->m_thumbnails.m_thumbound.Height());
  1408. fy = (float)rect1.Width()/(float)rect1.Height(); // 比例因子
  1409. if (rect1.Width() > rect2.Width())
  1410. rect1.DeflateRect(0, 0, rect1.Width()-rect2.Width(), (int)((rect1.Width()-rect2.Width())/fy));
  1411. if (rect1.Height() > rect2.Height())
  1412. rect1.DeflateRect(0, 0, (int)((rect1.Height()-rect2.Height())*fy), rect1.Height()-rect2.Height());
  1413. smark = TRUE;
  1414. }
  1415. // 删除以前的拇指图
  1416. if (lpCRRt->m_thumbnails.m_thumbits)
  1417. {
  1418. ::GlobalFree(lpCRRt->m_thumbnails.m_thumbits);
  1419. ASSERT(lpCRRt->m_thumbnails.m_thumlines);
  1420. ::GlobalFree(lpCRRt->m_thumbnails.m_thumlines);
  1421. }
  1422. else
  1423. ASSERT(!lpCRRt->m_thumbnails.m_thumlines);
  1424. // 校验拇指图结构已被正确初始化
  1425. ASSERT(lpCRRt->m_thumbnails.m_thuminfo.biSize == sizeof(BITMAPINFOHEADER));
  1426. lpCRRt->m_thumbnails.m_thumbits = NULL;
  1427. lpCRRt->m_thumbnails.m_thumlines= NULL;
  1428. lpCRRt->m_thumbnails.m_thumfrom = IRWETHUM_FROM_NULL;
  1429. lpCRRt->m_thumbnails.m_thuminfo.biWidth = 0;
  1430. lpCRRt->m_thumbnails.m_thuminfo.biHeight= 0;
  1431. // 分配用于存放标准图像位数据(拇指图)的内存块
  1432. lpCRRt->m_thumbnails.m_thumbits = (PBYTE)::GlobalAlloc(GPTR, rect1.Width()*(ISEE_IMAGE_BITCOUNT/8)*rect1.Height());
  1433. if (!lpCRRt->m_thumbnails.m_thumbits)
  1434. {
  1435. if (hait == FALSE) // 本次读入的位数据
  1436. lpCRRt->ClearImageBitData(); // 返回到信息状态
  1437. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  1438. lpCRRt->m_processing = IRWEPROC_FAIL;
  1439. return;
  1440. }
  1441. // 分配用于存放每一扫描行地址的指针数组并初始化
  1442. lpCRRt->m_thumbnails.m_thumlines = (DWORD**)::GlobalAlloc(GPTR, rect1.Height()*sizeof(DWORD*));
  1443. if (!lpCRRt->m_thumbnails.m_thumlines)
  1444. {
  1445. ::GlobalFree(lpCRRt->m_thumbnails.m_thumbits);
  1446. lpCRRt->m_thumbnails.m_thumbits = NULL;
  1447. if (hait == FALSE) // 本次读入的位数据
  1448. lpCRRt->ClearImageBitData(); // 返回到信息状态
  1449. lpCRRt->m_errorinfo = IRWEERR_MEMORYERR;
  1450. lpCRRt->m_processing = IRWEPROC_FAIL;
  1451. return;
  1452. }
  1453. // 设置拇指图参数
  1454. lpCRRt->m_thumbnails.m_thumfrom = IRWETHUM_FROM_CREATE;
  1455. lpCRRt->m_thumbnails.m_thuminfo.biWidth = rect1.Width();
  1456. lpCRRt->m_thumbnails.m_thuminfo.biHeight= rect1.Height();
  1457. // 初始化行首数组
  1458. int y;
  1459. int width = rect1.Width(), height = rect1.Height();
  1460. PBYTE lpBits = lpCRRt->m_thumbnails.m_thumbits;
  1461. DWORD **lppd = lpCRRt->m_thumbnails.m_thumlines;
  1462. for (y=0;y<height;y++)
  1463. lppd[y] = (DWORD*)((PBYTE)lpBits+((height-y-1)*(width*(ISEE_IMAGE_BITCOUNT/8))));
  1464. if (smark == TRUE)
  1465. {
  1466. // 缩小图像
  1467. _Thum_BlitStretch(lppd, width, height, 
  1468. (DWORD**)(lpCRRt->m_data.pLineAddr), 
  1469. lpCRRt->m_data.imginfo.width, 
  1470. lpCRRt->m_data.imginfo.height);
  1471. }
  1472. else
  1473. {
  1474. // 直接拷贝
  1475. ::CopyMemory((PVOID)lpBits, (PVOID)(lpCRRt->m_data._pbdata), 
  1476. width*(ISEE_IMAGE_BITCOUNT/8)*height);
  1477. }
  1478. if (hait == FALSE)
  1479. {
  1480. // 说明回执单中的位数据是本次调用读入的
  1481. if (keep == FALSE)
  1482. {
  1483. // 不保留位数据
  1484. lpCRRt->ClearImageBitData();
  1485. }
  1486. }
  1487. lpCRRt->m_errorinfo = IRWEERR_SUCCESS;
  1488. lpCRRt->m_processing = IRWEPROC_COMPLETE;
  1489. return;
  1490. }
  1491. default:
  1492. VERIFY(FALSE); // 不允许出现这种情况
  1493. ::AfxMessageBox((LPCTSTR)_T("程序发生异常,您现在最好关闭本程序,以免使系统崩溃。"));
  1494. lpCRRt->m_errorinfo = IRWEERR_ENGINEERR;
  1495. lpCRRt->m_modelID = -1;
  1496. lpCRRt->m_processing = IRWEPROC_FAIL;
  1497. return;
  1498. }
  1499. }
  1500. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  1501. // 图像读写引擎内部助手函数
  1502. //
  1503. // 确保指定插件已被调入
  1504. int _IRWE_SureActive(int ID)
  1505. {
  1506. // 引擎必需有一个以上的插件支持
  1507. ASSERT(m_EngineData.GetUsedElemSize());
  1508. CString dllpath;
  1509. ASSERT(ID < m_EngineData.GetUsedElemSize());
  1510. LPIRWMODULEINFO lpIRWEInfo = m_EngineData.GetAt(ID);
  1511. ASSERT(lpIRWEInfo);
  1512. if (lpIRWEInfo->m_ModuleState != IRWEMS_NULL)
  1513. {
  1514. ASSERT(lpIRWEInfo->m_SN == ID);
  1515. ASSERT(lpIRWEInfo->m_hDll);
  1516. ASSERT(lpIRWEInfo->m_IRWPInterFace);
  1517. return 1; // 已调入的插件
  1518. }
  1519. // 组合插件文件的全路径
  1520. dllpath = lpIRWEInfo->m_Path;
  1521. dllpath += lpIRWEInfo->m_FileName;
  1522. ASSERT(dllpath.GetLength());
  1523. // 此时m_hDll应该是NULL
  1524. ASSERT(!(lpIRWEInfo->m_hDll));
  1525. // 读入插件(实际上就是读入DLL)
  1526. lpIRWEInfo->m_hDll = ::LoadLibrary(dllpath);
  1527. if (lpIRWEInfo->m_hDll == NULL)
  1528. return -1; // 指定的DLL文件不存在或损坏
  1529. // 填写DLL接口函数地址
  1530. lpIRWEInfo->m_IRWPInterFace = (IRWP_INTERFACE)::GetProcAddress(
  1531. lpIRWEInfo->m_hDll, 
  1532. MAKEINTRESOURCE(1));
  1533. if (!(lpIRWEInfo->m_IRWPInterFace))
  1534. {
  1535. // 如果找不到接口函数,则返回-2
  1536. ::FreeLibrary(lpIRWEInfo->m_hDll);
  1537. lpIRWEInfo->m_hDll = NULL;
  1538. return -2; // 指定的DLL文件不是合法的ISee图像读写插件
  1539. }
  1540. // 设置模块状态(IRWEMS_CR-创建并空闲)
  1541. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  1542. // 已调入插件数加一
  1543. m_EngineData.m_Active++;
  1544. ASSERT(m_EngineData.m_Active <= m_EngineData.GetUsedElemSize());
  1545. return 0; // 成功调入
  1546. }
  1547. // 调入所有插件
  1548. int _IRWE_ActiveAll()
  1549. {
  1550. // 引擎必需有一个以上的插件支持
  1551. ASSERT(m_EngineData.GetUsedElemSize());
  1552. LPIRWMODULEINFO lpIRWEInfo;
  1553. CString dllpath;
  1554. int i = 0; 
  1555. int iUsed = m_EngineData.GetUsedElemSize();
  1556. // 如果所有插件都已经被调入,则直接返回
  1557. if (m_EngineData.GetActiveElemSize() == iUsed)
  1558. return iUsed;
  1559. // 激活插件
  1560. for (i=0;i<iUsed;i++)
  1561. {
  1562. lpIRWEInfo = m_EngineData.GetAt(i);
  1563. ASSERT(lpIRWEInfo);
  1564. if (lpIRWEInfo->m_ModuleState != IRWEMS_NULL)
  1565. continue; // 跨过已调入的插件
  1566. // 组合插件文件的全路径
  1567. dllpath = lpIRWEInfo->m_Path;
  1568. dllpath += lpIRWEInfo->m_FileName;
  1569. ASSERT(dllpath.GetLength());
  1570. // 此时m_hDll应该是NULL
  1571. ASSERT(!lpIRWEInfo->m_hDll);
  1572. // 填写DLL句柄
  1573. lpIRWEInfo->m_hDll = ::LoadLibrary((LPCTSTR)dllpath);
  1574. if (lpIRWEInfo->m_hDll == NULL)
  1575. return -1; // 指定的DLL文件不存在
  1576. // 填写DLL接口函数地址
  1577. lpIRWEInfo->m_IRWPInterFace = (IRWP_INTERFACE)::GetProcAddress(
  1578. lpIRWEInfo->m_hDll, 
  1579. MAKEINTRESOURCE(1));
  1580. if (!lpIRWEInfo->m_IRWPInterFace)
  1581. {
  1582. ::FreeLibrary(lpIRWEInfo->m_hDll);
  1583. lpIRWEInfo->m_hDll = NULL;
  1584. return -2; // 指定的DLL文件不是合法的ISee图像读写插件
  1585. }
  1586. // 设置模块状态(IRWEMS_CR-创建但空闲)
  1587. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  1588. // 已调入插件数加一
  1589. m_EngineData.m_Active++;
  1590. }
  1591. ASSERT(m_EngineData.m_Active == m_EngineData.m_Count);
  1592. return m_EngineData.m_Active;
  1593. }
  1594. // 确定指定的文件能被哪个插件处理,并返回插件的ID
  1595. int _IRWE_QueryFileProcID(LPCTSTR lpFileName)
  1596. {
  1597. ASSERT((lpFileName)&&(::lstrlen(lpFileName)));
  1598. ASSERT(m_ProcCount > 0);
  1599. int i, j;
  1600. BYTE ext[_MAX_EXT];
  1601. ::_splitpath(lpFileName, NULL, NULL, NULL, (char*)ext);
  1602. ::memmove((void*)ext, (const void*)&(ext[1]), ::lstrlen((LPCTSTR)ext));
  1603. if ((::lstrlen((LPCTSTR)ext) == 0)||(::lstrlen((LPCTSTR)ext) > 4)) // 插件只能处理扩展名小于等于4个字母的图像文件
  1604. return -1;
  1605. // 将文件扩展名转换为大写(因为插件只识别大写的扩展名)
  1606. ::_strupr((char*)ext);
  1607. PBYTE lpTmp = (PBYTE)m_ProcType;
  1608. BYTE ProcBuf[8], tmp;
  1609. for (i=0;i<m_ProcCount;i++)
  1610. {
  1611. j = 0;
  1612. while( ((tmp = *lpTmp++) != ',') && (tmp != 0) )
  1613. ProcBuf[j++] = tmp;
  1614. ProcBuf[j] = 0;
  1615. ASSERT(j < 5);
  1616. if (!::memcmp((const void*)ext, (const void*)ProcBuf, ::lstrlen((LPCTSTR)ProcBuf)+1))
  1617. return m_ProcID[i]; // 返回插件ID号(ID号都大于等于0)
  1618. }
  1619. // 未找到能处理该类型文件的插件,返回-1
  1620. return -1;
  1621. }
  1622. // 建立插件信息数组及初始化插件线程
  1623. int _IRWE_CreatePluginsInfoStock()
  1624. {
  1625. ASSERT(m_EngineData.GetUsedElemSize() == 0); // 本函数只能调用一次
  1626. CFile file;
  1627. CString dllpath;
  1628. BOOL loopcount = FALSE; // 循环标志,当变为TRUE时,表示注册表的信息已被刷新
  1629. PBYTE pbyNames = NULL;
  1630. BYTE byNames = 0;
  1631. LPTSTR pNames = NULL;
  1632. LPTSTR pPath = NULL;
  1633. LPTSTR pFN = NULL;
  1634. LPIRWMODULEINFO lpIRWEInfo = NULL;
  1635. DWORD curPRI = 0;
  1636. int Active[INIT_ACTIVE_PLUGINS_NUM];
  1637. BYTE ProcBuf[8];
  1638. PLUGSIN plugsaddinfo; // 插件文件附加信息结构
  1639. int i, j, k, iCurrent = 0, ActiveNum = 0;
  1640. HKEY hKey = NULL; // 插件信息根句柄
  1641. HKEY hPluginsKey = NULL; // 插件句柄
  1642. DWORD dwPluginsCount = 0; // 插件个数
  1643. begin:
  1644. // 初始化相关变量
  1645. dllpath.Empty();
  1646. ::ZeroMemory((PVOID)ProcBuf, 8);
  1647. ::ZeroMemory((PVOID)Active, sizeof(int)*INIT_ACTIVE_PLUGINS_NUM);
  1648. ::ZeroMemory((PVOID)&plugsaddinfo, sizeof(PLUGSIN));
  1649. m_EngineData.ZeroAllElement();
  1650. ::ZeroMemory((PVOID)m_ProcType, IRWE_PROCTYPE_SIZE);
  1651. for (i=0;i<IRWE_PROCID_SIZE;i++)
  1652. m_ProcID[i] = -1;
  1653. m_ProcCount = 0;
  1654. // 打开插件信息句柄(系统注册表)
  1655. hKey = _IRWERTF_OpenRegTab();
  1656. if (!hKey)
  1657. goto update;
  1658. // 获取插件个数
  1659. dwPluginsCount = _IRWERTF_GetPluginNumber(hKey);
  1660. if ((dwPluginsCount == 0)||((int)dwPluginsCount > m_EngineData.GetMaxElemSize()))
  1661. goto update;
  1662. VERIFY((m_EngineData.AddElement(dwPluginsCount)) == (int)dwPluginsCount);
  1663. // 获取模块名子串
  1664. pNames = _IRWERTF_GetPluginNames(hKey);
  1665. if (!pNames)
  1666. goto update;
  1667. VERIFY(::lstrlen((LPCTSTR)pNames));
  1668. pbyNames = (PBYTE)pNames;
  1669. byNames = 0;
  1670. iCurrent = 0;
  1671. // 分解模块名子串,并填写模块名
  1672. while((byNames = *pbyNames++) != '')
  1673. {
  1674. if (byNames == ' ')
  1675. continue;
  1676. i = 0;
  1677. lpIRWEInfo = m_EngineData.GetAt(iCurrent);
  1678. ASSERT(lpIRWEInfo);
  1679. do
  1680. {
  1681. lpIRWEInfo->m_ModuleName[i++] = byNames;
  1682. VERIFY(i <= 16);
  1683. byNames = *pbyNames++;
  1684. }while( (byNames != ' ')&&(byNames != '') );
  1685. lpIRWEInfo->m_ModuleName[i] = '';
  1686. if (++iCurrent > (int)dwPluginsCount)
  1687. goto update;
  1688. if (byNames == ' ')
  1689. continue;
  1690. ASSERT(byNames == '');
  1691. break;
  1692. }
  1693. ::GlobalFree(pNames); pNames = NULL;
  1694. VERIFY(iCurrent == (int)dwPluginsCount);
  1695. // 获取插件文件所在目录
  1696. pPath = _IRWERTF_GetPluginsPath(hKey);
  1697. if (!pPath)
  1698. goto update;
  1699. VERIFY(::lstrlen((LPCTSTR)pPath));
  1700. // 路径的最后一个字符必需是""符号
  1701. VERIFY(pPath[::lstrlen((LPCTSTR)pPath)-1] == '\');
  1702. // 获取并填写插件文件名、路径及优先级值
  1703. for (i=0;i<(int)dwPluginsCount;i++)
  1704. {
  1705. lpIRWEInfo = m_EngineData.GetAt(i);
  1706. ASSERT(lpIRWEInfo);
  1707. hPluginsKey = _IRWERTF_OpenPlugins(hKey, (LPCTSTR)(lpIRWEInfo->m_ModuleName));
  1708. if (hPluginsKey == NULL)
  1709. goto update;
  1710. // 填写插件优先级值
  1711. lpIRWEInfo->m_PRI = _IRWERTF_GetPluginPRI(hPluginsKey);
  1712. if (lpIRWEInfo->m_PRI < 10) // 优先级最小为10
  1713. goto update;
  1714. // 获取插件文件名子串
  1715. pFN = _IRWERTF_GetPluginsFileName(hPluginsKey);
  1716. if (!pFN)
  1717. goto update;
  1718. VERIFY(::lstrlen((LPCTSTR)pFN));
  1719. // 填写插件文件所在路径串
  1720. ::CopyMemory((PVOID)(lpIRWEInfo->m_Path), (CONST PVOID)pPath, 
  1721. ::lstrlen((LPCTSTR)pPath)+1); // +1 串尾0字符
  1722. // 填写插件文件名子串
  1723. ::CopyMemory((PVOID)(lpIRWEInfo->m_FileName), (CONST PVOID)pFN, 
  1724. ::lstrlen((LPCTSTR)pFN)+1); // +1 串尾0字符
  1725. // 确定插件的当前状态(现在是未调入型)
  1726. lpIRWEInfo->m_ModuleState = IRWEMS_NULL;
  1727. // 释放文件名串
  1728. ::GlobalFree(pFN); pFN = NULL;
  1729. _IRWERTF_CloseKey(hPluginsKey); hPluginsKey = NULL;
  1730. }
  1731. // 此时已无用,删之
  1732. ::GlobalFree(pPath); pPath = NULL;
  1733. // 能处理的文件类型串此时必然是空的
  1734. ASSERT(!::lstrlen((LPCTSTR)m_ProcType));
  1735. for (i=0;i<(int)dwPluginsCount;i++)
  1736. {
  1737. // 提取插件文件附加信息
  1738. lpIRWEInfo = m_EngineData.GetAt(i);
  1739. ASSERT(lpIRWEInfo);
  1740. dllpath = lpIRWEInfo->m_Path;
  1741. dllpath += lpIRWEInfo->m_FileName; // 合成文件的全路径
  1742. if (!file.Open(dllpath, CFile::modeRead|CFile::shareDenyNone))
  1743. goto update;
  1744. TRY
  1745. {
  1746. file.Seek(-(LONG)(sizeof(PLUGSIN)), SEEK_END);
  1747. // 读取插件附加信息块(在文件尾部)
  1748. file.Read(&plugsaddinfo, sizeof(PLUGSIN));
  1749. }
  1750. CATCH(CFileException, e)
  1751. {
  1752. goto update;
  1753. }
  1754. END_CATCH
  1755. file.Close();
  1756. dllpath.Empty();
  1757. VERIFY(!::memcmp((LPCTSTR)plugsaddinfo.IRWID, (LPCTSTR)"IRWP", 4));
  1758. lpIRWEInfo->m_ProcTypeNumber = plugsaddinfo.proctypenum;
  1759. ::CopyMemory((PVOID)(lpIRWEInfo->m_ProcTypeName), (CONST PVOID)plugsaddinfo.proctypestr, 32);
  1760. // 能处理的图像类型必需小于9种(最多有8种)
  1761. ASSERT(lpIRWEInfo->m_ProcTypeNumber < 9);
  1762. for (j=0;j<lpIRWEInfo->m_ProcTypeNumber;j++)
  1763. {
  1764. ::ZeroMemory((PVOID)ProcBuf, 8);
  1765. if (m_ProcCount == 0)
  1766. {
  1767. ::CopyMemory((PVOID)ProcBuf, (CONST PVOID)(lpIRWEInfo->m_ProcTypeName), 4);
  1768. }
  1769. else
  1770. {
  1771. ProcBuf[0] = ',';
  1772. ::CopyMemory((PVOID)&(ProcBuf[1]), (CONST PVOID)&(lpIRWEInfo->m_ProcTypeName[j*4]), 4);
  1773. }
  1774. ::lstrcat((LPTSTR)m_ProcType, (LPCTSTR)ProcBuf);
  1775. m_ProcID[m_ProcCount++] = lpIRWEInfo->m_SN;
  1776. }
  1777. // 引擎必需至少有一个插件支持
  1778. ASSERT((::lstrlen((LPCTSTR)m_ProcType) > 0)&&(m_ProcCount > 0));
  1779. lpIRWEInfo->m_Attrib = plugsaddinfo.attrib;
  1780. lpIRWEInfo->m_Version = plugsaddinfo.version;
  1781. lpIRWEInfo->m_Function = plugsaddinfo.function;
  1782. ::CopyMemory((PVOID)(lpIRWEInfo->m_Author), (CONST PVOID)plugsaddinfo.author, 16);
  1783. ::CopyMemory((PVOID)(lpIRWEInfo->m_EMail), (CONST PVOID)plugsaddinfo.EMail, 32);
  1784. ::CopyMemory((PVOID)(lpIRWEInfo->m_Notion), (CONST PVOID)plugsaddinfo.messages, 144);
  1785. }
  1786. ::ZeroMemory((PVOID)Active, sizeof(int)*INIT_ACTIVE_PLUGINS_NUM);
  1787. // 确定要激活哪些插件,结果存放在Active数组中
  1788. if (dwPluginsCount <= INIT_ACTIVE_PLUGINS_NUM)
  1789. {
  1790. ActiveNum = dwPluginsCount;
  1791. for (i=0;i<(int)dwPluginsCount;i++)
  1792. m_EngineData.GetAt(i)->m_SelectMark = TRUE;
  1793. }
  1794. else
  1795. {
  1796. ActiveNum = INIT_ACTIVE_PLUGINS_NUM;
  1797. // 挑选出优先级比较高的INIT_ACTIVE_PLUGINS_NUM个模块激活
  1798. for (i=0;i<INIT_ACTIVE_PLUGINS_NUM;i++)
  1799. {
  1800. for (j=0;j<(int)dwPluginsCount;j++)
  1801. {
  1802. if (m_EngineData.GetAt(j)->m_SelectMark == TRUE)
  1803. continue;
  1804. else
  1805. break;
  1806. }
  1807. ASSERT(j < (int)dwPluginsCount);
  1808. Active[i] = j;
  1809. curPRI = m_EngineData.GetAt(j)->m_PRI;
  1810. for (k=0;k<(int)dwPluginsCount;k++)
  1811. {
  1812. if (m_EngineData.GetAt(k)->m_SelectMark == TRUE)
  1813. continue;
  1814. if (curPRI > m_EngineData.GetAt(k)->m_PRI)
  1815. continue;
  1816. curPRI = m_EngineData.GetAt(k)->m_PRI;
  1817. Active[i] = k;
  1818. }
  1819. m_EngineData.GetAt(Active[i])->m_SelectMark = TRUE;
  1820. }
  1821. }
  1822. VERIFY(ActiveNum <= INIT_ACTIVE_PLUGINS_NUM);
  1823. m_EngineData.m_Active = ActiveNum;
  1824. // 激活插件
  1825. for (i=0;i<ActiveNum;i++)
  1826. {
  1827. k = Active[i];
  1828. lpIRWEInfo = m_EngineData.GetAt(k);
  1829. ASSERT(lpIRWEInfo);
  1830. ASSERT(lpIRWEInfo->m_SelectMark == TRUE);
  1831. dllpath = lpIRWEInfo->m_Path;
  1832. dllpath += lpIRWEInfo->m_FileName;
  1833. ASSERT(dllpath.GetLength());
  1834. // 填写DLL句柄
  1835. lpIRWEInfo->m_hDll = ::LoadLibrary((LPCTSTR)dllpath);
  1836. if (lpIRWEInfo->m_hDll == NULL)
  1837. goto update;
  1838. // 填写DLL接口函数地址
  1839. lpIRWEInfo->m_IRWPInterFace = (IRWP_INTERFACE)::GetProcAddress(
  1840. lpIRWEInfo->m_hDll, 
  1841. MAKEINTRESOURCE(1));
  1842. if (!lpIRWEInfo->m_IRWPInterFace)
  1843. goto update;
  1844. // 设置模块状态(IRWEMS_CR-创建但空闲)
  1845. lpIRWEInfo->m_ModuleState = IRWEMS_CR;
  1846. }
  1847. _IRWERTF_CloseKey(hKey); hKey = NULL;
  1848. // 必须有一个或一个以上的插件才能使引擎工作
  1849. ASSERT(m_EngineData.GetUsedElemSize());
  1850. return 0;
  1851. update:
  1852. if (hKey != NULL)
  1853. _IRWERTF_CloseKey(hKey);
  1854. if (hPluginsKey != NULL)
  1855. _IRWERTF_CloseKey(hPluginsKey);
  1856. if (pNames != NULL)
  1857. ::GlobalFree(pNames);
  1858. if (pPath != NULL)
  1859. ::GlobalFree(pPath);
  1860. if (pFN != NULL)
  1861. ::GlobalFree(pFN);
  1862. if (file.m_hFile != CFile::hFileNull)
  1863. file.Close();
  1864. m_EngineData.Destroy();
  1865. ActiveNum = 0;
  1866. pbyNames = NULL;
  1867. byNames = 0;
  1868. pNames = NULL;
  1869. pPath = NULL;
  1870. pFN = NULL;
  1871. lpIRWEInfo = NULL;
  1872. curPRI = 0;
  1873. iCurrent = ActiveNum = 0;
  1874. hKey = NULL; // 插件信息根句柄
  1875. hPluginsKey = NULL; // 插件句柄
  1876. dwPluginsCount = NULL; // 插件个数
  1877. if (loopcount == FALSE)
  1878. loopcount = TRUE;
  1879. else
  1880. return -1;
  1881. // 刷新系统注册表
  1882. if (_IRWE_UpdateRegTab() == -1)
  1883. return -1;
  1884. goto begin;
  1885. }
  1886. // 销毁插件信息数组
  1887. int _IRWE_DestroyPluginsInfoStock()
  1888. {
  1889. m_EngineData.Destroy();
  1890. ::ZeroMemory((PVOID)m_ProcType, IRWE_PROCTYPE_SIZE);
  1891. for (int i=0;i<IRWE_PROCID_SIZE;i++)
  1892. m_ProcID[i] = -1;
  1893. m_ProcCount = 0;
  1894. return 0;
  1895. }
  1896. // 初始化插件函数内部助手-刷新系统注册表
  1897. int _IRWE_UpdateRegTab()
  1898. {
  1899. HKEY hKey; // 引擎系统注册表句柄
  1900. HKEY hPlugKey;
  1901. LPTSTR pPath;
  1902. TCHAR m_SouPath[_MAX_PATH]; // 插件所在目录
  1903. TCHAR m_FinPath[_MAX_PATH]; // 插件搜索串(......*.irw)
  1904. // 打开插件信息句柄(系统注册表)
  1905. hKey = _IRWERTF_OpenRegTab();
  1906. if (hKey)
  1907. {
  1908. // 获取插件文件所在目录
  1909. pPath = _IRWERTF_GetPluginsPath(hKey);
  1910. if (!pPath)
  1911. {
  1912. ::GetCurrentDirectory(_MAX_PATH, (LPTSTR)m_SouPath);
  1913. if (m_SouPath[::strlen((const char*)m_SouPath)-1] != '\')
  1914. ::strcat((char*)m_SouPath, (const char*)"\");
  1915. ::strcat((char*)m_SouPath, (const char*)"IRW-PlugIn\");
  1916. }
  1917. else
  1918. {
  1919. ::strcpy((char*)m_SouPath, (const char*)pPath);
  1920. ::GlobalFree(pPath);
  1921. if (m_SouPath[::strlen((const char*)m_SouPath)-1] != '\')
  1922. ::strcat((char*)m_SouPath, (const char*)"\");
  1923. }
  1924. }
  1925. else
  1926. {
  1927. // 创建插件信息句柄
  1928. hKey = _IRWERTF_CreateRegTab();
  1929. if (!hKey)
  1930. return -1;
  1931. // 程序的IRW-PlugIn目录作为插件的缺省目录
  1932. ::GetCurrentDirectory(_MAX_PATH, (LPTSTR)m_SouPath);
  1933. if (m_SouPath[::strlen((const char*)m_SouPath)-1] != '\')
  1934. ::strcat((char*)m_SouPath, (const char*)"\");
  1935. ::strcat((char*)m_SouPath, (const char*)"IRW-PlugIn\");
  1936. }
  1937. ASSERT(hKey);
  1938. ::strcpy((char*)m_FinPath, (const char*)m_SouPath);
  1939. ::strcat((char*)m_FinPath, (const char*)"*.irw");
  1940. int i=0;
  1941. TCHAR m_SubName[256][32];
  1942. DWORD m_SubBufSize = 32;
  1943. FILETIME ft;
  1944. // 找出所有插件句柄
  1945. while(ERROR_SUCCESS == ::RegEnumKeyEx(hKey, i, (LPTSTR)(m_SubName[i]), (LPDWORD)&m_SubBufSize, NULL, NULL, NULL, &ft))
  1946. {
  1947. i++; m_SubBufSize = 32;
  1948. }
  1949. // 删之 :-)
  1950. while(i--)
  1951. ::RegDeleteKey(hKey, (LPTSTR)(m_SubName[i]));
  1952. // 搜索所有可用的插件
  1953. WIN32_FIND_DATA file;
  1954. HANDLE hFind;
  1955. int m_FineCount = 0;
  1956. TCHAR m_PlugNames[256][_MAX_PATH];
  1957. TCHAR m_FileNames[256][_MAX_PATH];
  1958. hFind = ::FindFirstFile((LPCTSTR)m_FinPath, &file);
  1959. if (INVALID_HANDLE_VALUE == hFind)
  1960. {
  1961. _IRWERTF_CloseRegTab(hKey);
  1962. return -1;
  1963. }
  1964. do
  1965. {
  1966. ::strcpy((char*)(m_PlugNames[m_FineCount]), (char*)m_SouPath);
  1967. ::strcat((char*)(m_PlugNames[m_FineCount]), (char*)(file.cFileName)); 
  1968. ::strcpy((char*)(m_FileNames[m_FineCount]), (char*)(file.cFileName)); 
  1969. m_FineCount++;
  1970. }while(::FindNextFile(hFind, &file));
  1971. ::FindClose(hFind);
  1972. CFile fp;
  1973. PLUGSIN psi;
  1974. DWORD m_RegNameCount = 0;
  1975. CString m_RegNameSpace;
  1976. m_RegNameSpace.Empty();
  1977. // 安装插件
  1978. for (i=0;i<m_FineCount;i++)
  1979. {
  1980. if (!fp.Open((LPCTSTR)m_PlugNames[i], CFile::modeRead|CFile::shareDenyNone))
  1981. {
  1982. _IRWERTF_CloseRegTab(hKey);
  1983. return -1;
  1984. }
  1985. TRY
  1986. {
  1987. fp.Seek(-(LONG)(sizeof(PLUGSIN)), CFile::end);
  1988. fp.Read((void*)&psi, sizeof(PLUGSIN));
  1989. }
  1990. CATCH(CFileException, e)
  1991. {
  1992. _IRWERTF_CloseRegTab(hKey);
  1993. fp.Close();
  1994. return -1;
  1995. }
  1996. END_CATCH
  1997. fp.Close();
  1998. if (m_RegNameCount)
  1999. m_RegNameSpace += (LPCTSTR)" ";
  2000. m_RegNameSpace += (LPCTSTR)(psi.modulename);
  2001. m_RegNameCount++;
  2002. // 创建插件句柄
  2003. hPlugKey = _IRWERTF_CreatePlugins(hKey, (LPCTSTR)(psi.modulename));
  2004. if (!hPlugKey)
  2005. {
  2006. _IRWERTF_CloseRegTab(hKey);
  2007. return -1;
  2008. }
  2009. _IRWERTF_SetPluginsFileName(hPlugKey, m_FileNames[i]);
  2010. _IRWERTF_SetPluginPRI(hPlugKey, 30); // 30为普通优先级
  2011. _IRWERTF_CloseKey(hPlugKey);
  2012. }
  2013. _IRWERTF_SetPluginNames(hKey, (LPCTSTR)m_RegNameSpace); // 设置插件名字空间:)
  2014. _IRWERTF_SetPluginsPath(hKey, (LPCTSTR)m_SouPath); // 设置插件所在路径
  2015. _IRWERTF_SetPluginNumber(hKey, m_RegNameCount); // 设置插件个数
  2016. _IRWERTF_CloseRegTab(hKey); // 关闭总句柄
  2017. return 0;
  2018. }
  2019. // 向图像读写引擎发送命令
  2020. int _IRWE_PostCommandToImgEngine(CReturnReceipt *lpCommand, BOOL pri)
  2021. {
  2022. ASSERT(lpCommand);
  2023. ::EnterCriticalSection(&m_CLCriticalSection);
  2024. if (pri == TRUE) // 优先处理的命令
  2025. m_CommandList.AddHead((void*)lpCommand);
  2026. else // 正常的命令
  2027. m_CommandList.AddTail((void*)lpCommand);
  2028. lpCommand->m_processing = IRWEPROC_FELL_IN;
  2029. ::LeaveCriticalSection(&m_CLCriticalSection);
  2030. return 0;
  2031. }
  2032. // 从总命令队列中读取命令信息
  2033. CReturnReceipt *_IRWE_ReadCommandFromTotalList()
  2034. {
  2035. CReturnReceipt *result = NULL;
  2036. ::EnterCriticalSection(&m_CLCriticalSection);
  2037. if (m_CommandList.GetCount() > 0)
  2038. {
  2039. result = (CReturnReceipt *)(m_CommandList.RemoveHead());
  2040. ASSERT(result);
  2041. result->m_processing = IRWEPROC_PROCESSING; // 表示命令开始被处理
  2042. }
  2043. ::LeaveCriticalSection(&m_CLCriticalSection);
  2044. return result;
  2045. }
  2046. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  2047. // 回执单实现
  2048. // 回执单申请次数的技术器初始化
  2049. UINT CReturnReceipt::m_obj_count = 0;
  2050. // 初始化回执单
  2051. CReturnReceipt::CReturnReceipt()
  2052. {
  2053. // 初始化数据包
  2054. ::ZeroMemory((PVOID)&m_data, sizeof(INFOSTR));
  2055. m_data.comm = CMD_NULL;
  2056. m_data.result = ER_EMPTY;
  2057. ::ZeroMemory((PVOID)m_data.annexdata.scAnnData, DPK_ANNEXINFOSIZE);
  2058. ::ZeroMemory((PVOID)&m_data.imginfo, sizeof(IMAGEINFOSTR));
  2059. ::ZeroMemory((PVOID)m_data.filename, DPK_FILENAMESIZE);
  2060. ::ZeroMemory((PVOID)&m_data.sDIBInfo, sizeof(INTERBITMAPINFO));
  2061. m_data.imginfo.imgtype = IMT_NULL;
  2062. m_data.imginfo.imgformat = IMF_NULL;
  2063. m_data.imginfo.compression = ICS_RGB;
  2064. m_data.pImgInfo = NULL;
  2065. m_data.pLineAddr = NULL;
  2066. m_data._pbdata = NULL;
  2067. m_data.psubimg = NULL;
  2068. m_data.state = PKST_NULL;
  2069. m_data.modify = 0;
  2070. m_data.fpProgress = fpProgress;
  2071. // 初始化回执单
  2072. m_ID = m_obj_count++; // 实例个数++
  2073. m_subproc = 0; // 数据包处理进度标志归0
  2074. m_break = FALSE; // 中断操作标志归0
  2075. m_processing = IRWEPROC_INITING; // 表明回执单处于初始化期
  2076. m_command = IRWEC_NULL;
  2077. m_modelID = -1; // 表明无插件与之对应
  2078. ::ZeroMemory((PVOID)m_filename, _MAX_PATH); // 清空文件路径缓冲区
  2079. }
  2080. // 销毁回执单
  2081. CReturnReceipt::~CReturnReceipt()
  2082. {
  2083. // 因为IRWEC_IN_END命令没有任何资源申请动作,所以略过
  2084. if (IRWEC_IN_END != m_command)
  2085. {
  2086. // 中断当前的处理作业
  2087. BreakProcess();
  2088. ASSERT(IRWEPROC_PROCESSING != m_processing);
  2089. if ((IRWEPROC_COMPLETE == m_processing)|| 
  2090. (IRWEPROC_FAIL == m_processing))
  2091. {
  2092. // 释放所有的资源
  2093. if ((LPTSTR)(m_data.pImgInfo))
  2094. ::GlobalFree(m_data.pImgInfo);
  2095. if ((LPTSTR)(m_data.pLineAddr))
  2096. ::GlobalFree(m_data.pLineAddr);
  2097. if ((LPTSTR)(m_data._pbdata))
  2098. ::GlobalFree(m_data._pbdata);
  2099. if ((LPTSTR)(m_data.psubimg))
  2100. _clear_list();
  2101. }
  2102. else
  2103. VERIFY((IRWEPROC_INITING == m_processing)||(IRWEPROC_FELL_IN == m_processing));
  2104. }
  2105. }
  2106. // 获取回执单最近执行的命令
  2107. IRWECOMMAND CReturnReceipt::GetCommand()
  2108. {
  2109. return m_command;
  2110. }
  2111. // 获取命令的执行情况的
  2112. IRWERRT_RESULT CReturnReceipt::GetResult()
  2113. {
  2114. IRWERRT_RESULT result;
  2115. switch(m_command)
  2116. {
  2117. case IRWEC_NULL: // 空命令
  2118. result = IRWERRT_SUCCESS;
  2119. break;
  2120. case IRWEC_IS_VALID_FILE_COMN: // 判断指定文件是否是指定的图像文件(普通判断)
  2121. case IRWEC_IS_VALID_FILE_NICETY: // 判断指定文件是否是指定的图像文件(精密判断)
  2122. if (m_processing == IRWEPROC_COMPLETE)
  2123. {
  2124. if (m_modelID == -1)
  2125. result = IRWERRT_FAIL;
  2126. else
  2127. result = IRWERRT_SUCCESS;// 指定的文件可以被插件处理
  2128. }
  2129. else if (m_processing == IRWEPROC_FAIL)
  2130. result = IRWERRT_FAIL;
  2131. else
  2132. result = IRWERRT_ING;
  2133. break;
  2134. case IRWEC_GET_FILE_INFO: // 获取图像文件的信息
  2135. if (m_processing == IRWEPROC_COMPLETE)
  2136. {
  2137. if (m_modelID < 0)
  2138. {
  2139. result = IRWERRT_FAIL; // 没有对应的插件支持它
  2140. break;
  2141. }
  2142. if (m_data.state == PKST_PASSINFO)
  2143. result = IRWERRT_SUCCESS;// 成功提取了图像信息
  2144. else
  2145. result = IRWERRT_FAIL;
  2146. }
  2147. else if (m_processing == IRWEPROC_FAIL)
  2148. result = IRWERRT_FAIL;
  2149. else
  2150. result = IRWERRT_ING;
  2151. break;
  2152. case IRWEC_LOAD_FROM_FILE: // 将图像文件读入内存
  2153. if (m_processing == IRWEPROC_COMPLETE)
  2154. {
  2155. if (m_modelID < 0)
  2156. {
  2157. result = IRWERRT_FAIL; // 没有对应的插件支持它,不能读取图像
  2158. break;
  2159. }
  2160. VERIFY(m_data.state == PKST_INFOANDBITS);
  2161. result = IRWERRT_SUCCESS; // 成功提取了图像信息
  2162. }
  2163. else if (m_processing == IRWEPROC_FAIL)
  2164. result = IRWERRT_FAIL;
  2165. else
  2166. result = IRWERRT_ING;
  2167. break;
  2168. case IRWEC_SAVE_TO_FILE: // 保存图像到文件
  2169. if (m_processing == IRWEPROC_COMPLETE)
  2170. {
  2171. VERIFY(m_modelID >= 0);
  2172. VERIFY(m_data.state == PKST_INFOANDBITS);
  2173. result = IRWERRT_SUCCESS; // 成功提取了图像信息
  2174. }
  2175. else if (m_processing == IRWEPROC_FAIL)
  2176. result = IRWERRT_FAIL;
  2177. else
  2178. result = IRWERRT_ING;
  2179. break;
  2180. case IRWEC_RESIZE: // 获取指定尺寸的图像
  2181. if (m_processing == IRWEPROC_COMPLETE)
  2182. {
  2183. if (m_modelID < 0)
  2184. {
  2185. result = IRWERRT_FAIL; // 没有对应的插件支持它,不能读取图像
  2186. break;
  2187. }
  2188. VERIFY(m_data.state == PKST_INFOANDBITS);
  2189. result = IRWERRT_SUCCESS; // 成功提取了图像信息
  2190. }
  2191. else if (m_processing == IRWEPROC_FAIL)
  2192. result = IRWERRT_FAIL;
  2193. else
  2194. result = IRWERRT_ING;
  2195. break;
  2196. case IRWEC_IN_END: // 结束引擎线程
  2197. if (m_processing == IRWEPROC_COMPLETE)
  2198. result = IRWERRT_SUCCESS;
  2199. else
  2200. result = IRWERRT_ING;
  2201. break;
  2202. case IRWEC_GET_THUMIMAGE: // 获取拇指图
  2203. case IRWEC_GET_THUMIMAGE_A_BIT:
  2204. if (m_processing == IRWEPROC_COMPLETE)
  2205. {
  2206. if (m_modelID < 0)
  2207. {
  2208. result = IRWERRT_FAIL; // 没有对应的插件支持它,不能读取图像
  2209. break;
  2210. }
  2211. VERIFY(this->m_thumbnails.m_thumbits);
  2212. VERIFY((m_data.state == PKST_INFOANDBITS)||(m_data.state == PKST_PASSINFO));
  2213. result = IRWERRT_SUCCESS; // 成功提取了拇指图像信息
  2214. }
  2215. else if (m_processing == IRWEPROC_FAIL)
  2216. result = IRWERRT_FAIL;
  2217. else
  2218. result = IRWERRT_ING;
  2219. break;
  2220. case IRWEC_IS_SUPPORT: // 查询指定的功能是否被支持(当前该命令未被支持)
  2221. default:
  2222. VERIFY(FALSE);
  2223. break;
  2224. }
  2225. return result;
  2226. }
  2227. // 获取最近一次操作的返回码(如果最近一次的操作失败,则
  2228. // 返回码就是失败的原因(参见IRWE_ERROR))
  2229. IRWE_ERROR CReturnReceipt::GetLastError()
  2230. {
  2231. return m_errorinfo;
  2232. }
  2233. // 获取回执单中数据包的当前状态(参见PACKSTATE枚举定义)
  2234. PACKSTATE CReturnReceipt::GetDataPackState()
  2235. {
  2236. return m_data.state;
  2237. }
  2238. // 获取图像的宽度(0表示还未获得图像文件的相关信息)
  2239. int CReturnReceipt::GetImageWidth()
  2240. {
  2241. if (((m_data.comm == CMD_LOAD_FROM_FILE)||(m_data.comm == CMD_SAVE_TO_FILE))||
  2242. ((m_data.comm == CMD_GET_FILE_INFO)&&(m_processing == IRWEPROC_COMPLETE)))
  2243. {
  2244. // 表明图像的宽高信息已经提取出来了
  2245. // 此时,数据包必须已经获得过图像的信息,并执行成功
  2246. ASSERT(m_command >= IRWEC_GET_FILE_INFO);
  2247. // 图像的宽度不会是0
  2248. ASSERT(m_data.imginfo.width);
  2249. return (int)(m_data.imginfo.width);
  2250. }
  2251. return 0;
  2252. }
  2253. // 获取图像的高度(0表示还未获得图像文件的相关信息。高度值不会是负值)
  2254. int CReturnReceipt::GetImageHeight()
  2255. {
  2256. if (((m_data.comm == CMD_LOAD_FROM_FILE)||(m_data.comm == CMD_SAVE_TO_FILE))||
  2257. ((m_data.comm == CMD_GET_FILE_INFO)&&(m_processing == IRWEPROC_COMPLETE)))
  2258. {
  2259. // 表明图像的宽高信息已经提取出来了
  2260. // 此时,数据包必须已经获得过图像的信息,并执行成功
  2261. ASSERT(m_command >= IRWEC_GET_FILE_INFO);
  2262. // 图像的高度不会是0,也不会是负数
  2263. ASSERT(m_data.imginfo.height);
  2264. return (int)(m_data.imginfo.height);
  2265. }
  2266. return 0;
  2267. }
  2268. // 获取图像的个数(即底片与子图像的总个数,如动画GIF中图像的个数,如果
  2269. // 是静态图像,该函数将返回1,返回0表示图像文件的信息还未被读入)
  2270. int CReturnReceipt::GetImageNumber()
  2271. {
  2272. switch(m_data.comm)
  2273. {
  2274. case CMD_GET_FILE_INFO:
  2275. if (m_processing != IRWEPROC_COMPLETE)
  2276. break; // 表明正在被处理,还无法提取出数据
  2277. case CMD_LOAD_FROM_FILE:
  2278. case CMD_SAVE_TO_FILE:
  2279. // 此时,数据包必须已经获得过图像的信息,并执行成功
  2280. ASSERT(m_data.imginfo.imgnumbers);
  2281. return (int)(m_data.imginfo.imgnumbers);
  2282. default:
  2283. break;
  2284. }
  2285. return 0;
  2286. }
  2287. // 获取图像的位数据(即RGB数组的首地址,只有在读取了图像
  2288. // 之后,该函数的返回值才有意义)
  2289. LPBYTE CReturnReceipt::GetImageBitData()
  2290. {
  2291. return (LPBYTE)(m_data._pbdata);
  2292. }
  2293. // 获取图像行首地址数组地址
  2294. LPBYTE *CReturnReceipt::GetImageLineAddr()
  2295. {
  2296. return (LPBYTE*)(m_data.pLineAddr);
  2297. }
  2298. // 获取图像的信息(INTERBITMAPINFO结构的地址)
  2299. LPINTERBITMAPINFO CReturnReceipt::GetImageBitmapInfo()
  2300. {
  2301. return (LPINTERBITMAPINFO)&(m_data.sDIBInfo);
  2302. }
  2303. // 获取图像信息
  2304. LPIMAGEINFOSTR CReturnReceipt::GetImageInfo()
  2305. {
  2306. return (LPIMAGEINFOSTR)&(m_data.imginfo);
  2307. }
  2308. // 获取子图像块头元素的地址
  2309. LPSUBIMGBLOCK CReturnReceipt::GetSubImageBlock()
  2310. {
  2311. return (LPSUBIMGBLOCK)(m_data.psubimg);
  2312. }
  2313. // 获取原始图像的信息结构地址
  2314. void *CReturnReceipt::GetOrgImageInfo()
  2315. {
  2316. // 注:该参数可能会是NULL,具体情况需视具体读写模块而定
  2317. return (void*)(m_data.pImgInfo);
  2318. }
  2319. // 获取能处理本文件的图像读写插件ID号
  2320. int CReturnReceipt::GetImagePluginID()
  2321. {
  2322. // 有可能是-1,表示还没有找到对应的插件,0-n为有效ID号
  2323. return m_modelID;
  2324. }
  2325. // 获取回执单的编号(每一个回执单都有一个唯一的编号)
  2326. int CReturnReceipt::GetReturnReceiptID()
  2327. {
  2328. return m_ID;
  2329. }
  2330. // 中断当前正在处理的命令(主要是为了加快程序对用户操作的反应速度)
  2331. void CReturnReceipt::BreakProcess()
  2332. {
  2333. POSITION pos;
  2334. ::EnterCriticalSection(&m_CLCriticalSection);
  2335. ASSERT(IRWEPROC_INITING != m_processing);
  2336. if (m_processing == IRWEPROC_FELL_IN)
  2337. {
  2338. // 如果该回执单在命令队列中,还未被处理,那么将其取出
  2339. pos = m_CommandList.Find((void*)this);
  2340. ASSERT(((void*)pos) != NULL);
  2341. m_CommandList.RemoveAt(pos);
  2342. }
  2343. ::LeaveCriticalSection(&m_CLCriticalSection);
  2344. m_break = TRUE; // 设置中断操作标志
  2345. // 如果回执单正在被执行,那么等待它执行完毕
  2346. while(m_processing == IRWEPROC_PROCESSING);
  2347. m_break = FALSE; // 恢复中断操作标志
  2348. return;
  2349. }
  2350. // 获取相关联文件的路径缓冲区首地址
  2351. LPCTSTR CReturnReceipt::GetFileName()
  2352. {
  2353. return (LPCTSTR)m_filename;
  2354. }
  2355. // 删除包中的图像位数据,使之返回到INFOANDBIT之前的状态。
  2356. // 如果当前的状态已经在INFOANDBIT状态之前了,则该函数直接
  2357. // 返回。
  2358. void CReturnReceipt::ClearImageBitData()
  2359. {
  2360. switch (m_data.state)
  2361. {
  2362. case PKST_NULL: // 数据包为空
  2363. case PKST_NOTVER: // 指定文件还未通过验证的阶段(此时只有文件名变量被设置)
  2364. case PKST_PASSVER: // 指定的文件已通过验证,是有效格式的文件
  2365. // 直接返回
  2366. break;
  2367. case PKST_PASSINFO: // 已通过验证,且数据包中有该文件的相关信息
  2368. case PKST_INFOANDBITS: // 已通过验证,且有该文件的相关信息,并含有图像的位数据
  2369. {
  2370. // 等待处理作业完成
  2371. while (m_processing == IRWEPROC_PROCESSING);
  2372. // 清理已分配的内存资源
  2373. if (m_data.pImgInfo)
  2374. {
  2375. ::GlobalFree(m_data.pImgInfo);
  2376. m_data.pImgInfo = NULL;
  2377. }
  2378. if (m_data.pLineAddr)
  2379. {
  2380. ::GlobalFree(m_data.pLineAddr);
  2381. m_data.pLineAddr = NULL;
  2382. }
  2383. if (m_data._pbdata)
  2384. {
  2385. ::GlobalFree(m_data._pbdata);
  2386. m_data._pbdata = NULL;
  2387. }
  2388. if (m_data.psubimg)
  2389. {
  2390. _clear_list();
  2391. m_data.psubimg = NULL;
  2392. }
  2393. // 将回执单状态设定为PKST_PASSINFO(只包含图像信息,不包括位数据)
  2394. ::ZeroMemory((PVOID)&(m_data.sDIBInfo), sizeof(INTERBITMAPINFO));
  2395. m_data.state = PKST_PASSINFO;
  2396. m_data.modify = 0;
  2397. m_data.comm = CMD_GET_FILE_INFO;
  2398. m_data.result = ER_SUCCESS;
  2399. m_processing = IRWEPROC_COMPLETE;
  2400. m_errorinfo = IRWEERR_SUCCESS;
  2401. m_command = IRWEC_GET_FILE_INFO;
  2402. m_subproc = 100;
  2403. }
  2404. break;
  2405. case PKST_MODIFY:// 数据包中的图像已经被修改过
  2406. // 此时数据包的imginfo数据与sDIBInfo数据可能会不同,
  2407. // 所以不能简单的使用以上的办法。
  2408. // 此处强制调用者不使用这种方法。
  2409. VERIFY(FALSE);
  2410. break;
  2411. default:
  2412. VERIFY(FALSE); // 不可能存在未定义的命令,除非系统崩溃
  2413. break;
  2414. }
  2415. }
  2416. // 获取当前命令的执行进度,有五种可能的进度值,参见IRWE_PROCESSING定义
  2417. IRWE_PROCESSING CReturnReceipt::GetProcessing()
  2418. {
  2419. return m_processing;
  2420. }
  2421. // 读写模块进度控制。即读写模块回调函数。
  2422. // 入口参数1是总的进度数,参数2是当前的进度数。
  2423. // 返回参数:如果返回0,则图像读写模块继续操作,
  2424. // 如果返回非0值,则读写模块终止操作,返回。
  2425. int WINAPI CReturnReceipt::fpProgress(int tol, int cur)
  2426. {
  2427. ASSERT(m_pCurrentReturnReceipt);
  2428. m_pCurrentReturnReceipt->m_subproc = cur;
  2429. TRACE("正在处理数据包:%d,总进度:%d,当前进度:%dn", m_pCurrentReturnReceipt, tol, cur);
  2430. if (m_pCurrentReturnReceipt->m_break == TRUE)
  2431. return 1; // 中断操作
  2432. else
  2433. return 0; // 继续操作
  2434. }
  2435. // 清除子图像链表(如果图像文件中包含多幅图像,那么该链表中可能有数据)
  2436. void CReturnReceipt::_clear_list()
  2437. {
  2438. if (m_data.psubimg == NULL)
  2439. return;
  2440. if (m_data.imginfo.imgnumbers >= 1)
  2441. m_data.imginfo.imgnumbers = 1; // 如果存在子图像,那么只保留背景图
  2442. else
  2443. m_data.imginfo.imgnumbers = 0; // 如果没有图像,设0
  2444. LPSUBIMGBLOCK   lpSubImg;
  2445. while((lpSubImg=m_data.psubimg) != NULL)
  2446. {
  2447. m_data.psubimg = lpSubImg->next;
  2448. lpSubImg->number = 0; // 子图像块的序列号
  2449. lpSubImg->left = lpSubImg->top = 0; // 子图像块的显示位置(左上角)
  2450. lpSubImg->width = lpSubImg->height = 0; // 子图像块的图像宽度及高度
  2451. lpSubImg->dowith = 0; // 处置方法(针对于动画GIF)
  2452. lpSubImg->userinput = 0; // 用户输入(针对于动画GIF)
  2453. lpSubImg->colorkey = 0; // 透明色分量值
  2454. lpSubImg->time = 0; // 显示的延迟时间
  2455. if (lpSubImg->pLineAddr)
  2456. ::GlobalFree(lpSubImg->pLineAddr);
  2457. if (lpSubImg->_pbdata)
  2458. ::GlobalFree(lpSubImg->_pbdata);
  2459. lpSubImg->parents = NULL; // 第一桢图像数据的结构地址(所属数据包结构的地址)
  2460. lpSubImg->prev = NULL; // 前一桢图像数据的结构地址
  2461. lpSubImg->next = NULL; // 后一桢图像数据的结构地址(NULL表示这是最后一副图像)
  2462. ::GlobalFree(lpSubImg);
  2463. };
  2464. return;
  2465. }
  2466. // 判断回执单中是否存在拇指图(返回TRUE表示有,FALSE则没有)
  2467. // 注:返回TRUE并不意味着拇指图已经形成,本函数只能说明用于
  2468. // 存放拇指图的缓冲区已经被分配,请使用GetResult()函数判断
  2469. // 命令是否真正完成
  2470. BOOL CReturnReceipt::IsThumImage()
  2471. {
  2472. return (m_thumbnails.m_thumbits&&m_thumbnails.m_thumlines) ? TRUE:FALSE;
  2473. }
  2474. // 获取拇指图数据的来源(请参见IRWETHUM_FROM定义)
  2475. IRWETHUM_FROM CReturnReceipt::GetThumImageFrom()
  2476. {
  2477. return m_thumbnails.m_thumfrom;
  2478. }
  2479. // 获取拇指图像的尺寸数据(宽度、高度,CRect的左上角为0,0)
  2480. CRect& CReturnReceipt::GetThumImageRect()
  2481. {
  2482. static CRect rect;
  2483. rect.SetRect(0, 0, m_thumbnails.m_thuminfo.biWidth, 
  2484. m_thumbnails.m_thuminfo.biHeight);
  2485. return rect;
  2486. }
  2487. // 获取拇指图的边界正方形的宽度、高度
  2488. CRect& CReturnReceipt::GetThumBoundRect()
  2489. {
  2490. return m_thumbnails.m_thumbound;
  2491. }
  2492. // 获取拇指图的详细信息(包括拇指图的宽、高,位深等)
  2493. BITMAPINFOHEADER *CReturnReceipt::GetThumImageInfo()
  2494. {
  2495. return &(m_thumbnails.m_thuminfo);
  2496. }
  2497. // 获取拇指图的位数据
  2498. PBYTE CReturnReceipt::GetThumImageBit()
  2499. {
  2500. return (PBYTE)(m_thumbnails.m_thumbits);
  2501. }
  2502. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  2503. // 拇指图类实现
  2504. //
  2505. CThumImage::CThumImage()
  2506. {
  2507. m_thumfrom = IRWETHUM_FROM_NULL;
  2508. ::ZeroMemory((PVOID)&m_thuminfo, sizeof(BITMAPINFOHEADER));
  2509. m_thuminfo.biSize = sizeof(BITMAPINFOHEADER);
  2510. m_thuminfo.biBitCount = ISEE_IMAGE_BITCOUNT; // 32位
  2511. m_thuminfo.biCompression = BI_RGB;
  2512. m_thuminfo.biPlanes = 1;
  2513. m_thuminfo.biWidth = 0;
  2514. m_thuminfo.biHeight = 0;
  2515. m_thumbits = NULL;
  2516. m_thumlines= NULL;
  2517. m_thumbound.SetRectEmpty();
  2518. }
  2519. CThumImage::~CThumImage()
  2520. {
  2521. if (m_thumbits)
  2522. ::GlobalFree(m_thumbits);
  2523. if (m_thumlines)
  2524. ::GlobalFree(m_thumlines);
  2525. }
  2526. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  2527. // 拇指图缩放代码
  2528. // 作者:Analyst
  2529. // 初始化Alpha表
  2530. void _Thum_InitAlphaTable()
  2531. {
  2532. QWORD temp;
  2533. for(int i=0;i<_IRWE_THUM_APLHATAB_SIZE;i++)
  2534. {
  2535. temp = (QWORD)i;
  2536. s_AlphaTable[i] = temp<<48 | temp<<32 | temp<<16 | temp;
  2537. }
  2538. }
  2539. // 缩放接口函数
  2540. void _Thum_BlitStretch(DWORD **lpDesLines, int deswidth, int desheight, 
  2541. DWORD **lpSrcLines, int srcwidth, int srcheight)
  2542. {
  2543. DWORD dU = (srcwidth << 16) / deswidth;
  2544. DWORD dV = (srcheight << 16) / desheight;
  2545. DWORD V1 = 0;
  2546. for(int i = 0; i < desheight-1; i++)
  2547. {
  2548. _Thum_DrawScanLine((DWORD*)(lpDesLines[i]), (DWORD *)(lpSrcLines[(V1>>16)]), deswidth, dU);
  2549. _Thum_DrawScanLineAlpha((DWORD*)(lpDesLines[i]), (DWORD *)(lpSrcLines[(V1>>16)+1]), deswidth, dU, (V1>>9)&0x7f);
  2550. V1 += dV;
  2551. }
  2552. }
  2553. // 行缩放函数
  2554. void _Thum_DrawScanLine(DWORD* DestAddr, DWORD* SrcAddr, int Width, DWORD dU)
  2555. {
  2556. __asm{
  2557. mov esi, SrcAddr;
  2558. mov edi, DestAddr;
  2559. mov ecx, Width;
  2560. xor edx, edx;  //edx = U1
  2561. mov ebx, dU;
  2562. pxor mm7, mm7;
  2563. LoopX:
  2564. mov eax, edx;
  2565. and eax, 0xffff;
  2566. shr eax, 9;
  2567. movq mm6, [s_AlphaTable + eax * 8]; //mm6 = a2
  2568. neg eax;
  2569. add eax, 128;
  2570. movq mm5, [s_AlphaTable + eax * 8]; //mm5 = a1
  2571. mov eax, edx;
  2572. shr eax, 16;
  2573. movq mm0, [esi + eax * 4];
  2574. movq mm1, mm0;
  2575. PUNPCKLBW mm0, mm7;  //mm0 = 0a10r10g10b1
  2576. PUNPCKHBW mm1, mm7;  //mm1 = 0a20r20g20b2
  2577. pmullw mm0, mm5;
  2578. pmullw mm1, mm6;
  2579. paddw  mm0, mm1;
  2580. psrlw  mm0, 7;
  2581. packuswb mm0, mm0;
  2582. movd eax, mm0;
  2583. add edx, ebx;
  2584. stosd;
  2585. dec ecx;
  2586. jnz LoopX;
  2587. emms;
  2588. }
  2589. }
  2590. void _Thum_DrawScanLineAlpha(DWORD* DestAddr, DWORD* SrcAddr, int Width, DWORD dU, DWORD Alpha)
  2591. {
  2592. if(!Alpha)
  2593. return;
  2594. __asm{
  2595. mov esi, SrcAddr;
  2596. mov edi, DestAddr;
  2597. mov ecx, Width;
  2598. xor edx, edx;  //edx = U1
  2599. mov ebx, dU;
  2600. mov eax, Alpha;
  2601. pxor mm7, mm7;
  2602. movq mm4, [s_AlphaTable + eax * 8]; //mm4 = alpha
  2603. LoopX:
  2604. mov eax, edx;
  2605. and eax, 0xffff;
  2606. shr eax, 9;
  2607. movq mm6, [s_AlphaTable + eax * 8]; //mm6 = a2
  2608. neg eax;
  2609. add eax, 128;
  2610. movq mm5, [s_AlphaTable + eax * 8]; //mm5 = a1
  2611. mov eax, edx;
  2612. shr eax, 16;
  2613. movq mm0, [esi + eax * 4];
  2614. movq mm1, mm0;
  2615. PUNPCKLBW mm0, mm7;  //mm0 = 0a10r10g10b1
  2616. movd mm2, [edi];
  2617. PUNPCKHBW mm1, mm7;  //mm1 = 0a20r20g20b2
  2618. pmullw mm0, mm5;
  2619. punpcklbw mm2, mm7;
  2620. pmullw mm1, mm6;
  2621. paddw  mm0, mm1;
  2622. psrlw  mm0, 7;
  2623. psubw mm0, mm2;
  2624. pmullw mm0, mm4;
  2625. psraw  mm0, 7;
  2626. paddw  mm0, mm2;
  2627. packuswb mm0, mm0;
  2628. movd eax, mm0;
  2629. add edx, ebx;
  2630. stosd;
  2631. dec ecx;
  2632. jnz LoopX;
  2633. emms;
  2634. }
  2635. }