summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2018-05-11 17:14:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2018-05-11 18:50:03 +0000
commitb40a556e20be3ee63480db849d5ba952768876e0 (patch)
tree1f401f7661c9029800875149439af1bb09109635
parentReleasing progress-linux version 0.1.34-1~dschinn1. (diff)
downloadbabl-b40a556e20be3ee63480db849d5ba952768876e0.zip
babl-b40a556e20be3ee63480db849d5ba952768876e0.tar.xz
Merging upstream version 0.1.38.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--INSTALL10
-rw-r--r--NEWS12
-rw-r--r--README22
-rw-r--r--babl/babl-cache.c28
-rw-r--r--babl/babl-conversion.c6
-rw-r--r--babl/babl-format.c29
-rw-r--r--babl/babl-icc.c2
-rw-r--r--babl/babl-internal.c2
-rw-r--r--babl/babl-memory.c2
-rw-r--r--babl/babl-palette.c2
-rw-r--r--babl/babl-space.c9
-rw-r--r--babl/babl-trc.c10
-rw-r--r--babl/babl-util.c12
-rw-r--r--babl/babl-version.h2
-rw-r--r--babl/babl.h9
-rw-r--r--babl/base/pow-24.c30
-rw-r--r--babl/base/pow-24.h30
-rwxr-xr-xconfigure30
-rw-r--r--configure.ac2
-rw-r--r--export-symbols1
-rw-r--r--extensions/CIE.c258
-rw-r--r--extensions/gggl-lies.c5
-rw-r--r--extensions/gggl.c13
-rw-r--r--extensions/sse2-float.c30
24 files changed, 467 insertions, 89 deletions
diff --git a/INSTALL b/INSTALL
index ea3004f..d2dc506 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,5 @@
-babl 0.1.34
+babl 0.1.38
Dynamic; any to any, pixel format conversion library.
@@ -12,10 +12,10 @@ From a released version the following is the expected method of
installation (or a variation on this theme):
------------------------------------------------------------
- foo$ wget ftp://ftp.gtk.org/pub/babl/0.1/babl-0.1.34.tar.bz2
- foo$ tar jxf babl-0.1.34.tar.gz
- foo$ cd babl-0.1.34
- foo/babl-0.1.34$ ./configure && make && sudo make install
+ foo$ wget ftp://ftp.gtk.org/pub/babl/0.1/babl-0.1.38.tar.bz2
+ foo$ tar jxf babl-0.1.38.tar.gz
+ foo$ cd babl-0.1.38
+ foo/babl-0.1.38$ ./configure && make && sudo make install
------------------------------------------------------------
diff --git a/NEWS b/NEWS
index c50a4ef..fba23b6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,17 @@
<dl><dt><!--
The NEWS file in the babl source tree is the source location for
the news section both in the README and the webpage.
-
-
-->
+
+2017-11-15 babl-0.1.38 </dt><dd>
+Added format "CIE L float", a couple of protections against division by 0.0
+ </dd><dt>
+2017-11-10 babl-0.1.36 </dt><dd>
+Optimized customized primary aware code paths for CIE Lab<->RGB conversions,
+improved accuracy of gamma approximations. New API babl_format_exists() for
+checking validity of babl format name, crash proofing of cache handling and use
+of environment variables.
+ </dd><dt>
2017-10-06 babl-0.1.34 </dt><dd>
Brown paper bag release, Fix indexed / custom primaries conflict, and re-export
a symbol used by old GEGL/GIMPs.
diff --git a/README b/README
index 6472d36..d213b53 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Babl-0.1.34
+Babl-0.1.38
Contents
@@ -64,6 +64,14 @@ babl release. If there are significant improvements to babl when a GEGL
release is done a babl release is most often put out just prior to the
GEGL release.
+2017-11-15 babl-0.1.38
+ Added format "CIE L float", a couple of protections against
+ division by 0.0
+2017-11-10 babl-0.1.36
+ Optimized customized primary aware code paths for CIE Lab<->RGB
+ conversions, improved accuracy of gamma approximations. New API
+ babl_format_exists() for checking validity of babl format name,
+ crash proofing of cache handling and use of environment variables.
2017-10-06 babl-0.1.34
Brown paper bag release, Fix indexed / custom primaries conflict,
and re-export a symbol used by old GEGL/GIMPs.
@@ -1691,6 +1699,16 @@ components
float CIE b
float A
+CIE L float
+
+bytes/pixel
+ 4
+model
+ CIE Lab
+components
+
+ float CIE L
+
CIE L alpha float
bytes/pixel
@@ -2186,4 +2204,4 @@ Massimo Valentini
Ell
fast paths
-/babl-0.1.34
+/babl-0.1.38
diff --git a/babl/babl-cache.c b/babl/babl-cache.c
index fa3f387..dcc76f4 100644
--- a/babl/babl-cache.c
+++ b/babl/babl-cache.c
@@ -37,6 +37,7 @@ mk_ancestry_iter (const char *path)
{
char copy[4096];
strncpy (copy, path, 4096);
+ copy[sizeof (copy) - 1] = '\0';
if (strrchr (copy, '/'))
{
*strrchr (copy, '/') = '\0';
@@ -63,6 +64,7 @@ mk_ancestry (const char *path)
{
char copy[4096];
strncpy (copy, path, 4096);
+ copy[sizeof (copy) - 1] = '\0';
#ifdef _WIN32
for (char *c = copy; *c; c++)
if (*c == '\\')
@@ -77,18 +79,19 @@ static const char *fish_cache_path (void)
static char path[4096];
strncpy (path, FALLBACK_CACHE_PATH, 4096);
+ path[sizeof (path) - 1] = '\0';
#ifndef _WIN32
if (getenv ("XDG_CACHE_HOME"))
- sprintf (path, "%s/babl/babl-fishes", getenv("XDG_CACHE_HOME"));
+ snprintf (path, sizeof (path), "%s/babl/babl-fishes", getenv("XDG_CACHE_HOME"));
else if (getenv ("HOME"))
- sprintf (path, "%s/.cache/babl/babl-fishes", getenv("HOME"));
+ snprintf (path, sizeof (path), "%s/.cache/babl/babl-fishes", getenv("HOME"));
#else
{
char win32path[4096];
if (SHGetFolderPathA (NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, win32path) == S_OK)
- sprintf (path, "%s\\%s\\babl-fishes.txt", win32path, BABL_LIBRARY);
+ snprintf (path, sizeof (path), "%s\\%s\\babl-fishes.txt", win32path, BABL_LIBRARY);
else if (getenv ("TEMP"))
- sprintf (path, "%s\\babl-fishes.txt", getenv("TEMP"));
+ snprintf (path, sizeof (path), "%s\\babl-fishes.txt", getenv("TEMP"));
}
#endif
@@ -150,13 +153,13 @@ static const char *cache_header (void)
{
static char buf[2048];
if (strchr (BABL_GIT_VERSION, ' ')) // we must be building from tarball
- sprintf (buf, "#%i.%i.%i BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
+ snprintf (buf, sizeof (buf),
+ "#%i.%i.%i BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
BABL_MAJOR_VERSION, BABL_MINOR_VERSION, BABL_MICRO_VERSION,
_babl_max_path_len (), _babl_legal_error ());
else
- sprintf (buf, "#%s BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
- BABL_GIT_VERSION,
- _babl_max_path_len (), _babl_legal_error ());
+ snprintf (buf, sizeof (buf), "#%s BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f",
+ BABL_GIT_VERSION, _babl_max_path_len (), _babl_legal_error ());
return buf;
}
@@ -167,10 +170,15 @@ void babl_store_db (void)
char *tmpp = calloc(8000,1);
FILE *dbfile;
- sprintf (tmpp, "%s~", fish_cache_path ());
+ if (!tmpp)
+ return;
+ snprintf (tmpp, 8000, "%s~", fish_cache_path ());
dbfile = fopen (tmpp, "w");
if (!dbfile)
+ {
+ free (tmpp);
return;
+ }
fprintf (dbfile, "%s\n", cache_header ());
/* sort the list of fishes by usage, making next run more efficient -
@@ -270,6 +278,7 @@ void babl_init_db (void)
{
fprintf (stderr, "%s:%i: loading of cache failed\n",
__FUNCTION__, __LINE__);
+ free (contents);
return;
}
@@ -312,6 +321,7 @@ void babl_init_db (void)
Babl *conv = (void*)babl_db_find(babl_conversion_db(), &token[1]);
if (!conv)
{
+ free (contents);
return;
}
else
diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c
index 75e5c93..17dccf8 100644
--- a/babl/babl-conversion.c
+++ b/babl/babl-conversion.c
@@ -154,7 +154,7 @@ create_name (Babl *source, Babl *destination, int type)
{
if (babl_extender ())
{
- snprintf (buf, 512 - 1, "%s %i: %s%s to %s",
+ snprintf (buf, sizeof (buf), "%s %i: %s%s to %s",
BABL (babl_extender ())->instance.name,
collisions,
type == BABL_CONVERSION_LINEAR ? "" :
@@ -162,18 +162,16 @@ create_name (Babl *source, Babl *destination, int type)
type == BABL_CONVERSION_PLANAR ? "planar " : "Eeeek! ",
source->instance.name,
destination->instance.name);
- buf[511] = '\0';
}
else
{
- snprintf (buf, 512 - 1, "%s %s to %s %i",
+ snprintf (buf, sizeof (buf), "%s %s to %s %i",
type == BABL_CONVERSION_LINEAR ? "" :
type == BABL_CONVERSION_PLANE ? "plane " :
type == BABL_CONVERSION_PLANAR ? "planar " : "Eeeek! ",
source->instance.name,
destination->instance.name,
collisions);
- buf[511] = '\0';
}
return buf;
}
diff --git a/babl/babl-format.c b/babl/babl-format.c
index 4ed14d0..45c62b2 100644
--- a/babl/babl-format.c
+++ b/babl/babl-format.c
@@ -135,8 +135,8 @@ format_new_from_format_with_space (const Babl *format, const Babl *space)
{
Babl *ret;
char new_name[256];
- sprintf (new_name, "%s-%s", babl_get_name ((void*)format),
- babl_get_name ((void*)space));
+ snprintf (new_name, sizeof (new_name), "%s-%s", babl_get_name ((void*)format),
+ babl_get_name ((void*)space));
ret = babl_db_find (babl_format_db(), new_name);
if (ret)
return ret;
@@ -161,6 +161,7 @@ create_name (const BablModel *model,
{
char buf[512] = "";
char *p = &buf[0];
+ ssize_t left;
int i;
int same_types = 1;
const BablType**t = type;
@@ -168,9 +169,11 @@ create_name (const BablModel *model,
BablComponent **c1 = component;
BablComponent **c2 = model->component;
-
- sprintf (p, "%s ", model->instance.name);
+ left = 512;
+ snprintf (p, left, "%s ", model->instance.name);
p += strlen (model->instance.name) + 1;
+ left -= strlen (model->instance.name) + 1;
+ babl_assert (left >= 0);
i = components;
while (i--)
@@ -202,7 +205,7 @@ create_name (const BablModel *model,
if (same_types)
{
- sprintf (p, "%s", first_type->instance.name);
+ snprintf (p, left, "%s", first_type->instance.name);
return babl_strdup (buf);
}
@@ -210,11 +213,14 @@ create_name (const BablModel *model,
while (i--)
{
- sprintf (p, "(%s as %s) ",
+ snprintf (p, left, "(%s as %s) ",
(*component)->instance.name,
(*type)->instance.name);
p += strlen ((*component)->instance.name) +
strlen ((*type)->instance.name) + strlen ("( as ) ");
+ left -= strlen ((*component)->instance.name) +
+ strlen ((*type)->instance.name) + strlen ("( as ) ");
+ babl_assert (left >= 0);
component++;
type++;
}
@@ -226,7 +232,7 @@ ncomponents_create_name (const Babl *type,
int components)
{
char buf[512];
- sprintf (buf, "%s[%i] ", type->instance.name, components);
+ snprintf (buf, sizeof (buf), "%s[%i] ", type->instance.name, components);
return babl_strdup (buf);
}
@@ -742,4 +748,13 @@ babl_format_with_space (const char *name, const Babl *space)
return ret;
}
+int
+babl_format_exists (const char *name)
+{
+ if (babl_db_exist_by_name (db, name))
+ return 1;
+ return 0;
+}
+
+
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 45ba8fa..20841b9 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -973,7 +973,7 @@ char *babl_icc_get_key (const char *icc_data,
{
char tag[5];
int val = icc_read (u32, 64);
- sprintf (tag, "%i", val);
+ snprintf (tag, sizeof (tag), "%i", val);
return strdup (tag);
} else if (!strcmp (key, "tags"))
{
diff --git a/babl/babl-internal.c b/babl/babl-internal.c
index 0589e3f..e0b4f7a 100644
--- a/babl/babl-internal.c
+++ b/babl/babl-internal.c
@@ -65,7 +65,7 @@ babl_backtrack (void)
{
char buf[512];
- sprintf (buf, "echo bt>/tmp/babl.gdb;"
+ snprintf (buf, sizeof (buf), "echo bt>/tmp/babl.gdb;"
"gdb -q --batch -x /tmp/babl.gdb --pid=%i | grep 'in ''babl_die' -A40", getpid ());
return system (buf);
}
diff --git a/babl/babl-memory.c b/babl/babl-memory.c
index d9e4d2f..d0229e4 100644
--- a/babl/babl-memory.c
+++ b/babl/babl-memory.c
@@ -71,7 +71,7 @@ mem_stats (void)
{
static char buf[128];
- sprintf (buf, "mallocs:%i callocs:%i strdups:%i dups:%i allocs:%i frees:%i reallocs:%i\t|",
+ snprintf (buf, sizeof (buf), "mallocs:%i callocs:%i strdups:%i dups:%i allocs:%i frees:%i reallocs:%i\t|",
mallocs, callocs, strdups, dups, mallocs + callocs + strdups + dups, frees, reallocs);
return buf;
}
diff --git a/babl/babl-palette.c b/babl/babl-palette.c
index 823ff0c..fda96ae 100644
--- a/babl/babl-palette.c
+++ b/babl/babl-palette.c
@@ -483,7 +483,7 @@ const Babl *babl_new_palette (const char *name,
if (!name)
{
static int cnt = 0;
- sprintf (cname, "_babl-int-%i", cnt++);
+ snprintf (cname, sizeof (cname), "_babl-int-%i", cnt++);
name = cname;
}
else
diff --git a/babl/babl-space.c b/babl/babl-space.c
index adc9e7a..781e419 100644
--- a/babl/babl-space.c
+++ b/babl/babl-space.c
@@ -285,9 +285,9 @@ babl_space_from_rgbxyz_matrix (const char *name,
space_db[i]=space;
space_db[i].instance.name = space_db[i].name;
if (name)
- sprintf (space_db[i].name, "%s", name);
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name);
else
- sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "space-%.4f,%.4f_%.4f,%.4f_%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
rx, gx, bx,
ry, gy, by,
rz, gz, bz,
@@ -348,10 +348,11 @@ babl_space_from_chromaticities (const char *name,
space_db[i]=space;
space_db[i].instance.name = space_db[i].name;
if (name)
- sprintf (space_db[i].name, "%s", name);
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name);
else
/* XXX: this can get longer than 256bytes ! */
- sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
+ snprintf (space_db[i].name, sizeof (space_db[i].name),
+ "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s",
wx,wy,rx,ry,bx,by,gx,gy,babl_get_name (space.trc[0]),
babl_get_name(space.trc[1]), babl_get_name(space.trc[2]));
diff --git a/babl/babl-trc.c b/babl/babl-trc.c
index 7524ef8..0a00710 100644
--- a/babl/babl-trc.c
+++ b/babl/babl-trc.c
@@ -292,11 +292,11 @@ babl_trc_new (const char *name,
trc_db[i]=trc;
trc_db[i].instance.name = trc_db[i].name;
if (name)
- sprintf (trc_db[i].name, "%s", name);
+ snprintf (trc_db[i].name, sizeof (trc_db[i].name), "%s", name);
else if (n_lut)
- sprintf (trc_db[i].name, "lut-trc");
+ snprintf (trc_db[i].name, sizeof (trc_db[i].name), "lut-trc");
else
- sprintf (trc_db[i].name, "trc-%i-%f", type, gamma);
+ snprintf (trc_db[i].name, sizeof (trc_db[i].name), "trc-%i-%f", type, gamma);
if (n_lut)
{
@@ -430,7 +430,7 @@ babl_trc_formula_srgb (double g, double a, double b, double c, double d)
fabs (c - (-3417)) < 0.01)
return babl_trc ("sRGB");
- sprintf (name, "%.6f %.6f %.4f %.4f %.4f", g, a, b, c, d);
+ snprintf (name, sizeof (name), "%.6f %.6f %.4f %.4f %.4f", g, a, b, c, d);
for (i = 0; name[i]; i++)
if (name[i] == ',') name[i] = '.';
while (name[strlen(name)-1]=='0')
@@ -446,7 +446,7 @@ babl_trc_gamma (double gamma)
if (fabs (gamma - 1.0) < 0.01)
return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL);
- sprintf (name, "%.6f", gamma);
+ snprintf (name, sizeof (name), "%.6f", gamma);
for (i = 0; name[i]; i++)
if (name[i] == ',') name[i] = '.';
while (name[strlen(name)-1]=='0')
diff --git a/babl/babl-util.c b/babl/babl-util.c
index 23c1513..60b695d 100644
--- a/babl/babl-util.c
+++ b/babl/babl-util.c
@@ -116,10 +116,18 @@ _babl_file_get_contents (const char *path,
if (!file)
return -1;
- fseek (file, 0, SEEK_END);
- size = ftell (file);
+ if (fseek (file, 0, SEEK_END) == -1 || (size = ftell (file)) == -1)
+ {
+ fclose (file);
+ return -1;
+ }
if (length) *length = size;
rewind (file);
+ if ((size_t) size > SIZE_MAX - 8)
+ {
+ fclose (file);
+ return -1;
+ }
buffer = calloc(size + 8, 1);
if (!buffer)
diff --git a/babl/babl-version.h b/babl/babl-version.h
index 4d1e2da..ed4a665 100644
--- a/babl/babl-version.h
+++ b/babl/babl-version.h
@@ -34,7 +34,7 @@
#define BABL_MAJOR_VERSION 0
#define BABL_MINOR_VERSION 1
-#define BABL_MICRO_VERSION 34
+#define BABL_MICRO_VERSION 38
/** Get the version information on the babl library */
void babl_get_version (int *major,
diff --git a/babl/babl.h b/babl/babl.h
index 5e299a7..a45de42 100644
--- a/babl/babl.h
+++ b/babl/babl.h
@@ -157,6 +157,15 @@ char *babl_icc_get_key (const char *icc_data,
const Babl * babl_format (const char *name);
/**
+ * babl_format_exists:
+ *
+ * Returns 1 if the provided format name is known by babl or 0 if it is
+ * not. Can also be used to verify that specific extension formats are
+ * available (though this can also be inferred from the version of babl).
+ */
+int babl_format_exists (const char *name);
+
+/**
* babl_format_with_space:
*
* Returns the babl object representing the color format given by
diff --git a/babl/base/pow-24.c b/babl/base/pow-24.c
index dbc4071..4587bf1 100644
--- a/babl/base/pow-24.c
+++ b/babl/base/pow-24.c
@@ -48,8 +48,13 @@ init_newton (double x, double exponent, double c0, double c1, double c2)
double
babl_pow_24 (double x)
{
- double y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
+ double y;
int i;
+ if (x > 16.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * 2.4);
+ }
+ y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
for (i = 0; i < 3; i++)
y = (1.+1./5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
x *= y;
@@ -61,9 +66,14 @@ babl_pow_24 (double x)
double
babl_pow_1_24 (double x)
{
- double y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
+ double y;
int i;
double z;
+ if (x > 1024.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * (1.0 / 2.4));
+ }
+ y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
x = sqrt (x);
/* newton's method for x^(-1/6) */
z = (1./6.) * x;
@@ -102,10 +112,15 @@ init_newtonf (float x, float exponent, float c0, float c1, float c2)
float
babl_pow_24f (float x)
{
- float y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
+ float y;
int i;
+ if (x > 16.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * 2.4f);
+ }
+ y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
for (i = 0; i < 3; i++)
- y = (1.f+1.f/5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
+ y = (1.f+1.f/5)*y - ((1.f/5)*x*(y*y))*((y*y)*(y*y));
x *= y;
return x*x*x;
}
@@ -115,9 +130,14 @@ babl_pow_24f (float x)
float
babl_pow_1_24f (float x)
{
- float y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
+ float y;
int i;
float z;
+ if (x > 1024.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * (1.0f / 2.4f));
+ }
+ y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
x = sqrtf (x);
/* newton's method for x^(-1/6) */
z = (1.f/6.f) * x;
diff --git a/babl/base/pow-24.h b/babl/base/pow-24.h
index a55c029..3ea6984 100644
--- a/babl/base/pow-24.h
+++ b/babl/base/pow-24.h
@@ -54,8 +54,13 @@ init_newton (double x, double exponent, double c0, double c1, double c2)
static inline double
babl_pow_24 (double x)
{
- double y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
+ double y;
int i;
+ if (x > 16.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * 2.4);
+ }
+ y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
for (i = 0; i < 3; i++)
y = (1.+1./5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
x *= y;
@@ -67,9 +72,14 @@ babl_pow_24 (double x)
static inline double
babl_pow_1_24 (double x)
{
- double y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
+ double y;
int i;
double z;
+ if (x > 1024.0) {
+ /* for large values, fall back to a slower but more accurate version */
+ return exp (log (x) * (1.0 / 2.4));
+ }
+ y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
x = sqrt (x);
/* newton's method for x^(-1/6) */
z = (1./6.) * x;
@@ -133,10 +143,15 @@ init_newtonf (float x, float exponent, float c0, float c1, float c2)
static inline float
babl_pow_24f (float x)
{
- float y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
+ float y;
int i;
+ if (x > 16.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * 2.4f);
+ }
+ y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f);
for (i = 0; i < 3; i++)
- y = (1.f+1.f/5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y));
+ y = (1.f+1.f/5)*y - ((1.f/5)*x*(y*y))*((y*y)*(y*y));
x *= y;
return x*x*x;
}
@@ -146,9 +161,14 @@ babl_pow_24f (float x)
static inline float
babl_pow_1_24f (float x)
{
- float y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
+ float y;
int i;
float z;
+ if (x > 1024.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return expf (logf (x) * (1.0f / 2.4f));
+ }
+ y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f);
x = sqrtf (x);
/* newton's method for x^(-1/6) */
z = (1.f/6.f) * x;
diff --git a/configure b/configure
index c808fee..bd885c5 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for babl 0.1.34.
+# Generated by GNU Autoconf 2.69 for babl 0.1.38.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='babl'
PACKAGE_TARNAME='babl'
-PACKAGE_VERSION='0.1.34'
-PACKAGE_STRING='babl 0.1.34'
+PACKAGE_VERSION='0.1.38'
+PACKAGE_STRING='babl 0.1.38'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1381,7 +1381,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures babl 0.1.34 to adapt to many kinds of systems.
+\`configure' configures babl 0.1.38 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1453,7 +1453,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of babl 0.1.34:";;
+ short | recursive ) echo "Configuration of babl 0.1.38:";;
esac
cat <<\_ACEOF
@@ -1573,7 +1573,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-babl configure 0.1.34
+babl configure 0.1.38
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1938,7 +1938,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by babl $as_me 0.1.34, which was
+It was created by babl $as_me 0.1.38, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2294,11 +2294,11 @@ ac_config_headers="$ac_config_headers config.h"
BABL_MAJOR_VERSION=0
BABL_MINOR_VERSION=1
-BABL_MICRO_VERSION=34
+BABL_MICRO_VERSION=38
BABL_INTERFACE_AGE=1
-BABL_BINARY_AGE=134
-BABL_VERSION=0.1.34
-BABL_REAL_VERSION=0.1.34
+BABL_BINARY_AGE=138
+BABL_VERSION=0.1.38
+BABL_REAL_VERSION=0.1.38
BABL_API_VERSION=0.1
@@ -2333,7 +2333,7 @@ fi
-BABL_LIBRARY_VERSION="133:1:133"
+BABL_LIBRARY_VERSION="137:1:137"
BABL_CURRENT_MINUS_AGE=0
@@ -2965,7 +2965,7 @@ fi
# Define the identity of the package.
PACKAGE='babl'
- VERSION='0.1.34'
+ VERSION='0.1.38'
# Some tools Automake needs.
@@ -14864,7 +14864,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by babl $as_me 0.1.34, which was
+This file was extended by babl $as_me 0.1.38, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14930,7 +14930,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-babl config.status 0.1.34
+babl config.status 0.1.38
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index dda45b1..c1fd10f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,7 @@ AC_PREREQ(2.54)
m4_define([babl_major_version], [0])
m4_define([babl_minor_version], [1])
-m4_define([babl_micro_version], [34])
+m4_define([babl_micro_version], [38])
m4_define([babl_real_version],
[babl_major_version.babl_minor_version.babl_micro_version])
m4_define([babl_version], [babl_real_version])
diff --git a/export-symbols b/export-symbols
index 2ba4bb8..f85fec9 100644
--- a/export-symbols
+++ b/export-symbols
@@ -8,6 +8,7 @@ babl_exit
babl_fast_fish
babl_fish
babl_format
+babl_format_exists
babl_format_get_bytes_per_pixel
babl_format_get_model
babl_format_get_n_components
diff --git a/extensions/CIE.c b/extensions/CIE.c
index d16d862..658fd2a 100644
--- a/extensions/CIE.c
+++ b/extensions/CIE.c
@@ -2,6 +2,7 @@
* Copyright (C) 2005, 2014 Øyvind Kolås.
* Copyright (C) 2009, Martin Nordholts
* Copyright (C) 2014, Elle Stone
+ * Copyright (C) 2017, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -168,13 +169,13 @@ XYZ_to_LAB (double X,
double y_r = Y / D50_WHITE_REF_Y;
double z_r = Z / D50_WHITE_REF_Z;
- if (x_r > LAB_EPSILON) f_x = pow(x_r, 1.0 / 3.0);
+ if (x_r > LAB_EPSILON) f_x = cbrt(x_r);
else ( f_x = ((LAB_KAPPA * x_r) + 16) / 116.0 );
- if (y_r > LAB_EPSILON) f_y = pow(y_r, 1.0 / 3.0);
+ if (y_r > LAB_EPSILON) f_y = cbrt(y_r);
else ( f_y = ((LAB_KAPPA * y_r) + 16) / 116.0 );
- if (z_r > LAB_EPSILON) f_z = pow(z_r, 1.0 / 3.0);
+ if (z_r > LAB_EPSILON) f_z = cbrt(z_r);
else ( f_z = ((LAB_KAPPA * z_r) + 16) / 116.0 );
*to_L = (116.0 * f_y) - 16.0;
@@ -592,6 +593,44 @@ cubef (float f)
}
static void
+Yf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ float yr = src[0];
+ float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr;
+
+ dst[0] = L;
+
+ src++;
+ dst++;
+ }
+}
+
+static void
+Yaf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ float yr = src[0];
+ float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr;
+
+ dst[0] = L;
+
+ src += 2;
+ dst += 1;
+ }
+}
+
+static void
Yaf_to_Laf (const Babl *conversion,float *src,
float *dst,
long samples)
@@ -617,6 +656,16 @@ rgbf_to_Labf (const Babl *conversion,float *src,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X;
+ float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X;
+ float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X;
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z;
+ float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z;
+ float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z;
long n = samples;
while (n--)
@@ -625,9 +674,9 @@ rgbf_to_Labf (const Babl *conversion,float *src,
float g = src[1];
float b = src[2];
- float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b;
- float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b;
- float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b;
+ float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b;
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+ float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b;
float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
@@ -647,10 +696,94 @@ rgbf_to_Labf (const Babl *conversion,float *src,
}
static void
+rgbaf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ long n = samples;
+
+ while (n--)
+ {
+ float r = src[0];
+ float g = src[1];
+ float b = src[2];
+
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+
+ float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
+
+ float L = 116.0f * fy - 16.0f;
+
+ dst[0] = L;
+
+ src += 4;
+ dst += 1;
+ }
+}
+
+static void
+rgbaf_to_Labf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X;
+ float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X;
+ float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X;
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z;
+ float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z;
+ float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z;
+ long n = samples;
+
+ while (n--)
+ {
+ float r = src[0];
+ float g = src[1];
+ float b = src[2];
+
+ float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b;
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+ float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b;
+
+ float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
+ float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
+ float fz = zr > LAB_EPSILON ? _cbrtf (zr) : (LAB_KAPPA * zr + 16.0f) / 116.0f;
+
+ float L = 116.0f * fy - 16.0f;
+ float A = 500.0f * (fx - fy);
+ float B = 200.0f * (fy - fz);
+
+ dst[0] = L;
+ dst[1] = A;
+ dst[2] = B;
+
+ src += 4;
+ dst += 3;
+ }
+}
+
+static void
rgbaf_to_Labaf (const Babl *conversion,float *src,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X;
+ float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X;
+ float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X;
+ float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y;
+ float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y;
+ float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y;
+ float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z;
+ float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z;
+ float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z;
long n = samples;
while (n--)
@@ -660,9 +793,9 @@ rgbaf_to_Labaf (const Babl *conversion,float *src,
float b = src[2];
float a = src[3];
- float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b;
- float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b;
- float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b;
+ float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b;
+ float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b;
+ float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b;
float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f;
float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f;
@@ -683,10 +816,52 @@ rgbaf_to_Labaf (const Babl *conversion,float *src,
}
static void
+Labf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ dst[0] = src[0];
+
+ src += 3;
+ dst += 1;
+ }
+}
+
+static void
+Labaf_to_Lf (const Babl *conversion,float *src,
+ float *dst,
+ long samples)
+{
+ long n = samples;
+
+ while (n--)
+ {
+ dst[0] = src[0];
+
+ src += 4;
+ dst += 1;
+ }
+}
+
+static void
Labf_to_rgbf (const Babl *conversion,float *src,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.XYZtoRGBf[0] * D50_WHITE_REF_X;
+ float m_0_1 = space->space.XYZtoRGBf[1] * D50_WHITE_REF_Y;
+ float m_0_2 = space->space.XYZtoRGBf[2] * D50_WHITE_REF_Z;
+ float m_1_0 = space->space.XYZtoRGBf[3] * D50_WHITE_REF_X;
+ float m_1_1 = space->space.XYZtoRGBf[4] * D50_WHITE_REF_Y;
+ float m_1_2 = space->space.XYZtoRGBf[5] * D50_WHITE_REF_Z;
+ float m_2_0 = space->space.XYZtoRGBf[6] * D50_WHITE_REF_X;
+ float m_2_1 = space->space.XYZtoRGBf[7] * D50_WHITE_REF_Y;
+ float m_2_2 = space->space.XYZtoRGBf[8] * D50_WHITE_REF_Z;
long n = samples;
while (n--)
@@ -703,9 +878,9 @@ Labf_to_rgbf (const Babl *conversion,float *src,
float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA;
float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA;
- float r = 3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr -0.490724283042f * D50_WHITE_REF_Z * zr;
- float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr +0.033453331711f * D50_WHITE_REF_Z * zr;
- float b = 0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr +1.405718224383f * D50_WHITE_REF_Z * zr;
+ float r = m_0_0 * xr + m_0_1 * yr + m_0_2 * zr;
+ float g = m_1_0 * xr + m_1_1 * yr + m_1_2 * zr;
+ float b = m_2_0 * xr + m_2_1 * yr + m_2_2 * zr;
dst[0] = r;
dst[1] = g;
@@ -721,6 +896,16 @@ Labaf_to_rgbaf (const Babl *conversion,float *src,
float *dst,
long samples)
{
+ const Babl *space = babl_conversion_get_source_space (conversion);
+ float m_0_0 = space->space.XYZtoRGBf[0] * D50_WHITE_REF_X;
+ float m_0_1 = space->space.XYZtoRGBf[1] * D50_WHITE_REF_Y;
+ float m_0_2 = space->space.XYZtoRGBf[2] * D50_WHITE_REF_Z;
+ float m_1_0 = space->space.XYZtoRGBf[3] * D50_WHITE_REF_X;
+ float m_1_1 = space->space.XYZtoRGBf[4] * D50_WHITE_REF_Y;
+ float m_1_2 = space->space.XYZtoRGBf[5] * D50_WHITE_REF_Z;
+ float m_2_0 = space->space.XYZtoRGBf[6] * D50_WHITE_REF_X;
+ float m_2_1 = space->space.XYZtoRGBf[7] * D50_WHITE_REF_Y;
+ float m_2_2 = space->space.XYZtoRGBf[8] * D50_WHITE_REF_Z;
long n = samples;
while (n--)
@@ -738,9 +923,9 @@ Labaf_to_rgbaf (const Babl *conversion,float *src,
float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA;
float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA;
- float r = 3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr -0.490724283042f * D50_WHITE_REF_Z * zr;
- float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr +0.033453331711f * D50_WHITE_REF_Z * zr;
- float b = 0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr +1.405718224383f * D50_WHITE_REF_Z * zr;
+ float r = m_0_0 * xr + m_0_1 * yr + m_0_2 * zr;
+ float g = m_1_0 * xr + m_1_1 * yr + m_1_2 * zr;
+ float b = m_2_0 * xr + m_2_1 * yr + m_2_2 * zr;
dst[0] = r;
dst[1] = g;
@@ -905,6 +1090,12 @@ conversions (void)
);
babl_conversion_new (
babl_format ("RGBA float"),
+ babl_format ("CIE Lab float"),
+ "linear", rgbaf_to_Labf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("RGBA float"),
babl_format ("CIE Lab alpha float"),
"linear", rgbaf_to_Labaf,
NULL
@@ -916,12 +1107,42 @@ conversions (void)
NULL
);
babl_conversion_new (
+ babl_format ("Y float"),
+ babl_format ("CIE L float"),
+ "linear", Yf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("YA float"),
+ babl_format ("CIE L float"),
+ "linear", Yaf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
babl_format ("YA float"),
babl_format ("CIE L alpha float"),
"linear", Yaf_to_Laf,
NULL
);
babl_conversion_new (
+ babl_format ("RGBA float"),
+ babl_format ("CIE L float"),
+ "linear", rgbaf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("CIE Lab float"),
+ babl_format ("CIE L float"),
+ "linear", Labf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
+ babl_format ("CIE Lab alpha float"),
+ babl_format ("CIE L float"),
+ "linear", Labaf_to_Lf,
+ NULL
+ );
+ babl_conversion_new (
babl_model ("RGBA"),
babl_model ("CIE LCH(ab)"),
"linear", rgba_to_lchab,
@@ -1020,6 +1241,13 @@ formats (void)
NULL);
babl_format_new (
+ "name", "CIE L float",
+ babl_model ("CIE Lab"),
+ babl_type ("float"),
+ babl_component ("CIE L"),
+ NULL);
+
+ babl_format_new (
"name", "CIE L alpha float",
babl_model ("CIE Lab alpha"),
babl_type ("float"),
diff --git a/extensions/gggl-lies.c b/extensions/gggl-lies.c
index b34f8ef..c08dccd 100644
--- a/extensions/gggl-lies.c
+++ b/extensions/gggl-lies.c
@@ -356,7 +356,10 @@ conv_gAF_gaF (const Babl *conversion,unsigned char *src, unsigned char *dst, lon
{
float alpha = (*(float *) (src + 4));
- *(float *) dst = ((*(float *) src) / alpha);
+ if (alpha == 0.0f)
+ *(float *) dst = 0.0f;
+ else
+ *(float *) dst = ((*(float *) src) / alpha);
dst += 4;
src += 4;
*(float *) dst = alpha;
diff --git a/extensions/gggl.c b/extensions/gggl.c
index 83352d2..cf83988 100644
--- a/extensions/gggl.c
+++ b/extensions/gggl.c
@@ -373,7 +373,10 @@ conv_gAF_gaF (const Babl *conversion,unsigned char *src, unsigned char *dst, lon
{
float alpha = (*(float *) (src + 4));
- *(float *) dst = ((*(float *) src) / alpha);
+ if (alpha == 0.0f)
+ *(float *) dst = 0.0f;
+ else
+ *(float *) dst = ((*(float *) src) / alpha);
dst += 4;
src += 4;
*(float *) dst = alpha;
@@ -557,10 +560,16 @@ conv_rgbA16_rgbaF (const Babl *conversion,unsigned char *src, unsigned char *dst
{
float alpha = (((unsigned short *) src)[3]) / 65535.0;
int c;
+ float recip_alpha;
+
+ if (alpha == 0.0f)
+ recip_alpha = 10000.0;
+ else
+ recip_alpha = 1.0/alpha;
for (c = 0; c < 3; c++)
{
- (*(float *) dst) = (*(unsigned short *) src / 65535.0) / alpha;
+ (*(float *) dst) = (*(unsigned short *) src / 65535.0) * recip_alpha;
dst += 4;
src += 2;
}
diff --git a/extensions/sse2-float.c b/extensions/sse2-float.c
index d26073c..223f85c 100644
--- a/extensions/sse2-float.c
+++ b/extensions/sse2-float.c
@@ -237,6 +237,22 @@ conv_rgbAF_linear_rgbaF_linear_spin (const Babl *conversion,const float *src, fl
#define FLT_ONE 0x3f800000 // ((union {float f; int i;}){1.0f}).i
#define FLT_MANTISSA (1<<23)
+static inline float
+sse_max_component (__v4sf x) {
+ __v4sf s;
+ __v4sf m;
+
+ /* m = [max (x[3], x[1]), max (x[2], x[0])] */
+ s = (__v4sf) _mm_shuffle_epi32 ((__m128i) x, _MM_SHUFFLE(0, 0, 3, 2));
+ m = _mm_max_ps (x, s);
+
+ /* m = [max (m[1], m[0])] = [max (max (x[3], x[1]), max (x[2], x[0]))] */
+ s = (__v4sf) _mm_shuffle_epi32 ((__m128i) m, _MM_SHUFFLE(0, 0, 0, 1));
+ m = _mm_max_ps (m, s);
+
+ return m[0];
+}
+
static inline __v4sf
sse_init_newton (__v4sf x, double exponent, double c0, double c1, double c2)
{
@@ -249,6 +265,13 @@ static inline __v4sf
sse_pow_1_24 (__v4sf x)
{
__v4sf y, z;
+ if (sse_max_component (x) > 1024.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return _mm_set_ps (expf (logf (x[3]) * (1.0f / 2.4f)),
+ expf (logf (x[2]) * (1.0f / 2.4f)),
+ expf (logf (x[1]) * (1.0f / 2.4f)),
+ expf (logf (x[0]) * (1.0f / 2.4f)));
+ }
y = sse_init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383);
x = _mm_sqrt_ps (x);
/* newton's method for x^(-1/6) */
@@ -262,6 +285,13 @@ static inline __v4sf
sse_pow_24 (__v4sf x)
{
__v4sf y, z;
+ if (sse_max_component (x) > 16.0f) {
+ /* for large values, fall back to a slower but more accurate version */
+ return _mm_set_ps (expf (logf (x[3]) * 2.4f),
+ expf (logf (x[2]) * 2.4f),
+ expf (logf (x[1]) * 2.4f),
+ expf (logf (x[0]) * 2.4f));
+ }
y = sse_init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332);
/* newton's method for x^(-1/5) */
z = splat4f (1.f/5.f) * x;