<ul>
<li><a href='#Babl'>Babl</a></li>
<li><a href='#Features'> Features</a></li>
+ <li><a href='#Symmetric-Alpha'> Symmetric-Alpha</a></li>
+ <li><a href='#CMYK'> CMYK</a></li>
+ <li><a href='#ColorManagement'> Color Management</a></li>
<li><a href='#Download'>Download</a></li>
<!--<li><a href='#Background'>Background</a></li>-->
<li><a href='#Documentation'>Documentation</a></li>
<li>Stable, small API, with singleton objects returned.</li>
<li>Extendable with new formats, color models, components
and datatypes.</li>
- <li>Can load color spaces from ICC v2 and v4 profiles containing RGB
- matrix + TRC, or CMYK profiles.</li>
+ <li>Can load <a href='#ColorManagement'> Color
+Spaces</a></li> rom ICC v2 and v4 profiles containing RGB matrix + TRC, or <a
+href='#CMYK'>CMYK</a> profiles.</li>
+ <li><a href='#Symmetric-Alpha'>Symmetric-Alpha</a> no loss of color fidelity due to asymptotic behavior near alpha 0.0 in floating point.</li>
<li>Reference 64bit floating point conversions for datatypes and color
models, with 32bit floating point reference speed-ups in some places.
</li>
<li>Self profiling/validating and optimizing, optimizing accuracy and
performance at runtime when the best performing single or multi-step conversion
-path is chosen.</li>
+path is chosen. This permits additional SIMD optimiations paths to be added and
+to ones supported are competing with each other.</li>
</ul>
<p><a href='http://www.gegl.org/'>GEGL</a> through <a
<p>When performing further extensions to the vocabulary of babl, the
internal consistency is governed by reference conversions that operate
- on <em>double</em> (64 bit floating point values). The only color model
- created during BablCore bootstrap is <em>RGBA</em> (linear light RGB,
- 0.0 - 1.0, with a linear 0.0 - 1.0 opacity channel) backed by the
- <em>double</em> datatype. Defined similarily to <a
+ on <em>double</em> (64 bit floating point values). Color Spaces can
+ be created from chromaticity coordinates or ICC profiles. The reference
+ color space - to maintain fast and bit-accurate conversions on with
+ sRGB is similar to <a
href='http://en.wikipedia.org/wiki/ScRGB_color_space'>scRGB</a> using
64bit floating point.
</p>
- <p>If babls conversion isn't fast enough, you can provide
- your own conversion shortcut between two formats. The registered
- shortcut might also be used by babl as an intermediate conversion when
- constructing BablFishes for other conversions.
+ <p>To speed up operations, ffast path conversions are used.
+ The registered shortcut might also be used by babl as an intermediate
+conversion when constructing BablFishes for other conversions.
</p>
<p>Babl extensions are shared objects. If you have already developed
a babl format can also be queried with babl_format_get_space.
</p>
- <a name='cmyk'></a>
+ <a name='Symmetric-Alpha'></a>
+ <h2>Symmetric transformations for floating point alpha</h2>
+
+
+ <p>
+ babl clamps the alpha used when going from separate alpha to associated alpha
+or from associated alpha to separate alpha to BABL_ALPHA_FLOOR. This avoids
+asymptotic behavior and direct precision loss of color precision when multiplying or dividing by alphas near 0.0.</p>
+
+<p>Original intent of data as well as non-asymptotic precision loss is thus
+maintained when the processing chain might temporarily use the other alpha
+representation.</p>
+
+<pre>
+ #define BABL_ALPHA_FLOOR (1.0/65536.0)
+ #define BABL_ALPHA_FLOOR_F (1.0f/65536.0f)
+</pre>
+
+<p>The deviation from not clamping near 0.0 is within the quantization margin
+of 16bit integer alpha, thus no adaptations of are introduced for the 8bit and 16bit versions of pixel format conversions were needed.
+ </p>
+
+ <p>This is the clamping function:</p>
+<pre>
+
+ static inline float
+ babl_epsilon_for_zero_float (float value)
+ {
+ if (value <= BABL_ALPHA_FLOOR_F)
+ {
+ /* for performance one could directly retun BABL_ALPHA_FLOOR_F here
+ and dropping handling negative values consistently. */
+ if (value >= 0.0f)
+ return BABL_ALPHA_FLOOR_F;
+ else if (value >= -BABL_ALPHA_FLOOR_F)
+ return -BABL_ALPHA_FLOOR_F;
+ }
+ return value; /* most common case, return input value */
+ }
+</pre>
+<p>And an example use of this clamping function that is consistent with babls behavior:</p>
+<pre>
+ static inline void
+ associated_to_separate_rgba (const float *associated_rgba,
+ float *separate_rgba)
+ {
+ float alpha = associated_rgba[3];
+ float clamped_alpha = babl_epsilon_for_zero_float (alpha);
+ float reciprocal_alpha = 1.0f / clamped_alpha;
+
+ separate_rgba[0] = associated_rgba[0] * reciprocal_alpha;
+ separate_rgba[1] = associated_rgba[1] * reciprocal_alpha;
+ separate_rgba[2] = associated_rgba[2] * reciprocal_alpha;
+ separate_rgba[3] = alpha;
+ }
+</pre>
+
+
+<p>For more detils see <a href='https://gitlab.gnome.org/GNOME/babl/commit/a4d607843d3cab18745d547fc8a46dec51dcea5e'>the commit message of the most recent refinement</a> as well as <a href='https://www.patreon.com/posts/premultiplied-in-21014115'>blog post with further background</a>.</p>
+
+
+ <a name='CMYK'></a>
<h2>CMYK</h2>
<p>CMYK handling is done using babl-spaces created with ICC profiles
-->
- <a name='premultiplied-alpha'></a>
- <h2>Pre-multiplied alpha</h2>
-
- <p>babl stores color information in transparent pre-multiplied or associated
-alpha pixels in floating point formats. With floating point pixel formats
-standard way of handling alpha maintains color information very near fully
-transparent pixels - by introducing a limit: BABL_ALPHA_FLOOR which is
-1/65536.0, and treating all alphas beteen zero and this value as this value we
-maintain color information while the discrepancy in behavior gets concealed by
-quantization in 16bit and 8bit formats.
- </p>
-<p>For images that already are in a premultiplied format on import, this change
-has no impact on its use for pre-multiplied arithmetic, meaning that
-superluminous colors are still supported, it also opens up to GEGL more widely
-expect premultiplied data in more operations which will become a speedup when
-more filters want to integrate in the layer processing pipeline.</p>
-
-<p>There is a <a href='https://www.patreon.com/posts/premultiplied-in-21014115'>post on patreon</a> with further details about the implementation.</p>
-
<a name='TODO'></a>
<!--TODO-->