1
2
3 #include "tfxparam.h"
4 #include "stdfx.h"
5 #include "tspectrumparam.h"
6 #include "tpixelutils.h"
7 #include "tparamuiconcept.h"
8
9 namespace {
pixelConvert(TPixel32 & dst,const TPixel32 & src)10 inline void pixelConvert(TPixel32 &dst, const TPixel32 &src) { dst = src; }
pixelConvert(TPixel64 & dst,const TPixel32 & src)11 inline void pixelConvert(TPixel64 &dst, const TPixel32 &src) {
12 dst = toPixel64(src);
13 }
14 } // namespace
15
16 class FourPointsGradientFx final : public TStandardZeraryFx {
17 FX_PLUGIN_DECLARATION(FourPointsGradientFx)
18 TSpectrumParamP m_colors;
19 TPointParamP m_point1;
20 TPointParamP m_point2;
21 TPointParamP m_point3;
22 TPointParamP m_point4;
23 TPixelParamP m_color1;
24 TPixelParamP m_color2;
25 TPixelParamP m_color3;
26 TPixelParamP m_color4;
27
28 public:
FourPointsGradientFx()29 FourPointsGradientFx()
30 : m_point1(TPointD(200.0, 200.0))
31 , m_point2(TPointD(-200.0, 200.0))
32 , m_point3(TPointD(-200.0, -200.0))
33 , m_point4(TPointD(200.0, -200.0))
34 , m_color1(TPixel32::Red)
35 , m_color2(TPixel32::Green)
36 , m_color3(TPixel32::Blue)
37 , m_color4(TPixel32::Yellow) {
38 m_point1->getX()->setMeasureName("fxLength");
39 m_point1->getY()->setMeasureName("fxLength");
40 m_point2->getX()->setMeasureName("fxLength");
41 m_point2->getY()->setMeasureName("fxLength");
42 m_point3->getX()->setMeasureName("fxLength");
43 m_point3->getY()->setMeasureName("fxLength");
44 m_point4->getX()->setMeasureName("fxLength");
45 m_point4->getY()->setMeasureName("fxLength");
46 /*
47 bindParam(this,"point1", m_point1);
48 bindParam(this,"point2", m_point2);
49 bindParam(this,"point3", m_point3);
50 bindParam(this,"point4", m_point4);
51 bindParam(this,"color_1", m_color1);
52 bindParam(this,"color_2", m_color2);
53 bindParam(this,"color_3", m_color3);
54 bindParam(this,"color_4", m_color4);
55 */
56 bindParam(this, "Point_1", m_point1);
57 bindParam(this, "Color_1", m_color1);
58
59 bindParam(this, "Point_2", m_point2);
60 bindParam(this, "Color_2", m_color2);
61
62 bindParam(this, "Point_3", m_point3);
63 bindParam(this, "Color_3", m_color3);
64
65 bindParam(this, "Point_4", m_point4);
66 bindParam(this, "Color_4", m_color4);
67 }
~FourPointsGradientFx()68 ~FourPointsGradientFx(){};
69
doGetBBox(double,TRectD & bbox,const TRenderSettings & info)70 bool doGetBBox(double, TRectD &bbox, const TRenderSettings &info) override {
71 bbox = TConsts::infiniteRectD;
72 return true;
73 };
74 void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
canHandle(const TRenderSettings & info,double frame)75 bool canHandle(const TRenderSettings &info, double frame) override {
76 return true;
77 }
78
getParamUIs(TParamUIConcept * & concepts,int & length)79 void getParamUIs(TParamUIConcept *&concepts, int &length) override {
80 concepts = new TParamUIConcept[length = 4];
81
82 concepts[0].m_type = TParamUIConcept::POINT;
83 concepts[0].m_label = "Point 1";
84 concepts[0].m_params.push_back(m_point1);
85
86 concepts[1].m_type = TParamUIConcept::POINT;
87 concepts[1].m_label = "Point 2";
88 concepts[1].m_params.push_back(m_point2);
89
90 concepts[2].m_type = TParamUIConcept::POINT;
91 concepts[2].m_label = "Point 3";
92 concepts[2].m_params.push_back(m_point3);
93
94 concepts[3].m_type = TParamUIConcept::POINT;
95 concepts[3].m_label = "Point 4";
96 concepts[3].m_params.push_back(m_point4);
97 }
98 };
99
100 template <typename PIXEL, typename CHANNEL_TYPE>
doFourPointsGradient(const TRasterPT<PIXEL> & ras,TPointD tilepos,TPointD pos1,TPointD pos2,TPointD pos3,TPointD pos4,TPixel32 ccol1,TPixel32 ccol2,TPixel32 ccol3,TPixel32 ccol4)101 void doFourPointsGradient(const TRasterPT<PIXEL> &ras, TPointD tilepos,
102 TPointD pos1, TPointD pos2, TPointD pos3,
103 TPointD pos4, TPixel32 ccol1, TPixel32 ccol2,
104 TPixel32 ccol3, TPixel32 ccol4) {
105 PIXEL col1, col2, col3, col4;
106 pixelConvert(col1, ccol1);
107 pixelConvert(col2, ccol2);
108 pixelConvert(col3, ccol3);
109 pixelConvert(col4, ccol4);
110
111 int j;
112 ras->lock();
113 for (j = 0; j < ras->getLy(); j++) {
114 TPointD pos = tilepos;
115 pos.y += j;
116 PIXEL *pix = ras->pixels(j);
117 PIXEL *endPix = pix + ras->getLx();
118 while (pix < endPix) {
119 double d1 = sqrt((pos1.x - pos.x) * (pos1.x - pos.x) +
120 (pos1.y - pos.y) * (pos1.y - pos.y));
121 if (!d1) {
122 *pix = col1;
123 pos.x += 1;
124 ++pix;
125 continue;
126 }
127 double d2 = sqrt((pos2.x - pos.x) * (pos2.x - pos.x) +
128 (pos2.y - pos.y) * (pos2.y - pos.y));
129 if (!d2) {
130 *pix = col2;
131 pos.x += 1;
132 ++pix;
133 continue;
134 }
135 double d3 = sqrt((pos3.x - pos.x) * (pos3.x - pos.x) +
136 (pos3.y - pos.y) * (pos3.y - pos.y));
137 if (!d3) {
138 *pix = col3;
139 pos.x += 1;
140 ++pix;
141 continue;
142 }
143 double d4 = sqrt((pos4.x - pos.x) * (pos4.x - pos.x) +
144 (pos4.y - pos.y) * (pos4.y - pos.y));
145 if (!d4) {
146 *pix = col4;
147 pos.x += 1;
148 ++pix;
149 continue;
150 }
151 double dtotal = 1 / d1 + 1 / d2 + 1 / d3 + 1 / d4;
152 pix->r = (CHANNEL_TYPE)(
153 ((1 / d1) / dtotal) * col1.r + ((1 / d2) / dtotal) * col2.r +
154 ((1 / d3) / dtotal) * col3.r + ((1 / d4) / dtotal) * col4.r);
155 pix->g = (CHANNEL_TYPE)(
156 ((1 / d1) / dtotal) * col1.g + ((1 / d2) / dtotal) * col2.g +
157 ((1 / d3) / dtotal) * col3.g + ((1 / d4) / dtotal) * col4.g);
158 pix->b = (CHANNEL_TYPE)(
159 ((1 / d1) / dtotal) * col1.b + ((1 / d2) / dtotal) * col2.b +
160 ((1 / d3) / dtotal) * col3.b + ((1 / d4) / dtotal) * col4.b);
161 pix->m = (CHANNEL_TYPE)(
162 ((1 / d1) / dtotal) * col1.m + ((1 / d2) / dtotal) * col2.m +
163 ((1 / d3) / dtotal) * col3.m + ((1 / d4) / dtotal) * col4.m);
164 pos.x += 1.0;
165 ++pix;
166 }
167 }
168 ras->unlock();
169 }
170
doCompute(TTile & tile,double frame,const TRenderSettings & ri)171 void FourPointsGradientFx::doCompute(TTile &tile, double frame,
172 const TRenderSettings &ri) {
173 TPointD pos1 = m_point1->getValue(frame) * (1.0 / ri.m_shrinkX);
174 TPointD pos2 = m_point2->getValue(frame) * (1.0 / ri.m_shrinkX);
175 TPointD pos3 = m_point3->getValue(frame) * (1.0 / ri.m_shrinkX);
176 TPointD pos4 = m_point4->getValue(frame) * (1.0 / ri.m_shrinkX);
177 pos1 = ri.m_affine * pos1;
178 pos2 = ri.m_affine * pos2;
179 pos3 = ri.m_affine * pos3;
180 pos4 = ri.m_affine * pos4;
181 TPixel32 col1 = m_color1->getPremultipliedValue(frame);
182 TPixel32 col2 = m_color2->getPremultipliedValue(frame);
183 TPixel32 col3 = m_color3->getPremultipliedValue(frame);
184 TPixel32 col4 = m_color4->getPremultipliedValue(frame);
185
186 TPointD pos = tile.m_pos;
187 TRaster32P raster32 = tile.getRaster();
188
189 if (raster32)
190 doFourPointsGradient<TPixel32, UCHAR>(raster32, pos, pos1, pos2, pos3, pos4,
191 col1, col2, col3, col4);
192 else {
193 TRaster64P raster64 = tile.getRaster();
194 if (raster64)
195 doFourPointsGradient<TPixel64, USHORT>(raster64, pos, pos1, pos2, pos3,
196 pos4, col1, col2, col3, col4);
197 else
198 throw TException("Brightness&Contrast: unsupported Pixel Type");
199 }
200 }
201
202 FX_PLUGIN_IDENTIFIER(FourPointsGradientFx, "fourPointsGradientFx");
203