Clarifying the behavior of SVG arithmetic feComposite filters

The SVG 1.1 (Second Edition) – 16 August 2011 feComposite filter
operation (http://www.w3.org/TR/SVG/filters.html#feCompositeElement)
currently defines arithmetic composite to act on pre-multiplied rgba
pixels, just as the other feComposite operations do. Combined with the
per-component nature of the filter, this allows the filter to generate
invalid pre-multiplied rgba values both as intermediate results and
the final output. For example, this filter sequence:

<!-- This filter produces intermediate results that are invalid
pre-multiplied rgba pixels. -->
<!-- Specifically, after the 4th step an interior pixel will contain
(0, 0.8, 0, 0.5) which -->
<!-- is invalid because g > a. When used in other operations, this may
generate bad results. -->
<filter id="arithmetic">
  <feComposite operator="arithmetic" in="SourceGraphic"
in2="SourceGraphic" k1="0" k2="0.2" k3="0" k4="0" result="rgba02" />
  <feComposite operator="arithmetic" in="SourceAlpha"
in2="SourceAlpha" k1="0" k2="0.3" k3="0" k4="0" result="alpha05" />
  <feComposite operator="arithmetic" in="rgba02" in2="alpha05" k1="0"
k2="1" k3="1" k4="0" result="tmp" />
  <feComposite operator="arithmetic" in="SourceGraphic" in2="tmp"
k1="0" k2="1" k3="-1" k4="0" />
  <feComposite operator="arithmetic" in="tmp" k1="0" k2="1" k3="1" k4="0" />
</filter>

An invalid pixel is anything with color component greater than alpha.
The easiest way to produce invalid pixels is in a subtraction
operation (k1=0, k2=1, k3=-1, k4=0), when one opaque image subtracted
from a different opaque image will generate an entire image of alpha =
0 pixels that have non-zero color components.

The Webkit team is concerned with this behavior because the invalid
pixels may feed into other operations and pollute the entire image. We
would like to tighten the spec on arithmetic filter operations to
preclude this behavior.

Option 1 is to define arthimetic feComposite to act on regular rgba
pixels. This prevents any issue of invalid data and is probably easier
for content authors to reason about. On the downside, it may be costly
to convert between pre-multiplied and regular pixel representations.

Option 2 is to modify the spec section 15.12 from this statement "with
the result clamped between [0..1]" to this statement "with alpha
clamped to [0..1] and color components clamped to [0..alpha]". This is
the simplest change that ensures valid pixels everywhere.

Option 3 is to modify the spec to require that arithmetic results be
clamped to valid pre-multiplied pixels before use in any other filter
operation, while intermediate arithmetic results must clamp only to
[0..1] per component. This seems to match current behavior in Opera,
Firefox and Webkit, although I have not extensively tested. I think
the behavior just falls out of current pixel conversion methods for
pre-multiplied to regular pixels, although Webkit catches the problem
in debug builds.

Personally I support Option 2 as it is least disruptive and simplest
to implement, although I am also satisfied with Option 1.

Regardless of which clarification is chosen, in the interests of
cross-browser consistency we would like the spec tightened.

Stephen.

Received on Tuesday, 7 February 2012 15:35:44 UTC