[babl/wip/pippin/inverted-cmyk: 8/9] lcms / icc integration for cmyk
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl/wip/pippin/inverted-cmyk: 8/9] lcms / icc integration for cmyk
- Date: Tue, 6 Nov 2018 13:36:23 +0000 (UTC)
commit 085345f742485989e1fff0d94c509bbf5ec56440
Author: Øyvind Kolås <pippin gimp org>
Date: Sat Nov 3 13:46:20 2018 +0100
lcms / icc integration for cmyk
babl/babl-fish-reference.c | 304 +++++++++++++++++++++++++++++++++++++++++++++
babl/babl-fish.c | 50 ++++----
babl/babl-icc.c | 29 ++++-
babl/babl-space.c | 16 ++-
4 files changed, 362 insertions(+), 37 deletions(-)
---
diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c
index 6d1aa84..8b7adc1 100644
--- a/babl/babl-fish-reference.c
+++ b/babl/babl-fish-reference.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "babl-internal.h"
+#include "lcms2.h"
static Babl *
assert_conversion_find (const void *source,
@@ -700,11 +701,18 @@ babl_fish_reference_process_double (const Babl *babl,
{
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);
@@ -733,6 +741,97 @@ babl_fish_reference_process_double (const Babl *babl,
);
}
+/******************************************************************************************/
+// is it cmyky now and goes to an rgb format - we first get to cmyk double, then convert to rgba
+// is it cmyky now and goes to a cmyky format .. then go to cmyka float and convert
to proper cmyky
+// is it rgb or grayish now and goes to a cmyky format, then go to rgba, convert to cmyka float and convert
to proper cmyky
+// if it is rgbish now and goes to rgbish do rgbish chain
+
+
+ if (babl->fish.source->format.space->space.lcms_profile &&
+ babl->fish.destination->format.space->space.lcms_profile)
+ {
+ if (babl->fish.source->format.space == babl->fish.destination->format.space)
+ {
+ /* both source format and target is same CMYK
+ do manual work rejuggling format and components
+ */
+ }
+ else
+ {
+ /* do manual rejuggling first to CMYK float, use lcms to CMYK float
+ then continue manual juggling.
+ */
+ }
+ }
+ else if (babl->fish.source->format.space->space.lcms_profile)
+ {
+ /* only the source format is CMYK, we need to first get it to floating point,
+ use lcms to get to RGBA float,
+ then recurse a manual conversion from RGBA float to actual destination */
+ if (babl_model_is ((void*)babl->fish.source->format.model, "cmykA"))
+ {
+ cmyka_double_buf = source_double_buf;
+ cmyka_image = babl_image_from_linear (
+ cmyka_double_buf,
+ (void*)babl->fish.source->format.model);
+ }
+ else
+ {
+ 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_alloc = babl_malloc (sizeof (double) * n * 5);
+ cmyka_double_buf = cmyka_double_buf_alloc;
+
+ 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");
+
+ }
+
+ /* we now have right data in cmyk_double_buf */
+
+ /* */
+
+ rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
+ rgba_double_buf = rgba_double_buf_alloc;
+ }
+ else if (babl->fish.destination->format.space->space.lcms_profile)
+ {
+ /* only the destination format is CMYK
+
+ we need to convert to RGBA float,
+ invoke lcms2 to get to CMYK float ..
+ then do type conversion and
+ component juggling.
+ */
+ }
+ else
+ {
+
+
+
if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA"))
{
rgba_double_buf = source_double_buf;
@@ -773,6 +872,8 @@ babl_fish_reference_process_double (const Babl *babl,
else babl_fatal ("oops");
}
+ /* color space conversions */
+
if (((babl->fish.source)->format.space !=
((babl->fish.destination)->format.space)))
{
@@ -786,6 +887,8 @@ babl_fish_reference_process_double (const Babl *babl,
babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n);
}
+
+ /* convert from right double float to target model double rgbish */
{
const Babl *destination_rgba_format =
babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
@@ -826,7 +929,12 @@ babl_fish_reference_process_double (const Babl *babl,
else babl_fatal ("oops");
}
}
+/***********************************************************************************************/
+ }
+
+
+ /* convert from double model backing target pixel format to final representation */
convert_from_double (
(BablFormat *) BABL (babl->fish.destination),
destination_double_buf,
@@ -838,12 +946,16 @@ babl_fish_reference_process_double (const Babl *babl,
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);
}
@@ -870,6 +982,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));
@@ -1030,6 +1143,191 @@ babl_fish_reference_process_float (const Babl *babl,
babl_free (destination_image);
}
+#if 0
+static void
+babl_fish_reference_process_cmyk (const Babl *babl,
+ const char *source,
+ char *destination,
+ long n,
+ void *data)
+{
+ 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 *cmyka_double_buf_alloc = NULL;
+ void *cmyka_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);
+
+ {
+ 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, "cmykA"))
+ {
+ cmyka_double_buf = source_double_buf;
+ cmyka_image = babl_image_from_linear (
+ cmyka_double_buf,
+ (void*)babl->fish.source->format.model);
+ rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
+ rgba_double_buf = rgba_double_buf_alloc;
+ }
+ else
+ {
+ 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_alloc = babl_malloc (sizeof (double) * n * 5);
+ cmyka_double_buf = cmyka_double_buf_alloc;
+ rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
+ rgba_double_buf = rgba_double_buf_alloc;
+
+ cmyka_image = babl_image_from_linear (
+ rgba_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");
+ }
+
+ if (((babl->fish.source)->format.space !=
+ ((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->fish.source)->format.space->space.RGBtoXYZ,
+ matrix);
+
+ babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n);
+ }
+
+ {
+ const Babl *destination_rgba_format =
+ babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
+ BABL (BABL ((babl->fish.destination))->format.space));
+
+ 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");
+ }
+ }
+
+ 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 (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);
+ fprintf (stderr, "%s:%s:NYI %s to %s....\n", __FILE__, __FUNCTION__, babl_get_name(babl->fish.source),
+ babl_get_name(babl->fish.destination));
+}
+
+static void
+babl_fish_reference_process_cmyk_src (const Babl *babl,
+ const char *source,
+ char *destination,
+ long n,
+ void *data)
+{
+ fprintf (stderr, "%s:%s:NYI %s to %s....\n", __FILE__, __FUNCTION__, babl_get_name(babl->fish.source),
+ babl_get_name(babl->fish.destination));
+ babl_fish_reference_process_cmyk (babl, source, destination, n, data);
+}
+
+static void
+babl_fish_reference_process_cmyk_dst (const Babl *babl,
+ const char *source,
+ char *destination,
+ long n,
+ void *data)
+{
+ fprintf (stderr, "%s:%s:NYI %s to %s....\n", __FILE__, __FUNCTION__, babl_get_name(babl->fish.source),
+ babl_get_name(babl->fish.destination));
+ babl_fish_reference_process_cmyk (babl, source, destination, n, data);
+}
+#endif
+
void
babl_fish_reference_process (const Babl *babl,
const char *source,
@@ -1070,6 +1368,12 @@ babl_fish_reference_process (const Babl *babl,
return;
}
+ if (babl->fish.source->format.space->space.lcms_profile ||
+ babl->fish.destination->format.space->space.lcms_profile
+ )
+ {
+ }
+
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 65c482e..9c8930f 100644
--- a/babl/babl-fish.c
+++ b/babl/babl-fish.c
@@ -264,33 +264,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.lcms_profile == 0 &&
+ dst_space->space.lcms_profile == 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 9f4fe80..1ef8ad5 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -720,6 +720,8 @@ static char *decode_string (ICC *state, const char *tag, const char *lang, const
return NULL;
}
+static cmsHPROFILE sRGBProfile = 0;
+
const Babl *
babl_space_from_icc (const char *icc_data,
int icc_length,
@@ -839,15 +841,30 @@ babl_space_from_icc (const char *icc_data,
ret->space.icc_profile = malloc (icc_length);
memcpy (ret->space.icc_profile, icc_data, icc_length);
+ if (sRGBProfile == 0)
+ {
+ const Babl *srgb = babl_space("sRGB"); /* should use a forced linear profile */
+ sRGBProfile = cmsOpenProfileFromMem(srgb->space.icc_profile, srgb->space.icc_length);
+ }
+
ret->space.lcms_profile = cmsOpenProfileFromMem(ret->space.icc_profile, ret->space.icc_length);
//ret->lcms_profile_rgb = cmsOpenProfileFromMem(ret->space.icc_profile, ret->space.icc_length);
- ret->space.lcms_to_rgba = cmsCreateTransform(ret->space.lcms_profile, TYPE_RGBA_FLT,
- ret->space.lcms_profile, TYPE_RGBA_FLT,
- intent & 7, 0);
- ret->space.lcms_from_rgba = cmsCreateTransform(ret->space.lcms_profile, TYPE_RGBA_FLT,
- ret->space.lcms_profile, TYPE_RGBA_FLT,
- intent & 7, 0);
+/* these are not defined by lcms2.h we hope that following the existing pattern of pixel-format definitions
work */
+#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
+#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
+
+
+ ret->space.lcms_to_rgba = cmsCreateTransform(ret->space.lcms_profile, TYPE_CMYKA_DBL,
+ sRGBProfile, TYPE_RGBA_DBL,
+ intent & 7, 0);
+ ret->space.lcms_from_rgba = cmsCreateTransform(sRGBProfile, TYPE_RGB_DBL,
+ ret->space.lcms_profile, TYPE_CMYKA_DBL,
+ intent & 7, 0);
cmsCloseProfile (ret->space.lcms_profile);
fprintf (stderr, "did a rig\n");
diff --git a/babl/babl-space.c b/babl/babl-space.c
index b4ff1d9..025ab50 100644
--- a/babl/babl-space.c
+++ b/babl/babl-space.c
@@ -229,16 +229,12 @@ _babl_space_for_lcms (const char *icc_data, int icc_length)
for (i = 0; space_db[i].instance.class_type; i++)
{
- // XXX adjust to use profile directly
-#if 0
- int offset = ((char*)&space_db[i].xr) - (char*)(&space_db[i]);
- int size = ((char*)&space_db[i].trc) + sizeof(space_db[i].trc) - ((char*)&space_db[i].xr);
-
- if (memcmp ((char*)(&space_db[i]) + offset, ((char*)&space) + offset, size)==0)
- {
+ if (space_db[i].icc_length ==
+ icc_length &&
+ (memcmp (space_db[i].icc_profile, icc_data, icc_length) == 0))
+ {
return (void*)&space_db[i];
- }
-#endif
+ }
}
if (i >= MAX_SPACES-1)
{
@@ -344,6 +340,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];
}
@@ -407,6 +404,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];
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]