/* * Copyright 2010 Inalogic® Inc. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, as * published by the Free Software Foundation; either version 2.1 or 3.0 * of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR * PURPOSE. See the applicable version of the GNU Lesser General Public * License for more details. * * You should have received a copy of both the GNU Lesser General Public * License along with this program. If not, see * * Authored by: Jay Taoko * */ #ifndef IMAGESURFACE_H #define IMAGESURFACE_H #include "BitmapFormats.h" #include "NuxCore/Math/MathUtility.h" #include #define DEBUG_ENTER(a) #define DEBUG_WARNING(a) #define DEBUG_EXIT(a) namespace nux { class RawData { public: RawData() {}; ~RawData() {}; //! Get number of elements. unsigned int GetElementCount() { return 0; } //! Get the number of bytes per elements. unsigned int GetElementSize() { return 0; } void GetSize() {}; private: void *m_RawDataPtr; }; struct DXTColBlock { unsigned short col0; unsigned short col1; unsigned char row[4]; }; struct DXT3AlphaBlock { unsigned short row[4]; }; struct DXT5AlphaBlock { unsigned char alpha0; unsigned char alpha1; unsigned char row[6]; }; //! Image Surface class /*! Represent and image surface inside a complex data structure such as a 2D texture, Volume texture or Cube map. */ class ImageSurface { public: ImageSurface(); ~ImageSurface(); ImageSurface(BitmapFormat format, unsigned int width, unsigned int height); ImageSurface(const ImageSurface &); ImageSurface &operator = (const ImageSurface &); bool IsNull() const; int GetWidth() const { return width_; } int GetHeight() const { return height_; } void Allocate(BitmapFormat format, int width, int height); void Write32b(int i, int j, unsigned int value); void Write24b(int i, int j, unsigned int value); void Write16b(int i, int j, unsigned short value); void Write8b(int i, int j, unsigned char value); void Write(int i, int j, unsigned char r, unsigned char g, unsigned char b, unsigned char a); //! Read an element of the surface. /*! Return a 32 bits value representing the image element at coordinates(i, j). For the RGBA format, the LSB of the returned value represent the read value, and the MSB represents the alpha value. | LSB: Red | Green | Blue | MSB: Alpha| @return The image element at coordinates(i, j). */ unsigned int Read(int i, int j); //! Set all surface elements to 0. void Clear(); //! Flip the surface horizontally. void FlipHorizontal(); //! Flip the surface vertically. void FlipVertical(); //! Returns the surface pitch. int GetPitch() const; int GetBlockHeight() const; int GetAlignment() const; int GetSize() const; BitmapFormat GetFormat() const; const unsigned char *GetPtrRawData() const; unsigned char *GetPtrRawData(); static int GetLevelPitch(BitmapFormat format, int width, int height, int miplevel); static int GetLevelPitchNoMemAlignment(BitmapFormat format, int width, int height, int miplevel); static int GetLevelSize(BitmapFormat format, int width, int height, int miplevel); static int GetLevelSize(BitmapFormat format, int width, int height, int depth, int miplevel); static int GetLevelWidth(BitmapFormat format, int width, int miplevel); static int GetLevelHeight(BitmapFormat format, int height, int miplevel); static int GetLevelDim(BitmapFormat format, int length, int miplevel); static int GetNumMipLevel(BitmapFormat format, int width, int height); static int GetMemAlignment(BitmapFormat format); static int GetLevelBlockWidth(BitmapFormat format, int width, int miplevel); static int GetLevelBlockHeight(BitmapFormat format, int height, int miplevel); // for DXT // Image Processing //! Compute the average color of the image surface. /*! Sum up all the image elements and divide by the number of elements. @return The average color of the image. */ Color AverageColor(); private: void FlipDXTVertical(); void SwapBlocks(void *byte1, void *byte2, int size); void FlipBlocksDXT1(DXTColBlock *line, int numBlocks); void FlipBlocksDXT3(DXTColBlock *line, int numBlocks); void FlipBlocksDXT5(DXTColBlock *line, int numBlocks); void FlipDXT5Alpha(DXT5AlphaBlock *block); int width_; //!< Image width int height_; //!< Image height. BitmapFormat format_; //!< Image format. int m_Pitch; //!< Image pitch. int bpe_; //!< Number of byte per element. int Alignment_; //!< Data alignment. unsigned char *RawData_; }; class NBitmapData { public: NBitmapData(); virtual ~NBitmapData(); virtual const ImageSurface &GetSurface(int MipLevel) const = 0; virtual ImageSurface &GetSurface(int MipLevel) = 0; virtual const ImageSurface &GetSurface(int face, int MipLevel) const = 0; virtual ImageSurface &GetSurface(int face, int MipLevel) = 0; virtual bool IsTextureData() const { return false; }; virtual bool IsCubemapTextureData() const { return false; } virtual bool IsVolumeTextureData() const { return false; } virtual bool IsAnimatedTextureData() const { return false; } virtual int GetNumMipmap() const = 0; virtual int GetWidth() const = 0; virtual int GetHeight() const = 0; virtual int GetDepth() const { return 0; } virtual BitmapFormat GetFormat() const = 0; virtual bool IsNull() const = 0; virtual int GetMemorySize() const { return m_TotalMemorySize; } protected: unsigned int m_TotalMemorySize; //protected: // unsigned int m_Width; // unsigned int m_Height; // BitmapFormat m_Format; }; class NTextureData: public NBitmapData { public: NTextureData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int NumMipmap = 1); virtual ~NTextureData(); //! Copy constructor. NTextureData(const NTextureData &); //! Assignment constructor. NTextureData &operator = (const NTextureData &); virtual void Allocate(BitmapFormat f, int width, int height, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int MipLevel) const { return *m_MipSurfaceArray[MipLevel]; }; virtual ImageSurface &GetSurface(int MipLevel) { return const_cast ((const_cast< const NTextureData * > (this))->GetSurface(MipLevel)); } virtual const ImageSurface &GetSurface(int face, int MipLevel) const { //nuxAssertMsg(0, "[NTextureData::GetSurface] Use GetSurface(unsigned int MipLevel) for NTextureData."); return GetSurface(MipLevel); } virtual ImageSurface &GetSurface(int face, int MipLevel) { //nuxAssertMsg(0, "[NTextureData::GetSurface] Use GetSurface(unsigned int MipLevel) for NTextureData."); return GetSurface(MipLevel); } bool SetSurface(int MipLevel, const ImageSurface &object); virtual bool IsTextureData() const { return true; } virtual int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0]->GetHeight(); } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0]->IsNull(); } private: int m_NumMipmap; std::vector m_MipSurfaceArray; void ClearData(); #if defined(NUX_OS_WINDOWS) friend NBitmapData *read_tga_file(const TCHAR *file_name); #endif }; class NCubemapData: public NBitmapData { public: NCubemapData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int NumMipmap = 1); virtual ~NCubemapData(); //! Copy constructor NCubemapData(const NCubemapData &); //! Assignment constructor NCubemapData &operator = (const NCubemapData &); virtual void Allocate(BitmapFormat f, int width, int height, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int face, int MipLevel) const { return *m_MipSurfaceArray[face][MipLevel]; }; virtual ImageSurface &GetSurface(int face, int MipLevel) { return const_cast ((const_cast< const NCubemapData * > (this))->GetSurface(face, MipLevel)); } virtual const ImageSurface &GetSurface(int MipLevel) const { nuxAssertMsg(0, "[NCubemapData::GetSurface] Use GetSurface(unsigned int face, unsigned int MipLevel) for NCubemapData."); return GetSurface(0, MipLevel); } virtual ImageSurface &GetSurface(int MipLevel) { nuxAssertMsg(0, "[NCubemapData::GetSurface] Use GetSurface(unsigned int face, unsigned int MipLevel) for NCubemapData."); return GetSurface(0, MipLevel); } bool SetSurface(int face, int MipLevel, const ImageSurface &object); virtual bool IsCubemapTextureData() const { return true; } virtual int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0][0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0][0]->GetHeight(); } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0][0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0][0]->IsNull(); } private: void ClearData(); int m_NumMipmap; std::vector m_MipSurfaceArray[6]; }; class NVolumeData: public NBitmapData { public: NVolumeData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int slice = 1, int NumMipmap = 1); virtual ~NVolumeData(); //! Copy constructor NVolumeData(const NVolumeData &); //! Assignment constructor NVolumeData &operator = (const NVolumeData &); virtual void Allocate(BitmapFormat f, int width, int height, int slice, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int slice, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int slice, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int slice, int MipLevel) const { return *m_MipSurfaceArray[MipLevel][slice]; }; virtual ImageSurface &GetSurface(int slice, int MipLevel) { return const_cast ((const_cast< const NVolumeData * > (this))->GetSurface(slice, MipLevel)); } virtual const ImageSurface &GetSurface(int MipLevel) const { nuxAssertMsg(0, "[NVolumeData::GetSurface] Use GetSurface(unsigned int MipLevel, unsigned int MipLevel) for NVolumeData."); return GetSurface(MipLevel, 0); } virtual ImageSurface &GetSurface(int MipLevel) { nuxAssertMsg(0, "[NVolumeData::GetSurface] Use GetSurface(unsigned int MipLevel, unsigned int MipLevel) for NVolumeData."); return GetSurface(MipLevel, 0); } bool SetSurface(int face, int MipLevel, const ImageSurface &object); virtual bool IsVolumeTextureData() const { return true; } int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0][0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0][0]->GetHeight(); } virtual int GetDepth() const { return m_Depth; } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0][0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0][0]->IsNull(); } private: void ClearData(); int m_NumMipmap; int m_Depth; std::vector *m_MipSurfaceArray; }; class NAnimatedTextureData: public NBitmapData { public: NAnimatedTextureData(BitmapFormat f = BITFMT_R8G8B8A8, int width = 16, int height = 16, int slice = 1 /*, unsigned int NumMipmap = 1*/); virtual ~NAnimatedTextureData(); //! Copy constructor NAnimatedTextureData(const NAnimatedTextureData &); //! Assignment constructor NAnimatedTextureData &operator = (const NAnimatedTextureData &); virtual void Allocate(BitmapFormat f, int width, int height, int slice, int NumMipmap = 1); virtual void AllocateCheckBoardTexture(int width, int height, int slice, int NumMipmap, Color color0, Color color1, int TileWidth = 4, int TileHeight = 4); virtual void AllocateColorTexture(int width, int height, int slice, int NumMipmap, Color color0 = Color(0xFFFFFFF)); virtual const ImageSurface &GetSurface(int MipLevel, int slice) const { nuxAssertMsg(0, "[NAnimatedTextureData::GetSurface] Use GetSurface(unsigned int Frame) for NAnimatedTextureData."); return GetSurface(0); } virtual ImageSurface &GetSurface(int MipLevel, int slice) { nuxAssertMsg(0, "[NAnimatedTextureData::GetSurface] Use GetSurface(unsigned int Frame) for NAnimatedTextureData."); return GetSurface(0); } virtual const ImageSurface &GetSurface(int Frame) const { nuxAssert(Frame >= 0); nuxAssert(Frame < m_Depth); return *m_MipSurfaceArray[0][Frame]; } virtual ImageSurface &GetSurface(int Frame) { nuxAssert(Frame >= 0); nuxAssert(Frame < m_Depth); return const_cast ((const_cast< const NAnimatedTextureData * > (this))->GetSurface(Frame)); } bool SetSurface(int face, int MipLevel, const ImageSurface &object); virtual bool IsAnimatedTextureData() const { return true; } int GetFrameTime(int Frame) const { nuxAssert(Frame >= 0); nuxAssert(Frame < m_Depth); return m_FrameTimeArray[Frame]; } void AddFrameTime(unsigned int FrameTime) { m_FrameTimeArray.push_back(FrameTime); } int GetNumMipmap() const; virtual int GetWidth() const { return m_MipSurfaceArray[0][0]->GetWidth(); } virtual int GetHeight() const { return m_MipSurfaceArray[0][0]->GetHeight(); } virtual int GetDepth() const { return m_Depth; } virtual BitmapFormat GetFormat() const { return m_MipSurfaceArray[0][0]->GetFormat(); } virtual bool IsNull() const { return m_MipSurfaceArray[0][0]->IsNull(); } private: void ClearData(); int m_NumMipmap; int m_Depth; std::vector *m_MipSurfaceArray; std::vector m_FrameTimeArray; }; struct ImageInfo { bool isDelegate; // true if delegate knows this format int width ; // Image size(if known) int height; int bytes_per_pixel; // Bytes per pixel(if known) int planes; // Number of planes(if known) 0=mono, 3=color std::string format; // Additional image format information }; void MakeCheckBoardImage(ImageSurface& Image, int width, int height, Color const& dark, Color const& light, int TileWidth = 4, int TileHeight = 4); bool HasOpenEXRSupport(); /*! Return and object that has to be destroyed with delete. @return A bitmap source. Destroy it with delete. */ NBitmapData* LoadGdkPixbuf(GdkPixbuf *pixbuf); /*! Return and object that has to be destroyed with delete. @return A bitmap source. Destroy it with delete. */ NBitmapData* LoadImageFile(const TCHAR *Filename); } #endif // IMAGE_H