[babl] babl: on demand clone sRGB conversions



commit dea8d7a3007bd4f7fb69d1cf1bb2b9657ab2bcb1
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Aug 29 11:51:17 2017 +0200

    babl: on demand clone sRGB conversions
    
    When a new RGB space is encountered clone all sRGB space to sRGB space
    conversions, under the assumption that they are implemented respecting/using
    the customizable TRCs of babl.

 babl/babl-conversion.c |   39 +++++++----
 babl/babl-fish-path.c  |  187 +++++++++++++++++++++++++++++++++++++++++++-----
 babl/babl-fish.c       |    8 ++-
 babl/babl-format.c     |    7 ++-
 babl/babl-internal.h   |    7 ++
 babl/babl-list.c       |    2 +-
 6 files changed, 213 insertions(+), 37 deletions(-)
---
diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c
index 3968504..14567e1 100644
--- a/babl/babl-conversion.c
+++ b/babl/babl-conversion.c
@@ -177,6 +177,29 @@ create_name (Babl *source, Babl *destination, int type)
     }
   return buf;
 }
+const char *
+babl_conversion_create_name (Babl *source, Babl *destination, int type);
+
+const char *
+babl_conversion_create_name (Babl *source, Babl *destination, int type)
+{
+  Babl *babl;
+  char *name;
+  int id = 0;
+  collisions = 0;
+  name = create_name (source, destination, type);
+  babl = babl_db_exist (db, id, name);
+  while (babl)
+    {
+      /* we allow multiple conversions to be registered per extender, each
+         of them ending up with their own unique name
+       */
+      collisions++;
+      name = create_name (source, destination, type);
+      babl = babl_db_exist (db, id, name);
+    }
+  return name;
+}
 
 const Babl *
 babl_conversion_new (const void *first_arg,
@@ -273,19 +296,7 @@ babl_conversion_new (const void *first_arg,
       type = BABL_CONVERSION_PLANAR;
     }
 
-  collisions = 0;
-  name = create_name (source, destination, type);
-
-  babl = babl_db_exist (db, id, name);
-  while (babl)
-    {
-      /* we allow multiple conversions to be registered per extender, each
-         of them ending up with their own unique name
-       */
-      collisions++;
-      name = create_name (source, destination, type);
-      babl = babl_db_exist (db, id, name);
-    }
+  name = (void*) babl_conversion_create_name (source, destination, type);
 
   babl = _conversion_new (name, id, source, destination, linear, plane, planar,
                          user_data);
@@ -505,7 +516,7 @@ babl_conversion_error (BablConversion *conversion)
         fmt_source->class_type == BABL_FORMAT &&
         fmt_destination->class_type == BABL_FORMAT))
     {
-      conversion->error = 0.000042;
+      conversion->error = 0.0000042;
     }
 
   source                      = babl_calloc (test_pixels, fmt_source->format.bytes_per_pixel);
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index 60b2fbe..df5f3e6 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -202,7 +202,7 @@ get_conversion_path (PathContext *pc,
 
           get_path_instrumentation (&fpi, pc->current_path, &path_cost, &ref_cost, &path_error);
           if(debug_conversions && current_length == 1)
-            fprintf (stderr, "%s  error:%f cost:%f  \n", 
+            fprintf (stderr, "%s  error:%f cost:%f  \n",
                  babl_get_name (pc->current_path->items[0]),
                  /*babl_get_name (pc->fish_path->fish.source),
                  babl_get_name (pc->fish_path->fish.destination),*/
@@ -227,7 +227,7 @@ get_conversion_path (PathContext *pc,
   else
     {
       /*
-       * Bummer, we have to search deeper... 
+       * we have to search deeper...
        */
       BablList *list;
       int i;
@@ -265,8 +265,8 @@ _babl_fish_create_name (char       *buf,
                         int         is_reference)
 {
   /* fish names are intentionally kept short */
-  snprintf (buf, BABL_MAX_NAME_LEN, "%s %p %p", "",
-            source, destination);
+  snprintf (buf, BABL_MAX_NAME_LEN, "%s %p %p %i", "",
+            source, destination, is_reference);
   return buf;
 }
 
@@ -283,11 +283,143 @@ _babl_fish_path_destroy (void *data)
   return 0;
 }
 
+BablList *accum = NULL;
+
+static int
+show_item (Babl *babl,
+           void *user_data)
+{
+  BablConversion *conv = (void *)babl;
+  //BablSpace *space = user_data;
+
+  if (conv->destination->class_type == BABL_FORMAT)
+  {
+    fprintf (stderr, "%s : %.9f\n", babl_get_name (babl), babl_conversion_error(conv));
+  }
+
+  return 0;
+}
+
+
+static int
+show_fmt (Babl *babl,
+          void *user_data)
+{
+  BablConversion *conv = (void *)babl;
+
+  fprintf (stderr, "[[%s\n", babl_get_name (babl));
+
+  return 0;
+}
+
+
+static int
+alias_conversion (Babl *babl,
+                  void *user_data)
+{
+  BablConversion *conv = (void *)babl;
+  BablSpace *space = user_data;
+
+  if ((conv->source->class_type == BABL_FORMAT) &&
+      (conv->destination->class_type == BABL_FORMAT))
+  {
+    if ((conv->source->format.space == (void*)babl_space ("sRGB")) &&
+        (conv->destination->format.space == babl_space ("sRGB")))
+  {
+    Babl *foo;
+    switch (conv->instance.class_type)
+    {
+      case BABL_CONVERSION_LINEAR:
+       foo= babl_conversion_new (
+              babl_format_with_space (
+                    (void*)conv->source->instance.name, (void*)space),
+              babl_format_with_space (
+                    (void*)conv->destination->instance.name, (void*)space),
+              "linear", conv->function.linear,
+              "data", conv->data,
+              NULL);
+        break;
+      case BABL_CONVERSION_PLANAR:
+       foo= babl_conversion_new (
+              babl_format_with_space (
+                    (void*)conv->source->instance.name, (void*)space),
+              babl_format_with_space (
+                    (void*)conv->destination->instance.name, (void*)space),
+              "planar", conv->function.planar,
+              "data", conv->data,
+              NULL);
+        break;
+      case BABL_CONVERSION_PLANE:
+        babl_conversion_new (
+              babl_format_with_space (
+                    (void*)conv->source->instance.name, (void*)space),
+              babl_format_with_space (
+                    (void*)conv->destination->instance.name, (void*)space),
+              "plane", conv->function.plane,
+              "data", conv->data,
+              NULL);
+        break;
+      default:
+        break;
+    }
+    if(0)fprintf (stderr, "{%s}\n", babl_get_name (foo));
+  }
+  }
+  else
+  if ((conv->source->class_type == BABL_MODEL) &&
+      (conv->destination->class_type == BABL_MODEL))
+  {
+    if ((conv->source->model.space == (void*)babl_space ("sRGB")) &&
+        (conv->destination->model.space == babl_space ("sRGB")))
+  {
+    switch (conv->instance.class_type)
+    {
+      case BABL_CONVERSION_LINEAR:
+        babl_conversion_new (
+              babl_remodel_with_space (
+                    (void*)conv->source, (void*)space),
+              babl_remodel_with_space (
+                    (void*)conv->destination, (void*)space),
+              "linear", conv->function,
+              NULL);
+        break;
+      case BABL_CONVERSION_PLANAR:
+        babl_conversion_new (
+              babl_remodel_with_space (
+                    (void*)conv->source, (void*)space),
+              babl_remodel_with_space (
+                    (void*)conv->destination, (void*)space),
+              "planar", conv->function,
+              NULL);
+        break;
+      case BABL_CONVERSION_PLANE:
+        babl_conversion_new (
+              babl_remodel_with_space (
+                    (void*)conv->source, (void*)space),
+              babl_remodel_with_space (
+                    (void*)conv->destination, (void*)space),
+              "plane", conv->function,
+              NULL);
+        break;
+      default:
+        break;
+    }
+  }
+  }
+  else
+  if ((conv->source->class_type == BABL_TYPE) &&
+      (conv->destination->class_type == BABL_TYPE))
+  {
+  }
+  return 0;
+}
+
 Babl *
 babl_fish_path (const Babl *source,
                 const Babl *destination)
 {
   Babl *babl = NULL;
+  const Babl *sRGB = babl_space ("sRGB");
   char name[BABL_MAX_NAME_LEN];
 
   _babl_fish_create_name (name, source, destination, 1);
@@ -302,6 +434,39 @@ babl_fish_path (const Babl *source,
       return babl;
     }
 
+  if ((source->format.space != sRGB) ||
+      (destination->format.space != sRGB))
+  {
+    static const Babl *run_once[512]={NULL};
+    int i;
+    int done = 0;
+    for (i = 0; run_once[i]; i++)
+    {
+      if (run_once[i] == source->format.space)
+        done |= 1;
+      else if (run_once[i] == destination->format.space)
+        done |= 2;
+    }
+
+    if ((done & 1) == 0 && (source->format.space != sRGB))
+    {
+      run_once[i++] = source->format.space;
+      babl_conversion_class_for_each (alias_conversion, (void*)source->format.space);
+    }
+    if ((done & 2) == 0 && (destination->format.space != source->format.space) && (destination->format.space 
!= sRGB))
+    {
+      run_once[i++] = destination->format.space;
+      babl_conversion_class_for_each (alias_conversion, (void*)destination->format.space);
+    }
+
+    if (!done)
+    {
+      //babl_conversion_class_for_each (show_item, (void*)source->format.space);
+      //babl_format_class_for_each (show_fmt, NULL);
+      //babl_model_class_for_each (show_fmt, NULL);
+    }
+  }
+
   babl = babl_calloc (1, sizeof (BablFishPath) +
                       strlen (name) + 1);
   babl_set_destructor (babl, _babl_fish_path_destroy);
@@ -543,9 +708,6 @@ process_conversion_path (BablList   *path,
           temp_buffer2 = align_16 (alloca (MIN(n, MAX_BUFFER_SIZE) * sizeof (double) * 5 + 16));
         }
 
-
-
-
       for (j = 0; j < n; j+= MAX_BUFFER_SIZE)
         {
           long c = MIN (n - j, MAX_BUFFER_SIZE);
@@ -602,6 +764,7 @@ init_path_instrumentation (FishPathInstrumentation *fpi,
     {
       fpi->fmt_rgba_double = babl_format_new (
         babl_model ("RGBA"),
+        babl_space ("sRGB"),
         babl_type ("double"),
         babl_component ("R"),
         babl_component ("G"),
@@ -727,15 +890,5 @@ get_path_instrumentation (FishPathInstrumentation *fpi,
                                     fpi->ref_destination_rgba_double,
                                      fpi->num_test_pixels * 4);
 
-#if 0
-  fpi->fish_rgba_to_source->fish.processings--;
-  fpi->fish_reference->fish.processings--;
-  fpi->fish_destination_to_rgba->fish.processings -= 2;
-
-  fpi->fish_rgba_to_source->fish.pixels      -= fpi->num_test_pixels;
-  fpi->fish_reference->fish.pixels           -= fpi->num_test_pixels;
-  fpi->fish_destination_to_rgba->fish.pixels -= 2 * fpi->num_test_pixels;
-#endif
-
   *ref_cost = fpi->reference_cost;
 }
diff --git a/babl/babl-fish.c b/babl/babl-fish.c
index 4cc4924..587c549 100644
--- a/babl/babl-fish.c
+++ b/babl/babl-fish.c
@@ -169,9 +169,9 @@ babl_fish_get_id (const Babl *source,
   /* value of 'id' will be used as argument for hash function,
    * substraction serves as simple combination of
    * source/destination values. */
-  ptrdiff_t id = source - destination;
+  int id = (((int)source * 93)) ^ ((int)destination);
   /* instances with id 0 won't be inserted into database */
-  id *= ((((size_t)  (source))) % 37);
+  id *= ((((size_t)  (destination))) % 37);
 
   if (id == 0)
     id = 1;
@@ -254,12 +254,12 @@ babl_fish (const void *source,
          * path.
          */
         babl_hash_table_find (id_htable, hashval, find_fish_path, (void *) &ffish);
-
         if (ffish.fish_path)
           {
             /* we have found suitable fish path in the database */
             return ffish.fish_path;
           }
+
         if (!ffish.fish_fish)
           {
             /* we haven't tried to search for suitable path yet */
@@ -269,6 +269,7 @@ babl_fish (const void *source,
               {
                 return fish_path;
               }
+#if 1
             else
               {
                 /* there isn't a suitable path for requested formats,
@@ -287,6 +288,7 @@ babl_fish (const void *source,
                 fish->fish.destination          = destination_format;
                 babl_db_insert (babl_fish_db (), fish);
               }
+#endif
           }
       }
 
diff --git a/babl/babl-format.c b/babl/babl-format.c
index 0afba64..ebf51db 100644
--- a/babl/babl-format.c
+++ b/babl/babl-format.c
@@ -130,13 +130,16 @@ format_new (const char      *name,
   return babl;
 }
 
-static Babl *
+Babl *
 format_new_from_format_with_space (const Babl *format, const Babl *space)
 {
   Babl *ret;
   char new_name[256];
   sprintf (new_name, "%s-%s", babl_get_name ((void*)format),
                               babl_get_name ((void*)space));
+  ret = babl_db_find (babl_format_db(), new_name);
+  if (ret)
+    return ret;
 
   ret = format_new (new_name,
                     0,
@@ -726,7 +729,7 @@ babl_format_with_space (const char *name, const Babl *space)
 
   {
     char *new_name = babl_malloc (strlen (name) +
-                                  strlen (babl_get_name ((Babl*)space)) + 1);
+                                  strlen (babl_get_name ((Babl*)space)) + 2);
     sprintf (new_name, "%s-%s", name, babl_get_name ((Babl*)space));
 
     ret = babl_db_exist_by_name (db, new_name);
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index e50fd91..b5a7532 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -389,5 +389,12 @@ const Babl *babl_space_from_icc (const char *icc,
 const Babl *babl_trc_lut_find (float *lut, int lut_size);
 const Babl * babl_trc_lut   (const char *name, int n, float *entries);
 
+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);
 
 #endif
diff --git a/babl/babl-list.c b/babl/babl-list.c
index 49647bb..beb7b61 100644
--- a/babl/babl-list.c
+++ b/babl/babl-list.c
@@ -31,7 +31,7 @@ babl_list_init (void)
   return babl_list_init_with_size (BABL_LIST_INITIAL_SIZE);
 }
 
-static int
+int
 babl_list_destroy (void *data)
 {
   BablList *list = data;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]