Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4435d33e7 | ||
|
|
73229d885d | ||
|
|
2983316028 | ||
|
|
f74c1b88a9 | ||
|
|
14f13c8b4e | ||
|
|
8fed1b3bc6 | ||
|
|
52faf7449c | ||
|
|
e1b3ffecdd | ||
|
|
a8626f8b45 | ||
|
|
df74525ef9 | ||
|
|
9b619d837a |
+1
-1
@@ -28,7 +28,7 @@ endif()
|
||||
# Project definition.
|
||||
|
||||
project(OpenColorIO
|
||||
VERSION 2.0.2
|
||||
VERSION 2.0.4
|
||||
DESCRIPTION "OpenColorIO (OCIO) is a complete color management solution"
|
||||
HOMEPAGE_URL https://github.com/AcademySoftwareFoundation/OpenColorIO
|
||||
LANGUAGES CXX C)
|
||||
|
||||
@@ -1328,30 +1328,28 @@ extern OCIOEXPORT std::ostream & operator<< (std::ostream &, const FileRules &);
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Move to .rst
|
||||
//
|
||||
// ViewingRules
|
||||
// ************
|
||||
// Viewing Rules allow config authors to filter the list of views an application should offer
|
||||
// based on the color space of an image. For example, a config may define a large number of
|
||||
// views but not all of them may be appropriate for use with all color spaces. E.g., some views
|
||||
// may be intended for use with scene-linear color space encodings and others with video color
|
||||
// space encodings.
|
||||
//
|
||||
// Each rule has a name key for applications to refer to the rule. Name values must be unique
|
||||
// (using case insensitive comparison). Viewing Rules may also have the following keys:
|
||||
//
|
||||
// * colorspaces: Either a single colorspace name or a list of names.
|
||||
//
|
||||
// * encodings: One or more strings to be found in the colorspace's encoding attribute.
|
||||
// Either this attribute or colorspaces must be present, but not both.
|
||||
//
|
||||
// * custom : Allows arbitrary key / value string pairs, similar to FileRules.
|
||||
//
|
||||
// Getters and setters are using the rule position, they will throw if the position is not
|
||||
// valid.
|
||||
|
||||
/**
|
||||
* ViewingRules
|
||||
*
|
||||
* Viewing Rules allow config authors to filter the list of views an application should offer
|
||||
* based on the color space of an image. For example, a config may define a large number of
|
||||
* views but not all of them may be appropriate for use with all color spaces. E.g., some views
|
||||
* may be intended for use with scene-linear color space encodings and others with video color
|
||||
* space encodings.
|
||||
*
|
||||
* Each rule has a name key for applications to refer to the rule. Name values must be unique
|
||||
* (using case insensitive comparison). Viewing Rules may also have the following keys:
|
||||
*
|
||||
* * colorspaces: Either a single colorspace name or a list of names.
|
||||
*
|
||||
* * encodings: One or more strings to be found in the colorspace's encoding attribute.
|
||||
* Either this attribute or colorspaces must be present, but not both.
|
||||
*
|
||||
* * custom : Allows arbitrary key / value string pairs, similar to FileRules.
|
||||
*
|
||||
* Getters and setters are using the rule position, they will throw if the position is not
|
||||
* valid.
|
||||
*/
|
||||
class OCIOEXPORT ViewingRules
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1737,7 +1737,7 @@ void Config::validate() const
|
||||
if (!path || !*path)
|
||||
{
|
||||
errMsg += " The search_path is empty.";
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string resolvedSearchPath = getImpl()->m_context->resolveStringVar(path);
|
||||
@@ -1755,17 +1755,16 @@ void Config::validate() const
|
||||
}
|
||||
|
||||
oss << ".";
|
||||
|
||||
errMsg += oss.str();
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
foundOne = true;
|
||||
}
|
||||
|
||||
// After looping over all the search paths, none of them can be successfully resolved.
|
||||
if (!foundOne)
|
||||
{
|
||||
// No valid paths were found.
|
||||
getImpl()->m_validationtext = errMsg;
|
||||
throw Exception(errMsg.c_str());
|
||||
}
|
||||
|
||||
@@ -838,17 +838,17 @@ void CDLWriter::writeContent() const
|
||||
|
||||
oss.str("");
|
||||
params = m_cdl->getSlopeParams();
|
||||
oss << params[0] << ", " << params[1] << ", " << params[2];
|
||||
oss << params[0] << " " << params[1] << " " << params[2];
|
||||
m_formatter.writeContentTag(TAG_SLOPE, oss.str());
|
||||
|
||||
oss.str("");
|
||||
params = m_cdl->getOffsetParams();
|
||||
oss << params[0] << ", " << params[1] << ", " << params[2];
|
||||
oss << params[0] << " " << params[1] << " " << params[2];
|
||||
m_formatter.writeContentTag(TAG_OFFSET, oss.str());
|
||||
|
||||
oss.str("");
|
||||
params = m_cdl->getPowerParams();
|
||||
oss << params[0] << ", " << params[1] << ", " << params[2];
|
||||
oss << params[0] << " " << params[1] << " " << params[2];
|
||||
m_formatter.writeContentTag(TAG_POWER, oss.str());
|
||||
}
|
||||
m_formatter.writeEndTag(TAG_SOPNODE);
|
||||
|
||||
@@ -192,7 +192,7 @@ void EstimateSlopes(const std::vector<GradingControlPoint> & ctrlPnts, std::vect
|
||||
{
|
||||
size_t j = i;
|
||||
float DL = secantLen[i];
|
||||
while ((j < numCtrlPnts - 2) && (fabs(secantSlope[j + 1] - secantSlope[j]) < 1e-6f))
|
||||
while ((j < numCtrlPnts - 2) && (std::fabs(secantSlope[j + 1] - secantSlope[j]) < 1e-6f))
|
||||
{
|
||||
DL += secantLen[j + 1];
|
||||
j++;
|
||||
@@ -255,7 +255,7 @@ void FitSpline(const std::vector<GradingControlPoint> & ctrlPnts,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fabs(aa) > fabs(bb))
|
||||
if (std::fabs(aa) > std::fabs(bb))
|
||||
{
|
||||
ksi = xi_pl1 + aa * del_x / (slopes[i + 1] - slopes[i]);
|
||||
}
|
||||
@@ -471,7 +471,7 @@ void GradingBSplineCurveImpl::AddShaderEval(GpuShaderText & st,
|
||||
st.newLine() << "{";
|
||||
st.newLine() << " float B = " << coefs << "[coefsOffs + coefsSets];";
|
||||
st.newLine() << " float C = " << coefs << "[coefsOffs + coefsSets * 2];";
|
||||
st.newLine() << " return (x - C) / B + knStart;";
|
||||
st.newLine() << " return abs(B) < 1e-5 ? knStart : (x - C) / B + knStart;";
|
||||
st.newLine() << "}";
|
||||
|
||||
st.newLine() << "else if (x >= knEndY)";
|
||||
@@ -483,7 +483,7 @@ void GradingBSplineCurveImpl::AddShaderEval(GpuShaderText & st,
|
||||
st.newLine() << " float t = knEnd - kn;";
|
||||
st.newLine() << " float slope = 2. * A * t + B;";
|
||||
st.newLine() << " float offs = ( A * t + B ) * t + C;";
|
||||
st.newLine() << " return (x - offs) / slope + knEnd;";
|
||||
st.newLine() << " return abs(slope) < 1e-5 ? knEnd : (x - offs) / slope + knEnd;";
|
||||
st.newLine() << "}";
|
||||
|
||||
// else
|
||||
@@ -580,7 +580,7 @@ float GradingBSplineCurveImpl::KnotsCoefs::evalCurveRev(int c, float y) const
|
||||
{
|
||||
const float B = m_coefsArray[coefsOffs + coefsSets];
|
||||
const float C = m_coefsArray[coefsOffs + coefsSets * 2];
|
||||
return (y - C) / B + knStart;
|
||||
return std::fabs(B) < 1e-5f ? knStart : (y - C) / B + knStart;
|
||||
}
|
||||
else if (y >= knEndY)
|
||||
{
|
||||
@@ -591,7 +591,7 @@ float GradingBSplineCurveImpl::KnotsCoefs::evalCurveRev(int c, float y) const
|
||||
const float t = knEnd - kn;
|
||||
const float slope = 2.f * A * t + B;
|
||||
const float offs = (A * t + B) * t + C;
|
||||
return (y - offs) / slope + knEnd;
|
||||
return std::fabs(slope) < 1e-5f ? knEnd : (y - offs) / slope + knEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -534,7 +534,7 @@ IndexPair IndexPair::GetEdgeFloatValues(float fIn)
|
||||
const float floatTemp = (float) halfVal;
|
||||
|
||||
// Strict comparison required otherwise negative fractions will occur.
|
||||
if (fabs(floatTemp)> fabs(fIn))
|
||||
if (fabs(floatTemp) > fabs(fIn))
|
||||
{
|
||||
idxPair.valB = halfVal.bits();
|
||||
idxPair.valA = idxPair.valB;
|
||||
@@ -551,6 +551,8 @@ IndexPair IndexPair::GetEdgeFloatValues(float fIn)
|
||||
{
|
||||
halfVal = halfVal.isNegative () ? -HALF_MAX : HALF_MAX;
|
||||
idxPair.valB = halfVal.bits();
|
||||
// Necessary to reset fIn too (consider fIn = 65519, it's > HALF_MAX but not Inf).
|
||||
fIn = halfVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -616,6 +616,17 @@ int main(int argc, const char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (useDisplayView)
|
||||
{
|
||||
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
|
||||
outputcolorspace = config->getDisplayViewColorSpaceName(display, view);
|
||||
}
|
||||
|
||||
if (outputcolorspace)
|
||||
{
|
||||
spec.attribute("oiio:ColorSpace", outputcolorspace);
|
||||
}
|
||||
|
||||
f->open(outputimage, spec);
|
||||
|
||||
if(!f->write_image(spec.format, img.getBuffer()))
|
||||
|
||||
@@ -72,6 +72,12 @@ Each item is a tuple containing format name and format extension.
|
||||
"shaperSize"_a = DEFAULT->getShaperSize(),
|
||||
DOC(Baker, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstBakerRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def_static("getFormats", []()
|
||||
{
|
||||
return FormatIterator(nullptr);
|
||||
|
||||
@@ -152,6 +152,12 @@ void bindPyColorSpace(py::module & m)
|
||||
"categories"_a = getCategoriesStdVec(DEFAULT),
|
||||
DOC(ColorSpace, Create, 2))
|
||||
|
||||
.def("__deepcopy__", [](const ConstColorSpaceRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("getName", &ColorSpace::getName,
|
||||
DOC(ColorSpace, getName))
|
||||
.def("setName", &ColorSpace::setName, "name"_a.none(false),
|
||||
|
||||
@@ -40,6 +40,12 @@ void bindPyColorSpaceSet(py::module & m)
|
||||
.def(py::init(&ColorSpaceSet::Create),
|
||||
DOC(ColorSpaceSet, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstColorSpaceSetRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("__eq__", &ColorSpaceSet::operator==, py::is_operator(),
|
||||
DOC(ColorSpaceSet, operator, eq))
|
||||
.def("__ne__", &ColorSpaceSet::operator!=, py::is_operator(),
|
||||
|
||||
@@ -33,7 +33,10 @@ enum ConfigIterator
|
||||
IT_NAMED_TRANSFORM_NAME,
|
||||
IT_NAMED_TRANSFORM,
|
||||
IT_ACTIVE_NAMED_TRANSFORM_NAME,
|
||||
IT_ACTIVE_NAMED_TRANSFORM
|
||||
IT_ACTIVE_NAMED_TRANSFORM,
|
||||
IT_DISPLAY_ALL,
|
||||
IT_DISPLAY_VIEW_TYPE,
|
||||
IT_VIRTUAL_DISPLAY_VIEW,
|
||||
};
|
||||
|
||||
using EnvironmentVarNameIterator = PyIterator<ConfigRcPtr, IT_ENVIRONMENT_VAR_NAME>;
|
||||
@@ -45,16 +48,21 @@ using ColorSpaceNameIterator = PyIterator<ConfigRcPtr,
|
||||
using ColorSpaceIterator = PyIterator<ConfigRcPtr,
|
||||
IT_COLOR_SPACE,
|
||||
SearchReferenceSpaceType,
|
||||
ColorSpaceVisibility>;
|
||||
ColorSpaceVisibility>;
|
||||
using ActiveColorSpaceNameIterator = PyIterator<ConfigRcPtr, IT_ACTIVE_COLOR_SPACE_NAME>;
|
||||
using ActiveColorSpaceIterator = PyIterator<ConfigRcPtr, IT_ACTIVE_COLOR_SPACE>;
|
||||
using RoleNameIterator = PyIterator<ConfigRcPtr, IT_ROLE_NAME>;
|
||||
using RoleColorSpaceIterator = PyIterator<ConfigRcPtr, IT_ROLE_COLOR_SPACE>;
|
||||
using DisplayIterator = PyIterator<ConfigRcPtr, IT_DISPLAY>;
|
||||
using DisplayAllIterator = PyIterator<ConfigRcPtr, IT_DISPLAY_ALL>;
|
||||
using SharedViewIterator = PyIterator<ConfigRcPtr, IT_SHARED_VIEW>;
|
||||
using VirtualViewIterator = PyIterator<ConfigRcPtr, IT_VIRTUAL_DISPLAY_VIEW,
|
||||
ViewType>;
|
||||
using ViewIterator = PyIterator<ConfigRcPtr, IT_DISPLAY_VIEW, std::string>;
|
||||
using ViewForColorSpaceIterator = PyIterator<ConfigRcPtr, IT_DISPLAY_VIEW_COLORSPACE,
|
||||
std::string, std::string>;
|
||||
using ViewForViewTypeIterator = PyIterator<ConfigRcPtr, IT_DISPLAY_VIEW_TYPE,
|
||||
ViewType, std::string>;
|
||||
using LookNameIterator = PyIterator<ConfigRcPtr, IT_LOOK_NAME>;
|
||||
using LookIterator = PyIterator<ConfigRcPtr, IT_LOOK>;
|
||||
using ViewTransformNameIterator = PyIterator<ConfigRcPtr, IT_VIEW_TRANSFORM_NAME>;
|
||||
@@ -110,10 +118,18 @@ void bindPyConfig(py::module & m)
|
||||
py::class_<DisplayIterator>(
|
||||
clsConfig, "DisplayIterator");
|
||||
|
||||
auto clsDisplayAllIterator =
|
||||
py::class_<DisplayAllIterator>(
|
||||
clsConfig, "DisplayAllIterator");
|
||||
|
||||
auto clsSharedViewIterator =
|
||||
py::class_<SharedViewIterator>(
|
||||
clsConfig, "SharedViewIterator");
|
||||
|
||||
auto clsVirtualViewIterator =
|
||||
py::class_<VirtualViewIterator>(
|
||||
clsConfig, "VirtualViewIterator");
|
||||
|
||||
auto clsViewIterator =
|
||||
py::class_<ViewIterator>(
|
||||
clsConfig, "ViewIterator");
|
||||
@@ -122,6 +138,10 @@ void bindPyConfig(py::module & m)
|
||||
py::class_<ViewForColorSpaceIterator>(
|
||||
clsConfig, "ViewForColorSpaceIterator");
|
||||
|
||||
auto clsViewForViewTypeIterator =
|
||||
py::class_<ViewForViewTypeIterator>(
|
||||
clsConfig, "ViewForViewTypeIterator");
|
||||
|
||||
auto clsLookNameIterator =
|
||||
py::class_<LookNameIterator>(
|
||||
clsConfig, "LookNameIterator");
|
||||
@@ -158,6 +178,12 @@ void bindPyConfig(py::module & m)
|
||||
.def(py::init(&Config::Create),
|
||||
DOC(Config, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstConfigRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def_static("CreateRaw", &Config::CreateRaw,
|
||||
DOC(Config, CreateRaw))
|
||||
.def_static("CreateFromEnv", &Config::CreateFromEnv,
|
||||
@@ -342,13 +368,24 @@ void bindPyConfig(py::module & m)
|
||||
{
|
||||
return DisplayIterator(self);
|
||||
})
|
||||
.def("getDefaultView", &Config::getDefaultView, "display"_a,
|
||||
.def("getDisplaysAll", [](ConfigRcPtr & self)
|
||||
{
|
||||
return DisplayAllIterator(self);
|
||||
})
|
||||
.def("getDefaultView",
|
||||
(const char * (Config::*)(const char *) const)
|
||||
&Config::getDefaultView, "display"_a,
|
||||
DOC(Config, getDefaultView))
|
||||
.def("getViews", [](ConfigRcPtr & self, const std::string & display)
|
||||
{
|
||||
return ViewIterator(self, display);
|
||||
},
|
||||
"display"_a)
|
||||
.def("getViews", [](ConfigRcPtr & self, ViewType type, const std::string & display)
|
||||
{
|
||||
return ViewForViewTypeIterator(self, type, display);
|
||||
},
|
||||
"type"_a, "display"_a)
|
||||
.def("getViews", [](ConfigRcPtr & self,
|
||||
const std::string & display,
|
||||
const std::string & colorSpaceName)
|
||||
@@ -394,6 +431,59 @@ void bindPyConfig(py::module & m)
|
||||
DOC(Config, removeDisplayView))
|
||||
.def("clearDisplays", &Config::clearDisplays,
|
||||
DOC(Config, clearDisplays))
|
||||
|
||||
// Virtual Display
|
||||
.def("addVirtualDisplayView", &Config::addVirtualDisplayView,
|
||||
"view"_a, "viewTransformName"_a, "colorSpaceName"_a,
|
||||
"looks"_a = "",
|
||||
"ruleName"_a = "",
|
||||
"description"_a = "",
|
||||
DOC(Config, addVirtualDisplayView))
|
||||
.def("addVirtualDisplaySharedView", &Config::addVirtualDisplaySharedView, "sharedView"_a,
|
||||
DOC(Config, addVirtualDisplaySharedView))
|
||||
.def("getVirtualDisplayViews", [](ConfigRcPtr & self, ViewType type)
|
||||
{
|
||||
return VirtualViewIterator(self, type);
|
||||
},
|
||||
"display"_a)
|
||||
.def("getVirtualDisplayViewTransformName", &Config::getVirtualDisplayViewTransformName,
|
||||
"view"_a,
|
||||
DOC(Config, getVirtualDisplayViewTransformName))
|
||||
.def("getVirtualDisplayViewColorSpaceName", &Config::getVirtualDisplayViewColorSpaceName,
|
||||
"view"_a,
|
||||
DOC(Config, getVirtualDisplayViewColorSpaceName))
|
||||
.def("getVirtualDisplayViewLooks", &Config::getVirtualDisplayViewLooks, "view"_a,
|
||||
DOC(Config, getVirtualDisplayViewLooks))
|
||||
.def("getVirtualDisplayViewRule", &Config::getVirtualDisplayViewRule, "view"_a,
|
||||
DOC(Config, getVirtualDisplayViewRule))
|
||||
.def("getVirtualDisplayViewDescription", &Config::getVirtualDisplayViewDescription,
|
||||
"view"_a,
|
||||
DOC(Config, getVirtualDisplayViewDescription))
|
||||
.def("removeVirtualDisplayView", &Config::removeVirtualDisplayView, "view"_a,
|
||||
DOC(Config, removeVirtualDisplayView))
|
||||
.def("clearVirtualDisplay", &Config::clearVirtualDisplay,
|
||||
DOC(Config, clearVirtualDisplay))
|
||||
.def("instantiateDisplayFromMonitorName", &Config::instantiateDisplayFromMonitorName,
|
||||
"monitorName"_a,
|
||||
DOC(Config, instantiateDisplayFromMonitorName))
|
||||
.def("instantiateDisplayFromICCProfile", &Config::instantiateDisplayFromICCProfile,
|
||||
"ICCProfileFilepath"_a,
|
||||
DOC(Config, instantiateDisplayFromICCProfile))
|
||||
.def("isDisplayTemporary", [](ConfigRcPtr & self, const std::string & display) -> bool
|
||||
{
|
||||
for (int i = 0; i < self->getNumDisplaysAll(); i++)
|
||||
{
|
||||
std::string other(self->getDisplayAll(i));
|
||||
if (StringUtils::Compare(display, other))
|
||||
{
|
||||
return self->isDisplayTemporary(i);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
"display"_a)
|
||||
|
||||
// Active Displays and Views
|
||||
.def("setActiveDisplays", &Config::setActiveDisplays, "displays"_a,
|
||||
DOC(Config, setActiveDisplays))
|
||||
.def("getActiveDisplays", &Config::getActiveDisplays,
|
||||
@@ -844,6 +934,20 @@ void bindPyConfig(py::module & m)
|
||||
return it.m_obj->getDisplay(i);
|
||||
});
|
||||
|
||||
clsDisplayAllIterator
|
||||
.def("__len__", [](DisplayAllIterator & it) { return it.m_obj->getNumDisplaysAll(); })
|
||||
.def("__getitem__", [](DisplayAllIterator & it, int i)
|
||||
{
|
||||
it.checkIndex(i, it.m_obj->getNumDisplaysAll());
|
||||
return it.m_obj->getDisplayAll(i);
|
||||
})
|
||||
.def("__iter__", [](DisplayAllIterator & it) -> DisplayAllIterator & { return it; })
|
||||
.def("__next__", [](DisplayAllIterator & it)
|
||||
{
|
||||
int i = it.nextIndex(it.m_obj->getNumDisplaysAll());
|
||||
return it.m_obj->getDisplayAll(i);
|
||||
});
|
||||
|
||||
clsSharedViewIterator
|
||||
.def("__len__", [](SharedViewIterator & it) { return it.m_obj->getNumViews(VIEW_SHARED,
|
||||
nullptr); })
|
||||
@@ -859,6 +963,23 @@ void bindPyConfig(py::module & m)
|
||||
return it.m_obj->getView(VIEW_SHARED, nullptr, i);
|
||||
});
|
||||
|
||||
clsVirtualViewIterator
|
||||
.def("__len__", [](VirtualViewIterator & it)
|
||||
{
|
||||
return it.m_obj->getVirtualDisplayNumViews(std::get<0>(it.m_args));
|
||||
})
|
||||
.def("__getitem__", [](VirtualViewIterator & it, int i)
|
||||
{
|
||||
it.checkIndex(i, it.m_obj->getVirtualDisplayNumViews(std::get<0>(it.m_args)));
|
||||
return it.m_obj->getVirtualDisplayView(std::get<0>(it.m_args), i);
|
||||
})
|
||||
.def("__iter__", [](VirtualViewIterator & it) -> VirtualViewIterator & { return it; })
|
||||
.def("__next__", [](VirtualViewIterator & it)
|
||||
{
|
||||
int i = it.nextIndex(it.m_obj->getVirtualDisplayNumViews(std::get<0>(it.m_args)));
|
||||
return it.m_obj->getVirtualDisplayView(std::get<0>(it.m_args), i);
|
||||
});
|
||||
|
||||
clsViewIterator
|
||||
.def("__len__", [](ViewIterator & it)
|
||||
{ return it.m_obj->getNumViews(std::get<0>(it.m_args).c_str()); })
|
||||
@@ -885,7 +1006,10 @@ void bindPyConfig(py::module & m)
|
||||
return it.m_obj->getView(std::get<0>(it.m_args).c_str(),
|
||||
std::get<1>(it.m_args).c_str(), i);
|
||||
})
|
||||
.def("__iter__", [](ViewForColorSpaceIterator & it) -> ViewForColorSpaceIterator & { return it; })
|
||||
.def("__iter__", [](ViewForColorSpaceIterator & it) -> ViewForColorSpaceIterator &
|
||||
{
|
||||
return it;
|
||||
})
|
||||
.def("__next__", [](ViewForColorSpaceIterator & it)
|
||||
{
|
||||
int i = it.nextIndex(it.m_obj->getNumViews(std::get<0>(it.m_args).c_str(),
|
||||
@@ -894,6 +1018,29 @@ void bindPyConfig(py::module & m)
|
||||
std::get<1>(it.m_args).c_str(), i);
|
||||
});
|
||||
|
||||
clsViewForViewTypeIterator
|
||||
.def("__len__", [](ViewForViewTypeIterator & it)
|
||||
{ return it.m_obj->getNumViews(std::get<0>(it.m_args),
|
||||
std::get<1>(it.m_args).c_str()); })
|
||||
.def("__getitem__", [](ViewForViewTypeIterator & it, int i)
|
||||
{
|
||||
it.checkIndex(i, it.m_obj->getNumViews(std::get<0>(it.m_args),
|
||||
std::get<1>(it.m_args).c_str()));
|
||||
return it.m_obj->getView(std::get<0>(it.m_args),
|
||||
std::get<1>(it.m_args).c_str(), i);
|
||||
})
|
||||
.def("__iter__", [](ViewForViewTypeIterator & it) -> ViewForViewTypeIterator &
|
||||
{
|
||||
return it;
|
||||
})
|
||||
.def("__next__", [](ViewForViewTypeIterator & it)
|
||||
{
|
||||
int i = it.nextIndex(it.m_obj->getNumViews(std::get<0>(it.m_args),
|
||||
std::get<1>(it.m_args).c_str()));
|
||||
return it.m_obj->getView(std::get<0>(it.m_args),
|
||||
std::get<1>(it.m_args).c_str(), i);
|
||||
});
|
||||
|
||||
clsLookNameIterator
|
||||
.def("__len__", [](LookNameIterator & it) { return it.m_obj->getNumLooks(); })
|
||||
.def("__getitem__", [](LookNameIterator & it, int i)
|
||||
|
||||
@@ -99,7 +99,13 @@ void bindPyContext(py::module & m)
|
||||
"searchPaths"_a = getSearchPathsStdVec(DEFAULT),
|
||||
"stringVars"_a = getStringVarsStdMap(DEFAULT),
|
||||
"environmentMode"_a = DEFAULT->getEnvironmentMode(),
|
||||
DOC(Context, Create))
|
||||
DOC(Context, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstContextRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("__iter__", [](ContextRcPtr & self)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,12 @@ void bindPyFileRules(py::module & m)
|
||||
.def(py::init(&FileRules::Create),
|
||||
DOC(FileRules, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstFileRulesRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("getNumEntries", &FileRules::getNumEntries,
|
||||
DOC(FileRules, getNumEntries))
|
||||
.def("getIndexForRule", &FileRules::getIndexForRule, "ruleName"_a,
|
||||
|
||||
@@ -38,6 +38,12 @@ void bindPyLook(py::module & m)
|
||||
"description"_a = DEFAULT->getDescription(),
|
||||
DOC(Look, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstLookRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("getName", &Look::getName,
|
||||
DOC(Look, getName))
|
||||
.def("setName", &Look::setName, "name"_a.none(false),
|
||||
|
||||
@@ -118,6 +118,12 @@ void bindPyNamedTransform(py::module & m)
|
||||
"categories"_a = getCategoriesStdVec(DEFAULT),
|
||||
DOC(NamedTransform, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstNamedTransformRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("getName", &NamedTransform::getName,
|
||||
DOC(NamedTransform, getName))
|
||||
.def("setName", &NamedTransform::setName, "name"_a.none(false),
|
||||
@@ -145,7 +151,7 @@ void bindPyNamedTransform(py::module & m)
|
||||
DOC(NamedTransform, setDescription))
|
||||
.def("getEncoding", &NamedTransform::getEncoding,
|
||||
DOC(NamedTransform, getEncoding))
|
||||
.def("setEncoding", &NamedTransform::setEncoding, "encodig"_a.none(false),
|
||||
.def("setEncoding", &NamedTransform::setEncoding, "encoding"_a.none(false),
|
||||
DOC(NamedTransform, setEncoding))
|
||||
|
||||
// Transform
|
||||
|
||||
@@ -13,6 +13,12 @@ void bindPyTransform(py::module & m)
|
||||
py::class_<Transform, TransformRcPtr>(
|
||||
m.attr("Transform"))
|
||||
|
||||
.def("__deepcopy__", [](const ConstTransformRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("validate", &Transform::validate,
|
||||
DOC(Transform, validate))
|
||||
.def("getTransformType", &Transform::getTransformType,
|
||||
|
||||
@@ -85,7 +85,13 @@ void bindPyViewTransform(py::module & m)
|
||||
"toReference"_a = DEFAULT->getTransform(VIEWTRANSFORM_DIR_TO_REFERENCE),
|
||||
"fromReference"_a = DEFAULT->getTransform(VIEWTRANSFORM_DIR_FROM_REFERENCE),
|
||||
"categories"_a = getCategoriesStdVec(DEFAULT),
|
||||
DOC(ViewTransform, Create))
|
||||
DOC(ViewTransform, Create))
|
||||
|
||||
.def("__deepcopy__", [](const ConstViewTransformRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("getName", &ViewTransform::getName,
|
||||
DOC(ViewTransform, getName))
|
||||
|
||||
@@ -33,7 +33,13 @@ void bindPyViewingRules(py::module & m)
|
||||
clsViewingRules
|
||||
.def(py::init(&ViewingRules::Create),
|
||||
DOC(ViewingRules, Create))
|
||||
|
||||
|
||||
.def("__deepcopy__", [](const ConstViewingRulesRcPtr & self, py::dict)
|
||||
{
|
||||
return self->createEditableCopy();
|
||||
},
|
||||
"memo"_a)
|
||||
|
||||
.def("getNumEntries", &ViewingRules::getNumEntries,
|
||||
DOC(ViewingRules, getNumEntries))
|
||||
.def("getIndexForRule", &ViewingRules::getIndexForRule, "ruleName"_a,
|
||||
|
||||
+161
-4
@@ -1433,9 +1433,97 @@ OCIO_ADD_TEST(Config, context_variable_with_display_view)
|
||||
}
|
||||
}
|
||||
|
||||
OCIO_ADD_TEST(Config, context_variable_with_search_path)
|
||||
OCIO_ADD_TEST(Config, context_variable_with_search_path_v1)
|
||||
{
|
||||
// Test a search_path pointing to a context variable.
|
||||
// Test a search_path containing a context variable for a v1 config file.
|
||||
|
||||
// Note: The config validation does not check the path existence, it checks only if the path can
|
||||
// be successfully resolved. But the processor creation needs to have at least one existing path.
|
||||
// That's why the tests below check for the config validation and the processor creation.
|
||||
|
||||
static const std::string CONFIG =
|
||||
"ocio_profile_version: 1\n"
|
||||
"\n"
|
||||
"search_path: $ENV1\n"
|
||||
"\n"
|
||||
"roles:\n"
|
||||
" default: cs1\n"
|
||||
" reference: cs1\n"
|
||||
"\n"
|
||||
"displays:\n"
|
||||
" disp1:\n"
|
||||
" - !<View> {name: view1, colorspace: cs2}\n"
|
||||
"\n"
|
||||
"colorspaces:\n"
|
||||
" - !<ColorSpace>\n"
|
||||
" name: cs1\n"
|
||||
"\n"
|
||||
" - !<ColorSpace>\n"
|
||||
" name: cs2\n"
|
||||
" from_reference: !<FileTransform> {src: lut1d_green.ctf}\n";
|
||||
|
||||
std::istringstream iss;
|
||||
iss.str(CONFIG);
|
||||
|
||||
// $ENV1 is missing.
|
||||
OCIO::ConfigRcPtr cfg;
|
||||
OCIO_CHECK_NO_THROW(cfg = OCIO::Config::CreateFromStream(iss)->createEditableCopy());
|
||||
OCIO_CHECK_THROW_WHAT(cfg->validate(), OCIO::Exception,
|
||||
"The search_path '$ENV1' cannot be resolved.");
|
||||
#ifdef _WIN32
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: '$ENV1\\lut1d_green.ctf'.");
|
||||
#else
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: '$ENV1/lut1d_green.ctf'.");
|
||||
#endif
|
||||
|
||||
// $ENV1 now exists.
|
||||
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", OCIO::GetTestFilesDir().c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
|
||||
// $ENV1 is faulty.
|
||||
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", "faulty/path"));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate()); // Success because there is at least one resolved path.
|
||||
#ifdef _WIN32
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: 'faulty\\path\\lut1d_green.ctf'.");
|
||||
#else
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: 'faulty/path/lut1d_green.ctf'.");
|
||||
#endif
|
||||
|
||||
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", nullptr));
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one successful path i.e. the first one.
|
||||
const std::string searchPath = OCIO::GetTestFilesDir() + ":$ENV1";
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
}
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one successful path i.e. the second one.
|
||||
const std::string searchPath = "$ENV1:" + OCIO::GetTestFilesDir();
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
}
|
||||
}
|
||||
|
||||
OCIO_ADD_TEST(Config, context_variable_with_search_path_v2)
|
||||
{
|
||||
// Test a search_path containing a context variable for a v2 config file.
|
||||
|
||||
// Note: The config validation does not check the path existence, it checks only if the path can
|
||||
// be successfully resolved. But the processor creation needs to have at least one existing path.
|
||||
// That's why the tests below check for the config validation and the processor creation.
|
||||
|
||||
static const std::string CONFIG =
|
||||
"ocio_profile_version: 2\n"
|
||||
@@ -1463,19 +1551,88 @@ OCIO_ADD_TEST(Config, context_variable_with_search_path)
|
||||
std::istringstream iss;
|
||||
iss.str(CONFIG);
|
||||
|
||||
// $ENV1 exists in the config itself.
|
||||
OCIO::ConfigRcPtr cfg;
|
||||
OCIO_CHECK_NO_THROW(cfg = OCIO::Config::CreateFromStream(iss)->createEditableCopy());
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
|
||||
/// Remove the context variable.
|
||||
/// Remove the context variable so, there is no more successful path.
|
||||
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", nullptr));
|
||||
|
||||
OCIO_CHECK_THROW_WHAT(cfg->validate(), OCIO::Exception,
|
||||
"The search_path '$ENV1' cannot be resolved.");
|
||||
|
||||
#ifdef _WIN32
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. ");
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: '$ENV1\\lut1d_green.ctf'.");
|
||||
#else
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: '$ENV1/lut1d_green.ctf'.");
|
||||
#endif
|
||||
|
||||
// The following tests validate that in a list of search paths at least one can be resolved.
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one successful path i.e. the first one.
|
||||
const std::string searchPath = OCIO::GetTestFilesDir() + ":$ENV1";
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
}
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one successful path i.e. the second one.
|
||||
const std::string searchPath = "$ENV1:" + OCIO::GetTestFilesDir();
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
}
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one successful path i.e. the first one.
|
||||
const std::string searchPath = OCIO::GetTestFilesDir() + ":";
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
}
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one successful path i.e. the second one.
|
||||
const std::string searchPath = ":" + OCIO::GetTestFilesDir();
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
|
||||
}
|
||||
|
||||
// The following test highlights the difference between the validation and the processor
|
||||
// creation related to the search paths i.e. resolved vs. existing search paths.
|
||||
|
||||
{
|
||||
// Change the search_path to have at least one potentially successful path
|
||||
// i.e. the second one.
|
||||
const std::string searchPath = "$ENV1:faulty/path";
|
||||
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
|
||||
|
||||
// The validation succeeds because the first path does not resolve but the second path does.
|
||||
OCIO_CHECK_NO_THROW(cfg->validate());
|
||||
|
||||
// The first path does not resolve and the second path does resolve but it does not exist
|
||||
// so the processor creation fails.
|
||||
#ifdef _WIN32
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: "
|
||||
"'$ENV1\\lut1d_green.ctf' : 'faulty\\path\\lut1d_green.ctf'.");
|
||||
#else
|
||||
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
|
||||
"The specified file reference 'lut1d_green.ctf' could not be located. "
|
||||
"The following attempts were made: "
|
||||
"'$ENV1/lut1d_green.ctf' : 'faulty/path/lut1d_green.ctf'.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
OCIO_ADD_TEST(Config, role_without_colorspace)
|
||||
|
||||
@@ -5725,9 +5725,9 @@ OCIO_ADD_TEST(CTFTransform, cdl_clf)
|
||||
<SOPNode>
|
||||
<Description>SOP description 1</Description>
|
||||
<Description>SOP description 2</Description>
|
||||
<Slope>1, 1.1, 1.2</Slope>
|
||||
<Offset>0.2, 0.3, 0.4</Offset>
|
||||
<Power>3.1, 3.2, 3.3</Power>
|
||||
<Slope>1 1.1 1.2</Slope>
|
||||
<Offset>0.2 0.3 0.4</Offset>
|
||||
<Power>3.1 3.2 3.3</Power>
|
||||
</SOPNode>
|
||||
<SatNode>
|
||||
<Description>Sat description 1</Description>
|
||||
@@ -5740,6 +5740,24 @@ OCIO_ADD_TEST(CTFTransform, cdl_clf)
|
||||
|
||||
OCIO_CHECK_EQUAL(expected.size(), outputTransform.str().size());
|
||||
OCIO_CHECK_EQUAL(expected, outputTransform.str());
|
||||
|
||||
// Now test if the read is working.
|
||||
|
||||
std::istringstream ctfStream;
|
||||
ctfStream.str(expected);
|
||||
|
||||
std::string emptyString;
|
||||
OCIO::LocalFileFormat tester;
|
||||
OCIO::CachedFileRcPtr file = tester.read(ctfStream, emptyString, OCIO::INTERP_DEFAULT);
|
||||
auto cachedFile = OCIO::DynamicPtrCast<OCIO::LocalCachedFile>(file);
|
||||
|
||||
const OCIO::ConstOpDataVec & opList = cachedFile->m_transform->getOps();
|
||||
OCIO_REQUIRE_EQUAL(opList.size(), 1);
|
||||
auto cdlData = std::dynamic_pointer_cast<const OCIO::CDLOpData>(opList[0]);
|
||||
OCIO_REQUIRE_ASSERT(cdlData);
|
||||
OCIO_CHECK_EQUAL(cdlData->getSlopeParams()[0], 1.);
|
||||
OCIO_CHECK_EQUAL(cdlData->getSlopeParams()[1], 1.1);
|
||||
OCIO_CHECK_EQUAL(cdlData->getSlopeParams()[2], 1.2);
|
||||
}
|
||||
|
||||
OCIO_ADD_TEST(CTFTransform, cdl_ctf)
|
||||
@@ -5768,9 +5786,9 @@ OCIO_ADD_TEST(CTFTransform, cdl_ctf)
|
||||
"<ProcessList version=\"1.7\" id=\"cdl2\">\n"
|
||||
" <ASC_CDL inBitDepth=\"32f\" outBitDepth=\"32f\" style=\"Fwd\">\n"
|
||||
" <SOPNode>\n"
|
||||
" <Slope>1, 1.1, 1.2</Slope>\n"
|
||||
" <Offset>0.2, 0.3, 0.4</Offset>\n"
|
||||
" <Power>3.1, 3.2, 3.3</Power>\n"
|
||||
" <Slope>1 1.1 1.2</Slope>\n"
|
||||
" <Offset>0.2 0.3 0.4</Offset>\n"
|
||||
" <Power>3.1 3.2 3.3</Power>\n"
|
||||
" </SOPNode>\n"
|
||||
" <SatNode>\n"
|
||||
" <Saturation>2.1</Saturation>\n"
|
||||
|
||||
@@ -176,14 +176,14 @@ OCIO_ADD_TEST(GradingRGBCurveOpCPU, log)
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
|
||||
const long num_samples = 2;
|
||||
constexpr long num_samples = 2;
|
||||
float res[4 * num_samples]{ 0.f };
|
||||
|
||||
const float input_32f[] = {
|
||||
constexpr float input_32f[] = {
|
||||
-0.2f, 0.2f, 0.5f, 0.0f,
|
||||
0.8f, 1.0f, 2.0f, 0.5f };
|
||||
|
||||
const float expected_32f[] = {
|
||||
constexpr float expected_32f[] = {
|
||||
0.25306581f, 0.35779659f, 0.98416632f, 0.0f,
|
||||
1.09451043f, 1.54596428f, 1.78067802f, 0.5f };
|
||||
|
||||
@@ -219,14 +219,14 @@ OCIO_ADD_TEST(GradingRGBCurveOpCPU, log_partial_identity)
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
|
||||
const long num_samples = 2;
|
||||
constexpr long num_samples = 2;
|
||||
float res[4 * num_samples]{ 0.f };
|
||||
|
||||
float input_32f[] = {
|
||||
-0.2f, 0.2f, 0.5f, 0.0f,
|
||||
0.8f, 1.0f, 2.0f, 0.5f };
|
||||
|
||||
const float expected_32f[] = {
|
||||
constexpr float expected_32f[] = {
|
||||
-0.2f, 0.15779659f, 0.5f, 0.0f,
|
||||
0.8f, 1.34596419f, 2.0f, 0.5f };
|
||||
|
||||
@@ -264,14 +264,14 @@ OCIO_ADD_TEST(GradingRGBCurveOpCPU, monotonic)
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
|
||||
const long num_samples = 2;
|
||||
constexpr long num_samples = 2;
|
||||
float res[4 * num_samples]{ 0.f };
|
||||
|
||||
float input_32f[] = {
|
||||
0.8f, 0.2f, 0.5f, 0.0f,
|
||||
0.9f, 1.0f, 2.0f, 0.5f };
|
||||
|
||||
const float expected_32f[] = {
|
||||
constexpr float expected_32f[] = {
|
||||
0.52230538f, 0.2f, 0.5f, 0.0f,
|
||||
0.68079938f, 1.0f, 2.0f, 0.5f };
|
||||
|
||||
@@ -311,14 +311,14 @@ OCIO_ADD_TEST(GradingRGBCurveOpCPU, lin_bypass)
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
|
||||
const long num_samples = 2;
|
||||
constexpr long num_samples = 2;
|
||||
float res[4 * num_samples]{ 0.f };
|
||||
|
||||
float input_32f[] = {
|
||||
-8.f, -3.f, -1.f, 0.0f,
|
||||
1.f, 2.5f, 4.0f, 0.5f };
|
||||
|
||||
const float expected_32f[] = {
|
||||
constexpr float expected_32f[] = {
|
||||
-8.50508935f, -6.37181915f, -3.01264257f, 0.0f,
|
||||
1.95205522f, 4.76796850f, 5.76796850f, 0.5f };
|
||||
|
||||
@@ -357,14 +357,14 @@ OCIO_ADD_TEST(GradingRGBCurveOpCPU, lin)
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
|
||||
const long num_samples = 2;
|
||||
constexpr long num_samples = 2;
|
||||
float res[4 * num_samples]{ 0.f };
|
||||
|
||||
float input_32f[] = {
|
||||
-0.003f, 0.02f, 0.09f, 0.0f,
|
||||
0.360f, 1.00f, 3.00f, 0.5f };
|
||||
|
||||
const float expected_32f[] = {
|
||||
constexpr float expected_32f[] = {
|
||||
-4.20784139e-03f, 1.26825221e-03f, 2.23983977e-02f, 0.0f,
|
||||
6.96706128e-01f, 4.79411018e+00f, 9.95152432e+00f, 0.5f };
|
||||
|
||||
@@ -410,14 +410,33 @@ OCIO_ADD_TEST(GradingRGBCurveOpCPU, slopes)
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
|
||||
const long num_samples = 1;
|
||||
constexpr long num_samples = 2;
|
||||
float input_32f[] = {
|
||||
-3.f, -1.f, 1.f, 0.5f };
|
||||
-3.f, -1.f, 1.f, 0.5f,
|
||||
-7.f, 0.f, 7.f, 1.0f };
|
||||
|
||||
// Test that the slopes were used (the values are significantly different without slopes).
|
||||
const float expected_32f[] = {
|
||||
-2.92582282f, 0.28069129f, 2.81987724f, 0.5f };
|
||||
constexpr float expected_32f[] = {
|
||||
-2.92582282f, 0.28069129f, 2.81987724f, 0.5f,
|
||||
-4.0f, 1.73250193f, 4.0f, 1.0f };
|
||||
|
||||
OCIO_CHECK_NO_THROW(op->apply(input_32f, input_32f, num_samples));
|
||||
ValidateImage(expected_32f, input_32f, num_samples, __LINE__);
|
||||
|
||||
// Test in inverse direction.
|
||||
|
||||
float rev_input_32f[] = {
|
||||
-2.92582282f, 0.28069129f, 2.81987724f, 0.5f,
|
||||
-7.0f, 1.73250193f, 7.0f, 1.0f };
|
||||
|
||||
constexpr float rev_expected_32f[] = {
|
||||
-3.f, -1.f, 1.f, 0.5f,
|
||||
-5.26017743f, 0.f, 4.67381243f, 1.0f };
|
||||
|
||||
gc->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
|
||||
|
||||
OCIO_CHECK_NO_THROW(op = OCIO::GetGradingRGBCurveCPURenderer(gcc));
|
||||
OCIO_CHECK_ASSERT(op);
|
||||
OCIO_CHECK_NO_THROW(op->apply(rev_input_32f, rev_input_32f, num_samples));
|
||||
ValidateImage(rev_expected_32f, rev_input_32f, num_samples, __LINE__);
|
||||
}
|
||||
|
||||
@@ -1238,6 +1238,46 @@ OCIO_ADD_TEST(Lut1DRenderer, lut_1d_special_values)
|
||||
OCIO_CHECK_EQUAL(outImage[7], 1.0f);
|
||||
}
|
||||
|
||||
OCIO_ADD_TEST(Lut1DRenderer, lut_1d_hd_above_half_max)
|
||||
{
|
||||
// Test the processing of half-domain Lut1D for float input values that are greater than
|
||||
// HALF_MAX but round down to HALF_MAX. These are the values 65504 < x < 65520.
|
||||
// In other words, half(65519) rounds down to 65504 and half(65520) rounds up to Inf.
|
||||
// There was a bug where these values were not processed correctly.
|
||||
|
||||
OCIO::ConfigRcPtr config = OCIO::Config::Create();
|
||||
|
||||
const std::string ctfLUT("lut1d_hd_16f_16i_1chan.ctf");
|
||||
OCIO::FileTransformRcPtr fileTransform = OCIO::CreateFileTransform(ctfLUT);
|
||||
|
||||
OCIO::ConstProcessorRcPtr proc;
|
||||
OCIO_CHECK_NO_THROW(proc = config->getProcessor(fileTransform));
|
||||
|
||||
OCIO::ConstCPUProcessorRcPtr cpuFwd;
|
||||
OCIO_CHECK_NO_THROW(cpuFwd = proc->getDefaultCPUProcessor());
|
||||
|
||||
float inImage[] = {
|
||||
65505.0f, 65519.0f, 65520.0f, 0.0f,
|
||||
-65505.0f, -65519.0f, -65520.0f, 1.0f
|
||||
};
|
||||
|
||||
std::vector<float> outImage(2 * 4, -12.345f);
|
||||
OCIO::PackedImageDesc srcImgDesc((void*)&inImage[0], 2, 1, 4);
|
||||
OCIO::PackedImageDesc dstImgDesc((void*)&outImage[0], 2, 1, 4);
|
||||
cpuFwd->apply(srcImgDesc, dstImgDesc);
|
||||
|
||||
static const float rtol = 1e-5f;
|
||||
OCIO_CHECK_CLOSE(outImage[0], 0.7785763f, rtol);
|
||||
OCIO_CHECK_CLOSE(outImage[1], 0.7785763f, rtol);
|
||||
OCIO_CHECK_CLOSE(outImage[2], 0.7785763f, rtol);
|
||||
OCIO_CHECK_EQUAL(outImage[3], 0.0f);
|
||||
|
||||
OCIO_CHECK_CLOSE(outImage[4], 0.f, rtol);
|
||||
OCIO_CHECK_CLOSE(outImage[5], 0.f, rtol);
|
||||
OCIO_CHECK_CLOSE(outImage[6], 0.f, rtol);
|
||||
OCIO_CHECK_EQUAL(outImage[7], 1.0f);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr OCIO::OptimizationFlags DefaultNoLutInvFast =
|
||||
|
||||
@@ -105,6 +105,68 @@ OCIO_ADD_GPU_TEST(GradingRGBCurve, style_lin_rev_dynamic)
|
||||
GradingRGBCurveLin(test, OCIO::TRANSFORM_DIR_INVERSE, true);
|
||||
}
|
||||
|
||||
void GradingRGBSCurve(OCIOGPUTest & test, OCIO::TransformDirection dir, bool dynamic)
|
||||
{
|
||||
// Create an S-curve with 0 slope at each end.
|
||||
auto curve = OCIO::GradingBSplineCurve::Create({
|
||||
{-5.26017743f, -4.f},
|
||||
{-3.75502745f, -3.57868829f},
|
||||
{-2.24987747f, -1.82131329f},
|
||||
{-0.74472749f, 0.68124124f},
|
||||
{ 1.06145248f, 2.87457742f},
|
||||
{ 2.86763245f, 3.83406206f},
|
||||
{ 4.67381243f, 4.f}
|
||||
});
|
||||
float slopes[] = { 0.f, 0.55982688f, 1.77532247f, 1.55f, 0.8787017f, 0.18374463f, 0.f };
|
||||
for (size_t i = 0; i < 7; ++i)
|
||||
{
|
||||
curve->setSlope( i, slopes[i] );
|
||||
}
|
||||
|
||||
OCIO::ConstGradingBSplineCurveRcPtr m = curve;
|
||||
// Adjust scaling to ensure the test vector for the inverse hits the flat areas.
|
||||
auto scaling = OCIO::GradingBSplineCurve::Create({ { -5.f, 0.f }, { 5.f, 1.f } });
|
||||
OCIO::ConstGradingBSplineCurveRcPtr z = scaling;
|
||||
OCIO::ConstGradingRGBCurveRcPtr curves = OCIO::GradingRGBCurve::Create(m, m, m, z);
|
||||
|
||||
auto gc = OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LOG);
|
||||
gc->setValue(curves);
|
||||
gc->setDirection(dir);
|
||||
if (dynamic)
|
||||
{
|
||||
gc->makeDynamic();
|
||||
}
|
||||
|
||||
test.setProcessor(gc);
|
||||
|
||||
test.setErrorThreshold(1.5e-4f);
|
||||
test.setExpectedMinimalValue(1.0f);
|
||||
test.setRelativeComparison(true);
|
||||
test.setTestWideRange(true);
|
||||
test.setTestInfinity(false);
|
||||
test.setTestNaN(true);
|
||||
}
|
||||
|
||||
OCIO_ADD_GPU_TEST(GradingRGBCurve, scurve_fwd)
|
||||
{
|
||||
GradingRGBSCurve(test, OCIO::TRANSFORM_DIR_FORWARD, false);
|
||||
}
|
||||
|
||||
OCIO_ADD_GPU_TEST(GradingRGBCurve, scurve_fwd_dynamic)
|
||||
{
|
||||
GradingRGBSCurve(test, OCIO::TRANSFORM_DIR_FORWARD, true);
|
||||
}
|
||||
|
||||
OCIO_ADD_GPU_TEST(GradingRGBCurve, scurve_rev)
|
||||
{
|
||||
GradingRGBSCurve(test, OCIO::TRANSFORM_DIR_INVERSE, false);
|
||||
}
|
||||
|
||||
OCIO_ADD_GPU_TEST(GradingRGBCurve, scurve_rev_dynamic)
|
||||
{
|
||||
GradingRGBSCurve(test, OCIO::TRANSFORM_DIR_INVERSE, true);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# TODO: Add getFormatMetadata tests.
|
||||
|
||||
import unittest, os, sys
|
||||
import copy, unittest, os, sys
|
||||
import PyOpenColorIO as OCIO
|
||||
|
||||
class BakerTest(unittest.TestCase):
|
||||
@@ -55,6 +55,32 @@ END METADATA
|
||||
|
||||
"""
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE)
|
||||
|
||||
bake = OCIO.Baker()
|
||||
bake.setConfig(cfg)
|
||||
bake.setFormat("cinespace")
|
||||
bake.setInputSpace("lnh")
|
||||
bake.setLooks("foo, +bar")
|
||||
bake.setTargetSpace("test")
|
||||
bake.setShaperSize(4)
|
||||
bake.setCubeSize(2)
|
||||
|
||||
other = copy.deepcopy(bake)
|
||||
self.assertFalse(other is bake)
|
||||
|
||||
self.assertEqual(other.getConfig(), bake.getConfig())
|
||||
self.assertEqual(other.getFormat(), bake.getFormat())
|
||||
self.assertEqual(other.getInputSpace(), bake.getInputSpace())
|
||||
self.assertEqual(other.getLooks(), bake.getLooks())
|
||||
self.assertEqual(other.getTargetSpace(), bake.getTargetSpace())
|
||||
self.assertEqual(other.getShaperSize(), bake.getShaperSize())
|
||||
self.assertEqual(other.getCubeSize(), bake.getCubeSize())
|
||||
|
||||
def test_interface(self):
|
||||
"""
|
||||
Test similar to C++ CPU test.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import copy
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
@@ -10,6 +11,7 @@ from UnitTestUtils import SIMPLE_CONFIG, TEST_NAMES, TEST_DESCS, TEST_CATEGORIES
|
||||
|
||||
|
||||
class ColorSpaceTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.colorspace = OCIO.ColorSpace()
|
||||
self.log_tr = OCIO.LogTransform(10)
|
||||
@@ -18,6 +20,42 @@ class ColorSpaceTest(unittest.TestCase):
|
||||
self.colorspace = None
|
||||
self.log_tr = None
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
self.colorspace.setName('colorspace1')
|
||||
self.colorspace.setFamily('family')
|
||||
self.colorspace.setEqualityGroup('group')
|
||||
self.colorspace.setDescription('description')
|
||||
self.colorspace.setBitDepth(OCIO.BIT_DEPTH_UINT8)
|
||||
self.colorspace.setEncoding('encoding')
|
||||
self.colorspace.setIsData(False)
|
||||
self.colorspace.setAllocation(OCIO.ALLOCATION_LG2)
|
||||
self.colorspace.setAllocationVars([-8, 5, 0.00390625])
|
||||
mat = OCIO.MatrixTransform()
|
||||
self.colorspace.setTransform(mat, OCIO.COLORSPACE_DIR_TO_REFERENCE)
|
||||
self.colorspace.setTransform(direction=OCIO.COLORSPACE_DIR_FROM_REFERENCE, transform=mat)
|
||||
self.colorspace.addAlias('alias')
|
||||
self.colorspace.addCategory('cat')
|
||||
|
||||
other = copy.deepcopy(self.colorspace)
|
||||
self.assertFalse(other is self.colorspace)
|
||||
|
||||
self.assertEqual(other.getName(), self.colorspace.getName())
|
||||
self.assertEqual(other.getFamily(), self.colorspace.getFamily())
|
||||
self.assertEqual(other.getEqualityGroup(), self.colorspace.getEqualityGroup())
|
||||
self.assertEqual(other.getDescription(), self.colorspace.getDescription())
|
||||
self.assertEqual(other.getBitDepth(), self.colorspace.getBitDepth())
|
||||
self.assertEqual(other.getEncoding(), self.colorspace.getEncoding())
|
||||
self.assertEqual(other.isData(), self.colorspace.isData())
|
||||
self.assertEqual(other.getAllocation(), self.colorspace.getAllocation())
|
||||
self.assertEqual(other.getAllocationVars(), self.colorspace.getAllocationVars())
|
||||
self.assertTrue(other.getTransform(OCIO.COLORSPACE_DIR_TO_REFERENCE).equals(self.colorspace.getTransform(OCIO.COLORSPACE_DIR_TO_REFERENCE)))
|
||||
self.assertTrue(other.getTransform(OCIO.COLORSPACE_DIR_FROM_REFERENCE).equals(self.colorspace.getTransform(OCIO.COLORSPACE_DIR_FROM_REFERENCE)))
|
||||
self.assertEqual(list(other.getAliases()), list(self.colorspace.getAliases()))
|
||||
self.assertEqual(list(other.getCategories()), list(self.colorspace.getCategories()))
|
||||
|
||||
def test_allocation(self):
|
||||
"""
|
||||
Test the setAllocation() and getAllocation() methods.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import copy
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
@@ -241,6 +242,45 @@ from UnitTestUtils import TEST_DATAFILES_DIR, TEST_NAMES, TEST_DESCS
|
||||
|
||||
class ConfigTest(unittest.TestCase):
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
cfg = OCIO.Config.CreateRaw()
|
||||
cfg.setMajorVersion(2)
|
||||
cfg.setMinorVersion(0)
|
||||
cfg.setName('test config')
|
||||
cfg.setDescription('test description')
|
||||
|
||||
cfg.addColorSpace(
|
||||
OCIO.ColorSpace(OCIO.REFERENCE_SPACE_DISPLAY,
|
||||
"display_cs",
|
||||
toReference=OCIO.CDLTransform(sat=1.5)))
|
||||
cfg.addColorSpace(
|
||||
OCIO.ColorSpace(OCIO.REFERENCE_SPACE_SCENE,
|
||||
"raw",
|
||||
isData=True))
|
||||
|
||||
rules = OCIO.FileRules()
|
||||
rules.insertRule(0, 'A', 'raw', '*', 'exr')
|
||||
rules.insertRule(1, 'B', 'display_cs', '*', 'png')
|
||||
cfg.setFileRules(rules)
|
||||
|
||||
other = copy.deepcopy(cfg)
|
||||
self.assertFalse(other is cfg)
|
||||
|
||||
self.assertEqual(other.getMajorVersion(), cfg.getMajorVersion())
|
||||
self.assertEqual(other.getMinorVersion(), cfg.getMinorVersion())
|
||||
self.assertEqual(other.getName(), cfg.getName())
|
||||
self.assertEqual(other.getDescription(), cfg.getDescription())
|
||||
self.assertEqual(list(other.getColorSpaceNames()), list(cfg.getColorSpaceNames()))
|
||||
self.assertEqual(other.getFileRules().getNumEntries(), cfg.getFileRules().getNumEntries())
|
||||
|
||||
# Check that the file rules are not shared between the two config instances.
|
||||
rules.removeRule(0)
|
||||
other.setFileRules(rules)
|
||||
self.assertEqual(other.getFileRules().getNumEntries(), cfg.getFileRules().getNumEntries() - 1)
|
||||
|
||||
def test_shared_views(self):
|
||||
# Test these Config functions: addSharedView, getSharedViews, removeSharedView.
|
||||
|
||||
@@ -751,3 +791,105 @@ colorspaces:
|
||||
self.assertEqual(cfg.getCanonicalName('NT1'), 'nt1')
|
||||
self.assertEqual(cfg.getCanonicalName('Alias1'), 'nt1')
|
||||
self.assertEqual(cfg.getCanonicalName('Test1'), 'nt1')
|
||||
|
||||
def test_virtual_display(self):
|
||||
# Test platform agnostic virtual display interface.
|
||||
|
||||
cfg = OCIO.Config().CreateRaw()
|
||||
cfg.addColorSpace(
|
||||
OCIO.ColorSpace(OCIO.REFERENCE_SPACE_DISPLAY,
|
||||
"display_cs",
|
||||
toReference=OCIO.CDLTransform(sat=1.5)))
|
||||
cfg.addColorSpace(
|
||||
OCIO.ColorSpace(OCIO.REFERENCE_SPACE_SCENE,
|
||||
"raw",
|
||||
isData=True))
|
||||
cfg.addViewTransform(
|
||||
OCIO.ViewTransform(OCIO.REFERENCE_SPACE_SCENE,
|
||||
"default_vt",
|
||||
toReference=OCIO.CDLTransform(sat=1.5)))
|
||||
cfg.addViewTransform(
|
||||
OCIO.ViewTransform(OCIO.REFERENCE_SPACE_DISPLAY,
|
||||
"display_vt",
|
||||
toReference=OCIO.CDLTransform(sat=1.5)))
|
||||
cfg.addDisplayView("sRGB", "Raw", "raw")
|
||||
cfg.addDisplayView("sRGB", "view",
|
||||
viewTransform="display_vt",
|
||||
displayColorSpaceName="display_cs")
|
||||
cfg.addSharedView("sview1", "", "raw")
|
||||
cfg.addSharedView("sview2", "", "raw")
|
||||
cfg.addDisplaySharedView("sRGB", "sview1")
|
||||
|
||||
# Add virtual display and views
|
||||
cfg.addVirtualDisplayView("Raw", "", "raw")
|
||||
cfg.addVirtualDisplayView("Film", "display_vt",
|
||||
OCIO.OCIO_VIEW_USE_DISPLAY_NAME)
|
||||
cfg.addVirtualDisplaySharedView("sview2")
|
||||
|
||||
# Some basic checks
|
||||
self.assertEqual(3, len(cfg.getViews("sRGB")))
|
||||
self.assertEqual(2, len(cfg.getViews(OCIO.VIEW_DISPLAY_DEFINED,
|
||||
"sRGB")))
|
||||
self.assertEqual(1, len(cfg.getViews(OCIO.VIEW_SHARED, "sRGB")))
|
||||
|
||||
# Validate the virtual display information
|
||||
self.assertEqual(
|
||||
2,
|
||||
len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)))
|
||||
|
||||
view_name = cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)[0]
|
||||
self.assertEqual("Raw", view_name)
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewTransformName(view_name))
|
||||
self.assertEqual("raw",
|
||||
cfg.getVirtualDisplayViewColorSpaceName(view_name))
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewLooks(view_name))
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewRule(view_name))
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewDescription(view_name))
|
||||
|
||||
view_name = cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)[1]
|
||||
self.assertEqual("Film", view_name)
|
||||
self.assertEqual("display_vt",
|
||||
cfg.getVirtualDisplayViewTransformName(view_name))
|
||||
self.assertEqual(OCIO.OCIO_VIEW_USE_DISPLAY_NAME,
|
||||
cfg.getVirtualDisplayViewColorSpaceName(view_name))
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewLooks(view_name))
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewRule(view_name))
|
||||
self.assertEqual("", cfg.getVirtualDisplayViewDescription(view_name))
|
||||
|
||||
self.assertEqual(1, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)))
|
||||
self.assertEqual("sview2",
|
||||
cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)[0])
|
||||
|
||||
# Remove a view from the virtual display
|
||||
cfg.removeVirtualDisplayView("Raw")
|
||||
|
||||
self.assertEqual(
|
||||
1,
|
||||
len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)))
|
||||
self.assertEqual(
|
||||
"Film",
|
||||
cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)[0])
|
||||
|
||||
self.assertEqual(1, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)))
|
||||
self.assertEqual("sview2",
|
||||
cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)[0])
|
||||
|
||||
# Remove a shared view from the virtual display
|
||||
cfg.removeVirtualDisplayView("sview2")
|
||||
self.assertEqual(
|
||||
1,
|
||||
len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)))
|
||||
self.assertEqual(0, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)))
|
||||
|
||||
cfg.addVirtualDisplaySharedView("sview2")
|
||||
self.assertEqual(
|
||||
1,
|
||||
len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)))
|
||||
self.assertEqual(1, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)))
|
||||
|
||||
# Remove the virtual display
|
||||
cfg.clearVirtualDisplay()
|
||||
self.assertEqual(
|
||||
0,
|
||||
len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)))
|
||||
self.assertEqual(0, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)))
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import unittest, os, sys
|
||||
import copy, unittest, os, sys
|
||||
import PyOpenColorIO as OCIO
|
||||
|
||||
class ContextTest(unittest.TestCase):
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
cont = OCIO.Context()
|
||||
cont.setSearchPath('testing123:testing456')
|
||||
cont.setWorkingDir('/dir/123')
|
||||
cont.setEnvironmentMode(OCIO.ENV_ENVIRONMENT_LOAD_PREDEFINED)
|
||||
cont['TeSt'] = 'foobar'
|
||||
cont['Bar'] = 'Foo'
|
||||
|
||||
other = copy.deepcopy(cont)
|
||||
self.assertFalse(other is cont)
|
||||
|
||||
self.assertEqual(other.getCacheID(), cont.getCacheID())
|
||||
self.assertEqual(other.getSearchPath(), cont.getSearchPath())
|
||||
self.assertEqual(other.getWorkingDir(), cont.getWorkingDir())
|
||||
self.assertEqual(other.getEnvironmentMode(), cont.getEnvironmentMode())
|
||||
self.assertEqual(list(other), list(cont))
|
||||
|
||||
def test_interface(self):
|
||||
"""
|
||||
Construct and use Context.
|
||||
|
||||
@@ -1,11 +1,36 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import unittest, os, sys
|
||||
import copy, unittest, os, sys
|
||||
import PyOpenColorIO as OCIO
|
||||
|
||||
class FileRulesTest(unittest.TestCase):
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
rules = OCIO.FileRules()
|
||||
rules.insertRule(0, 'test0', 'colorspace', 'pattern', 'ext')
|
||||
rules.setCustomKey(0, 'key1', 'val1')
|
||||
rules.insertRule(1, 'test2', 'colorspace', 'regex')
|
||||
rules.setCustomKey(1, 'key2', 'val2')
|
||||
|
||||
other = copy.deepcopy(rules)
|
||||
self.assertFalse(other is rules)
|
||||
|
||||
self.assertEqual(other.getNumEntries(), rules.getNumEntries())
|
||||
for idx in range(other.getNumEntries()):
|
||||
self.assertEqual(other.getName(idx), rules.getName(idx))
|
||||
self.assertEqual(other.getPattern(idx), rules.getPattern(idx))
|
||||
self.assertEqual(other.getExtension(idx), rules.getExtension(idx))
|
||||
self.assertEqual(other.getRegex(idx), rules.getRegex(idx))
|
||||
self.assertEqual(other.getColorSpace(idx), rules.getColorSpace(idx))
|
||||
self.assertEqual(other.getNumCustomKeys(idx), rules.getNumCustomKeys(idx))
|
||||
for idx_inner in range(other.getNumCustomKeys(idx)):
|
||||
self.assertEqual(other.getCustomKeyName(idx, idx_inner), rules.getCustomKeyName(idx, idx_inner))
|
||||
self.assertEqual(other.getCustomKeyValue(idx, idx_inner), rules.getCustomKeyValue(idx, idx_inner))
|
||||
|
||||
def test_default(self):
|
||||
"""
|
||||
Construct and verify default values.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import copy
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
@@ -19,6 +20,26 @@ class LookTest(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
self.look = None
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
self.look.setName('test name')
|
||||
self.look.setProcessSpace('test space')
|
||||
self.look.setDescription('test description')
|
||||
mat = OCIO.MatrixTransform()
|
||||
self.look.setTransform(mat)
|
||||
self.look.setInverseTransform(mat)
|
||||
|
||||
other = copy.deepcopy(self.look)
|
||||
self.assertFalse(other is self.look)
|
||||
|
||||
self.assertEqual(other.getName(), self.look.getName())
|
||||
self.assertEqual(other.getProcessSpace(), self.look.getProcessSpace())
|
||||
self.assertEqual(other.getDescription(), self.look.getDescription())
|
||||
self.assertTrue(other.getTransform().equals(self.look.getTransform()))
|
||||
self.assertTrue(other.getInverseTransform().equals(self.look.getInverseTransform()))
|
||||
|
||||
def test_name(self):
|
||||
"""
|
||||
Test the setName() and getName() methods.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import copy
|
||||
import unittest
|
||||
|
||||
import PyOpenColorIO as OCIO
|
||||
@@ -19,6 +20,32 @@ class NamedTransformTest(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
self.named_tr = None
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
self.named_tr.setName('test name')
|
||||
self.named_tr.setFamily('test family')
|
||||
self.named_tr.setDescription('test description')
|
||||
self.named_tr.setEncoding('test encoding')
|
||||
mat = OCIO.MatrixTransform()
|
||||
self.named_tr.setTransform(mat, OCIO.TRANSFORM_DIR_FORWARD)
|
||||
self.named_tr.setTransform(direction=OCIO.TRANSFORM_DIR_INVERSE, transform=mat)
|
||||
self.named_tr.addCategory('cat1')
|
||||
self.named_tr.addAlias("alias1")
|
||||
|
||||
other = copy.deepcopy(self.named_tr)
|
||||
self.assertFalse(other is self.named_tr)
|
||||
|
||||
self.assertEqual(other.getName(), self.named_tr.getName())
|
||||
self.assertEqual(other.getFamily(), self.named_tr.getFamily())
|
||||
self.assertEqual(other.getDescription(), self.named_tr.getDescription())
|
||||
self.assertEqual(other.getEncoding(), self.named_tr.getEncoding())
|
||||
self.assertTrue(other.getTransform(OCIO.TRANSFORM_DIR_FORWARD).equals(self.named_tr.getTransform(OCIO.TRANSFORM_DIR_FORWARD)))
|
||||
self.assertTrue(other.getTransform(OCIO.TRANSFORM_DIR_INVERSE).equals(self.named_tr.getTransform(OCIO.TRANSFORM_DIR_INVERSE)))
|
||||
self.assertEqual(list(other.getCategories()), list(self.named_tr.getCategories()))
|
||||
self.assertEqual(list(other.getAliases()), list(self.named_tr.getAliases()))
|
||||
|
||||
def test_name(self):
|
||||
"""
|
||||
Test the setName() and getName() methods.
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import unittest, os, sys
|
||||
import copy, unittest, os, sys
|
||||
import PyOpenColorIO as OCIO
|
||||
import inspect
|
||||
|
||||
class TransformsTest(unittest.TestCase):
|
||||
|
||||
def test_binding_group_polymorphism(self):
|
||||
"""
|
||||
Tests polymorphism issue where transforms are cast as parent class when using
|
||||
GroupTransforms. Flagged in https://github.com/AcademySoftwareFoundation/OpenColorIO/issues/1211
|
||||
"""
|
||||
def all_transforms_as_group(self):
|
||||
# Default arguments for Transforms that can't be instantiated without arguments.
|
||||
default_args = {
|
||||
OCIO.FixedFunctionTransform: {
|
||||
@@ -42,7 +38,31 @@ class TransformsTest(unittest.TestCase):
|
||||
'Unintended Error Raised: {0}'.format(e)
|
||||
)
|
||||
|
||||
for transform in allTransformsAsGroup:
|
||||
return allTransformsAsGroup
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
for transform in self.all_transforms_as_group():
|
||||
other = copy.deepcopy(transform)
|
||||
self.assertFalse(other is transform)
|
||||
|
||||
self.assertEquals(other.getTransformType(), transform.getTransformType())
|
||||
self.assertEquals(other.getDirection(), transform.getDirection())
|
||||
# Not all OCIO.Transform have equals methods
|
||||
if hasattr(transform, 'equals'):
|
||||
self.assertTrue(other.equals(transform))
|
||||
|
||||
other.setDirection(OCIO.TRANSFORM_DIR_INVERSE)
|
||||
self.assertNotEquals(other.getDirection(), transform.getDirection())
|
||||
|
||||
def test_binding_group_polymorphism(self):
|
||||
"""
|
||||
Tests polymorphism issue where transforms are cast as parent class when using
|
||||
GroupTransforms. Flagged in https://github.com/AcademySoftwareFoundation/OpenColorIO/issues/1211
|
||||
"""
|
||||
for transform in self.all_transforms_as_group():
|
||||
# Ensure no transforms have been cast as parent transform
|
||||
self.assertNotEqual(
|
||||
type(transform),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
import copy
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
@@ -16,6 +17,30 @@ class ViewingRulesTest(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
self.rule = None
|
||||
|
||||
def test_copy(self):
|
||||
"""
|
||||
Test the deepcopy() method.
|
||||
"""
|
||||
|
||||
self.rules.insertRule(0, "rule1")
|
||||
self.rules.insertRule(1, "rule2")
|
||||
self.rules.insertRule(2, "rule3")
|
||||
|
||||
self.rules.addColorSpace(0, "cs1")
|
||||
self.rules.addEncoding(1, "enc1")
|
||||
self.rules.setCustomKey(2, "key1", "value1")
|
||||
|
||||
other = copy.deepcopy(self.rules)
|
||||
self.assertFalse(other is self.rules)
|
||||
|
||||
self.assertEqual(other.getNumEntries(), self.rules.getNumEntries())
|
||||
for idx in range(self.rules.getNumEntries()):
|
||||
self.assertEqual(other.getName(idx), self.rules.getName(idx))
|
||||
self.assertEqual(list(other.getColorSpaces(0)), list(self.rules.getColorSpaces(0)))
|
||||
self.assertEqual(list(other.getEncodings(1)), list(self.rules.getEncodings(1)))
|
||||
self.assertEqual(list(other.getCustomKeyName(2, 0)), list(self.rules.getCustomKeyName(2, 0)))
|
||||
self.assertEqual(list(other.getCustomKeyValue(2, 0)), list(self.rules.getCustomKeyValue(2, 0)))
|
||||
|
||||
def test_insert_remove(self):
|
||||
"""
|
||||
Test the insertRule(), removeRule(), getNumEntrie(), getIndexForRule(), getName() methods.
|
||||
|
||||
Reference in New Issue
Block a user