00001
00002
00025 #include "utils.h"
00026 #include "hugin_version.h"
00027 #include "hugin_config.h"
00028
00029 #ifdef _WIN32
00030 #define NOMINMAX
00031 #include <sys/utime.h>
00032 #include <shlobj.h>
00033 #else
00034 #include <sys/time.h>
00035 #include <cstdlib>
00036 #include <unistd.h>
00037 #include <sys/types.h>
00038 #include <pwd.h>
00039 #endif
00040 #include <time.h>
00041 #include <fstream>
00042 #include <stdio.h>
00043 #include <cstdio>
00044 #ifdef _WIN32
00045 #define NOMINMAX
00046 #include <windows.h>
00047 #else
00048 #include <hugin_config.h>
00049 #endif
00050 #include <algorithm>
00051 #include <hugin_utils/filesystem.h>
00052 #include <lcms2.h>
00053
00054 #ifdef __APPLE__
00055 #include <mach-o/dyld.h>
00056 #include <limits.h>
00057 #include <libgen.h>
00058 #endif
00059
00060 #include <GL/glew.h>
00061 #ifdef _WIN32
00062 #include <GL/wglew.h>
00063 #elif defined __APPLE__
00064 #include <GLUT/glut.h>
00065 #endif
00066
00067 namespace hugin_utils {
00068
00069 #ifdef UNIX_LIKE
00070 std::string GetCurrentTimeString()
00071 {
00072 char tmp[100];
00073 struct tm t;
00074 struct timeval tv;
00075 gettimeofday(&tv,NULL);
00076 localtime_r((time_t*)&tv.tv_sec, &t);
00077 strftime(tmp,99,"%H:%M:%S",&t);
00078 sprintf(tmp+8,".%06ld", (long)tv.tv_usec);
00079 return tmp;
00080 }
00081 #else
00082 std::string GetCurrentTimeString()
00083 {
00084
00085 return "";
00086 }
00087 #endif
00088
00089
00090 std::string getExtension(const std::string & basename2)
00091 {
00092 std::string::size_type idx = basename2.rfind('.');
00093
00094
00095 if (idx == std::string::npos) {
00096
00097 return std::string("");
00098 }
00099 #ifdef UNIX_LIKE
00100
00101 std::string::size_type slashidx = basename2.find('/', idx);
00102 if ( slashidx == std::string::npos)
00103 {
00104 return basename2.substr(idx+1);
00105 } else {
00106 return std::string("");
00107 }
00108 #else
00109
00110 std::string::size_type slashidx = basename2.find('/', idx);
00111 std::string::size_type backslashidx = basename2.find('\\', idx);
00112 if ( slashidx == std::string::npos && backslashidx == std::string::npos)
00113 {
00114 return basename2.substr(idx+1);
00115 } else {
00116 return std::string("");
00117 }
00118 #endif
00119 }
00120
00121 std::string stripExtension(const std::string & basename2)
00122 {
00123 std::string::size_type idx = basename2.rfind('.');
00124
00125
00126 if (idx == std::string::npos) {
00127
00128 return basename2;
00129 }
00130 #ifdef UNIX_LIKE
00131 std::string::size_type slashidx = basename2.find('/', idx);
00132 if ( slashidx == std::string::npos)
00133 {
00134 return basename2.substr(0, idx);
00135 } else {
00136 return basename2;
00137 }
00138 #else
00139
00140 std::string::size_type slashidx = basename2.find('/', idx);
00141 std::string::size_type backslashidx = basename2.find('\\', idx);
00142 if ( slashidx == std::string::npos && backslashidx == std::string::npos)
00143 {
00144 return basename2.substr(0, idx);
00145 } else {
00146 return basename2;
00147 }
00148 #endif
00149 }
00150
00151 std::string stripPath(const std::string & filename)
00152 {
00153 #ifdef UNIX_LIKE
00154 std::string::size_type idx = filename.rfind('/');
00155 #else
00156 std::string::size_type idx1 = filename.rfind('\\');
00157 std::string::size_type idx2 = filename.rfind('/');
00158 std::string::size_type idx;
00159 if (idx1 == std::string::npos) {
00160 idx = idx2;
00161 } else if (idx2 == std::string::npos) {
00162 idx = idx1;
00163 } else {
00164 idx = std::max(idx1, idx2);
00165 }
00166 #endif
00167 if (idx != std::string::npos) {
00168
00169 return filename.substr(idx + 1);
00170 } else {
00171 return filename;
00172 }
00173 }
00174
00175 std::string getPathPrefix(const std::string & filename)
00176 {
00177 #ifdef UNIX_LIKE
00178 std::string::size_type idx = filename.rfind('/');
00179 #else
00180 std::string::size_type idx1 = filename.rfind('\\');
00181 std::string::size_type idx2 = filename.rfind('/');
00182 std::string::size_type idx;
00183 if (idx1 == std::string::npos) {
00184 idx = idx2;
00185 } else if (idx2 == std::string::npos) {
00186 idx = idx1;
00187 } else {
00188 idx = std::max(idx1, idx2);
00189 }
00190 #endif
00191 if (idx != std::string::npos) {
00192
00193 return filename.substr(0, idx+1);
00194 } else {
00195 return "";
00196 }
00197 }
00198
00199 std::string StrTrim(const std::string& str)
00200 {
00201 std::string s(str);
00202 std::string::size_type pos = s.find_last_not_of(" \t");
00203 if (pos != std::string::npos)
00204 {
00205 s.erase(pos + 1);
00206 pos = s.find_first_not_of(" \t");
00207 if (pos != std::string::npos)
00208 {
00209 s.erase(0, pos);
00210 };
00211 }
00212 else
00213 {
00214 s.erase(s.begin(), s.end());
00215 };
00216 return s;
00217 }
00218
00219 std::string doubleToString(double d, int digits)
00220 {
00221 char fmt[10];
00222 if (digits < 0) {
00223 strcpy(fmt,"%f");
00224 } else {
00225 std::sprintf(fmt,"%%.%df",digits);
00226 }
00227 char c[1024];
00228 c[1023] = 0;
00229 #ifdef _MSC_VER
00230 _snprintf (c, 1023, fmt, d);
00231 #else
00232 snprintf (c, 1023, fmt, d);
00233 #endif
00234
00235 std::string number (c);
00236
00237 int l = (int)number.length()-1;
00238
00239 while ( l != 0 && number[l] == '0' ) {
00240 number.erase (l);
00241 l--;
00242 }
00243 if ( number[l] == ',' ) {
00244 number.erase (l);
00245 l--;
00246 }
00247 if ( number[l] == '.' ) {
00248 number.erase (l);
00249 l--;
00250 }
00251 return number;
00252 }
00253
00254 bool stringToInt(const std::string& s, int& val)
00255 {
00256 if (StrTrim(s) == "0")
00257 {
00258 val = 0;
00259 return true;
00260 };
00261 int x = atoi(s.c_str());
00262 if (x != 0)
00263 {
00264 val = x;
00265 return true;
00266 };
00267 return false;
00268 };
00269
00270 bool stringToUInt(const std::string&s, unsigned int& val)
00271 {
00272 int x;
00273 if (stringToInt(s, x))
00274 {
00275 if (x >= 0)
00276 {
00277 val = static_cast<unsigned int>(x);
00278 return true;
00279 };
00280 };
00281 return false;
00282 };
00283
00284 std::vector<std::string> SplitString(const std::string& s, const std::string& sep)
00285 {
00286 std::vector<std::string> result;
00287 std::size_t pos = s.find_first_of(sep, 0);
00288 std::size_t pos2 = 0;
00289 while (pos != std::string::npos)
00290 {
00291 if (pos - pos2 > 0)
00292 {
00293 std::string t(s.substr(pos2, pos - pos2));
00294 t=StrTrim(t);
00295 if (!t.empty())
00296 {
00297 result.push_back(t);
00298 };
00299 };
00300 pos2 = pos + 1;
00301 pos = s.find_first_of(sep, pos2);
00302 }
00303 if (pos2 < s.length())
00304 {
00305 std::string t(s.substr(pos2));
00306 t = StrTrim(t);
00307 if (!t.empty())
00308 {
00309 result.push_back(t);
00310 };
00311 };
00312 return result;
00313 };
00314
00315 void ReplaceAll(std::string& s, const std::string& oldChar, char newChar)
00316 {
00317 std::size_t found = s.find_first_of(oldChar);
00318 while (found != std::string::npos)
00319 {
00320 s[found] = newChar;
00321 found = s.find_first_of(oldChar, found + 1);
00322 };
00323 };
00324
00325 void ControlPointErrorColour(const double cperr,
00326 double &r,double &g, double &b)
00327 {
00328
00329 #define XP1 5.0f
00330 #define XP2 10.0f
00331
00332 if ( cperr<= XP1)
00333 {
00334
00335 r = cperr / XP1;
00336 g = 0.75;
00337 }
00338 else
00339 {
00340 r = 1.0;
00341 g = 0.75 * ((1.0 - std::min<double>(cperr - XP1, XP2 - XP1) / (XP2 - XP1)));
00342 }
00343 b = 0.0;
00344 }
00345
00346 bool FileExists(const std::string& filename)
00347 {
00348 std::ifstream ifile(filename.c_str());
00349 return !ifile.fail();
00350 }
00351
00352 std::string GetAbsoluteFilename(const std::string& filename)
00353 {
00354 #ifdef _WIN32
00355 char fullpath[_MAX_PATH];
00356 _fullpath(fullpath,filename.c_str(),_MAX_PATH);
00357 return std::string(fullpath);
00358 #else
00359
00360
00361
00363 bool tempFileCreated=false;
00364 if(!FileExists(filename))
00365 {
00366 tempFileCreated=true;
00367 std::ofstream os(filename.c_str());
00368 os.close();
00369 };
00370 char *real_path = realpath(filename.c_str(), NULL);
00371 std::string absPath;
00372 if(real_path!=NULL)
00373 {
00374 absPath=std::string(real_path);
00375 free(real_path);
00376 }
00377 else
00378 {
00379 absPath=filename;
00380 };
00381 if(tempFileCreated)
00382 {
00383 remove(filename.c_str());
00384 };
00385 return absPath;
00386 #endif
00387 };
00388
00389 bool IsFileTypeSupported(const std::string& filename)
00390 {
00391 const std::string extension = getExtension(filename);
00392 return (vigra::impexListExtensions().find(extension) != std::string::npos);
00393 };
00394
00395 void EnforceExtension(std::string& filename, const std::string& defaultExtension)
00396 {
00397 const std::string extension = getExtension(filename);
00398 if (extension.empty())
00399 {
00400 filename = stripExtension(filename) + "." + defaultExtension;
00401 };
00402 };
00403
00404 std::string GetDataDir()
00405 {
00406 #ifdef _WIN32
00407 char buffer[MAX_PATH];
00408 GetModuleFileName(NULL,buffer,sizeof(buffer));
00409 std::string working_path(buffer);
00410 std::string data_path("");
00411
00412 std::string::size_type pos=working_path.rfind("\\");
00413 if(pos!=std::string::npos)
00414 {
00415 working_path.erase(pos);
00416
00417 pos=working_path.rfind("\\");
00418 if(pos!=std::string::npos)
00419 {
00420 working_path.erase(pos);
00421
00422 working_path.append("\\share\\hugin\\data\\");
00423 data_path=working_path;
00424 }
00425 }
00426 #elif defined MAC_SELF_CONTAINED_BUNDLE
00427 char path[PATH_MAX + 1];
00428 uint32_t size = sizeof(path);
00429 std::string data_path("");
00430 if (_NSGetExecutablePath(path, &size) == 0)
00431 {
00432 data_path=dirname(path);
00433 data_path.append("/../Resources/xrc/");
00434 }
00435 #else
00436 std::string data_path = (INSTALL_DATA_DIR);
00437 #endif
00438 return data_path;
00439 };
00440
00441 std::string GetUserAppDataDir()
00442 {
00443 fs::path path;
00444 #ifdef _WIN32
00445 char fullpath[_MAX_PATH];
00446 if(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, fullpath)!=S_OK)
00447 {
00448 return std::string();
00449 };
00450 path = fs::path(fullpath);
00451 path /= "hugin";
00452 #else
00453 char *homedir = getenv("HOME");
00454 struct passwd *pw;
00455 if (homedir == NULL)
00456 {
00457 pw = getpwuid(getuid());
00458 if(pw != NULL)
00459 {
00460 homedir = pw->pw_dir;
00461 };
00462 };
00463 if(homedir == NULL)
00464 {
00465 return std::string();
00466 };
00467 path = fs::path(homedir);
00468
00469
00470 path /= ".hugindata";
00471 #endif
00472 if (!fs::exists(path))
00473 {
00474 if (!fs::create_directories(path))
00475 {
00476 std::cerr << "ERROR: Could not create destination directory: " << path.string() << std::endl
00477 << "Maybe you have not sufficient rights to create this directory." << std::endl;
00478 return std::string();
00479 };
00480 };
00481 return path.string();
00482 };
00483
00484
00485 #ifdef _WIN32
00486 struct ContextSettings
00487 {
00488 HWND window;
00489 HDC dc;
00490 HGLRC renderingContext;
00491
00492 ContextSettings()
00493 {
00494 window = NULL;
00495 dc = NULL;
00496 renderingContext = NULL;
00497 }
00498 };
00499 static ContextSettings context;
00500
00501
00502 bool CreateContext(int *argcp, char **argv)
00503 {
00504 WNDCLASS windowClass;
00505
00506 ZeroMemory(&windowClass, sizeof(WNDCLASS));
00507 windowClass.hInstance = GetModuleHandle(NULL);
00508 windowClass.lpfnWndProc = DefWindowProc;
00509 windowClass.lpszClassName = "Hugin";
00510 if (RegisterClass(&windowClass) == 0)
00511 {
00512 return false;
00513 };
00514
00515 context.window = CreateWindow("Hugin", "Hugin", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
00516 CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL);
00517 if (context.window == NULL)
00518 {
00519 return false;
00520 };
00521
00522 context.dc = GetDC(context.window);
00523 if (context.dc == NULL)
00524 {
00525 return false;
00526 };
00527
00528 PIXELFORMATDESCRIPTOR pixelFormatDesc;
00529 ZeroMemory(&pixelFormatDesc, sizeof(PIXELFORMATDESCRIPTOR));
00530 pixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00531 pixelFormatDesc.nVersion = 1;
00532 pixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
00533 int pixelFormat = ChoosePixelFormat(context.dc, &pixelFormatDesc);
00534 if (pixelFormat == 0)
00535 {
00536 return false;
00537 }
00538
00539 if (SetPixelFormat(context.dc, pixelFormat, &pixelFormatDesc) == FALSE)
00540 {
00541 return false;
00542 };
00543
00544 context.renderingContext = wglCreateContext(context.dc);
00545 if (context.renderingContext == NULL)
00546 {
00547 return false;
00548 };
00549 if (wglMakeCurrent(context.dc, context.renderingContext) == FALSE)
00550 {
00551 return false;
00552 };
00553 return true;
00554 }
00555
00556 void DestroyContext()
00557 {
00558 if (context.renderingContext != NULL)
00559 {
00560 wglMakeCurrent(NULL, NULL);
00561 wglDeleteContext(context.renderingContext);
00562 }
00563 if (context.window != NULL && context.dc != NULL)
00564 {
00565 ReleaseDC(context.window, context.dc);
00566 };
00567 if (context.window != NULL)
00568 {
00569 DestroyWindow(context.window);
00570 };
00571 UnregisterClass("Hugin", GetModuleHandle(NULL));
00572 }
00573
00574 #elif defined __APPLE__
00575 static GLuint GlutWindowHandle;
00576 bool CreateContext(int *argcp, char **argv)
00577 {
00578 glutInit(argcp, argv);
00579 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_ALPHA);
00580 GlutWindowHandle = glutCreateWindow("Hugin");
00581 return true;
00582 }
00583
00584 void DestroyContext()
00585 {
00586 glutDestroyWindow(GlutWindowHandle);
00587 }
00588
00589 #else
00590 #if defined HAVE_EGL && HAVE_EGL
00591 #include <EGL/egl.h>
00592
00593 struct ContextSettings
00594 {
00595 EGLDisplay m_display;
00596 EGLContext m_context;
00597 };
00598
00599 static ContextSettings context;
00600
00601 static const EGLint configAttribs[] = {
00602 EGL_BLUE_SIZE, 8,
00603 EGL_GREEN_SIZE, 8,
00604 EGL_RED_SIZE, 8,
00605 EGL_ALPHA_SIZE, 8,
00606 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
00607 EGL_CONFORMANT, EGL_OPENGL_BIT,
00608 EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
00609 EGL_NONE
00610 };
00611
00612 bool CreateContext(int *argcp, char **argv)
00613 {
00614
00615 context.m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
00616 if (context.m_display == EGL_NO_DISPLAY)
00617 {
00618 std::cerr << "Could not connect to EGL_DEFAULT_DISPLAY" << std::endl;
00619 return false;
00620 };
00621
00622 EGLint major, minor;
00623 if (eglInitialize(context.m_display, &major, &minor) != EGL_TRUE)
00624 {
00625 std::cerr << "Could not initialize EGL" << std::endl
00626 << "Error: 0x" << std::hex << eglGetError() << std::endl;
00627 return false;
00628 };
00629 std::cout << "Init OpenGL ES " << major << "." << minor << std::endl;
00630 std::cout << "Client API: " << eglQueryString(context.m_display, EGL_CLIENT_APIS) << std::endl
00631 << "Vendor: " << eglQueryString(context.m_display, EGL_VENDOR) << std::endl
00632 << "Version: " << eglQueryString(context.m_display, EGL_VERSION) << std::endl
00633 << "EGL Extensions: " << eglQueryString(context.m_display, EGL_EXTENSIONS) << std::endl;
00634
00635 if (!eglBindAPI(EGL_OPENGL_API))
00636 {
00637 std::cerr << "Could not bind OpenGL API" << std::endl
00638 << "Error: 0x" << std::hex << eglGetError() << std::endl;
00639 return false;
00640 };
00641
00642 EGLint numConfigs;
00643 EGLConfig egl_config;
00644 if (eglChooseConfig(context.m_display, configAttribs, &egl_config, 1, &numConfigs) != EGL_TRUE)
00645 {
00646 std::cerr << "Cound not set egl config" << std::endl
00647 << "Error: 0x" << std::hex << eglGetError() << std::endl;
00648 return false;
00649 };
00650
00651
00652 context.m_context = eglCreateContext(context.m_display, egl_config, EGL_NO_CONTEXT, NULL);
00653 if (context.m_context == EGL_NO_CONTEXT)
00654 {
00655 std::cerr << "Cound not create context" << std::endl
00656 << "Error: 0x" << std::hex << eglGetError() << std::endl;
00657 return false;
00658 };
00659 if (eglMakeCurrent(context.m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, context.m_context) != EGL_TRUE)
00660 {
00661 std::cerr << "Could not make current context" << std::endl
00662 << "Error: 0x" << std::hex << eglGetError() << std::endl;
00663 return false;
00664 };
00665 return true;
00666 }
00667
00668 void DestroyContext()
00669 {
00670
00671 eglTerminate(context.m_display);
00672 };
00673
00674 #else
00675 #include <X11/Xlib.h>
00676 #include <X11/Xutil.h>
00677 #include <GL/glx.h>
00678
00679 struct ContextSettings
00680 {
00681 Display* display;
00682 XVisualInfo* visualInfo;
00683 GLXContext context;
00684 Window window;
00685 Colormap colormap;
00686
00687 ContextSettings()
00688 {
00689 display=NULL;
00690 visualInfo=NULL;
00691 context=NULL;
00692 window=0;
00693 colormap=0;
00694 };
00695 };
00696
00697 static ContextSettings context;
00698
00699 bool CreateContext(int *argcp, char **argv)
00700 {
00701
00702 context.display = XOpenDisplay(NULL);
00703 if (context.display == NULL)
00704 {
00705 return false;
00706 };
00707
00708 int erb, evb;
00709 if (!glXQueryExtension(context.display, &erb, &evb))
00710 {
00711 return false;
00712 };
00713
00714 int attrib[] = { GLX_RGBA, None };
00715 context.visualInfo = glXChooseVisual(context.display, DefaultScreen(context.display), attrib);
00716 if (context.visualInfo == NULL)
00717 {
00718 return false;
00719 };
00720
00721 context.context = glXCreateContext(context.display, context.visualInfo, None, True);
00722 if (context.context == NULL)
00723 {
00724 return false;
00725 };
00726
00727 context.colormap = XCreateColormap(context.display, RootWindow(context.display, context.visualInfo->screen), context.visualInfo->visual, AllocNone);
00728 XSetWindowAttributes swa;
00729 swa.border_pixel = 0;
00730 swa.colormap = context.colormap;
00731 context.window = XCreateWindow(context.display, RootWindow(context.display, context.visualInfo->screen),
00732 0, 0, 1, 1, 0, context.visualInfo->depth, InputOutput, context.visualInfo->visual,
00733 CWBorderPixel | CWColormap, &swa);
00734
00735 if (!glXMakeCurrent(context.display, context.window, context.context))
00736 {
00737 return false;
00738 };
00739 return true;
00740 };
00741
00742 void DestroyContext()
00743 {
00744 if (context.display != NULL && context.context != NULL)
00745 {
00746 glXDestroyContext(context.display, context.context);
00747 }
00748 if (context.display != NULL && context.window != 0)
00749 {
00750 XDestroyWindow(context.display, context.window);
00751 };
00752 if (context.display != NULL && context.colormap != 0)
00753 {
00754 XFreeColormap(context.display, context.colormap);
00755 };
00756 if (context.visualInfo != NULL)
00757 {
00758 XFree(context.visualInfo);
00759 };
00760 if (context.display != NULL)
00761 {
00762 XCloseDisplay(context.display);
00763 };
00764 };
00765 #endif
00766 #endif
00767
00768 bool initGPU(int *argcp, char **argv)
00769 {
00770 if (!CreateContext(argcp, argv))
00771 {
00772 return false;
00773 };
00774 int err = glewInit();
00775 if (err != GLEW_OK)
00776 {
00777 std::cerr << argv[0] << ": an error occurred while setting up the GPU:" << std::endl;
00778 std::cerr << glewGetErrorString(err) << std::endl;
00779 std::cerr << argv[0] << ": Switching to CPU calculation." << std::endl;
00780 DestroyContext();
00781 return false;
00782 }
00783
00784 std::cout << hugin_utils::stripPath(argv[0]) << ": using graphics card: " << glGetString(GL_VENDOR) << " " << glGetString(GL_RENDERER) << std::endl;
00785
00786 const GLboolean has_arb_fragment_shader = glewGetExtension("GL_ARB_fragment_shader");
00787 const GLboolean has_arb_vertex_shader = glewGetExtension("GL_ARB_vertex_shader");
00788 const GLboolean has_arb_shader_objects = glewGetExtension("GL_ARB_shader_objects");
00789 const GLboolean has_arb_shading_language = glewGetExtension("GL_ARB_shading_language_100");
00790 const GLboolean has_ext_framebuffer = glewGetExtension("GL_EXT_framebuffer_object");
00791 const GLboolean has_arb_texture_rectangle = glewGetExtension("GL_ARB_texture_rectangle");
00792 const GLboolean has_arb_texture_border_clamp = glewGetExtension("GL_ARB_texture_border_clamp");
00793 const GLboolean has_arb_texture_float = glewGetExtension("GL_ARB_texture_float");
00794
00795 if (!(has_arb_fragment_shader && has_arb_vertex_shader && has_arb_shader_objects && has_arb_shading_language && has_ext_framebuffer && has_arb_texture_rectangle && has_arb_texture_border_clamp && has_arb_texture_float)) {
00796 const char * msg[] = {"false", "true"};
00797 std::cerr << argv[0] << ": extension GL_ARB_fragment_shader = " << msg[has_arb_fragment_shader] << std::endl;
00798 std::cerr << argv[0] << ": extension GL_ARB_vertex_shader = " << msg[has_arb_vertex_shader] << std::endl;
00799 std::cerr << argv[0] << ": extension GL_ARB_shader_objects = " << msg[has_arb_shader_objects] << std::endl;
00800 std::cerr << argv[0] << ": extension GL_ARB_shading_language_100 = " << msg[has_arb_shading_language] << std::endl;
00801 std::cerr << argv[0] << ": extension GL_EXT_framebuffer_object = " << msg[has_ext_framebuffer] << std::endl;
00802 std::cerr << argv[0] << ": extension GL_ARB_texture_rectangle = " << msg[has_arb_texture_rectangle] << std::endl;
00803 std::cerr << argv[0] << ": extension GL_ARB_texture_border_clamp = " << msg[has_arb_texture_border_clamp] << std::endl;
00804 std::cerr << argv[0] << ": extension GL_ARB_texture_float = " << msg[has_arb_texture_float] << std::endl;
00805 std::cerr << argv[0] << ": This graphics system lacks the necessary extensions for -g." << std::endl;
00806 std::cerr << argv[0] << ": Switching to CPU calculation." << std::endl;
00807 DestroyContext();
00808 return false;
00809 }
00810
00811 return true;
00812 }
00813
00814 bool wrapupGPU()
00815 {
00816 DestroyContext();
00817 return true;
00818 }
00819
00820 std::string GetHuginVersion()
00821 {
00822 return std::string(DISPLAY_VERSION);
00823 };
00824
00825 std::string GetICCDesc(const vigra::ImageImportInfo::ICCProfile& iccProfile)
00826 {
00827 if (iccProfile.empty())
00828 {
00829
00830 return std::string();
00831 };
00832 cmsHPROFILE profile = cmsOpenProfileFromMem(iccProfile.data(), iccProfile.size());
00833 if (profile == NULL)
00834 {
00835
00836 return std::string();
00837 };
00838 const std::string name=GetICCDesc(profile);
00839 cmsCloseProfile(profile);
00840 return name;
00841 };
00842
00843 std::string GetICCDesc(const cmsHPROFILE& profile)
00844 {
00845 const size_t size = cmsGetProfileInfoASCII(profile, cmsInfoDescription, cmsNoLanguage, cmsNoCountry, nullptr, 0);
00846 std::string information(size, '\000');
00847 cmsGetProfileInfoASCII(profile, cmsInfoDescription, cmsNoLanguage, cmsNoCountry, &information[0], size);
00848 StrTrim(information);
00849 return information;
00850 }
00851 }