From 3d918ef35f27ca3fa90eb9219cc929da4f2fcfe0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 Jun 2007 19:18:27 +0000 Subject: [PATCH] From Vladimir Shabanov, "DDS plugin now works with these formats: R3G3B2, R5G6B5, A1R5G5B5, X1R5G5B5, A4R4G4B4, X4R4G4B4, R8G8B8 (now without swaping of red and blue), A8R8G8B8 (also w/o swapping), X8R8G8B8, A8B8G8R8, X8B8G8R8, A2R10G10B10, A2B10G10R10, L4A4 (not work on my machine), L16A16, L16, A16B16G16R16, A16B16G16R16F, Q16W16V16U16, R32F, R16F and A32B32G32R32F. And these ones are correctly detected, but prints "unsupported" using osg::notify(osg::WARN) and are not loaded: A8R3G3B2, G16R16, G16R16F, G32R32F and CxV8U8. Also added checking of not supported DDPF_BUMPDUDV (V8U8, V16U16, Q8W8U8L8, A2W10U10V10 etc.) and DDPF_BUMPLUMINANCE (L6V5U5, X8L8V8U8, etc.) pixel formats. Mipmap handling is slightly modified and now support all additional formats. " --- src/osgPlugins/dds/ReaderWriterDDS.cpp | 267 +++++++++++++++++++++++-- 1 file changed, 246 insertions(+), 21 deletions(-) diff --git a/src/osgPlugins/dds/ReaderWriterDDS.cpp b/src/osgPlugins/dds/ReaderWriterDDS.cpp index 00d55c977..6489e4a25 100644 --- a/src/osgPlugins/dds/ReaderWriterDDS.cpp +++ b/src/osgPlugins/dds/ReaderWriterDDS.cpp @@ -24,6 +24,7 @@ #include #include +#include #include @@ -67,6 +68,7 @@ struct DDPIXELFORMAT UI32 dwYUVBitCount; UI32 dwZBufferBitDepth; UI32 dwAlphaBitDepth; + UI32 dwLuminanceBitDepth; }; union { @@ -189,6 +191,8 @@ struct DXT1TexelsBlock #define DDPF_ALPHA 0x00000002l #define DDPF_COMPRESSED 0x00000080l #define DDPF_LUMINANCE 0x00020000l +#define DDPF_BUMPLUMINANCE 0x00040000l // L,U,V +#define DDPF_BUMPDUDV 0x00080000l // U,V // // DDSCAPS flags @@ -266,6 +270,28 @@ osg::Image* ReadDDSFile(std::istream& _istream) unsigned int pixelFormat = 0; unsigned int internalFormat = 0; + // Handle some esoteric formats + if(ddsd.ddpfPixelFormat.dwFlags & DDPF_BUMPDUDV) + { + osg::notify(osg::WARN) << "ReadDDSFile warning: DDPF_BUMPDUDV format is not supported" << std::endl; + return NULL; +// ddsd.ddpfPixelFormat.dwFlags = +// DDPF_LUMINANCE + DDPF_ALPHAPIXELS; +// // handle V8U8 as A8L8 +// // handle V16U16 as A16L16 +// // but Q8W8U8L8 as RGB? +// // A2W10U10V10 as RGBA (dwFlags == DDPF_BUMPDUDV + DDPF_ALPHAPIXELS) + } + if(ddsd.ddpfPixelFormat.dwFlags & DDPF_BUMPLUMINANCE) + { + osg::notify(osg::WARN) << "ReadDDSFile warning: DDPF_BUMPLUMINANCE format is not supported" << std::endl; + return NULL; +// ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; +// // handle as RGB +// // L6V5U5 -- 655 is not supported data type in GL +// // X8L8V8U8 -- just as RGB + } + // Uncompressed formats will usually use DDPF_RGB to indicate an RGB format, // while compressed formats will use DDPF_FOURCC with a four-character code. @@ -275,38 +301,155 @@ osg::Image* ReadDDSFile(std::istream& _istream) // Uncompressed formats. if(ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB) { - switch(ddsd.ddpfPixelFormat.dwRGBBitCount) + struct RGBFormat { - case 32: - internalFormat = 4; - pixelFormat = GL_RGBA; - break; - case 24: - internalFormat = 3; - pixelFormat = GL_RGB; - break; - case 16: - default: - osg::notify(osg::WARN)<<"Warning:: unhandled pixel format in dds file, image not loaded"<> 8) + << (char)((ddsd.ddpfPixelFormat.dwFourCC & 0x00ff0000) >> 16) + << (char)((ddsd.ddpfPixelFormat.dwFourCC & 0xff000000) >> 24) + << " = 0x" << std::hex << std::setw(8) << std::setfill('0') + << ddsd.ddpfPixelFormat.dwFourCC << std::dec + << ") in dds file, image not loaded." << std::endl; return NULL; } } else { - osg::notify(osg::WARN)<<"Warning:: unhandled pixel format in dds file, image not loaded."<setMipmapData(mipmaps); } // Handle uncompressed mipmaps - if(ddsd.ddpfPixelFormat.dwFlags & (DDPF_RGB | DDPF_LUMINANCE | DDPF_ALPHA)) + else { int offset = 0; int width = ddsd.dwWidth; @@ -416,7 +637,8 @@ osg::Image* ReadDDSFile(std::istream& _istream) width = 1; if (height == 0) height = 1; - offset += (width*height*(ddsd.ddpfPixelFormat.dwRGBBitCount/8)); + offset += height * + osg::Image::computeRowWidthInBytes( width, pixelFormat, dataType, 1 ); mipmaps[k-1] = offset; width >>= 1; height >>= 1; @@ -425,19 +647,22 @@ osg::Image* ReadDDSFile(std::istream& _istream) } } - osgImage->setImage(s,t,r, internalFormat, pixelFormat, dataType, 0, osg::Image::USE_NEW_DELETE); if (mipmaps.size()>0) osgImage->setMipmapLevels(mipmaps); unsigned int size = osgImage->getTotalSizeInBytesIncludingMipmaps(); + osg::notify(osg::INFO) << "ReadDDSFile info : size = " << size << std::endl; + if(size <= 0) { + osg::notify(osg::WARN) << "ReadDDSFile warning: size <= 0" << std::endl; return NULL; } unsigned char* imageData = new unsigned char [size]; if(!imageData) { + osg::notify(osg::WARN) << "ReadDDSFile warning: imageData == NULL" << std::endl; return NULL; }