Bonjour,
Try repeating the command line several times in the same terminal.
You must never see the cursor of the mouse.
You can change the image with the spacing bar, the ENTER key without touching the mouse.
I see what you mean. Before your suggestion, I tried 3 times with the cursor present at the beginning. After several more tries I see your point on it being there and not being there at the beginning. It isn’t consistently correct or wrong. Maybe it is a Windows issue because the OS sometimes has focus problems depending on your configuration and the software in use.
I confirm this. I’ll investigate
La modification " Fix command ‘cursor’ when applied on other display than ‘w0’ " supprime l’erreur "sp lena,256 sp colorful,256 sp earth,256 w2[2] cursor[2] 0 … " sous Windows.
Merci :o)
Le ‘problème’ d’affichage du curseur en plein écran avec le terminal Windows est toujours présent.
I notice there is no da_pop()
, and da_remove()
does not return the removed value either. Must we do da_pop=(V=i[da_size()-1];da_remove();V)
or did I miss something?
I was struck by such asymmetry as well.
gstatedemo.gmic
:
# First in, first out queue...
foopush : -skip ${1=0}
-local[stack]
-eval "da_push(#0,$1)"
-endlocal
barpop :
-local[stack]
-status {"if(da_size(#0)>0,pop=I;da_remove(#0,0,0));_(Do things with pop.);pop"}
-endlocal
where one custom command, foopush
pushes state subsequently accessed by another custom command barpop
:
$ gmic gstatedemo.gmic 0 name. stack foopush 1234 barpop echo "From the stack: "'${}'
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Input custom command file 'gstatedemo.gmic' (4 new, total: 4468).
[gmic]-0./ Input empty image at position 0 (1 image 0x0x0x0).
[gmic]-1./ Set name of image [0] to 'stack'.
[gmic]-1./ From the stack: 1234
[gmic]-1./ Display image [0] = 'stack'.
[0] = 'stack':
size = (1,2,1,1) [8 b of floats].
data = (1234;0).
min = 0, max = 1234, mean = 617, std = 872.57, coords_min = (0,1,0,0), coords_max = (0,0,0,0).
[gmic]-1./ End G'MIC interpreter
Note the local blocks in each custom, for there may be many such images serving as backing storage, and custom commands coordinating their state around one such store probably should address such by name.
Some further remarks along these lines may appear later in G’MIC Tutorial Fragments in the sweet by-and-by.
Getting to the point of too many questions now, I do apologise!
Update: I did some testing, it seems arg2var
handles the below properly. That should give me enough to work with - this question can now be ignored
The next one: is there a good way to handle the use of files
where some of the returned file/directory names contain commas and/or spaces?
So far I’ve worked around spaces in my own way, but commas give me trouble when trying to get the individual file names…
Edit: don’t shoot me, I would never use commas in filenames by choice!
This must explain why my changes to random rectangle division has failed. I ended up sticking with old math_lib.
-
da_remove()
does not return the removed value (or vector) indeed. The main reason is that I don’t like the idea of havingda_remove()
systematically return a new object that wil take memory space (and that will require initialization with copy), if, after all, the user does not want to do anything useful with the removed value. -
If necessary, I could add a
da_back()
function that would return the latest element of a dynamic array. Eventually, ada_pop()
that does asda_back()
but also remove it from the array.
Now I remember why I haven’t implemented it already…
Basically, what kind of object should da_back()
and da_pop()
return ?
- If the dynamic array is vector-valued, that would be probably a vector. In that case, it means the
#index
specified should be aconst
value (otherwise, the compiler cannot determine what the size of the output vector at compile time). - If the dynamic array is scalar-valued, that would be a scalar.
But it would be definitely not clear in the code whether the returned object is a scalar or a vector, while using i[da_size()-1]
and I[da_size()-1]
makes it explicit in the code.
Why can’t there be a identifier for if it is a scalar array or not, and make it compile based on that?
Hah yes, that very problem occurred to me later as well - a consequence of being a scripting language without strong typing I suppose. It’s not at all difficult to work around anyway!
There is a saying in France that goes, “Only fools don’t change their minds!”
and
After thinking a lot about this proposal, I don’t think I’ll let G’MIC support this syntax.
Let me detail a few reasons for that:
1 - The advantage of conciseness
Considering that a syntax as
add[0] $img
would be actually valid. What could be an equivalent syntax with the current version of the language? Well, it would be equivalent to:
$img add[0,-1]
which is really not that longer to write. The worst case would be to pass $img
to a command different from add
, that is not able to ‘merge’ the specified selection as a single image for the result. But even with that, it would only require:
$img command[0] . rm.
rather than command[0] $img
. It is indeed longer, but not to the point where it becomes problematic. So for me, the argument of conciseness do not hold here.
2 - Required changes in the interpreter
On the other hand, from a technical point of view, supporting this syntax would require a quite large amount of changes in the current interpreter code, leading probably to a slight decrease of the interpreter performance concerning the parsing. Probably not enough to make it visible though. Anyway, something that requires a lot of work with only the benefit of begin slightly more concise than the existing syntax sounds not good to me.
You’re going to tell me that this is my problem, not the users’, so it’s not a valid point.
But as I am alone to develop this interpreter, and there is no lack of things to do…
3- Toward bad habits
Another problem I see with that new syntax : Why the user would have to deal with the list of images anymore ? It would be actually tempting to store each new image into a variable, with command store
, then use those variables as arguments each time a command requires it.
That sounds good said like this, but I see several problems with this approach:
- First, you have to know that command
store
basically acts likeserialize
: it transforms the image data into a form storable as a variable (basically a set ofuchar8
, stored as a string). This transformation has a real cost in terms of CPU cycles and memory usage, particularly if the image resolution is high. The reverse transform too (i.e. getting back aCImg<T>
image from a string). So, generalizing this approach would lead to performance loss, because a lot of conversions fromCImg<T>
to*uchar8
could happen in practice (transparent to the user, but not for the CPU and for the memory!). - Second, I don’t really see the advantages of this new approach compared to the existing possibility to name your images in the stack and to use these names as variable names. This is actually a good coding practice when you have lot of different images to manage in a G’MIC command. It makes the code more clear and generally you don’t have to worry about the position of each image into the list.
foo :
lena.bmp
earth.jpg
colorful.png
nm[-3--1] lena,earth,colorful # Set variable names to images in the stack
r[lena,earth,colorful] 256,256,1,3
+matchpatch[colorful] [lena],5 nm. displacement
warp_patch[lena] [displacement],5
blend[lena] [earth],softlight
k[lena]
In the above example, you can permute the order of the three input images in the list, and you won’t be in trouble. Just name the images correctly and everything becomes simple, no more [-4]
to deal with I’d actually suggest to do this as quickly as possible when you have more than 4 or 5 images to manage at the same time in your filters.
shame on me, it’s not something I do very often!
So, all these reasons make me think that there is already what is needed in G’MIC to not need this new syntax, syntax that could also make things slower in practice
Apart from anything else, nice presentation on G’MIC internals, in particular, the internal workings of -store
.
@grosgood @David_Tschumperle
General consensus is it would be a bad move then, but thank you both for taking the time to consider it carefully!
I’ve already got some script which replicates the behaviour using the above alternatives, but I’m considering switching to named images instead. I had problems with those in the past when using implicit combination commands, such as add[firstname,secondname]
, but perhaps it’s time to give it another try…
Interestingly, I did actually test performance of store
beforehand and discovered for the smaller meta-images I intend to use it with the overhead is insignificant. It’s quite slow with an entire usual image, but I wouldn’t be contemplating that.
Now I’m probably pushing my luck with one more question, but I can’t find a way to get the output of files
(i.e. status) directly into an image with quoting intact, without first going via arg2var
(or at least “converting” them individually to variables with $=var
). Is that correct? The goal being to preserve filenames which contain spaces and/or commas.
Interesting question! It’s definitely not easy, as space and comma characters have a special meaning in the G’MIC language, and string substitution may occur here and there.
After experimenting a bit, I found this ‘minimal’ way (so far) to handle this case. Beware, it’s very tricky!!
# Tricky way of getting list of filenames containing spaces or commas!
foo :
files *
# Convert status into an image where each row = one filename.
m "$0_f2i: $""=arg repeat $""# ({'${arg{1+$>}}'}) done a y" $0_f2i[] ${} um $0_f2i
# Print filenames.
repeat h e {`crop(0,$>,w,1)`} done
EDIT: Fix code snippet.
Multiple labels in selection is now handled correctly (was not the case before I guess).
Anyway, in that particular case of add[first,second]
(without arguments), you need to know how the indices of first
and last
are sorted, to guess in which of the two image the result is merged.
In that case, I’d rather suggest to add the version of add
that takes one argument:
add[first] [second] rm[second]
so this works whatever the relative order of [first]
and [second]
is.