Ell [Tue, 7 Nov 2017 20:44:39 +0000 (15:44 -0500)]
babl, sse2-float: fall back to slow, accurate path for large pow-2.4 inputs
The approximations we use for pow_24() and pow_1_24() diverge from
the actual function for large-enough input values. This can lead
not just to inaccurate results, but also to infinities and NaNs,
especially when multiple conversions are strung in a row.
When the input value is large enough to produce notable divergence
(the difference between the approximate and actual values is ~1% at
the chosen limits,) fall back to a slower, but more accurate
version.
For the SSE2 float conversions, this results in an increase of ~5%
in conversion time, when all values are below the limit. When most
values are above the limit, performance can be 10x slower or worse.
Øyvind Kolås [Tue, 31 Oct 2017 19:48:23 +0000 (20:48 +0100)]
babl: add babl_format_exists
A function to check if a specific format - by name - is already known by babl.
Should be used in conjunction with babl_format() for user supplied format
strings.
Debarshi Ray [Tue, 31 Oct 2017 08:43:53 +0000 (09:43 +0100)]
CIE: Make the RGB to Lab fast paths as accurate as the reference
The matrices used by the fast paths to convert from RGB to XYZ didn't
exactly match the reference matrices in the Babl space. This caused a
measurable error in their output.
Debarshi Ray [Tue, 31 Oct 2017 08:36:39 +0000 (09:36 +0100)]
CIE: Use cbrt instead of pow for the reference XYZ to LAB conversion
The fast-paths use an inlining-friendly version of cbrt(3). Using
something similar removes superficial differences between the two
conversion paths. It's not like the C library's cbrt(3) will perform
any worse than its own pow(3).
Debarshi Ray [Sun, 29 Oct 2017 12:52:26 +0000 (13:52 +0100)]
CIE: Add conversion from "RGBA float" to "CIE Lab float"
Conversions from "RaGaBaA float" to "CIE Lab float", as seen when
using gegl:shadows-highlights" go via:
"RaGaBaA float" to "RGBA float"
"RGBA float" to "RGB float"
"RGB float" to "CIE Lab float"
A direct conversion from "RaGaBaA float" to "CIE Lab float" in simple
C is hindered by the need to check every pixel's alpha value to avoid
dividing by zero. The pipeline stalls make it lose out to the look-up
table and SIMD based conversions to unassociated alpha.
However, we can trivially cut out the second step and still reduce
some memory traffic.
The function strncpy(3) does not guarantee to end the destination string
with NUL character if not enough space was available. This could happen
on systems which allow paths which are longer than 4096 characters.
Øyvind Kolås [Tue, 3 Oct 2017 13:54:19 +0000 (15:54 +0200)]
babl: rename babl_space_from_icc to babl_icc_make_space
Thus being more consistent that functions that take icc_data + length have the
prefix babl_icc_, since each icc space in the future potentially can have more
spaces than the relative-colorimetric space defined, _make_ seems better than
_to_ or _new_.
Ell [Tue, 3 Oct 2017 14:01:58 +0000 (10:01 -0400)]
babl: fix clang warnings in babl-polynomial
Cast the input polynomial from BablPolynomial* to
BablBigPolynomial* in the evaluator functions, so that clang
doesn't warn us about out-of-bounds access to its coefficient
array.
babl: set babl_rel_avg_error to a high value on NaN
In relation to bug #787441, if the sum of errors contain a nan the sum
is nan, we return pi as a much higher than expected average error to
indicate that this is not 0.0.
For now, also including symbols needed for internal tools and tests, that are
not part of the public API; the API promised by babl remains the public
headers, but this reduces the public dynamic loaders namespace a little.
babl: in babl_polynomial_approximate_gamma(), verify that x0 >= 0
Now that the previous commit (hopefully) makes us iPhone-proof, we
can add an assertion for this condition. If we want to replace the
assertions with some sort of bailing, we'll need to replace the rest
of them too anyway.
babl: avoid negative degree when shrinking a zero polynomial
When shrinking a zero polynomial, avoid trying to set its degree
to a negative value, and just keep it at 0, which is the minimal
degree we support.
Note that this also happens for polynomials whose coefficients are
all NaN, as is the case in bug 788093, so they also become zero
polynomials after shrinking, incidentally.
Also adds an optimized 26 entry LUT, as used in the creation of
http://pippin.gimp.org/sRGBz/
Please enter the commit message for your changes. Lines starting
This optimizes the coefficients of the matrix ensuring that a RGB 1.0 1.0 1.0
results in exactly CIE Lab 100.0 0.0 0.0 and that equal R,G,B triples yield 0.0
for CIE a, b. This is achieved by rounding to 16.16 fixed point precision,
which can be exactly represented by IEEE double, and then brute-force jittering
the coefficients +/- 1 for the best solution. This is also the rounding needed
for making the matrix well behaved when used in an ICC profile.
babl: replace a fprintf (stderr, ...) with babl_log().
It will make it visible in the logcat, for instance in Android Studio.
As a general rule, we should use babl_log() for anything which we
consider as "logs", unless we want to direct them to a given output for
sure (for instance in the case of CLI tools where we want the output to
be on standard I/O in terminal, fprintf() still is the best choice).
Formats based on custom primaries provided by applications are unknown to babl
at launch, we still want to keep the data though, since this list of most used
fishes first is useful resource in combination with the warnings about missing
fast paths.
Instead of extracting all meta-data of ICC profiles and attaching them to
BablSpaces, we provide an string key/value API to query meta data of in-memory
ICC profiles.
babl: avoid accidental matrix overwrite by long names
.. by increasing the static per space allocation to 512 bytes, these names need
to become shorter - or the name be allocated dynamically. This fixes problems
with parameterized lab / sRGB like TRCs - which yielded really long names.
It would be really nice if others, and prolifix people like
you, prepared git formatted patches, so that it is much saner
and easier to push and work with contributions as a maintainer
with a dirty tree, and in even more valuable bugs than this
one.. without needing to re-read and re-understand the entire
context of the fix, before fully reimplementing it.
This commit fixes bug #787441, where NaN is polluting the
computer error/tolerance.
They are propagated and instructions are spent on that, but their value are
never used. Some conversion functions in base even used the argument passed for
counting down to 0 and return 0 instead, to no ill effect.
Since we do not currently see external babl extensions, we can break extensions
API without bumping the library version, this is even a change where due to
varargs, old extensions will continue working until migrated.
Not going through/bench-marking chains that will make the number of components
drop below the input/output counts, and not permitting a temporary lack of
alpha both fixes bugs at higher tolerances and speeds up path selection.