1 /*
2  * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ARX_GRAPHICS_IMAGE_IMAGE_H
21 #define ARX_GRAPHICS_IMAGE_IMAGE_H
22 
23 #include "graphics/Color.h"
24 
25 namespace fs { class path; }
26 namespace res { class path; }
27 
28 class Image {
29 
30 public:
31 
32 	enum Format {
33 		Format_L8,
34 		Format_A8,
35 		Format_L8A8,
36 		Format_R8G8B8,
37 		Format_B8G8R8,
38 		Format_R8G8B8A8,
39 		Format_B8G8R8A8,
40 		Format_DXT1,
41 		Format_DXT3,
42 		Format_DXT5,
43 		Format_Unknown,
44 		Format_Num,
45 		Format_MAX = 0xFF
46 	};
47 
48 	Image();
49 	Image(const Image & pOther);
50 	virtual ~Image();
51 
52 	const Image& operator=(const Image & pOther);
53 
54 	bool LoadFromFile(const res::path & filename);
55 	bool LoadFromMemory(void * pData, unsigned int size,
56 	                    const char * file = NULL);
57 
58 	void Create(unsigned int width, unsigned int height, Format format, unsigned int numMipmaps = 1, unsigned int depth = 1);
59 
60 	// Convert
61 	bool ConvertTo(Format format);
62 
63 	// reset to fresh constructor state
64 	void Reset();
65 
66 	// zero image data with memset
67 	void Clear();
68 
69 	// info accessors
GetWidth()70 	unsigned int GetWidth() const { return mWidth;      }
GetHeight()71 	unsigned int GetHeight() const { return mHeight;     }
GetDepth()72 	unsigned int GetDepth() const { return mDepth;      }
GetNumMipmaps()73 	unsigned int GetNumMipmaps() const { return mNumMipmaps; }
GetFormat()74 	Format GetFormat() const { return mFormat;     }
GetDataSize()75 	unsigned int GetDataSize() const { return mDataSize;   }
GetNumChannels()76 	unsigned int  GetNumChannels() const { return Image::GetNumChannels( mFormat ); }
77 
78 	// bool accessors
IsValid()79 	bool IsValid() const { return mData != NULL; }
IsCompressed()80 	bool IsCompressed() const { return Image::IsCompressed( mFormat ); }
IsVolume()81 	bool IsVolume() const { return mDepth > 1;  }
HasAlpha()82 	bool HasAlpha() const { return mFormat == Format_A8 || mFormat == Format_L8A8 || mFormat == Format_R8G8B8A8 || mFormat == Format_B8G8R8A8 || mFormat == Format_DXT3 || mFormat == Format_DXT5; }
83 
84 	//! Access to internal data.
GetData()85 	inline const unsigned char * GetData() const { return mData; }
GetData()86 	inline unsigned char * GetData() { return mData; }
87 
88 	// conversions
89 
90 	void FlipY();
91 	bool ToGrayscale(Format newFormat = Format_L8);
92 	bool ToNormalMap();
93 
94 	void ResizeFrom(const Image &source, unsigned int width, unsigned int height, bool flip_vertical = false);
95 
96 	/// Set the alpha of pixels matching the color key to 0. Will add an alpha channel if needed.
97 	void ApplyColorKeyToAlpha(Color colorKey = Color::black);
98 
99 	///! Copy an image into this image's buffer.
100 	///! Works only with uncompressed formats
101 	bool Copy(const Image & srcImage, unsigned int dstX, unsigned int dstY);
102 	bool Copy(const Image & srcImage, unsigned int dstX, unsigned int dstY, unsigned int srcX, unsigned int srcY, unsigned int width, unsigned int height);
103 
104 	bool save(const fs::path & filename) const;
105 
106 	// processing functions
107 	// destructively adjust image content
108 
109 	/// blur using gaussian kernel
110 	void Blur(int radius);
111 
112 	/// scales value and normalizes by max component value
113 	void QuakeGamma(float pGamma);
114 	//! Copy the alpha of img to this image.
115 	void SetAlpha(const Image& img, bool bInvertAlpha);
116 
117 	void AdjustGamma(const float &v);
118 	void AdjustBrightness(const float &v);
119 	void AdjustContrast(const float &v);
120 
121 	void ApplyThreshold(unsigned char threshold, int component_mask);
122 
123 	// statics
124 	static unsigned int	GetSize(Format pFormat, unsigned int pWidth = 1, unsigned int pHeight = 1, unsigned int pDepth = 1);
125 	static unsigned int	GetSizeWithMipmaps(Format pFormat, unsigned int pWidth, unsigned int pHeight, unsigned int pDepth = 1, int pMipmapCount = -1);
126 	static unsigned int	GetNumChannels(Format pFormat);
127 	static bool IsCompressed(Format pFormat);
128 
129 private:
130 
131 	void FlipY(unsigned char* pData, unsigned int pWidth, unsigned int pHeight, unsigned int pDepth);
132 
133 	unsigned int mWidth; //!< Image width.
134 	unsigned int mHeight; //!< Image height.
135 	unsigned int mDepth; //!< Image depth. Depth == 1 for normal images, > 1 for depth images.
136 
137 	unsigned int mNumMipmaps; //!< Number of mipmaps.
138 	Format mFormat; //!< Image format.
139 
140 	unsigned char* mData; //!< Pointer to image data buffer.
141 	unsigned int mDataSize; //!< Size of image buffer.
142 
143 };
144 
145 #endif // ARX_GRAPHICS_IMAGE_IMAGE_H
146