colour lib

Manu via Digitalmars-d digitalmars-d at puremagic.com
Fri Sep 2 17:17:21 PDT 2016


On 3 September 2016 at 03:25, Marco Leise via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> Am Fri, 2 Sep 2016 15:58:05 +1000
> schrieb Manu via Digitalmars-d <digitalmars-d at puremagic.com>:
>
>> I wonder, should NormalizedInt be a module beneath the color package,
>> or should it be a separate module in its own right?
>> I don't know of uses for that type outside packed colours, but it
>> could theoretically be used for anything...
>
> I guess audio sample would be a perfect match for signed and
> unsigned normalized integers.

Perfect! I moved out outside the colour package. Contention resolved :)


>> > Surely adding sRGB(22,22,22) + sRGB(11,11,11) gives sRGB(28, 28, 28),
>> > with a higher precision while performing the addition and then
>> > rounding back.
>>
>> Umm, no. I think operations should be within their own colourspace,
>> otherwise what's the point of selecting your working colourspace?
>> You need to be able to do operations in gamma space too. If you want
>> to do a linear operation, cast to a linear type before doing the
>> operation.
>
> So it is not a library that unifies color spaces into working
> with light intensities

That's a design goal, and it's very easy to cast to a linear type to
do that work.


> but more of a library to perform
> linear blending directly in the color-space.

This is another goal.
A colour implementation in the std library is a little tricky, it
needs to be both correct AND efficient for the different use cases
where the trade-off lines are drawn differently.
The only reasonable way I can think to support this is to do
operations within the typed colourspace, and let the user cast to the
colourspace desired for their operations.
So the meat of the lib is really about convenient colourspace
conversion, and making the colourspaces easy to describe, particularly
for non-experts.

I'm feeling like it's getting pretty close to my intent.

Naturally, image processing libs would tend to do linear conversions
internally. So it shouldn't be a detail that reaches the end-user very
often.
Remember that when doing linear conversions of colours, you tend to
also need to use float colour channels, since floats naturally express
the same non-linear precision curve that the gamma curves exist to
compensate for. Linear RGB8 will severely lose precision and band very
badly.


> That means when I add two HSV colors of the same ubyte hue
> = 200, the result will have hue == 144, right ?

Yes, it would necessarily be that. If it didn't behave that way, you
wouldn't be able to express a lerp in HSV space.
Additive colour blending in HSV doesn't really make sense. It works as
expected if you're adding deltas.

Ideally, hue would be expressed with a circular angle type (rather
than NormalizedInt as I've used for the other channels), which is
something we don't have in phobos, and I'm not motivated to write one
just for this one color channel...


>> > Anything requiring multiple operations on an
>> > image should use a higher precision linear color space from
>> > the start.
>>
>> Right, I think you would typically cast from the storage type to the
>> working type before doing some work. But there are so many cases, and
>> various levels of tradeoff between efficiency and correct-ness, the
>> lib can't make presumptions.
>> The way it is currently, the operations are done in the typed
>> colourspace. Simple as that. If you want to do linear operations, cast
>> to a linear type first.
>
> Ok, might be worth it for people new to color spaces to
> highlight the fact that RGB is not linear and what that means
> for operations like brightness or contrast change. I've seen a
> hobbyist write a 3D engine and after he had deferred
> rendering, flash lights & shadows, scripting and animations,
> he stumbled over an article about screen gamma and why it
> matters. My first attempts at image manipulation show the same
> ignorance.

I understand this pattern very, very well. I've worked in games my
whole career ;)
This is precisely why the std library needs to be batteries-included
with respect to knowledge about colourspaces and conversions, but that
doesn't mean every operation can do it properly behind the scenes.
Colours are a fairly low-level primitive, and appear in
low-level/high-frequency code. The std library offering wouldn't be
very useful if it were so slow from doing linear conversions every
time you do any operation. That's a lot of int<->float conversions,
and pow's!

I think the presence of all this colour space information as type
arguments should nudge users in the right direction. They'll be all
"I've never seen this parameter before..." and google it... maybe.
I don't think it's the std lib doco's job to give users a lesson in
colour theory...? :/


More information about the Digitalmars-d mailing list