RSS/Atom feed Twitter
Site is read-only, email is disabled

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.

This is a read-only list on gimpusers.com so this discussion thread is read-only, too.

14 of 14 messages available
Toggle history

Please log in to manage your subscriptions.

pdb.gimp_get_item_by_id(), or ids and layers and layer groups Javier Candeira 06 Feb 08:41
  pdb.gimp_get_item_by_id(), or ids and layers and layer groups Rob Antonishen 06 Feb 13:15
   pdb.gimp_get_item_by_id(), or ids and layers and layer groups saulgoode@flashingtwelve.brickfilms.com 06 Feb 15:30
    pdb.gimp_get_item_by_id(), or ids and layers and layer groups Rob Antonishen 06 Feb 16:18
    Creating sub-directories from Script-Fu scripts Kevin Cozens 06 Feb 18:06
     Creating sub-directories from Script-Fu scripts saulgoode@flashingtwelve.brickfilms.com 07 Feb 09:05
      Creating sub-directories from Script-Fu scripts Rob Antonishen 07 Feb 14:12
       Creating sub-directories from Script-Fu scripts Alexia Death 07 Feb 15:24
        Creating sub-directories from Script-Fu scripts Joao S. O. Bueno 07 Feb 16:26
       Creating sub-directories from Script-Fu scripts Kevin Cozens 07 Feb 17:00
        Creating sub-directories from Script-Fu scripts Rob Antonishen 07 Feb 18:01
        Creating sub-directories from Script-Fu scripts saulgoode@flashingtwelve.brickfilms.com 07 Feb 20:04
pdb.gimp_get_item_by_id(), or ids and layers and layer groups saulgoode@flashingtwelve.brickfilms.com 07 Feb 09:44
  pdb.gimp_get_item_by_id(), or ids and layers and layer groups Javier Candeira 07 Feb 10:10
Javier Candeira
2011-02-06 08:41:49 UTC (almost 14 years ago)

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

First of all, a big thank you to the developers for an great image editing program.

I am writing a python-gimp export script for an animation tool, using Ubuntu 10.10 "maverick" with Gimp version 2.7.3 from this ubuntu PPA, which is not a nightly build of your devel tree, but close enough: https://launchpad.net/~matthaeus123/+archive/mrw-gimp-svn

The workflow expects a gimp document's layers to be exported as a tree of files, where the directory structure is determined by the document's layer groups. So, if group "panel_1" has sublayers "foo" and "bar", and group "panel_2" has sublayers "blargh" and "foobar", the expected output looks like this:

$ tree exported_layers exported_layers
|-- panel_1
| |-- bar.png
| `-- foo.png
`-- panel_2
|-- blargh.png
`-- foobar.png

How can one get the layer objects that correspond to a given group? It's easy to get layer IDs, it's not clear how to access the layer object even if one knows its ID.

The gimp.image.layers sequence only contains the first-level layers and layer groups, not all the layers. In our document, all layers belong to a group, so that sequence only contains layer groups.

When getting the children of a given group, "pdb.gimp_item_get_children(group)[1]" returns a tuple of IDs. Having only each layer's ID and not the layer object means one can't, for instance, make a new layer as a duplicate of an existing one. This code fails with a type error:
newlayer = pdb.gimp_layer_new_from_drawable(layerID, image)

Is there something I'm missing/doing wrong, or is this a gap in the available script-fu methods?

Thanks,

Javier Candeira.

Rob Antonishen
2011-02-06 13:15:12 UTC (almost 14 years ago)

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

I'm not a dev but AFAIK none of the layer group stuff es exposed in the pdb, so has not been added to script-fu or python.

-Rob A>

On 2/6/11, Javier Candeira wrote:

First of all, a big thank you to the developers for an great image editing program.

I am writing a python-gimp export script for an animation tool, using Ubuntu 10.10 "maverick" with Gimp version 2.7.3 from this ubuntu PPA, which is not a nightly build of your devel tree, but close enough: https://launchpad.net/~matthaeus123/+archive/mrw-gimp-svn

The workflow expects a gimp document's layers to be exported as a tree of files, where the directory structure is determined by the document's layer groups. So, if group "panel_1" has sublayers "foo" and "bar", and group "panel_2" has sublayers "blargh" and "foobar", the expected output looks like this:

$ tree exported_layers exported_layers
|-- panel_1
| |-- bar.png
| `-- foo.png
`-- panel_2
|-- blargh.png
`-- foobar.png

How can one get the layer objects that correspond to a given group? It's easy to get layer IDs, it's not clear how to access the layer object even if one knows its ID.

The gimp.image.layers sequence only contains the first-level layers and layer groups, not all the layers. In our document, all layers belong to a group, so that sequence only contains layer groups.

When getting the children of a given group, "pdb.gimp_item_get_children(group)[1]" returns a tuple of IDs. Having only each layer's ID and not the layer object means one can't, for instance, make a new layer as a duplicate of an existing one. This code fails with a type error:
newlayer = pdb.gimp_layer_new_from_drawable(layerID, image)

Is there something I'm missing/doing wrong, or is this a gap in the available script-fu methods?

Thanks,

Javier Candeira. _______________________________________________ Gimp-developer mailing list
Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer

saulgoode@flashingtwelve.brickfilms.com
2011-02-06 15:30:25 UTC (almost 14 years ago)

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

Quoting Rob Antonishen :

I'm not a dev but AFAIK none of the layer group stuff es exposed in the pdb, so has not been added to script-fu or python.

On 2/6/11, Javier Candeira wrote:

:
:
The gimp.image.layers sequence only contains the first-level layers and layer groups, not all the layers. In our document, all layers belong to a group, so that sequence only contains layer groups. :
:
Is there something I'm missing/doing wrong, or is this a gap in the available script-fu methods?

The PDB functions already exist for handling layer groups, and Script-fu does not have any problem making use of these functions. The Python-fu extension has not yet been updated to handle groups (there is no 'group' class).

Unfortunately, Script-fu does not provide a way to create subdirectories so a direct scripting solution to Javier's problem is not available. Using Script-fu, each layer could be saved with the layer tree structure information embedded in the filenames. For example

exported_layers++panel_1++bar.png exported_layers++panel_1++foo.png
exported_layers++panel_2++blargh.png exported_layers++panel_2++foobar.png

A BASH script could then relocate these files to a suitable directory tree (or perhaps the animation tool could deal with the flat files directly, extracting the embedded information from the filenames).

Of course, writing a C plug-in would avoid these problems.

Rob Antonishen
2011-02-06 16:18:11 UTC (almost 14 years ago)

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

On Sun, Feb 6, 2011 at 10:30 AM,
wrote:

The PDB functions already exist for handling layer groups, and Script-fu does not have any problem making use of these functions. The Python-fu extension has not yet been updated to handle groups (there is no 'group' class).

I stand corrected. When were they added into 2.7?

-Rob A>

Kevin Cozens
2011-02-06 18:06:40 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

saulgoode@flashingtwelve.brickfilms.com wrote:

Script-fu does not provide a way to create subdirectories

This came up in #gimp recently. It would be a useful addition to Script-Fu. This could be done by adding a "dir-create" function to the ftx extension used by the TinyScheme portion of Script-Fu. If a directory creation function is added then another function to add would be "dir-exists?".

saulgoode@flashingtwelve.brickfilms.com
2011-02-07 09:05:26 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

Quoting Kevin Cozens :

saulgoode@flashingtwelve.brickfilms.com wrote:

Script-fu does not provide a way to create subdirectories

This came up in #gimp recently. It would be a useful addition to Script-Fu. This could be done by adding a "dir-create" function to the ftx extension used by the TinyScheme portion of Script-Fu. If a directory creation function is added then another function to add would be "dir-exists?".

Before I responded to the original post, I attempted to create just such a function by modifying 'dir-open-stream'. I came up with the following code but couldn't figure out how to build it out-of-tree in a way the original poster could use without recompiling his GIMP (the #include of scheme.h and scheme-private.h were basically where I bogged down).

It should be trivial to add such a function to GIT tree. A file copy function might also be useful (since file extensions are not always available to indicate the type and copying text files using read-char/write-char is slow and apparently unreliable).

pointer foreign_dircreate(scheme *sc, pointer args) {
pointer first_arg;
char *dirpath;
GDir *dir;

if (args == sc->NIL) return sc->F;

first_arg = sc->vptr->pair_car(args); if (!sc->vptr->is_string(first_arg)) return sc->F;

dirpath = sc->vptr->string_value(first_arg); dirpath = g_filename_from_utf8 (dirpath, -1, NULL, NULL, NULL);

dir = g_mkdir(dirpath, 0700); if (dir != 0)
return sc->F;

/* Stuffing a pointer in a long may not always be portable ~~~~~ */ return (sc->vptr->mk_integer(sc, (long) dir)); }

/* This function gets called when TinyScheme is loading the extension */ void init_dircreate (scheme *sc)
{
sc->vptr->scheme_define(sc, sc->global_env, sc->vptr->mk_symbol(sc,"dir-create"), sc->vptr->mk_foreign_func(sc, foreign_dircreate)); }

saulgoode@flashingtwelve.brickfilms.com
2011-02-07 09:44:21 UTC (almost 14 years ago)

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

Quoting Javier Candeira :

On Mon, Feb 7, 2011 at 2:30 AM,
wrote:

The PDB functions already exist for handling layer groups, and Script-fu does not have any problem making use of these functions. The Python-fu extension has not yet been updated to handle groups (there is no 'group' class).

Do you mean that the Python-fu extension doesn't yet have access to the proper script-fu functions from pdb?

Not exactly. In Python, a "layer" is a reference to a data structure (in C terminology, a pointer to a struct). One of the fields is the layer's ID number. The PDB only deals with these ID numbers, and Python doesn't provide a direct way to handle IDs. The only thing you could do is get a list of all layers/groups (which would be a list of pointers to structures) and search that list for the structure containing the appropriate ID. Since the 'gimp-image-get-layers' procedure now only returns the IDs of the top-level layers/groups, there is no way to perform such a search. At some point, this will be remedied but to my knowledge there is currently no way to do what you want with Python.

Script-fu does not encounter this problem because there is no Script-fu data structure for a layer -- a layer is identified by the same ID number that the PDB uses. It does not matter that the "layer" IDs returned by 'gimp-image-get-layers' might actually be "group" IDs, to Script-fu it is just a number. Script-fu can pass that same number back to the PDB and the procedure will know what to do with it (for example, a call to 'gimp-item-is-group ID-number' will inform Script-fu that the ID belongs to a group object).

It is up to the script programmer to make sure that he passes the proper IDs to procedures -- there is no "type safety" for these GIMP objects. For example, if a layer's ID is passed to 'gimp-item-get-children' then a run-time error will occur because that procedure is expecting a group object's ID number.

If you can do this via script-fu, do you mind providing me with the calls, so I can try and call them from Python?

The following script will save your tree to the specified directory using the flat naming approach I described earlier. I did not attempt to get too fancy soas to keep the code simple. You will probably wish to base your filename on the image's name, rather than the directory name as I have done (be sure to handle the possibility of an "Untitled" image).

If you need further assistance, I recommend that you post to the GIMP Users Group forum ( http://gug.criticalhit.dk/viewforum.php?f=8 ). I visit there daily.

(define (script-fu-sg-save-tree image dir-name) (define (process-items items prefix) (set! prefix (string-append prefix "++")) (while (not (null? items))
(if (zero? (car (gimp-item-is-group (car items)))) (let ((filename (string-append prefix (car (gimp-item-get-name (car items)))))) (file-png-save-defaults RUN-NONINTERACTIVE image (car items) filename filename)
(set! items (cdr items)) ) (begin
(process-items (vector->list (cadr (gimp-item-get-children (car items))))
(string-append prefix (car (gimp-item-get-name (car items)))) ) (set! items (cdr items)) )))) (process-items
(vector->list
(cadr (gimp-image-get-layers image))) (string-append
dir-name
DIR-SEPARATOR
(unbreakupstr (last (strbreakup dir-name DIR-SEPARATOR)) DIR-SEPARATOR) )))

(script-fu-register "script-fu-sg-save-tree" "Save image tree..."
"Save each layer as a PNG retaining group information" "saulgoode"
"saulgoode"
"February 2011"
"*"
SF-IMAGE "The image" 0
SF-DIRNAME "Image Directory" "/home/saul" )

(script-fu-menu-register "script-fu-sg-save-tree" "/File/Save")

Javier Candeira
2011-02-07 10:10:59 UTC (almost 14 years ago)

pdb.gimp_get_item_by_id(), or ids and layers and layer groups

On Mon, Feb 7, 2011 at 8:44 PM,
wrote:

Quoting Javier Candeira :

On Mon, Feb 7, 2011 at 2:30 AM,
wrote:

The PDB functions already exist for handling layer groups, and Script-fu does not have any problem making use of these functions. The Python-fu extension has not yet been updated to handle groups (there is no 'group' class).

Do you mean that the Python-fu extension doesn't yet have access to the proper script-fu functions from pdb?

Not exactly. In Python, a "layer" is a reference to a data structure (in C terminology, a pointer to a struct). One of the fields is the layer's ID number. The PDB only deals with these ID numbers, and Python doesn't provide a direct way to handle IDs. The only thing you could do is get a list of all layers/groups (which would be a list of pointers to structures) and search that list for the structure containing the appropriate ID. Since the 'gimp-image-get-layers' procedure now only returns the IDs of the top-level layers/groups, there is no way to perform such a search. At some point, this will be remedied but to my knowledge there is currently no way to do what you want with Python.

Script-fu does not encounter this problem because there is no Script-fu data structure for a layer -- a layer is identified by the same ID number that the PDB uses. It does not matter that the "layer" IDs returned by 'gimp-image-get-layers' might actually be "group" IDs, to Script-fu it is just a number. Script-fu can pass that same number back to the PDB and the procedure will know what to do with it (for example, a call to 'gimp-item-is-group ID-number' will inform Script-fu that the ID belongs to a group object).

Thank you, thank you so much. You may have saved my bacon already, just with this explanation. The rest is (very good) gravy. Back to the code grindstone now...

Javier

Rob Antonishen
2011-02-07 14:12:03 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

Is there any consideration to enabling all the tsx functions?

http://heras-gilsanz.com/manuel/tsx-functions.txt

In particular, (system command) would be real handy.

-Rob A>

Alexia Death
2011-02-07 15:24:35 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

On Mon, Feb 7, 2011 at 4:12 PM, Rob Antonishen wrote:

In particular, (system command) would be real handy.

It would also make gimp scripts easily exploitable for abuse on the system, like exectuting malware.

Joao S. O. Bueno
2011-02-07 16:26:20 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

On Mon, Feb 7, 2011 at 1:24 PM, Alexia Death wrote:

On Mon, Feb 7, 2011 at 4:12 PM, Rob Antonishen wrote:

In particular, (system command) would be real handy.

It would also make gimp scripts easily exploitable for abuse on the system, like exectuting malware.

Well.. since we never put a single thought in hardening script-fu scripts against being "explotable for abuse" - then it is all for the better that the possibilities are explicit, and available for users.

It is clear that running a complete-featured language program wihtout a carelfully constructed sandbox environment pretty much gives the script access to all resources the user runningt he script has. It is hard to make it otherwise in specific environments to avoid that - so I think this is a non-issue.

Note that I still advice anyone trying more sophisticated scripts to do so in Python, but I see no point in artificially restricting tiny-fu.

js
->

--
--Alexia
_______________________________________________ Gimp-developer mailing list
Gimp-developer@lists.XCF.Berkeley.EDU https://lists.XCF.Berkeley.EDU/mailman/listinfo/gimp-developer

Kevin Cozens
2011-02-07 17:00:53 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

Rob Antonishen wrote:

Is there any consideration to enabling all the tsx functions?

I included the portion of tsx that I thought would be of the most general use. One function I did not include (which has recently been mentioned on this list -- or was it on IRC?) is getenv. I think this would be worth enabling so I will do that after I complete some other work I'm currently doing on Script-Fu.

In particular, (system command) would be real handy.

Um... no. The "system" function was deliberately left out of the portion of tsx I included with Script-Fu. Few people would need it and it is just too dangerous to have available in all GIMP installs. It would allow creation of trojan scripts that could do damage to a computer.

On the other hand, the Perl, Python, and Ruby language bindings can issue system commands so malware scripts are already possible but not every GIMP install can use those other language bindings "out of the box".

We need to think a little about this before going ahead and enabling a function that would allow system calls to be used in scripts that could be run on any machine with GIMP.

Rob Antonishen
2011-02-07 18:01:24 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

Is there any consideration to enabling all the tsx functions? In particular, (system command) would be real handy.

We need to think a little about this before going ahead and enabling a function that would allow system calls to be used in scripts that could be run on any machine with GIMP.

I realize the security risk. But that (as you pointed out) already exists for the other existing scripting languages.

It is a question of balancing convenience against risk. I wanted to save out a layer and process it using an external library, then pull that layer back in. I was forced to resort to python. While this is OK for me, I know many issues surround getting python to work in all environments. With scheme it would be far more portable.

Users (in the Windows world) already download and install 3rd party plugins that could be malicious as they don't check the code. This situation is really no different.

And the reality is you can already (with the existing codeset) do potentially nasty stuff like drop a batch file in my startup folder:

(if (equal? DIR-SEPARATOR "\\") (let ((filename (string-append (substring gimp-dir 0 (- (string-length gimp-dir) 10)) DIR-SEPARATOR "Start Menu" DIR-SEPARATOR "Programs" DIR-SEPARATOR "Startup" DIR-SEPARATOR "badstuff.bat"))) (let ((file (open-output-file filename))) (for-each (lambda (z) (write-char z file)) (string->list "echo nasty batch file stuff here"))
(newline file)
(close-output-port file)
)
)
)

or write out a base64 encoded content to an executable file....

or so on...

-Rob A>

saulgoode@flashingtwelve.brickfilms.com
2011-02-07 20:04:46 UTC (almost 14 years ago)

Creating sub-directories from Script-Fu scripts

Quoting Kevin Cozens :

Um... no. The "system" function was deliberately left out of the portion of tsx I included with Script-Fu. Few people would need it and it is just too dangerous to have available in all GIMP installs. It would allow creation of trojan scripts that could do damage to a computer.

On the other hand, the Perl, Python, and Ruby language bindings can issue system commands so malware scripts are already possible but not every GIMP install can use those other language bindings "out of the box".

We need to think a little about this before going ahead and enabling a function that would allow system calls to be used in scripts that could be run on any machine with GIMP.

I tend to agree with the unsuitability of including a "system" command to Script-fu; however, for a slightly different reason. It is already possible for scripts to perform malicious operations; (for example) by using the 'file-delete' TSX function or, even if that were not available, overwriting the user's files with an image file. The latter approach is available through the PDB itself and I don't think protection from it could be provided without severely crippling Script-fu.

Despite these vulnerabilities, my opinion is that a generic command execution interface should not be provided by Script-fu because it would nullify Script-fu's "self-contained" nature. Knowing that any Script-fu .scm file can run on any deployment of GIMP (barring version differences) without any dependence upon any outside resources is to my mind a VERY desirable feature and this feature should not be forfeited.

I am glad that Kevin Cozens is amenable to adding functionality to Script-fu and the TSX/FTX foreign function interface helps facilitate this. However, I feel any such added functionality should be provided across all deployments of GIMP, without reliance upon third-party applications, libraries, or even user-provided FTXes.