C++ Sample for TLPSDLD.DLL
///////// sample.cpp version 104 ////////////////////////////////////////////////////
// May 11 2003
// Fab 26 2005
// Mar 13 2005
// Aug 23 2005
// By Tail
#include <iostream>
#include <vector>
#include <fstream>
#include "tlpsd.h"
using namespace std;
TLPSDLOAD_GETVERSION TlPsdLoad_GetVersion;
TLDSDLOAD_OPEN TlPsdLoad_Open;
TLDSDLOAD_CLOSE TlPsdLoad_Close = NULL;
TLDSDLOAD_GETLAYERCOUNT TlPsdLoad_GetLayerCount;
TLDSDLOAD_GETIMAGEINFO TlPsdLoad_GetImageInfo;
TLDSDLOAD_GETIMAGE TlPsdLoad_GetImage;
TLDSDLOAD_UNDERSCAN TlPsdLoad_UnderScan;
TLDSDLOAD_MINIMIZE TlPsdLoad_Minimize;
struct LAYER_IMAGE_ARRAY
{
TLPSD_IMAGE_INFO info;
vector<RGBQUAD> image;
};
class CTestException
{
public:
CTestException(int err){m_err = err;};
int m_err;
};
int Width(const RECT &rc) {return rc.right - rc.left;};
int Height(const RECT &rc) {return rc.bottom - rc.top;};
void InitialLoadDll();
void InitialSaveDll();
void FreeDll();
void LoadAndSaveImage(LPCSTR lpszFileName, LPCSTR lpszPath);
bool GetMargedImage(vector<RGBQUAD>& image, TLPSD_IMAGE_INFO& info);
bool GetILayerImage(int index, LAYER_IMAGE_ARRAY& layer, RECT rcFrame);
void SaveBitmap (LPCSTR lpszFileName, const LPVOID lpData, const RECT& rc);
void SaveCkissCel(LPCSTR lpszFileName, const LPVOID lpData, const RECT& rc);
HINSTANCE g_hLoadPsd = NULL;
HINSTANCE g_hSavePsd = NULL;
vector<RGBQUAD> g_merge_image;
TLPSD_IMAGE_INFO g_marge_info;
vector<LAYER_IMAGE_ARRAY> g_layer;
// ===================================================================================
// INPUT
// xxx.exe c:\temp\sample.psd c:\temp\
// ===================================================================================
int main(int argc, char *argv[])
{
int result = 0;
// Check parameters
cout << endl;
if(argc < 3){
cout << "Bad parameters" << endl;
cout << "\t < executable file > < input filename >, < output path >" << endl;
cout << "\t i.e., xxx.exe c:\\temp\\sample.psd c:\\temp\\ " << endl;
cout << "\t input filename : path to a loading psd file " << endl;
cout << "\t output path : path to a directory for saving fies " << endl;
cout << "Press Return Key" << endl;
cin.get();
return 1;
}
cout << argv[1] << endl;
cout << argv[2] << endl;
try
{
cout << "--- Loading psd file ---" << endl;
InitialLoadDll();
cout << "Load Dll Version " << TlPsdLoad_GetVersion() << endl;
LoadAndSaveImage(argv[1], argv[2]);
}
catch(const CTestException e)
{
result = e.m_err;
cout << "Error: " << e.m_err << endl;
if(TlPsdLoad_Close)
TlPsdLoad_Close();
}
FreeDll();
cout << "Press Return Key" << endl;
cin.get();
return result;
}
// ===================================================================================
void InitialLoadDll()
{
if(!(g_hLoadPsd = ::LoadLibrary("tlpsdload.dll"))
|| !(TlPsdLoad_GetVersion = (TLPSDLOAD_GETVERSION) GetProcAddress(g_hLoadPsd, "TlPsdLoad_GetVersion"))
|| !(TlPsdLoad_Open = (TLDSDLOAD_OPEN) GetProcAddress(g_hLoadPsd, "TlPsdLoad_Open"))
|| !(TlPsdLoad_Close = (TLDSDLOAD_CLOSE) GetProcAddress(g_hLoadPsd, "TlPsdLoad_Close"))
|| !(TlPsdLoad_GetLayerCount = (TLDSDLOAD_GETLAYERCOUNT)GetProcAddress(g_hLoadPsd, "TlPsdLoad_GetLayerCount"))
|| !(TlPsdLoad_GetImageInfo = (TLDSDLOAD_GETIMAGEINFO) GetProcAddress(g_hLoadPsd, "TlPsdLoad_GetImageInfo"))
|| !(TlPsdLoad_GetImage = (TLDSDLOAD_GETIMAGE) GetProcAddress(g_hLoadPsd, "TlPsdLoad_GetImage"))
|| !(TlPsdLoad_UnderScan = (TLDSDLOAD_UNDERSCAN) GetProcAddress(g_hLoadPsd, "TlPsdLoad_UnderScan"))
|| !(TlPsdLoad_Minimize = (TLDSDLOAD_MINIMIZE) GetProcAddress(g_hLoadPsd, "TlPsdLoad_Minimize")))
{
cout << "Error: InitialLoadDll()" << endl;
throw CTestException(2);
}
}
// ===================================================================================
void FreeDll()
{
if(g_hLoadPsd)
::FreeLibrary(g_hLoadPsd);
if(g_hSavePsd)
::FreeLibrary(g_hSavePsd);
}
// ===================================================================================
void LoadAndSaveImage(LPCSTR lpszFileName, LPCSTR lpszPath)
{
int nErr;
char szFileName[MAX_PATH];
//===== Loading =====
// Open, read and analyze the psd file.
// The file must be 8-bit deph and RGB mode.
if((nErr = TlPsdLoad_Open(lpszFileName, 2000, NULL))){
cout << "Error: File "<< lpszFileName << " not open " << endl;
throw CTestException(nErr);
}
//===== Loading a merged image =====
g_marge_info.nIndex = -1;
if(!GetMargedImage(g_merge_image, g_marge_info))
cout << "Can not get the merged image. " << endl;
//----- Saving the merged image as a bitmap file. -----
sprintf(szFileName, "%smerge.bmp", lpszPath);
SaveBitmap(szFileName, &g_merge_image.at(0), g_marge_info.rcImage);
//===== Loading layers =====
int nSavedCount = 0;
const int nCount = TlPsdLoad_GetLayerCount();
if(nCount)
g_layer.resize(nCount);
for(int j = 0; j < nCount; ++j){
if(GetILayerImage(j, g_layer.at(j), g_marge_info.rcImage)){
//----- Saving the layers as bitmap and CKiSS format files. -----
sprintf(szFileName, "%slayer%02d.bmp", lpszPath, g_layer.at(j).info.nIndex);
SaveBitmap(szFileName, &g_layer.at(j). image.at(0), g_layer.at(j).info.rcImage);
sprintf(szFileName, "%slayer%02d.cel", lpszPath, g_layer.at(j).info.nIndex);
SaveCkissCel(szFileName, &g_layer.at(j).image.at(0), g_layer.at(j).info.rcImage);
++nSavedCount;
}
}
// Loading results
cout << "The number of loaded layers of " << nCount << endl;
cout << "The number of saved layers of " << nSavedCount << endl;
TlPsdLoad_Close();
cout << "--- End loading ---" << endl;
}
// ===================================================================================
bool GetMargedImage(vector<RGBQUAD>& image, TLPSD_IMAGE_INFO& info)
{
if(TlPsdLoad_GetImageInfo(&info) != TLPSDERR_NO_ERROR)
return false;
int nSize = Width(info.rcImage) * Height(info.rcImage);
image.resize(nSize);
if(TlPsdLoad_GetImage(info.nIndex, &image.at(0), nSize * sizeof(RGBQUAD), &info.rcImage))
return false;
return true;
}
// ===================================================================================
bool GetILayerImage(int index, LAYER_IMAGE_ARRAY& layer, RECT rcFrame)
{
ZeroMemory(&layer.info, sizeof(TLPSD_IMAGE_INFO));
layer.info.nIndex = index;
if(TlPsdLoad_GetImageInfo(&layer.info) != TLPSDERR_NO_ERROR)
return false;
int nSize = Width(layer.info.rcImage) * Height(layer.info.rcImage);
if(nSize == 0)
return false; // There is nothing iamge data.
// Getting image data
layer.image.resize(nSize);
if(TlPsdLoad_GetImage(layer.info.nIndex, &layer.image.at(0), nSize * sizeof(RGBQUAD), &layer.info.rcImage))
return false;
// Trimming the image
TlPsdLoad_UnderScan(&layer.image.at(0), &layer.info.rcImage, &rcFrame);
TlPsdLoad_Minimize (&layer.image.at(0), &layer.info.rcImage);
// Check the image size
if(Width(layer.info.rcImage) == 0 || Height(layer.info.rcImage) == 0){
layer.image.clear();
return false;
}
cout << "Layer " << layer.info.nIndex << "\t( "
<< Width(layer.info.rcImage) << ", " << Height(layer.info.rcImage) << ") "
<< layer.info.nOpacity << " " << layer.info.szBlendMode
<< " " << layer.info.szName
<< endl;
return true;
}
// ===================================================================================
void SaveBitmap(LPCSTR lpszFileName, const LPVOID lpData, const RECT& rc)
{
BITMAPFILEHEADER bmfh = {0};
BITMAPINFOHEADER bmih = {0};
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biBitCount = 0X20;
bmih.biWidth = Width(rc);
bmih.biHeight = Height(rc);
bmih.biSizeImage = bmih.biWidth * bmih.biHeight * sizeof(RGBQUAD);
bmih.biPlanes = 1;
bmfh.bfType = 'B' + ((WORD)'M' << 8);
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfh.bfSize = bmfh.bfOffBits + bmih.biSizeImage;
ofstream fo;
fo.open(lpszFileName, ios::out|ios::binary|ios::trunc);
if(!fo){
cout << "Error: File "<< lpszFileName << " not open " << endl;
return;
}
fo.write(reinterpret_cast<char *>(&bmfh), sizeof(BITMAPFILEHEADER));
fo.write(reinterpret_cast<char *>(&bmih), sizeof(BITMAPINFOHEADER));
fo.write(reinterpret_cast<char *>(lpData), bmih.biSizeImage);
}
// ===================================================================================
void SaveCkissCel(LPCSTR lpszFileName, const LPVOID lpData, const RECT& rc)
{
char id[] = "KiSS";
char maker[2] = {0X21};
char bits[2] = {0X20};
char pad[2] = {0};
WORD width = (WORD)Width (rc);
WORD height = (WORD)Height(rc);
POINTS offset = {0, 0};
char reserved[16] = {0};
int size = width * height * sizeof(RGBQUAD);
ofstream fo(lpszFileName, ios::binary);
if(!fo){
cout << "Error: File "<< lpszFileName << " not open " << endl;
return;
}
fo.write(id, 4);
fo.write(maker, sizeof(char));
fo.write(bits, sizeof(char));
fo.write(pad, sizeof(pad));
fo.write(reinterpret_cast<char *>(&width), sizeof(width));
fo.write(reinterpret_cast<char *>(&height), sizeof(height));
fo.write(reinterpret_cast<char *>(&offset), sizeof(offset));
fo.write(reserved, sizeof(reserved));
fo.write(reinterpret_cast<char *>(lpData), size);
}