[gegl/soc-2011-ops] Added deinterlace op with some new options



commit 6af0a8346054420a0298b6e2c6a31719a23d8a9e
Author: Robert Sasu <sasu robert gmail com>
Date:   Sat Aug 13 13:03:01 2011 +0300

    Added deinterlace op with some new options

 operations/workshop/deinterlace.c |  198 ++++++++++++++++++++++++++++---------
 1 files changed, 150 insertions(+), 48 deletions(-)
---
diff --git a/operations/workshop/deinterlace.c b/operations/workshop/deinterlace.c
index b76f69f..76e7ec0 100644
--- a/operations/workshop/deinterlace.c
+++ b/operations/workshop/deinterlace.c
@@ -28,6 +28,10 @@
 #ifdef GEGL_CHANT_PROPERTIES
 
 gegl_chant_boolean (even, _("Even/Odd"), TRUE, _("Keep even/odd fields"))
+gegl_chant_boolean (horizontal, _("Horizontal/Vertical"), TRUE,
+                    _("Choose horizontal or vertical"))
+gegl_chant_int (size, _("Block size"), 0, 100, 1,
+                _("Block size of deinterlacing rows/columns"))
 
 #else
 
@@ -41,10 +45,19 @@ gegl_chant_boolean (even, _("Even/Odd"), TRUE, _("Keep even/odd fields"))
 static void prepare (GeglOperation *operation)
 {
   GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
+  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
 
-  op_area->left = op_area->right = 0; 
-  op_area->top = op_area->bottom = 2;
-
+  
+  if (o->horizontal)
+     {
+        op_area->left = op_area->right = 0; 
+        op_area->top = op_area->bottom = o->size + 1;
+     }
+  else
+     {
+        op_area->left = op_area->right = o->size + 1; 
+        op_area->top = op_area->bottom = 0;
+     }
   gegl_operation_set_format (operation, "input", 
                              babl_format ("RGBA float"));
   gegl_operation_set_format (operation, "output",
@@ -52,56 +65,133 @@ static void prepare (GeglOperation *operation)
 }
 
 static void
-de_interlace (gfloat              *src_buf,
-              gfloat              *dest,
-              const GeglRectangle *result,
-              const GeglRectangle *extended,
-              const GeglRectangle *boundary,
-              gint                 inter,
-              gint                 y)
+de_interlace_hor (gfloat              *src_buf,
+                  gfloat              *dest,
+                  const GeglRectangle *result,
+                  const GeglRectangle *extended,
+                  const GeglRectangle *boundary,
+                  gint                 inter,
+                  gint                 y,
+                  gint                 size)
 {
-  gfloat *upper, *lower;
-  gint    x, up_offset, low_offset, offset;
- 
-  upper = g_new0 (gfloat, result->width * 4);
-  lower = g_new0 (gfloat, result->width * 4);
-
-  if (y > 0)
-     up_offset = (y - extended->y) * extended->width * 4;
-  else
-     up_offset = inter * extended->width * 4;
-
-  if (y + 1 < boundary->height)
-     low_offset = (y + 1 - extended->y) * extended->width * 4;
-  else
-     low_offset = (y - 1 + inter - extended->y) * extended->width * 4;
-
-  for (x=0; x < extended->width * 4; x++)
+  gfloat  upper[4], lower[4], temp_buf[4];
+  gint    x, up_offset, low_offset, offset = 0, i;
+  
+  for (x=0; x < result->width; x++)
      {
-        upper[x] = src_buf[up_offset + x];
-        lower[x] = src_buf[low_offset + x]; 
+       gfloat ualpha, lalpha, temp;
+       gfloat alpha = 0;
+
+       temp_buf[0] = temp_buf[1] = temp_buf[2] = temp_buf[3] = 0;
+
+       for (i = 0; i < size; i++)
+        {
+          gint b;
+
+          if (y  - i> 0)
+            up_offset = (y - i - extended->y) * extended->width * 4;
+          else
+            up_offset = inter * extended->width * 4;
+
+          if (y + i + 1 < boundary->height)
+            low_offset = (y + i + 1 - extended->y) * extended->width * 4;
+          else
+            low_offset = (y - 1 + inter - extended->y) * extended->width * 4;
+
+          offset = (y - result->y) * extended->width * 4;
+
+          for (b=0; b<4; b++)
+             {
+                upper[b] = src_buf[up_offset + x * 4 + b];
+                lower[b] = src_buf[low_offset + x * 4 + b];
+             }
+
+          ualpha = upper[3];
+          lalpha = lower[3];
+          temp   = ualpha + lalpha;
+          alpha += temp;
+
+          for (b=0; b < 3; b++)
+               temp_buf[b] += (upper[b] * ualpha +
+                               lower[b] * lalpha);
+        }
+       
+       if ((dest[offset + x * 4 + 3] = alpha / (2 * size)))
+          {
+             gint b;
+             for (b=0; b < 3; b++)
+                dest[offset + x * 4 + b] = temp_buf[b] / alpha;
+
+          }
      }
+}
 
-  offset = (y - result->y) * extended->width * 4;
-
-  for (x=0; x < extended->width; x++)
+static void
+de_interlace_ver (gfloat              *src_buf,
+                  gfloat              *dest,
+                  const GeglRectangle *result,
+                  const GeglRectangle *extended,
+                  const GeglRectangle *boundary,
+                  gint                 inter,
+                  gint                 x,
+                  gint                 size)
+{
+  gfloat  upper[4], lower[4], temp_buf[4];
+  gint    y, up_offset, low_offset, offset = 0, i;
+  
+  for (y=result->y; y < result->y + result->height; y++)
      {
-        gfloat ualpha = upper[x * 4 + 3];
-        gfloat lalpha = lower[x * 4 + 3];
-        gfloat alpha  = ualpha + lalpha;
-
-        if ((dest[offset + x*4 + 3] = alpha / 2))
-           {
-              gint b;
-              for (b=0; b < 3; b++)
-                  dest[offset + x*4 + b] = (upper[x*4 + b] * ualpha +
-                                            lower[x*4 + b] * lalpha) / alpha;
-           }
+       gfloat ualpha, lalpha, temp;
+       gfloat alpha = 0;
+
+       temp_buf[0] = temp_buf[1] = temp_buf[2] = temp_buf[3] = 0;
+
+       for (i = 0; i < size; i++)
+        {
+          gint b;
+
+          if (x  - i > 0)
+            up_offset = (y - extended->y) * extended->width * 4
+                      + (x - i - extended->x) * 4;
+          else
+            up_offset = (y - extended->y) * extended->width * 4 + inter * 4;
+
+          if (x + i + 1 < boundary->width)
+            low_offset = (y - extended->y) * extended->width * 4 + 
+                         (x + i + 1 - extended->x) * 4;
+          else
+            low_offset = (y - extended->y) * extended->width * 4 + 
+                         (x + i - 1 + inter - extended->x) * 4;
+
+          offset = (y - result->y) * result->width * 4 + (x - result->x) * 4;
+
+          for (b=0; b<4; b++)
+             {
+                upper[b] = src_buf[up_offset + b];
+                lower[b] = src_buf[low_offset + b];
+             }
+
+          ualpha = upper[3];
+          lalpha = lower[3];
+          temp   = ualpha + lalpha;
+          alpha += temp;
+
+          for (b=0; b < 3; b++)
+               temp_buf[b] += (upper[b] * ualpha +
+                               lower[b] * lalpha);
+        }
+       
+       if ((dest[offset + 3] = alpha / (2 * size)))
+          {
+             gint b;
+             for (b=0; b < 3; b++)
+                dest[offset + b] = temp_buf[b] / alpha;
+
+          }
      }
 }
 
 
-
 static GeglRectangle
 get_effective_area (GeglOperation *operation)
 {
@@ -125,7 +215,7 @@ process (GeglOperation       *operation,
 
   GeglRectangle  rect;
   GeglRectangle  boundary = get_effective_area (operation);
-  gint           y;
+  gint           x, y;
   gfloat        *dst_buf, *src_buf;
 
   rect.x      = CLAMP (result->x - op_area->left, boundary.x, boundary.x +
@@ -143,10 +233,22 @@ process (GeglOperation       *operation,
   gegl_buffer_get (input, 1.0, result, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
   gegl_buffer_get (input, 1.0, &rect, format, src_buf, GEGL_AUTO_ROWSTRIDE);
 
-  for (y = result->y; y < result->y + result->height; y++)
-     if ((o->even && y%2==0) || (!o->even && y%2!=0))
-        de_interlace (src_buf, dst_buf, result, &rect, &boundary, 
-                      o->even ? 0 : 1, y);
+  if (o->horizontal)
+    {
+       for (y = result->y; y < result->y + result->height; y++)
+          if ((o->even && y%2==0) || (!o->even && y%2!=0))
+             de_interlace_hor (src_buf, dst_buf, result, &rect, &boundary, 
+                               o->even ? 0 : 1, y, o->size);
+    }
+  else 
+    {
+       for (x = result->x; x < result->x + result->width; x++)
+          if ((o->even && x%2==0) || (!o->even && x%2!=0))
+             de_interlace_ver (src_buf, dst_buf, result, &rect, &boundary, 
+                               o->even ? 0 : 1, x, o->size);
+             
+    }
+
 
   gegl_buffer_set (output, result, format, dst_buf, GEGL_AUTO_ROWSTRIDE);
 



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