1

The numeric extension for boost::gil contains algorithms like this:

template <typename Channel1,typename Channel2,typename ChannelR>
struct channel_plus_t : public std::binary_function<Channel1,Channel2,ChannelR> {
   ChannelR operator()(typename channel_traits<Channel1>::const_reference ch1,
                       typename channel_traits<Channel2>::const_reference ch2) const {
      return ChannelR(ch1)+ChannelR(ch2);
   }
};

When filled with two uint8 channel values, an overflow will occur if ChannelR is also uint8.

I think the calculation should

  • use a different type for the processing (how to derive this from the templated channel types?)
  • clip the result to the range of the ChannelR type to get a saturated result (using boost::gil::channel_traits<ChannelR>::min_value() / ...max_value()?)

How to do this in a way that allows for performance-optimized results?

  • Convert to the biggest possible type? Sounds counter productive...
  • Provide an arsenal of template specializations? Any better idea?
ildjarn
  • 62,044
  • 9
  • 127
  • 211
OK.
  • 2,374
  • 2
  • 17
  • 20
  • 1
    You might find this interesting: http://codereview.stackexchange.com/questions/6502/fastest-way-to-clamp-an-integer-to-the-range-0-255 – Mark Ransom Jun 21 '12 at 22:10

1 Answers1

0

I don't see what the problem is here... my reaction is "so don't set ChannelR to uint8 if that's going to break"

You seem to be doing the equivalent of arguing that code like

  uint8 a=128;
  uint8 b=128;
  uint8 c=a+b;  // Uh-Oh...

should do something clever (e.g saturating arithmetic).

I'd suggest the solution is to use more precision, or define your own channel_saturating_plus_t with the behaviour you require, much as I'd suggest the solution to the above is

uint16 c=uint16(a)+uint16(b)

or

uint8 c=saturating_add(a,b);

And be thankful that the creators of GIL even thought to expose the result type as a separate type parameter; there's plenty of libs out there which wouldn't!

timday
  • 24,582
  • 12
  • 83
  • 135
  • Thanks for your thoughts on this topic. – OK. Jun 26 '12 at 13:50
  • I understand the analogy to the standard C++ operator+ behaviour, but as this channel operator is supposed to work on (large) image data I am not able to use a bigger ChannelR type. I am searching for a solution that delivers saturated results in the same result type. – OK. Jun 26 '12 at 14:01
  • ...so your second suggestion is the way to go - but this is the main aspect of my question: how to implement struct saturating_channel_plus_t in a generic and optimal way? – OK. Jun 26 '12 at 14:05
  • For saturating arithmetic, see http://stackoverflow.com/questions/741301/add-and-subtract-128-bit-integers-in-c ; should be obvious enough how to generalize it. For the generic part, yes you're along the right lines with the channel traits. – timday Jun 26 '12 at 19:27