1
2
3 #include "texception.h"
4 #include "stdfx.h"
5 #include "tpixelutils.h"
6 #include "tbasefx.h"
7 #include "tfxparam.h"
8 #include "trop.h"
9
10 #include "tparamset.h"
11
12 //---------------------------------------------------------------------
13
backlit(TRaster32P lighted,TRaster32P light,TRaster32P out,double blur,const TPixel & color,double fade,double scale)14 static void backlit(TRaster32P lighted, TRaster32P light, TRaster32P out,
15 double blur, const TPixel &color, double fade,
16 double scale) {
17 assert(light && lighted && out);
18
19 assert(lighted->getSize() == light->getSize());
20 assert(lighted->getSize() == out->getSize());
21
22 int j;
23
24 if (fade > 0.0) {
25 assert(fade <= 1.0);
26 light->lock();
27 for (j = 0; j < light->getLy(); j++) {
28 TPixel *pix = light->pixels(j);
29 TPixel *endPix = pix + light->getLx();
30
31 while (pix < endPix) {
32 if (pix->m > 0) {
33 if (pix->m == 255) {
34 pix->r = troundp(pix->r + fade * (color.r - pix->r));
35 pix->g = troundp(pix->g + fade * (color.g - pix->g));
36 pix->b = troundp(pix->b + fade * (color.b - pix->b));
37 pix->m = troundp(pix->m + fade * (color.m - pix->m));
38 } else {
39 int val;
40 double factor = pix->m / 255.0;
41 val = troundp(pix->r + fade * (color.r * factor - pix->r));
42 pix->r = (val > 255) ? 255 : val;
43 val = troundp(pix->g + fade * (color.g * factor - pix->g));
44 pix->g = (val > 255) ? 255 : val;
45 val = troundp(pix->b + fade * (color.b * factor - pix->b));
46 pix->b = (val > 255) ? 255 : val;
47 val = troundp(pix->m + fade * (color.m * factor - pix->m));
48 pix->m = (val > 255) ? 255 : val;
49 }
50 }
51 ++pix;
52 }
53 }
54 light->unlock();
55 }
56
57 TRop::ropout(light, lighted, light);
58
59 if (blur > 0) {
60 double _blur = blur * scale;
61 int bi = tceil(_blur);
62 TRaster32P ras(light->getLx() + bi, light->getLy() + bi);
63
64 TRect rect(light->getBounds() + TPoint(bi, bi));
65 TRop::copy(ras->extract(rect), light);
66
67 TRop::blur(out, ras, _blur, -bi, -bi, true);
68
69 double ampl = 1.0 + blur / 15.0;
70 out->lock();
71 for (j = 0; j < out->getLy(); j++) {
72 TPixel *pix = out->pixels(j);
73 TPixel *endPix = pix + out->getLx();
74 while (pix < endPix) {
75 if (pix->m != 0) {
76 int val = troundp(pix->r * ampl);
77 pix->r = (val > 204) ? 204 : val;
78 val = troundp(pix->g * ampl);
79 pix->g = (val > 204) ? 204 : val;
80 val = troundp(pix->b * ampl);
81 pix->b = (val > 204) ? 204 : val;
82 val = troundp(pix->m * ampl);
83 pix->m = (val > 204) ? 204 : val;
84 }
85 pix++;
86 }
87 }
88 out->unlock();
89 TRop::over(out, lighted, out);
90 } else
91 TRop::over(out, lighted, light);
92 }
93
94 //---------------------------------------------------------------------
95
backlit(TRaster64P lighted,TRaster64P light,TRaster64P out,double blur,const TPixel & color32,double fade,double scale)96 static void backlit(TRaster64P lighted, TRaster64P light, TRaster64P out,
97 double blur, const TPixel &color32, double fade,
98 double scale) {
99 assert(light && lighted && out);
100
101 assert(lighted->getSize() == light->getSize());
102 assert(lighted->getSize() == out->getSize());
103
104 int j;
105 TPixel64 color = toPixel64(color32);
106
107 if (fade > 0.0) {
108 assert(fade <= 1.0);
109 light->lock();
110 for (j = 0; j < light->getLy(); j++) {
111 TPixel64 *pix = light->pixels(j);
112 TPixel64 *endPix = pix + light->getLx();
113
114 while (pix < endPix) {
115 if (pix->m > 0) {
116 if (pix->m == 65535) {
117 pix->r = troundp(pix->r + fade * (color.r - pix->r));
118 pix->g = troundp(pix->g + fade * (color.g - pix->g));
119 pix->b = troundp(pix->b + fade * (color.b - pix->b));
120 pix->m = troundp(pix->m + fade * (color.m - pix->m));
121 } else {
122 int val;
123 double factor = pix->m / 65535.0;
124 val = troundp(pix->r + fade * (color.r * factor - pix->r));
125 pix->r = (val > 65535) ? 65535 : val;
126 val = troundp(pix->g + fade * (color.g * factor - pix->g));
127 pix->g = (val > 65535) ? 65535 : val;
128 val = troundp(pix->b + fade * (color.b * factor - pix->b));
129 pix->b = (val > 65535) ? 65535 : val;
130 val = troundp(pix->m + fade * (color.m * factor - pix->m));
131 pix->m = (val > 65535) ? 65535 : val;
132 }
133 }
134 ++pix;
135 }
136 }
137 light->unlock();
138 }
139
140 TRop::ropout(light, lighted, light);
141
142 if (blur > 0) {
143 double _blur = blur * scale;
144 int bi = tceil(_blur);
145 TRaster64P ras(light->getLx() + bi, light->getLy() + bi);
146
147 TRect rect(light->getBounds() + TPoint(bi, bi));
148 TRop::copy(ras->extract(rect), light);
149
150 TRop::blur(out, ras, _blur, -bi, -bi, false);
151
152 double ampl = 1.0 + blur / 15.0;
153 out->lock();
154 int fac = (204 << 8) | 204;
155
156 for (j = 0; j < out->getLy(); j++) {
157 TPixel64 *pix = out->pixels(j);
158 TPixel64 *endPix = pix + out->getLx();
159 while (pix < endPix) {
160 if (pix->m != 0) {
161 int val = troundp(pix->r * ampl);
162 pix->r = (val > fac) ? fac : val;
163 val = troundp(pix->g * ampl);
164 pix->g = (val > fac) ? fac : val;
165 val = troundp(pix->b * ampl);
166 pix->b = (val > fac) ? fac : val;
167 val = troundp(pix->m * ampl);
168 pix->m = (val > fac) ? fac : val;
169 }
170 pix++;
171 }
172 }
173 out->unlock();
174 TRop::over(out, lighted, out);
175 } else
176 TRop::over(out, lighted, light);
177 }
178
179 //---------------------------------------------------------------------
180
181 class BacklitFx final : public TBaseRasterFx {
182 FX_DECLARATION(BacklitFx)
183 TRasterFxPort m_lighted, m_light;
184 TDoubleParamP m_value;
185 TDoubleParamP m_fade;
186
187 TPixelParamP m_color;
188
189 public:
BacklitFx()190 BacklitFx() : m_value(0.0), m_color(TPixel::White), m_fade(0.0) {
191 m_color->enableMatte(true);
192 m_value->setValueRange(0, (std::numeric_limits<double>::max)());
193 m_fade->setValueRange(0.0, 100.0);
194 bindParam(this, "value", m_value);
195 bindParam(this, "color", m_color);
196 bindParam(this, "fade", m_fade);
197
198 addInputPort("Light", m_light);
199 addInputPort("Source", m_lighted);
200 }
~BacklitFx()201 ~BacklitFx() {}
doGetBBox(double frame,TRectD & bbox,const TRenderSettings & info)202 bool doGetBBox(double frame, TRectD &bbox,
203 const TRenderSettings &info) override {
204 if (getActiveTimeRegion().contains(frame)) {
205 if (m_light.isConnected()) {
206 if (m_lighted.isConnected()) {
207 TRectD b0, b1;
208 bool ret = m_light->doGetBBox(frame, b0, info);
209 ret = ret && m_lighted->doGetBBox(frame, b1, info);
210 bbox = b0.enlarge(tceil(m_value->getValue(frame))) + b1;
211 return ret;
212 } else {
213 return m_light->doGetBBox(frame, bbox, info);
214 }
215 } else if (m_lighted.isConnected()) {
216 return m_lighted->doGetBBox(frame, bbox, info);
217 }
218 }
219 return false;
220 }
221
doDryCompute(TRectD & rect,double frame,const TRenderSettings & info)222 void doDryCompute(TRectD &rect, double frame,
223 const TRenderSettings &info) override {
224 if (!m_light.isConnected()) return;
225 if (!m_lighted.isConnected()) {
226 m_light->dryCompute(rect, frame, info);
227 return;
228 }
229
230 double value = m_value->getValue(frame);
231 double scale = sqrt(fabs(info.m_affine.det()));
232 int brad = tceil(value * scale);
233
234 TRectD inRect = rect.enlarge(brad);
235 inRect = TRectD(tfloor(inRect.x0), tfloor(inRect.y0), tceil(inRect.x1),
236 tceil(inRect.y1));
237
238 m_lighted->dryCompute(inRect, frame, info);
239 m_light->dryCompute(inRect, frame, info);
240 }
241
doCompute(TTile & tile,double frame,const TRenderSettings & ri)242 void doCompute(TTile &tile, double frame,
243 const TRenderSettings &ri) override {
244 if (!m_light.isConnected()) return;
245
246 if (!m_lighted.isConnected()) {
247 m_light->compute(tile, frame, ri);
248 return;
249 }
250
251 double value = m_value->getValue(frame);
252 double scale = sqrt(fabs(ri.m_affine.det()));
253 int brad = tceil(value * scale);
254
255 TDimension tileSize(tile.getRaster()->getSize());
256 TRectD rect(tile.m_pos, TDimensionD(tileSize.lx, tileSize.ly));
257
258 // TRectD
259 // rect(tile.m_pos,convert(tile.getRaster()->getBounds().getP11())+tile.m_pos);
260 rect = rect.enlarge(brad);
261 TRect rectI(tfloor(rect.x0), tfloor(rect.y0), tceil(rect.x1) - 1,
262 tceil(rect.y1) - 1);
263 // m_light->compute(tile, frame, ri);
264 TTile srcTile;
265 m_lighted->allocateAndCompute(srcTile, rect.getP00(), rectI.getSize(),
266 tile.getRaster(), frame, ri);
267 TTile ctrTile;
268 m_light->allocateAndCompute(ctrTile, rect.getP00(), rectI.getSize(),
269 tile.getRaster(), frame, ri);
270 if ((TRaster32P)srcTile.getRaster() && (TRaster32P)tile.getRaster())
271 backlit((TRaster32P)srcTile.getRaster(), (TRaster32P)ctrTile.getRaster(),
272 (TRaster32P)ctrTile.getRaster(), value, m_color->getValue(frame),
273 m_fade->getValue(frame) / 100.0, scale);
274 else if ((TRaster64P)srcTile.getRaster() && (TRaster64P)tile.getRaster())
275 backlit((TRaster64P)srcTile.getRaster(), (TRaster64P)ctrTile.getRaster(),
276 (TRaster64P)ctrTile.getRaster(), value, m_color->getValue(frame),
277 m_fade->getValue(frame) / 100.0, scale);
278 else
279 throw TRopException("TRop::max invalid raster combination");
280 tile.getRaster()->copy(ctrTile.getRaster(), TPoint(-brad, -brad));
281 }
282
canHandle(const TRenderSettings & info,double frame)283 bool canHandle(const TRenderSettings &info, double frame) override {
284 return true;
285 }
286
getMemoryRequirement(const TRectD & rect,double frame,const TRenderSettings & info)287 int getMemoryRequirement(const TRectD &rect, double frame,
288 const TRenderSettings &info) override {
289 double value = m_value->getValue(frame);
290 double scale = sqrt(fabs(info.m_affine.det()));
291 int brad = tceil(value * scale);
292
293 return TRasterFx::memorySize(rect.enlarge(brad), info.m_bpp);
294 }
295 };
296
297 //==================================================================
298
299 FX_PLUGIN_IDENTIFIER(BacklitFx, "backlitFx")
300 //==================================================================
301