Release of G'MIC 3.1

Above an image size, structuretensors yields different values. E.g.,

gmic sp pencils,1300 +structuretensors structuretensors.. -
1 Like

Confirmed, at a glance it looks like a threading problem.

Fixed with https://github.com/dtschump/CImg/commit/53cf0df323b65a76c7283bc45a61322fe52ac55d
(as structuretensors is a native, it requires a re-compilation though, so will be available in next version 3.0.3).

I noticed structuretensors is no longer core. I wonder how much slower the stdlib version is versus the (fixed) core one. If substantial, I hope it returns to core. This takes 12 s on my laptop:

gmic sp tiger,4000 tic structuretensors toc

I see. When I’ve tested the difference in time was not that big (a few ms), but it was on my office PC that has 24 cores. I think I can optimize it for more standard computers.

Another idea. A new function where you specify the threshold by percentage, and it will cut based on frequency values. The threshold is used for search values starting from each end, and if it frequency is greater than percentage threshold, then cut values is returned as a vector.

Concerning the new “::” syntax of “nm” resp. “name”

Using the new syntax, how is it possible to declare “::” for older versions, something like

if $_version<303 
  :: : name $*
fi

?

It is not possible, that is probably why the next release will be 3.1.0 rather than 3.0.3. I’ll just try keeping the compatibility with the current code.

Another idea, and I know that it’s not that common where it’s needed. I would like a option for a function to treat all arguments inside it as a vector of arguments.

Something like this.

func(?)=(
 v=?; # ? means vector of arguments.
sort(v);
);

func_alt(?)=(
 v=?; # ? means vector of arguments.
sum(v)+min(v)+max(v);
);

func(5,4,1,2) -> [1,2,4,5];
func_alt(5,4,1,2) -> 18;

This eliminates the need to add [] for functions that are intended to be something like avg(). Granted, only useful for filters with custom expression support.

(Probably “bad”) News:

Next version will be G’MIC 3.1.0. I’ve already planned some important changes, that go hopefully in the right direction. I’ll try to post binary packages of the development version as soon as possible.

The important changes so far, compared to 3.0.2:

  • New command foreach[selection] ... done loops over each image of the selection, and creates a local environment containing only a single image for each iteration of the loop.
    So, it will be possible to write:
foo : 
  foreach
    +mirror x +
  done

This was really tricky to achieve in the G’MIC code, so I spent several days in order to find the best solution in terms of code. I’m almost done with it. It’s faster than using a repeat $! l[$>] ... endl done syntax, so that’s pretty cool.

  • Note that +foreach[selection] is also possible, to insert the resulting list of images at the end of the current image list.

  • Commands endif, endlocal and endl disappear. Replaced respectively by fi and done.
    Fewer commands for flow control make the interpreter actually faster because it eases the parsing.
    I know endl was largely used, so this change will break things, obviously. Unfortunately, I cannot just add a “shortcut” named endl for done for keeping compatibility. So basically, replacing all endl by done in your scripts is something that will be necessary for 3.1.0.

done is now used to terminate for...done, foreach...done and local...done blocks.

That’s exactly what I was hoping you would allow!

I see you already did some of that in the repo… should I fix that for mine? It’s no problem for me to do that anyway.

I’ve disabled the automatic filter updates for G’MIC 3.0.0, 3.0.1 and 3.0.2, to avoid breaking things for users of these versions.
So I’d say you can already make the changes if you wish. But no hurry, the code change is quite large and I’ll have a lot to do before actually releasing 3.1.0.

1 Like

OK thanks, I’ll perhaps wait a little to leave some breathing room. Really looking forward to this though, it’s great news!

1 Like

Hi David,
interesting progress. For certain situations foreach seems really helpful.
Still I have often the case that one or more images have to be applied to a list of others, e.g. for shading correction. Up to now I see only the possibility to store and to input those images in the foreach environment. Maybe pass could help, but how?

Local is still going to be there. Foreach can replace repeat l…endl done where appropriate. That’s how I see it. I would have to test my commands on where I can replace repeat l…endl done with foreach. No rush though.

@KaRo Was really tricky to navigate when I tried a few(?) years ago. Would certainly like a more streamlined way of doing it. Edit i.e., referring to passing images into (often nested) loops. store certainly makes it easier but I want to avoid it because it slows down the command.

Yes, basically, it should be made like this (in the future, pass is not yet implemented for foreach block) :

foo : 
  image1.jpg image2.jpg image3.jpg image4.jpg
  mask.png
  
  foreach[^-1] pass.  
    # From here, you have two images in the list.
    .. do something with [0]=image?.jpg and [1]=mask.png..
    .. and don't forget to keep only one image before reaching the `done` command below ..
  done

More generally, my aim is to have a kind of ‘unified’ behavior for all the flow control commands, meaning for instance :

  • Iteration counters $> and $< (when possible) available inside any kind of loops.
  • onfail also available everywhere, for easy error management.

So, I’ve still a lot of things to do, but I think I’m on the right path.

2 Likes

Yeah, still dangerous, pass would reach out of the foreach environment. Possibly an image parameter would be better for additional images e.g. foreach[^-1] [-1] . Still it looks not good (and would break syntax too)!

How that ?

I would like reverse direction as a option for foreach. As for additional images, there are community codes like these:

repeat $!-2 l[$<,-2,-1] do_something_here endl done