<commit_before>/**
 * @file llwlparamset.cpp
 * @brief Implementation for the LLWLParamSet class.
 *
 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llwlparamset.h"
#include "llwlanimator.h"

#include "llwlparammanager.h"
#include "llglslshader.h"
#include "lluictrlfactory.h"
#include "llsliderctrl.h"
#include "pipeline.h"

#include <llgl.h>

#include <sstream>

LLWLParamSet::LLWLParamSet(void) :
	mName("Unnamed Preset"),
	mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f)
{}

static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update");

void LLWLParamSet::update(LLGLSLShader * shader) const
{
	LLFastTimer t(FTM_WL_PARAM_UPDATE);

	for(LLSD::map_const_iterator i = mParamValues.beginMap();
		i != mParamValues.endMap();
		++i)
	{
		const std::string& param = i->first;

		if (param == "star_brightness" || param == "preset_num" || param == "sun_angle" ||
			param == "east_angle" || param == "enable_cloud_scroll" ||
			param == "cloud_scroll_rate" || param == "lightnorm" )
		{
			continue;
		}

		if (param == "cloud_pos_density1")
		{
			LLVector4 val;
			val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
			val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
			val.mV[2] = (F32) i->second[2].asReal();
			val.mV[3] = (F32) i->second[3].asReal();

			stop_glerror();
			shader->uniform4fv(param, 1, val.mV);
			stop_glerror();
		}
		else if (param == "cloud_scale" || param == "cloud_shadow" ||
				 param == "density_multiplier" || param == "distance_multiplier" ||
				 param == "haze_density" || param == "haze_horizon" ||
				 param == "max_y" )
		{
			F32 val = (F32) i->second[0].asReal();

			stop_glerror();
			shader->uniform1f(param, val);
			stop_glerror();
		}
		else // param is the uniform name
		{
			// handle all the different cases
			if (i->second.isArray() && i->second.size() == 4)
			{
				LLVector4 val;

				val.mV[0] = (F32) i->second[0].asReal();
				val.mV[1] = (F32) i->second[1].asReal();
				val.mV[2] = (F32) i->second[2].asReal();
				val.mV[3] = (F32) i->second[3].asReal();

				stop_glerror();
				shader->uniform4fv(param, 1, val.mV);
				stop_glerror();
			}
			else if (i->second.isReal())
			{
				F32 val = (F32) i->second.asReal();

				stop_glerror();
				shader->uniform1f(param, val);
				stop_glerror();
			}
			else if (i->second.isInteger())
			{
				S32 val = (S32) i->second.asInteger();

				stop_glerror();
				shader->uniform1i(param, val);
				stop_glerror();
			}
			else if (i->second.isBoolean())
			{
				S32 val = (i->second.asBoolean() ? 1 : 0);

				stop_glerror();
				shader->uniform1i(param, val);
				stop_glerror();
			}
		}
	}

	if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender)
	{
		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
	} else {
		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
	}
}

void LLWLParamSet::set(const std::string& paramName, float x)
{
	// handle case where no array
	if(mParamValues[paramName].isReal())
	{
		mParamValues[paramName] = x;
	}

	// handle array
	else if(mParamValues[paramName].isArray() &&
			mParamValues[paramName][0].isReal())
	{
		mParamValues[paramName][0] = x;
	}
}

void LLWLParamSet::set(const std::string& paramName, float x, float y)
{
	mParamValues[paramName][0] = x;
	mParamValues[paramName][1] = y;
}

void LLWLParamSet::set(const std::string& paramName, float x, float y, float z)
{
	mParamValues[paramName][0] = x;
	mParamValues[paramName][1] = y;
	mParamValues[paramName][2] = z;
}

void LLWLParamSet::set(const std::string& paramName, float x, float y, float z, float w)
{
	mParamValues[paramName][0] = x;
	mParamValues[paramName][1] = y;
	mParamValues[paramName][2] = z;
	mParamValues[paramName][3] = w;
}

void LLWLParamSet::set(const std::string& paramName, const float * val)
{
	mParamValues[paramName][0] = val[0];
	mParamValues[paramName][1] = val[1];
	mParamValues[paramName][2] = val[2];
	mParamValues[paramName][3] = val[3];
}

void LLWLParamSet::set(const std::string& paramName, const LLVector4 & val)
{
	mParamValues[paramName][0] = val.mV[0];
	mParamValues[paramName][1] = val.mV[1];
	mParamValues[paramName][2] = val.mV[2];
	mParamValues[paramName][3] = val.mV[3];
}

void LLWLParamSet::set(const std::string& paramName, const LLColor4 & val)
{
	mParamValues[paramName][0] = val.mV[0];
	mParamValues[paramName][1] = val.mV[1];
	mParamValues[paramName][2] = val.mV[2];
	mParamValues[paramName][3] = val.mV[3];
}

LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error)
{
	// test to see if right type
	LLSD cur_val = mParamValues.get(paramName);
	if (!cur_val.isArray())
	{
		error = true;
		return LLVector4(0,0,0,0);
	}

	LLVector4 val;
	val.mV[0] = (F32) cur_val[0].asReal();
	val.mV[1] = (F32) cur_val[1].asReal();
	val.mV[2] = (F32) cur_val[2].asReal();
	val.mV[3] = (F32) cur_val[3].asReal();

	error = false;
	return val;
}

F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error)
{
	// test to see if right type
	LLSD cur_val = mParamValues.get(paramName);
	if (cur_val.isArray() && cur_val.size() != 0)
	{
		error = false;
		return (F32) cur_val[0].asReal();
	}

	if(cur_val.isReal())
	{
		error = false;
		return (F32) cur_val.asReal();
	}

	error = true;
	return 0;
}

void LLWLParamSet::setSunAngle(float val)
{
	// keep range 0 - 2pi
	if(val > F_TWO_PI || val < 0)
	{
		F32 num = val / F_TWO_PI;
		num -= floor(num);
		val = F_TWO_PI * num;
	}

	mParamValues["sun_angle"] = val;
}

void LLWLParamSet::setEastAngle(float val)
{
	// keep range 0 - 2pi
	if(val > F_TWO_PI || val < 0)
	{
		F32 num = val / F_TWO_PI;
		num -= floor(num);
		val = F_TWO_PI * num;
	}

	mParamValues["east_angle"] = val;
}

void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
{
	// set up the iterators

	// keep cloud positions and coverage the same
	/// TODO masking will do this later
	F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
	F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
	F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
	F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
	F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();

	LLSD srcVal;
	LLSD destVal;

	// Iterate through values
	for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
	{
		// If param exists in both src and dest, set the holder variables, otherwise skip
		if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first))
		{
			srcVal = src.mParamValues[iter->first];
			destVal = dest.mParamValues[iter->first];
		}
		else
		{
			continue;
		}

		if(iter->second.isReal())									// If it's a real, interpolate directly
		{
			iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight);
		}
		else if(iter->second.isArray() && iter->second[0].isReal()	// If it's an array of reals, loop through the reals and interpolate on those
				&& iter->second.size() == srcVal.size() && iter->second.size() == destVal.size())
		{
			// Actually do interpolation: old value + (difference in values * factor)
			for(int i=0; i < iter->second.size(); ++i)
			{
				// iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal();	// old way of doing it -- equivalent but one more operation
				iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight);
			}
		}
		else														// Else, skip
		{
			continue;
		}
	}

	// now mix the extra parameters
	setStarBrightness((1 - weight) * (F32) src.getStarBrightness()
		+ weight * (F32) dest.getStarBrightness());

	llassert(src.getSunAngle() >= - F_PI &&
					src.getSunAngle() <= 3 * F_PI);
	llassert(dest.getSunAngle() >= - F_PI &&
					dest.getSunAngle() <= 3 * F_PI);
	llassert(src.getEastAngle() >= 0 &&
					src.getEastAngle() <= 4 * F_PI);
	llassert(dest.getEastAngle() >= 0 &&
					dest.getEastAngle() <= 4 * F_PI);

	// sun angle and east angle require some handling to make sure
	// they go in circles.  Yes quaternions would work better.
	F32 srcSunAngle = src.getSunAngle();
	F32 destSunAngle = dest.getSunAngle();
	F32 srcEastAngle = src.getEastAngle();
	F32 destEastAngle = dest.getEastAngle();

	if(fabsf(srcSunAngle - destSunAngle) > F_PI)
	{
		if(srcSunAngle > destSunAngle)
		{
			destSunAngle += 2 * F_PI;
		}
		else
		{
			srcSunAngle += 2 * F_PI;
		}
	}

	if(fabsf(srcEastAngle - destEastAngle) > F_PI)
	{
		if(srcEastAngle > destEastAngle)
		{
			destEastAngle += 2 * F_PI;
		}
		else
		{
			srcEastAngle += 2 * F_PI;
		}
	}

	setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
	setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);

	// now setup the sun properly

	// reset those cloud positions
	mParamValues["cloud_pos_density1"][0] = cloudPos1X;
	mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
	mParamValues["cloud_pos_density2"][0] = cloudPos2X;
	mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
	mParamValues["cloud_shadow"][0] = cloudCover;
}

void LLWLParamSet::updateCloudScrolling(void)
{
	static LLTimer s_cloud_timer;

	F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();

	if(getEnableCloudScrollX())
	{
		mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f);
	}
	if(getEnableCloudScrollY())
	{
		mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f);
	}
}
<commit_msg>NORSPEC-230 Fix for incorrect gamma under water.<commit_after>/**
 * @file llwlparamset.cpp
 * @brief Implementation for the LLWLParamSet class.
 *
 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "llwlparamset.h"
#include "llwlanimator.h"

#include "llwlparammanager.h"
#include "llglslshader.h"
#include "lluictrlfactory.h"
#include "llsliderctrl.h"
#include "pipeline.h"

#include <llgl.h>

#include <sstream>

LLWLParamSet::LLWLParamSet(void) :
	mName("Unnamed Preset"),
	mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f)
{}

static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update");

void LLWLParamSet::update(LLGLSLShader * shader) const
{
	LLFastTimer t(FTM_WL_PARAM_UPDATE);

	for(LLSD::map_const_iterator i = mParamValues.beginMap();
		i != mParamValues.endMap();
		++i)
	{
		const std::string& param = i->first;

		if (param == "star_brightness" || param == "preset_num" || param == "sun_angle" ||
			param == "east_angle" || param == "enable_cloud_scroll" ||
			param == "cloud_scroll_rate" || param == "lightnorm" )
		{
			continue;
		}

		if (param == "cloud_pos_density1")
		{
			LLVector4 val;
			val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
			val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
			val.mV[2] = (F32) i->second[2].asReal();
			val.mV[3] = (F32) i->second[3].asReal();

			stop_glerror();
			shader->uniform4fv(param, 1, val.mV);
			stop_glerror();
		}
		else if (param == "cloud_scale" || param == "cloud_shadow" ||
				 param == "density_multiplier" || param == "distance_multiplier" ||
				 param == "haze_density" || param == "haze_horizon" ||
				 param == "max_y" )
		{
			F32 val = (F32) i->second[0].asReal();

			stop_glerror();
			shader->uniform1f(param, val);
			stop_glerror();
		}
		else // param is the uniform name
		{
			// handle all the different cases
			if (i->second.isArray() && i->second.size() == 4)
			{
				LLVector4 val;

				val.mV[0] = (F32) i->second[0].asReal();
				val.mV[1] = (F32) i->second[1].asReal();
				val.mV[2] = (F32) i->second[2].asReal();
				val.mV[3] = (F32) i->second[3].asReal();

				stop_glerror();
				shader->uniform4fv(param, 1, val.mV);
				stop_glerror();
			}
			else if (i->second.isReal())
			{
				F32 val = (F32) i->second.asReal();

				stop_glerror();
				shader->uniform1f(param, val);
				stop_glerror();
			}
			else if (i->second.isInteger())
			{
				S32 val = (S32) i->second.asInteger();

				stop_glerror();
				shader->uniform1i(param, val);
				stop_glerror();
			}
			else if (i->second.isBoolean())
			{
				S32 val = (i->second.asBoolean() ? 1 : 0);

				stop_glerror();
				shader->uniform1i(param, val);
				stop_glerror();
			}
		}
	}

	if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender)
	{
		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
	} else {
		shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
	}
}

void LLWLParamSet::set(const std::string& paramName, float x)
{
	// handle case where no array
	if(mParamValues[paramName].isReal())
	{
		mParamValues[paramName] = x;
	}

	// handle array
	else if(mParamValues[paramName].isArray() &&
			mParamValues[paramName][0].isReal())
	{
		mParamValues[paramName][0] = x;
	}
}

void LLWLParamSet::set(const std::string& paramName, float x, float y)
{
	mParamValues[paramName][0] = x;
	mParamValues[paramName][1] = y;
}

void LLWLParamSet::set(const std::string& paramName, float x, float y, float z)
{
	mParamValues[paramName][0] = x;
	mParamValues[paramName][1] = y;
	mParamValues[paramName][2] = z;
}

void LLWLParamSet::set(const std::string& paramName, float x, float y, float z, float w)
{
	mParamValues[paramName][0] = x;
	mParamValues[paramName][1] = y;
	mParamValues[paramName][2] = z;
	mParamValues[paramName][3] = w;
}

void LLWLParamSet::set(const std::string& paramName, const float * val)
{
	mParamValues[paramName][0] = val[0];
	mParamValues[paramName][1] = val[1];
	mParamValues[paramName][2] = val[2];
	mParamValues[paramName][3] = val[3];
}

void LLWLParamSet::set(const std::string& paramName, const LLVector4 & val)
{
	mParamValues[paramName][0] = val.mV[0];
	mParamValues[paramName][1] = val.mV[1];
	mParamValues[paramName][2] = val.mV[2];
	mParamValues[paramName][3] = val.mV[3];
}

void LLWLParamSet::set(const std::string& paramName, const LLColor4 & val)
{
	mParamValues[paramName][0] = val.mV[0];
	mParamValues[paramName][1] = val.mV[1];
	mParamValues[paramName][2] = val.mV[2];
	mParamValues[paramName][3] = val.mV[3];
}

LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error)
{
	// test to see if right type
	LLSD cur_val = mParamValues.get(paramName);
	if (!cur_val.isArray())
	{
		error = true;
		return LLVector4(0,0,0,0);
	}

	LLVector4 val;
	val.mV[0] = (F32) cur_val[0].asReal();
	val.mV[1] = (F32) cur_val[1].asReal();
	val.mV[2] = (F32) cur_val[2].asReal();
	val.mV[3] = (F32) cur_val[3].asReal();

	error = false;
	return val;
}

F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error)
{
	// test to see if right type
	LLSD cur_val = mParamValues.get(paramName);
	if (cur_val.isArray() && cur_val.size() != 0)
	{
		error = false;
		return (F32) cur_val[0].asReal();
	}

	if(cur_val.isReal())
	{
		error = false;
		return (F32) cur_val.asReal();
	}

	error = true;
	return 0;
}

void LLWLParamSet::setSunAngle(float val)
{
	// keep range 0 - 2pi
	if(val > F_TWO_PI || val < 0)
	{
		F32 num = val / F_TWO_PI;
		num -= floor(num);
		val = F_TWO_PI * num;
	}

	mParamValues["sun_angle"] = val;
}

void LLWLParamSet::setEastAngle(float val)
{
	// keep range 0 - 2pi
	if(val > F_TWO_PI || val < 0)
	{
		F32 num = val / F_TWO_PI;
		num -= floor(num);
		val = F_TWO_PI * num;
	}

	mParamValues["east_angle"] = val;
}

void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
{
	// set up the iterators

	// keep cloud positions and coverage the same
	/// TODO masking will do this later
	F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
	F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
	F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
	F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
	F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();

	LLSD srcVal;
	LLSD destVal;

	// Iterate through values
	for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
	{
		// If param exists in both src and dest, set the holder variables, otherwise skip
		if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first))
		{
			srcVal = src.mParamValues[iter->first];
			destVal = dest.mParamValues[iter->first];
		}
		else
		{
			continue;
		}

		if(iter->second.isReal())									// If it's a real, interpolate directly
		{
			iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight);
		}
		else if(iter->second.isArray() && iter->second[0].isReal()	// If it's an array of reals, loop through the reals and interpolate on those
				&& iter->second.size() == srcVal.size() && iter->second.size() == destVal.size())
		{
			// Actually do interpolation: old value + (difference in values * factor)
			for(int i=0; i < iter->second.size(); ++i)
			{
				// iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal();	// old way of doing it -- equivalent but one more operation
				iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight);
			}
		}
		else														// Else, skip
		{
			continue;
		}
	}

	// now mix the extra parameters
	setStarBrightness((1 - weight) * (F32) src.getStarBrightness()
		+ weight * (F32) dest.getStarBrightness());

	llassert(src.getSunAngle() >= - F_PI &&
					src.getSunAngle() <= 3 * F_PI);
	llassert(dest.getSunAngle() >= - F_PI &&
					dest.getSunAngle() <= 3 * F_PI);
	llassert(src.getEastAngle() >= 0 &&
					src.getEastAngle() <= 4 * F_PI);
	llassert(dest.getEastAngle() >= 0 &&
					dest.getEastAngle() <= 4 * F_PI);

	// sun angle and east angle require some handling to make sure
	// they go in circles.  Yes quaternions would work better.
	F32 srcSunAngle = src.getSunAngle();
	F32 destSunAngle = dest.getSunAngle();
	F32 srcEastAngle = src.getEastAngle();
	F32 destEastAngle = dest.getEastAngle();

	if(fabsf(srcSunAngle - destSunAngle) > F_PI)
	{
		if(srcSunAngle > destSunAngle)
		{
			destSunAngle += 2 * F_PI;
		}
		else
		{
			srcSunAngle += 2 * F_PI;
		}
	}

	if(fabsf(srcEastAngle - destEastAngle) > F_PI)
	{
		if(srcEastAngle > destEastAngle)
		{
			destEastAngle += 2 * F_PI;
		}
		else
		{
			srcEastAngle += 2 * F_PI;
		}
	}

	setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
	setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);

	// now setup the sun properly

	// reset those cloud positions
	mParamValues["cloud_pos_density1"][0] = cloudPos1X;
	mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
	mParamValues["cloud_pos_density2"][0] = cloudPos2X;
	mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
	mParamValues["cloud_shadow"][0] = cloudCover;
}

void LLWLParamSet::updateCloudScrolling(void)
{
	static LLTimer s_cloud_timer;

	F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();

	if(getEnableCloudScrollX())
	{
		mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f);
	}
	if(getEnableCloudScrollY())
	{
		mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f);
	}
}
<|endoftext|>


<commit_before>/** Copyright (C) 2016, 2017 European Spallation Source ERIC */

#include <common/Trace.h>
#include <gdgem/vmm2srs/EventletBuilderSRS.h>

// #undef TRC_LEVEL
// #define TRC_LEVEL TRC_L_DEB

BuilderSRS::BuilderSRS(SRSTime time_intepreter,
                       SRSMappings geometry_interpreter, std::string dump_dir,
                       bool dump_csv, bool dump_h5)
    : AbstractBuilder(dump_dir, dump_csv, dump_h5), parser_(1125),
      time_intepreter_(time_intepreter),
      geometry_interpreter_(geometry_interpreter) {
  if (dump_csv_) {
    vmmsave->tofile("# fec, chip_id, frame counter, srs timestamp, channel, "
                    "bcid, tdc, adc, overthreshold\n");
  }
}

AbstractBuilder::ResultStats BuilderSRS::process_buffer(char *buf, size_t size,
                                                        Clusterer &clusterer,
                                                        NMXHists &hists) {
  parser_.receive(buf, size);
  if (!parser_.elems)
    return AbstractBuilder::ResultStats();

  uint16_t fec_id = 1; /**< @todo not hardcode */
  uint16_t chip_id =
      parser_.srshdr.dataid & 0xf; /**< @todo may belong elswhere */
  uint32_t geom_errors{0};

  Eventlet eventlet;
  for (unsigned int i = 0; i < parser_.elems; i++) {
    auto &d = parser_.data[i];
    eventlet.time =
        time_intepreter_.timestamp(parser_.srshdr.time, d.bcid, d.tdc);
    eventlet.plane_id = geometry_interpreter_.get_plane(fec_id, chip_id);
    eventlet.strip = geometry_interpreter_.get_strip(fec_id, chip_id, d.chno);
    eventlet.adc = d.adc;
    eventlet.over_threshold = (d.overThreshold != 0);

    XTRACE(PROCESS, DEB,
           "srs/vmm timestamp: srs: 0x%08x, bc: 0x%08x, tdc: 0x%08x\n",
           parser_.srshdr.time, d.bcid, d.tdc);
    XTRACE(PROCESS, DEB, "srs/vmm chip: %d, channel: %d\n", chip_id, d.chno);
    XTRACE(PROCESS, DEB,
           "eventlet plane_id: %d, strip: %d, time: %" PRIu64 "\n",
           eventlet.plane_id, eventlet.strip, eventlet.time);
    /**< @todo flags? */

    if (eventlet.plane_id == NMX_INVALID_PLANE_ID) {
      geom_errors++;
      XTRACE(PROCESS, DEB, "Bad SRS mapping --  fec: %d, chip: %d\n", fec_id,
             chip_id);
    } else {
      hists.bin(eventlet);
      clusterer.insert(eventlet);
    }
    if (dump_csv_) {
      vmmsave->tofile("%2d, %2d, %u, %u, %2d, %d, %d, %d, %d\n", fec_id,
                      chip_id, parser_.srshdr.fc, parser_.srshdr.time, d.chno,
                      d.bcid, d.tdc, d.adc, d.overThreshold);
    }
      //printf("readout: time: %llu, plane: %d, strip: %d, adc: %d\n", eventlet.time, eventlet.plane_id, eventlet.strip, eventlet.adc);
  }

  return AbstractBuilder::ResultStats(parser_.elems, parser_.error,
                                      geom_errors);
}
<commit_msg>eliminated one more xtrace error; updates #32'<commit_after>/** Copyright (C) 2016, 2017 European Spallation Source ERIC */

#include <common/Trace.h>
#include <gdgem/vmm2srs/EventletBuilderSRS.h>

// #undef TRC_LEVEL
// #define TRC_LEVEL TRC_L_DEB

BuilderSRS::BuilderSRS(SRSTime time_intepreter,
                       SRSMappings geometry_interpreter, std::string dump_dir,
                       bool dump_csv, bool dump_h5)
    : AbstractBuilder(dump_dir, dump_csv, dump_h5), parser_(1125),
      time_intepreter_(time_intepreter),
      geometry_interpreter_(geometry_interpreter) {
  if (dump_csv_) {
    vmmsave->tofile("# fec, chip_id, frame counter, srs timestamp, channel, "
                    "bcid, tdc, adc, overthreshold\n");
  }
}

AbstractBuilder::ResultStats BuilderSRS::process_buffer(char *buf, size_t size,
                                                        Clusterer &clusterer,
                                                        NMXHists &hists) {
  parser_.receive(buf, size);
  if (!parser_.elems)
    return AbstractBuilder::ResultStats();

  uint16_t fec_id = 1; /**< @todo not hardcode */
  uint16_t chip_id =
      parser_.srshdr.dataid & 0xf; /**< @todo may belong elswhere */
  uint32_t geom_errors{0};

  Eventlet eventlet;
  for (unsigned int i = 0; i < parser_.elems; i++) {
    auto &d = parser_.data[i];
    eventlet.time =
        time_intepreter_.timestamp(parser_.srshdr.time, d.bcid, d.tdc);
    eventlet.plane_id = geometry_interpreter_.get_plane(fec_id, chip_id);
    eventlet.strip = geometry_interpreter_.get_strip(fec_id, chip_id, d.chno);
    eventlet.adc = d.adc;
    eventlet.over_threshold = (d.overThreshold != 0);

    XTRACE(PROCESS, DEB,
           "srs/vmm timestamp: srs: 0x%08x, bc: 0x%08x, tdc: 0x%08x\n",
           parser_.srshdr.time, d.bcid, d.tdc);
    XTRACE(PROCESS, DEB, "srs/vmm chip: %d, channel: %d\n", chip_id, d.chno);
    XTRACE(PROCESS, DEB,
           "eventlet plane_id: %d, strip: %d, time: %f\n",
           eventlet.plane_id, eventlet.strip, eventlet.time);
    /**< @todo flags? */

    if (eventlet.plane_id == NMX_INVALID_PLANE_ID) {
      geom_errors++;
      XTRACE(PROCESS, DEB, "Bad SRS mapping --  fec: %d, chip: %d\n", fec_id,
             chip_id);
    } else {
      hists.bin(eventlet);
      clusterer.insert(eventlet);
    }
    if (dump_csv_) {
      vmmsave->tofile("%2d, %2d, %u, %u, %2d, %d, %d, %d, %d\n", fec_id,
                      chip_id, parser_.srshdr.fc, parser_.srshdr.time, d.chno,
                      d.bcid, d.tdc, d.adc, d.overThreshold);
    }
      //printf("readout: time: %llu, plane: %d, strip: %d, adc: %d\n", eventlet.time, eventlet.plane_id, eventlet.strip, eventlet.adc);
  }

  return AbstractBuilder::ResultStats(parser_.elems, parser_.error,
                                      geom_errors);
}
<|endoftext|>


<commit_before>/*
* Copyright (c) 2013-2016 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* VapourSynth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "VapourSynth.h"
#include "VSScript.h"
#include "cython/vapoursynth_api.h"
#include <mutex>
#include <atomic>
#include <vector>

#ifdef VS_TARGET_OS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#endif

static std::once_flag flag;

struct VSScript : public VPYScriptExport {
};

static std::atomic<int> initializationCount(0);
static std::atomic<int> scriptId(1000);
static bool initialized = false;
static PyThreadState *ts = nullptr;
static PyGILState_STATE s;

static void real_init(void) {
#ifdef VS_TARGET_OS_WINDOWS
    // portable
    HMODULE module;
    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)&real_init, &module);
    std::vector<wchar_t> pathBuf(65536);
    GetModuleFileNameW(module, pathBuf.data(), (DWORD)pathBuf.size());
    std::wstring dllPath = pathBuf.data();
    dllPath.resize(dllPath.find_last_of('\\') + 1);
    std::wstring portableFilePath = dllPath + L"portable.vs";
    FILE *portableFile = _wfopen(portableFilePath.c_str(), L"rb");
    bool isPortable = !!portableFile;
    if (portableFile)
        fclose(portableFile);

    HMODULE pythonDll = nullptr;

    if (isPortable) {
        std::wstring pyPath = dllPath + L"\\python35.dll";
        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    } else {
        DWORD dwType = REG_SZ;
        HKEY hKey = 0;

        wchar_t value[1024];
        DWORD valueLength = 1000;
        if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\VapourSynth", &hKey) != ERROR_SUCCESS)
            return;
        LSTATUS status = RegQueryValueExW(hKey, L"PythonPath", nullptr, &dwType, (LPBYTE)&value, &valueLength);
        RegCloseKey(hKey);
        if (status != ERROR_SUCCESS)
            return;

        std::wstring pyPath = value;
        pyPath += L"\\python35.dll";

        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    }
    if (!pythonDll)
        return;
#endif
    int preInitialized = Py_IsInitialized();
    if (!preInitialized)
        Py_InitializeEx(0);
    s = PyGILState_Ensure();
    if (import_vapoursynth())
        return;
    if (vpy_initVSScript())
        return;
    ts = PyEval_SaveThread();
    initialized = true;
}

VS_API(int) vsscript_init() {
    std::call_once(flag, real_init);
    if (initialized)
        return ++initializationCount;
    else
        return initializationCount;
}

VS_API(int) vsscript_finalize(void) {
    int count = --initializationCount;
    assert(count >= 0);
    return count;
}

VS_API(int) vsscript_createScript(VSScript **handle) {
    *handle = new(std::nothrow)VSScript();
    if (*handle) {
        (*handle)->pyenvdict = nullptr;
        (*handle)->errstr = nullptr;
        (*handle)->id = ++scriptId;
        return vpy_createScript(*handle);
    } else {
        return 1;
    }
}

VS_API(int) vsscript_evaluateScript(VSScript **handle, const char *script, const char *scriptFilename, int flags) {
    if (*handle == nullptr) {
        *handle = new(std::nothrow)VSScript();
        if (*handle) {
            (*handle)->pyenvdict = nullptr;
            (*handle)->errstr = nullptr;
            (*handle)->id = ++scriptId;
        } else {
            return 1;
        }
    }
    return vpy_evaluateScript(*handle, script, scriptFilename ? scriptFilename : "<string>", flags);
}

VS_API(int) vsscript_evaluateFile(VSScript **handle, const char *scriptFilename, int flags) {
    if (*handle == nullptr) {
        *handle = new(std::nothrow)VSScript();
        if (*handle) {
            (*handle)->pyenvdict = nullptr;
            (*handle)->errstr = nullptr;
            (*handle)->id = ++scriptId;
        } else {
            return 1;
        }
    }
    return vpy_evaluateFile(*handle, scriptFilename, flags);
}

VS_API(void) vsscript_freeScript(VSScript *handle) {
    if (handle) {
        vpy_freeScript(handle);
        delete handle;
    }
}

VS_API(const char *) vsscript_getError(VSScript *handle) {
    if (handle)
        return vpy_getError(handle);
    else
        return "Invalid handle (NULL)";
}

VS_API(VSNodeRef *) vsscript_getOutput(VSScript *handle, int index) {
    return vpy_getOutput(handle, index);
}

VS_API(int) vsscript_clearOutput(VSScript *handle, int index) {
    return vpy_clearOutput(handle, index);
}

VS_API(VSCore *) vsscript_getCore(VSScript *handle) {
    return vpy_getCore(handle);
}

VS_API(const VSAPI *) vsscript_getVSApi(void) {
    return vpy_getVSApi();
}

VS_API(int) vsscript_getVariable(VSScript *handle, const char *name, VSMap *dst) {
    return vpy_getVariable(handle, name, dst);
}

VS_API(int) vsscript_setVariable(VSScript *handle, const VSMap *vars) {
    return vpy_setVariable(handle, vars);
}

VS_API(int) vsscript_clearVariable(VSScript *handle, const char *name) {
    return vpy_clearVariable(handle, name);
}

VS_API(void) vsscript_clearEnvironment(VSScript *handle) {
    vpy_clearEnvironment(handle);
}
<commit_msg>More python 3.6 fixes<commit_after>/*
* Copyright (c) 2013-2016 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* VapourSynth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "VapourSynth.h"
#include "VSScript.h"
#include "cython/vapoursynth_api.h"
#include <mutex>
#include <atomic>
#include <vector>

#ifdef VS_TARGET_OS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#endif

static std::once_flag flag;

struct VSScript : public VPYScriptExport {
};

static std::atomic<int> initializationCount(0);
static std::atomic<int> scriptId(1000);
static bool initialized = false;
static PyThreadState *ts = nullptr;
static PyGILState_STATE s;

static void real_init(void) {
#ifdef VS_TARGET_OS_WINDOWS
    // portable
    const std::wstring pythonDllName = L"python36.dll";
    HMODULE module;
    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)&real_init, &module);
    std::vector<wchar_t> pathBuf(65536);
    GetModuleFileNameW(module, pathBuf.data(), (DWORD)pathBuf.size());
    std::wstring dllPath = pathBuf.data();
    dllPath.resize(dllPath.find_last_of('\\') + 1);
    std::wstring portableFilePath = dllPath + L"portable.vs";
    FILE *portableFile = _wfopen(portableFilePath.c_str(), L"rb");
    bool isPortable = !!portableFile;
    if (portableFile)
        fclose(portableFile);

    HMODULE pythonDll = nullptr;

    if (isPortable) {
        std::wstring pyPath = dllPath + L"\\" + pythonDllName;
        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    } else {
        DWORD dwType = REG_SZ;
        HKEY hKey = 0;

        wchar_t value[1024];
        DWORD valueLength = 1000;
        if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\VapourSynth", &hKey) != ERROR_SUCCESS)
            return;
        LSTATUS status = RegQueryValueExW(hKey, L"PythonPath", nullptr, &dwType, (LPBYTE)&value, &valueLength);
        RegCloseKey(hKey);
        if (status != ERROR_SUCCESS)
            return;

        std::wstring pyPath = value;
        pyPath += L"\\" + pythonDllName;

        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    }
    if (!pythonDll)
        return;
#endif
    int preInitialized = Py_IsInitialized();
    if (!preInitialized)
        Py_InitializeEx(0);
    s = PyGILState_Ensure();
    if (import_vapoursynth())
        return;
    if (vpy_initVSScript())
        return;
    ts = PyEval_SaveThread();
    initialized = true;
}

VS_API(int) vsscript_init() {
    std::call_once(flag, real_init);
    if (initialized)
        return ++initializationCount;
    else
        return initializationCount;
}

VS_API(int) vsscript_finalize(void) {
    int count = --initializationCount;
    assert(count >= 0);
    return count;
}

VS_API(int) vsscript_createScript(VSScript **handle) {
    *handle = new(std::nothrow)VSScript();
    if (*handle) {
        (*handle)->pyenvdict = nullptr;
        (*handle)->errstr = nullptr;
        (*handle)->id = ++scriptId;
        return vpy_createScript(*handle);
    } else {
        return 1;
    }
}

VS_API(int) vsscript_evaluateScript(VSScript **handle, const char *script, const char *scriptFilename, int flags) {
    if (*handle == nullptr) {
        *handle = new(std::nothrow)VSScript();
        if (*handle) {
            (*handle)->pyenvdict = nullptr;
            (*handle)->errstr = nullptr;
            (*handle)->id = ++scriptId;
        } else {
            return 1;
        }
    }
    return vpy_evaluateScript(*handle, script, scriptFilename ? scriptFilename : "<string>", flags);
}

VS_API(int) vsscript_evaluateFile(VSScript **handle, const char *scriptFilename, int flags) {
    if (*handle == nullptr) {
        *handle = new(std::nothrow)VSScript();
        if (*handle) {
            (*handle)->pyenvdict = nullptr;
            (*handle)->errstr = nullptr;
            (*handle)->id = ++scriptId;
        } else {
            return 1;
        }
    }
    return vpy_evaluateFile(*handle, scriptFilename, flags);
}

VS_API(void) vsscript_freeScript(VSScript *handle) {
    if (handle) {
        vpy_freeScript(handle);
        delete handle;
    }
}

VS_API(const char *) vsscript_getError(VSScript *handle) {
    if (handle)
        return vpy_getError(handle);
    else
        return "Invalid handle (NULL)";
}

VS_API(VSNodeRef *) vsscript_getOutput(VSScript *handle, int index) {
    return vpy_getOutput(handle, index);
}

VS_API(int) vsscript_clearOutput(VSScript *handle, int index) {
    return vpy_clearOutput(handle, index);
}

VS_API(VSCore *) vsscript_getCore(VSScript *handle) {
    return vpy_getCore(handle);
}

VS_API(const VSAPI *) vsscript_getVSApi(void) {
    return vpy_getVSApi();
}

VS_API(int) vsscript_getVariable(VSScript *handle, const char *name, VSMap *dst) {
    return vpy_getVariable(handle, name, dst);
}

VS_API(int) vsscript_setVariable(VSScript *handle, const VSMap *vars) {
    return vpy_setVariable(handle, vars);
}

VS_API(int) vsscript_clearVariable(VSScript *handle, const char *name) {
    return vpy_clearVariable(handle, name);
}

VS_API(void) vsscript_clearEnvironment(VSScript *handle) {
    vpy_clearEnvironment(handle);
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <boost/program_options.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
namespace po = boost::program_options;
namespace fs = boost::filesystem;

#include <vw/Core/Debugging.h>
#include <vw/Math.h>
#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/InterestPoint/InterestData.h>
#include <vw/Stereo/OptimizedCorrelator.h>
#include <vw/Stereo/ReferenceCorrelator.h>
#include <vw/Stereo/PyramidCorrelator.h>

using namespace vw;
using namespace vw::stereo;

int main( int argc, char *argv[] ) {
  try {

    std::string left_file_name, right_file_name;
    float log, slog;
    int h_corr_min, h_corr_max;
    int v_corr_min, v_corr_max;
    int xkernel, ykernel;
    int lrthresh;
    float corrscore_thresh;
    int cost_blur;
    int correlator_type;
    bool found_alignment = false;
    Matrix3x3 alignment;

    po::options_description desc("Options");
    desc.add_options()
      ("help,h", "Display this help message")
      ("left", po::value(&left_file_name), "Explicitly specify the \"left\" input file")
      ("right", po::value(&right_file_name), "Explicitly specify the \"right\" input file")
      ("slog", po::value(&slog)->default_value(1.0), "Apply SLOG filter with the given sigma, or 0 to disable")
      ("log", po::value(&log)->default_value(0.0), "Apply LOG filter with the given sigma, or 0 to disable")
      ("h-corr-min", po::value(&h_corr_min)->default_value(0), "Minimum horizontal disparity")
      ("h-corr-max", po::value(&h_corr_max)->default_value(0), "Maximum horizontal disparity")
      ("v-corr-min", po::value(&v_corr_min)->default_value(5), "Minimum vertical disparity")
      ("v-corr-max", po::value(&v_corr_max)->default_value(5), "Maximum vertical disparity")
      ("xkernel", po::value(&xkernel)->default_value(15), "Horizontal correlation kernel size")
      ("ykernel", po::value(&ykernel)->default_value(15), "Vertical correlation kernel size")
      ("lrthresh", po::value(&lrthresh)->default_value(2), "Left/right correspondence threshold")
      ("csthresh", po::value(&corrscore_thresh)->default_value(1.0), "Correlation score rejection threshold (1.0 is Off <--> 2.0 is Aggressive outlier rejection")
      ("cost-blur", po::value(&cost_blur)->default_value(1), "Kernel size for bluring the cost image")
      ("correlator-type", po::value(&correlator_type)->default_value(0), "0 - Abs difference; 1 - Sq Difference; 2 - NormXCorr")
      ("hsubpix", "Enable horizontal sub-pixel correlation")
      ("vsubpix", "Enable vertical sub-pixel correlation")
      ("affine-subpix", "Enable affine adaptive sub-pixel correlation (slower, but more accurate)")
      ("reference", "Use the slower, simpler reference correlator")
      ("pyramid", "Use the pyramid based correlator")
      ("bitimage", "Force the use of the optimized bit-image correlator")
      ("nonbitimage", "Fore the use of the slower, non bit-image optimized correlator")
      ;
    po::positional_options_description p;
    p.add("left", 1);
    p.add("right", 1);

    po::variables_map vm;
    try {
      po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
      po::notify( vm );
    } catch (po::error &e) {
      std::cout << "An error occured while parsing command line arguments.\n";
      std::cout << "\t" << e.what() << "\n\n";
      std::cout << desc << std::endl;
      return 1;
    }

    if( vm.count("help") ) {
      vw_out() << desc << std::endl;
      return 1;
    }

    if( vm.count("left") != 1 || vm.count("right") != 1 ) {
      vw_out() << "Error: Must specify one (and only one) left and right input file!" << std::endl;
      vw_out() << desc << std::endl;
      return 1;
    }

    std::string match_filename = fs::path( left_file_name ).replace_extension().string() + "__" + fs::path( right_file_name ).stem() + ".match";
    if ( fs::exists( match_filename ) ) {
      vw_out() << "Found a match file. Using it to pre-align images.\n";
      std::vector<ip::InterestPoint> matched_ip1, matched_ip2;
      ip::read_binary_match_file( match_filename,
                                  matched_ip1, matched_ip2 );
      std::vector<Vector3> ransac_ip1 = ip::iplist_to_vectorlist(matched_ip1);
      std::vector<Vector3> ransac_ip2 = ip::iplist_to_vectorlist(matched_ip2);
      vw::math::RandomSampleConsensus<vw::math::HomographyFittingFunctor, vw::math::InterestPointErrorMetric> ransac( vw::math::HomographyFittingFunctor(), vw::math::InterestPointErrorMetric(), 30 );
      alignment = ransac( ransac_ip2, ransac_ip1 );

      DiskImageView<PixelGray<float> > right_disk_image( right_file_name );
      right_file_name = "aligned_right.tif";
      write_image( right_file_name, transform(right_disk_image, HomographyTransform(alignment)),
                   TerminalProgressCallback( "tools.correlate", "Aligning: ") );
      found_alignment = true;
    }

    DiskImageView<PixelGray<float> > left_disk_image(left_file_name );
    DiskImageView<PixelGray<float> > right_disk_image(right_file_name );
    int cols = std::max(left_disk_image.cols(),right_disk_image.cols());
    int rows = std::max(left_disk_image.rows(),right_disk_image.rows());
    ImageViewRef<PixelGray<float> > left = edge_extend(left_disk_image,0,0,cols,rows);
    ImageViewRef<PixelGray<float> > right = edge_extend(right_disk_image,0,0,cols,rows);

    ImageViewRef<uint8> left_mask = channel_cast<uint8>(select_channel(edge_mask(left_disk_image),1));
    ImageViewRef<uint8> right_mask = channel_cast<uint8>(select_channel(edge_mask(right_disk_image),1));

    stereo::CorrelatorType corr_type = ABS_DIFF_CORRELATOR; // the default
    if (correlator_type == 1)
      corr_type = SQR_DIFF_CORRELATOR;
    else if (correlator_type == 2)
      corr_type = NORM_XCORR_CORRELATOR;

    ImageView<PixelMask<Vector2f> > disparity_map;
    if (vm.count("reference")>0) {
      vw::stereo::ReferenceCorrelator correlator( h_corr_min, h_corr_max,
                                                  v_corr_min, v_corr_max,
                                                  xkernel, ykernel,
                                                  true, lrthresh,
                                                  (vm.count("hsubpix")>0),
                                                  (vm.count("vsubpix")>0),
                                                  (vm.count("affine-subpix")>0) );
      if (log > 0)
        disparity_map = correlator( left, right, stereo::LogStereoPreprocessingFilter(log));
      else
        disparity_map = correlator( left, right, stereo::SlogStereoPreprocessingFilter(slog));
    } else if (vm.count("pyramid")>0) {
      vw::stereo::PyramidCorrelator correlator( BBox2(Vector2(h_corr_min, v_corr_min),
                                                      Vector2(h_corr_max, v_corr_max)),
                                                Vector2i(xkernel, ykernel),
                                                lrthresh,
                                                corrscore_thresh,
                                                cost_blur,
                                                corr_type);
      correlator.set_debug_mode("debug");
      {
        vw::Timer corr_timer("Correlation Time");
        if (log > 0)
          disparity_map = correlator( left, right, left_mask, right_mask, stereo::LogStereoPreprocessingFilter(log));
        else
          disparity_map = correlator( left, right, left_mask, right_mask, stereo::SlogStereoPreprocessingFilter(slog));
      }
    } else {
      vw::stereo::OptimizedCorrelator correlator( BBox2i(Vector2(h_corr_min, v_corr_min),
                                                         Vector2(h_corr_max, v_corr_max)),
                                                  xkernel,
                                                  lrthresh,
                                                  corrscore_thresh,
                                                  cost_blur,
                                                  corr_type);
      {
        vw::Timer corr_timer("Correlation Time");
        if (log > 0)
          disparity_map = correlator( left, right, stereo::LogStereoPreprocessingFilter(log));
        else
          disparity_map = correlator( left, right, stereo::SlogStereoPreprocessingFilter(slog));
      }
    }

    ImageViewRef<PixelMask<Vector2f> > result = disparity_map;
    if ( found_alignment )
      result = transform_disparities(disparity_map, HomographyTransform(alignment) );

    // Write disparity debug images
    BBox2 disp_range = get_disparity_range(result);
    write_image( "x_disparity.png", normalize(clamp(select_channel(apply_mask(result, disp_range.min()),0), disp_range.min().x(), disp_range.max().x() )));
    write_image( "y_disparity.png", normalize(clamp(select_channel(apply_mask(result, disp_range.min()),1), disp_range.min().y(), disp_range.max().y() )));
  }
  catch( vw::Exception& e ) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
  return 0;
}

<commit_msg>Small improvements to correlate executable<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#include <boost/program_options.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
namespace po = boost::program_options;
namespace fs = boost::filesystem;

#include <vw/Core/Debugging.h>
#include <vw/Math.h>
#include <vw/Image.h>
#include <vw/FileIO.h>
#include <vw/InterestPoint/InterestData.h>
#include <vw/Stereo/OptimizedCorrelator.h>
#include <vw/Stereo/ReferenceCorrelator.h>
#include <vw/Stereo/PyramidCorrelator.h>

using namespace vw;
using namespace vw::stereo;

int main( int argc, char *argv[] ) {
  try {

    std::string left_file_name, right_file_name;
    float log, slog;
    int h_corr_min, h_corr_max;
    int v_corr_min, v_corr_max;
    int xkernel, ykernel;
    int lrthresh;
    float corrscore_thresh;
    int cost_blur;
    int correlator_type;
    bool found_alignment = false;
    Matrix3x3 alignment;

    po::options_description desc("Options");
    desc.add_options()
      ("help,h", "Display this help message")
      ("left", po::value(&left_file_name), "Explicitly specify the \"left\" input file")
      ("right", po::value(&right_file_name), "Explicitly specify the \"right\" input file")
      ("slog", po::value(&slog)->default_value(1.0), "Apply SLOG filter with the given sigma, or 0 to disable")
      ("log", po::value(&log)->default_value(0.0), "Apply LOG filter with the given sigma, or 0 to disable")
      ("h-corr-min", po::value(&h_corr_min)->default_value(0), "Minimum horizontal disparity")
      ("h-corr-max", po::value(&h_corr_max)->default_value(0), "Maximum horizontal disparity")
      ("v-corr-min", po::value(&v_corr_min)->default_value(5), "Minimum vertical disparity")
      ("v-corr-max", po::value(&v_corr_max)->default_value(5), "Maximum vertical disparity")
      ("xkernel", po::value(&xkernel)->default_value(15), "Horizontal correlation kernel size")
      ("ykernel", po::value(&ykernel)->default_value(15), "Vertical correlation kernel size")
      ("lrthresh", po::value(&lrthresh)->default_value(2), "Left/right correspondence threshold")
      ("csthresh", po::value(&corrscore_thresh)->default_value(1.0), "Correlation score rejection threshold (1.0 is Off <--> 2.0 is Aggressive outlier rejection")
      ("cost-blur", po::value(&cost_blur)->default_value(1), "Kernel size for bluring the cost image")
      ("correlator-type", po::value(&correlator_type)->default_value(0), "0 - Abs difference; 1 - Sq Difference; 2 - NormXCorr")
      ("hsubpix", "Enable horizontal sub-pixel correlation")
      ("vsubpix", "Enable vertical sub-pixel correlation")
      ("affine-subpix", "Enable affine adaptive sub-pixel correlation (slower, but more accurate)")
      ("reference", "Use the slower, simpler reference correlator")
      ("pyramid", "Use the pyramid based correlator")
      ("bitimage", "Force the use of the optimized bit-image correlator")
      ("nonbitimage", "Fore the use of the slower, non bit-image optimized correlator")
      ;
    po::positional_options_description p;
    p.add("left", 1);
    p.add("right", 1);

    po::variables_map vm;
    try {
      po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
      po::notify( vm );
    } catch (po::error &e) {
      std::cout << "An error occured while parsing command line arguments.\n";
      std::cout << "\t" << e.what() << "\n\n";
      std::cout << desc << std::endl;
      return 1;
    }

    if( vm.count("help") ) {
      vw_out() << desc << std::endl;
      return 1;
    }

    if( vm.count("left") != 1 || vm.count("right") != 1 ) {
      vw_out() << "Error: Must specify one (and only one) left and right input file!" << std::endl;
      vw_out() << desc << std::endl;
      return 1;
    }

    std::string match_filename = fs::path( left_file_name ).replace_extension().string() + "__" + fs::path( right_file_name ).stem() + ".match";
    if ( fs::exists( match_filename ) ) {
      vw_out() << "Found a match file. Using it to pre-align images.\n";
      std::vector<ip::InterestPoint> matched_ip1, matched_ip2;
      ip::read_binary_match_file( match_filename,
                                  matched_ip1, matched_ip2 );
      std::vector<Vector3> ransac_ip1 = ip::iplist_to_vectorlist(matched_ip1);
      std::vector<Vector3> ransac_ip2 = ip::iplist_to_vectorlist(matched_ip2);
      vw::math::RandomSampleConsensus<vw::math::HomographyFittingFunctor, vw::math::InterestPointErrorMetric> ransac( vw::math::HomographyFittingFunctor(), vw::math::InterestPointErrorMetric(), 30 );
      alignment = ransac( ransac_ip2, ransac_ip1 );

      DiskImageView<PixelGray<float> > right_disk_image( right_file_name );
      right_file_name = "aligned_right.tif";
      write_image( right_file_name, transform(right_disk_image, HomographyTransform(alignment)),
                   TerminalProgressCallback( "tools.correlate", "Aligning: ") );
      found_alignment = true;
    }

    DiskImageView<PixelGray<float> > left_disk_image(left_file_name );
    DiskImageView<PixelGray<float> > right_disk_image(right_file_name );
    int cols = std::min(left_disk_image.cols(),right_disk_image.cols());
    int rows = std::min(left_disk_image.rows(),right_disk_image.rows());
    ImageViewRef<PixelGray<float> > left = edge_extend(left_disk_image,0,0,cols,rows);
    ImageViewRef<PixelGray<float> > right = edge_extend(right_disk_image,0,0,cols,rows);

    ImageViewRef<uint8> left_mask = select_channel(edge_mask(pixel_cast_rescale<uint8>(left)),1);
    ImageViewRef<uint8> right_mask = select_channel(edge_mask(pixel_cast_rescale<uint8>(right)),1);

    stereo::CorrelatorType corr_type = ABS_DIFF_CORRELATOR; // the default
    if (correlator_type == 1)
      corr_type = SQR_DIFF_CORRELATOR;
    else if (correlator_type == 2)
      corr_type = NORM_XCORR_CORRELATOR;

    ImageView<PixelMask<Vector2f> > disparity_map;
    if (vm.count("reference")) {
      vw::stereo::ReferenceCorrelator correlator( h_corr_min, h_corr_max,
                                                  v_corr_min, v_corr_max,
                                                  xkernel, ykernel,
                                                  true, lrthresh,
                                                  (vm.count("hsubpix")>0),
                                                  (vm.count("vsubpix")>0),
                                                  (vm.count("affine-subpix")>0) );
      if (log > 0)
        disparity_map = correlator( left, right, stereo::LogStereoPreprocessingFilter(log));
      else
        disparity_map = correlator( left, right, stereo::SlogStereoPreprocessingFilter(slog));
    } else if (vm.count("pyramid")) {
      vw::stereo::PyramidCorrelator correlator( BBox2(Vector2(h_corr_min, v_corr_min),
                                                      Vector2(h_corr_max, v_corr_max)),
                                                Vector2i(xkernel, ykernel),
                                                lrthresh,
                                                corrscore_thresh,
                                                cost_blur,
                                                corr_type);
      correlator.set_debug_mode("debug");
      {
        vw::Timer corr_timer("Correlation Time");
        if (log > 0)
          disparity_map = correlator( left, right, left_mask, right_mask, stereo::LogStereoPreprocessingFilter(log));
        else
          disparity_map = correlator( left, right, left_mask, right_mask, stereo::SlogStereoPreprocessingFilter(slog));
      }
    } else {
      vw::stereo::OptimizedCorrelator correlator( BBox2i(Vector2(h_corr_min, v_corr_min),
                                                         Vector2(h_corr_max, v_corr_max)),
                                                  xkernel,
                                                  lrthresh,
                                                  corrscore_thresh,
                                                  cost_blur,
                                                  corr_type);
      {
        vw::Timer corr_timer("Correlation Time");
        if (log > 0)
          disparity_map = correlator( left, right, stereo::LogStereoPreprocessingFilter(log));
        else
          disparity_map = correlator( left, right, stereo::SlogStereoPreprocessingFilter(slog));
      }
    }

    ImageViewRef<PixelMask<Vector2f> > result = disparity_map;
    if ( found_alignment )
      result = transform_disparities(disparity_map, HomographyTransform(alignment) );

    // Write disparity debug images
    BBox2 disp_range = get_disparity_range(result);
    std::cout << "Found disparity range: " << disp_range << "\n";
    ImageViewRef<float32> horizontal = apply_mask(copy_mask(clamp(normalize(select_channel(result,0), disp_range.min().x(), disp_range.max().x(),0,1)),result));
    ImageViewRef<float32> vertical = apply_mask(copy_mask(clamp(normalize(select_channel(result,1), disp_range.min().y(), disp_range.max().y(),0,1)),result));

    write_image( "x_disparity.png", channel_cast_rescale<uint8>(horizontal) );
    write_image( "y_disparity.png", channel_cast_rescale<uint8>(vertical) );
  }
  catch( vw::Exception& e ) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
  return 0;
}

<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2017 Axel Waggershauser
    Copyright (C) 2017 Roman Lebedev

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "decompressors/LJpegDecompressor.h"
#include "common/Common.h"                // for uint32, unroll_loop, ushort16
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpJPEG.h"               // for BitPumpJPEG
#include <algorithm>                      // for min, copy_n

using std::copy_n;

namespace rawspeed {

LJpegDecompressor::LJpegDecompressor(const ByteStream& bs, const RawImage& img)
    : AbstractLJpegDecompressor(bs, img) {
  if (mRaw->getDataType() != TYPE_USHORT16)
    ThrowRDE("Unexpected data type (%u)", mRaw->getDataType());

  if (!((mRaw->getCpp() == 1 && mRaw->getBpp() == 2) ||
        (mRaw->getCpp() == 3 && mRaw->getBpp() == 6)))
    ThrowRDE("Unexpected component count (%u)", mRaw->getCpp());

  if (mRaw->dim.x == 0 || mRaw->dim.y == 0)
    ThrowRDE("Image has zero size");

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  // Yeah, sure, here it would be just dumb to leave this for production :)
  if (mRaw->dim.x > 7424 || mRaw->dim.y > 5552) {
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x,
             mRaw->dim.y);
  }
#endif
}

void LJpegDecompressor::decode(uint32 offsetX, uint32 offsetY, uint32 width,
                               uint32 height, bool fixDng16Bug_) {
  if (offsetX >= static_cast<unsigned>(mRaw->dim.x))
    ThrowRDE("X offset outside of image");
  if (offsetY >= static_cast<unsigned>(mRaw->dim.y))
    ThrowRDE("Y offset outside of image");

  offX = offsetX;
  offY = offsetY;
  w = width;
  h = height;

  fixDng16Bug = fixDng16Bug_;

  AbstractLJpegDecompressor::decode();
}

void LJpegDecompressor::decodeScan()
{
  if (predictorMode != 1)
    ThrowRDE("Unsupported predictor mode: %u", predictorMode);

  for (uint32 i = 0; i < frame.cps;  i++)
    if (frame.compInfo[i].superH != 1 || frame.compInfo[i].superV != 1)
      ThrowRDE("Unsupported subsampling");

  assert(static_cast<unsigned>(mRaw->dim.x) > offX);
  if ((mRaw->getCpp() * (mRaw->dim.x - offX)) < frame.cps)
    ThrowRDE("Got less pixels than the components per sample");

  const auto frameWidth = frame.cps * frame.w;
  if (frameWidth < w || frame.h < h) {
    ThrowRDE("LJpeg frame (%u, %u) is smaller than expected (%u, %u)",
             frameWidth, frame.h, w, h);
  }

  switch (frame.cps) {
  case 2:
    decodeN<2>();
    break;
  case 3:
    decodeN<3>();
    break;
  case 4:
    decodeN<4>();
    break;
  default:
    ThrowRDE("Unsupported number of components: %u", frame.cps);
  }
}

// N_COMP == number of components (2, 3 or 4)

template <int N_COMP>
void LJpegDecompressor::decodeN()
{
  assert(mRaw->getCpp() > 0);
  assert(N_COMP > 0);
  assert(N_COMP >= mRaw->getCpp());
  assert((N_COMP / mRaw->getCpp()) > 0);

  assert(mRaw->dim.x >= N_COMP);
  assert((mRaw->getCpp() * (mRaw->dim.x - offX)) >= N_COMP);

  auto ht = getHuffmanTables<N_COMP>();
  auto pred = getInitialPredictors<N_COMP>();
  auto predNext = pred.data();

  BitPumpJPEG bitStream(input);

  // A recoded DNG might be split up into tiles of self contained LJpeg blobs.
  // The tiles at the bottom and the right may extend beyond the dimension of
  // the raw image buffer. The excessive content has to be ignored.

  const auto height = std::min(frame.h, h);
  const auto width = std::min(frame.w, (mRaw->getCpp() * w) / N_COMP);

  // For y, we can simply stop decoding when we reached the border.
  for (unsigned y = 0; y < height; ++y) {
    auto destY = offY + y;
    auto dest =
        reinterpret_cast<ushort16*>(mRaw->getDataUncropped(offX, destY));

    copy_n(predNext, N_COMP, pred.data());
    // the predictor for the next line is the start of this line
    predNext = dest;

    // For x, we first process all pixels within the image buffer ...
    for (unsigned x = 0; x < width; ++x) {
      unroll_loop<N_COMP>([&](int i) {
        *dest++ = pred[i] += ht[i]->decodeNext(bitStream);
      });
    }
    // ... and discard the rest.
    for (unsigned x = width; x < frame.w; ++x) {
      unroll_loop<N_COMP>([&](int i) {
        ht[i]->decodeNext(bitStream);
      });
    }
  }
}

} // namespace rawspeed
<commit_msg>LJpegDecompressor::decodeN(): cleanup the max pixel count calculation<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2017 Axel Waggershauser
    Copyright (C) 2017 Roman Lebedev

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "decompressors/LJpegDecompressor.h"
#include "common/Common.h"                // for uint32, unroll_loop, ushort16
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpJPEG.h"               // for BitPumpJPEG
#include <algorithm>                      // for min, copy_n

using std::copy_n;

namespace rawspeed {

LJpegDecompressor::LJpegDecompressor(const ByteStream& bs, const RawImage& img)
    : AbstractLJpegDecompressor(bs, img) {
  if (mRaw->getDataType() != TYPE_USHORT16)
    ThrowRDE("Unexpected data type (%u)", mRaw->getDataType());

  if (!((mRaw->getCpp() == 1 && mRaw->getBpp() == 2) ||
        (mRaw->getCpp() == 3 && mRaw->getBpp() == 6)))
    ThrowRDE("Unexpected component count (%u)", mRaw->getCpp());

  if (mRaw->dim.x == 0 || mRaw->dim.y == 0)
    ThrowRDE("Image has zero size");

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  // Yeah, sure, here it would be just dumb to leave this for production :)
  if (mRaw->dim.x > 7424 || mRaw->dim.y > 5552) {
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", mRaw->dim.x,
             mRaw->dim.y);
  }
#endif
}

void LJpegDecompressor::decode(uint32 offsetX, uint32 offsetY, uint32 width,
                               uint32 height, bool fixDng16Bug_) {
  if (offsetX >= static_cast<unsigned>(mRaw->dim.x))
    ThrowRDE("X offset outside of image");
  if (offsetY >= static_cast<unsigned>(mRaw->dim.y))
    ThrowRDE("Y offset outside of image");

  offX = offsetX;
  offY = offsetY;
  w = width;
  h = height;

  fixDng16Bug = fixDng16Bug_;

  AbstractLJpegDecompressor::decode();
}

void LJpegDecompressor::decodeScan()
{
  if (predictorMode != 1)
    ThrowRDE("Unsupported predictor mode: %u", predictorMode);

  for (uint32 i = 0; i < frame.cps;  i++)
    if (frame.compInfo[i].superH != 1 || frame.compInfo[i].superV != 1)
      ThrowRDE("Unsupported subsampling");

  assert(static_cast<unsigned>(mRaw->dim.x) > offX);
  if ((mRaw->getCpp() * (mRaw->dim.x - offX)) < frame.cps)
    ThrowRDE("Got less pixels than the components per sample");

  const auto frameWidth = frame.cps * frame.w;
  if (frameWidth < w || frame.h < h) {
    ThrowRDE("LJpeg frame (%u, %u) is smaller than expected (%u, %u)",
             frameWidth, frame.h, w, h);
  }

  switch (frame.cps) {
  case 2:
    decodeN<2>();
    break;
  case 3:
    decodeN<3>();
    break;
  case 4:
    decodeN<4>();
    break;
  default:
    ThrowRDE("Unsupported number of components: %u", frame.cps);
  }
}

// N_COMP == number of components (2, 3 or 4)

template <int N_COMP>
void LJpegDecompressor::decodeN()
{
  assert(mRaw->getCpp() > 0);
  assert(N_COMP > 0);
  assert(N_COMP >= mRaw->getCpp());
  assert((N_COMP / mRaw->getCpp()) > 0);

  assert(mRaw->dim.x >= N_COMP);
  assert((mRaw->getCpp() * (mRaw->dim.x - offX)) >= N_COMP);

  assert((mRaw->getCpp() * w) % N_COMP == 0);

  auto ht = getHuffmanTables<N_COMP>();
  auto pred = getInitialPredictors<N_COMP>();
  auto predNext = pred.data();

  BitPumpJPEG bitStream(input);

  // A recoded DNG might be split up into tiles of self contained LJpeg blobs.
  // The tiles at the bottom and the right may extend beyond the dimension of
  // the raw image buffer. The excessive content has to be ignored.

  const auto height = std::min(frame.h, h);
  assert(height == h);
  const auto wBlocks = (mRaw->getCpp() * w) / N_COMP;
  const auto width = std::min(frame.w, wBlocks);
  assert(width == wBlocks);

  // For y, we can simply stop decoding when we reached the border.
  for (unsigned y = 0; y < height; ++y) {
    auto destY = offY + y;
    auto dest =
        reinterpret_cast<ushort16*>(mRaw->getDataUncropped(offX, destY));

    copy_n(predNext, N_COMP, pred.data());
    // the predictor for the next line is the start of this line
    predNext = dest;

    // For x, we first process all pixels within the image buffer ...
    for (unsigned x = 0; x < width; ++x) {
      unroll_loop<N_COMP>([&](int i) {
        *dest++ = pred[i] += ht[i]->decodeNext(bitStream);
      });
    }
    // ... and discard the rest.
    for (unsigned x = width; x < frame.w; ++x) {
      unroll_loop<N_COMP>([&](int i) {
        ht[i]->decodeNext(bitStream);
      });
    }
  }
}

} // namespace rawspeed
<|endoftext|>


<commit_before>/*
 * Copyright 2016-2018 Kacper Kasper <kacperkasper@gmail.com>
 * All rights reserved. Distributed under the terms of the MIT license.
 */

#include "QuitAlert.h"

#include <Application.h>
#include <Button.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <LayoutBuilder.h>
#include <ScrollView.h>
#include <StringView.h>

#include <string>
#include <vector>

#include "EditorWindow.h"
#include "Utils.h"

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "QuitAlert"

namespace {
const int kSemTimeOut = 50000;
const uint32 kMaxItems = 4;
}

QuitAlert::QuitAlert(const std::vector<std::string> &unsavedFiles)
	:
	BWindow(BRect(100, 100, 200, 200), B_TRANSLATE("Unsaved files"), B_MODAL_WINDOW,
		B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS, 0),
	fUnsavedFiles(unsavedFiles),
	fAlertValue(0),
	fCheckboxes(unsavedFiles.size(), nullptr)
{
	_InitInterface();
	CenterOnScreen();
}

QuitAlert::~QuitAlert()
{
	if (fAlertSem >= B_OK)
		delete_sem(fAlertSem);
}

void
QuitAlert::_InitInterface()
{
	fMessageString = new BStringView("message", B_TRANSLATE("There are unsaved changes.\nSelect the files to save."));
	fSaveAll = new BButton(B_TRANSLATE("Save all"), new BMessage((uint32) Actions::SAVE_ALL));
	fSaveSelected = new BButton(B_TRANSLATE("Save selected"), new BMessage((uint32) Actions::SAVE_SELECTED));
	fDontSave = new BButton(B_TRANSLATE("Don't save"), new BMessage((uint32) Actions::DONT_SAVE));
	fCancel = new BButton(B_TRANSLATE("Cancel"), new BMessage(B_QUIT_REQUESTED));
	fCancel->MakeDefault(true);
	BGroupView* filesView = new BGroupView(B_VERTICAL, 0);
	filesView->SetViewUIColor(B_CONTROL_BACKGROUND_COLOR);
	fScrollView = new BScrollView("files", filesView, 0, false, true);
	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
		.Add(fMessageString)
		.Add(fScrollView)
		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
			.Add(fSaveAll)
			.Add(fSaveSelected)
			.Add(fDontSave)
			.AddGlue()
			.Add(fCancel)
		.End()
		.SetInsets(B_USE_SMALL_INSETS);
	font_height fh;
	be_plain_font->GetHeight(&fh);
	float textHeight = fh.ascent + fh.descent + fh.leading + 5;
	fScrollView->SetExplicitSize(BSize(B_SIZE_UNSET,
		textHeight * std::min<uint32>(fUnsavedFiles.size(), kMaxItems) + 25.0f));

	float height = 0.0f;
	EditorWindow* current;
	BGroupLayout* files = filesView->GroupLayout();
	files->SetInsets(B_USE_SMALL_INSETS);
	for(int i = 0; i < fUnsavedFiles.size(); ++i) {
		fCheckboxes[i] = new BCheckBox("file", fUnsavedFiles[i].c_str(), new BMessage((uint32) i));
		SetChecked(fCheckboxes[i]);
		files->AddView(fCheckboxes[i]);
	}
}

void
QuitAlert::Show()
{
	BWindow::Show();
	fScrollView->SetExplicitSize(BSize(Bounds().Width(), B_SIZE_UNSET));
	font_height fh;
	be_plain_font->GetHeight(&fh);
	float textHeight = fh.ascent + fh.descent + fh.leading + 5;
	if(LockLooper()) {
		BScrollBar* bar = fScrollView->ScrollBar(B_VERTICAL);
		bar->SetSteps(textHeight / 2.0f, textHeight * 3.0f / 2.0f);
		bar->SetRange(0.0f, fUnsavedFiles.size() > kMaxItems ?
			(textHeight + 3.0f) * (fUnsavedFiles.size() - kMaxItems) : 0.0f);
		UnlockLooper();
	}
}

// borrowed from BAlert
std::vector<bool>
QuitAlert::Go()
{
	fAlertSem = create_sem(0, "AlertSem");
	if (fAlertSem < 0) {
		Quit();
		return std::vector<bool>(0);
	}

	// Get the originating window, if it exists
	BWindow* window = dynamic_cast<BWindow*>(
		BLooper::LooperForThread(find_thread(nullptr)));

	Show();

	if (window != nullptr) {
		status_t status;
		for (;;) {
			do {
				status = acquire_sem_etc(fAlertSem, 1, B_RELATIVE_TIMEOUT,
					kSemTimeOut);
				// We've (probably) had our time slice taken away from us
			} while (status == B_INTERRUPTED);

			if (status == B_BAD_SEM_ID) {
				// Semaphore was finally nuked in MessageReceived
				break;
			}
			window->UpdateIfNeeded();
		}
	} else {
		// No window to update, so just hang out until we're done.
		while (acquire_sem(fAlertSem) == B_INTERRUPTED) {
		}
	}

	// Have to cache the value since we delete on Quit()
	auto value = fAlertValue;
	if (Lock())
		Quit();

	return value;
}

void
QuitAlert::MessageReceived(BMessage* message)
{
	switch(message->what) {
		case Actions::SAVE_ALL: {
			fAlertValue = std::vector<bool>(fUnsavedFiles.size(), true);
		} break;
		case Actions::SAVE_SELECTED: {
			fAlertValue = std::vector<bool>(fUnsavedFiles.size(), false);
			for(uint32 i = 0; i < fCheckboxes.size(); ++i) {
				fAlertValue[i] = fCheckboxes[i]->Value() ? true : false;
			}
		} break;
		case Actions::DONT_SAVE: {
			fAlertValue = std::vector<bool>(fUnsavedFiles.size(), false);
		} break;
		default: {
			BWindow::MessageReceived(message);
		} return;
	}
	delete_sem(fAlertSem);
	fAlertSem = -1;
}
<commit_msg>QuitAlert: move scroll bar initialization<commit_after>/*
 * Copyright 2016-2018 Kacper Kasper <kacperkasper@gmail.com>
 * All rights reserved. Distributed under the terms of the MIT license.
 */

#include "QuitAlert.h"

#include <Application.h>
#include <Button.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <LayoutBuilder.h>
#include <ScrollView.h>
#include <StringView.h>

#include <string>
#include <vector>

#include "EditorWindow.h"
#include "Utils.h"

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "QuitAlert"

namespace {
const int kSemTimeOut = 50000;
const uint32 kMaxItems = 4;
}

QuitAlert::QuitAlert(const std::vector<std::string> &unsavedFiles)
	:
	BWindow(BRect(100, 100, 200, 200), B_TRANSLATE("Unsaved files"), B_MODAL_WINDOW,
		B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS, 0),
	fUnsavedFiles(unsavedFiles),
	fAlertValue(0),
	fCheckboxes(unsavedFiles.size(), nullptr)
{
	_InitInterface();
	CenterOnScreen();
}

QuitAlert::~QuitAlert()
{
	if (fAlertSem >= B_OK)
		delete_sem(fAlertSem);
}

void
QuitAlert::_InitInterface()
{
	fMessageString = new BStringView("message", B_TRANSLATE("There are unsaved changes.\nSelect the files to save."));
	fSaveAll = new BButton(B_TRANSLATE("Save all"), new BMessage((uint32) Actions::SAVE_ALL));
	fSaveSelected = new BButton(B_TRANSLATE("Save selected"), new BMessage((uint32) Actions::SAVE_SELECTED));
	fDontSave = new BButton(B_TRANSLATE("Don't save"), new BMessage((uint32) Actions::DONT_SAVE));
	fCancel = new BButton(B_TRANSLATE("Cancel"), new BMessage(B_QUIT_REQUESTED));
	fCancel->MakeDefault(true);
	BGroupView* filesView = new BGroupView(B_VERTICAL, 0);
	filesView->SetViewUIColor(B_CONTROL_BACKGROUND_COLOR);
	fScrollView = new BScrollView("files", filesView, 0, false, true);
	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
		.Add(fMessageString)
		.Add(fScrollView)
		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
			.Add(fSaveAll)
			.Add(fSaveSelected)
			.Add(fDontSave)
			.AddGlue()
			.Add(fCancel)
		.End()
		.SetInsets(B_USE_SMALL_INSETS);

	font_height fh;
	be_plain_font->GetHeight(&fh);
	float textHeight = fh.ascent + fh.descent + fh.leading + 5;
	fScrollView->SetExplicitSize(BSize(B_SIZE_UNSET,
		textHeight * std::min<uint32>(fUnsavedFiles.size(), kMaxItems) + 25.0f));
	BScrollBar* bar = fScrollView->ScrollBar(B_VERTICAL);
	bar->SetSteps(textHeight / 2.0f, textHeight * 3.0f / 2.0f);
	bar->SetRange(0.0f, fUnsavedFiles.size() > kMaxItems ?
		(textHeight + 3.0f) * (fUnsavedFiles.size() - kMaxItems) : 0.0f);

	EditorWindow* current;
	BGroupLayout* files = filesView->GroupLayout();
	files->SetInsets(B_USE_SMALL_INSETS);
	for(int i = 0; i < fUnsavedFiles.size(); ++i) {
		fCheckboxes[i] = new BCheckBox("file", fUnsavedFiles[i].c_str(), new BMessage((uint32) i));
		SetChecked(fCheckboxes[i]);
		files->AddView(fCheckboxes[i]);
	}
}

void
QuitAlert::Show()
{
	BWindow::Show();
	fScrollView->SetExplicitSize(BSize(Bounds().Width(), B_SIZE_UNSET));
}

// borrowed from BAlert
std::vector<bool>
QuitAlert::Go()
{
	fAlertSem = create_sem(0, "AlertSem");
	if (fAlertSem < 0) {
		Quit();
		return std::vector<bool>(0);
	}

	// Get the originating window, if it exists
	BWindow* window = dynamic_cast<BWindow*>(
		BLooper::LooperForThread(find_thread(nullptr)));

	Show();

	if (window != nullptr) {
		status_t status;
		for (;;) {
			do {
				status = acquire_sem_etc(fAlertSem, 1, B_RELATIVE_TIMEOUT,
					kSemTimeOut);
				// We've (probably) had our time slice taken away from us
			} while (status == B_INTERRUPTED);

			if (status == B_BAD_SEM_ID) {
				// Semaphore was finally nuked in MessageReceived
				break;
			}
			window->UpdateIfNeeded();
		}
	} else {
		// No window to update, so just hang out until we're done.
		while (acquire_sem(fAlertSem) == B_INTERRUPTED) {
		}
	}

	// Have to cache the value since we delete on Quit()
	auto value = fAlertValue;
	if (Lock())
		Quit();

	return value;
}

void
QuitAlert::MessageReceived(BMessage* message)
{
	switch(message->what) {
		case Actions::SAVE_ALL: {
			fAlertValue = std::vector<bool>(fUnsavedFiles.size(), true);
		} break;
		case Actions::SAVE_SELECTED: {
			fAlertValue = std::vector<bool>(fUnsavedFiles.size(), false);
			for(uint32 i = 0; i < fCheckboxes.size(); ++i) {
				fAlertValue[i] = fCheckboxes[i]->Value() ? true : false;
			}
		} break;
		case Actions::DONT_SAVE: {
			fAlertValue = std::vector<bool>(fUnsavedFiles.size(), false);
		} break;
		default: {
			BWindow::MessageReceived(message);
		} return;
	}
	delete_sem(fAlertSem);
	fAlertSem = -1;
}
<|endoftext|>


<commit_before>#include "utest_helper.hpp"
#include "string.h"

static void cpu_exec (int n, float* src, float* dst)
{
    int i = 0;
    for (; i < n; i++) {
	float f = src[i];
	f = f < 0 ? -f : f;
	dst[i] = f;
    }
}

#define QUEUE_SECONDS_LIMIT 10
#define SUBMIT_SECONDS_LIMIT 20
#define COMMAND_SECONDS_LIMIT 10

static void check_profiling_time(cl_ulong queued, cl_ulong submit, cl_ulong start, cl_ulong end)
{
    size_t profiling_resolution = 0;
    OCL_CALL(clGetDeviceInfo, device, CL_DEVICE_PROFILING_TIMER_RESOLUTION,
             sizeof(profiling_resolution), &profiling_resolution, NULL);

    /* Convert the time to second. */
    double queue_to_submit = (double)(submit - queued)*1e-9;
    double submit_to_start = (double)(start - submit)*1e-9;
    double start_to_end = (double)(end - start)*1e-9;

    //printf("Profiling info:\n");
    //printf("Time from queue to submit : %fms\n", (double)(queue_to_submit) * 1000.f );
    //printf( "Time from submit to start : %fms\n", (double)(submit_to_start) * 1000.f );
    //printf( "Time from start to end: %fms\n", (double)(start_to_end) * 1000.f );

    OCL_ASSERTM(queued <= submit, "Enqueue time is later than submit time, invalid\n");
    OCL_ASSERTM(submit <= start, "Submit time is later than start time, invalid\n");
    OCL_ASSERTM(start <= end, "Start time is later than end time, invalid\n");

    OCL_ASSERTM(queue_to_submit <= QUEUE_SECONDS_LIMIT, "Too large time from queue to submit\n");
    OCL_ASSERTM(submit_to_start <= QUEUE_SECONDS_LIMIT, "Too large time from submit to start\n");
    OCL_ASSERTM(start_to_end <= QUEUE_SECONDS_LIMIT, "Too large time from start to end\n");
}

static void profiling_exec(void)
{
    const size_t n = 512;
    cl_int status = CL_SUCCESS;
    cl_command_queue profiling_queue = NULL;
    cl_command_queue tmp_queue = NULL;
    float* cpu_src = (float *)malloc(n*sizeof(float));
    float* cpu_dst = (float *)malloc(n*sizeof(float));
    cl_event exec_event;
    cl_ulong time_queue, time_submit, time_start, time_end;

    /* Because the profiling prop, we can not use default queue. */
    profiling_queue = clCreateCommandQueue(ctx, device, CL_QUEUE_PROFILING_ENABLE, &status);
    OCL_ASSERT(status == CL_SUCCESS);

    /* save the default queue. */
    tmp_queue = queue;
    queue = profiling_queue;

    OCL_CREATE_KERNEL("compiler_fabs");

    OCL_CREATE_BUFFER(buf[0], 0, n * sizeof(float), NULL);
    OCL_CREATE_BUFFER(buf[1], 0, n * sizeof(float), NULL);
    OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
    OCL_SET_ARG(1, sizeof(cl_mem), &buf[1]);
    globals[0] = n;
    locals[0] = 256;

    OCL_MAP_BUFFER(0);
    for (int32_t i = 0; i < (int32_t) n; ++i)
	cpu_src[i] = ((float*)buf_data[0])[i] = .1f * (rand() & 15) - .75f;
    OCL_UNMAP_BUFFER(0);

    cpu_exec(n, cpu_src, cpu_dst);

    // Run the kernel on GPU
    OCL_CALL(clEnqueueNDRangeKernel, queue, kernel, 1, NULL, globals, locals, 0, NULL, &exec_event);
    OCL_CALL(clWaitForEvents, 1, &exec_event);

    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &time_queue, NULL);
    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &time_submit, NULL);
    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &time_start, NULL);
    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &time_end, NULL);

    clReleaseEvent(exec_event);
    check_profiling_time(time_queue, time_submit, time_start, time_end);

    // Compare
    OCL_MAP_BUFFER(1);
    for (int32_t i = 0; i < (int32_t) n; ++i)
	OCL_ASSERT(((float *)buf_data[1])[i] == cpu_dst[i]);
    OCL_UNMAP_BUFFER(1);

    queue = tmp_queue;
    clReleaseCommandQueue(profiling_queue);
    free(cpu_dst);
    free(cpu_src);
}

MAKE_UTEST_FROM_FUNCTION(profiling_exec);
<commit_msg>utests: fix multithread queue chaos<commit_after>#include "utest_helper.hpp"
#include "string.h"

static void cpu_exec (int n, float* src, float* dst)
{
    int i = 0;
    for (; i < n; i++) {
	float f = src[i];
	f = f < 0 ? -f : f;
	dst[i] = f;
    }
}

#define QUEUE_SECONDS_LIMIT 10
#define SUBMIT_SECONDS_LIMIT 20
#define COMMAND_SECONDS_LIMIT 10

static void check_profiling_time(cl_ulong queued, cl_ulong submit, cl_ulong start, cl_ulong end)
{
    size_t profiling_resolution = 0;
    OCL_CALL(clGetDeviceInfo, device, CL_DEVICE_PROFILING_TIMER_RESOLUTION,
             sizeof(profiling_resolution), &profiling_resolution, NULL);

    /* Convert the time to second. */
    double queue_to_submit = (double)(submit - queued)*1e-9;
    double submit_to_start = (double)(start - submit)*1e-9;
    double start_to_end = (double)(end - start)*1e-9;

    //printf("Profiling info:\n");
    //printf("Time from queue to submit : %fms\n", (double)(queue_to_submit) * 1000.f );
    //printf( "Time from submit to start : %fms\n", (double)(submit_to_start) * 1000.f );
    //printf( "Time from start to end: %fms\n", (double)(start_to_end) * 1000.f );

    OCL_ASSERTM(queued <= submit, "Enqueue time is later than submit time, invalid\n");
    OCL_ASSERTM(submit <= start, "Submit time is later than start time, invalid\n");
    OCL_ASSERTM(start <= end, "Start time is later than end time, invalid\n");

    OCL_ASSERTM(queue_to_submit <= QUEUE_SECONDS_LIMIT, "Too large time from queue to submit\n");
    OCL_ASSERTM(submit_to_start <= QUEUE_SECONDS_LIMIT, "Too large time from submit to start\n");
    OCL_ASSERTM(start_to_end <= QUEUE_SECONDS_LIMIT, "Too large time from start to end\n");
}

static void profiling_exec(void)
{
    const size_t n = 512;
    cl_int status = CL_SUCCESS;
    cl_command_queue profiling_queue = NULL;
    float* cpu_src = (float *)malloc(n*sizeof(float));
    float* cpu_dst = (float *)malloc(n*sizeof(float));
    cl_event exec_event;
    cl_ulong time_queue, time_submit, time_start, time_end;

    /* Because the profiling prop, we can not use default queue. */
    profiling_queue = clCreateCommandQueue(ctx, device, CL_QUEUE_PROFILING_ENABLE, &status);
    OCL_ASSERT(status == CL_SUCCESS);

    OCL_CREATE_KERNEL("compiler_fabs");

    OCL_CREATE_BUFFER(buf[0], 0, n * sizeof(float), NULL);
    OCL_CREATE_BUFFER(buf[1], 0, n * sizeof(float), NULL);
    OCL_SET_ARG(0, sizeof(cl_mem), &buf[0]);
    OCL_SET_ARG(1, sizeof(cl_mem), &buf[1]);
    globals[0] = n;
    locals[0] = 256;

    OCL_MAP_BUFFER(0);
    for (int32_t i = 0; i < (int32_t) n; ++i)
	cpu_src[i] = ((float*)buf_data[0])[i] = .1f * (rand() & 15) - .75f;
    OCL_UNMAP_BUFFER(0);

    cpu_exec(n, cpu_src, cpu_dst);

    // Run the kernel on GPU
    OCL_CALL(clEnqueueNDRangeKernel, profiling_queue, kernel, 1, NULL, globals, locals, 0, NULL, &exec_event);
    OCL_CALL(clWaitForEvents, 1, &exec_event);

    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &time_queue, NULL);
    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &time_submit, NULL);
    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &time_start, NULL);
    OCL_CALL(clGetEventProfilingInfo, exec_event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &time_end, NULL);

    clReleaseEvent(exec_event);
    check_profiling_time(time_queue, time_submit, time_start, time_end);

    // Compare
    OCL_MAP_BUFFER(1);
    for (int32_t i = 0; i < (int32_t) n; ++i)
	OCL_ASSERT(((float *)buf_data[1])[i] == cpu_dst[i]);
    OCL_UNMAP_BUFFER(1);

    clReleaseCommandQueue(profiling_queue);
    free(cpu_dst);
    free(cpu_src);
}

MAKE_UTEST_FROM_FUNCTION(profiling_exec);
<|endoftext|>


<commit_before>
bool UnitTest_Dummy(int argc, char** argv) {
	try
	{
		// do unit test
		return true;
	}
//	catch (const std::exception& e)
//	{
//		std::cerr << "Exception in UnitTest_Dummy" << std::endl;
//		std::cerr << e.what() << std::endl;
//		return false;
//	}
}

// Handy macro from: s2client-api/tests/all_tests.cc
#define TEST(X)                                                     \
    std::cout << "Running unit test: " << #X << std::endl;               \
    if (X(argc, argv)) {                                            \
        std::cout << "Test: " << #X << " succeeded." << std::endl;  \
    }                                                               \
    else {                                                          \
        success = false;                                            \
        std::cerr << "Test: " << #X << " failed!" << std::endl;     \
    }

int main(int argc, char** argv) {
	bool success = true;

	TEST(UnitTest_Dummy);
	//TEST(TestMatch_Bot2Eliminated);
	//TEST(sc2ai::TestMatch_Bot1Leave);
	//TEST(sc2ai::TestMatch_Bot2Leave);
	//TEST(sc2ai::TestMatch_Bot1Quit);
	//TEST(sc2ai::TestMatch_Bot2Quit);
	//TEST(sc2ai::TestMatch_BotVerseBlizzardAI);
	//TEST(sc2ai::TestMatch_BotBinaryVerseBotPython);
	// Add more tests here...

	if (success)
		std::cout << "All unit tests succeeded!" << std::endl;
	else
		std::cerr << "Some unit tests failed!" << std::endl;

	return success ? 0 : -1;
}<commit_msg>Uncomment test exception code.<commit_after>
bool UnitTest_Dummy(int argc, char** argv) {
	try
	{
		// do unit test
		return true;
	}
	catch (const std::exception& e)
	{
		std::cerr << "Exception in UnitTest_Dummy" << std::endl;
		std::cerr << e.what() << std::endl;
		return false;
	}
}

// Handy macro from: s2client-api/tests/all_tests.cc
#define TEST(X)                                                     \
    std::cout << "Running unit test: " << #X << std::endl;               \
    if (X(argc, argv)) {                                            \
        std::cout << "Test: " << #X << " succeeded." << std::endl;  \
    }                                                               \
    else {                                                          \
        success = false;                                            \
        std::cerr << "Test: " << #X << " failed!" << std::endl;     \
    }

int main(int argc, char** argv) {
	bool success = true;

	TEST(UnitTest_Dummy);
	//TEST(TestMatch_Bot2Eliminated);
	//TEST(sc2ai::TestMatch_Bot1Leave);
	//TEST(sc2ai::TestMatch_Bot2Leave);
	//TEST(sc2ai::TestMatch_Bot1Quit);
	//TEST(sc2ai::TestMatch_Bot2Quit);
	//TEST(sc2ai::TestMatch_BotVerseBlizzardAI);
	//TEST(sc2ai::TestMatch_BotBinaryVerseBotPython);
	// Add more tests here...

	if (success)
		std::cout << "All unit tests succeeded!" << std::endl;
	else
		std::cerr << "Some unit tests failed!" << std::endl;

	return success ? 0 : -1;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: unomodel.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: tl $ $Date: 2001-07-23 12:52:38 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef UNOMODEL_HXX
#define UNOMODEL_HXX

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XMULTIPROPERTYSET_HPP_
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
#include <com/sun/star/beans/XPropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _SFX_SFXBASEMODEL_HXX_
#include <sfx2/sfxbasemodel.hxx>
#endif
#ifndef _COMPHELPER_PROPERTYSETHELPER_HXX_
#include <comphelper/propertysethelper.hxx>
#endif

class SmFormat;

//-----------------------------------------------------------------------------
class SmModel : public SfxBaseModel,
                public comphelper::PropertySetHelper,
                public com::sun::star::lang::XServiceInfo,
                public com::sun::star::lang::XUnoTunnel
{
protected:
    virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const ::com::sun::star::uno::Any* pValues )
        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException );
    virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::uno::Any* pValue )
        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException );
public:
    SmModel( SfxObjectShell *pObjSh = 0 );
    virtual ~SmModel();

    //XInterface
    virtual     ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL acquire(  )
        throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL release(  )
        throw(::com::sun::star::uno::RuntimeException);

    //XTypeProvider
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes(  ) throw(::com::sun::star::uno::RuntimeException);

    static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();

    //XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName(void)
        throw( ::com::sun::star::uno::RuntimeException );
    virtual BOOL SAL_CALL supportsService(const rtl::OUString& ServiceName)
            throw( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void)
            throw( ::com::sun::star::uno::RuntimeException );

    inline ::rtl::OUString SmModel::getImplementationName_Static() throw(  );
};

inline ::rtl::OUString SmModel::getImplementationName_Static() throw(  )
{
    return rtl::OUString::createFromAscii("math.SmModel");
}

#endif
<commit_msg>#92075# exception specification<commit_after>/*************************************************************************
 *
 *  $RCSfile: unomodel.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2001-09-13 08:24:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef UNOMODEL_HXX
#define UNOMODEL_HXX

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XMULTIPROPERTYSET_HPP_
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
#include <com/sun/star/beans/XPropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _SFX_SFXBASEMODEL_HXX_
#include <sfx2/sfxbasemodel.hxx>
#endif
#ifndef _COMPHELPER_PROPERTYSETHELPER_HXX_
#include <comphelper/propertysethelper.hxx>
#endif

class SmFormat;

//-----------------------------------------------------------------------------
class SmModel : public SfxBaseModel,
                public comphelper::PropertySetHelper,
                public com::sun::star::lang::XServiceInfo,
                public com::sun::star::lang::XUnoTunnel
{
protected:
    virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const ::com::sun::star::uno::Any* pValues )
        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException );
    virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, ::com::sun::star::uno::Any* pValue )
        throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException );
public:
    SmModel( SfxObjectShell *pObjSh = 0 );
    virtual ~SmModel() throw ();

    //XInterface
    virtual     ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL acquire(  )
        throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL release(  )
        throw(::com::sun::star::uno::RuntimeException);

    //XTypeProvider
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes(  ) throw(::com::sun::star::uno::RuntimeException);

    static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();

    //XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName(void)
        throw( ::com::sun::star::uno::RuntimeException );
    virtual BOOL SAL_CALL supportsService(const rtl::OUString& ServiceName)
            throw( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void)
            throw( ::com::sun::star::uno::RuntimeException );

    inline ::rtl::OUString SmModel::getImplementationName_Static() throw(  );
};

inline ::rtl::OUString SmModel::getImplementationName_Static() throw(  )
{
    return rtl::OUString::createFromAscii("math.SmModel");
}

#endif
<|endoftext|>