diff options
Diffstat (limited to 'intern/opencolorio/ocio_impl.cc')
-rw-r--r-- | intern/opencolorio/ocio_impl.cc | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index 82536a74159..ac167692647 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -55,6 +55,27 @@ using namespace OCIO_NAMESPACE; # define __func__ __FUNCTION__ #endif +/* NOTE: This is because OCIO 1.1.0 has a bug which makes default + * display to be the one which is first alphabetically. + * + * Fix has been submitted as a patch + * https://github.com/imageworks/OpenColorIO/pull/638 + * + * For until then we use first usable display instead. */ +#define DEFAULT_DISPLAY_WORKAROUND +#ifdef DEFAULT_DISPLAY_WORKAROUND +# include <algorithm> +# include <map> +# include <mutex> +# include <vector> +# include <string> +# include <set> +using std::vector; +using std::set; +using std::string; +using std::map; +#endif + static void OCIO_reportError(const char *err) { std::cerr << "OpenColorIO Error: " << err << std::endl; @@ -197,6 +218,31 @@ int OCIOImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const c const char *OCIOImpl::configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) { +#ifdef DEFAULT_DISPLAY_WORKAROUND + if (getenv("OCIO_ACTIVE_DISPLAYS") == NULL) { + const char *active_displays = + (*(ConstConfigRcPtr *) config)->getActiveDisplays(); + if (active_displays[0] != '\0') { + const char *separator_pos = strchr(active_displays, ','); + if (separator_pos == NULL) { + return active_displays; + } + static std::string active_display; + /* NOTE: Configuration is shared and is never changed during + * runtime, so we only guarantee two threads don't initialize at the + * same. */ + static std::mutex mutex; + mutex.lock(); + if (active_display.empty()) { + active_display = active_displays; + active_display[separator_pos - active_displays] = '\0'; + } + mutex.unlock(); + return active_display.c_str(); + } + } +#endif + try { return (*(ConstConfigRcPtr *) config)->getDefaultDisplay(); } @@ -231,8 +277,92 @@ const char *OCIOImpl::configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) return NULL; } +#ifdef DEFAULT_DISPLAY_WORKAROUND +namespace { + +void splitStringEnvStyle(vector<string>* tokens, const string& str) +{ + tokens->clear(); + const int len = str.length(); + int token_start = 0, token_length = 0; + for (int i = 0; i < len; ++i) { + const char ch = str[i]; + if (ch != ',' && ch != ':') { + /* Append non-separator char to a token. */ + ++token_length; + } else { + /* Append current token to the list (if any). */ + if (token_length > 0) { + string token = str.substr(token_start, token_length); + tokens->push_back(token); + } + /* Re-set token pointers. */ + token_start = i + 1; + token_length = 0; + } + } + /* Append token which might be at the end of the string. */ + if (token_length != 0) { + string token = str.substr(token_start, token_length); + tokens->push_back(token); + } +} + +string stringToLower(const string& str) { + string lower = str; + std::transform(lower.begin(), lower.end(), lower.begin(), tolower); + return lower; +} + +} // namespace +#endif + const char *OCIOImpl::configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) { +#ifdef DEFAULT_DISPLAY_WORKAROUND + /* NOTE: We assume that first active view always exists for a default + * display. */ + if (getenv("OCIO_ACTIVE_VIEWS") == NULL) { + ConstConfigRcPtr config_ptr = *((ConstConfigRcPtr *) config); + const char *active_views_encoded = config_ptr->getActiveViews(); + if (active_views_encoded[0] != '\0') { + const string display_lower = stringToLower(display); + static map<string, string> default_display_views; + static std::mutex mutex; + mutex.lock(); + /* Check if the view is already known. */ + map<string, string>::const_iterator it = + default_display_views.find(display_lower); + if (it != default_display_views.end()) { + mutex.unlock(); + return it->second.c_str(); + } + /* Active views. */ + vector<string> active_views; + splitStringEnvStyle(&active_views, active_views_encoded); + /* Get all views supported by tge display. */ + set<string> display_views; + const int num_display_views = config_ptr->getNumViews(display); + for (int view_index = 0; + view_index < num_display_views; + ++view_index) + { + const char *view = config_ptr->getView(display, view_index); + display_views.insert(stringToLower(view)); + } + /* Get first view which is supported by tge display. */ + for (const string& view : active_views) { + const string view_lower = stringToLower(view); + if (display_views.find(view_lower) != display_views.end()) { + default_display_views[display_lower] = view; + mutex.unlock(); + return default_display_views[display_lower].c_str(); + } + } + mutex.unlock(); + } + } +#endif try { return (*(ConstConfigRcPtr *) config)->getDefaultView(display); } @@ -289,6 +419,33 @@ void OCIOImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *r } } +void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rgb[3][3]) +{ + ConstConfigRcPtr config = (*(ConstConfigRcPtr *) config_); + + /* Default to ITU-BT.709 in case no appropriate transform found. */ + memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB)); + + /* Auto estimate from XYZ and scene_linear roles, assumed to be a linear transform. */ + if(config->hasRole("XYZ") && config->hasRole("scene_linear")) { + ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear"); + if(to_rgb_processor) { + xyz_to_rgb[0][0] = 1.0f; + xyz_to_rgb[0][1] = 0.0f; + xyz_to_rgb[0][2] = 0.0f; + xyz_to_rgb[1][0] = 0.0f; + xyz_to_rgb[1][1] = 1.0f; + xyz_to_rgb[1][2] = 0.0f; + xyz_to_rgb[2][0] = 0.0f; + xyz_to_rgb[2][1] = 0.0f; + xyz_to_rgb[2][2] = 1.0f; + to_rgb_processor->applyRGB(xyz_to_rgb[0]); + to_rgb_processor->applyRGB(xyz_to_rgb[1]); + to_rgb_processor->applyRGB(xyz_to_rgb[2]); + } + } +} + int OCIOImpl::configGetNumLooks(OCIO_ConstConfigRcPtr *config) { try { |