#include "stdfx.h" #include "tfxparam.h" namespace { template void prepare_lut(int levels, vector &lut) { int i, j; int valuestep = PIXEL::maxChannelValue / (levels - 1); int step = PIXEL::maxChannelValue / levels; for (j = 0; j < levels; j++) for (i = 0; i <= step; i++) lut[i + j * step] = j * valuestep; } } //=================================================================== class PosterizeFx : public TStandardRasterFx { FX_PLUGIN_DECLARATION(PosterizeFx) TRasterFxPort m_input; TDoubleParamP m_levels; public: PosterizeFx() : m_levels(7.0) { bindParam(this, "levels", m_levels); addInputPort("Source", m_input); m_levels->setValueRange(2.0, 10.0); } ~PosterizeFx(){}; bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) { 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); bool canHandle(const TRenderSettings &info, double frame) { return true; } }; //------------------------------------------------------------------- template void doPosterize(TRasterPT ras, int levels) { vector solarize_lut(PIXEL::maxChannelValue + 1); prepare_lut(levels, 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 PosterizeFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { if (!m_input.isConnected()) return; m_input->compute(tile, frame, ri); int levels = (int)m_levels->getValue(frame); TRaster32P raster32 = tile.getRaster(); if (raster32) doPosterize(raster32, levels); else { TRaster64P raster64 = tile.getRaster(); if (raster64) doPosterize(raster64, levels); else throw TException("Brightness&Contrast: unsupported Pixel Type"); } } FX_PLUGIN_IDENTIFIER(PosterizeFx, "posterizeFx");