G'MIC command inpaint_matchpatch not work in iOS ?

Hi,

I’m experimenting with the G’MIC inpainting algorithm to remove objects from image. I used this command:

-input image.png mask.png +inpaint_matchpatch[0] [1],10,15,10,5,1,1 -output[-1] output.png

it works perfectly in a C++ project on mac, but when I used the exactly same command in an iOS project on iPhone, the application crashed on Cimg.h - compile() method.

I have also tried other inpainting commands, such as:

-input image.png mask.png +inpaint[0] [1],15,15,1.0,2,2,0.5,0.01,1,1 output[-1] -output[-1] output.png

this command works in iOS project.

Does it mean that the command “inpaint_matchpatch” is not supported on iOS? What should I do to make the command work on iOS? Thank you!

You may have found a bug.
It could be nice to get a debug log or something equivalent (output of valgrind, or gdb).

Thank you for your reply, David.

I used Xcode as the IDE currently, and I used its default debugger. The position that the application crashes at and the call stack is as follow:

If necessary, I can provide more detail.

At a first glance, it may look like a stack overflow issue.
Maybe the stack size allocated to the program on iOS is not large enough.

We already had this kind of issue on MacOSX actually, and we had to explicitly increase the stack size in this case (see line 10599–10606 of gmic.cpp) :

#if defined(__MACOSX__) || defined(__APPLE__)
            const uint64T stacksize = (uint64T)8*1024*1024;
            pthread_attr_t thread_attr;
            if (!pthread_attr_init(&thread_attr) && !pthread_attr_setstacksize(&thread_attr,stacksize))
              // Reserve enough stack size for the new thread.
              pthread_create(&_gmic_threads[l].thread_id,&thread_attr,gmic_parallel<T>,(void*)&_gmic_threads[l]);

It wouldn’t be surprising that the default stack size allocated for threads/processes on iOS is not large enough as well.
The compile() function is a recursive function that may require quite a lot of stack, so filters that use it often could lead to crashes.

Hi, David,
You are right! I solved the issue by increasing the stack size. I tried to increase the stack size with the code below:

#ifdef gmic_is_parallel
#ifdef _PTHREAD_H

#if defined(__MACOSX__) || defined(__APPLE__)
            const uint64T stacksize = (uint64T)16*1024*1024;
            pthread_attr_t thread_attr;
            if (!pthread_attr_init(&thread_attr) && !pthread_attr_setstacksize(&thread_attr,stacksize))
              // Reserve enough stack size for the new thread.
              pthread_create(&_gmic_threads[l].thread_id,&thread_attr,gmic_parallel<T>,(void*)&_gmic_threads[l]);
            else
#endif // #if defined(__MACOSX__) || defined(__APPLE__)
              pthread_create(&_gmic_threads[l].thread_id,0,gmic_parallel<T>,(void*)&_gmic_threads[l]);

But it seems that the application crashed with this code block not being executed. It means the stack size remains unchanged. I have defined ‘gmic_is_parallel’ before, and I guess the reason may be the ‘_PTHREAD_H’ is not defined, so I try to define ‘_PTHREAD_H’ in Preprocessor Macros manually. I know it should be related with the compiler, but I have no idea how to get it compiled successfully.

Finally, I found another way to increase the stack size, after adding “-Wl,-stack_size,1000000” in Project - Build Settings - Linking - Other Linker Flags, the command ‘inpaint_matchpatch’ works perfectly!

Thank you so much for your valuable tips and the great work, David.

1 Like