|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "texception.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamset.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static void OLDRGB2HSV(double r, double g, double b,
|
|
Toshihiro Shimizu |
890ddd |
double *h, double *s, double *v)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double max, min;
|
|
Toshihiro Shimizu |
890ddd |
double delta;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
12c444 |
max = std::max({r, g, b});
|
|
Shinya Kitaoka |
12c444 |
min = std::min({r, g, b});
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*v = max;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (max != 0)
|
|
Toshihiro Shimizu |
890ddd |
*s = (max - min) / max;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
*s = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (*s == 0)
|
|
Toshihiro Shimizu |
890ddd |
*h = 0;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
delta = max - min;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (r == max)
|
|
Toshihiro Shimizu |
890ddd |
*h = (g - b) / delta;
|
|
Toshihiro Shimizu |
890ddd |
else if (g == max)
|
|
Toshihiro Shimizu |
890ddd |
*h = 2 + (b - r) / delta;
|
|
Toshihiro Shimizu |
890ddd |
else if (b == max)
|
|
Toshihiro Shimizu |
890ddd |
*h = 4 + (r - g) / delta;
|
|
Toshihiro Shimizu |
890ddd |
*h = *h * 60;
|
|
Toshihiro Shimizu |
890ddd |
if (*h < 0)
|
|
Toshihiro Shimizu |
890ddd |
*h += 360;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static void OLDHSV2RGB(double hue, double sat, double value,
|
|
Toshihiro Shimizu |
890ddd |
double *red, double *green, double *blue)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
double p, q, t, f;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// if (hue > 360 || hue < 0)
|
|
Toshihiro Shimizu |
890ddd |
// hue=0;
|
|
Toshihiro Shimizu |
890ddd |
if (hue > 360)
|
|
Toshihiro Shimizu |
890ddd |
hue -= 360;
|
|
Toshihiro Shimizu |
890ddd |
if (hue < 0)
|
|
Toshihiro Shimizu |
890ddd |
hue += 360;
|
|
Toshihiro Shimizu |
890ddd |
if (sat < 0)
|
|
Toshihiro Shimizu |
890ddd |
sat = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (sat > 1)
|
|
Toshihiro Shimizu |
890ddd |
sat = 1;
|
|
Toshihiro Shimizu |
890ddd |
if (value < 0)
|
|
Toshihiro Shimizu |
890ddd |
value = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (value > 1)
|
|
Toshihiro Shimizu |
890ddd |
value = 1;
|
|
Toshihiro Shimizu |
890ddd |
if (sat == 0) {
|
|
Toshihiro Shimizu |
890ddd |
*red = value;
|
|
Toshihiro Shimizu |
890ddd |
*green = value;
|
|
Toshihiro Shimizu |
890ddd |
*blue = value;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (hue == 360)
|
|
Toshihiro Shimizu |
890ddd |
hue = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
hue = hue / 60;
|
|
Toshihiro Shimizu |
890ddd |
i = (int)hue;
|
|
Toshihiro Shimizu |
890ddd |
f = hue - i;
|
|
Toshihiro Shimizu |
890ddd |
p = value * (1 - sat);
|
|
Toshihiro Shimizu |
890ddd |
q = value * (1 - (sat * f));
|
|
Toshihiro Shimizu |
890ddd |
t = value * (1 - (sat * (1 - f)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
switch (i) {
|
|
Shinya Kitaoka |
d4642c |
case 0:
|
|
Shinya Kitaoka |
d4642c |
*red = value;
|
|
Toshihiro Shimizu |
890ddd |
*green = t;
|
|
Toshihiro Shimizu |
890ddd |
*blue = p;
|
|
Shinya Kitaoka |
d4642c |
break;
|
|
Shinya Kitaoka |
d4642c |
case 1:
|
|
Shinya Kitaoka |
d4642c |
*red = q;
|
|
Toshihiro Shimizu |
890ddd |
*green = value;
|
|
Toshihiro Shimizu |
890ddd |
*blue = p;
|
|
Shinya Kitaoka |
d4642c |
break;
|
|
Shinya Kitaoka |
d4642c |
case 2:
|
|
Shinya Kitaoka |
d4642c |
*red = p;
|
|
Toshihiro Shimizu |
890ddd |
*green = value;
|
|
Toshihiro Shimizu |
890ddd |
*blue = t;
|
|
Shinya Kitaoka |
d4642c |
break;
|
|
Shinya Kitaoka |
d4642c |
case 3:
|
|
Shinya Kitaoka |
d4642c |
*red = p;
|
|
Toshihiro Shimizu |
890ddd |
*green = q;
|
|
Toshihiro Shimizu |
890ddd |
*blue = value;
|
|
Shinya Kitaoka |
d4642c |
break;
|
|
Shinya Kitaoka |
d4642c |
case 4:
|
|
Shinya Kitaoka |
d4642c |
*red = t;
|
|
Toshihiro Shimizu |
890ddd |
*green = p;
|
|
Toshihiro Shimizu |
890ddd |
*blue = value;
|
|
Shinya Kitaoka |
d4642c |
break;
|
|
Shinya Kitaoka |
d4642c |
case 5:
|
|
Shinya Kitaoka |
d4642c |
*red = value;
|
|
Toshihiro Shimizu |
890ddd |
*green = p;
|
|
Toshihiro Shimizu |
890ddd |
*blue = q;
|
|
Shinya Kitaoka |
d4642c |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class ChangeColorFx : public TStandardRasterFx
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_DECLARATION(ChangeColorFx)
|
|
Toshihiro Shimizu |
890ddd |
TRasterFxPort m_input;
|
|
Toshihiro Shimizu |
890ddd |
TPixelParamP m_from_color;
|
|
Toshihiro Shimizu |
890ddd |
TPixelParamP m_to_color;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_range;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_falloff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
ChangeColorFx()
|
|
Toshihiro Shimizu |
890ddd |
: m_from_color(TPixel32::Red), m_to_color(TPixel32::Blue), m_range(0.0), m_falloff(0.0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
addInputPort("Source", m_input);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "range", m_range);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "falloff", m_falloff);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "from_color", m_from_color);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "to_color", m_to_color);
|
|
Toshihiro Shimizu |
890ddd |
m_range->setValueRange(0, 100);
|
|
Toshihiro Shimizu |
890ddd |
m_falloff->setValueRange(0, 100);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
~ChangeColorFx(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_input.isConnected())
|
|
Toshihiro Shimizu |
890ddd |
return m_input->doGetBBox(frame, bBox, info);
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bBox = TRectD();
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void doCompute(TTile &tile, double frame, const TRenderSettings &ri);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double normalize_h(double h)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (h < 0)
|
|
Toshihiro Shimizu |
890ddd |
h += 360;
|
|
Toshihiro Shimizu |
890ddd |
if (h > 360)
|
|
Toshihiro Shimizu |
890ddd |
h -= 360;
|
|
Toshihiro Shimizu |
890ddd |
return h;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChangeColorFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_input.isConnected())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_input->compute(tile, frame, ri);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double from_h, from_s, from_v, to_h, to_s, to_v;
|
|
Toshihiro Shimizu |
890ddd |
bool swaprange = false, swapfallmin = false, swapfallmax;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 from_color = m_from_color->getPremultipliedValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 to_color = m_to_color->getPremultipliedValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
double range = m_range->getValue(frame) / 100;
|
|
Toshihiro Shimizu |
890ddd |
double falloff = m_falloff->getValue(frame) / 100;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
OLDRGB2HSV(from_color.r / 255.0, from_color.g / 255.0, from_color.b / 255.0, &from_h, &from_s, &from_v);
|
|
Toshihiro Shimizu |
890ddd |
OLDRGB2HSV(to_color.r / 255.0, to_color.g / 255.0, to_color.b / 255.0, &to_h, &to_s, &to_v);
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
int from_hsv[3];
|
|
Toshihiro Shimizu |
890ddd |
int to_hsv[3];
|
|
Toshihiro Shimizu |
890ddd |
rgb2hsv(from_hsv, from_color);
|
|
Toshihiro Shimizu |
890ddd |
rgb2hsv(to_hsv, to_color);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/////////////// verificare ///////
|
|
Toshihiro Shimizu |
890ddd |
from_h =((double)from_hsv[0]/255.)*360.;
|
|
Toshihiro Shimizu |
890ddd |
from_s =from_hsv[1]/255.;
|
|
Toshihiro Shimizu |
890ddd |
from_v =from_hsv[2]/255.;
|
|
Toshihiro Shimizu |
890ddd |
to_h =((double)to_hsv[0]/255.)*360.;
|
|
Toshihiro Shimizu |
890ddd |
to_s =to_hsv[1]/255.;
|
|
Toshihiro Shimizu |
890ddd |
to_v =to_hsv[2]/255.;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
////////////////////////
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P raster32 = tile.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
assert(raster32); // per ora gestisco solo i Raster32
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double hmin = from_h - range * 180;
|
|
Toshihiro Shimizu |
890ddd |
hmin = normalize_h(hmin);
|
|
Toshihiro Shimizu |
890ddd |
double hmax = from_h + range * 180;
|
|
Toshihiro Shimizu |
890ddd |
hmax = normalize_h(hmax);
|
|
Toshihiro Shimizu |
890ddd |
if (hmax <= hmin) {
|
|
Toshihiro Shimizu |
890ddd |
tswap(hmin, hmax);
|
|
Toshihiro Shimizu |
890ddd |
swaprange = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
double smin = from_s - range;
|
|
Toshihiro Shimizu |
890ddd |
double smax = from_s + range;
|
|
Toshihiro Shimizu |
890ddd |
double vmin = from_v - range;
|
|
Toshihiro Shimizu |
890ddd |
double vmax = from_v + range;
|
|
Toshihiro Shimizu |
890ddd |
double hfallmin = hmin - falloff * 180;
|
|
Toshihiro Shimizu |
890ddd |
double hfallmax = hmax + falloff * 180;
|
|
Toshihiro Shimizu |
890ddd |
hfallmin = normalize_h(hfallmin);
|
|
Toshihiro Shimizu |
890ddd |
hfallmax = normalize_h(hfallmax);
|
|
Toshihiro Shimizu |
890ddd |
if (hfallmin > hmin) {
|
|
Toshihiro Shimizu |
890ddd |
swapfallmin = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (hfallmax < hmax) {
|
|
Toshihiro Shimizu |
890ddd |
swapfallmax = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
double sfallmin = smin - falloff;
|
|
Toshihiro Shimizu |
890ddd |
double sfallmax = smax + falloff;
|
|
Toshihiro Shimizu |
890ddd |
double vfallmin = vmin - falloff;
|
|
Toshihiro Shimizu |
890ddd |
double vfallmax = vmax + falloff;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int j;
|
|
Toshihiro Shimizu |
890ddd |
raster32->lock();
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0; j < raster32->getLy(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *pix = raster32->pixels(j);
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *endPix = pix + raster32->getLx();
|
|
Toshihiro Shimizu |
890ddd |
while (pix < endPix) {
|
|
Toshihiro Shimizu |
890ddd |
double r, g, b, h, s, v;
|
|
Toshihiro Shimizu |
890ddd |
r = pix->r / 255.0;
|
|
Toshihiro Shimizu |
890ddd |
g = pix->g / 255.0;
|
|
Toshihiro Shimizu |
890ddd |
b = pix->b / 255.0;
|
|
Toshihiro Shimizu |
890ddd |
//int hsv[3];
|
|
Toshihiro Shimizu |
890ddd |
OLDRGB2HSV(r, g, b, &h, &s, &v);
|
|
Toshihiro Shimizu |
890ddd |
int hflag = (h <= hmax && h >= hmin);
|
|
Toshihiro Shimizu |
890ddd |
if (swaprange)
|
|
Toshihiro Shimizu |
890ddd |
hflag = !hflag;
|
|
Toshihiro Shimizu |
890ddd |
if (hflag && s <= smax && s >= smin && v <= vmax && v >= vmin)
|
|
Toshihiro Shimizu |
890ddd |
*pix = to_color;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
double hcorr = 0;
|
|
Toshihiro Shimizu |
890ddd |
double scorr = 0;
|
|
Toshihiro Shimizu |
890ddd |
double vcorr = 0;
|
|
Toshihiro Shimizu |
890ddd |
int hfallminflag = (h <= hmin && h >= hfallmin);
|
|
Toshihiro Shimizu |
890ddd |
if (hfallminflag)
|
|
Toshihiro Shimizu |
890ddd |
hcorr = h - hmin;
|
|
Toshihiro Shimizu |
890ddd |
int hfallmaxflag = (h >= hmax && h <= hfallmax);
|
|
Toshihiro Shimizu |
890ddd |
if (hfallmaxflag)
|
|
Toshihiro Shimizu |
890ddd |
hcorr = h - hmax;
|
|
Toshihiro Shimizu |
890ddd |
if (hcorr) {
|
|
Toshihiro Shimizu |
890ddd |
if (s <= smin && s >= sfallmin)
|
|
Toshihiro Shimizu |
890ddd |
scorr = s - smin;
|
|
Toshihiro Shimizu |
890ddd |
if (s >= smax && s <= sfallmax)
|
|
Toshihiro Shimizu |
890ddd |
scorr = s - smax;
|
|
Toshihiro Shimizu |
890ddd |
if (v <= vmin && v >= vfallmin)
|
|
Toshihiro Shimizu |
890ddd |
vcorr = v - vmin;
|
|
Toshihiro Shimizu |
890ddd |
if (v >= vmax && v <= vfallmax)
|
|
Toshihiro Shimizu |
890ddd |
vcorr = v - vmax;
|
|
Toshihiro Shimizu |
890ddd |
if (s < smin && s > sfallmin)
|
|
Toshihiro Shimizu |
890ddd |
scorr = s - smin;
|
|
Toshihiro Shimizu |
890ddd |
if (s > smax && s < sfallmax)
|
|
Toshihiro Shimizu |
890ddd |
scorr = s - smax;
|
|
Toshihiro Shimizu |
890ddd |
h = to_h + hcorr;
|
|
Toshihiro Shimizu |
890ddd |
if (h < 0)
|
|
Toshihiro Shimizu |
890ddd |
h += 360;
|
|
Toshihiro Shimizu |
890ddd |
if (h > 360)
|
|
Toshihiro Shimizu |
890ddd |
h -= 360;
|
|
Toshihiro Shimizu |
890ddd |
OLDHSV2RGB(h, s, v, &r, &g, &b);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pix->r = (UCHAR)(r * 255);
|
|
Toshihiro Shimizu |
890ddd |
pix->g = (UCHAR)(g * 255);
|
|
Toshihiro Shimizu |
890ddd |
pix->b = (UCHAR)(b * 255);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//premultiply(*pix);
|
|
Toshihiro Shimizu |
890ddd |
*pix++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
raster32->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//FX_PLUGIN_IDENTIFIER(ChangeColorFx , "changeColorFx")
|