Please help understand G'MIC source code

I’ve been reading G’MIC source code and I see code I don’t understand.

Some functions don’t seem to be declared as class members, but behave like they are. For example get_inpaint in gmic.cpp. I don’t see it declared as member of CImg class or any other class (neither in CImg.h, nor signature indicates class member function), but the function accesses “this” pointer.

How does this work?

CImg has a system of plug-ins, that allows to define methods of class CImg<T> in an external file to the class definition. It works basically by putting this kind of stuffs in the class CImg<T>:

struct CImg {
   ... 
#ifdef cimg_plugin
#include cimg_plugin
#endif
 ....
}

G’MIC uses this possibility to add its own custom methods into the CImg<T> class.
Now, the trick is that the value of the macro cimg_plugin defined by gmic.cpp is actually "gmic.cpp", which means the CImg Library will try to include file gmic.cpp as a plug-in.

So the file gmic.cpp defines both a plug-in for CImg, and the code of the G’MIC interpreter. It’s like a self-inclusion, that’s why the file starts with something like:

// Add G'MIC-specific methods to the CImg library.
//------------------------------------------------
#ifdef cimg_plugin
    ... Define some custom methods for class CImg<T>
        (part of the CImg plug-in).
#else
    ... Now, that's the part of the G'MIC interpreter 
        (not included by CImg).
#endif 

to assure only the right content of the file is included as a CImg plug-in.

If you are looking for a CImg method called from G’MIC which is not present in main library file CImg.h, then it is probably defined as a plug-in method in file gmic.cpp (that’s the case e.g. for the inpaint method). Note that the license of the two files CImg.h and gmic.cpp are not the same (CeCILL-C for the former, CeCILL for the latter), which means parts of gmic.cpp cannot be re-used as easily as parts of CImg.h.

Tnank you. It makes sense now. Very unconventional design.

Yes, and that’s why it works so well :slight_smile: