2017-03-29 2 views
2

minimale Exemple de travail

Je tente de passer un tableau d'entiers à un plugin GIMP en utilisant le Scheme Script-Fu interface. J'ai un fichier de code source nommé main.c avec le contenu suivant:Passer un tableau à un module GIMP via Script-Fu

#include <libgimp/gimp.h> 
#include <stdlib.h> 
#include <stdio.h> 

static void query (void); 

static void run (
    const gchar *name, 
    gint nparams, 
    const GimpParam *param, 
    gint *nreturn_vals, 
    GimpParam **return_vals 
); 

const GimpPlugInInfo PLUG_IN_INFO = { 
    NULL, /* init_proc */ 
    NULL, /* quit_proc */ 
    query, /* query_proc */ 
    run, /* run_proc */ 
}; 

MAIN() 

static void query (void) 
{ 
    static GimpParamDef args[] = { 
    { 
     GIMP_PDB_INT32, 
     "run-mode", 
     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" 
    }, 
    { 
     GIMP_PDB_INT8ARRAY, 
     "an array", 
     "" 
     "an array" 
     } 
    }; 

    gimp_install_procedure (
     "my-test-plugin", 
     "My test plug-in", 
     "Description", 
     "Jane Doe <[email protected]>", 
     "Copyright (C) Jane Doe\n" 
     "http://foo.bar", 
     "2017", 
     g_strconcat("My test plug-in", "...", NULL), 
     "RGB*, GRAY*", 
     GIMP_PLUGIN, 
     G_N_ELEMENTS (args), 
     0, 
     args, 
     NULL 
    ); 
} 

static void run (
    const gchar *name, 
    gint nparams, 
    const GimpParam *param, 
    gint *nreturn_vals, 
    GimpParam **return_vals) 
{ 
    static GimpParam value; 
    value.type = GIMP_PDB_STATUS; 
    value.data.d_status = GIMP_PDB_SUCCESS; 
    *nreturn_vals = 1; 
    *return_vals = &value; 

    FILE* out = fopen("mylog.log", "w"); 
    fprintf(out, "Parameter #0:\t%d\nParameter #1:\t", param[0].data.d_int32); 
    for (int i = 0; i < 16; ++i) 
     fprintf(out, "%d ", param[1].data.d_int8array[i]); 
    fprintf(out, "\n"); 
    fclose(out); 
} 

Je compiler et installer le fichier en tant que plugin GIMP sur comme suit:

sudo apt install libgimp2.0-dev 
gcc `gimptool-2.0 --cflags --libs` main.c 
gimptool-2.0 --install-bin ./a.out 

Je fais cela sur une boîte Debian 9 . Lorsque je tente de lancer le plug-in en utilisant l'interface Script-Fu:

(my-test-plugin 1 #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)) 

Calling the plugin via Script-Fu

un fichier nommé mylog.log est créé avec le contenu suivant:

Parameter #0: 1 
Parameter #1: 1 0 0 0 0 0 0 0 64 201 246 126 174 85 0 0 

alors que ce qui suit est la contenu prévu:

Parameter #0: 1 
Parameter #1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 

La version du monde réel

J'essaie d'utiliser the gimp-plugin-morphop GIMP plugin en utilisant le Scheme Script-Fu interface. Lorsque j'utilise l'interface graphique, le plugin fonctionne comme prévu:

Hit-or-Miss via GUI #1 Hit-or-Miss via GUI #1

Cependant, quand j'utilise le script-fu suivant:

(plug-in-morphop RUN-NONINTERACTIVE 1 2 6 7 
    #(-1 -1 -1 -1 -1 -1 -1 
    -1 1 -1 -1 -1 1 -1 
    -1 -1 0 0 0 -1 -1 
    -1 -1 0 0 0 -1 -1 
    -1 -1 0 0 0 -1 -1 
    -1 1 -1 -1 -1 1 -1 
    -1 -1 -1 -1 -1 -1 -1) 24 2) 

le plugin ne produit pas le résultat escompté :

Hit-or-Miss via Script-Fu #1 Hit-or-Miss via Script-Fu #1

J'ai modifié le plugin pour voir ce que la différence réelle était:

diff --git a/src/morphop-algorithms.c b/src/morphop-algorithms.c 
index b927ba3..9dff320 100644 
--- a/src/morphop-algorithms.c 
+++ b/src/morphop-algorithms.c 
@@ -166,7 +166,16 @@ void start_operation(GimpDrawable *drawable, GimpPreview *preview, MorphOpSettin 
       GimpPixelRgn src_rgn_c, dst_rgn_c; 
       guchar* src_preview_c = NULL, *dst_preview_c = NULL; 

+    FILE* log = fopen("morphop-operation.log", "w"); 
       int i, j; 
+    for(i = 0; i < STRELEM_DEFAULT_SIZE; i++) { 
+      for(j = 0; j < STRELEM_DEFAULT_SIZE; j++) { 
+        fprintf(log, "%d ", settings.element.matrix[i][j]); 
+      } 
+      fprintf(log, "\n"); 
+    } 
+    fclose(log); 
+ 
       // white structuring element 
       for(i = 0; i < STRELEM_DEFAULT_SIZE; i++) { 
         for(j = 0; j < STRELEM_DEFAULT_SIZE; j++) { 

Après avoir utilisé le module via l'interface graphique, le fichier morphop-operation.log contient le texte suivant:

-1 -1 -1 -1 -1 -1 -1 
-1 1 -1 -1 -1 1 -1 
-1 -1 0 0 0 -1 -1 
-1 -1 0 0 0 -1 -1 
-1 -1 0 0 0 -1 -1 
-1 1 -1 -1 -1 1 -1 
-1 -1 -1 -1 -1 -1 -1 

comme prévu. Après avoir exécuté le code Script-Fu, le fichier morphop-operation.log contient le texte suivant:

-1 0 0 86 0 103 114 
-1 64 0 0 0 45 112 
-1 41 64 0 0 105 104 
-1 8 42 33 0 110 111 
-1 95 8 0 112 45 112 
-1 36 95 0 108 109 0 
-1 86 36 0 117 111 32 

où les six entiers sur chaque ligne les plus à droite semblent être des données aléatoires qui change à chaque appel.Depuis settings.element.matrix est déjà une représentation interne du tableau reçu, j'ai modifié le plugin un peu plus loin pour afficher le tableau reçu directement:

diff --git a/src/morphop.c b/src/morphop.c 
index 3895770..cb814b6 100644 
--- a/src/morphop.c 
+++ b/src/morphop.c 
@@ -150,9 +150,16 @@ static void run (
           } 

           msettings.operator = param[3].data.d_int32; 
-        
+      
+        FILE* log = fopen("morphop-init.log", "w"); 
           int i; 
           for (i = 0; i < STRELEM_DEFAULT_SIZE * STRELEM_DEFAULT_SIZE; i++) { 
+          fprintf(log, "%d ", param[5].data.d_int8array[i]); 
+        } 
+        fprintf(log, "\n"); 
+        fclose(log); 
+ 
+        for (i = 0; i < STRELEM_DEFAULT_SIZE * STRELEM_DEFAULT_SIZE; i++) { 
             msettings.element.matrix[i % STRELEM_DEFAULT_SIZE][(int)ceil((i + 1.0)/STRELEM_DEFAULT_SIZE) - 1] = param[5].data.d_int8array[i]; 
           } 

Après avoir exécuté le code Script-Fu, le fichier morphop-init.log contient le texte suivant:

255 255 255 255 255 255 255 0 64 169 248 158 193 85 0 0 64 170 248 158 193 85 0 0 33 0 0 0 0 0 0 0 112 108 117 103 45 105 110 45 109 111 114 112 104 111 112 0 32 

les valeurs au-delà de la huitième semblent être au hasard des déchets, bien que certains conservent leur valeur à travers plusieurs pistes:

255 255 255 255 255 255 255 0 64 89 10 89 79 86 0 0 64 90 10 89 79 86 0 0 33 0 0 0 0 0 0 0 112 108 117 103 45 105 110 45 109 111 114 112 104 111 112 0 32 
255 255 255 255 255 255 255 0 64 217 110 172 167 85 0 0 64 218 110 172 167 85 0 0 33 0 0 0 0 0 0 0 112 108 117 103 45 105 110 45 109 111 114 112 104 111 112 0 32 

Pour moi cela signifie que le tableau est passé dans un format différent de celui prévu par le plug-in. Comment puis-je passer un tableau dans un plug-in GIMP via Script-Fu, afin qu'il reste intact?

+0

En supposant complètement, est-il possible qu'en sortie de morphop-operation.log matrice transposée? Donc, la première colonne est correctement passée en tant que première ligne d'origine et après cela est tout poubelle? Peut-être que la fin des lignes dans votre script est tout déconner? ... (plug-in-morphop RUN-NON INTERACTIVE 1 2 6 7 # (- 1 -1 -1 -1 -1 -1 -1 ici -1 1 -1 -1 -1 1 -1 ici - 1 -1 0 0 0 -1 -1 ici -1 -1 0 0 0 -1 -1 etc. -1 -1 0 0 0 -1 -1 -1 1 -1 -1 -1 1 - 1 -1 -1 -1 -1 -1 -1) – Ondrej

+0

(i) En effet, il est transposé.Voir le contexte du second diff, le tableau 'msettings.element.matrix' est une version transposée de la matrice d'entrée 'param [5] .data.d_int8array'. (ii) Non, les retours à la ligne n'ont aucune incidence sur le résultat – Witiko

+0

(plug-in-morphop RUN-NONINTERACTIVE 1 2 6 7 # (- 1 -1 -1 -1 -1 -1 -1] [-1 1 -1 -1 -1 1 -1] [-1 -1 0 0 0 -1 -1] [-1 -1 0 0 0 -1 -1] [-1 -1 0 0 0 -1 -1] [-1 1 -1 -1 -1 1 -1] [-1 -1 -1 -1 -1 -1 -1]) 24 2) – Ondrej

Répondre

1

Dans l'API, il s'agit de necessary to pass the size of the array before the array.

--- /tmp/plugin.orig 2017-04-02 16:45:34.902108610 +0200 
+++ /tmp/plugin.c 2017-04-02 16:43:26.510105281 +0200 
@@ -30,6 +30,11 @@ 
     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" 
    }, 
    { 
+  GIMP_PDB_INT32, 
+  "array-size", 
+  "The array bellow" 
+ }, 
+ { 
     GIMP_PDB_INT8ARRAY, 
     "an array", 
     "" 
@@ -69,9 +74,9 @@ 
    *return_vals = &value; 

    FILE* out = fopen("mylog.log", "w"); 
- fprintf(out, "Parameter #0:\t%d\nParameter #1:\t", param[0].data.d_int32); 
+ fprintf(out, "Parameter #0:\t%d\nParameter #2:\t", param[0].data.d_int32); 
    for (int i = 0; i < 16; ++i) 
-  fprintf(out, "%d ", param[1].data.d_int8array[i]); 
+  fprintf(out, "%d ", param[2].data.d_int8array[i]); 
    fprintf(out, "\n"); 
    fclose(out); 
} 

Puis:

> (my-test-plugin 1 16 #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)) 
(#t) 

Résultats dans:

$ cat mylog.log 
Parameter #0: 1 
Parameter #2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 

Et vous pouvez vérifier les paramètres sont liés implicitement en faisant la plus grande taille que la longueur:

> (my-test-plugin 1 17 #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)) 
Error: (: 1) INT8 vector (argument 3) for function my-test-plugin has 
size of 15 but expected size of 17 

(Le paramètre précédent ter étant RUN-NONINTERACTIVE (1) ou element-size (7), explique les différentes quantités de contenu de tableau disponibles dans vos 2 tests.)

+0

En effet, cela semble être le problème; Je vous remercie! La documentation sur n'est pas vraiment utile (elle liste simplement les différentes définitions de type et de méthode). Existe-t-il une meilleure ressource ou un développeur de plugins devrait-il être familier avec le code libgimp? – Witiko

+0

@Witiko heureux que c'était ça.Je trouve qu'il est plutôt difficile de déboguer ceux-ci d'une manière autre que celles que vous avez essayées, bien que les exemples de procédures intégrées/actives/populaires soient un peu plus sûrs et montrent toujours des corrélations comme les paramètres de taille redondants avant les tableaux. Trouver le code est aussi difficile jusqu'à ce que vous ayez forcé une erreur (ou quelque chose dans le traçage), c'est-à-dire que l'erreur que j'ai forcé à vérifier le problème m'amène finalement au code: https://git.gnome.org/browse/gimp- tiny-fu/tree/minuscule-fu/ts-wrapper.C# n914 – lossleader

+1

Eh bien, que savez-vous? J'ai également réussi à trouver ce code, mais en quelque sorte la partie 'args [i-1] .data.d_int32' n'a pas cliqué pour moi. :-) – Witiko