From: Pablo d'A. <da...@us...> - 2007-04-15 20:18:13
|
Update of /cvsroot/hugin/hugin/src/foreign/vigra_impex In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv3448 Added Files: exr.cxx exr.hxx Log Message: first (non-working) prototype of an OpenEXR codec --- NEW FILE: exr.cxx --- /************************************************************************/ /* */ /* Copyright 2007 by Pablo d'Angelo */ /* */ /* This file is part of the VIGRA computer vision library. */ /* The VIGRA Website is */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* Please direct questions, bug reports, and contributions to */ /* ko...@in... or */ /* vi...@ko... */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation */ /* files (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, */ /* copy, modify, merge, publish, distribute, sublicense, and/or */ /* sell copies of the Software, and to permit persons to whom the */ /* Software is furnished to do so, subject to the following */ /* conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the */ /* Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* OTHER DEALINGS IN THE SOFTWARE. */ /* */ /************************************************************************/ #ifdef HasEXR #include "vigra/config.hxx" #include "vigra/sized_int.hxx" #include "void_vector.hxx" #include "auto_file.hxx" #include "exr.hxx" #include "byteorder.hxx" #include "error.hxx" #include <stdexcept> #include <iostream> #include <OpenEXR/ImfRgbaFile.h> #include <OpenEXR/ImfStringAttribute.h> #include <OpenEXR/ImfMatrixAttribute.h> #include <OpenEXR/ImfArray.h> using namespace Imf; using namespace Imath; namespace vigra { CodecDesc ExrCodecFactory::getCodecDesc() const { CodecDesc desc; std::cout << "Registering OpenEXR" << std::endl; // init file type desc.fileType = "EXR"; // init pixel types desc.pixelTypes.resize(1); desc.pixelTypes[0] = "FLOAT"; // init compression types desc.compressionTypes.resize(1); desc.compressionTypes[0] = "LOSSLESS"; // init magic strings desc.magicStrings.resize(1); desc.magicStrings[0].resize(4); desc.magicStrings[0][0] = '\x2f'; desc.magicStrings[0][1] = '\x76'; desc.magicStrings[0][2] = '\x01'; desc.magicStrings[0][3] = '\x31'; // init file extensions desc.fileExtensions.resize(1); desc.fileExtensions[0] = "exr"; desc.bandNumbers.resize(1); desc.bandNumbers[0] = 4; return desc; } std::auto_ptr<Decoder> ExrCodecFactory::getDecoder() const { return std::auto_ptr<Decoder>( new ExrDecoder() ); } std::auto_ptr<Encoder> ExrCodecFactory::getEncoder() const { return std::auto_ptr<Encoder>( new ExrEncoder() ); } struct ExrDecoderImpl { std::string filename; // data source // auto_file file; // this is where libopenexr stores its state RgbaInputFile file; // data container ArrayVector<Rgba> pixels; ArrayVector<float> bands; // scanline counter int scanline; int width; int height; int components; int extra_components; Diff2D position; float x_resolution, y_resolution; // ctor, dtor ExrDecoderImpl( const std::string & filename ); ~ExrDecoderImpl(); // methods void init(); void nextScanline(); }; ExrDecoderImpl::ExrDecoderImpl( const std::string & filename ) #ifdef VIGRA_NEED_BIN_STREAMS : file( filename.c_str() ), #else : file( filename.c_str() ), #endif bands(0), scanline(-1), width(0), height(0), components(4), extra_components(1), x_resolution(0), y_resolution(0) { } ExrDecoderImpl::~ExrDecoderImpl() { } void ExrDecoderImpl::init() { // setup framebuffer Box2i dw = file.header().dataWindow(); width = dw.max.x - dw.min.x + 1; height = dw.max.y - dw.min.y + 1; position.x = dw.min.x; position.y = dw.min.y; // allocate data buffers pixels.resize(width); bands.resize(4*width); } void ExrDecoderImpl::nextScanline() { file.setFrameBuffer (pixels.begin(), 1, width); file.readPixels (1, width); // convert scanline to float float * dest = bands.begin(); for (int i=0; i < width; i++) { *dest++ = pixels[i].r; *dest++ = pixels[i].g; *dest++ = pixels[i].b; *dest++ = pixels[i].a; } } void ExrDecoder::init( const std::string & filename ) { pimpl = new ExrDecoderImpl(filename); pimpl->init(); } ExrDecoder::~ExrDecoder() { delete pimpl; } std::string ExrDecoder::getFileType() const { return "EXR"; } unsigned int ExrDecoder::getWidth() const { return pimpl->width; } unsigned int ExrDecoder::getHeight() const { return pimpl->height; } unsigned int ExrDecoder::getNumBands() const { return pimpl->components; } unsigned int ExrDecoder::getNumExtraBands() const { return pimpl->extra_components; } float ExrDecoder::getXResolution() const { return pimpl->x_resolution; } float ExrDecoder::getYResolution() const { return pimpl->y_resolution; } Diff2D ExrDecoder::getPosition() const { return pimpl->position; } std::string ExrDecoder::getPixelType() const { return "FLOAT"; } unsigned int ExrDecoder::getOffset() const { return pimpl->components; } const void * ExrDecoder::currentScanlineOfBand( unsigned int band ) const { return pimpl->bands.begin() + band; } void ExrDecoder::nextScanline() { pimpl->nextScanline(); } void ExrDecoder::close() {} void ExrDecoder::abort() {} struct ExrEncoderImpl { std::string filename; // data sink RgbaOutputFile *file; // data container ArrayVector<float> bands; ArrayVector<Rgba> pixels; // image header fields int width, height, components; int extra_components; int bit_depth, color_type; // scanline counter int scanline; // state bool finalized; // image layer position Diff2D position; // resolution float x_resolution, y_resolution; // ctor, dtor ExrEncoderImpl( const std::string & filename ); ~ExrEncoderImpl(); // methods void nextScanline(); void finalize(); void close(); }; ExrEncoderImpl::ExrEncoderImpl( const std::string & filename ) : filename(filename), file(0), bands(0), scanline(0), finalized(false), x_resolution(0), y_resolution(0) { } ExrEncoderImpl::~ExrEncoderImpl() { if (file) delete file; } void ExrEncoderImpl::finalize() { // prepare the bands bands.resize( 3 * width ); pixels.resize(width); file = new RgbaOutputFile( filename.c_str(), width, height, WRITE_RGBA ); // enter finalized state finalized = true; } void ExrEncoderImpl::nextScanline() { // check if there are scanlines left at all, eventually write one if ( scanline < height ) { float * src = bands.data(); for (int i=0; i < width; i++) { // convert to half for (int i=0; i < width; i++) { pixels[i].r = *src++; pixels[i].g = *src++; pixels[i].b = *src++; pixels[i].a = *src++; } } file->setFrameBuffer (pixels.begin(), 1, width); file->writePixels (1); } scanline++; } void ExrEncoderImpl::close() { delete file; file = 0; } void ExrEncoder::init( const std::string & filename ) { pimpl = new ExrEncoderImpl(filename); } ExrEncoder::~ExrEncoder() { delete pimpl; } std::string ExrEncoder::getFileType() const { return "EXR"; } void ExrEncoder::setWidth( unsigned int width ) { VIGRA_IMPEX_FINALIZED(pimpl->finalized); pimpl->width = width; } void ExrEncoder::setHeight( unsigned int height ) { VIGRA_IMPEX_FINALIZED(pimpl->finalized); pimpl->height = height; } void ExrEncoder::setNumBands( unsigned int bands ) { if ( bands != 4 ) vigra_fail( "internal error: number of components not supported." ); pimpl->components = bands; } void ExrEncoder::setCompressionType( const std::string & comp, int quality ) { // TODO: support compression types } void ExrEncoder::setPosition( const Diff2D & pos ) { VIGRA_IMPEX_FINALIZED(pimpl->finalized); pimpl->position = pos; } void ExrEncoder::setXResolution( float xres ) { VIGRA_IMPEX_FINALIZED(pimpl->finalized); pimpl->x_resolution = xres; } void ExrEncoder::setYResolution( float yres ) { VIGRA_IMPEX_FINALIZED(pimpl->finalized); pimpl->y_resolution = yres; } void ExrEncoder::setPixelType( const std::string & pixelType ) { VIGRA_IMPEX_FINALIZED(pimpl->finalized); if ( pixelType != "FLOAT" ) vigra_fail( "internal error: pixeltype not supported." ); } unsigned int ExrEncoder::getOffset() const { return pimpl->components; } void ExrEncoder::finalizeSettings() { VIGRA_IMPEX_FINALIZED(pimpl->finalized); pimpl->finalize(); } void * ExrEncoder::currentScanlineOfBand( unsigned int band ) { return pimpl->bands.begin() + band; } void ExrEncoder::nextScanline() { // write scanline pimpl->nextScanline(); } void ExrEncoder::close() { pimpl->close(); } void ExrEncoder::abort() {} } #endif // HasPNG --- NEW FILE: exr.hxx --- /************************************************************************/ /* */ /* Copyright 2007 by Pablo d'Angelo */ /* */ /* This file is part of the VIGRA computer vision library. */ /* ( Version 1.5.0, Dec 07 2006 ) */ /* The VIGRA Website is */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* Please direct questions, bug reports, and contributions to */ /* ko...@in... or */ /* vi...@ko... */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation */ /* files (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, */ /* copy, modify, merge, publish, distribute, sublicense, and/or */ /* sell copies of the Software, and to permit persons to whom the */ /* Software is furnished to do so, subject to the following */ /* conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the */ /* Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* OTHER DEALINGS IN THE SOFTWARE. */ /* */ /************************************************************************/ #ifndef VIGRA_IMPEX_EXR_HXX #define VIGRA_IMPEX_EXR_HXX #include "vigra/codec.hxx" // EXR - OpenEXR namespace vigra { struct ExrDecoderImpl; struct ExrEncoderImpl; struct ExrCodecFactory : public CodecFactory { CodecDesc getCodecDesc() const; std::auto_ptr<Decoder> getDecoder() const; std::auto_ptr<Encoder> getEncoder() const; }; class ExrDecoder : public Decoder { ExrDecoderImpl * pimpl; public: ExrDecoder() : pimpl(0) {} ~ExrDecoder(); void init( const std::string & ); void close(); void abort(); std::string getFileType() const; std::string getPixelType() const; unsigned int getWidth() const; unsigned int getHeight() const; unsigned int getNumBands() const; unsigned int getNumExtraBands() const; float getXResolution() const; float getYResolution() const; Diff2D getPosition() const; unsigned int getOffset() const; const void * currentScanlineOfBand( unsigned int ) const; void nextScanline(); }; class ExrEncoder : public Encoder { ExrEncoderImpl * pimpl; public: ExrEncoder() : pimpl(0) {} ~ExrEncoder(); void init( const std::string & ); void close(); void abort(); std::string getFileType() const; unsigned int getOffset() const; void setWidth( unsigned int ); void setHeight( unsigned int ); void setNumBands( unsigned int ); void setCompressionType( const std::string &, int = -1 ); void setPixelType( const std::string & ); void setPosition( const Diff2D & pos ); void setXResolution( float xres ); void setYResolution( float yres ); void finalizeSettings(); void * currentScanlineOfBand( unsigned int ); void nextScanline(); }; } #endif // VIGRA_IMPEX_PNG_HXX |