本文整理汇总了C++中ImageBuf::save方法的典型用法代码示例。如果您正苦于以下问题:C++ ImageBuf::save方法的具体用法?C++ ImageBuf::save怎么用?C++ ImageBuf::save使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ImageBuf
的用法示例。
在下文中一共展示了ImageBuf::save方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: postagespec
static void
test_getimagespec_gettexels (ustring filename)
{
ImageSpec spec;
if (! texsys->get_imagespec (filename, 0, spec)) {
std::cerr << "Could not get spec for " << filename << "\n";
std::string e = texsys->geterror ();
if (! e.empty())
std::cerr << "ERROR: " << e << "\n";
return;
}
int w = spec.width/2, h = spec.height/2;
ImageSpec postagespec (w, h, spec.nchannels, TypeDesc::FLOAT);
ImageBuf buf ("postage.exr", postagespec);
TextureOptions opt;
opt.nchannels = spec.nchannels;
if (missing[0] >= 0)
opt.missingcolor.init ((float *)&missing, 0);
std::vector<float> tmp (w*h*spec.nchannels);
bool ok = texsys->get_texels (filename, opt, 0, w/2, w/2+w, h/2, h/2+h,
0, 1, postagespec.format, &tmp[0]);
if (! ok)
std::cerr << texsys->geterror() << "\n";
for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x) {
imagesize_t offset = (y*w + x) * spec.nchannels;
buf.setpixel (x, y, &tmp[offset]);
}
buf.save ();
}
示例2: getBig
bool
SMT::decompile()
{
ImageBuf *bigBuf = getBig();
char filename[256];
sprintf(filename, "%s_tiles.png", outPrefix.c_str());
if(verbose )cout << "INFO: Saving to " << filename << endl;
bigBuf->save(filename);
return false;
}
示例3: getMinimap
bool
SMF::decompileMinimap()
{
ImageBuf *imageBuf = getMinimap();
if( !imageBuf ) return true;
char filename[256];
sprintf( filename, "%s_minimap.png", outPrefix.c_str() );
imageBuf->save( filename );
return false;
}
示例4: getHeight
bool
SMF::decompileHeight()
{
ImageBuf *imageBuf = getHeight();
if( !imageBuf ) return true;
char filename[256];
sprintf( filename, "%s_height.tif", outPrefix.c_str() );
imageBuf->save( filename );
return false;
}
示例5: tileSpec
void
SMTool::imageToSMT( SMT *smt, ImageBuf *sourceBuf )
{
using namespace std::chrono;
if( verbose )
cout << "INFO: Converting image to tiles and saving to smt" << endl;
ImageSpec sourceSpec = sourceBuf->spec();
unsigned int tileRes = smt->getTileSize();
ImageBuf tileBuf;
ImageSpec tileSpec( tileRes, tileRes, 4, TypeDesc::UINT8 );
ROI roi( 0, 1, 0, 1, 0, 1, 0, 4 );
ImageSpec mapSpec(
sourceSpec.width / tileSpec.width,
sourceSpec.height / tileSpec.height,
1,
TypeDesc::UINT );
ImageBuf mapBuf( "tilemap", mapSpec );
// Loop vars
unsigned int currentTile;
// Comparison vars
bool match;
unsigned int i;
string hash;
vector<string> hashTable;
TileBufListEntry *listEntry;
deque<TileBufListEntry *> tileList;
if( verbose ){
cout << "\tSource: " << sourceSpec.width << "x" << sourceSpec.height << endl;
cout << "\ttileRes: " << tileSpec.width << "x" << tileSpec.height << endl;
cout << "\ttilemap: " << mapSpec.width << "x" << mapSpec.height << endl;
cout << "\tmaxTiles: " << mapSpec.image_pixels() << endl;
cout << " Processing tiles:\n";
}
for( ImageBuf::Iterator<unsigned int, unsigned int> it(mapBuf); ! it.done(); ++it ){
currentTile = it.y() * mapSpec.width + it.x();
// define the cropping region.
roi.xbegin = it.x() * tileSpec.width;
roi.xend = it.x() * tileSpec.width + tileSpec.width;
roi.ybegin = it.y() * tileSpec.height;
roi.yend = it.y() * tileSpec.height + tileSpec.height;
// crop out tile.
ImageBufAlgo::cut( tileBuf, *sourceBuf, roi );
#ifdef DEBUG_IMG
tileBuf.save("SMTool::imageToSMT_tileBuf_" + to_string( currentTile + 1 ) + ".tif", "tif");
#endif //DEBUG_IMG
// reset match variables
match = false;
i = smt->getNTiles();
// Optimisation
if( cnum == 0){
// only exact matches will be referenced.
hash = ImageBufAlgo::computePixelHashSHA1( tileBuf );
for( i = 0; i < hashTable.size(); ++i ){
if(! hashTable[ i ].compare( hash ) ){
match = true;
break;
}
}
if(! match ) hashTable.push_back( hash );
}
else {
//Comparison based on numerical differences of pixels
listEntry = new TileBufListEntry;
listEntry->image.copy( tileBuf );
listEntry->tileNum = smt->getNTiles();
ImageBufAlgo::CompareResults result;
for( auto it = tileList.begin(); it != tileList.end(); it++ ){
TileBufListEntry *listEntry2 = *it;
ImageBufAlgo::compare( tileBuf, listEntry2->image,
cpet, 1.0f, result);
// TODO give control on tweaking matching
if( (int)result.nfail < cnet ){
match = true;
i = listEntry2->tileNum;
delete listEntry;
break;
}
}
if(! match ){
tileList.push_back( listEntry );
if( (int)tileList.size() > cnum ){
delete tileList[ 0 ];
tileList.pop_front();
}
//.........这里部分代码省略.........
示例6: outspec
//.........这里部分代码省略.........
opt.missingcolor.init ((float *)&missing, 0);
opt.swrap = opt.twrap = opt.rwrap = TextureOptions::WrapPeriodic;
int shadepoints = blocksize*blocksize;
Imath::V3f *P = ALLOCA (Imath::V3f, shadepoints);
Runflag *runflags = ALLOCA (Runflag, shadepoints);
Imath::V3f *dPdx = ALLOCA (Imath::V3f, shadepoints);
Imath::V3f *dPdy = ALLOCA (Imath::V3f, shadepoints);
Imath::V3f *dPdz = ALLOCA (Imath::V3f, shadepoints);
float *result = ALLOCA (float, shadepoints*nchannels);
for (int iter = 0; iter < iters; ++iter) {
// Iterate over blocks
// Trick: switch to second texture, if given, for second iteration
if (iter && filenames.size() > 1)
filename = ustring (filenames[1]);
for (int by = 0; by < output_yres; by+=blocksize) {
for (int bx = 0; bx < output_xres; bx+=blocksize) {
// Process pixels within a block. First save the texture warp
// (s,t) and derivatives into SIMD vectors.
int idx = 0;
for (int y = by; y < by+blocksize; ++y) {
for (int x = bx; x < bx+blocksize; ++x) {
if (x < output_xres && y < output_yres) {
if (nowarp) {
P[idx][0] = (float)x/output_xres * sscale;
P[idx][1] = (float)y/output_yres * tscale;
P[idx][2] = 0.5f * sscale;
P[idx] += offset;
dPdx[idx][0] = 1.0f/output_xres * sscale;
dPdx[idx][1] = 0;
dPdx[idx][2] = 0;
dPdy[idx][0] = 0;
dPdy[idx][1] = 1.0f/output_yres * tscale;
dPdy[idx][2] = 0;
dPdz[idx].setValue (0,0,0);
} else {
Imath::V3f coord = warp ((float)x/output_xres,
(float)y/output_yres,
0.5, xform);
coord.x *= sscale;
coord.y *= tscale;
coord += offset;
Imath::V3f coordx = warp ((float)(x+1)/output_xres,
(float)y/output_yres,
0.5, xform);
coordx.x *= sscale;
coordx.y *= tscale;
coordx += offset;
Imath::V3f coordy = warp ((float)x/output_xres,
(float)(y+1)/output_yres,
0.5, xform);
coordy.x *= sscale;
coordy.y *= tscale;
coordy += offset;
P[idx] = coord;
dPdx[idx] = coordx - coord;
dPdy[idx] = coordy - coord;
dPdz[idx].setValue (0,0,0);
}
runflags[idx] = RunFlagOn;
} else {
runflags[idx] = RunFlagOff;
}
++idx;
}
}
// Call the texture system to do the filtering.
bool ok = texsys->texture3d (filename, opt, runflags, 0, shadepoints,
Varying(P), Varying(dPdx),
Varying(dPdy), Varying(dPdz),
result);
if (! ok) {
std::string e = texsys->geterror ();
if (! e.empty())
std::cerr << "ERROR: " << e << "\n";
}
for (int i = 0; i < shadepoints*nchannels; ++i)
result[i] *= scalefactor;
// Save filtered pixels back to the image.
idx = 0;
for (int y = by; y < by+blocksize; ++y) {
for (int x = bx; x < bx+blocksize; ++x) {
if (runflags[idx]) {
image.setpixel (x, y, result + idx*nchannels);
}
++idx;
}
}
}
}
}
if (! image.save ())
std::cerr << "Error writing " << output_filename
<< " : " << image.geterror() << "\n";
}
示例7: decalList
void
SMT::pasteDecals(ImageBuf *bigBuf)
{
printf("WARNING: decal pasting is not yet implemented\n");
return;
// load definitions file
vector<type> list;
// Parse the file
printf( "INFO: Reading %s\n", decalFile.c_str() );
ifstream decalList( decalFile.c_str() );
string line;
string cell;
vector<string> tokens;
while ( getline( decalList, line ) ) {
stringstream lineStream( line );
tokens.clear();
while( getline( lineStream, cell, ',' ) ) tokens.push_back( cell );
if(tokens.size() <2 ) continue;
// use parsed line
coord xy;
type *decal;
// search for existing decal filename
bool found = false;
for(unsigned int i = 0; i < list.size(); ++i ) {
if( !list[i].imageName.compare( tokens[0].c_str() ) ) {
decal = &list[i];
found = true;
break;
}
}
if( !found ) {
decal = new type;
decal->imageName = tokens[0].c_str();
}
xy.x = atoi( tokens[1].c_str() );
xy.y = atoi( tokens[2].c_str() );
decal->coordinates.push_back(xy);
if( !found ) list.push_back(*decal);
}
// loop through list of decals.
for(unsigned int i = 0; i < list.size(); ++i ) {
if( verbose )printf(" %i %s ", (int)list[i].coordinates.size(),
list[i].imageName.c_str() );
ImageBuf decalBuf( list[i].imageName );
decalBuf.read( 0, 0, false, TypeDesc::FLOAT );
if( !decalBuf.initialized() ) {
printf("ERROR: could not load %s\n", list[i].imageName.c_str() );
continue;
}
ImageSpec decalSpec = decalBuf.spec();
printf("(%i,%i)%i\n", decalSpec.width, decalSpec.height,
decalSpec.nchannels );
// loop through list of coordinates
for(unsigned int j = 0; j < list[i].coordinates.size(); ++j ) {
coord xy = list[i].coordinates[j];
ROI roi( xy.x, xy.x + decalSpec.width,
xy.y, xy.y + decalSpec.height,
0,1,
0,5);
ImageBuf pasteBuf;
ImageBufAlgo::crop(pasteBuf, *bigBuf, roi);
ImageBuf compBuf;
if( !ImageBufAlgo::over( compBuf, decalBuf, pasteBuf) ) {
cout << "ERROR with composite: ";
cout << compBuf.geterror() << endl;
continue;
}
char filename[256];
sprintf(filename, "test%i.png", j);
compBuf.save(filename);
}
}
return;
}
示例8: diff
//.........这里部分代码省略.........
// Print the report
//
std::cout << " Mean error = ";
safe_double_print (cr.meanerror);
std::cout << " RMS error = ";
safe_double_print (cr.rms_error);
std::cout << " Peak SNR = ";
safe_double_print (cr.PSNR);
std::cout << " Max error = " << cr.maxerror;
if (cr.maxerror != 0) {
std::cout << " @ (" << cr.maxx << ", " << cr.maxy;
if (img0.spec().depth > 1)
std::cout << ", " << cr.maxz;
std::cout << ", " << img0.spec().channelnames[cr.maxc] << ')';
}
std::cout << "\n";
// when Visual Studio is used float values in scientific foramt are
// printed with three digit exponent. We change this behaviour to fit
// Linux way
#ifdef _MSC_VER
_set_output_format(_TWO_DIGIT_EXPONENT);
#endif
int precis = std::cout.precision();
std::cout << " " << cr.nwarn << " pixels ("
<< std::setprecision(3) << (100.0*cr.nwarn / npels)
<< std::setprecision(precis) << "%) over " << warnthresh << "\n";
std::cout << " " << cr.nfail << " pixels ("
<< std::setprecision(3) << (100.0*cr.nfail / npels)
<< std::setprecision(precis) << "%) over " << failthresh << "\n";
if (perceptual)
std::cout << " " << yee_failures << " pixels ("
<< std::setprecision(3) << (100.0*yee_failures / npels)
<< std::setprecision(precis)
<< "%) failed the perceptual test\n";
if (cr.nfail > (failpercent/100.0 * npels) || cr.maxerror > hardfail ||
yee_failures > (failpercent/100.0 * npels)) {
ret = ErrFail;
} else if (cr.nwarn > (warnpercent/100.0 * npels) || cr.maxerror > hardwarn) {
if (ret != ErrFail)
ret = ErrWarn;
}
// If the user requested that a difference image be output,
// do that. N.B. we only do this for the first subimage
// right now, because ImageBuf doesn't really know how to
// write subimages.
if (diffimage.size() && (cr.maxerror != 0 || !outdiffonly)) {
ImageBuf diff (diffimage, img0.spec());
ImageBuf::ConstIterator<float,float> pix0 (img0);
ImageBuf::ConstIterator<float,float> pix1 (img1);
ImageBuf::Iterator<float,float> pixdiff (diff);
// Subtract the second image from the first. At which
// time we no longer need the second image, so free it.
if (diffabs) {
for ( ; pix0.valid(); ++pix0) {
pix1.pos (pix0.x(), pix0.y()); // ensure alignment
pixdiff.pos (pix0.x(), pix0.y());
for (int c = 0; c < img0.nchannels(); ++c)
pixdiff[c] = diffscale * fabsf (pix0[c] - pix1[c]);
}
} else {
for ( ; pix0.valid(); ++pix0) {
pix1.pos (pix0.x(), pix0.y()); // ensure alignment
pixdiff.pos (pix0.x(), pix0.y());
for (int c = 0; c < img0.spec().nchannels; ++c)
pixdiff[c] = diffscale * (pix0[c] - pix1[c]);
}
}
diff.save (diffimage);
// Clear diff image name so we only save the first
// non-matching subimage.
diffimage = "";
}
}
}
if (compareall && img0.nsubimages() != img1.nsubimages()) {
std::cout << "Images had differing numbers of subimages ("
<< img0.nsubimages() << " vs " << img1.nsubimages() << ")\n";
ret = ErrFail;
}
if (!compareall && (img0.nsubimages() > 1 || img1.nsubimages() > 1)) {
std::cout << "Only compared the first subimage (of "
<< img0.nsubimages() << " and " << img1.nsubimages()
<< ", respectively)\n";
}
if (ret == ErrOK)
std::cout << "PASS\n";
else if (ret == ErrWarn)
std::cout << "WARNING\n";
else
std::cout << "FAILURE\n";
ImageCache::destroy (imagecache);
return ret;
}
示例9: main
int main (int argc, char *argv[])
{
// Arguments
if(argc != 3)
{
std::cerr << "mkthumbnail usage : mkthumbnail <input> <output>" << std::endl;
return EXIT_FAILURE;
}
std::string inputname=argv[1];
std::string outputname=argv[2];
std::string colortransfer_to = "sRGB";
std::string colortransfer_from = "sRGB";
// Colorspace selection
if(extensionIs(inputname, "exr") )
{
colortransfer_from="Linear";
}
else if(extensionIs(inputname, "dpx"))
{
colortransfer_from="KodakLog";
}
else
{
colortransfer_from="sRGB";
}
bool ok = true;
ImageBuf in;
if (! read_input (inputname, in))
{
std::cerr << "mkthumbnail: read error: " << in.geterror() << "\n";
return EXIT_FAILURE;
}
ColorTransfer *from_func = ColorTransfer::create (colortransfer_from + "_to_linear");
if (from_func == NULL) {
std::cerr << "mkthumbnail: --colorspace needs a 'colorspace' of "
<< "Linear, Gamma, sRGB, AdobeRGB, Rec709 or KodakLog\n";
return EXIT_FAILURE;
}
ColorTransfer *to_func = ColorTransfer::create (std::string("linear_to_") + colortransfer_to);
if (to_func == NULL) {
std::cerr << "mkthumbnail: --transfer needs a 'colorspace' of "
<< "Linear, Gamma, sRGB, AdobeRGB, Rec709 or KodakLog\n";
return EXIT_FAILURE;
}
std::cout << "Converting [" << colortransfer_from << "] " << inputname
<< " to [" << colortransfer_to << "] " << outputname << "\n";
//
ImageBuf linear;
ImageBuf outtmp;
ImageBufAlgo::colortransfer (linear, in, from_func);
ImageBufAlgo::colortransfer (outtmp, linear, to_func);
std::cout << "finished color transfer\n";
// Pixel aspect ratio
const ImageIOParameter *aspect = in.spec().find_attribute ("pixelaspectratio", TypeDesc::FLOAT);
float pixel_ratio = aspect ? *(float *)aspect->data() : 1.0f;
float ratio = ((float)in.spec().height+(float)in.spec().y)/((float)in.spec().width+(float)in.spec().x);
pixel_ratio = pixel_ratio != 0.f ? pixel_ratio : 1.f;
const int resize_w = 480; // resize target width
int resize_y = (int)((float)resize_w*ratio/pixel_ratio);
int resize_x = resize_w;
ImageSpec outspec = outtmp.spec();
outspec.x = 0;
outspec.y = 0;
outspec.full_x = 0;
outspec.full_y = 0;
outspec.width = resize_x;
outspec.height = resize_y;
outspec.full_width = resize_x;
outspec.full_height = resize_y;
ImageBuf out (outputname, outspec);
float pixel[3] = { .1f, .1f, .1f };
ImageBufAlgo::fill (out, pixel);
if(!ImageBufAlgo::resize (out, outtmp, out.xbegin(), out.xend(),
out.ybegin(), out.yend()))
{
std::cerr << "mkthumbnail: unable to resize image, " << out.geterror() << std::endl;
return EXIT_FAILURE;
}
if(out.spec().nchannels>3)
{
std::cout << "Changing number of channels to 3 "<< "\n";
ImageBuf newout("temp", out.spec());
setNbChannels (newout, out, 3);
out = newout;
}
if(!out.save (outputname))
{
std::cerr << "mkthumbnail: unable to save output image, " << out.geterror() << std::endl;
//.........这里部分代码省略.........
示例10: outspec
//.........这里部分代码省略.........
float theta = atan2f (yt, xt);
// See OSL's Dual2 for partial derivs of
// atan2, hypot, and 1/x
float denom = 1.0f / (xt*xt + yt*yt);
float dtheta_dx = yt*dxt_dx * denom;
float dtheta_dy = -xt*dyt_dy * denom;
s[idx] = 4.0f * theta / (2.0f * M_PI);
dsdx[idx] = 4.0f * dtheta_dx / (2.0f * M_PI);
dsdy[idx] = 4.0f * dtheta_dy / (2.0f * M_PI);
float h = hypot(xt,yt);
float dh_dx = xt*dxt_dx / h;
float dh_dy = yt*dyt_dy / h;
h *= M_SQRT2;
dh_dx *= M_SQRT2; dh_dy *= M_SQRT2;
float hinv = 1.0f / h;
t[idx] = hinv;
dtdx[idx] = hinv * (-hinv * dh_dx);
dtdy[idx] = hinv * (-hinv * dh_dy);
} else {
Imath::V3f coord = warp ((float)x/output_xres,
(float)y/output_yres,
xform);
coord.x *= sscale;
coord.y *= tscale;
coord += offset;
Imath::V3f coordx = warp ((float)(x+1)/output_xres,
(float)y/output_yres,
xform);
coordx.x *= sscale;
coordx.y *= tscale;
coordx += offset;
Imath::V3f coordy = warp ((float)x/output_xres,
(float)(y+1)/output_yres,
xform);
coordy.x *= sscale;
coordy.y *= tscale;
coordy += offset;
s[idx] = coord[0];
t[idx] = coord[1];
dsdx[idx] = coordx[0] - coord[0];
dtdx[idx] = coordx[1] - coord[1];
dsdy[idx] = coordy[0] - coord[0];
dtdy[idx] = coordy[1] - coord[1];
}
runflags[idx] = RunFlagOn;
} else {
runflags[idx] = RunFlagOff;
}
++idx;
}
}
// Call the texture system to do the filtering.
bool ok;
if (blocksize == 1) {
if (use_handle)
ok = texsys->texture (texture_handle, perthread_info, opt1,
s[0], t[0], dsdx[0], dtdx[0],
dsdy[0], dtdy[0], result);
else
ok = texsys->texture (filename, opt1,
s[0], t[0], dsdx[0], dtdx[0],
dsdy[0], dtdy[0], result);
} else {
ok = texsys->texture (filename, opt, runflags, 0,
shadepoints, Varying(s), Varying(t),
Varying(dsdx), Varying(dtdx),
Varying(dsdy), Varying(dtdy), result);
}
if (! ok) {
std::string e = texsys->geterror ();
if (! e.empty())
std::cerr << "ERROR: " << e << "\n";
}
for (int i = 0; i < shadepoints*nchannels; ++i)
result[i] *= scalefactor;
// Save filtered pixels back to the image.
idx = 0;
for (int y = by; y < by+blocksize; ++y) {
for (int x = bx; x < bx+blocksize; ++x) {
if (runflags[idx]) {
image.setpixel (x, y, result + idx*nchannels);
}
++idx;
}
}
}
}
if (resetstats) {
std::cout << texsys->getstats(2) << "\n";
texsys->reset_stats ();
}
}
if (! image.save ())
std::cerr << "Error writing " << output_filename
<< " : " << image.geterror() << "\n";
}
示例11: diff
//.........这里部分代码省略.........
std::cout << " Mean error = ";
safe_double_print (cr.meanerror);
std::cout << " RMS error = ";
safe_double_print (cr.rms_error);
std::cout << " Peak SNR = ";
safe_double_print (cr.PSNR);
std::cout << " Max error = " << cr.maxerror;
if (cr.maxerror != 0) {
std::cout << " @ (" << cr.maxx << ", " << cr.maxy;
if (img0.spec().depth > 1)
std::cout << ", " << cr.maxz;
std::cout << ", " << img0.spec().channelnames[cr.maxc] << ')';
}
std::cout << "\n";
// when Visual Studio is used float values in scientific foramt are
// printed with three digit exponent. We change this behaviour to fit
// Linux way
#ifdef _MSC_VER
_set_output_format(_TWO_DIGIT_EXPONENT);
#endif
int precis = std::cout.precision();
std::cout << " " << cr.nwarn << " pixels ("
<< std::setprecision(3) << (100.0*cr.nwarn / npels)
<< std::setprecision(precis) << "%) over " << ot.diff_warnthresh << "\n";
std::cout << " " << cr.nfail << " pixels ("
<< std::setprecision(3) << (100.0*cr.nfail / npels)
<< std::setprecision(precis) << "%) over " << ot.diff_failthresh << "\n";
#if 0
if (perceptual)
std::cout << " " << yee_failures << " pixels ("
<< std::setprecision(3) << (100.0*yee_failures / npels)
<< std::setprecision(precis)
<< "%) failed the perceptual test\n";
#endif
if (cr.nfail > (ot.diff_failpercent/100.0 * npels) || cr.maxerror > ot.diff_hardfail ||
yee_failures > (ot.diff_failpercent/100.0 * npels)) {
ret = DiffErrFail;
} else if (cr.nwarn > (ot.diff_warnpercent/100.0 * npels) || cr.maxerror > ot.diff_hardwarn) {
if (ret != DiffErrFail)
ret = DiffErrWarn;
}
#if 0
// If the user requested that a difference image be output,
// do that. N.B. we only do this for the first subimage
// right now, because ImageBuf doesn't really know how to
// write subimages.
if (diffimage.size() && (cr.maxerror != 0 || !outdiffonly)) {
ImageBuf diff (diffimage, img0.spec());
ImageBuf::ConstIterator<float,float> pix0 (img0);
ImageBuf::ConstIterator<float,float> pix1 (img1);
ImageBuf::Iterator<float,float> pixdiff (diff);
// Subtract the second image from the first. At which
// time we no longer need the second image, so free it.
if (diffabs) {
for ( ; pix0.valid(); ++pix0) {
pix1.pos (pix0.x(), pix0.y()); // ensure alignment
pixdiff.pos (pix0.x(), pix0.y());
for (int c = 0; c < img0.nchannels(); ++c)
pixdiff[c] = diffscale * fabsf (pix0[c] - pix1[c]);
}
} else {
for ( ; pix0.valid(); ++pix0) {
pix1.pos (pix0.x(), pix0.y()); // ensure alignment
pixdiff.pos (pix0.x(), pix0.y());
for (int c = 0; c < img0.spec().nchannels; ++c)
pixdiff[c] = diffscale * (pix0[c] - pix1[c]);
}
}
diff.save (diffimage);
// Clear diff image name so we only save the first
// non-matching subimage.
diffimage = "";
}
#endif
}
}
if (ot.allsubimages && ir0.subimages() != ir1.subimages()) {
std::cout << "Images had differing numbers of subimages ("
<< ir0.subimages() << " vs " << ir1.subimages() << ")\n";
ret = DiffErrFail;
}
if (!ot.allsubimages && (ir0.subimages() > 1 || ir1.subimages() > 1)) {
std::cout << "Only compared the first subimage (of "
<< ir0.subimages() << " and " << ir1.subimages()
<< ", respectively)\n";
}
if (ret == DiffErrOK)
std::cout << "PASS\n";
else if (ret == DiffErrWarn)
std::cout << "WARNING\n";
else {
std::cout << "FAILURE\n";
}
return ret;
}