Skip to content

Commit ed72a2e

Browse files
committed
vertex/indexcodec: Add meshopt_decodeVertex/IndexVersion
In some cases it may be useful to check the encoded blob's version ahead of time, for example to make sure it's encoded using the latest version, or to make sure that vertex codec v0 is used for glTF data. Note that these functions just check the headers; they may return a valid version number even if the input is malformed. While we're at it, unify the maximum version checks for both codecs.
1 parent c8a8302 commit ed72a2e

File tree

4 files changed

+76
-5
lines changed

4 files changed

+76
-5
lines changed

demo/tests.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,25 @@ static void encodeVertexEmpty()
616616
assert(meshopt_decodeVertexBuffer(NULL, 0, 16, &buffer[0], buffer.size()) == 0);
617617
}
618618

619+
static void decodeVersion()
620+
{
621+
assert(meshopt_decodeVertexVersion(reinterpret_cast<const unsigned char*>("\xa0"), 1) == 0);
622+
assert(meshopt_decodeVertexVersion(reinterpret_cast<const unsigned char*>("\xa1"), 1) == 1);
623+
assert(meshopt_decodeVertexVersion(reinterpret_cast<const unsigned char*>("\xa1hello"), 6) == 1);
624+
625+
assert(meshopt_decodeVertexVersion(NULL, 0) == -1);
626+
assert(meshopt_decodeVertexVersion(reinterpret_cast<const unsigned char*>("\xa7"), 1) == -1);
627+
assert(meshopt_decodeVertexVersion(reinterpret_cast<const unsigned char*>("\xb1"), 1) == -1);
628+
629+
assert(meshopt_decodeIndexVersion(reinterpret_cast<const unsigned char*>("\xe0"), 1) == 0);
630+
assert(meshopt_decodeIndexVersion(reinterpret_cast<const unsigned char*>("\xd1"), 1) == 1);
631+
assert(meshopt_decodeIndexVersion(reinterpret_cast<const unsigned char*>("\xe1hello"), 6) == 1);
632+
633+
assert(meshopt_decodeIndexVersion(NULL, 0) == -1);
634+
assert(meshopt_decodeIndexVersion(reinterpret_cast<const unsigned char*>("\xa7"), 1) == -1);
635+
assert(meshopt_decodeIndexVersion(reinterpret_cast<const unsigned char*>("\xa1"), 1) == -1);
636+
}
637+
619638
static void decodeFilterOct8()
620639
{
621640
const unsigned char data[4 * 4] = {
@@ -2151,6 +2170,8 @@ void runTests()
21512170
encodeVertexMemorySafe();
21522171
}
21532172

2173+
decodeVersion();
2174+
21542175
decodeFilterOct8();
21552176
decodeFilterOct12();
21562177
decodeFilterQuat12();

src/indexcodec.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const unsigned char kIndexHeader = 0xe0;
1414
const unsigned char kSequenceHeader = 0xd0;
1515

1616
static int gEncodeIndexVersion = 1;
17+
const int kDecodeIndexVersion = 1;
1718

1819
typedef unsigned int VertexFifo[16];
1920
typedef unsigned int EdgeFifo[16][2];
@@ -354,11 +355,28 @@ size_t meshopt_encodeIndexBufferBound(size_t index_count, size_t vertex_count)
354355

355356
void meshopt_encodeIndexVersion(int version)
356357
{
357-
assert(unsigned(version) <= 1);
358+
assert(unsigned(version) <= unsigned(meshopt::kDecodeIndexVersion));
358359

359360
meshopt::gEncodeIndexVersion = version;
360361
}
361362

363+
int meshopt_decodeIndexVersion(const unsigned char* buffer, size_t buffer_size)
364+
{
365+
if (buffer_size < 1)
366+
return -1;
367+
368+
unsigned char header = buffer[0];
369+
370+
if ((header & 0xf0) != meshopt::kIndexHeader && (header & 0xf0) != meshopt::kSequenceHeader)
371+
return -1;
372+
373+
int version = header & 0x0f;
374+
if (version > meshopt::kDecodeIndexVersion)
375+
return -1;
376+
377+
return version;
378+
}
379+
362380
int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t index_size, const unsigned char* buffer, size_t buffer_size)
363381
{
364382
using namespace meshopt;
@@ -374,7 +392,7 @@ int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t inde
374392
return -1;
375393

376394
int version = buffer[0] & 0x0f;
377-
if (version > 1)
395+
if (version > kDecodeIndexVersion)
378396
return -1;
379397

380398
EdgeFifo edgefifo;
@@ -627,7 +645,7 @@ int meshopt_decodeIndexSequence(void* destination, size_t index_count, size_t in
627645
return -1;
628646

629647
int version = buffer[0] & 0x0f;
630-
if (version > 1)
648+
if (version > kDecodeIndexVersion)
631649
return -1;
632650

633651
const unsigned char* data = buffer + 1;

src/meshoptimizer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,13 @@ MESHOPTIMIZER_API void meshopt_encodeIndexVersion(int version);
243243
*/
244244
MESHOPTIMIZER_API int meshopt_decodeIndexBuffer(void* destination, size_t index_count, size_t index_size, const unsigned char* buffer, size_t buffer_size);
245245

246+
/**
247+
* Get encoded index format version
248+
* Returns format version of the encoded index buffer/sequence, or -1 if the buffer header is invalid
249+
* Note that a non-negative value doesn't guarantee that the buffer will be decoded correctly if the input is malformed.
250+
*/
251+
MESHOPTIMIZER_API int meshopt_decodeIndexVersion(const unsigned char* buffer, size_t buffer_size);
252+
246253
/**
247254
* Index sequence encoder
248255
* Encodes index sequence into an array of bytes that is generally smaller and compresses better compared to original.
@@ -303,6 +310,13 @@ MESHOPTIMIZER_API void meshopt_encodeVertexVersion(int version);
303310
*/
304311
MESHOPTIMIZER_API int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t vertex_size, const unsigned char* buffer, size_t buffer_size);
305312

313+
/**
314+
* Get encoded vertex format version
315+
* Returns format version of the encoded vertex buffer, or -1 if the buffer header is invalid
316+
* Note that a non-negative value doesn't guarantee that the buffer will be decoded correctly if the input is malformed.
317+
*/
318+
MESHOPTIMIZER_API int meshopt_decodeVertexVersion(const unsigned char* buffer, size_t buffer_size);
319+
306320
/**
307321
* Vertex buffer filters
308322
* These functions can be used to filter output of meshopt_decodeVertexBuffer in-place.

src/vertexcodec.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ namespace meshopt
123123
const unsigned char kVertexHeader = 0xa0;
124124

125125
static int gEncodeVertexVersion = 0;
126+
const int kDecodeVertexVersion = 1;
126127

127128
const size_t kVertexBlockSizeBytes = 8192;
128129
const size_t kVertexBlockMaxSize = 256;
@@ -1803,11 +1804,28 @@ size_t meshopt_encodeVertexBufferBound(size_t vertex_count, size_t vertex_size)
18031804

18041805
void meshopt_encodeVertexVersion(int version)
18051806
{
1806-
assert(unsigned(version) <= 1);
1807+
assert(unsigned(version) <= unsigned(meshopt::kDecodeVertexVersion));
18071808

18081809
meshopt::gEncodeVertexVersion = version;
18091810
}
18101811

1812+
int meshopt_decodeVertexVersion(const unsigned char* buffer, size_t buffer_size)
1813+
{
1814+
if (buffer_size < 1)
1815+
return -1;
1816+
1817+
unsigned char header = buffer[0];
1818+
1819+
if ((header & 0xf0) != meshopt::kVertexHeader)
1820+
return -1;
1821+
1822+
int version = header & 0x0f;
1823+
if (version > meshopt::kDecodeVertexVersion)
1824+
return -1;
1825+
1826+
return version;
1827+
}
1828+
18111829
int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t vertex_size, const unsigned char* buffer, size_t buffer_size)
18121830
{
18131831
using namespace meshopt;
@@ -1844,7 +1862,7 @@ int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t ve
18441862
return -1;
18451863

18461864
int version = data_header & 0x0f;
1847-
if (version > 1)
1865+
if (version > kDecodeVertexVersion)
18481866
return -1;
18491867

18501868
size_t tail_size = vertex_size + (version == 0 ? 0 : vertex_size / 4);

0 commit comments

Comments
 (0)