diff --git a/doc/fmtconv.html b/doc/fmtconv.html
index 73ad8ff..6a98cc5 100644
--- a/doc/fmtconv.html
+++ b/doc/fmtconv.html
@@ -959,6 +959,7 @@
primaries
wd : float[]: opt;
prims : data : opt;
primd : data : opt;
+ wconv : int : opt; (False)
cpuopt: int : opt; (-1)
)
fmtc_primaries (
@@ -973,6 +974,7 @@ primaries
arrayf wd (undefined),
string prims (undefined),
string primd (undefined),
+ bool wconv (False),
int cpuopt (-1)
) |
@@ -1070,6 +1072,21 @@ Parameters
"redwide" | R G B W (D65) | 0.780308, 0.121595, 0.095612, 0.3217, | 0.304253 1.493994 −0.084589 0.3290 | REDWideGamutRGB |
+wconv
+Indicates we want a full conversion for the white point.
+If set to False
, chromatic adaptation will be used, so the
+white will stay white on the destination illuminant and colors will be adapted
+to implement a real illuminant change.
+This is generally what you want when converting between gamuts: the eye adapts
+to the new white and colors should be matched accordingly.
+If set to True
, the chromatic adaptation is bypassed.
+The white from the source colorspace will appear with a tint if the target
+colorspace has a different white point.
+Use this if you want to emulate what a picture displayed with a monitor using
+the source illuminant looks like on a display using the target illuminant.
+This is also what you want when converting to and from XYZ for further
+operations in this colorspace.
+
cpuopt
Limits the CPU instruction set.
−1: automatic (no limitation),
@@ -1978,7 +1995,8 @@
V) Changelog
matrix
: The _ColorRange
frame property is now set when a matrix preset is used.
transfer
: Added ACEScct transfer function.
primaries
: Added DCI P3+ and Cinema Gamut presets.
-Changed the configure options to compile with Clang.
+primaries
: Added wconv parameter for full conversion.
+Changed the configure
options to compile with Clang.
Updated datatypes in the examples.
diff --git a/src/fmtc/Primaries_vs.cpp b/src/fmtc/Primaries_vs.cpp
index ced609e..e5e2089 100644
--- a/src/fmtc/Primaries_vs.cpp
+++ b/src/fmtc/Primaries_vs.cpp
@@ -105,8 +105,10 @@ Primaries::Primaries (const ::VSMap &in, ::VSMap &out, void *user_data_ptr, ::VS
init (_prim_d, *this, in, out, "rd", "gd", "bd", "wd");
assert (_prim_d.is_ready ());
+ const auto conv_flag = (get_arg_int (in, out, "wconv", 0) != 0);
+
const fmtcl::Mat3 mat_conv =
- fmtcl::PrimUtil::compute_conversion_matrix (_prim_s, _prim_d);
+ fmtcl::PrimUtil::compute_conversion_matrix (_prim_s, _prim_d, conv_flag);
_mat_main.insert3 (mat_conv);
_mat_main.clean3 (1);
diff --git a/src/fmtcavs/Primaries.h b/src/fmtcavs/Primaries.h
index e1d067b..e3d248e 100644
--- a/src/fmtcavs/Primaries.h
+++ b/src/fmtcavs/Primaries.h
@@ -62,6 +62,7 @@ class Primaries
Param_WD,
Param_PRIMS,
Param_PRIMD,
+ Param_WCONV,
Param_CPUOPT,
Param_NBR_ELT
diff --git a/src/fmtcavs/Primaries_avs.cpp b/src/fmtcavs/Primaries_avs.cpp
index 85ae49f..989148a 100644
--- a/src/fmtcavs/Primaries_avs.cpp
+++ b/src/fmtcavs/Primaries_avs.cpp
@@ -110,8 +110,10 @@ Primaries::Primaries (::IScriptEnvironment &env, const ::AVSValue &args)
init (_prim_d, env, args, Param_RD, Param_GD, Param_BD, Param_WD);
assert (_prim_d.is_ready ());
+ const auto conv_flag = args [Param_WCONV].AsBool (false);
+
const fmtcl::Mat3 mat_conv =
- fmtcl::PrimUtil::compute_conversion_matrix (_prim_s, _prim_d);
+ fmtcl::PrimUtil::compute_conversion_matrix (_prim_s, _prim_d, conv_flag);
_mat_main.insert3 (mat_conv);
_mat_main.clean3 (1);
diff --git a/src/fmtcl/PrimUtil.cpp b/src/fmtcl/PrimUtil.cpp
index 88ab707..30c6b0a 100644
--- a/src/fmtcl/PrimUtil.cpp
+++ b/src/fmtcl/PrimUtil.cpp
@@ -45,13 +45,20 @@ constexpr int PrimUtil::_nbr_planes;
-Mat3 PrimUtil::compute_conversion_matrix (const RgbSystem &prim_s, const RgbSystem &prim_d)
+// conv_flag indicates we want a full conversion, not a chromatic adatpation
+Mat3 PrimUtil::compute_conversion_matrix (const RgbSystem &prim_s, const RgbSystem &prim_d, bool conv_flag)
{
assert (prim_s.is_ready ());
assert (prim_d.is_ready ());
const Mat3 rgb2xyz = compute_rgb2xyz (prim_s);
const Mat3 xyz2rgb = compute_rgb2xyz (prim_d).invert ();
+
+ if (conv_flag)
+ {
+ return xyz2rgb * rgb2xyz;
+ }
+
const Mat3 adapt = compute_chroma_adapt (prim_s, prim_d);
return xyz2rgb * adapt * rgb2xyz;
diff --git a/src/fmtcl/PrimUtil.h b/src/fmtcl/PrimUtil.h
index 72cf11d..2cbf773 100644
--- a/src/fmtcl/PrimUtil.h
+++ b/src/fmtcl/PrimUtil.h
@@ -44,7 +44,7 @@ class PrimUtil
static constexpr int _nbr_planes = RgbSystem::_nbr_planes;
- static Mat3 compute_conversion_matrix (const RgbSystem &prim_s, const RgbSystem &prim_d);
+ static Mat3 compute_conversion_matrix (const RgbSystem &prim_s, const RgbSystem &prim_d, bool conv_flag);
static Mat3 compute_rgb2xyz (const RgbSystem &prim);
static Mat3 compute_chroma_adapt (const RgbSystem &prim_s, const RgbSystem &prim_d);
static Vec3 conv_xy_to_xyz (const RgbSystem::Vec2 &xy);
diff --git a/src/main-avs.cpp b/src/main-avs.cpp
index dd70871..5316237 100644
--- a/src/main-avs.cpp
+++ b/src/main-avs.cpp
@@ -60,7 +60,8 @@ const char * __stdcall AvisynthPluginInit3 (::IScriptEnvironment *env_ptr, const
env_ptr->AddFunction (fmtcavs_PRIMARIES,
"c" "[rs].+" "[gs].+" "[bs].+" // 0
"[ws].+" "[rd].+" "[gd].+" "[bd].+" // 4
- "[wd].+" "[prims]s" "[primd]s" "[cpuopt]i" // 8
+ "[wd].+" "[prims]s" "[primd]s" "[wconv]b" // 8
+ "[cpuopt]i" // 12
, &main_avs_create , nullptr
);
env_ptr->AddFunction (fmtcavs_RESAMPLE,
diff --git a/src/main-vs.cpp b/src/main-vs.cpp
index 7d4a2ce..facd5f4 100644
--- a/src/main-vs.cpp
+++ b/src/main-vs.cpp
@@ -380,6 +380,7 @@ VS_EXTERNAL_API (void) VapourSynthPluginInit2 (::VSPlugin *plugin_ptr, const ::V
"wd:float[]:opt;"
"prims:data:opt;"
"primd:data:opt;"
+ "wconv:int:opt;"
"cpuopt:int:opt;"
, "clip:vnode;"
, &vsutl::Redirect ::create, nullptr, plugin_ptr