Toshihiro Shimizu 890ddd
#include "iwa_adjustexposurefx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 ソース画像を0〜1に正規化してホストメモリに読み込む
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void Iwa_AdjustExposureFx::setSourceRaster(const RASTER srcRas,
Toshihiro Shimizu 890ddd
										   float4 *dstMem,
Toshihiro Shimizu 890ddd
										   TDimensionI dim)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float4 *chann_p = dstMem;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int j = 0; j < dim.ly; j++) {
Toshihiro Shimizu 890ddd
		PIXEL *pix = srcRas->pixels(j);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < dim.lx; i++) {
Toshihiro Shimizu 890ddd
			(*chann_p).x = (float)pix->r / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			(*chann_p).y = (float)pix->g / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			(*chann_p).z = (float)pix->b / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			(*chann_p).w = (float)pix->m / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
			chann_p++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 出力結果をChannel値に変換してタイルに格納
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void Iwa_AdjustExposureFx::setOutputRaster(float4 *srcMem,
Toshihiro Shimizu 890ddd
										   const RASTER dstRas,
Toshihiro Shimizu 890ddd
										   TDimensionI dim)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float4 *chan_p = srcMem;
Toshihiro Shimizu 890ddd
	for (int j = 0; j < dim.ly; j++) {
Toshihiro Shimizu 890ddd
		PIXEL *pix = dstRas->pixels(j);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < dim.lx; i++) {
Toshihiro Shimizu 890ddd
			float val;
Toshihiro Shimizu 890ddd
			val = (*chan_p).x * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->r = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = (*chan_p).y * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->g = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = (*chan_p).z * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->b = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = (*chan_p).w * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->m = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
			chan_p++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Iwa_AdjustExposureFx::Iwa_AdjustExposureFx()
Toshihiro Shimizu 890ddd
	: m_hardness(3.3), m_scale(0.0), m_offset(0.0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	addInputPort("Source", m_source);
Toshihiro Shimizu 890ddd
	bindParam(this, "hardness", m_hardness, false);
Toshihiro Shimizu 890ddd
	bindParam(this, "scale", m_scale, false);
Toshihiro Shimizu 890ddd
	bindParam(this, "offset", m_offset, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_hardness->setValueRange(0.05, 20.0);
Toshihiro Shimizu 890ddd
	m_scale->setValueRange(-10.0, 10.0);
Toshihiro Shimizu 890ddd
	m_offset->setValueRange(-0.5, 0.5);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_AdjustExposureFx::doCompute(TTile &tile,
Toshihiro Shimizu 890ddd
									 double frame,
Toshihiro Shimizu 890ddd
									 const TRenderSettings &settings)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*- Sourceが無ければreturn -*/
Toshihiro Shimizu 890ddd
	if (!m_source.isConnected()) {
Toshihiro Shimizu 890ddd
		tile.getRaster()->clear();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_source->compute(tile, frame, settings);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float4 *tile_host;
Toshihiro Shimizu 890ddd
	TDimensionI dim(tile.getRaster()->getSize());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- ホストメモリ確保 -*/
Toshihiro Shimizu 890ddd
	TRasterGR8P tile_host_ras(sizeof(float4) * dim.lx, dim.ly);
Toshihiro Shimizu 890ddd
	tile_host_ras->lock();
Toshihiro Shimizu 890ddd
	tile_host = (float4 *)tile_host_ras->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P ras32 = tile.getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P ras64 = tile.getRaster();
Toshihiro Shimizu 890ddd
	if (ras32)
Toshihiro Shimizu 890ddd
		setSourceRaster<traster32p, tpixel32="">(ras32, tile_host, dim);</traster32p,>
Toshihiro Shimizu 890ddd
	else if (ras64)
Toshihiro Shimizu 890ddd
		setSourceRaster<traster64p, tpixel64="">(ras64, tile_host, dim);</traster64p,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	doCompute_CPU(tile, frame, settings, dim, tile_host);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*-  出力結果をチャンネル値に変換 -*/
Toshihiro Shimizu 890ddd
	tile.getRaster()->clear();
Toshihiro Shimizu 890ddd
	if (ras32)
Toshihiro Shimizu 890ddd
		setOutputRaster<traster32p, tpixel32="">(tile_host, ras32, dim);</traster32p,>
Toshihiro Shimizu 890ddd
	else if (ras64)
Toshihiro Shimizu 890ddd
		setOutputRaster<traster64p, tpixel64="">(tile_host, ras64, dim);</traster64p,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tile_host_ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_AdjustExposureFx::doCompute_CPU(TTile &tile,
Toshihiro Shimizu 890ddd
										 double frame,
Toshihiro Shimizu 890ddd
										 const TRenderSettings &settings,
Toshihiro Shimizu 890ddd
										 TDimensionI &dim,
Toshihiro Shimizu 890ddd
										 float4 *tile_host)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float hardness = (float)m_hardness->getValue(frame);
Toshihiro Shimizu 890ddd
	float scale = (float)m_scale->getValue(frame);
Toshihiro Shimizu 890ddd
	float offset = (float)m_offset->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float exposureOffset = (powf(10.0f, (float)(abs(offset) / hardness)) - 1.0f) * ((offset < 0.0f) ? -1.0f : 1.0f);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float4 *pix = tile_host;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int size = dim.lx * dim.ly;
Toshihiro Shimizu 890ddd
	for (int i = 0; i < size; i++, pix++) {
Toshihiro Shimizu 890ddd
		/*- RGB->Exposure -*/
Toshihiro Shimizu 890ddd
		pix->x = powf(10, (pix->x - 0.5f) * hardness);
Toshihiro Shimizu 890ddd
		pix->y = powf(10, (pix->y - 0.5f) * hardness);
Toshihiro Shimizu 890ddd
		pix->z = powf(10, (pix->z - 0.5f) * hardness);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- スケール -*/
Toshihiro Shimizu 890ddd
		pix->x *= powf(10, scale);
Toshihiro Shimizu 890ddd
		pix->y *= powf(10, scale);
Toshihiro Shimizu 890ddd
		pix->z *= powf(10, scale);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- オフセット -*/
Toshihiro Shimizu 890ddd
		pix->x += exposureOffset;
Toshihiro Shimizu 890ddd
		pix->y += exposureOffset;
Toshihiro Shimizu 890ddd
		pix->z += exposureOffset;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- Exposure->RGB -*/
Toshihiro Shimizu 890ddd
		pix->x = log10f(pix->x) / hardness + 0.5f;
Toshihiro Shimizu 890ddd
		pix->y = log10f(pix->y) / hardness + 0.5f;
Toshihiro Shimizu 890ddd
		pix->z = log10f(pix->z) / hardness + 0.5f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- クランプ -*/
Toshihiro Shimizu 890ddd
		pix->x = (pix->x > 1.0f) ? 1.0f : ((pix->x < 0.0f) ? 0.0f : pix->x);
Toshihiro Shimizu 890ddd
		pix->y = (pix->y > 1.0f) ? 1.0f : ((pix->y < 0.0f) ? 0.0f : pix->y);
Toshihiro Shimizu 890ddd
		pix->z = (pix->z > 1.0f) ? 1.0f : ((pix->z < 0.0f) ? 0.0f : pix->z);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Iwa_AdjustExposureFx::doGetBBox(double frame,
Toshihiro Shimizu 890ddd
									 TRectD &bBox,
Toshihiro Shimizu 890ddd
									 const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_source.isConnected()) {
Toshihiro Shimizu 890ddd
		bool ret = m_source->doGetBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
		return ret;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		bBox = TRectD();
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Iwa_AdjustExposureFx::canHandle(const TRenderSettings &info,
Toshihiro Shimizu 890ddd
									 double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(Iwa_AdjustExposureFx, "iwa_AdjustExposureFx")