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); }
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; }
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; }
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; }
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; }
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); }
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); }
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); }
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; }
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 }