static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o            = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle            boundary     = get_effective_area (operation);
  const Babl              *format       = babl_format ("RGBA float");

  gint      x,y;
  gfloat   *src_buf, *dst_buf;
  gfloat    dest[4];
  gint      i, offset = 0;
  gboolean  inside;
  gdouble   px, py;

  GeglMatrix2  scale;        /* a matrix indicating scaling factors around the
                                current center pixel.
                             */

  src_buf = g_new0 (gfloat, result->width * result->height * 4);
  dst_buf = g_new0 (gfloat, result->width * result->height * 4);

  gegl_buffer_get (input, result, 1.0, format, src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  if (o->middle)
    {
      o->pole_x = boundary.width / 2;
      o->pole_y = boundary.height / 2;
    }

  for (y = result->y; y < result->y + result->height; y++)
    for (x = result->x; x < result->x + result->width; x++)
      {
#define gegl_unmap(u,v,ud,vd) {                                         \
          gdouble rx, ry;                                               \
          inside = calc_undistorted_coords ((gdouble)x, (gdouble)y,     \
                                            &rx, &ry, o, boundary);     \
          ud = rx;                                                      \
          vd = ry;                                                      \
        }
        gegl_sampler_compute_scale (scale, x, y);
        gegl_unmap(x,y,px,py);
#undef gegl_unmap

        if (inside)
          gegl_buffer_sample (input, px, py, &scale, dest, format,
                              GEGL_SAMPLER_NOHALO, GEGL_ABYSS_NONE);
        else
          for (i=0; i<4; i++)
            dest[i] = 0.0;

        for (i=0; i<4; i++)
          dst_buf[offset++] = dest[i];
      }

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

  g_free (src_buf);
  g_free (dst_buf);

  return  TRUE;
}
Exemple #2
0
static gboolean
process (GeglOperation       *op,
         void                *in_buf,
         void                *out_buf,
         glong                samples,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (op);
  gint        num_sampling_points;
  GeglCurve  *curve;
  gint i;
  gfloat  *in  = in_buf;
  gfloat  *out = out_buf;
  gdouble *xs, *ys;

  num_sampling_points = o->sampling_points;
  curve = o->curve;

  if (num_sampling_points > 0)
  {
    xs = g_new(gdouble, num_sampling_points);
    ys = g_new(gdouble, num_sampling_points);

    gegl_curve_calc_values(o->curve, 0.0, 1.0, num_sampling_points, xs, ys);

    g_free(xs);

    for (i=0; i<samples; i++)
    {
      gint x = in[0] * num_sampling_points;
      gfloat y;

      if (x < 0)
       y = ys[0];
      else if (x >= num_sampling_points)
       y = ys[num_sampling_points - 1];
      else
       y = ys[x];

      out[0] = y;
      out[1]=in[1];

      in += 2;
      out+= 2;
    }

    g_free(ys);
  }
  else
    for (i=0; i<samples; i++)
    {
      gfloat u = in[0];

      out[0] = gegl_curve_calc_value(curve, u);
      out[1]=in[1];

      in += 2;
      out+= 2;
    }

  return TRUE;
}
Exemple #3
0
static void
prepare (GeglOperation *operation)
{
    GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
    Priv       *p = (Priv*)o->chant_data;

    if (p == NULL)
        init (o);
    p = (Priv*)o->chant_data;

    g_assert (o->chant_data != NULL);

    gegl_operation_set_format (operation, "output", babl_format ("R'G'B'A u8"));


    if (!p->loadedfilename ||
            strcmp (p->loadedfilename, o->path))
    {
        gint i;
        gint err;

        ff_cleanup (o);
        err = av_open_input_file (&p->ic, o->path, NULL, 0, NULL);
        if (err < 0)
        {
            print_error (o->path, err);
        }
        err = av_find_stream_info (p->ic);
        if (err < 0)
        {
            g_warning ("ff-load: error finding stream info for %s", o->path);

            return;
        }
        for (i = 0; i< p->ic->nb_streams; i++)
        {
            AVCodecContext *c = p->ic->streams[i]->codec;
#if LIBAVFORMAT_VERSION_MAJOR >= 53
            if (c->codec_type == AVMEDIA_TYPE_VIDEO)
#else
            if (c->codec_type == CODEC_TYPE_VIDEO)
#endif
            {
                p->video_st = p->ic->streams[i];
                p->video_stream = i;
            }
        }

        p->enc = p->video_st->codec;
        p->codec = avcodec_find_decoder (p->enc->codec_id);

        /* p->enc->error_resilience = 2; */
        p->enc->error_concealment = 3;
        p->enc->workaround_bugs = FF_BUG_AUTODETECT;

        if (p->codec == NULL)
        {
            g_warning ("codec not found");
        }

        if (p->codec->capabilities & CODEC_CAP_TRUNCATED)
            p->enc->flags |= CODEC_FLAG_TRUNCATED;

        if (avcodec_open (p->enc, p->codec) < 0)
        {
            g_warning ("error opening codec %s", p->enc->codec->name);
            return;
        }

        p->width = p->enc->width;
        p->height = p->enc->height;
        p->frames = 10000000;
        p->lavc_frame = avcodec_alloc_frame ();

        if (p->fourcc)
            g_free (p->fourcc);
        p->fourcc = g_strdup ("none");
        p->fourcc[0] = (p->enc->codec_tag) & 0xff;
        p->fourcc[1] = (p->enc->codec_tag >> 8) & 0xff;
        p->fourcc[2] = (p->enc->codec_tag >> 16) & 0xff;
        p->fourcc[3] = (p->enc->codec_tag >> 24) & 0xff;

        if (p->codec_name)
            g_free (p->codec_name);
        if (p->codec->name)
        {
            p->codec_name = g_strdup (p->codec->name);
        }
        else
        {
            p->codec_name = g_strdup ("");
        }

        if (p->loadedfilename)
            g_free (p->loadedfilename);
        p->loadedfilename = g_strdup (o->path);
        p->prevframe = -1;
        p->coded_bytes = 0;
        p->coded_buf = NULL;
    }
Exemple #4
0
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o  = GEGL_CHANT_PROPERTIES (operation);

  gdouble  noise_coeff = 0.0;
  int      rint = 0;
  gint     b, i;
  gint     x, y;
  gdouble  noise[4];
  gfloat   tmp;
  gfloat   * GEGL_ALIGNED in_pixel;
  gfloat   * GEGL_ALIGNED out_pixel;

  in_pixel   = in_buf;
  out_pixel  = out_buf;

  noise[0] = o->red;
  noise[1] = o->green;
  noise[2] = o->blue;
  noise[3] = o->alpha;

  x = roi->x;
  y = roi->y;

  for (i=0; i<n_pixels; i++)
  {
    for (b = 0; b < 4; b++)
    {
      if (b == 0 || o->independent || b == 3 )
         noise_coeff = noise[b] * gauss (o->seed, &rint, x, y) * 0.5;

      if (noise[b] > 0.0)
      {
        if (o->correlated)
        {
          tmp = (in_pixel[b] + (in_pixel[b] * (noise_coeff / 0.5)) );
        }
        else
        {
          tmp = (in_pixel[b] + noise_coeff );
        }

        out_pixel[b] = CLAMP(tmp, 0.0, 1.0);
      }
      else
      {
        out_pixel[b] = in_pixel[b];
      }
    }

    in_pixel  += 4;
    out_pixel += 4;

    x++;
    if (x >= roi->x + roi->width)
      {
        x = roi->x;
        y++;
      }
  }

  return TRUE;
}
Exemple #5
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);

  gfloat *src_buf;
  gfloat *dst_buf;

  gint n_pixels = result->width * result->height;
  GeglRectangle src_rect;

  gfloat *current_pix;
  gfloat *target_pix;
  gfloat *dst_pix;

  gint x, y;
  gint total_src_pixels;
  gint total_dst_pixels;

  gint bleed_max;
  gint bleed_index;
  gfloat blend_coefficient;

  GHashTable *bleed_table;

  static GMutex mutex = { 0, };

  g_mutex_lock (&mutex);
  if (!o->chant_data)
    {
      o->chant_data = g_hash_table_new_full (tuple_hash, tuple_equal, g_free, g_free);
      calculate_bleed (operation, input);
    }
  g_mutex_unlock (&mutex);

  bleed_table = (GHashTable*) o->chant_data;

  src_rect.x      = result->x - op_area->left;
  src_rect.width  = result->width + op_area->left + op_area->right;
  src_rect.y      = result->y - op_area->top;
  src_rect.height = result->height + op_area->top + op_area->bottom;

  total_src_pixels = src_rect.width * src_rect.height;
  total_dst_pixels = result->width * result->height;

  src_buf = gegl_malloc (4 * total_src_pixels * sizeof (gfloat));
  dst_buf = gegl_malloc (4 * total_dst_pixels * sizeof (gfloat));

  gegl_buffer_get (input,
                   &src_rect,
                   1.0,
                   babl_format ("RGBA float"),
                   src_buf,
                   GEGL_AUTO_ROWSTRIDE,
                   GEGL_ABYSS_NONE);

  current_pix = src_buf + 4*(o->strength + src_rect.width * o->strength);
  dst_pix = dst_buf;
  x = 0;
  y = 0;
  n_pixels = result->width * result->height;
  bleed_max = 0;
  bleed_index = 0;
  while (n_pixels--)
    {
      gint i;
      pair key = {x + result->x, y + result->y};
      gint *bleed = g_hash_table_lookup (bleed_table, &key);

      if (x == 0) {
        for (i = 0; i < o->strength; i++)
          {
            pair key = {result->x - i, y + result->y};
            gint *bleed = g_hash_table_lookup (bleed_table, &key);
            if (bleed) {
              bleed_max = *bleed;
              bleed_index = *bleed - i;
              break;
            }
          }
      }

      for (i = 0; i < 4; i++)
        dst_pix[i] = current_pix[i];

      if (bleed)
        {
          gfloat blend_color[4];
          gfloat blend_amount[4];
          gfloat *blend_pix;

          bleed_max = *bleed;
          bleed_index = *bleed;
          target_pix = current_pix;
          blend_pix = current_pix - 12;
          for (i = 0; i < 4; i++)
            {
              blend_amount[i] = target_pix[i] - blend_pix[i];
              blend_color[i] = blend_pix[i] + blend_amount[i];
              dst_pix[i] = (2.0 * blend_color[i] + dst_pix[i])/3.0;
            }
        }
      else if (bleed_index > 0)
        {
          gfloat blend_color[4];
          gfloat blend_amount[4];
          gfloat *blend_pix;
          bleed_index--;
          blend_coefficient = 1.0 - ((gfloat) bleed_index)/(gfloat) bleed_max;
          blend_pix = current_pix - 4 * (bleed_max - bleed_index) - 12;
          target_pix = current_pix;
          for (i = 0; i < 4; i++)
            {
              blend_amount[i] = target_pix[i] - blend_pix[i];
              blend_color[i] = blend_pix[i] + blend_amount[i] * blend_coefficient;
              dst_pix[i] = (2.0 * blend_color[i] + dst_pix[i])/3.0;
            }
        }

      x++;
      current_pix += 4;
      dst_pix += 4;
      if (x >= result->width)
        {
          bleed_max = 0;
          bleed_index = 0;
          x = 0;
          y++;
          current_pix += 8 * o->strength;
        }
    }
  gegl_buffer_set (output,
                   result,
                   1,
                   babl_format ("RGBA float"),
                   dst_buf,
                   GEGL_AUTO_ROWSTRIDE);

  gegl_free (src_buf);
  gegl_free (dst_buf);

  return TRUE;
}
Exemple #6
0
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat       *GEGL_ALIGNED in_pixel;
  gfloat       *GEGL_ALIGNED out_pixel;
  GeglRectangle whole_region;
  gfloat        lightness, chroma, hue, alpha;
  gint          i;
  gint          x, y;

  in_pixel  = in_buf;
  out_pixel = out_buf;

  x = roi->x;
  y = roi->y;

  whole_region = *(gegl_operation_source_get_bounding_box (operation, "input"));

  for (i = 0; i < n_pixels; i++)
  {
    /* n is independent from the roi, but from the whole image */
    gint n = (3 * o->holdness + 4) * (x + whole_region.width * y);

    lightness = in_pixel[0];
    chroma    = in_pixel[1];
    hue       = in_pixel[2];
    alpha     = in_pixel[3];

    if ((o->hue_distance > 0) && (chroma > 0))
      hue = randomize_value (hue, 0.0, 359.0, TRUE, o->hue_distance,
                             o->holdness, x, y, n, o->rand);

    n += o->holdness + 1;
    if (o->chroma_distance > 0) {
      if (chroma == 0)
        hue = gegl_random_float_range (o->rand, x, y, 0, n, 0.0, 360.0);
      chroma = randomize_value (chroma, 0.0, 100.0, FALSE, o->chroma_distance,
                                o->holdness, x, y, n+1, o->rand);
    }

    n += o->holdness + 2;
    if (o->lightness_distance > 0)
      lightness = randomize_value (lightness, 0.0, 100.0, FALSE,
                                   o->lightness_distance, o->holdness,
                                   x, y, n, o->rand);

    /*n += o->holdness + 1*/
    out_pixel[0] = lightness;
    out_pixel[1] = chroma;
    out_pixel[2] = hue;
    out_pixel[3] = alpha;

    in_pixel  += 4;
    out_pixel += 4;

    x++;
    if (x >= roi->x + roi->width)
      {
        x = roi->x;
        y++;
      }
  }

  return TRUE;
}
Exemple #7
0
static void
prepare (GeglOperation *operation)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  Priv *p= (Priv*)o->chant_data;

  if (p == NULL)
    init (o);
  p = (Priv*)o->chant_data;

  gegl_operation_set_format (operation, "output",
                            babl_format_new (
                                  babl_model ("R'G'B'"),
                                  babl_type ("u8"),
                                  babl_component ("B'"),
                                  babl_component ("G'"),
                                  babl_component ("R'"),
                                  NULL));

  p->w = o->width;
  p->h = o->height;

  if (!p->vd)
    {
      p->vd = g_malloc0 (sizeof (v4ldevice));

      if (v4lopen (o->path, p->vd))
        return;

      p->active = 1;

      if (v4lmmap (p->vd))
        return;

      v4lsetdefaultnorm (p->vd, VIDEO_MODE_PAL);
      v4lgetcapability (p->vd);

      if (!(p->vd->capability.type & VID_TYPE_CAPTURE)) {
          g_warning (
               "video_init: This device seems not to support video capturing.\n");
         return;
      }
    }

  if (p->w != p->w_stored || p->h != p->h_stored)
    {

      if (p->w > p->vd->capability.maxwidth
          || p->h > p->vd->capability.maxheight)
        {
          p->w = p->vd->capability.maxwidth;
          p->h = p->vd->capability.maxheight;
          o->width = p->w;
          o->height = p->h;
          g_warning ( "capturing size is set to %dx%d.\n", p->w, p->h);
        }
      else if (p->w < p->vd->capability.minwidth
               || p->h < p->vd->capability.minheight)
        {
          p->w = p->vd->capability.minwidth;
          p->h = p->vd->capability.minheight;
          o->width = p->w;
          o->height = p->h;
          g_warning ( "capturing size is set to %dx%d.\n", p->w, p->h);
        }

      p->w_stored = p->w;
      p->h_stored = p->h;

      /* FIXME: try other palettes as well, do some profiling on the spca
       * based cameras to see what is the ideal format wrt performance
       */

      if (!v4lsetpalette (p->vd, VIDEO_PALETTE_RGB24))
        {
           p->decode=0;
        }
      else if (!v4lsetpalette (p->vd, VIDEO_PALETTE_YUV420P))
        {
           p->decode=1;
        }
      else
        {
          g_warning ( "oops,. no usable v4l format found\n");
          return;
        }
      v4lgrabinit (p->vd, p->w, p->h);
      v4lgrabf (p->vd);
    }
}
Exemple #8
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         const GeglRectangle *result)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglBuffer   *source;
  SDL_Surface **sdl_outwin = NULL;      /*op_sym (op, "sdl_outwin");*/

  init_sdl ();
  if (!handle)
    handle = g_timeout_add (500, idle, NULL);

  if (!o->screen ||
       o->width  != result->width ||
       o->height != result->height)
    {
      if (sdl_outwin)
        {
          if (o->screen)
            {
              SDL_FreeSurface (o->screen);
              o->screen = NULL;
            }

          o->screen = SDL_CreateRGBSurface (SDL_SWSURFACE,
                                            result->width, result->height, 32, 0xff0000,
                                            0x00ff00, 0x0000ff, 0x000000);

          *sdl_outwin = o->screen;
          if (!o->screen)
            {
              fprintf (stderr, "CreateRGBSurface failed: %s\n",
                       SDL_GetError ());
              return -1;
            }
        }
      else
        {
          o->screen = SDL_SetVideoMode (result->width, result->height, 32, SDL_SWSURFACE);
          if (!o->screen)
            {
              fprintf (stderr, "Unable to set SDL mode: %s\n",
                       SDL_GetError ());
              return -1;
            }
        }
      o->width  = result->width ;
      o->height = result->height;
    }

  /*
   * There seems to be a valid faster path to the SDL desired display format
   * in B'G'R'A, perhaps babl should have been able to figure this out ito?
   *
   */
  source = gegl_buffer_create_sub_buffer (input, result);
  gegl_buffer_get (source,
       1.0,
       NULL,
       babl_format_new (babl_model ("RGBA"),
                        babl_type ("u8"),
                        babl_component ("B"),
                        babl_component ("G"),
                        babl_component ("R"),
                        babl_component ("A"),
                        NULL),
       ((SDL_Surface*)o->screen)->pixels, GEGL_AUTO_ROWSTRIDE);
  g_object_unref (source);

  if (!sdl_outwin)
    {
      SDL_UpdateRect (o->screen, 0, 0, 0, 0);
      SDL_WM_SetCaption (o->window_title, o->icon_title);
    }

  o->width = result->width ;
  o->height = result->height;

  return  TRUE;
}
Exemple #9
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);

  gint x = result->x; /* initial x                   */
  gint y = result->y; /*           and y coordinates */

  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat));

  gfloat *out_pixel = dst_buf;

  GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                  babl_format ("RGBA float"),
                                                  o->sampler_type);

  gint n_pixels = result->width * result->height;

  while (n_pixels--)
    {
      gdouble coordsx = 0.0;
      gdouble coordsy = 0.0;
      gdouble radius = 0.0;
      gdouble shift = 0.0;
      gdouble ux = 0.0; /* unit vector of the radius */
      gdouble uy = 0.0;
      gdouble vx = 0.0; /* orthogonal vector of u */
      gdouble vy = 0.0;
      gdouble dx = 0.0;
      gdouble dy = 0.0;

      dx = (gdouble)x-o->x;
      dy = (gdouble)y-o->y;

      radius = sqrt( dx * dx + dy * dy );
      shift = o->amplitude * sin(2.0 * G_PI * radius / o->period + 2.0 * G_PI * o->phi);

      ux = dx / radius;
      uy = dy / radius;
      vx = -uy;
      vy = ux;

      coordsx = x + shift * vx;
      coordsy = y + shift * vy;


      gegl_sampler_get (sampler,
                        coordsx,
                        coordsy,
                        NULL,
                        out_pixel);

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=result->x + result->width)
        {
          x=result->x;
          y++;
        }
    }

  gegl_buffer_set (output, result, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);

  g_object_unref (sampler);

  return  TRUE;
}
Exemple #10
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  Priv       *p = (Priv*)o->chant_data;
  guchar     *capbuf;
  static gboolean inited = FALSE;

    if (!inited && o->fps != 0)
      {
        inited= TRUE;
        g_timeout_add (1000/o->fps, update, operation);
      }

  if (!p->active)
    return FALSE;

  v4lgrabf (p->vd);
  capbuf = v4lgetaddress (p->vd);
  v4lsyncf (p->vd);

  if (!capbuf)
    {
      g_warning ("no capbuf found");
      return FALSE;
    }

  if (p->decode)
    {
      guchar foobuf[o->width*o->height*3];
          /* XXX: foobuf is unneeded the conversions resets for every
           * scanline and could thus have been done in a line by line
           * manner an fed into the output buffer
           */
      gint y;
      for (y = 0; y < p->h; y++)
        {
          gint       x;

          guchar *dst = &foobuf[y*p->w*3];
          guchar *ysrc = (guchar *) (capbuf + (y) * (p->w) * 1);
          guchar *usrc = (guchar *) (capbuf + (p->w) * (p->h) + (y) / 2 * (p->w) / 2);
          guchar *vsrc = (guchar *) (capbuf + (p->w) * (p->h) + ((p->w) * (p->h)) / 4 + (y) / 2 * (p->w) / 2);

          for (x = 0; x < p->w; x++)
            {

              gint       R, G, B;

#ifndef byteclamp
#define byteclamp(j) do{if(j<0)j=0; else if(j>255)j=255;}while(0)
#endif

#define YUV82RGB8(Y,U,V,R,G,B)do{\
                  R= ((Y<<15)                 + 37355*(V-128))>>15;\
                  G= ((Y<<15) -12911* (U-128) - 19038*(V-128))>>15;\
                  B= ((Y<<15) +66454* (U-128)                )>>15;\
                  byteclamp(R);\
                  byteclamp(G);\
                  byteclamp(B);\
              }while(0)

      /* the format support for this code is not very good, but it
       * works for the devices I have tested with, conversion even
       * for chroma subsampled images is something we should let
       * babl handle.
       */
              YUV82RGB8 (*ysrc, *usrc, *vsrc, R, G, B);
              dst[0] = B;
              dst[1] = G;
              dst[2] = R;

              dst += 3;
              ysrc++;
              if (x % 2)
                {
                  usrc++;
                  vsrc++;
                }
            }
        }
      gegl_buffer_set (output, NULL, NULL, foobuf, GEGL_AUTO_ROWSTRIDE);
    }
  else
    {
      gegl_buffer_set (output, NULL, NULL, capbuf, GEGL_AUTO_ROWSTRIDE);
    }
  return  TRUE;
}
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglRectangle src_rect;
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area;
  gfloat* in_buf;
  gfloat* out_buf;
  gfloat* out_pixel;
  gint x,y;

  gdouble theta = o->angle * G_PI / 180.0;
  gdouble offset_x = o->length * cos(theta);
  gdouble offset_y = o->length * sin(theta);
  gint num_steps = (gint)ceil(o->length) + 1;
  gfloat inv_num_steps = 1.0f / num_steps;

  op_area = GEGL_OPERATION_AREA_FILTER (operation);

  src_rect = *roi;
  src_rect.x -= op_area->left;
  src_rect.y -= op_area->top;
  src_rect.width += op_area->left + op_area->right;
  src_rect.height += op_area->top + op_area->bottom;

  if (gegl_cl_is_accelerated ())
    if (cl_process (operation, input, output, roi, &src_rect))
      return TRUE;

  in_buf = g_new (gfloat, src_rect.width * src_rect.height * 4);
  out_buf = g_new0 (gfloat, roi->width * roi->height * 4);
  out_pixel = out_buf;

  gegl_buffer_get (input, &src_rect, 1.0, babl_format ("RaGaBaA float"), in_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  for (y=0; y<roi->height; ++y)
    {
      for (x=0; x<roi->width; ++x)
        {
          gint step;
          gint c;
          gint px = x+roi->x;
          gint py = y+roi->y;
          gfloat sum[4] = {0,0,0,0};
          for (step=0; step<num_steps; ++step)
            {
              gdouble t = num_steps == 1 ? 0.0 : step / (gdouble)(num_steps-1) - 0.5;

              /* get the interpolated pixel position for this step */
              gdouble xx = px + t*offset_x;
              gdouble yy = py + t*offset_y;
              gint ix = (gint)floor(xx);
              gint iy = (gint)floor(yy);
              gdouble dx = xx - floor(xx);
              gdouble dy = yy - floor(yy);

              /* do bilinear interpolation to get a nice smooth result */
              gfloat *pix0, *pix1, *pix2, *pix3;
              gfloat mixy0[4];
              gfloat mixy1[4];

              pix0 = get_pixel_color(in_buf, &src_rect, ix, iy);
              pix1 = get_pixel_color(in_buf, &src_rect, ix+1, iy);
              pix2 = get_pixel_color(in_buf, &src_rect, ix, iy+1);
              pix3 = get_pixel_color(in_buf, &src_rect, ix+1, iy+1);
              for (c=0; c<4; ++c)
                {
                  mixy0[c] = dy*(pix2[c] - pix0[c]) + pix0[c];
                  mixy1[c] = dy*(pix3[c] - pix1[c]) + pix1[c];
                  sum[c] += dx*(mixy1[c] - mixy0[c]) + mixy0[c];
                }
            }

          for (c=0; c<4; ++c)
            *out_pixel++ = sum[c] * inv_num_steps;
        }
    }

  gegl_buffer_set (output, roi, 0, babl_format ("RaGaBaA float"), out_buf, GEGL_AUTO_ROWSTRIDE);

  g_free (in_buf);
  g_free (out_buf);


  return  TRUE;
}
Exemple #12
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);
  GeglBuffer              *tmp;
  gfloat                  *src_buf;
  gfloat                  *dst_buf;
  gfloat                  *in_pixel;
  gfloat                  *out_pixel;
  gint                     n_pixels = result->width * result->height;
  gint                     width    = result->width;
  GeglRectangle            src_rect;
  gint                     total_pixels;
  gint                     i;

  tmp = gegl_buffer_new (result, babl_format ("RGBA float"));

  src_rect.x      = result->x - op_area->left;
  src_rect.width  = result->width + op_area->left + op_area->right;
  src_rect.y      = result->y - op_area->top;
  src_rect.height = result->height + op_area->top + op_area->bottom;

  total_pixels = src_rect.height * src_rect.width;

  src_buf = g_slice_alloc (4 * total_pixels * sizeof (gfloat));
  dst_buf = g_slice_alloc (4 * n_pixels * sizeof (gfloat));

  gegl_buffer_copy (input, NULL, tmp, NULL);

  for (i = 0; i < o->repeat; i++)
    {
      gint x, y, n;

      x = result->x;
      y = result->y;
      n = 0;

      n_pixels = result->width * result->height;

      gegl_buffer_get (tmp, &src_rect, 1.0,
                       babl_format ("RGBA float"), src_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);

      in_pixel  = src_buf + (src_rect.width + 1) * 4;
      out_pixel = dst_buf;

      while (n_pixels--)
        {
          gint b;

          if (gegl_random_double_range (o->seed, x, y, 0, n++, 0.0, 100.0) <=
              o->pct_random)
            {
              gint k = gegl_random_int_range (o->seed, x, y, 0, n++, 0, 9);

              for (b = 0; b < 4; b++)
                {
                  switch (k)
                    {
                    case 0:
                      out_pixel[b] = in_pixel[b - src_rect.width * 4 - 4];
                      break;
                    case 1:
                      out_pixel[b] = in_pixel[b - src_rect.width * 4];
                      break;
                    case 2:
                      out_pixel[b] = in_pixel[b - src_rect.width * 4 + 4];
                      break;
                    case 3:
                      out_pixel[b] = in_pixel[b - 4];
                      break;
                    case 4:
                      out_pixel[b] = in_pixel[b];
                      break;
                    case 5:
                      out_pixel[b] = in_pixel[b + 4];
                      break;
                    case 6:
                      out_pixel[b] = in_pixel[b + src_rect.width * 4 - 4];
                      break;
                    case 7:
                      out_pixel[b] = in_pixel[b + src_rect.width * 4];
                      break;
                    case 8:
                      out_pixel[b] = in_pixel[b + src_rect.width * 4 + 4];
                      break;
                    }
                }
            }
          else
            {
              for (b = 0; b < 4; b++)
                {
                  out_pixel[b] = in_pixel[b];
                }
            }

          if (n_pixels % width == 0)
            in_pixel += 12;
          else
            in_pixel += 4;

          out_pixel += 4;

          x++;
          if (x >= result->x + result->width)
            {
              x = result->x;
              y++;
            }
        }

      gegl_buffer_set (tmp, result, 0,
                       babl_format ("RGBA float"), dst_buf,
                       GEGL_AUTO_ROWSTRIDE);
    }

  gegl_buffer_copy (tmp, NULL, output, NULL);

  g_slice_free1 (4 * total_pixels * sizeof (gfloat), src_buf);
  g_slice_free1 (4 * n_pixels * sizeof (gfloat), dst_buf);

  return TRUE;
}
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o       = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area = GEGL_OPERATION_AREA_FILTER (operation);

  GeglRectangle   rect;
  GeglRectangle   boundary = get_effective_area (operation);
  gfloat         *src_buf;
  gfloat         *dst_buf;
  gdouble       **matrix;

  gchar         *type;
  gint           x, y;
  gdouble        matrixsum = 0.0;

  type = "RGBA float";

  matrix = g_new0 (gdouble*, MATRIX_SIZE);

  for (x=0; x < MATRIX_SIZE ;x++)
    matrix[x] = g_new0 (gdouble, MATRIX_SIZE);

  make_matrix (o, matrix);

  if (o->norm)
    normalize_o (o, matrix);

  for (x=0; x < MATRIX_SIZE; x++)
    for (y=0; y < MATRIX_SIZE; y++)
      matrixsum += fabs (matrix[x][y]);

  rect.x      = result->x - op_area->left;
  rect.width  = result->width + op_area->left + op_area->right;
  rect.y      = result->y - op_area->top;
  rect.height = result->height + op_area->top + op_area->bottom;

  src_buf = g_new0 (gfloat, rect.width * rect.height * 4);
  dst_buf = g_new0 (gfloat, result->width * result->height * 4);

  gegl_buffer_get (input, &rect, 1.0, babl_format (type), src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  /*fill src_buf with wrap pixels if it is the case*/

  if (o->div != 0)
    {
      for (y=result->y; y < result->height + result->y; y++)
        for (x=result->x; x < result->width + result->x; x++)
          convolve_pixel (src_buf, dst_buf, result, &rect, &boundary,
                          matrix, o, input, x, y, matrixsum);

      gegl_buffer_set (output, result, 0, babl_format (type),
                       dst_buf, GEGL_AUTO_ROWSTRIDE);
    }
  else
    gegl_buffer_set (output, &rect, 0, babl_format (type),
                     src_buf, GEGL_AUTO_ROWSTRIDE);



  g_free (src_buf);
  g_free (dst_buf);

  return TRUE;
}
Exemple #14
0
static gboolean
cl_process (GeglOperation       *self,
            cl_mem               in_tex,
            cl_mem               out_tex,
            size_t               global_worksize,
            const GeglRectangle *roi,
            gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (self);
  gint       num_sampling_points;
  gdouble    *xs, *ys;
  gfloat     *ysf = NULL;
  cl_mem     cl_curve = NULL;
  cl_ulong   cl_max_constant_size;
  cl_int     cl_err = 0;

  num_sampling_points = o->sampling_points;

  if (!cl_data)
    {
      const char *kernel_name[] = {"cl_contrast_curve",NULL};
      cl_data = gegl_cl_compile_and_build (contrast_curve_cl_source,
                                           kernel_name);
    }
  if (!cl_data)
    return TRUE;

  if (num_sampling_points > 0)
    {
      xs = g_new (gdouble, num_sampling_points);
      ys = g_new (gdouble, num_sampling_points);

      gegl_curve_calc_values (o->curve, 0.0, 1.0, num_sampling_points, xs, ys);
      g_free (xs);

      /*We need to downscale the array to pass it to the GPU*/
      ysf = g_new (gfloat, num_sampling_points);
      copy_double_array_to_float_array (ys, ysf, num_sampling_points);
      g_free (ys);

      cl_err = gegl_clGetDeviceInfo (gegl_cl_get_device (),
                                     CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
                                     sizeof (cl_ulong),
                                     &cl_max_constant_size,
                                     NULL);
      CL_CHECK;

      GEGL_NOTE (GEGL_DEBUG_OPENCL, "Max Constant Mem Size: %lu bytes",
                 (unsigned long) cl_max_constant_size);

      if (sizeof (cl_float) * num_sampling_points < cl_max_constant_size)
        {
          cl_curve = gegl_clCreateBuffer (gegl_cl_get_context (),
                                          CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY,
                                          num_sampling_points * sizeof (cl_float),
                                          ysf, &cl_err);
          CL_CHECK;
          cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 0, sizeof (cl_mem),
                                        (void*) &in_tex);
          CL_CHECK;
          cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 1, sizeof (cl_mem),
                                        (void*) &out_tex);
          CL_CHECK;
          cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 2, sizeof (cl_mem),
                                        (void*) &cl_curve);
          CL_CHECK;
          cl_err = gegl_clSetKernelArg (cl_data->kernel[0], 3, sizeof (gint),
                                        (void*) &num_sampling_points);
          CL_CHECK;
          cl_err = gegl_clEnqueueNDRangeKernel (gegl_cl_get_command_queue (),
                                                cl_data->kernel[0], 1,
                                                NULL, &global_worksize, NULL,
                                                0, NULL, NULL);
          CL_CHECK;

          cl_err = gegl_clFinish (gegl_cl_get_command_queue ());
          CL_CHECK;

          cl_err = gegl_clReleaseMemObject (cl_curve);
          CL_CHECK_ONLY (cl_err);
        }
      else
        {
          /*If the curve size doesn't fit constant memory is better to use CPU*/
          GEGL_NOTE (GEGL_DEBUG_OPENCL,
                     "Not enough constant memory for the curve");
          g_free (ysf);
          return TRUE;
        }

      g_free (ysf);
      return FALSE;
error:
      if (ysf)
        g_free (ysf);
      if (cl_curve)
        gegl_clReleaseMemObject (cl_curve);

      return TRUE;
    }
  else  /*If the curve doesn't have a lookup table is better to use CPU*/
    {
      GEGL_NOTE (GEGL_DEBUG_OPENCL,
                 "Curve not suitable to be computed in the GPU");
      return TRUE;
    }
}
Exemple #15
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o                    = GEGL_CHANT_PROPERTIES (operation);

  gint x = result->x; /* initial x                   */
  gint y = result->y; /*           and y coordinates */

  gfloat *dst_buf = g_slice_alloc (result->width * result->height * 4 * sizeof(gfloat));

  gfloat *out_pixel = dst_buf;

  GeglSampler *sampler = gegl_buffer_sampler_new (input,
                                                  babl_format ("RGBA float"),
                                                  o->sampler_type);

  gint n_pixels = result->width * result->height;

  GeglAbyssPolicy abyss = o->tileable ? GEGL_ABYSS_LOOP : GEGL_ABYSS_NONE;

  while (n_pixels--)
    {
      gdouble shift;
      gdouble coordsx;
      gdouble coordsy;
      gdouble lambda;

      gdouble angle_rad = o->angle / 180.0 * G_PI;
      gdouble nx = x * cos (angle_rad) + y * sin (angle_rad);

      switch (o->wave_type)
        {
          case GEGl_RIPPLE_WAVE_TYPE_SAWTOOTH:
            lambda = div (nx,o->period).rem - o->phi * o->period;
            if (lambda < 0)
              lambda += o->period;
            shift = o->amplitude * (fabs (((lambda / o->period) * 4) - 2) - 1);
            break;
          case GEGl_RIPPLE_WAVE_TYPE_SINE:
          default:
            shift = o->amplitude * sin (2.0 * G_PI * nx / o->period + 2.0 * G_PI * o->phi);
            break;
        }

      coordsx = x + shift * sin (angle_rad);
      coordsy = y + shift * cos (angle_rad);

      gegl_sampler_get (sampler,
                        coordsx,
                        coordsy,
                        NULL,
                        out_pixel,
                        abyss);

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=result->x + result->width)
        {
          x=result->x;
          y++;
        }
    }

  gegl_buffer_set (output, result, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_slice_free1 (result->width * result->height * 4 * sizeof(gfloat), dst_buf);

  g_object_unref (sampler);

  return  TRUE;
}
Exemple #16
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  FILE         *fp;
  pnm_struct    img;
  GeglRectangle rect = {0,0,0,0};
  gboolean      ret = FALSE;

  fp = (!strcmp (o->path, "-") ? stdin : fopen (o->path,"rb"));

  if (!fp)
    return FALSE;

  if (!ppm_load_read_header (fp, &img))
    goto out;

  /* Allocating Array Size */

  /* Should use g_try_malloc(), but this causes crashes elsewhere because the
   * error signalled by returning FALSE isn't properly acted upon. Therefore
   * g_malloc() is used here which aborts if the requested memory size can't be
   * allocated causing a controlled crash. */
  img.data = (guchar*) g_malloc (img.numsamples * img.bpc);

  /* No-op without g_try_malloc(), see above. */
  if (! img.data)
    {
      g_warning ("Couldn't allocate %" G_GSIZE_FORMAT " bytes, giving up.", ((gsize)img.numsamples * img.bpc));
      goto out;
    }

  rect.height = img.height;
  rect.width = img.width;

  switch (img.bpc)
    {
    case 1:
      gegl_buffer_get (output, &rect, 1.0, babl_format ("R'G'B' u8"), img.data,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
      break;

    case 2:
      gegl_buffer_get (output, &rect, 1.0, babl_format ("R'G'B' u16"), img.data,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
      break;

    default:
      g_warning ("%s: Programmer stupidity error", G_STRLOC);
    }

  ppm_load_read_image (fp, &img);

  switch (img.bpc)
    {
    case 1:
      gegl_buffer_set (output, &rect, 0, babl_format ("R'G'B' u8"), img.data,
                       GEGL_AUTO_ROWSTRIDE);
      break;

    case 2:
      gegl_buffer_set (output, &rect, 0, babl_format ("R'G'B' u16"), img.data,
                       GEGL_AUTO_ROWSTRIDE);
      break;

    default:
      g_warning ("%s: Programmer stupidity error", G_STRLOC);
    }

  g_free (img.data);

  ret = TRUE;

 out:
  if (stdin != fp)
    fclose (fp);

  return ret;
}
Exemple #17
0
static gboolean process(GeglOperation *op, void *in_buf, void *out_buf, glong n_pixels,
                        const GeglRectangle *roi)
{
#if 0 // precise computation
  gfloat *in = in_buf;
  gfloat *out = out_buf;
  gint    i;

  gfloat gamma_value  = GEGL_CHANT_PROPERTIES (op)->gamma_value;
  gfloat linear_value = GEGL_CHANT_PROPERTIES (op)->linear_value;
  for (i=0; i<n_pixels; i++)
  {
    gfloat a, b, c, g;
    if(linear_value<1.0)
    {
      g = gamma_value*(1.0-linear_value)/(1.0-gamma_value*linear_value);
      a = 1.0/(1.0+linear_value*(g-1));
      b = linear_value*(g-1)*a;
      c = powf(a*linear_value+b, g)/linear_value;
    }
    else
    {
      a = b = g = 0.0;
      c = 1.0;
    }

    gint   j;
    gfloat col;
    for (j=0; j<3; j++)
    {
      col = in[j];
      if(col < linear_value) col = fminf(c*col, 1.0);
      else col = fminf(powf(a*col+b, g), 1.0);
      out[j] = col;
    }
    in += 3;
    out+= 3;
  }
#else // table:
  // printf("gamma processing %d samples\n", n_pixels);
  guint16 *in = in_buf;
  guint8 *out = out_buf;
  gint i;

  gfloat gamma_value = GEGL_CHANT_PROPERTIES(op)->gamma_value;
  gfloat linear_value = GEGL_CHANT_PROPERTIES(op)->linear_value;
  guint8 table[0x10000];
  gfloat a, b, c, g;
  if(linear_value < 1.0)
  {
    g = gamma_value * (1.0 - linear_value) / (1.0 - gamma_value * linear_value);
    a = 1.0 / (1.0 + linear_value * (g - 1));
    b = linear_value * (g - 1) * a;
    c = powf(a * linear_value + b, g) / linear_value;
  }
  else
  {
    a = b = g = 0.0;
    c = 1.0;
  }
  for(int k = 0; k < 0x10000; k++)
  {
    gint32 tmp;
    if(k < 0x10000 * linear_value)
      tmp = MIN(c * k, 0xFFFF);
    else
      tmp = MIN(pow(a * k / 0x10000 + b, g) * 0x10000, 0xFFFF);
    table[k] = tmp >> 8;
  }
  for(i = 0; i < n_pixels; i++)
  {
    gint j;
    for(j = 0; j < 3; j++) out[2 - j] = table[in[j]];
    in += 3;
    out += 4;
  }
#endif
  return TRUE;
}
Exemple #18
0
static gboolean
reinhard05_process (GeglOperation       *operation,
                    GeglBuffer          *input,
                    GeglBuffer          *output,
                    const GeglRectangle *result)
{
  const GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  const gint  pix_stride = 4, /* RGBA */
              RGB        = 3;

  gfloat *lum,
         *pix;
  gfloat  key, contrast, intensity,
          chrom      =       o->chromatic,
          chrom_comp = 1.0 - o->chromatic,
          light      =       o->light,
          light_comp = 1.0 - o->light;

  stats   world_lin,
          world_log,
          channel [RGB],
          normalise;

  gint    i, c;

  g_return_val_if_fail (operation, FALSE);
  g_return_val_if_fail (input, FALSE);
  g_return_val_if_fail (output, FALSE);
  g_return_val_if_fail (result, FALSE);

  g_return_val_if_fail (babl_format_get_n_components (babl_format (OUTPUT_FORMAT)) == pix_stride, FALSE);

  g_return_val_if_fail (chrom      >= 0.0 && chrom      <= 1.0, FALSE);
  g_return_val_if_fail (chrom_comp >= 0.0 && chrom_comp <= 1.0, FALSE);
  g_return_val_if_fail (light      >= 0.0 && light      <= 1.0, FALSE);
  g_return_val_if_fail (light_comp >= 0.0 && light_comp <= 1.0, FALSE);


  /* Obtain the pixel data */
  lum = g_new (gfloat, result->width * result->height),
  gegl_buffer_get (input, 1.0, result, babl_format ("Y float"),
                   lum, GEGL_AUTO_ROWSTRIDE);

  pix = g_new (gfloat, result->width * result->height * pix_stride);
  gegl_buffer_get (input, 1.0, result, babl_format (OUTPUT_FORMAT),
                   pix, GEGL_AUTO_ROWSTRIDE);

  /* Collect the image stats, averages, etc */
  reinhard05_stats_start (&world_lin);
  reinhard05_stats_start (&world_log);
  reinhard05_stats_start (&normalise);
  for (i = 0; i < RGB; ++i)
    {
      reinhard05_stats_start (channel + i);
    }

  for (i = 0; i < result->width * result->height; ++i)
    {
      reinhard05_stats_update (&world_lin,                 lum[i] );
      reinhard05_stats_update (&world_log, logf (2.3e-5f + lum[i]));

      for (c = 0; c < RGB; ++c)
        {
          reinhard05_stats_update (channel + c, pix[i * pix_stride + c]);
        }
    }

  g_return_val_if_fail (world_lin.min >= 0.0, FALSE);

  reinhard05_stats_finish (&world_lin);
  reinhard05_stats_finish (&world_log);
  for (i = 0; i < RGB; ++i)
    {
      reinhard05_stats_finish (channel + i);
    }

  /* Calculate key parameters */
  key       = (logf (world_lin.max) -                 world_log.avg) /
              (logf (world_lin.max) - logf (2.3e-5f + world_lin.min));
  contrast  = 0.3 + 0.7 * powf (key, 1.4);
  intensity = expf (-o->brightness);

  g_return_val_if_fail (contrast >= 0.3 && contrast <= 1.0, FALSE);

  /* Apply the operator */
  for (i = 0; i < result->width * result->height; ++i)
    {
      gfloat local, global, adapt;

      if (lum[i] == 0.0)
        continue;

      for (c = 0; c < RGB; ++c)
        {
          gfloat *_p = pix + i * pix_stride + c,
                   p = *_p;

          local  = chrom      * p +
                   chrom_comp * lum[i];
          global = chrom      * channel[c].avg +
                   chrom_comp * world_lin.avg;
          adapt  = light      * local +
                   light_comp * global;

          p  /= p + powf (intensity * adapt, contrast);
          *_p = p;
          reinhard05_stats_update (&normalise, p);
        }
    }

  /* Normalise the pixel values */
  reinhard05_stats_finish (&normalise);

  for (i = 0; i < result->width * result->height; ++i)
    {
      for (c = 0; c < pix_stride; ++c)
        {
          gfloat *p = pix + i * pix_stride + c;
          *p        = (*p - normalise.min) / normalise.range;
        }
    }

  /* Cleanup and set the output */
  gegl_buffer_set (output, result, babl_format (OUTPUT_FORMAT), pix,
                   GEGL_AUTO_ROWSTRIDE);
  g_free (pix);
  g_free (lum);

  return TRUE;
}
Exemple #19
0
static cl_int
cl_process (GeglOperation       *operation,
            cl_mem               in_tex,
            cl_mem               out_tex,
            size_t               global_worksize,
            const GeglRectangle *roi,
            gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat      scale;
  gfloat      radius0, radius1;
  gint        roi_x, roi_y,x;
  gint        midx, midy;
  GeglRectangle *bounds = gegl_operation_source_get_bounding_box (operation, "input");

  gfloat length = hypot (bounds->width, bounds->height)/2;
  gfloat rdiff;
  gfloat cost, sint;
  gfloat      color[4];

  scale = bounds->width / (1.0 * bounds->height);
  scale = scale * (o->proportion) + 1.0 * (1.0-o->proportion);
  scale *= aspect_to_scale (o->squeeze);
  length = (bounds->width/2.0);

  if (scale > 1.0)
    length /= scale;

  gegl_color_get_pixel (o->color, babl_format ("RGBA float"), color);

  for (x=0; x<3; x++)   /* premultiply */
    color[x] *= color[3];

  radius0 = o->radius * (1.0-o->softness);
  radius1 = o->radius;
  rdiff = radius1-radius0;
  if (fabs (rdiff) < 0.0001)
    rdiff = 0.0001;

  midx = bounds->x + bounds->width * o->x;
  midy = bounds->y + bounds->height * o->y;

  roi_x = roi->x;
  roi_y = roi->y;

  /* constant for all pixels */
  cost = cos(-o->rotation * (G_PI*2/360.0));
  sint = sin(-o->rotation * (G_PI*2/360.0));

  if (!cl_data)
    {
      const char *kernel_name[] = {"vignette_cl",NULL};
      cl_data = gegl_cl_compile_and_build (kernel_source, kernel_name);
    }
  if (!cl_data) return 1;

  {
  const size_t gbl_size[2] = {roi->width, roi->height};

  gint   shape = o->shape;
  gfloat gamma = o->gamma;

  cl_int cl_err = 0;
  cl_float4 f_color;
  f_color.s[0] = color[0];
  f_color.s[1] = color[1];
  f_color.s[2] = color[2];
  f_color.s[3] = color[3];

  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 0,  sizeof(cl_mem),   (void*)&in_tex);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 1,  sizeof(cl_mem),   (void*)&out_tex);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 2,  sizeof(cl_float4),(void*)&f_color);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 3,  sizeof(cl_float), (void*)&scale);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 4,  sizeof(cl_float), (void*)&cost);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 5,  sizeof(cl_float), (void*)&sint);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 6,  sizeof(cl_int),   (void*)&roi_x);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 7,  sizeof(cl_int),   (void*)&roi_y);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 8,  sizeof(cl_int),   (void*)&midx);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 9,  sizeof(cl_int),   (void*)&midy);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 10, sizeof(cl_int),   (void*)&shape);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 11, sizeof(cl_float), (void*)&gamma);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 12, sizeof(cl_float), (void*)&length);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 13, sizeof(cl_float), (void*)&radius0);
  cl_err |= gegl_clSetKernelArg(cl_data->kernel[0], 14, sizeof(cl_float), (void*)&rdiff);
  if (cl_err != CL_SUCCESS) return cl_err;

  cl_err = gegl_clEnqueueNDRangeKernel(gegl_cl_get_command_queue (),
                                       cl_data->kernel[0], 2,
                                       NULL, gbl_size, NULL,
                                       0, NULL, NULL);
  if (cl_err != CL_SUCCESS) return cl_err;
  }

  return  CL_SUCCESS;
}
Exemple #20
0
static void
calculate_bleed (GeglOperation *operation,
                 GeglBuffer    *input)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle rectA, rectB;
  GeglBufferIterator *iter;
  gfloat max_length = (gfloat) o->strength;
  gfloat threshold  = o->threshold;
  GHashTable *bleed_table = o->chant_data;

  rectA = *gegl_operation_source_get_bounding_box (operation, "input");
  rectA.width -= 3;
  rectB = rectA;
  rectB.x += 3;

  if (rectA.width <= 0)
    return;

  iter = gegl_buffer_iterator_new (input,
                                   &rectA,
                                   0,
                                   babl_format ("RGBA float"),
                                   GEGL_BUFFER_READ,
                                   GEGL_ABYSS_NONE);

  gegl_buffer_iterator_add (iter,
                            input,
                            &rectB,
                            0,
                            babl_format ("RGBA float"),
                            GEGL_BUFFER_READ,
                            GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gint ix, iy;
      gfloat *pixelsA = (gfloat *)iter->data[0];
      gfloat *pixelsB = (gfloat *)iter->data[1];

      for (ix = 0; ix < iter->roi[0].width; ix++)
        for (iy = 0; iy < iter->roi[0].height; iy++)
          {
            gint idx = iy * iter->roi[0].width + ix * 4;
            if (threshold_exceeded (&pixelsA[idx], &pixelsB[idx], threshold))
              {
                gint x = ix + iter->roi[0].x;
                gint y = iy + iter->roi[0].y;
                pair *k = g_new (pair, 1);
                gint *v = g_new (gint, 1);
                gint bleed_length = 1 + gegl_random_int_range (o->rand, x, y, 0, 0, 0, max_length);

                k->x = x;
                k->y = y;

                *v = bleed_length;
                g_hash_table_insert (bleed_table, k, v);
              }
          }
    }
}
Exemple #21
0
static gboolean
process (GeglOperation       *operation,
         void                *in_buf,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat     *in_pixel =  in_buf;
  gfloat     *out_pixel = out_buf;
  gfloat      scale;
  gfloat      radius0, radius1;
  gint        x, y;
  gint        midx, midy;
  GeglRectangle *bounds = gegl_operation_source_get_bounding_box (operation, "input");
  gfloat length = hypot (bounds->width, bounds->height)/2;
  gfloat rdiff;
  gfloat cost, sint;
  gfloat costy, sinty;

  gfloat      color[4];

  scale = bounds->width / (1.0 * bounds->height);
  scale = scale * (o->proportion) + 1.0 * (1.0-o->proportion);

  scale *= aspect_to_scale (o->squeeze);

  length = (bounds->width/2.0);

  if (scale > 1.0)
    length /= scale;

  gegl_color_get_pixel (o->color, babl_format ("RGBA float"), color);

  for (x=0; x<3; x++)   /* premultiply */
    color[x] *= color[3];

  radius0 = o->radius * (1.0-o->softness);
  radius1 = o->radius;
  rdiff = radius1-radius0;
  if (fabs (rdiff) < 0.0001)
    rdiff = 0.0001;

  midx = bounds->x + bounds->width * o->x;
  midy = bounds->y + bounds->height * o->y;

  x = roi->x;
  y = roi->y;

  /* constant for all pixels */
  cost = cos(-o->rotation * (G_PI*2/360.0));
  sint = sin(-o->rotation * (G_PI*2/360.0));

  /* constant per scanline */
  sinty = sint * (y-midy) - midx;
  costy = cost * (y-midy) + midy;

  while (n_pixels--)
    {
      gfloat strength = 0.0;
      gfloat u, v;
#if 0
      u = cost * (x-midx) - sint * (y-midy) + midx;
      v = sint * (x-midx) + cost * (y-midy) + midy;
      /* optimized out of innerscanline loop */
#endif
      u = cost * (x-midx) - sinty;
      v = sint * (x-midx) + costy;

      if (length == 0.0)
        strength = 0.0;
      else
        {
          switch (o->shape)
          {
            case 0:  /* circle */
              strength = hypot ((u-midx) / scale, v-midy);      break;
            case 1: /* square */
              strength = MAX(ABS(u-midx) / scale, ABS(v-midy)); break;
            case 2: /* diamond */
              strength = ABS(u-midx) / scale + ABS(v-midy);     break;
          }
          strength /= length;
          strength = (strength-radius0) / rdiff;
        }

      if (strength<0.0)
        strength = 0.0;
      if (strength>1.0)
        strength = 1.0;

      if (o->gamma > 0.9999 && o->gamma < 2.0001)
        strength *= strength;  /* fast path for default gamma */
      else if (o->gamma != 1.0)
        strength = powf(strength, o->gamma); /* this gamma factor is
                                              * very expensive..
                                              */

      out_pixel[0]=in_pixel[0] * (1.0-strength) + color[0] * strength;
      out_pixel[1]=in_pixel[1] * (1.0-strength) + color[1] * strength;
      out_pixel[2]=in_pixel[2] * (1.0-strength) + color[2] * strength;
      out_pixel[3]=in_pixel[3] * (1.0-strength) + color[3] * strength;

      out_pixel += 4;
      in_pixel  += 4;

      /* update x and y coordinates */
      if (++x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
          sinty = sint * (y-midy) - midx;
          costy = cost * (y-midy) + midy;
        }
    }

  return  TRUE;
}
Exemple #22
0
static int
decode_frame (GeglOperation *operation,
              glong          frame)
{
    GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
    Priv       *p = (Priv*)o->chant_data;
    glong       prevframe = p->prevframe;
    glong       decodeframe;        /*< frame to be requested decoded */

    if (frame >= p->frames)
    {
        frame = p->frames - 1;
    }

    if (frame < 0)
    {
        frame = 0;
    }

    if (frame == prevframe)
    {
        return 0;
    }

    /* figure out which frame we should start decoding at */

    if (frame == prevframe + 1)
    {
        decodeframe = prevframe + 1;
    }
    else
    {
        decodeframe = prev_keyframe (p, frame);
        if (prevframe > decodeframe && prevframe < frame)
            decodeframe = prevframe + 1;
    }

    if (decodeframe < prevframe)
    {
        /* seeking backwards, since it ffmpeg doesn't allow us,. we'll reload the file */
        g_free (p->loadedfilename);
        p->loadedfilename = NULL;
        init (o);
    }

    while (decodeframe <= frame)
    {
        int       got_picture = 0;

        do
        {
            int       decoded_bytes;

            if (p->coded_bytes <= 0)
            {
                do
                {
                    if (av_read_packet (p->ic, &p->pkt) < 0)
                    {
                        fprintf (stderr, "av_read_packet failed for %s\n",
                                 o->path);
                        return -1;
                    }
                }
                while (p->pkt.stream_index != p->video_stream);

                p->coded_bytes = p->pkt.size;
                p->coded_buf = p->pkt.data;
            }
            decoded_bytes =
                avcodec_decode_video2 (p->video_st->codec, p->lavc_frame,
                                       &got_picture, &p->pkt);
            if (decoded_bytes < 0)
            {
                fprintf (stderr, "avcodec_decode_video failed for %s\n",
                         o->path);
                return -1;
            }

            p->coded_buf += decoded_bytes;
            p->coded_bytes -= decoded_bytes;
        }
        while (!got_picture);

        decodeframe++;
    }
    p->prevframe = frame;
    return 0;
}
Exemple #23
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *output,
         const GeglRectangle *result)
{
  GeglChantO   *o = GEGL_CHANT_PROPERTIES (operation);
  GeglRectangle rect = {0,0,0,0};
  jas_image_t *image;
  gint width, height, depth;
  gsize bpc;
  guchar *data = NULL;
  gboolean ret;
  int components[3];
  jas_matrix_t *matrices[3] = {NULL, NULL, NULL};
  gint i;
  gint row;
  gboolean b;
  gushort *ptr_s;
  guchar *ptr_b;

  image = NULL;
  width = height = depth = 0;

  if (!query_jp2 (o->path, &width, &height, &depth, &image))
    return FALSE;

  rect.height = height;
  rect.width = width;

  switch (depth)
    {
    case 8:
      bpc = sizeof (guchar);
      break;

    case 16:
      bpc = sizeof (gushort);
      break;

    default:
      g_warning ("%s: Programmer stupidity error", G_STRLOC);
      return FALSE;
    }

  data = (guchar *) g_malloc (width * height * 3 * bpc);
  ptr_s = (gushort *) data;
  ptr_b = data;

  switch (depth)
    {
    case 16:
      gegl_buffer_get (output, 1.0, &rect, babl_format ("R'G'B' u16"), data,
                       GEGL_AUTO_ROWSTRIDE);
      break;

    case 8:
    default:
      gegl_buffer_get (output, 1.0, &rect, babl_format ("R'G'B' u8"), data,
                       GEGL_AUTO_ROWSTRIDE);
    }

  ret = FALSE;
  b = FALSE;

  do
    {
      components[0] = jas_image_getcmptbytype
        (image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R));
      components[1] = jas_image_getcmptbytype
        (image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G));
      components[2] = jas_image_getcmptbytype
        (image, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B));

      if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
        {
          g_warning (_("One or more of R, G, B components are missing "
                       "from '%s'"), o->path);
          break;
        }

      if (jas_image_cmptsgnd (image, components[0]) ||
          jas_image_cmptsgnd (image, components[1]) ||
          jas_image_cmptsgnd (image, components[2]))
        {
          g_warning (_("One or more of R, G, B components have signed "
                       "data in '%s'"), o->path);
          break;
        }

      for (i = 0; i < 3; i++)
        matrices[i] = jas_matrix_create(1, width);

      for (row = 0; row < height; row++)
        {
          gint plane, col;
          jas_seqent_t *jrow[3] = {NULL, NULL, NULL};

          for (plane = 0; plane < 3; plane++)
            {
              int r = jas_image_readcmpt (image, components[plane], 0, row,
                                          width, 1, matrices[plane]);
              if (r)
                {
                  g_warning (_("Error reading row %d component %d from '%s'"),
                             row, plane, o->path);
                  b = TRUE;
                  break;
                }
            }

          if (b)
            break;

          for (plane = 0; plane < 3; plane++)
            jrow[plane] = jas_matrix_getref (matrices[plane], 0, 0);

          for (col = 0; col < width; col++)
            {
              switch (depth)
                {
                case 16:
                  *ptr_s++ = (gushort) jrow[0][col];
                  *ptr_s++ = (gushort) jrow[1][col];
                  *ptr_s++ = (gushort) jrow[2][col];
                  break;

                case 8:
                default:
                  *ptr_b++ = (guchar) jrow[0][col];
                  *ptr_b++ = (guchar) jrow[1][col];
                  *ptr_b++ = (guchar) jrow[2][col];
                }
            }
        }

      if (b)
        break;

      switch (depth)
        {
        case 16:
          gegl_buffer_set (output, &rect, babl_format ("R'G'B' u16"), data,
                           GEGL_AUTO_ROWSTRIDE);
          break;

        case 8:
        default:
          gegl_buffer_set (output, &rect, babl_format ("R'G'B' u8"), data,
                           GEGL_AUTO_ROWSTRIDE);
        }

      ret = TRUE;
    }
  while (FALSE); /* structured goto */

  for (i = 0; i < 3; i++)
    if (matrices[i])
      jas_matrix_destroy (matrices[i]);

  if (data)
    g_free (data);

  if (image)
    jas_image_destroy (image);

  return ret;
}
Exemple #24
0
static gboolean
process (GeglOperation       *operation,
         void                *out_buf,
         glong                n_pixels,
         const GeglRectangle *roi,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  gfloat     *out_pixel = out_buf;
  gfloat      color1[4];
  gfloat      color2[4];
  gint        x = roi->x; /* initial x                   */
  gint        y = roi->y; /*           and y coordinates */

  gegl_color_get_pixel (o->color1, babl_format ("RGBA float"), color1);
  gegl_color_get_pixel (o->color2, babl_format ("RGBA float"), color2);

  while (n_pixels--)
    {
      gint nx,ny;

      if ((x - o->x_offset) < 0)
        {
          nx = div (x - o->x_offset + 1, o->x).quot;
        }
      else
        {
          nx = div (x - o->x_offset, o->x).quot;
        }

      if ((y - o->y_offset) < 0)
        {
          ny = div (y - o->y_offset + 1, o->y).quot;
        }
      else
        {
          ny = div (y - o->y_offset, o->y).quot;
        }

      /* shift negative cell indices */
      nx -= (x - o->x_offset) < 0 ? 1 : 0;
      ny -= (y - o->y_offset) < 0 ? 1 : 0;

      if ( (nx+ny) % 2 == 0)
        {
          out_pixel[0]=color1[0];
          out_pixel[1]=color1[1];
          out_pixel[2]=color1[2];
          out_pixel[3]=color1[3];
        }
      else
        {
          out_pixel[0]=color2[0];
          out_pixel[1]=color2[1];
          out_pixel[2]=color2[2];
          out_pixel[3]=color2[3];
        }

      out_pixel += 4;

      /* update x and y coordinates */
      x++;
      if (x>=roi->x + roi->width)
        {
          x=roi->x;
          y++;
        }
    }

  return  TRUE;
}
Exemple #25
0
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);

  if (o->buffer)
    {
      GeglBuffer *output = GEGL_BUFFER (o->buffer);
      const Babl *in_format = gegl_buffer_get_format (input);
      const Babl *out_format = gegl_buffer_get_format (output);

      if (gegl_operation_use_opencl (operation)
          && gegl_cl_color_supported (in_format, out_format) == GEGL_CL_COLOR_CONVERT)
        {
          size_t size;
          gboolean err;
          cl_int cl_err = 0;

          GeglBufferClIterator *i = gegl_buffer_cl_iterator_new (output,
                                                                 result,
                                                                 out_format,
                                                                 GEGL_CL_BUFFER_WRITE);

          gint read = gegl_buffer_cl_iterator_add (i,
                                                   input,
                                                   result,
                                                   out_format,
                                                   GEGL_CL_BUFFER_READ,
                                                   GEGL_ABYSS_NONE);

          gegl_cl_color_babl (out_format, &size);

          GEGL_NOTE (GEGL_DEBUG_OPENCL,
                     "write-buffer: "
                     "%p %p %s %s {%d %d %d %d}",
                     input,
                     output,
                     babl_get_name (in_format),
                     babl_get_name (out_format),
                     result->x,
                     result->y,
                     result->width,
                     result->height);

          while (gegl_buffer_cl_iterator_next (i, &err))
            {
              if (err) break;

              cl_err = gegl_clEnqueueCopyBuffer (gegl_cl_get_command_queue (),
                                                 i->tex[read],
                                                 i->tex[0],
                                                 0,
                                                 0,
                                                 i->size[0] * size,
                                                 0,
                                                 NULL,
                                                 NULL);

              if (cl_err != CL_SUCCESS)
                {
                  GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", gegl_cl_errstring (cl_err));
                  break;
                }
            }

          if (cl_err || err)
            gegl_buffer_copy (input, result, output, result);
        }
      else
        gegl_buffer_copy (input, result, output, result);

      gegl_buffer_flush (output);
    }

  return TRUE;
}