658 lines
17 KiB
C++
658 lines
17 KiB
C++
// DDSReader.cpp : Defines the entry point for the DLL application.
|
|
//
|
|
#include "DDSReader.h"
|
|
#include "dds.h"
|
|
#include "ddraw.h"
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
#ifdef USE_DX9
|
|
#include "d3dx9.h"
|
|
|
|
#define LPDIRECT3DDEVICE LPDIRECT3DDEVICE9
|
|
#define LPDIRECT3DTEXTURE LPDIRECT3DTEXTURE9
|
|
#define LPDIRECT3DSURFACE LPDIRECT3DSURFACE9
|
|
#define Direct3DCreate Direct3DCreate9
|
|
|
|
IDirect3D9* g_D3D = NULL;
|
|
IDirect3DDevice9* g_Device = NULL;
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
#else
|
|
#include "d3dx8.h"
|
|
|
|
#define LPDIRECT3DDEVICE LPDIRECT3DDEVICE8
|
|
#define LPDIRECT3DTEXTURE LPDIRECT3DTEXTURE8
|
|
#define LPDIRECT3DSURFACE LPDIRECT3DSURFACE8
|
|
#define Direct3DCreate Direct3DCreate8
|
|
|
|
IDirect3D8* g_D3D = NULL;
|
|
IDirect3DDevice8* g_Device = NULL;
|
|
#endif
|
|
|
|
#define READER_COUNT 1
|
|
|
|
#define DDS_READER_ID 0
|
|
|
|
|
|
/*********************************************************
|
|
Since we are using D3D8 for file io and format conversion
|
|
we need a IDirect3D8 interface created and destroyed with this DLL
|
|
**********************************************************/
|
|
#ifndef CK_LIB
|
|
|
|
BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
|
|
{
|
|
switch (ul_reason_for_call)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
g_D3D = Direct3DCreate(D3D_SDK_VERSION);
|
|
if (!g_D3D) return FALSE;
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
if(g_Device) g_Device->Release();
|
|
if (g_D3D) g_D3D->Release();
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
break;
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
#endif
|
|
|
|
/************************************************************************
|
|
PLUGIN DECLARATION
|
|
**************************************************************************/
|
|
CKPluginInfo g_DDSReader_PInfo[READER_COUNT]={
|
|
CKPluginInfo( DDS_READER_GUID, // GUID
|
|
"Dds", // Extension supported
|
|
"Direct Draw Surface", // Reader Name
|
|
"Virtools", // Company
|
|
"Direct Draw Surface", // Summary String
|
|
DDS_READER_VERSION, // Reader Version
|
|
NULL, // No Init Instance function needed
|
|
NULL, // No Exit Instance function needed
|
|
CKPLUGIN_BITMAP_READER)}; // Plugin Type : Bitmap Reader
|
|
|
|
|
|
|
|
/**********************************************
|
|
Called by the engine when a file with the DDS
|
|
extension is being loaded, a reader has to be
|
|
created.
|
|
***********************************************/
|
|
#ifdef CK_LIB
|
|
CKDataReader *CKGet_DDSReader_Static(int pos)
|
|
#else
|
|
CKDataReader *CKGetReader(int pos)
|
|
#endif
|
|
{
|
|
switch(pos) {
|
|
case DDS_READER_ID: return new DDSReader(); break;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/******************************************
|
|
Returns information about the reader which
|
|
is the same as given to the engine at
|
|
initialisation.
|
|
*******************************************/
|
|
#ifndef CK_LIB
|
|
CKPluginInfo* CKGetPluginInfo(int index)
|
|
#else
|
|
CKPluginInfo* CKGet_DDSReader_PluginInfo(int index)
|
|
#endif
|
|
{
|
|
return &g_DDSReader_PInfo[index];
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
PLUGIN IMPLEMENTATION
|
|
**************************************************************************/
|
|
|
|
|
|
//-----------------------------------------
|
|
// Construction...
|
|
|
|
DDSReader::DDSReader()
|
|
{
|
|
m_Properties.m_Extension = "dds";
|
|
m_Properties.m_ReaderGuid = DDS_READER_GUID;
|
|
m_Properties.m_Data = NULL;
|
|
|
|
VxPixelFormat2ImageDesc(_32_ARGB8888,m_Properties.m_Format);
|
|
|
|
}
|
|
|
|
DDSReader::~DDSReader()
|
|
{
|
|
delete[] m_Properties.m_Data;
|
|
m_Properties.m_Data = NULL;
|
|
}
|
|
|
|
|
|
CKPluginInfo* DDSReader::GetReaderInfo()
|
|
{
|
|
return &g_DDSReader_PInfo[DDS_READER_ID];
|
|
}
|
|
|
|
//-----------------------------------------
|
|
// Get Options Count (1 in our case which is the
|
|
// pixel format when saving..)
|
|
int DDSReader::GetOptionsCount() { return 1; }
|
|
|
|
/*--------------------------------------------------
|
|
Get Options Description: Returns a string describing the
|
|
options this reader has when writing to file...
|
|
|
|
In this case we want to alias a DirectX enumeration (D3DFormat)
|
|
|
|
typedef enum _D3DFORMAT {
|
|
D3DFMT_R8G8B8 = 20,
|
|
D3DFMT_A8R8G8B8 = 21,
|
|
D3DFMT_R5G6B5 = 23,
|
|
D3DFMT_A1R5G5B5 = 25,
|
|
D3DFMT_A4R4G4B4 = 26,
|
|
D3DFMT_R3G3B2 = 27,
|
|
D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'),
|
|
D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'),
|
|
D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'),
|
|
D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'),
|
|
D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'),
|
|
} D3DFORMAT;
|
|
*/
|
|
CKSTRING
|
|
DDSReader::GetOptionDescription(int i)
|
|
{
|
|
static XString OptionsString;
|
|
|
|
OptionsString.Format("Enum:Pixel Format:"
|
|
"D3DFMT_R8G8B8=%d,"
|
|
"D3DFMT_A8R8G8B8=%d,"
|
|
"D3DFMT_R5G6B5=%d,"
|
|
"D3DFMT_A1R5G5B5=%d,"
|
|
"D3DFMT_A4R4G4B4=%d,"
|
|
"D3DFMT_R3G3B2=%d,"
|
|
"D3DFMT_DXT1=%d,"
|
|
"D3DFMT_DXT2=%d,"
|
|
"D3DFMT_DXT3=%d,"
|
|
"D3DFMT_DXT4=%d,"
|
|
"D3DFMT_DXT5=%d"
|
|
,D3DFMT_R8G8B8
|
|
,D3DFMT_A8R8G8B8
|
|
,D3DFMT_R5G6B5
|
|
,D3DFMT_A1R5G5B5
|
|
,D3DFMT_A4R4G4B4
|
|
,D3DFMT_R3G3B2
|
|
,D3DFMT_DXT1
|
|
,D3DFMT_DXT2
|
|
,D3DFMT_DXT3
|
|
,D3DFMT_DXT4
|
|
,D3DFMT_DXT5);
|
|
|
|
|
|
switch(i) {
|
|
case 0:
|
|
return OptionsString.Str();
|
|
break;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
//-------------------------------------
|
|
// Alpha Support : This function must return
|
|
// whether the format stored in bp will handle
|
|
// alpha information..
|
|
CKBOOL DDSReader::IsAlphaSaved(CKBitmapProperties* bp)
|
|
{
|
|
// TODO : optimize...
|
|
DDSBitmapProperties dds_bp;
|
|
if(bp->m_Size == dds_bp.m_Size) { // It's a Jpg Properties
|
|
memcpy(&dds_bp,bp,bp->m_Size);
|
|
} else {
|
|
memcpy(&dds_bp,bp,sizeof(CKBitmapProperties));
|
|
}
|
|
|
|
switch ( dds_bp.m_PixelFormat) {
|
|
case D3DFMT_R8G8B8:
|
|
case D3DFMT_R5G6B5:
|
|
case D3DFMT_R3G3B2: return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CreateTemporaryDevice(LPDIRECT3DDEVICE* Device)
|
|
{
|
|
D3DDISPLAYMODE dispMode;
|
|
D3DPRESENT_PARAMETERS presentParams;
|
|
|
|
//----- Create a D3D Device for the time to load the file...
|
|
g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispMode);
|
|
|
|
ZeroMemory(&presentParams, sizeof(presentParams));
|
|
presentParams.Windowed = TRUE;
|
|
|
|
#ifdef USE_DX9
|
|
presentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
#else
|
|
presentParams.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
|
|
#endif
|
|
|
|
presentParams.BackBufferWidth = 8;
|
|
presentParams.BackBufferHeight = 8;
|
|
presentParams.BackBufferFormat = dispMode.Format;
|
|
|
|
HRESULT res = g_D3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,GetDesktopWindow(),
|
|
D3DCREATE_MULTITHREADED|D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,&presentParams,Device);
|
|
|
|
return SUCCEEDED(res);
|
|
|
|
}
|
|
|
|
|
|
#define CLEANUPIFFAILED(res,error)\
|
|
if (FAILED(res)) {\
|
|
if (Surface) Surface->Release();\
|
|
if (TextureSurface) TextureSurface->Release();\
|
|
if (Texture) Texture->Release();\
|
|
return error;\
|
|
}\
|
|
|
|
/************************************************************
|
|
Load a .dds file (from memory or from file)
|
|
*************************************************************/
|
|
CKERROR DDS_Read(void* memptr,int size,CKBitmapProperties* bp)
|
|
{
|
|
LPDIRECT3DTEXTURE Texture = NULL;
|
|
LPDIRECT3DSURFACE Surface = NULL;
|
|
LPDIRECT3DSURFACE TextureSurface = NULL;
|
|
HRESULT res;
|
|
|
|
#ifdef CK_LIB
|
|
if (!g_D3D) {
|
|
g_D3D = Direct3DCreate(D3D_SDK_VERSION);
|
|
}
|
|
#endif
|
|
|
|
if(!g_Device){
|
|
CreateTemporaryDevice(&g_Device);
|
|
}
|
|
|
|
//-------- Create a texture from this file
|
|
if (!size) {
|
|
// Loads from a file
|
|
//res = D3DXCreateTextureFromFile(Device,(char *)memptr,&Texture);
|
|
res = D3DXCreateTextureFromFileEx(g_Device,(char *)memptr,D3DX_DEFAULT,D3DX_DEFAULT,1,0,
|
|
D3DFMT_UNKNOWN,D3DPOOL_SCRATCH ,D3DX_DEFAULT,D3DX_DEFAULT,0x00000000,NULL,NULL,&Texture);
|
|
|
|
} else {
|
|
// Loads from a file in a memory buffer
|
|
//res = D3DXCreateTextureFromFileInMemory(Device,memptr,size,&Texture);
|
|
|
|
res = D3DXCreateTextureFromFileInMemoryEx(g_Device,(char *)memptr,size,D3DX_DEFAULT,D3DX_DEFAULT,1,0,
|
|
D3DFMT_UNKNOWN,D3DPOOL_SCRATCH ,D3DX_DEFAULT,D3DX_DEFAULT,0x00000000,NULL,NULL,&Texture);
|
|
|
|
|
|
}
|
|
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
|
|
D3DSURFACE_DESC TextureDesc;
|
|
Texture->GetLevelDesc(0,&TextureDesc);
|
|
|
|
VX_PIXELFORMAT vpf = VxImageDesc2PixelFormat(((CKBitmapProperties*)bp)->m_Format);
|
|
D3DFORMAT dpf = DDS_VxPixelFormatToD3DFormat(vpf);
|
|
vpf = DDS_D3DFormatToVxPixelFormat(dpf);
|
|
|
|
if(TextureDesc.Format != dpf){
|
|
|
|
//--- Create a surface to perform conversion from the loaded image..
|
|
|
|
VxPixelFormat2ImageDesc(vpf,((CKBitmapProperties*)bp)->m_Format);
|
|
|
|
#ifdef USE_DX9
|
|
res = g_Device->CreateOffscreenPlainSurface(TextureDesc.Width, TextureDesc.Height, dpf, D3DPOOL_SCRATCH, &Surface, NULL);
|
|
#else
|
|
res = g_Device->CreateImageSurface(TextureDesc.Width,TextureDesc.Height,dpf,&Surface);
|
|
#endif
|
|
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
|
|
res= Texture->GetSurfaceLevel(0,&TextureSurface);
|
|
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
|
|
res= D3DXLoadSurfaceFromSurface(Surface,NULL,NULL,TextureSurface,NULL,NULL,D3DX_FILTER_NONE,0);
|
|
TextureSurface->Release();
|
|
TextureSurface = NULL;
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
}else{
|
|
Texture->GetSurfaceLevel(0,&Surface);
|
|
}
|
|
|
|
//--------- Copy bits from DX surface to our surface...
|
|
D3DLOCKED_RECT src;
|
|
res= Surface->LockRect(&src,NULL,D3DLOCK_READONLY);
|
|
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
|
|
//-------- Create the Image in virtools format
|
|
VxPixelFormat2ImageDesc(vpf,bp->m_Format);
|
|
bp->m_Format.Width = TextureDesc.Width;
|
|
bp->m_Format.Height = TextureDesc.Height;
|
|
bp->m_Format.BytesPerLine = TextureDesc.Width*(bp->m_Format.BitsPerPixel/8);
|
|
|
|
BYTE* memory = NULL;
|
|
|
|
if(bp->m_Format.BytesPerLine){
|
|
memory = new BYTE[ bp->m_Format.BytesPerLine * bp->m_Format.Height ];
|
|
}else{
|
|
memory = new BYTE[ src.Pitch/4 * bp->m_Format.Height ];
|
|
}
|
|
|
|
BYTE* Src = (BYTE *)src.pBits;
|
|
BYTE* Dst = memory;
|
|
|
|
bp->m_Data = memory;
|
|
|
|
if(bp->m_Format.BytesPerLine){
|
|
for (unsigned int i = 0; i< TextureDesc.Height; ++i,Src+=src.Pitch,Dst+=bp->m_Format.BytesPerLine) {
|
|
memcpy(Dst,Src,bp->m_Format.BytesPerLine);
|
|
}
|
|
}else{
|
|
memcpy(Dst,Src,src.Pitch/4 * bp->m_Format.Height);
|
|
}
|
|
|
|
Surface->UnlockRect();
|
|
|
|
Surface->Release();
|
|
Texture->Release();
|
|
#ifdef CK_LIB
|
|
if(g_Device) {
|
|
g_Device->Release();
|
|
g_Device=NULL;
|
|
}
|
|
if (g_D3D) {
|
|
g_D3D->Release();
|
|
g_D3D=NULL;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///------------------------------------------------------------
|
|
// Saving Functions
|
|
int DDS_Save(void** memptr,DDSBitmapProperties* bp)
|
|
{
|
|
LPDIRECT3DTEXTURE Texture = NULL;
|
|
LPDIRECT3DSURFACE Surface = NULL;
|
|
LPDIRECT3DSURFACE TextureSurface = NULL;
|
|
HRESULT res;
|
|
|
|
if(!g_Device){
|
|
CreateTemporaryDevice(&g_Device);
|
|
}
|
|
|
|
|
|
//--- Source format can only be a 32 bits image
|
|
// if (bp->m_Format.BitsPerPixel != 32) return 0;
|
|
|
|
|
|
D3DFORMAT fmt = DDS_VxPixelFormatToD3DFormat(VxImageDesc2PixelFormat(bp->m_Format));
|
|
|
|
//---- Create Source image surface
|
|
#ifdef USE_DX9
|
|
res = g_Device->CreateOffscreenPlainSurface(bp->m_Format.Width, bp->m_Format.Height, fmt, D3DPOOL_SCRATCH, &Surface, NULL);
|
|
#else
|
|
res = g_Device->CreateImageSurface(bp->m_Format.Width,bp->m_Format.Height,fmt,&Surface);
|
|
#endif
|
|
|
|
CLEANUPIFFAILED(res,0);
|
|
|
|
//--------- Copy bits from our surface to DX 32 bit surface
|
|
D3DLOCKED_RECT SrcLock;
|
|
res= Surface->LockRect(&SrcLock,NULL,0 );
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
BYTE* Src = (BYTE *)bp->m_Data;
|
|
BYTE* Dst = (BYTE*)SrcLock.pBits;
|
|
|
|
if(bp->m_Format.BytesPerLine){
|
|
for (int i = 0; i< bp->m_Format.Height; ++i,Src+=SrcLock.Pitch,Dst+=bp->m_Format.BytesPerLine) {
|
|
memcpy(Dst,Src,bp->m_Format.BytesPerLine);
|
|
}
|
|
}else{
|
|
memcpy(Dst,Src,SrcLock.Pitch/4 * bp->m_Format.Height);
|
|
}
|
|
Surface->UnlockRect();
|
|
|
|
if(bp->m_PixelFormat != fmt){
|
|
//---- Create destnation image surface
|
|
#ifdef USE_DX9
|
|
res = g_Device->CreateOffscreenPlainSurface(bp->m_Format.Width, bp->m_Format.Height, bp->m_PixelFormat, D3DPOOL_SCRATCH, &TextureSurface, NULL);
|
|
#else
|
|
res = g_Device->CreateImageSurface(bp->m_Format.Width,bp->m_Format.Height,bp->m_PixelFormat,&TextureSurface);
|
|
#endif
|
|
CLEANUPIFFAILED(res,0);
|
|
//---- Convert formats
|
|
res= D3DXLoadSurfaceFromSurface(TextureSurface,NULL,NULL,Surface,NULL,NULL,D3DX_FILTER_NONE,0);
|
|
CLEANUPIFFAILED(res,CKBITMAPERROR_READERROR);
|
|
}else{
|
|
TextureSurface = Surface;
|
|
Surface->AddRef();
|
|
}
|
|
|
|
//---- And Save
|
|
D3DSURFACE_DESC Desc;
|
|
TextureSurface->GetDesc(&Desc);
|
|
|
|
//--------- Copy bits from DX surface to a DDS file buffer...
|
|
D3DLOCKED_RECT Dest;
|
|
res = TextureSurface->LockRect(&Dest,NULL,D3DLOCK_READONLY);
|
|
|
|
//-- Prepare a big buffer to store the file
|
|
#ifdef USE_DX9
|
|
int DataSize = Dest.Pitch * Desc.Height;
|
|
|
|
if ( bp->m_PixelFormat == D3DFMT_DXT1 )
|
|
DataSize = max(1, Desc.Width/4) * max(1,Desc.Height/4) * 8;
|
|
else if ( (bp->m_PixelFormat == D3DFMT_DXT2) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT3) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT4) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT5) )
|
|
DataSize = max(1, Desc.Width/4) * max(1, Desc.Height/4) * 16;
|
|
#else
|
|
int DataSize = Desc.Size;
|
|
#endif
|
|
|
|
DWORD FileSize = 4 + sizeof(DDS_HEADER) + DataSize;
|
|
BYTE* FileData = new BYTE[FileSize];
|
|
|
|
//memset(&FileData[4 + sizeof(DDS_HEADER)],0xFF,Desc.Size);
|
|
memcpy(&FileData[4 + sizeof(DDS_HEADER)],Dest.pBits,DataSize);
|
|
|
|
TextureSurface->UnlockRect();
|
|
|
|
//---- Release all Dx Objects...
|
|
Surface->Release();
|
|
TextureSurface->Release();
|
|
|
|
//------ Now write Header
|
|
DWORD MagicDword = MAKEFOURCC('D','D','S',' ');
|
|
DDS_HEADER Header;
|
|
memset(&Header,0,sizeof(Header));
|
|
|
|
BOOL Compressed = ((bp->m_PixelFormat == D3DFMT_DXT1) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT2) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT3) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT4) ||
|
|
(bp->m_PixelFormat == D3DFMT_DXT5));
|
|
|
|
Header.dwSize = 124;
|
|
Header.dwHeaderFlags = DDSD_CAPS|DDSD_PIXELFORMAT|DDSD_WIDTH|DDSD_HEIGHT;
|
|
if (Compressed) {
|
|
Header.dwHeaderFlags |= DDS_HEADER_FLAGS_LINEARSIZE;
|
|
} else {
|
|
Header.dwHeaderFlags |= DDS_HEADER_FLAGS_PITCH;
|
|
}
|
|
Header.dwHeight = bp->m_Format.Height;
|
|
Header.dwWidth = bp->m_Format.Width;
|
|
Header.dwPitchOrLinearSize = Compressed ? DataSize : Dest.Pitch;
|
|
Header.dwSurfaceFlags = DDSCAPS_TEXTURE;
|
|
|
|
//--- Pixel Format
|
|
Header.ddspf.dwSize = 32;
|
|
if (Compressed) {
|
|
Header.ddspf.dwFlags = DDPF_FOURCC;
|
|
Header.ddspf.dwFourCC = bp->m_PixelFormat;
|
|
} else {
|
|
switch ( bp->m_PixelFormat) {
|
|
case D3DFMT_R8G8B8:
|
|
case D3DFMT_R5G6B5:
|
|
case D3DFMT_R3G3B2:
|
|
Header.ddspf.dwFlags = DDS_RGB;
|
|
break;
|
|
default:
|
|
Header.ddspf.dwFlags = DDS_RGBA;
|
|
break;
|
|
}
|
|
|
|
|
|
VxImageDescEx TempFormat;
|
|
VxPixelFormat2ImageDesc(DDS_D3DFormatToVxPixelFormat(bp->m_PixelFormat),TempFormat);
|
|
|
|
Header.ddspf.dwRGBBitCount = TempFormat.BitsPerPixel;
|
|
Header.ddspf.dwRBitMask = TempFormat.RedMask;
|
|
Header.ddspf.dwGBitMask = TempFormat.GreenMask;
|
|
Header.ddspf.dwBBitMask = TempFormat.BlueMask;
|
|
Header.ddspf.dwABitMask = TempFormat.AlphaMask;
|
|
}
|
|
|
|
|
|
//----- And Write to buffer
|
|
memcpy(FileData,&MagicDword,sizeof(DWORD));
|
|
memcpy(&FileData[4],&Header,sizeof(Header));
|
|
|
|
//---- File ? or memory
|
|
if (*memptr == NULL) {
|
|
// Memory
|
|
*memptr = FileData;
|
|
} else{
|
|
// File
|
|
XString filename = (char*)*memptr;
|
|
filename.CheckFileNameValidity();
|
|
FILE* f = fopen(filename.Str(),"wb");
|
|
if (!f) {
|
|
delete[] FileData;
|
|
return 0;
|
|
}
|
|
fwrite(FileData,FileSize,1,f);
|
|
fclose(f);
|
|
}
|
|
|
|
return FileSize;
|
|
}
|
|
|
|
|
|
///-----------------------------------------------
|
|
// Loading Functions
|
|
|
|
// Synchronous Reading from file or URL
|
|
int DDSReader::ReadFile(char* name,CKBitmapProperties** bp)
|
|
{
|
|
if (!name || !bp) return CKBITMAPERROR_GENERIC;
|
|
CKERROR ret=DDS_Read(name,0,&m_Properties);
|
|
*bp=&m_Properties;
|
|
return ret;
|
|
}
|
|
|
|
// Synchronous Reading from memory
|
|
int DDSReader::ReadMemory(void* memory,int size,CKBitmapProperties** bp)
|
|
{
|
|
if (!bp) return CKBITMAPERROR_GENERIC;
|
|
CKERROR ret=DDS_Read(memory,size,&m_Properties);
|
|
*bp=&m_Properties;
|
|
return ret;
|
|
}
|
|
|
|
///-----------------------------------------------
|
|
// Saving Functions
|
|
|
|
|
|
// Synchronous Reading from file or URL
|
|
int DDSReader::SaveFile(char* name,CKBitmapProperties* bp)
|
|
{
|
|
if (!name || !bp) return 0;
|
|
|
|
DDSBitmapProperties jbp;
|
|
if(bp->m_Size == jbp.m_Size) { // It's a Bmp Properties
|
|
memcpy(&jbp,bp,bp->m_Size);
|
|
} else {
|
|
memcpy(&jbp,bp,sizeof(CKBitmapProperties));
|
|
}
|
|
|
|
return DDS_Save((void**)&name,&jbp);
|
|
}
|
|
|
|
// Synchronous Reading from memory, return number of bytes written
|
|
int DDSReader::SaveMemory(void** memory,CKBitmapProperties* bp)
|
|
{
|
|
if (!memory || !bp) return 0;
|
|
|
|
DDSBitmapProperties jbp;
|
|
if(bp->m_Size == jbp.m_Size) { // It's a DDS Properties
|
|
memcpy(&jbp,bp,bp->m_Size);
|
|
} else {
|
|
memcpy(&jbp,bp,sizeof(CKBitmapProperties));
|
|
}
|
|
|
|
*memory=NULL;
|
|
return DDS_Save(memory,&jbp);
|
|
}
|
|
|
|
///-----------------------------------------------
|
|
// Image Properties
|
|
|
|
|
|
void DDSReader::SetBitmapDefaultProperties(CKBitmapProperties* bm)
|
|
{
|
|
if(bm->m_Size == m_Properties.m_Size) {
|
|
// It's a valid DDS Properties we can copy our properties
|
|
memcpy(&m_Properties,bm,bm->m_Size);
|
|
} else {
|
|
memcpy(&m_Properties,bm,sizeof(CKBitmapProperties));
|
|
}
|
|
}
|
|
|
|
void DDSReader::GetBitmapDefaultProperties(CKBitmapProperties** bm)
|
|
{
|
|
// We return the properties
|
|
*bm = &m_Properties;
|
|
}
|
|
|
|
//--------------------------------------------
|
|
// Cleaning
|
|
|
|
void DDSReader::ReleaseMemory(void* memory)
|
|
{
|
|
delete [] memory;
|
|
}
|
|
|
|
void DDSReader::Release()
|
|
{
|
|
delete this;
|
|
}
|