-
Notifications
You must be signed in to change notification settings - Fork 0
quick hack of gegl to use libvips as the backend
License
LGPL-3.0, GPL-3.0 licenses found
Licenses found
LGPL-3.0
COPYING.LESSER
GPL-3.0
COPYING
jcupitt/gegl-vips
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
gegl-vips ========= This is a quick proof-of-concept hack of gegl-0.1.6 to use libvips as the backend. You need to have the development version of libvips installed (7.25), plus babl-0.1.4 or later. Then configure ; make ; make install as usual. Test program ============ ------ #include <stdio.h> #include <stdlib.h> #include <gegl.h> int main (int argc, char **argv) { GeglNode *gegl, *load, *crop, *scale, *sharp, *save; g_thread_init (NULL); gegl_init (&argc, &argv); if (argc != 3) { fprintf (stderr, "usage: %s file-in file-out\n", argv[0]); exit (1); } gegl = gegl_node_new (); load = gegl_node_new_child (gegl, "operation", "gegl:load", "path", argv[1], NULL); crop = gegl_node_new_child (gegl, "operation", "gegl:crop", "x", 100.0, "y", 100.0, "width", 4800.0, "height", 4800.0, NULL); scale = gegl_node_new_child (gegl, "operation", "gegl:scale", "x", 0.9, "y", 0.9, "filter", "linear", "hard-edges", FALSE, NULL); sharp = gegl_node_new_child (gegl, "operation", "gegl:unsharp-mask", "std-dev", 1.0, // diameter 7 mask in gegl NULL); save = gegl_node_new_child (gegl, "operation", "gegl:save", "path", argv[2], NULL); gegl_node_link_many (load, crop, scale, sharp, save, NULL); //gegl_node_dump( gegl, 0 ); gegl_node_process (save); //gegl_node_dump( gegl, 0 ); g_object_unref (gegl); gegl_exit (); return (0); } --- ie. load, crop 100 px off the edges (you need to give it a 5k x 5k RGB image), bilinear 10% shrink, sharpen, save. See: http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use for results with other libraries. Compile with: gcc -g -Wall gegl.c `pkg-config gegl --cflags --libs` and run with something like: $ time ./a.out wtc_small.png wtc2.png or $ time ./a.out wtc_small.tif wtc2.tif (gegl-vips allows most image file formats) Results ======= On my laptop I get the following run times: gegl-0.1.6, default settings 70s r, 39 u export BABL_TOLERANCE=0.004 65s r, 33s u export BABL_TOLERANCE=0.004 export GEGL_CACHE_SIZE=1000 (my laptop only has 2gb) 53 r, 34s u (memuse peaks at 1.0gb) + 8-bit PNG output 47s r, 30s u gegl-vips match gegl processing (don't forget to append :1 to the png output name to force compression == 1, the gegl default), 19s r, 23s u + 8-bit output 10s r, 14s u + faster unsharp 7.8s r, 10.6s u + skip alpha 6.5s r, 8.5s u + tif files 3.0s r, 3.8s u + 8-bit path 1.0s r, 1.4s u Results #2 ========== On a desktop machine with more RAM and a fast hard drive, but slightly slower 2 x 2.7 GHz Operton 254 processors, I get: gegl-0.1.6, default settings 50s r, 44s u export BABL_TOLERANCE=0.004 46s r, 39s u export BABL_TOLERANCE=0.004 export GEGL_SWAP=RAM 41s r, 39s u (memuse peaks at 1.8gb) + 8-bit PNG output 38s r, 36s u gegl-vips match gegl processing (don't forget to append :1 to the png output name to force compression == 1, the gegl default), 13.8s r, 22.1s u + 8-bit output 8.6s r, 14.4s u + faster unsharp 7.2s r, 11.2s u + skip alpha 5.9s r, 9.0s u + tif files 2.9s r, 5.0s u + 8-bit path 1.4s r, 1.9s u Conclusions =========== In the most comparable case, gegl-vips needs about 15s less CPU but finishes 25s earlier, due to on-by-default threading. The difference is more marked on the laptop where the slow harddrive hurts the tile cache. Only saving 8-bit PNGs saves 5s. Faster unsharp, save 1.5s. Dropping the alpha channel (not needed in this case) saves 1.3s. Using the faster libtif saves 3s. Using an 8-bit path throughout saves another 1.5s. How it works ============ - add this to every GeglNode: VipsImage *vips_image; guint64 vips_hash; - in every operation (I've only done load/save/crop/affine/usharp) change the GeglOperation::process() member to be something like this (this is crop): GeglNode *input; guint64 hash; // make sure input is ready input = gegl_operation_get_source_node (operation, "input"); if (!input || !input->vips_image) return; // calculate a hash of the input args hash = 0; hash = GEGL_VIPS_HASH_POINTER (hash, input->vips_image); hash = GEGL_VIPS_HASH_DOUBLE (hash, o->x); hash = GEGL_VIPS_HASH_DOUBLE (hash, o->y); hash = GEGL_VIPS_HASH_DOUBLE (hash, o->width); hash = GEGL_VIPS_HASH_DOUBLE (hash, o->height); // if args have changed, or this is the first time we've run if (!node->vips_image || node->vips_hash != hash) { VipsImage *image; // perform the equivalent vips operation image = vips_image_new ("p"); if (im_extract_area (input->vips_image, image, o->x, o->y, o->width, o->height)) { gegl_vips_error ("crop"); g_object_unref (image); return; } // install the new image on the node, update the hash if (node->vips_image) { g_object_unref (node->vips_image); node->vips_image = NULL; } node->vips_image = image; node->vips_hash = hash; } - change gegl_node_process() to simply walk the graph, bottom-up, calling all the prepare() members ... and that's about it, very simple. TODO: - add a display sink - try a couple more operations - maybe get hello-world.c working - vips needs area invalidation before we can support destructive operations
About
quick hack of gegl to use libvips as the backend
Resources
License
LGPL-3.0, GPL-3.0 licenses found
Licenses found
LGPL-3.0
COPYING.LESSER
GPL-3.0
COPYING
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published