コード例 #1
0
static void
despeckle_median (guchar   *src,
                  guchar   *dst,
                  gint      width,
                  gint      height,
                  gint      bpp,
                  gint      radius,
                  gboolean  preview)
{
  guint  progress;
  guint  max_progress;
  gint   x, y;
  gint   input_radius = radius;
  gint   pos;
  gint   ymin;
  gint   ymax;
  gint   xmin;
  gint   xmax;

  memset (&histogram, 0, sizeof(histogram));
  progress     = 0;
  max_progress = width * height;

  if (! preview)
    gimp_progress_init(_("Despeckle"));


  for (y = 0; y < height; y++)
    {
      x = 0;
      ymin = MAX (0, y - radius);
      ymax = MIN (height - 1, y + radius);
      xmin = MAX (0, x - radius);
      xmax = MIN (width - 1, x + radius);
      hist0   = 0;
      histrest = 0;
      hist255 = 0;
      histogram_clean (&histogram);
      histogram.xmin = xmin;
      histogram.ymin = ymin;
      histogram.xmax = xmax;
      histogram.ymax = ymax;
      add_vals (&histogram,
                src, width, bpp,
                histogram.xmin, histogram.ymin, histogram.xmax, histogram.ymax);

      for (x = 0; x < width; x++)
        {
          const guchar *pixel;

          ymin = MAX (0, y - radius); /* update ymin, ymax when radius changed (FILTER_ADAPTIVE) */
          ymax = MIN (height - 1, y + radius);
          xmin = MAX (0, x - radius);
          xmax = MIN (width - 1, x + radius);

          update_histogram (&histogram,
                            src, width, bpp, xmin, ymin, xmax, ymax);

          pos = (x + (y * width)) * bpp;
          pixel = histogram_get_median (&histogram, src + pos);

          if (filter_type & FILTER_RECURSIVE)
            {
              del_val (&histogram, src, width, bpp, x, y);
              pixel_copy (src + pos, pixel, bpp);
              add_val (&histogram, src, width, bpp, x, y);
            }

          pixel_copy (dst + pos, pixel, bpp);

          /*
           * Check the histogram and adjust the diameter accordingly...
           */
          if (filter_type & FILTER_ADAPTIVE)
            {
              if (hist0 >= radius || hist255 >= radius)
                {
                  if (radius < input_radius)
                    radius++;
                }
              else if (radius > 1)
                {
                  radius--;
                }
            }
        }

      progress += width;

      if (! preview && y % 32 == 0)
        gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
    }

  if (! preview)
    gimp_progress_update (1.0);
}
コード例 #2
0
ファイル: median-blur.c プロジェクト: elEnemigo/GEGL-OpenCL
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);

  gdouble         percentile           = o->percentile       / 100.0;
  gdouble         alpha_percentile     = o->alpha_percentile / 100.0;
  const gint     *neighborhood_outline = o->user_data;

  const Babl     *format               = gegl_operation_get_format (operation, "input");
  gint            n_components         = babl_format_get_n_components (format);
  gboolean        has_alpha            = babl_format_has_alpha (format);

  G_STATIC_ASSERT (sizeof (gint32) == sizeof (gfloat));
  gint32         *src_buf;
  gfloat         *dst_buf;
  GeglRectangle   src_rect;
  gint            src_stride;
  gint            dst_stride;
  gint            n_pixels;

  Histogram      *hist;

  const gint32   *src;
  gfloat         *dst;
  gint            dst_x, dst_y;
  Direction       dir;

  gint            i;
  gint            c;

  src_rect   = gegl_operation_get_required_for_output (operation, "input", roi);
  src_stride = src_rect.width * n_components;
  dst_stride = roi->width * n_components;
  n_pixels   = roi->width * roi->height;
  dst_buf = g_new0 (gfloat, n_pixels                         * n_components);
  src_buf = g_new0 (gint32, src_rect.width * src_rect.height * n_components);

  gegl_buffer_get (input, &src_rect, 1.0, format, src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
  convert_values_to_bins (src_buf, n_components, has_alpha,
                          src_rect.width * src_rect.height);

  hist = g_slice_new0 (Histogram);

  src = src_buf + o->radius * (src_rect.width + 1) * n_components;
  dst = dst_buf;

  /* compute the first window */

  for (i = -o->radius; i <= o->radius; i++)
    {
      histogram_modify_vals (hist, src, n_components, src_stride, has_alpha,
                             i, -neighborhood_outline[abs (i)],
                             i, +neighborhood_outline[abs (i)],
                             +1);

      hist->size += 2 * neighborhood_outline[abs (i)] + 1;
    }

  for (c = 0; c < 3; c++)
    dst[c] = histogram_get_median (hist, c, percentile);

  if (has_alpha)
    dst[3] = histogram_get_median (hist, 3, alpha_percentile);

  dst_x = 0;
  dst_y = 0;

  n_pixels--;
  dir = LEFT_TO_RIGHT;

  while (n_pixels--)
    {
      /* move the src coords based on current direction and positions */
      if (dir == LEFT_TO_RIGHT)
        {
          if (dst_x != roi->width - 1)
            {
              dst_x++;
              src += n_components;
              dst += n_components;
            }
          else
            {
              dst_y++;
              src += src_stride;
              dst += dst_stride;
              dir = TOP_TO_BOTTOM;
            }
        }
      else if (dir == TOP_TO_BOTTOM)
        {
          if (dst_x == 0)
            {
              dst_x++;
              src += n_components;
              dst += n_components;
              dir = LEFT_TO_RIGHT;
            }
          else
            {
              dst_x--;
              src -= n_components;
              dst -= n_components;
              dir = RIGHT_TO_LEFT;
            }
        }
      else if (dir == RIGHT_TO_LEFT)
        {
          if (dst_x != 0)
            {
              dst_x--;
              src -= n_components;
              dst -= n_components;
            }
          else
            {
              dst_y++;
              src += src_stride;
              dst += dst_stride;
              dir = TOP_TO_BOTTOM;
            }
        }

      histogram_update (hist, src, n_components, src_stride, has_alpha,
                        o->neighborhood, o->radius, neighborhood_outline,
                        dir);

      for (c = 0; c < 3; c++)
        dst[c] = histogram_get_median (hist, c, percentile);

      if (has_alpha)
        dst[3] = histogram_get_median (hist, 3, alpha_percentile);
    }

  gegl_buffer_set (output, roi, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

  g_slice_free (Histogram, hist);
  g_free (dst_buf);
  g_free (src_buf);

  return TRUE;
}
コード例 #3
0
ファイル: median-blur.c プロジェクト: OpenCL/GEGL-OpenCL-old
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
    GeglProperties *o  = GEGL_PROPERTIES (operation);
    const Babl *format = gegl_operation_get_format (operation, "input");
    gint n_components  = babl_format_get_n_components (format);
    gboolean has_alpha = babl_format_has_alpha (format);

    gfloat *src_buf;
    gfloat *dst_buf;
    gint    n_pixels;
    GeglRectangle src_rect;

    Histogram *hist;
    Direction  dir;

    gint src_x, src_y;
    gint dst_x, dst_y;
    gint dst_idx, src_idx;
    gint xmin, ymin, xmax, ymax;

    src_rect = gegl_operation_get_required_for_output (operation, "input", roi);
    n_pixels = roi->width * roi->height;
    dst_buf = g_new0 (gfloat, n_pixels * n_components);
    src_buf = g_new0 (gfloat, src_rect.width * src_rect.height * n_components);

    gegl_buffer_get (input, &src_rect, 1.0, format, src_buf,
                     GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

    hist = g_slice_new0 (Histogram);

    dst_x = 0;
    dst_y = 0;
    src_x = o->radius;
    src_y = o->radius;

    /* compute the first window */

    hist->xmin = src_x - o->radius;
    hist->ymin = src_y - o->radius;
    hist->xmax = src_x + o->radius;
    hist->ymax = src_y + o->radius;

    histogram_add_vals (hist, src_buf, &src_rect, n_components,
                        hist->xmin, hist->ymin,
                        hist->xmax, hist->ymax);

    dst_idx = (dst_x + dst_y * roi->width) * n_components;

    dst_buf[dst_idx]     = histogram_get_median (hist, 0);
    dst_buf[dst_idx + 1] = histogram_get_median (hist, 1);
    dst_buf[dst_idx + 2] = histogram_get_median (hist, 2);

    if (has_alpha)
    {
        src_idx = (src_x + src_y * src_rect.width) * n_components;
        dst_buf[dst_idx + 3] = src_buf[src_idx + 3];
    }

    n_pixels--;
    dir = LEFT_TO_RIGHT;

    while (n_pixels--)
    {
        /* move the src coords based on current direction and positions */
        if (dir == LEFT_TO_RIGHT)
        {
            if (dst_x != roi->width - 1)
            {
                src_x++;
                dst_x++;
            }
            else
            {
                src_y++;
                dst_y++;
                dir = TOP_TO_BOTTOM;
            }
        }
        else if (dir == TOP_TO_BOTTOM)
        {
            if (dst_x == 0)
            {
                src_x++;
                dst_x++;
                dir = LEFT_TO_RIGHT;
            }
            else
            {
                src_x--;
                dst_x--;
                dir = RIGHT_TO_LEFT;
            }
        }
        else if (dir == RIGHT_TO_LEFT)
        {
            if (dst_x != 0)
            {
                src_x--;
                dst_x--;
            }
            else
            {
                src_y++;
                dst_y++;
                dir = TOP_TO_BOTTOM;
            }
        }

        xmin = src_x - o->radius;
        ymin = src_y - o->radius;
        xmax = src_x + o->radius;
        ymax = src_y + o->radius;

        histogram_update (hist, src_buf, &src_rect, n_components,
                          xmin, ymin, xmax, ymax, dir);

        dst_idx = (dst_x + dst_y * roi->width) * n_components;

        dst_buf[dst_idx]     = histogram_get_median (hist, 0);
        dst_buf[dst_idx + 1] = histogram_get_median (hist, 1);
        dst_buf[dst_idx + 2] = histogram_get_median (hist, 2);

        if (has_alpha)
        {
            src_idx = (src_x + src_y * src_rect.width) * n_components;
            dst_buf[dst_idx + 3] = src_buf[src_idx + 3];
        }
    }

    gegl_buffer_set (output, roi, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

    g_free (src_buf);
    g_free (dst_buf);
    g_slice_free (Histogram, hist);

    return TRUE;
}