MCPcopy Create free account
hub / github.com/AcademySoftwareFoundation/OpenColorIO / RemoveInverseOps

Function RemoveInverseOps

src/OpenColorIO/OpOptimizers.cpp:207–300  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

205}
206
207int RemoveInverseOps(OpRcPtrVec & opVec, OptimizationFlags oFlags)
208{
209 int count = 0;
210 int firstindex = 0; // this must be a signed int
211
212 while (firstindex < (static_cast<int>(opVec.size()) - 1))
213 {
214 ConstOpRcPtr op1 = opVec[firstindex];
215 ConstOpRcPtr op2 = opVec[firstindex + 1];
216 const auto type1 = op1->data()->getType();
217 const auto type2 = op2->data()->getType();
218 // The common case of inverse ops is to have a deep nesting:
219 // ..., A, B, B', A', ...
220 //
221 // Consider the above, when firstindex reaches B:
222 //
223 // |
224 // ..., A, B, B', A', ...
225 //
226 // We will remove B and B'.
227 // Firstindex remains pointing at the original location:
228 //
229 // |
230 // ..., A, A', ...
231 //
232 // We then decrement firstindex by 1,
233 // to backstep and reconsider the A, A' case:
234 //
235 // | <-- firstindex decremented
236 // ..., A, A', ...
237 //
238
239 if (type1 == type2 &&
240 IsPairInverseEnabled(type1, oFlags) &&
241 op1->isInverse(op2))
242 {
243 // When a pair of inverse ops is removed, we want the optimized ops to give the
244 // same result as the original. For certain ops such as Lut1D or Log this may
245 // mean inserting a Range to emulate the clamping done by the original ops.
246
247 OpRcPtr replacedBy;
248 if (type1 == OpData::Lut1DType)
249 {
250 // Lut1D gets special handling so that both halfs of the pair are available.
251 // Only the inverse LUT has the values needed to generate the replacement.
252
253 ConstLut1DOpDataRcPtr lut1 = OCIO_DYNAMIC_POINTER_CAST<const Lut1DOpData>(op1->data());
254 ConstLut1DOpDataRcPtr lut2 = OCIO_DYNAMIC_POINTER_CAST<const Lut1DOpData>(op2->data());
255
256 OpDataRcPtr opData = lut1->getPairIdentityReplacement(lut2);
257
258 OpRcPtrVec ops;
259 if (opData->getType() == OpData::MatrixType)
260 {
261 // No-op that will be optimized.
262 auto mat = OCIO_DYNAMIC_POINTER_CAST<MatrixOpData>(opData);
263 CreateMatrixOp(ops, mat, TRANSFORM_DIR_FORWARD);
264 }

Callers 2

optimizeMethod · 0.85
OCIO_ADD_TESTFunction · 0.85

Calls 13

IsPairInverseEnabledFunction · 0.85
CreateMatrixOpFunction · 0.85
CreateRangeOpFunction · 0.85
eraseMethod · 0.80
sizeMethod · 0.45
getTypeMethod · 0.45
dataMethod · 0.45
isInverseMethod · 0.45
finalizeMethod · 0.45
isNoOpMethod · 0.45

Tested by 1

OCIO_ADD_TESTFunction · 0.68