// DEPRECATED version bool ImageBufAlgo::add (ImageBuf &dst, const ImageBuf &A, const ImageBuf &B, int options) { // Sanity checks // dst must be distinct from A and B if ((const void *)&A == (const void *)&dst || (const void *)&B == (const void *)&dst) { dst.error ("destination image must be distinct from source"); return false; } // all three images must have the same number of channels if (A.spec().nchannels != B.spec().nchannels) { dst.error ("channel number mismatch: %d vs. %d", A.spec().nchannels, B.spec().nchannels); return false; } // If dst has not already been allocated, set it to the right size, // make it unconditinally float if (! dst.pixels_valid()) { ImageSpec dstspec = A.spec(); dstspec.set_format (TypeDesc::TypeFloat); dst.alloc (dstspec); } // Clear dst pixels if instructed to do so if (options & ADD_CLEAR_DST) { zero (dst); } ASSERT (A.spec().format == TypeDesc::FLOAT && B.spec().format == TypeDesc::FLOAT && dst.spec().format == TypeDesc::FLOAT); ImageBuf::ConstIterator<float,float> a (A); ImageBuf::ConstIterator<float,float> b (B); ImageBuf::Iterator<float> d (dst); int nchannels = A.nchannels(); // Loop over all pixels in A for ( ; a.valid(); ++a) { // Point the iterators for B and dst to the corresponding pixel if (options & ADD_RETAIN_WINDOWS) { b.pos (a.x(), a.y()); } else { // ADD_ALIGN_WINDOWS: make B line up with A b.pos (a.x()-A.xbegin()+B.xbegin(), a.y()-A.ybegin()+B.ybegin()); } d.pos (a.x(), b.y()); if (! b.valid() || ! d.valid()) continue; // Skip pixels that don't align // Add the pixel for (int c = 0; c < nchannels; ++c) d[c] = a[c] + b[c]; } return true; }