--- CImg-1.2.2.1/examples/greycstoration4gimp.cpp.252 2007-07-11 10:29:24.000000000 +0200 +++ CImg-1.2.2.1/examples/greycstoration4gimp.cpp 2007-07-25 19:18:29.000000000 +0200 @@ -10,13 +10,13 @@ "Fast Anisotropic Smoothing of Multi-Valued Images using Curvature-Preserving PDE's" - (D. Tschumperle) + (D. Tschumperlé) International Journal of Computer Vision, May 2006. (see also http://www.greyc.ensicaen.fr/~dtschump/greycstoration) "Vector-Valued Image Regularization with PDE's : A Common Framework for Different Applications" - (D. Tschumperle, R. Deriche). + (D. Tschumperlé, R. Deriche). IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol 27, No 4, pp 506-517, April 2005. @@ -74,12 +74,15 @@ /* Include the CImg Library, with the GREYCstoration plugin included */ #define cimg_plugin "plugins/greycstoration.h" +#if defined(sun) || defined(__sun) || defined(linux) || defined(__linux) \ + || defined(__linux__) || defined(__CYGWIN__) || defined(BSD) || defined(__FreeBSD__) \ + || defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__) || defined(sgi) \ + || defined(__sgi) +#include <pthread.h> +#endif #define cimg_display_type 0 #include "CImg.h" using namespace cimg_library; -#if cimg_OS!=2 -#include <pthread.h> -#endif /* Uncomment the line below if you want to use preview with zoom (GIMP >= 2.3.4) */ /*#define ZOOMPREVIEW*/ --- CImg-1.2.2.1/examples/greycstoration4integration.cpp.252 2007-07-11 10:29:24.000000000 +0200 +++ CImg-1.2.2.1/examples/greycstoration4integration.cpp 2007-07-25 19:18:29.000000000 +0200 @@ -4,7 +4,7 @@ Description : Example of used of the GREYCstoration_4integration plug-in. - (see http://www.greyc.ensicaen.fr/~dtschump/greycstoration/) + (see http://www.greyc.ensicaen.fr/~dtschump/greycstoration/) THIS VERSION IS FOR DEVELOPERS ONLY. IT SHOWS AN EXAMPLE OF HOW THE INTEGRATION OF THE GREYCSTORATION ALGORITHM CAN BE DONE IN @@ -47,20 +47,16 @@ // Include the CImg Library, with the GREYCstoration plugin included #define cimg_plugin "plugins/greycstoration.h" -#include "../CImg.h" -using namespace cimg_library; #if cimg_OS!=2 #include <pthread.h> #endif +#include "../CImg.h" +using namespace cimg_library; -// The lines below is necessary when using a non-standard compiler as visualcpp6. +// The undef below is necessary when using a non-standard compiler. #ifdef cimg_use_visualcpp6 #define std #endif -#ifdef min -#undef min -#undef max -#endif // Main procedure //---------------- @@ -94,7 +90,7 @@ int main(int argc,char **argv) { // This function will start a thread running one iteration of the GREYCstoration filter. // It returns immediately, so you can do what you want after (update a progress bar for instance). - img.greycstoration_run(amplitude,sharpness,anisotropy,alpha,sigma,1.0f,dl,da,gauss_prec,interp,fast_approx,tile,btile); + img.greycstoration_run(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interp,fast_approx,tile,btile); // Here, we print the overall progress percentage. do { --- CImg-1.2.2.1/examples/greycstoration.cpp.252 2007-07-11 10:29:24.000000000 +0200 +++ CImg-1.2.2.1/examples/greycstoration.cpp 2007-07-25 19:33:33.000000000 +0200 @@ -9,13 +9,13 @@ "Fast Anisotropic Smoothing of Multi-Valued Images using Curvature-Preserving PDE's" - (D. Tschumperle) + (D. Tschumperlé) International Journal of Computer Vision, May 2006. (see also http://www.greyc.ensicaen.fr/~dtschump/greycstoration) "Vector-Valued Image Regularization with PDE's : A Common Framework for Different Applications" - (D. Tschumperle, R. Deriche). + (D. Tschumperlé, R. Deriche). IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol 27, No 4, pp 506-517, April 2005. @@ -50,24 +50,20 @@ ------------------------------------------------------------------------------*/ #define greycstoration_version 2.52 -#ifndef cimg_debug -#define cimg_debug 1 +#if defined(sun) || defined(__sun) || defined(linux) || defined(__linux) \ + || defined(__linux__) || defined(__CYGWIN__) || defined(BSD) || defined(__FreeBSD__) \ + || defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__) || defined(sgi) \ + || defined(__sgi) +#include <pthread.h> #endif +#define cimg_debug 1 #define cimg_plugin "plugins/greycstoration.h" #include "../CImg.h" using namespace cimg_library; -#if cimg_OS!=2 -#include <pthread.h> -#endif - -// The lines below are necessary when using a non-standard compiler as visualcpp6. +// The undef below is necessary when using a non-standard compiler. #ifdef cimg_use_visualcpp6 #define std #endif -#ifdef min -#undef min -#undef max -#endif //----------- // get_geom() : read geometry from a string (for instance '320x256' or '200%x200%'). @@ -154,8 +150,8 @@ template<typename T> void greycstoration (restore && resize) || (inpaint && resize)) { cimg::dialog(cimg::basename(argv[0]), - "You must specify (only) one of the '-restore', '-inpaint', or '-resize' options.\n" - "(try option '-h', '-h -restore','-h -inpaint' or '-h -resize' to get options relative to specific actions\n"); + "You must specify (only) one of the '-restore', '-inpaint', or '-resize' options.\n" + "(try option '-h', '-h -restore','-h -inpaint' or '-h -resize' to get options relative to specific actions\n"); std::exit(0); } @@ -163,7 +159,7 @@ template<typename T> void greycstoration //---------------- CImg<T> img0, img, imgr; CImg<unsigned char> mask; - CImgDisplay disp; + CImgDisplay *disp = 0; // Specific parameters for image denoising //---------------------------------------- @@ -182,7 +178,7 @@ template<typename T> void greycstoration img.load(restore); const CImgStats stats(img,false); std::fprintf(stderr,"\r- Input image : '%s' (size %ux%u, value range [%g,%g])\n", - cimg::basename(restore),img.width,img.height,stats.min,stats.max); + cimg::basename(restore),img.width,img.height,stats.min,stats.max); if (ng>0 || nu>0 || ns>0) { img0 = img; if (ng>0) img.noise(ng,0); @@ -190,7 +186,7 @@ template<typename T> void greycstoration if (ns>0) img.noise(ns,2); const CImgStats stats(img,false); std::fprintf(stderr,"\r- Noisy image : value range [%g,%g], PSNR Noisy / Original : %g\n", - stats.min,stats.max,img.PSNR(img0)); + stats.min,stats.max,img.PSNR(img0)); } } @@ -211,7 +207,7 @@ template<typename T> void greycstoration img.load(inpaint); const CImgStats stats(img,false); std::fprintf(stderr,"\r- Input image : '%s' (size %ux%u, value range [%g,%g])\n", - cimg::basename(inpaint),img.width,img.height,stats.min,stats.max); + cimg::basename(inpaint),img.width,img.height,stats.min,stats.max); if (!file_m) { cimg::dialog(cimg::basename(argv[0]),"You need to specify a valid inpainting mask filename after the '-m' flag."); std::exit(0); @@ -240,18 +236,18 @@ template<typename T> void greycstoration CImg_3x3(M,uchar); CImg_3x3(I,T); while (CImgStats(ntmask,false).max>0) { - cimg_for3x3(tmask,x,y,0,0,M) if (Mcc && (!Mpc || !Mnc || !Mcp || !Mcn)) { - const float + cimg_for3x3(tmask,x,y,0,0,M) if (Mcc && (!Mpc || !Mnc || !Mcp || !Mcn)) { + const float ccp = Mcp?0.0f:1.0f, cpc = Mpc?0.0f:1.0f, - cnc = Mnc?0.0f:1.0f, ccn = Mcn?0.0f:1.0f, + cnc = Mnc?0.0f:1.0f, ccn = Mcn?0.0f:1.0f, csum = ccp + cpc + cnc + ccn; - cimg_forV(img,k) { - cimg_get3x3(img,x,y,0,k,I); - img(x,y,k) = (T)((ccp*Icp + cpc*Ipc + cnc*Inc + ccn*Icn)/csum); - } - ntmask(x,y) = 0; - } - tmask = ntmask; + cimg_forV(img,k) { + cimg_get3x3(img,x,y,0,k,I); + img(x,y,k) = (T)((ccp*Icp + cpc*Ipc + cnc*Inc + ccn*Icn)/csum); + } + ntmask(x,y) = 0; + } + tmask = ntmask; } } break; } @@ -279,7 +275,7 @@ template<typename T> void greycstoration img.load(resize); const CImgStats stats(img,false); std::fprintf(stderr,"\r- Input image : '%s' (size %ux%u, value range [%g,%g])\n", - cimg::basename(resize),img.width,img.height,stats.min,stats.max); + cimg::basename(resize),img.width,img.height,stats.min,stats.max); int w,h; if (geom0) { int w0,h0; @@ -287,7 +283,7 @@ template<typename T> void greycstoration w0 = w0>0?w0:-w0*img.dimx()/100; h0 = h0>0?h0:-h0*img.dimy()/100; std::fprintf(stderr,"- Reducing geometry to %dx%d using %s interpolation.\n",w0,h0, - init==1?"bloc":(init==3?"linear":"bicubic")); + init==1?"bloc":(init==3?"linear":"bicubic")); img0.assign(img); w = img.dimx(); h = img.dimy(); @@ -301,7 +297,7 @@ template<typename T> void greycstoration mask.assign(img.dimx(),img.dimy(),1,1,255); if (!anchor) mask.resize(w,h,1,1,1); else mask = !mask.resize(w,h,1,1,4); img.resize(w,h,1,-100,init); - if (img0) std::fprintf(stderr,"\r- PSNR Original / Thumbnail : %g\n",img.PSNR(img0)); + if (!img0.is_empty()) std::fprintf(stderr,"\r- PSNR Original / Thumbnail : %g\n",img.PSNR(img0)); } // Load reference image if any mentioned @@ -311,8 +307,8 @@ template<typename T> void greycstoration imgr.load(refer); const CImgStats stats(imgr,false); std::fprintf(stderr,"\r- Reference image : '%s' (size %ux%u, value range [%g,%g])", - cimg::basename(refer),imgr.width,imgr.height,stats.min,stats.max); - if (img0) { + cimg::basename(refer),imgr.width,imgr.height,stats.min,stats.max); + if (!img0.is_empty()) { imgr.resize(img0); std::fprintf(stderr,", PSNR Reference / Original : %g dB\n",imgr.PSNR(img0)); } else { @@ -330,8 +326,8 @@ template<typename T> void greycstoration int nwidth=dest.dimx(), nheight=dest.dimy(); if (nwidth>sx) { nheight = nheight*sx/nwidth; nwidth = sx; } if (nheight>sy) { nwidth = nwidth*sy/nheight; nheight = sy; } - disp.assign(img.get_resize(nwidth,nheight),"GREYCstoration"); - dest.display(disp); + disp = new CImgDisplay(img.get_resize(nwidth,nheight),"GREYCstoration"); + dest.display(*disp); } const float gfact = (sizeof(T)==2)?1.0f/256:1.0f; @@ -352,9 +348,9 @@ template<typename T> void greycstoration const unsigned int progress = (unsigned int)dest.greycstoration_progress(); std::fprintf(stderr,"\r- Processing : Iteration %u/%u (%u%%)\t\t",1+iter,nb_iter,progress); if (disp) { - if (disp.is_resized) disp.resize(); - disp.set_title("Processing : Iteration %u/%u (%u%%)",1+iter,nb_iter,progress); - if (disp.is_closed || disp.key==cimg::keyQ || disp.key==cimg::keyESC) { + if (disp->is_resized) disp->resize(); + disp->set_title("Processing : Iteration %u/%u (%u%%)",1+iter,nb_iter,progress); + if (disp->is_closed || disp->key==cimg::keyQ || disp->key==cimg::keyESC) { dest.greycstoration_stop(); stop_iteration = true; iter = nb_iter-1; @@ -367,86 +363,87 @@ template<typename T> void greycstoration // Prepare for next iteration //--------------------------- - if (disp && visu) dest.display(disp); + if (disp && visu) dest.display(*disp); if (file_o && save && !(iter%save)) dest.save(file_o,iter); // Display result and allows user interaction if needed. //------------------------------------------------------- if (iter==nb_iter-1) { std::fprintf(stderr,"\r- Processing : Done ! \n"); - if (img0) std::fprintf(stderr,"- PSNR Restored / Original : %g dB\n",dest.PSNR(img0)); + if (!img0.is_empty()) std::fprintf(stderr,"- PSNR Restored / Original : %g dB\n",dest.PSNR(img0)); if (disp) { - static bool first_time = true; - if (first_time) { - first_time = false; - std::fprintf(stderr, - "- GREYCstoration interface :\n" - " > You can now zoom to a particular rectangular region,\n" + static bool first_time = true; + if (first_time) { + first_time = false; + std::fprintf(stderr, + "- GREYCstoration interface :\n" + " > You can now zoom to a particular rectangular region,\n" " or press one of the following key on the display window :\n" - " SPACE : Swap views.\n" - " S : Save a snapshot of the current image.\n" - " I : Run another iteration.\n" - " Q : Quit GREYCstoration.\n"); - } - - CImgList<T> visu; - visu.insert_shared(img0).insert_shared(img).insert_shared(dest).insert_shared(imgr); - const char *titles[4] = { "original", "noisy", "restored", "reference"}; - unsigned int visupos = 2; - CImgDisplay dispz; - CImg<T> zoom; - int s[6], snb=0; - bool stop_interact = false; - while (!stop_interact) { - disp.show().set_title("GREYCstoration (%s)",titles[visupos]); - visu(visupos).feature_selection(s,2,disp); - if (disp.is_closed) stop_interact = true; - switch (disp.key) { - case cimg::keySPACE: do { visupos = (visupos+1)%visu.size; } while (!visu(visupos)); break; - case cimg::keyBACKSPACE: do { visupos = (visupos-1+visu.size)%visu.size; } while (!visu(visupos)); break; - case cimg::keyQ: stop_interact = stop_all = true; break; - case cimg::keyI: - stop_interact = true; - std::fprintf(stderr,"- Perform iteration %u...\n",++nb_iter); - dest.display(disp); - break; - case cimg::keyS: - if (!snb) { + " SPACE : Swap views.\n" + " S : Save a snapshot of the current image.\n" + " I : Run another iteration.\n" + " Q : Quit GREYCstoration.\n"); + } + + CImgList<T> visu; + visu.insert_shared(img0).insert_shared(img).insert_shared(dest).insert_shared(imgr); + const char *titles[4] = { "original", "noisy", "restored", "reference"}; + unsigned int visupos = 2; + CImgDisplay *dispz = 0; + CImg<T> zoom; + int s[6], snb=0; + bool stop_interact = false; + while (!stop_interact) { + disp->show().set_title("GREYCstoration (%s)",titles[visupos]); + visu(visupos).feature_selection(s,2,*disp); + if (disp->is_closed) stop_interact = true; + switch (disp->key) { + case cimg::keySPACE: do { visupos = (visupos+1)%visu.size; } while (visu(visupos).is_empty()); break; + case cimg::keyBACKSPACE: do { visupos = (visupos-1+visu.size)%visu.size; } while (visu(visupos).is_empty()); break; + case cimg::keyQ: stop_interact = stop_all = true; break; + case cimg::keyI: + stop_interact = true; + std::fprintf(stderr,"- Perform iteration %u...\n",++nb_iter); + dest.display(*disp); + break; + case cimg::keyS: + if (!snb) { if (!append_result) dest.save(file_o?file_o:"GREYCstoration.bmp"); else CImgList<T>(img,dest).get_append('x').save(file_o?file_o:"GREYCstoration.bmp"); } - if (zoom) zoom.save(file_o?file_o:"GREYCstoration.bmp",snb); - std::fprintf(stderr,"- Snapshot %u : '%s' saved\n",snb++,file_o?file_o:"GREYCstoration.bmp"); - break; - } - disp.key = 0; - if (disp.is_resized) disp.resize().display(visu(visupos)); - if (dispz && dispz.is_resized) dispz.resize().display(zoom); - if (dispz && dispz.is_closed) dispz.assign(); - - if (s[0]>=0 && s[1]>=0 && s[3]>=0 && s[4]>=0) { - const int x0 = s[0], y0 = s[1], x1 = s[3], y1 = s[4]; - if (cimg::abs(x0-x1)>4 && cimg::abs(y0-y1)>4) { - CImgList<T> tmp(img.get_crop(x0,y0,x1,y1), dest.get_crop(x0,y0,x1,y1)); - if (img0) tmp.insert(img0.get_crop(x0,y0,x1,y1),0); - if (imgr) tmp.insert(imgr.get_crop(x0,y0,x1,y1)); - zoom = tmp.get_append('x','c'); - if (!dispz) { - const int sx = 5*CImgDisplay::screen_dimx()/6, sy = 5*CImgDisplay::screen_dimy()/6; - int nwidth = zoom.dimx(), nheight = zoom.dimy(); - if (nwidth>nheight) { nheight = nheight*sx/nwidth; nwidth = sx; } - else { nwidth = nwidth*sy/nheight; nheight = sy; } - dispz.assign(zoom.get_resize(nwidth,nheight)); - dispz.set_title("GREYCstoration (zoom) : - %s %s %s %s", - img0?"original -":"", - img?"noisy -":"", - dest?"restored -":"", - imgr?"reference -":""); - } else dispz.resize(dispz.dimx(),dispz.dimx()*zoom.dimy()/zoom.dimx(),false); - dispz.display(zoom).show(); - } - } - } + if (!zoom.is_empty()) zoom.save(file_o?file_o:"GREYCstoration.bmp",snb); + std::fprintf(stderr,"- Snapshot %u : '%s' saved\n",snb++,file_o?file_o:"GREYCstoration.bmp"); + break; + } + disp->key = 0; + if (disp->is_resized) disp->resize().display(visu(visupos)); + if (dispz && dispz->is_resized) dispz->resize().display(zoom); + if (dispz && dispz->is_closed) { delete dispz; dispz = 0; } + + if (s[0]>=0 && s[1]>=0 && s[3]>=0 && s[4]>=0) { + const int x0 = s[0], y0 = s[1], x1 = s[3], y1 = s[4]; + if (cimg::abs(x0-x1)>4 && cimg::abs(y0-y1)>4) { + CImgList<T> tmp(img.get_crop(x0,y0,x1,y1), dest.get_crop(x0,y0,x1,y1)); + if (!img0.is_empty()) tmp.insert(img0.get_crop(x0,y0,x1,y1),0); + if (!imgr.is_empty()) tmp.insert(imgr.get_crop(x0,y0,x1,y1)); + zoom = tmp.get_append('x','c'); + if (!dispz) { + const int sx = 5*CImgDisplay::screen_dimx()/6, sy = 5*CImgDisplay::screen_dimy()/6; + int nwidth = zoom.dimx(), nheight = zoom.dimy(); + if (nwidth>nheight) { nheight = nheight*sx/nwidth; nwidth = sx; } + else { nwidth = nwidth*sy/nheight; nheight = sy; } + dispz = new CImgDisplay(zoom.get_resize(nwidth,nheight)); + dispz->set_title("GREYCstoration (zoom) : - %s %s %s %s", + img0.is_empty()?"":"original -", + img.is_empty()?"":"noisy -", + dest.is_empty()?"":"restored -", + imgr.is_empty()?"":"reference -"); + } else dispz->resize(dispz->dimx(),dispz->dimx()*zoom.dimy()/zoom.dimx(),false); + dispz->display(zoom).show(); + } + } + } + if (dispz) delete dispz; } } } @@ -464,6 +461,7 @@ template<typename T> void greycstoration else CImgList<T>(img,dest).get_append('x').save(file_o); } } + if (disp) delete disp; std::fprintf(stderr,"\n- Quit\n\n"); } --- CImg-1.2.2.1/plugins/greycstoration.h.252 2007-07-11 10:29:23.000000000 +0200 +++ CImg-1.2.2.1/plugins/greycstoration.h 2007-07-25 19:18:29.000000000 +0200 @@ -44,7 +44,7 @@ #ifndef cimg_plugin_greycstoration // This tells you about the version of the GREYCstoration algorithm implemented -#define cimg_plugin_greycstoration 2.51 +#define cimg_plugin_greycstoration 2.5.1 //------------------------------------------------------------------------------ // GREYCstoration structure, storing important informations about algorithm @@ -125,7 +125,7 @@ static void* greycstoration_thread(void for (unsigned int z=0; z<source.depth && !*(p.stop_request); z+=p.tile) for (unsigned int y=0; y<source.height && !*(p.stop_request); y+=p.tile) for (unsigned int x=0; x<source.width && !*(p.stop_request); x+=p.tile) - if (!p.threads || ((ctile++)%p.threads)==p.thread) { + if (((ctile++)%p.threads)==p.thread) { const unsigned int x1 = x+p.tile-1, y1 = y+p.tile-1, @@ -143,7 +143,7 @@ static void* greycstoration_thread(void } else { for (unsigned int y=0; y<source.height && !*(p.stop_request); y+=p.tile) for (unsigned int x=0; x<source.width && !*(p.stop_request); x+=p.tile) - if (!p.threads || ((ctile++)%p.threads)==p.thread) { + if (((ctile++)%p.threads)==p.thread) { const unsigned int x1 = x+p.tile-1, y1 = y+p.tile-1, @@ -183,15 +183,13 @@ static void* greycstoration_thread(void } p.is_running = false; - if (p.threads) { #if cimg_OS==1 - pthread_exit(arg); - return arg; + pthread_exit(arg); + return arg; #elif cimg_OS==2 - ExitThread(0); -#endif - } + ExitThread(0); return 0; +#endif } //---------------------------------------------------------- @@ -250,7 +248,7 @@ static void* greycstoration_thread(void cimg::warn(threads>16,"CImg<%s>::greycstoration_run() : Multi-threading mode limited to 16 threads max."); const unsigned int ntile = (tile && (tile<width || tile<height || (depth>1 && tile<depth)))?tile:0, - nthreads = ntile?cimg::min(threads,16U):cimg::min(threads,1U); + nthreads = ntile?cimg::max(cimg::min(threads,16U),1U):1; CImg<T> *const temporary = ntile?new CImg<T>(*this):0; unsigned long *const counter = new unsigned long; @@ -258,7 +256,7 @@ static void* greycstoration_thread(void bool *const stop_request = new bool; *stop_request = false; - for (unsigned int k=0; k<(nthreads?nthreads:1); k++) { + for (unsigned int k=0; k<nthreads; k++) { greycstoration_params[k].mask = &mask; greycstoration_params[k].amplitude = amplitude; greycstoration_params[k].sharpness = sharpness; @@ -281,26 +279,24 @@ static void* greycstoration_thread(void greycstoration_params[k].is_running = true; greycstoration_params[k].stop_request = stop_request; } - if (nthreads) { // Threaded version #if cimg_OS==1 - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - for (unsigned int k=0; k<greycstoration_params->threads; k++) { - pthread_t thread; - const int err = pthread_create(&thread, &attr, greycstoration_thread, (void*)(greycstoration_params+k)); - if (err) throw CImgException("CImg<%s>::greycstoration_run() : pthread_create returned error %d", - pixel_type(), err); - } + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + for (unsigned int k=0; k<greycstoration_params->threads; k++) { + pthread_t thread; + const int err = pthread_create(&thread, &attr, greycstoration_thread, (void*)(greycstoration_params+k)); + if (err) throw CImgException("CImg<%s>::greycstoration_run() : pthread_create returned error %d", + pixel_type(), err); + } #elif cimg_OS==2 - for (unsigned int k=0; k<greycstoration_params->threads; k++) { - unsigned long ThreadID = 0; - CreateThread(0,0,greycstoration_thread,(void*)(greycstoration_params+k),0,&ThreadID); - } + for (unsigned int k=0; k<greycstoration_params->threads; k++) { + unsigned long ThreadID = 0; + CreateThread(0,0,greycstoration_thread,(void*)(greycstoration_params+k),0,&ThreadID); + } #else - throw CImgInstanceException("CImg<T>::greycstoration_run() : Threads are not supported, please define cimg_OS first."); + throw CImgInstanceException("CImg<T>::greycstoration_run() : Threads are not supported, please define cimg_OS first."); #endif - } else greycstoration_thread((void*)greycstoration_params); // Non-threaded version } return *this; }