Skip to content

Commit 031ce80

Browse files
authored
Merge pull request #842 from zeux/versions
vertex/indexcodec: Add meshopt_decodeVertex/IndexVersion
2 parents c8a8302 + 8805c18 commit 031ce80

File tree

5 files changed

+88
-5
lines changed

5 files changed

+88
-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();

gltf/parsegltf.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ static bool freeUnusedBuffers(cgltf_data* data)
518518

519519
static cgltf_result decompressMeshopt(cgltf_data* data)
520520
{
521+
bool warned = false;
522+
521523
for (size_t i = 0; i < data->buffer_views_count; ++i)
522524
{
523525
if (!data->buffer_views[i].has_meshopt_compression)
@@ -536,18 +538,22 @@ static cgltf_result decompressMeshopt(cgltf_data* data)
536538
data->buffer_views[i].data = result;
537539

538540
int rc = -1;
541+
bool warn = false;
539542

540543
switch (mc->mode)
541544
{
542545
case cgltf_meshopt_compression_mode_attributes:
546+
warn = meshopt_decodeVertexVersion(source, mc->size) != 0;
543547
rc = meshopt_decodeVertexBuffer(result, mc->count, mc->stride, source, mc->size);
544548
break;
545549

546550
case cgltf_meshopt_compression_mode_triangles:
551+
warn = meshopt_decodeIndexVersion(source, mc->size) != 1;
547552
rc = meshopt_decodeIndexBuffer(result, mc->count, mc->stride, source, mc->size);
548553
break;
549554

550555
case cgltf_meshopt_compression_mode_indices:
556+
warn = meshopt_decodeIndexVersion(source, mc->size) != 1;
551557
rc = meshopt_decodeIndexSequence(result, mc->count, mc->stride, source, mc->size);
552558
break;
553559

@@ -558,6 +564,12 @@ static cgltf_result decompressMeshopt(cgltf_data* data)
558564
if (rc != 0)
559565
return cgltf_result_io_error;
560566

567+
if (warn && !warned)
568+
{
569+
fprintf(stderr, "Warning: EXT_meshopt_compression data uses versions outside of the glTF specification (vertex 0 / index 1 expected)\n");
570+
warned = true;
571+
}
572+
561573
switch (mc->filter)
562574
{
563575
case cgltf_meshopt_compression_filter_octahedral:

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)