Blame IlmImfTest/testCompression.cpp

Packit Service 6754ca
///////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
//
Packit Service 6754ca
// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
Packit Service 6754ca
// Digital Ltd. LLC
Packit Service 6754ca
// 
Packit Service 6754ca
// All rights reserved.
Packit Service 6754ca
// 
Packit Service 6754ca
// Redistribution and use in source and binary forms, with or without
Packit Service 6754ca
// modification, are permitted provided that the following conditions are
Packit Service 6754ca
// met:
Packit Service 6754ca
// *       Redistributions of source code must retain the above copyright
Packit Service 6754ca
// notice, this list of conditions and the following disclaimer.
Packit Service 6754ca
// *       Redistributions in binary form must reproduce the above
Packit Service 6754ca
// copyright notice, this list of conditions and the following disclaimer
Packit Service 6754ca
// in the documentation and/or other materials provided with the
Packit Service 6754ca
// distribution.
Packit Service 6754ca
// *       Neither the name of Industrial Light & Magic nor the names of
Packit Service 6754ca
// its contributors may be used to endorse or promote products derived
Packit Service 6754ca
// from this software without specific prior written permission. 
Packit Service 6754ca
// 
Packit Service 6754ca
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 6754ca
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 6754ca
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit Service 6754ca
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit Service 6754ca
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit Service 6754ca
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit Service 6754ca
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit Service 6754ca
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit Service 6754ca
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit Service 6754ca
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 6754ca
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 6754ca
//
Packit Service 6754ca
///////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
#include "compareB44.h"
Packit Service 6754ca
Packit Service 6754ca
#include <ImfOutputFile.h>
Packit Service 6754ca
#include <ImfInputFile.h>
Packit Service 6754ca
#include <ImfChannelList.h>
Packit Service 6754ca
#include <ImfArray.h>
Packit Service 6754ca
#include <ImathRandom.h>
Packit Service 6754ca
#include <half.h>
Packit Service 6754ca
#include "compareFloat.h"
Packit Service 6754ca
Packit Service 6754ca
#include <stdio.h>
Packit Service 6754ca
#include <assert.h>
Packit Service 6754ca
Packit Service 6754ca
namespace IMF = OPENEXR_IMF_NAMESPACE;
Packit Service 6754ca
using namespace IMF;
Packit Service 6754ca
using namespace std;
Packit Service 6754ca
using namespace IMATH_NAMESPACE;
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
namespace {
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
fillPixels1 (Array2D<unsigned int> &pi,
Packit Service 6754ca
	     Array2D<half> &ph,
Packit Service 6754ca
	     Array2D<float> &pf,
Packit Service 6754ca
	     int width,
Packit Service 6754ca
	     int height)
Packit Service 6754ca
{
Packit Service 6754ca
    cout << "only zeroes" << endl;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < height; ++y)
Packit Service 6754ca
	for (int x = 0; x < width; ++x)
Packit Service 6754ca
	{
Packit Service 6754ca
	    pi[y][x] = 0;
Packit Service 6754ca
	    ph[y][x] = 0;
Packit Service 6754ca
	    pf[y][x] = 0;
Packit Service 6754ca
	}
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
fillPixels2 (Array2D<unsigned int> &pi,
Packit Service 6754ca
	     Array2D<half> &ph,
Packit Service 6754ca
	     Array2D<float> &pf,
Packit Service 6754ca
	     int width,
Packit Service 6754ca
	     int height)
Packit Service 6754ca
{
Packit Service 6754ca
    cout << "pattern 1" << endl;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < height; ++y)
Packit Service 6754ca
	for (int x = 0; x < width; ++x)
Packit Service 6754ca
	{
Packit Service 6754ca
	    pi[y][x] = (x + y) & 1;
Packit Service 6754ca
	    ph[y][x] = pi[y][x];
Packit Service 6754ca
	    pf[y][x] = pi[y][x];
Packit Service 6754ca
	}
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
fillPixels3 (Array2D<unsigned int> &pi,
Packit Service 6754ca
	     Array2D<half> &ph,
Packit Service 6754ca
	     Array2D<float> &pf,
Packit Service 6754ca
	     int width,
Packit Service 6754ca
	     int height)
Packit Service 6754ca
{
Packit Service 6754ca
    cout << "pattern 2" << endl;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < height; ++y)
Packit Service 6754ca
	for (int x = 0; x < width; ++x)
Packit Service 6754ca
	{
Packit Service 6754ca
	    pi[y][x] = x % 100 + 100 * (y % 100);
Packit Service 6754ca
	    ph[y][x] = sin (double (x)) + sin (y * 0.5);
Packit Service 6754ca
	    pf[y][x] = sin (double (y)) + sin (x * 0.5);
Packit Service 6754ca
	}
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
fillPixels4 (Array2D<unsigned int> &pi,
Packit Service 6754ca
	     Array2D<half> &ph,
Packit Service 6754ca
	     Array2D<float> &pf,
Packit Service 6754ca
	     int width,
Packit Service 6754ca
	     int height)
Packit Service 6754ca
{
Packit Service 6754ca
    cout << "random bits" << endl;
Packit Service 6754ca
Packit Service 6754ca
    //
Packit Service 6754ca
    // Use of a union to extract the bit pattern from a float, as is
Packit Service 6754ca
    // done below, works only if int and float have the same size.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    assert (sizeof (int) == sizeof (float));
Packit Service 6754ca
Packit Service 6754ca
    Rand48 rand;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < height; ++y)
Packit Service 6754ca
	for (int x = 0; x < width; ++x)
Packit Service 6754ca
	{
Packit Service 6754ca
	    pi[y][x] = rand.nexti();
Packit Service 6754ca
Packit Service 6754ca
	    ph[y][x].setBits (rand.nexti());
Packit Service 6754ca
Packit Service 6754ca
	    union {int i; float f;} u;
Packit Service 6754ca
	    u.i = rand.nexti();
Packit Service 6754ca
Packit Service 6754ca
	    pf[y][x] = u.f;
Packit Service 6754ca
	}
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
writeRead (const Array2D<unsigned int> &pi1,
Packit Service 6754ca
	   const Array2D<half> &ph1,
Packit Service 6754ca
	   const Array2D<float> &pf1,
Packit Service 6754ca
	   const char fileName[],
Packit Service 6754ca
	   int width,
Packit Service 6754ca
	   int height,
Packit Service 6754ca
	   int xOffset,
Packit Service 6754ca
	   int yOffset,
Packit Service 6754ca
	   Compression comp,
Packit Service 6754ca
	   int xs,
Packit Service 6754ca
	   int ys)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Write the pixel data in pi1, ph1 and ph2 to an
Packit Service 6754ca
    // image file using the specified compression type
Packit Service 6754ca
    // and subsampling rates.  Read the pixel data back
Packit Service 6754ca
    // from the file and verify that the data did not
Packit Service 6754ca
    // change.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    cout << "compression " << comp <<
Packit Service 6754ca
	    ", x sampling " << xs <<
Packit Service 6754ca
	    ", y sampling " << ys <<
Packit Service 6754ca
	    ":" << flush;
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
    Header hdr ((Box2i (V2i (0, 0),			// display window
Packit Service 6754ca
		        V2i (width - 1, height -1))),
Packit Service 6754ca
		(Box2i (V2i (xOffset, yOffset),		// data window
Packit Service 6754ca
		        V2i (xOffset + width - 1, yOffset + height - 1))));
Packit Service 6754ca
Packit Service 6754ca
    hdr.compression() = comp;
Packit Service 6754ca
Packit Service 6754ca
    hdr.channels().insert ("I",			// name
Packit Service 6754ca
			   Channel (IMF::UINT,	// type
Packit Service 6754ca
				    xs,		// xSampling
Packit Service 6754ca
				    ys)		// ySampling
Packit Service 6754ca
			  );
Packit Service 6754ca
Packit Service 6754ca
    hdr.channels().insert ("H",			// name
Packit Service 6754ca
			   Channel (IMF::HALF,	// type
Packit Service 6754ca
				    xs,		// xSampling
Packit Service 6754ca
				    ys)		// ySampling
Packit Service 6754ca
			  );
Packit Service 6754ca
Packit Service 6754ca
    hdr.channels().insert ("F",			// name
Packit Service 6754ca
			   Channel (IMF::FLOAT,	// type
Packit Service 6754ca
				    xs,		// xSampling
Packit Service 6754ca
				    ys)		// ySampling
Packit Service 6754ca
			  );
Packit Service 6754ca
Packit Service 6754ca
    {
Packit Service 6754ca
	FrameBuffer fb; 
Packit Service 6754ca
Packit Service 6754ca
	fb.insert ("I",						// name
Packit Service 6754ca
		   Slice (IMF::UINT,				// type
Packit Service 6754ca
			  (char *) &pi1[-yOffset / ys][-xOffset / xs], // base
Packit Service 6754ca
			  sizeof (pi1[0][0]), 			// xStride
Packit Service 6754ca
			  sizeof (pi1[0][0]) * (width / xs),	// yStride
Packit Service 6754ca
			  xs,					// xSampling
Packit Service 6754ca
			  ys)					// ySampling
Packit Service 6754ca
		  );
Packit Service 6754ca
	
Packit Service 6754ca
	fb.insert ("H",						// name
Packit Service 6754ca
		   Slice (IMF::HALF,				// type
Packit Service 6754ca
			  (char *) &ph1[-yOffset / ys][-xOffset / xs], // base
Packit Service 6754ca
			  sizeof (ph1[0][0]), 			// xStride
Packit Service 6754ca
			  sizeof (ph1[0][0]) * (width / xs),	// yStride
Packit Service 6754ca
			  xs,					// xSampling
Packit Service 6754ca
			  ys)					// ySampling
Packit Service 6754ca
		  );
Packit Service 6754ca
	
Packit Service 6754ca
	fb.insert ("F",						// name
Packit Service 6754ca
		   Slice (IMF::FLOAT,				// type
Packit Service 6754ca
			  (char *) &pf1[-yOffset / ys][-xOffset / xs], // base
Packit Service 6754ca
			  sizeof (pf1[0][0]), 			// xStride
Packit Service 6754ca
			  sizeof (pf1[0][0]) * (width / xs),	// yStride
Packit Service 6754ca
			  xs,					// xSampling
Packit Service 6754ca
			  ys)					// ySampling
Packit Service 6754ca
		  );
Packit Service 6754ca
	
Packit Service 6754ca
	cout << " writing" << flush;
Packit Service 6754ca
Packit Service 6754ca
	remove (fileName);
Packit Service 6754ca
	OutputFile out (fileName, hdr);
Packit Service 6754ca
	out.setFrameBuffer (fb);
Packit Service 6754ca
	out.writePixels (height);
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    {
Packit Service 6754ca
	cout << " reading" << flush;
Packit Service 6754ca
Packit Service 6754ca
	InputFile in (fileName);
Packit Service 6754ca
	
Packit Service 6754ca
	const Box2i &dw = in.header().dataWindow();
Packit Service 6754ca
	int w = dw.max.x - dw.min.x + 1;
Packit Service 6754ca
	int h = dw.max.y - dw.min.y + 1;
Packit Service 6754ca
	int dx = dw.min.x;
Packit Service 6754ca
	int dy = dw.min.y;
Packit Service 6754ca
Packit Service 6754ca
	Array2D<unsigned int> pi2 (h / ys, w / xs);
Packit Service 6754ca
	Array2D<half>         ph2 (h / ys, w / xs);
Packit Service 6754ca
	Array2D<float>        pf2 (h / ys, w / xs);
Packit Service 6754ca
Packit Service 6754ca
	FrameBuffer fb;
Packit Service 6754ca
Packit Service 6754ca
	{
Packit Service 6754ca
	    int xs = in.header().channels()["I"].xSampling;
Packit Service 6754ca
	    int ys = in.header().channels()["I"].ySampling;
Packit Service 6754ca
Packit Service 6754ca
	    fb.insert ("I",					// name
Packit Service 6754ca
		       Slice (IMF::UINT,			// type
Packit Service 6754ca
			      (char *) &pi2[-dy / ys][-dx / xs], // base
Packit Service 6754ca
			      sizeof (pi2[0][0]), 		// xStride
Packit Service 6754ca
			      sizeof (pi2[0][0]) * (w / xs),	// yStride
Packit Service 6754ca
			      xs,				// xSampling
Packit Service 6754ca
			      ys)				// ySampling
Packit Service 6754ca
		      );
Packit Service 6754ca
	}
Packit Service 6754ca
	    
Packit Service 6754ca
	{
Packit Service 6754ca
	    int xs = in.header().channels()["H"].xSampling;
Packit Service 6754ca
	    int ys = in.header().channels()["H"].ySampling;
Packit Service 6754ca
Packit Service 6754ca
	    fb.insert ("H",					// name
Packit Service 6754ca
		       Slice (IMF::HALF,			// type
Packit Service 6754ca
			      (char *) &ph2[-dy / ys][-dx / xs], // base
Packit Service 6754ca
			      sizeof (ph2[0][0]), 		// xStride
Packit Service 6754ca
			      sizeof (ph2[0][0]) * (w / xs),	// yStride
Packit Service 6754ca
			      xs,				// xSampling
Packit Service 6754ca
			      ys)				// ySampling
Packit Service 6754ca
		      );
Packit Service 6754ca
	}
Packit Service 6754ca
	    
Packit Service 6754ca
	{
Packit Service 6754ca
	    int xs = in.header().channels()["F"].xSampling;
Packit Service 6754ca
	    int ys = in.header().channels()["F"].ySampling;
Packit Service 6754ca
Packit Service 6754ca
	    fb.insert ("F",					// name
Packit Service 6754ca
		       Slice (IMF::FLOAT,			// type
Packit Service 6754ca
			      (char *) &pf2[-dy / ys][-dx / xs], // base
Packit Service 6754ca
			      sizeof (pf2[0][0]), 		// xStride
Packit Service 6754ca
			      sizeof (pf2[0][0]) * (w / xs),	// yStride
Packit Service 6754ca
			      xs,				// xSampling
Packit Service 6754ca
			      ys)				// ySampling
Packit Service 6754ca
		      );
Packit Service 6754ca
	}
Packit Service 6754ca
	
Packit Service 6754ca
	in.setFrameBuffer (fb);
Packit Service 6754ca
	in.readPixels (dw.min.y, dw.max.y);
Packit Service 6754ca
Packit Service 6754ca
	cout << " comparing" << flush;
Packit Service 6754ca
Packit Service 6754ca
	assert (in.header().displayWindow() == hdr.displayWindow());
Packit Service 6754ca
	assert (in.header().dataWindow() == hdr.dataWindow());
Packit Service 6754ca
	assert (in.header().pixelAspectRatio() == hdr.pixelAspectRatio());
Packit Service 6754ca
	assert (in.header().screenWindowCenter() == hdr.screenWindowCenter());
Packit Service 6754ca
	assert (in.header().screenWindowWidth() == hdr.screenWindowWidth());
Packit Service 6754ca
	assert (in.header().lineOrder() == hdr.lineOrder());
Packit Service 6754ca
	assert (in.header().compression() == hdr.compression());
Packit Service 6754ca
Packit Service 6754ca
	ChannelList::ConstIterator hi = hdr.channels().begin();
Packit Service 6754ca
	ChannelList::ConstIterator ii = in.header().channels().begin();
Packit Service 6754ca
Packit Service 6754ca
	while (hi != hdr.channels().end())
Packit Service 6754ca
	{
Packit Service 6754ca
	    assert (!strcmp (hi.name(), ii.name()));
Packit Service 6754ca
	    assert (hi.channel().type == ii.channel().type);
Packit Service 6754ca
	    assert (hi.channel().xSampling == ii.channel().xSampling);
Packit Service 6754ca
	    assert (hi.channel().ySampling == ii.channel().ySampling);
Packit Service 6754ca
Packit Service 6754ca
	    ++hi;
Packit Service 6754ca
	    ++ii;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	assert (ii == in.header().channels().end());
Packit Service 6754ca
Packit Service 6754ca
	for (int y = 0; y < h / ys; ++y)
Packit Service 6754ca
	{
Packit Service 6754ca
	    for (int x = 0; x < w / xs; ++x)
Packit Service 6754ca
	    {
Packit Service 6754ca
		assert (pi1[y][x] == pi2[y][x]);
Packit Service 6754ca
		assert (equivalent (pf1[y][x], pf2[y][x], comp));
Packit Service 6754ca
Packit Service 6754ca
		if (comp != B44_COMPRESSION &&
Packit Service 6754ca
                    comp != B44A_COMPRESSION)
Packit Service 6754ca
                {
Packit Service 6754ca
		    assert (ph1[y][x].bits() == ph2[y][x].bits());
Packit Service 6754ca
                }
Packit Service 6754ca
	    }
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
	if (comp == B44_COMPRESSION ||
Packit Service 6754ca
            comp == B44A_COMPRESSION)
Packit Service 6754ca
	{
Packit Service 6754ca
	    Array2D<half> ph3 (h / ys, w / xs);
Packit Service 6754ca
Packit Service 6754ca
	    for (int y = 0; y < h / ys; ++y)
Packit Service 6754ca
		for (int x = 0; x < w / xs; ++x)
Packit Service 6754ca
		    ph3[y][x] = ph1[y][x];
Packit Service 6754ca
Packit Service 6754ca
	    compareB44 (w / xs, h / ys, ph3, ph2);
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    remove (fileName);
Packit Service 6754ca
    cout << endl;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
writeRead (const std::string &tempDir,
Packit Service 6754ca
           const Array2D<unsigned int> &pi,
Packit Service 6754ca
	   const Array2D<half> &ph,
Packit Service 6754ca
	   const Array2D<float> &pf,
Packit Service 6754ca
	   int w,
Packit Service 6754ca
	   int h,
Packit Service 6754ca
	   int dx,
Packit Service 6754ca
	   int dy)
Packit Service 6754ca
{
Packit Service 6754ca
    std::string filename = tempDir + "imf_test_comp.exr";
Packit Service 6754ca
Packit Service 6754ca
    for (int xs = 1; xs <= 2; ++xs)
Packit Service 6754ca
    {
Packit Service 6754ca
	for (int ys = 1; ys <= 2; ++ys)
Packit Service 6754ca
	{
Packit Service 6754ca
	    for (int comp = 0; comp < NUM_COMPRESSION_METHODS; ++comp)
Packit Service 6754ca
	    {
Packit Service 6754ca
		writeRead (pi, ph, pf,
Packit Service 6754ca
			   filename.c_str(),
Packit Service 6754ca
			   w  * xs, h  * ys,
Packit Service 6754ca
			   dx * xs, dy * ys,
Packit Service 6754ca
			   Compression (comp),
Packit Service 6754ca
			   xs, ys);
Packit Service 6754ca
	    }
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
} // namespace
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
testCompression (const std::string &tempDir)
Packit Service 6754ca
{
Packit Service 6754ca
    try
Packit Service 6754ca
    {
Packit Service 6754ca
	cout << "Testing pixel data types, "
Packit Service 6754ca
		"subsampling and "
Packit Service 6754ca
		"compression schemes" << endl;
Packit Service 6754ca
Packit Service 6754ca
	const int W = 1371;
Packit Service 6754ca
	const int H = 159;
Packit Service 6754ca
	const int DX = 17;
Packit Service 6754ca
	const int DY = 29;
Packit Service 6754ca
Packit Service 6754ca
	Array2D<unsigned int> pi (H, W);
Packit Service 6754ca
	Array2D<half> ph (H, W);
Packit Service 6754ca
	Array2D<float> pf (H, W);
Packit Service 6754ca
Packit Service 6754ca
	//
Packit Service 6754ca
	// If the following assertion fails, new pixel types have
Packit Service 6754ca
	// been added to the Imf library; testing code for the new
Packit Service 6754ca
	// pixel types should be added to this file.
Packit Service 6754ca
	//
Packit Service 6754ca
Packit Service 6754ca
	assert (NUM_PIXELTYPES == 3);
Packit Service 6754ca
Packit Service 6754ca
	fillPixels1 (pi, ph, pf, W, H);
Packit Service 6754ca
	writeRead (tempDir, pi, ph, pf, W, H, DX, DY);
Packit Service 6754ca
Packit Service 6754ca
	fillPixels2 (pi, ph, pf, W, H);
Packit Service 6754ca
	writeRead (tempDir, pi, ph, pf, W, H, DX, DY);
Packit Service 6754ca
Packit Service 6754ca
	fillPixels3 (pi, ph, pf, W, H);
Packit Service 6754ca
	writeRead (tempDir, pi, ph, pf, W, H, DX, DY);
Packit Service 6754ca
Packit Service 6754ca
	fillPixels4 (pi, ph, pf, W, H);
Packit Service 6754ca
	writeRead (tempDir, pi, ph, pf, W, H, DX, DY);
Packit Service 6754ca
Packit Service 6754ca
	cout << "ok\n" << endl;
Packit Service 6754ca
    }
Packit Service 6754ca
    catch (const std::exception &e)
Packit Service 6754ca
    {
Packit Service 6754ca
	cerr << "ERROR -- caught exception: " << e.what() << endl;
Packit Service 6754ca
	assert (false);
Packit Service 6754ca
    }
Packit Service 6754ca
}