Skip to content

Commit ccd2ece

Browse files
committed
store ktx metdata in the images user data structure and remove the warning about orientation.
1 parent bdc9762 commit ccd2ece

1 file changed

Lines changed: 28 additions & 30 deletions

File tree

src/osgPlugins/ktx/ReaderWriterKTX.cpp

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313

1414
#include "ReaderWriterKTX.h"
1515
#include <osg/Endian>
16+
#include <osg/ValueObject>
1617
#include <osgDB/FileNameUtils>
1718
#include <osgDB/FileUtils>
1819
#include <istream>
1920
#include <vector>
2021
#include <cstring>
22+
#include <map>
2123

2224
// Macro similar to what's in FLT/TRP plugins (except it uses wide char under Windows if OSG_USE_UTF8_FILENAME)
2325
#if defined(_WIN32)
@@ -117,9 +119,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterKTX::readKTXStream(std::istream& fin
117119
if (header.numberOfMipmapLevels == 0)
118120
header.numberOfMipmapLevels = 1;
119121

120-
// Parse key-value metadata to check for KTXorientation
121-
bool hasValidOrientation = true; // Default to true for non-ASTC or when no metadata
122-
std::string ktxOrientation;
122+
// Parse key-value metadata
123+
std::map<std::string, std::string> ktxMetadata;
123124

124125
if (header.bytesOfKeyValueData > 0)
125126
{
@@ -158,20 +159,18 @@ osgDB::ReaderWriter::ReadResult ReaderWriterKTX::readKTXStream(std::istream& fin
158159
{
159160
key = std::string(kvData.data() + keyStart, keyEnd - keyStart);
160161

161-
// Check for KTXorientation (note: some files incorrectly use KTXOrientation)
162-
if (key == "KTXorientation" || key == "KTXOrientation")
163-
{
164-
size_t valueStart = keyEnd + 1;
165-
size_t valueSize = keyAndValueByteSize - (valueStart - keyStart);
166-
ktxOrientation = std::string(kvData.data() + valueStart, valueSize);
162+
// Extract the value (everything after the null terminator)
163+
size_t valueStart = keyEnd + 1;
164+
size_t valueSize = keyAndValueByteSize - (valueStart - keyStart);
165+
std::string value(kvData.data() + valueStart, valueSize);
167166

168-
// Remove any trailing null bytes
169-
size_t nullPos = ktxOrientation.find('\0');
170-
if (nullPos != std::string::npos)
171-
ktxOrientation = ktxOrientation.substr(0, nullPos);
167+
// Remove any trailing null bytes from the value
168+
size_t nullPos = value.find('\0');
169+
if (nullPos != std::string::npos)
170+
value = value.substr(0, nullPos);
172171

173-
OSG_INFO << "Found KTXorientation: " << ktxOrientation << std::endl;
174-
}
172+
// Store the metadata
173+
ktxMetadata[key] = value;
175174
}
176175

177176
// Align to 4 bytes
@@ -186,20 +185,6 @@ osgDB::ReaderWriter::ReadResult ReaderWriterKTX::readKTXStream(std::istream& fin
186185
fin.ignore(0);
187186
}
188187

189-
// Warn about orientation issues
190-
if (ktxOrientation.empty())
191-
{
192-
OSG_WARN << "KTX file lacks KTXorientation metadata. OpenSceneGraph expects KTX textures "
193-
<< "in OpenGL orientation (S=r,T=u). Textures created for DirectX/Vulkan (S=r,T=d) "
194-
<< "may appear vertically flipped." << std::endl;
195-
}
196-
else if (ktxOrientation == "S=r,T=d" || ktxOrientation == "S=r,T=d,R=i" || ktxOrientation == "S=r,T=d,R=o")
197-
{
198-
OSG_WARN << "KTX file has DirectX/Vulkan orientation (" << ktxOrientation
199-
<< "). OpenSceneGraph expects OpenGL orientation (S=r,T=u). "
200-
<< "Texture may appear vertically flipped." << std::endl;
201-
}
202-
203188
uint32_t imageSize;
204189
uint32_t totalImageSize = fileLength -
205190
(sizeof(KTXTexHeader) + header.bytesOfKeyValueData +
@@ -295,7 +280,13 @@ osgDB::ReaderWriter::ReadResult ReaderWriterKTX::readKTXStream(std::istream& fin
295280
// Set origin based on KTXorientation metadata
296281
// S=r,T=u means OpenGL orientation (bottom-left origin)
297282
// S=r,T=d means standard image orientation (top-left origin)
298-
if (ktxOrientation == "S=r,T=u" || ktxOrientation == "S=r,T=u,R=o")
283+
// Note: some files incorrectly use KTXOrientation with capital O
284+
auto orientIt = ktxMetadata.find("KTXorientation");
285+
if (orientIt == ktxMetadata.end())
286+
orientIt = ktxMetadata.find("KTXOrientation");
287+
288+
if (orientIt != ktxMetadata.end() &&
289+
(orientIt->second == "S=r,T=u" || orientIt->second == "S=r,T=u,R=o"))
299290
{
300291
image->setOrigin(osg::Image::BOTTOM_LEFT);
301292
}
@@ -308,6 +299,13 @@ osgDB::ReaderWriter::ReadResult ReaderWriterKTX::readKTXStream(std::istream& fin
308299
if (header.numberOfMipmapLevels > 1)
309300
image->setMipmapLevels(mipmapData);
310301

302+
// Store all KTX metadata in the image's userdata with "KTX:" prefix
303+
// This avoids conflicts with other OSG metadata
304+
for (const auto& kv : ktxMetadata)
305+
{
306+
image->setUserValue("KTX:" + kv.first, kv.second);
307+
}
308+
311309
return image.get();
312310
}
313311

0 commit comments

Comments
 (0)