Skip to content

Commit b3252c7

Browse files
authored
Add mirrored displays (#2183)
Signed-off-by: Doug Walker <[email protected]>
1 parent e151865 commit b3252c7

File tree

2 files changed

+126
-28
lines changed

2 files changed

+126
-28
lines changed

src/OpenColorIO/transforms/builtins/Displays.cpp

Lines changed: 96 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -176,80 +176,139 @@ void GenerateLinearToHLGOps(OpRcPtrVec& ops)
176176

177177
void RegisterAll(BuiltinTransformRegistryImpl & registry) noexcept
178178
{
179+
using ConversionFunctor = std::function<void(OpRcPtrVec&)>;
180+
179181
{
180-
auto CIE_XYZ_D65_to_REC1886_REC709_Functor = [](OpRcPtrVec & ops)
182+
auto CIE_XYZ_D65_to_REC1886_REC709 = [](OpRcPtrVec & ops, GammaOpData::Style gammaStyle)
181183
{
182-
MatrixOpData::MatrixArrayPtr matrix
184+
MatrixOpData::MatrixArrayPtr matrix
183185
= build_conversion_matrix_from_XYZ_D65(REC709::primaries, ADAPTATION_NONE);
184186
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
185187

186188
const GammaOpData::Params rgbParams = { 2.4 };
187189
const GammaOpData::Params alphaParams = { 1.0 };
188-
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::BASIC_REV,
189-
rgbParams, rgbParams, rgbParams, alphaParams);
190+
191+
auto gammaData = std::make_shared<GammaOpData>(gammaStyle,
192+
rgbParams, rgbParams, rgbParams, alphaParams);
190193
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
191194
};
192195

196+
ConversionFunctor CIE_XYZ_D65_to_REC1886_REC709_BASIC =
197+
[CIE_XYZ_D65_to_REC1886_REC709](OpRcPtrVec& ops)
198+
{
199+
CIE_XYZ_D65_to_REC1886_REC709(ops, GammaOpData::BASIC_REV);
200+
};
193201
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.709",
194-
"Convert CIE XYZ (D65 white) to Rec.1886/Rec.709 (HD video)",
195-
CIE_XYZ_D65_to_REC1886_REC709_Functor);
202+
"Convert CIE XYZ (D65 white) to Rec.1886/Rec.709, clamp neg. values",
203+
CIE_XYZ_D65_to_REC1886_REC709_BASIC);
204+
205+
ConversionFunctor CIE_XYZ_D65_to_REC1886_REC709_MIRROR =
206+
[CIE_XYZ_D65_to_REC1886_REC709](OpRcPtrVec& ops)
207+
{
208+
CIE_XYZ_D65_to_REC1886_REC709(ops, GammaOpData::BASIC_MIRROR_REV);
209+
};
210+
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.709 - MIRROR NEGS",
211+
"Convert CIE XYZ (D65 white) to Rec.1886/Rec.709, mirror neg. values",
212+
CIE_XYZ_D65_to_REC1886_REC709_MIRROR);
196213
}
197214

198215
{
199-
auto CIE_XYZ_D65_to_REC1886_REC2020_Functor = [](OpRcPtrVec & ops)
216+
auto CIE_XYZ_D65_to_REC1886_REC2020 = [](OpRcPtrVec & ops, GammaOpData::Style gammaStyle)
200217
{
201218
MatrixOpData::MatrixArrayPtr matrix
202219
= build_conversion_matrix_from_XYZ_D65(REC2020::primaries, ADAPTATION_NONE);
203220
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
204221

205222
const GammaOpData::Params rgbParams = { 2.4 };
206223
const GammaOpData::Params alphaParams = { 1.0 };
207-
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::BASIC_REV,
224+
auto gammaData = std::make_shared<GammaOpData>(gammaStyle,
208225
rgbParams, rgbParams, rgbParams, alphaParams);
209226
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
210227
};
211228

229+
ConversionFunctor CIE_XYZ_D65_to_REC1886_REC2020_BASIC =
230+
[CIE_XYZ_D65_to_REC1886_REC2020](OpRcPtrVec& ops)
231+
{
232+
CIE_XYZ_D65_to_REC1886_REC2020(ops, GammaOpData::BASIC_REV);
233+
};
212234
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.2020",
213-
"Convert CIE XYZ (D65 white) to Rec.1886/Rec.2020 (UHD video)",
214-
CIE_XYZ_D65_to_REC1886_REC2020_Functor);
235+
"Convert CIE XYZ (D65 white) to Rec.1886/Rec.2020, clamp neg. values",
236+
CIE_XYZ_D65_to_REC1886_REC2020_BASIC);
237+
238+
ConversionFunctor CIE_XYZ_D65_to_REC1886_REC2020_MIRROR =
239+
[CIE_XYZ_D65_to_REC1886_REC2020](OpRcPtrVec& ops)
240+
{
241+
CIE_XYZ_D65_to_REC1886_REC2020(ops, GammaOpData::BASIC_MIRROR_REV);
242+
};
243+
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.2020 - MIRROR NEGS",
244+
"Convert CIE XYZ (D65 white) to Rec.1886/Rec.2020, mirror neg. values",
245+
CIE_XYZ_D65_to_REC1886_REC2020_MIRROR);
215246
}
216247

217248
{
218-
auto CIE_XYZ_D65_to_G22_REC709_Functor = [](OpRcPtrVec & ops)
249+
auto CIE_XYZ_D65_to_G22_REC709 = [](OpRcPtrVec & ops, GammaOpData::Style gammaStyle)
219250
{
220251
MatrixOpData::MatrixArrayPtr matrix
221252
= build_conversion_matrix_from_XYZ_D65(REC709::primaries, ADAPTATION_NONE);
222253
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
223254

224255
const GammaOpData::Params rgbParams = { 2.2 };
225256
const GammaOpData::Params alphaParams = { 1.0 };
226-
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::BASIC_REV,
257+
auto gammaData = std::make_shared<GammaOpData>(gammaStyle,
227258
rgbParams, rgbParams, rgbParams, alphaParams);
228259
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
229260
};
230261

262+
ConversionFunctor CIE_XYZ_D65_to_G22_REC709_BASIC =
263+
[CIE_XYZ_D65_to_G22_REC709](OpRcPtrVec& ops)
264+
{
265+
CIE_XYZ_D65_to_G22_REC709(ops, GammaOpData::BASIC_REV);
266+
};
231267
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_G2.2-REC.709",
232-
"Convert CIE XYZ (D65 white) to Gamma2.2, Rec.709",
233-
CIE_XYZ_D65_to_G22_REC709_Functor);
268+
"Convert CIE XYZ (D65 white) to Gamma2.2, Rec.709, clamp neg. values",
269+
CIE_XYZ_D65_to_G22_REC709_BASIC);
270+
271+
ConversionFunctor CIE_XYZ_D65_to_G22_REC709_MIRROR =
272+
[CIE_XYZ_D65_to_G22_REC709](OpRcPtrVec& ops)
273+
{
274+
CIE_XYZ_D65_to_G22_REC709(ops, GammaOpData::BASIC_MIRROR_REV);
275+
};
276+
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_G2.2-REC.709 - MIRROR NEGS",
277+
"Convert CIE XYZ (D65 white) to Gamma2.2, Rec.709, mirror neg. values",
278+
CIE_XYZ_D65_to_G22_REC709_MIRROR);
234279
}
235280

236281
{
237-
auto CIE_XYZ_D65_to_SRGB_Functor = [](OpRcPtrVec & ops)
282+
auto CIE_XYZ_D65_to_SRGB = [](OpRcPtrVec & ops, GammaOpData::Style gammaStyle)
238283
{
239284
MatrixOpData::MatrixArrayPtr matrix
240285
= build_conversion_matrix_from_XYZ_D65(REC709::primaries, ADAPTATION_NONE);
241286
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
242287

243288
const GammaOpData::Params rgbParams = { 2.4, 0.055 };
244289
const GammaOpData::Params alphaParams = { 1.0, 0.0 };
245-
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::MONCURVE_REV,
290+
auto gammaData = std::make_shared<GammaOpData>(gammaStyle,
246291
rgbParams, rgbParams, rgbParams, alphaParams);
247292
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
248293
};
249294

295+
ConversionFunctor CIE_XYZ_D65_to_SRGB_MONCURVE =
296+
[CIE_XYZ_D65_to_SRGB](OpRcPtrVec& ops)
297+
{
298+
CIE_XYZ_D65_to_SRGB(ops, GammaOpData::MONCURVE_REV);
299+
};
250300
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_sRGB",
251301
"Convert CIE XYZ (D65 white) to sRGB (piecewise EOTF)",
252-
CIE_XYZ_D65_to_SRGB_Functor);
302+
CIE_XYZ_D65_to_SRGB_MONCURVE);
303+
304+
ConversionFunctor CIE_XYZ_D65_to_SRGB_MIRROR =
305+
[CIE_XYZ_D65_to_SRGB](OpRcPtrVec& ops)
306+
{
307+
CIE_XYZ_D65_to_SRGB(ops, GammaOpData::MONCURVE_MIRROR_REV);
308+
};
309+
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_sRGB - MIRROR NEGS",
310+
"Convert CIE XYZ (D65 white) to sRGB (piecewise EOTF), mirror neg. values",
311+
CIE_XYZ_D65_to_SRGB_MIRROR);
253312
}
254313

255314
{
@@ -272,22 +331,36 @@ void RegisterAll(BuiltinTransformRegistryImpl & registry) noexcept
272331
}
273332

274333
{
275-
auto CIE_XYZ_D65_to_P3_D65_Functor = [](OpRcPtrVec & ops)
334+
auto CIE_XYZ_D65_to_P3_D65 = [](OpRcPtrVec & ops, GammaOpData::Style gammaStyle)
276335
{
277336
MatrixOpData::MatrixArrayPtr matrix
278337
= build_conversion_matrix_from_XYZ_D65(P3_D65::primaries, ADAPTATION_NONE);
279338
CreateMatrixOp(ops, matrix, TRANSFORM_DIR_FORWARD);
280339

281340
const GammaOpData::Params rgbParams = { 2.6 };
282341
const GammaOpData::Params alphaParams = { 1.0 };
283-
auto gammaData = std::make_shared<GammaOpData>(GammaOpData::BASIC_REV,
342+
auto gammaData = std::make_shared<GammaOpData>(gammaStyle,
284343
rgbParams, rgbParams, rgbParams, alphaParams);
285344
CreateGammaOp(ops, gammaData, TRANSFORM_DIR_FORWARD);
286345
};
287346

347+
ConversionFunctor CIE_XYZ_D65_to_P3_D65_BASIC =
348+
[CIE_XYZ_D65_to_P3_D65](OpRcPtrVec& ops)
349+
{
350+
CIE_XYZ_D65_to_P3_D65(ops, GammaOpData::BASIC_REV);
351+
};
288352
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D65",
289-
"Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D65",
290-
CIE_XYZ_D65_to_P3_D65_Functor);
353+
"Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D65, clamp neg. values",
354+
CIE_XYZ_D65_to_P3_D65_BASIC);
355+
356+
ConversionFunctor CIE_XYZ_D65_to_P3_D65_MIRROR =
357+
[CIE_XYZ_D65_to_P3_D65](OpRcPtrVec& ops)
358+
{
359+
CIE_XYZ_D65_to_P3_D65(ops, GammaOpData::BASIC_MIRROR_REV);
360+
};
361+
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D65 - MIRROR NEGS",
362+
"Convert CIE XYZ (D65 white) to Gamma 2.6, P3-D65, mirror neg. values",
363+
CIE_XYZ_D65_to_P3_D65_MIRROR);
291364
}
292365

293366
{
@@ -356,13 +429,13 @@ void RegisterAll(BuiltinTransformRegistryImpl & registry) noexcept
356429
};
357430

358431
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_DisplayP3",
359-
"Convert CIE XYZ (D65 white) to Apple Display P3",
432+
"Convert CIE XYZ (D65 white) to Apple Display P3, mirror neg. values",
360433
CIE_XYZ_D65_to_DisplayP3_Functor);
361434

362435
// NOTE: This builtin is defined to be able to partition SDR and HDR view transforms under two separate
363436
// displays rather than a single one.
364437
registry.addBuiltin("DISPLAY - CIE-XYZ-D65_to_DisplayP3-HDR",
365-
"Convert CIE XYZ (D65 white) to Apple Display P3 (HDR)",
438+
"Convert CIE XYZ (D65 white) to Apple Display P3 (HDR), mirror neg. values",
366439
CIE_XYZ_D65_to_DisplayP3_Functor);
367440
}
368441

tests/cpu/transforms/BuiltinTransform_tests.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -636,22 +636,47 @@ AllValues UnitTestValues
636636

637637
{ "DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.709",
638638
{ 1.0e-6f,
639-
{ 0.5f, 0.4f, 0.3f }, { 0.937245093108f, 0.586817090358f, 0.573498106368f } } },
639+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
640+
{ 0.937245093108f, 0.586817090358f, 0.573498106368f, 0.f, 0.505174310421f, 1.118456082347f } } },
641+
{ "DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.709 - MIRROR NEGS",
642+
{ 1.0e-6f,
643+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
644+
{ 0.937245093108f, 0.586817090358f, 0.573498106368f, -0.940082660458f, 0.505174310421f, 1.118456082347f } } },
640645
{ "DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.2020",
641646
{ 1.0e-6f,
642-
{ 0.5f, 0.4f, 0.3f }, { 0.830338272693f, 0.620393283803f, 0.583385370254f } } },
647+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
648+
{ 0.830338272693f, 0.620393283803f, 0.583385370254f, 0.f, 0.432629991358f, 1.069355537167f } } },
649+
{ "DISPLAY - CIE-XYZ-D65_to_REC.1886-REC.2020 - MIRROR NEGS",
650+
{ 1.0e-6f,
651+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
652+
{ 0.830338272693f, 0.620393283803f, 0.583385370254f, -0.696883299726f, 0.432629991358f, 1.069355537167f } } },
643653
{ "DISPLAY - CIE-XYZ-D65_to_G2.2-REC.709",
644654
{ 1.0e-6f,
645-
{ 0.5f, 0.4f, 0.3f }, { 0.931739212204f, 0.559058879141f, 0.545230761999f } } },
655+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
656+
{ 0.931739212204f, 0.559058879141f, 0.545230761999f, 0.f, 0.474767926071f, 1.129896956592f } } },
657+
{ "DISPLAY - CIE-XYZ-D65_to_G2.2-REC.709 - MIRROR NEGS",
658+
{ 1.0e-6f,
659+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
660+
{ 0.931739212204f, 0.559058879141f, 0.545230761999f, -0.934816978533f, 0.474767926071f, 1.129896956592f } } },
646661
{ "DISPLAY - CIE-XYZ-D65_to_sRGB",
647662
{ 1.0e-6f,
648-
{ 0.5f, 0.4f, 0.3f }, { 0.933793573229f, 0.564092030327f, 0.550040502218f } } },
663+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
664+
{ 0.933793573229f, 0.564092030327f, 0.550040502218f, -11.142147651136028f, 0.477958897494f, 1.124971166876f } } },
665+
{ "DISPLAY - CIE-XYZ-D65_to_sRGB - MIRROR NEGS",
666+
{ 1.0e-6f,
667+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
668+
{ 0.933793573229f, 0.564092030327f, 0.550040502218f, -0.936787206783f, 0.477958897494f, 1.124971166876f } } },
649669
{ "DISPLAY - CIE-XYZ-D65_to_G2.6-P3-DCI-BFD",
650670
{ 1.0e-6f,
651671
{ 0.5f, 0.4f, 0.3f }, { 0.908856342287f, 0.627840575107f, 0.608053675805f } } },
652672
{ "DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D65",
653673
{ 1.0e-6f,
654-
{ 0.5f, 0.4f, 0.3f }, { 0.896805202281f, 0.627254277624f, 0.608228132100f } } },
674+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
675+
{ 0.896805202281f, 0.627254277624f, 0.608228132100f, 0.f, 0.493163009212f, 1.069368427937f } } },
676+
{ "DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D65 - MIRROR NEGS",
677+
{ 1.0e-6f,
678+
{ 0.5f, 0.4f, 0.3f, -0.05f, 0.05f, 1.25f },
679+
{ 0.896805202281f, 0.627254277624f, 0.608228132100f, -0.859521292874f, 0.493163009212f, 1.069368427937f } } },
655680
{ "DISPLAY - CIE-XYZ-D65_to_G2.6-P3-D60-BFD",
656681
{ 1.0e-6f,
657682
{ 0.5f, 0.4f, 0.3f }, { 0.892433142142f, 0.627011653770f, 0.608093643982f } } },

0 commit comments

Comments
 (0)