Re: [filter-effects] hue-rotate() and saturate() filters

On Tue, Oct 15, 2013 at 11:31 AM, Chris Lilley <chris@w3.org> wrote:

> Hello Stephen,
>
> Tuesday, October 15, 2013, 4:11:00 PM, you wrote:
>
> > On Tue, Oct 15, 2013 at 5:37 AM, Dirk Schulze <dschulze@adobe.com>wrote:
>
> >  Shouldn't the conversion between RGB and HSL be bijective? So if
> > both color spaces are bijective, the algorithm described by
> > feColorMatrix must be wrong[1]. Polar coordinates or not, every
> > color in HSL should be describable in RGB. And we still do the
> > animation on the hue value and not on the RGB values. It also
> > depends of course if the definition of hue in Filter Effects is
> > equivalent to the definition of hue in HSL. Same (and probably more
> > dramatic) for saturate. SVG 1.1 is not very clear about that.
>
>
>
> > feColorMatrix does not use HSL, AFAICT it uses what appears to be
> > HSY'.
>
> Its just a tilted RGB cube. The problem with calling that HSY is that
> people may assume the HSL equations are used to calculate H and S. And
> it is Y, not Y'.
>
> Looking at the matrix, and assuming the default value for
> color-interpolation-filters is being correctly applied, the
> coefficients are computing the luminance and the cube is
> rotated around the luminance (black to white) axis.
>
> > So the issue is that some fully-saturated colours go
> > out-of-gamut when rotated to the far side of the HSY' colour space.
> > So when rotated, they must clip.
>
> Yes, exactly. You can't rotate a cube within the bounding box of the
> unrotated cube without clipping.
>
> > E.g., when fully-saturated green is rotated into blue, in HSY'
> > space it is actually over-saturated, but clips to fully-saturated
> > blue (since the colour is now out-of-gamut). If fully-saturated blue
> > is rotated into green, it is under-saturated, and stays that way
> > (since it's in-gamut), so that the perceived luminance is preserved.
> > So it's not a matter of clipping between two filter stages; it's
> > actually clipping caused by the rotation. Imagine a horizontal slice
> > on the Y' axis of the HSY' space: fully-saturated blue rotated by
> > 180 degrees ends up as a partly-saturated yellow, such as in the
> > lower right image here:
> > http://en.wikipedia.org/wiki/File:Hsl-hsv_chroma-lightness_slices.svg
>
>
>
> > This is due to the CCIR 601 luma computation built into
> > feColorMatrix hueRotate (Y = 0.213 R + 0.715 G + 0.072 B).
>
> Note that due to color-interpolation-filters initial value of
> linearRGB, it is true luminance (not video luma) that is being
> calculated. Also, unlike Rec.601 the values for black and white are 0
> and 255 (not 16 and 235).
>

Thanks for the clarifications and corrections, Chris. I learned what I know
of colour theory from work in digital video, which is why I called it CCIR
601, but it makes more sense to consider sRGB in this case.

I actually think color-interpolation-filters has a related problem, which
is that in all current implementations, the conversions implied by
linearRGB introduce some ugly banding, due again to limited precision. One
solution to both problems might be floating point (or better, half float)
intermediate buffers, which in the hueRotate case would allow for
out-of-gamut colours, at least internally. Of course that would introduce a
heavier computational and memory burden.

The primary chromaticities and white point of Rec.709 and sRGB are
> identical.
>
> Cutting to the chase, given that filter effects uses early clamping,
> my conclusion is that feMatrix is useful when type=matrix or
> type=luminanceToAlpha but that the hueRotate value is misleading. The
> specification should note the undesireable side effects for any
> colours which fall outside a sphere in RGB space bunded by and centred
> on the RGB cube, and a better option offered (especially as a
> shorthand) which gives the more expected results without gross
> roundoff error.
>

An additional shorthand seems like a good idea. I would be interested to
know the rationale for the current spec of hueRotate, since there's not
much in the current SVG spec besides the math. Perhaps there's something in
the archives of the SVG mailing list(s).

The saturate value is also potentially misleading when used in a
> filter chain of the form
>
> saturate(s) -> something -> saturate(1/s)
>
> where s > 1.0
> again due to the early clipping.
>

Stephen


>
> --
> Best regards,
>  Chris                            mailto:chris@w3.org
>
>

Received on Tuesday, 15 October 2013 15:51:07 UTC