Example #1
0
  /*! load an EXR file from disk */
  Ref<Image> loadExr(const FileName& filename)
  {
    Imf::RgbaInputFile file (filename.c_str());
    Imath::Box2i dw = file.dataWindow();
    ssize_t width = dw.max.x - dw.min.x + 1;
    ssize_t height = dw.max.y - dw.min.y + 1;

    Imf::Array2D<Imf::Rgba> pixels(height, width);
    file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width);
    file.readPixels (dw.min.y, dw.max.y);

    Ref<Image> img = new Image3f(width,height,filename);

    if (file.lineOrder() == Imf::INCREASING_Y) {
      for (ssize_t y=0; y<height; y++) {
        for (ssize_t x=0; x<width; x++) {
          Imf::Rgba c = pixels[y][x];
          img->set(x,y,Color4(c.r,c.g,c.b,c.a));
        }
      }
    }
    else {
      for (ssize_t y=0; y<height; y++) {
        for (ssize_t x=0; x<width; x++) {
          Imf::Rgba c = pixels[y][x];
          img->set(x,height-y-1,Color4(c.r,c.g,c.b,c.a));
        }
      }
    }

    return img;
  }
Example #2
0
////////////////////////////////////////////////////////////////////////////
// Take a file name/location and load an OpenEXR
// Load the image into the "texture" texture object and pass back the texture sizes
// 
bool LoadOpenEXRImage(char *fileName, GLint textureName, GLuint &texWidth, GLuint &texHeight)
{
    // The OpenEXR uses exception handling to report errors or failures
    // Do all work in a try block to catch any thrown exceptions.
    try
    {
        Imf::Array2D<Imf::Rgba> pixels;
        Imf::RgbaInputFile file (fileName);
        Imath::Box2i dw = file.dataWindow();

        texWidth  = dw.max.x - dw.min.x + 1;
        texHeight = dw.max.y - dw.min.y + 1;
        
        pixels.resizeErase (texHeight, texWidth); 

        file.setFrameBuffer (&pixels[0][0] - dw.min.x - dw.min.y * texWidth, 1, texWidth);
        file.readPixels (dw.min.y, dw.max.y); 

        GLfloat* texels = (GLfloat*)malloc(texWidth * texHeight * 3 * sizeof(GLfloat));
        GLfloat* pTex = texels;

        // Copy OpenEXR into local buffer for loading into a texture
        for (unsigned int v = 0; v < texHeight; v++)
        {
            for (unsigned int u = 0; u < texWidth; u++)
            {
                Imf::Rgba texel = pixels[texHeight - v - 1][u];  
                pTex[0] = texel.r;
                pTex[1] = texel.g;
                pTex[2] = texel.b;

                pTex += 3;
            }
        }

        // Bind texture, load image, set tex state
        glBindTexture(GL_TEXTURE_2D, textureName);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, texWidth, texHeight, 0, GL_RGB, GL_FLOAT, texels);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        
        free(texels);
    }
    catch(Iex::BaseExc & e)  
    {
        std::cerr << e.what() << std::endl;
        //
        // Handle exception.
        //
    }

    return true;
}
Example #3
0
void make_preview(Imf::RgbaInputFile &in,
                   float exposure,
                   int previewWidth,
                   int previewHeight,
                   Imf::Array2D <Imf::PreviewRgba> &previewPixels)
    {
    //
    // Read image
    //
    Box2i dw = in.dataWindow();
    int w = dw.max.x - dw.min.x + 1;
    int h = dw.max.y - dw.min.y + 1;

    Array2D <Rgba> pixels (h, w);
    in.setFrameBuffer (&pixels[0][0] - dw.min.y * w - dw.min.x, 1, w);
    in.readPixels (dw.min.y, dw.max.y);

    //
    // Make a preview image
    //
    previewPixels.resizeErase (previewHeight, previewWidth);

    float fx = (previewWidth  > 0)? (float (w - 1) / (previewWidth  - 1)): 1;
    float fy = (previewHeight > 0)? (float (h - 1) / (previewHeight - 1)): 1;
    float m  = Math<float>::pow (2.f, clamp (exposure + 2.47393f, -20.f, 20.f));

    for (int y = 0; y < previewHeight; ++y)
    {
        for (int x = 0; x < previewWidth; ++x)
        {
            PreviewRgba &preview = previewPixels[y][x];
            const Rgba &pixel = pixels[int (y * fy + .5f)][int (x * fx + .5f)];

            preview.r = gamma (pixel.r, m);
            preview.g = gamma (pixel.g, m);
            preview.b = gamma (pixel.b, m);
            preview.a = int (clamp (pixel.a * 255.f, 0.f, 255.f) + .5f);
        }
    }
}
Example #4
0
int
main (int argc, char * argv[])
{
    int status = 0;

    try
    {
	clo::parser parser;
	parser.parse (argc, argv);

	const clo::options & options = parser.get_options ();

	const vector<string> & nonopts = parser.get_non_options ();
	if (nonopts.size () != 4)
	{
	    clo::option_error e ("illegal syntax.");
	    throw e;
	}

	const std::string & exrA = nonopts[0];
	const std::string & op   = nonopts[1];
	const std::string & exrB = nonopts[2];
	const std::string & exrC = nonopts[3];

	if (op != "over" && op != "in" && op != "out")
	{
	    clo::option_error e ("unknown operation");
	    throw e;
	}

	//
	// Open A and B for reading.
	//
	// The images must have the same data and display window,
	// but this requirement should be relaxed.
	//

	Imf::RgbaInputFile inA (exrA.c_str ());
	Imf::RgbaInputFile inB (exrB.c_str ());

	Imath::Box2i dataWinA = inA.dataWindow ();
	Imath::Box2i dataWinB = inB.dataWindow ();

	if ((dataWinA.min.x != dataWinB.min.x) || 
	    (dataWinA.min.y != dataWinB.min.y) ||
	    (dataWinA.max.x != dataWinB.max.x) || 
	    (dataWinA.max.y != dataWinB.max.y))
	{
	    THROW (Iex::BaseExc, "both images must have the same data window");
	}

	Imath::Box2i dpyWinA = inA.displayWindow ();
	Imath::Box2i dpyWinB = inB.displayWindow ();

	if ((dpyWinA.min.x != dpyWinB.min.x) || 
	    (dpyWinA.min.y != dpyWinB.min.y) ||
	    (dpyWinA.max.x != dpyWinB.max.x) || 
	    (dpyWinA.max.y != dpyWinB.max.y))
	{
	    THROW (Iex::BaseExc, "both images must have the same display "
		   << "window");
	}

	//
	// Open C for writing, preserving the data window and display
	// window of the original images.
	//

	Imf::RgbaOutputFile outC (exrC.c_str (), dpyWinA, dataWinA,
				  Imf::WRITE_RGBA);

	//
	// Read A and B.
	//

	Imath::V2i dim (dataWinA.max.x - dataWinA.min.x + 1,
			dataWinA.max.y - dataWinA.min.y + 1);
	int dx = dataWinA.min.x;
	int dy = dataWinA.min.y;

	Imf::Array<Imf::Rgba> imgA (dim.x * dim.y);
	Imf::Array<Imf::Rgba> imgB (dim.x * dim.y);

	inA.setFrameBuffer (imgA - dx - dy * dim.x, 1, dim.x);
	inA.readPixels (dataWinA.min.y, dataWinA.max.y);

	inB.setFrameBuffer (imgB - dx - dy * dim.x, 1, dim.x);
	inB.readPixels (dataWinB.min.y, dataWinB.max.y);

	//
	// Do the comp, overwrite image B with the result.
	//

	if (op == "over")
	    Comp::over (dim, imgA, imgB, imgB);
	else if (op == "in")
	    Comp::in (dim, imgA, imgB, imgB);
	else
	    Comp::out (dim, imgA, imgB, imgB);

	//
	// Write comp'ed image.
	//

	outC.setFrameBuffer (imgB - dx - dy * dim.x, 1, dim.x);
	outC.writePixels (dim.y);
    }
    catch (clo::autoexcept & e)
    {
	switch (e.get_autothrow_id ())
	{
	  case clo::autothrow_help:
	      cout << "Usage: exrcomp [options] <a.exr> <over|in|out> "
		   << "<b.exr> <output.exr>" << endl;
	      cout << e.what ();
	      break;

	  case clo::autothrow_version:
	      cout << "exrcomp version 1.0" << endl;
	      break;

	  default:
	      cerr << "Internal error (illegal autothrow)" << endl;
	      cerr << e.what () << endl;
	      status = 1;
	}
    }
    catch (clo::option_error & e)
    {
	cerr << "exrcomp: " << e.what () << endl;
	cerr << "Use -h for help." << endl;
	status = 1;
    }
    catch (exception & e)
    {
	cerr << "exrcomp: " << e.what () << endl;
	status = 1;
    }
    catch (...)
    {
	cerr << "exrcomp: caught unhandled exception" << endl;
	status = 1;
    }

    return status;
}