
I have a question about this approach: what is the purpose of using templates? What operations do you see as being performed on colors polymorphically? In other words, the only advantage I see to this templated approach would be to allow clients to write templated functions/classes which could operate on arbitrary color types, but I can't think of any interesting functions that would work with your approach. (P.S. sorry if this has been addressed earlier in the thread; I only just joined the list) On 9/25/05, Adam Badura <abadura@o2.pl> wrote:
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@sig.com> wrote in message news:200509201642.j8KGgYci010670@shannonhoon.balstatdev.susq.com...
From: "Adam Badura" <abadura@o2.pl>
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@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer; _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost