Initial commit: client source
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,143 @@
|
||||
#ifndef AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_
|
||||
#define AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include <vector>
|
||||
|
||||
enum EPixFormat
|
||||
{
|
||||
PF_ARGB,
|
||||
PF_DXT1,
|
||||
PF_DXT2,
|
||||
PF_DXT3,
|
||||
PF_DXT4,
|
||||
PF_DXT5,
|
||||
PF_UNKNOWN
|
||||
};
|
||||
|
||||
#define MAX_MIPLEVELS 12
|
||||
|
||||
#ifndef DUMMYUNIONNAMEN
|
||||
#if defined(__cplusplus) || !defined(NONAMELESSUNION)
|
||||
#define DUMMYUNIONNAMEN(n)
|
||||
#else
|
||||
#define DUMMYUNIONNAMEN(n) u##n
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct _XDDPIXELFORMAT
|
||||
{
|
||||
DWORD dwSize; // size of structure
|
||||
DWORD dwFlags; // pixel format flags
|
||||
DWORD dwFourCC; // (FOURCC code)
|
||||
|
||||
union
|
||||
{
|
||||
DWORD dwRGBBitCount; // how many bits per pixel
|
||||
DWORD dwYUVBitCount; // how many bits per pixel
|
||||
DWORD dwZBufferBitDepth; // how many total bits/pixel in z buffer (including any stencil bits)
|
||||
DWORD dwAlphaBitDepth; // how many bits for alpha channels
|
||||
DWORD dwLuminanceBitCount; // how many bits per pixel
|
||||
DWORD dwBumpBitCount; // how many bits per "buxel", total
|
||||
DWORD dwPrivateFormatBitCount;// Bits per pixel of private driver formats. Only valid in texture
|
||||
// format list and if DDPF_D3DFORMAT is set
|
||||
} DUMMYUNIONNAMEN(1);
|
||||
union
|
||||
{
|
||||
DWORD dwRBitMask; // mask for red bit
|
||||
DWORD dwYBitMask; // mask for Y bits
|
||||
DWORD dwStencilBitDepth; // how many stencil bits (note: dwZBufferBitDepth-dwStencilBitDepth is total Z-only bits)
|
||||
DWORD dwLuminanceBitMask; // mask for luminance bits
|
||||
DWORD dwBumpDuBitMask; // mask for bump map U delta bits
|
||||
DWORD dwOperations; // DDPF_D3DFORMAT Operations
|
||||
} DUMMYUNIONNAMEN(2);
|
||||
union
|
||||
{
|
||||
DWORD dwGBitMask; // mask for green bits
|
||||
DWORD dwUBitMask; // mask for U bits
|
||||
DWORD dwZBitMask; // mask for Z bits
|
||||
DWORD dwBumpDvBitMask; // mask for bump map V delta bits
|
||||
struct
|
||||
{
|
||||
WORD wFlipMSTypes; // Multisample methods supported via flip for this D3DFORMAT
|
||||
WORD wBltMSTypes; // Multisample methods supported via blt for this D3DFORMAT
|
||||
} MultiSampleCaps;
|
||||
|
||||
} DUMMYUNIONNAMEN(3);
|
||||
union
|
||||
{
|
||||
DWORD dwBBitMask; // mask for blue bits
|
||||
DWORD dwVBitMask; // mask for V bits
|
||||
DWORD dwStencilBitMask; // mask for stencil bits
|
||||
DWORD dwBumpLuminanceBitMask; // mask for luminance in bump map
|
||||
} DUMMYUNIONNAMEN(4);
|
||||
union
|
||||
{
|
||||
DWORD dwRGBAlphaBitMask; // mask for alpha channel
|
||||
DWORD dwYUVAlphaBitMask; // mask for alpha channel
|
||||
DWORD dwLuminanceAlphaBitMask;// mask for alpha channel
|
||||
DWORD dwRGBZBitMask; // mask for Z channel
|
||||
DWORD dwYUVZBitMask; // mask for Z channel
|
||||
} DUMMYUNIONNAMEN(5);
|
||||
} XDDPIXELFORMAT;
|
||||
|
||||
|
||||
class CDXTCImage
|
||||
{
|
||||
public:
|
||||
CDXTCImage();
|
||||
virtual ~CDXTCImage();
|
||||
|
||||
void Initialize();
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
const BYTE * m_pbCompBufferByLevels[MAX_MIPLEVELS];
|
||||
std::vector<BYTE> m_bCompVector[MAX_MIPLEVELS];
|
||||
|
||||
int m_nCompSize;
|
||||
int m_nCompLineSz;
|
||||
|
||||
char m_strFormat[32];
|
||||
EPixFormat m_CompFormat;
|
||||
|
||||
long m_lPitch;
|
||||
DWORD m_dwMipMapCount;
|
||||
bool m_bMipTexture; // texture has mipmaps?
|
||||
DWORD m_dwFlags;
|
||||
|
||||
int m_nWidth; // in pixels of uncompressed image
|
||||
int m_nHeight;
|
||||
|
||||
XDDPIXELFORMAT m_xddPixelFormat;
|
||||
|
||||
bool LoadFromFile(const char * filename); // true if success
|
||||
bool LoadFromMemory(const BYTE * c_pbMap);
|
||||
bool LoadHeaderFromMemory(const BYTE * c_pbMap);
|
||||
bool Copy(int miplevel, BYTE * pbDest, long lDestPitch);
|
||||
|
||||
void Decompress(int miplevel, DWORD * pdwDest);
|
||||
void DecompressDXT1(int miplevel, DWORD * pdwDest);
|
||||
void DecompressDXT3(int miplevel, DWORD * pdwDest);
|
||||
void DecompressDXT5(int miplevel, DWORD * pdwDest);
|
||||
void DecompressARGB(int miplevel, DWORD * pdwDest);
|
||||
|
||||
VOID DecodePixelFormat(CHAR* strPixelFormat, XDDPIXELFORMAT* pddpf);
|
||||
|
||||
void Unextract(BYTE * pbDest, int iWidth, int iHeight, int iPitch);
|
||||
/*
|
||||
struct TimingInfo; // defined in Image_DXTC.cpp
|
||||
void RunTimingSession(); // run a few methods & time the code
|
||||
|
||||
// must use dxt5 texture
|
||||
void Time_Decomp5_01(int ntimes, TimingInfo * info);
|
||||
void Time_Decomp5_02(int ntimes, TimingInfo * info);
|
||||
void Time_Decomp5_03(int ntimes, TimingInfo * info);
|
||||
void Time_Decomp5_04(int ntimes, TimingInfo * info);
|
||||
*/
|
||||
};
|
||||
|
||||
#endif // #ifndef AFX_IMAGE_DXTC_H__4B89D8D0_7857_11D4_9630_00A0C996DE3D__INCLUDED_
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "Image.h"
|
||||
|
||||
CImage::CImage(CImage & image)
|
||||
{
|
||||
Initialize();
|
||||
|
||||
int w = image.GetWidth();
|
||||
int h = image.GetHeight();
|
||||
|
||||
Create(w, h);
|
||||
|
||||
DWORD * pdwDest = GetBasePointer();
|
||||
DWORD * pdwSrc = image.GetBasePointer();
|
||||
|
||||
memcpy(pdwDest, pdwSrc, w * h * sizeof(DWORD));
|
||||
}
|
||||
|
||||
void CImage::SetFileName(const char* c_szFileName)
|
||||
{
|
||||
m_stFileName = c_szFileName;
|
||||
}
|
||||
|
||||
const std::string& CImage::GetFileNameString()
|
||||
{
|
||||
return m_stFileName;
|
||||
}
|
||||
|
||||
void CImage::PutImage(int x, int y, CImage* pImage)
|
||||
{
|
||||
assert(x >= 0 && x + pImage->GetWidth() <= GetWidth());
|
||||
assert(y >= 0 && y + pImage->GetHeight() <= GetHeight());
|
||||
|
||||
int len = pImage->GetWidth() * sizeof(DWORD);
|
||||
|
||||
for (int j = 0; j < pImage->GetHeight(); ++j)
|
||||
{
|
||||
DWORD * pdwDest = GetLinePointer(y + j) + x;
|
||||
memcpy(pdwDest, pImage->GetLinePointer(j), len);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD* CImage::GetBasePointer()
|
||||
{
|
||||
assert(m_pdwColors != NULL);
|
||||
return m_pdwColors;
|
||||
}
|
||||
|
||||
DWORD* CImage::GetLinePointer(int line)
|
||||
{
|
||||
assert(m_pdwColors != NULL);
|
||||
return m_pdwColors + line * m_width;
|
||||
}
|
||||
|
||||
int CImage::GetWidth() const
|
||||
{
|
||||
assert(m_pdwColors != NULL);
|
||||
return m_width;
|
||||
}
|
||||
|
||||
int CImage::GetHeight() const
|
||||
{
|
||||
assert(m_pdwColors != NULL);
|
||||
return m_height;
|
||||
}
|
||||
|
||||
void CImage::Clear(DWORD color)
|
||||
{
|
||||
assert(m_pdwColors != NULL);
|
||||
|
||||
for (int y = 0; y < m_height; ++y)
|
||||
{
|
||||
DWORD * colorLine = &m_pdwColors[y * m_width];
|
||||
|
||||
for (int x = 0; x < m_width; ++x)
|
||||
colorLine[x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void CImage::Create(int width, int height)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_pdwColors = new DWORD[m_width*m_height];
|
||||
}
|
||||
|
||||
void CImage::Destroy()
|
||||
{
|
||||
if (m_pdwColors)
|
||||
{
|
||||
delete [] m_pdwColors;
|
||||
m_pdwColors = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CImage::Initialize()
|
||||
{
|
||||
m_pdwColors = NULL;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
}
|
||||
|
||||
bool CImage::IsEmpty() const
|
||||
{
|
||||
return (m_pdwColors == NULL) ? true : false;
|
||||
}
|
||||
|
||||
void CImage::FlipTopToBottom()
|
||||
{
|
||||
DWORD * swap = new DWORD[m_width * m_height];
|
||||
|
||||
int row;
|
||||
UINT width = GetWidth();
|
||||
UINT height = GetHeight();
|
||||
DWORD * end_row;
|
||||
DWORD * start_row;
|
||||
|
||||
for (row = 0; row < GetHeight() / 2; row++)
|
||||
{
|
||||
end_row = &(m_pdwColors[width * (height - row - 1)]);
|
||||
start_row = &(m_pdwColors[width * row]);
|
||||
|
||||
memcpy(swap, end_row, width * sizeof(DWORD));
|
||||
memcpy(end_row, start_row, width * sizeof(DWORD));
|
||||
memcpy(start_row, swap, width * sizeof(DWORD));
|
||||
}
|
||||
|
||||
delete [] swap;
|
||||
}
|
||||
|
||||
CImage::CImage()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CImage::~CImage()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef __INC_ETERIMAGELIB_IMAGE_H__
|
||||
#define __INC_ETERIMAGELIB_IMAGE_H__
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct TGA_HEADER
|
||||
{
|
||||
char idLen; // 0
|
||||
char palType; // 파레트있으면 1, 없음 0
|
||||
char imgType; // 파레트있으면 1, 없음 2
|
||||
WORD colorBegin; // 0
|
||||
WORD colorCount; // 파레트 있으면 256, 없음 0
|
||||
char palEntrySize; // 파레트 있으면 24, 없음 0
|
||||
WORD left;
|
||||
WORD top;
|
||||
WORD width;
|
||||
WORD height;
|
||||
char colorBits;
|
||||
char desc;
|
||||
};
|
||||
#define IMAGEDESC_ORIGIN_MASK 0x30
|
||||
#define IMAGEDESC_TOPLEFT 0x20
|
||||
#define IMAGEDESC_BOTLEFT 0x00
|
||||
#define IMAGEDESC_BOTRIGHT 0x10
|
||||
#define IMAGEDESC_TOPRIGHT 0x30
|
||||
#pragma pack(pop)
|
||||
|
||||
class CImage
|
||||
{
|
||||
public:
|
||||
CImage();
|
||||
CImage(CImage & image);
|
||||
|
||||
virtual ~CImage();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void Create(int width, int height);
|
||||
|
||||
void Clear(DWORD color = 0);
|
||||
|
||||
int GetWidth() const;
|
||||
int GetHeight() const;
|
||||
|
||||
DWORD * GetBasePointer();
|
||||
DWORD * GetLinePointer(int line);
|
||||
|
||||
void PutImage(int x, int y, CImage* pImage);
|
||||
void FlipTopToBottom();
|
||||
|
||||
void SetFileName(const char* c_szFileName);
|
||||
|
||||
const std::string & GetFileNameString();
|
||||
|
||||
bool IsEmpty() const;
|
||||
|
||||
protected:
|
||||
void Initialize();
|
||||
|
||||
protected:
|
||||
DWORD * m_pdwColors;
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
std::string m_stFileName;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// eterImageLib.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__BCF68E23_E7D8_4BF3_A905_AFDBEF92B0F6__INCLUDED_)
|
||||
#define AFX_STDAFX_H__BCF68E23_E7D8_4BF3_A905_AFDBEF92B0F6__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#pragma warning(disable:4786)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
//#include <crtdbg.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
|
||||
#pragma warning(push, 3)
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#pragma warning(pop)
|
||||
|
||||
inline void _TraceForImage(const char* c_szFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, c_szFormat);
|
||||
|
||||
static char szBuf[1024];
|
||||
_vsnprintf(szBuf, sizeof(szBuf), c_szFormat, args);
|
||||
#ifdef _DEBUG
|
||||
OutputDebugString(szBuf);
|
||||
#endif
|
||||
va_end(args);
|
||||
printf(szBuf);
|
||||
}
|
||||
|
||||
#pragma warning(default:4018)
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__BCF68E23_E7D8_4BF3_A905_AFDBEF92B0F6__INCLUDED_)
|
||||
@@ -0,0 +1,364 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "../eterBase/MappedFile.h"
|
||||
#include "TGAImage.h"
|
||||
|
||||
CTGAImage::CTGAImage() : m_dwFlag(0)
|
||||
{
|
||||
}
|
||||
|
||||
CTGAImage::~CTGAImage()
|
||||
{
|
||||
}
|
||||
|
||||
CTGAImage::CTGAImage(CImage &image) : m_dwFlag(0)
|
||||
{
|
||||
int w = image.GetWidth();
|
||||
int h = image.GetHeight();
|
||||
|
||||
Create(w, h);
|
||||
|
||||
DWORD * pdwDest = GetBasePointer();
|
||||
memcpy(pdwDest, image.GetBasePointer(), w * h * sizeof(DWORD));
|
||||
FlipTopToBottom();
|
||||
}
|
||||
|
||||
void CTGAImage::Create(int width, int height)
|
||||
{
|
||||
memset(&m_Header, 0, sizeof(m_Header));
|
||||
|
||||
m_Header.imgType = 2;
|
||||
m_Header.width = (short) width;
|
||||
m_Header.height = (short) height;
|
||||
m_Header.colorBits = 32;
|
||||
m_Header.desc = 0x08; // alpha channel 있음
|
||||
|
||||
CImage::Create(width, height);
|
||||
}
|
||||
|
||||
bool CTGAImage::LoadFromMemory(int iSize, const BYTE * c_pbMem)
|
||||
{
|
||||
memcpy(&m_Header, c_pbMem, 18);
|
||||
c_pbMem += 18;
|
||||
iSize -= 18;
|
||||
|
||||
CImage::Create(m_Header.width, m_Header.height);
|
||||
|
||||
UINT hxw = m_Header.width * m_Header.height;
|
||||
BYTE r, g, b, a;
|
||||
DWORD i;
|
||||
|
||||
DWORD * pdwDest = GetBasePointer();
|
||||
|
||||
switch (m_Header.imgType)
|
||||
{
|
||||
case 3: // 알파만 있는 것 (1bytes per pixel, 거의 안쓰임)
|
||||
{
|
||||
for (i = 0; i < hxw; ++i)
|
||||
{
|
||||
a = (char) *(c_pbMem++);
|
||||
pdwDest[i] = (a << 24) | (a << 16) | (a << 8) | a;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // 압축 안된 TGA
|
||||
{
|
||||
if (m_Header.colorBits == 16) // 16bit
|
||||
{
|
||||
for (i = 0; i < hxw; ++i)
|
||||
{
|
||||
WORD w;
|
||||
|
||||
memcpy(&w, c_pbMem, sizeof(WORD));
|
||||
c_pbMem += sizeof(WORD);
|
||||
iSize -= sizeof(WORD);
|
||||
|
||||
b = (BYTE) (w & 0x1F);
|
||||
g = (BYTE) ((w >> 5) & 0x1F);
|
||||
r = (BYTE) ((w >> 10) & 0x1F);
|
||||
|
||||
b <<= 3;
|
||||
g <<= 3;
|
||||
r <<= 3;
|
||||
a = 0xff;
|
||||
|
||||
pdwDest[i] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
else if (m_Header.colorBits == 24) // 24bit
|
||||
{
|
||||
for (i = 0; i < hxw; ++i)
|
||||
{
|
||||
r = (BYTE) *(c_pbMem++); --iSize;
|
||||
g = (BYTE) *(c_pbMem++); --iSize;
|
||||
b = (BYTE) *(c_pbMem++); --iSize;
|
||||
a = 0xff;
|
||||
|
||||
pdwDest[i] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
else if (m_Header.colorBits == 32) // 32bit
|
||||
{
|
||||
int size = GetWidth();
|
||||
size *= GetHeight() * 4;
|
||||
|
||||
memcpy(pdwDest, c_pbMem, size);
|
||||
c_pbMem += size;
|
||||
iSize -= size;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 10: // 압축 된 TGA (RLE)
|
||||
{
|
||||
BYTE rle;
|
||||
|
||||
if (m_Header.colorBits == 24)
|
||||
{
|
||||
i = 0;
|
||||
while (i < hxw)
|
||||
{
|
||||
rle = (BYTE) *(c_pbMem++); --iSize;
|
||||
|
||||
if (rle < 0x80) // 압축 안된 곳
|
||||
{
|
||||
rle++;
|
||||
|
||||
while (rle)
|
||||
{
|
||||
b = (BYTE) *(c_pbMem++); --iSize;
|
||||
g = (BYTE) *(c_pbMem++); --iSize;
|
||||
r = (BYTE) *(c_pbMem++); --iSize;
|
||||
a = 0xff;
|
||||
pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
if (i > hxw)
|
||||
{
|
||||
assert(!"RLE overflow");
|
||||
printf("RLE overflow");
|
||||
return false;
|
||||
}
|
||||
--rle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 압축 된 곳
|
||||
rle -= 127;
|
||||
|
||||
b = (BYTE) *(c_pbMem++); --iSize;
|
||||
g = (BYTE) *(c_pbMem++); --iSize;
|
||||
r = (BYTE) *(c_pbMem++); --iSize;
|
||||
a = 0xff;
|
||||
|
||||
while (rle)
|
||||
{
|
||||
pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
if (i > hxw)
|
||||
{
|
||||
assert(!"RLE overflow");
|
||||
printf("RLE overflow");
|
||||
return false;
|
||||
}
|
||||
--rle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_Header.colorBits == 32)
|
||||
{
|
||||
i = 0;
|
||||
while (i < hxw)
|
||||
{
|
||||
rle = (BYTE) *(c_pbMem++); --iSize;
|
||||
|
||||
if (rle < 0x80)
|
||||
{
|
||||
rle++;
|
||||
|
||||
while (rle)
|
||||
{
|
||||
b = (BYTE) *(c_pbMem++); --iSize;
|
||||
g = (BYTE) *(c_pbMem++); --iSize;
|
||||
r = (BYTE) *(c_pbMem++); --iSize;
|
||||
a = (BYTE) *(c_pbMem++); --iSize;
|
||||
pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
if (i > hxw)
|
||||
{
|
||||
assert(!"RLE overflow");
|
||||
printf("RLE overflow");
|
||||
return false;
|
||||
}
|
||||
--rle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rle -= 127;
|
||||
|
||||
b = (BYTE) *(c_pbMem++); --iSize;
|
||||
g = (BYTE) *(c_pbMem++); --iSize;
|
||||
r = (BYTE) *(c_pbMem++); --iSize;
|
||||
a = (BYTE) *(c_pbMem++); --iSize;
|
||||
|
||||
while (rle)
|
||||
{
|
||||
pdwDest[i++] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
if (i > hxw)
|
||||
{
|
||||
assert(!"RLE overflow");
|
||||
printf("RLE overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
--rle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(m_Header.desc & 0x20))
|
||||
{
|
||||
FlipTopToBottom();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTGAImage::LoadFromDiskFile(const char * c_szFileName)
|
||||
{
|
||||
CMappedFile file;
|
||||
|
||||
const BYTE * c_pbMap;
|
||||
|
||||
if (!file.Create(c_szFileName, (const void **) &c_pbMap, 0, 0))
|
||||
return false;
|
||||
|
||||
return LoadFromMemory(file.Size(), c_pbMap);
|
||||
}
|
||||
|
||||
int CTGAImage::GetRLEPixelCount(const DWORD * data)
|
||||
{
|
||||
int r = 0;
|
||||
DWORD pixel;
|
||||
|
||||
r = 1;
|
||||
|
||||
if (data >= m_pdwEndPtr)
|
||||
return 0;
|
||||
|
||||
pixel = *data;
|
||||
|
||||
while ((r < 127) && (data < m_pdwEndPtr))
|
||||
{
|
||||
if (pixel != *(++data))
|
||||
return r;
|
||||
|
||||
r++;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int CTGAImage::GetRawPixelCount(const DWORD * data)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (data >= m_pdwEndPtr)
|
||||
return 0;
|
||||
|
||||
while ((data < m_pdwEndPtr) && (i < 127))
|
||||
{
|
||||
int rle = GetRLEPixelCount(data);
|
||||
|
||||
if (rle >= 4)
|
||||
break;
|
||||
|
||||
data++;
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void CTGAImage::SetCompressed(bool isCompress)
|
||||
{
|
||||
if (isCompress)
|
||||
m_Header.imgType = 10;
|
||||
else
|
||||
m_Header.imgType = 2;
|
||||
}
|
||||
|
||||
void CTGAImage::SetAlphaChannel(bool isExist)
|
||||
{
|
||||
if (isExist)
|
||||
m_Header.desc |= 0x08;
|
||||
else
|
||||
m_Header.desc &= ~0x08;
|
||||
}
|
||||
|
||||
bool CTGAImage::SaveToDiskFile(const char* c_szFileName)
|
||||
{
|
||||
FILE * fp = fopen(c_szFileName, "wb");
|
||||
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
fwrite(&m_Header, 18, 1, fp);
|
||||
|
||||
if (m_Header.imgType == 10) // RLE 압축으로 저장
|
||||
{
|
||||
DWORD * data = GetBasePointer();
|
||||
|
||||
while (data < m_pdwEndPtr)
|
||||
{
|
||||
int rle = GetRLEPixelCount(data);
|
||||
|
||||
if (rle < 4)
|
||||
{
|
||||
int raw = GetRawPixelCount(data);
|
||||
|
||||
if (raw == 0)
|
||||
break;
|
||||
|
||||
fputc(raw - 1, fp);
|
||||
|
||||
while (raw)
|
||||
{
|
||||
fwrite(data, sizeof(DWORD), 1, fp);
|
||||
data++;
|
||||
raw--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fputc((rle - 1) | 0x80, fp);
|
||||
fwrite(data, sizeof(DWORD), 1, fp);
|
||||
data += rle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int size = GetWidth();
|
||||
size *= GetHeight() * 4;
|
||||
fwrite(GetBasePointer(), size, 1, fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
TGA_HEADER & CTGAImage::GetHeader()
|
||||
{
|
||||
return m_Header;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef __INC_ETERIMAGELIB_TGAIMAGE_H__
|
||||
#define __INC_ETERIMAGELIB_TGAIMAGE_H__
|
||||
|
||||
#include "Image.h"
|
||||
|
||||
class CTGAImage : public CImage
|
||||
{
|
||||
public:
|
||||
enum ETGAImageFlags
|
||||
{
|
||||
FLAG_RLE_COMPRESS = (1 << 0)
|
||||
};
|
||||
|
||||
CTGAImage();
|
||||
CTGAImage(CImage &image);
|
||||
virtual ~CTGAImage();
|
||||
|
||||
virtual void Create(int width, int height);
|
||||
virtual bool LoadFromMemory(int iSize, const BYTE * c_pbMem);
|
||||
virtual bool LoadFromDiskFile(const char * c_szFileName);
|
||||
virtual bool SaveToDiskFile(const char* c_szFileName);
|
||||
|
||||
void SetCompressed(bool isCompress = true);
|
||||
void SetAlphaChannel(bool isExist = true);
|
||||
|
||||
TGA_HEADER & GetHeader();
|
||||
protected:
|
||||
int GetRawPixelCount(const DWORD * data);
|
||||
int GetRLEPixelCount(const DWORD * data);
|
||||
|
||||
protected:
|
||||
TGA_HEADER m_Header;
|
||||
DWORD m_dwFlag;
|
||||
DWORD * m_pdwEndPtr;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user