diff --git a/stuff/config/current.txt b/stuff/config/current.txt
index 574bf5a..6da2821 100644
--- a/stuff/config/current.txt
+++ b/stuff/config/current.txt
@@ -840,67 +840,130 @@
- "STD_inoColorBurnFx" "Color Burn Ino"
- "STD_inoColorBurnFx.opacity" "Opacity"
- "STD_inoColorBurnFx.clipping_mask" "Clipping Mask"
+ - "STD_inoColorBurnFx.linear" "Linear Color Space"
+ - "STD_inoColorBurnFx.gamma" "Gamma"
+ - "STD_inoColorBurnFx.premultiplied" "Source is Premultiplied"
- "STD_inoColorDodgeFx" "Color Dodge Ino"
- "STD_inoColorDodgeFx.opacity" "Opacity"
- "STD_inoColorDodgeFx.clipping_mask" "Clipping Mask"
+ - "STD_inoColorDodgeFx.linear" "Linear Color Space"
+ - "STD_inoColorDodgeFx.gamma" "Gamma"
+ - "STD_inoColorDodgeFx.premultiplied" "Source is Premultiplied"
- "STD_inoCrossDissolveFx" "Cross Dissolve Ino"
- "STD_inoCrossDissolveFx.opacity" "Opacity"
- "STD_inoCrossDissolveFx.clipping_mask" "Clipping Mask"
+ - "STD_inoCrossDissolveFx.linear" "Linear Color Space"
+ - "STD_inoCrossDissolveFx.gamma" "Gamma"
+ - "STD_inoCrossDissolveFx.premultiplied" "Source is Premultiplied"
- "STD_inoDarkenFx" "Darken Ino"
- "STD_inoDarkenFx.opacity" "Opacity"
- "STD_inoDarkenFx.clipping_mask" "Clipping Mask"
+ - "STD_inoDarkenFx.linear" "Linear Color Space"
+ - "STD_inoDarkenFx.gamma" "Gamma"
+ - "STD_inoDarkenFx.premultiplied" "Source is Premultiplied"
- "STD_inoDarkerColorFx" "Darker Color Ino"
- "STD_inoDarkerColorFx.opacity" "Opacity"
- "STD_inoDarkerColorFx.clipping_mask" "Clipping Mask"
+ - "STD_inoDarkerColorFx.linear" "Linear Color Space"
+ - "STD_inoDarkerColorFx.gamma" "Gamma"
+ - "STD_inoDarkerColorFx.premultiplied" "Source is Premultiplied"
- "STD_inoDivideFx" "Divide Ino"
- "STD_inoDivideFx.opacity" "Opacity"
- "STD_inoDivideFx.clipping_mask" "Clipping Mask"
+ - "STD_inoDivideFx.linear" "Linear Color Space"
+ - "STD_inoDivideFx.gamma" "Gamma"
+ - "STD_inoDivideFx.premultiplied" "Source is Premultiplied"
- "STD_inoHardLightFx" "Hard Light Ino"
- "STD_inoHardLightFx.opacity" "Opacity"
- "STD_inoHardLightFx.clipping_mask" "Clipping Mask"
+ - "STD_inoHardLightFx.linear" "Linear Color Space"
+ - "STD_inoHardLightFx.gamma" "Gamma"
+ - "STD_inoHardLightFx.premultiplied" "Source is Premultiplied"
- "STD_inoHardMixFx" "Hard Mix Ino"
- "STD_inoHardMixFx.opacity" "Opacity"
- "STD_inoHardMixFx.clipping_mask" "Clipping Mask"
+ - "STD_inoHardMixFx.linear" "Linear Color Space"
+ - "STD_inoHardMixFx.gamma" "Gamma"
+ - "STD_inoHardMixFx.premultiplied" "Source is Premultiplied"
- "STD_inoLightenFx" "Lighten Ino"
- "STD_inoLightenFx.opacity" "Opacity"
- "STD_inoLightenFx.clipping_mask" "Clipping Mask"
+ - "STD_inoLightenFx.linear" "Linear Color Space"
+ - "STD_inoLightenFx.gamma" "Gamma"
+ - "STD_inoLightenFx.premultiplied" "Source is Premultiplied"
- "STD_inoLighterColorFx" "Lighter Color Ino"
- "STD_inoLighterColorFx.opacity" "Opacity"
- "STD_inoLighterColorFx.clipping_mask" "Clipping Mask"
+ - "STD_inoLighterColorFx.linear" "Linear Color Space"
+ - "STD_inoLighterColorFx.gamma" "Gamma"
+ - "STD_inoLighterColorFx.premultiplied" "Source is Premultiplied"
- "STD_inoLinearBurnFx" "Linear Burn Ino"
- "STD_inoLinearBurnFx.opacity" "Opacity"
- "STD_inoLinearBurnFx.clipping_mask" "Clipping Mask"
+ - "STD_inoLinearBurnFx.linear" "Linear Color Space"
+ - "STD_inoLinearBurnFx.gamma" "Gamma"
+ - "STD_inoLinearBurnFx.premultiplied" "Source is Premultiplied"
- "STD_inoLinearDodgeFx" "Linear Dodge Ino"
- "STD_inoLinearDodgeFx.opacity" "Opacity"
- "STD_inoLinearDodgeFx.clipping_mask" "Clipping Mask"
+ - "STD_inoLinearDodgeFx.linear" "Linear Color Space"
+ - "STD_inoLinearDodgeFx.gamma" "Gamma"
+ - "STD_inoLinearDodgeFx.premultiplied" "Source is Premultiplied"
- "STD_inoLinearLightFx" "Linear Light Ino"
- "STD_inoLinearLightFx.opacity" "Opacity"
- "STD_inoLinearLightFx.clipping_mask" "Clipping Mask"
+ - "STD_inoLinearLightFx.linear" "Linear Color Space"
+ - "STD_inoLinearLightFx.gamma" "Gamma"
+ - "STD_inoLinearLightFx.premultiplied" "Source is Premultiplied"
- "STD_inoMultiplyFx" "Multiply Ino"
- "STD_inoMultiplyFx.opacity" "Opacity"
- "STD_inoMultiplyFx.clipping_mask" "Clipping Mask"
+ - "STD_inoMultiplyFx.linear" "Linear Color Space"
+ - "STD_inoMultiplyFx.gamma" "Gamma"
+ - "STD_inoMultiplyFx.premultiplied" "Source is Premultiplied"
- "STD_inoOverFx" "Over Ino"
- "STD_inoOverFx.opacity" "Opacity"
- "STD_inoOverFx.clipping_mask" "Clipping Mask"
+ - "STD_inoOverFx.linear" "Linear Color Space"
+ - "STD_inoOverFx.gamma" "Gamma"
+ - "STD_inoOverFx.premultiplied" "Source is Premultiplied"
- "STD_inoOverlayFx" "Overlay Ino"
- "STD_inoOverlayFx.opacity" "Opacity"
- "STD_inoOverlayFx.clipping_mask" "Clipping Mask"
+ - "STD_inoOverlayFx.linear" "Linear Color Space"
+ - "STD_inoOverlayFx.gamma" "Gamma"
+ - "STD_inoOverlayFx.premultiplied" "Source is Premultiplied"
- "STD_inoPinLightFx" "Pin Light Ino"
- "STD_inoPinLightFx.opacity" "Opacity"
- "STD_inoPinLightFx.clipping_mask" "Clipping Mask"
+ - "STD_inoPinLightFx.linear" "Linear Color Space"
+ - "STD_inoPinLightFx.gamma" "Gamma"
+ - "STD_inoPinLightFx.premultiplied" "Source is Premultiplied"
- "STD_inoScreenFx" "Screen Ino"
- "STD_inoScreenFx.opacity" "Opacity"
- "STD_inoScreenFx.clipping_mask" "Clipping Mask"
+ - "STD_inoScreenFx.linear" "Linear Color Space"
+ - "STD_inoScreenFx.gamma" "Gamma"
+ - "STD_inoScreenFx.premultiplied" "Source is Premultiplied"
- "STD_inoSoftLightFx" "Soft Light Ino"
- "STD_inoSoftLightFx.opacity" "Opacity"
- "STD_inoSoftLightFx.clipping_mask" "Clipping Mask"
+ - "STD_inoSoftLightFx.linear" "Linear Color Space"
+ - "STD_inoSoftLightFx.gamma" "Gamma"
+ - "STD_inoSoftLightFx.premultiplied" "Source is Premultiplied"
- "STD_inoSubtractFx" "Subtract Ino"
- "STD_inoSubtractFx.opacity" "Opacity"
- "STD_inoSubtractFx.clipping_mask" "Clipping Mask"
- "STD_inoSubtractFx.alpha_rendering" "Alpha Rendering"
+ - "STD_inoSubtractFx.linear" "Linear Color Space"
+ - "STD_inoSubtractFx.gamma" "Gamma"
+ - "STD_inoSubtractFx.premultiplied" "Source is Premultiplied"
- "STD_inoVividLightFx" "Vivid Light Ino"
- "STD_inoVividLightFx.opacity" "Opacity"
- "STD_inoVividLightFx.clipping_mask" "Clipping Mask"
+ - "STD_inoVividLightFx.linear" "Linear Color Space"
+ - "STD_inoVividLightFx.gamma" "Gamma"
+ - "STD_inoVividLightFx.premultiplied" "Source is Premultiplied"
- "STD_inoBlurFx" "Blur Ino"
- "STD_inoBlurFx.radius" "Radius"
- "STD_inoBlurFx.reference" "Reference"
diff --git a/stuff/profiles/layouts/fxs/STD_inoColorBurnFx.xml b/stuff/profiles/layouts/fxs/STD_inoColorBurnFx.xml
index 4e061e8..6073f3c 100644
--- a/stuff/profiles/layouts/fxs/STD_inoColorBurnFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoColorBurnFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoColorDodgeFx.xml b/stuff/profiles/layouts/fxs/STD_inoColorDodgeFx.xml
index 808776b..3d4e87d 100644
--- a/stuff/profiles/layouts/fxs/STD_inoColorDodgeFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoColorDodgeFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoCrossDissolveFx.xml b/stuff/profiles/layouts/fxs/STD_inoCrossDissolveFx.xml
index fa04bd3..171b739 100644
--- a/stuff/profiles/layouts/fxs/STD_inoCrossDissolveFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoCrossDissolveFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoDarkenFx.xml b/stuff/profiles/layouts/fxs/STD_inoDarkenFx.xml
index 4d9555b..8041df3 100644
--- a/stuff/profiles/layouts/fxs/STD_inoDarkenFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoDarkenFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoDarkerColorFx.xml b/stuff/profiles/layouts/fxs/STD_inoDarkerColorFx.xml
index 3d28fe5..358c5a0 100644
--- a/stuff/profiles/layouts/fxs/STD_inoDarkerColorFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoDarkerColorFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoDivideFx.xml b/stuff/profiles/layouts/fxs/STD_inoDivideFx.xml
index e52dc55..42eaca0 100644
--- a/stuff/profiles/layouts/fxs/STD_inoDivideFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoDivideFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoHardLightFx.xml b/stuff/profiles/layouts/fxs/STD_inoHardLightFx.xml
index 0c624e7..8b822ef 100644
--- a/stuff/profiles/layouts/fxs/STD_inoHardLightFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoHardLightFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoHardMixFx.xml b/stuff/profiles/layouts/fxs/STD_inoHardMixFx.xml
index 30e073c..c69b392 100644
--- a/stuff/profiles/layouts/fxs/STD_inoHardMixFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoHardMixFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoLightenFx.xml b/stuff/profiles/layouts/fxs/STD_inoLightenFx.xml
index f8ccb1f..6c6a760 100644
--- a/stuff/profiles/layouts/fxs/STD_inoLightenFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoLightenFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoLighterColorFx.xml b/stuff/profiles/layouts/fxs/STD_inoLighterColorFx.xml
index 56d6903..a143e51 100644
--- a/stuff/profiles/layouts/fxs/STD_inoLighterColorFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoLighterColorFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoLinearBurnFx.xml b/stuff/profiles/layouts/fxs/STD_inoLinearBurnFx.xml
index 54b4cec..ed64746 100644
--- a/stuff/profiles/layouts/fxs/STD_inoLinearBurnFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoLinearBurnFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoLinearDodgeFx.xml b/stuff/profiles/layouts/fxs/STD_inoLinearDodgeFx.xml
index 8f6d1e9..70f34a5 100644
--- a/stuff/profiles/layouts/fxs/STD_inoLinearDodgeFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoLinearDodgeFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoLinearLightFx.xml b/stuff/profiles/layouts/fxs/STD_inoLinearLightFx.xml
index ff37116..303bd46 100644
--- a/stuff/profiles/layouts/fxs/STD_inoLinearLightFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoLinearLightFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoMultiplyFx.xml b/stuff/profiles/layouts/fxs/STD_inoMultiplyFx.xml
index bee7925..5064564 100644
--- a/stuff/profiles/layouts/fxs/STD_inoMultiplyFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoMultiplyFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoOverFx.xml b/stuff/profiles/layouts/fxs/STD_inoOverFx.xml
index 5d2de36..5d3f173 100644
--- a/stuff/profiles/layouts/fxs/STD_inoOverFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoOverFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoOverlayFx.xml b/stuff/profiles/layouts/fxs/STD_inoOverlayFx.xml
index b44ce29..d87c028 100644
--- a/stuff/profiles/layouts/fxs/STD_inoOverlayFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoOverlayFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoPinLightFx.xml b/stuff/profiles/layouts/fxs/STD_inoPinLightFx.xml
index ce8953d..d8332df 100644
--- a/stuff/profiles/layouts/fxs/STD_inoPinLightFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoPinLightFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoScreenFx.xml b/stuff/profiles/layouts/fxs/STD_inoScreenFx.xml
index 8543c3a..5e301a8 100644
--- a/stuff/profiles/layouts/fxs/STD_inoScreenFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoScreenFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoSoftLightFx.xml b/stuff/profiles/layouts/fxs/STD_inoSoftLightFx.xml
index 8ece638..416be10 100644
--- a/stuff/profiles/layouts/fxs/STD_inoSoftLightFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoSoftLightFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoSubtractFx.xml b/stuff/profiles/layouts/fxs/STD_inoSubtractFx.xml
index 8c3c075..4922cf0 100644
--- a/stuff/profiles/layouts/fxs/STD_inoSubtractFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoSubtractFx.xml
@@ -3,5 +3,11 @@
opacity
clipping_mask
alpha_rendering
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/stuff/profiles/layouts/fxs/STD_inoVividLightFx.xml b/stuff/profiles/layouts/fxs/STD_inoVividLightFx.xml
index c226972..12eb439 100644
--- a/stuff/profiles/layouts/fxs/STD_inoVividLightFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_inoVividLightFx.xml
@@ -2,5 +2,11 @@
opacity
clipping_mask
+
+ linear
+
+ gamma
+ premultiplied
+
diff --git a/toonz/sources/stdfx/ino_blend_add.cpp b/toonz/sources/stdfx/ino_blend_add.cpp
index 3ed79a8..6bcebdc 100644
--- a/toonz/sources/stdfx/ino_blend_add.cpp
+++ b/toonz/sources/stdfx/ino_blend_add.cpp
@@ -3,6 +3,7 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
//------------------------------------------------------------
// Regarding computation in linear color space mode is based on the "ComposeAdd"
@@ -10,475 +11,24 @@
// "ComposeAdd" is the "Source is premultiplied" option; the semi-transparent
// pixels are un-premultiplied before converting to linear color space. Also
// modified the transfer functions to use standard gamma correction.
-//------------------------------------------------------------
-
-namespace {
-inline void to_xyz(double *xyz, double const *bgr) {
- xyz[0] = 0.6069 * bgr[2] + 0.1735 * bgr[1] + 0.2003 * bgr[0]; // X
- xyz[1] = 0.2989 * bgr[2] + 0.5866 * bgr[1] + 0.1145 * bgr[0]; // Y
- xyz[2] = 0.0000 * bgr[2] + 0.0661 * bgr[1] + 1.1162 * bgr[0]; // Z
-}
-
-inline void to_bgr(double *bgr, double const *xyz) {
- bgr[0] = +0.0585 * xyz[0] - 0.1187 * xyz[1] + 0.9017 * xyz[2]; // blue
- bgr[1] = -0.9844 * xyz[0] + 1.9985 * xyz[1] - 0.0279 * xyz[2]; // green
- bgr[2] = +1.9104 * xyz[0] - 0.5338 * xyz[1] - 0.2891 * xyz[2]; // red
-}
-
-// convert sRGB color space to power space
-template
-inline T to_linear_color_space(T nonlinear_color, T exposure, T gamma) {
- // return -std::log(T(1) - std::pow(nonlinear_color, gamma)) / exposure;
- return std::pow(nonlinear_color, gamma) / exposure;
-}
-// convert power space to sRGB color space
-template
-inline T to_nonlinear_color_space(T linear_color, T exposure, T gamma) {
- // return std::pow(T(1) - std::exp(-exposure * linear_color), T(1) / gamma);
- return std::pow(linear_color * exposure, T(1) / gamma);
-}
-
-template
-const T &clamp(const T &v, const T &lo, const T &hi) {
- assert(!(hi < lo));
- return (v < lo) ? lo : (hi < v) ? hi : v;
-}
-} // namespace
+//-------------
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_add final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_add)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
-
- TBoolParamP m_linear;
- TDoubleParamP m_gamma;
-
- // If the pixel is premultiplied, divide color data by the alpha before
- // converting from the colorspace, and then multiply by the alpha afterwards.
- // This will correct the color of the semi-transparent pixels in most cases.
- TBoolParamP m_premultiplied;
public:
- ino_blend_add()
- : m_opacity(1.0 * ino::param_range())
- , m_clipping_mask(true)
- , m_linear(false)
- , m_gamma(2.2)
- , m_premultiplied(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- bindParam(this, "linear", this->m_linear);
- bindParam(this, "gamma", this->m_gamma);
- bindParam(this, "premultiplied", this->m_premultiplied);
+ ino_blend_add() : TBlendForeBackRasterFx(true) {
+ // expand the opacity range
this->m_opacity->setValueRange(0, 10.0 * ino::param_range());
- this->m_gamma->setValueRange(0.2, 5.0);
}
~ino_blend_add() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::add(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
-FX_PLUGIN_IDENTIFIER(ino_blend_add, "inoAddFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-} // namespace
-void ino_blend_add::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_add::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::add(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-
-template
-void linearAdd(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw,
- const double gamma, const bool premultiplied_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
- double limit = (maxi + 0.5) / (maxi + 1.0);
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- if (up_pix->m <= 0 || up_opacity <= 0) {
- continue;
- }
-
- double dna = static_cast(out_pix->m) / maxi;
- double tmp_opacity = clipping_mask_sw ? up_opacity * dna : up_opacity;
- if (tmp_opacity <= 0) continue;
-
- double dnBGR[3];
- dnBGR[0] = static_cast(out_pix->b) / maxi;
- dnBGR[1] = static_cast(out_pix->g) / maxi;
- dnBGR[2] = static_cast(out_pix->r) / maxi;
- double dnXYZ[3] = {0.0, 0.0, 0.0};
- if (dna > 0.0) {
- for (int c = 0; c < 3; c++) {
- if (premultiplied_sw)
- dnBGR[c] = to_linear_color_space(dnBGR[c] / dna, 1.0, gamma) * dna;
- else
- dnBGR[c] = to_linear_color_space(dnBGR[c], 1.0, gamma);
- }
- to_xyz(dnXYZ, dnBGR);
- }
-
- double exposure = 1.0 / tmp_opacity;
- double upBGR[3];
- upBGR[0] = static_cast(up_pix->b) / maxi;
- upBGR[1] = static_cast(up_pix->g) / maxi;
- upBGR[2] = static_cast(up_pix->r) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- for (int c = 0; c < 3; c++) {
- if (premultiplied_sw)
- upBGR[c] =
- to_linear_color_space(upBGR[c] / upa, exposure, gamma) * upa;
- else
- upBGR[c] = to_linear_color_space(upBGR[c], exposure, gamma);
- }
-
- double upXYZ[3];
- to_xyz(upXYZ, upBGR);
-
- for (int c = 0; c < 3; c++) dnXYZ[c] += upXYZ[c];
-
- to_bgr(dnBGR, dnXYZ);
- // just do over-composite for alpha channel
- dna = upa * tmp_opacity + dna * (1.0 - upa * tmp_opacity);
- dna = clamp(dna, 0.0, 1.0);
- // premultiply the result
- double nonlinear_b =
- to_nonlinear_color_space(dnBGR[0] / dna, 1.0, gamma) * dna;
- double nonlinear_g =
- to_nonlinear_color_space(dnBGR[1] / dna, 1.0, gamma) * dna;
- double nonlinear_r =
- to_nonlinear_color_space(dnBGR[2] / dna, 1.0, gamma) * dna;
-
- out_pix->r =
- static_cast(clamp(nonlinear_r, 0.0, 1.0) * (maxi + 0.999999));
- out_pix->g =
- static_cast(clamp(nonlinear_g, 0.0, 1.0) * (maxi + 0.999999));
- out_pix->b =
- static_cast(clamp(nonlinear_b, 0.0, 1.0) * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw,
- const bool linear_sw, const double gamma,
- const bool premultiplied_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- if (linear_sw)
- linearAdd(rout32, rup32, up_opacity, clipping_mask_sw,
- gamma, premultiplied_sw);
- else
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- if (linear_sw)
- linearAdd(rout64, rup64, up_opacity, clipping_mask_sw,
- gamma, premultiplied_sw);
- else
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-} // namespace
-void ino_blend_add::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- const double gamma = this->m_gamma->getValue(frame);
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity, this->m_clipping_mask->getValue(),
- this->m_linear->getValue(), gamma, this->m_premultiplied->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
+FX_PLUGIN_IDENTIFIER(ino_blend_add, "inoAddFx");
\ No newline at end of file
diff --git a/toonz/sources/stdfx/ino_blend_color_burn.cpp b/toonz/sources/stdfx/ino_blend_color_burn.cpp
index 2c18627..6c143fe 100644
--- a/toonz/sources/stdfx/ino_blend_color_burn.cpp
+++ b/toonz/sources/stdfx/ino_blend_color_burn.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_color_burn final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_color_burn)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_color_burn()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_color_burn() : TBlendForeBackRasterFx(true) {}
~ino_blend_color_burn() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::color_burn(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_color_burn, "inoColorBurnFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_color_burn::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_color_burn::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::color_burn(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_color_burn::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_color_dodge.cpp b/toonz/sources/stdfx/ino_blend_color_dodge.cpp
index ddda38e..eaf4180 100644
--- a/toonz/sources/stdfx/ino_blend_color_dodge.cpp
+++ b/toonz/sources/stdfx/ino_blend_color_dodge.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_color_dodge final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_color_dodge)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_color_dodge()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_color_dodge() : TBlendForeBackRasterFx(true) {}
~ino_blend_color_dodge() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::color_dodge(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_color_dodge, "inoColorDodgeFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_color_dodge::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_color_dodge::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::color_dodge(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_color_dodge::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_cross_dissolve.cpp b/toonz/sources/stdfx/ino_blend_cross_dissolve.cpp
index 9c774f6..c323c50 100644
--- a/toonz/sources/stdfx/ino_blend_cross_dissolve.cpp
+++ b/toonz/sources/stdfx/ino_blend_cross_dissolve.cpp
@@ -3,335 +3,20 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_cross_dissolve final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_cross_dissolve)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_cross_dissolve()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(false) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_cross_dissolve() : TBlendForeBackRasterFx(false) {}
~ino_blend_cross_dissolve() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::cross_dissolve(dnr, dng, dnb, dna, upr, upg, upb, upa,
+ up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_cross_dissolve, "inoCrossDissolveFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_cross_dissolve::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras,
- TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_cross_dissolve::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::cross_dissolve(
- dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_cross_dissolve::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_darken.cpp b/toonz/sources/stdfx/ino_blend_darken.cpp
index bbfc76f..6015bb4 100644
--- a/toonz/sources/stdfx/ino_blend_darken.cpp
+++ b/toonz/sources/stdfx/ino_blend_darken.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_darken final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_darken)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_darken()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(false) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_darken() : TBlendForeBackRasterFx(false) {}
~ino_blend_darken() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::darken(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_darken, "inoDarkenFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_darken::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_darken::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::darken(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_darken::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_darker_color.cpp b/toonz/sources/stdfx/ino_blend_darker_color.cpp
index 658a94d..3e2c67c 100644
--- a/toonz/sources/stdfx/ino_blend_darker_color.cpp
+++ b/toonz/sources/stdfx/ino_blend_darker_color.cpp
@@ -3,335 +3,20 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_darker_color final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_darker_color)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_darker_color()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(false) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_darker_color() : TBlendForeBackRasterFx(false) {}
~ino_blend_darker_color() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::darker_color(dnr, dng, dnb, dna, upr, upg, upb, upa,
+ up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_darker_color, "inoDarkerColorFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_darker_color::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras,
- TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_darker_color::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::darker_color(
- dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_darker_color::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_divide.cpp b/toonz/sources/stdfx/ino_blend_divide.cpp
index 42cd07a..8d91a19 100644
--- a/toonz/sources/stdfx/ino_blend_divide.cpp
+++ b/toonz/sources/stdfx/ino_blend_divide.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_divide final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_divide)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_divide()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_divide() : TBlendForeBackRasterFx(true) {}
~ino_blend_divide() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::divide(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_divide, "inoDivideFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_divide::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_divide::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::divide(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_divide::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_hard_light.cpp b/toonz/sources/stdfx/ino_blend_hard_light.cpp
index bc40569..5a83902 100644
--- a/toonz/sources/stdfx/ino_blend_hard_light.cpp
+++ b/toonz/sources/stdfx/ino_blend_hard_light.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_hard_light final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_hard_light)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_hard_light()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_hard_light() : TBlendForeBackRasterFx(true) {}
~ino_blend_hard_light() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::hard_light(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_hard_light, "inoHardLightFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_hard_light::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_hard_light::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::hard_light(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_hard_light::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_hard_mix.cpp b/toonz/sources/stdfx/ino_blend_hard_mix.cpp
index bc2b5cb..992bac7 100644
--- a/toonz/sources/stdfx/ino_blend_hard_mix.cpp
+++ b/toonz/sources/stdfx/ino_blend_hard_mix.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_hard_mix final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_hard_mix)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_hard_mix()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_hard_mix() : TBlendForeBackRasterFx(true) {}
~ino_blend_hard_mix() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::hard_mix(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_hard_mix, "inoHardMixFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_hard_mix::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_hard_mix::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::hard_mix(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_hard_mix::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_lighten.cpp b/toonz/sources/stdfx/ino_blend_lighten.cpp
index 5bb8bb9..a70810d 100644
--- a/toonz/sources/stdfx/ino_blend_lighten.cpp
+++ b/toonz/sources/stdfx/ino_blend_lighten.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_lighten final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_lighten)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_lighten()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(false) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_lighten() : TBlendForeBackRasterFx(false) {}
~ino_blend_lighten() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::lighten(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_lighten, "inoLightenFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_lighten::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_lighten::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::lighten(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_lighten::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_lighter_color.cpp b/toonz/sources/stdfx/ino_blend_lighter_color.cpp
index b8d081e..d491082 100644
--- a/toonz/sources/stdfx/ino_blend_lighter_color.cpp
+++ b/toonz/sources/stdfx/ino_blend_lighter_color.cpp
@@ -3,335 +3,20 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_lighter_color final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_lighter_color)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_lighter_color()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(false) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_lighter_color() : TBlendForeBackRasterFx(false) {}
~ino_blend_lighter_color() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::lighter_color(dnr, dng, dnb, dna, upr, upg, upb, upa,
+ up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_lighter_color, "inoLighterColorFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_lighter_color::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras,
- TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_lighter_color::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::lighter_color(
- dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_lighter_color::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_linear_burn.cpp b/toonz/sources/stdfx/ino_blend_linear_burn.cpp
index d1e63ec..7dffc0b 100644
--- a/toonz/sources/stdfx/ino_blend_linear_burn.cpp
+++ b/toonz/sources/stdfx/ino_blend_linear_burn.cpp
@@ -3,333 +3,19 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_linear_burn final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_linear_burn)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_linear_burn()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_linear_burn() : TBlendForeBackRasterFx(true) {}
~ino_blend_linear_burn() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::linear_burn(dnr, dng, dnb, dna, upr, upg, upb, upa, up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_linear_burn, "inoLinearBurnFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_linear_burn::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_linear_burn::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast(up_pix->r) / maxi;
- double upg = static_cast(up_pix->g) / maxi;
- double upb = static_cast(up_pix->b) / maxi;
- double upa = static_cast(up_pix->m) / maxi;
- double dnr = static_cast(out_pix->r) / maxi;
- double dng = static_cast(out_pix->g) / maxi;
- double dnb = static_cast(out_pix->b) / maxi;
- double dna = static_cast(out_pix->m) / maxi;
- igs::color::linear_burn(dnr, dng, dnb, dna, upr, upg, upb, upa,
- clipping_mask_sw ? up_opacity * dna : up_opacity);
- out_pix->r = static_cast(dnr * (maxi + 0.999999));
- out_pix->g = static_cast(dng * (maxi + 0.999999));
- out_pix->b = static_cast(dnb * (maxi + 0.999999));
- out_pix->m = static_cast(dna * (maxi + 0.999999));
- }
- }
-}
-void fx_(TRasterP &dn_ras_out, const TRasterP &up_ras, const TPoint &pos,
- const double up_opacity, const bool clipping_mask_sw) {
- /* 交差したエリアを処理するようにする、いるのか??? */
- TRect outRect(dn_ras_out->getBounds());
- TRect upRect(up_ras->getBounds() + pos);
- TRect intersection = outRect * upRect;
- if (intersection.isEmpty()) return;
-
- TRasterP cRout = dn_ras_out->extract(intersection);
- TRect rr = intersection - pos;
- TRasterP cRup = up_ras->extract(rr);
-
- TRaster32P rout32 = cRout, rup32 = cRup;
- TRaster64P rout64 = cRout, rup64 = cRup;
-
- if (rout32 && rup32) {
- tmpl_(rout32, rup32, up_opacity, clipping_mask_sw);
- } else if (rout64 && rup64) {
- tmpl_(rout64, rup64, up_opacity, clipping_mask_sw);
- } else {
- throw TRopException("unsupported pixel type");
- }
-}
-}
-void ino_blend_linear_burn::doCompute(TTile &tile, double frame,
- const TRenderSettings &rs) {
- /* ------ 画像生成 ---------------------------------------- */
- TRasterP dn_ras, up_ras;
- this->computeUpAndDown(tile, frame, rs, dn_ras, up_ras);
- if (!dn_ras || !up_ras) {
- return;
- }
- /* ------ 動作パラメータを得る ---------------------------- */
- const double up_opacity =
- this->m_opacity->getValue(frame) / ino::param_range();
- /* ------ (app_begin)log記憶 ------------------------------ */
- const bool log_sw = ino::log_enable_sw();
-
- if (log_sw) {
- std::ostringstream os;
- os << "params"
- << " up_opacity " << up_opacity << " dn_tile w " << dn_ras->getLx()
- << " wrap " << dn_ras->getWrap() << " h " << dn_ras->getLy()
- << " pixbits " << ino::pixel_bits(dn_ras) << " up_tile w "
- << up_ras->getLx() << " wrap " << up_ras->getWrap() << " h "
- << up_ras->getLy() << " pixbits " << ino::pixel_bits(up_ras)
- << " frame " << frame;
- }
- /* ------ fx処理 ------------------------------------------ */
- try {
- if (dn_ras) {
- dn_ras->lock();
- }
- if (up_ras) {
- up_ras->lock();
- }
- fx_(dn_ras, up_ras, TPoint(), up_opacity,
- this->m_clipping_mask->getValue());
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- }
- /* ------ error処理 --------------------------------------- */
- catch (std::exception &e) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("exception <");
- str += e.what();
- str += '>';
- }
- throw;
- } catch (...) {
- if (up_ras) {
- up_ras->unlock();
- }
- if (dn_ras) {
- dn_ras->unlock();
- }
- if (log_sw) {
- std::string str("other exception");
- }
- throw;
- }
-}
diff --git a/toonz/sources/stdfx/ino_blend_linear_dodge.cpp b/toonz/sources/stdfx/ino_blend_linear_dodge.cpp
index 9e8598a..aecbe55 100644
--- a/toonz/sources/stdfx/ino_blend_linear_dodge.cpp
+++ b/toonz/sources/stdfx/ino_blend_linear_dodge.cpp
@@ -3,335 +3,20 @@
#include "stdfx.h"
#include "ino_common.h"
+#include "igs_color_blend.h"
/* tnzbase --> Source Files --> tfx --> binaryFx.cppを参照 */
class ino_blend_linear_dodge final : public TBlendForeBackRasterFx {
FX_PLUGIN_DECLARATION(ino_blend_linear_dodge)
- TRasterFxPort m_up;
- TRasterFxPort m_down;
- TDoubleParamP m_opacity;
- TBoolParamP m_clipping_mask;
public:
- ino_blend_linear_dodge()
- : m_opacity(1.0 * ino::param_range()), m_clipping_mask(true) {
- addInputPort("Fore", this->m_up);
- addInputPort("Back", this->m_down);
- bindParam(this, "opacity", this->m_opacity);
- bindParam(this, "clipping_mask", this->m_clipping_mask);
- this->m_opacity->setValueRange(0, 1.0 * ino::param_range());
- }
+ ino_blend_linear_dodge() : TBlendForeBackRasterFx(true) {}
~ino_blend_linear_dodge() {}
- bool canHandle(const TRenderSettings &rs, double frame) override {
- return true;
- }
- bool doGetBBox(double frame, TRectD &bBox,
- const TRenderSettings &rs) override {
- TRectD up_bx;
- const bool up_sw =
- (m_up.isConnected() ? m_up->doGetBBox(frame, up_bx, rs) : false);
- TRectD dn_bx;
- const bool dn_sw =
- (m_down.isConnected() ? m_down->doGetBBox(frame, dn_bx, rs) : false);
- if (up_sw && dn_sw) {
- bBox = up_bx + dn_bx;
- return !bBox.isEmpty();
- } else if (up_sw) {
- bBox = up_bx;
- return true;
- } else if (dn_sw) {
- bBox = dn_bx;
- return true;
- } else {
- bBox = TRectD();
- return false;
- }
- }
- // TRect getInvalidRect(const TRect &max) {return max;}
- // void doSetParam(const std::string &name, const TParamP ¶m) {}
- int getMemoryRequirement(const TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- return TRasterFx::memorySize(rect, rs.m_bpp);
- }
-
- void doDryCompute(TRectD &rect, double frame,
- const TRenderSettings &rs) override {
- this->dryComputeUpAndDown(rect, frame, rs, false);
+ void brendKernel(double& dnr, double& dng, double& dnb, double& dna,
+ const double upr, double upg, double upb, double upa,
+ const double up_opacity,
+ const bool alpha_rendering_sw = true) override {
+ igs::color::linear_dodge(dnr, dng, dnb, dna, upr, upg, upb, upa,
+ up_opacity);
}
- void doCompute(TTile &tile, double frame, const TRenderSettings &rs) override;
- void computeUpAndDown(TTile &tile, double frame, const TRenderSettings &rs,
- TRasterP &dn_ras, TRasterP &up_ras,
- bool upComputesWholeTile = false);
- void dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile = false
- /*
- upComputesWholeTile は Screen, Min, Blendでtrueにして使用している。
- */
- );
};
FX_PLUGIN_IDENTIFIER(ino_blend_linear_dodge, "inoLinearDodgeFx");
-//------------------------------------------------------------
-namespace {
-/* より大きな四角エリアにPixel整数値で密着する */
-void makeRectCoherent(TRectD &rect, const TPointD &pos) {
- rect -= pos;
- rect.x0 = tfloor(rect.x0); /* ((x)<(int)(x)? (int)(x)-1: (int)(x))*/
- rect.y0 = tfloor(rect.y0);
- rect.x1 = tceil(rect.x1); /* ((int)(x)<(x)? (int)(x)+1: (int)(x))*/
- rect.y1 = tceil(rect.y1);
- rect += pos;
-}
-}
-void ino_blend_linear_dodge::computeUpAndDown(TTile &tile, double frame,
- const TRenderSettings &rs,
- TRasterP &dn_ras,
- TRasterP &up_ras,
- bool upComputesWholeTile) {
- /* ------ サポートしていないPixelタイプはエラーを投げる --- */
- if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
- throw TRopException("unsupported input pixel type");
- }
- /*
-m_down,m_upは繋がっている方があればそれを表示する
-両方とも接続していれば合成処理する
-表示スイッチを切ってあるならm_upを表示する
-fxをreplaceすると、
- m_source --> m_up (=port0)
- m_refernce --> m_down(=port1)
-となる
-*/
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- tile.getRaster()->clear();
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->compute(tile, frame, rs);
- return;
- }
- /* ------ down接続時 downのみ描画して... ------------------ */
- if (down_is) {
- this->m_down->compute(tile, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* upと重なる部分を描画する */
-
- /* ------ tileの範囲 -------------------------------------- */
- const TDimension tsz(tile.getRaster()->getSize()); /* 整数 */
- const TRectD tileRect(tile.m_pos, TDimensionD(tsz.lx, tsz.ly));
- TRectD upBBox;
- if (upComputesWholeTile) {
- upBBox = tileRect;
- } /* tile全体を得る */
- else { /* 厳密なエリア... */
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= tileRect; /* upとtileの交差エリア */
-
- /* より大きな四角エリアにPixel整数値で密着する */
- makeRectCoherent(upBBox, tile.m_pos); // double-->int grid
- }
-
- TDimensionI upSize( /* TRectDをTDimensionIに変換 */
- tround(upBBox.getLx()) // getLx() = "x1>=x0?x1-x0:0"
- ,
- tround(upBBox.getLy()) // getLy() = "y1>=y0?y1-y0:0"
- );
- if ((upSize.lx <= 0) || (upSize.ly <= 0)) {
- return;
- }
-
- /* ------ upのメモリ確保と描画 ---------------------------- */
- TTile upTile;
- this->m_up->allocateAndCompute(upTile, upBBox.getP00(), upSize,
- tile.getRaster() /* 32/64bitsの判定に使う */
- ,
- frame, rs);
- /* ------ upとdownのTRasterを得る ------------------------- */
- TRectI dnRect(upTile.getRaster()->getSize()); // TDimensionI(-)
-
- dnRect += convert(upTile.m_pos - tile.m_pos); /* uptile->tile原点 */
- /*
- ここで問題はdoubleの位置を、四捨五入して整数値にしていること
- 移動してから四捨五入ではないの???
- dnRectの元位置が整数位置なので、問題ないか...
- */
-
- dn_ras = upComputesWholeTile ? tile.getRaster()
- : tile.getRaster()->extract(dnRect);
- up_ras = upTile.getRaster();
- assert(dn_ras->getSize() == up_ras->getSize());
-}
-void ino_blend_linear_dodge::dryComputeUpAndDown(TRectD &rect, double frame,
- const TRenderSettings &rs,
- bool upComputesWholeTile) {
- const bool up_is = (this->m_up.isConnected() &&
- this->m_up.getFx()->getTimeRegion().contains(frame));
- const bool down_is = (this->m_down.isConnected() &&
- this->m_down.getFx()->getTimeRegion().contains(frame));
- /* ------ 両方とも切断の時処理しない ---------------------- */
- if (!up_is && !down_is) {
- return;
- }
- /* ------ up接続かつdown切断の時 -------------------------- */
- if (up_is && !down_is) {
- this->m_up->dryCompute(rect, frame, rs);
- return;
- }
- /* ------ down接続時 -------------------------------------- */
- if (down_is) {
- this->m_down->dryCompute(rect, frame, rs);
- }
- /* ------ up切断時 ---------------------------------------- */
- if (!up_is) {
- return;
- }
-
- /* ------ tileのgeometryを計算する ------------------------ */
- TRectD upBBox;
-
- if (upComputesWholeTile) {
- upBBox = rect;
- } else {
- this->m_up->getBBox(frame, upBBox, rs);
- upBBox *= rect;
- makeRectCoherent(upBBox, rect.getP00());
- }
- if ((upBBox.getLx() > 0.5) && (upBBox.getLy() > 0.5)) {
- this->m_up->dryCompute(upBBox, frame, rs);
- }
-}
-//------------------------------------------------------------
-#include /* std::ostringstream */
-#include "igs_color_blend.h"
-namespace {
-template
-void tmpl_(TRasterPT dn_ras_out, const TRasterPT &up_ras,
- const double up_opacity, const bool clipping_mask_sw) {
- double maxi = static_cast(T::maxChannelValue); // 255or65535
-
- assert(dn_ras_out->getSize() == up_ras->getSize());
-
- for (int yy = 0; yy < dn_ras_out->getLy(); ++yy) {
- T *out_pix = dn_ras_out->pixels(yy);
- const T *const out_end = out_pix + dn_ras_out->getLx();
- const T *up_pix = up_ras->pixels(yy);
- for (; out_pix < out_end; ++out_pix, ++up_pix) {
- double upr = static_cast