GEGL 0.3.0 et babl 0.1.12 sont de sortie

Babl est une bibliothèque de conversion de formats de pixels. GEGL est un moteur de traitement d’images en graphe, construit autour de babl.

Ce sont deux bibliothèques nées du projet GIMP, qui constitueront son nouveau moteur interne d’édition d’image dès la version majeure suivante (GIMP 2.10, date de sortie non connue). Mais ce sont aussi bien plus que les moteurs de GIMP, ce sont surtout des projets indépendants qui commencent à être utilisés par d’autres projets, que ce soient des logiciels Libres, comme des services propriétaires.

De nouvelles versions viennent de sortir (GEGL 0.3.0 et babl 0.1.12), et je profite donc de l’occasion pour présenter ces logiciels, leurs spécificités, leurs historiques et leurs utilisations dans la seconde partie de la dépêche.

Sommaire

babl

babl

Babl est une bibliothèque de conversion de formats de pixels. Quand on parle de formats de pixels, on entend la représentation du pixel en mémoire comme par exemple l’espace de couleur (RVB, CIE Lab…), une profondeur de couleur (nombre de bits utilisés par canal…) ou le type de données (entiers, flottants…), utilisés pour la représentation et non un format de fichier d’image pour enregistrer sur un espace de stockage.

Ainsi, cela permet par exemple de traduire des représentations de pixels RVB, RVBA, CMJN, CIE Lab, etc. Babl ne fait pas de traitement d’image dans le but de la modifier, mais uniquement des conversions (les seules modifications étant par exemple de la perte éventuelle de données si on passe à un format moins précis, ou de l’approximation entre deux formats qui ne sont pas parfaitement équivalents bijectivement).

Cette bibliothèque fournit une API extrêmement petite (le dépôt de source fait 4 Mo en tout, pour moins de 900 ko de code), simple et stable par conception.

GEGL

GEGL logo

GEGL est une bibliothèque permettant de traiter des images sous la formes de graphes de nœuds, chaque nœud pouvant avoir des entrées, sorties et une configuration.

Un nœud représente ce qu’on appelle une « opération ». Typiquement, il y a des opérations servant principalement d’entrée à partir d’image stockées en mémoire ou sur disque, des opérations servant de sortie pour enregistrer ou afficher de nouvelles images, et des opérations intermédiaires servant de filtres mathématiques pour modifier l’image entre le nœud d’entrée et de sortie. Ces opérations intermédiaires sont par exemple:

  • les filtres classiques que l’on aurait dans le menu « Filtres » de GIMP (flou, netteté, filtres artistiques, etc.);
  • des modifications des couleurs (balance, saturation, etc.);
  • de la composition (avec 2 images en entrée pour 1 en sortie, ce qui correspond notamment aux modes de composition des calques de GIMP : normal, multiply, add, substract, etc.):
  • des traitements plus utilitaires (découpe, redimensionnement, rotation, etc.):

Formats d’images

GEGL sait de base ouvrir et sauver de nombreux formats d’images, des plus classiques (PNG, JPEG, BMP, tiff…) aux formats plus spécialisés (RAW, OpenEXR…), et même des formats vectoriels (SVG…). En outre, il sait tirer profit d’autres sources, comme des fichiers vidéos (avec ffmpeg) ou de l’acquisition vidéo directe (v4l).

GEGL sait aussi tirer profit de très hautes précisions de couleur (high bit precision depth), permettant par là de travailler sur des images à 8, 16, 32 ou même 64 bits par canal (et en nombre entier ou flottant, avec codage linéaire ou correction gamma), ainsi que de charger et sauver les données en haute précision lorsqu’on utilise un format l’autorisant (comme ce sera le cas des fichiers d’image de GIMP, XCF, à la sortie de GIMP 2.10).
Cela permet des traitements intermédiaires complexes avec beaucoup moins de perte de données et de qualité.

Traitement d’image en graphe

Si un traitement simple (toute action basique sur une image) peut être représenté en un nœud unique avec l’image en entrée et le résultat en sortie, un traitement complexe est un graphe liant de multiples nœuds.

Schématiquement, travailler sur une image ressemble à l’éditeur de nœuds de Blender.
Éditeur de Nœuds de Blender

Le traitement par graphe a deux intérêts principaux:

  1. Du traitement « non destructif » si l’interface logicielle le permet.
    Cela implique un flot de travail où on ne touche jamais l’image originelle. Elle est en entrée, et toute modification du graphe influe sur les pixels dans le nœud de sortie (qui peut être théoriquement le même fichier que celui chargé en entrée, mais alors cela rend le concept moins intéressant).
    On peut à tout moment supprimer ou modifier les paramètres d’une opération sans craindre pour l’image de base (plutôt qu’appliquer, voir, annuler, refaire avec d’autres paramètres, revoir, et ainsi de suite). Le concept de traitement non destructif rend donc presque caduque le concept d’historique et d’annulation des opérations.
  2. La limitation de la dégradation d’une image qui se produit lors de l’application de filtres.
    Un exemple explicite: une simple rotation d’image à 45° dégrade une image. Si on se rend compte qu’on préfère une rotation à 90° et qu’on applique donc une nouvelle rotation à 45° : on a alors dégradé 2 fois l’image et on se retrouve avec une qualité très amoindrie par rapport à l’original. Or une rotation à 90° directement se fait entièrement sans perte (puisqu’on travaille dans des matrices de pixels). Si on avait sauvé un graphe et qu’au lieu d’appliquer 2 rotations successives, on modifiait seulement les paramètres de la première rotation, on se retrouve avec un traitement sans perte. Bien sûr dans le cas général, on aura de la dégradation, mais celle-ci peut être limitée par la création d’un graphe optimal qui ne sera appliqué qu’une seule fois.

Développement d’opérations maison

GEGL est livré avec de nombreuses opérations par défaut, mais cela ne le rend pas exhaustif pour autant. La bibliothèque est conçue pour être étendue à volonté par les développeurs.

Vous avez besoin d’ajouter la prise en charge d’un format d’image maison ou peu répandu ? Vous avez besoin d’un filtre qui n’a pas été déjà développé, ou vous avez développé une version algorithmique bien plus efficace ? Vous avez besoin de traitements un peu particuliers qui servent spécifiquement à votre application et n’auraient aucun sens en upstream ? Il n’y a pas besoin d’attendre que vos opérations soient intégrées dans GEGL ou de le patcher. Vous pouvez créer et étendre GEGL à l’infini.

En ce sens, GEGL est un « cadriciel » (framework) pour la création d’opérations de traitement d’image.

Scriptable

Grâce à l’introspection GObject, cette bibliothèque est accessible à de nombreux langages tiers, notamment des langages de scripts (Python, Ruby, JavaScript, PHP…). Cela signifie notamment qu’il est possible de l’utiliser pour des petits scripts rapides ou en ligne de commande, et en augmente considérablement l’accès.

Bien sûr, certains wrappers existent déjà, permettant une encore meilleure intégration aux spécificités d’un langage. Le wrapper Python est un bon exemple de bibliothèque maintenue.

Voici par exemple un court script Python pour inverser une image avec GEGL :

import gegl

x = gegl.Graph("png-load", "invert", "png-save")
x[0].path = "/home/user/input.png"
x[2].path = "/home/user/output.png"
x()

Enfin, il est possible, avec l’outil console gegl fourni par défaut de lui passer des graphes d’opérations GEGL en XML, pour un traitement d’image scripté.

Performance : OpenCL et multi-threading

GEGL prend en charge OpenCL, langage de programmation et bibliothèque « conçu pour programmer des systèmes parallèles hétérogènes comprenant par exemple à la fois un CPU multi-cœur et un GPU » (cf. OpenCL sur Wikipédia). En d’autres termes, cela permet de faire travailler votre carte graphique, en plus de votre processeur, en parallèle, pour accélérer les calculs.
Cela couplé avec du traitement « thread-safe » (pour vous autoriser à utiliser du multi-thread dans votre propre code), et un début de multi-thread dans GEGL même, nous essayons d’obtenir une utilisation aussi performante que possible.

Traitement de très grandes images

Un des points forts de GEGL est sa gestion intelligente des buffers (objet gérant les données bitmap à l’aide des formats de pixel babl), permettant à l’utilisateur d’allouer une partie seulement de sa mémoire, mais également de travailler sur des images plus grandes que la mémoire disponible. Un buffer GEGL est une matrice de dalles, chacune pouvant avoir un backend de stockage différent, en particulier en mémoire RAM, ou en swap lorsque l’on dépasse la mémoire allouée.
Dans l’avenir, on pourrait avoir un backend en mémoire GPU, en réseau, etc.

Cela permet ainsi d’avoir une majeure partie d’une image en mémoire, ainsi qu’une autre partie en swap disque, lors du travail sur de très grandes images. Le travail en dalle autorise aussi un travail plus efficace lorsqu’il s’applique sur de petites parties d’une image.

Utilisation actuelle de GEGL

Historique et relation à GIMP

GEGL est un projet très ancien avec pour raison initiale son intégration dans GIMP. Les plus anciennes annonces officielles de GIMP datent de 1995, et le plus vieux commit daté du dépôt de source est du 1er janvier 1997. De son côté, le plus vieux commit daté du dépôt de source de GEGL est du… 2 janvier 1997, avec comme auteur « People doing a 16 bpc version of gimp » (traduisible en « personnes faisant une version de gimp à 16 bits par canal »). À un jour près, les dépôts de source des deux projets ont donc été créés quasiment en même temps. GEGL n’est donc pas seulement né de GIMP, c’est presque son frère ! Certains n’ont cependant pas cru en GEGL (du moins pas suffisamment pour y consacrer du temps, ce qui a même engendré un fork célèbre de GIMP), et il faut avouer que cela a pris son temps (presque 20 ans !).
La première tentative d’intégration n’est apparue qu’en 2008 dans GIMP 2.6, soit 11 ans après la naissance du projet GEGL. Cette version comprenait seulement un port des opérations de couleur sur GEGL, optionnel (par défaut les opérations de couleur utilisaient toujours le code non GEGL) et un outil « GEGL » expérimental (donc non disponible par défaut dans la boîte à outils). Ainsi, cela initia un balbutiement du port où rien n’était activé par défaut, mais pouvait l’être par l’utilisateur aventureux.

GIMP 2.8 a vu plusieurs autres ports de fonctionnalités sur GEGL, notamment la projection des calques, les modes de calques, les sélections flottantes et le redimensionnement des calques. Néanmoins là encore, tous ces ports restaient désactivés par défaut dans la version stable.

GIMP 2.8 a vu plusieurs autres ports de fonctionnalités sur GEGL, notamment la projection des calques, les modes de calques, les sélections flottantes et le redimensionnement des calques. Néanmoins là encore, tous ces ports restaient désactivés par défaut dans la version stable.

Ainsi, bien que GEGL soit présent dans GIMP depuis 7 ans, cette partie du code est techniquement inexistante pour les utilisateurs, du code mort, inutilisé, dans le reste du programme. Dans les faits, GIMP ne contient donc pas encore de code GEGL du point de vue de l’utilisateur de base. C’est en 2012 que, finalement, deux contributeurs majeurs de GIMP (Mitch, mainteneur de GIMP et Pippin, mainteneur de GEGL) se sont un jour enfermés chez Mitch sans vraiment le planifier, et ne sont ressortis à la lumière du jour que 3 semaines plus tard, après avoir porté 90 % du cœur applicatif de GIMP vers GEGL.
Invasion des chèvres

Ces 90 % n’étaient en fait que le début. Car en plus du cœur, il restait toute la plateforme applicative de GIMP (les greffons, filtres, etc.) à porter, l’interface graphique à mettre à jour pour profiter du nouveau cœur, les détails à fignoler et la bibliothèque à optimiser.

D’ailleurs, c’est seulement quelques mois après cet évènement que je suis arrivé moi-même dans ce projet : un peu par hasard aussi et sans le vouloir, un jour j’ai donné un patch. À l’époque, je n’avais même jamais entendu parler de GEGL. Eh bien, laissez-moi vous dire que la version de développement de GIMP, à ce moment là, était totalement inutilisable, et ce, encore jusqu’à il y a à peine deux ans, car si lente que l’on pouvait donner un coup de pinceau puis aller préparer un café en regardant le trait s’afficher (ou presque !). C’est seulement très récemment que la bibliothèque a été massivement optimisée et commence à peine à atteindre la vitesse de la version précédente du cœur de GIMP pour les opérations de base (voire est plus rapide, dans pas mal de cas).

Un avant-goût de GIMP 2.10

GIMP 2.10 sera donc la première version où GEGL sera utilisée, remplaçant le code originel de traitement d’image, ce qui est une étape majeure de l’histoire de GIMP. En fait, ce ne sera même pas une alternative. Tout traitement d’image utilisera désormais GEGL.

Cela donnera à GIMP la prise en charge de nombreux nouveaux formats de fichiers, de la haute précision de couleur, une prévisualisation (partielle ou totale) des effets directement dans le canvas pour peaufiner les paramètres, et surtout à terme du traitement d’image non destructif. Mais… ceci est une histoire pour une prochaine news… 🙂

Intégration dans les bibliothèqes graphiques

Il existe plusieurs bibliothèques intermédiaires pour simplifier l’utilisation de GEGL :

Autres projets

Bien que GEGL soit né de GIMP, c’est avant tout dorénavant un projet à considérer comme une bibliothèque indépendante. Et nous espérons que de plus en plus de projets l’intégreront dans leur code.

Jon Nordby est l’un des grands implémenteurs de GEGL. Il a ainsi intégré GEGL comme backend supplémentaire dans MyPaint.
Il a également expérimenté le traitement vidéo par GEGL en implémentant un filtre GEGL pour GStreamer permettant d’intégrer un graphe GEGL dans son traitement vidéo, bien que celui-ci n’ait finalement pas été intégré upstream, non par intérêt des développeurs GStreamer, mais simplement par manque de temps pour le porter sur l’interface changeante du projet (laissant ouverte la possibilité).
Son dernier gros projet, imgflo, est un serveur web pour le traitement d’image, avec une interface graphique orientée graphes.
imgflo
Jon Nordby étant désormais employé par The Grid, plateforme commerciale de création de sites web générés par une intelligence artificielle, imgflo, et par conséquent GEGL est utilisé comme composant majeur pour toute l’automatisation des traitements d’image (ajustements de couleurs pour que les images utilisateurs s’adaptent au jeu de couleur du site, par exemple). Ce traitement passe par imgflo-server.
Enfin le travail de Jon Nordby sur imgflo montre un des grands intérêts de GEGL : Jon a développé un format JSON pour déclarer des graphes GEGL qui peuvent alors être sauvés dans imgflo puis chargés dans GIMP, par exemple. Il est ainsi très simple de partager des processus de travail complets entre applications pour automatiser des traitements sur de multiples images.
Bien entendu, cela a permis plusieurs améliorations de GEGL, sponsorisées par The Grid.

En dehors de ce développeur très prolifique, GNOME-photos dépend désormais de GEGL-gtk.
Certains autres projets bien établis ont aussi montré leur intérêt pour GEGL. Darktable par exemple avait entamé un port GEGL, en 2011 déjà, et annoncé qu’ils le termineraient quand GIMP prendrait en charge la haute précision des couleurs et l’édition non destructrice, ceci afin de pouvoir partager une image entre les deux applications. On est donc à la moitié du chemin.
Blender a aussi montré son intérêt pour GEGL, dans le but de mettre au niveau leur compositeur (« node editor », ou éditeur de nœuds en français), vieux et souffrant d’un design inadéquat pour de la composition efficace, comme le montre cette page de wiki proposant l’usage de GEGL comme alternative à une ré-implémentation maison. Bien sûr, rien ne dit s’ils agiront dans ce sens au final, mais ce serait une très bonne nouvelle, bénéfique pour tous les projets.

Nous découvrons aussi des plus petits projets qui utilisent GEGL. Par exemple lors des Libre Graphics Meeting 2014, Manuel Quiñones a annoncé son début d’implémentation d’un logiciel d’animation 2D, xsheet. On ne sait pas vraiment ce que cela va donner, mais il est toujours intéressant de voir apparaître des développeurs extérieurs qui commencent à utiliser GEGL.

Ces divers exemples montrent bien que le projet atteint une certaine maturité, et il faut maintenant continuer dans cette voie.

Note de sortie

Nous terminerons par un survol de la liste des nouveautés dans GEGL 0.3.0 et babl 0.1.12, qui comptent 92 contributeurs.

  • Amélioration du parallélisme et de la sécurité du multi-tâche.
  • OpenCL est désormais activé par défaut si détecté.
  • Multi-tâche expérimental, activé avec la variable d’environnement GEGL_THREADS=<nombre de tâches>.
  • Rendu mipmap expérimental permettant la prévisualisation sur des versions de petite taille de manière transparente, avec la variable d’environnement GEGL_MIPMAP_RENDERING=true.
  • Nouveau site web, galerie d’opérations et navigateur d’API.
  • Découverte et documentation des opérations en ligne de commande, avec les options suivantes sur la commande gegl: --list-all (liste de toutes les opérations disponibles), --properties (imprime les détails d’une opération) et --exists (teste l’existence d’une opération).
  • Prise en charge des URI pour le chargement d’image.
  • Chargement de meta-opérations en format JSON.
  • Nouvelles opérations: alien-map, antialias, apply-lens, bilateral-filter, bump.map, cartoon, channel-mixer, color-enhance, color-exchange, color-reduction, color-rotate, convolution-matrix, copy-buffer, cubism, deinterlace, diffraction-patterns, distance-transform, displace, edge, emboss, engrave, exposure, fractal-trace, high-pass, image-compare, illusion, invert-gamma, lens-flare, linear, linear-gradient, mosaic, motion-blur-circular, motion-blur-zoom, noise-cell noise-cie-lch, noise-hsv, noise-hurl, noise-pick, noise-rgb, noise-simplex, noise-spread, n-point deformation ops, oilify, panorama-projection, photocopy, plasma, radial-gradient, red-eye-removal, scale-size-keep-aspect, softglow, stretch-contrast, texturize-canvas, tile-glass, tile-seamless, tile-paper, tile, warp, whirl-pinch, wind, cache, cast-format, lcms-from-profile, npy-save, webp-load, webp-save, scale-ratio, scale-size, seamless-clone, sinus, supernova, value-propagate, video-degradation
  • Réimplémentation de gaussian-blur (plus rapide et précis).
  • Nouveau backend de tuiles par défaut, écrivant sur le disque en tâche séparée.

Lire les commentaires

(Source: LinuxFr.org : les dépêches)

Étiquettes: