Boost logo

Boost :

From: Adam Badura (abadura_at_[hidden])
Date: 2005-09-25 07:32:54


    Actually, to be mor acurate I do something like this:

struct rgb_8888 {
    unsigned char _r : 8;
    unsigned char _g : 8;
    unsigned char _b : 8;
    unsigned char : 8;
    unsigned char red() const {/*...*/}
    void red(unsigned char r) {/*...*/}
    unsigned char green() const {/*...*/}
    void green(unsigned char r) {/*...*/}
    unsigned char blue() const {/*...*/}
    void blue(unsigned char r) {/*...*/}
    unsigned char component(unsigned int index) const {{/*...*/}
    unsigned char& component(unsigned int index) {/*...*/}
};

template<typename Components> class component_traits {
public:
    typedef ? component_type;
    static const int components;
    static const int indexes[components];
    static const component_type min[components];
    static const component_type max[components];
};

and than specialization could look like this:

    component_traits<rgb_8888>::component_type === usnigned char
    component_traits<rgb_8888>::min === [0, 0, 0]
    component_traits<rgb_8888>::max === [255, 255, 255]

    component_traits<rgb_double>::component_type === double
    component_traits<rgb_8888>::min === [0.0, 0.0, 0.0]
    component_traits<rgb_8888>::max === [1.0, 1.0, 1.0]

and so on...

    The base concept is that "color" class (like for example "color_rgb",
"color_yuv") akes car of color model or color space things, and therefore
must be a template (polymorphism could be used as well, but code speed is
here very important [graphic manipulation!] so I decidet: templates)
parametrized with "components type". This "component type" takes care for
serving color data lika values of channels. "components type" knows exact
types and palcement in memory.
    So if you want to use your own format in wich all channels have 10 bits
size and all is stored in double word you just write simple components type:

struct your_rgb {
    unsigned int _r : 10;
    unsigned int _g : 10;
    unsigned int _b : 10;
    unsigned int : 2;
    unsigned int red() const { return _r;}
    void red(unsigned int r) {_r = r;}
    unsigned int green() const {return _g;}
    void green(unsigned int r) {_g = g;}
    unsigned int blue() const {return _b;}
    void blue(unsigned int r) {_b = b;}
    unsigned int component(unsigned int index) const {/*...*/}
    unsigned int& component(unsigned int index) {/*...*/}
};

    component_traits<your_rgb>::component_type === usnigned int
    component_traits<your_rgb>::indexes === [0, 1, 2]
    component_traits<your_rgb>::min === [0, 0, 0]
    component_traits<your_rgb>::max === [2^10, 2^10, 2^10]

in this case writing "component" could be a little difficult however youy
can be sure taht "color class" will not call your functions with improper
arguments by it self (actually to speed up code control can be turned of and
the user may give wrong arguments, but if someone wants to spoild program he
will do it anyway). Also you dont have to actualy retrun type
"component_traits<your_rgb>::component_type" but type that behaves like it
were this type.
    (component_traits::indexes is to allow another order of data not only
RGB but for example also BGR, "color class" always [to ease using] uses
index 0 for R, 1 for G and 3 for B, this is problem for "compoinent"
function, to avoid using "swich" in this function, what would make its
execution longer, indexes are staticly mapped, so for BGR this array would
look like:

    component_traits<bgr>::indexes === [2, 1, 0]

and "color class" still uses its indexes, but in calls to components
"component" maps them (staticly) to right indexes.
    Hope everything is understandable... :)

    But now I encountered another problem, which I post in differen message.

    Adam Badura

"Rob Stewart" <stewart_at_[hidden]> wrote in message
news:200509201642.j8KGgYci010670_at_shannonhoon.balstatdev.susq.com...
> From: "Adam Badura" <abadura_at_[hidden]>
> >
> > For now I think taht template representation would be best. What i
mean
> > is for example
> >
> > struct rgb_8888 {
> > unsigned char r : 8;
> > unsigned char g : 8;
> > unsigned char b : 8;
> > unsigned char : 8;
> > };
> >
> > struct yuv_422 {
> > unsigned char y : 4;
> > unsigned char u : 2;
> > unsigned char v : 2;
> > };
> >
> > template<typename Components> class color {
> > private:
> > Components mComponents;
> > };
>
> I haven't been following your discussion but this looks suspect.
>
> First, you'd need to specialize color for each color structure
> type so the color member functions know how to do the right
> thing. That obviates what I think you're trying to do with the
> template.
>
> Second, all code using colors must be either templated on color
> type or will only work with one type. That is, including the
> representation in the type (color<yuv_422>) means that functions
> must be written in terms of color<something> and can't work with
> color<something_else_entirely>.
>
> To fix the former problem, you might consider that the color
> template can provide higher level functionality from primitives
> supplied by a policy type. Thus, your Components type would have
> to provide represention plus primitives.
>
> To fix the latter problem, you would need an ABC from which
> color<T> derives.
>
> HTH
>
> --
> Rob Stewart stewart_at_[hidden]
> Software Engineer http://www.sig.com
> Susquehanna International Group, LLP using std::disclaimer;
> _______________________________________________
> Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost
>


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