#ifdef NDEBUG /*------------------------------------------------------------------*/ #include /* std::ostringstream */ #include "tfxparam.h" #include "stdfx.h" #include "tfxattributes.h" #include "ino_common.h" #include "igs_line_blur.h" class ino_line_blur final : public TStandardRasterFx { FX_PLUGIN_DECLARATION(ino_line_blur) TRasterFxPort m_input; TIntEnumParamP m_b_action_mode; TDoubleParamP m_b_blur_count; TDoubleParamP m_b_blur_power; TIntEnumParamP m_b_blur_subpixel; TDoubleParamP m_b_blur_near_ref; TDoubleParamP m_b_blur_near_len; TDoubleParamP m_v_smooth_retry; TDoubleParamP m_v_near_ref; TDoubleParamP m_v_near_len; TDoubleParamP m_b_smudge_thick; TDoubleParamP m_b_smudge_remain; public: ino_line_blur() : m_b_action_mode(new TIntEnumParam(0, "Blur")) , m_b_blur_count(51) , m_b_blur_power(1.0) , m_b_blur_subpixel(new TIntEnumParam()) , m_b_blur_near_ref(5) , m_b_blur_near_len(160) , m_v_smooth_retry(100) , m_v_near_ref(4) , m_v_near_len(160) , m_b_smudge_thick(7) , m_b_smudge_remain(0.85) { addInputPort("Source", this->m_input); bindParam(this, "action_mode", this->m_b_action_mode); bindParam(this, "blur_count", this->m_b_blur_count); bindParam(this, "blur_power", this->m_b_blur_power); bindParam(this, "blur_subpixel", this->m_b_blur_subpixel); bindParam(this, "blur_near_ref", this->m_b_blur_near_ref); bindParam(this, "blur_near_len", this->m_b_blur_near_len); bindParam(this, "vector_smooth_retry", this->m_v_smooth_retry); bindParam(this, "vector_near_ref", this->m_v_near_ref); bindParam(this, "vector_near_len", this->m_v_near_len); bindParam(this, "smudge_thick", this->m_b_smudge_thick); bindParam(this, "smudge_remain", this->m_b_smudge_remain); this->m_b_action_mode->addItem(1, "Smudge"); this->m_b_blur_count->setValueRange(1, 100); this->m_b_blur_power->setValueRange(0.1, 10.0); this->m_b_blur_subpixel->addItem(1, "1"); this->m_b_blur_subpixel->addItem(2, "4"); this->m_b_blur_subpixel->addItem(3, "9"); this->m_b_blur_subpixel->setDefaultValue(2); this->m_b_blur_subpixel->setValue(2); this->m_b_blur_near_ref->setValueRange(1, 100); this->m_b_blur_near_len->setValueRange(1, 1000); this->m_v_smooth_retry->setValueRange(1, 1000); this->m_v_near_ref->setValueRange(1, 100); this->m_v_near_len->setValueRange(1, 1000); this->m_b_smudge_thick->setValueRange(1, 100); this->m_b_smudge_remain->setValueRange(0.0, 1.0); } double get_render_real_radius(const double frame, const TAffine affine) { double rad = this->m_b_blur_count->getValue(frame); /*--- 単位について考察必要 ---*/ // rad *= ino::pixel_per_mm(); /*--- Geometryを反映させる ---*/ // TAffine aff(affine); return rad; } void get_render_enlarge(const double frame, const TAffine affine, TRectD &bBox) { const int margin = static_cast(ceil(this->get_render_real_radius(frame, affine))); if (0 < margin) { bBox = bBox.enlarge(static_cast(margin)); } } bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) override { if (false == this->m_input.isConnected()) { bBox = TRectD(); return false; } const bool ret = this->m_input->doGetBBox(frame, bBox, info); this->get_render_enlarge(frame, info.m_affine, bBox); return ret; } int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info) override { TRectD bBox(rect); this->get_render_enlarge(frame, info.m_affine, bBox); return TRasterFx::memorySize(bBox, info.m_bpp); } void transform(double frame, int port, const TRectD &rectOnOutput, const TRenderSettings &infoOnOutput, TRectD &rectOnInput, TRenderSettings &infoOnInput) override { rectOnInput = rectOnOutput; infoOnInput = infoOnOutput; this->get_render_enlarge(frame, infoOnOutput.m_affine, rectOnInput); } bool canHandle(const TRenderSettings &info, double frame) override { // return true;/* geometry処理済の画像に加工することになる */ return false; /* ここでの処理後にgeometryがかかる */ } void doCompute(TTile &tile, double frame, const TRenderSettings &rend_sets) override; }; FX_PLUGIN_IDENTIFIER(ino_line_blur, "inoLineBlurFx"); namespace { void fx_(const TRasterP in_ras // no margin , TRasterP out_ras // no margin , const int action_mode, const int blur_count, const double blur_power, const int blur_subpixel, const int blur_near_ref, const int blur_near_len, const int vector_smooth_retry, const int vector_near_ref, const int vector_near_len, const int smudge_thick, const double smudge_remain) { igs::line_blur::convert( in_ras->getRawData(), // const void *in_no_margin (BGRA) out_ras->getRawData(), // void *out_no_margin (BGRA) in_ras->getLy(), // const int height_no_margin in_ras->getLx(), // const int width_no_margin in_ras->getWrap(), out_ras->getWrap(), ino::channels(), // const int channels ino::bits(in_ras), // const int bits blur_count, blur_power, blur_subpixel, blur_near_ref, blur_near_len, smudge_thick, smudge_remain, vector_smooth_retry, vector_near_ref, vector_near_len, false, /* bool mv_sw false=OFF */ false, /* bool pv_sw false=OFF */ false, /* bool cv_sw false=OFF */ 3, /* long reference_channel 3=Red:RGBA or Blue:BGRA */ false, /* bool debug_save_sw false=OFF */ action_mode); } } // namespace void ino_line_blur::doCompute( TTile &tile, /* 注意:doGetBBox(-)が返す範囲の画像 */ double frame, const TRenderSettings &rend_sets) { /*--- 接続していなければ処理しない -------------------------*/ if (!this->m_input.isConnected()) { tile.getRaster()->clear(); /* 塗りつぶしクリア */ return; } /*--- サポートしていないPixelタイプはエラーを投げる --------*/ if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) { throw TRopException("unsupported input pixel type"); } /*--- パラメータを得る -------------------------------------*/ const int action_mode = this->m_b_action_mode->getValue(); const int blur_count = this->m_b_blur_count->getValue(frame); const double blur_power = this->m_b_blur_power->getValue(frame); const int blur_subpixel = this->m_b_blur_subpixel->getValue(); const int blur_near_ref = this->m_b_blur_near_ref->getValue(frame); const int blur_near_len = this->m_b_blur_near_len->getValue(frame); const int vector_smooth_retry = this->m_v_smooth_retry->getValue(frame); const int vector_near_ref = this->m_v_near_ref->getValue(frame); const int vector_near_len = this->m_v_near_len->getValue(frame); const int smudge_thick = this->m_b_smudge_thick->getValue(frame); const double smudge_remain = this->m_b_smudge_remain->getValue(frame); /*--- 表示の範囲を得る -------------------------------------*/ TRectD bBox = TRectD(tile.m_pos, /* Render画像上(Pixel単位)の位置 */ TDimensionD(/* Render画像上(Pixel単位)のサイズ */ tile.getRaster()->getLx(), tile.getRaster()->getLy())); /*--- doGetBBox(-)が返す範囲の画像を生成 -------------------*/ TTile in_tile; this->m_input->allocateAndCompute( in_tile, bBox.getP00(), TDimensionI(/* Pixel単位に四捨五入 */ static_cast(bBox.getLx() + 0.5), static_cast(bBox.getLy() + 0.5)), tile.getRaster(), frame, rend_sets); /*--- 保存すべき画像メモリを塗りつぶしクリア ---------------*/ tile.getRaster()->clear(); /*--- 画像処理 ---------------------------------------------*/ try { tile.getRaster()->lock(); fx_(in_tile.getRaster() // in no margin , tile.getRaster() // out no margin , action_mode, blur_count, blur_power, blur_subpixel, blur_near_ref, blur_near_len, vector_smooth_retry, vector_near_ref, vector_near_len, smudge_thick, smudge_remain); tile.getRaster()->unlock(); } /*--- error処理 --------------------------------------------*/ catch (std::bad_alloc &) { tile.getRaster()->unlock(); throw; } catch (std::exception &) { tile.getRaster()->unlock(); throw; } catch (...) { tile.getRaster()->unlock(); throw; } } #endif