|
Packit |
0d464f |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Copyright (c) 2012, Weta Digital Ltd
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// All rights reserved.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
0d464f |
// modification, are permitted provided that the following conditions are
|
|
Packit |
0d464f |
// met:
|
|
Packit |
0d464f |
// * Redistributions of source code must retain the above copyright
|
|
Packit |
0d464f |
// notice, this list of conditions and the following disclaimer.
|
|
Packit |
0d464f |
// * Redistributions in binary form must reproduce the above
|
|
Packit |
0d464f |
// copyright notice, this list of conditions and the following disclaimer
|
|
Packit |
0d464f |
// in the documentation and/or other materials provided with the
|
|
Packit |
0d464f |
// distribution.
|
|
Packit |
0d464f |
// * Neither the name of Weta Digital nor the names of
|
|
Packit |
0d464f |
// its contributors may be used to endorse or promote products derived
|
|
Packit |
0d464f |
// from this software without specific prior written permission.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
0d464f |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
0d464f |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
0d464f |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
0d464f |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
0d464f |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
0d464f |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
0d464f |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
0d464f |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
0d464f |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
0d464f |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include "testCompositeDeepScanLine.h"
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include <vector>
|
|
Packit |
0d464f |
#include <string>
|
|
Packit |
0d464f |
#include <Iex.h>
|
|
Packit |
0d464f |
#include <ostream>
|
|
Packit |
0d464f |
#include <iostream>
|
|
Packit |
0d464f |
#include <typeinfo>
|
|
Packit |
0d464f |
#include <stdlib.h>
|
|
Packit |
0d464f |
#include <assert.h>
|
|
Packit |
0d464f |
#include <sstream>
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include <ImfMultiPartOutputFile.h>
|
|
Packit |
0d464f |
#include <ImfMultiPartInputFile.h>
|
|
Packit |
0d464f |
#include <ImfDeepScanLineOutputPart.h>
|
|
Packit |
0d464f |
#include <ImfDeepScanLineInputPart.h>
|
|
Packit |
0d464f |
#include <ImfChannelList.h>
|
|
Packit |
0d464f |
#include <ImfHeader.h>
|
|
Packit |
0d464f |
#include <ImfDeepFrameBuffer.h>
|
|
Packit |
0d464f |
#include <ImfFrameBuffer.h>
|
|
Packit |
0d464f |
#include <ImfPartType.h>
|
|
Packit |
0d464f |
#include <ImfCompression.h>
|
|
Packit |
0d464f |
#include <ImfInputFile.h>
|
|
Packit |
0d464f |
#include <ImfCompositeDeepScanLine.h>
|
|
Packit |
0d464f |
#include <ImfThreading.h>
|
|
Packit |
0d464f |
#include <IlmThread.h>
|
|
Packit |
0d464f |
#include <ImfNamespace.h>
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
namespace
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
using std::vector;
|
|
Packit |
0d464f |
using std::string;
|
|
Packit |
0d464f |
using std::ostream;
|
|
Packit |
0d464f |
using std::endl;
|
|
Packit |
0d464f |
using std::cout;
|
|
Packit |
0d464f |
using std::ostringstream;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::DeepScanLineOutputFile;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::MultiPartInputFile;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::DeepScanLineOutputPart;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::DeepScanLineInputPart;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::Header;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::PixelType;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::DeepFrameBuffer;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::FrameBuffer;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::FLOAT;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::HALF;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::UINT;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::Slice;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::DeepSlice;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::MultiPartOutputFile;
|
|
Packit |
0d464f |
using IMATH_NAMESPACE::Box2i;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::DEEPSCANLINE;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::ZIPS_COMPRESSION;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::InputFile;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::setGlobalThreadCount;
|
|
Packit |
0d464f |
using OPENEXR_IMF_NAMESPACE::CompositeDeepScanLine;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// a marker to say we've done inserting values into a sample: do mydata << end()
|
|
Packit |
0d464f |
struct end{};
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// a marker to say we're about to send the final result, not another sample: do mydata << result()
|
|
Packit |
0d464f |
struct result{};
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// support class that generates deep data, along with the 'ground truth'
|
|
Packit |
0d464f |
// result
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
template<class T>
|
|
Packit |
0d464f |
class data
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
public:
|
|
Packit |
0d464f |
vector<string> _channels; // channel names - same size and order as in all other arrays,
|
|
Packit |
0d464f |
vector<T> _current_result; // one value per channel: the ground truth value for the given pixel
|
|
Packit |
0d464f |
vector<vector <T> >_results; // a list of result pixels
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bool _inserting_result;
|
|
Packit |
0d464f |
bool _started; // we've started to assemble the values - no more channels permitted
|
|
Packit |
0d464f |
vector<T> _current_sample; // one value per channel for the sample currently being inserted
|
|
Packit |
0d464f |
vector< vector <T> > _current_pixel; // a list of results for the current pixwel
|
|
Packit |
0d464f |
vector< vector< vector<T> > > _samples; // a list of pixels
|
|
Packit |
0d464f |
PixelType _type;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
data() : _inserting_result(false),_started(false)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(typeid(T)==typeid(half))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_type = OPENEXR_IMF_NAMESPACE::HALF;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_type = OPENEXR_IMF_NAMESPACE::FLOAT;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// add a value to the current sample
|
|
Packit |
0d464f |
data & operator << (float value)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_inserting_result)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_current_result.push_back(value);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
_current_sample.push_back(T(value));
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
_started=true;
|
|
Packit |
0d464f |
return *this;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// switch between writing samples and the result
|
|
Packit |
0d464f |
data & operator << (const result &)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_current_sample.size()!=0)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc("bug in test code: can't switch to inserting result: values written without 'end' statement");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
if(_current_result.size()!=0)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc("bug in test suite: already inserting result");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
_inserting_result=true;
|
|
Packit |
0d464f |
return *this;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// finalise the current sample/results
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
data & operator << (const end &)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_inserting_result)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_current_result.size()!=_channels.size())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc("bug in test suite: cannot end result: wrong number of values written");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
_results.push_back(_current_result);
|
|
Packit |
0d464f |
_current_result.resize(0);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// also cause the current_samples to be written as the given number of pixels
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
_samples.push_back(_current_pixel);
|
|
Packit |
0d464f |
_current_pixel.resize(0);
|
|
Packit |
0d464f |
_inserting_result=false;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_current_sample.size()!=_channels.size())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc("bug in test suite: cannot end sample: wrong number of values written");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
_current_pixel.push_back(_current_sample);
|
|
Packit |
0d464f |
_current_sample.resize(0);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
return *this;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// add a new channel
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
data & operator << (const string & s)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_started)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc("bug in test suite: cannot insert new channels here");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
_channels.push_back(s);
|
|
Packit |
0d464f |
return *this;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// total number of samples - storage for one copy of everything is sizeof(T)*channels.size()*totalSamples
|
|
Packit |
0d464f |
size_t totalSamples() const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
size_t answer=0;
|
|
Packit |
0d464f |
for(size_t i=0;i<_samples.size();i++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
answer+=_samples[i].size();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
return answer;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//copy the channels into the header list
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
setHeader(Header & hdr) const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for(size_t i=0;i<_channels.size();i++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
hdr.channels().insert(_channels[i],_type);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void frak(vector< data<T> > & parts) const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for(size_t i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
parts[i]._channels = _channels;
|
|
Packit |
0d464f |
parts[i]._results = _results;
|
|
Packit |
0d464f |
parts[i]._type = _type;
|
|
Packit |
0d464f |
parts[i]._samples.resize(_samples.size());
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// loop over each pixel, pushing its values to a random part
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
for(size_t i=0;i<_samples.size();i++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
// copy sample to a random part
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(int s=0;s<_samples[i].size();s++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
int part = rand()% parts.size();
|
|
Packit |
0d464f |
parts[part]._samples[i].push_back(_samples[i][s]);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
writeData(DeepScanLineOutputPart & part) const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Box2i dw=part.header().dataWindow();
|
|
Packit |
0d464f |
size_t output_pixels = (dw.size().x+1)*(dw.size().y+1);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// how many times we'll write the same pattern
|
|
Packit |
0d464f |
size_t repeats = 1+(output_pixels/_results.size());
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
size_t sample_buffer_size = totalSamples()*repeats;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// buffer for sample counts
|
|
Packit |
0d464f |
vector<unsigned int> counts(output_pixels);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// buffers for sample pointers
|
|
Packit |
0d464f |
vector< vector<T *> > sample_pointers(_channels.size());
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// buffer for actual sample data
|
|
Packit |
0d464f |
vector< vector<T> > sample_buffers(_channels.size());
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(size_t i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
sample_pointers[i].resize(output_pixels);
|
|
Packit |
0d464f |
sample_buffers[i].resize(sample_buffer_size);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
size_t pixel=0; // which pixel we are currently writing
|
|
Packit |
0d464f |
size_t sample=0; // which sample we are currently writing into
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(size_t p=0;p
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
size_t count = _samples[pixel].size();
|
|
Packit |
0d464f |
counts[p]=count;
|
|
Packit |
0d464f |
if( count>0 )
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for(size_t c=0 ; c<_channels.size() ; c++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for(size_t s=0 ; s < count ; s++ )
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
sample_buffers[c][sample+s]=_samples[pixel][s][c];
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
sample_pointers[c][p]=&sample_buffers[c][sample];
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
sample+=count;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
pixel++;
|
|
Packit |
0d464f |
if(pixel==_samples.size()) pixel=0;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
cout << " wrote " << sample << " samples into " << output_pixels << " pixels\n";
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
DeepFrameBuffer fb;
|
|
Packit |
0d464f |
fb.insertSampleCountSlice(Slice(UINT,
|
|
Packit |
0d464f |
(char *)(&counts[0]-dw.min.x-(dw.size().x+1)*dw.min.y),
|
|
Packit |
0d464f |
sizeof(unsigned int),
|
|
Packit |
0d464f |
sizeof(unsigned int)*(dw.size().x+1)
|
|
Packit |
0d464f |
)
|
|
Packit |
0d464f |
);
|
|
Packit |
0d464f |
for(size_t c=0;c<_channels.size();c++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
fb.insert(_channels[c],
|
|
Packit |
0d464f |
DeepSlice(_type,(char *)(&sample_pointers[c][0]-dw.min.x-(dw.size().x+1)*dw.min.y),
|
|
Packit |
0d464f |
sizeof(T *),
|
|
Packit |
0d464f |
sizeof(T *)*(dw.size().x+1),
|
|
Packit |
0d464f |
sizeof(T)
|
|
Packit |
0d464f |
)
|
|
Packit |
0d464f |
);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
part.setFrameBuffer(fb);
|
|
Packit |
0d464f |
part.writePixels(dw.size().y+1);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
setUpFrameBuffer(vector<T> & data,FrameBuffer & framebuf,const Box2i & dw,bool dontbotherloadingdepth) const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// allocate enough space for all channels (even the depth channel)
|
|
Packit |
0d464f |
data.resize(_channels.size()*(dw.size().x+1)*(dw.size().y+1));
|
|
Packit |
0d464f |
for(size_t i=0;i<_channels.size();i++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(!dontbotherloadingdepth || (_channels[i]!="Z" && _channels[i]!="ZBack") )
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
framebuf.insert(_channels[i].c_str(),
|
|
Packit |
0d464f |
Slice(_type,(char *) (&data[i] - (dw.min.x + dw.min.y*(dw.size().x+1))*_channels.size() ),
|
|
Packit |
0d464f |
sizeof(T)*_channels.size(),
|
|
Packit |
0d464f |
sizeof(T)*(dw.size().x+1)*_channels.size())
|
|
Packit |
0d464f |
);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// check values are within a suitable tolerance of the expected value (expect some errors due to half float storage etc)
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
checkValues(const vector<T> & data,const Box2i & dw,bool dontbothercheckingdepth)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
size_t size = _channels.size()+(dw.size().x+1)*(dw.size().y+1);
|
|
Packit |
0d464f |
size_t pel=0;
|
|
Packit |
0d464f |
size_t channel=0;
|
|
Packit |
0d464f |
if(dontbothercheckingdepth)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for(size_t i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_channels[channel]!="Z" && _channels[channel]!="ZBack")
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(fabs(_results[pel][channel] - data[i])>0.005)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
cout << "sample " << i << " (channel " << _channels[channel] << " of pixel " << i % _channels.size() << ") ";
|
|
Packit |
0d464f |
cout << "doesn't match expected value (channel " << channel << " of pixel " << pel << ") : ";
|
|
Packit |
0d464f |
cout << "got " << data[i] << " expected " << _results[pel][channel] << endl;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
assert(fabs(_results[pel][channel]- data[i])<=0.005);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
channel++;
|
|
Packit |
0d464f |
if(channel==_channels.size())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
channel=0;
|
|
Packit |
0d464f |
pel++;
|
|
Packit |
0d464f |
if(pel==_results.size())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
pel=0;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
for(size_t i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(fabs(_results[pel][channel] - data[i])>0.005)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
cout << "sample " << i << " (channel " << _channels[channel] << " of pixel " << i % _channels.size() << ") ";
|
|
Packit |
0d464f |
cout << "doesn't match expected value (channel " << channel << " of pixel " << pel << ") : ";
|
|
Packit |
0d464f |
cout << "got " << data[i] << " expected " << _results[pel][channel] << endl;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
assert(fabs(_results[pel][channel] - data[i])<=0.005);
|
|
Packit |
0d464f |
channel++;
|
|
Packit |
0d464f |
if(channel==_channels.size())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
channel=0;
|
|
Packit |
0d464f |
pel++;
|
|
Packit |
0d464f |
if(pel==_results.size())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
pel=0;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
};
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
template<class T>
|
|
Packit |
0d464f |
ostream & operator << (ostream & o,data<T> & d)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
o << "channels: [ ";
|
|
Packit |
0d464f |
for(size_t i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
o << d._channels[i] << " ";
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
o << "]" << endl;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(size_t i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
o << "pixel: " << d._samples[i].size() << " samples" << endl;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(size_t j=0;j
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
o << " " << j << ": [ ";
|
|
Packit |
0d464f |
for(size_t k = 0; k < d._samples[i][j].size();k++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
o << d._samples[i][j][k] << ' ';
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
o << "]" << endl;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
o << "result: [ ";
|
|
Packit |
0d464f |
for(size_t k=0;k
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
o << d._results[i][k] << ' ' ;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
o << "]\n" << endl;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
return o;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
template<class DATA>
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
make_pattern(data<DATA> & bob,int pattern_number)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (pattern_number==0)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
// set channels
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bob << string("Z") << string("ZBack") << string("A") << string("R");
|
|
Packit |
0d464f |
PixelType t;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// regular two-pixel composite
|
|
Packit |
0d464f |
bob << 1.0 << 2.0 << 0.0 << 1.0 << end();
|
|
Packit |
0d464f |
bob << 2.1 << 2.3 << 0.5 << 0.4 << end();
|
|
Packit |
0d464f |
bob << result();
|
|
Packit |
0d464f |
bob << 3.1 << 4.3 << 0.5 << 1.4 << end();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bob << 10 << 20 << 1.0 << 1.0 << end();
|
|
Packit |
0d464f |
bob << 20 << 30 << 1.0 << 2.0 << end();
|
|
Packit |
0d464f |
bob << result();
|
|
Packit |
0d464f |
bob << 10 << 20 << 1.0 << 1.0 << end();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bob << result();
|
|
Packit |
0d464f |
bob << 0.0 << 0.0 << 0.0 << 0.0 << end();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else if (pattern_number==1)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// out of order channels, no zback - should-re-order them for us
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
bob << string("Z") << string("R") << string("G") << string("B") << string("A");
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// write this four times, so we get various patterns for splitting the blocks
|
|
Packit |
0d464f |
for(int pass=0;pass<4;pass++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
// regular four-pixel composite
|
|
Packit |
0d464f |
bob << 1.0 << 0.4 << 1.25 << -0.1 << 0.7 << end();
|
|
Packit |
0d464f |
bob << 2.2 << 0.2 << -0.1 << 0.0 << 0.24 << end();
|
|
Packit |
0d464f |
bob << 2.3 << 0.9 << 0.56 << 2.26 << 0.9 << end();
|
|
Packit |
0d464f |
bob << 5.0 << 1.0 << 0.5 << 0.60 << 0.2 << end();
|
|
Packit |
0d464f |
bob << result();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// eight-pixel composite
|
|
Packit |
0d464f |
bob << 2.2984 << 0.68800 << 1.35908 << 0.42896 << 0.9817 << end();
|
|
Packit |
0d464f |
bob << 1.0 << 0.4 << 1.25 << -0.1 << 0.7 << end();
|
|
Packit |
0d464f |
bob << 2.2 << 0.2 << -0.1 << 0.0 << 0.24 << end();
|
|
Packit |
0d464f |
bob << 2.3 << 0.9 << 0.56 << 2.26 << 0.9 << end();
|
|
Packit |
0d464f |
bob << 5.0 << 1.0 << 0.5 << 0.60 << 0.2 << end();
|
|
Packit |
0d464f |
bob << 11.0 << 0.4 << 1.25 << -0.1 << 0.7 << end();
|
|
Packit |
0d464f |
bob << 12.2 << 0.2 << -0.1 << 0.0 << 0.24 << end();
|
|
Packit |
0d464f |
bob << 12.3 << 0.9 << 0.56 << 2.26 << 0.9 << end();
|
|
Packit |
0d464f |
bob << 15.0 << 1.0 << 0.5 << 0.60 << 0.2 << end();
|
|
Packit |
0d464f |
bob << result();
|
|
Packit |
0d464f |
bob << 2.62319 << 0.7005 << 1.38387 << 0.43678 << 0.99967 << end();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// one-pixel composite
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bob << 27.0 << 1.0 << -1.0 << 42.0 << 14 << end(); // alpha>1 should still work
|
|
Packit |
0d464f |
bob << result();
|
|
Packit |
0d464f |
bob << 27.0 << 1.0 << -1.0 << 42.0 << 14 << end();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
template<class T>
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
write_file(const char * filename, const data<T> & master, int number_of_parts)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
vector<Header> headers(number_of_parts);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// all headers are the same in this test
|
|
Packit |
0d464f |
headers[0].displayWindow().max.x=164;
|
|
Packit |
0d464f |
headers[0].displayWindow().max.y=216;
|
|
Packit |
0d464f |
headers[0].dataWindow().min.x=rand()%400 - 200;
|
|
Packit |
0d464f |
headers[0].dataWindow().max.x=headers[0].dataWindow().min.x+40+rand()%400;
|
|
Packit |
0d464f |
headers[0].dataWindow().min.y=rand()%400 - 200;
|
|
Packit |
0d464f |
headers[0].dataWindow().max.y=headers[0].dataWindow().min.y+40+rand()%400;
|
|
Packit |
0d464f |
cout << "data window: " << headers[0].dataWindow().min.x << ',' << headers[0].dataWindow().min.y << ' ' <<
|
|
Packit |
0d464f |
headers[0].dataWindow().max.x << ',' << headers[0].dataWindow().max.y << endl;
|
|
Packit |
0d464f |
headers[0].setType(DEEPSCANLINE);
|
|
Packit |
0d464f |
headers[0].compression()=ZIPS_COMPRESSION;
|
|
Packit |
0d464f |
headers[0].setName("Part0");
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(int i=1;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
headers[i]=headers[0];
|
|
Packit |
0d464f |
ostringstream s;
|
|
Packit |
0d464f |
s << "Part" << i;
|
|
Packit |
0d464f |
headers[i].setName(s.str());
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
vector< data<T> > sub_parts(number_of_parts);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if(number_of_parts>1)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
master.frak(sub_parts);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if(number_of_parts==1)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
master.setHeader(headers[0]);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(int i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
sub_parts[i].setHeader(headers[i]);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
MultiPartOutputFile f(filename,&headers[0],headers.size());
|
|
Packit |
0d464f |
for(int i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
DeepScanLineOutputPart p(f,i);
|
|
Packit |
0d464f |
if(number_of_parts==1)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
master.writeData(p);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
sub_parts[i].writeData(p);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
template<class T>
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
test_parts (int pattern_number,
|
|
Packit |
0d464f |
int number_of_parts,
|
|
Packit |
0d464f |
bool load_depths,
|
|
Packit |
0d464f |
bool entire_buffer,
|
|
Packit |
0d464f |
const std::string &tempDir)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
std::string fn = tempDir + "imf_test_composite_deep_scanline_source.exr";
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
data<T> master;
|
|
Packit |
0d464f |
make_pattern (master, pattern_number);
|
|
Packit |
0d464f |
write_file (fn.c_str(), master,number_of_parts);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
vector<T> data;
|
|
Packit |
0d464f |
CompositeDeepScanLine comp;
|
|
Packit |
0d464f |
FrameBuffer testbuf;
|
|
Packit |
0d464f |
MultiPartInputFile input(fn.c_str());
|
|
Packit |
0d464f |
vector<DeepScanLineInputPart *> parts(number_of_parts);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// use 'part' interface TODO test file interface too
|
|
Packit |
0d464f |
for(int i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
parts[i] = new DeepScanLineInputPart(input,i);
|
|
Packit |
0d464f |
comp.addSource(parts[i]);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
master.setUpFrameBuffer(data,testbuf,comp.dataWindow(),load_depths);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
comp.setFrameBuffer(testbuf);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// try loading the whole buffer
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
if(entire_buffer)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
comp.readPixels(comp.dataWindow().min.y,comp.dataWindow().max.y);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
int low = comp.dataWindow().min.y;
|
|
Packit |
0d464f |
while(low
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
int high = low + rand()%64;
|
|
Packit |
0d464f |
if(high>comp.dataWindow().max.y)
|
|
Packit |
0d464f |
high = comp.dataWindow().max.y;
|
|
Packit |
0d464f |
comp.readPixels(low,high);
|
|
Packit |
0d464f |
low = high;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
master.checkValues(data,comp.dataWindow(),load_depths);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(int i=0;i
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
delete parts[i];
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
if(number_of_parts==1)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
// also test InputFile interface
|
|
Packit |
0d464f |
InputFile file(fn.c_str());
|
|
Packit |
0d464f |
vector<T> data;
|
|
Packit |
0d464f |
FrameBuffer testbuf;
|
|
Packit |
0d464f |
const Box2i & dataWindow = file.header().dataWindow();
|
|
Packit |
0d464f |
master.setUpFrameBuffer(data,testbuf,dataWindow,load_depths);
|
|
Packit |
0d464f |
file.setFrameBuffer(testbuf);
|
|
Packit |
0d464f |
if(entire_buffer)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
file.readPixels(dataWindow.min.y,dataWindow.max.y);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
int low = dataWindow.min.y;
|
|
Packit |
0d464f |
while(low
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
int high = low + rand()%64;
|
|
Packit |
0d464f |
if(high>dataWindow.max.y)
|
|
Packit |
0d464f |
high = dataWindow.max.y;
|
|
Packit |
0d464f |
file.readPixels(low,high);
|
|
Packit |
0d464f |
low = high;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
master.checkValues (data, dataWindow, load_depths);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
remove (fn.c_str());
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void testCompositeDeepScanLine (const std::string & tempDir)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
cout << "\n\nTesting deep compositing interface basic functionality:\n" << endl;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int passes=2;
|
|
Packit |
0d464f |
if (!ILMTHREAD_NAMESPACE::supportsThreads ())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
passes=1;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
srand(1);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for(int pass=0;pass<2;pass++)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
test_parts<float>(0, 1, true, true, tempDir);
|
|
Packit |
0d464f |
test_parts<float>(0, 1, false, false, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (0, 1, true, false, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (0, 1, false, true, tempDir);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// test pattern 1: tested by confirming data is written correctly and
|
|
Packit |
0d464f |
// then reading correct results in Nuke
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
test_parts<float>(1, 1, true, false, tempDir);
|
|
Packit |
0d464f |
test_parts<float>(1, 1, false, true, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (1, 1, true, true, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (1, 1, false, false, tempDir);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
cout << "Testing deep compositing across multiple parts:\n" << endl;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
test_parts<float>(0, 5, true, false, tempDir);
|
|
Packit |
0d464f |
test_parts<float>(0, 5, false, true, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (0, 5, true, false, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (0, 5, false, true, tempDir);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
test_parts<float>(1, 3, true, true, tempDir);
|
|
Packit |
0d464f |
test_parts<float>(1, 3, false, false, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (1, 3, true, true, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (1, 3, false, false, tempDir);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
test_parts<float>(1, 4, true, true, tempDir);
|
|
Packit |
0d464f |
test_parts<float>(1, 4, false, false, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (1, 4, true, false, tempDir);
|
|
Packit |
0d464f |
test_parts<half> (1, 4, false, true, tempDir);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if(passes==2 && pass==0)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
cout << " testing with multithreading...\n";
|
|
Packit |
0d464f |
setGlobalThreadCount(64);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
cout << " ok\n" << endl;
|
|
Packit |
0d464f |
}
|