SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
PSFrames.cpp
Go to the documentation of this file.
1// ReSharper disable CppRedundantQualifier
2
3#include <vtfpp/PSFrames.h>
4
5#include <BufferStream.h>
6#include <sourcepp/FS.h>
8#include <vtfpp/ImagePixel.h>
9
10using namespace sourcepp;
11using namespace vtfpp;
12
13PSFrames::PSFrames(std::vector<std::byte>&& psFramesData) {
14 this->data = std::move(psFramesData);
15 BufferStreamReadOnly stream{this->data};
16 stream
17 .read(this->frameCount)
18 .read(this->fps);
19
20 this->frames.reserve(this->frameCount);
21 for (uint32_t i = 0; i < this->frameCount; i++) {
22 auto& [width, height, paletteData, imageData] = this->frames.emplace_back();
23
24 if (stream.read<uint32_t>() != 65793) {
25 return;
26 }
27 stream.skip(1);
28 if (const auto palettePixelCount = stream.read<uint16_t>(); palettePixelCount != 256) {
29 return;
30 }
31 if (const auto palettePixelBits = stream.read<uint16_t>(); palettePixelBits != 24) {
32 return;
33 }
34 stream.skip(3) >> width >> height;
35 if (const auto paletteIndexBits = stream.read<uint8_t>(); paletteIndexBits != 8) {
36 return;
37 }
38 if (const auto decodedPixelBits = stream.read<uint16_t>(); decodedPixelBits != 32) {
39 return;
40 }
41
42 paletteData = stream.read_span<std::byte>(256 * sizeof(ImagePixel::BGR888)); // static_cast<uint32_t>(palettePixelCount) * palettePixelBits / 8
43 imageData = stream.read_span<std::byte>(width * height); // static_cast<uint32_t>(width) * height * paletteIndexBits / 8
44 }
45
46 this->opened = true;
47}
48
49PSFrames::PSFrames(std::span<const std::byte> psFramesData)
50 : PSFrames(std::vector<std::byte>{psFramesData.begin(), psFramesData.end()}) {}
51
52PSFrames::PSFrames(const std::filesystem::path& psFramesPath)
53 : PSFrames(fs::readFileBuffer(psFramesPath)) {}
54
55PSFrames::operator bool() const {
56 return this->opened;
57}
58
59uint32_t PSFrames::getFrameCount() const {
60 return this->frameCount;
61}
62
63uint32_t PSFrames::getFPS() const {
64 return this->fps;
65}
66
67uint16_t PSFrames::getWidth(uint32_t frame) const {
68 return this->frames.at(frame).width;
69}
70
71uint16_t PSFrames::getHeight(uint32_t frame) const {
72 return this->frames.at(frame).height;
73}
74
75std::span<const std::byte> PSFrames::getPaletteDataRaw(uint32_t frame) const {
76 return this->frames.at(frame).paletteData;
77}
78
79std::span<std::byte> PSFrames::getPaletteDataRaw(uint32_t frame) {
80 return this->frames.at(frame).paletteData;
81}
82
83std::vector<std::byte> PSFrames::getPaletteDataAs(ImageFormat newFormat, uint32_t frame) const {
84 return ImageConversion::convertImageDataToFormat(this->frames.at(frame).paletteData, ImageFormat::BGR888, newFormat, 16, 16);
85}
86
87std::span<const std::byte> PSFrames::getImageDataRaw(uint32_t frame) const {
88 return this->frames.at(frame).imageData;
89}
90
91std::span<std::byte> PSFrames::getImageDataRaw(uint32_t frame) {
92 return this->frames.at(frame).imageData;
93}
94
95std::vector<std::byte> PSFrames::getImageDataAs(ImageFormat newFormat, uint32_t frame) const {
96 const auto& frameData = this->frames.at(frame);
97 return ImageConversion::convertImageDataToFormat(this->getImageDataAsBGR888(frame), ImageFormat::BGR888, newFormat, frameData.width, frameData.height);
98}
99
100std::vector<std::byte> PSFrames::getImageDataAsBGR888(uint32_t frame) const {
101 const auto& [width, height, paletteData, imageData] = this->frames.at(frame);
102 const std::span palettePixelData{reinterpret_cast<const ImagePixel::BGR888*>(paletteData.data()), 256};
103
104 std::vector<std::byte> out;
105 out.resize(width * height * sizeof(ImagePixel::BGR888));
106 BufferStream stream{out};
107 for (uint32_t i = 0; i < width * height; i++) {
108 stream << palettePixelData[static_cast<uint8_t>(imageData[i])];
109 }
110 return out;
111}
uint32_t getFPS() const
Definition PSFrames.cpp:63
uint32_t getFrameCount() const
Definition PSFrames.cpp:59
std::span< const std::byte > getImageDataRaw(uint32_t frame) const
Definition PSFrames.cpp:87
std::vector< std::byte > data
Definition PSFrames.h:63
uint32_t fps
Definition PSFrames.h:61
uint16_t getHeight(uint32_t frame) const
Definition PSFrames.cpp:71
std::span< const std::byte > getPaletteDataRaw(uint32_t frame) const
Definition PSFrames.cpp:75
std::vector< Frame > frames
Definition PSFrames.h:64
std::vector< std::byte > getImageDataAsBGR888(uint32_t frame) const
Definition PSFrames.cpp:100
std::vector< std::byte > getPaletteDataAs(ImageFormat newFormat, uint32_t frame) const
Definition PSFrames.cpp:83
uint16_t getWidth(uint32_t frame) const
Definition PSFrames.cpp:67
std::vector< std::byte > getImageDataAs(ImageFormat newFormat, uint32_t frame) const
Definition PSFrames.cpp:95
PSFrames(std::vector< std::byte > &&psFramesData)
Definition PSFrames.cpp:13
uint32_t frameCount
Definition PSFrames.h:60
std::vector< std::byte > convertImageDataToFormat(std::span< const std::byte > imageData, ImageFormat oldFormat, ImageFormat newFormat, uint16_t width, uint16_t height, float quality=DEFAULT_COMPRESSED_QUALITY)
Converts an image from one format to another.