(is vxlmaintainers a subset of vxlusers?)
In file "vil_interpolate.txx", function "template <class T, class U> bool vil_interpolate_bilinear",
the final line is:
*out = U(pix00 * weight00 + pix10 * weight10 + pix01 * weight01 + pix11 * weight11);
*out is of type T. This is a nice and general template, but if both T and U are integral types, then
the right hand side above gets promoted to double because the weight* vars are type double. Then,
the cast to type U gets to an integer by truncation. I think it would be much better to go to the
nearest integer. This is causing problems for me and I'd like to fix it. I have not yet come up
with a clean and easy way, so I'm looking for suggestions. My favorite attempt so far is below.
Alas, it is really not sufficient. For one, I don't think vcl_numeric_limits works. For two, this
breaks when instantiated with T as an rgb<unsigned char> (not quite the right name, but you know what
I mean) type because both the if and else clauses must be compiled even if only one will be used for
a certain type, and there is no >= for the rgb<unsigned char>. Any suggestions or pointers?
T x = pix00 * weight00 + pix10 * weight10 +
pix01 * weight01 + pix11 * weight11;
// conversion done depending on the template types
// when casting a floating type to an integral type, round to nearest int
if (std::numeric_limits<U>::is_specialized &&
std::numeric_limits<T>::is_specialized &&
std::numeric_limits<U>::is_integer &&
! std::numeric_limits<T>::is_integer ) {
// add (subtract) 0.5 if greater (less) than 0
// so truncation will lead to the nearest integer
*out = U( x + ( (x >= T(0.0)) ? T(0.5) : T(0.5) ) );
} else {
*out = U(x);
}
Thanks,
Fred Wheeler
