Script-Fu Exceptions and errors
This discussion is connected to the gimp-user-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.
Script-Fu Exceptions and errors | Thomas DuBuisson | 24 Nov 19:05 |
Script-Fu Exceptions and errors | Thomas DuBuisson | 24 Nov 20:34 |
Script-Fu Exceptions and errors | Thomas DuBuisson | 25 Nov 02:15 |
Script-Fu Exceptions and errors | Simon Budig | 25 Nov 13:23 |
Script-Fu Exceptions and errors | Thomas DuBuisson | 25 Nov 17:45 |
Script-Fu Exceptions and errors
Hello list,
I am planning on evolving image transformations using an AST of the script-fu langauge and generating random (but syntatically correct) scripts. I would like to avoid programming in hundreds of corner cases into the system and thus have the following questions:
1) Script-fu throws exceptions
If/when I do something basic like call "gimp-image-raise-layer" on a layer that can not be raised, an exception is thrown. I would very much like to catch/ignore exceptions such as this but it seems script-fu is too primitive. Am I missing something?
2) gimp-layer-new-from-drawable nearly always fails
------------- CODE --------------
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "image.png" "image.png")))
(layer0 (car (gimp-image-get-active-layer image))))
(let* ((layer1 (car (gimp-image-flatten image))))
(gimp-layer-set-mode layer1 25)
) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image))))
...
----------------- END CODE --------------
In the above you see I define layer0 as the active layer (which I thought was a drawable) but this doesn't work for gimp-layer-new-from-drawable. Replacing layer0 with 'image' also doesn't work and most frustratingly, using " (gimp-image-get-active-drawable image)" also doesn't work - which I really thought it should based on the documentation. What does this function expect?
(I understand gimp-image-flatten somehow screws everything up by eliminating the layer, but am still not clear how to once-again get a valid layer from my image)
3) C Assertation failures Perhaps most concerning are the assertation failures. Presumably, these are not supposed to happen. How concerned should I be?
-------------------- START CONSOLE DUMP -------------------------
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "image.png" "image.png")))
(layer0 (car (gimp-image-get-active-layer image))))
(let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image))))
(gimp-layer-add-alpha layer1)
(gimp-image-merge-down image layer1 2))
(set! layer0 (gimp-image-get-active-layer image))
(let* ((layer1 (car (gimp-image-flatten image))))
(gimp-layer-set-opacity layer1 21.811554)
(gimp-image-merge-down image layer1 0))
(set! layer0 (gimp-image-get-active-layer image))
(let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image))))
(gimp-layer-flatten layer1)
(gimp-image-merge-down image layer1 0))
(set! layer0 (gimp-image-get-active-layer image))
(let* ((currDraw (car (gimp-image-get-active-layer image))))
(gimp-file-save RUN-NONINTERACTIVE image currDraw "newImage.png"
"newImage.png" ))
)
(gimp-console:2987): Gimp-Core-CRITICAL **: gimp_image_remove_layer: assertion `gimp_container_have (image->layers, GIMP_OBJECT (layer))' failed
---------------------------- END CONSOLE DUMP -------------------------
Cheers, Thomas
Script-Fu Exceptions and errors
Update:
1) The question regarding exceptions remains - there are too many corner cases, mostly undocumented, so it would be nice to ignore them silently.
2) I see my fix was almost right but I forgot to take the head of the list: "(car (gimp-image-get-active-drawable image))" is what I want, not the no-longer-existing layer0 or the whole list returned by gimp-image-get-active-{layer,drawable}.
3) I still get things like the message below, so same question. (gimp-console:2987): Gimp-Core-CRITICAL **: gimp_image_remove_layer: assertion `gimp_container_have (image->layers, GIMP_OBJECT (layer))' failed
On Tue, Nov 24, 2009 at 10:05 AM, Thomas DuBuisson wrote:
Hello list,
I am planning on evolving image transformations using an AST of the script-fu langauge and generating random (but syntatically correct) scripts. I would like to avoid programming in hundreds of corner cases into the system and thus have the following questions:
1) Script-fu throws exceptions
If/when I do something basic like call "gimp-image-raise-layer" on a layer that can not be raised, an exception is thrown. I would very much like to catch/ignore exceptions such as this but it seems script-fu is too primitive. Am I missing something?
2) gimp-layer-new-from-drawable nearly always fails
------------- CODE -------------- (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "image.png" "image.png"))) (layer0 (car (gimp-image-get-active-layer image)))) (let* ((layer1 (car (gimp-image-flatten image)))) (gimp-layer-set-mode layer1 25) ) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image)))) ...
----------------- END CODE --------------In the above you see I define layer0 as the active layer (which I thought was a drawable) but this doesn't work for gimp-layer-new-from-drawable. Replacing layer0 with 'image' also doesn't work and most frustratingly, using " (gimp-image-get-active-drawable image)" also doesn't work - which I really thought it should based on the documentation. What does this function expect?
(I understand gimp-image-flatten somehow screws everything up by eliminating the layer, but am still not clear how to once-again get a valid layer from my image)
3) C Assertation failures Perhaps most concerning are the assertation failures. Presumably, these are not supposed to happen. How concerned should I be?
-------------------- START CONSOLE DUMP -------------------------
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "image.png" "image.png")))
(layer0 (car (gimp-image-get-active-layer image)))) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image)))) (gimp-layer-add-alpha layer1) (gimp-image-merge-down image layer1 2)) (set! layer0 (gimp-image-get-active-layer image)) (let* ((layer1 (car (gimp-image-flatten image)))) (gimp-layer-set-opacity layer1 21.811554) (gimp-image-merge-down image layer1 0)) (set! layer0 (gimp-image-get-active-layer image)) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image)))) (gimp-layer-flatten layer1)
(gimp-image-merge-down image layer1 0)) (set! layer0 (gimp-image-get-active-layer image)) (let* ((currDraw (car (gimp-image-get-active-layer image)))) (gimp-file-save RUN-NONINTERACTIVE image currDraw "newImage.png" "newImage.png" ))
)(gimp-console:2987): Gimp-Core-CRITICAL **: gimp_image_remove_layer: assertion `gimp_container_have (image->layers, GIMP_OBJECT (layer))' failed
---------------------------- END CONSOLE DUMP -------------------------
Cheers, Thomas
Script-Fu Exceptions and errors
Update 2:
1) Exceptions
The macro (not sure of the underlying primitives) "catch" will catch
errors. The web page didn't even call them exceptions, which explains
why I/google didn't find it quickly.
Ex: when converting an image that might already be RGB to RGB: (catch (gimp-image-convert-rgb image))
2) The layer issue As stated before, an earlier command was obliterating my layer and I forgot to take the head of the get-active-{layer,drawable} in my later operations.
3) Assertation failures and segfaults
The assertation failures are probably somehow connected with my layer merging - not that it is good to be able to hit this so easily. I also found a segfault, do to out of range arguments, since my previous post and see that this doesn't crash the program - so its running in a different thread or processs I guess. Not sure if I can catch this with "catch", if I can't then I'll have to fix these corner cases. Perhaps I'll make some patches for the function documentation if people are interested.
Thomas
On Tue, Nov 24, 2009 at 11:34 AM, Thomas DuBuisson wrote:
Update:
1) The question regarding exceptions remains - there are too many corner cases, mostly undocumented, so it would be nice to ignore them silently.
2) I see my fix was almost right but I forgot to take the head of the list: "(car (gimp-image-get-active-drawable image))" is what I want, not the no-longer-existing layer0 or the whole list returned by gimp-image-get-active-{layer,drawable}.
3) I still get things like the message below, so same question. (gimp-console:2987): Gimp-Core-CRITICAL **: gimp_image_remove_layer: assertion `gimp_container_have (image->layers, GIMP_OBJECT (layer))' failed
On Tue, Nov 24, 2009 at 10:05 AM, Thomas DuBuisson wrote:
Hello list,
I am planning on evolving image transformations using an AST of the script-fu langauge and generating random (but syntatically correct) scripts. I would like to avoid programming in hundreds of corner cases into the system and thus have the following questions:
1) Script-fu throws exceptions
If/when I do something basic like call "gimp-image-raise-layer" on a layer that can not be raised, an exception is thrown. I would very much like to catch/ignore exceptions such as this but it seems script-fu is too primitive. Am I missing something?
2) gimp-layer-new-from-drawable nearly always fails
------------- CODE -------------- (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "image.png" "image.png"))) (layer0 (car (gimp-image-get-active-layer image)))) (let* ((layer1 (car (gimp-image-flatten image)))) (gimp-layer-set-mode layer1 25) ) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image)))) ...
----------------- END CODE --------------In the above you see I define layer0 as the active layer (which I thought was a drawable) but this doesn't work for gimp-layer-new-from-drawable. Replacing layer0 with 'image' also doesn't work and most frustratingly, using " (gimp-image-get-active-drawable image)" also doesn't work - which I really thought it should based on the documentation. What does this function expect?
(I understand gimp-image-flatten somehow screws everything up by eliminating the layer, but am still not clear how to once-again get a valid layer from my image)
3) C Assertation failures Perhaps most concerning are the assertation failures. Presumably, these are not supposed to happen. How concerned should I be?
-------------------- START CONSOLE DUMP -------------------------
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "image.png" "image.png")))
(layer0 (car (gimp-image-get-active-layer image)))) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image)))) (gimp-layer-add-alpha layer1) (gimp-image-merge-down image layer1 2)) (set! layer0 (gimp-image-get-active-layer image)) (let* ((layer1 (car (gimp-image-flatten image)))) (gimp-layer-set-opacity layer1 21.811554) (gimp-image-merge-down image layer1 0)) (set! layer0 (gimp-image-get-active-layer image)) (let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image)))) (gimp-layer-flatten layer1)
(gimp-image-merge-down image layer1 0)) (set! layer0 (gimp-image-get-active-layer image)) (let* ((currDraw (car (gimp-image-get-active-layer image)))) (gimp-file-save RUN-NONINTERACTIVE image currDraw "newImage.png" "newImage.png" ))
)(gimp-console:2987): Gimp-Core-CRITICAL **: gimp_image_remove_layer: assertion `gimp_container_have (image->layers, GIMP_OBJECT (layer))' failed
---------------------------- END CONSOLE DUMP -------------------------
Cheers, Thomas
Script-Fu Exceptions and errors
Thomas DuBuisson (thomas.dubuisson@gmail.com) wrote:
------------- CODE --------------
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE
"image.png" "image.png")))
(layer0 (car (gimp-image-get-active-layer image)))
)
(let* ((layer1 (car (gimp-image-flatten image))))
(gimp-layer-set-mode layer1 25)
)
(let* ((layer1 (car (gimp-layer-new-from-drawable layer0 image))))
...
----------------- END CODE --------------
As you already found out, flattening the image makes its layers invalid, this is because it generates a new one, which it returns as result.
As you can see in my re-indented version of your code, you use let* to bind the newly created layer to the "layer1" variable, yet you forget it too early, since you need to use it for the gimp-layer-new-from-drawable.
I don't like how you nest the various let*-statements. That makes the code hard to track.
It would be better if you have some dummy variable declarations in your outer let*-statement and then use set! to redefine the values. Something like this:
(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE
"image.png" "image.png")))
(layer0 (car (gimp-image-get-active-layer image)))
(layer1 0)
)
(set! layer0 (car (gimp-image-flatten image)))
(gimp-layer-set-mode layer0 25)
(set! layer1 (car (gimp-layer-new-from-drawable layer0 image)))
...
Also note that the use of "25" for the mode is not nice, you really should use the symbolic constants.
3) C Assertation failures
Perhaps most concerning are the assertation failures. Presumably, these are not supposed to happen. How concerned should I be?
[...]
(gimp-console:2987): Gimp-Core-CRITICAL **: gimp_image_remove_layer: assertion `gimp_container_have (image->layers, GIMP_OBJECT (layer))' failed
You should be concerned moderately, since your code apparently is doing some bogus stuff and does not properly keep track of the layers in the image. However, the critical warning should not happen, we really should catch these errors in the PDB wrappers already.
Hope this helps, Simon
Script-Fu Exceptions and errors
I don't like how you nest the various let*-statements. That makes the code hard to track.
It would be better if you have some dummy variable declarations in your outer let*-statement and then use set! to redefine the values.
Also note that the use of "25" for the mode is not nice, you really should use the symbolic constants.
These issues are because my code is randomly generated using a Script-fu syntax tree I wrote. I'll add indentation to the AST/Script-fu compiler and that should make things easier to read. Not sure how to handle the side-effects of flattening, I'll think on it more.
You should be concerned moderately, since your code apparently is doing some bogus stuff and does not properly keep track of the layers in the image. However, the critical warning should not happen, we really should catch these errors in the PDB wrappers already.
It's a little more concerning to me that I found 1 infinite loop that nearly crashed my system (took a while to register, but I finally killed gimp-console) and several memory bugs where a gimp plugin requests gigabytes of memory (and then fails). Also, values aren't garbage collected after fails scripts thus my constant testing lead to a gimp-console taking nearly all of my 4GB of RAM; this forced me to stop using GIMP for the project. After I finish with this project I'd be happy to re-generate some of the buggy scripts and post to the developers list if you'd like - somewhat like BNF fuzzing script-fu :-)
Thanks Simon,
Thomas