Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
template <typename pixel="" t,="" typename=""></typename>
Shinya Kitaoka 120a6e
void prepare_lut(int levels, std::vector<t> &lut) {</t>
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int valuestep = PIXEL::maxChannelValue / (levels - 1);
Shinya Kitaoka 120a6e
  int step      = PIXEL::maxChannelValue / levels;
Shinya Kitaoka 120a6e
  for (j = 0; j < levels; j++)
Shinya Kitaoka 120a6e
    for (i = 0; i <= step; i++) lut[i + j * step] = j * valuestep;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class PosterizeFx final : public TStandardRasterFx {
Shinya Kitaoka 120a6e
  FX_PLUGIN_DECLARATION(PosterizeFx)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterFxPort m_input;
Shinya Kitaoka 120a6e
  TDoubleParamP m_levels;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PosterizeFx() : m_levels(7.0) {
Shinya Kitaoka 120a6e
    bindParam(this, "levels", m_levels);
Shinya Kitaoka 120a6e
    addInputPort("Source", m_input);
Shinya Kitaoka 120a6e
    m_levels->setValueRange(2.0, 10.0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~PosterizeFx(){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 38fd86
                 const TRenderSettings &info) override {
Shinya Kitaoka 120a6e
    if (m_input.isConnected()) {
Shinya Kitaoka 120a6e
      bool ret = m_input->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
      return ret;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      bBox = TRectD();
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool canHandle(const TRenderSettings &info, double frame) override {
Shinya Kitaoka 38fd86
    return true;
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename channel_type="" pixel,="" typename=""></typename>
Shinya Kitaoka 120a6e
void doPosterize(TRasterPT<pixel> ras, int levels) {</pixel>
Shinya Kitaoka 120a6e
  std::vector<channel_type> solarize_lut(PIXEL::maxChannelValue + 1);</channel_type>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  prepare_lut<channel_type, pixel="">(levels, solarize_lut);</channel_type,>
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  for (j = 0; j < ras->getLy(); j++) {
Shinya Kitaoka 120a6e
    PIXEL *pix    = ras->pixels(j);
Shinya Kitaoka 120a6e
    PIXEL *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      pix->r = (CHANNEL_TYPE)(solarize_lut[(int)(pix->r)]);
Shinya Kitaoka 120a6e
      pix->g = (CHANNEL_TYPE)(solarize_lut[(int)(pix->g)]);
Shinya Kitaoka 120a6e
      pix->b = (CHANNEL_TYPE)(solarize_lut[(int)(pix->b)]);
Shinya Kitaoka 120a6e
      *pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PosterizeFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                            const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  if (!m_input.isConnected()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_input->compute(tile, frame, ri);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int levels          = (int)m_levels->getValue(frame);
Shinya Kitaoka 120a6e
  TRaster32P raster32 = tile.getRaster();
Shinya Kitaoka 120a6e
  if (raster32)
Shinya Kitaoka 120a6e
    doPosterize<tpixel32, uchar="">(raster32, levels);</tpixel32,>
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRaster64P raster64 = tile.getRaster();
Shinya Kitaoka 120a6e
    if (raster64)
Shinya Kitaoka 120a6e
      doPosterize<tpixel64, ushort="">(raster64, levels);</tpixel64,>
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      throw TException("Brightness&Contrast: unsupported Pixel Type");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(PosterizeFx, "posterizeFx");