void Iwa_GradientWarpFx::doCompute(TTile &tile,
								   double frame,
								   const TRenderSettings &settings)
{
	/*- ソース画像が刺さっていなければreturn -*/
	if (!m_source.isConnected()) {
		tile.getRaster()->clear();
		return;
	}
	/*- 参照画像が刺さっていなければ、ソース画像をそのまま返す -*/
	if (!m_warper.isConnected()) {
		m_source->compute(tile, frame, settings);
		return;
	}

	/*-  計算パラメータを得る -*/
	/*- 移動距離のピクセルサイズ -*/
	/*--- 拡大縮小(移動回転しないで)のGeometryを反映させる ---*/
	double k = sqrt(fabs(settings.m_affine.det()));
	double hLength = m_h_maxlen->getValue(frame) * k;
	double vLength = m_v_maxlen->getValue(frame) * k;

	double scale = m_scale->getValue(frame);

	/*- ワープ距離が0なら、ソース画像をそのまま返す -*/
	if (hLength == 0.0 && vLength == 0.0) {
		m_source->compute(tile, frame, settings);
		return;
	}

	int margin = static_cast<int>(ceil((abs(hLength) < abs(vLength)) ? abs(vLength) : abs(hLength)));

	/*- 素材計算範囲を計算 -*/
	/*- 出力範囲 -*/
	TRectD rectOut(tile.m_pos, TDimensionD(
								   tile.getRaster()->getLx(), tile.getRaster()->getLy()));
	TRectD enlargedRect = rectOut.enlarge((double)margin);
	TDimensionI enlargedDim((int)enlargedRect.getLx(), (int)enlargedRect.getLy());

	/*- ソース画像を正規化して格納 -*/
	float4 *source_host;
	TRasterGR8P source_host_ras(enlargedDim.lx * sizeof(float4), enlargedDim.ly);
	source_host_ras->lock();
	source_host = (float4 *)source_host_ras->getRawData();
	{
		/*- タイルはこのフォーカス内だけ使用。正規化してsource_hostに取り込んだらもう使わない。 -*/
		TTile sourceTile;
		m_source->allocateAndCompute(
			sourceTile, enlargedRect.getP00(),
			enlargedDim,
			tile.getRaster(), frame, settings);
		/*- タイルの画像を0〜1に正規化してホストメモリに読み込む -*/
		TRaster32P ras32 = (TRaster32P)sourceTile.getRaster();
		TRaster64P ras64 = (TRaster64P)sourceTile.getRaster();
		if (ras32)
			setSourceRaster<TRaster32P, TPixel32>(ras32, source_host, enlargedDim);
		else if (ras64)
			setSourceRaster<TRaster64P, TPixel64>(ras64, source_host, enlargedDim);
	}

	/*- 参照画像を正規化して格納 -*/
	float *warper_host;
	TRasterGR8P warper_host_ras(enlargedDim.lx * sizeof(float), enlargedDim.ly);
	warper_host_ras->lock();
	warper_host = (float *)warper_host_ras->getRawData();
	{
		/*- タイルはこのフォーカス内だけ使用。正規化してwarper_hostに取り込んだらもう使わない -*/
		TTile warperTile;
		m_warper->allocateAndCompute(
			warperTile, enlargedRect.getP00(),
			enlargedDim,
			tile.getRaster(), frame, settings);
		/*- タイルの画像の輝度値を0〜1に正規化してホストメモリに読み込む -*/
		TRaster32P ras32 = (TRaster32P)warperTile.getRaster();
		TRaster64P ras64 = (TRaster64P)warperTile.getRaster();
		if (ras32)
			setWarperRaster<TRaster32P, TPixel32>(ras32, warper_host, enlargedDim);
		else if (ras64)
			setWarperRaster<TRaster64P, TPixel64>(ras64, warper_host, enlargedDim);
	}

	/*- 変位値をScale倍して増やす -*/
	hLength *= scale;
	vLength *= scale;

	TRasterGR8P result_host_ras;

	result_host_ras = TRasterGR8P(enlargedDim.lx * sizeof(float4), enlargedDim.ly);
	/*- 結果を収めるメモリ -*/
	float4 *result_host;
	result_host_ras->lock();
	result_host = (float4 *)result_host_ras->getRawData();
	doCompute_CPU(tile, frame, settings,
				  hLength, vLength,
				  margin,
				  enlargedDim,
				  source_host,
				  warper_host,
				  result_host);
	/*- ポインタ入れ替え -*/
	source_host = result_host;

	int2 yohaku = {(enlargedDim.lx - tile.getRaster()->getSize().lx) / 2,
				   (enlargedDim.ly - tile.getRaster()->getSize().ly) / 2};
	/*- ラスタのクリア -*/
	tile.getRaster()->clear();
	TRaster32P outRas32 = (TRaster32P)tile.getRaster();
	TRaster64P outRas64 = (TRaster64P)tile.getRaster();
	if (outRas32)
		setOutputRaster<TRaster32P, TPixel32>(source_host, outRas32, enlargedDim, yohaku);
	else if (outRas64)
		setOutputRaster<TRaster64P, TPixel64>(source_host, outRas64, enlargedDim, yohaku);

	/*- ソース画像のメモリ解放 -*/
	source_host_ras->unlock();
	/*- 参照画像のメモリ解放 -*/
	warper_host_ras->unlock();
	result_host_ras->unlock();
}
Exemplo n.º 2
0
void Iwa_MotionBlurCompFx::doCompute(TTile &tile, double frame,
                                     const TRenderSettings &settings) {
  /*- 接続していない場合は処理しない -*/
  if (!m_input.isConnected() && !m_background.isConnected()) {
    tile.getRaster()->clear();
    return;
  }
  /*- BGのみ接続の場合 -*/
  if (!m_input.isConnected()) {
    m_background->compute(tile, frame, settings);
    return;
  }

  /*- 動作パラメータを得る -*/
  QList<TPointD> points = getAttributes()->getMotionPoints();
  double hardness       = m_hardness->getValue(frame);
  double shutterStart   = m_shutterStart->getValue(frame);
  double shutterEnd     = m_shutterEnd->getValue(frame);
  int traceResolution   = m_traceResolution->getValue();
  float startValue      = (float)m_startValue->getValue(frame);
  float startCurve      = (float)m_startCurve->getValue(frame);
  float endValue        = (float)m_endValue->getValue(frame);
  float endCurve        = (float)m_endCurve->getValue(frame);

  /*- 軌跡データが2つ以上無い場合は、処理しない -*/
  if (points.size() < 2) {
    if (!m_background.isConnected()) m_input->compute(tile, frame, settings);
    /*- 背景があり、前景が動かない場合、単純にOverする -*/
    else
      composeWithNoMotion(tile, frame, settings);
    return;
  }
  /*-  表示の範囲を得る -*/
  TRectD bBox =
      TRectD(tile.m_pos /*- Render画像上(Pixel単位)の位置 -*/
             ,
             TDimensionD(/*- Render画像上(Pixel単位)のサイズ -*/
                         tile.getRaster()->getLx(), tile.getRaster()->getLy()));

  /*- 上下左右のマージンを得る -*/
  double minX = 0.0;
  double maxX = 0.0;
  double minY = 0.0;
  double maxY = 0.0;
  for (int p = 0; p < points.size(); p++) {
    if (points.at(p).x > maxX) maxX = points.at(p).x;
    if (points.at(p).x < minX) minX = points.at(p).x;
    if (points.at(p).y > maxY) maxY = points.at(p).y;
    if (points.at(p).y < minY) minY = points.at(p).y;
  }
  int marginLeft   = (int)ceil(abs(minX));
  int marginRight  = (int)ceil(abs(maxX));
  int marginTop    = (int)ceil(abs(maxY));
  int marginBottom = (int)ceil(abs(minY));

  /*- 動かない(=フィルタマージンが全て0)場合、入力タイルをそのまま返す -*/
  if (marginLeft == 0 && marginRight == 0 && marginTop == 0 &&
      marginBottom == 0) {
    if (!m_background.isConnected()) m_input->compute(tile, frame, settings);
    /*- 背景があり、前景が動かない場合、単純にOverする -*/
    else
      composeWithNoMotion(tile, frame, settings);
    return;
  }

  /*- マージンは、フィルタの上下左右を反転した寸法になる -*/
  TRectD enlargedBBox(bBox.x0 - (double)marginRight,
                      bBox.y0 - (double)marginTop, bBox.x1 + (double)marginLeft,
                      bBox.y1 + (double)marginBottom);

  // std::cout<<"Margin Left:"<<marginLeft<<" Right:"<<marginRight<<
  //	" Bottom:"<<marginBottom<<" Top:"<<marginTop<<std::endl;

  TDimensionI enlargedDimIn(/*- Pixel単位に四捨五入 -*/
                            (int)(enlargedBBox.getLx() + 0.5),
                            (int)(enlargedBBox.getLy() + 0.5));

  TTile enlarge_tile;
  m_input->allocateAndCompute(enlarge_tile, enlargedBBox.getP00(),
                              enlargedDimIn, tile.getRaster(), frame, settings);

  /*- 背景が必要な場合 -*/
  TTile back_Tile;
  if (m_background.isConnected()) {
    m_background->allocateAndCompute(back_Tile, tile.m_pos,
                                     tile.getRaster()->getSize(),
                                     tile.getRaster(), frame, settings);
  }

  //-------------------------------------------------------
  /*- 計算範囲 -*/
  TDimensionI dimOut(tile.getRaster()->getLx(), tile.getRaster()->getLy());
  TDimensionI filterDim(marginLeft + marginRight + 1,
                        marginTop + marginBottom + 1);

  /*- pointsTableの解放は各doCompute内でやっている -*/
  int pointAmount     = points.size();
  float4 *pointsTable = new float4[pointAmount];
  float dt = (float)(shutterStart + shutterEnd) / (float)traceResolution;
  for (int p = 0; p < pointAmount; p++) {
    pointsTable[p].x = (float)points.at(p).x;
    pointsTable[p].y = (float)points.at(p).y;
    /*- zにはp→p+1のベクトルの距離を格納 -*/
    if (p < pointAmount - 1) {
      float2 vec = {(float)(points.at(p + 1).x - points.at(p).x),
                    (float)(points.at(p + 1).y - points.at(p).y)};
      pointsTable[p].z = sqrtf(vec.x * vec.x + vec.y * vec.y);
    }
    /*- wにはシャッター時間のオフセットを格納 -*/
    pointsTable[p].w = -(float)shutterStart + (float)p * dt;
  }

  doCompute_CPU(tile, frame, settings, pointsTable, pointAmount, hardness,
                shutterStart, shutterEnd, traceResolution, startValue,
                startCurve, endValue, endCurve, marginLeft, marginRight,
                marginTop, marginBottom, enlargedDimIn, enlarge_tile, dimOut,
                filterDim, back_Tile);
}