[babl/wip/pippin/inverted-cmyk: 4/5] babl: implement proper CMYK support
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl/wip/pippin/inverted-cmyk: 4/5] babl: implement proper CMYK support
- Date: Sat, 24 Nov 2018 02:21:04 +0000 (UTC)
commit 92c36826c1cdbeca96633a6ead78dba9423688ef
Author: Øyvind Kolås <pippin gimp org>
Date: Mon Nov 12 23:35:31 2018 +0100
babl: implement proper CMYK support
babl/babl-conversion.c | 27 +-
babl/babl-fish-reference.c | 480 +++++++++++++++-----
babl/babl-fish.c | 58 +--
babl/babl-icc.c | 60 ++-
babl/babl-internal.h | 9 +-
babl/babl-model.c | 12 +-
babl/babl-model.h | 1 +
babl/babl-sanity.c | 11 +-
babl/babl-space.c | 63 ++-
babl/babl-space.h | 16 +
babl/babl.c | 4 -
babl/babl.h | 3 +
babl/base/Makefile.am | 1 +
babl/base/babl-base.c | 1 +
babl/base/babl-base.h | 1 +
babl/base/model-cmyk.c | 1083 ++++++++++++++++++++++++++++++++++++++++++++
export-symbols | 1 +
extensions/Makefile.am | 1 +
extensions/naive-CMYK.c | 243 +---------
19 files changed, 1667 insertions(+), 408 deletions(-)
---
diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c
index ef68fd3..b4af910 100644
--- a/babl/babl-conversion.c
+++ b/babl/babl-conversion.c
@@ -152,7 +152,8 @@ _conversion_new (const char *name,
BablFuncLinear linear,
BablFuncPlane plane,
BablFuncPlanar planar,
- void *user_data)
+ void *user_data,
+ int allow_collision)
{
Babl *babl = NULL;
@@ -237,16 +238,17 @@ _conversion_new (const char *name,
BABL (babl->conversion.destination),
babl_type_from_id (BABL_DOUBLE));
- if(0){
+ if(allow_collision){
const Babl *fish = babl_conversion_find (src_format, dst_format);
if (fish)
- return fish;
+ return (void*)fish;
}
babl_conversion_new (
src_format,
dst_format,
"linear", linear,
"data", user_data,
+ allow_collision?"allow-collision":NULL,
NULL);
babl->conversion.error = 0.0;
}
@@ -283,13 +285,10 @@ create_name (Babl *source, Babl *destination, int type)
}
return buf;
}
-const char *
-babl_conversion_create_name (Babl *source, Babl *destination, int type);
-
-int _babl_loaded = 0;
const char *
-babl_conversion_create_name (Babl *source, Babl *destination, int type)
+babl_conversion_create_name (Babl *source, Babl *destination, int type,
+ int allow_collision)
{
Babl *babl;
char *name;
@@ -297,7 +296,7 @@ babl_conversion_create_name (Babl *source, Babl *destination, int type)
collisions = 0;
name = create_name (source, destination, type);
- if (!_babl_loaded)
+ if (allow_collision == 0)
{
babl = babl_db_exist (db, id, name);
while (babl)
@@ -331,8 +330,8 @@ babl_conversion_new (const void *first_arg,
Babl *source;
Babl *destination;
-
char *name;
+ int allow_collision = 0;
va_start (varg, first_arg);
source = (Babl *) arg;
@@ -355,6 +354,10 @@ babl_conversion_new (const void *first_arg,
user_data = va_arg (varg, void*);
}
+ else if (!strcmp (arg, "allow-collision"))
+ {
+ allow_collision = 1;
+ }
else if (!strcmp (arg, "linear"))
{
if (got_func++)
@@ -408,10 +411,10 @@ babl_conversion_new (const void *first_arg,
type = BABL_CONVERSION_PLANAR;
}
- name = (void*) babl_conversion_create_name (source, destination, type);
+ name = (void*) babl_conversion_create_name (source, destination, type, allow_collision);
babl = _conversion_new (name, id, source, destination, linear, plane, planar,
- user_data);
+ user_data, allow_collision);
/* Since there is not an already registered instance by the required
* id/name, inserting newly created class into database.
diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c
index 6d1aa84..e4f1bc4 100644
--- a/babl/babl-fish-reference.c
+++ b/babl/babl-fish-reference.c
@@ -18,6 +18,10 @@
#include "config.h"
#include "babl-internal.h"
+#ifdef HAVE_LCMS
+#include "lcms2.h"
+#endif
+
static Babl *
assert_conversion_find (const void *source,
@@ -28,6 +32,7 @@ assert_conversion_find (const void *source,
if (!ret)
babl_fatal ("failed finding conversion between %s and %s aborting",
babl_get_name (source), babl_get_name (destination));
+
return ret;
}
@@ -251,7 +256,6 @@ convert_from_double (BablFormat *destination_fmt,
src_img->stride[0] = 0;
dst_img->data[0] = destination_buf;
- dst_img->type[0] = (BablType *) babl_type_from_id (BABL_DOUBLE);
dst_img->pitch[0] = destination_fmt->bytes_per_pixel;
dst_img->stride[0] = 0;
@@ -690,6 +694,13 @@ process_same_model (const Babl *babl,
}
}
+typedef enum _Kind Kind;
+enum _Kind { KIND_RGB, KIND_CMYK};
+
+static int format_has_cmyk_model (const Babl *format)
+{
+ return format->format.model->is_cmyk;
+}
static void
babl_fish_reference_process_double (const Babl *babl,
@@ -698,81 +709,122 @@ babl_fish_reference_process_double (const Babl *babl,
long n,
void *data)
{
- Babl *source_image = NULL;
- Babl *rgba_image = NULL;
- Babl *destination_image = NULL;
- void *source_double_buf_alloc = NULL;
- void *source_double_buf;
- void *rgba_double_buf_alloc = NULL;
- void *rgba_double_buf;
- void *destination_double_buf_alloc = NULL;
- void *destination_double_buf;
- const void *type_double = babl_type_from_id (BABL_DOUBLE);
-
- if (babl->fish.source->format.type[0] == type_double &&
- BABL(babl->fish.source)->format.components ==
- BABL(babl->fish.source)->format.model->components && 0)
- {
- source_double_buf = (void*)source;
- source_image = babl_image_from_linear (
- source_double_buf, BABL (BABL ((babl->fish.source))->format.model));
- }
- else
- {
- source_double_buf_alloc = babl_malloc (sizeof (double) * n *
- BABL (babl->fish.source)->format.model->components);
-
- source_double_buf = source_double_buf_alloc;
- source_image = babl_image_from_linear (
- source_double_buf, BABL (BABL ((babl->fish.source))->format.model));
- convert_to_double (
- (BablFormat *) BABL (babl->fish.source),
- source,
- source_double_buf,
- n
- );
- }
-
- if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA"))
- {
- rgba_double_buf = source_double_buf;
- rgba_image = babl_image_from_linear (
- rgba_double_buf,
- (void*)babl->fish.source->format.model);
- }
- else
- {
- Babl *conv =
- assert_conversion_find (
- BABL (babl->fish.source)->format.model,
+ Kind source_kind = KIND_RGB;
+ Kind destination_kind = KIND_RGB;
+ Babl *source_image = NULL;
+ Babl *rgba_image = NULL;
+ Babl *cmyka_image = NULL;
+ Babl *destination_image = NULL;
+ void *source_double_buf_alloc = NULL;
+ void *source_double_buf;
+ void *rgba_double_buf_alloc = NULL;
+ void *rgba_double_buf;
+ void *cmyka_double_buf_alloc = NULL;
+ void *cmyka_double_buf;
+ void *destination_double_buf_alloc = NULL;
+ void *destination_double_buf;
+ const void *type_double = babl_type_from_id (BABL_DOUBLE);
+
+ /* This is not the full/only condition XXX */
+
+ /* XXX : sometimes is_cmyk is neither 0 or 1 */
+
+ if (format_has_cmyk_model (babl->fish.source))
+ source_kind = KIND_CMYK;
+ if (format_has_cmyk_model (babl->fish.destination))
+ destination_kind = KIND_CMYK;
+
+ if (babl->fish.source->format.type[0] == type_double &&
+ BABL(babl->fish.source)->format.components ==
+ BABL(babl->fish.source)->format.model->components)
+ {
+ source_double_buf = (void*)source;
+ source_image = babl_image_from_linear (
+ source_double_buf, BABL (BABL ((babl->fish.source))->format.model));
+ }
+ else
+ {
+ source_double_buf =
+ source_double_buf_alloc = babl_malloc (sizeof (double) * n *
+ BABL (babl->fish.source)->format.model->components);
+
+ source_image = babl_image_from_linear (
+ source_double_buf, BABL (BABL ((babl->fish.source))->format.model));
+ convert_to_double (
+ (BablFormat *) BABL (babl->fish.source),
+ source,
+ source_double_buf,
+ n
+ );
+ }
- babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
- BABL (BABL ((babl->fish.source))->format.space)));
+ babl_mutex_lock (babl_reference_mutex);
+ switch (source_kind)
+ {
+ case KIND_RGB:
+ {
+ Babl *conv = assert_conversion_find (
+ BABL (babl->fish.source)->format.model,
+ babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
+ BABL (BABL ((babl->fish.source))->format.space)));
- rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
- rgba_double_buf = rgba_double_buf_alloc;
+ rgba_double_buf =
+ rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
- rgba_image = babl_image_from_linear (
+ rgba_image = babl_image_from_linear (
rgba_double_buf, babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
BABL (BABL ((babl->fish.source))->format.space)) );
- if (conv->class_type == BABL_CONVERSION_PLANAR)
+ if (conv->class_type == BABL_CONVERSION_PLANAR)
+ {
+ babl_conversion_process (conv,
+ (void*)source_image, (void*)rgba_image, n);
+ }
+ else if (conv->class_type == BABL_CONVERSION_LINEAR)
+ {
+ babl_conversion_process (conv, source_double_buf, rgba_double_buf, n);
+ }
+ else babl_fatal ("oops");
+ }
+ break;
+ case KIND_CMYK:
+ if (babl_model_is ((void*)babl->fish.source->format.model, "cmykA"))
{
- babl_conversion_process (
- conv,
- (void*)source_image, (void*)rgba_image,
- n);
+ cmyka_double_buf = source_double_buf;
+ cmyka_image = babl_image_from_linear (cmyka_double_buf,
+ (void*)babl->fish.source->format.model);
}
- else if (conv->class_type == BABL_CONVERSION_LINEAR)
+ else
{
- babl_conversion_process (
- conv,
- source_double_buf, rgba_double_buf,
- n);
+ Babl *conv = assert_conversion_find (
+ BABL (babl->fish.source)->format.model,
+ babl_remodel_with_space (babl_model ("cmykA"),
+ BABL (BABL ((babl->fish.source))->format.space)));
+
+ cmyka_double_buf =
+ cmyka_double_buf_alloc = babl_malloc (sizeof (double) * n * 5);
+
+ cmyka_image = babl_image_from_linear (
+ cmyka_double_buf, babl_remodel_with_space (babl_model ("cmykA"),
+ BABL (BABL ((babl->fish.source))->format.space)) );
+
+ if (conv->class_type == BABL_CONVERSION_PLANAR)
+ {
+ babl_conversion_process (conv,
+ (void*)source_image, (void*)cmyka_image, n);
+ }
+ else if (conv->class_type == BABL_CONVERSION_LINEAR)
+ {
+ babl_conversion_process (conv,source_double_buf, cmyka_double_buf, n);
+ }
+ else babl_fatal ("oops");
}
- else babl_fatal ("oops");
- }
+ break;
+ }
+ if (source_kind == KIND_RGB &&
+ destination_kind == KIND_RGB)
+ {
if (((babl->fish.source)->format.space !=
((babl->fish.destination)->format.space)))
{
@@ -785,67 +837,262 @@ babl_fish_reference_process_double (const Babl *babl,
babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n);
}
+ }
+ else if (source_kind == KIND_RGB &&
+ destination_kind == KIND_CMYK)
+ {
+ cmyka_double_buf =
+ cmyka_double_buf_alloc = babl_malloc (sizeof (double) * n * 5);
+ cmyka_image = babl_image_from_linear (
+ cmyka_double_buf, babl_remodel_with_space (babl_model ("cmykA"),
+ BABL (BABL ((babl->fish.destination))->format.space)) );
+
+#if HAVE_LCMS
+ if (babl->fish.destination->format.space->space.cmyk.lcms_profile)
+ {
+ /* lcms expect floats with normalized range 0.0-100.0 for CMYK data,
+ we also do our inversion from profile here.
+ */
+ double *rgba=rgba_double_buf;
+ double *cmyka=cmyka_double_buf;
+ int i;
+ /* use lcms for doing conversion from RGBA */
+ cmsDoTransform (babl->fish.destination->format.space->space.cmyk.lcms_from_rgba,
+ rgba_double_buf, cmyka_double_buf, n);
+
+ for (i = 0; i < n; i++)
+ {
+ cmyka[i * 5 + 0] = 1.0-(cmyka[i * 5 + 0])/100.0;
+ cmyka[i * 5 + 1] = 1.0-(cmyka[i * 5 + 1])/100.0;
+ cmyka[i * 5 + 2] = 1.0-(cmyka[i * 5 + 2])/100.0;
+ cmyka[i * 5 + 3] = 1.0-(cmyka[i * 5 + 3])/100.0;
+ cmyka[i * 5 + 4] = rgba[i * 4 + 3];
+ }
+ }
+ else
+#endif
+ {
+ double *rgba=rgba_double_buf;
+ double *cmyka=cmyka_double_buf;
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ /* A very naive conversion - but it is usable */
+ double key=0.0;
+ cmyka[i * 5 + 0] = 1.0 - rgba[i * 4 + 0];
+ cmyka[i * 5 + 1] = 1.0 - rgba[i * 4 + 1];
+ cmyka[i * 5 + 2] = 1.0 - rgba[i * 4 + 2];
+
+ if (cmyka[i * 5 + 0] < key) key = cmyka[i*5+0];
+ if (cmyka[i * 5 + 1] < key) key = cmyka[i*5+1];
+ if (cmyka[i * 5 + 2] < key) key = cmyka[i*5+2];
+ key *= 1.0; // pullout - XXX tune default pullout?;
+
+ if (key < 1.0)
+ {
+ cmyka[i * 5 + 0] = (cmyka[i * 5 + 0] - key) / (1.0-key);
+ cmyka[i * 5 + 1] = (cmyka[i * 5 + 1] - key) / (1.0-key);
+ cmyka[i * 5 + 2] = (cmyka[i * 5 + 2] - key) / (1.0-key);
+ }
+ cmyka[i * 5 + 0] = 1.0-cmyka[i * 5 + 0];
+ cmyka[i * 5 + 1] = 1.0-cmyka[i * 5 + 1];
+ cmyka[i * 5 + 2] = 1.0-cmyka[i * 5 + 2];
+ cmyka[i * 5 + 3] = 1.0-key;
+ cmyka[i * 5 + 4] = rgba[i * 4 + 3];
+ }
+ }
+ }
+ else if (source_kind == KIND_CMYK &&
+ destination_kind == KIND_RGB)
+ {
+ /* */
+ rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
+ rgba_double_buf = rgba_double_buf_alloc;
+ rgba_image = babl_image_from_linear (
+ rgba_double_buf, babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
+ BABL (BABL ((babl->fish.source))->format.space)) );
+
+#if HAVE_LCMS
+ if (babl->fish.source->format.space->space.cmyk.lcms_profile)
+ {
{
- const Babl *destination_rgba_format =
- babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
- BABL (BABL ((babl->fish.destination))->format.space));
+ /* lcms expect floats with normalized range 0.0-100.0 for CMYK data,
+ we also do our inversion from profile here.
+ */
+ double *cmyka=cmyka_double_buf;
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ cmyka[i * 5 + 0] = (1.0-cmyka[i * 5 + 0])*100.0;
+ cmyka[i * 5 + 1] = (1.0-cmyka[i * 5 + 1])*100.0;
+ cmyka[i * 5 + 2] = (1.0-cmyka[i * 5 + 2])*100.0;
+ cmyka[i * 5 + 3] = (1.0-cmyka[i * 5 + 3])*100.0;
+ }
+ }
+ /* use lcms for doing conversion to RGBA */
+ cmsDoTransform (babl->fish.source->format.space->space.cmyk.lcms_to_rgba,
+ cmyka_double_buf, rgba_double_buf, n);
- if(BABL (babl->fish.destination)->format.model == (void*)destination_rgba_format)
+ {
+ double *rgba=rgba_double_buf;
+ double *cmyka=cmyka_double_buf;
+ int i;
+ for (i = 0; i < n; i++)
{
- destination_double_buf = rgba_double_buf;
+ rgba[i * 4 + 3] = cmyka[i * 5 + 4];
}
- else
+ }
+ }
+ else
+#endif
+ {
+ double *rgba=rgba_double_buf;
+ double *cmyka=cmyka_double_buf;
+ int i;
+ for (i = 0; i < n; i++)
{
- Babl *conv =
- assert_conversion_find (destination_rgba_format,
- BABL (babl->fish.destination)->format.model);
+ /* A very naive conversion - but it is usable */
+ rgba[i * 4 + 0] = cmyka[i * 5 + 0]*cmyka[i*5+3];
+ rgba[i * 4 + 1] = cmyka[i * 5 + 1]*cmyka[i*5+3];
+ rgba[i * 4 + 2] = cmyka[i * 5 + 2]*cmyka[i*5+3];
+ rgba[i * 4 + 3] = cmyka[i * 5 + 4];
+ }
+ }
- destination_double_buf_alloc = babl_malloc (sizeof (double) * n *
- BABL (babl->fish.destination)->format.model->components);
- destination_double_buf = destination_double_buf_alloc;
+ /* color space conversions */
+ if ((babl_space ("babl-rgb")!=
+ ((babl->fish.destination)->format.space)))
+ {
+ double matrix[9];
+ double *rgba = rgba_double_buf;
+ babl_matrix_mul_matrix (
+ (babl->fish.destination)->format.space->space.XYZtoRGB,
+ babl_space("babl-rgb")->space.RGBtoXYZ,
+ matrix);
- if (conv->class_type == BABL_CONVERSION_PLANAR)
- {
- destination_image = babl_image_from_linear (
- destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model));
+ babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n);
+ }
+ }
+ else if (source_kind == KIND_CMYK &&
+ destination_kind == KIND_CMYK)
+ {
+#if HAVE_LCMS
+ /* XXX XXX XXX NYI, keep a global list of lcms2 based conversions,
+ make k-preserve k-plane preserve intents a global setting, defaulting
+ to k-preserve
+ */
+#endif
+ }
- babl_conversion_process (
- conv,
- (void*)rgba_image, (void*)destination_image,
- n);
+ switch (destination_kind) /* XXX: the cases can share logic */
+ {
+ case KIND_CMYK:
+ {
+ const Babl *destination_cmyka_format =
+ babl_remodel_with_space (babl_model ("cmykA"),
+ BABL (BABL ((babl->fish.destination))->format.space));
+ if(BABL (babl->fish.destination)->format.model == (void*)destination_cmyka_format)
+ {
+ destination_double_buf = cmyka_double_buf;
}
- else if (conv->class_type == BABL_CONVERSION_LINEAR)
+ else
{
- babl_conversion_process (
- conv,
- rgba_double_buf, destination_double_buf,
- n);
+ Babl *conv =
+ assert_conversion_find (destination_cmyka_format,
+ BABL (babl->fish.destination)->format.model);
+ destination_double_buf =
+ destination_double_buf_alloc = babl_malloc (sizeof (double) * n *
+ BABL (babl->fish.destination)->format.model->components);
+ if (conv->class_type == BABL_CONVERSION_PLANAR)
+ {
+ destination_image = babl_image_from_linear (
+ destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model));
+ babl_conversion_process (conv,
+ (void*)cmyka_image, (void*)destination_image, n);
+ }
+ else if (conv->class_type == BABL_CONVERSION_LINEAR)
+ {
+ babl_conversion_process (conv,
+ cmyka_double_buf, destination_double_buf, n);
+ }
+ else
+ {
+ babl_fatal ("oops");
+ }
}
- else babl_fatal ("oops");
- }
- }
-
- convert_from_double (
- (BablFormat *) BABL (babl->fish.destination),
- destination_double_buf,
- destination,
- n
- );
+ }
+ break;
+ case KIND_RGB:
+ {
+ const Babl *destination_rgba_format =
+ babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
+ BABL (BABL ((babl->fish.destination))->format.space));
- if (destination_double_buf_alloc)
- babl_free (destination_double_buf_alloc);
- if (rgba_double_buf_alloc)
- babl_free (rgba_double_buf_alloc);
- if (source_double_buf_alloc)
- babl_free (source_double_buf_alloc);
- if (source_image)
- babl_free (source_image);
- if (rgba_image)
- babl_free (rgba_image);
- if (destination_image)
- babl_free (destination_image);
+ if(BABL (babl->fish.destination)->format.model == (void*)destination_rgba_format)
+ {
+ destination_double_buf = rgba_double_buf;
+ }
+ else
+ {
+ Babl *conv =
+ assert_conversion_find (destination_rgba_format,
+ BABL (babl->fish.destination)->format.model);
+ destination_double_buf_alloc = babl_malloc (sizeof (double) * n *
+ BABL (babl->fish.destination)->format.model->components);
+ destination_double_buf = destination_double_buf_alloc;
+
+ if (conv->class_type == BABL_CONVERSION_PLANAR)
+ {
+ destination_image = babl_image_from_linear (
+ destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model));
+ babl_conversion_process (
+ conv,
+ (void*)rgba_image, (void*)destination_image,
+ n);
+ }
+ else if (conv->class_type == BABL_CONVERSION_LINEAR)
+ {
+ babl_conversion_process (
+ conv,
+ rgba_double_buf, destination_double_buf,
+ n);
+ }
+ else
+ {
+ babl_fatal ("oops");
+ }
+ }
+ }
+ break;
+ }
+ babl_mutex_unlock (babl_reference_mutex);
+
+ /* convert from double model backing target pixel format to final representation */
+ convert_from_double (
+ (BablFormat *) BABL (babl->fish.destination),
+ destination_double_buf,
+ destination,
+ n
+ );
+
+ if (destination_double_buf_alloc)
+ babl_free (destination_double_buf_alloc);
+ if (rgba_double_buf_alloc)
+ babl_free (rgba_double_buf_alloc);
+ if (cmyka_double_buf_alloc)
+ babl_free (cmyka_double_buf_alloc);
+ if (source_double_buf_alloc)
+ babl_free (source_double_buf_alloc);
+ if (source_image)
+ babl_free (source_image);
+ if (rgba_image)
+ babl_free (rgba_image);
+ if (cmyka_image)
+ babl_free (cmyka_image);
+ if (destination_image)
+ babl_free (destination_image);
}
static void
@@ -870,6 +1117,7 @@ babl_fish_reference_process_float (const Babl *babl,
Babl *conv_from_rgba;
char dst_name[256];
+
{
char src_name[256];
sprintf (src_name, "%s float", babl_get_name((void*)babl->fish.source->format.model));
@@ -978,7 +1226,6 @@ babl_fish_reference_process_float (const Babl *babl,
}
{
-
if(babl_format_with_space ("RGBA float",
BABL (BABL ((babl->fish.destination))->format.space)) ==
babl_format_with_space (dst_name,
@@ -1070,6 +1317,13 @@ babl_fish_reference_process (const Babl *babl,
return;
}
+ if (format_has_cmyk_model (babl->fish.source) ||
+ format_has_cmyk_model (babl->fish.destination))
+ {
+ babl_fish_reference_process_double (babl, source, destination, n, data);
+ return;
+ }
+
if (allow_float_reference == -1)
allow_float_reference = getenv ("BABL_REFERENCE_NOFLOAT") ? 0 : 1;
diff --git a/babl/babl-fish.c b/babl/babl-fish.c
index 8c239eb..a3d299c 100644
--- a/babl/babl-fish.c
+++ b/babl/babl-fish.c
@@ -126,7 +126,7 @@ babl_conversion_find (const void *source,
babl_list_each (BABL (source)->type.from_list, match_conversion, &data);
if (data != (void*)destination) /* didn't change */
{
- return data;
+ return data; /* found conversion */
}
data = NULL;
@@ -160,19 +160,19 @@ babl_conversion_find (const void *source,
reference->conversion.function.linear,
NULL,
NULL,
- reference->conversion.data);
+ reference->conversion.data, 1);
case BABL_CONVERSION_PLANE:
return _conversion_new ("", 0, source, destination,
NULL,
reference->conversion.function.plane,
NULL,
- reference->conversion.data);
+ reference->conversion.data, 1);
case BABL_CONVERSION_PLANAR:
return _conversion_new ("", 0, source, destination,
NULL,
NULL,
reference->conversion.function.planar,
- reference->conversion.data);
+ reference->conversion.data, 1);
}
}
return NULL;
@@ -278,33 +278,39 @@ babl_fish (const void *source,
if (!ffish.fish_fish)
{
+ const Babl *src_space = (void*)source_format->format.space;
+ const Babl *dst_space = (void*)destination_format->format.space;
/* we haven't tried to search for suitable path yet */
- Babl *fish_path = babl_fish_path (source_format, destination_format);
- if (fish_path)
+ if (src_space->space.cmyk.is_cmyk == 0 &&
+ dst_space->space.cmyk.is_cmyk == 0)
{
- return fish_path;
- }
+ Babl *fish_path = babl_fish_path (source_format, destination_format);
+ if (fish_path)
+ {
+ return fish_path;
+ }
#if 1
- else
- {
- /* there isn't a suitable path for requested formats,
- * let's create a dummy BABL_FISH instance and insert
- * it into the fish database to indicate that such path
- * does not exist.
- */
- char *name = "X"; /* name does not matter */
- Babl *fish = babl_calloc (1, sizeof (BablFish) + strlen (name) + 1);
-
- fish->class_type = BABL_FISH;
- fish->instance.id = babl_fish_get_id (source_format, destination_format);
- fish->instance.name = ((char *) fish) + sizeof (BablFish);
- strcpy (fish->instance.name, name);
- fish->fish.source = source_format;
- fish->fish.destination = destination_format;
- babl_db_insert (babl_fish_db (), fish);
- }
+ else
+ {
+ /* there isn't a suitable path for requested formats,
+ * let's create a dummy BABL_FISH instance and insert
+ * it into the fish database to indicate that such path
+ * does not exist.
+ */
+ char *name = "X"; /* name does not matter */
+ Babl *fish = babl_calloc (1, sizeof (BablFish) + strlen (name) + 1);
+
+ fish->class_type = BABL_FISH;
+ fish->instance.id = babl_fish_get_id (source_format, destination_format);
+ fish->instance.name = ((char *) fish) + sizeof (BablFish);
+ strcpy (fish->instance.name, name);
+ fish->fish.source = source_format;
+ fish->fish.destination = destination_format;
+ babl_db_insert (babl_fish_db (), fish);
+ }
#endif
+ }
}
else if (ffish.fish_fish->fish.data)
{
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 1ffe415..67c98e6 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -16,7 +16,7 @@
* <https://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#include "../config.h"
#include "babl-internal.h"
#include <stdio.h>
#include <stdlib.h>
@@ -720,6 +720,10 @@ static char *decode_string (ICC *state, const char *tag, const char *lang, const
return NULL;
}
+#ifdef HAVE_LCMS
+static cmsHPROFILE sRGBProfile = 0;
+#endif
+
const Babl *
babl_space_from_icc (const char *icc_data,
int icc_length,
@@ -748,14 +752,55 @@ babl_space_from_icc (const char *icc_data,
else
{
profile_class = icc_read (sign, 12);
- if (strcmp (profile_class.str, "mntr"))
- *error = "not a monitor-class profile";
- else
+ color_space = icc_read (sign, 16);
+
+ if (!strcmp (color_space.str, "CMYK"))
{
- color_space = icc_read (sign, 16);
- if (strcmp (color_space.str, "RGB "))
- *error = "not defining an RGB space";
+ ret = _babl_space_for_lcms (icc_data, icc_length);
+ if (ret->space.cmyk.is_cmyk)
+ return ret;
+ ret->space.cmyk.is_cmyk = 1;
+ ret->space.icc_length = icc_length;
+ ret->space.icc_profile = malloc (icc_length);
+ memcpy (ret->space.icc_profile, icc_data, icc_length);
+
+#ifdef HAVE_LCMS
+ if (sRGBProfile == 0)
+ {
+ const Babl *rgb = babl_space("babl-rgb"); /* should use a forced linear profile */
+ sRGBProfile = cmsOpenProfileFromMem(rgb->space.icc_profile, rgb->space.icc_length);
+ }
+
+ ret->space.cmyk.lcms_profile = cmsOpenProfileFromMem(ret->space.icc_profile, ret->space.icc_length);
+
+/* these are not defined by lcms2.h we hope that following the existing pattern of pixel-format definitions
work */
+#ifndef TYPE_CMYKA_DBL
+#define TYPE_CMYKA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(0))
+#endif
+#ifndef TYPE_RGBA_DBL
+#define TYPE_RGBA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(0))
+#endif
+
+ ret->space.cmyk.lcms_to_rgba = cmsCreateTransform(ret->space.cmyk.lcms_profile, TYPE_CMYKA_DBL,
+ sRGBProfile, TYPE_RGBA_DBL,
+ INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_BLACKPOINTCOMPENSATION);
+// INTENT_PERCEPTUAL,0);//intent & 7, 0);
+ ret->space.cmyk.lcms_from_rgba = cmsCreateTransform(sRGBProfile, TYPE_RGBA_DBL,
+ ret->space.cmyk.lcms_profile, TYPE_CMYKA_DBL,
+ INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_BLACKPOINTCOMPENSATION);
+ // INTENT_PERCEPTUAL,0);//intent & 7, 0);
+ cmsCloseProfile (ret->space.cmyk.lcms_profile); // XXX keep it open in case of CMYK to CMYK
transforms needed?
+#endif
+ return ret;
}
+
+ if (strcmp (color_space.str, "RGB "))
+ *error = "not defining an RGB space";
+ else
+ {
+ if (strcmp (profile_class.str, "mntr"))
+ *error = "not a monitor-class profile";
+ }
}
if (!*error)
@@ -827,6 +872,7 @@ babl_space_from_icc (const char *icc_data,
if (*error)
{
+
babl_free (state);
return NULL;
}
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 73fe18f..95ca661 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -347,7 +347,8 @@ _conversion_new (const char *name,
BablFuncLinear linear,
BablFuncPlane plane,
BablFuncPlanar planar,
- void *user_data);
+ void *user_data,
+ int allow_collision);
double _babl_legal_error (void);
void babl_init_db (void);
@@ -373,7 +374,9 @@ Babl * format_new_from_format_with_space (const Babl *format, const Babl *space)
int babl_list_destroy (void *data);
const char *
-babl_conversion_create_name (Babl *source, Babl *destination, int is_reference);
+babl_conversion_create_name (Babl *source, Babl *destination, int type,
+ int allow_collision);
+
void _babl_space_add_universal_rgb (const Babl *space);
const Babl *
babl_trc_formula_srgb (double gamma, double a, double b, double c, double d);
@@ -453,5 +456,7 @@ char *babl_space_to_icc (const Babl *space,
const char *copyright,
BablICCFlags flags,
int *icc_length);
+Babl *
+_babl_space_for_lcms (const char *icc_data, int icc_length); // XXX pass profile for dedup?
#endif
diff --git a/babl/babl-model.c b/babl/babl-model.c
index f5330fe..4ce2211 100644
--- a/babl/babl-model.c
+++ b/babl/babl-model.c
@@ -56,7 +56,8 @@ model_new (const char *name,
const Babl *space,
int id,
int components,
- BablComponent **component)
+ BablComponent **component,
+ int is_cmyk)
{
Babl *babl;
@@ -73,6 +74,7 @@ model_new (const char *name,
babl->model.space = space;
babl->model.data = NULL;
babl->model.model = NULL;
+ babl->model.is_cmyk = is_cmyk;
strcpy (babl->instance.name, name);
memcpy (babl->model.component, component, sizeof (BablComponent *) * components);
@@ -114,6 +116,7 @@ babl_model_new (void *first_argument,
char *name = NULL;
const Babl *space = babl_space ("sRGB");
BablComponent *component [BABL_MAX_COMPONENTS];
+ int is_cmyk = 0;
va_start (varg, first_argument);
@@ -130,6 +133,11 @@ babl_model_new (void *first_argument,
assigned_name = va_arg (varg, char *);
}
+ else if (!strcmp (arg, "cmyk"))
+ {
+ is_cmyk = 1;
+ }
+
/* if we didn't point to a known string, we assume argument to be babl */
else if (BABL_IS_BABL (arg))
{
@@ -211,7 +219,7 @@ babl_model_new (void *first_argument,
if (! babl)
{
- babl = model_new (name, space, id, components, component);
+ babl = model_new (name, space, id, components, component, is_cmyk);
babl_db_insert (db, babl);
construct_double_format (babl);
}
diff --git a/babl/babl-model.h b/babl/babl-model.h
index ee0e51f..74595a8 100644
--- a/babl/babl-model.h
+++ b/babl/babl-model.h
@@ -32,6 +32,7 @@ typedef struct
void *data; /* user-data, used for palette */
const Babl *space;
void *model; /* back pointer to model with sRGB space */
+ int is_cmyk; /* is an cmyk based model */
} BablModel;
#endif
diff --git a/babl/babl-sanity.c b/babl/babl-sanity.c
index 2c18d56..7282766 100644
--- a/babl/babl-sanity.c
+++ b/babl/babl-sanity.c
@@ -69,7 +69,7 @@ model_sanity (Babl *babl,
void *user_data)
{
/* ensure that every type has reference conversions to
- * and from rgba */
+ * and from RGBA / cmykA */
int ok, i;
BablList *list;
@@ -79,17 +79,22 @@ model_sanity (Babl *babl,
{
for (i = 0; i < babl_list_size (list); i++)
{
- if (babl_conversion_destination ((Babl *) list->items[i]) == babl_model_from_id (BABL_RGBA))
+ if (babl_conversion_destination ((Babl *) list->items[i]) == babl_model_from_id (BABL_RGBA) ||
+ babl_conversion_destination ((Babl *) list->items[i]) == babl_model ("cmykA"))
{
ok = 1;
break;
}
}
}
+
+ if (ok == 0 && babl == babl_model ("cmykA"))
+ ok = 1;
+
if (!ok)
{
OK = 0;
- babl_log ("lack of sanity! model '%s' has no conversion to 'rgba'",
+ babl_log ("lack of sanity! model '%s' has no conversion to 'RGBA' or 'cmykA'",
babl->instance.name);
}
diff --git a/babl/babl-space.c b/babl/babl-space.c
index 9a78d38..fcadc8c 100644
--- a/babl/babl-space.c
+++ b/babl/babl-space.c
@@ -219,6 +219,50 @@ babl_space (const char *name)
return NULL;
}
+Babl *
+_babl_space_for_lcms (const char *icc_data, int icc_length)
+{
+ int i=0;
+ BablSpace space;
+
+
+ for (i = 0; space_db[i].instance.class_type; i++)
+ {
+ if (space_db[i].icc_length ==
+ icc_length &&
+ (memcmp (space_db[i].icc_profile, icc_data, icc_length) == 0))
+ {
+ return (void*)&space_db[i];
+ }
+ }
+
+ memset (&space, 0, sizeof(space));
+ space.instance.class_type = BABL_SPACE;
+ space.instance.id = 0;
+
+ if (i >= MAX_SPACES-1)
+ {
+ babl_log ("too many BablSpaces");
+ return NULL;
+ }
+
+ /* initialize it with copy of srgb content */
+ if(1){
+ const BablSpace *srgb = &babl_space("sRGB")->space;
+ memcpy (&space.xw,
+ &srgb->xw,
+((char*)&srgb->icc_profile -
+(char*)&srgb->xw));
+ }
+
+ space_db[i]=space;
+ space_db[i].instance.name = space_db[i].name;
+ snprintf (space_db[i].name, sizeof (space_db[i].name), "space-lcms-%i", i);
+
+
+ return (Babl*)&space_db[i];
+}
+
const Babl *
babl_space_from_rgbxyz_matrix (const char *name,
double wx, double wy, double wz,
@@ -310,6 +354,7 @@ babl_space_from_rgbxyz_matrix (const char *name,
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]));
+ babl_space_get_icc ((Babl*)&space_db[i], NULL);
return (Babl*)&space_db[i];
}
@@ -373,6 +418,7 @@ const Babl * babl_space_from_chromaticities (const char *name,
/* compute matrixes */
babl_space_compute_matrices (&space_db[i], flags);
+ babl_space_get_icc ((Babl*)&space_db[i], NULL);
return (Babl*)&space_db[i];
}
@@ -406,6 +452,14 @@ babl_space_class_init (void)
0);
/* hard-coded pre-quantized values - to match exactly what is used in standards see issue #18 */
#endif
+ babl_space_from_chromaticities ("babl-rgb",
+ 0.3127, 0.3290, /* D65 */
+ 0.639998686, 0.330010138,
+ 0.300003784, 0.600003357,
+ 0.150002046, 0.059997204,
+ babl_trc("linear"), NULL, NULL,
+ 0);
+ /* hard-coded pre-quantized values - to match exactly what is used in standards see issue #18 */
babl_space_from_chromaticities ("Rec2020",
0.3127, 0.3290, /* D65 */
@@ -1015,7 +1069,8 @@ const Babl *babl_space_match_trc_matrix (const Babl *trc_red,
for (i = 0; space_db[i].instance.class_type; i++)
{
BablSpace *space = &space_db[i];
- if (trc_red == space->trc[0] &&
+ if (space->cmyk.is_cmyk == 0 &&
+ trc_red == space->trc[0] &&
trc_green == space->trc[1] &&
trc_blue == space->trc[2] &&
fabs(rx - space->RGBtoXYZ[0]) < delta &&
@@ -1082,6 +1137,11 @@ void babl_space_get (const Babl *babl,
if(blue_trc)*blue_trc = space->trc[2];
}
+int babl_space_is_cmyk (const Babl *space)
+{
+ return space?space->space.cmyk.is_cmyk:0;
+}
+
/* Trademarks:
*
* International Color Consortium is a registered trademarks of the.
@@ -1091,3 +1151,4 @@ void babl_space_get (const Babl *babl,
* RGB- without actualy being it, Adobe is a trademark or registered trademark
* of Adobe Systems Incorporated in many countires.
*/
+
diff --git a/babl/babl-space.h b/babl/babl-space.h
index 35fd2c3..92926ba 100644
--- a/babl/babl-space.h
+++ b/babl/babl-space.h
@@ -19,13 +19,28 @@
#ifndef _BABL_SPACE_H
#define _BABL_SPACE_H
+#include "../config.h"
#include <math.h>
#include <string.h>
#include "base/util.h"
#include "babl-matrix.h"
+#ifdef HAVE_LCMS
+#include <lcms2.h>
+#endif
+
BABL_CLASS_DECLARE (space);
+typedef struct
+{
+ int is_cmyk;
+#ifdef HAVE_LCMS
+ cmsHPROFILE lcms_profile;
+ cmsHTRANSFORM lcms_to_rgba;
+ cmsHTRANSFORM lcms_from_rgba;
+#endif
+} BablCMYK;
+
typedef struct
{
BablInstance instance;
@@ -62,6 +77,7 @@ typedef struct
char *icc_profile;
int icc_length;
+ BablCMYK cmyk;
} BablSpace;
diff --git a/babl/babl.c b/babl/babl.c
index ef2cfb7..4479f68 100644
--- a/babl/babl.c
+++ b/babl/babl.c
@@ -125,8 +125,6 @@ babl_dir_list (void)
return ret;
}
-extern int _babl_loaded;
-
void
babl_init (void)
{
@@ -135,7 +133,6 @@ babl_init (void)
if (ref_count++ == 0)
{
char * dir_list;
- _babl_loaded = 0;
babl_internal_init ();
babl_sampling_class_init ();
@@ -158,7 +155,6 @@ babl_init (void)
babl_free (dir_list);
babl_init_db ();
- _babl_loaded = 1;
}
}
diff --git a/babl/babl.h b/babl/babl.h
index 943de99..1301270 100644
--- a/babl/babl.h
+++ b/babl/babl.h
@@ -584,6 +584,9 @@ babl_space_from_rgbxyz_matrix (const char *name,
*/
const char * babl_format_get_encoding (const Babl *babl);
+
+int babl_space_is_cmyk (const Babl *space);
+
/* values below this are stored premultiplied with this value,
* it can also be used as a generic alpha zero epsilon in GEGL
*
diff --git a/babl/base/Makefile.am b/babl/base/Makefile.am
index 1b0fabe..70a2f30 100644
--- a/babl/base/Makefile.am
+++ b/babl/base/Makefile.am
@@ -14,6 +14,7 @@ c_sources = \
type-u32.c \
model-rgb.c \
model-gray.c \
+ model-cmyk.c \
model-ycbcr.c
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/babl
diff --git a/babl/base/babl-base.c b/babl/base/babl-base.c
index 7931cfc..1d93341 100644
--- a/babl/base/babl-base.c
+++ b/babl/base/babl-base.c
@@ -69,6 +69,7 @@ models (void)
babl_hmpf_on_name_lookups--;
babl_base_model_rgb ();
babl_base_model_gray ();
+ babl_base_model_cmyk ();
babl_hmpf_on_name_lookups++;
babl_base_model_ycbcr ();
}
diff --git a/babl/base/babl-base.h b/babl/base/babl-base.h
index bc67f5c..64f1667 100644
--- a/babl/base/babl-base.h
+++ b/babl/base/babl-base.h
@@ -33,6 +33,7 @@ void babl_base_type_u32 (void);
void babl_base_model_pal (void);
void babl_base_model_rgb (void);
+void babl_base_model_cmyk (void);
void babl_base_model_gray (void);
void babl_base_model_ycbcr (void);
diff --git a/babl/base/model-cmyk.c b/babl/base/model-cmyk.c
new file mode 100644
index 0000000..6b771a5
--- /dev/null
+++ b/babl/base/model-cmyk.c
@@ -0,0 +1,1083 @@
+/* babl - dynamically extendable universal pixel conversion library.
+ * Copyright (C) 2005, 2018 Øyvind Kolås.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+/* This file define the "cmy" and "cmyk" models and related formats these
+ * are CMYK formats withthe components stored so that 0 means full coverage
+ * and 1.0 means no coverage which makes additive compositing/blending work
+ * like as if it was RGB
+
+ * conversions should be made with reference to the icc profile in the space
+ * using lcms2 for handling.
+ */
+
+#include "config.h"
+#include <math.h>
+#include <string.h>
+
+#include "babl.h"
+#include "babl-base.h"
+#include "base/util.h"
+
+
+static void
+cmyka_to_cmykA (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+ double alpha = ((double *) src)[4];
+
+ ((double *) dst)[0] = (cyan) * alpha;
+ ((double *) dst)[1] = (magenta) * alpha;
+ ((double *) dst)[2] = (yellow) * alpha;
+ ((double *) dst)[3] = (key) * alpha;
+ ((double *) dst)[4] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+cmykA_to_cmyka (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double alpha = ((double *) src)[4];
+ double ralpha = alpha>0.000001?1.0/alpha:0.0;
+ double cyan = ((double *) src)[0] * ralpha;
+ double magenta= ((double *) src)[1] * ralpha;
+ double yellow = ((double *) src)[2] * ralpha;
+ double key = ((double *) src)[3] * ralpha;
+
+ ((double *) dst)[0] = cyan;
+ ((double *) dst)[1] = magenta;
+ ((double *) dst)[2] = yellow;
+ ((double *) dst)[3] = key;
+ ((double *) dst)[4] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+cmyk_to_cmyka (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+
+ ((double *) dst)[0] = cyan;
+ ((double *) dst)[1] = magenta;
+ ((double *) dst)[2] = yellow;
+ ((double *) dst)[3] = key;
+ ((double *) dst)[4] = 1.0;
+
+ src += 4 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+cmyka_to_cmyk (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+
+ ((double *) dst)[0] = cyan;
+ ((double *) dst)[1] = magenta;
+ ((double *) dst)[2] = yellow;
+ ((double *) dst)[3] = key;
+
+ src += 5 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+
+/////////////////////
+static void
+cmyka_to_CMYKA (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+ double alpha = ((double *) src)[4];
+
+ ((double *) dst)[0] = (1.0-cyan) * alpha;
+ ((double *) dst)[1] = (1.0-magenta) * alpha;
+ ((double *) dst)[2] = (1.0-yellow) * alpha;
+ ((double *) dst)[3] = (1.0-key) * alpha;
+ ((double *) dst)[4] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+CMYKA_to_cmyka (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double alpha = ((double *) src)[4];
+ double ralpha = alpha>0.000001?1.0/alpha:0.0;
+ double cyan = ((double *) src)[0] * ralpha;
+ double magenta= ((double *) src)[1] * ralpha;
+ double yellow = ((double *) src)[2] * ralpha;
+ double key = ((double *) src)[3] * ralpha;
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+ ((double *) dst)[3] = 1.0-key;
+ ((double *) dst)[4] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+
+
+static void
+CMYK_to_cmyka (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+ ((double *) dst)[3] = 1.0-key;
+ ((double *) dst)[4] = 1.0;
+
+ src += 4 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+cmyka_to_CMYK (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+ ((double *) dst)[3] = 1.0-key;
+
+ src += 5 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+
+static void
+cmyka_to_CMYKa (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = ((double *) src)[0];
+ double magenta = ((double *) src)[1];
+ double yellow = ((double *) src)[2];
+ double key = ((double *) src)[3];
+ double alpha = ((double *) src)[4];
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+ ((double *) dst)[3] = 1.0-key;
+ ((double *) dst)[4] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+
+
+
+
+
+
+#if 0
+static void
+rgba_to_cmykA (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double red = (((double *) src)[0]);
+ double green = (((double *) src)[1]);
+ double blue = (((double *) src)[2]);
+ double alpha = ((double *) src)[3];
+
+ double cyan, magenta, yellow, key;
+
+ double pullout = 1.0;
+
+ cyan = 1.0 - red;
+ magenta = 1.0 - green;
+ yellow = 1.0 - blue;
+
+ key = 1.0;
+ if (cyan < key) key = cyan;
+ if (magenta < key) key = magenta;
+ if (yellow < key) key = yellow;
+
+ key *= pullout;
+
+ if (key < 1.0)
+ {
+ cyan = (cyan - key) / (1.0 - key);
+ magenta = (magenta - key) / (1.0 - key);
+ yellow = (yellow - key) / (1.0 - key);
+ }
+ else
+ {
+ cyan = 0.0;
+ magenta = 0.0;
+ yellow = 0.0;
+ }
+
+ ((double *) dst)[0] = (1.0-cyan) * alpha;
+ ((double *) dst)[1] = (1.0-magenta) * alpha;
+ ((double *) dst)[2] = (1.0-yellow) * alpha;
+ ((double *) dst)[3] = (1.0-key) * alpha;
+ ((double *) dst)[4] = alpha;
+
+ src += 4 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+cmykA_to_rgba (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double alpha = ((double *) src)[4];
+ double ralpha = alpha>0.000001?1.0/alpha:0.0;
+ double cyanI = ((double *) src)[0] * ralpha;
+ double magentaI= ((double *) src)[1] * ralpha;
+ double yellowI = ((double *) src)[2] * ralpha;
+ double keyI = ((double *) src)[3] * ralpha;
+
+ double cyan = 1.0-cyanI;
+ double magenta = 1.0-magentaI;
+ double yellow = 1.0-yellowI;
+ double key = 1.0-keyI;
+
+ double red, green, blue;
+
+ if (key < 1.0)
+ {
+ cyan = cyan * (1.0 - key) + key;
+ magenta = magenta * (1.0 - key) + key;
+ yellow = yellow * (1.0 - key) + key;
+ }
+ else
+ {
+ cyan = magenta = yellow = 1.0;
+ }
+
+ red = 1.0 - cyan;
+ green = 1.0 - magenta;
+ blue = 1.0 - yellow;
+
+ ((double *) dst)[0] = (red);
+ ((double *) dst)[1] = (green);
+ ((double *) dst)[2] = (blue);
+ ((double *) dst)[3] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+
+static void
+rgba_to_cmyka (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double red = (((double *) src)[0]);
+ double green = (((double *) src)[1]);
+ double blue = (((double *) src)[2]);
+ double alpha = ((double *) src)[3];
+
+ double cyan, magenta, yellow, key;
+
+ double pullout = 1.0;
+
+ cyan = 1.0 - red;
+ magenta = 1.0 - green;
+ yellow = 1.0 - blue;
+
+ key = 1.0;
+ if (cyan < key) key = cyan;
+ if (magenta < key) key = magenta;
+ if (yellow < key) key = yellow;
+
+ key *= pullout;
+
+ if (key < 1.0)
+ {
+ cyan = (cyan - key) / (1.0 - key);
+ magenta = (magenta - key) / (1.0 - key);
+ yellow = (yellow - key) / (1.0 - key);
+ }
+ else
+ {
+ cyan = 0.0;
+ magenta = 0.0;
+ yellow = 0.0;
+ }
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+ ((double *) dst)[3] = 1.0-key;
+ ((double *) dst)[4] = alpha;
+
+ src += 4 * sizeof (double);
+ dst += 5 * sizeof (double);
+ }
+}
+
+static void
+cmyka_to_rgba (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = 1.0-((double *) src)[0];
+ double magenta = 1.0-((double *) src)[1];
+ double yellow = 1.0-((double *) src)[2];
+ double key = 1.0-((double *) src)[3];
+ double alpha = ((double *) src)[4];
+
+ double red, green, blue;
+
+ if (key < 1.0)
+ {
+ cyan = cyan * (1.0 - key) + key;
+ magenta = magenta * (1.0 - key) + key;
+ yellow = yellow * (1.0 - key) + key;
+ }
+ else
+ {
+ cyan = magenta = yellow = 1.0;
+ }
+
+ red = 1.0 - cyan;
+ green = 1.0 - magenta;
+ blue = 1.0 - yellow;
+
+ ((double *) dst)[0] = (red);
+ ((double *) dst)[1] = (green);
+ ((double *) dst)[2] = (blue);
+ ((double *) dst)[3] = alpha;
+
+ src += 5 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+
+static void
+rgba_to_cmyk (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double red = (((double *) src)[0]);
+ double green = (((double *) src)[1]);
+ double blue = (((double *) src)[2]);
+
+ double cyan, magenta, yellow, key;
+
+ double pullout = 1.0;
+
+ cyan = 1.0 - red;
+ magenta = 1.0 - green;
+ yellow = 1.0 - blue;
+
+ key = 1.0;
+ if (cyan < key) key = cyan;
+ if (magenta < key) key = magenta;
+ if (yellow < key) key = yellow;
+
+ key *= pullout;
+
+ if (key < 1.0)
+ {
+ cyan = (cyan - key) / (1.0 - key);
+ magenta = (magenta - key) / (1.0 - key);
+ yellow = (yellow - key) / (1.0 - key);
+ }
+ else
+ {
+ cyan = 0.0;
+ magenta = 0.0;
+ yellow = 0.0;
+ }
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+ ((double *) dst)[3] = 1.0-key;
+
+ src += 4 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+
+static void
+cmyk_to_rgba (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = 1.0-((double *) src)[0];
+ double magenta = 1.0-((double *) src)[1];
+ double yellow = 1.0-((double *) src)[2];
+ double key = 1.0-((double *) src)[3];
+
+ double red, green, blue;
+
+ if (key < 1.0)
+ {
+ cyan = cyan * (1.0 - key) + key;
+ magenta = magenta * (1.0 - key) + key;
+ yellow = yellow * (1.0 - key) + key;
+ }
+ else
+ {
+ cyan = magenta = yellow = 1.0;
+ }
+
+ red = 1.0 - cyan;
+ green = 1.0 - magenta;
+ blue = 1.0 - yellow;
+
+ ((double *) dst)[0] = (red);
+ ((double *) dst)[1] = (green);
+ ((double *) dst)[2] = (blue);
+
+ ((double *) dst)[3] = 1.0;
+
+ src += 4 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+
+static void
+rgba_to_cmy (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double red = (((double *) src)[0]);
+ double green = (((double *) src)[1]);
+ double blue = (((double *) src)[2]);
+
+ double cyan, magenta, yellow;
+
+ cyan = 1.0 - red;
+ magenta = 1.0 - green;
+ yellow = 1.0 - blue;
+
+ ((double *) dst)[0] = 1.0-cyan;
+ ((double *) dst)[1] = 1.0-magenta;
+ ((double *) dst)[2] = 1.0-yellow;
+
+ src += 4 * sizeof (double);
+ dst += 3 * sizeof (double);
+ }
+}
+
+static void
+cmy_to_rgba (const Babl *conversion,char *src,
+ char *dst,
+ long n)
+{
+ while (n--)
+ {
+ double cyan = 1.0-((double *) src)[0];
+ double magenta = 1.0-((double *) src)[1];
+ double yellow = 1.0-((double *) src)[2];
+
+ double red, green, blue;
+
+ red = 1.0 - cyan;
+ green = 1.0 - magenta;
+ blue = 1.0 - yellow;
+
+ ((double *) dst)[0] = (red);
+ ((double *) dst)[1] = (green);
+ ((double *) dst)[2] = (blue);
+
+ ((double *) dst)[3] = 1.0;
+
+ src += 3 * sizeof (double);
+ dst += 4 * sizeof (double);
+ }
+}
+#endif
+
+void
+babl_base_model_cmyk (void)
+{
+ babl_component_new ("cyan", NULL);
+ babl_component_new ("yellow", NULL);
+ babl_component_new ("magenta", NULL);
+ babl_component_new ("key", NULL);
+
+
+ babl_component_new ("ca", NULL);
+ babl_component_new ("ma", NULL);
+ babl_component_new ("ya", NULL);
+ babl_component_new ("ka", NULL);
+
+
+ babl_component_new ("Cyan", NULL);
+ babl_component_new ("Yellow", NULL);
+ babl_component_new ("Magenta", NULL);
+ babl_component_new ("Key", NULL);
+
+
+ babl_component_new ("Ca", NULL);
+ babl_component_new ("Ma", NULL);
+ babl_component_new ("Yea", NULL);
+ babl_component_new ("Ka", NULL);
+
+ babl_model_new (
+ "name", "camayakaA",
+ babl_component ("ca"),
+ babl_component ("ma"),
+ babl_component ("ya"),
+ babl_component ("ka"),
+ babl_component ("A"),
+ "cmyk",
+ NULL
+ );
+
+ babl_model_new (
+ "name", "cmykA",
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ babl_component ("A"),
+ "cmyk",
+ NULL
+ );
+ babl_model_new (
+ "name", "cmyk",
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ "cmyk",
+ NULL
+ );
+
+ babl_model_new (
+ "name", "CaMaYaKaA",
+ babl_component ("Ca"),
+ babl_component ("Ma"),
+ babl_component ("Yea"),
+ babl_component ("Ka"),
+ babl_component ("A"),
+ "cmyk",
+ NULL
+ );
+
+ babl_model_new (
+ "name", "CMYKA",
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ babl_component ("A"),
+ "cmyk",
+ NULL
+ );
+ babl_model_new (
+ "name", "CMYK",
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ "cmyk",
+ NULL
+ );
+
+ babl_conversion_new (
+ babl_model ("cmykA"),
+ babl_model ("cmyk"),
+ "linear", cmyka_to_cmyk,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("cmyk"),
+ babl_model ("cmykA"),
+ "linear", cmyk_to_cmyka,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("cmykA"),
+ babl_model ("camayakaA"),
+ "linear", cmyka_to_cmykA,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("camayakaA"),
+ babl_model ("cmykA"),
+ "linear", cmykA_to_cmyka,
+ NULL
+ );
+
+ babl_conversion_new (
+ babl_model ("cmykA"),
+ babl_model ("CMYKA"),
+ "linear", cmyka_to_CMYKa,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("CMYKA"),
+ babl_model ("cmykA"),
+ "linear", cmyka_to_CMYKa, // does the same job
+ NULL
+ );
+
+
+ babl_conversion_new (
+ babl_model ("cmykA"),
+ babl_model ("CMYK"),
+ "linear", cmyka_to_CMYK,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("CMYK"),
+ babl_model ("cmykA"),
+ "linear", CMYK_to_cmyka,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("cmykA"),
+ babl_model ("CaMaYaKaA"),
+ "linear", cmyka_to_CMYKA,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("CaMaYaKaA"),
+ babl_model ("cmykA"),
+ "linear", CMYKA_to_cmyka,
+ NULL
+ );
+
+
+
+#if 0
+
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ babl_model ("camayakaA"),
+ "linear", rgba_to_cmykA,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("camayakaA"),
+ babl_model ("RGBA"),
+ "linear", cmykA_to_rgba,
+ NULL
+ );
+
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ babl_model ("cmykA"),
+ "linear", rgba_to_cmyka,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("cmykA"),
+ babl_model ("RGBA"),
+ "linear", cmyka_to_rgba,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ babl_model ("cmyk"),
+ "linear", rgba_to_cmyk,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("cmyk"),
+ babl_model ("RGBA"),
+ "linear", cmyk_to_rgba,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ babl_model ("cmy"),
+ "linear", rgba_to_cmy,
+ NULL
+ );
+ babl_conversion_new (
+ babl_model ("cmy"),
+ babl_model ("RGBA"),
+ "linear", cmy_to_rgba,
+ NULL
+ );
+#endif
+
+ babl_format_new (
+ "name", "camayakaA float",
+ babl_model ("camayakaA"),
+ babl_type ("float"),
+ babl_component ("ca"),
+ babl_component ("ma"),
+ babl_component ("ya"),
+ babl_component ("ka"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmykA float",
+ babl_model ("cmykA"),
+ babl_type ("float"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmyk float",
+ babl_model ("cmyk"),
+ babl_type ("float"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ NULL
+ );
+
+ babl_format_new (
+ "name", "cmyk u8",
+ babl_model ("cmyk"),
+ babl_type ("u8"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmykA u8",
+ babl_model ("cmykA"),
+ babl_type ("u8"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ babl_component ("A"),
+ NULL
+ );
+
+ babl_format_new (
+ "name", "cmyk u16",
+ babl_model ("cmyk"),
+ babl_type ("u16"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmykA u16",
+ babl_model ("cmykA"),
+ babl_type ("u16"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmyk u32",
+ babl_model ("cmyk"),
+ babl_type ("u32"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmykA u32",
+ babl_model ("cmykA"),
+ babl_type ("u32"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ babl_component ("A"),
+ NULL
+ );
+
+ babl_format_new (
+ "name", "cmyk float",
+ babl_model ("cmyk"),
+ babl_type ("float"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "cmykA float",
+ babl_model ("cmykA"),
+ babl_type ("float"),
+ babl_component ("cyan"),
+ babl_component ("magenta"),
+ babl_component ("yellow"),
+ babl_component ("key"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "camayakaA u16",
+ babl_model ("camayakaA"),
+ babl_type ("u16"),
+ babl_component ("ca"),
+ babl_component ("ma"),
+ babl_component ("ya"),
+ babl_component ("ka"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "camayakaA half",
+ babl_model ("camayakaA"),
+ babl_type ("half"),
+ babl_component ("ca"),
+ babl_component ("ma"),
+ babl_component ("ya"),
+ babl_component ("ka"),
+ babl_component ("A"),
+ NULL
+ );
+
+ /********************************/
+ babl_format_new (
+ "name", "CaMaYaKaA float",
+ babl_model ("CaMaYaKaA"),
+ babl_type ("float"),
+ babl_component ("Ca"),
+ babl_component ("Ma"),
+ babl_component ("Ya"),
+ babl_component ("Ka"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYKA float",
+ babl_model ("CMYKA"),
+ babl_type ("float"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYK float",
+ babl_model ("CMYK"),
+ babl_type ("float"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ NULL
+ );
+
+ babl_format_new (
+ "name", "CMYK u8",
+ babl_model ("CMYK"),
+ babl_type ("u8"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYKA u8",
+ babl_model ("CMYKA"),
+ babl_type ("u8"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ babl_component ("A"),
+ NULL
+ );
+
+ babl_format_new (
+ "name", "CMYK u16",
+ babl_model ("CMYK"),
+ babl_type ("u16"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYKA u16",
+ babl_model ("CMYKA"),
+ babl_type ("u16"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYK u32",
+ babl_model ("CMYK"),
+ babl_type ("u32"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYKA u32",
+ babl_model ("CMYKA"),
+ babl_type ("u32"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ babl_component ("A"),
+ NULL
+ );
+
+ babl_format_new (
+ "name", "CMYK float",
+ babl_model ("CMYK"),
+ babl_type ("float"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CMYKA float",
+ babl_model ("CMYKA"),
+ babl_type ("float"),
+ babl_component ("Cyan"),
+ babl_component ("Magenta"),
+ babl_component ("Yellow"),
+ babl_component ("Key"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CaMaYaKaA u16",
+ babl_model ("CaMaYaKaA"),
+ babl_type ("u16"),
+ babl_component ("Ca"),
+ babl_component ("Ma"),
+ babl_component ("Yea"),
+ babl_component ("Ka"),
+ babl_component ("A"),
+ NULL
+ );
+ babl_format_new (
+ "name", "CaMaYaKaA half",
+ babl_model ("CaMaYaKaA"),
+ babl_type ("half"),
+ babl_component ("Ca"),
+ babl_component ("Ma"),
+ babl_component ("Yea"),
+ babl_component ("Ka"),
+ babl_component ("A"),
+ NULL
+ );
+}
+
diff --git a/export-symbols b/export-symbols
index 476238e..89a24e9 100644
--- a/export-symbols
+++ b/export-symbols
@@ -51,6 +51,7 @@ babl_space_to_xyz
babl_space_from_xyz
babl_space_to_icc
babl_space_with_trc
+babl_space_is_cmyk
babl_icc_make_space
babl_icc_get_key
babl_ticks
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index a066e8d..50e2a8e 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -54,6 +54,7 @@ gggl_table_la_SOURCES = gggl-table.c
gggl_la_SOURCES = gggl.c
gimp_8bit_la_SOURCES = gimp-8bit.c
grey_la_SOURCES = grey.c
+CMYK_la_SOURCES = CMYK.c
naive_CMYK_la_SOURCES = naive-CMYK.c
HCY_la_SOURCES = HCY.c
HSL_la_SOURCES = HSL.c
diff --git a/extensions/naive-CMYK.c b/extensions/naive-CMYK.c
index 3b7a70c..a8a874a 100644
--- a/extensions/naive-CMYK.c
+++ b/extensions/naive-CMYK.c
@@ -1,5 +1,5 @@
/* babl - dynamically extendable universal pixel conversion library.
- * Copyright (C) 2005, Øyvind Kolås.
+ * Copyright (C) 2005, 2018 Øyvind Kolås.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -14,6 +14,9 @@
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see
* <https://www.gnu.org/licenses/>.
+ *
+ * this is an interim file, to keep babl from complaining about double
+ * registration of cmyk formats.
*/
#include "config.h"
@@ -23,248 +26,12 @@
#include "babl.h"
#include "base/util.h"
-
-static void rgba_to_cmyk (const Babl *conversion,char *src,
- char *dst,
- long n);
-
-static void cmyk_to_rgba (const Babl *conversion,char *src,
- char *dst,
- long n);
-
-static void rgba_to_cmy (const Babl *conversion,char *src,
- char *dst,
- long n);
-
-static void cmy_to_rgba (const Babl *conversion,char *src,
- char *dst,
- long n);
-
int init (void);
int
init (void)
{
- babl_component_new ("cyan", NULL);
- babl_component_new ("yellow", NULL);
- babl_component_new ("magenta", NULL);
- babl_component_new ("key", NULL);
-
- babl_model_new (
- "name", "CMYK",
- babl_component ("cyan"),
- babl_component ("magenta"),
- babl_component ("yellow"),
- babl_component ("key"),
- NULL
- );
- babl_model_new (
- "name", "CMY",
- babl_component ("cyan"),
- babl_component ("magenta"),
- babl_component ("yellow"),
- NULL
- );
-
- babl_conversion_new (
- babl_model ("RGBA"),
- babl_model ("CMYK"),
- "linear", rgba_to_cmyk,
- NULL
- );
- babl_conversion_new (
- babl_model ("CMYK"),
- babl_model ("RGBA"),
- "linear", cmyk_to_rgba,
- NULL
- );
- babl_conversion_new (
- babl_model ("RGBA"),
- babl_model ("CMY"),
- "linear", rgba_to_cmy,
- NULL
- );
- babl_conversion_new (
- babl_model ("CMY"),
- babl_model ("RGBA"),
- "linear", cmy_to_rgba,
- NULL
- );
-
- babl_format_new (
- "name", "CMYK float",
- babl_model ("CMYK"),
- babl_type ("float"),
- babl_component ("cyan"),
- babl_component ("magenta"),
- babl_component ("yellow"),
- babl_component ("key"),
- NULL
- );
- babl_format_new (
- "name", "CMY float",
- babl_model ("CMY"),
- babl_type ("float"),
- babl_component ("cyan"),
- babl_component ("magenta"),
- babl_component ("yellow"),
- NULL
- );
-
- babl_format_new (
- "name", "CMYK u8",
- babl_model ("CMYK"),
- babl_type ("u8"),
- babl_component ("cyan"),
- babl_component ("magenta"),
- babl_component ("yellow"),
- babl_component ("key"),
- NULL
- );
-
+ /* do nothing, drop this whole file after a couple of releases */
return 0;
}
-
-static void
-rgba_to_cmyk (const Babl *conversion,char *src,
- char *dst,
- long n)
-{
- while (n--)
- {
- double red = linear_to_gamma_2_2 (((double *) src)[0]);
- double green = linear_to_gamma_2_2 (((double *) src)[1]);
- double blue = linear_to_gamma_2_2 (((double *) src)[2]);
-
- double cyan, magenta, yellow, key;
-
- double pullout = 1.0;
-
- cyan = 1.0 - red;
- magenta = 1.0 - green;
- yellow = 1.0 - blue;
-
- key = 1.0;
- if (cyan < key) key = cyan;
- if (magenta < key) key = magenta;
- if (yellow < key) key = yellow;
-
- key *= pullout;
-
- if (key < 1.0)
- {
- cyan = (cyan - key) / (1.0 - key);
- magenta = (magenta - key) / (1.0 - key);
- yellow = (yellow - key) / (1.0 - key);
- }
- else
- {
- cyan = 0.0;
- magenta = 0.0;
- yellow = 0.0;
- }
-
- ((double *) dst)[0] = cyan;
- ((double *) dst)[1] = magenta;
- ((double *) dst)[2] = yellow;
- ((double *) dst)[3] = key;
-
- src += 4 * sizeof (double);
- dst += 4 * sizeof (double);
- }
-}
-
-static void
-cmyk_to_rgba (const Babl *conversion,char *src,
- char *dst,
- long n)
-{
- while (n--)
- {
- double cyan = ((double *) src)[0];
- double magenta = ((double *) src)[1];
- double yellow = ((double *) src)[2];
- double key = ((double *) src)[3];
-
- double red, green, blue;
-
- if (key < 1.0)
- {
- cyan = cyan * (1.0 - key) + key;
- magenta = magenta * (1.0 - key) + key;
- yellow = yellow * (1.0 - key) + key;
- }
- else
- {
- cyan = magenta = yellow = 1.0;
- }
-
- red = 1.0 - cyan;
- green = 1.0 - magenta;
- blue = 1.0 - yellow;
-
- ((double *) dst)[0] = gamma_2_2_to_linear (red);
- ((double *) dst)[1] = gamma_2_2_to_linear (green);
- ((double *) dst)[2] = gamma_2_2_to_linear (blue);
-
- ((double *) dst)[3] = 1.0;
-
- src += 4 * sizeof (double);
- dst += 4 * sizeof (double);
- }
-}
-
-static void
-rgba_to_cmy (const Babl *conversion,char *src,
- char *dst,
- long n)
-{
- while (n--)
- {
- double red = linear_to_gamma_2_2 (((double *) src)[0]);
- double green = linear_to_gamma_2_2 (((double *) src)[1]);
- double blue = linear_to_gamma_2_2 (((double *) src)[2]);
-
- double cyan, magenta, yellow;
-
- cyan = 1.0 - red;
- magenta = 1.0 - green;
- yellow = 1.0 - blue;
-
- ((double *) dst)[0] = cyan;
- ((double *) dst)[1] = magenta;
- ((double *) dst)[2] = yellow;
-
- src += 4 * sizeof (double);
- dst += 3 * sizeof (double);
- }
-}
-
-static void
-cmy_to_rgba (const Babl *conversion,char *src,
- char *dst,
- long n)
-{
- while (n--)
- {
- double cyan = ((double *) src)[0];
- double magenta = ((double *) src)[1];
- double yellow = ((double *) src)[2];
-
- double red, green, blue;
-
- red = 1.0 - cyan;
- green = 1.0 - magenta;
- blue = 1.0 - yellow;
-
- ((double *) dst)[0] = gamma_2_2_to_linear (red);
- ((double *) dst)[1] = gamma_2_2_to_linear (green);
- ((double *) dst)[2] = gamma_2_2_to_linear (blue);
-
- ((double *) dst)[3] = 1.0;
-
- src += 3 * sizeof (double);
- dst += 4 * sizeof (double);
- }
-}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]