Пример #1
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;
}
Пример #2
0
// OpenEXR writing
void writeRgba (const char fileName[], const Imf::Rgba *pixels, int width, int height)
{
	Imf::RgbaOutputFile file (fileName, width, height, Imf::WRITE_RGBA);
	file.setFrameBuffer (pixels, 1, width);
	file.writePixels (height);
}