[gegl] gegl: add gegl_babl_variant
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] gegl: add gegl_babl_variant
- Date: Wed, 31 Oct 2018 18:02:57 +0000 (UTC)
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]