GreycLab / gmic

GREYC's Magic for Image Computing: A Full-Featured Open-Source Framework for Image Processing
Other
66 stars 11 forks source link

Continuous Droste Floating Point Exception + Sometimes Causes BSOD #47

Closed ThioJoe closed 4 days ago

ThioJoe commented 4 months ago

I've been messing around with the continuous droste effect and have been having repeated issues, both with the GUI for the photoshop plugin and the CLI.

Here is an example of a command I'd run, where the droste component of the command comes from copying directly from the Photoshop plugin GUI after resetting to defaults parameters: gmic -input 1000.png -souphead_droste10 40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0 -output output-1000.png

Extremely often, but not quite consistently, it fails like this, for no apparent reason, it just stops:

image

The verbose output seems to suggest it stops at a particular fill command. I'll paste a debug output at the end:

image

What's strange is that at one point, using the same command, it started working if the size of the image was smaller enough (roughly 1000x1000 or less), but now it doesn't again. I've also tried this in a virtual machine and it does the same thing. And it also does it with both version 3.3.5 and 3.3.6, and with both update335.gmic and update336.gmic, which I tested by specifying the exact filter file version:

image

The same thing appears to happen in the photoshop version though, and this one at least gives some kind of error message. In this case, the error occurs immediately when clicking on the Continuous Droste effect, or if the effect was already selected (and therefore it tries to open that immediately), the error occurs immediately after trying to open the plugin: image

The error 0xc000008f means "Floating-point inexact result". (Technically it could also mean "The system cannot join or substitute a drive to or for a directory on the same drive" but I think the other meaning is more likely).

The reason I noticed image size might be a contributing factor (but not the only factor) is that for a while it worked in the photoshop GUI when I was trying to do the effect on a very large image (6000x6000) and the effect preview window was able to show the effect being done. But if I tried to hit "apply", it would crash, and if I expanded the GUI preview window too large (as to expand the preview image size) it would also crash. Therefore I tried downsizing the image and then it worked in the CLI where it wouldn't before with the large version. But again, now for some reason it won't even work with those same exact smaller images.

Windows Event Viewer log shows that it is indeed the same crash whether in the GUI or CLI, as you can see the "Exception Code" is the same one that is shown in the window of the GUI when it crashes:

image

What's more concerning is if I try to run the command via the CLI too many times in succession, it causes a BSOD. And by this I mean, the command fails and gmic.exe exits, and the terminal window shows the C:\whatever> prompt again, and if I do that too many times in a row too quickly, it BSODs. After it happened the first time, I tried the same thing again to see if it was a fluke, but it happened again. See the event viewer log below showing the crashes (these events don't have info about the cause). The actual stop code for both BSODs was 0000007E aka SYSTEM_THREAD_EXCEPTION_NOT_HANDLED.

image

More strange behavior - I just tried to replicate the BSOD issue in a virtual machine, and while it didn't seem to cause it, it demonstrated the weird inconsistency I was talking about. Here you can see the same command ran back-to-back 5 times and failing each time, but randomly working on the 6th time (see that it actually got to the "output image" stage):

image

Here's a full debug example:

C:\Users\Joe\Downloads\gmic_3.3.5_cli_win64>gmic -debug -input 1000.png -souphead_droste10 40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0 -output output-1000.png
[gmic]./ Start G'MIC interpreter (v.3.3.5, debug mode).
<gmic>./ Initial command line: 'cli_start , -debug -input 1000.png -souphead_droste10 40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0 -output output-1000.png'.

<gmic>./ Enter scope './'.
<gmic>./ Item[0]: 'cli_start', selection [].
<gmic>./ Found custom command 'cli_start: ' (takes no arguments).
<gmic>./ Expand command line for command 'cli_start' to: ''.
<gmic>./cli_start/ Return from empty command 'cli_start/'.
<gmic>./ Item[2]: '-debug' -> 'debug', selection [].
<gmic>./ Item[3]: '-input' -> 'input', selection [].
<gmic>./ Command 'input': arguments = '1000.png'.
[gmic]./ Input file '1000.png' at position 0 (1 image 1000x1000x1x3).
<gmic>./ Item[5]: '-souphead_droste10' -> 'souphead_droste10', selection [0].
<gmic>./ Found custom command 'souphead_droste10:  _souphead_droste10 ${1-26},0,${28-31}' (takes arguments).
<gmic>./ Command 'souphead_droste10': arguments = '40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0'.
<gmic>./ Found 31 given arguments for command 'souphead_droste10':
<gmic>./   $1 = '40'
<gmic>./   $2 = '100'
<gmic>./   $3 = '1'
<gmic>./   $4 = '1'
<gmic>./   $5 = '1'
<gmic>./   $6 = '0'
<gmic>./   $7 = '0'
<gmic>./   $8 = '0'
<gmic>./   $9 = '0'
<gmic>./   $10 = '0'
<gmic>./   $11 = '1'
<gmic>./   $12 = '10'
<gmic>./   $13 = '1'
<gmic>./   $14 = '0'
<gmic>./   $15 = '90'
<gmic>./   $16 = '0'
<gmic>./   $17 = '0'
<gmic>./   $18 = '0'
<gmic>./   $19 = '0'
<gmic>./   $20 = '1'
<gmic>./   $21 = '0'
<gmic>./   $22 = '0'
<gmic>./   $23 = '1'
<gmic>./   $24 = '0'
<gmic>./   $25 = '0'
<gmic>./   $26 = '0'
<gmic>./   $27 = '0'
<gmic>./   $28 = '0'
<gmic>./   $29 = '1'
<gmic>./   $30 = '0'
<gmic>./   $31 = '0'
<gmic>./ Expand command line for command 'souphead_droste10' to: ' _souphead_droste10 40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0'.
<gmic>./ Decompose command line into 2 items:
<gmic>./   item[0] = '_souphead_droste10'
<gmic>./   item[1] = '40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0'

<gmic>./souphead_droste10/ Enter scope 'souphead_droste10/'.
<gmic>./souphead_droste10/ Item[0]: '_souphead_droste10', selection [0].
<gmic>./souphead_droste10/ Found custom command '_souphead_droste10:  repeat $! l[$>] to_a +f. 0 sh. 0 f. "* begin(InnerRadius = $1; OuterRadius = $2; Periodicity = $3; Strands = $4; Zoom = $5; Rot(...),ColorOutA=1); i(#1,x,y,0,1)=ColorOutG*255; i(#1,x,y,0,2)=ColorOutB*255; i(#1,x,y,0,3)=ColorOutA*255; ColorOutR*255" k.. done done' (takes arguments).
<gmic>./souphead_droste10/ Command '_souphead_droste10': arguments = '40,100,1,1,1,0,0,0,0,0,1,10,1,0,90,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0'.
<gmic>./souphead_droste10/ Found 31 given arguments for command '_souphead_droste10':
<gmic>./souphead_droste10/   $1 = '40'
<gmic>./souphead_droste10/   $2 = '100'
<gmic>./souphead_droste10/   $3 = '1'
<gmic>./souphead_droste10/   $4 = '1'
<gmic>./souphead_droste10/   $5 = '1'
<gmic>./souphead_droste10/   $6 = '0'
<gmic>./souphead_droste10/   $7 = '0'
<gmic>./souphead_droste10/   $8 = '0'
<gmic>./souphead_droste10/   $9 = '0'
<gmic>./souphead_droste10/   $10 = '0'
<gmic>./souphead_droste10/   $11 = '1'
<gmic>./souphead_droste10/   $12 = '10'
<gmic>./souphead_droste10/   $13 = '1'
<gmic>./souphead_droste10/   $14 = '0'
<gmic>./souphead_droste10/   $15 = '90'
<gmic>./souphead_droste10/   $16 = '0'
<gmic>./souphead_droste10/   $17 = '0'
<gmic>./souphead_droste10/   $18 = '0'
<gmic>./souphead_droste10/   $19 = '0'
<gmic>./souphead_droste10/   $20 = '1'
<gmic>./souphead_droste10/   $21 = '0'
<gmic>./souphead_droste10/   $22 = '0'
<gmic>./souphead_droste10/   $23 = '1'
<gmic>./souphead_droste10/   $24 = '0'
<gmic>./souphead_droste10/   $25 = '0'
<gmic>./souphead_droste10/   $26 = '0'
<gmic>./souphead_droste10/   $27 = '0'
<gmic>./souphead_droste10/   $28 = '0'
<gmic>./souphead_droste10/   $29 = '1'
<gmic>./souphead_droste10/   $30 = '0'
<gmic>./souphead_droste10/   $31 = '0'
<gmic>./souphead_droste10/ Expand command line for command '_souphead_droste10' to: ' repeat $! l[$>] to_a +f. 0 sh. 0 f. "* begin(InnerRadius = 40; OuterRadius = 100; Periodicity = 1; Strands = 1; Zoom = 1; Rotat(...),ColorOutA=1); i(#1,x,y,0,1)=ColorOutG*255; i(#1,x,y,0,2)=ColorOutB*255; i(#1,x,y,0,3)=ColorOutA*255; ColorOutR*255" k.. done done'.
<gmic>./souphead_droste10/ Decompose command line into 13 items:
<gmic>./souphead_droste10/   item[0] = 'repeat'
<gmic>./souphead_droste10/   item[1] = '$!'
<gmic>./souphead_droste10/   item[2] = 'l[$>]'
<gmic>./souphead_droste10/   item[3] = 'to_a'
<gmic>./souphead_droste10/   item[4] = '+f.'
<gmic>./souphead_droste10/   item[5] = '0'
<gmic>./souphead_droste10/   item[6] = 'sh.'
<gmic>./souphead_droste10/   item[7] = '0'
<gmic>./souphead_droste10/   item[8] = 'f.'
<gmic>./souphead_droste10/   item[9] = '* begin(InnerRadius = 40; OuterRadius = 100; Periodicity = 1; Strands = 1; Zoom = 1; Rotate = 0; XShift = 0; YShift = 0; XCenterShift = 0; YCenterShift = 0; StartingLevel = 1; NumberOfLevels = 10; LevelFrequency = 1; ShowBothPoles = 0; PoleRotation = 90; PoleLong = 0; PoleLat = 0; TilePoles = 0; HyperDroste = 0; FractalPoints = 1; AutoSetPeriodicity = 0; NoTransparency = 0; ExternalTransparency = 1; MirrorEffect = 0; Untwist = 0; DoNotFlattenTransparency = 0; ShowGrid = 0; ShowFrame = 0; Antialias = 1; XEdgeType = 0; YEdgeType = 0; r1 = InnerRadius/100; r2 = OuterRadius/100; p1 = Periodicity; p2 = Strands; xCenterShift = XCenterShift/100; yCenterShift = YCenterShift/100; W = (w-1)/2; H = (h-1)/2; xShift = (XShift*w/W)/100; yShift = (YShift*h/H)/100; tileBasedOnTransparency=!(NoTransparency); transparentPointsIn=!(ExternalTransparency); levelsToLookOut=StartingLevel; levelToShow=LevelFrequency; retwist=!(Untwist); if (AutoSetPeriodicity\,p1=p2/2*(1+sqrt(1-(log(r2/r1)/pi)^2))); if (p1>0\,rotat(...)
<gmic>./souphead_droste10/   item[10] = 'k..'
<gmic>./souphead_droste10/   item[11] = 'done'
<gmic>./souphead_droste10/   item[12] = 'done'

<gmic>./souphead_droste10/_souphead_droste10/ Enter scope '_souphead_droste10/'.
<gmic>./souphead_droste10/_souphead_droste10/ Item[0]: 'repeat', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/ Command 'repeat': arguments = '$!' -> '1'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/ Start 'repeat...done' block (1 iteration).
<gmic>./souphead_droste10/_souphead_droste10/*repeat/ Item[2]: 'l[$>]' -> 'l[0]', selection [0].
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/ Start 'local...done' block, with image [0].

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Enter scope '*local/'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Item[3]: 'to_a', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Found custom command 'to_a:  e[^-1] "Force image$? to have an alpha channel." foreach { if !s||s>4 error[0--5] "Command '$0': Image ["$>"] is not a G,GA,RGB or RGBA image ("{s}" channels)." elif s==1||s==3 channels 0,{s} sh. {s-1} f. 255 rm. fi }' (takes no arguments).
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Expand command line for command 'to_a' to: ' e[^-1] "Force image$? to have an alpha channel." foreach { if !s||s>4 error[0--5] "Command 'to_a': Image ["$>"] is not a G,GA,RGB or RGBA image ("{s}" channels)." elif s==1||s==3 channels 0,{s} sh. {s-1} f. 255 rm. fi }'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Decompose command line into 19 items:
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[0] = 'e[^-1]'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[1] = 'Force image$? to have an alpha channel.'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[2] = 'foreach'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[3] = '{'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[4] = 'if'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[5] = '!s||s>4'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[6] = 'error[0--5]'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[7] = 'Command 'to_a': Image [$>] is not a G\,GA\,RGB or RGBA image ({s} channels).'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[8] = 'elif'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[9] = 's==1||s==3'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[10] = 'channels'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[11] = '0,{s}'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[12] = 'sh.'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[13] = '{s-1}'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[14] = 'f.'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[15] = '255'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[16] = 'rm.'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[17] = 'fi'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/   item[18] = '}'

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/ Enter scope 'to_a/'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/ Item[0]: 'e[^-1]', selections [0,1,2,3,4].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/ Command 'echo': arguments = 'Force image$? to have an alpha channel.' -> 'Force image [0] to have an alpha channel.'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/ Force image [0] to have an alpha channel.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/ Item[2]: 'foreach', selection [0].
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/ Start 'foreach...done' block, with image [0].

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/ Enter scope '*foreach/'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/ Item[4]: 'if', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/ Command 'if': arguments = '!s||s>4'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Start 'if...endif' block -> condition '!s||s>4' does not hold.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Item[8]: 'elif', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Command 'elif': arguments = 's==1||s==3'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Reach 'elif' block -> condition 's==1||s==3' holds.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Item[10]: 'channels', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Found custom command 'channels: skip ${2=$1} e[^-1] "Keep channels $1...$2 of image$?." z 0,0,0,$1,100%,100%,100%,$2' (takes arguments).
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Command 'channels': arguments = '0,{s}' -> '0,3'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Found 2 given arguments for command 'channels':
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   $1 = '0'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   $2 = '3'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Expand command line for command 'channels' to: 'skip 3 e[^-1] "Keep channels 0...3 of image$?." z 0,0,0,0,100%,100%,100%,3'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Decompose command line into 6 items:
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   item[0] = 'skip'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   item[1] = '3'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   item[2] = 'e[^-1]'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   item[3] = 'Keep channels 0...3 of image$?.'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   item[4] = 'z'
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/   item[5] = '0,0,0,0,100%,100%,100%,3'

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Enter scope 'channels/'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Item[0]: 'skip', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Command 'skip': arguments = '3'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Skip argument '3'.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Item[2]: 'e[^-1]', selections [0,1,2,(...),5,6,7].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Command 'echo': arguments = 'Keep channels 0...3 of image$?.' -> 'Keep channels 0...3 of image [0].'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Keep channels 0...3 of image [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Item[4]: 'z', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Command 'crop': arguments = '0,0,0,0,100%,100%,100%,3'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Crop image [0] with coordinates (0,0,0,0) - (100%,100%,100%,3) and dirichlet boundary conditions.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/channels/ Exit scope 'channels/'.

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Item[12]: 'sh.', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Command 'shared': arguments = '{s-1}' -> '3'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Insert shared buffer from channel 3 of image [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Item[14]: 'f.', selection [1].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Command 'fill': arguments = '255'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Fill image [1] with 255.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Item[16]: 'rm.', selection [1].
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Remove image [1] (1 image left).
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ Item[17]: 'fi', selection [0].
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/*if/ End 'if...endif' block.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/ Item[18]: '}', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/*foreach/ Exit scope '*foreach/'.

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/to_a/ Exit scope 'to_a/'.

<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Item[4]: '+f.' -> 'f.', selection [0].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Command 'fill': arguments = '0'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/ Fill image [0] with 0.
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Item[6]: 'sh.', selection [1].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Command 'shared': arguments = '0'.
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/ Insert shared buffer from channel 0 of image [1].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Item[8]: 'f.', selection [2].
<gmic>./souphead_droste10/_souphead_droste10/*repeat/*local/ Command 'fill': arguments = '* begin(InnerRadius = 40; OuterRadius = 100; Periodicity = 1; Strands = 1; Zoom = 1; Rotate = 0; XShift = 0; YShift = 0; XCenterShift = 0; YCenterShift = 0; StartingLevel = 1; NumberOfLevels = 10; LevelFrequency = 1; ShowBothPoles = 0; PoleRotation = 90; PoleLong = 0; PoleLat = 0; TilePoles = 0; HyperDroste = 0; FractalPoints = 1; AutoSetPeriodicity = 0; NoTransparency = 0; ExternalTransparency = 1; MirrorEffect = 0; Untwist = 0; DoNotFlattenTransparency = 0; ShowGrid = 0; ShowFrame = 0; Antialias = 1; XEdgeType = 0; YEdgeType = 0; r1 = InnerRadius/100; r2 = OuterRadius/100; p1 = Periodicity; p2 = Strands; xCenterShift = XCenterShift/100; yCenterShift = YCenterShift/100; W = (w-1)/2; H = (h-1)/2; xShift = (XShift*w/W)/100; yShift = (YShift*h/H)/100; tileBasedOnTransparency=!(NoTransparency); transparentPointsIn=!(ExternalTransparency); levelsToLookOut=StartingLevel; levelToShow=LevelFrequency; retwist=!(Untwist); if (AutoSetPeriodicity\,p1=p2/2*(1+sqrt(1-(log(r2/r1)/pi)^2)))(...)
[gmic]./souphead_droste10/_souphead_droste10/*repeat/*local/ Fill image [2] with expression '* begin(InnerRadius = 40; OuterRadius (...)x,y,0,3)=ColorOutA*255; ColorOutR*255'.
grosgood commented 4 months ago

Hi ThioJoe, First, thanks for the really really detailed bug report. Few appreciate the effort involved in putting together such a report. Tip of the hat to you, sir.

Second, apologies that no one replied really really quickly. We're a small group with daytime jobs.

Third, my suspicions center on the G'MIC shared command. The command allows a component of one image ('donor') to be constituted as a separate image ('share'); from there forward manipulation of 'share', functionally a separate image, impacts 'donor' as well. Perhaps 'donor' shares out one of its channels (say channel 0, representing red data, as in the debug dump). Then the second, shared out, image seems to be only a single channel image, a grayscale — in fact, it is sharing the donor's red channel. Change the gamma of of 'share', and the red channel of 'donor' sees a gamma change as well — because it is shared memory space between two images! There are other ways to do such a thing, but with super-huge images and a constrained memory setting, the shared command is tempting.

Now, there is a protocol in using the shared command: Don't delete the donor while share images are still extant! Do so, and the shares now have pointers into a block of memory that has been reconsigned to the heap — maybe, because it's not quite clear when heap clean up occurs vis-à-vis the running gmic process. But, if the stars aren't aligning, then further operations on the now-dangling-share images will be detected by the OS as an access violation, which leads to an immediate kill of the gmic process — it doesn't even get a chance to wind down; the OS no longer trusts gmic's use of memory. That explains the utter silence of the crash. No exception stack, no die message, nothing. Maybe you get the shell prompt back. Maybe Blue Screen Of Death. It also explains the randomness of the bug's behavior: the gmic process is racing heap clean-up. Sometimes it wins.

I see you've dropped a comment at discuss.pixls.us. Will drop a word there to look here.

In the hunt now. Thanks for the report!

ThioJoe commented 4 days ago

I forgot about this issue but turns out it was apparently a hardware issue. After a BIOS update which included some updates by intel the problem went away. Probably related to the Intel 13th and 14th gen issues. So I'm gonna close this.