Ejemplo n.º 1
0
static void
median (GeglBuffer *src,
        GeglBuffer *dst,
        gint        radius,
        gdouble     rank)
{
  RankList list = {0};

  gint x,y;
  gint offset;
  gfloat *src_buf;
  gfloat *dst_buf;


  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
  dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 4);

  gegl_buffer_get (src, NULL, 1.0, babl_format ("RGBA float"), src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  offset = 0;
  for (y=0; y<gegl_buffer_get_height (dst); y++)
    for (x=0; x<gegl_buffer_get_width (dst); x++)
      {
        gint u,v;
        gfloat *median_pix;

        list_clear (&list);

        for (v=y-radius;v<=y+radius;v++)
          for (u=x-radius;u<=x+radius;u++)
            {
              gint ru, rv;

              ru = (x-u)*(x-u);
              rv = (y-v)*(y-v);

              if (u >= 0 && u < gegl_buffer_get_width (dst) &&
                  v >= 0 && v < gegl_buffer_get_height (dst) &&
                  (ru+rv) < radius* radius
                  )
                {
                  gfloat *src_pix = src_buf + (u+(v * gegl_buffer_get_width (src))) * 4;
                  gfloat luma = (src_pix[0] * 0.212671 +
                                 src_pix[1] * 0.715160 +
                                 src_pix[2] * 0.072169);
                  list_add (&list, luma, src_pix);
                }
            }

        median_pix = list_percentile (&list, rank);
        for (u=0; u<4;u++)
          dst_buf[offset*4+u] = median_pix[u];
        offset++;
      }
  gegl_buffer_set (dst, NULL, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_free (src_buf);
  g_free (dst_buf);
}
Ejemplo n.º 2
0
gint
main (gint    argc,
      gchar **argv)
{
  GeglBuffer *buffer, *buffer2;
  GeglNode   *gegl, *sink;
  gint i;

  gegl_init (&argc, &argv);

  buffer = test_buffer (1024, 1024, babl_format ("RGBA float"));

#define ITERATIONS 8
  test_start ();
  for (i=0;i< ITERATIONS;i++)
  gegl = gegl_graph (sink = gegl_node ("gegl:buffer-sink", "buffer", &buffer2, NULL,
                            gegl_node ("gegl:brightness-contrast", "contrast", 0.2, NULL,
                            gegl_node ("gegl:brightness-contrast", "contrast", 0.2, NULL,
                            gegl_node ("gegl:brightness-contrast", "contrast", 0.2, NULL,
                            gegl_node ("gegl:brightness-contrast", "contrast", 1.2, NULL,
                            gegl_node ("gegl:buffer-source", "buffer", buffer, NULL)))))));

  gegl_node_process (sink);
  test_end ("passthrough", gegl_buffer_get_pixel_count (buffer2) * 16);
  g_object_unref (gegl);
  g_object_unref (buffer2);

  return 0;
}
Ejemplo n.º 3
0
gint
main (gint    argc,
      gchar **argv)
{
  GeglBuffer *buffer, *buffer2;
  GeglNode   *gegl, *source, *node1, *node2, *node3, *node4, *sink;
  gint i;

  gegl_init (&argc, &argv);

  buffer = test_buffer (2048, 1024, babl_format ("RGBA float"));

#define ITERATIONS 16
  test_start ();
  for (i=0;i< ITERATIONS;i++)
    {
      gegl = gegl_node_new ();
      source = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", buffer, NULL);
      node1 = gegl_node_new_child (gegl, "operation", "gegl:brightness-contrast", "contrast", 0.2, NULL);
      node2 = gegl_node_new_child (gegl, "operation", "gegl:brightness-contrast", "contrast", 0.2, NULL);
      node3 = gegl_node_new_child (gegl, "operation", "gegl:brightness-contrast", "contrast", 0.2, NULL);
      node4 = gegl_node_new_child (gegl, "operation", "gegl:brightness-contrast", "contrast", 0.2, NULL);
      sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer2, NULL);

      gegl_node_link_many (source, node1, node2, node3, node4, sink, NULL);
      gegl_node_process (sink);
      g_object_unref (gegl);
      g_object_unref (buffer2);
    }
  test_end ("bcontrast_4x", gegl_buffer_get_pixel_count (buffer) * 16 * ITERATIONS);

  return 0;
}
Ejemplo n.º 4
0
gint
main (gint    argc,
      gchar **argv)
{
  GeglBuffer *buffer, *buffer2;
  GeglNode   *gegl, *sink;
  gint i;

  g_thread_init (NULL);
  gegl_init (&argc, &argv);

  g_object_set (gegl_config (), "chunk-size", 128 * 128, NULL);

  buffer = test_buffer (1024, 1024, babl_format ("RGBA float"));

#define ITERATIONS 6
  test_start ();
  for (i=0;i< ITERATIONS;i++)
    {
      gegl = gegl_graph (sink = gegl_node ("gegl:buffer-sink", "buffer", &buffer2, NULL,
                                gegl_node ("gegl:brightness-contrast", "contrast", 0.2, NULL,
                                gegl_node ("gegl:buffer-source", "buffer", buffer, NULL))));

      gegl_node_process (sink);
      g_object_unref (gegl);
      g_object_unref (buffer2);
    }
  test_end ("bcontrast-minichunk", gegl_buffer_get_pixel_count (buffer) * 16 * ITERATIONS);


  return 0;
}
Ejemplo n.º 5
0
gint
main (gint    argc,
      gchar **argv)
{
  GeglBuffer *buffer, *buffer2;
  GeglNode   *gegl, *sink;

  gegl_init (&argc, &argv);

  buffer = test_buffer (1024, 1024, babl_format ("RGBA float"));

  gegl = gegl_graph (sink = gegl_node ("gegl:buffer-sink", "buffer", &buffer2, NULL,
                            gegl_node ("gegl:rotate", "degrees", 4.0, NULL,
                            gegl_node ("gegl:buffer-source", "buffer", buffer, NULL))));

  test_start ();
  gegl_node_process (sink);
  test_end ("rotate",  gegl_buffer_get_pixel_count (buffer) * 16);

  g_object_unref (gegl);

  return 0;
}
Ejemplo n.º 6
0
static void
snn_percentile (GeglBuffer *src,
                GeglBuffer *dst,
                gdouble     radius,
                gdouble     percentile,
                gint        pairs)
{
    gint    x, y;
    gint    offset;
    gfloat *src_buf;
    gfloat *dst_buf;
    RankList list = {0};

    src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
    dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 4);

    gegl_buffer_get (src, 1.0, NULL, babl_format ("RGBA float"), src_buf, GEGL_AUTO_ROWSTRIDE);

    offset = 0;
    percentile/= 100.0;

    for (y=0; y<gegl_buffer_get_height (dst); y++)
        for (x=0; x<gegl_buffer_get_width (dst); x++)
        {
            gint u,v;
            gfloat *center_pix = src_buf + offset * 4;

            list_clear (&list);

            /* iterate through the upper left quater of pixels */
            for (v=-radius; v<=0; v++)
                for (u=-radius; u<= (pairs==1?radius:0); u++)
                {
                    gfloat *selected_pix = center_pix;
                    gfloat  best_diff = 1000.0;
                    gint    i;

                    /* skip computations for the center pixel */
                    if (u != 0 &&
                            v != 0)
                    {
                        /* compute the coordinates of the symmetric pairs for
                         * this locaiton in the quadrant
                         */
                        gint xs[4] = {x+u, x-u, x-u, x+u};
                        gint ys[4] = {y+v, y-v, y+v, y-v};

                        /* check which member of the symmetric quadruple to use */
                        for (i=0; i<pairs*2; i++)
                        {
                            if (xs[i] >= 0 && xs[i] < gegl_buffer_get_width (src) &&
                                    ys[i] >= 0 && ys[i] < gegl_buffer_get_height (src))
                            {
                                gfloat *tpix = src_buf + (xs[i]+ys[i]*gegl_buffer_get_width (src))*4;
                                gfloat diff = colordiff (tpix, center_pix);
                                if (diff < best_diff)
                                {
                                    best_diff = diff;
                                    selected_pix = tpix;
                                }
                            }
                        }
                    }

                    list_add (&list, rgb2luminance(selected_pix), selected_pix);

                    if (u==0 && v==0)
                        break; /* to avoid doubly processing when using only 1 pair */
                }
            {
                gfloat *result = list_percentile (&list, percentile);
                for (u=0; u<4; u++)
                    dst_buf[offset*4+u] = result[u];
            }
            offset++;
        }
    gegl_buffer_set (dst, NULL, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
    g_free (src_buf);
    g_free (dst_buf);
}
Ejemplo n.º 7
0
static void
kuwahara (GeglBuffer *src,
          GeglBuffer *dst,
          gint        radius)
{
  gint u,v;
  gint offset;
  gfloat *src_buf;
  gfloat *dst_buf;

  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
  dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 4);

  gegl_buffer_get (src, NULL, 1.0, babl_format ("RGBA float"), src_buf,
                   GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  offset = 0;
  for (v=0; v<gegl_buffer_get_height (dst); v++)
    for (u=0; u<gegl_buffer_get_width (dst); u++)
      {
        gint component;

        for (component=0; component<3; component++)
          {
            gfloat value=0.0;
            gfloat best=1000000.0;

            gfloat mean = 0.0;
            gfloat variance = 0.0;

            compute_rectangle (src_buf,
                               gegl_buffer_get_width (src),
                               gegl_buffer_get_height (src),
                               u - radius - 1,
                               v - radius - 1,
                               1 + radius,
                               1 + radius,
                               component,
                               NULL, /* min */
                               NULL, /* max */
                               &mean,
                               &variance);
            if (variance<best)
              {
                best = variance;
                value = mean;
              }

            compute_rectangle (src_buf,
                               gegl_buffer_get_width (src),
                               gegl_buffer_get_height (src),
                               u,
                               v - radius - 1,
                               1 + radius,
                               1 + radius,
                               component,
                               NULL, /* min */
                               NULL, /* max */
                               &mean,
                               &variance);
            if (variance<best)
              {
                best = variance;
                value = mean;
              }

            compute_rectangle (src_buf,
                               gegl_buffer_get_width (src),
                               gegl_buffer_get_height (src),
                               u - radius - 1,
                               v,
                               1 + radius,
                               1 + radius,
                               component,
                               NULL, /* min */
                               NULL, /* max */
                               &mean,
                               &variance);
            if (variance<best)
              {
                best = variance;
                value = mean;
              }

            compute_rectangle (src_buf,
                               gegl_buffer_get_width (src),
                               gegl_buffer_get_height (src),
                               u,
                               v,
                               1 + radius,
                               1 + radius,
                               component,
                               NULL, /* min */
                               NULL, /* max */
                               &mean,
                               &variance);

            if (variance<best)
              {
                best = variance;
                value = mean;
              }
            dst_buf [offset++] = value;
          }
          dst_buf [offset] = src_buf[offset];
          offset++;
      }

  gegl_buffer_set (dst, NULL, 0, babl_format ("RGBA float"), dst_buf, GEGL_AUTO_ROWSTRIDE);
  g_free (src_buf);
  g_free (dst_buf);
}
Ejemplo n.º 8
0
static void
snn_mean (GeglBuffer          *src,
          GeglBuffer          *dst,
          const GeglRectangle *dst_rect,
          gdouble              dradius,
          gint                 pairs)
{
  gint x,y;
  gint offset;
  gfloat *src_buf;
  gfloat *dst_buf;
  gint radius = dradius;
  gint src_width = gegl_buffer_get_width (src);
  gint src_height = gegl_buffer_get_height (src);

  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 4);
  dst_buf = g_new0 (gfloat, dst_rect->width * dst_rect->height * 4);

  gegl_buffer_get (src, NULL, 1.0, babl_format ("RGBA float"), src_buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

  offset = 0;

  for (y=0; y<dst_rect->height; y++)
    {
      gfloat *center_pix;

      center_pix = src_buf + ((radius) + (y+radius)* src_width)*4;

      for (x=0; x<dst_rect->width; x++)
        {
          gint u,v;

          gfloat  accumulated[4]={0,};
          gint    count=0;

          /* iterate through the upper left quater of pixels */
          for (v=-radius;v<=0;v++)
            for (u=-radius;u<= (pairs==1?radius:0);u++)
              {
                gfloat *selected_pix = center_pix;
                gfloat  best_diff = 1000.0;
                gint    i;

                /* skip computations for the center pixel */
                if (u != 0 &&
                    v != 0)
                  {
                    /* compute the coordinates of the symmetric pairs for
                     * this locaiton in the quadrant
                     */
                    gint xs[4], ys[4];

                    xs[0] = x+u+radius;
                    xs[1] = x-u+radius;
                    xs[2] = x-u+radius;
                    xs[3] = x+u+radius;
                    ys[0] = y+v+radius;
                    ys[1] = y-v+radius;
                    ys[2] = y+v+radius;
                    ys[3] = y-v+radius;

                    /* check which member of the symmetric quadruple to use */
                    for (i=0;i<pairs*2;i++)
                      {
                        if (xs[i] >= 0 && xs[i] < src_width &&
                            ys[i] >= 0 && ys[i] < src_height)
                          {
                            gfloat *tpix = src_buf + (xs[i]+ys[i]* src_width)*4;
                            gfloat diff = colordiff (tpix, center_pix);
                            if (diff < best_diff)
                              {
                                best_diff = diff;
                                selected_pix = tpix;
                              }
                          }
                      }
                  }

                /* accumulate the components of the best sample from
                 * the symmetric quadruple
                 */
                for (i=0;i<4;i++)
                  {
                    accumulated[i] += selected_pix[i];
                  }
                count++;

                if (u==0 && v==0)
                  break; /* to avoid doubly processing when using only 1 pair */
              }
          for (u=0; u<4; u++)
            dst_buf[offset*4+u] = accumulated[u]/count;
          offset++;

          center_pix += 4;
        }
    }
  gegl_buffer_set (dst, dst_rect, 0, babl_format ("RGBA float"), dst_buf,
                   GEGL_AUTO_ROWSTRIDE);
  g_free (src_buf);
  g_free (dst_buf);
}
Ejemplo n.º 9
0
gint
main (gint    argc,
      gchar **argv)
{
  GeglBuffer *bufferA = NULL;
  GeglBuffer *bufferB = NULL;
  GeglBuffer *debug_buf = NULL;

  g_thread_init (NULL);
  gegl_init (&argc, &argv);

  if (argc != 3)
    {
      g_print ("This is simple image difference detection tool for use in regression testing"
               "return message is non zero if images are different, if they are equal"
               "the output will contain the string identical.");
      g_print ("Usage: %s <imageA> <imageB>\n", argv[0]);
      return 1;
    }

  {
    GeglNode *graph, *sink;
    graph = gegl_graph (sink=gegl_node ("gegl:buffer-sink", "buffer", &bufferA, NULL,
                             gegl_node ("gegl:load", "path", argv[1], NULL)));
    gegl_node_process (sink);
    g_object_unref (graph);
    if (!bufferA)
      {
        g_printerr ("Failed to open %s\n", argv[1]);
        return 1;
      }

    graph = gegl_graph (sink=gegl_node ("gegl:buffer-sink", "buffer", &bufferB, NULL,
                             gegl_node ("gegl:load", "path", argv[2], NULL)));
    gegl_node_process (sink);
    g_object_unref (graph);
    if (!bufferB)
      {
        g_printerr ("Failed to open %s\n", argv[2]);
        return 1;
      }
  }

  if (gegl_buffer_get_width (bufferA) != gegl_buffer_get_width (bufferB) ||
      gegl_buffer_get_height (bufferA) != gegl_buffer_get_height (bufferB))
    {
      g_printerr ("%s and %s differ in size\n", argv[1], argv[2]);
      g_printerr ("  %ix%i vs %ix%i\n",
                  gegl_buffer_get_width (bufferA), gegl_buffer_get_height (bufferA),
                  gegl_buffer_get_width (bufferB), gegl_buffer_get_height (bufferB));
      return 1;
    }

  debug_buf = gegl_buffer_new (gegl_buffer_get_extent (bufferA), babl_format ("R'G'B' u8"));
  
   

  {
     gfloat *bufA, *bufB;
     gfloat *a, *b;
     guchar *debug, *d;
     gint   rowstrideA, rowstrideB, dRowstride;
     gint   pixels;
     gint   wrong_pixels=0;
     gint   i;
     gdouble diffsum = 0.0;
     gdouble max_diff = 0.0;

     pixels = gegl_buffer_get_pixel_count (bufferA);

     bufA = (void*)gegl_buffer_linear_open (bufferA, NULL, &rowstrideA,
                                            babl_format ("CIE Lab float"));
     bufB = (void*)gegl_buffer_linear_open (bufferB, NULL, &rowstrideB,
                                            babl_format ("CIE Lab float"));
     debug = (void*)gegl_buffer_linear_open (debug_buf, NULL, &dRowstride, babl_format ("R'G'B' u8"));

     a = bufA;
     b = bufB;
     d = debug;

     for (i=0;i<pixels;i++)
       {
         gdouble diff = sqrt ( SQR(a[0]-b[0])+
                               SQR(a[1]-b[1])+
                               SQR(a[2]-b[2])
                               /*+SQR(a[3]-b[3])*/);
         if (diff>=0.01)
           {
             wrong_pixels++;
             diffsum += diff;
             if (diff > max_diff)
               max_diff = diff;
             d[0]=(diff/100.0 * 255);
             d[1]=0;
             d[2]=a[0]/100.0*255;
           }
         else
           {
             d[0]=a[0]/100.0*255;
             d[1]=a[0]/100.0*255;
             d[2]=a[0]/100.0*255;
           }
         a+=3;
         b+=3;
         d+=3;
       }

     a = bufA;
     b = bufB;
     d = debug;

     if (wrong_pixels)
       for (i=0;i<pixels;i++)
         {
           gdouble diff = sqrt ( SQR(a[0]-b[0])+
                                 SQR(a[1]-b[1])+
                                 SQR(a[2]-b[2])
                                 /*+SQR(a[3]-b[3])*/);
           if (diff>=0.01)
             {
               d[0]=(100-a[0])/100.0*64+32;
               d[1]=(diff/max_diff * 255);
               d[2]=0;
             }
           else
             {
               d[0]=a[0]/100.0*255;
               d[1]=a[0]/100.0*255;
               d[2]=a[0]/100.0*255;
             }
           a+=3;
           b+=3;
           d+=3;
         }

     gegl_buffer_linear_close (bufferA, bufA);
     gegl_buffer_linear_close (bufferB, bufB);
     gegl_buffer_linear_close (debug_buf, debug);

     if (max_diff >= 0.1)
       {
         g_printerr ("%s and %s differ\n"
                     "  wrong pixels   : %i/%i (%2.2f%%)\n"
                     "  max Δe         : %2.3f\n"
                     "  avg Δe (wrong) : %2.3f(wrong) %2.3f(total)\n",
                     argv[1], argv[2],
                     wrong_pixels, pixels, (wrong_pixels*100.0/pixels),
                     max_diff,
                     diffsum/wrong_pixels,
                     diffsum/pixels);
         if (max_diff > 1.5 &&
             !strstr (argv[2], "broken"))
           {
             GeglNode *sink;
             gchar *debug_path = g_malloc (strlen (argv[2])+16);
             memcpy (debug_path, argv[2], strlen (argv[2])+1);
             memcpy (debug_path + strlen(argv[2])-4, "-diff.png", 11);
             gegl_graph (sink=gegl_node ("gegl:png-save",
                                 "path", debug_path, NULL,
                                 gegl_node ("gegl:buffer-source", "buffer", debug_buf, NULL)));
             gegl_node_process (sink);
             return 1;
           }
         if (strstr (argv[2], "broken"))
           g_print ("because the test is expected to fail ");
         else
           g_print ("because the error is small ");
         g_print ("we'll say ");
       }

  }

  g_print ("%s and %s are identical\n", argv[1], argv[2]);
  g_object_unref (debug_buf); 
  g_object_unref (bufferA); 
  g_object_unref (bufferB); 
  gegl_exit ();
  return 0;
}
Ejemplo n.º 10
0
static void
copy_through_lens (LensCorrectionModel *oip,
                   GeglBuffer *src,
                   GeglBuffer *dst)
{
  const GeglRectangle *src_extent;
  const GeglRectangle *dst_extent;
  gfloat *src_buf;
  gfloat *dst_buf;
  gint x,y;             /* Coordinate of current dst pixel. */
  gint rgb;             /* Color channel of dst pixel being processed. */
  gint doffset;             /* Buffer offset of current dst pixel. */
  gint tmpx, tmpy, toff;
  ChannelCorrectionModel *ccm[3];   /* Allow access to red,green,blue models in loop. */

  src_extent = gegl_buffer_get_extent (src);
  #ifdef TRACE
    g_warning ("> copy_through_lens src_extent = %dx%d+%d+%d",
                 src_extent->width, src_extent->height, src_extent->x,src_extent->y);
  #endif
  if (dst == NULL)
    {
      #ifdef TRACE
        g_warning ("  dst is NULL");
        g_warning ("< copy_through_lens");
      #endif
      return;
    }
  dst_extent = gegl_buffer_get_extent (dst);
  if (dst_extent == NULL) {
      #ifdef TRACE
        g_warning ("  dst_extent is NULL");
        g_warning ("< copy_through_lens");
      #endif
      return;
  }

  /* Get src pixels. */
  src_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (src) * 3);
  gegl_buffer_get (src, 1.0, NULL, babl_format ("RGB float"), src_buf, GEGL_AUTO_ROWSTRIDE);

  /* Get buffer in which to place dst pixels. */
  dst_buf = g_new0 (gfloat, gegl_buffer_get_pixel_count (dst) * 3);

  /* Compute each dst pixel in turn and store into dst buffer. */
  ccm[0] = &oip->red;
  ccm[1] = &oip->green;
  ccm[2] = &oip->blue;
  doffset = 0;
  for (y=dst_extent->y; y<dst_extent->height + dst_extent->y; y++)
    {
      for (x=dst_extent->x; x<dst_extent->width + dst_extent->x; x++)
    {
      for (rgb = 0; rgb < 3; rgb++)
        {
          gfloat gx, gy;
          gfloat val = 0.0;
          gint xx, yy;
          gfloat wx[2], wy[2], wt = 0.0;

          find_src_pixel (oip, ccm[rgb], (gfloat)x, (gfloat)y, &gx, &gy);
          tmpx = gx;
          tmpy = gy;
          wx[1] = gx - tmpx;
          wx[0] = 1.0 - wx[1];
          wy[1] = gy - tmpy;
          wy[0] = 1.0 - wy[1];
          tmpx -= src_extent->x;
          tmpy -= src_extent->y;
          toff = (tmpy * ROW + tmpx) * 3;
          for (xx = 0; xx < 2; xx++)
            {
          for (yy = 0; yy < 2; yy++)
            {
              if (tmpx+xx >= 0 && tmpx+xx < src_extent->width &&
                  tmpy+yy >= 0 && tmpy+yy < src_extent->height)
                {
              val += src_buf[toff+(yy*ROW+xx)*3+rgb] * wx[xx] * wy[yy];
              wt += wx[xx] * wy[yy];
            }
            }
        }
          if (wt <= 0)
        {
          g_warning ("gegl_lens_correct: mapped pixel %g,%g not in %dx%d+%d+%d", gx, gy,
                 src_extent->width, src_extent->height, src_extent->x, src_extent->y);
          g_warning ("                   dst = %dx%d+%d+%d", dst_extent->width, dst_extent->height, dst_extent->x,dst_extent->y);
          dst_buf [doffset+rgb] = 0.0;
        }
          else
        {
          dst_buf [doffset+rgb] = val / wt;
        }
        }
      doffset+=3;
    }
    }

  /* Store dst pixels. */
  gegl_buffer_set (dst, NULL, babl_format ("RGB float"), dst_buf, GEGL_AUTO_ROWSTRIDE);

  /* Free acquired storage. */
  g_free (src_buf);
  g_free (dst_buf);

  #ifdef TRACE
    g_warning ("< copy_through_lens");
  #endif
}