Quantize function missing in Windows .dll

Hi there. I’m currently writing a rust wrapper around the C API (here’s the repo), and the nvttContextQuantize function seems to be missing from the Windows .dll.

Hi mijalko, it’s fantastic to hear you’re putting together a Rust wrapper! Please let me know if there’s anything I can do to help.

Thank you for the bug report, that’s a good find! It’s now fixed in our trunk, and the fix will be in the next release.

It turned out the root cause was the C wrapper declared nvttContextQuantize() like this:

NVTT_API void nvttContextQuantize(const NvttContext * context, NvttSurface * tex, const NvttCompressionOptions * compressionOptions);

But when I was putting together the definition, I missed the const qualifier on the first argument:

void nvttContextQuantize(NvttContext * context, NvttSurface * tex, const NvttCompressionOptions * compressionOptions)

As a result, the nvttContextQuantize symbol was optimized out.

As a quick heads-up, we know of one other bug in the 3.1.6 NVTT C wrapper headers that will be fixed in the next release: the first two elements of the NvttError enum are out of order with respect to the nvtt::Error enum. The correct order should look like this:

typedef enum
{
	NVTT_Error_Unknown,
	NVTT_Error_InvalidInput,
	NVTT_Error_UnsupportedFeature,
	NVTT_Error_CudaError,
	NVTT_Error_FileOpen,
	NVTT_Error_FileWrite,
	NVTT_Error_UnsupportedOutputFormat,
	NVTT_Error_Count
} NvttError;

In 3.1.6, this should only affect the value passed to the OutputOptions error handler if the width, height, depth, or mipmap count are negative (in which case it should output 1, which is NVTT_Error_InvalidInput).

Hope this helps!

–Neil

Hi Neil, thanks for the detailed response! Good to hear it’ll be fixed in the next release. For the time being, I’ve chosen to just remove the quantize function from my wrapper.

As a side note, you asked if there’s anything that might help with my rust wrapper. As a bit of feedback, the two pain points I found were functions internally performing bitshifts, and file I/O.

There are many functions performing bitshifts internally, which cause undefined behaviour if values > 32 are passed in. I assume that they still perform bitshifts based on a previous open sourced version. But it’s not entirely clear what the lower/upper bounds are. Generally just documenting this more would be helpful.

Secondly, a major issue I’ve found is file I/O. To my knowledge, the character encoding of paths in NVTT must be ANSI/ASCII, but rust allows file paths to be any valid UTF8. This causes problems when functions ask for char *, as rust paths generally do not work the same as char *. This is further complicated because different operating systems have different path encoding schemes.

A very simple work around would be to allow file loading from raw bytes, e.g. nvttLoadFile(NvttSurface *img, const void *data, size_t len, format FileFormat), where img will be updated to hold the file data, data/size correspond to raw texture data, and format can be from an enum of all supported files, e.g. png, dds, etc. This removes any need for file paths. A similar function could exist such as nvttWriteFile for saving. Not sure if this API is necessarily correct, but anything that could keep file I/O in memory would be useful.