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

图形图象

开发平台:

Visual C++

  1. //xuhappy  2000-7-10
  2. //本程序参照了BMP模块中的相应函数
  3. // TiffModule.cpp : Defines the initialization routines for the DLL.
  4. //
  5. #include "stdafx.h"
  6. #include "TiffModule.h"
  7. #include "TiffField.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. static char ModuleProcessImgType[]="TIFF,TIF"; // 本模块能处理的图像类型
  14. static char WriterList[]="此处写上你的名字"; // 本模块的作者列表
  15. static char WriterMess[]="在此处添入你的留言^_^"; // 作者留言
  16. //
  17. // Note!
  18. //
  19. // If this DLL is dynamically linked against the MFC
  20. // DLLs, any functions exported from this DLL which
  21. // call into MFC must have the AFX_MANAGE_STATE macro
  22. // added at the very beginning of the function.
  23. //
  24. // For example:
  25. //
  26. // extern "C" BOOL PASCAL EXPORT ExportedFunction()
  27. // {
  28. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  29. // // normal function body here
  30. // }
  31. //
  32. // It is very important that this macro appear in each
  33. // function, prior to any calls into MFC.  This means that
  34. // it must appear as the first statement within the 
  35. // function, even before any object variable declarations
  36. // as their constructors may generate calls into the MFC
  37. // DLL.
  38. //
  39. // Please see MFC Technical Notes 33 and 58 for additional
  40. // details.
  41. //
  42. // 在图像读写模块中,如果想分配内存,请使用API函数GlobalAlloc()
  43. // ,如果想释放内存请使用GlobalFree()函数。不要使用诸如:new
  44. // 、malloc()等函数。这是为了使各模块之间可以异地释放内存。
  45. //
  46. //
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CTiffModuleApp
  49. BEGIN_MESSAGE_MAP(CTiffModuleApp, CWinApp)
  50. //{{AFX_MSG_MAP(CTiffModuleApp)
  51. // NOTE - the ClassWizard will add and remove mapping macros here.
  52. //    DO NOT EDIT what you see in these blocks of generated code!
  53. //}}AFX_MSG_MAP
  54. END_MESSAGE_MAP()
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CTiffModuleApp construction
  57. CTiffModuleApp::CTiffModuleApp()
  58. {
  59. // TODO: add construction code here,
  60. // Place all significant initialization in InitInstance
  61. }
  62. /////////////////////////////////////////////////////////////////////////////
  63. // The one and only CTiffModuleApp object
  64. CTiffModuleApp theApp;
  65. // 接口函数声明 — 第一层,唯一与外界联系的接口
  66. int WINAPI AccessTIFFModule(INFOSTR *pInfo)
  67. {
  68. // 这个函数可以不作修改的使用,除非你的返回值多于两种。
  69. switch(pInfo->comm)
  70. {
  71. case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
  72. _fnCMD_GETPROCTYPE(pInfo);
  73. break;
  74. case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
  75. _fnCMD_GETWRITERS(pInfo);
  76. break;
  77. case CMD_GETWRITERMESS: // 获取作者们的留言
  78. _fnCMD_GETWRITERMESS(pInfo);
  79. break;
  80. case CMD_GETBUILDID: // 获取图像模块内部版本号
  81. _fnCMD_GETBUILDID(pInfo);
  82. break;
  83. case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的WMF文件
  84. _fnCMD_IS_VALID_FILE(pInfo);
  85. break;
  86. case CMD_GET_FILE_INFO: // 获取指定文件的信息
  87. _fnCMD_GET_FILE_INFO(pInfo);
  88. break;
  89. case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
  90. _fnCMD_LOAD_FROM_FILE(pInfo);
  91. break;
  92. case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
  93. _fnCMD_SAVE_TO_FILE(pInfo);
  94. break;
  95. case CMD_IS_SUPPORT: // 查询某个命令是否被支持
  96. _fnCMD_IS_SUPPORT(pInfo);
  97. break;
  98. case CMD_RESIZE: // 从新获取指定尺寸的图像位数据(只适用于矢量图像)
  99. _fnCMD_RESIZE(pInfo);
  100. break;
  101. default:
  102. pInfo->result = ER_ILLCOMM; // 非法命令
  103. ASSERT(FALSE); // 调用者的程序设计有问题 :-)
  104. break;
  105. }
  106. // 执行命令成功返回1, 失败返回0
  107. return (pInfo->result==ER_SUCCESS)? 1:0;
  108. }
  109. // 命令解释函数 — 第二层解释函数
  110. //********************************************************************//
  111. // 操作命令解释函数---解释:CMD_IS_SUPPORT命令
  112. // 查询某个命令是否被支持
  113. void _fnCMD_IS_SUPPORT(INFOSTR *pInfo)
  114. {
  115. // 这个函数是为客户程序查询时使用,如果你实现了对某个命令的
  116. // 解释,可修改相应的case中的设置,使其返回ER_SUCCESS,这就
  117. // 表示你的模块已经支持该命令了。同时,现在的这个文件中已包
  118. // 含了对前四个命令的解释,你只需向还未支持的命令函数中添加
  119. // 代码即可。
  120. ASSERT(pInfo->result == ER_EMPTY);
  121. switch(pInfo->annexdata.cmAnnData)  
  122. {
  123. case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
  124. pInfo->result = ER_SUCCESS;
  125. break;
  126. case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
  127. pInfo->result = ER_SUCCESS;
  128. break;
  129. case CMD_GETWRITERMESS: // 获取作者们的留言
  130. pInfo->result = ER_SUCCESS;
  131. break;
  132. case CMD_GETBUILDID: // 获取图像模块内部版本号
  133. pInfo->result = ER_SUCCESS;
  134. break;
  135. case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的WMF文件
  136. pInfo->result = ER_NOTSUPPORT;
  137. break;
  138. case CMD_GET_FILE_INFO: // 获取指定文件的信息
  139. pInfo->result = ER_NOTSUPPORT;
  140. break;
  141. case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
  142. pInfo->result = ER_NOTSUPPORT;
  143. break;
  144. case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
  145. pInfo->result = ER_NOTSUPPORT;
  146. break;
  147. case CMD_IS_SUPPORT: // 查询某个命令是否被支持
  148. pInfo->result = ER_SUCCESS;
  149. break;
  150. case CMD_RESIZE: // 获取指定尺寸的图像(只适用于矢量图像)
  151. pInfo->result = ER_NOTSUPPORT;
  152. break;
  153. default:
  154. pInfo->result = ER_NOTSUPPORT;
  155. break;
  156. }
  157. }
  158. // 操作命令解释函数---解释:CMD_GETPROCTYPE命令
  159. // 获取本模块能处理的图像类型,如:BMP,PCX等等
  160. void _fnCMD_GETPROCTYPE(INFOSTR *pInfo)
  161. {
  162. // 这是预定义的函数代码,你可以不必修改的使用。
  163. // 根据接口定义,此时附加数据应被清空为0,所以下此断言
  164. ASSERT(pInfo->annexdata.scAnnData[0] == 0);
  165. ASSERT(pInfo->result == ER_EMPTY);
  166. // 复制能处理的类型字符串
  167. ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)ModuleProcessImgType, 
  168. sizeof(ModuleProcessImgType));
  169. pInfo->result = ER_SUCCESS;
  170. }
  171. // 操作命令解释函数---解释:CMD_GETWRITER命令
  172. // 获取本模块的作者列表,多人时用逗号分隔
  173. void _fnCMD_GETWRITERS(INFOSTR *pInfo)
  174. {
  175. // 这是预定义的函数代码,你可以不必修改的使用。
  176. // 根据接口定义,此时附加数据应被清空为0,所以下此断言
  177. ASSERT(pInfo->annexdata.scAnnData[0] == 0);
  178. ASSERT(pInfo->result == ER_EMPTY);
  179. // 复制开发者名单串
  180. ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterList, 
  181. sizeof(WriterList));
  182. pInfo->result = ER_SUCCESS;
  183. }
  184. // 操作命令解释函数---解释:CMD_GETWRITERMESS命令
  185. // 获取作者们的留言
  186. void _fnCMD_GETWRITERMESS(INFOSTR *pInfo)
  187. {
  188. // 这是预定义的函数代码,你可以不必修改的使用。
  189. // 根据接口定义,此时附加数据应被清空为0,所以下此断言
  190. ASSERT(pInfo->annexdata.scAnnData[0] == 0);
  191. ASSERT(pInfo->result == ER_EMPTY);
  192. // 复制开发者们的留言字符串
  193. ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterMess, 
  194. sizeof(WriterMess));
  195. pInfo->result = ER_SUCCESS;
  196. }
  197. // 操作命令解释函数---解释:CMD_GETBUILDID命令
  198. // 获取图像模块内部版本号
  199. void _fnCMD_GETBUILDID(INFOSTR *pInfo)
  200. {
  201. // 这是预定义的函数代码,你可以不必修改的使用。
  202. // 根据接口定义,此时annexdata.dwAnnData应被设为0,所以下此断言
  203. ASSERT(pInfo->annexdata.dwAnnData == 0);
  204. ASSERT(pInfo->result == ER_EMPTY);
  205. // 填写内部版本号码
  206. pInfo->annexdata.dwAnnData = MODULE_BUILDID;
  207. pInfo->result = ER_SUCCESS;
  208. }
  209. // 操作命令解释函数---解释:CMD_IS_VALID_FILE命令
  210. // 判断指定文件是否是有效的WMF文件
  211. void _fnCMD_IS_VALID_FILE(INFOSTR *pInfo)
  212. {
  213. CFile file;
  214. TIFFHEADER tifHeader;
  215. ASSERT(pInfo->result == ER_EMPTY);
  216. ASSERT(pInfo->annexdata.iAnnData == 0);
  217. ASSERT(::strlen(pInfo->filename));
  218. ASSERT(pInfo->state == PKST_NOTVER);
  219. ASSERT(pInfo);
  220. //设置初始值
  221. pInfo->result = ER_COMMINFOERR;
  222. pInfo->annexdata.iAnnData=0;
  223. //检测文件是否存在
  224. if(IsFileExist(pInfo->filename)){
  225. pInfo->result=ER_SUCCESS;
  226. if(!file.Open(pInfo->filename,CFile::modeRead)){
  227. pInfo->result=ER_FILERWERR;
  228. return;
  229. }
  230. file.SeekToBegin();
  231. //读取TIFF文件头信息
  232. int ReadRet=file.Read((LPSTR)&tifHeader,sizeof(TIFFHEADER));
  233. if(ReadRet!=sizeof(TIFFHEADER)){
  234. pInfo->result=ER_FILERWERR;
  235. file.Close();
  236. return;
  237. }
  238. //检验TIFF文件0-1字节  'II' or 'MM'
  239. if((tifHeader.wImageType==TIFF_MARKER1)||(tifHeader.wImageType==TIFF_MARKER2)){
  240. //检测TIFF文件的版本号42
  241. if(tifHeader.wVersion!=0x2A){
  242. pInfo->result=ER_FILERWERR;
  243. file.Close();
  244. }
  245. //检验TIFF文件4-7字节的第一个IFD的偏移量应该>8字节
  246. if(tifHeader.dwIFDOffset<8){
  247. pInfo->result=ER_FILERWERR;
  248. file.Close();
  249. }else{
  250. //检验第一个IFD中的信息
  251. try{file.Seek((LONG)tifHeader.dwIFDOffset,CFile::begin);}
  252. catch(CFileException* pFileEx)
  253. {
  254. TRACE1("Read File Error /5dn",pFileEx->m_cause);
  255. pInfo->result=ER_FILERWERR;
  256. file.Close();
  257. }
  258. TiffTag ImageTag;
  259. WORD TagCount;
  260. int TagIndex=0;
  261. //读取IFD中的标签个数
  262. try{file.Read((LPSTR)&TagCount,sizeof(WORD));}
  263. catch(CFileException* pFileEx)
  264. {
  265. TRACE1("Read File Error /5dn",pFileEx->m_cause);
  266. pInfo->result=ER_FILERWERR;
  267. file.Close();
  268. }
  269. if(TagCount>0){
  270. int DetectOver=0;
  271. //读取ImageWidth,ImageLength标签的信息
  272. for(TagIndex=0;TagIndex<TagCount;TagIndex++){
  273. file.Read((LPSTR)&ImageTag,sizeof(TiffTag));
  274. //检验图像宽度
  275. if(ImageTag.wTag==IMAGEWIDTH){
  276. if(ImageTag.OffVal.dwValue<=0){
  277. pInfo->result=ER_FILERWERR;
  278. file.Close();
  279. }
  280. DetectOver++;
  281. }
  282. //检验图像长度
  283. if(ImageTag.wTag==IMAGELENGTH){
  284. if(ImageTag.OffVal.dwValue<=0){
  285. pInfo->result=ER_FILERWERR;
  286. file.Close();
  287. }
  288. DetectOver++;
  289. }
  290. //检验通过,退出循环
  291. if(DetectOver>1){
  292. break;
  293. }
  294. }
  295. //图像通过检验,参考了BMP模块
  296. pInfo->annexdata.iAnnData = 1;
  297. pInfo->state = PKST_PASSVER;
  298. }else{
  299. pInfo->result=ER_FILERWERR;
  300. file.Close();
  301. }
  302. }
  303. }
  304. file.Close();
  305. }
  306. }
  307. // 操作命令解释函数---解释:CMD_GET_FILE_INFO命令
  308. // 获取指定文件的信息
  309. void _fnCMD_GET_FILE_INFO(INFOSTR *pInfo)
  310. {
  311. // 这个命令一般都要进行解释,你可以参考已经编写完的某个图像读写
  312. // 模块的代码,并结合本图像格式的特点来完成该函数。
  313. // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
  314. // ----------------------------------------------------------------->
  315. pInfo->result = ER_NOTSUPPORT;
  316. }
  317. // 操作命令解释函数---解释:CMD_LOAD_FROM_FILE命令
  318. // 从指定图像文件中读取数据
  319. void _fnCMD_LOAD_FROM_FILE(INFOSTR *pInfo)
  320. {
  321. // 这个命令一般都要进行解释,你可以参考已经编写完的某个图像读写
  322. // 模块的代码,并结合本图像格式的特点来完成该函数。
  323. // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
  324. // ----------------------------------------------------------------->
  325. pInfo->result = ER_NOTSUPPORT;
  326. }
  327. // 操作命令解释函数---解释:CMD_SAVE_TO_FILE命令
  328. // 将数据保存到指定文件中
  329. void _fnCMD_SAVE_TO_FILE(INFOSTR *pInfo)
  330. {
  331. // 这个命令不一定要解释,你可以参考本图像格式的具体境况来决定
  332. // 是否解释该命令。
  333. // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
  334. // ----------------------------------------------------------------->
  335. pInfo->result = ER_NOTSUPPORT;
  336. }
  337. // 操作命令解释函数---解释:CMD_RESIZE命令
  338. // 重新获取指定尺寸的图像位数据(只适用于矢量图像)
  339. void _fnCMD_RESIZE(INFOSTR *pInfo)
  340. {
  341. // 这个命令一般的图像读写模块不需要支持,它只适用于矢量图像,
  342. // 比如WMF、EMF之类。
  343. // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
  344. // ----------------------------------------------------------------->
  345. pInfo->result = ER_NOTSUPPORT;
  346. }
  347. BOOL IsFileExist(char *lpFileName)
  348. {
  349. CFile file;
  350. BOOL bExist = FALSE; // 文件存在是TRUE,不存在是FALSE
  351. // 确定指定的文件是否存在
  352. if (file.Open(lpFileName, CFile::modeReadWrite))
  353. {
  354. bExist = TRUE;
  355. file.Close();
  356. }
  357. return bExist;
  358. }