From b9999639aab19f25a95852ca4cd59b7878d3dded Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 17 Oct 2010 23:37:36 -0700 Subject: [PATCH] Unified and cleaned up locating icc profiles, including adding missing OS X location. Fixes bug 494932, bug 494940 and bug 551162. --- src/color-profile.cpp | 147 ++++++++++++++++--------- src/color-profile.h | 3 +- src/ui/dialog/document-properties.cpp | 61 ++++------ src/ui/dialog/inkscape-preferences.cpp | 2 +- 4 files changed, 115 insertions(+), 98 deletions(-) diff --git a/src/color-profile.cpp b/src/color-profile.cpp index a8238556c..1352e4e14 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef DEBUG_LCMS #include @@ -630,7 +631,14 @@ Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) } #endif // ENABLE_LCMS -std::list ColorProfile::getProfileDirs() { +std::list ColorProfile::getBaseProfileDirs() { +#if ENABLE_LCMS + static bool warnSet = false; + if (!warnSet) { + cmsErrorAction( LCMS_ERROR_SHOW ); + warnSet = true; + } +#endif // ENABLE_LCMS std::list sources; gchar* base = profile_path("XXX"); @@ -655,17 +663,26 @@ std::list ColorProfile::getProfileDirs() { } // On OS X: - if ( g_file_test("/Library/ColorSync/Profiles", G_FILE_TEST_EXISTS) && g_file_test("/Library/ColorSync/Profiles", G_FILE_TEST_IS_DIR) ) { - sources.push_back("/Library/ColorSync/Profiles"); - - gchar* path = g_build_filename(g_get_home_dir(), "Library", "ColorSync", "Profiles", NULL); - if ( g_file_test(path, G_FILE_TEST_EXISTS) && g_file_test(path, G_FILE_TEST_IS_DIR) ) { - sources.push_back(path); + { + bool onOSX = false; + std::list possible; + possible.push_back("/System/Library/ColorSync/Profiles"); + possible.push_back("/Library/ColorSync/Profiles"); + for ( std::list::const_iterator it = possible.begin(); it != possible.end(); ++it ) { + if ( g_file_test(it->c_str(), G_FILE_TEST_EXISTS) && g_file_test(it->c_str(), G_FILE_TEST_IS_DIR) ) { + sources.push_back(it->c_str()); + onOSX = true; + } + } + if ( onOSX ) { + gchar* path = g_build_filename(g_get_home_dir(), "Library", "ColorSync", "Profiles", NULL); + if ( g_file_test(path, G_FILE_TEST_EXISTS) && g_file_test(path, G_FILE_TEST_IS_DIR) ) { + sources.push_back(path); + } + g_free(path); } - g_free(path); } - #ifdef WIN32 wchar_t pathBuf[MAX_PATH + 1]; pathBuf[0] = 0; @@ -685,10 +702,38 @@ std::list ColorProfile::getProfileDirs() { return sources; } -#if ENABLE_LCMS -static void findThings() { - std::list sources = ColorProfile::getProfileDirs(); +static bool isIccFile( gchar const *filepath ) +{ + bool isIccFile = false; + struct stat st; + if ( g_stat(filepath, &st) == 0 && (st.st_size > 128) ) { + //0-3 == size + //36-39 == 'acsp' 0x61637370 + int fd = g_open( filepath, O_RDONLY, S_IRWXU); + if ( fd != -1 ) { + guchar scratch[40] = {0}; + size_t len = sizeof(scratch); + + //size_t left = 40; + ssize_t got = read(fd, scratch, len); + if ( got != -1 ) { + size_t calcSize = (scratch[0] << 24) | (scratch[1] << 16) | (scratch[2] << 8) | scratch[3]; + if ( calcSize > 128 && calcSize <= static_cast(st.st_size) ) { + isIccFile = (scratch[36] == 'a') && (scratch[37] == 'c') && (scratch[38] == 's') && (scratch[39] == 'p'); + } + } + + close(fd); + } + } + return isIccFile; +} +std::list ColorProfile::getProfileFiles() +{ + std::list files; + + std::list sources = ColorProfile::getBaseProfileDirs(); for ( std::list::const_iterator it = sources.begin(); it != sources.end(); ++it ) { if ( g_file_test( it->c_str(), G_FILE_TEST_EXISTS ) && g_file_test( it->c_str(), G_FILE_TEST_IS_DIR ) ) { GError *err = 0; @@ -697,57 +742,49 @@ static void findThings() { if (dir) { for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { gchar *filepath = g_build_filename(it->c_str(), file, NULL); - - if ( g_file_test( filepath, G_FILE_TEST_IS_DIR ) ) { sources.push_back(g_strdup(filepath)); } else { - bool isIccFile = false; - struct stat st; - if ( g_stat(filepath, &st) == 0 && (st.st_size > 128) ) { - //0-3 == size - //36-39 == 'acsp' 0x61637370 - int fd = g_open( filepath, O_RDONLY, S_IRWXU); - if ( fd != -1 ) { - guchar scratch[40] = {0}; - size_t len = sizeof(scratch); - - //size_t left = 40; - ssize_t got = read(fd, scratch, len); - if ( got != -1 ) { - size_t calcSize = (scratch[0] << 24) | (scratch[1] << 16) | (scratch[2] << 8) | scratch[3]; - if ( calcSize > 128 && calcSize <= static_cast(st.st_size) ) { - isIccFile = (scratch[36] == 'a') && (scratch[37] == 'c') && (scratch[38] == 's') && (scratch[39] == 'p'); - } - } - - close(fd); - } - } - - if ( isIccFile ) { - cmsHPROFILE prof = cmsOpenProfileFromFile( filepath, "r" ); - if ( prof ) { - ProfileInfo info( prof, Glib::filename_to_utf8( filepath ) ); - cmsCloseProfile( prof ); - - bool sameName = false; - for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { - if ( it->getName() == info.getName() ) { - sameName = true; - break; - } - } - - if ( !sameName ) { - knownProfiles.push_back(info); - } - } + if ( isIccFile( filepath ) ) { + files.push_back( filepath ); } } g_free(filepath); } + g_dir_close(dir); + dir = 0; + } else { + gchar *safeDir = Inkscape::IO::sanitizeString(it->c_str()); + g_warning(_("Color profiles directory (%s) is unavailable."), safeDir); + g_free(safeDir); + } + } + } + + return files; +} + +#if ENABLE_LCMS +static void findThings() { + std::list files = ColorProfile::getProfileFiles(); + + for ( std::list::const_iterator it = files.begin(); it != files.end(); ++it ) { + cmsHPROFILE prof = cmsOpenProfileFromFile( it->c_str(), "r" ); + if ( prof ) { + ProfileInfo info( prof, Glib::filename_to_utf8( it->c_str() ) ); + cmsCloseProfile( prof ); + + bool sameName = false; + for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { + if ( it->getName() == info.getName() ) { + sameName = true; + break; + } + } + + if ( !sameName ) { + knownProfiles.push_back(info); } } } diff --git a/src/color-profile.h b/src/color-profile.h index 40d0d7698..fa8f35395 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -33,7 +33,8 @@ struct ColorProfile : public SPObject { static GType getType(); static void classInit( ColorProfileClass *klass ); - static std::list getProfileDirs(); + static std::list getBaseProfileDirs(); + static std::list getProfileFiles(); #if ENABLE_LCMS static cmsHPROFILE getSRGBProfile(); static cmsHPROFILE getNULLProfile(); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index e14779163..0dfac0c7d 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -333,49 +333,28 @@ DocumentProperties::populate_available_profiles(){ delete(*it2); } - std::list sources = ColorProfile::getProfileDirs(); - - // Use this loop to iterate through a list of possible document locations. - for ( std::list::const_iterator it = sources.begin(); it != sources.end(); ++it ) { - if ( Inkscape::IO::file_test( it->c_str(), G_FILE_TEST_EXISTS ) - && Inkscape::IO::file_test( it->c_str(), G_FILE_TEST_IS_DIR )) { - GError *err = 0; - GDir *directory = g_dir_open(it->c_str(), 0, &err); - if (!directory) { - gchar *safeDir = Inkscape::IO::sanitizeString(it->c_str()); - g_warning(_("Color profiles directory (%s) is unavailable."), safeDir); - g_free(safeDir); - } else { - gchar *filename = 0; - while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { - gchar* full = g_build_filename(it->c_str(), filename, NULL); - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - cmsErrorAction( LCMS_ERROR_SHOW ); - cmsHPROFILE hProfile = cmsOpenProfileFromFile(full, "r"); - if (hProfile != NULL){ - const gchar* name; - lcms_profile_get_name(hProfile, &name); - Gtk::MenuItem* mi = manage(new Gtk::MenuItem()); - mi->set_data("filepath", g_strdup(full)); - mi->set_data("name", g_strdup(name)); - Gtk::HBox *hbox = manage(new Gtk::HBox()); - hbox->show(); - Gtk::Label* lbl = manage(new Gtk::Label(name)); - lbl->show(); - hbox->pack_start(*lbl, true, true, 0); - mi->add(*hbox); - mi->show_all(); - _menu.append(*mi); - // g_free((void*)name); - cmsCloseProfile(hProfile); - } - } - g_free(full); - } - g_dir_close(directory); - } + std::list files = ColorProfile::getProfileFiles(); + for ( std::list::const_iterator it = files.begin(); it != files.end(); ++it ) { + cmsHPROFILE hProfile = cmsOpenProfileFromFile(it->c_str(), "r"); + if ( hProfile ){ + const gchar* name = 0; + lcms_profile_get_name(hProfile, &name); + Gtk::MenuItem* mi = manage(new Gtk::MenuItem()); + mi->set_data("filepath", g_strdup(it->c_str())); + mi->set_data("name", g_strdup(name)); + Gtk::HBox *hbox = manage(new Gtk::HBox()); + hbox->show(); + Gtk::Label* lbl = manage(new Gtk::Label(name)); + lbl->show(); + hbox->pack_start(*lbl, true, true, 0); + mi->add(*hbox); + mi->show_all(); + _menu.append(*mi); +// g_free((void*)name); + cmsCloseProfile(hProfile); } } + _menu.show_all(); } diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 13c11a1c1..5e1bf6b5b 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -896,7 +896,7 @@ void InkscapePreferences::initPageCMS() _page_cms.add_group_header( _("Display adjustment")); Glib::ustring tmpStr; - std::list sources = ColorProfile::getProfileDirs(); + std::list sources = ColorProfile::getBaseProfileDirs(); for ( std::list::const_iterator it = sources.begin(); it != sources.end(); ++it ) { gchar* part = g_strdup_printf( "\n%s", it->c_str() ); tmpStr += part; -- 2.30.2