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

图形图象

开发平台:

Visual C++

  1. /*----------------------------------------------------------------------------------*
  2. $                                                                                    $
  3. =>  000000    000000   00000000     PSD File Format Read Program                     $
  4. =>  00   00  00        00     00     这是自由软件 ISee 图像浏览器的一部分            $
  5. =>  00   00  00        00      00     这个模块实现了 PSD 格式的读取                  $
  6. =>  000000    000000   00      00     这个模块的当前版本是 1.5                       $
  7. =>  00             00  00      00     这个模块的当前作者是 Pegasus                   $
  8. =>  00             00  00     00     这个模块的主架构来自于 YZ 的 BMP 模块           $
  9. =>  00        000000   00000000     这个模块的部分函数也来自于 YZ                    $
  10. $                                                                                    $
  11. *---------------------------------------------------------------------2000-10-27---*/
  12. //
  13. //=> 这是你二个版本,不第一个版本节省了一些内存,但程序也增加了一些,模块化少了,请见谅
  14. //
  15. // 测试日志
  16. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\
  17. ////////////// 当前模块还没有实现 CMYK 和 Lab 颜色格式的真正读取
  18. ///////////// 我用于测试的所有图像都是来自于 Photoshop V5.0.2
  19. //////////// 用于测试的图像有大小 216*297 和 20*100 的 以及 Photoshop 5.0.2 自带的图像
  20. /////////// 目前支持的图像有:
  21. ////////// RGB色,8位,RLE压缩与无压缩; RGB色,16位,无压缩;
  22. ///////// 灰度,8位,RLE压缩与无压缩; 灰度,16位,无压缩;
  23. //////// 单色,1位,按位存储;
  24. /////// Duotone, 8位,RLE压缩与无压缩; // 相近读取(灰度)
  25. ////// CMYK色,8位,RLE压缩与无压缩; CMYK色,16位,无压缩; // 相近读取(丢掉黑色)
  26. ///// Lab色,8位,RLE压缩与无压缩; // 相近读取(灰度)
  27. //// Multichannel(多通道),按8位RGB来读,当图的通道数少于3时,颜色会发生大的变化
  28. /// ACDSee处理通道数少于3的图像的方法是-显示全黑色,可我让他显示变色的图
  29. // 当前我对CMYK的处理是丢去黑色,这样会使颜色发生变化,ACDSee也会但他变得少
  30. // 当前我对Lab的处理也是丢去a与b的分量,这样使图像成了灰度的图
  31. // 此程序还有多处可以优化!!! ^_^
  32. //
  33. // eMail : Pegasusgod@163.net
  34. //
  35. // PsdModule.cpp : Defines the initialization routines for the DLL.
  36. #include "stdafx.h"
  37. #include "PsdModule.h"
  38. #include "FormYZ.h"
  39. #ifdef _DEBUG
  40. #define new DEBUG_NEW
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #endif
  44. static char ModuleProcessImgType[]="PSD"; // 本模块能处理的图像类型
  45. static char WriterList[]="Pegasus"; // 本模块的作者列表
  46. static char WriterMess[]="请不要写作者留言!! ^_^"; // 作者留言
  47. //
  48. // Note!
  49. //
  50. // If this DLL is dynamically linked against the MFC
  51. // DLLs, any functions exported from this DLL which
  52. // call into MFC must have the AFX_MANAGE_STATE macro
  53. // added at the very beginning of the function.
  54. //
  55. // For example:
  56. //
  57. // extern "C" BOOL PASCAL EXPORT ExportedFunction()
  58. // {
  59. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  60. // // normal function body here
  61. // }
  62. //
  63. // It is very important that this macro appear in each
  64. // function, prior to any calls into MFC.  This means that
  65. // it must appear as the first statement within the 
  66. // function, even before any object variable declarations
  67. // as their constructors may generate calls into the MFC
  68. // DLL.
  69. //
  70. // Please see MFC Technical Notes 33 and 58 for additional
  71. // details.
  72. //
  73. // 在图像读写模块中,如果想分配内存,请使用API函数GlobalAlloc()
  74. // ,如果想释放内存请使用GlobalFree()函数。不要使用诸如:new
  75. // 、malloc()等函数。这是为了使各模块之间可以异地释放内存。
  76. //
  77. //
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CPsdModuleApp
  80. BEGIN_MESSAGE_MAP(CPsdModuleApp, CWinApp)
  81. //{{AFX_MSG_MAP(CPsdModuleApp)
  82. // NOTE - the ClassWizard will add and remove mapping macros here.
  83. //    DO NOT EDIT what you see in these blocks of generated code!
  84. //}}AFX_MSG_MAP
  85. END_MESSAGE_MAP()
  86. /////////////////////////////////////////////////////////////////////////////
  87. // CPsdModuleApp construction
  88. CPsdModuleApp::CPsdModuleApp()
  89. {
  90. // TODO: add construction code here,
  91. // Place all significant initialization in InitInstance
  92. }
  93. /////////////////////////////////////////////////////////////////////////////
  94. // The one and only CPsdModuleApp object
  95. CPsdModuleApp theApp;
  96. // 接口函数声明 — 第一层,唯一与外界联系的接口
  97. int WINAPI AccessPSDModule(INFOSTR *pInfo)
  98. {
  99. // 这个函数可以不作修改的使用,除非你的返回值多于两种。
  100. switch(pInfo->comm)
  101. {
  102. case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
  103. _fnCMD_GETPROCTYPE(pInfo);
  104. break;
  105. case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
  106. _fnCMD_GETWRITERS(pInfo);
  107. break;
  108. case CMD_GETWRITERMESS: // 获取作者们的留言
  109. _fnCMD_GETWRITERMESS(pInfo);
  110. break;
  111. case CMD_GETBUILDID: // 获取图像模块内部版本号
  112. _fnCMD_GETBUILDID(pInfo);
  113. break;
  114. case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的WMF文件
  115. _fnCMD_IS_VALID_FILE(pInfo);
  116. break;
  117. case CMD_GET_FILE_INFO: // 获取指定文件的信息
  118. _fnCMD_GET_FILE_INFO(pInfo);
  119. break;
  120. case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
  121. _fnCMD_LOAD_FROM_FILE(pInfo);
  122. break;
  123. case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
  124. _fnCMD_SAVE_TO_FILE(pInfo);
  125. break;
  126. case CMD_IS_SUPPORT: // 查询某个命令是否被支持
  127. _fnCMD_IS_SUPPORT(pInfo);
  128. break;
  129. case CMD_RESIZE: // 从新获取指定尺寸的图像位数据(只适用于矢量图像)
  130. _fnCMD_RESIZE(pInfo);
  131. break;
  132. default:
  133. pInfo->result = ER_ILLCOMM; // 非法命令
  134. ASSERT(FALSE); // 调用者的程序设计有问题 :-)
  135. break;
  136. }
  137. // 执行命令成功返回1, 失败返回0
  138. return (pInfo->result==ER_SUCCESS)? 1:0;
  139. }
  140. // 命令解释函数 — 第二层解释函数
  141. //********************************************************************//
  142. // 操作命令解释函数---解释:CMD_IS_SUPPORT命令
  143. // 查询某个命令是否被支持
  144. void _fnCMD_IS_SUPPORT(INFOSTR *pInfo)
  145. {
  146. // 这个函数是为客户程序查询时使用,如果你实现了对某个命令的
  147. // 解释,可修改相应的case中的设置,使其返回ER_SUCCESS,这就
  148. // 表示你的模块已经支持该命令了。同时,现在的这个文件中已包
  149. // 含了对前四个命令的解释,你只需向还未支持的命令函数中添加
  150. // 代码即可。
  151. ASSERT(pInfo->result == ER_EMPTY);
  152. switch(pInfo->annexdata.cmAnnData)  
  153. {
  154. case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
  155. pInfo->result = ER_SUCCESS;
  156. break;
  157. case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
  158. pInfo->result = ER_SUCCESS;
  159. break;
  160. case CMD_GETWRITERMESS: // 获取作者们的留言
  161. pInfo->result = ER_SUCCESS;
  162. break;
  163. case CMD_GETBUILDID: // 获取图像模块内部版本号
  164. pInfo->result = ER_SUCCESS;
  165. break;
  166. case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的PSD文件
  167. pInfo->result = ER_SUCCESS;
  168. break;
  169. case CMD_GET_FILE_INFO: // 获取指定文件的信息
  170. pInfo->result = ER_SUCCESS;
  171. break;
  172. case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
  173. pInfo->result = ER_SUCCESS;
  174. break;
  175. case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
  176. pInfo->result = ER_NOTSUPPORT;
  177. break;
  178. case CMD_IS_SUPPORT: // 查询某个命令是否被支持
  179. pInfo->result = ER_SUCCESS;
  180. break;
  181. case CMD_RESIZE: // 获取指定尺寸的图像(只适用于矢量图像)
  182. pInfo->result = ER_NOTSUPPORT;
  183. break;
  184. default:
  185. pInfo->result = ER_NOTSUPPORT;
  186. break;
  187. }
  188. }
  189. // 操作命令解释函数---解释:CMD_GETPROCTYPE命令
  190. // 获取本模块能处理的图像类型,如:BMP,PCX等等
  191. void _fnCMD_GETPROCTYPE(INFOSTR *pInfo)
  192. {
  193. // 这是预定义的函数代码,你可以不必修改的使用。
  194. // 根据接口定义,此时附加数据应被清空为0,所以下此断言
  195. ASSERT(pInfo->annexdata.scAnnData[0] == 0);
  196. ASSERT(pInfo->result == ER_EMPTY);
  197. // 复制能处理的类型字符串
  198. ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)ModuleProcessImgType, 
  199. sizeof(ModuleProcessImgType));
  200. pInfo->result = ER_SUCCESS;
  201. }
  202. // 操作命令解释函数---解释:CMD_GETWRITER命令
  203. // 获取本模块的作者列表,多人时用逗号分隔
  204. void _fnCMD_GETWRITERS(INFOSTR *pInfo)
  205. {
  206. // 这是预定义的函数代码,你可以不必修改的使用。
  207. // 根据接口定义,此时附加数据应被清空为0,所以下此断言
  208. ASSERT(pInfo->annexdata.scAnnData[0] == 0);
  209. ASSERT(pInfo->result == ER_EMPTY);
  210. // 复制开发者名单串
  211. ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterList, 
  212. sizeof(WriterList));
  213. pInfo->result = ER_SUCCESS;
  214. }
  215. // 操作命令解释函数---解释:CMD_GETWRITERMESS命令
  216. // 获取作者们的留言
  217. void _fnCMD_GETWRITERMESS(INFOSTR *pInfo)
  218. {
  219. // 这是预定义的函数代码,你可以不必修改的使用。
  220. // 根据接口定义,此时附加数据应被清空为0,所以下此断言
  221. ASSERT(pInfo->annexdata.scAnnData[0] == 0);
  222. ASSERT(pInfo->result == ER_EMPTY);
  223. // 复制开发者们的留言字符串
  224. ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterMess, 
  225. sizeof(WriterMess));
  226. pInfo->result = ER_SUCCESS;
  227. }
  228. // 操作命令解释函数---解释:CMD_GETBUILDID命令
  229. // 获取图像模块内部版本号
  230. void _fnCMD_GETBUILDID(INFOSTR *pInfo)
  231. {
  232. // 这是预定义的函数代码,你可以不必修改的使用。
  233. // 根据接口定义,此时annexdata.dwAnnData应被设为0,所以下此断言
  234. ASSERT(pInfo->annexdata.dwAnnData == 0);
  235. ASSERT(pInfo->result == ER_EMPTY);
  236. // 填写内部版本号码
  237. pInfo->annexdata.dwAnnData = MODULE_BUILDID;
  238. pInfo->result = ER_SUCCESS;
  239. }
  240. // 操作命令解释函数---解释:CMD_IS_VALID_FILE命令
  241. // 判断指定文件是否是有效的PSD文件
  242. void _fnCMD_IS_VALID_FILE(INFOSTR *pInfo)
  243. {
  244. CFile file ;
  245. PSDFILEHEADER PsdHeader ;
  246. DWORD dwFileSize ;
  247. UINT uReadSize ;
  248. // 检验入口参数是否符合接口定义
  249. ASSERT(pInfo->result == ER_EMPTY);
  250. ASSERT(pInfo->annexdata.iAnnData == 0);
  251. ASSERT(::strlen(pInfo->filename));
  252. ASSERT(pInfo->state == PKST_NOTVER);
  253. ASSERT(pInfo);
  254. // 设初值
  255. pInfo->result = ER_SUCCESS;
  256. pInfo->annexdata.iAnnData = 0;
  257. // 先判断指定的文件是否存在
  258. if (!IsFileExist(pInfo->filename))
  259. pInfo->result = ER_COMMINFOERR;
  260. else
  261. {
  262. // 打开指定文件
  263. if (!file.Open(pInfo->filename, CFile::modeRead))
  264. {
  265. pInfo->result = ER_FILERWERR; // 打开文件时出错
  266. return;
  267. }
  268. // 获取PSD文件的长度(以字节为单位)
  269. dwFileSize = file.GetLength();
  270. // 用长度判断
  271. if (dwFileSize < sizeof(PSDFILEHEADER) )
  272. {
  273. // 这不是一个PSD文件,PSD文件的长度起码大于文件头
  274. file.Close();
  275. return;
  276. }
  277. // 读取PSD的文件头结构,并检查它们的有效性
  278. file.SeekToBegin();
  279. uReadSize  = file.Read((LPSTR)&PsdHeader, sizeof(PSDFILEHEADER));
  280. if ( uReadSize != sizeof(PSDFILEHEADER) )
  281. {
  282. pInfo->result = ER_FILERWERR; // 读文件时出错
  283. file.Close();
  284. return;
  285. }
  286. // 判断文件头部的PSD文件标志('8BPS')和Version标志(1)
  287. // PSD 的 Version 一定是 1,如果是其他的就错了
  288. if ( (PsdHeader.Signature != PSD_SIGNATURE_MARKER) ||
  289. (PsdHeader.Version != PSD_VERSION_MARKER) )
  290. {
  291. file.Close();
  292. return;
  293. }
  294. ///////////////////////////////////////////////////////////////////////////
  295. //  其实到了这里就可以说基本是PSD的图了。
  296. ///////////////////////////////////////////////////////////////////////////
  297. PsdHeader.Channels = ExchangeWord( PsdHeader.Channels ) ;
  298. PsdHeader.Rows = ExchangeDWord( PsdHeader.Rows ) ;
  299. PsdHeader.Columns = ExchangeDWord( PsdHeader.Columns ) ;
  300. PsdHeader.Depth = ExchangeWord( PsdHeader.Depth ) ;
  301. PsdHeader.Mode = ExchangeWord( PsdHeader.Mode ) ;
  302. // 通道数必须在 1 到 24 之间
  303. // 长宽的范围在 1 到 30000 之间
  304. if( PsdHeader.Channels<1 || PsdHeader.Channels>24 
  305. || PsdHeader.Rows<1 || PsdHeader.Rows>30000 
  306. || PsdHeader.Columns<1 || PsdHeader.Columns>30000 )
  307. {
  308. file.Close() ;
  309. return ;
  310. }
  311. if( IsSupportFormat( PsdHeader.Mode, PsdHeader.Depth ) )
  312. { // 文件的格式不支持(也包括是PSD但不支持的文件)
  313. file.Close() ;
  314. return ;
  315. }
  316. // 到此,大致可以表明该文件是一个有效的PSD文件,iAnnData变量设为1
  317. ///////////////////////////////////////////////////////////////////////////
  318. //  要向下判断也可以,不过比较花时间(还有好多条件)
  319. ///////////////////////////////////////////////////////////////////////////
  320. pInfo->annexdata.iAnnData = 1;
  321. pInfo->state = PKST_PASSVER; // 表示通过校验
  322. file.Close();
  323. }
  324. }
  325. // 操作命令解释函数---解释:CMD_GET_FILE_INFO命令
  326. // 获取指定文件的信息
  327. void _fnCMD_GET_FILE_INFO(INFOSTR *pInfo)
  328. {
  329. CFile file ;
  330. CFileStatus status ;
  331. PSDFILEHEADER PsdHeader ;
  332. DWORD TempData ;
  333. WORD Compression ;
  334. UINT uReadSize ;
  335. // 检验入口参数是否符合接口定义
  336. ASSERT(pInfo->result == ER_EMPTY);
  337. ASSERT(::strlen(pInfo->filename));
  338. // 此时,该文件必需是一个已存在的、并且是有效的BMP文件
  339. ASSERT(pInfo->state == PKST_PASSVER);
  340. // 客户模块必需要先将imginfo清空为0
  341. ASSERT(pInfo->imginfo.imgtype == IMT_NULL);
  342. // 打开指定文件
  343. if (!file.Open(pInfo->filename, CFile::modeRead))
  344. {
  345. pInfo->result = ER_FILERWERR;
  346. return;
  347. }
  348. // 读取PSD的文件头结构
  349. file.SeekToBegin();
  350. uReadSize  = file.Read((LPSTR)&PsdHeader, sizeof(PSDFILEHEADER));
  351. if ( uReadSize != sizeof(PSDFILEHEADER) )
  352. {
  353. pInfo->result = ER_FILERWERR; // 读文件时出错
  354. file.Close();
  355. return;
  356. }
  357. LPIMAGEINFOSTR lpImgInfoStr = &pInfo->imginfo;
  358. // 获取文件的长度、图像的宽度、高度等信息
  359. lpImgInfoStr->imgtype = IMT_RESSTATIC;
  360. lpImgInfoStr->imgformat = IMF_PSD;
  361. lpImgInfoStr->filesize = file.GetLength();
  362. lpImgInfoStr->width = ExchangeDWord(PsdHeader.Columns) ;
  363. // 图像的高度值有时可能是负值,所以使用了abs()函数
  364. lpImgInfoStr->height = (DWORD)::abs( ExchangeDWord(PsdHeader.Rows) ) ;
  365. lpImgInfoStr->bitcount = (DWORD)ExchangeWord(PsdHeader.Depth) ;
  366. ///////////////////////////////////////////////////////////////////////
  367. // Begin Read Compression Type
  368. // 读Color mode data section 的长度
  369. uReadSize = file.Read( &TempData, sizeof(DWORD) ) ;
  370. if( uReadSize != sizeof(DWORD) )
  371. {
  372. pInfo->result = ER_FILERWERR ; // 读文件时出错
  373. return ;
  374. }
  375. // 如果有调色板信息(只有 Indexed color 和 duotone 的图才又信息)
  376. TempData = ExchangeDWord( TempData ) ;
  377. if( TempData )
  378. {
  379. file.Seek( TempData, CFile::current ) ;
  380. }
  381. // 读Image resoureces Length
  382. uReadSize = file.Read( &TempData, sizeof(DWORD) ) ;
  383. if( uReadSize != sizeof(DWORD) )
  384. {
  385. pInfo->result = ER_FILERWERR ; // 读文件时出错
  386. return ;
  387. }
  388. // 跳过 Image resoureces
  389. TempData = ExchangeDWord( TempData ) ;
  390. if( TempData )
  391. {
  392. file.Seek(TempData, CFile::current);
  393. }
  394. // 读Image Layer and mask information section Length
  395. uReadSize = file.Read( &TempData, sizeof(DWORD) ) ;
  396. if( uReadSize != sizeof(DWORD) )
  397. {
  398. pInfo->result = ER_FILERWERR ; // 读文件时出错
  399. return ;
  400. }
  401. // 跳过 Image Layer and mask information section
  402. TempData = ExchangeDWord( TempData ) ;
  403. if( TempData )
  404. {
  405. file.Seek(TempData, CFile::current);
  406. }
  407. // 当图像格式对时分配内存
  408. uReadSize = file.Read( &Compression, sizeof(WORD) ) ;
  409. if( uReadSize != sizeof(WORD) )
  410. {
  411. pInfo->result = ER_FILERWERR ; // 读文件时出错
  412. return ;
  413. }
  414. Compression = ExchangeWord( Compression ) ;
  415. if( Compression )
  416. { // 这里,他虽是 RLE 8位的压缩,但可能有些不一样(与 Tiff的 RLE相同)
  417. lpImgInfoStr->compression = ICS_RLE8 ;
  418. }else
  419. { // 这里也有分 888 的RGB 和只有8位的灰度等
  420. if( PsdHeader.Depth == 1 )
  421. lpImgInfoStr->compression = ICS_RGB; // 简单了一些,做不得准的
  422. else
  423. lpImgInfoStr->compression = ICS_BITFIELDS ; // 分位的
  424. }
  425. // Read Compression Type is End
  426. // 这么长才读了一个压缩类型(对于PSD这种特殊格式的文件是不是可以不要呢?)
  427. ///////////////////////////////////////////////////////////////////////////
  428. // 每一图像行所占的字节数(DWORD对齐,并且只对非压缩位图有效)
  429. lpImgInfoStr->linesize = ExchangeWord(PsdHeader.Depth) * ExchangeDWord(PsdHeader.Columns) ;
  430. lpImgInfoStr->imgnumbers = 1; // PSD文件中只有一个图像
  431. lpImgInfoStr->imgchang = 1; // 表示不能被编辑
  432. // 获取文件最后的修改日期(月在高字节,日在低字节)
  433. file.GetStatus(status);
  434. lpImgInfoStr->year = (WORD)status.m_mtime.GetYear();
  435. lpImgInfoStr->monday = (WORD)status.m_mtime.GetMonth();
  436. lpImgInfoStr->monday <<= 8;
  437. lpImgInfoStr->monday |= (WORD)status.m_mtime.GetDay();
  438. // 获取文件最后的修改时间(字序:最高—0, 2—时,1—分,0—秒)
  439. lpImgInfoStr->time = status.m_mtime.GetHour();
  440. lpImgInfoStr->time <<= 8;
  441. lpImgInfoStr->time |= status.m_mtime.GetMinute();
  442. lpImgInfoStr->time <<= 8;
  443. lpImgInfoStr->time |= status.m_mtime.GetSecond();
  444. lpImgInfoStr->time &= 0xffffff;
  445. file.Close();
  446. // 设置出口数据
  447. pInfo->state = PKST_PASSINFO;
  448. pInfo->result = ER_SUCCESS;
  449. }
  450. // 操作命令解释函数---解释:CMD_LOAD_FROM_FILE命令
  451. // 从指定图像文件中读取数据
  452. void _fnCMD_LOAD_FROM_FILE(INFOSTR *pInfo)
  453. {
  454. // 检验入口参数是否符合接口定义
  455. ASSERT(pInfo->result == ER_EMPTY);
  456. ASSERT(::strlen(pInfo->filename));
  457. // 此时,该文件必需是一个已存在的、有效的PSD文件,并且数据包中
  458. // 含有该文件的信息(imginfo结构中)
  459. ASSERT(pInfo->state == PKST_PASSINFO);
  460. ASSERT(pInfo->imginfo.imgformat == IMF_PSD);
  461. ASSERT(pInfo->pImgInfo == NULL);
  462. // 必需设置标准图像格式信息
  463. ASSERT(pInfo->sDIBInfo.bmi.biSize == sizeof(BITMAPINFOHEADER));
  464. ASSERT(pInfo->pLineAddr != NULL);
  465. ASSERT(pInfo->_pbdata != NULL);
  466. CFile file;
  467. if (pInfo->fpProgress)
  468. {
  469. if ((*pInfo->fpProgress)(RWPROGRESSSIZE, 6))
  470. { // 如果进度函数返回1,则说明用户想中断操作,返回。
  471. pInfo->result = ER_USERBREAK;
  472. return;
  473. }
  474. }
  475. // 打开指定文件
  476. if (!file.Open(pInfo->filename, CFile::modeRead))
  477. {
  478. pInfo->result = ER_FILERWERR;
  479. return;
  480. }
  481. file.Seek(0, CFile::begin);
  482. // 读取并转换图像到数据包中
  483. if (ReadFormPSDFile(file, pInfo) == 0)
  484. {
  485. // 成功
  486. pInfo->state = PKST_INFOANDBITS;
  487. pInfo->modify = 0;
  488. pInfo->result = ER_SUCCESS;
  489. }
  490. file.Close();
  491. if (pInfo->fpProgress) // 结束进度条,此调用不再支持用户中断
  492. (*pInfo->fpProgress)(RWPROGRESSSIZE, RWPROGRESSSIZE);
  493. }
  494. // 操作命令解释函数---解释:CMD_SAVE_TO_FILE命令
  495. // 将数据保存到指定文件中
  496. void _fnCMD_SAVE_TO_FILE(INFOSTR *pInfo)
  497. {
  498. // 这个命令不一定要解释,你可以参考本图像格式的具体境况来决定
  499. // 是否解释该命令。
  500. // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
  501. // ----------------------------------------------------------------->
  502. // Pegasus:
  503. //     1,我认为PSD的格式特殊,即使保存也只能保存成多通道(深度)的单张背景图
  504. //     2,PhotoShop 能识别大部分的图像格式
  505. //     3,除PhotoShop 外PSD 格式的应用很少
  506. //   所以不要保存命令. &_* 我是不是有点懒,"是!!" 不要这样说我嘛!
  507. // ----------------------------------------------------------------->
  508. pInfo->result = ER_NOTSUPPORT;
  509. }
  510. // 操作命令解释函数---解释:CMD_RESIZE命令
  511. // 重新获取指定尺寸的图像位数据(只适用于矢量图像)
  512. void _fnCMD_RESIZE(INFOSTR *pInfo)
  513. {
  514. // 这个命令一般的图像读写模块不需要支持,它只适用于矢量图像,
  515. // 比如WMF、EMF之类。
  516. // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
  517. // ----------------------------------------------------------------->
  518. pInfo->result = ER_NOTSUPPORT;
  519. }
  520. ///////////////////////////////////////////////////////////////////////////////////
  521. //////////////////    以下是 内部处理函数   ///////////////////////////////////////
  522. ///////////////////////////////////////////////////////////////////////////////////
  523. //  对了,我写的函数里的,检察一些空指针之类的错误的代码不多
  524. //
  525. /***********************************************************************************
  526. $                                                                                   $
  527. $    函数: int ReadFormPSDFile( CFile& file, LPINFOSTR pInfo)                      $
  528. $           将指定文件读入目标缓冲区                                                $
  529. $                                                                                   $
  530. $    参数: file        指定文件                                                    $
  531. $           pInfo       图像读写数据包结构指针                                      $
  532. $                                                                                   $
  533. $    返回:int 型                                                                   $
  534. $                 成功读入=0, 读文件时出错=1, 内存不足=2, 文件不支持=3              $
  535. $                                                                                   $
  536. ***********************************************************************************/
  537. int ReadFormPSDFile(CFile& file, LPINFOSTR pInfo)
  538. {
  539. /////////////////////////////////////////////////////////////////////////////////
  540. /// 变量的定义
  541. PSDFILEHEADER PsdHeader ; // PSD 文件信息头
  542. PBYTE pColorMode; // RGB调色板指针
  543. DWORD PaletteSize ; // 调色板大小
  544. PBYTE FileBuffer; // 文件的缓冲区-原始数据
  545. DWORD dwFileSize ; // 文件大小-字节单位
  546. DWORD dwImageSize ; // 图像的像素数
  547. DWORD dwReadData ; // 已读取的数据量
  548. UINT uReadSize ; // 一般变量-用于取得读取数据的大小
  549. DWORD dwTempData ; // 一般变量-用于读取 DWORD大小的数据
  550. unsigned int Compression ; // 数据格式 0-未压缩, 1-8位RLE压缩
  551. // unsigned int Channels ; // 要处理的通道数(不一定等于总的通道数)
  552. unsigned long HeightCount, WidthCount ; // Height, Width 的计数
  553. int ret_val ; // 返回值
  554. /////////////////////////////////////////////////////////////////////////////////
  555. /////////////////////////////////////////////////////////////////////////////////
  556. /// 函数的实现
  557. ret_val = 0 ; // 成功
  558. dwReadData = 0 ; // 累计已读的文件字节数
  559. // 读取PSD的文件头结构
  560. file.SeekToBegin();
  561. uReadSize  = file.Read((LPSTR)&PsdHeader, sizeof(PSDFILEHEADER));
  562. if ( uReadSize != sizeof(PSDFILEHEADER) )
  563. {
  564. pInfo->result = ER_FILERWERR; // 读文件时出错
  565. return 1;
  566. }
  567. dwReadData += uReadSize ;
  568. PsdHeader.Channels = ExchangeWord( PsdHeader.Channels ) ;
  569. PsdHeader.Rows = ExchangeDWord( PsdHeader.Rows ) ;
  570. PsdHeader.Columns = ExchangeDWord( PsdHeader.Columns ) ;
  571. PsdHeader.Depth = ExchangeWord( PsdHeader.Depth ) ;
  572. PsdHeader.Mode = ExchangeWord( PsdHeader.Mode ) ;
  573. // 读Color mode data section 的长度
  574. uReadSize = file.Read( &PaletteSize, sizeof(DWORD) ) ;
  575. PaletteSize = ExchangeDWord( PaletteSize ) ;
  576. if( uReadSize != sizeof(DWORD) )
  577. {
  578. pInfo->result = ER_FILERWERR ; // 读文件时出错
  579. return 1 ;
  580. }
  581. dwReadData += sizeof(DWORD) ;
  582. // 如果有调色板信息(只有 Indexed color 和 duotone 的图才又信息)
  583. if( PaletteSize )
  584. {
  585. pColorMode = (PBYTE)::GlobalAlloc(GPTR, PaletteSize);
  586. if( pColorMode == NULL )
  587. {
  588. pInfo->result = ER_MEMORYERR; // 内存不足
  589. return 2;
  590. }
  591. // 读调色板信息
  592. uReadSize = file.Read((void*)pColorMode, PaletteSize ) ;
  593. if( uReadSize != PaletteSize )
  594. {
  595. ::GlobalFree( pColorMode ) ;
  596. pInfo->result = ER_FILERWERR ; // 读文件时出错
  597. return 1 ;
  598. }
  599. dwReadData += PaletteSize ;
  600. }
  601. // 读Image resoureces Length
  602. uReadSize = file.Read( &dwTempData, sizeof(DWORD) ) ;
  603. dwTempData = ExchangeDWord( dwTempData ) ;
  604. if( uReadSize != sizeof(DWORD) )
  605. {
  606. pInfo->result = ER_FILERWERR ; // 读文件时出错
  607. return 1 ;
  608. }
  609. dwReadData += sizeof(DWORD) ;
  610. // 跳过 Image resoureces
  611. file.Seek(dwTempData, CFile::current);
  612. dwReadData += dwTempData ;
  613. // 读Image Layer and mask information section Length
  614. uReadSize = file.Read( &dwTempData, sizeof(DWORD) ) ;
  615. dwTempData = ExchangeDWord( dwTempData ) ;
  616. if( uReadSize != sizeof(DWORD) )
  617. {
  618. pInfo->result = ER_FILERWERR ; // 读文件时出错
  619. return 1 ;
  620. }
  621. dwReadData += sizeof(DWORD) ;
  622. // 跳过 Image Layer and mask information section
  623. file.Seek(dwTempData, CFile::current);
  624. dwReadData += dwTempData ;
  625. // 读数据的格式(有无压缩)
  626. uReadSize = file.Read( &Compression, sizeof(WORD) ) ;
  627. Compression = ExchangeWord( Compression ) ;
  628. if( uReadSize != sizeof(WORD) )
  629. {
  630. pInfo->result = ER_FILERWERR ; // 读文件时出错
  631. return 1 ;
  632. }
  633. dwReadData += sizeof( WORD ) ;
  634. dwFileSize = file.GetLength() ;
  635. /// 下面是测试 ColorMode ,ColorPixel 的值的正确性 ///
  636. if( IsSupportFormat( PsdHeader.Mode, PsdHeader.Depth ) )
  637. { // 文件的格式不支持
  638. return 3 ;
  639. }
  640. // 当图像格式对时分配内存
  641. FileBuffer = (PBYTE)::GlobalAlloc(GPTR, dwFileSize-dwReadData);
  642. if( FileBuffer == NULL )
  643. {
  644. pInfo->result = ER_MEMORYERR; // 内存不足
  645. return 2;
  646. }
  647. // 读信息
  648. uReadSize = file.Read(FileBuffer, dwFileSize-dwReadData ) ;
  649. if( uReadSize != dwFileSize-dwReadData )
  650. {
  651. ::GlobalFree( FileBuffer ) ;
  652. pInfo->result = ER_FILERWERR ; // 读文件时出错
  653. return 1 ;
  654. }
  655. ///////////////////////////////////////////////////////////////////////////
  656. // 解码
  657. DESFORMAT DesFormat ;
  658. PBYTE pColorR, pColorG, pColorB, pColorK, pR, pG, pB, pK;
  659. PBYTE pImage1, pImage2, pImage3, pImage4 ;
  660. PWORD pwDesPixel ;
  661. PBYTE pbDesPixel ;
  662. PDWORD pdwDesPixel ;
  663. dwImageSize = PsdHeader.Columns * PsdHeader.Rows ;
  664. DesFormat = _get_desformat(pInfo) ;
  665. pColorR = (PBYTE)::GlobalAlloc( GPTR, PsdHeader.Columns * 4 ) ;
  666. pColorG = pColorR + PsdHeader.Columns ;
  667. pColorB = pColorG + PsdHeader.Columns ;
  668. pColorK = pColorB + PsdHeader.Columns ;
  669. if( FileBuffer == NULL )
  670. {
  671. ::GlobalFree( FileBuffer ) ;
  672. pInfo->result = ER_MEMORYERR; // 内存不足
  673. return 2;
  674. }
  675. switch( Compression )
  676. {
  677. case 0: // 无压缩
  678. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  679. //%%%%%%%%%%%%%%%%%%%%%%%%% 无压缩 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  680. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  681. switch( PsdHeader.Depth )
  682. {
  683. case 1: // 位深为 1,只有 Bitmap 图才会
  684. BYTE BColor, Color ;
  685. for( HeightCount=0 ; HeightCount<PsdHeader.Rows ; HeightCount++ )
  686. { // 原来是才一个字节对齐的,我还以为是4字节呢 !  :(-=
  687. pImage1 = FileBuffer + HeightCount*((PsdHeader.Columns+7)/8) ;
  688. //pImage1 = FileBuffer + HeightCount*((PsdHeader.Columns+31)/32)*4 ;
  689. pR = pColorR ; pG = pColorG ; pB = pColorB ;
  690. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  691. {
  692. if( WidthCount%8 == 0 ) BColor = *(pImage1++) ;
  693. Color = (BColor&0x80)?0x00:0xFF ;
  694. *(pR++) = Color ;
  695. *(pG++) = Color ;
  696. *(pB++) = Color ;
  697. BColor <<= 1 ;
  698. } // 每次循环处理一个点
  699. pR = pColorR ; pG = pColorG ; pB = pColorB ;
  700. switch( DesFormat )
  701. {
  702. case DF_16_555:
  703. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  704. //pR = pColorR ; pG = pColorG ; pB = pColorB ;
  705. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  706. *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
  707. break;
  708. case DF_16_565:
  709. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  710. //pR = pColorR ; pG = pColorG ; pB = pColorB ;
  711. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  712. *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
  713. break;
  714. case DF_24:
  715. pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
  716. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  717. {
  718. *(pbDesPixel++) = *(pR++) ;
  719. *(pbDesPixel++) = *(pG++) ;
  720. *(pbDesPixel++) = *(pB++) ;
  721. }
  722. break;
  723. case DF_32:
  724. pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
  725. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  726. *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
  727. break ;
  728. }
  729. } // 每次循环处理一行
  730. break ;
  731. case 8:
  732. for( HeightCount=0 ; HeightCount<PsdHeader.Rows && !ret_val ; HeightCount++ )
  733. {
  734. pImage1 = FileBuffer + HeightCount*PsdHeader.Columns ;
  735. pImage2 = pImage1 + dwImageSize ;
  736. pImage3 = pImage2 + dwImageSize ;
  737. pImage4 = pImage3 + dwImageSize ;
  738. pR = pColorR ; pG = pColorG ; pB = pColorB ;
  739. switch( PsdHeader.Mode )
  740. {
  741. case DUOTONE_Image:
  742. case GRAYSCALE_Image:
  743. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  744. {
  745. *pR = *(pImage1++) ;
  746. *(pG++) = *pR ;
  747. *(pB++) = *pR ;
  748. pR ++ ;
  749. } // 每次循环处理一个点
  750. break ;
  751. case INDEXED_Image:
  752. pImage2 = pColorMode ;
  753. pImage3 = pImage2 + 256 ;
  754. pImage4 = pImage3 + 256 ;
  755. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  756. {
  757. *(pR++) = pImage2[*pImage1] ;
  758. *(pG++) = pImage3[*pImage1] ;
  759. *(pB++) = pImage4[*pImage1] ;
  760. pImage1 ++ ;
  761. } // 每次循环处理一个点
  762. break ;
  763. case RGB_Image:
  764. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  765. {
  766. *(pR++) = *(pImage1++) ;
  767. *(pG++) = *(pImage2++) ;
  768. *(pB++) = *(pImage3++) ;
  769. } // 每次循环处理一个点
  770. break ;
  771. case CMYK_Image:
  772. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  773. {
  774. *(pR++) = *(pImage1++) ; // C
  775. *(pG++) = *(pImage2++) ; // M
  776. *(pB++) = *(pImage3++) ; // Y
  777. pImage4 ++ ; // K
  778. } // 每次循环处理一个点
  779. break ;
  780. case MULTICHANNEL_Image:
  781. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  782. { // 如果大于三个通道,则只算三个通道。
  783. if( PsdHeader.Channels>0 ) *(pR++) = *(pImage1++) ;
  784. else *(pR++) = 0 ;
  785. if( PsdHeader.Channels>2 ) *(pG++) = *(pImage2++) ;
  786. else *(pG++) = 0 ;
  787. if( PsdHeader.Channels>3 ) *(pB++) = *(pImage3++) ;
  788. else *(pB++) = 0 ;
  789. } // 每次循环处理一个点
  790. break ;
  791. case LAB_Image:
  792. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  793. {
  794. *(pR++) = *(pImage1++) ;
  795. *(pG++) = *(pImage2++) ;
  796. *(pB++) = *(pImage3++) ;
  797. } // 每次循环处理一个点
  798. break ;
  799. default:
  800. ret_val = 3 ;
  801. break ;
  802. }
  803. pR = pColorR ; pG = pColorG ; pB = pColorB ;
  804. switch( DesFormat )
  805. {
  806. case DF_16_555:
  807. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  808. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  809. *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
  810. break;
  811. case DF_16_565:
  812. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  813. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  814. *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
  815. break;
  816. case DF_24:
  817. pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
  818. //pR = pColorR ; pG = pColorG ; pB = pColorB ;
  819. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  820. {
  821. *(pbDesPixel++) = *(pR++) ;
  822. *(pbDesPixel++) = *(pG++) ;
  823. *(pbDesPixel++) = *(pB++) ;
  824. }
  825. break;
  826. case DF_32:
  827. pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
  828. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  829. *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
  830. break ;
  831. }
  832. } // 每次循环处理一行
  833. break ;
  834. case 16:
  835. for( HeightCount=0 ; HeightCount<PsdHeader.Rows && !ret_val ; HeightCount++ )
  836. {
  837. pImage1 = FileBuffer + HeightCount*PsdHeader.Columns*2 ;
  838. pImage2 = pImage1 + dwImageSize * 2 ;
  839. pImage3 = pImage2 + dwImageSize * 2 ;
  840. pImage4 = pImage3 + dwImageSize * 2 ;
  841. pR = pColorR ; pG = pColorG ; pB = pColorB ;
  842. switch( PsdHeader.Mode )
  843. {
  844. case GRAYSCALE_Image:
  845. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  846. {
  847. *(pR++) = *pImage1 ;
  848. *(pG++) = *pImage1 ;
  849. *(pB++) = *pImage1 ;
  850. pImage1 += 2 ;
  851. } // 每次循环处理一个点
  852. break ;
  853. case RGB_Image:
  854. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  855. {
  856. *(pR++) = *pImage1 ;
  857. *(pG++) = *pImage2 ;
  858. *(pB++) = *pImage3 ;
  859. pImage1 += 2 ;
  860. pImage2 += 2 ;
  861. pImage3 += 2 ;
  862. } // 每次循环处理一个点
  863. break ;
  864. case CMYK_Image:
  865. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  866. {
  867. *(pR++) = *pImage1 ; // C
  868. *(pG++) = *pImage2 ; // M
  869. *(pB++) = *pImage3 ; // Y
  870. // 我把K分量丢了,不要了,因此图的颜色有些变化
  871. pImage1 += 2 ;
  872. pImage2 += 2 ;
  873. pImage3 += 2 ;
  874. pImage4 += 2 ; // K
  875. } // 每次循环处理一个点
  876. break ;
  877. default:
  878. ret_val = 3 ;
  879. break ;
  880. }
  881. pR = pColorR ; pG = pColorG ; pB = pColorB ;
  882. switch( DesFormat )
  883. {
  884. case DF_16_555:
  885. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  886. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  887. *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
  888. break;
  889. case DF_16_565:
  890. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  891. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  892. *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
  893. break;
  894. case DF_24:
  895. pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
  896. //pR = pColorR ; pG = pColorG ; pB = pColorB ;
  897. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  898. {
  899. *(pbDesPixel++) = *(pR++) ;
  900. *(pbDesPixel++) = *(pG++) ;
  901. *(pbDesPixel++) = *(pB++) ;
  902. }
  903. break;
  904. case DF_32:
  905. pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
  906. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  907. *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
  908. break ;
  909. }
  910. } // 每次循环处理一行
  911. break ;
  912. default:
  913. ret_val = 3 ;
  914. break ;
  915. }
  916. break ;
  917. case 1: // 8位RLE压缩
  918. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  919. //%%%%%%%%%%%%%%%%%%%%%%%%%% 8位RLE压缩 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  920. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  921. if( PsdHeader.Depth == 8 )
  922. {
  923. PWORD pLineR, pLineG, pLineB, pLineK ;
  924. // PBYTE pRB, pGB, pBB, pKB ; // 分别指向各个色的通道的首地址
  925. DWORD Count, wData ;
  926. BYTE Data ;
  927. signed char Flag, Mark ;
  928. pImage1 = FileBuffer + PsdHeader.Rows * PsdHeader.Channels * 2 ;
  929. pLineR = (PWORD)FileBuffer ;
  930. pLineG = pLineR + PsdHeader.Rows ;
  931. pLineB = pLineG + PsdHeader.Rows ;
  932. pLineK = pLineB + PsdHeader.Rows ;
  933. Count = 0 ;
  934. for( ; pLineR<=pLineK ; pLineR ++ )
  935. {
  936. if( pLineR == pLineG ) pImage2 = pImage1 + Count ;
  937. if( pLineR == pLineB ) pImage3 = pImage1 + Count ;
  938. if( pLineR == pLineK ) pImage4 = pImage1 + Count ;
  939. wData = *pLineR ;
  940. Count += ExchangeWord( wData ) ;
  941. }
  942. pLineR = (PWORD)FileBuffer ;
  943. //////////////////////////////// 初始化完成 ////////////////////////
  944. for( HeightCount=0 ; HeightCount<PsdHeader.Rows && !ret_val ; HeightCount++ )
  945. {
  946. pR = pColorR ; pG = pColorG ; pB = pColorB ; pK = pColorK ;
  947. switch( PsdHeader.Mode )
  948. {
  949. case DUOTONE_Image:
  950. case GRAYSCALE_Image:
  951. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  952. {
  953. if( Flag<0 )
  954. {
  955. Flag = *(pImage1++) ;
  956. if( Flag<0 )
  957. {
  958. if( Flag == -128 ) break ;
  959. Flag = - Flag ;
  960. Data = *(pImage1++) ;
  961. Mark = 0 ;
  962. }else
  963. {
  964. Mark = 1 ;
  965. }
  966. }
  967. if( Flag>= 0 )
  968. {
  969. if( Mark ) *pR = *(pImage1++) ;
  970. else *pR = Data ;
  971. Flag -- ;
  972. }
  973. *(pG++) = *pR ;
  974. *(pB++) = *pR ;
  975. pR ++ ;
  976. } // 每次循环处理一个点
  977. break ;
  978. case INDEXED_Image:
  979. pImage2 = pColorMode ;
  980. pImage3 = pImage2 + 256 ;
  981. pImage4 = pImage3 + 256 ;
  982. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  983. {
  984. if( Flag<0 )
  985. {
  986. Flag = *(pImage1++) ;
  987. if( Flag<0 )
  988. {
  989. if( Flag == -128 ) break ;
  990. Flag = - Flag ;
  991. Data = *(pImage1++) ;
  992. Mark = 0 ;
  993. }else
  994. {
  995. Mark = 1 ;
  996. }
  997. }
  998. if( Flag>= 0 )
  999. {
  1000. if( Mark ) Data = *(pImage1++) ;
  1001. Flag -- ;
  1002. }
  1003. *(pR++) = pImage2[ Data ] ;
  1004. *(pG++) = pImage3[ Data ] ;
  1005. *(pB++) = pImage4[ Data ] ;
  1006. } // 每次循环处理一个点
  1007. break ;
  1008. case RGB_Image:
  1009. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1010. {
  1011. if( Flag<0 )
  1012. {
  1013. Flag = *(pImage1++) ;
  1014. if( Flag<0 )
  1015. {
  1016. if( Flag == -128 ) break ;
  1017. Flag = - Flag ;
  1018. Data = *(pImage1++) ;
  1019. Mark = 0 ;
  1020. }else
  1021. {
  1022. Mark = 1 ;
  1023. }
  1024. }
  1025. if( Flag>= 0 )
  1026. {
  1027. if( Mark ) *(pR++) = *(pImage1++) ;
  1028. else *(pR++) = Data ;
  1029. Flag -- ;
  1030. }
  1031. } // 每次循环处理一个点
  1032. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1033. {
  1034. if( Flag<0 )
  1035. {
  1036. Flag = *(pImage2++) ;
  1037. if( Flag<0 )
  1038. {
  1039. if( Flag == -128 ) break ;
  1040. Flag = - Flag ;
  1041. Data = *(pImage2++) ;
  1042. Mark = 0 ;
  1043. }else
  1044. {
  1045. Mark = 1 ;
  1046. }
  1047. }
  1048. if( Flag>= 0 )
  1049. {
  1050. if( Mark ) *(pG++) = *(pImage2++) ;
  1051. else *(pG++) = Data ;
  1052. Flag -- ;
  1053. }
  1054. } // 每次循环处理一个点
  1055. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1056. {
  1057. if( Flag<0 )
  1058. {
  1059. Flag = *(pImage3++) ;
  1060. if( Flag<0 )
  1061. {
  1062. if( Flag == -128 ) break ;
  1063. Flag = - Flag ;
  1064. Data = *(pImage3++) ;
  1065. Mark = 0 ;
  1066. }else
  1067. {
  1068. Mark = 1 ;
  1069. }
  1070. }
  1071. if( Flag>= 0 )
  1072. {
  1073. if( Mark ) *(pB++) = *(pImage3++) ;
  1074. else *(pB++) = Data ;
  1075. Flag -- ;
  1076. }
  1077. } // 每次循环处理一个点
  1078. break ;
  1079. case CMYK_Image:
  1080. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1081. {
  1082. if( Flag<0 )
  1083. {
  1084. Flag = *(pImage1++) ;
  1085. if( Flag<0 )
  1086. {
  1087. if( Flag == -128 ) break ;
  1088. Flag = - Flag ;
  1089. Data = *(pImage1++) ;
  1090. Mark = 0 ;
  1091. }else
  1092. {
  1093. Mark = 1 ;
  1094. }
  1095. }
  1096. if( Flag>= 0 )
  1097. {
  1098. if( Mark ) *(pR++) = *(pImage1++) ;
  1099. else *(pR++) = Data ;
  1100. Flag -- ;
  1101. }
  1102. } // 每次循环处理一个点
  1103. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1104. {
  1105. if( Flag<0 )
  1106. {
  1107. Flag = *(pImage2++) ;
  1108. if( Flag<0 )
  1109. {
  1110. if( Flag == -128 ) break ;
  1111. Flag = - Flag ;
  1112. Data = *(pImage2++) ;
  1113. Mark = 0 ;
  1114. }else
  1115. {
  1116. Mark = 1 ;
  1117. }
  1118. }
  1119. if( Flag>= 0 )
  1120. {
  1121. if( Mark ) *(pG++) = *(pImage2++) ;
  1122. else *(pG++) = Data ;
  1123. Flag -- ;
  1124. }
  1125. } // 每次循环处理一个点
  1126. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1127. {
  1128. if( Flag<0 )
  1129. {
  1130. Flag = *(pImage3++) ;
  1131. if( Flag<0 )
  1132. {
  1133. if( Flag == -128 ) break ;
  1134. Flag = - Flag ;
  1135. Data = *(pImage3++) ;
  1136. Mark = 0 ;
  1137. }else
  1138. {
  1139. Mark = 1 ;
  1140. }
  1141. }
  1142. if( Flag>= 0 )
  1143. {
  1144. if( Mark ) *(pB++) = *(pImage3++) ;
  1145. else *(pB++) = Data ;
  1146. Flag -- ;
  1147. }
  1148. } // 每次循环处理一个点
  1149. break ;
  1150. case MULTICHANNEL_Image:
  1151. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1152. {
  1153. if( Flag<0 )
  1154. {
  1155. Flag = *(pImage1++) ;
  1156. if( Flag<0 )
  1157. {
  1158. if( Flag == -128 ) break ;
  1159. Flag = - Flag ;
  1160. Data = *(pImage1++) ;
  1161. Mark = 0 ;
  1162. }else
  1163. {
  1164. Mark = 1 ;
  1165. }
  1166. }
  1167. if( Flag>= 0 )
  1168. {
  1169. if( Mark ) *(pR++) = *(pImage1++) ;
  1170. else *(pR++) = Data ;
  1171. Flag -- ;
  1172. }
  1173. } // 每次循环处理一个点
  1174. if( PsdHeader.Channels > 1 )
  1175. {
  1176. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1177. {
  1178. if( Flag<0 )
  1179. {
  1180. Flag = *(pImage2++) ;
  1181. if( Flag<0 )
  1182. {
  1183. if( Flag == -128 ) break ;
  1184. Flag = - Flag ;
  1185. Data = *(pImage2++) ;
  1186. Mark = 0 ;
  1187. }else
  1188. {
  1189. Mark = 1 ;
  1190. }
  1191. }
  1192. if( Flag>= 0 )
  1193. {
  1194. if( Mark ) *(pG++) = *(pImage2++) ;
  1195. else *(pG++) = Data ;
  1196. Flag -- ;
  1197. }
  1198. } // 每次循环处理一个点
  1199. }else
  1200. {
  1201. pR = pColorR ;
  1202. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1203. {
  1204. *(pG++) = *(pR++) ;
  1205. } // 每次循环处理一个点
  1206. }
  1207. if( PsdHeader.Channels > 2 )
  1208. {
  1209. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1210. {
  1211. if( Flag<0 )
  1212. {
  1213. Flag = *(pImage3++) ;
  1214. if( Flag<0 )
  1215. {
  1216. if( Flag == -128 ) break ;
  1217. Flag = - Flag ;
  1218. Data = *(pImage3++) ;
  1219. Mark = 0 ;
  1220. }else
  1221. {
  1222. Mark = 1 ;
  1223. }
  1224. }
  1225. if( Flag>= 0 )
  1226. {
  1227. if( Mark ) *(pB++) = *(pImage3++) ;
  1228. else *(pB++) = Data ;
  1229. Flag -- ;
  1230. }
  1231. } // 每次循环处理一个点
  1232. }else
  1233. {
  1234. pR = pColorR ;
  1235. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1236. {
  1237. *(pB++) = *(pR++) ;
  1238. } // 每次循环处理一个点
  1239. }
  1240. break ;
  1241. case LAB_Image:
  1242. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1243. {
  1244. if( Flag<0 )
  1245. {
  1246. Flag = *(pImage1++) ;
  1247. if( Flag<0 )
  1248. {
  1249. if( Flag == -128 ) break ;
  1250. Flag = - Flag ;
  1251. Data = *(pImage1++) ;
  1252. Mark = 0 ;
  1253. }else
  1254. {
  1255. Mark = 1 ;
  1256. }
  1257. }
  1258. if( Flag>= 0 )
  1259. {
  1260. // if( Mark ) *(pR++) = *(pImage1++) ;
  1261. // else *(pR++) = Data ;
  1262. // Flag -- ;
  1263. if( Mark ) *pR = *(pImage1++) ;
  1264. else *pR = Data ;
  1265. Flag -- ;
  1266. *(pG++) = *pR ; // 现在只是把Lab显示成灰度
  1267. *(pB++) = *pR ;
  1268. pR ++ ;
  1269. }
  1270. } // 每次循环处理一个点
  1271. /*
  1272. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1273. {
  1274. if( Flag<0 )
  1275. {
  1276. Flag = *(pImage2++) ;
  1277. if( Flag<0 )
  1278. {
  1279. if( Flag == -128 ) break ;
  1280. Flag = - Flag ;
  1281. Data = *(pImage2++) ;
  1282. Mark = 0 ;
  1283. }else
  1284. {
  1285. Mark = 1 ;
  1286. }
  1287. }
  1288. if( Flag>= 0 )
  1289. {
  1290. if( Mark ) *(pG++) = *(pImage2++) ;
  1291. else *(pG++) = Data ;
  1292. Flag -- ;
  1293. }
  1294. } // 每次循环处理一个点
  1295. for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1296. {
  1297. if( Flag<0 )
  1298. {
  1299. Flag = *(pImage3++) ;
  1300. if( Flag<0 )
  1301. {
  1302. if( Flag == -128 ) break ;
  1303. Flag = - Flag ;
  1304. Data = *(pImage3++) ;
  1305. Mark = 0 ;
  1306. }else
  1307. {
  1308. Mark = 1 ;
  1309. }
  1310. }
  1311. if( Flag>= 0 )
  1312. {
  1313. if( Mark ) *(pB++) = *(pImage3++) ;
  1314. else *(pB++) = Data ;
  1315. Flag -- ;
  1316. }
  1317. } // 每次循环处理一个点
  1318. */ break ;
  1319. default:
  1320. ret_val = 3 ;
  1321. break ;
  1322. }
  1323. pR = pColorR ; pG = pColorG ; pB = pColorB ; pK = pColorK ;
  1324. switch( DesFormat )
  1325. {
  1326. case DF_16_555:
  1327. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  1328. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1329. *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
  1330. break;
  1331. case DF_16_565:
  1332. pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
  1333. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1334. *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
  1335. break;
  1336. case DF_24:
  1337. pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
  1338. //pR = pColorR ; pG = pColorG ; pB = pColorB ;
  1339. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1340. {
  1341. *(pbDesPixel++) = *(pR++) ;
  1342. *(pbDesPixel++) = *(pG++) ;
  1343. *(pbDesPixel++) = *(pB++) ;
  1344. }
  1345. break;
  1346. case DF_32:
  1347. pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
  1348. for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
  1349. *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
  1350. break ;
  1351. }
  1352. } // 每次循环处理一行
  1353. }
  1354. else
  1355. {
  1356. ret_val = 3 ;
  1357. }
  1358. break ;
  1359. default:
  1360. ret_val = 1 ; // 认为是文件出错
  1361. break ;
  1362. }
  1363. ::GlobalFree( pColorR ) ; // 图像行数据
  1364. ///////////////////////////////////////////////////////////////////////////
  1365. // 解码完成,(不管是否成功)释放内存(文件缓冲区和色盘)
  1366. ::GlobalFree( FileBuffer ) ; // 文件缓冲区
  1367. FileBuffer=NULL;
  1368. if( pColorMode ) // 色盘
  1369. {
  1370. ::GlobalFree( pColorMode ) ;
  1371. pColorMode = NULL ;
  1372. }
  1373. /************************************************
  1374. pImageData = (PBYTE)::GlobalAlloc(GPTR, pInfo->imginfo.width*pInfo->imginfo.height*3 );
  1375. if( pImageData == NULL )
  1376. {
  1377. pInfo->result = ER_MEMORYERR; // 内存不足
  1378. ::GlobalFree( FileBuffer ) ;
  1379. return 2;
  1380. }
  1381. // 解码
  1382. if( DecodePSDImageToBuffer( FileBuffer, pColorMode, pImageData, pInfo, &PsdHeader ) )
  1383. { // 文件的格式不支持 或 数据有错 或 都是我的错
  1384. return 3 ;
  1385. }
  1386. // 解码完成,释放内存(文件缓冲区和色盘)
  1387. ::GlobalFree( FileBuffer ) ; // 文件缓冲区
  1388. FileBuffer=NULL;
  1389. if( pColorMode ) // 色盘
  1390. {
  1391. ::GlobalFree( pColorMode ) ;
  1392. pColorMode = NULL ;
  1393. }
  1394. if( FormatImageToStandard( pImageData, pInfo) )
  1395. {
  1396. ::GlobalFree( pImageData ) ;
  1397. return 1 ;
  1398. }
  1399. ::GlobalFree( pImageData ) ;
  1400. ********************************************************/
  1401. return 0 ;
  1402. }
  1403. /***********************************************************************************
  1404. $                                                                                   $
  1405. $    函数:int IsSupportFormat( WORD ColorMode, WORD ColorPixel ) ;                 $
  1406. $          检查颜色模式和色深是否被支持                                             $
  1407. $                                                                                   $
  1408. $    参数:ColorMode   颜色的模式                                                   $
  1409. $                 Bitmap=0, Grayscale=1, Indexed=2, RGB=3,                          $
  1410. $                 CMYK=4, Multichannel=7, Duotone=8, Lab=9                          $
  1411. $          ColorPixel  颜色的位深                                                   $
  1412. $                 PSD 格式只有 1, 8, 16                                             $
  1413. $                                                                                   $
  1414. $    返回:int 型                                                                   $
  1415. $                 成功支持=0, 颜色模式不支持=1, 位深不支持=2                        $
  1416. $                                                                                   $
  1417. ***********************************************************************************/
  1418. int IsSupportFormat( WORD ColorMode, WORD ColorPixel )
  1419. {
  1420. /// 下面是测试 ColorMode ,ColorPixel 的值的正确性 ///
  1421. switch( ColorMode )
  1422. {
  1423. case 0: // Bitmap
  1424. if( ColorPixel == 1) break ;
  1425. return 2 ;
  1426. case 1: // Grayscale
  1427. if( ColorPixel == 8 || ColorPixel == 16 ) break ;
  1428. return 2 ;
  1429. case 2: // Indexed
  1430. if( ColorPixel == 8 ) break ;
  1431. return 2;
  1432. case 3: // RGB ( Only 8 or 16 byte )
  1433. if( ColorPixel == 8 || ColorPixel ==16 ) break ;
  1434. return 2 ;
  1435. case 4: // CMYK
  1436. if( ColorPixel == 8 || ColorPixel ==16 ) break ;
  1437. return 2 ;
  1438. case 7: // Multichannel
  1439. if( ColorPixel == 8 ) break ;
  1440. return 2 ;
  1441. case 8: // Duotone //按灰度的方法读取
  1442. if( ColorPixel == 8 ) break ;
  1443. return 2 ;
  1444. case 9: // Lab
  1445. if( ColorPixel == 8 ) break ;
  1446. return 2 ;
  1447. default: // Unknow -> Error
  1448. return 1 ;
  1449. }
  1450. return 0 ;
  1451. }