SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
VTF.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstddef>
5#include <span>
6#include <string>
7#include <tuple>
8#include <utility>
9#include <variant>
10#include <vector>
11
13#include <sourcepp/Macros.h>
14
15#include "HOT.h"
16#include "ImageConversion.h"
17#include "SHT.h"
18
19namespace vtfpp {
20
25
26enum class CompressionMethod : int16_t {
27 // Strata Source v7.6 defines
28 DEFLATE = 8,
29 ZSTD = 93,
30
31 // Signify the image resource should be compressed with LZMA on console
32 CONSOLE_LZMA = 0x360,
33};
34
35struct Resource {
36 enum Type : uint32_t {
37 TYPE_UNKNOWN = 0, // Unknown
39 TYPE_PALETTE_DATA = 2, // Hack for XBOX platform
40 TYPE_FALLBACK_DATA = 3, // Hack for XBOX platform
49 };
50 static consteval std::array<Type, 11> getOrder() {
51 return {
57 // regular Source can't handle out of order resources, but Strata can,
58 // and it's the only branch that can read this and 7.6.
59 // Put this before the image data to fix resources being cut off when skipping mips
66 };
67 }
68
69 enum Flags : uint8_t {
72 };
73
76 std::span<std::byte> data;
77
78 using ConvertedData = std::variant<
79 std::monostate, // Anything that would be equivalent to just returning data directly, or used as an error
80 SHT, // Particle Sheet
81 uint32_t, // CRC, TS0
82 std::tuple<uint8_t, uint8_t, uint8_t, uint8_t>, // LOD
83 std::string, // KVD
84 HOT // Hotspot data
85 >;
86 [[nodiscard]] ConvertedData convertData() const;
87
88 [[nodiscard]] std::vector<std::byte> getDataAsPalette(uint16_t frame) const {
89 static constexpr auto PALETTE_FRAME_SIZE = 256 * sizeof(ImagePixel::BGRA8888);
90 if (this->data.size() % PALETTE_FRAME_SIZE != 0 || PALETTE_FRAME_SIZE * frame > this->data.size()) {
91 return {};
92 }
93 return {this->data.data() + PALETTE_FRAME_SIZE * frame, this->data.data() + PALETTE_FRAME_SIZE * (frame + 1)};
94 }
95
96 [[nodiscard]] SHT getDataAsParticleSheet() const {
97 return std::get<SHT>(this->convertData());
98 }
99
100 [[nodiscard]] uint32_t getDataAsCRC() const {
101 return std::get<uint32_t>(this->convertData());
102 }
103
104 [[nodiscard]] uint32_t getDataAsExtendedFlags() const {
105 return std::get<uint32_t>(this->convertData());
106 }
107
108 [[nodiscard]] std::tuple<uint8_t, uint8_t, uint8_t, uint8_t> getDataAsLODControlInfo() const {
109 return std::get<std::tuple<uint8_t, uint8_t, uint8_t, uint8_t>>(this->convertData());
110 }
111
112 [[nodiscard]] std::string getDataAsKeyValuesData() const {
113 return std::get<std::string>(this->convertData());
114 }
115
116 [[nodiscard]] HOT getDataAsHotspotData() const {
117 return std::get<HOT>(this->convertData());
118 }
119
120 [[nodiscard]] int16_t getDataAsAuxCompressionLevel() const {
121 if (this->data.size() < sizeof(uint32_t) * 2) {
122 return 0;
123 }
124 return static_cast<int16_t>(BufferStream{this->data}.skip<uint32_t>().read<uint32_t>() & 0xffff);
125 }
126
128 if (this->data.size() < sizeof(uint32_t) * 2) {
130 }
131 const auto method = static_cast<int16_t>((BufferStream{this->data}.skip<uint32_t>().read<uint32_t>() & 0xffff0000) >> 16);
132 if (method <= 0) {
134 }
135 return static_cast<CompressionMethod>(method);
136 }
137
138 [[nodiscard]] uint32_t getDataAsAuxCompressionLength(uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint16_t face, uint16_t faceCount) const {
139 if (this->data.size() < ((mipCount - 1 - mip) * frameCount * faceCount + frame * faceCount + face + 2) * sizeof(uint32_t)) {
140 return 0;
141 }
142 return BufferStream{this->data}.skip<uint32_t>((mipCount - 1 - mip) * frameCount * faceCount + frame * faceCount + face + 2).read<uint32_t>();
143 }
144};
146
147/*
148 * === EASY DIFFICULTY WRITER API ===
149 *
150 * Use a static helper function to create a VTF in one function call - VTF::create
151 *
152 * === MEDIUM DIFFICULTY WRITER API ===
153 *
154 * Constructing a VTF instance from existing VTF data will let you modify that data.
155 *
156 * When constructing a VTF instance from scratch, this class has methods that should be
157 * called in a particular order. If they aren't your output VTF will look incorrect or
158 * have heavy artifacting. Some of these steps are optional, but the steps actually taken
159 * should be done in this order. Reference VTF::create and VTF::createInternal to see the
160 * intended "order of operations".
161 */
162class VTF {
163public:
164 enum Flags : uint32_t {
165 FLAG_V0_POINT_SAMPLE = 1u << 0,
166 FLAG_V0_TRILINEAR = 1u << 1,
167 FLAG_V0_CLAMP_S = 1u << 2,
168 FLAG_V0_CLAMP_T = 1u << 3,
169 FLAG_V0_ANISOTROPIC = 1u << 4,
170 FLAG_V0_VTEX_HINT_DXT5 = 1u << 5, // Internal to vtex
171 FLAG_V0_VTEX_NO_COMPRESS = 1u << 6, // Internal to vtex
172 FLAG_V0_NORMAL = 1u << 7,
173 FLAG_V0_NO_MIP = 1u << 8, // Controlled by mip count
174 FLAG_V0_NO_LOD = 1u << 9,
175 FLAG_V0_LOAD_SMALL_MIPS = 1u << 10,
176 FLAG_V0_PROCEDURAL = 1u << 11,
177 FLAG_V0_ONE_BIT_ALPHA = 1u << 12,
178 FLAG_V0_MULTI_BIT_ALPHA = 1u << 13,
179 FLAG_V0_ENVMAP = 1u << 14, // Controlled by face count
180 FLAG_MASK_V0 = FLAG_V0_POINT_SAMPLE | FLAG_V0_TRILINEAR | FLAG_V0_CLAMP_S | FLAG_V0_CLAMP_T | FLAG_V0_ANISOTROPIC | FLAG_V0_VTEX_HINT_DXT5 | FLAG_V0_VTEX_NO_COMPRESS | FLAG_V0_NORMAL | FLAG_V0_NO_MIP | FLAG_V0_NO_LOD | FLAG_V0_LOAD_SMALL_MIPS | FLAG_V0_PROCEDURAL | FLAG_V0_ONE_BIT_ALPHA | FLAG_V0_MULTI_BIT_ALPHA | FLAG_V0_ENVMAP,
181 FLAG_MASK_V0_VTEX = FLAG_V0_VTEX_HINT_DXT5 | FLAG_V0_VTEX_NO_COMPRESS,
182
183 FLAG_V1_RENDERTARGET = 1u << 15,
184 FLAG_V1_DEPTH_RENDERTARGET = 1u << 16,
185 FLAG_V1_NO_DEBUG_OVERRIDE = 1u << 17,
186 FLAG_V1_SINGLE_COPY = 1u << 18,
187 FLAG_V1_VTEX_ONE_OVER_MIP_LEVEL_IN_ALPHA = 1u << 19, // Internal to vtex
188 FLAG_V1_VTEX_PREMULTIPLY_COLOR_BY_ONE_OVER_MIP_LEVEL = 1u << 20, // Internal to vtex
189 FLAG_V1_VTEX_CONVERT_NORMAL_TO_DUDV = 1u << 21, // Internal to vtex
190 FLAG_MASK_V1 = FLAG_V1_RENDERTARGET | FLAG_V1_DEPTH_RENDERTARGET | FLAG_V1_NO_DEBUG_OVERRIDE | FLAG_V1_SINGLE_COPY | FLAG_V1_VTEX_ONE_OVER_MIP_LEVEL_IN_ALPHA | FLAG_V1_VTEX_PREMULTIPLY_COLOR_BY_ONE_OVER_MIP_LEVEL | FLAG_V1_VTEX_CONVERT_NORMAL_TO_DUDV,
191 FLAG_MASK_V1_VTEX = FLAG_V1_VTEX_ONE_OVER_MIP_LEVEL_IN_ALPHA | FLAG_V1_VTEX_PREMULTIPLY_COLOR_BY_ONE_OVER_MIP_LEVEL | FLAG_V1_VTEX_CONVERT_NORMAL_TO_DUDV,
192
193 FLAG_V2_VTEX_ALPHA_TEST_MIP_GENERATION = 1u << 22, // Internal to vtex
194 FLAG_V2_NO_DEPTH_BUFFER = 1u << 23,
195 FLAG_V2_VTEX_NICE_FILTERED = 1u << 24, // Internal to vtex
196 FLAG_V2_CLAMP_U = 1u << 25,
197 FLAG_MASK_V2 = FLAG_V2_VTEX_ALPHA_TEST_MIP_GENERATION | FLAG_V2_NO_DEPTH_BUFFER | FLAG_V2_VTEX_NICE_FILTERED | FLAG_V2_CLAMP_U,
198 FLAG_MASK_V2_VTEX = FLAG_V2_VTEX_ALPHA_TEST_MIP_GENERATION | FLAG_V2_VTEX_NICE_FILTERED,
199
200 FLAG_XBOX_VTEX_PRESWIZZLED = 1u << 26,
201 FLAG_XBOX_CACHEABLE = 1u << 27,
202 FLAG_XBOX_UNFILTERABLE_OK = 1u << 28,
203 FLAG_MASK_XBOX = FLAG_XBOX_VTEX_PRESWIZZLED | FLAG_XBOX_CACHEABLE | FLAG_XBOX_UNFILTERABLE_OK,
204 FLAG_MASK_XBOX_VTEX = FLAG_XBOX_VTEX_PRESWIZZLED,
205
206 FLAG_V3_LOAD_ALL_MIPS = 1u << 10,
207 FLAG_V3_VERTEX_TEXTURE = 1u << 26,
208 FLAG_V3_SSBUMP = 1u << 27,
209 FLAG_V3_BORDER = 1u << 29,
210 FLAG_MASK_V3 = FLAG_V3_LOAD_ALL_MIPS | FLAG_V3_VERTEX_TEXTURE | FLAG_V3_SSBUMP | FLAG_V3_BORDER,
211
212 FLAG_V4_SRGB = 1u << 6,
213 FLAG_MASK_V4 = FLAG_V4_SRGB,
214
215 FLAG_V4_TF2_STAGING_MEMORY = 1u << 19,
216 FLAG_V4_TF2_IMMEDIATE_CLEANUP = 1u << 20,
217 FLAG_V4_TF2_IGNORE_PICMIP = 1u << 21,
218 FLAG_V4_TF2_STREAMABLE_COARSE = 1u << 30,
219 FLAG_V4_TF2_STREAMABLE_FINE = 1u << 31,
220 FLAG_MASK_V4_TF2 = FLAG_V4_TF2_STAGING_MEMORY | FLAG_V4_TF2_IMMEDIATE_CLEANUP | FLAG_V4_TF2_IGNORE_PICMIP | FLAG_V4_TF2_STREAMABLE_COARSE | FLAG_V4_TF2_STREAMABLE_FINE,
221
222 FLAG_V5_PWL_CORRECTED = 1u << 6,
223 FLAG_V5_SRGB = 1u << 19,
224 FLAG_V5_DEFAULT_POOL = 1u << 20,
225 FLAG_V5_LOAD_MOST_MIPS = 1u << 28,
226 FLAG_MASK_V5 = FLAG_V5_PWL_CORRECTED | FLAG_V5_SRGB | FLAG_V5_DEFAULT_POOL | FLAG_V5_LOAD_MOST_MIPS,
227
228 FLAG_V5_CSGO_COMBINED = 1u << 21,
229 FLAG_V5_CSGO_ASYNC_DOWNLOAD = 1u << 22,
230 FLAG_V5_CSGO_SKIP_INITIAL_DOWNLOAD = 1u << 24,
231 FLAG_V5_CSGO_YCOCG = 1u << 30,
232 FLAG_V5_CSGO_ASYNC_SKIP_INITIAL_LOW_RES = 1u << 31,
233 FLAG_MASK_V5_CSGO = FLAG_V5_CSGO_COMBINED | FLAG_V5_CSGO_ASYNC_DOWNLOAD | FLAG_V5_CSGO_SKIP_INITIAL_DOWNLOAD | FLAG_V5_CSGO_YCOCG | FLAG_V5_CSGO_ASYNC_SKIP_INITIAL_LOW_RES,
234
235 FLAG_MASK_INTERNAL = FLAG_V0_NO_MIP | FLAG_V0_ENVMAP,
236 };
237
238 enum Platform : uint32_t {
239 PLATFORM_UNKNOWN = 0x000,
240 PLATFORM_PC = 0x007,
241 PLATFORM_XBOX = 0x005,
242 PLATFORM_X360 = 0x360,
243 PLATFORM_PS3_ORANGEBOX = 0x333,
244 PLATFORM_PS3_PORTAL2 = 0x334,
245 };
246
248 uint32_t version = 4;
249 ImageFormat outputFormat = FORMAT_DEFAULT;
250 float compressedFormatQuality = ImageConversion::DEFAULT_COMPRESSED_QUALITY;
251 ImageConversion::ResizeMethod widthResizeMethod = ImageConversion::ResizeMethod::POWER_OF_TWO_BIGGER;
252 ImageConversion::ResizeMethod heightResizeMethod = ImageConversion::ResizeMethod::POWER_OF_TWO_BIGGER;
253 ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT;
254 uint32_t flags = 0;
255 uint16_t initialFrameCount = 1;
256 uint16_t startFrame = 0;
257 bool isCubeMap = false;
258 uint16_t initialDepth = 1;
259 bool computeTransparencyFlags = true;
260 bool computeMips = true;
261 bool computeThumbnail = true;
262 bool computeReflectivity = true;
263 Platform platform = PLATFORM_PC;
264 int16_t compressionLevel = -1;
265 CompressionMethod compressionMethod = CompressionMethod::ZSTD;
266 float bumpMapScale = 1.f;
267 float gammaCorrection = 1.f;
268 bool invertGreenChannel = false;
269 uint8_t consoleMipScale = 0;
270 };
271
273 static constexpr auto FORMAT_UNCHANGED = static_cast<ImageFormat>(-2);
274
276 static constexpr auto FORMAT_DEFAULT = static_cast<ImageFormat>(-1);
277
278 VTF();
279
280 explicit VTF(std::vector<std::byte>&& vtfData, bool parseHeaderOnly = false);
281
282 explicit VTF(std::span<const std::byte> vtfData, bool parseHeaderOnly = false);
283
284 explicit VTF(const std::string& vtfPath, bool parseHeaderOnly = false);
285
286 VTF(const VTF& other);
287
288 VTF& operator=(const VTF& other);
289
290 VTF(VTF&&) noexcept = default;
291
292 VTF& operator=(VTF&&) noexcept = default;
293
294 [[nodiscard]] explicit operator bool() const;
295
296 static bool create(std::span<const std::byte> imageData, ImageFormat format, uint16_t width, uint16_t height, const std::string& vtfPath, const CreationOptions& options);
297
298 static bool create(ImageFormat format, uint16_t width, uint16_t height, const std::string& vtfPath, const CreationOptions& options);
299
300 [[nodiscard]] static VTF create(std::span<const std::byte> imageData, ImageFormat format, uint16_t width, uint16_t height, const CreationOptions& options);
301
302 [[nodiscard]] static VTF create(ImageFormat format, uint16_t width, uint16_t height, const CreationOptions& options);
303
304 static bool create(const std::string& imagePath, const std::string& vtfPath, const CreationOptions& options);
305
306 [[nodiscard]] static VTF create(const std::string& imagePath, const CreationOptions& options);
307
308 [[nodiscard]] Platform getPlatform() const;
309
310 void setPlatform(Platform newPlatform);
311
312 [[nodiscard]] uint32_t getVersion() const;
313
314 void setVersion(uint32_t newVersion);
315
316 [[nodiscard]] ImageConversion::ResizeMethod getImageWidthResizeMethod() const;
317
318 [[nodiscard]] ImageConversion::ResizeMethod getImageHeightResizeMethod() const;
319
320 void setImageResizeMethods(ImageConversion::ResizeMethod imageWidthResizeMethod_, ImageConversion::ResizeMethod imageHeightResizeMethod_);
321
322 void setImageWidthResizeMethod(ImageConversion::ResizeMethod imageWidthResizeMethod_);
323
324 void setImageHeightResizeMethod(ImageConversion::ResizeMethod imageHeightResizeMethod_);
325
326 [[nodiscard]] uint16_t getWidth(uint8_t mip = 0) const;
327
328 [[nodiscard]] uint16_t getHeight(uint8_t mip = 0) const;
329
330 void setSize(uint16_t newWidth, uint16_t newHeight, ImageConversion::ResizeFilter filter);
331
332 [[nodiscard]] uint32_t getFlags() const;
333
334 void setFlags(uint32_t flags_);
335
336 void addFlags(uint32_t flags_);
337
338 void removeFlags(uint32_t flags_);
339
340 [[nodiscard]] bool isSRGB() const;
341
342 void setSRGB(bool srgb);
343
344 void computeTransparencyFlags();
345
346 [[nodiscard]] static ImageFormat getDefaultCompressedFormat(ImageFormat inputFormat, uint32_t version, bool isCubeMap);
347
348 [[nodiscard]] ImageFormat getFormat() const;
349
350 void setFormat(ImageFormat newFormat, ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
351
352 [[nodiscard]] uint8_t getMipCount() const;
353
354 bool setMipCount(uint8_t newMipCount);
355
356 bool setRecommendedMipCount();
357
358 void computeMips(ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT);
359
360 [[nodiscard]] uint16_t getFrameCount() const;
361
362 bool setFrameCount(uint16_t newFrameCount);
363
364 [[nodiscard]] uint8_t getFaceCount() const;
365
366 bool setFaceCount(bool isCubeMap);
367
368 [[nodiscard]] uint16_t getDepth() const;
369
370 bool setDepth(uint16_t newDepth);
371
372 bool setFrameFaceAndDepth(uint16_t newFrameCount, bool isCubeMap, uint16_t newDepth = 1);
373
374 [[nodiscard]] uint16_t getStartFrame() const;
375
376 void setStartFrame(uint16_t newStartFrame);
377
378 [[nodiscard]] sourcepp::math::Vec3f getReflectivity() const;
379
380 void setReflectivity(sourcepp::math::Vec3f newReflectivity);
381
382 void computeReflectivity();
383
384 [[nodiscard]] float getBumpMapScale() const;
385
386 void setBumpMapScale(float newBumpMapScale);
387
388 [[nodiscard]] ImageFormat getThumbnailFormat() const;
389
390 [[nodiscard]] uint8_t getThumbnailWidth() const;
391
392 [[nodiscard]] uint8_t getThumbnailHeight() const;
393
394 [[nodiscard]] uint8_t getFallbackWidth() const;
395
396 [[nodiscard]] uint8_t getFallbackHeight() const;
397
398 [[nodiscard]] uint8_t getFallbackMipCount() const;
399
400 [[nodiscard]] const std::vector<Resource>& getResources() const;
401
402 [[nodiscard]] const Resource* getResource(Resource::Type type) const;
403
404 [[nodiscard]] std::vector<std::byte> getPaletteResourceFrame(uint16_t frame = 0) const;
405
407 [[nodiscard]] std::vector<std::byte> getParticleSheetFrameDataRaw(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
408
410 [[nodiscard]] std::vector<std::byte> getParticleSheetFrameDataAs(ImageFormat newFormat, uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
411
413 [[nodiscard]] std::vector<std::byte> getParticleSheetFrameDataAsRGBA8888(uint16_t& spriteWidth, uint16_t& spriteHeight, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds = 0, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
414
415 void setParticleSheetResource(const SHT& value);
416
417 void removeParticleSheetResource();
418
419 void setCRCResource(uint32_t value);
420
421 void removeCRCResource();
422
423 void setLODResource(uint8_t u, uint8_t v, uint8_t u360 = 0, uint8_t v360 = 0);
424
425 void removeLODResource();
426
427 void setExtendedFlagsResource(uint32_t value);
428
429 void removeExtendedFlagsResource();
430
431 void setKeyValuesDataResource(const std::string& value);
432
433 void removeKeyValuesDataResource();
434
435 void setHotspotDataResource(const HOT& value);
436
437 void removeHotspotDataResource();
438
439 [[nodiscard]] int16_t getCompressionLevel() const;
440
441 void setCompressionLevel(int16_t newCompressionLevel);
442
443 [[nodiscard]] CompressionMethod getCompressionMethod() const;
444
445 void setCompressionMethod(CompressionMethod newCompressionMethod);
446
447 [[nodiscard]] bool hasImageData() const;
448
449 [[nodiscard]] std::span<const std::byte> getImageDataRaw(uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
450
451 [[nodiscard]] std::vector<std::byte> getImageDataAs(ImageFormat newFormat, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
452
453 [[nodiscard]] std::vector<std::byte> getImageDataAsRGBA8888(uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0) const;
454
455 bool setImage(std::span<const std::byte> imageData_, ImageFormat format_, uint16_t width_, uint16_t height_, ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
456
457 bool setImage(const std::string& imagePath, ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
458
459 [[nodiscard]] std::vector<std::byte> saveImageToFile(uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0, ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const;
460
461 bool saveImageToFile(const std::string& imagePath, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, uint16_t slice = 0, ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const; // NOLINT(*-use-nodiscard)
462
463 [[nodiscard]] bool hasThumbnailData() const;
464
465 [[nodiscard]] std::span<const std::byte> getThumbnailDataRaw() const;
466
467 [[nodiscard]] std::vector<std::byte> getThumbnailDataAs(ImageFormat newFormat) const;
468
469 [[nodiscard]] std::vector<std::byte> getThumbnailDataAsRGBA8888() const;
470
471 void setThumbnail(std::span<const std::byte> imageData_, ImageFormat format_, uint16_t width_, uint16_t height_, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
472
473 bool setThumbnail(const std::string& imagePath, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY); // NOLINT(*-use-nodiscard)
474
475 void computeThumbnail(ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
476
477 void removeThumbnail();
478
479 [[nodiscard]] std::vector<std::byte> saveThumbnailToFile(ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const;
480
481 bool saveThumbnailToFile(const std::string& imagePath, ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const; // NOLINT(*-use-nodiscard)
482
483 [[nodiscard]] bool hasFallbackData() const;
484
485 [[nodiscard]] std::span<const std::byte> getFallbackDataRaw(uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0) const;
486
487 [[nodiscard]] std::vector<std::byte> getFallbackDataAs(ImageFormat newFormat, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0) const;
488
489 [[nodiscard]] std::vector<std::byte> getFallbackDataAsRGBA8888(uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0) const;
490
491 void computeFallback(ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT);
492
493 void removeFallback();
494
495 [[nodiscard]] std::vector<std::byte> saveFallbackToFile(uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const;
496
497 bool saveFallbackToFile(const std::string& imagePath, uint8_t mip = 0, uint16_t frame = 0, uint8_t face = 0, ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const; // NOLINT(*-use-nodiscard)
498
499 [[nodiscard]] uint8_t getConsoleMipScale() const;
500
501 void setConsoleMipScale(uint8_t consoleMipScale_);
502
503 [[nodiscard]] uint64_t estimateBakeSize() const;
504
505 [[nodiscard]] uint64_t estimateBakeSize(bool& isExact) const;
506
507 [[nodiscard]] std::vector<std::byte> bake() const;
508
509 bool bake(const std::string& vtfPath) const; // NOLINT(*-use-nodiscard)
510
511protected:
512 static bool createInternal(VTF& writer, CreationOptions options);
513
514 [[nodiscard]] Resource* getResourceInternal(Resource::Type type);
515
516 void setResourceInternal(Resource::Type type, std::span<const std::byte> data_);
517
518 void removeResourceInternal(Resource::Type type);
519
520 void regenerateImageData(ImageFormat newFormat, uint16_t newWidth, uint16_t newHeight, uint8_t newMipCount, uint16_t newFrameCount, uint8_t newFaceCount, uint16_t newDepth, ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
521
522 bool opened = false;
523
524 std::vector<std::byte> data;
525
526 uint32_t version = 4;
527
528 uint16_t width = 0;
529 uint16_t height = 0;
530 uint32_t flags = FLAG_V0_NO_MIP | FLAG_V0_NO_LOD;
531
532 uint16_t frameCount = 1;
533 uint16_t startFrame = 0;
534
535 sourcepp::math::Vec3f reflectivity{0.2f, 0.2f, 0.2f};
536
537 float bumpMapScale = 0.f;
539 uint8_t mipCount = 1;
540
542 uint8_t thumbnailWidth = 0;
543 uint8_t thumbnailHeight = 0;
544
545 uint8_t fallbackWidth = 0;
546 uint8_t fallbackHeight = 0;
547 uint8_t fallbackMipCount = 0;
548
549 // Number of times to multiply the scale of each mip by 2 when rendering on console
550 uint8_t consoleMipScale = 0;
551
552 // 1 for v7.1 and lower
553 uint16_t depth = 1;
554
555 // Technically added in v7.3, but we use it to store image and thumbnail data in v7.2 and lower anyway
556 std::vector<Resource> resources;
557
558 // These aren't in the header
559 Platform platform = PLATFORM_PC;
560 int16_t compressionLevel = 0;
564};
566
567} // namespace vtfpp
#define SOURCEPP_BITFLAGS_ENUM(Enum)
Defines bitwise operators for an enum or enum class.
Definition: Macros.h:26
Definition: HOT.h:13
Definition: SHT.h:13
Platform
Definition: VTF.h:238
VTF(VTF &&) noexcept=default
std::vector< Resource > resources
Definition: VTF.h:556
consteval uint32_t makeFourCC(const char fourCC[4])
Creates a FourCC identifier from a string of 4 characters.
Definition: Binary.h:18
Definition: LZMA.h:11
Definition: HOT.h:11
constexpr uint32_t VTF_SIGNATURE
Definition: VTF.h:21
constexpr uint32_t XTF_SIGNATURE
Definition: VTF.h:22
constexpr uint32_t VTFX_SIGNATURE
Definition: VTF.h:23
constexpr uint32_t VTF3_SIGNATURE
Definition: VTF.h:24
CompressionMethod
Definition: VTF.h:26
ImageFormat
Definition: ImageFormats.h:7
std::variant< std::monostate, SHT, uint32_t, std::tuple< uint8_t, uint8_t, uint8_t, uint8_t >, std::string, HOT > ConvertedData
Definition: VTF.h:85
SHT getDataAsParticleSheet() const
Definition: VTF.h:96
CompressionMethod getDataAsAuxCompressionMethod() const
Definition: VTF.h:127
uint32_t getDataAsAuxCompressionLength(uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint16_t face, uint16_t faceCount) const
Definition: VTF.h:138
Type type
Definition: VTF.h:74
ConvertedData convertData() const
Definition: VTF.cpp:230
static consteval std::array< Type, 11 > getOrder()
Definition: VTF.h:50
std::tuple< uint8_t, uint8_t, uint8_t, uint8_t > getDataAsLODControlInfo() const
Definition: VTF.h:108
std::string getDataAsKeyValuesData() const
Definition: VTF.h:112
uint32_t getDataAsCRC() const
Definition: VTF.h:100
uint32_t getDataAsExtendedFlags() const
Definition: VTF.h:104
@ FLAG_LOCAL_DATA
Definition: VTF.h:71
@ FLAG_NONE
Definition: VTF.h:70
std::vector< std::byte > getDataAsPalette(uint16_t frame) const
Definition: VTF.h:88
int16_t getDataAsAuxCompressionLevel() const
Definition: VTF.h:120
HOT getDataAsHotspotData() const
Definition: VTF.h:116
@ TYPE_KEYVALUES_DATA
Definition: VTF.h:48
@ TYPE_FALLBACK_DATA
Definition: VTF.h:40
@ TYPE_CRC
Definition: VTF.h:45
@ TYPE_PALETTE_DATA
Definition: VTF.h:39
@ TYPE_PARTICLE_SHEET_DATA
Definition: VTF.h:41
@ TYPE_EXTENDED_FLAGS
Definition: VTF.h:44
@ TYPE_UNKNOWN
Definition: VTF.h:37
@ TYPE_IMAGE_DATA
Definition: VTF.h:43
@ TYPE_AUX_COMPRESSION
Definition: VTF.h:46
@ TYPE_LOD_CONTROL_INFO
Definition: VTF.h:47
@ TYPE_THUMBNAIL_DATA
Definition: VTF.h:38
@ TYPE_HOTSPOT_DATA
Definition: VTF.h:42
Flags flags
Definition: VTF.h:75
std::span< std::byte > data
Definition: VTF.h:76