[babl/wip/pippin/inverted-cmyk: 8/9] lcms / icc integration for cmyk



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]