A few words about a new feature I’ve implemented for G’MIC 2.9.9 :
It will be possible to write a +-specialization of a custom command, in case it is invoked with the +command syntax (preprended +).
In which case it is useful ? Not so often to be honest, but in certain occasions it may be more efficient, by saving memory usage and avoiding unnecessary image copies.
Here is one example to illustrate this fact.
Suppose we want to rewrite the mse command as a custom command. The mse command computes the mean-squared error between several images, and replaces the N input images as a NxN (symetric) matrix containing the MSE between all possible pairs of images.
One way to write it would be:
my_mse :
$!,$!,1,1,">x==y?0:x>y?(i(y,x) = run('+-[',x,',',y,'] sqr. u {ia} rm.')):i" k.
And then, you would use it as:
$ gmic sp portrait1,portrait2,portrait3 my_mse
But in fact, that’s not how this would be used the most, because most of the time you probably want to keep your 3 images after the MSE is computed, so, you’d rather use it like this:
$ gmic sp portrait1,portrait2,portrait3 +my_mse
Here, the +my_mse works as expected, but is not efficient : indeed, when a custom command is invoked with a +command syntax, the interpreter first duplicates the input selection of images (here all images) and run my_mse on this new (temporary) set of images. In our case, the three input images are then duplicated in memory, just to be able to compute the MSE on them.
This is not optimal : you know you won’t modify the input images, so there is no need to duplicate them before invoking my_mse.
Of course, you could write a version of the my_mse command that just inserts the MSE matrix at the end of the image list (simply by removing the last k. in the my_mse code). But this would go a bit against the G’MIC philosophy that says a command[selection] acts in place (so modify the selection) and that +command[selection] returns its result as a new image in the list (so keep the selection unmodified).
That is where the +command specialization is useful.
In G’MIC 2.99, you’ll be able to define the custom command my_mse as:
+my_mse : # Specialization for the '+my_mse' invokation.
$!,$!,1,1,">x==y?0:x>y?(i(y,x) = run('+-[',x,',',y,'] sqr. u {ia} rm.')):i"
my_mse:
+my_mse k.
Here, when the interpreter encounters a call to +my_mse, it recognizes it as a +command specialization and executes the specialized command just as a regular command (so, without the + sign). Consequence: no image copies done and the command is 2x faster to execute here (with 3 input images).
Here, we also defined a regular my_mse command to get a consistent behavior when my_mse is invoked without the + preprended.
Also, note that:
- Custom commands that have no
+-specializations defined (most of the commands basically) just works as before when they are invoked with the+commandsyntax. - If you define a
+commandspecialization without defining the correspondingcommand, then only the+commandinvokation will be recognized. In practice, this means you can decide to allow of forbid the execution of a command when it is invoked with+commandorcommand. - It is obviously not recommended to implement a
+commandspecialization that is not consistent with the correspondingcommandimplementation
(but it becomes possible anyway).
It’s not a big thing, but this will further optimize the calling of some custom commands by avoiding unnecessary copies of images.
I’m actually planning to use this mechanism to have non-builting implementations of mse and psnr in next G’MIC version.