Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1830 - trunk/Image


Chronological Thread 
  • From: kmorley@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1830 - trunk/Image
  • Date: Wed, 7 Nov 2007 10:39:20 -0700 (MST)

Author: kmorley
Date: Wed Nov  7 10:39:19 2007
New Revision: 1830

Modified:
   trunk/Image/EXRFile.cc
   trunk/Image/EXRFile.h
Log:
Getting rid of OpenEXR/ in exr ehader include statements. Also, some more 
work-in-progress EXR support.

Modified: trunk/Image/EXRFile.cc
==============================================================================
--- trunk/Image/EXRFile.cc      (original)
+++ trunk/Image/EXRFile.cc      Wed Nov  7 10:39:19 2007
@@ -32,23 +32,30 @@
 #include <Image/Pixel.h>
 #include <Image/SimpleImage.h>
 
-#include <Core/Exceptions/UnknownPixel.h>
 #include <Core/Exceptions/InputError.h>
 #include <Core/Exceptions/OutputError.h>
 
-#include <OpenEXR/half.h>
-#include <OpenEXR/ImfInputFile.h>
-#include <OpenEXR/ImfRgba.h>
-#include <OpenEXR/ImfRgbaFile.h>
-#include <OpenEXR/ImfChannelList.h>
-#include <OpenEXR/ImfArray.h>
-#include <OpenEXR/ImfFrameBuffer.h>
-#include <OpenEXR/ImathBox.h>
+#include <half.h>
+#include <ImfHeader.h>
+#include <ImfInputFile.h>
+#include <ImfOutputFile.h>
+#include <ImfRgba.h>
+#include <ImfRgbaFile.h>
+#include <ImfChannelList.h>
+#include <ImfArray.h>
+#include <ImfFrameBuffer.h>
+#include <ImathBox.h>
+#include <ImathVec.h>
 
 #include <fstream>
 #include <iostream>
+#include <memory>
+#include <exception>
+
+
 using namespace Manta;
 
+
 extern "C" 
 bool isEXR( const std::string& filename )
 {
@@ -141,7 +148,8 @@
   file.setFrameBuffer( frame_buffer ); 
   file.readPixels( dw.min.y, dw.max.y ); 
   
-  SimpleImage<RGBA8Pixel>* image = new SimpleImage<RGBA8Pixel>( false, 
width, 
+  SimpleImage<RGBAfloatPixel>* image = 
+    new SimpleImage<RGBAfloatPixel>( false, width, 
       height );
 
   for ( int i = 0; i < width; ++i ) {
@@ -151,7 +159,7 @@
                 << g_pixels[i][j] << " " 
                 << b_pixels[i][j] << std::endl;
       
-      RGBA8Pixel pixel;
+      RGBAfloatPixel pixel;
       RGBColor color( r_pixels[i][j], g_pixels[i][j], b_pixels[i][j] );
 
       convertToPixel( pixel, color );
@@ -159,9 +167,9 @@
     }
   }
   return image;
-#else
+#endif
                                         
-     
+#if 0 
   Imf::RgbaInputFile file( filename.c_str() ); 
 
   Imath::Box2i dw = file.dataWindow(); 
@@ -196,6 +204,9 @@
   return image;
 
 #endif
+  
+  EXR::InputFile input_file( filename );
+  return input_file.getImage();
 }
 
 
@@ -204,5 +215,204 @@
 {
   return true;
 }
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 
+//  EXRInputFile
+// 
+
+EXR::InputFile::InputFile( const std::string& filename )
+  : _filename( filename )
+{
+  try {
+
+    Imf::RgbaInputFile file( filename.c_str() ); 
+    Imath::Box2i dw = file.dataWindow(); 
+
+    _width  = dw.max.x - dw.min.x + 1; 
+    _height = dw.max.y - dw.min.y + 1; 
+
+    _rgbas = new(std::nothrow) Imf::Rgba[ _width*_height ];
+
+    file.setFrameBuffer (&_rgbas[0] - dw.min.x - dw.min.y * _width, 1, 
_width); 
+    file.readPixels (dw.min.y, dw.max.y); 
+
+  } catch( std::exception& e ) {
+    throw InputError( std::string( "OpenEXR lib read failed: " ) + e.what() 
); 
+  }
+
+  /*
+  int width = 512, height = 512;
+  float* floats = new float[ width*height ];
+  for (int i = 0; i < width*height; ++i )
+     floats[i] = float(i) / (width * height);
+
+  ChannelList clist;
+  clist.push_back( new Channel( "R", FLOAT, reinterpret_cast<char*>(floats) 
) );
+  EXR::OutputFile out( clist, 512, 512 );
+  out.write( "/Users/kmorley/Desktop/foo.exr" );
+  */
+
+}
+
+
+EXR::InputFile::~InputFile()
+{
+  delete [] _rgbas;
+  for (ChannelList::iterator it = _channels.begin(); 
+      it != _channels.end(); ++it ) {
+    delete [] (**it).data;
+  }
+}
+
+
+Image* EXR::InputFile::getImage()
+{
+  if (_rgbas) {
+
+    SimpleImage<RGBAfloatPixel>* image = 
+      new SimpleImage<RGBAfloatPixel>( false, _width, _height );
+
+    for ( unsigned int i = 0; i < _width; ++i ) {
+      for ( unsigned int j = 0; j < _height; ++j ) {
+
+        int index = (_height-1-j) * _width + i;
+        float r = _rgbas[ index ].r;
+        float g = _rgbas[ index ].g;
+        float b = _rgbas[ index ].b;
+        RGBColor color( r, g, b ); 
+
+        //std::cerr << float( _rgbas[ index ].r ) << " " 
+        //          << float( _rgbas[ index ].g ) << " " 
+        //          << float( _rgbas[ index ].b ) << std::endl;
+
+        RGBAfloatPixel pixel;
+        convertToPixel( pixel, color );
+        image->set( pixel, i, j, 0 ); 
+      }
+    }
+    return image;
+
+  } else {
+    throw InputError( "Non-RGBA image reading not supported yet" );
+  }
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 
+//  EXROutputFile
+// 
+
+
+EXR::OutputFile::OutputFile( Imf::Rgba* pixels, unsigned int x, unsigned int 
y,
+    unsigned int min_x, unsigned int max_x, unsigned int min_y,
+    unsigned int max_y, float aspect, float screen_width)
+: _rgbas( pixels )
+{
+  if ( min_x < 0 || min_x > max_x || 
+       min_y < 0 || min_y > max_y ) {
+    throw OutputError( " EXR::OutputFile bad data window coordinates passed \
+        to constructor " );
+  }
+
+  Imath::Box2i dw( Imath::V2i(0, 0), Imath::V2i (x-1, y-1) );
+  if ( max_x != min_x && max_y != min_y ) {
+    dw = Imath::Box2i( Imath::V2i(min_x, min_y), Imath::V2i (max_x, max_y) );
+  }
+
+  _header = new Imf::Header( x, y, dw, aspect, Imath::V2f( 0.0f, 0.0f), 
+      screen_width );
+}
+
+
+EXR::OutputFile::OutputFile( const ChannelList& channels, unsigned int x,
+    unsigned int y, unsigned int min_x, unsigned int max_x, unsigned int 
min_y,
+    unsigned int max_y, float aspect, float screen_width)
+: _channels( channels )
+{
+  if ( min_x < 0 || min_x > max_x || 
+       min_y < 0 || min_y > max_y ) {
+    throw OutputError( " EXR::OutputFile bad data window coordinates passed \
+        to constructor " );
+  }
+
+  Imath::Box2i dw = Imath::Box2i( Imath::V2i(min_x, min_y), 
+                                  Imath::V2i(max_x, max_y) );
+  
+  // If zero-area data window set data window to entire display window
+  if ( max_x == min_x || max_y == min_y ) {
+    dw = Imath::Box2i( Imath::V2i(0, 0), Imath::V2i (x-1, y-1) );
+  }
+
+  _header = new Imf::Header( x, y, dw, aspect, Imath::V2f( 0.0f, 0.0f), 
+      screen_width );
+
+  for ( ChannelIter it = _channels.begin(); it != _channels.end(); ++it ) {
+    Channel* chan = *it;
+    _header->channels().insert( chan->name.c_str(), 
+        static_cast<Imf::PixelType>( chan->type ) );
+  }
+}
+
+
+EXR::OutputFile::~OutputFile()
+{
+  delete _header;
+}
+
+
+void EXR::OutputFile::write( const std::string& filename )
+{
+
+  Imath::Box2i dw = _header->dataWindow(); 
+  int width  = dw.max.x - dw.min.x + 1;
+  int height = dw.max.y - dw.min.y + 1;
+
+  if ( _rgbas ) {
+
+
+    //  NOT FINISHED YET
+
+  } else if ( _channels.size() > 0 ) {
+
+    try {
+
+      Imf::FrameBuffer frameBuffer;
+      for ( ChannelIter it = _channels.begin(); it != _channels.end(); ++it 
) {
+        Channel* chan = *it;
+        int data_size = chan->type == UINT ? sizeof( unsigned int ) :
+          chan->type == HALF ? sizeof( half )    :
+          sizeof( float );
+
+        frameBuffer.insert ( chan->name.c_str(),
+            Imf::Slice ( static_cast<Imf::PixelType>( chan->type ),
+              reinterpret_cast<char*>( chan->data ),
+              data_size * 1,
+              data_size * width ) );
+      }
+
+      Imf::OutputFile file(filename.c_str(), *_header);
+      file.setFrameBuffer (frameBuffer);
+
+      file.writePixels (height);
+
+
+    } catch( std::exception& e ) {
+
+      throw InputError( std::string( "OpenEXR lib write failed: " )+e.what() 
); 
+
+    }
+
+  } else {
+
+    throw OutputError( "EXROutputFile::write called without Pixel data" );
+  }
+
+}
+
+
 
 

Modified: trunk/Image/EXRFile.h
==============================================================================
--- trunk/Image/EXRFile.h       (original)
+++ trunk/Image/EXRFile.h       Wed Nov  7 10:39:19 2007
@@ -37,6 +37,7 @@
 namespace Imf 
 {
   class Rgba;
+  class Header;
 }
 
 
@@ -59,10 +60,9 @@
   bool EXRSupported();
 
 
-  class EXRFile 
-  {
-  public:
 
+  namespace EXR
+  {
 
     enum PixelType        // Should be identical to Imf::PixelType
     {
@@ -72,30 +72,85 @@
       NUM_PIXELTYPES      // number of different pixel types
     };
 
-
-    class Channel
+    struct Channel
     {
+      Channel() : type( HALF ), data( NULL ) {}
+      Channel( const std::string& n, PixelType t, char* d) 
+        : name( n ), type( t ), data( d ) {}
+
       std::string     name;  // Name of the channel, eg "R", "G", "B"
-      PixelType       type;  // Should match Imf::PixelType enum
+      PixelType       type;  // Data type 
       char*           data;  // The raster data 
     };
 
     typedef std::vector<Channel*> ChannelList;
+    typedef ChannelList::iterator ChannelIter;
+
 
-    EXRFile( const std::string& filename, unsigned int x, unsigned int y );
-    EXRFile( const ChannelList& channel_list, unsigned int x, unsigned int y 
);
-    EXRFile( Imf::Rgba* pixels, unsigned int x, unsigned int y );
+    
+    class InputFile 
+    {
+    public:
 
-    void write( const std::string& filename );
-    Image* getImage();
+      InputFile( const std::string& filename );
+      ~InputFile();
 
-  private:
-    EXRFile() {}
+      Image* getImage();
 
-    unsigned int _x; // Width
-    unsigned int _y; // Height
+    private:
+      InputFile() {}
+
+      std::string  _filename;  // Filename read from or last written to
+      unsigned int _width;
+      unsigned int _height;
+
+      Imf::Rgba*   _rgbas;     // Array of Rgba Halfs.  Null if using 
channels 
+      ChannelList  _channels;  // List of arbitrary channels
+    };
+
+
+
+    class OutputFile 
+    {
+    public:
+      OutputFile( Imf::Rgba* pixels, 
+               unsigned int x, 
+               unsigned int y, 
+               unsigned int min_x=0, 
+               unsigned int max_x=0, 
+               unsigned int min_y=0, 
+               unsigned int max_y=0, 
+               float aspect=1.0f, 
+               float screen_width=1.0f
+               );
+
+      OutputFile( const ChannelList& channels, 
+               unsigned int x, 
+               unsigned int y, 
+               unsigned int min_x=0, 
+               unsigned int max_x=0, 
+               unsigned int min_y=0, 
+               unsigned int max_y=0, 
+               float aspect=1.0f, 
+               float screen_width=1.0f 
+               );
+
+      ~OutputFile();
+
+      void write( const std::string& filename );
+
+    private:
+      OutputFile() {}
+
+      Imf::Header* _header;
+
+      ChannelList  _channels;  // List of arbitrary channels
+      Imf::Rgba*   _rgbas;     // Array of Rgba Halfs. Null if using 
channels  
+    };
+
+  } // namespace EXR
+
+} // namespace Manta
 
-  };
-}
 
 #endif




  • [Manta] r1830 - trunk/Image, kmorley, 11/07/2007

Archive powered by MHonArc 2.6.16.

Top of page