From Farshid Lashakari, support for png write.

This commit is contained in:
Robert Osfield
2006-03-02 14:58:13 +00:00
parent 74f073c2a8
commit 507fb0074f

View File

@@ -36,12 +36,77 @@ void png_read_istream(png_structp png_ptr, png_bytep data, png_size_t length)
stream->read((char*)data,length); //Read requested amount of data
}
void png_write_ostream(png_structp png_ptr, png_bytep data, png_size_t length)
{
std::ostream *stream = (std::ostream*)png_get_io_ptr(png_ptr); //Get pointer to ostream
stream->write((char*)data,length); //Write requested amount of data
}
void png_flush_ostream(png_structp png_ptr)
{
std::ostream *stream = (std::ostream*)png_get_io_ptr(png_ptr); //Get pointer to ostream
stream->flush();
}
class ReaderWriterPNG : public osgDB::ReaderWriter
{
public:
virtual const char* className() const { return "PNG Image Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension) const { return osgDB::equalCaseInsensitive(extension,"png"); }
WriteResult::WriteStatus writePngStream(std::ostream& fout, const osg::Image& img) const
{
png_structp png = NULL;
png_infop info = NULL;
int color;
png_bytep *rows = NULL;
//Create write structure
png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png) return WriteResult::ERROR_IN_WRITING_FILE;
//Create infr structure
info = png_create_info_struct(png);
if(!info) return WriteResult::ERROR_IN_WRITING_FILE;
//Set custom write function so it will write to ostream
png_set_write_fn(png,&fout,png_write_ostream,png_flush_ostream);
switch(img.getPixelFormat()) {
case(GL_LUMINANCE): color = PNG_COLOR_TYPE_GRAY; break;
case(GL_ALPHA): color = PNG_COLOR_TYPE_GRAY; break; //Couldn't find a color type for pure alpha, using gray instead
case(GL_LUMINANCE_ALPHA): color = PNG_COLOR_TYPE_GRAY_ALPHA ; break;
case(GL_RGB): color = PNG_COLOR_TYPE_RGB; break;
case(GL_RGBA): color = PNG_COLOR_TYPE_RGB_ALPHA; break;
default: return WriteResult::ERROR_IN_WRITING_FILE; break;
}
//Create row data
rows = new png_bytep[img.t()];
for(int i = 0; i < img.t(); ++i) {
rows[i] = (png_bytep)img.data(0,img.t() - i - 1);
}
//Write header info
png_set_IHDR(png, info, img.s(), img.t(),
8, color, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png, info);
//Write data
png_write_image(png, rows);
//End write
png_write_end(png, NULL);
//Cleanup
png_destroy_write_struct(&png,&info);
delete [] rows;
return WriteResult::FILE_SAVED;
}
ReadResult readPNGStream(std::istream& fin) const
{
int trans = PNG_ALPHA;
@@ -213,6 +278,23 @@ class ReaderWriterPNG : public osgDB::ReaderWriter
if(rr.validImage()) rr.getImage()->setFileName(file);
return rr;
}
virtual WriteResult writeImage(const osg::Image& img,std::ostream& fout,const osgDB::ReaderWriter::Options *options) const
{
WriteResult::WriteStatus ws = writePngStream(fout,img);
return ws;
}
virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options *options) const
{
std::string ext = osgDB::getFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
return writeImage(img,fout,options);
}
};
// now register with Registry to instantiate the above