Release of G'MIC 3.3

This is the changelog for the release of the 3.3.0 version of the G’MIC software, released on 2023/09/04.

It lists all new features and changes done since the previous minor version 3.2.

What is G’MIC?

G’MIC (GREYC’s Magic for Image Computing) is a full-featured open-source framework for image processing. It provides several different user interfaces to convert/manipulate/filter/visualize generic image datasets, ranging from 1D scalar signals to 3D+t sequences of multi-spectral volumetric images, thus including 2D color images.

supportus


^ The plug-in G’MIC-Qt in action, running for GIMP 2.10 ^

What’s new in version 3.3?

New features:

Version 3.3.0:

  • [gmic-stdlib-330] Commands display and display0 have been recoded from scratch as stdlib commands (not native anymore). Interactive image viewer using display has been improved a lot.

  • [gmic-stdlib-330] Command print has been recoded as a stdlib command (not native anymore).

  • [gmic-stdlib-330] Command is_3d renamed as is_mesh3d.

  • [gmic-stdlib-330] New command strbuffer returns a string describing a buffer size.

  • [gmic-stdlib-330] New command rand_sum fills selected images with strictly positive, random, integer values, that sums to specified fixed value.

  • [math-core-330] Starting a fill expression with + forces it to be evaluated in a single thread, but with an image copy (equivalent to * without multi-threading).

  • [math-core-330] Allow run() to be run in parallel in math parser.

Version 3.2.6:

  • [gmic-qt-326] New filter Degradations / Sloppy Mess. Filter written by Prawnsushi, a new contributor to the G’MIC project.

  • [gmic-stdlib-326] New command imagealpha (shortcut ja) draws a sprite into selected images, considering the last channel of the specified sprite represents an alpha-channel for the drawing.

Version 3.2.5:

  • [math-core-325] Add predefined variable id#ind whose value is the standard deviation of the image [ind].

Version 3.2.4:

  • [gmic-qt-324] New filter Degradations / Huffman Glitches simulates the effect of bit-inversion noise on Huffman compressions of parts of the image. Nice filter to simulate various kind of transmission glitches.

  • [math-core-324] New function unitnorm(V,_p) in math evaluator: return normalized version of the vector V by the Lp norm.

  • [math-core-324] New function normp(V,_p) in math evaluator: return Lp norm of the vector V.

  • [stdlib-324] New command fov3d sets and return the 3D focale associated to the specified angle of view, for selected image.

  • [stdlib-324] New commands compress_huffman, decompress_huffman and huffman_tree implement Huffman coding for lossly compression/decompression of image data.

  • [stdlib-324] New command input_bytes (eq. to ib) loads specified filename as a 1D array of bytes.

Version 3.2.3:

  • [gmic-qt-323] New filter Patterns / Pack Ellipses packs colored circles or ellipses together in order to recreate the input image.

  • [stdlib-323] New command display_clut (shortcut dclut) renders a 3D color LUT as a colored 3D cube, that shows the RGB\rightarrow RGB color mapping.

  • [core-323] Add functions o2c() (offset to image coordinates) and c2o() (image coordinates to offset) in the math evaluator.

Version 3.2.2:

  • [gmic-qt-322] New filter Colors / Random Color Transformation generates a random color LUT that transforms the colors of the image to give it another look.

  • [gmic-qt-322] New settings allow the user to add external filter sources. This allows to get “non-official” additional filters in the plug-in.

  • [gmic-qt-322] When clicking on “Apply” and when the selected filter finishes rendering, the Elapsed time is displayed on the plug-in window.

  • [stdlib-322] New command random_clut generates a 33x33x33 random 3D color LUT.

  • [stdlib-322] New commands color2name and name2color converts a R,G,B triplet to its color name (in English), and vice-versa.

Version 3.2.1:

  • [math-core-321] New function csqrt() computes the square root of a complex number (commit).

  • [stdlib-321] Add new command line_aa: draws anti-aliased lines in images, using Xiaolin Wu’s line algorithm (commit).

gmic_line_aa

  • [stdlib-321] New command to_voxels3d converts a 3D meshed object into a binary shape made of voxels in a 3D volumetric image.

  • [stdlib-321] New command display_voxels3d (eq. to dv3d) displays a 3D view of selected volumetric images of 3D voxels.

  • [stdlib-321] New command subdivide3d subdivides primitives of a 3D mesh into several sub-primitives.

  • [stdlib-321] New command extract_textures3d extract textures from 3D objects.

It can be used for instance to process and remap textures on a 3D object, like in the example below.

  • [stdlib-321] New command chainring3d generate a 3D colored chain ring (commit).

  • [stdlib-321] New command da_freeze allows to freeze several dynamic arrays at the same time (commit).

  • [stdlib-321] New command lof returns the list of specified features (separated by commas) for each selected images (commit). For instance: sp lena,eagle,cat,dog ${"lof [w,h]"} returns 512,512,520,480,600,550,1024,685.

  • [gmic-qt-321] New filter Testing / Garagecoder / Upscale [Recursive2x], developed by long-term contributor Garagecoder upscales image using self-similarity, to preserve details as much as possible.

  • [stdlib-321] New commands shape_menger and shape_mosely generate 3D voxelized representations of respectively, a Menger Sponge and a Mosely Snowflake.

  • [stdlib-321] New commands curve3d generates a parameterized 3D curve (x(t),y(t),z(t)) with a possibly varying radius r(t).


Improvements / Changes:

Version 3.3.0:

  • [gmic-qt-330] Filter Light Rays: Add option to render color light rays.

  • [gmic-qt-330] Command drop_shadow has been recoded from scratch, as well as corresponding filter Light & Shadows / Drop Shadow. It now better manages several isolated opaque components in a transparent image.

  • [stdlib-330] Command projections3d: Improve object subdivision to allow better rendering.

  • [stdlib-330] Fix possible issue when using ‘for…done’ in recursively called commands.

  • [core-330] Fixed issue in .bmp loader to prevent malicious files to make the loader crash.

  • [core-330] Command permute : Detect special cases that do not actually require pixel inversions in image buffer.

Version 3.2.6:

  • [math-core-326] Better determine if multi-threading must be enabled, in particular for volumetric images (favor parallelization).

  • [math-core-326] Modulo operator % now returns nan if second argument is 0.

  • [gmic-qt-326] Allow string type for the $_persistent variable.

Version 3.2.5:

  • [math-core-325] Optimization of functions norm() and normp() in the math evaluator.

Version 3.2.4:

  • [core-324] Optimization of command parser: decrease number of string comparisons to detect the use of a native command name.

  • [core-324] Improve suggestion of command name when error occured (include ‘+commands’ as well).

Version 3.2.3:

  • [gmic-qt-323] Many improvements for more stability of the G’MIC-Qt plug-in. Better management of unfinished threads.

  • [core-323] On Windows, change path of G’MIC user file to %USERPROFILE%/user.gmic.

  • [core-323] - Make abort signal checked when using command display.

Version 3.2.2:

  • [gmic-qt-322] Various optimizations for speeding up startup time: faster filter parsing, generation of a binary cache for parsed filter informations, etc.

  • [stdlib-322] Command colorcube3d gets a new option for generating a wireframe object.

  • [core-322] Make use of left/right braces more intuitive to start/end any kind of code block. So, they can be used in more various situations, like in C++. For instance:

repeat 3 { echo $> }  # OK (3.2.1 && 3.2.2)
if (u<0.5) { echo "success" } else { echo "fail"} fi # OK (3.2.2), FAILED (3.2.1)
do {  # OK (3.2.2), FAILED (3.2.1)
  val:=u 
  echo $val
} while ($u<0.5)

Version 3.2.1:

  • [gmic-qt-321] Filter Repair / Banding Denoise gets improvements, with new options for tiled denoising and split preview mode.

  • [core-321] Command foreach: Add copymark to resulting image names when +foreach is used (commit).

  • [core-321] Parser for selections/subsets expressions has been written from scratch.

  • [core-321] Make dynamic arrays handle large number of elements (at least 2^31).

  • [core-321] Commands eval and fill now replace the status value by the result of the end() block, if any specified (status is emptied otherwise).

  • [math-core-321] Optimize evaluation of empty boolean expressions (commit).

  • [math-core-321] Add detection of the not operator for faster pre-evaluation of some math expressions.

  • [stdlib-321] Command primitives3d has been recoded from scratch. It better manages texture → color transformation, as well as avoid duplicates of segment/point primitives when possible.

  • [stdlib-321] Convert commands mode3d, moded3d, double3d, focale3d, specl3d, specs3d, split3d, color3d, opacity3d, reverse3d (aka m3d, md3d, db3d, f3d, sl3d, ss3d, s3d, col3d, o3d, rv3d), as well as sphere3d, as custom commands rather than native ones (commit).

  • [stdlib-321] Command sphere3d is now able to generate 3D spherical mesh using three different methods: icosahedron subdivision, cube subdivision and spherical angle discretization.

  • [stdlib-321] Command boundingbox3d now manage correctly 3D object containing sphere primitives.

  • [stdlib-321] Commands transfer_pca, transfer_histogram and transfer_rgb have been renamed to match_pca, match_histogram and match_rgb.


Bug fixes:

Version 3.3.0:

  • [core-330] Fix scope management of ‘onfail’ block when error happens in a repeat, for or foreach block.

  • [core-330] Fix command ‘text’ when applied on empty image, without color specified.

Version 3.2.6:

  • [gmic-qt-326] Fix visibility after filter update when parameter count changes.

  • [gmic-qt-326] Fix bug with parameter visibilities when no ‘actual parameter’.

  • [stdlib-326] Fix command remove_empty when no images have to be removed.

  • [core-326] Fix selection parsing: selections starting with characters , and % are considered as invalid.

Version 3.2.4:

  • [core-324] Fix bug that prevented accessing a G’MIC variable in a math expression after a local... onfail... done block where an error occurred.

  • [core-324] Fix path for $_path_user on Windows.

Version 3.2.3:

  • [gmic-qt-323] Fix parsing of status returned by filters to set up the value/visibility of filter parameter widgets.

  • [core-323] Make command break works properly when used in a { code block }.

  • [core-323] Add mutex to protect possible decompression of stdlib by parallel threads.

  • [stdlib-323] Fix computer player in command x_connect4.

Version 3.2.2:

  • [core-322] Ensure mutexes are active when compiling G’MIC without display support.

Version 3.2.1:

  • [core-321] Fix command name when empty argument is specified (commit).
3 Likes

Bonjour,

Thank you for this new command (line_aa).
Many pixels of the original color are lost with this new command.
It is very visible on a black background.
Is this normal?

‘line_aa’ vs ‘line’ :

line_aa

line

Code used for the test :


test_lines :
512,512,1,3
512,512,1,3
repeat 16
 srand $>
 line. {round(u([w,h,w,h])-1)},1,${-RGB} 
 srand $>
 line_aa.. {round(u([w,h,w,h])-1)},1,${-RGB} 
done
text. "line",20,20,16,1,127,127,127
text.. "line_aa",20,20,16,1,127,127,127

That may be the nature of antialiasing. Perhaps allow smudging as opposed to blurring of corners…?

Sometimes it might be helpful to have

PRERELEASE = $(shell date +%y%m%d%H%M)

in the gmic Makefile, if that is accepted in gmic?

I think the anti-aliasing should apply only on the alpha channel if no alpha has been detected, and apply on color if alpha has been detected.

I don’t understand the question, this is exactly line 181 of the current Makefile.

No no %H %M is added!

Ah I see. What would be the point of adding the hour/minute to the prerelease name?
Manage several prerelease done the same day?
Does it happen that often that we need it?

Yes exactly, as I follow your changes/additions!

@afre

line_aa : A simple analysis is enough to see that the result is very different from what is presented on the page

@samj Now I remember the solution. You divide the alpha by 255 if the Alpha(1) is equal to 255. Then divide the color channel by the alpha ignoring zero (just wish G’MIC has a special case of div which ignores 0), then change the alpha back to normal value. This works if and only if your image has an alpha value.

I wonder what would prevent someone needing it to actually write it as a new command.
This seems pretty straightforward :wink:

Concerning the anti-aliased drawing, it may need some update, I’ve just implemented the algorithm as described in the wikipedia page. Any good improvement is welcome.

It depends heavily on each case what you want to happen, I tend to include specific handling per command. Having said that, here’s what I use in my own local testing when required:

gcd_divnz : skip ${1=};
  l[] is_image_arg=${"is_image_arg $1"} onfail is_image_arg=0 done
  if $is_image_arg pass$1 1 +eq. 0 add. .. rm.. div[^-1] . rm.
  else +eq. 0 add[-2,-1] div[^-1] . rm. noarg fi

It handles either gcd_divnz[-2,-1] or gcd_divnz.. . which is convenient for me.

2 Likes

Anyway, another remark on anti-aliased line.

The classical way of doing anti-aliasing is rendering an image at 200%, then reduce its resolution by half when your rendering is finished.
If you do this for the line drawing over a black background, and you compare with the use of line_aa:

foo :
  256,256,1,3
  512,512,1,3

  repeat 100
    coords:=round(u([w,h,w,h]-1))
    col=${-RGB}
    line_aa.. {[$coords]/2},1,$col
    line. $coords,1,$col
  done
  r2dx. 50%

Then you already see that line_aa (left) artificially adds some thickness to the drawn segments, compared to the standard way of doing anti-aliasing rendering (right).

I’m really not sure at which point you want your drawn line pixels having exactly the specified color.
it seems to be in opposition with making anti-aliased rendering.

Nice discussion here: https://diglib.eg.org/xmlui/bitstream/handle/10.2312/14944/025-032.pdf?sequence=1&isAllowed=y

This part pretty much echoes my thoughts on the matter (manual being what a pixel artist would do - automatic/Superpixelator being their method):

image

PS - Wu’s method is fine but I don’t like its ropey appearance.
PPS - Iterative guided filter or rolling guidance may be a dirty way to solidify the line.

It is a trial to improve the visibility of ‘line_aa’.
The result of the rendering is ‘line_aa_plus_matrice’
The original rendering is ‘line_aa’

line_aa_plus_matrice

line_aa

Code :

test_lines_2 :
512,512,1,3
repeat 16
 srand $>
 line_aa. {round(u([w,h,w,h])-1)},1,${-RGB}
done
(0.2,0,0.2;0,1,0;0.2,0,0.2)
convolve[-2] [-1]
rm.
text. "line_aa_plus_matrice",20,20,16,1,127,127,127

@Reptorian
@garagecoder
Thank you for research and the idea.

1 Like

The Cascading Self-Glitching filter in the Gimp GMIC 3.2.0 (stable) GUI at Testing > Joan Rake > Degradations works fine however in the Windows cli latest stable 3.2.0 I get this error:

‘’’
C:\Users\me>gmic v -99 in.png fx_self_glitching_cascade 5,1,0,50,50,3,3,1,55,55,0,45,45,0.75,3,0,0,0,0,1,0,0,256,1,19,0 o out.png

 [gmic] *** Error in ./fx_self_glitching_cascade/*repeat/*local/(...)/*if/modf/*if/modular_formula/ *** Command 'fill': Function 'if()': Missing argument, in expression 'if(!skip; if(0>3, if(!(0%2) ,calc(a)=mf(a+var3_mod); ,calc(a)=amf(a+var3_mod); ); ,if(0>1, if(!(0%2) ,calc(a)=mf(a*(abs(256)/var3_mod)); ,calc(a)=amf(a*(abs(256)/var3_mod)); ); ,if(!(0%2) ,calc(a)=mf(a); ,calc(a)=amf(a); )'.
 [gmic] Command 'fill' has the following description:

fill (+):
value1,_value2,… |
[image] |
‘formula’

Fill selected images with values read from the specified value list,
existing image
or mathematical expression. Single quotes may be omitted in 'formula'.
(equivalent to shortcut command 'f').

Example:
  [#1] 4,4 fill 1,2,3,4,5,6,7
  [#2] 4,4 (1,2,3,4,5,6,7) fill[-2] [-1]
  [#3] 400,400,1,3 fill "X=x-w/2; Y=y-h/2; R=sqrt(X^2+Y^2); a=atan2(Y,X);
   if(R<=180,255*abs(cos(c+200*(x/w-0.5)*(y/h-0.5))),
   850*(a%(0.1*(c+1))))"

‘’’

In Windows cli Version 3.2.0 (pre-release #221102) it works perfectly well, so somehing broke along the way.

I know there’s a perfectly usable Self-Glitching filter under normal Degradations, however I prefer the multiple x,y positional shifts available in the broken one.

Cheers!

line_aa

@David_Tschumperle

Bonjour,

For information I compared the rendering of line_aa with the program of the page Anti-aliased Line | Xiaolin Wu's algorithm - GeeksforGeeks
The results are identical (attached file : comparaison_Xiaolin-Wu.xcf.bz2).
For me there is too much loss of quality using this algorithm on lines :smiling_face_with_tear:
Merci quand même pour la programmation de cette commande :grinning:
comparaison_Xiaolin-Wu.xcf.bz2 (6.2 KB)

I’ll have a look at it. Modf is my command.

1 Like

line_aa

There may be an error in the Wikipedia code:

There is a very clear difference between the rendering of Wikipedia and line_aa visible on test4_Xiaolin-Wu.xcf.bz2 (Gimp image)
test4_Xiaolin-Wu.xcf.bz2 (92.8 KB)

Code :

test_lines_4 :
Larg=394
784,510,1,3
fill_color 255,255,255
repeat 16
 line_aa. 394,5,$Larg,510,1,0,0,255
 Larg+=21
done