base: model-rgb add float version of conversions for RaGaBaA
authorØyvind Kolås <pippin@gimp.org>
Wed, 29 Aug 2018 14:53:43 +0000 (16:53 +0200)
committerØyvind Kolås <pippin@gimp.org>
Wed, 29 Aug 2018 14:53:43 +0000 (16:53 +0200)
babl/base/model-rgb.c

index 391ff3b369383f32d286d96abcb3cc8feee3111d..d4036d221873265f307a101df5d9639f14f04efb 100644 (file)
@@ -414,6 +414,88 @@ non_premultiplied_to_premultiplied (Babl  *conversion,
     }
 }
 
+
+static void
+non_premultiplied_to_premultiplied_float (Babl  *conversion,
+                                          int    src_bands,
+                                          char **src,
+                                          int   *src_pitch,
+                                          int    dst_bands,
+                                          char **dst,
+                                          int   *dst_pitch,
+                                          long   samples)
+{
+  long n = samples;
+
+  BABL_PLANAR_SANITY
+  while (n--)
+    {
+      float alpha = *(float *) src[src_bands - 1];
+      int    band;
+
+      if (alpha < BABL_ALPHA_FLOOR)
+      {
+        int non_zero_components = 0;
+        if (alpha >= 0.0f)
+          alpha = BABL_ALPHA_FLOOR;
+        else if (alpha >= -BABL_ALPHA_FLOOR)
+          alpha = -BABL_ALPHA_FLOOR;
+        for (band = 0 ; band< src_bands-1; band++)
+          if (*(float *) src[band] != 0.0f)
+            non_zero_components++;
+        if (non_zero_components == 0)
+          alpha = 0.0f;
+      }
+
+      for (band = 0; band < src_bands - 1; band++)
+        {
+          *(float *) dst[band] = *(float *) src[band] * alpha;
+        }
+      *(float *) dst[dst_bands - 1] = alpha;
+
+      BABL_PLANAR_STEP
+    }
+}
+
+static void
+premultiplied_to_non_premultiplied_float (Babl  *conversion,
+                                          int    src_bands,
+                                          char **src,
+                                          int   *src_pitch,
+                                          int    dst_bands,
+                                          char **dst,
+                                          int   *dst_pitch,
+                                          long   samples)
+{
+  long n = samples;
+
+  BABL_PLANAR_SANITY
+  while (n--)
+    {
+      float alpha;
+      float recip_alpha;
+      int    band;
+
+      alpha = *(float *) src[src_bands - 1];
+      if (alpha == 0.0f)
+         recip_alpha = 0.0f;
+      else
+      {
+        recip_alpha  = 1.0f / alpha;
+        if (alpha == BABL_ALPHA_FLOOR)
+          alpha = 0.0f; // making 0 round-trip to zero, causing discontinuity
+      }
+
+      for (band = 0; band < src_bands - 1; band++)
+        *(float *) dst[band] = *(float *) src[band] * recip_alpha;
+      *(float *) dst[dst_bands - 1] = alpha;
+
+      BABL_PLANAR_STEP
+    }
+}
+
+
+
 static void
 premultiplied_to_non_premultiplied (Babl  *conversion,
                                     int    src_bands,
@@ -850,7 +932,6 @@ conversions (void)
     "planar", non_premultiplied_to_premultiplied,
     NULL
   );
-
   babl_conversion_new (
     babl_model_from_id (BABL_RGBA_PREMULTIPLIED),
     babl_model_from_id (BABL_RGBA),
@@ -1217,6 +1298,15 @@ formats (void)
     babl_component_from_id (BABL_ALPHA),
     NULL);
 
+  babl_format_new (
+    babl_model_from_id (BABL_RGBA_PREMULTIPLIED),
+    babl_type_from_id (BABL_FLOAT),
+    babl_component_from_id (BABL_RED_MUL_ALPHA),
+    babl_component_from_id (BABL_GREEN_MUL_ALPHA),
+    babl_component_from_id (BABL_BLUE_MUL_ALPHA),
+    babl_component_from_id (BABL_ALPHA),
+    NULL);
+
 #ifdef XXXX
   babl_format_new (
     "id", BABL_RGB565,
@@ -1234,8 +1324,6 @@ formats (void)
     "planar", g3_nonlinear_to_linear_float,
     NULL
   );
-
-
   babl_conversion_new (
     babl_format ("RGBA float"),
     babl_format ("R'G'B' float"),
@@ -1243,7 +1331,6 @@ formats (void)
     NULL
   );
 
-
   babl_conversion_new (
     babl_format ("RGBA float"),
     babl_format ("R'aG'aB'aA float"),
@@ -1256,5 +1343,19 @@ formats (void)
     NULL);
 
 
+  babl_conversion_new (
+    babl_format ("RGBA float"),
+    babl_format ("RaGaBaA float"),
+    "planar", non_premultiplied_to_premultiplied_float,
+    NULL
+  );
+  babl_conversion_new (
+    babl_format ("RaGaBaA float"),
+    babl_format ("RGBA float"),
+    "planar", premultiplied_to_non_premultiplied_float,
+    NULL
+  );
+
+
 }