Boost logo

Boost :

From: Simon Buchan (simon_at_[hidden])
Date: 2005-09-29 21:49:29


Adam Badura wrote:
>>So, more on topic: is an actual implementation of the proposed color lib
>>in development? ie. is there any code that I can compile and take a look
>>at the decisions being made in context?
>
> I have included only one example (rather simple just to check if
> everything compiles) because you were hurrying me so much... :)

Sorry if I have been sounding like a arrogant manager or something, I
was just tring to say have the code out quickly, cause it's easier to
fix design issues /before/ you write 53 classes depending in it. Or at
least, I should have.

Disclaimer: Below is my _personal_ opinion about the library, anyone
who's looked at my previous posts will know that I'm not always the
brightest something in the something!

> I compiled on Microsoft Visual C++ Toolkit 2003 and Borland C++ 5.5
> both compiled without errors.
>
You should also test with GCC, btw. But two is one more that most test
with! (Heck, it's /two/ more than some test with.)

> So what do the files containt? Almost everything is in color.hpp because
> almost everything is template or inline. Now only RGB model is implemented -
> I wanted to get clear idea what to do and how do it. Then write CMYK or YUV
> (they should be almost the same) and project conversions. Then write the
> rest.
>
I'm not sure CMYK is common as a representation in memory. HSV and YUV
are more likely, though. Maybe some of the CIE formats?

> Actual project looks like this:
>
> 1)
> We have classes for color data representations (in color.hpp
> components_rgb, components_32b, components_32b_inv). They are responsible
> for storing and serving "raw" data. This is done because for a color class
> (see 3) it does not matter wheather color components have all 8 or 16 bits
> or how are they placed in memory. Color class (see 3) must know only some
> details given in components_traits (see 2). Color representation class must
> serve 6 functions:
>
> TYPE_OF_R r() const; // return R value
> void r(TYPE_OF_R value); // set R value
> TYPE_OF_G g() const; // return G value
> void g(TYPE_OF_G value); // set G value
> TYPE_OF_B b() const; // return B value
> void b(TYPE_OF_B value); // set B value
>
ugh... getter-setter methods. Why don't we just directly access the
values? This /is/ only the representation in memory, right?

> They should be as fast as only possible. No error checking - color class
> (see 3) will do it when needed. Also a copy constructor and copy operator
> should be available but this usually is no problem because default compiler
> generated one will do.
> All this is introduced to allow use of library with other libraries
> (DirectX, OpenGL, native WinAPI, ...) and formats of color storing.

Sensible.

> I declared all this classes actually as structures to emphasise on
> importance of memory model. This classes have to be allocated in memory
> exactyl as they have data memers to allow worinkg with buffers for and from
> other devices and libraries.
>
> 2)
> We have template class components_traits which has to be specialized for
> every representation class (see 1). It serves basic static data of the
> component:
>
> typedef TYPE_OF_R r_type;
> typedef TYPE_OF_G g_type;
> typedef TYPE_OF_B b_type;
> static const r_type r_min;
> static const r_type r_max;
> static const g_type g_min;
> static const g_type g_max;
> static const b_type b_min;
> static const b_type b_max;
>
OK. (Although I don't know how often min and max for each type will be
used. Hue for HSV is about all I can think of, and even then, full
range should be more common than [0, 360) )
Requiring a specialisation every time shouldn't be neccesary:

template <class Repr>
components_traits {
        typedef typename Repr::r_type r_type;
        // ..
        static const r_type r_min = typename template
numeric_limits<r_type>::min();
        // ..
};

Then you just need to define r_type, etc in the representation. Keep
the traits class, though. It may be usefull for edge cases and using
other interfaces.

> this is used be color class (see 3) in conversions correcting values and
> defining interface.
> r_type, g_type and b_type must be convertable to long double and must
> construct from long double. This is no problem in case of standard types.
> And because this types must (or at least should to be functional) behave
> like number so requirement is quite natural...
>
> 3)
> We have color class. It is parametrized by representation class (see 1)
> and its traits (see 2).

Sounds reasonable, however, see below

> This class gives 2 way access to color data.
> First one is unified by type long double. Components are of type long
> double in range [0; 1]. Actually the can be in any representation but they
> color class takes care of conversion to long double. Conversion form long
> double to actual representation is done by the representation (by the type
> of component) so kind of rounding is determined there and in usual case it
> will be rounding to nearest representable color (or it should be like this).
> This is added to allow writing of generic functions taht do not care about
> actual representation and its limits. But it should be remembered that this
> is not the fastes access (aspecially in writng) because it requires
> conversions and mathematical operations.
> Second is by actual component type (all functions postfixed with _o).
> This is as fast as possible but not as generic...
> All (write) functions come in few versions. Version without postfix
> makes no error chcecking (to be used in releas version of program to make it
> faster). Version ending in _c corrects values. If value given for component
> is smaller the minimum for that component minimum is writen instead, if
> value is larger then maximum then maximum is writen instead. This is
> aspecially useful for generic functions because rounding in floating point
> operations can actually take value beyond accepted range. Version ending in
> _e throws an exception when component value is out of range (or when
> component is out of range see further remarks). This is intended to be used
> in debuging application and then in release to replace by non-checking
> calls.
> I writed an indexed function where index 0 gives (or sets) R, 1 is for G
> and 2 is for B. But they only are available in long double version because
> actual component tpyes me be different.
>
All this sounds like it could be done cleaner with generic programming.
  You already are exposing the types of the components: why pass
everything though long double? The behaviour of the functions would be
better determined by a policy template parameter, IMHO. Less names to
keep track of. So:

        // Default traits = color_traits< rgbx_8 >, like basic_string
        typedef color_rgb< rgbx_8, colors::exception_policy > my_color;
        my_color::r_type red_value;

> So I think its all by now.
>
> What do I want to do futher?
> 1) add "nice features" like functions "darker", "brighter" and so on...

Just one "lightness" should do: we have to figure out what canonical
colourspace to use, or whether the user can specify it, though.

> 2) add comparing with or without "toleration range" (colors [0.00000001,
> 0.0, 0.0] and [0.0, 0.0, 0.0] really do not differ that much aspecially
> converted to integer based representation...

This is more general a problem than color (unfortunately).

> 3) add and test useful representations
> 4) add reading and writing form a string and all web-color as predefined,
> but this will I do perhabs after completting everything else (actually there
> is an << operator defined but only to ease testing)

The library shouldn't try to handle every format ever used to store
color, of course.

> 5) add other models and convertions betwean them

A lot of the work will be trying to define how to have a sensible
interface to drasticly different color representations. Think STL: a
lot of very different ways to contain things, but everything can be used
with a single generalised interface. Of course, you can should still be
able to access the special abilities of each type (like you can op []
for vector, splice for list, in STL).
>
> So what you think?
>
It could be very usefull> Colour is one of those things that doesn't
want to be tied to a number, though, so you have a bit of work infront
of you. I hope (for your sake!) that you know what you've gotten
yourself into.

> Adam Badura
>
<snip binary files dumped inline>
Looks like something along the line killed the files.


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