Cafu Engine
Loader_mdl_hl2_vtf.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_HL2_MDL_VTF_TEXTURE_FILE_HPP_INCLUDED
8 #define CAFU_HL2_MDL_VTF_TEXTURE_FILE_HPP_INCLUDED
9 
10 #include "Templates/Array.hpp"
11 #include <stdexcept>
12 
13 #if defined(_WIN32) && _MSC_VER<1600
14 #include "pstdint.h" // Paul Hsieh's portable implementation of the stdint.h header.
15 #else
16 #include <stdint.h>
17 #endif
18 
19 #define HL2_VTF_MAX_RES 32
20 
21 
22 namespace HL2mdl
23 {
24  /// Possible image formats that can occur in VTF files.
25  /// Named indices into an internal array of vtfImageFormatInfoT.
26  enum vtfImageFormatT
27  {
28  IMAGE_FORMAT_NONE = -1,
29  IMAGE_FORMAT_RGBA8888 = 0, ///< Red, Green, Blue, Alpha - 32 bpp
30  IMAGE_FORMAT_ABGR8888, ///< Alpha, Blue, Green, Red - 32 bpp
31  IMAGE_FORMAT_RGB888, ///< Red, Green, Blue - 24 bpp
32  IMAGE_FORMAT_BGR888, ///< Blue, Green, Red - 24 bpp
33  IMAGE_FORMAT_RGB565, ///< Red, Green, Blue - 16 bpp
34  IMAGE_FORMAT_I8, ///< Luminance - 8 bpp
35  IMAGE_FORMAT_IA88, ///< Luminance, Alpha - 16 bpp
36  IMAGE_FORMAT_P8, ///< Paletted - 8 bpp
37  IMAGE_FORMAT_A8, ///< Alpha - 8 bpp
38  IMAGE_FORMAT_RGB888_BLUESCREEN, ///< Red, Green, Blue - 24 bpp, (0, 0, 255) is translucent
39  IMAGE_FORMAT_BGR888_BLUESCREEN, ///< Blue, Green, Red - 24 bpp, (0, 0, 255) is translucent
40  IMAGE_FORMAT_ARGB8888, ///< Alpha, Red, Green, Blue - 32 bpp
41  IMAGE_FORMAT_BGRA8888, ///< Blue, Green, Red, Alpha - 32 bpp
42  IMAGE_FORMAT_DXT1, ///< DXT1 compressed format - 4 bpp
43  IMAGE_FORMAT_DXT3, ///< DXT3 compressed format - 8 bpp
44  IMAGE_FORMAT_DXT5, ///< DXT5 compressed format - 8 bpp
45  IMAGE_FORMAT_BGRX8888, ///< Blue, Green, Red, Unused - 32 bpp
46  IMAGE_FORMAT_BGR565, ///< Blue, Green, Red - 16 bpp
47  IMAGE_FORMAT_BGRX5551, ///< Blue, Green, Red, Unused - 16 bpp
48  IMAGE_FORMAT_BGRA4444, ///< Red, Green, Blue, Alpha - 16 bpp
49  IMAGE_FORMAT_DXT1_ONEBITALPHA, ///< DXT1 compressed format with 1-bit alpha - 4 bpp
50  IMAGE_FORMAT_BGRA5551, ///< Blue, Green, Red, Alpha - 16 bpp
51  IMAGE_FORMAT_UV88, ///< 2 channel format for DuDv/Normal maps - 16 bpp
52  IMAGE_FORMAT_UVWQ8888, ///< 4 channel format for DuDv/Normal maps - 32 bpp
53  IMAGE_FORMAT_RGBA16161616F, ///< Red, Green, Blue, Alpha - 64 bpp
54  IMAGE_FORMAT_RGBA16161616, ///< Red, Green, Blue, Alpha signed with mantissa - 64 bpp
55  IMAGE_FORMAT_UVLX8888, ///< 4 channel format for DuDv/Normal maps - 32 bpp
56  IMAGE_FORMAT_R32F, ///< Luminance - 32 bpp
57  IMAGE_FORMAT_RGB323232F, ///< Red, Green, Blue - 96 bpp
58  IMAGE_FORMAT_RGBA32323232F, ///< Red, Green, Blue, Alpha - 128 bpp
59  IMAGE_FORMAT_NV_DST16,
60  IMAGE_FORMAT_NV_DST24,
61  IMAGE_FORMAT_NV_INTZ,
62  IMAGE_FORMAT_NV_RAWZ,
63  IMAGE_FORMAT_ATI_DST16,
64  IMAGE_FORMAT_ATI_DST24,
65  IMAGE_FORMAT_NV_NULL,
66  IMAGE_FORMAT_ATI1N,
67  IMAGE_FORMAT_ATI2N,
68  /* IMAGE_FORMAT_X360_DST16, ///< XBox formats.
69  IMAGE_FORMAT_X360_DST24,
70  IMAGE_FORMAT_X360_DST24F,
71  IMAGE_FORMAT_LINEAR_BGRX8888, ///< Blue, Green, Red, Unused - 32 bpp
72  IMAGE_FORMAT_LINEAR_RGBA8888, ///< Red, Green, Blue, Alpha - 32 bpp
73  IMAGE_FORMAT_LINEAR_ABGR8888, ///< Alpha, Blue, Green, Red - 32 bpp
74  IMAGE_FORMAT_LINEAR_ARGB8888, ///< Alpha, Red, Green, Blue - 32 bpp
75  IMAGE_FORMAT_LINEAR_BGRA8888, ///< Blue, Green, Red, Alpha - 32 bpp
76  IMAGE_FORMAT_LINEAR_RGB888, ///< Red, Green, Blue - 24 bpp
77  IMAGE_FORMAT_LINEAR_BGR888, ///< Blue, Green, Red - 24 bpp
78  IMAGE_FORMAT_LINEAR_BGRX5551, ///< Blue, Green, Red, Unused - 16 bpp
79  IMAGE_FORMAT_LINEAR_I8, ///< Luminance - 8 bpp
80  IMAGE_FORMAT_LINEAR_RGBA16161616, ///< Red, Green, Blue, Alpha signed with mantissa - 64 bpp
81  IMAGE_FORMAT_LE_BGRX8888, ///< Blue, Green, Red, Unused - 32 bpp
82  IMAGE_FORMAT_LE_BGRA8888, ///< Blue, Green, Red, Alpha - 32 bpp */
83  IMAGE_FORMAT_COUNT
84  };
85 
86 
87  /// The vtfImageFormatInfoT struct provides information about VTF image formats.
89  {
90  typedef void (*TransformProc)(uint16_t& R, uint16_t& G, uint16_t& B, uint16_t& A);
91 
92  const char* Name; ///< Enumeration text equivalent.
93  uint32_t BitsPerPixel; ///< Bits per pixel.
94  uint32_t BytesPerPixel; ///< Bytes per pixel.
95  uint32_t RedBitsPerPixel; ///< Red bits per pixel.
96  uint32_t GreenBitsPerPixel; ///< Green bits per pixel.
97  uint32_t BlueBitsPerPixel; ///< Blue bits per pixel.
98  uint32_t AlphaBitsPerPixel; ///< Alpha bits per pixel.
99  int32_t IndexRed; ///< Red index.
100  int32_t IndexGreen; ///< Green index.
101  int32_t IndexBlue; ///< Blue index.
102  int32_t IndexAlpha; ///< Alpha index.
103  bool IsCompressed; ///< Is compressed (DXT).
104  bool IsSupported; ///< Format is supported by the implementation.
105  TransformProc pToTransform; ///< Custom transform to function.
106  TransformProc pFromTransform; ///< Custom transform from function.
107  vtfImageFormatT Format;
108  };
109 
110 
111  /// Maps a vtfImageFormatT constant to an vtfImageFormatInfoT instance.
112  const vtfImageFormatInfoT& GetImageFormatInfo(vtfImageFormatT ImageFormat);
113 
114  /// Convert an image from any format to IMAGE_FORMAT_RGBA8888.
115  ///
116  /// \param lpSource is a pointer to the source image data.
117  /// \param lpDest is a pointer to the buffer for the converted data.
118  /// \param Width is the width of the source image in pixels.
119  /// \param Height is the height of the source image in pixels.
120  /// \param SourceFormat is the image format you are converting from.
121  /// \return true on successful conversion, otherwise false.
122  bool Convert(uint8_t* lpSource, uint8_t* lpDest, uint32_t Width, uint32_t Height, vtfImageFormatT SourceFormat);
123 
124 
125  /// Constants used for the Flags member in the file header.
126  enum vtfFlagsT
127  {
128  TEXTUREFLAGS_POINTSAMPLE = 0x00000001,
129  TEXTUREFLAGS_TRILINEAR = 0x00000002,
130  TEXTUREFLAGS_CLAMPS = 0x00000004,
131  TEXTUREFLAGS_CLAMPT = 0x00000008,
132  TEXTUREFLAGS_ANISOTROPIC = 0x00000010,
133  TEXTUREFLAGS_HINT_DXT5 = 0x00000020,
134  TEXTUREFLAGS_DEPRECATED_NOCOMPRESS = 0x00000040,
135  TEXTUREFLAGS_NORMAL = 0x00000080,
136  TEXTUREFLAGS_NOMIP = 0x00000100,
137  TEXTUREFLAGS_NOLOD = 0x00000200,
138  TEXTUREFLAGS_MINMIP = 0x00000400,
139  TEXTUREFLAGS_PROCEDURAL = 0x00000800,
140  TEXTUREFLAGS_ONEBITALPHA = 0x00001000,
141  TEXTUREFLAGS_EIGHTBITALPHA = 0x00002000,
142  TEXTUREFLAGS_ENVMAP = 0x00004000,
143  TEXTUREFLAGS_RENDERTARGET = 0x00008000,
144  TEXTUREFLAGS_DEPTHRENDERTARGET = 0x00010000,
145  TEXTUREFLAGS_NODEBUGOVERRIDE = 0x00020000,
146  TEXTUREFLAGS_SINGLECOPY = 0x00040000,
147  TEXTUREFLAGS_DEPRECATED_ONEOVERMIPLEVELINALPHA = 0x00080000,
148  TEXTUREFLAGS_DEPRECATED_PREMULTCOLORBYONEOVERMIPLEVEL = 0x00100000,
149  TEXTUREFLAGS_DEPRECATED_NORMALTODUDV = 0x00200000,
150  TEXTUREFLAGS_DEPRECATED_ALPHATESTMIPGENERATION = 0x00400000,
151  TEXTUREFLAGS_NODEPTHBUFFER = 0x00800000,
152  TEXTUREFLAGS_DEPRECATED_NICEFILTERED = 0x01000000,
153  TEXTUREFLAGS_CLAMPU = 0x02000000,
154  TEXTUREFLAGS_VERTEXTEXTURE = 0x04000000,
155  TEXTUREFLAGS_SSBUMP = 0x08000000,
156  TEXTUREFLAGS_DEPRECATED_UNFILTERABLE_OK = 0x10000000,
157  TEXTUREFLAGS_BORDER = 0x20000000,
158  TEXTUREFLAGS_DEPRECATED_SPECVAR_RED = 0x40000000,
159  TEXTUREFLAGS_DEPRECATED_SPECVAR_ALPHA = 0x80000000,
160  TEXTUREFLAGS_LAST = 0x20000000
161  };
162 
163 
164 #if defined(_MSC_VER)
165  #pragma pack(push, 1)
166  #define GCC_PACKED
167 #elif defined(__GNUG__)
168  #define GCC_PACKED __attribute__ ((packed))
169 #endif
170 
171 
173  {
174  union
175  {
176  uint32_t Type;
177  struct
178  {
179  uint8_t ID[3]; ///< Resource ID
180  uint8_t Flags; ///< Resource flags
181  };
182  };
183 
184  /// Depending on the type, this can be the immediate resource data, e.g. a CRC,
185  /// or the offset from start of the file to an uint32_t with the number of bytes, followed by the bytes.
186  uint32_t Data;
187  } GCC_PACKED;
188 
189 
190  /// This is the header for VTF files, covering all 7.x versions up to 7.5 (current).
192  {
193  public:
194 
195  char TypeString[4]; ///< "VTF\0"
196  uint32_t Version[2];
197  uint32_t HeaderSize; ///< Size of the header struct (currently 80 bytes (+ resources(??))
198  uint16_t Width; ///< Width at the largest MipMap level
199  uint16_t Height; ///< Height at the largest MipMap level
200  uint32_t Flags; ///< As defined in vtfFlagsT.
201  uint16_t NumFrames; ///< It's a small movie if NumFrames > 1.
202  uint16_t StartFrame;
203  uint8_t Padding0[4]; ///< for 16 byte alignment
204  float Reflectivity[3];
205  uint8_t Padding1[4]; ///< for 16 byte alignment
206  float BumpScale;
207  vtfImageFormatT ImageFormat;
208  uint8_t NumMipMaps; ///< Number of MipMap levels (including the largest image)
209  vtfImageFormatT LowResImageFormat;
210  uint8_t LowResImageWidth;
211  uint8_t LowResImageHeight;
212 
213  /// Returns the file version times ten, e.g. 75 for the current version.
214  uint32_t GetVersion() const
215  {
216  return Version[0] * 10 + Version[1];
217  }
218 
219  /// Returns the number of faces in the file (usually 1).
220  uint32_t GetNumFaces() const
221  {
222  // Cubemaps have 6 or 7 faces, others just 1.
223  if ((Flags & TEXTUREFLAGS_ENVMAP) == 0)
224  return 1;
225 
226  // Spheremaps were only supported from version 7.1 to 7.4.
227  if (StartFrame != 0xffff && 71 <= GetVersion() && GetVersion() <= 74)
228  return 7;
229 
230  return 6;
231  }
232 
233  /// Returns the depth (number of z-slices) of the image in pixels.
234  uint16_t GetDepth() const
235  {
236  return GetVersion() < 72 ? 1 : m_Depth;
237  }
238 
239  uint32_t GetNumResources() const
240  {
241  return GetVersion() < 73 ? 0 : m_ResourceCount;
242  }
243 
244  const vtfResourceT& GetResource(uint32_t i) const
245  {
246  assert(i < GetNumResources());
247  return m_Resources[i];
248  }
249 
250 
251  private:
252 
253  // These fields are only available in newer versions of the file format.
254  // Use the Get*() methods in order to safely access their values.
255  uint16_t m_Depth; ///< Depth at the largest MipMap level.
256  uint8_t m_Padding2[3];
257  uint32_t m_ResourceCount; ///< Number of image resources.
258  uint8_t m_Padding3[8];
259 
260  // --- Up to here, 80 header bytes. ---
261  vtfResourceT m_Resources[HL2_VTF_MAX_RES];
262  } GCC_PACKED;
263 
264 
265 #if defined(_MSC_VER)
266  #pragma pack(pop)
267 #endif
268 #undef GCC_PACKED
269 
270 
271  /// A class that is thrown on VTF load errors.
272  class vtfLoadErrorT : public std::runtime_error
273  {
274  public:
275 
276  vtfLoadErrorT(const std::string& Message)
277  : std::runtime_error(Message)
278  {
279  }
280  };
281 
282 
283  /**
284  This class represents a VTF image file as documented at https://developer.valvesoftware.com/wiki/VTF
285 
286  In summary, the disk file format for VTF files is:
287  - VTF header (80 bytes)
288  - low-res image data
289  - image data
290 
291  The image data is stored as follows:
292  - for each mipmap level (starting with the smallest and getting larger)
293  - for each frame
294  - for each face (for cubemaps)
295  - for each z-slice
296  - image data
297  */
298  class vtfFileT
299  {
300  public:
301 
302  vtfFileT(const std::string& FileName);
303 
304  const vtfHeaderT* GetHeader() const { return m_Header; }
305 
306  /// Returns a pointer to the image data for a given frame, face, z-slice and MIP level.
307  /// Frames start at index 0 for the first frame. Faces start at index 0
308  /// for the first face. Cubemaps have 6 faces, others only 1.
309  /// MIP levels start at index 0 for the largest image moving down in size.
310  uint8_t* GetData(uint32_t Frame, uint32_t Face, uint32_t Slice, uint32_t MipmapLevel) const;
311 
312 
313  private:
314 
315  uint32_t ComputeDataOffset(uint32_t Frame, uint32_t Face, uint32_t Slice, uint32_t MipmapLevel) const;
316 
317  ArrayT<uint8_t> m_RawBytes;
318  vtfHeaderT* m_Header;
319  uint8_t* m_ImageBuffer;
320  };
321 }
322 
323 #endif
uint32_t BytesPerPixel
Bytes per pixel.
Definition: Loader_mdl_hl2_vtf.hpp:94
uint32_t HeaderSize
Size of the header struct (currently 80 bytes (+ resources(??))
Definition: Loader_mdl_hl2_vtf.hpp:197
uint8_t Padding1[4]
for 16 byte alignment
Definition: Loader_mdl_hl2_vtf.hpp:205
uint32_t BitsPerPixel
Bits per pixel.
Definition: Loader_mdl_hl2_vtf.hpp:93
uint32_t GetNumFaces() const
Returns the number of faces in the file (usually 1).
Definition: Loader_mdl_hl2_vtf.hpp:220
uint32_t Data
Depending on the type, this can be the immediate resource data, e.g.
Definition: Loader_mdl_hl2_vtf.hpp:186
int32_t IndexAlpha
Alpha index.
Definition: Loader_mdl_hl2_vtf.hpp:102
uint8_t NumMipMaps
Number of MipMap levels (including the largest image)
Definition: Loader_mdl_hl2_vtf.hpp:208
uint32_t GreenBitsPerPixel
Green bits per pixel.
Definition: Loader_mdl_hl2_vtf.hpp:96
uint8_t Flags
Resource flags.
Definition: Loader_mdl_hl2_vtf.hpp:180
int32_t IndexGreen
Green index.
Definition: Loader_mdl_hl2_vtf.hpp:100
bool IsCompressed
Is compressed (DXT).
Definition: Loader_mdl_hl2_vtf.hpp:103
uint32_t RedBitsPerPixel
Red bits per pixel.
Definition: Loader_mdl_hl2_vtf.hpp:95
uint8_t Padding0[4]
for 16 byte alignment
Definition: Loader_mdl_hl2_vtf.hpp:203
This class represents a VTF image file as documented at https://developer.valvesoftware.com/wiki/VTF.
Definition: Loader_mdl_hl2_vtf.hpp:298
The vtfImageFormatInfoT struct provides information about VTF image formats.
Definition: Loader_mdl_hl2_vtf.hpp:88
const char * Name
Enumeration text equivalent.
Definition: Loader_mdl_hl2_vtf.hpp:92
uint16_t Width
Width at the largest MipMap level.
Definition: Loader_mdl_hl2_vtf.hpp:198
char TypeString[4]
"VTF\0"
Definition: Loader_mdl_hl2_vtf.hpp:195
TransformProc pToTransform
Custom transform to function.
Definition: Loader_mdl_hl2_vtf.hpp:105
Definition: Loader_mdl_hl2_vtf.hpp:172
uint32_t Flags
As defined in vtfFlagsT.
Definition: Loader_mdl_hl2_vtf.hpp:200
This is the header for VTF files, covering all 7.x versions up to 7.5 (current).
Definition: Loader_mdl_hl2_vtf.hpp:191
uint8_t * GetData(uint32_t Frame, uint32_t Face, uint32_t Slice, uint32_t MipmapLevel) const
Returns a pointer to the image data for a given frame, face, z-slice and MIP level.
Definition: Loader_mdl_hl2_vtf.cpp:1078
uint16_t Height
Height at the largest MipMap level.
Definition: Loader_mdl_hl2_vtf.hpp:199
uint32_t BlueBitsPerPixel
Blue bits per pixel.
Definition: Loader_mdl_hl2_vtf.hpp:97
uint16_t GetDepth() const
Returns the depth (number of z-slices) of the image in pixels.
Definition: Loader_mdl_hl2_vtf.hpp:234
uint32_t GetVersion() const
Returns the file version times ten, e.g. 75 for the current version.
Definition: Loader_mdl_hl2_vtf.hpp:214
TransformProc pFromTransform
Custom transform from function.
Definition: Loader_mdl_hl2_vtf.hpp:106
int32_t IndexBlue
Blue index.
Definition: Loader_mdl_hl2_vtf.hpp:101
uint16_t NumFrames
It's a small movie if NumFrames > 1.
Definition: Loader_mdl_hl2_vtf.hpp:201
A class that is thrown on VTF load errors.
Definition: Loader_mdl_hl2_vtf.hpp:272
uint32_t AlphaBitsPerPixel
Alpha bits per pixel.
Definition: Loader_mdl_hl2_vtf.hpp:98
bool IsSupported
Format is supported by the implementation.
Definition: Loader_mdl_hl2_vtf.hpp:104
uint8_t ID[3]
Resource ID.
Definition: Loader_mdl_hl2_vtf.hpp:179
int32_t IndexRed
Red index.
Definition: Loader_mdl_hl2_vtf.hpp:99