#ifndef IMAGEFORMAT_H #define IMAGEFORMAT_H #ifdef _WIN32 #pragma once #endif #include enum NormalDecodeMode_t { NORMAL_DECODE_NONE = 0, NORMAL_DECODE_ATI2N = 1, NORMAL_DECODE_ATI2N_ALPHA = 2 }; #ifdef _WIN32 typedef enum _D3DFORMAT D3DFORMAT; #endif #pragma warning(disable : 4514) enum ImageFormat { IMAGE_FORMAT_UNKNOWN = -1, IMAGE_FORMAT_RGBA8888 = 0, IMAGE_FORMAT_ABGR8888, IMAGE_FORMAT_RGB888, IMAGE_FORMAT_BGR888, IMAGE_FORMAT_RGB565, IMAGE_FORMAT_I8, IMAGE_FORMAT_IA88, IMAGE_FORMAT_P8, IMAGE_FORMAT_A8, IMAGE_FORMAT_RGB888_BLUESCREEN, IMAGE_FORMAT_BGR888_BLUESCREEN, IMAGE_FORMAT_ARGB8888, IMAGE_FORMAT_BGRA8888, IMAGE_FORMAT_DXT1, IMAGE_FORMAT_DXT3, IMAGE_FORMAT_DXT5, IMAGE_FORMAT_BGRX8888, IMAGE_FORMAT_BGR565, IMAGE_FORMAT_BGRX5551, IMAGE_FORMAT_BGRA4444, IMAGE_FORMAT_DXT1_ONEBITALPHA, IMAGE_FORMAT_BGRA5551, IMAGE_FORMAT_UV88, IMAGE_FORMAT_UVWQ8888, IMAGE_FORMAT_RGBA16161616F, IMAGE_FORMAT_RGBA16161616, IMAGE_FORMAT_UVLX8888, IMAGE_FORMAT_R32F, IMAGE_FORMAT_RGB323232F, IMAGE_FORMAT_RGBA32323232F, IMAGE_FORMAT_NV_DST16, IMAGE_FORMAT_NV_DST24, IMAGE_FORMAT_NV_INTZ, IMAGE_FORMAT_NV_RAWZ, IMAGE_FORMAT_ATI_DST16, IMAGE_FORMAT_ATI_DST24, IMAGE_FORMAT_NV_NULL, IMAGE_FORMAT_ATI2N, IMAGE_FORMAT_ATI1N, #if defined( _X360 ) IMAGE_FORMAT_X360_DST16, IMAGE_FORMAT_X360_DST24, IMAGE_FORMAT_X360_DST24F, IMAGE_FORMAT_LINEAR_BGRX8888, IMAGE_FORMAT_LINEAR_RGBA8888, IMAGE_FORMAT_LINEAR_ABGR8888, IMAGE_FORMAT_LINEAR_ARGB8888, IMAGE_FORMAT_LINEAR_BGRA8888, IMAGE_FORMAT_LINEAR_RGB888, IMAGE_FORMAT_LINEAR_BGR888, IMAGE_FORMAT_LINEAR_BGRX5551, IMAGE_FORMAT_LINEAR_I8, IMAGE_FORMAT_LINEAR_RGBA16161616, IMAGE_FORMAT_LE_BGRX8888, IMAGE_FORMAT_LE_BGRA8888, #endif NUM_IMAGE_FORMATS }; #if defined( POSIX ) || defined( DX_TO_GL_ABSTRACTION ) typedef enum _D3DFORMAT { D3DFMT_INDEX16, D3DFMT_D16, D3DFMT_D24S8, D3DFMT_A8R8G8B8, D3DFMT_A4R4G4B4, D3DFMT_X8R8G8B8, D3DFMT_R5G6R5, D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_L8, D3DFMT_A8L8, D3DFMT_A, D3DFMT_DXT1, D3DFMT_DXT3, D3DFMT_DXT5, D3DFMT_V8U8, D3DFMT_Q8W8V8U8, D3DFMT_X8L8V8U8, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16, D3DFMT_R32F, D3DFMT_A32B32G32R32F, D3DFMT_R8G8B8, D3DFMT_D24X4S4, D3DFMT_A8, D3DFMT_R5G6B5, D3DFMT_D15S1, D3DFMT_D24X8, D3DFMT_VERTEXDATA, D3DFMT_INDEX32, D3DFMT_NV_INTZ = 0x5a544e49, D3DFMT_NV_RAWZ = 0x5a574152, D3DFMT_NV_NULL = 0x4c4c554e, D3DFMT_ATI_D16 = 0x36314644, D3DFMT_ATI_D24S8 = 0x34324644, D3DFMT_ATI_2N = 0x32495441, D3DFMT_ATI_1N = 0x31495441, D3DFMT_UNKNOWN } D3DFORMAT; #endif struct BGRA8888_t { unsigned char b; unsigned char g; unsigned char r; unsigned char a; inline BGRA8888_t& operator=(const BGRA8888_t& in) { *(unsigned int*)this = *(unsigned int*)∈ return *this; } }; struct RGBA8888_t { unsigned char r; unsigned char g; unsigned char b; unsigned char a; inline RGBA8888_t& operator=(const BGRA8888_t& in) { r = in.r; g = in.g; b = in.b; a = in.a; return *this; } }; struct RGB888_t { unsigned char r; unsigned char g; unsigned char b; inline RGB888_t& operator=(const BGRA8888_t& in) { r = in.r; g = in.g; b = in.b; return *this; } inline bool operator==(const RGB888_t& in) const { return (r == in.r) && (g == in.g) && (b == in.b); } inline bool operator!=(const RGB888_t& in) const { return (r != in.r) || (g != in.g) || (b != in.b); } }; struct BGR888_t { unsigned char b; unsigned char g; unsigned char r; inline BGR888_t& operator=(const BGRA8888_t& in) { r = in.r; g = in.g; b = in.b; return *this; } }; #if defined( _X360 ) #pragma bitfield_order( push, lsb_to_msb ) #endif struct BGR565_t { unsigned short b : 5; unsigned short g : 6; unsigned short r : 5; inline BGR565_t& operator=(const BGRA8888_t& in) { r = in.r >> 3; g = in.g >> 2; b = in.b >> 3; return *this; } inline BGR565_t& Set(int red, int green, int blue) { r = red >> 3; g = green >> 2; b = blue >> 3; return *this; } }; #if defined( _X360 ) #pragma bitfield_order( pop ) #endif struct BGRA5551_t { unsigned short b : 5; unsigned short g : 5; unsigned short r : 5; unsigned short a : 1; inline BGRA5551_t& operator=(const BGRA8888_t& in) { r = in.r >> 3; g = in.g >> 3; b = in.b >> 3; a = in.a >> 7; return *this; } }; struct BGRA4444_t { unsigned short b : 4; unsigned short g : 4; unsigned short r : 4; unsigned short a : 4; inline BGRA4444_t& operator=(const BGRA8888_t& in) { r = in.r >> 4; g = in.g >> 4; b = in.b >> 4; a = in.a >> 4; return *this; } }; struct RGBX5551_t { unsigned short r : 5; unsigned short g : 5; unsigned short b : 5; unsigned short x : 1; inline RGBX5551_t& operator=(const BGRA8888_t& in) { r = in.r >> 3; g = in.g >> 3; b = in.b >> 3; return *this; } }; #define ARTWORK_GAMMA ( 2.2f ) #define IMAGE_MAX_DIM ( 2048 ) struct ImageFormatInfo_t { const char* m_pName; int m_NumBytes; int m_NumRedBits; int m_NumGreeBits; int m_NumBlueBits; int m_NumAlphaBits; bool m_IsCompressed; }; namespace ImageLoader { bool GetInfo(const char* fileName, int* width, int* height, enum ImageFormat* imageFormat, float* sourceGamma); int GetMemRequired(int width, int height, int depth, ImageFormat imageFormat, bool mipmap); int GetMipMapLevelByteOffset(int width, int height, enum ImageFormat imageFormat, int skipMipLevels); void GetMipMapLevelDimensions(int* width, int* height, int skipMipLevels); int GetNumMipMapLevels(int width, int height, int depth = 1); bool Load(unsigned char* imageData, const char* fileName, int width, int height, enum ImageFormat imageFormat, float targetGamma, bool mipmap); bool Load(unsigned char* imageData, FILE* fp, int width, int height, enum ImageFormat imageFormat, float targetGamma, bool mipmap); bool ConvertImageFormat(const unsigned char* src, enum ImageFormat srcImageFormat, unsigned char* dst, enum ImageFormat dstImageFormat, int width, int height, int srcStride = 0, int dstStride = 0); void PreConvertSwapImageData(unsigned char* pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0); void PostConvertSwapImageData(unsigned char* pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0); void ByteSwapImageData(unsigned char* pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0); bool IsFormatValidForConversion(ImageFormat fmt); ImageFormat D3DFormatToImageFormat(D3DFORMAT format); D3DFORMAT ImageFormatToD3DFormat(ImageFormat format); enum { RESAMPLE_NORMALMAP = 0x1, RESAMPLE_ALPHATEST = 0x2, RESAMPLE_NICE_FILTER = 0x4, RESAMPLE_CLAMPS = 0x8, RESAMPLE_CLAMPT = 0x10, RESAMPLE_CLAMPU = 0x20, }; struct ResampleInfo_t { ResampleInfo_t() : m_nFlags(0), m_flAlphaThreshhold(0.4f), m_flAlphaHiFreqThreshhold(0.4f), m_nSrcDepth(1), m_nDestDepth(1) { m_flColorScale[0] = 1.0f, m_flColorScale[1] = 1.0f, m_flColorScale[2] = 1.0f, m_flColorScale[3] = 1.0f; m_flColorGoal[0] = 0.0f, m_flColorGoal[1] = 0.0f, m_flColorGoal[2] = 0.0f, m_flColorGoal[3] = 0.0f; } unsigned char* m_pSrc; unsigned char* m_pDest; int m_nSrcWidth; int m_nSrcHeight; int m_nSrcDepth; int m_nDestWidth; int m_nDestHeight; int m_nDestDepth; float m_flSrcGamma; float m_flDestGamma; float m_flColorScale[4]; float m_flColorGoal[4]; float m_flAlphaThreshhold; float m_flAlphaHiFreqThreshhold; int m_nFlags; }; bool ResampleRGBA8888(const ResampleInfo_t& info); bool ResampleRGBA16161616(const ResampleInfo_t& info); bool ResampleRGB323232F(const ResampleInfo_t& info); void ConvertNormalMapRGBA8888ToDUDVMapUVLX8888(const unsigned char* src, int width, int height, unsigned char* dst_); void ConvertNormalMapRGBA8888ToDUDVMapUVWQ8888(const unsigned char* src, int width, int height, unsigned char* dst_); void ConvertNormalMapRGBA8888ToDUDVMapUV88(const unsigned char* src, int width, int height, unsigned char* dst_); void ConvertIA88ImageToNormalMapRGBA8888(const unsigned char* src, int width, int height, unsigned char* dst, float bumpScale); void NormalizeNormalMapRGBA8888(unsigned char* src, int numTexels); void GammaCorrectRGBA8888(unsigned char* src, unsigned char* dst, int width, int height, int depth, float srcGamma, float dstGamma); void ConstructGammaTable(unsigned char* pTable, float srcGamma, float dstGamma); void GammaCorrectRGBA8888(unsigned char* pSrc, unsigned char* pDst, int width, int height, int depth, unsigned char* pGammaTable); void GenerateMipmapLevels(unsigned char* pSrc, unsigned char* pDst, int width, int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma, int numLevels = 0); bool RotateImageLeft(const unsigned char* src, unsigned char* dst, int widthHeight, ImageFormat imageFormat); bool RotateImage180(const unsigned char* src, unsigned char* dst, int widthHeight, ImageFormat imageFormat); bool FlipImageVertically(void* pSrc, void* pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0); bool FlipImageHorizontally(void* pSrc, void* pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0); bool SwapAxes(unsigned char* src, int widthHeight, ImageFormat imageFormat); ImageFormatInfo_t const& ImageFormatInfo(ImageFormat fmt); inline char const* GetName(ImageFormat fmt) { return ImageFormatInfo(fmt).m_pName; } inline int SizeInBytes(ImageFormat fmt) { return ImageFormatInfo(fmt).m_NumBytes; } inline bool IsTransparent(ImageFormat fmt) { return ImageFormatInfo(fmt).m_NumAlphaBits > 0; } inline bool IsCompressed(ImageFormat fmt) { return ImageFormatInfo(fmt).m_IsCompressed; } inline bool HasChannelLargerThan8Bits(ImageFormat fmt) { ImageFormatInfo_t info = ImageFormatInfo(fmt); return (info.m_NumRedBits > 8 || info.m_NumGreeBits > 8 || info.m_NumBlueBits > 8 || info.m_NumAlphaBits > 8); } } #endif