epfl-archive/cs440-acg/ext/openexr/OpenEXR/IlmImfTest/testDeepScanLineMultipleRead.cpp
2022-04-07 18:46:57 +02:00

230 lines
6.6 KiB
C++

///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Weta Digital Ltd
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Weta Digital nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#include "testCompositeDeepScanLine.h"
#include <ImfDeepScanLineOutputFile.h>
#include <ImfDeepScanLineInputFile.h>
#include <ImfChannelList.h>
#include <ImfPartType.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfHeader.h>
#include <ImfNamespace.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "tmpDir.h"
namespace{
const char source_filename[] = IMF_TMP_DIR "imf_test_multiple_read.exr";
using std::cout;
using std::endl;
using std::flush;
using std::vector;
using OPENEXR_IMF_NAMESPACE::Header;
using OPENEXR_IMF_NAMESPACE::Channel;
using OPENEXR_IMF_NAMESPACE::UINT;
using OPENEXR_IMF_NAMESPACE::FLOAT;
using OPENEXR_IMF_NAMESPACE::DEEPSCANLINE;
using OPENEXR_IMF_NAMESPACE::ZIPS_COMPRESSION;
using OPENEXR_IMF_NAMESPACE::DeepScanLineOutputFile;
using OPENEXR_IMF_NAMESPACE::DeepScanLineInputFile;
using OPENEXR_IMF_NAMESPACE::DeepFrameBuffer;
using OPENEXR_IMF_NAMESPACE::Slice;
using OPENEXR_IMF_NAMESPACE::DeepSlice;
using IMATH_NAMESPACE::Box2i;
namespace IMF = OPENEXR_IMF_NAMESPACE;
static void
make_file(const char * filename)
{
int width=4;
int height=48;
//
// create a deep output file of widthxheight, where each pixel has 'y' samples,
// each with value 'x'
//
Header header( width,height);
header.channels().insert("Z", Channel(IMF::FLOAT));
header.compression()=ZIPS_COMPRESSION;
header.setType(DEEPSCANLINE);
remove (filename);
DeepScanLineOutputFile file(filename, header);
unsigned int sample_count;
float sample;
float * sample_ptr = &sample;
DeepFrameBuffer fb;
fb.insertSampleCountSlice(Slice(IMF::UINT,(char *)&sample_count));
fb.insert("Z",DeepSlice(IMF::FLOAT,(char *) &sample_ptr));
file.setFrameBuffer(fb);
for( int y=0 ; y < height ; y++ )
{
//
// ensure each scanline contains a different number of samples,
// with different values. We don't care that each sample has the same
// value, or that each pixel on the scanline is identical
//
sample_count = y;
sample = y+100.0;
file.writePixels(1);
}
}
static void read_file(const char * filename)
{
DeepScanLineInputFile file(filename);
Box2i datawin = file.header().dataWindow();
int width = datawin.size().x+1;
int height = datawin.size().y+1;
int x_offset = datawin.min.x;
int y_offset = datawin.min.y;
const char * channel = file.header().channels().begin().name();
vector<unsigned int> samplecounts(width);
vector<float *> sample_pointers(width);
vector<float> samples;
DeepFrameBuffer fb;
fb.insertSampleCountSlice(Slice(IMF::UINT,(char *) (&samplecounts[0]-x_offset) , sizeof(unsigned int)));
fb.insert( channel, DeepSlice(IMF::FLOAT,(char *) (&sample_pointers[0]-x_offset) , sizeof(float *),0,sizeof(float)) );
file.setFrameBuffer(fb);
for(int count=0;count<4000;count++)
{
int row = rand() % height + y_offset;
//
// read row y (at random)
//
file.readPixelSampleCounts(row,row);
//
// check that's correct, and also resize samples array
//
int total_samples = 0;
for(int i=0;i<width;i++)
{
if( samplecounts[i]!= row)
{
cout << i << ", " << row << " error, sample counts hould be "
<< row << ", is " << samplecounts[i]
<< endl << flush;
}
assert (samplecounts[i]== row);
total_samples+=samplecounts[i];
}
samples.resize(total_samples);
//
// set pointers to point to the correct place
//
int total=0;
for(int i=0 ; i<width && total < total_samples ; i++)
{
sample_pointers[i] = &samples[total];
total+=samplecounts[i];
}
//
// read channel
//
file.readPixels(row,row);
//
// check
//
for(int i=0;i<total_samples;i++)
{
if(samples[i]!=row+100.f)
{
cout << " sample " << i << " on row " << row << " error, shuold be "
<< 100.f+row << " got " << samples[i] << endl;
cout << flush;
}
assert(samples[i]==row+100.f);
}
}
}
}
void
testDeepScanLineMultipleRead(const std::string & tempDir)
{
cout << "\n\nTesting random re-reads from deep scanline file:\n" << endl;
std::string source_filename = tempDir + "imf_test_multiple_read";
srand(1);
make_file(source_filename.c_str());
read_file(source_filename.c_str());
remove(source_filename.c_str());
cout << " ok\n" << endl;
}