#include "texception.h" #include "tfxparam.h" #include "stdfx.h" namespace { template void prepare_lut(double max, int edge, std::vector &lut) { double aux = (double)PIXEL::maxChannelValue; int i = 0; for (i = 0; i <= edge; i++) { lut[i] = (int)((max / edge) * i); } for (i = edge + 1; i < PIXEL::maxChannelValue + 1; i++) { lut[i] = (int)((max / (edge - aux)) * (i - aux)); } } } //=================================================================== class SolarizeFx final : public TStandardRasterFx { FX_PLUGIN_DECLARATION(SolarizeFx) TRasterFxPort m_input; TDoubleParamP m_maximum; TDoubleParamP m_edge; public: SolarizeFx() : m_maximum(1.0), m_edge(128.0) { bindParam(this, "maximum", m_maximum); bindParam(this, "peak_edge", m_edge); addInputPort("Source", m_input); // m_value->setValueRange(0, std::numeric_limits::max()); m_maximum->setValueRange(0.0, 10.0); m_edge->setValueRange(0.0, 255.0); } ~SolarizeFx(){}; bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) override { if (m_input.isConnected()) { bool ret = m_input->doGetBBox(frame, bBox, info); return ret; } else { bBox = TRectD(); return false; } } void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override; bool canHandle(const TRenderSettings &info, double frame) override { return true; } }; namespace { template void update_param(T ¶m, TRaster32P ras) { return; } template void update_param(T ¶m, TRaster64P ras) { param = param * 257; return; } } //------------------------------------------------------------------- template void doSolarize(TRasterPT ras, double max, int edge) { std::vector solarize_lut(PIXEL::maxChannelValue + 1); update_param(max, ras); update_param(edge, ras); prepare_lut(max, edge, solarize_lut); int j; ras->lock(); for (j = 0; j < ras->getLy(); j++) { PIXEL *pix = ras->pixels(j); PIXEL *endPix = pix + ras->getLx(); while (pix < endPix) { pix->r = (CHANNEL_TYPE)(solarize_lut[(int)(pix->r)]); pix->g = (CHANNEL_TYPE)(solarize_lut[(int)(pix->g)]); pix->b = (CHANNEL_TYPE)(solarize_lut[(int)(pix->b)]); *pix++; } } ras->unlock(); } //------------------------------------------------------------------- void SolarizeFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { if (!m_input.isConnected()) return; m_input->compute(tile, frame, ri); double min, max, step; m_maximum->getValueRange(min, max, step); double maxValue = 128 * tcrop(m_maximum->getValue(frame), min, max); m_edge->getValueRange(min, max, step); int edge = (int)tcrop(m_edge->getValue(frame), min, max); TRaster32P raster32 = tile.getRaster(); if (raster32) doSolarize(raster32, maxValue, edge); else { TRaster64P raster64 = tile.getRaster(); if (raster64) doSolarize(raster64, maxValue, edge); else throw TException("SolarizeFx: unsupported Pixel Type"); } } FX_PLUGIN_IDENTIFIER(SolarizeFx, "solarizeFx");