[gegl] dither: pass-through for floyd-steinberg method on infinite planes (issue #179)



commit adca60f25e6354531f83b1548ac56d62c28df0af
Author: Thomas Manni <thomas manni free fr>
Date:   Wed Jul 31 18:52:30 2019 +0200

    dither: pass-through for floyd-steinberg method on infinite planes (issue #179)

 operations/common/dither.c | 70 +++++++++++++++++++++++++++-------------------
 1 file changed, 42 insertions(+), 28 deletions(-)
---
diff --git a/operations/common/dither.c b/operations/common/dither.c
index 59099c2cc..4967bb1ef 100644
--- a/operations/common/dither.c
+++ b/operations/common/dither.c
@@ -519,28 +519,29 @@ process_standard (GeglBuffer          *input,
 }
 
 static GeglRectangle
-get_required_for_output (GeglOperation       *self,
-                         const gchar         *input_pad,
-                         const GeglRectangle *roi)
+get_cached_region (GeglOperation       *self,
+                   const GeglRectangle *roi)
 {
   GeglProperties *o = GEGL_PROPERTIES (self);
 
   if (o->dither_method == GEGL_DITHER_FLOYD_STEINBERG)
-    return *gegl_operation_source_get_bounding_box (self, "input");
-  else
-    return *roi;
+    {
+      const GeglRectangle *in_rect =
+          gegl_operation_source_get_bounding_box (self, "input");
+
+      if (in_rect && ! gegl_rectangle_is_infinite_plane (in_rect))
+        return *in_rect;
+    }
+
+  return *roi;
 }
 
 static GeglRectangle
-get_cached_region (GeglOperation       *self,
-                   const GeglRectangle *roi)
+get_required_for_output (GeglOperation       *self,
+                         const gchar         *input_pad,
+                         const GeglRectangle *roi)
 {
-  GeglProperties *o = GEGL_PROPERTIES (self);
-
-  if (o->dither_method == GEGL_DITHER_FLOYD_STEINBERG)
-    return *gegl_operation_source_get_bounding_box (self, "input");
-  else
-    return *roi;
+  return get_cached_region (self, roi);
 }
 
 static gboolean
@@ -580,25 +581,38 @@ operation_process (GeglOperation        *operation,
 
   if (o->dither_method == GEGL_DITHER_FLOYD_STEINBERG)
     {
-      GeglOperationFilterClass *klass;
-      GeglBuffer  *input;
-      GeglBuffer  *output;
+      const GeglRectangle *in_rect =
+        gegl_operation_source_get_bounding_box (operation, "input");
 
-      if (strcmp (output_prop, "output"))
+      if (in_rect && gegl_rectangle_is_infinite_plane (in_rect))
         {
-          g_warning ("requested processing of %s pad on a filter", output_prop);
-          return FALSE;
+          gpointer in = gegl_operation_context_get_object (context, "input");
+          gegl_operation_context_take_object (context, "output",
+                                          g_object_ref (G_OBJECT (in)));
+          return TRUE;
         }
+      else
+        {
+          GeglOperationFilterClass *klass;
+          GeglBuffer  *input;
+          GeglBuffer  *output;
+
+          if (strcmp (output_prop, "output"))
+            {
+              g_warning ("requested processing of %s pad on a filter", output_prop);
+              return FALSE;
+            }
 
-      input  = (GeglBuffer*) gegl_operation_context_dup_object (context, "input");
-      output = gegl_operation_context_get_output_maybe_in_place (operation,
-                                                                 context,
-                                                                 input,
-                                                                 result);
-      klass = GEGL_OPERATION_FILTER_GET_CLASS (operation);
-      success = klass->process (operation, input, output, result, level);
+          input  = (GeglBuffer*) gegl_operation_context_dup_object (context, "input");
+          output = gegl_operation_context_get_output_maybe_in_place (operation,
+                                                                     context,
+                                                                     input,
+                                                                     result);
+          klass = GEGL_OPERATION_FILTER_GET_CLASS (operation);
+          success = klass->process (operation, input, output, result, level);
 
-      g_clear_object (&input);
+          g_clear_object (&input);
+        }
     }
   else
     {


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