From: Wheeler, Fred (CRD) <wheeler@cr...>  20020125 15:40:55

Not using template functions leads to a maintenance problem. A vil_round must be defined for all possible pixel types for which template <class T, class U> bool vil_interpolate_bilinear is instantiated, including combos with rgb<whatever type>. If vil_round could be a templated function with a default (ordinary cast) and specializations (better rounding from floating to integral) we would have a nice solution, but it sounds like msvc won't support that. I agree that a conditional inside the loop should be avoided, but in this case I'm sure it would be compiled out. That's moot anyway, since that technique would not work due to the absence of >= ops for rgb<> types. Fred Wheeler Original Message From: Ian Scott [mailto:ian.m.scott@...] Sent: Friday, January 25, 2002 10:26 AM To: Wheeler, Fred (CRD); Blezek, Daniel J (CRD) Cc: Vxlmaintainers (Email) Subject: RE: [Vxlmaintainers] casting instead of rounding in templates If the rounding/summation function is a separate inline function, having 10 or 20 specialisations doesn't sound like a big deal to me. Afterall they can probably be four lines each. e.g. (roughly  the code may be wrong) inline vil_round(float * out, double in, unsigned char dummy){ *out = in; } inline vil_round(unsigned char * out, double in, unsigned char dummy){ *out = in + ( (in >= T(0.0)) ? T(0.5) : T(0.5) ); } Dan  n.b no need for partial specialiations here. Having 10 or twenty of these sounds fine to me, unlike having my code run twice as slowly because it is performing an unnecessary test in the middle of a loop. Ian. > Original Message > From: Wheeler, Fred (CRD) [mailto:wheeler@...] > Sent: Friday, January 25, 2002 3:10 PM > To: Ian Scott > Cc: Vxlmaintainers (Email) > Subject: RE: [Vxlmaintainers] casting instead of rounding in > templates > > > I agree that oneline template inline function with > specializations to do this conversion would be a > good solution. The only problem I see is that it would need > to be specialized for so many cases. We > would want special rounding whenever a floating type is > converted to an integral type. We would have > a specialization for > > <all integral types, all float types> > > by which I mean <unsigned char, float>, ... <short, double>, > ... <long long, double> and everything > in between, about 20 odd specializations. Actually, I guess > we can forget about float, because if > the pixels are float, the righthandside will be converted > to double, so now were down to 10 or so. > Oops, but then there is long double, back up to 20. > > So many specializations does not seem like a clean solution to me. > > Fred Wheeler > > > Original Message > From: Ian Scott [mailto:ian.m.scott@...] > Sent: Friday, January 25, 2002 9:57 AM > To: Wheeler, Fred (CRD) > Cc: Vxlmaintainers (Email) > Subject: RE: [Vxlmaintainers] casting instead of rounding in > templates > > > I would have thought that template specialisations were more > appropriate. > They are certainly more efficient that having an if in the > middle of a loop. > > > > Original Message > > From: Wheeler, Fred (CRD) [mailto:wheeler@...] > > Sent: Thursday, January 24, 2002 9:50 PM > > To: vxlusers@...; > > vxlmaintainers@... > > Subject: [Vxlmaintainers] casting instead of rounding in templates > > > > > > > > (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 > > > > _______________________________________________ > > Vxlmaintainers mailing list > > Vxlmaintainers@... > > https://lists.sourceforge.net/lists/listinfo/vxlmaintainers > > > 