[babl] babl: add Y~aA formats - for completeness



commit 496e9a78115b2eddc8967346c339b2903bd5486c
Author: Øyvind Kolås <pippin gimp org>
Date:   Thu May 9 16:26:37 2019 +0200

    babl: add Y~aA formats - for completeness
    
    In order for higher level code to be abstracted across all available
    permutations we need this. This fixes gegl issue no 151

 babl/babl-ids.h        |   1 +
 babl/base/formats.c    |   7 ++
 babl/base/model-gray.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 243 insertions(+), 2 deletions(-)
---
diff --git a/babl/babl-ids.h b/babl/babl-ids.h
index 6937ee4..727d828 100644
--- a/babl/babl-ids.h
+++ b/babl/babl-ids.h
@@ -74,6 +74,7 @@ enum {
   BABL_GREEN_MUL_ALPHA,
   BABL_BLUE_MUL_ALPHA,
   BABL_GRAY_PERCEPTUAL,
+  BABL_GRAY_PERCEPTUAL_MUL_ALPHA,
   BABL_GRAY_NONLINEAR,
   BABL_GRAY_NONLINEAR_MUL_ALPHA,
   BABL_RED_NONLINEAR,
diff --git a/babl/base/formats.c b/babl/base/formats.c
index 99bf605..bad9d14 100644
--- a/babl/base/formats.c
+++ b/babl/base/formats.c
@@ -131,6 +131,13 @@ babl_formats_init (void)
     babl_component_from_id (BABL_ALPHA),
     NULL);
 
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED),
+    type,
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL_MUL_ALPHA),
+    babl_component_from_id (BABL_ALPHA),
+    NULL);
+
   babl_format_new (
     babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED),
     type,
diff --git a/babl/base/model-gray.c b/babl/base/model-gray.c
index 210dce8..37136d0 100644
--- a/babl/base/model-gray.c
+++ b/babl/base/model-gray.c
@@ -72,6 +72,12 @@ components (void)
     "id", BABL_GRAY_PERCEPTUAL,
     "luma",
     NULL);
+
+  babl_component_new (
+    "Y~a",
+    "id", BABL_GRAY_PERCEPTUAL_MUL_ALPHA,
+    "luma",
+    NULL);
 }
 
 static void
@@ -146,6 +152,16 @@ models (void)
     "alpha",
     NULL);
 
+  babl_model_new (
+    "id", BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED,
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL_MUL_ALPHA),
+    babl_component_from_id (BABL_ALPHA),
+    "gray",
+    "perceptual",
+    "premultiplied",
+    "alpha",
+    NULL);
+
 }
 
 static void
@@ -584,6 +600,49 @@ premultiplied_to_non_premultiplied (Babl  *conversion,
     }
 }
 
+
+
+static void
+rgba2gray_perceptual_premultiplied (Babl *conversion,
+                                    char *src,
+                                    char *dst,
+                                    long  n)
+{
+  const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl *trc = perceptual_trc;
+  double RGB_LUMINANCE_RED   = space->space.RGBtoXYZ[3];
+  double RGB_LUMINANCE_GREEN = space->space.RGBtoXYZ[4];
+  double RGB_LUMINANCE_BLUE  = space->space.RGBtoXYZ[5];
+
+  while (n--)
+    {
+      double red   = ((double *) src)[0];
+      double green = ((double *) src)[1];
+      double blue  = ((double *) src)[2];
+      double luminance;
+      double luma;
+      double alpha = ((double *) src)[3];
+      if (alpha < BABL_ALPHA_FLOOR)
+      {
+        if (alpha >= 0.0f)
+          alpha = BABL_ALPHA_FLOOR;
+        else if (alpha >= -BABL_ALPHA_FLOOR)
+          alpha = -BABL_ALPHA_FLOOR;
+      }
+
+      luminance = red * RGB_LUMINANCE_RED +
+                  green * RGB_LUMINANCE_GREEN +
+                  blue * RGB_LUMINANCE_BLUE;
+      luma = babl_trc_from_linear (trc, luminance);
+
+      ((double *) dst)[0] = luma * alpha;
+      ((double *) dst)[1] = alpha;
+
+      src += 4 * sizeof (double);
+      dst += 2 * sizeof (double);
+    }
+}
+
 static void
 rgba2gray_nonlinear_premultiplied (Babl *conversion,
                                    char *src,
@@ -626,6 +685,40 @@ rgba2gray_nonlinear_premultiplied (Babl *conversion,
 }
 
 
+static void
+gray_perceptual_premultiplied2rgba (Babl *conversion,
+                                    char *src,
+                                    char *dst,
+                                    long  n)
+{
+  const Babl *trc = perceptual_trc;
+
+  while (n--)
+    {
+      double luma  = ((double *) src)[0];
+      double luminance;
+      double alpha;
+      alpha = ((double *) src)[1];
+      if (alpha == 0.0)
+        luma = 0.0;
+      else
+        luma = luma / alpha;
+
+      luminance = babl_trc_to_linear (trc, luma);
+
+      if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR)
+        alpha = 0.0;
+
+      ((double *) dst)[0] = luminance;
+      ((double *) dst)[1] = luminance;
+      ((double *) dst)[2] = luminance;
+      ((double *) dst)[3] = alpha;
+
+      src += 2 * sizeof (double);
+      dst += 4 * sizeof (double);
+    }
+}
+
 static void
 gray_nonlinear_premultiplied2rgba (Babl *conversion,
                                    char *src,
@@ -701,6 +794,13 @@ conversions (void)
     NULL
   );
 
+  babl_conversion_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED),
+    babl_model_from_id (BABL_RGBA),
+    "linear", gray_perceptual_premultiplied2rgba,
+    NULL
+  );
+
   babl_conversion_new (
     babl_model_from_id (BABL_RGBA),
     babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED),
@@ -708,7 +808,12 @@ conversions (void)
     NULL
   );
 
-
+  babl_conversion_new (
+    babl_model_from_id (BABL_RGBA),
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED),
+    "linear", rgba2gray_perceptual_premultiplied,
+    NULL
+  );
 
   babl_conversion_new (
     babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL),
@@ -833,6 +938,23 @@ formats (void)
     babl_type_from_id (BABL_HALF),
     babl_component_from_id (BABL_GRAY_NONLINEAR),
     NULL);
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL),
+    babl_type_from_id (BABL_HALF),
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL),
+    NULL);
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA),
+    babl_type_from_id (BABL_HALF),
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL),
+    babl_component_from_id (BABL_ALPHA),
+    NULL);
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED),
+    babl_type_from_id (BABL_HALF),
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL_MUL_ALPHA),
+    babl_component_from_id (BABL_ALPHA),
+    NULL);
   /***********/
 
   babl_format_new (
@@ -904,6 +1026,24 @@ formats (void)
     babl_type_from_id (BABL_U32),
     babl_component_from_id (BABL_GRAY_NONLINEAR),
     NULL);
+
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL),
+    babl_type_from_id (BABL_U32),
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL),
+    NULL);
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA),
+    babl_type_from_id (BABL_U32),
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL),
+    babl_component_from_id (BABL_ALPHA),
+    NULL);
+  babl_format_new (
+    babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED),
+    babl_type_from_id (BABL_U32),
+    babl_component_from_id (BABL_GRAY_PERCEPTUAL_MUL_ALPHA),
+    babl_component_from_id (BABL_ALPHA),
+    NULL);
 }
 
 /********** float versions ***********/
@@ -1428,6 +1568,81 @@ gray_nonlinear_premultiplied2rgba_float (Babl *conversion,
     }
 }
 
+static void
+rgba2gray_perceptual_premultiplied_float (Babl *conversion,
+                                         char *src,
+                                         char *dst,
+                                         long  n)
+{
+  const Babl *space = babl_conversion_get_destination_space (conversion);
+  const Babl *trc = perceptual_trc;
+  float RGB_LUMINANCE_RED   = space->space.RGBtoXYZf[3];
+  float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4];
+  float RGB_LUMINANCE_BLUE  = space->space.RGBtoXYZf[5];
+
+  while (n--)
+    {
+      float red   = ((float *) src)[0];
+      float green = ((float *) src)[1];
+      float blue  = ((float *) src)[2];
+      float luminance;
+      float luma;
+      float alpha = ((float *) src)[3];
+      if (alpha < BABL_ALPHA_FLOOR)
+      {
+        if (alpha >= 0.0f)
+          alpha = BABL_ALPHA_FLOOR;
+        else if (alpha >= -BABL_ALPHA_FLOOR)
+          alpha = -BABL_ALPHA_FLOOR;
+      }
+
+      luminance = red * RGB_LUMINANCE_RED +
+                  green * RGB_LUMINANCE_GREEN +
+                  blue * RGB_LUMINANCE_BLUE;
+      luma = babl_trc_from_linear (trc, luminance);
+
+      ((float *) dst)[0] = luma * alpha;
+      ((float *) dst)[1] = alpha;
+
+      src += 4 * sizeof (float);
+      dst += 2 * sizeof (float);
+    }
+}
+
+static void
+gray_perceptual_premultiplied2rgba_float (Babl *conversion,
+                                          char *src,
+                                          char *dst,
+                                          long  n)
+{
+  const Babl *trc = perceptual_trc;
+
+  while (n--)
+    {
+      float luma  = ((float *) src)[0];
+      float luminance;
+      float alpha;
+      alpha = ((float *) src)[1];
+      if (alpha == 0.0f)
+        luma = 0.0f;
+      else
+        luma = luma / alpha;
+
+      luminance = babl_trc_to_linear (trc, luma);
+
+      if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR)
+        alpha = 0.0f;
+
+      ((float *) dst)[0] = luminance;
+      ((float *) dst)[1] = luminance;
+      ((float *) dst)[2] = luminance;
+      ((float *) dst)[3] = alpha;
+
+      src += 2 * sizeof (float);
+      dst += 4 * sizeof (float);
+    }
+}
+
 static void init_single_precision (void)
 {
   babl_format_new (
@@ -1479,6 +1694,12 @@ static void init_single_precision (void)
     babl_component ("Y'a"),
     babl_component ("A"),
     NULL);
+  babl_format_new (
+    babl_model ("Y~aA"),
+    babl_type_from_id (BABL_FLOAT),
+    babl_component ("Y~a"),
+    babl_component ("A"),
+    NULL);
 
   babl_conversion_new (
     babl_format ("Y' float"),
@@ -1516,6 +1737,13 @@ static void init_single_precision (void)
     NULL
   );
 
+  babl_conversion_new (
+    babl_format ("Y~aA float"),
+    babl_format ("RGBA float"),
+    "linear", gray_perceptual_premultiplied2rgba_float,
+    NULL
+  );
+
   babl_conversion_new (
     babl_format ("RGBA float"),
     babl_format ("Y'aA float"),
@@ -1523,7 +1751,12 @@ static void init_single_precision (void)
     NULL
   );
 
-
+  babl_conversion_new (
+    babl_format ("RGBA float"),
+    babl_format ("Y~aA float"),
+    "linear", rgba2gray_perceptual_premultiplied_float,
+    NULL
+  );
 
   babl_conversion_new (
     babl_format ("Y~ float"),


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