PsdModule.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:47k
- /*----------------------------------------------------------------------------------*
- $ $
- => 000000 000000 00000000 PSD File Format Read Program $
- => 00 00 00 00 00 这是自由软件 ISee 图像浏览器的一部分 $
- => 00 00 00 00 00 这个模块实现了 PSD 格式的读取 $
- => 000000 000000 00 00 这个模块的当前版本是 1.5 $
- => 00 00 00 00 这个模块的当前作者是 Pegasus $
- => 00 00 00 00 这个模块的主架构来自于 YZ 的 BMP 模块 $
- => 00 000000 00000000 这个模块的部分函数也来自于 YZ $
- $ $
- *---------------------------------------------------------------------2000-10-27---*/
- //
- //=> 这是你二个版本,不第一个版本节省了一些内存,但程序也增加了一些,模块化少了,请见谅
- //
- // 测试日志
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\
- ////////////// 当前模块还没有实现 CMYK 和 Lab 颜色格式的真正读取
- ///////////// 我用于测试的所有图像都是来自于 Photoshop V5.0.2
- //////////// 用于测试的图像有大小 216*297 和 20*100 的 以及 Photoshop 5.0.2 自带的图像
- /////////// 目前支持的图像有:
- ////////// RGB色,8位,RLE压缩与无压缩; RGB色,16位,无压缩;
- ///////// 灰度,8位,RLE压缩与无压缩; 灰度,16位,无压缩;
- //////// 单色,1位,按位存储;
- /////// Duotone, 8位,RLE压缩与无压缩; // 相近读取(灰度)
- ////// CMYK色,8位,RLE压缩与无压缩; CMYK色,16位,无压缩; // 相近读取(丢掉黑色)
- ///// Lab色,8位,RLE压缩与无压缩; // 相近读取(灰度)
- //// Multichannel(多通道),按8位RGB来读,当图的通道数少于3时,颜色会发生大的变化
- /// ACDSee处理通道数少于3的图像的方法是-显示全黑色,可我让他显示变色的图
- // 当前我对CMYK的处理是丢去黑色,这样会使颜色发生变化,ACDSee也会但他变得少
- // 当前我对Lab的处理也是丢去a与b的分量,这样使图像成了灰度的图
- // 此程序还有多处可以优化!!! ^_^
- //
- // eMail : Pegasusgod@163.net
- //
- // PsdModule.cpp : Defines the initialization routines for the DLL.
- #include "stdafx.h"
- #include "PsdModule.h"
- #include "FormYZ.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- static char ModuleProcessImgType[]="PSD"; // 本模块能处理的图像类型
- static char WriterList[]="Pegasus"; // 本模块的作者列表
- static char WriterMess[]="请不要写作者留言!! ^_^"; // 作者留言
- //
- // Note!
- //
- // If this DLL is dynamically linked against the MFC
- // DLLs, any functions exported from this DLL which
- // call into MFC must have the AFX_MANAGE_STATE macro
- // added at the very beginning of the function.
- //
- // For example:
- //
- // extern "C" BOOL PASCAL EXPORT ExportedFunction()
- // {
- // AFX_MANAGE_STATE(AfxGetStaticModuleState());
- // // normal function body here
- // }
- //
- // It is very important that this macro appear in each
- // function, prior to any calls into MFC. This means that
- // it must appear as the first statement within the
- // function, even before any object variable declarations
- // as their constructors may generate calls into the MFC
- // DLL.
- //
- // Please see MFC Technical Notes 33 and 58 for additional
- // details.
- //
- // 在图像读写模块中,如果想分配内存,请使用API函数GlobalAlloc()
- // ,如果想释放内存请使用GlobalFree()函数。不要使用诸如:new
- // 、malloc()等函数。这是为了使各模块之间可以异地释放内存。
- //
- //
- /////////////////////////////////////////////////////////////////////////////
- // CPsdModuleApp
- BEGIN_MESSAGE_MAP(CPsdModuleApp, CWinApp)
- //{{AFX_MSG_MAP(CPsdModuleApp)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CPsdModuleApp construction
- CPsdModuleApp::CPsdModuleApp()
- {
- // TODO: add construction code here,
- // Place all significant initialization in InitInstance
- }
- /////////////////////////////////////////////////////////////////////////////
- // The one and only CPsdModuleApp object
- CPsdModuleApp theApp;
- // 接口函数声明 — 第一层,唯一与外界联系的接口
- int WINAPI AccessPSDModule(INFOSTR *pInfo)
- {
- // 这个函数可以不作修改的使用,除非你的返回值多于两种。
- switch(pInfo->comm)
- {
- case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
- _fnCMD_GETPROCTYPE(pInfo);
- break;
- case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
- _fnCMD_GETWRITERS(pInfo);
- break;
- case CMD_GETWRITERMESS: // 获取作者们的留言
- _fnCMD_GETWRITERMESS(pInfo);
- break;
- case CMD_GETBUILDID: // 获取图像模块内部版本号
- _fnCMD_GETBUILDID(pInfo);
- break;
- case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的WMF文件
- _fnCMD_IS_VALID_FILE(pInfo);
- break;
- case CMD_GET_FILE_INFO: // 获取指定文件的信息
- _fnCMD_GET_FILE_INFO(pInfo);
- break;
- case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
- _fnCMD_LOAD_FROM_FILE(pInfo);
- break;
- case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
- _fnCMD_SAVE_TO_FILE(pInfo);
- break;
- case CMD_IS_SUPPORT: // 查询某个命令是否被支持
- _fnCMD_IS_SUPPORT(pInfo);
- break;
- case CMD_RESIZE: // 从新获取指定尺寸的图像位数据(只适用于矢量图像)
- _fnCMD_RESIZE(pInfo);
- break;
- default:
- pInfo->result = ER_ILLCOMM; // 非法命令
- ASSERT(FALSE); // 调用者的程序设计有问题 :-)
- break;
- }
- // 执行命令成功返回1, 失败返回0
- return (pInfo->result==ER_SUCCESS)? 1:0;
- }
- // 命令解释函数 — 第二层解释函数
- //********************************************************************//
- // 操作命令解释函数---解释:CMD_IS_SUPPORT命令
- // 查询某个命令是否被支持
- void _fnCMD_IS_SUPPORT(INFOSTR *pInfo)
- {
- // 这个函数是为客户程序查询时使用,如果你实现了对某个命令的
- // 解释,可修改相应的case中的设置,使其返回ER_SUCCESS,这就
- // 表示你的模块已经支持该命令了。同时,现在的这个文件中已包
- // 含了对前四个命令的解释,你只需向还未支持的命令函数中添加
- // 代码即可。
- ASSERT(pInfo->result == ER_EMPTY);
- switch(pInfo->annexdata.cmAnnData)
- {
- case CMD_GETPROCTYPE: // 获取本模块能处理的图像类型
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GETWRITERS: // 获取本模块的作者列表,多人时用逗号分隔
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GETWRITERMESS: // 获取作者们的留言
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GETBUILDID: // 获取图像模块内部版本号
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_IS_VALID_FILE: // 判断指定文件是否是有效的PSD文件
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_GET_FILE_INFO: // 获取指定文件的信息
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_LOAD_FROM_FILE: // 从指定图像文件中读取数据
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_SAVE_TO_FILE: // 将数据保存到指定文件中
- pInfo->result = ER_NOTSUPPORT;
- break;
- case CMD_IS_SUPPORT: // 查询某个命令是否被支持
- pInfo->result = ER_SUCCESS;
- break;
- case CMD_RESIZE: // 获取指定尺寸的图像(只适用于矢量图像)
- pInfo->result = ER_NOTSUPPORT;
- break;
- default:
- pInfo->result = ER_NOTSUPPORT;
- break;
- }
- }
- // 操作命令解释函数---解释:CMD_GETPROCTYPE命令
- // 获取本模块能处理的图像类型,如:BMP,PCX等等
- void _fnCMD_GETPROCTYPE(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时附加数据应被清空为0,所以下此断言
- ASSERT(pInfo->annexdata.scAnnData[0] == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 复制能处理的类型字符串
- ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)ModuleProcessImgType,
- sizeof(ModuleProcessImgType));
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_GETWRITER命令
- // 获取本模块的作者列表,多人时用逗号分隔
- void _fnCMD_GETWRITERS(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时附加数据应被清空为0,所以下此断言
- ASSERT(pInfo->annexdata.scAnnData[0] == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 复制开发者名单串
- ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterList,
- sizeof(WriterList));
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_GETWRITERMESS命令
- // 获取作者们的留言
- void _fnCMD_GETWRITERMESS(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时附加数据应被清空为0,所以下此断言
- ASSERT(pInfo->annexdata.scAnnData[0] == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 复制开发者们的留言字符串
- ::CopyMemory((PVOID)pInfo->annexdata.scAnnData, (PVOID)WriterMess,
- sizeof(WriterMess));
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_GETBUILDID命令
- // 获取图像模块内部版本号
- void _fnCMD_GETBUILDID(INFOSTR *pInfo)
- {
- // 这是预定义的函数代码,你可以不必修改的使用。
- // 根据接口定义,此时annexdata.dwAnnData应被设为0,所以下此断言
- ASSERT(pInfo->annexdata.dwAnnData == 0);
- ASSERT(pInfo->result == ER_EMPTY);
- // 填写内部版本号码
- pInfo->annexdata.dwAnnData = MODULE_BUILDID;
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_IS_VALID_FILE命令
- // 判断指定文件是否是有效的PSD文件
- void _fnCMD_IS_VALID_FILE(INFOSTR *pInfo)
- {
- CFile file ;
- PSDFILEHEADER PsdHeader ;
- DWORD dwFileSize ;
- UINT uReadSize ;
- // 检验入口参数是否符合接口定义
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(pInfo->annexdata.iAnnData == 0);
- ASSERT(::strlen(pInfo->filename));
- ASSERT(pInfo->state == PKST_NOTVER);
- ASSERT(pInfo);
- // 设初值
- pInfo->result = ER_SUCCESS;
- pInfo->annexdata.iAnnData = 0;
- // 先判断指定的文件是否存在
- if (!IsFileExist(pInfo->filename))
- pInfo->result = ER_COMMINFOERR;
- else
- {
- // 打开指定文件
- if (!file.Open(pInfo->filename, CFile::modeRead))
- {
- pInfo->result = ER_FILERWERR; // 打开文件时出错
- return;
- }
- // 获取PSD文件的长度(以字节为单位)
- dwFileSize = file.GetLength();
- // 用长度判断
- if (dwFileSize < sizeof(PSDFILEHEADER) )
- {
- // 这不是一个PSD文件,PSD文件的长度起码大于文件头
- file.Close();
- return;
- }
- // 读取PSD的文件头结构,并检查它们的有效性
- file.SeekToBegin();
- uReadSize = file.Read((LPSTR)&PsdHeader, sizeof(PSDFILEHEADER));
- if ( uReadSize != sizeof(PSDFILEHEADER) )
- {
- pInfo->result = ER_FILERWERR; // 读文件时出错
- file.Close();
- return;
- }
- // 判断文件头部的PSD文件标志('8BPS')和Version标志(1)
- // PSD 的 Version 一定是 1,如果是其他的就错了
- if ( (PsdHeader.Signature != PSD_SIGNATURE_MARKER) ||
- (PsdHeader.Version != PSD_VERSION_MARKER) )
- {
- file.Close();
- return;
- }
- ///////////////////////////////////////////////////////////////////////////
- // 其实到了这里就可以说基本是PSD的图了。
- ///////////////////////////////////////////////////////////////////////////
- PsdHeader.Channels = ExchangeWord( PsdHeader.Channels ) ;
- PsdHeader.Rows = ExchangeDWord( PsdHeader.Rows ) ;
- PsdHeader.Columns = ExchangeDWord( PsdHeader.Columns ) ;
- PsdHeader.Depth = ExchangeWord( PsdHeader.Depth ) ;
- PsdHeader.Mode = ExchangeWord( PsdHeader.Mode ) ;
- // 通道数必须在 1 到 24 之间
- // 长宽的范围在 1 到 30000 之间
- if( PsdHeader.Channels<1 || PsdHeader.Channels>24
- || PsdHeader.Rows<1 || PsdHeader.Rows>30000
- || PsdHeader.Columns<1 || PsdHeader.Columns>30000 )
- {
- file.Close() ;
- return ;
- }
- if( IsSupportFormat( PsdHeader.Mode, PsdHeader.Depth ) )
- { // 文件的格式不支持(也包括是PSD但不支持的文件)
- file.Close() ;
- return ;
- }
- // 到此,大致可以表明该文件是一个有效的PSD文件,iAnnData变量设为1
- ///////////////////////////////////////////////////////////////////////////
- // 要向下判断也可以,不过比较花时间(还有好多条件)
- ///////////////////////////////////////////////////////////////////////////
- pInfo->annexdata.iAnnData = 1;
- pInfo->state = PKST_PASSVER; // 表示通过校验
- file.Close();
- }
- }
- // 操作命令解释函数---解释:CMD_GET_FILE_INFO命令
- // 获取指定文件的信息
- void _fnCMD_GET_FILE_INFO(INFOSTR *pInfo)
- {
- CFile file ;
- CFileStatus status ;
- PSDFILEHEADER PsdHeader ;
- DWORD TempData ;
- WORD Compression ;
- UINT uReadSize ;
- // 检验入口参数是否符合接口定义
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(::strlen(pInfo->filename));
- // 此时,该文件必需是一个已存在的、并且是有效的BMP文件
- ASSERT(pInfo->state == PKST_PASSVER);
- // 客户模块必需要先将imginfo清空为0
- ASSERT(pInfo->imginfo.imgtype == IMT_NULL);
- // 打开指定文件
- if (!file.Open(pInfo->filename, CFile::modeRead))
- {
- pInfo->result = ER_FILERWERR;
- return;
- }
- // 读取PSD的文件头结构
- file.SeekToBegin();
- uReadSize = file.Read((LPSTR)&PsdHeader, sizeof(PSDFILEHEADER));
- if ( uReadSize != sizeof(PSDFILEHEADER) )
- {
- pInfo->result = ER_FILERWERR; // 读文件时出错
- file.Close();
- return;
- }
- LPIMAGEINFOSTR lpImgInfoStr = &pInfo->imginfo;
- // 获取文件的长度、图像的宽度、高度等信息
- lpImgInfoStr->imgtype = IMT_RESSTATIC;
- lpImgInfoStr->imgformat = IMF_PSD;
- lpImgInfoStr->filesize = file.GetLength();
- lpImgInfoStr->width = ExchangeDWord(PsdHeader.Columns) ;
- // 图像的高度值有时可能是负值,所以使用了abs()函数
- lpImgInfoStr->height = (DWORD)::abs( ExchangeDWord(PsdHeader.Rows) ) ;
- lpImgInfoStr->bitcount = (DWORD)ExchangeWord(PsdHeader.Depth) ;
- ///////////////////////////////////////////////////////////////////////
- // Begin Read Compression Type
- // 读Color mode data section 的长度
- uReadSize = file.Read( &TempData, sizeof(DWORD) ) ;
- if( uReadSize != sizeof(DWORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return ;
- }
- // 如果有调色板信息(只有 Indexed color 和 duotone 的图才又信息)
- TempData = ExchangeDWord( TempData ) ;
- if( TempData )
- {
- file.Seek( TempData, CFile::current ) ;
- }
- // 读Image resoureces Length
- uReadSize = file.Read( &TempData, sizeof(DWORD) ) ;
- if( uReadSize != sizeof(DWORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return ;
- }
- // 跳过 Image resoureces
- TempData = ExchangeDWord( TempData ) ;
- if( TempData )
- {
- file.Seek(TempData, CFile::current);
- }
- // 读Image Layer and mask information section Length
- uReadSize = file.Read( &TempData, sizeof(DWORD) ) ;
- if( uReadSize != sizeof(DWORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return ;
- }
- // 跳过 Image Layer and mask information section
- TempData = ExchangeDWord( TempData ) ;
- if( TempData )
- {
- file.Seek(TempData, CFile::current);
- }
- // 当图像格式对时分配内存
- uReadSize = file.Read( &Compression, sizeof(WORD) ) ;
- if( uReadSize != sizeof(WORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return ;
- }
- Compression = ExchangeWord( Compression ) ;
- if( Compression )
- { // 这里,他虽是 RLE 8位的压缩,但可能有些不一样(与 Tiff的 RLE相同)
- lpImgInfoStr->compression = ICS_RLE8 ;
- }else
- { // 这里也有分 888 的RGB 和只有8位的灰度等
- if( PsdHeader.Depth == 1 )
- lpImgInfoStr->compression = ICS_RGB; // 简单了一些,做不得准的
- else
- lpImgInfoStr->compression = ICS_BITFIELDS ; // 分位的
- }
- // Read Compression Type is End
- // 这么长才读了一个压缩类型(对于PSD这种特殊格式的文件是不是可以不要呢?)
- ///////////////////////////////////////////////////////////////////////////
- // 每一图像行所占的字节数(DWORD对齐,并且只对非压缩位图有效)
- lpImgInfoStr->linesize = ExchangeWord(PsdHeader.Depth) * ExchangeDWord(PsdHeader.Columns) ;
- lpImgInfoStr->imgnumbers = 1; // PSD文件中只有一个图像
- lpImgInfoStr->imgchang = 1; // 表示不能被编辑
- // 获取文件最后的修改日期(月在高字节,日在低字节)
- file.GetStatus(status);
- lpImgInfoStr->year = (WORD)status.m_mtime.GetYear();
- lpImgInfoStr->monday = (WORD)status.m_mtime.GetMonth();
- lpImgInfoStr->monday <<= 8;
- lpImgInfoStr->monday |= (WORD)status.m_mtime.GetDay();
- // 获取文件最后的修改时间(字序:最高—0, 2—时,1—分,0—秒)
- lpImgInfoStr->time = status.m_mtime.GetHour();
- lpImgInfoStr->time <<= 8;
- lpImgInfoStr->time |= status.m_mtime.GetMinute();
- lpImgInfoStr->time <<= 8;
- lpImgInfoStr->time |= status.m_mtime.GetSecond();
- lpImgInfoStr->time &= 0xffffff;
- file.Close();
- // 设置出口数据
- pInfo->state = PKST_PASSINFO;
- pInfo->result = ER_SUCCESS;
- }
- // 操作命令解释函数---解释:CMD_LOAD_FROM_FILE命令
- // 从指定图像文件中读取数据
- void _fnCMD_LOAD_FROM_FILE(INFOSTR *pInfo)
- {
- // 检验入口参数是否符合接口定义
- ASSERT(pInfo->result == ER_EMPTY);
- ASSERT(::strlen(pInfo->filename));
- // 此时,该文件必需是一个已存在的、有效的PSD文件,并且数据包中
- // 含有该文件的信息(imginfo结构中)
- ASSERT(pInfo->state == PKST_PASSINFO);
- ASSERT(pInfo->imginfo.imgformat == IMF_PSD);
- ASSERT(pInfo->pImgInfo == NULL);
- // 必需设置标准图像格式信息
- ASSERT(pInfo->sDIBInfo.bmi.biSize == sizeof(BITMAPINFOHEADER));
- ASSERT(pInfo->pLineAddr != NULL);
- ASSERT(pInfo->_pbdata != NULL);
- CFile file;
- if (pInfo->fpProgress)
- {
- if ((*pInfo->fpProgress)(RWPROGRESSSIZE, 6))
- { // 如果进度函数返回1,则说明用户想中断操作,返回。
- pInfo->result = ER_USERBREAK;
- return;
- }
- }
- // 打开指定文件
- if (!file.Open(pInfo->filename, CFile::modeRead))
- {
- pInfo->result = ER_FILERWERR;
- return;
- }
- file.Seek(0, CFile::begin);
- // 读取并转换图像到数据包中
- if (ReadFormPSDFile(file, pInfo) == 0)
- {
- // 成功
- pInfo->state = PKST_INFOANDBITS;
- pInfo->modify = 0;
- pInfo->result = ER_SUCCESS;
- }
-
- file.Close();
- if (pInfo->fpProgress) // 结束进度条,此调用不再支持用户中断
- (*pInfo->fpProgress)(RWPROGRESSSIZE, RWPROGRESSSIZE);
- }
- // 操作命令解释函数---解释:CMD_SAVE_TO_FILE命令
- // 将数据保存到指定文件中
- void _fnCMD_SAVE_TO_FILE(INFOSTR *pInfo)
- {
- // 这个命令不一定要解释,你可以参考本图像格式的具体境况来决定
- // 是否解释该命令。
- // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
- // ----------------------------------------------------------------->
- // Pegasus:
- // 1,我认为PSD的格式特殊,即使保存也只能保存成多通道(深度)的单张背景图
- // 2,PhotoShop 能识别大部分的图像格式
- // 3,除PhotoShop 外PSD 格式的应用很少
- // 所以不要保存命令. &_* 我是不是有点懒,"是!!" 不要这样说我嘛!
- // ----------------------------------------------------------------->
- pInfo->result = ER_NOTSUPPORT;
- }
- // 操作命令解释函数---解释:CMD_RESIZE命令
- // 重新获取指定尺寸的图像位数据(只适用于矢量图像)
- void _fnCMD_RESIZE(INFOSTR *pInfo)
- {
- // 这个命令一般的图像读写模块不需要支持,它只适用于矢量图像,
- // 比如WMF、EMF之类。
- // 如果你想解释该命令,请在下面加入代码,并修改pInfo->result的返回值:
- // ----------------------------------------------------------------->
- pInfo->result = ER_NOTSUPPORT;
- }
- ///////////////////////////////////////////////////////////////////////////////////
- ////////////////// 以下是 内部处理函数 ///////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////
- // 对了,我写的函数里的,检察一些空指针之类的错误的代码不多
- //
- /***********************************************************************************
- $ $
- $ 函数: int ReadFormPSDFile( CFile& file, LPINFOSTR pInfo) $
- $ 将指定文件读入目标缓冲区 $
- $ $
- $ 参数: file 指定文件 $
- $ pInfo 图像读写数据包结构指针 $
- $ $
- $ 返回:int 型 $
- $ 成功读入=0, 读文件时出错=1, 内存不足=2, 文件不支持=3 $
- $ $
- ***********************************************************************************/
- int ReadFormPSDFile(CFile& file, LPINFOSTR pInfo)
- {
- /////////////////////////////////////////////////////////////////////////////////
- /// 变量的定义
- PSDFILEHEADER PsdHeader ; // PSD 文件信息头
- PBYTE pColorMode; // RGB调色板指针
- DWORD PaletteSize ; // 调色板大小
- PBYTE FileBuffer; // 文件的缓冲区-原始数据
- DWORD dwFileSize ; // 文件大小-字节单位
- DWORD dwImageSize ; // 图像的像素数
- DWORD dwReadData ; // 已读取的数据量
- UINT uReadSize ; // 一般变量-用于取得读取数据的大小
- DWORD dwTempData ; // 一般变量-用于读取 DWORD大小的数据
- unsigned int Compression ; // 数据格式 0-未压缩, 1-8位RLE压缩
- // unsigned int Channels ; // 要处理的通道数(不一定等于总的通道数)
- unsigned long HeightCount, WidthCount ; // Height, Width 的计数
- int ret_val ; // 返回值
- /////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////
- /// 函数的实现
- ret_val = 0 ; // 成功
- dwReadData = 0 ; // 累计已读的文件字节数
- // 读取PSD的文件头结构
- file.SeekToBegin();
- uReadSize = file.Read((LPSTR)&PsdHeader, sizeof(PSDFILEHEADER));
- if ( uReadSize != sizeof(PSDFILEHEADER) )
- {
- pInfo->result = ER_FILERWERR; // 读文件时出错
- return 1;
- }
- dwReadData += uReadSize ;
- PsdHeader.Channels = ExchangeWord( PsdHeader.Channels ) ;
- PsdHeader.Rows = ExchangeDWord( PsdHeader.Rows ) ;
- PsdHeader.Columns = ExchangeDWord( PsdHeader.Columns ) ;
- PsdHeader.Depth = ExchangeWord( PsdHeader.Depth ) ;
- PsdHeader.Mode = ExchangeWord( PsdHeader.Mode ) ;
- // 读Color mode data section 的长度
- uReadSize = file.Read( &PaletteSize, sizeof(DWORD) ) ;
- PaletteSize = ExchangeDWord( PaletteSize ) ;
- if( uReadSize != sizeof(DWORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return 1 ;
- }
- dwReadData += sizeof(DWORD) ;
- // 如果有调色板信息(只有 Indexed color 和 duotone 的图才又信息)
- if( PaletteSize )
- {
- pColorMode = (PBYTE)::GlobalAlloc(GPTR, PaletteSize);
- if( pColorMode == NULL )
- {
- pInfo->result = ER_MEMORYERR; // 内存不足
- return 2;
- }
- // 读调色板信息
- uReadSize = file.Read((void*)pColorMode, PaletteSize ) ;
- if( uReadSize != PaletteSize )
- {
- ::GlobalFree( pColorMode ) ;
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return 1 ;
- }
- dwReadData += PaletteSize ;
- }
- // 读Image resoureces Length
- uReadSize = file.Read( &dwTempData, sizeof(DWORD) ) ;
- dwTempData = ExchangeDWord( dwTempData ) ;
- if( uReadSize != sizeof(DWORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return 1 ;
- }
- dwReadData += sizeof(DWORD) ;
- // 跳过 Image resoureces
- file.Seek(dwTempData, CFile::current);
- dwReadData += dwTempData ;
- // 读Image Layer and mask information section Length
- uReadSize = file.Read( &dwTempData, sizeof(DWORD) ) ;
- dwTempData = ExchangeDWord( dwTempData ) ;
- if( uReadSize != sizeof(DWORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return 1 ;
- }
- dwReadData += sizeof(DWORD) ;
- // 跳过 Image Layer and mask information section
- file.Seek(dwTempData, CFile::current);
- dwReadData += dwTempData ;
- // 读数据的格式(有无压缩)
- uReadSize = file.Read( &Compression, sizeof(WORD) ) ;
- Compression = ExchangeWord( Compression ) ;
- if( uReadSize != sizeof(WORD) )
- {
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return 1 ;
- }
- dwReadData += sizeof( WORD ) ;
- dwFileSize = file.GetLength() ;
- /// 下面是测试 ColorMode ,ColorPixel 的值的正确性 ///
- if( IsSupportFormat( PsdHeader.Mode, PsdHeader.Depth ) )
- { // 文件的格式不支持
- return 3 ;
- }
- // 当图像格式对时分配内存
- FileBuffer = (PBYTE)::GlobalAlloc(GPTR, dwFileSize-dwReadData);
- if( FileBuffer == NULL )
- {
- pInfo->result = ER_MEMORYERR; // 内存不足
- return 2;
- }
- // 读信息
- uReadSize = file.Read(FileBuffer, dwFileSize-dwReadData ) ;
- if( uReadSize != dwFileSize-dwReadData )
- {
- ::GlobalFree( FileBuffer ) ;
- pInfo->result = ER_FILERWERR ; // 读文件时出错
- return 1 ;
- }
- ///////////////////////////////////////////////////////////////////////////
- // 解码
- DESFORMAT DesFormat ;
- PBYTE pColorR, pColorG, pColorB, pColorK, pR, pG, pB, pK;
- PBYTE pImage1, pImage2, pImage3, pImage4 ;
- PWORD pwDesPixel ;
- PBYTE pbDesPixel ;
- PDWORD pdwDesPixel ;
- dwImageSize = PsdHeader.Columns * PsdHeader.Rows ;
- DesFormat = _get_desformat(pInfo) ;
- pColorR = (PBYTE)::GlobalAlloc( GPTR, PsdHeader.Columns * 4 ) ;
- pColorG = pColorR + PsdHeader.Columns ;
- pColorB = pColorG + PsdHeader.Columns ;
- pColorK = pColorB + PsdHeader.Columns ;
- if( FileBuffer == NULL )
- {
- ::GlobalFree( FileBuffer ) ;
- pInfo->result = ER_MEMORYERR; // 内存不足
- return 2;
- }
- switch( Compression )
- {
- case 0: // 无压缩
- //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- //%%%%%%%%%%%%%%%%%%%%%%%%% 无压缩 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- switch( PsdHeader.Depth )
- {
- case 1: // 位深为 1,只有 Bitmap 图才会
- BYTE BColor, Color ;
- for( HeightCount=0 ; HeightCount<PsdHeader.Rows ; HeightCount++ )
- { // 原来是才一个字节对齐的,我还以为是4字节呢 ! :(-=
- pImage1 = FileBuffer + HeightCount*((PsdHeader.Columns+7)/8) ;
- //pImage1 = FileBuffer + HeightCount*((PsdHeader.Columns+31)/32)*4 ;
- pR = pColorR ; pG = pColorG ; pB = pColorB ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( WidthCount%8 == 0 ) BColor = *(pImage1++) ;
- Color = (BColor&0x80)?0x00:0xFF ;
- *(pR++) = Color ;
- *(pG++) = Color ;
- *(pB++) = Color ;
- BColor <<= 1 ;
- } // 每次循环处理一个点
- pR = pColorR ; pG = pColorG ; pB = pColorB ;
- switch( DesFormat )
- {
- case DF_16_555:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- //pR = pColorR ; pG = pColorG ; pB = pColorB ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_16_565:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- //pR = pColorR ; pG = pColorG ; pB = pColorB ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_24:
- pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pbDesPixel++) = *(pR++) ;
- *(pbDesPixel++) = *(pG++) ;
- *(pbDesPixel++) = *(pB++) ;
- }
- break;
- case DF_32:
- pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
- break ;
- }
- } // 每次循环处理一行
- break ;
- case 8:
- for( HeightCount=0 ; HeightCount<PsdHeader.Rows && !ret_val ; HeightCount++ )
- {
- pImage1 = FileBuffer + HeightCount*PsdHeader.Columns ;
- pImage2 = pImage1 + dwImageSize ;
- pImage3 = pImage2 + dwImageSize ;
- pImage4 = pImage3 + dwImageSize ;
- pR = pColorR ; pG = pColorG ; pB = pColorB ;
- switch( PsdHeader.Mode )
- {
- case DUOTONE_Image:
- case GRAYSCALE_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *pR = *(pImage1++) ;
- *(pG++) = *pR ;
- *(pB++) = *pR ;
- pR ++ ;
- } // 每次循环处理一个点
- break ;
- case INDEXED_Image:
- pImage2 = pColorMode ;
- pImage3 = pImage2 + 256 ;
- pImage4 = pImage3 + 256 ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = pImage2[*pImage1] ;
- *(pG++) = pImage3[*pImage1] ;
- *(pB++) = pImage4[*pImage1] ;
- pImage1 ++ ;
- } // 每次循环处理一个点
- break ;
- case RGB_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = *(pImage1++) ;
- *(pG++) = *(pImage2++) ;
- *(pB++) = *(pImage3++) ;
- } // 每次循环处理一个点
- break ;
- case CMYK_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = *(pImage1++) ; // C
- *(pG++) = *(pImage2++) ; // M
- *(pB++) = *(pImage3++) ; // Y
- pImage4 ++ ; // K
- } // 每次循环处理一个点
- break ;
- case MULTICHANNEL_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- { // 如果大于三个通道,则只算三个通道。
- if( PsdHeader.Channels>0 ) *(pR++) = *(pImage1++) ;
- else *(pR++) = 0 ;
- if( PsdHeader.Channels>2 ) *(pG++) = *(pImage2++) ;
- else *(pG++) = 0 ;
- if( PsdHeader.Channels>3 ) *(pB++) = *(pImage3++) ;
- else *(pB++) = 0 ;
- } // 每次循环处理一个点
- break ;
- case LAB_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = *(pImage1++) ;
- *(pG++) = *(pImage2++) ;
- *(pB++) = *(pImage3++) ;
- } // 每次循环处理一个点
- break ;
- default:
- ret_val = 3 ;
- break ;
- }
- pR = pColorR ; pG = pColorG ; pB = pColorB ;
- switch( DesFormat )
- {
- case DF_16_555:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_16_565:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_24:
- pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
- //pR = pColorR ; pG = pColorG ; pB = pColorB ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pbDesPixel++) = *(pR++) ;
- *(pbDesPixel++) = *(pG++) ;
- *(pbDesPixel++) = *(pB++) ;
- }
- break;
- case DF_32:
- pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
- break ;
- }
- } // 每次循环处理一行
- break ;
- case 16:
- for( HeightCount=0 ; HeightCount<PsdHeader.Rows && !ret_val ; HeightCount++ )
- {
- pImage1 = FileBuffer + HeightCount*PsdHeader.Columns*2 ;
- pImage2 = pImage1 + dwImageSize * 2 ;
- pImage3 = pImage2 + dwImageSize * 2 ;
- pImage4 = pImage3 + dwImageSize * 2 ;
- pR = pColorR ; pG = pColorG ; pB = pColorB ;
- switch( PsdHeader.Mode )
- {
- case GRAYSCALE_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = *pImage1 ;
- *(pG++) = *pImage1 ;
- *(pB++) = *pImage1 ;
- pImage1 += 2 ;
- } // 每次循环处理一个点
- break ;
- case RGB_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = *pImage1 ;
- *(pG++) = *pImage2 ;
- *(pB++) = *pImage3 ;
- pImage1 += 2 ;
- pImage2 += 2 ;
- pImage3 += 2 ;
- } // 每次循环处理一个点
- break ;
- case CMYK_Image:
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pR++) = *pImage1 ; // C
- *(pG++) = *pImage2 ; // M
- *(pB++) = *pImage3 ; // Y
- // 我把K分量丢了,不要了,因此图的颜色有些变化
- pImage1 += 2 ;
- pImage2 += 2 ;
- pImage3 += 2 ;
- pImage4 += 2 ; // K
- } // 每次循环处理一个点
- break ;
- default:
- ret_val = 3 ;
- break ;
- }
- pR = pColorR ; pG = pColorG ; pB = pColorB ;
- switch( DesFormat )
- {
- case DF_16_555:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_16_565:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_24:
- pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
- //pR = pColorR ; pG = pColorG ; pB = pColorB ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pbDesPixel++) = *(pR++) ;
- *(pbDesPixel++) = *(pG++) ;
- *(pbDesPixel++) = *(pB++) ;
- }
- break;
- case DF_32:
- pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
- break ;
- }
- } // 每次循环处理一行
- break ;
- default:
- ret_val = 3 ;
- break ;
- }
- break ;
- case 1: // 8位RLE压缩
- //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- //%%%%%%%%%%%%%%%%%%%%%%%%%% 8位RLE压缩 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- if( PsdHeader.Depth == 8 )
- {
- PWORD pLineR, pLineG, pLineB, pLineK ;
- // PBYTE pRB, pGB, pBB, pKB ; // 分别指向各个色的通道的首地址
- DWORD Count, wData ;
- BYTE Data ;
- signed char Flag, Mark ;
- pImage1 = FileBuffer + PsdHeader.Rows * PsdHeader.Channels * 2 ;
- pLineR = (PWORD)FileBuffer ;
- pLineG = pLineR + PsdHeader.Rows ;
- pLineB = pLineG + PsdHeader.Rows ;
- pLineK = pLineB + PsdHeader.Rows ;
- Count = 0 ;
- for( ; pLineR<=pLineK ; pLineR ++ )
- {
- if( pLineR == pLineG ) pImage2 = pImage1 + Count ;
- if( pLineR == pLineB ) pImage3 = pImage1 + Count ;
- if( pLineR == pLineK ) pImage4 = pImage1 + Count ;
- wData = *pLineR ;
- Count += ExchangeWord( wData ) ;
- }
- pLineR = (PWORD)FileBuffer ;
- //////////////////////////////// 初始化完成 ////////////////////////
- for( HeightCount=0 ; HeightCount<PsdHeader.Rows && !ret_val ; HeightCount++ )
- {
-
- pR = pColorR ; pG = pColorG ; pB = pColorB ; pK = pColorK ;
- switch( PsdHeader.Mode )
- {
- case DUOTONE_Image:
- case GRAYSCALE_Image:
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage1++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage1++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *pR = *(pImage1++) ;
- else *pR = Data ;
- Flag -- ;
- }
- *(pG++) = *pR ;
- *(pB++) = *pR ;
- pR ++ ;
- } // 每次循环处理一个点
- break ;
- case INDEXED_Image:
- pImage2 = pColorMode ;
- pImage3 = pImage2 + 256 ;
- pImage4 = pImage3 + 256 ;
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage1++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage1++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) Data = *(pImage1++) ;
- Flag -- ;
- }
- *(pR++) = pImage2[ Data ] ;
- *(pG++) = pImage3[ Data ] ;
- *(pB++) = pImage4[ Data ] ;
- } // 每次循环处理一个点
- break ;
- case RGB_Image:
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage1++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage1++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pR++) = *(pImage1++) ;
- else *(pR++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage2++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage2++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pG++) = *(pImage2++) ;
- else *(pG++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage3++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage3++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pB++) = *(pImage3++) ;
- else *(pB++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- break ;
- case CMYK_Image:
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage1++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage1++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pR++) = *(pImage1++) ;
- else *(pR++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage2++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage2++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pG++) = *(pImage2++) ;
- else *(pG++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage3++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage3++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pB++) = *(pImage3++) ;
- else *(pB++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- break ;
- case MULTICHANNEL_Image:
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage1++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage1++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pR++) = *(pImage1++) ;
- else *(pR++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- if( PsdHeader.Channels > 1 )
- {
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage2++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage2++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pG++) = *(pImage2++) ;
- else *(pG++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- }else
- {
- pR = pColorR ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pG++) = *(pR++) ;
- } // 每次循环处理一个点
- }
- if( PsdHeader.Channels > 2 )
- {
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage3++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage3++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pB++) = *(pImage3++) ;
- else *(pB++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- }else
- {
- pR = pColorR ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pB++) = *(pR++) ;
- } // 每次循环处理一个点
- }
- break ;
- case LAB_Image:
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage1++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage1++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- // if( Mark ) *(pR++) = *(pImage1++) ;
- // else *(pR++) = Data ;
- // Flag -- ;
- if( Mark ) *pR = *(pImage1++) ;
- else *pR = Data ;
- Flag -- ;
- *(pG++) = *pR ; // 现在只是把Lab显示成灰度
- *(pB++) = *pR ;
- pR ++ ;
- }
- } // 每次循环处理一个点
- /*
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage2++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage2++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pG++) = *(pImage2++) ;
- else *(pG++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- for( WidthCount=0,Flag=-1 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- if( Flag<0 )
- {
- Flag = *(pImage3++) ;
- if( Flag<0 )
- {
- if( Flag == -128 ) break ;
- Flag = - Flag ;
- Data = *(pImage3++) ;
- Mark = 0 ;
- }else
- {
- Mark = 1 ;
- }
- }
- if( Flag>= 0 )
- {
- if( Mark ) *(pB++) = *(pImage3++) ;
- else *(pB++) = Data ;
- Flag -- ;
- }
- } // 每次循环处理一个点
- */ break ;
- default:
- ret_val = 3 ;
- break ;
- }
- pR = pColorR ; pG = pColorG ; pB = pColorB ; pK = pColorK ;
- switch( DesFormat )
- {
- case DF_16_555:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_555( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_16_565:
- pwDesPixel = (WORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pwDesPixel++) = _cnv_rgb_to_565( *(pR++), *(pG++), *(pB++) ) ;
- break;
- case DF_24:
- pbDesPixel = (BYTE*)pInfo->pLineAddr[ HeightCount ] ;
- //pR = pColorR ; pG = pColorG ; pB = pColorB ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- {
- *(pbDesPixel++) = *(pR++) ;
- *(pbDesPixel++) = *(pG++) ;
- *(pbDesPixel++) = *(pB++) ;
- }
- break;
- case DF_32:
- pdwDesPixel = (DWORD*)pInfo->pLineAddr[ HeightCount ] ;
- for( WidthCount=0 ; WidthCount<PsdHeader.Columns ; WidthCount ++ )
- *(pdwDesPixel++) = _cnv_rgb_to_888( *(pR++), *(pG++), *(pB++) ) ;
- break ;
- }
- } // 每次循环处理一行
- }
- else
- {
- ret_val = 3 ;
- }
- break ;
- default:
- ret_val = 1 ; // 认为是文件出错
- break ;
- }
- ::GlobalFree( pColorR ) ; // 图像行数据
- ///////////////////////////////////////////////////////////////////////////
- // 解码完成,(不管是否成功)释放内存(文件缓冲区和色盘)
- ::GlobalFree( FileBuffer ) ; // 文件缓冲区
- FileBuffer=NULL;
- if( pColorMode ) // 色盘
- {
- ::GlobalFree( pColorMode ) ;
- pColorMode = NULL ;
- }
- /************************************************
- pImageData = (PBYTE)::GlobalAlloc(GPTR, pInfo->imginfo.width*pInfo->imginfo.height*3 );
- if( pImageData == NULL )
- {
- pInfo->result = ER_MEMORYERR; // 内存不足
- ::GlobalFree( FileBuffer ) ;
- return 2;
- }
- // 解码
- if( DecodePSDImageToBuffer( FileBuffer, pColorMode, pImageData, pInfo, &PsdHeader ) )
- { // 文件的格式不支持 或 数据有错 或 都是我的错
- return 3 ;
- }
- // 解码完成,释放内存(文件缓冲区和色盘)
- ::GlobalFree( FileBuffer ) ; // 文件缓冲区
- FileBuffer=NULL;
- if( pColorMode ) // 色盘
- {
- ::GlobalFree( pColorMode ) ;
- pColorMode = NULL ;
- }
- if( FormatImageToStandard( pImageData, pInfo) )
- {
- ::GlobalFree( pImageData ) ;
- return 1 ;
- }
- ::GlobalFree( pImageData ) ;
- ********************************************************/
- return 0 ;
- }
- /***********************************************************************************
- $ $
- $ 函数:int IsSupportFormat( WORD ColorMode, WORD ColorPixel ) ; $
- $ 检查颜色模式和色深是否被支持 $
- $ $
- $ 参数:ColorMode 颜色的模式 $
- $ Bitmap=0, Grayscale=1, Indexed=2, RGB=3, $
- $ CMYK=4, Multichannel=7, Duotone=8, Lab=9 $
- $ ColorPixel 颜色的位深 $
- $ PSD 格式只有 1, 8, 16 $
- $ $
- $ 返回:int 型 $
- $ 成功支持=0, 颜色模式不支持=1, 位深不支持=2 $
- $ $
- ***********************************************************************************/
- int IsSupportFormat( WORD ColorMode, WORD ColorPixel )
- {
- /// 下面是测试 ColorMode ,ColorPixel 的值的正确性 ///
- switch( ColorMode )
- {
- case 0: // Bitmap
- if( ColorPixel == 1) break ;
- return 2 ;
- case 1: // Grayscale
- if( ColorPixel == 8 || ColorPixel == 16 ) break ;
- return 2 ;
- case 2: // Indexed
- if( ColorPixel == 8 ) break ;
- return 2;
- case 3: // RGB ( Only 8 or 16 byte )
- if( ColorPixel == 8 || ColorPixel ==16 ) break ;
- return 2 ;
- case 4: // CMYK
- if( ColorPixel == 8 || ColorPixel ==16 ) break ;
- return 2 ;
- case 7: // Multichannel
- if( ColorPixel == 8 ) break ;
- return 2 ;
- case 8: // Duotone //按灰度的方法读取
- if( ColorPixel == 8 ) break ;
- return 2 ;
- case 9: // Lab
- if( ColorPixel == 8 ) break ;
- return 2 ;
- default: // Unknow -> Error
- return 1 ;
- }
- return 0 ;
- }