Archive pour la catégorie ‘Gimp’

Gimp warp tool: c’est la mi-parcours !

Et voilà, on est déjà à la mi-parcours pour le Google Summer of Code, et je n’ai pas posté de mise à jour comme je le voulais. Il faut croire que réflechir et coder reste plus amusant pour moi qu’écrire. Néamoins, corrigeons ça.

Le moins que l’on puisse dire, c’est que l’outil warp (il va falloir que je trouve une traduction française) est en bien meilleure forme que l’outil cage à la même époque l’an dernier. La raison est simple, j’ai appris énormement l’an passé, et il faut bien avouer que l’outil warp fait appel à des compétences similaires, voir reprend quelques portions de code.

Ceci étant dit, voilà le bilan:

  • Toute l’infrastructure de l’outil est en place et fonctionnelle.
  • On peut appliquer des déformations directement sur le canvas.
  • 7 comportements sont supportés actuellement:
    • déplacement de pixels
    • grossissement d’une zone
    • rétrécissement d’une zone
    • spirale dans le sens horaire
    • spirale dans le sens anti-horaire
    • effacement local d’une transformation
    • lissage local d’une transformation
  • Les actions sur le canvas se font grâce à un pinceau rond, avec une courbe d’influence gaussiene.
  • Les réglages du pinceau sont la force, la taille et la dureté de la courbe d’influence (plus ou moins raide).

Une petite vidéo pour la forme:

Les différentes opérations effectuées sur le canvas sont implémentées comme des opérations Gegl qui produisent un buffer de coordonées relatives, que l’on insère dans le graph de rendu. L’image finale est calculée grace à une opération de rendu map-relative.

Et voilà ce qu’il reste à corriger:

  • Les performances restent à améliorer. Actuellement, à chaque action sur l’image, chaque opérations déjà effectuées est recalculées (le cache ne fonctionne pas correctement), et ce pour toute la surface de l’image (un problème dans le code historique qui n’a pas été conçu pour ça). D’autres pistes d’amélioration existent, comme l’implémentation du Copy On Write (COW) pour les GeglBuffer. Le but final est d’effectuer les actions de manière interactive.
  • Un bon réglage est nécessaire, les différents comportements ne sont pas cohérents actuellement.
  • Implémenter l’interface selon les spécifications de Peter Sikking et de son équipe.
  • Implémenter l’annulation des opérations.

Comme j’ai plus de facilités cette année, j’en profite pour aller un peu plus en profondeur et de travailler sur des choses annexes, en particulier dans Gegl. Une chose intéressante est de constater que l’outil warp est structurellement assez proche d’un moteur de dessin (dans le sens pinceau), et fait donc un pas de plus vers un moteur de dessin basé sur Gegl dans Gimp.

On da road again !

Et voilà. Cette année encore, je vais participer au programme Google Summer of Code !

Ma participation à l’édition de l’an dernier aura été pour moi un énorme défi, un moyen d’apprendre énormément de chose, de rencontrer et côtoyer des gens très intéressants, et une grande source de fierté (même pour ma famille, c’est dire si le nom de Google veut dire quelque chose pour la société d’aujourd’hui).

Cette année, je vais pouvoir mettre à profit toutes ces connaissances engrangés l’an dernier pour réécrire l’ancien plugin iWarp comme un véritable outil interne à Gimp (dont le petit nom sera le Gimp Warp tool). C’est un outil qui a longtemps été demandé par les utilisateurs de Gimp. Là encore, cet outil s’intégrera dans la « grande vision » du futur de Gimp (Gegl, prévisualisation directement sur l’image, ..).

D’un point de vue plus personnel, il est clair que ma tâche de cette année présente moins de défi que l’an dernier (un autre outil de déformation, structure relativement proche ..), et c’est presque dommage. Néanmoins, c’est toujours sympathique de travailler sur un projet comme Gimp, et les utilisateurs le rendent bien la plupart du temps. Et puis, il faut bien faire travailler son cerveau pendant l’été =)

Cette fois, je devrais être capable de faire cet outil de la bonne façon, dès la première fois (et donc éviter les 3 ou 4 réécritures partielles qui ont suivit la période officielle de développement du programme Summer of Code). Avec un peu de chance, cet outil pourrait être intégré à Gimp 2.8. Le début de la période de code est finalement pas si loin !

A bientôt !

 

 

Quelques new de l’outil cage

Cela fait maintenant quelques temps que je n’ai pas posté de news a propos de de l’outil cage. Il est même resté quelques mois sans changements, quand je me suis mis en tête de coder un ERP adapté au Junior-Entreprise. J’y ai passé quelques heures aujourd’hui, et je me suis dit qu’il serait temps de faire un petit bilan des changements depuis ce temps:

  • comme annoncé précédemment, une réécriture de la gestion de l’interface sous forme d’une machine à état, avec pas mal de nettoyage (et quelques régression également, il faut avouer)
  • utilisation d’une structure de donnée spécifique, ce qui permet ..
  • la sélection multiple des poignées, avec une sélection par ruban, pour pouvoir éditer une cage plus rapidement, ou simplement la bouger en entier d’un coup
  • la possibilité de revenir dans dans le mode d’édition de la cage, et ajuster la cage de départ
  • quelques optimisations dans l’opérateur Gegl qui effectue la transformation

Il reste des bugs à attraper, le plus évident étant que l’image se décale après un retour en mode d’édition. Mais promis, ça sera près pour la sortie de Gimp 2.8 ! D’ailleurs, les dernières corrections se feront a partir de maintenant dans la branche master de Gimp, donc ce n’est plus la peine de récupérer la branche de l’outil.

Pour fêter tout ça, j’ai fait un rapide screencast avec un lézard comme victime.

14 années de développement de Gimp

Le développement d’un logiciel tel que Gimp se fait sur de longues années, et par un nombre conséquent de personne. Pour vous donner une idée de la chose, j’ai fais une vidéo des changements intervenu sur le dépôt de code depuis 14 ans.

Une précision cependant, les 2 premières années du développement ne sont pas sur la vidéo car les logs ne sont pas disponible dans Git.

Cette vidéo a été faite avec le logiciel Gource, très sympathique au demeurant =)

Compiler Gimp avec LLVM/Clang et analyse statique

Clang, qui utilise l’infrastructure de LLVM, est un compilateur pour la famille de langage du C. Son but est d’offrir une alternative moderne à GCC. Avec Clang arrive notamment un très sympathique analyseur statique du code source. Nous allons appliquer ça à Gimp.

Pour ça, j’ai lâchement copié et adapté la procédure donné par Campbell Barton, de la team Blender. (http://wiki.blender.org/index.php/User:Ideasman42/BlenderClang).

Voici ce que ça donne à la sauce Gimp:

Etape 1: compiler LLVM/Clang

J’ai d’abord essayé avec la version fournis dans ArchLinux, mais Clang s’arrêtait avec une fatal error. Ça se passe bien mieux avec la version de développement. Pour la récupérer, le script de Campbell Barton fonctionne très bien.

Etape 2: configurer la compilation de Gimp

Déjà, il faut ajouter les binaires de LLVM dans le PATH:

export PATH=$PATH:/opt/llvm/bin

La seule différence avec une compilation classique, c’est qu’on demande explicitement le compilateur de CLang:

CC=ccc-analyzer ./autogen.sh --prefix=/opt/gimp/

Etape 3: compiler

Si vous voulez juste compiler, la procédure ne change pas.

make -j3

Si vous voulez lancer en même temps une analyse statique, il faut utiliser scan-build:

scan-build -o clang make -j3

Attention, une compilation avec analyse statique prend pas mal de temps (3h40 avec mon Core 2 Duo E4500).

Etape 4: profit !

L’analyseur statique de LLVM va probablement trouver tout un tas de bug dans le code. Il y a bien sûr des faux positifs, mais c’est dans l’ensemble remarquablement bien fait ! Vous trouverez le résultat de l’analyse de master que j’ai fait aujourd’hui ici: http://pellelatarte.fr/dawa/gimp-llvm/

Refactorisation et évolution de l’outil Cage

Hello,

Un article rapide pour vous dire que j’ai commencé un refactoring du code de l’outil cage de Gimp. C’est une étape nécessaire pour atteindre une bonne qualité de fonctionnement et une bonne base pour implémenter de nouvelle choses. Cela passe ici par une réécriture de la gestion de l’interface avec une machine à états (comme décrit ici il y a quelques jours),  des changements dans les structures de données, de la documentation, et pas mal de petites simplifications et corrections.

Pour l’avenir, une sélection multiple des points de la cage devrait arriver rapidement dans la branche soc-2010-cage-2. Ce mode d’édition fonctionnera de manière similaire à celui de l’outil chemin.

Un mode d’édition proportionnelle similaire à ce qu’on peut trouver dans Blender devrait voir le jour également.

Si ça se trouve, je vais finir par être satisfait de mon boulot un jour … =)

L’outil cage est dans la branche principale !

Gimp Cage Tool Splash

Ça y est ! Depuis 48h maintenant, le code de l’outil de déformation par cage est dans la branche principale de Gimp ! Il sera donc, sauf surprise, inclus dans la prochaine release, la 2.8 !

Un grand merci à mon mentor, Alexia Death et à Michael Natterer (Mitch) de s’occuper de cette fusion et du nettoyage qui l’accompagne.

Vidéo de l’outil de déformation par cage

Hello,

Un internaute à fait une petite revue de mon outil de déformation par cage et l’a publié sur le site d’une communauté d’utilisateur de Gimp. C’est sur le site GimpUser.com !

L’article contient notamment une vidéo de l’outil en action !

En tout cas, ça fait vraiment plaisir de voir que la chose plait, et que c’est utile =)

Il faut vraiment que je trouve du temps pour fignoler tout ça (interface et optimisation surtout) …

Trick list

Voici une liste d’astuces, de techniques que j’ai apprise durant mon Summer of Code. Elle est livré un peu en vrac, et peu, ou non, vous intéresser.

Allocation mémoire avec la Glib:

allocation mémoire pour des objets:

– g_new (struct_type, nombre)
– g_renew (struct_type, ancienne_allocation, nombre)
– g_unref_object (objet)

allocation simple:

– g_malloc (nombre_d’octet)
– g_realloc (ancienne_allocation, nombre_d’octet)
– g_free (mémoire)
Les allocations avec g_malloc sont couteuse, donc si la mémoire a une taille fixe, preferez g_slice.

Coder pour Gimp

debug des gobject et erreurs glib

Lancez Gimp avec l’argument –g-fatal-warnings

debug des evenements GTK

Lorsque GTK envois un évenement (appuie d’une touche, clic souris ..), Gimp prend la main sur le gestionnaire d’entrée/sortie. Si vous mettez un breackpoint dans la gestion d’un evenement, ce gestionnaire d’evenement n’est pas rendu à GTK quand le débuggeur bloque Gimp. Résultat vous ne pouvez plus utiliser ni clavier, ni souris. Pas pratique. La solution est de compiler votre propre GTK avec l’option –enable-debug=yes, compiler Gimp avec ce GTK, et lancer Gimp avec l’option –gtk-no-grabs.

autogen.sh

Les options de compilation sont visible avec ./configure –help

compiler sans optimisation

CFLAGS=-O0 ./autogen.sh –prefix=….

installation rapide des binaires uniquement

cd app/ && sudo make install-binPROGRAMS

Gobject

les gobject, c’est mal.

si vous avec un warning relatif au gobject, essayer un make install

quelque chose cloche ? essayez un make install

Babl

Babl est une librairie qui sert à l’abstraction des différents format de pixel (RVB, CMJN, ..)

déclarer un format

babl_type (« float »)
babl_type (« u8″)
babl_format_n (babl_type (« float »), nombre_element)
Voir la doc http://www.gegl.org/babl/#Vocabulary pour voir les formats disponible. Une petite précision:
– R': gamma ajusté
– Ra: alpha pré-multiplié
<http://www.gimp.org/docs/plugin_in/appendix-alpha.html>

convertir des formats avec un Babl fish

babl_process (babl_fish, buffer_source, buffer_destination, nombre_d’element)

Gegl

creer un buffer

GeglBuffer *bfr = gegl_buffer_new (gegl_rectangle, babl_format)

buffer leak

Dans le fichier gegl/buffer/gegl_buffer.c, décommentez #define GEGL_BUFFER_DEBUG_ALLOCATION. A la sortie de Gimp, une trace d’allocation va être affiché. Vous pouvez convertir les adresses du binaire en position dans le code source avec addr2line -e app/.libs/gimp-2.7 adresse

Git

push dans une branche distante

git push origin soc-2010-cage

garder la branche à jour

git fetch origin && git rebase origin

Fin officielle

Et voilà, le summer of code est terminé, du moins officiellement.
J’ai finalement moins mis à jour le blog que je voulais. Il faut avouer qu’au bout de 2 mois à se taper la tête contre le code, la motivation faiblit un peu. Enfin, voilà les news:
Comme annoncé dans le dernier billet, j’ai travaillé sur une méthode pour inverser le calcul de la transformation (c’est à dire savoir d’où viennent les pixels, plutôt que où ils vont), ce qui permet d’avoir une bonne qualité d’image, en évitant surtout l’aliasing. Le principe est le suivant:
  • on positionne sur l’image une grille de la surface de la cage avant déformation.
  • on applique la déformation aux points de cette grille.
  • on divise chaque case de cette grille en deux triangles
  • on parcourt chacun de ces triangles, on trouve les pixels à l’intérieur, et on en déduit les coordonnées du pixel source, par interpolation.
  • on obtient donc, pour chaque pixel de l’image, à quelle coordonnée de l’image il faut piocher des pixels pour trouver l’image transformée (sampling).
Ma première approche pour le problème de l’interpolation dans les triangles a été de retrouver un sens (trouver le point le plus haut, les points droite et gauche), puis de le parcourir avec des équations de droites. Et bien c’est pas une grande idée. Il y a un tas de cas particulier, c’est compliqué et inefficace. Finalement, un ami m’a suggéré de procéder de manière récursive, c’est à dire de découper les triangles en 4, jusqu’à qu’il ne contienne plus qu’un pixel. Ensuite on interpole ses coordonnées source grâce à un système de barycentre. Et là, ça marche tout le temps, et c’est même efficace ! Merci Théophile (oui, tu as donc contribué au logiciel libre avec plus qu’un patch pour la libcaca =) ).
En fait c’est tellement efficace que ça va probablement remplacer la méthode « directe » qui sert pour l’instant de prévisualisation interactive (qui en plus est assez moche).
Voici donc à quoi ressemble le coeur de l’outil. Chaque cercle est une opération Gegl.
  • Cage_coef_calc sert à calculer, pour chaque pixel à transformer, la série de coefficient qui sert à la transformation.
  • Cage_transform calcule et inverse la transformation.
  • Render_mapping recompose l’image finale.
L’intérêt de cette architecture et de Gegl en général, c’est qu’on peux facilement réutiliser les éléments. Typiquement, le code de mon outil pourra être réutilisé assez facilement pour créer un outil dans le style du plugin iWarp.
Pour en revenir à l’essentiel, voici l’état des lieux. L’outil est globalement terminé. Par globalement, je veux dire que le coeur fonctionne correctement, et qu’il est utilisable dans une utilisation « classique ». Il reste quelque défaut de jeunesse à corriger (par exemple, il ne marche pas sur les masques de calques), peaufiner l’interface, et il sera près pour une relecture de code et l’inclusion dans la branche principale de Gimp.
Voici quelques exemples de déformation;