Boost logo

Boost :

From: Lubomir Bourdev (lbourdev_at_[hidden])
Date: 2006-06-18 02:43:39


Jose wrote:
>It would also be nice if you could also reply to a previous email
>regarding GIL not being flexible enough

Pavel Chikulaev wrote:
>Sure there is, but I do think that this library is not flexible enough
>- image layout (RGB and RGB classes).

It is hard to compare the two approaches if you don't have the code side
by side, but let me say a few words about GIL's flexibility.

Pavel's concern was that every channel permutation (like BGR, for
example) requires creating a new color space, which seems inflexible.

I think his concern is in part a misunderstanding based on terminology.
In both GIL and his example, to support BGR we have to write some new
code - in GIL we call it "derived color space" while Pavel calls it
"layout"

But let me point out that:
1. Adding a channel permutation (like BGR) requires very little new code
2. All channel-level support (assignment, copy-construction, etc) will
automatically work for BGR 3. All the algorithms that operate on RGB
will automatically work for BGR (unless explicitly prevented).

In detail:

___1. Adding a channel permutation (like BGR) requires very little new
code

The only changes that you need to do to make BGR are more or less the
following:

struct bgr_t : public rgb_t {};

template <typename T>
struct color_base<T,bgr_t> {
    T blue,green,red;

    color_base() {}
    color_base(T v0, T v1, T v2) : blue(v0),green(v1),red(v2) {}
    template <typename T1, typename C1> color_base(const
color_base<T1,C1>&);

    template <int N> T& semantic_channel();
    template<> T& semantic_channel<0>() { return red; }
    template<> T& semantic_channel<1>() { return green; }
    template<> T& semantic_channel<2>() { return blue; } };

The only catch is that it is illegal to create full specialization
(semantic_channel<0>) inside a partially specialized class, which
requires us instead to use a channel_accessor class. Note that the above
color_base class is homogeneous (every channel type is the same) but a
heterogeneous one can be created the same way. The "semantic channel"
accessor is needed to pair channels semantically. We are investigating a
more compact representation, for example using mpl::vector_c<int,
2,1,0>.

The color base class is reused in many places - when T is a channel, it
is used to construct a pixel. When T is a channel reference, it is used
to construct a proxy reference to a planar pixel (a bundle of three
references). When T is a channel iterator, it is used to form the basis
of a planar pointer (a bundle of three pointers)

___2. All channel-level support will automatically work for BGR

All the channel-level operations are abstracted out of the pixel and are
automatically provided. In other words, I never have to explicitly
define how to copy-construct, assign or compare between BGR pixels.
fill_channels, transform_channels, max_channel, etc. already work for
BGR. Not only that, they also work for planar references and planar
pointers (see how planar pointers are incremented).

Not only are things like copy constructor and operator== automatically
available for BGR; they are also optimally efficient - we are using a
compile-time recursion to avoid explicit loops over the channels.

One important feature: channel-level operations properly pair the
channels semantically. For example, if you assign an RGB pixel to a BGR
pixel, GIL will properly assign the red source to the red destination.

___3. All the algorithms that operate on RGB will automatically work for
BGR (unless explicitly prevented).

No special code is needed to handle color space variations. For example,
if you provide an "RBG" variation, you can automatically color convert
between RBG and CMYK (the RGB to CMYK code will be reused.) Another
example - the I/O code will allow you to read into an RBG image, (as
long as RGB is supported for the given file format).

______________

Flexibility is one of the principal design goals of GIL. Everything is
based on concepts, which means that you can replace just about any part
of GIL and use the rest. One developer can provide XYZ color space,
another can provide 64-bit channel, a third one can provide a fully
synthetic image view, such as the Mandelbrot set, and we can use the
existing GIL algorithms (for example x_gradient from the tutorial) to
compute the gradient of the Mandelbrot set in the new color space using
the new channel type. Furthermore, all these developers don't need to
coordinate with each other (or even know about each other) and the GIL
core doesn't need to change. Pavel's example of constructing a pixel is
nice. But I see no theoretical reason why we can't get GIL to work with
his pixels, for example.

GIL is flexible enough to allow you to specify the ordering of the
channels (and any other property of your image) at run-time as well. If
you follow certain rules, your run-time version will be practically as
efficient as a compile-time version.

We feel really good about GIL's flexibility. Other advantages of GIL are
its performance, extensibility, compatibility with existing
code/libraries, minimality of constructs, nonintrusiveness and the
high-profile projects that use GIL already. If you are interested in any
of these aspects let me know and I can say a few words about them too.

Lubomir


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