Boost logo

Boost :

From: Lubomir Bourdev (lbourdev_at_[hidden])
Date: 2006-11-01 13:43:55


 
Lubomir Bourdev wrote:
> 2. Now that we have writing out of the way, we can create a
> model of an r-value channel reference (ChannelConcept, but
> not MutableChannelConcept) that takes two channels and
> returns a value half-way in between (or if generalization is
> important, an arbitrary interpolation). Lets call it
> InterpolatingChannel

Of course, the moment I submitted the post I came up with a much simpler
alternative.

We don't need any InterpolatingChannel.
We simply need to create a subbyte channel value. Synopsis:

// Represents a channel *value* whose size is not byte-divisible
// Models ChannelValueConcept
template <typename UnpackedChannelValue, int NumBits>
class packed_channel_value {
public:
    typedef ChannelValue value_type;

    packed_channel_value(const value_type& data) : _data(data) {}
    packed_channel_value(const packed_channel_value& c) : _data(c._data)
{}

    operator value_type() const { return _data&MAX_VALUE; }

    packed_channel_value& operator=(const value_type& data) {
        // warning: using this method may indicate a bug in your code!
        _data=data; return *this;
    }
    ...
private:
    value_type _data;

    static const value_type MAX_VALUE = (1<<NumBits)-1;
};

The difference between this and the packed_channel_reference class is
that this one holds a copy of the data, whereas the packed channel
reference holds a reference to the data which is located remotely.

Now our channel type is simply:

typedef packed_channel_value<uint16_t,10> v210_channel_t;

Our pixel model is simply:

typedef pixel<v210_channel_t, ycbcr_t> v210_pixel_t;

We keep the same model of pixel iterator I outlined earlier. But we
simply instantiate it with the correct values:

reference v120_pixel_ptr::dereference() const {
   switch (index) {
      ...
      case 3: return reference(
             v120_channel_t(Y3),
             v120_channel_t((CB1+CB2)/2),
             v120_channel_t((CR1+CR2)/2));
   }
}

Where "reference" is the same type as "value_type" (since this is an
immutable view)
Y3,CB1,CB2,CR1 and CR2 are the values of the corresponding 10-bit
channels (some shift and mask math necessary)

In short, dropping the requirement to write pixel-by-pixel into v210
(which is not a well defined operation anyway) results in a simpler and
faster implementation.

Lubomir


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk