[gegl] gegl: add gegl_babl_variant



commit 326b0c865a00514cdd886542c8f3d602de1b1987
Author: Øyvind Kolås <pippin gimp org>
Date:   Wed Oct 31 18:37:43 2018 +0100

    gegl: add gegl_babl_variant
    
    This function returns a babl format derived from the passed in format,
    based on which variant is requested it will at least be floating point
    and possibly also premultiplied forced, the enum/bitflags available
    as an argument is a work in progress.

 gegl/gegl-enums.c |  30 ++++++
 gegl/gegl-enums.h |  26 +++++
 gegl/gegl-utils.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gegl/gegl-utils.h |   2 +
 4 files changed, 354 insertions(+)
---
diff --git a/gegl/gegl-enums.c b/gegl/gegl-enums.c
index a9a219534..d75e2f294 100644
--- a/gegl/gegl-enums.c
+++ b/gegl/gegl-enums.c
@@ -107,3 +107,33 @@ gegl_orientation_get_type (void)
   return etype;
 }
 
+GType
+gegl_babl_variant_get_type (void)
+{
+  static GType etype = 0;
+
+  if (etype == 0)
+    {
+      static GEnumValue values[] = {
+        { GEGL_BABL_VARIANT_FLOAT, N_("Float"), "float"},
+        { GEGL_BABL_VARIANT_LINEAR, N_("Linear"), "linear"},
+        { GEGL_BABL_VARIANT_NONLINEAR, N_("Non-linear"), "non-linear"},
+        { GEGL_BABL_VARIANT_PERCEPTUAL, N_("Perceptual"), "perceptual"},
+        { GEGL_BABL_VARIANT_LINEAR_PREMULTIPLIED, N_("Linear-premultiplied"), "linear-premultiplied"},
+        { GEGL_BABL_VARIANT_PERCEPTUAL_PREMULTIPLIED, N_("Perceptual-premultiplied"), 
"perceptual-premultiplied"},
+        { GEGL_BABL_VARIANT_LINEAR_PREMULTIPLIED_IF_ALPHA, N_("Linear-premultiplied-if-alpha"), 
"linear-premultiplied-if-alpha"},
+        { GEGL_BABL_VARIANT_PERCEPTUAL_PREMULTIPLIED_IF_ALPHA, N_("Perceptual-premultiplied-if-alpha"), 
"perceptual-premultiplied-if-alpha"},
+        { 0, NULL, NULL }
+      };
+      gint i;
+
+      for (i = 0; i < G_N_ELEMENTS (values); i++)
+        if (values[i].value_name)
+          values[i].value_name =
+            dgettext (GETTEXT_PACKAGE, values[i].value_name);
+
+      etype = g_enum_register_static ("GeglBablVariant", values);
+    }
+
+  return etype;
+}
diff --git a/gegl/gegl-enums.h b/gegl/gegl-enums.h
index 80ff8c3e5..6a656e5dc 100644
--- a/gegl/gegl-enums.h
+++ b/gegl/gegl-enums.h
@@ -72,6 +72,32 @@ GType gegl_orientation_get_type (void) G_GNUC_CONST;
 
 #define GEGL_TYPE_ORIENTATION (gegl_orientation_get_type ())
 
+
+enum _GeglBablVariant
+{
+  GEGL_BABL_VARIANT_FLOAT=0,
+     /* pass this one to just ensure a format is float */
+  GEGL_BABL_VARIANT_LINEAR,
+     /* Y YA RGB RGBA         */
+  GEGL_BABL_VARIANT_NONLINEAR,
+     /* Y' Y'A R'G'B' R'G'B'A */
+  GEGL_BABL_VARIANT_PERCEPTUAL,
+     /* Y~ Y~A R~G~B~ R~G~B~A */
+  GEGL_BABL_VARIANT_LINEAR_PREMULTIPLIED,
+     /* YaA RaGaBaA           */
+  GEGL_BABL_VARIANT_PERCEPTUAL_PREMULTIPLIED,
+     /* Y~aA R~aG~aB~aA       */
+  GEGL_BABL_VARIANT_LINEAR_PREMULTIPLIED_IF_ALPHA,
+     /* Y YaA RGB RaGaBaA           */
+  GEGL_BABL_VARIANT_PERCEPTUAL_PREMULTIPLIED_IF_ALPHA,
+     /* Y~ Y~aA R~G~B~A R~aG~aB~aA       */
+};
+typedef enum _GeglBablVariant GeglBablVariant;
+
+GType gegl_babl_variant_get_type (void) G_GNUC_CONST;
+
+#define GEGL_TYPE_BABL_VARIANT (gegl_babl_variant_get_type ())
+
 G_END_DECLS
 
 #endif /* __GEGL_ENUMS_H__ */
diff --git a/gegl/gegl-utils.c b/gegl/gegl-utils.c
index 9e241055a..482f0c2b0 100644
--- a/gegl/gegl-utils.c
+++ b/gegl/gegl-utils.c
@@ -42,3 +42,299 @@ gegl_buffer_set_color (GeglBuffer          *dst,
   gegl_buffer_set_color_from_pixel (dst, dst_rect, &pixel[0], format);
 }
 
+
+static const Babl *gegl_babl_format_linear_float (const Babl *format)
+{
+  const Babl *space = babl_format_get_space (format);
+  const Babl *model = NULL;
+  if (!format)
+    return babl_format ("RGBA float");
+
+  model = babl_format_get_model (format);
+
+  if (babl_model_is (model, "Y") ||
+      babl_model_is (model, "Y'") ||
+      babl_model_is (model, "Y~"))
+  {
+    format = babl_format_with_space ("Y float", space);
+  }
+  else if (babl_model_is (model, "YA") ||
+           babl_model_is (model, "Y'A") ||
+           babl_model_is (model, "Y~A") ||
+           babl_model_is (model, "YaA") ||
+           babl_model_is (model, "Y'aA"))
+  {
+    format = babl_format_with_space ("YA float", space);
+  }
+  else if (babl_model_is (model, "RGB") ||
+           babl_model_is (model, "R'G'B'") ||
+           babl_model_is (model, "R~G~B~"))
+  {
+    format = babl_format_with_space ("RGB float", space);
+  }
+#if 0 // just treat as else
+           babl_model_is (model, "RGBA")    ||
+           babl_model_is (model, "R'G'B'A") ||
+           babl_model_is (model, "R'G'B'")  ||
+           babl_model_is (model, "R~G~B~A") ||
+           babl_model_is (model, "R~G~B~")  ||
+           babl_model_is (model, "RaGaBaA") ||
+           babl_model_is (model, "R'aG'aB'aA"))
+  {
+    format  = babl_format_with_space (use_srgb?"R~aG~aB~aA float":"RaGaBaA float", space);
+  }
+#endif
+  else
+  {
+    format  = babl_format_with_space ("RGBA float", space);
+  }
+  return format;
+}
+
+static const Babl *gegl_babl_format_perceptual_float (const Babl *format)
+{
+  const Babl *space = babl_format_get_space (format);
+  const Babl *model = NULL;
+  if (!format)
+    return babl_format ("R~G~B~A float");
+
+  model = babl_format_get_model (format);
+
+  if (babl_model_is (model, "Y") ||
+      babl_model_is (model, "Y'") ||
+      babl_model_is (model, "Y~"))
+  {
+    format = babl_format_with_space ("Y~ float", space);
+  }
+  else if (babl_model_is (model, "YA") ||
+           babl_model_is (model, "Y'A") ||
+           babl_model_is (model, "Y~A") ||
+           babl_model_is (model, "YaA") ||
+           babl_model_is (model, "Y'aA"))
+  {
+    format = babl_format_with_space ("Y~A float", space);
+  }
+  else if (babl_model_is (model, "RGB") ||
+           babl_model_is (model, "R'G'B'") ||
+           babl_model_is (model, "R~G~B~"))
+  {
+    format = babl_format_with_space ("R~G~B~ float", space);
+  }
+#if 0 // just treat as else
+           babl_model_is (model, "RGBA")    ||
+           babl_model_is (model, "R'G'B'A") ||
+           babl_model_is (model, "R'G'B'")  ||
+           babl_model_is (model, "R~G~B~A") ||
+           babl_model_is (model, "R~G~B~")  ||
+           babl_model_is (model, "RaGaBaA") ||
+           babl_model_is (model, "R'aG'aB'aA"))
+  {
+    format  = babl_format_with_space (use_srgb?"R~aG~aB~aA float":"RaGaBaA float", space);
+  }
+#endif
+  else
+  {
+    format  = babl_format_with_space ("R~G~B~A float", space);
+  }
+  return format;
+}
+
+static const Babl *gegl_babl_format_nonlinear_float (const Babl *format)
+{
+  const Babl *space = babl_format_get_space (format);
+  const Babl *model = NULL;
+  if (!format)
+    return babl_format ("R'G'B'A float");
+
+  model = babl_format_get_model (format);
+
+  if (babl_model_is (model, "Y") ||
+      babl_model_is (model, "Y'") ||
+      babl_model_is (model, "Y~"))
+  {
+    format = babl_format_with_space ("Y' float", space);
+  }
+  else if (babl_model_is (model, "YA") ||
+           babl_model_is (model, "Y'A") ||
+           babl_model_is (model, "Y~A") ||
+           babl_model_is (model, "YaA") ||
+           babl_model_is (model, "Y'aA"))
+  {
+    format = babl_format_with_space ("Y'A float", space);
+  }
+  else if (babl_model_is (model, "RGB") ||
+           babl_model_is (model, "R'G'B'") ||
+           babl_model_is (model, "R~G~B~"))
+  {
+    format = babl_format_with_space ("R'G'B' float", space);
+  }
+#if 0 // just treat as else
+           babl_model_is (model, "RGBA")    ||
+           babl_model_is (model, "R'G'B'A") ||
+           babl_model_is (model, "R'G'B'")  ||
+           babl_model_is (model, "R~G~B~A") ||
+           babl_model_is (model, "R~G~B~")  ||
+           babl_model_is (model, "RaGaBaA") ||
+           babl_model_is (model, "R'aG'aB'aA"))
+  {
+    format  = babl_format_with_space (use_srgb?"R~aG~aB~aA float":"RaGaBaA float", space);
+  }
+#endif
+  else
+  {
+    format  = babl_format_with_space ("R'G'B'A float", space);
+  }
+  return format;
+}
+
+static const Babl *gegl_babl_format_premultiplied_linear_float (const Babl *format)
+{
+  const Babl *space = babl_format_get_space (format);
+  const Babl *model = NULL;
+  if (!format)
+    return babl_format ("RaGaBaA float");
+
+  model = babl_format_get_model (format);
+
+  if (babl_model_is (model, "Y") ||
+      babl_model_is (model, "Y'") ||
+      babl_model_is (model, "Y~") ||
+      babl_model_is (model, "YA") ||
+      babl_model_is (model, "Y'A") ||
+      babl_model_is (model, "Y~A") ||
+      babl_model_is (model, "YaA") ||
+      babl_model_is (model, "Y'aA"))
+  {
+    format = babl_format_with_space ("YaA float", space);
+  }
+#if 0 // just treat as else
+  else if (babl_model_is (model, "RGB") ||
+           babl_model_is (model, "R'G'B'") ||
+           babl_model_is (model, "R~G~B~") ||
+           babl_model_is (model, "RGBA")    ||
+           babl_model_is (model, "RGB")     ||
+           babl_model_is (model, "R'G'B'A") ||
+           babl_model_is (model, "R'G'B'")  ||
+           babl_model_is (model, "R~G~B~A") ||
+           babl_model_is (model, "R~G~B~")  ||
+           babl_model_is (model, "RaGaBaA") ||
+           babl_model_is (model, "R'aG'aB'aA"))
+  {
+    format  = babl_format_with_space (use_srgb?"R~aG~aB~aA float":"RaGaBaA float", space);
+  }
+#endif
+  else
+  {
+    format  = babl_format_with_space ("RaGaBaA float", space);
+  }
+  return format;
+}
+
+static const Babl *gegl_babl_format_premultiplied_perceptual_float (const Babl *format)
+{
+  const Babl *space = babl_format_get_space (format);
+  const Babl *model = NULL;
+  if (!format)
+    return babl_format ("R~aG~aB~aA float");
+
+  model = babl_format_get_model (format);
+
+  if (babl_model_is (model, "Y") ||
+      babl_model_is (model, "Y'") ||
+      babl_model_is (model, "Y~") ||
+      babl_model_is (model, "YA") ||
+      babl_model_is (model, "Y'A") ||
+      babl_model_is (model, "Y~A") ||
+      babl_model_is (model, "YaA") ||
+      babl_model_is (model, "Y'aA"))
+  {
+    format = babl_format_with_space ("Y~aA float", space);
+  }
+#if 0 // just treat as else
+  else if (babl_model_is (model, "RGB") ||
+           babl_model_is (model, "R'G'B'") ||
+           babl_model_is (model, "R~G~B~") ||
+           babl_model_is (model, "RGBA")    ||
+           babl_model_is (model, "RGB")     ||
+           babl_model_is (model, "R'G'B'A") ||
+           babl_model_is (model, "R'G'B'")  ||
+           babl_model_is (model, "R~G~B~A") ||
+           babl_model_is (model, "R~G~B~")  ||
+           babl_model_is (model, "RaGaBaA") ||
+           babl_model_is (model, "R'aG'aB'aA"))
+  {
+    format  = babl_format_with_space (use_srgb?"R~aG~aB~aA float":"RaGaBaA float", space);
+  }
+#endif
+  else
+  {
+    format  = babl_format_with_space ("R~aG~aB~aA float", space);
+  }
+  return format;
+}
+
+static const Babl *gegl_babl_format_float (const Babl *format)
+{
+  const Babl *space;
+  const char *encoding;
+  if (!format)
+    return NULL;
+  space = babl_format_get_space (format);
+  encoding  = babl_format_get_encoding (format);
+
+  char *encdup = g_strdup (encoding);
+  char *newenc;
+  char *s = strrchr (encdup, ' ');
+  if (s) *s = 0;
+  newenc = g_strdup_printf ("%s float", encdup);
+  format = babl_format_with_space (newenc, space);
+
+  g_free (encdup);
+  g_free (newenc);
+  return format;
+}
+
+static const Babl *gegl_babl_format_float_premultiplied_linear_if_alpha (const Babl *format)
+{
+  if (!format)
+    return NULL;
+  if (babl_format_has_alpha (format))
+    return gegl_babl_format_premultiplied_linear_float (format);
+  return gegl_babl_format_float (format);
+}
+
+static const Babl *gegl_babl_format_float_premultiplied_perceptual_if_alpha (const Babl *format)
+{
+  if (!format)
+    return NULL;
+  if (babl_format_has_alpha (format))
+    return gegl_babl_format_premultiplied_perceptual_float (format);
+  return gegl_babl_format_float (format);
+}
+
+const Babl *gegl_babl_variant (const Babl *format, GeglBablVariant variant)
+{
+  if (!format)
+    return NULL;
+  switch (variant)
+  {
+    case GEGL_BABL_VARIANT_FLOAT:
+      return gegl_babl_format_float (format);
+    case GEGL_BABL_VARIANT_LINEAR:
+      return gegl_babl_format_linear_float (format);
+    case GEGL_BABL_VARIANT_NONLINEAR:
+      return gegl_babl_format_nonlinear_float (format);
+    case GEGL_BABL_VARIANT_PERCEPTUAL:
+      return gegl_babl_format_perceptual_float (format);
+    case GEGL_BABL_VARIANT_LINEAR_PREMULTIPLIED:
+      return gegl_babl_format_premultiplied_linear_float (format);
+    case GEGL_BABL_VARIANT_PERCEPTUAL_PREMULTIPLIED:
+      return gegl_babl_format_premultiplied_perceptual_float (format);
+    case GEGL_BABL_VARIANT_LINEAR_PREMULTIPLIED_IF_ALPHA:
+      return gegl_babl_format_float_premultiplied_linear_if_alpha (format);
+    case GEGL_BABL_VARIANT_PERCEPTUAL_PREMULTIPLIED_IF_ALPHA:
+      return gegl_babl_format_float_premultiplied_perceptual_if_alpha (format);
+  }
+  return format;
+}
+
diff --git a/gegl/gegl-utils.h b/gegl/gegl-utils.h
index ae7d4bc1e..557a2e808 100644
--- a/gegl/gegl-utils.h
+++ b/gegl/gegl-utils.h
@@ -116,6 +116,8 @@ void            gegl_buffer_set_color         (GeglBuffer          *buffer,
                                                const GeglRectangle *rect,
                                                GeglColor           *color);
 
+const Babl *gegl_babl_variant (const Babl *format, GeglBablVariant variant);
+
 
 G_END_DECLS
 


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