Re: [AD] 4.0.2 release

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


> Do you mean if hue is so close to 360.0 (but still strictly smaller),
> that hue/60.0 is represented exactly as 6?

At least gives 6 after casting to int.

> I'm not sure if this can happen, but I think my code treats this case
> correctly too.

This was precisely the bug: the original routine was

else {
   while (h < 0)
      h += 360;
   h = fmod(h, 360) / 60.0;
   i = (int)h;
   f = h - i;

[...]

switch (i) {
   case 0: *r = v; *g = z; *b = x; break;
   case 1: *r = y; *g = v; *b = x; break;
   case 2: *r = x; *g = v; *b = z; break;
   case 3: *r = x; *g = y; *b = v; break;
   case 4: *r = z; *g = x; *b = v; break;
   case 5: *r = v; *g = x; *b = y; break;
}

Some pixels were missed, because i=6 for them.

> To convince yourself, first consider the case when hue is pretty close
> to 360, say 359.94, so that hue/60.0 is close to, but still strictly
> smaller than 6.0, namely 5.999. In this case:
>    i=5,
>    f=0.999,
>    x is very close to v*(1-s),
>    y is very close to v*(1-s),
> so
>    *r=v,
>    *g=v*(1-s),
>    *b=v*(1-s).
>
> Now consider the case when hue is so close to 360 that hue/60.0 is equal
> to 6.0. In this case:
>    i=6,
>    f=0,
>    x=v*(1-s),
>    z=v*(1-s),
> so
>    *r=v,
>    *g=v*(1-s),
>    *b=v*(1-s).
>
> So the two cases produce the same results, as the user would expect.
> Magic! :-) This works because the hue parameter really is periodic, with
> period 360.0.

Hmm... yes, you're right. And the tiny patch contained in my previous
message is wrong, because it wrongly assumes the continuity of the
transformation of h into (i, f), which of course doesn't exist because of
fmod(). So 360-epsilon should indeed be treated like 0-60.

I applied your patch to the branch. Thanks.

--
Eric Botcazou
ebotcazou@xxxxxxxxxx



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/