Why Color rgb components are on 10 bits?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Why Color rgb components are on 10 bits?

Nicolas Cellier
I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?


Reply | Threaded
Open this post in threaded view
|

Re: Why Color rgb components are on 10 bits?

Bert Freudenberg

On 19.12.2013, at 18:06, Nicolas Cellier <[hidden email]> wrote:

I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?

All opaque colors would be LargeIntegers, not SmallIntegers: 16rFFxxxxxx.

- Bert -




Reply | Threaded
Open this post in threaded view
|

Re: Why Color rgb components are on 10 bits?

Nicolas Cellier

2013/12/19 Bert Freudenberg <[hidden email]>

On 19.12.2013, at 18:06, Nicolas Cellier <[hidden email]> wrote:

I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?

All opaque colors would be LargeIntegers, not SmallIntegers: 16rFFxxxxxx.

- Bert -


Yes, that's why we would need to invert the encoding of alpha channel...
But this change would be much more intrusive (change primitives...), and not really compatible with established practices where alpha channel is interpreted as opcity level, not as transparency level (http://en.wikipedia.org/wiki/RGBA_color_space)
I think we can forget this part of the proposition which is too much Smalltalk-centric.

Nicolas

 



Reply | Threaded
Open this post in threaded view
|

Re: Why Color rgb components are on 10 bits?

Igor Stasenko
In reply to this post by Bert Freudenberg
i can go even further: why we can't just have 3 inst vars for Color (red,green,blue)
+ alpha in case of transparency and be done with it :)
and if we get rid of unused cachedDepth cachedBitPattern,
the space in memory for Color intance(s) won't get much higher,
(if it makes any sense to care about it).

i guess that any change in color storage format will involve changing VM primitives (bitblt plugin and friends), where operations with color involved



On 19 December 2013 18:12, Bert Freudenberg <[hidden email]> wrote:

On 19.12.2013, at 18:06, Nicolas Cellier <[hidden email]> wrote:

I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?

All opaque colors would be LargeIntegers, not SmallIntegers: 16rFFxxxxxx.

- Bert -








--
Best regards,
Igor Stasenko.


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] Why Color rgb components are on 10 bits?

Nicolas Cellier
In reply to this post by Nicolas Cellier

2013/12/19 <[hidden email]>
Nicolas Cellier wrote:
I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?
Could 6 bits be enough for transparency?  Perhaps only for Pharo's own system & UI stuff.  Any bitmap editor application would probably need to extend to handle the full 8 bit alpha.  Or maybe that adds unneeded complexity.

cheers -ben

Yes, it would be sufficient, but it seems simpler to manage a separate 8 bit alpha channel as it is the case now.



Reply | Threaded
Open this post in threaded view
|

Re: Why Color rgb components are on 10 bits?

Nicolas Cellier
In reply to this post by Igor Stasenko
2013/12/19 Igor Stasenko <[hidden email]>
i can go even further: why we can't just have 3 inst vars for Color (red,green,blue)
+ alpha in case of transparency and be done with it :)
and if we get rid of unused cachedDepth cachedBitPattern,
the space in memory for Color intance(s) won't get much higher,
(if it makes any sense to care about it).

i guess that any change in color storage format will involve changing VM primitives (bitblt plugin and friends), where operations with color involved


If it is just Color, then no primitive change is necessary, Juan did it in Cuis, and he his using Floats (or rather FloatArray).
If it's the encoding of Bitmaps then sure, it's another matter (so let's forget about inverting the alpha channel encoding).

Packing rgb in a single SmallInteger is an optimization.
But sure, while at it, we can also question the packing.
How many Colors are stored in the system, how many short lived colors are created during graphics operations?

To judge whether this is really necessary or not, we have to measure the costs of various solutions in term of memory/CPU...
My proposition was a sort of local optimum in the neighbourhood of current implementation, keep an efficient packing, but avoid unecessary conversion in most used case (32 bit depth).

Most colors are held by the color map (colors) of ColorForm, but this usage is already mitigated because those colors are often encoded as WordArray already, not as Array of Color (well it depends, and code isn't crystal clear currently).

For clarity of code, it should not change much as long as we do not optimize too many messages and keep using self red, self green, self blue instead of direct ivar access.
 


On 19 December 2013 18:12, Bert Freudenberg <[hidden email]> wrote:

On 19.12.2013, at 18:06, Nicolas Cellier <[hidden email]> wrote:

I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?

All opaque colors would be LargeIntegers, not SmallIntegers: 16rFFxxxxxx.

- Bert -








--
Best regards,
Igor Stasenko.






Reply | Threaded
Open this post in threaded view
|

Re: Why Color rgb components are on 10 bits?

Igor Stasenko



On 19 December 2013 19:24, Nicolas Cellier <[hidden email]> wrote:
2013/12/19 Igor Stasenko <[hidden email]>
i can go even further: why we can't just have 3 inst vars for Color (red,green,blue)
+ alpha in case of transparency and be done with it :)
and if we get rid of unused cachedDepth cachedBitPattern,
the space in memory for Color intance(s) won't get much higher,
(if it makes any sense to care about it).

i guess that any change in color storage format will involve changing VM primitives (bitblt plugin and friends), where operations with color involved


If it is just Color, then no primitive change is necessary, Juan did it in Cuis, and he his using Floats (or rather FloatArray).

nice.. so then i don't see any reason to keep using 10 bits per color component,
since most often used formats are 8bit, or floating-point and both require (lossy) conversion from 10-bit format
 
If it's the encoding of Bitmaps then sure, it's another matter (so let's forget about inverting the alpha channel encoding).

Packing rgb in a single SmallInteger is an optimization.
But sure, while at it, we can also question the packing.
How many Colors are stored in the system, how many short lived colors are created during graphics operations?

6k instances of Color in my image.
right now Pharo's Color class has following slots:

'rgb cachedDepth cachedBitPattern alpha'

as you can see, if you replace it with:

'red green blue alpha'

there will be no any loss in space efficiency, if you use smallintegers for color components!

by adding one extra ivar - scale, we can choose which way to store color components
either 0..255, or 0.0 ..1.0
or as variant, if red component is integer, then assume all components  is within 0..255
range and if not, then color components are in 0..1 range


To judge whether this is really necessary or not, we have to measure the costs of various solutions in term of memory/CPU...
My proposition was a sort of local optimum in the neighbourhood of current implementation, keep an efficient packing, but avoid unecessary conversion in most used case (32 bit depth).

Most colors are held by the color map (colors) of ColorForm, but this usage is already mitigated because those colors are often encoded as WordArray already, not as Array of Color (well it depends, and code isn't crystal clear currently).

For clarity of code, it should not change much as long as we do not optimize too many messages and keep using self red, self green, self blue instead of direct ivar access.
 


On 19 December 2013 18:12, Bert Freudenberg <[hidden email]> wrote:

On 19.12.2013, at 18:06, Nicolas Cellier <[hidden email]> wrote:

I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
So it's the best we can do, while keeping an efficient format.

But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.

I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
But did not change the rgb ComponentMax... Any reason why?

If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
But I don't know if it is really inter-operable, or more natural...

Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...

Thoughts?

All opaque colors would be LargeIntegers, not SmallIntegers: 16rFFxxxxxx.

- Bert -








--
Best regards,
Igor Stasenko.










--
Best regards,
Igor Stasenko.


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] Why Color rgb components are on 10 bits?

Stéphane Ducasse
In reply to this post by Nicolas Cellier
Hello nicolas

> I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
> So it's the best we can do, while keeping an efficient format.
>
> But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
> Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.
>
> I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
> But did not change the rgb ComponentMax... Any reason why?

No special reason. We just started to clean the code to understand it and avoid isKindOf: and because we thought
that there is no need to have color and translucent colors anymore.

> If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
> But I don't know if it is really inter-operable, or more natural…

Thanks for the discussion. Now do you have an idea about the speed gain?
>
> Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...
>
> Thoughts?


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] Why Color rgb components are on 10 bits?

Nicolas Cellier

2013/12/25 Stéphane Ducasse <[hidden email]>
Hello nicolas

> I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
> So it's the best we can do, while keeping an efficient format.
>
> But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
> Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.
>
> I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
> But did not change the rgb ComponentMax... Any reason why?

No special reason. We just started to clean the code to understand it and avoid isKindOf: and because we thought
that there is no need to have color and translucent colors anymore.

> If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
> But I don't know if it is really inter-operable, or more natural…

Thanks for the discussion. Now do you have an idea about the speed gain?

Absolutely no idea.
BitBlt is rich enough (color maps or direct color components, depths, endianness) to make this unpredictable by simply analyzing sender chain in source code (it's too deep and convoluted).
The best way is to try it, but then one must choose a benchmark, and here again it is a difficult decision, because maybe you didn't bench a path that some other use intensively, how to guess without above analysis?

I saw those un-necessary mismatch while analyzing Graphics code...
By a principle of economy, I suggest to remove them.
Simplifying code a little bit is already a win.

Then, les petits ruisseaux font les grandes rivières, cumulated micro optimizations may pay.

>
> Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...
>
> Thoughts?





Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] Why Color rgb components are on 10 bits?

Nicolas Cellier

2013/12/25 Nicolas Cellier <[hidden email]>

2013/12/25 Stéphane Ducasse <[hidden email]>
Hello nicolas

> I know the answer, we have 30 bits available for keeping the rgb instance variable as SmallInteger...
> So it's the best we can do, while keeping an efficient format.
>
> But we are never using 10 bits for each component, for 32 bits image only 8 bit by color are used.
> Since nowadays most Forms are 32 bits deep, this force useless conversions where we could have none.
>
> I see that Pharo 3.0 did unify Color and TranslucentColor by moving the alpha information in Color.
> But did not change the rgb ComponentMax... Any reason why?

No special reason. We just started to clean the code to understand it and avoid isKindOf: and because we thought
that there is no need to have color and translucent colors anymore.

> If we encoded rgb component on 8 bits, and reverted the alpha channel encoding, then we could have colors pre-encoded on 32 bits, but most using only 24 bits (because most are opaque) would be represented as SmallInteger.
> But I don't know if it is really inter-operable, or more natural…

Thanks for the discussion. Now do you have an idea about the speed gain?

Absolutely no idea.
BitBlt is rich enough (color maps or direct color components, depths, endianness) to make this unpredictable by simply analyzing sender chain in source code (it's too deep and convoluted).
The best way is to try it, but then one must choose a benchmark, and here again it is a difficult decision, because maybe you didn't bench a path that some other use intensively, how to guess without above analysis?

I saw those un-necessary mismatch while analyzing Graphics code...
By a principle of economy, I suggest to remove them.
Simplifying code a little bit is already a win.

BTW, did you see that scaled rgb components use 10bits while scaled alpha uses 8?
This was in Squeak already and has been perpetuated in Pharo refactoring...

Then, les petits ruisseaux font les grandes rivières, cumulated micro optimizations may pay.

>
> Juan followed another path for Cuis, opting for float components, which is another possibility, but our VM are not yet optimized for handling Floats...
>
> Thoughts?






Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [squeak-dev] Re: Why Color rgb components are on 10 bits?

Stéphane Ducasse


Absolutely no idea.
BitBlt is rich enough (color maps or direct color components, depths, endianness) to make this unpredictable by simply analyzing sender chain in source code (it's too deep and convoluted).
The best way is to try it, but then one must choose a benchmark, and here again it is a difficult decision, because maybe you didn't bench a path that some other use intensively, how to guess without above analysis?

I saw those un-necessary mismatch while analyzing Graphics code...
By a principle of economy, I suggest to remove them.
Simplifying code a little bit is already a win.

BTW, did you see that scaled rgb components use 10bits while scaled alpha uses 8?

No :) because I’m totally ignorant of this part and I need time to learn and I’m too busy and too sick because I work too much.


This was in Squeak already and has been perpetuated in Pharo refactoring...