WoW Model Viewer
Your premiere tool for viewing, equipping and animating World of Warcraft models.
Loading...
Searching...
No Matches
ChunkReader.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cstdint>
5#include <cstring>
6#include <string>
7#include <vector>
8
17namespace ChunkReader
18{
20#pragma pack(push, 1)
22 {
23 char magic[4];
24 uint32_t size;
25 };
26#pragma pack(pop)
27
29 struct ChunkInfo
30 {
31 std::string magic;
32 uint32_t start;
33 uint32_t size;
34 };
35
39 inline const std::vector<std::string>& knownFirstChunks()
40 {
41 static const std::vector<std::string> chunks =
42 {
43 // M2 model chunks
44 "PFID", "SFID", "AFID", "BFID", "MD21",
45 "TXAC", "EXPT", "EXP2", "PABC", "PADC",
46 "PSBC", "PEDC", "SKID", "TXID", "LDV1",
47 // Animation / skeleton chunks
48 "AFM2", "AFSA", "AFSB",
49 "SKL1", "SKA1", "SKB1", "SKS1", "SKPD",
50 };
51 return chunks;
52 }
53
61 inline bool isChunked(const unsigned char* data, size_t dataSize)
62 {
63 if (!data || dataSize < sizeof(ChunkHeader))
64 return false;
65
66 ChunkHeader header{};
67 std::memcpy(&header, data, sizeof(ChunkHeader));
68
69 const std::string magic(header.magic, 4);
70 const auto& known = knownFirstChunks();
71 if (std::find(known.begin(), known.end(), magic) == known.end())
72 return false;
73
74 // The first chunk's data must fit within the file.
75 return (sizeof(ChunkHeader) + header.size) <= dataSize;
76 }
77
86 inline std::vector<ChunkInfo> parse(const unsigned char* data, size_t dataSize)
87 {
88 std::vector<ChunkInfo> result;
89
90 if (!data || dataSize < sizeof(ChunkHeader))
91 return result;
92
93 uint32_t offset = 0;
94 while (offset + sizeof(ChunkHeader) <= dataSize)
95 {
96 ChunkHeader header{};
97 std::memcpy(&header, data + offset, sizeof(ChunkHeader));
98 offset += sizeof(ChunkHeader);
99
100 // If the chunk data would exceed the buffer, stop.
101 if (offset + header.size > dataSize)
102 break;
103
104 ChunkInfo info;
105 info.magic = std::string(header.magic, 4);
106 info.start = offset;
107 info.size = header.size;
108 result.push_back(std::move(info));
109
110 offset += header.size;
111 }
112
113 return result;
114 }
115}
Standalone utility for parsing WoW chunk-based file formats.
Definition ChunkReader.h:18
const std::vector< std::string > & knownFirstChunks()
Definition ChunkReader.h:39
bool isChunked(const unsigned char *data, size_t dataSize)
Determine whether a buffer begins with a known chunked-file header.
Definition ChunkReader.h:61
std::vector< ChunkInfo > parse(const unsigned char *data, size_t dataSize)
Parse all top-level chunks from a buffer.
Definition ChunkReader.h:86
On-disk chunk header: 4-byte magic + 4-byte size.
Definition ChunkReader.h:22
Runtime representation of a single parsed chunk.
Definition ChunkReader.h:30
std::string magic
Four-character chunk identifier.
Definition ChunkReader.h:31
uint32_t start
Byte offset of the chunk data (after the header).
Definition ChunkReader.h:32
uint32_t size
Size of the chunk data in bytes.
Definition ChunkReader.h:33