Hi all,
As discussed in the "HDRloader error" thread, I've started a little
program that tests every (potentially valid) combination of an image
reader and writer. See
http://thread.gmane.org/gmane.comp.graphics.openscenegraph.cvs/4897/focus=4923
The hope is that it can turn into a way of automatically testing both
model and image plugins prior to a release, to make sure what should
read some data file actually does, and what should be able to write an
image/3D model actually does.
For now I started with images. I went through the plugins looking for
readFile and writeFile methods. Sometimes I found some weirdness (for
example the VTF plugin implements a writeFile method, but it just calls
another function that always returns false, so the file is created but
writing fails) and some combinations didn't work (possibly because of
pixel format, but should the writing plugin convert pixel formats
automatically, or should OSG have facilities to do that for the plugin?)
Anyways, it's a start.
Notes:
The program reads files from a data/ directory, which must be called
osgPluginsTest.<extension>. I've got about 15 images (all the same image
just saved to the different formats) right now to test, but there are
some formats I can't save to using the software I have, so perhaps we
can build a collection of files to test collectively and we'll have
better chances of getting all the formats OSG supports.
The program will write output files to an output/ directory which it
will create. I have added a command line argument to tell it to keep
output files (the default would be to delete them after having tested
the writer) but I didn't want to do the deletion itself right now
(platform-independent way...).
I've made the program build a default hard-coded list of readers and
writers, and there's a way to override that list with extensions given
on the command line (colon-separated list, untested).
I've put a way of skipping combinations that I think are incompatible by
design (though that needs to be verified, so there's a
--testIncompatibleCombinations command line option and there's a TODO
comment where the blacklisting occurs in the code).
The program redirects cerr to cout so that any plugin error messages
will also be picked up if you redirect stdout to a file. (I can never
remember how to redirect stdout AND stderr to a file on Windows...)
I've attached the code (for discussion more than actual submission) and
also the results it prints out.
Comments? Is this a good direction?
J-S
--
______________________________________________________
Jean-Sebastien Guay [email protected]
http://www.cm-labs.com/
http://whitestar02.webhop.org/
-------------------------------------------------------------
Input image extension: bmp
Testing read of [bmp] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: dds
Testing read of [dds] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Skipping [png] writer based on blacklist
Skipping [ppm] writer based on blacklist
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Skipping [tif] writer based on blacklist
-------------------------------------------------------------
Input image extension: gif
Testing read of [gif] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Skipping [ppm] writer based on blacklist
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: hdr
Testing read of [hdr] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Skipping [ppm] writer based on blacklist
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: jpg
Testing read of [jpg] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: jpeg
Testing read of [jpeg] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: pic
Testing read of [pic] image - file not found
-------------------------------------------------------------
Input image extension: png
Testing read of [png] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: pnm
Testing read of [pnm] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: ppm
Testing read of [ppm] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: pgm
Testing read of [pgm] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Skipping [ppm] writer based on blacklist
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: pbm
Testing read of [pbm] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Skipping [ppm] writer based on blacklist
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: rgb
Testing read of [rgb] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: rgba
Testing read of [rgba] image - file not found
-------------------------------------------------------------
Input image extension: sgi
Testing read of [sgi] image - file not found
-------------------------------------------------------------
Input image extension: int
Testing read of [int] image - file not found
-------------------------------------------------------------
Input image extension: inta
Testing read of [inta] image - file not found
-------------------------------------------------------------
Input image extension: bw
Testing read of [bw] image - file not found
-------------------------------------------------------------
Input image extension: tga
Testing read of [tga] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: tif
Testing read of [tif] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: tiff
Testing read of [tiff] image - success
Testing write of [bmp] image - success
Testing write of [dds] image - success
Testing write of [jpg] image - success
Testing write of [png] image - success
Testing write of [ppm] image - success
Testing write of [rgb] image - success
Testing write of [rgba] image - success
Testing write of [sgi] image - success
Testing write of [int] image - success
Testing write of [inta] image - success
Testing write of [bw] image - success
Testing write of [tif] image - success
-------------------------------------------------------------
Input image extension: vtf
Testing read of [vtf] image - file not found
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/FileUtils>
#include <osg/ArgumentParser>
#include <iostream>
#include <vector>
#include <map>
//---------------------------------------------------------------------------
// Utilities
//---------------------------------------------------------------------------
char const kBlankChars[] = " \t\n\r";
/// Returns a string with leading/trailing characters of a set stripped
std::string trim( std::string const& str, char const* sepSet = kBlankChars )
{
std::string::size_type const first = str.find_first_not_of(sepSet);
return ( first==std::string::npos )
? std::string()
: str.substr(first, str.find_last_not_of(sepSet)-first+1);
}
std::string rtrim( std::string const& str, char const* sepSet = kBlankChars )
{
std::string::size_type const last = str.find_last_not_of(sepSet);
return ( last==std::string::npos )
? std::string()
: str.substr(0, last+1);
}
std::string ltrim( std::string const& str, char const* sepSet = kBlankChars )
{
std::string::size_type const first = str.find_first_not_of(sepSet);
return ( first==std::string::npos )
? std::string()
: str.substr( first );
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
std::vector<std::string> imageReaders;
std::vector<std::string> imageWriters;
typedef std::map<std::string, std::vector<std::string> > IgnoreWriterMap;
IgnoreWriterMap ignoreWriter;
void addImageReader(const std::string& extension)
{
imageReaders.push_back(extension);
}
void addImageWriter(const std::string& extension)
{
imageWriters.push_back(extension);
}
void addImageReaderAndWriter(const std::string& extension)
{
addImageReader(extension);
addImageWriter(extension);
}
//---------------------------------------------------------------------------
void addDefaultImageReadersAndWriters()
{
// ReaderWriterBMP
addImageReaderAndWriter("bmp");
// ReaderWriterDDS
addImageReaderAndWriter("dds");
// ReaderWriterGIF
addImageReader("gif");
// ReaderWriterHDR - Writes only float images unless we pass options...
addImageReader("hdr");
// ReaderWriterJPEG - just need to test writing once.
addImageReaderAndWriter("jpg");
addImageReader("jpeg");
// ReaderWriterPIC
addImageReader("pic");
// ReaderWriterPNG
addImageReaderAndWriter("png");
// ReaderWriterPNM - reads all four formats, but writes only ppm
addImageReader("pnm");
addImageReaderAndWriter("ppm");
addImageReader("pgm");
addImageReader("pbm");
// ReaderWriterRGB
addImageReaderAndWriter("rgb");
addImageReaderAndWriter("rgba");
addImageReaderAndWriter("sgi");
addImageReaderAndWriter("int");
addImageReaderAndWriter("inta");
addImageReaderAndWriter("bw");
// ReaderWriterTGA
addImageReader("tga");
// ReaderWriterTIFF - just need to test writing once.
addImageReaderAndWriter("tif");
addImageReader("tiff");
// ReaderWriterVTF - Has a writeFile() method, but it calls WriteVTF()
// which does nothing and only returns false, which is
// false advertisement dammit!
addImageReader("vtf");
std::vector<std::string> writersToIgnore;
// DDS images cannot be written back as png, ppm or tif...
// TODO: Check why and fix it if necessary.
writersToIgnore.push_back("png");
writersToIgnore.push_back("ppm");
writersToIgnore.push_back("tif");
ignoreWriter["dds"] = writersToIgnore;
writersToIgnore.clear();
// GIF images cannot be written back as ppm...
// TODO: Check why and fix it if necessary.
writersToIgnore.push_back("ppm");
ignoreWriter["gif"] = writersToIgnore;
writersToIgnore.clear();
// HDR images cannot be written back as ppm...
// TODO: Check why and fix it if necessary.
writersToIgnore.push_back("ppm");
ignoreWriter["hdr"] = writersToIgnore;
writersToIgnore.clear();
// PGM images cannot be written back as ppm...
// TODO: Check why and fix it if necessary.
writersToIgnore.push_back("ppm");
ignoreWriter["pgm"] = writersToIgnore;
writersToIgnore.clear();
// PBM images cannot be written back as ppm...
// TODO: Check why and fix it if necessary.
writersToIgnore.push_back("ppm");
ignoreWriter["pbm"] = writersToIgnore;
writersToIgnore.clear();
}
//---------------------------------------------------------------------------
std::string extractFirstExtension(std::string& extensionList)
{
// Extract the first extension, return it and remove it from the original
string.
std::string::size_type pos = extensionList.find_first_of(":");
std::string ext = extensionList.substr(0, pos);
extensionList = extensionList.substr(pos+1);
return ext;
}
void addImageReaders(const std::string& imageReaderExtensions)
{
std::string extensions = imageReaderExtensions;
while (!extensions.empty())
{
std::string ext = extractFirstExtension(extensions);
addImageReader(ext);
}
}
void addImageWriters(const std::string& imageWriterExtensions)
{
std::string extensions = imageWriterExtensions;
while (!extensions.empty())
{
std::string ext = extractFirstExtension(extensions);
addImageWriter(ext);
}
}
//---------------------------------------------------------------------------
osg::Image* testImageReader(const std::string& extension)
{
std::cout << "Testing read of [" << extension << "] image - ";
// Find an image that matches the extension
// TODO
std::string filename = "data/osgPluginsTest." + extension;
// Check if the file even exists
if (!osgDB::fileExists(filename))
{
std::cout << "file not found" << std::endl;
return 0;
}
// Try to read the image
osg::Image* image = osgDB::readImageFile(filename);
// Report whether it worked or not.
std::cout << (image ? "success" : "failed") << std::endl;
return image;
}
void testImageWriter(osg::Image* image, const std::string& extension,
bool deleteOutputFile = true)
{
if (!image) return;
std::cout << "Testing write of [" << extension << "] image - ";
// Create a directory for output files
bool created = osgDB::makeDirectory("output");
if (!created)
{
std::cout << "could not create output directory" << std::endl;
return;
}
// Try to write the image
// Just create any filename so we can write the image
std::string filename = "output/osgPluginsTest_output." + extension;
bool success = osgDB::writeImageFile(*image, filename);
if (success)
{
// Check that the file really exists?
if (!osgDB::fileExists(filename))
{
std::cout << "no file written" << std::endl;
return;
}
// Delete the file if requested
if (deleteOutputFile)
{
// TODO
}
}
// Report whether it worked or not.
std::cout << (success ? "success" : "failed") << std::endl;
}
//---------------------------------------------------------------------------
int main(int argc, char** argv)
{
std::streambuf* cerr_sbuf = std::cerr.rdbuf(); // save original sbuf
std::cerr.rdbuf(std::cout.rdbuf()); // redirect 'cerr' to a
'cout'
osg::ArgumentParser arguments(&argc,argv);
std::string imageReaderExtensions = "";
std::string imageWriterExtensions = "";
while (arguments.read("--imageReaders", imageReaderExtensions));
while (arguments.read("--imageWriters", imageWriterExtensions));
bool deleteOutputFiles = true;
while (arguments.read("--keepOutputFiles")) deleteOutputFiles = false;
bool testIncompatibleCombinations = false;
while (arguments.read("--testIncompatibleCombinations"))
testIncompatibleCombinations = true;
if (imageReaderExtensions.empty() && imageWriterExtensions.empty())
addDefaultImageReadersAndWriters();
else
{
addImageReaders(imageReaderExtensions);
addImageWriters(imageWriterExtensions);
}
// Test every reader-writer combination.
for (unsigned int i = 0; i < imageReaders.size(); i++)
{
std::cout <<
"-------------------------------------------------------------" << std::endl;
std::cout << "Input image extension: " << imageReaders[i] << std::endl;
osg::ref_ptr<osg::Image> image = testImageReader(imageReaders[i]);
if (image)
{
for (unsigned int j = 0; j < imageWriters.size(); j++)
{
// Check if we should skip this writer for this image.
if (!testIncompatibleCombinations)
{
IgnoreWriterMap::const_iterator it =
ignoreWriter.find(imageReaders[i]);
if (it != ignoreWriter.end())
{
if (std::find(it->second.begin(), it->second.end(),
imageWriters[j]) != it->second.end())
{
std::cout << "Skipping [" << imageWriters[j] << "]
writer based on blacklist" << std::endl;
continue;
}
}
}
testImageWriter(image, imageWriters[j], deleteOutputFiles);
}
}
}
std::cerr.rdbuf(cerr_sbuf); // restore the original stream buffer
return 0;
}_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org