AcademySoftwareFoundation / OpenColorIO

A color management framework for visual effects and animation.
https://opencolorio.org
BSD 3-Clause "New" or "Revised" License
1.8k stars 456 forks source link

Add some view helper functions #2049

Open doug-walker opened 2 months ago

doug-walker commented 2 months ago

Here are some utility functions related to views that would be helpful to add to OCIO. The API of the functions below should be altered, as appropriate, when adding them to the Config class. As always, unit tests must be added.

bool displayHasView(const ConstConfigRcPtr & cfg, const char * dispName, const char * viewName)
{
    // This returns null if either the display or view doesn't exist.
    // It works regardless of whether the display or view are active,
    // and it works regardless of whether the view is display-defined
    // or if the display has this as a shared view.
    //
    // It will only check config level shared views if dispName is null.
    // It will not check config level shared views if dispName is not null.
    const char * cs = cfg->getDisplayViewColorSpaceName(dispName, viewName);

    // All views must have a color space, so if it's not empty, the view exists.
    return (cs && *cs);
}
bool hasVirtualView(const ConstConfigRcPtr & cfg, const char * viewName)
{
    const char * cs = cfg->getVirtualDisplayViewColorSpaceName(viewName);

    // All views must have a color space, so if it's not empty, the view exists.
    return (cs && *cs);
}
void clearSharedViews(ConfigRcPtr & cfg)
{
    int numViews = cfg->getNumViews(VIEW_SHARED, nullptr);
    for (int v = numViews - 1; v >= 0; v--)
    {
        const char * sharedViewName = cfg->getView(VIEW_SHARED, nullptr, v);
        if (sharedViewName && *sharedViewName)
        {
            cfg->removeSharedView(sharedViewName);
        }
    }
}
bool viewIsShared(const ConstConfigRcPtr & cfg,
                  const char * dispName,
                  const char * viewName)
{
    // Check if a view within a given display is a display-defined view or is referencing
    // one of the config's shared views.

    for (int v = 0; v < cfg->getNumViews(VIEW_SHARED, dispName); v++)
    {
        const char * sharedViewName = cfg->getView(VIEW_SHARED, dispName, v);
        if (sharedViewName && *sharedViewName && Platform::Strcasecmp(sharedViewName, viewName) == 0)
        {
            return true;
        }
    }

    return false;
}
bool virtualViewIsShared(const ConstConfigRcPtr & cfg,
                         const char * viewName)
{
    for (int v = 0; v < cfg->getVirtualDisplayNumViews(VIEW_SHARED); v++)
    {
        const char * sharedViewName = cfg->getVirtualDisplayView(VIEW_SHARED, v);
        if (sharedViewName && *sharedViewName && Platform::Strcasecmp(sharedViewName, viewName) == 0)
        {
            return true;
        }
    }

    return false;
}
bool viewsAreEqual(const ConstConfigRcPtr & first,
                   const ConstConfigRcPtr & second,
                   const char * dispName,               // may be empty or nullptr for shared views
                   const char * viewName)
{
    // It's ok to call this even for displays/views that don't exist, it will simply return false.

    // Note that this will return true even if the view is display-defined in one config and a reference
    // to a shared view in the other config (both within the same display), as long as the contents match.

    // These calls return null if either the display or view doesn't exist (regardless if it's active).
    const char * cs1 = first->getDisplayViewColorSpaceName(dispName, viewName);
    const char * cs2 = second->getDisplayViewColorSpaceName(dispName, viewName);

    // If the color space is not null, the display and view exist.
    if (cs1 && *cs1 && cs2 && *cs2)
    {
        // Both configs have a display and view by this name, now check the contents.
        if (Platform::Strcasecmp(cs1, cs2) == 0)
        {
            // Note the remaining strings may be empty in a valid view.
            // Intentionally not checking the description since it is not a functional difference.
            if ( (Platform::Strcasecmp(first->getDisplayViewLooks(dispName, viewName),
                                       second->getDisplayViewLooks(dispName, viewName)) == 0) &&
                 (Platform::Strcasecmp(first->getDisplayViewTransformName(dispName, viewName),
                                       second->getDisplayViewTransformName(dispName, viewName)) == 0) &&
                 (Platform::Strcasecmp(first->getDisplayViewRule(dispName, viewName),
                                       second->getDisplayViewRule(dispName, viewName)) == 0) )
            {
                return true;
            }
        }
    }
    return false;
}
bool virtualViewsAreEqual(const ConstConfigRcPtr & first,
                          const ConstConfigRcPtr & second,
                          const char * viewName)
{
    const char * cs1 = first->getVirtualDisplayViewColorSpaceName(viewName);
    const char * cs2 = second->getVirtualDisplayViewColorSpaceName(viewName);

    // If the color space is not null, the display and view exist.
    if (cs1 && *cs1 && cs2 && *cs2)
    {
        if (Platform::Strcasecmp(cs1, cs2) == 0)
        {
            // Note the remaining strings may be empty in a valid view.
            // Intentionally not checking the description since it is not a functional difference.
            if ( (Platform::Strcasecmp(first->getVirtualDisplayViewLooks(viewName),
                                       second->getVirtualDisplayViewLooks(viewName)) == 0) &&
                 (Platform::Strcasecmp(first->getVirtualDisplayViewTransformName(viewName),
                                       second->getVirtualDisplayViewTransformName(viewName)) == 0) &&
                 (Platform::Strcasecmp(first->getVirtualDisplayViewRule(viewName),
                                       second->getVirtualDisplayViewRule(viewName)) == 0) )
            {
                return true;
            }
        }
    }
    return false;
}
annieln commented 1 month ago

Not sure if I can complete this before Dev Days is over, but I'd like to take this on!

carolalynn commented 1 month ago

Thanks @annieln! I'll assign it to you!