Re: An alternative to gdk-pixbuf



On Fri, 7 Sep 2018 17:28:04 +0000
Debarshi Ray <rishi is lostca se> wrote:

Hey Magnus,

I haven't yet worked my way through the whole thread. It's pretty
long and will take me a while longer, but I did want to mention a
few things before the weekend draws me away from the computer.

On Wed, Sep 05, 2018 at 12:02:45AM +0200, Magnus Bergman wrote:
Over the years it has been discussed from time to time to replace
gdk-pixbuf with something else[1][2]. Something was even in the
making (I guess over ten years ago) but it never replaced gdk-pixbuf
apparently. Now I don't even remember what it was called. And
something else called pig was proposed more recently.  

As Emmanuele mentioned, if you ignore the use-case of loading icons
in GTK, and focus on image applications dealing with high resolution
images, then GEGL [1] is the way to go. It's a GObject-based image
processing framework that's used by GIMP and GNOME Photos, and is
way more advanced than anything that we have in the GNOME platform.

If you use GIMP 2.10 or practically any version of GNOME Photos, then
all the image decoding and processing is happening with GEGL.

A GeglBuffer is the equivalent of GdkPixbuf in GEGL. It can:

(a) Be converted to and from a GdkPixbuf. That makes porting trivial
    and boosts interoperability.

(b) Handle massive images that are larger than the amount of physical
    RAM available on the system. This is achieved by spliting the
    pixels into smaller tiles that get transparently swapped out of
    memory into a disk-backed cache when necessary.

    It can be dumbed down into a GdkPixbuf-like linear sequence of
    bytes, if need be.

(c) Represent a whole horde of pixel formats, colour spaces, bit
depths, etc. [2], which can be programmatically extended at run-time.

(d) Automatically convert between pixel formats, colour spaces, bit
    depths, etc., with accelerated fast paths.

(e) Be serialized into a named file, which is interesting for passing
    pixels across process boundaries.

(f) Use mipmaps for scaling, rendering and processing the pixels.

(g) Be used with OpenCL.

(h) Do all that and is still fast. Try zooming in and out in GNOME
    Photos.

Not to mention a vast array of image processing operations. If it's in
GIMP, it's in GEGL. Interesting operations are ported from elsewhere,
and there's a constant flow of new things under development.

GEGL is certainly impressive. Especially the ability to handle images
larger than RAM, I think. I must admit that it was some years ago that
I looked at the API and concluded that it couldn't do everything I
wanted from a general purpose image loading library (for image
viewing). Back then it could only load images from disk (but I've heard
that has changed at least). And as far as I know it still only does
raster images, not vector images. It also has no support for
animations, not to mention vector animations. Or rather, it can't (or
couldn't) distinguish between the concepts of animation frames, layers,
variants (which I explained earlier), stereoscopic images and files
that simply contains multiple images with an otherwise unspecified
relation (which I call pages in lack of a better term). I don't know
about aspect ratio correction, but I don't think GEGL has it. Some of
those things might get added to GEGL. But I doubt vector animations
will ever be considered. I will, however, take a new look at GEGL and
see if it's the best solution for at least some of the problems I want
to solve.

One major reason to replace gdk-pixbuf has been the long term goal
to phase out GDK in favour of cairo.  

De/encoding images and manipulating the pixels is related to rendering
them on the screen, but aren't necessarily the same thing. It's
important to ensure that the pixels can be efficiently drawn, but I
wouldn't add a hard dependency on the drawing framework. For example,
GEGL has fast paths for drawing with Cairo, but doesn't mandate it.
It also doesn't require GTK, even though it has helper widgets for it.

That's why GIMP 2.10 and GNOME Photos can use the same libgegl-0.4.so,
even though they use different widget toolkits (GTK 2.x versus 3.x).

This is how to convert an SVG file to a PNG file.

    cairo_surface_t *surface = abydos_load("image/svg+xml",
    "example.svg"); cairo_surface_write_to_png(surface,
"example.png"); cairo_surface_destroy(surface);

This is how to convert the second frame of a GIF animation to PNG.

   abydos_t *ar = abydos_create_from_file("image/gif",
"example.gif"); abydos_set_frame(ar, 1);
   cairo_surface_t *surface = abydos_get_image_surface(ar, 0);
   abydos_destroy(ar);
   cairo_surface_write_to_png(surface, "example.png");
   cairo_surface_destroy(surface);  

I don't see any error handling. Maybe I should read the actual code.

I just intended to show the general code flow so I left out the error
handling. Both abydos_load() and abydos_create_from_file() are
convenience functions that will simply return NULL if they fail. It's
possible to separate the process into more steps for a more fine
grained error handling. The other functions, abydos_set_frame() and
abydos_get_image_surface() are guaranteed not to fail (provided there
were no prior errors). See: http://snisurset.net/code/abydos/api/

[...]

Of course, one could use the GdkPixbuf codecs for I/O and then covert
to and from a GeglBuffer. But then you wouldn't be able to handle RAWs
or higher bit-depth PNGs and will likely run into problems with your
80 megapixel images [4] - things that a good image application will
care about. :)

I expect a general purpose image viewer to handle images of that size
too. That's even small enough to fit in RAM. (But I have tested and am
aware of the problem.) Many fields of science deal with images of multi
gigabyte sizes. Ideally any image viewer should be able to handle these
too with the right plugin (probably using GEGL in that case). But I
think the problem with large images (say 12000x12000 or so) is giving
it to the application as a pixmap. From my own tests it seams it's fine
at least as long as the images are no bigger than the screen. So if the
drawing (and implicitly also scaling) is handed over to the loading
library (which in turn might hand it over to the plugin), this problem
can be avoided. Even without the really big muscles of GEGL in most
cases. But of course there is no point in not using GEGL if I can't
manage to come up with anything faster (faster loading and fast enough
drawing that is).

I've been in contact with a two creators of image viewers  

Which ones? Just curious. :)

Oh, man, it was quite a while ago then I think about it. My quest for a
general purpose image viewer reaches back over 20 years. And I've been
following gdk-pixbuf for over 15. The first one was some guy who, like
me, was interested in the art scene and was developing a viewer to
handle those kind of image formats. It didn't take off and I don't think
he ever made a public release. The other one was closer in time, but
then I think about it almost 10 years ago. It was an image viewer I
used a lot, but seamlessly replaced with the very similar (but better)
viewer viewnior. I'm kind of surprised myself that I don't remember the
name. I think it was something quite anonymous, GTK Picture, GImageView
or something like that. Not much of a hint, but you might be able to
guess? Time certainly flies.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]