My 2¢ (USD):
TL;DR: Methinks the original culprit is an overlooked, misplaced space character:
Pragmatic advice. Nonetheless, for those starting out with GâMIC, I recommend a deliberate study of command line science, as it pays dividends in future frustrations avoided and makes GâMIC snippets less like mystical incantations and more like intelligible tools that serve concrete purposes.
Details: In his transcription, @David_Tschumperle left the offending space character out, as he has written about 148 bazillion GâMIC pipelines by now, and for him some on-the-fly corrective edits just arise from an instinctive muscle memory and he glides over the difficulty.
That said, GâMICâs command line parser very much depends on spaces to block out commands from their arguments; an unintended space character in an argument string derails this blocking. See Items of a Processing Pipeline.
For a take-away: Become familiar with GâMICâs processing log. In this particular case, it gave the first evidence that GâMIC had derailed:
[gmic]-0./ Apply command '' on input image files 'f*.png', with first frame 0, last frame -1, frame step 1 and output filename ''.
That GâMIC assigns an empty string to the command it thinks it is supposed to apply serially to files, and that the output filename template is also an empty string, should raise red flags. In the majority of cases, such red flags indicate that there is a blocking mismatch between what is intended as the pipeline and what actually is the pipeline, as seen by GâMICâs âeyesâ.
Such is a good time to push away from the computer, play a bit with a handy cat or dog, raid the kitchen, stretch a bit, and then return to re-read the processing log and proofread the command line. Usually, such an exercise â taken after a mind-clearing break! â turns up misplaced spaces or incorrectly composed command arguments. For the latter, confer with gmic h
frequently.
Perhaps a theory of what is going wrong fails to emerge. Take a deep breath and then insert -debug
after gmic
, then follow that with your intended pipeline.
gmic -debug -apply_files "f*.png", "samj_Angoisse 1,5,0,5,100,2,4,1,250" output.png
What emerges is an explosion of text: an excruciatingly detailed commentary on GâMICâs traversal of the dependency graph into which GâMIC pipelines decompose. We need not apprehend all of it; just the expansion of the root node (our pipeline, as we wrote it) and the initial children. Under -debug
, GâMIC tells us exactly! how it blocks out the initial command line. That blocking is either how we want it or not, no ifs, ands or buts.
[gmic]-0./ Start G'MIC interpreter (in debug mode).<gmic>-0./ Initial command line: 'cli_start , -debug -apply_files f*.png, "samj_Angoisse 1,5,0,5,100,2,4,1,250" output.png'.
<gmic>./ Decompose command line into 7 items:
<gmic>./ item[0] = 'cli_start'
<gmic>./ item[1] = ','
<gmic>./ item[2] = '-debug'
<gmic>./ item[3] = '-apply_files'
<gmic>./ item[4] = 'f*.png,'
<gmic>./ item[5] = 'samj_Angoisse 1\,5\,0\,5\,100\,2\,4\,1\,250'
<gmic>./ item[6] = 'output.png'
<gmic>-0./ Enter scope './'.
<gmic>-0./ Item 'cli_start', selection [].
<gmic>-0./ Found custom command 'cli_start: ' (takes no arguments).
<gmic>-0./ Expand command line for command 'cli_start' to: ''.
<gmic>-0./cli_start/ Return from empty command 'cli_start/'.
<gmic>-0./ Item '-debug' -> 'debug', selection [].
<gmic>-0./ Item '-apply_files' -> 'apply_files', selection [].
<gmic>-0./ Found custom command 'apply_files: check "isint(${3=0}) && $3>=0 && isint(${4=-1}) && ($4>=0 || $4==-1) && ${5=1}>=1" skip "${2=},${6=}" e[^-1] "Apply command '$2'(...)utput filename '$6'.\n" files 3,"$1" _N=/{narg(${})-1} arg2var _file,${} v + _apply_stream[] "${_file{$frame+1}}","$2",${3-5},"$6"' (takes arguments).
<gmic>-0./ Command 'apply_files': arguments = 'f*.png,'.
<gmic>-0./ Found 1 given argument for command 'apply_files':
<gmic>-0./ $1 = 'f*.png'
âŚ
The first two items: cli_start
and ,
may surprise us: we didnât write those. GâMIC assumes that such initial pipeline items are present. However, GâMIC does not itself define cli_start
. The ,
constitutes its (empty) argument list. We may choose to define a cli_start
: perhaps to include one or more site- or task-specific command files as an initializer for any pipeline we may write. For present purposes, cli_start
and its empty argument list may be ignored. That leaves the remaining items, those which we had specifically written.
At this juncture, we should see that we are â indeed â derailed, for GâMIC perceives three separate items following apply_files
that, by our intentions, were all destined to be arguments for apply_files
. The pipeline following apply_files
has been overly decomposed into too many (wrong) items. That is why the command line and the output file template are being assigned empty strings. Insofar as what GâMIC âseesâ of the command line, those arguments were never given and so defaulted them to empty strings. Looking down further in the debug log, we obtain confirmation of this suspicion. Command 'apply_files': arguments = 'f*.png,'
GâMIC thinks that only one argument is being given to apply_files.
This is where the wheels are leaving the rails.
What controls the itemization of command lines? According to Items of a Processing Pipeline it is the space character, not otherwise embedded in a double-quoted string. âIn GâMIC, an image processing pipeline is described as a sequence of items separated by the space character.â
So. We should be looking for misplaced space characters, and, indeed, there are: one preceding the command line we want to apply, and one preceding the output file template we wanted to use. This broke up what we perceived to be one argument list into three separate items.
The first became the truncated argument list.
GâMIC does not recognize the second item as a known command (the pipeline we wished to have serially applied), and in that circumstance infers that -input
should precede it: this, the convention that allows us to populate image lists expediently by not writing -input
, input
, -i
or i
at all â most times, a blessing, this time a curse.
The tangle goes on, of course, but weâre already dead in the ditch, so who cares?
Armed with a bit of science from Items of a Processing Pipeline and various consultations with gmic help
we arrive at our next pipeline version:
gmic -debug -apply_files "f*.png",\"samj_Angoisse 1,5,0,5,100,2,4,1,250\",0,1,-1,"output.png"
In my shell (Linux, bash) double-quotes are significant to the âBorn Again Shellâ interpreter, so must be escaped to become visible to the GâMIC interpreter (and ignored by the bash shell). Your shell may behave differently; see concluding remarks on how to normalize this vagary. Duelling shells aside, this is what -debug
tells us about the root level pipeline decomposition:
[gmic]-0./ Start G'MIC interpreter (in debug mode).<gmic>-0./ Initial command line: 'cli_start , -debug -apply_files f*.png,"samj_Angoisse 1,5,0,5,100,2,4,1,250",0,1,-1,output.png'.
<gmic>./ Decompose command line into 5 items:
<gmic>./ item[0] = 'cli_start'
<gmic>./ item[1] = ','
<gmic>./ item[2] = '-debug'
<gmic>./ item[3] = '-apply_files'
<gmic>./ item[4] = 'f*.png,samj_Angoisse 1\,5\,0\,5\,100\,2\,4\,1\,250,0,1,-1,output.png'
<gmic>-0./ Enter scope './'.
<gmic>-0./ Item 'cli_start', selection [].
<gmic>-0./ Found custom command 'cli_start: ' (takes no arguments).
<gmic>-0./ Expand command line for command 'cli_start' to: ''.
<gmic>-0./cli_start/ Return from empty command 'cli_start/'.
<gmic>-0./ Item '-debug' -> 'debug', selection [].
<gmic>-0./ Item '-apply_files' -> 'apply_files', selection [].
<gmic>-0./ Found custom command 'apply_files: check "isint(${3=0}) && $3>=0 && isint(${4=-1}) && ($4>=0 || $4==-1) && ${5=1}>=1" skip "${2=},${6=}" e[^-1] "Apply command '$2'(...)utput filename '$6'.\n" files 3,"$1" _N=/{narg(${})-1} arg2var _file,${} v + _apply_stream[] "${_file{$frame+1}}","$2",${3-5},"$6"' (takes arguments).
<gmic>-0./ Command 'apply_files': arguments = 'f*.png,samj_Angoisse 1\,5\,0\,5\,100\,2\,4\,1\,250,0,1,-1,output.png'.
<gmic>-0./ Found 6 given arguments for command 'apply_files':
<gmic>-0./ $1 = 'f*.png'
<gmic>-0./ $2 = 'samj_Angoisse 1\,5\,0\,5\,100\,2\,4\,1\,250'
<gmic>-0./ $3 = '0'
<gmic>-0./ $4 = '1'
<gmic>-0./ $5 = '-1'
<gmic>-0./ $6 = 'output.png'
âŚ
The signal difference is that apply_files
has only one following item, its complete argument list. Scrolling down, we get ample confirmation that the individual terms in this argument list are correctly assigned to the scriptâs internal variables. Indeed, the command proceeds on its merry way.
So, instead of unfocused, guesswork-motivated stabs at the pipeline in hopes that â next time! â youâll hit a jack-pot and get a successful run, I heartily recommend cultivating a savvy on how GâMIC digests command lines and leverage that to quick, nearly effortless, corrections, for youâll be guided by science and principles, not guesswork. In short order, youâll have experience enough so that you need not consult -debug
very often. 999 out of a 1,000 cases, pipeline errors shake down to (1) shell interference, (2) miscomposed argument lists or (3) misplaced spaces. Youâll observe as much in proof-reading pipelines after a brief, healthful break. If that fails, invoke -debug
to observe how GâMIC is blocking out the pipeline and what kind of argument lists are being presented to the commands. If that fails â then maybe there is a bug-in-waiting and you have ample reason to post here.
On a closing note, I should like to observe that (1) shell interference, may be easily dealt with by making use of a very simplified form of custom commands outlined here in this new cheat: Cheat #2: Use Custom Commands to Bypass the Shell. Jumping through character-escape hoops and generally fighting with multiple interpreters can be put to one side, mostly, letting you concentrate on the interesting stuff.