/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Image comparison utilities.
 *//*--------------------------------------------------------------------*/

#include "tcuImageCompare.hpp"
#include "tcuSurface.hpp"
#include "tcuFuzzyImageCompare.hpp"
#include "tcuBilinearImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuFloat.hpp"

#include <string.h>

namespace tcu
{

namespace
{

void computeScaleAndBias (const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, tcu::Vec4& scale, tcu::Vec4& bias)
{
	Vec4 minVal;
	Vec4 maxVal;
	const float eps = 0.0001f;

	{
		Vec4 refMin;
		Vec4 refMax;
		estimatePixelValueRange(reference, refMin, refMax);

		minVal	= refMin;
		maxVal	= refMax;
	}

	{
		Vec4 resMin;
		Vec4 resMax;

		estimatePixelValueRange(result, resMin, resMax);

		minVal[0] = de::min(minVal[0], resMin[0]);
		minVal[1] = de::min(minVal[1], resMin[1]);
		minVal[2] = de::min(minVal[2], resMin[2]);
		minVal[3] = de::min(minVal[3], resMin[3]);

		maxVal[0] = de::max(maxVal[0], resMax[0]);
		maxVal[1] = de::max(maxVal[1], resMax[1]);
		maxVal[2] = de::max(maxVal[2], resMax[2]);
		maxVal[3] = de::max(maxVal[3], resMax[3]);
	}

	for (int c = 0; c < 4; c++)
	{
		if (maxVal[c] - minVal[c] < eps)
		{
			scale[c]	= (maxVal[c] < eps) ? 1.0f : (1.0f / maxVal[c]);
			bias[c]		= (c == 3) ? (1.0f - maxVal[c]*scale[c]) : (0.0f - minVal[c]*scale[c]);
		}
		else
		{
			scale[c]	= 1.0f / (maxVal[c] - minVal[c]);
			bias[c]		= 0.0f - minVal[c]*scale[c];
		}
	}
}

static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& errorMask, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue)
{
	const int	width				= reference.getWidth();
	const int	height				= reference.getHeight();
	const int	depth				= reference.getDepth();
	int			numFailingPixels	= 0;

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				const IVec4	refPix = reference.getPixelInt(x, y, z);
				const IVec4	cmpPix = result.getPixelInt(x, y, z);

				// Exact match
				{
					const UVec4	diff = abs(refPix - cmpPix).cast<deUint32>();
					const bool	isOk = boolAll(lessThanEqual(diff, threshold));

					if (isOk)
					{
						errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z);
						continue;
					}
				}

				// Accept over the image bounds pixels since they could be anything

				if (acceptOutOfBoundsAsAnyValue &&
					(x < maxPositionDeviation.x() || x + maxPositionDeviation.x() >= width  ||
					 y < maxPositionDeviation.y() || y + maxPositionDeviation.y() >= height ||
					 z < maxPositionDeviation.z() || z + maxPositionDeviation.z() >= depth))
				{
					errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z);
					continue;
				}

				// Find matching pixels for both result and reference pixel

				{
					bool pixelFoundForReference = false;
					bool pixelFoundForResult	= false;

					// Find deviated result pixel for reference

					for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth  - 1, z + maxPositionDeviation.z()) && !pixelFoundForReference; ++sz)
					for (int sy = de::max(0, y - maxPositionDeviation.y()); sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForReference; ++sy)
					for (int sx = de::max(0, x - maxPositionDeviation.x()); sx <= de::min(width  - 1, x + maxPositionDeviation.x()) && !pixelFoundForReference; ++sx)
					{
						const IVec4	deviatedCmpPix	= result.getPixelInt(sx, sy, sz);
						const UVec4	diff			= abs(refPix - deviatedCmpPix).cast<deUint32>();
						const bool	isOk			= boolAll(lessThanEqual(diff, threshold));

						pixelFoundForReference		|= isOk;
					}

					// Find deviated reference pixel for result

					for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth  - 1, z + maxPositionDeviation.z()) && !pixelFoundForResult; ++sz)
					for (int sy = de::max(0, y - maxPositionDeviation.y()); sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForResult; ++sy)
					for (int sx = de::max(0, x - maxPositionDeviation.x()); sx <= de::min(width  - 1, x + maxPositionDeviation.x()) && !pixelFoundForResult; ++sx)
					{
						const IVec4	deviatedRefPix	= reference.getPixelInt(sx, sy, sz);
						const UVec4	diff			= abs(cmpPix - deviatedRefPix).cast<deUint32>();
						const bool	isOk			= boolAll(lessThanEqual(diff, threshold));

						pixelFoundForResult			|= isOk;
					}

					if (pixelFoundForReference && pixelFoundForResult)
						errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z);
					else
					{
						errorMask.setPixel(IVec4(0xff, 0, 0, 0xff), x, y, z);
						++numFailingPixels;
					}
				}
			}
		}
	}

	return numFailingPixels;
}

} // anonymous

/*--------------------------------------------------------------------*//*!
 * \brief Fuzzy image comparison
 *
 * This image comparison is designed for comparing images rendered by 3D
 * graphics APIs such as OpenGL. The comparison allows small local differences
 * and compensates for aliasing.
 *
 * The algorithm first performs light blurring on both images and then
 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
 * defined by adjecent pixels. This compensates for both 1-pixel deviations
 * in geometry and aliasing in texture data.
 *
 * Error metric is computed based on the differences. On valid images the
 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
 * 0.05.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note				Currently supports only UNORM_INT8 formats
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Error metric threshold (good values are 0.02-0.05)
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool fuzzyCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, float threshold, CompareLogMode logMode)
{
	FuzzyCompareParams	params;		// Use defaults.
	TextureLevel		errorMask		(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
	float				difference		= fuzzyCompare(params, reference, result, errorMask.getAccess());
	bool				isOk			= difference <= threshold;
	Vec4				pixelBias		(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale		(1.0f, 1.0f, 1.0f, 1.0f);

	if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// Generate more accurate error mask.
		params.maxSampleSkip = 0;
		fuzzyCompare(params, reference, result, errorMask.getAccess());

		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computeScaleAndBias(reference, result, pixelScale, pixelBias);

		if (!isOk)
			log << TestLog::Message << "Image comparison failed: difference = " << difference << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result, pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return isOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fuzzy image comparison
 *
 * This image comparison is designed for comparing images rendered by 3D
 * graphics APIs such as OpenGL. The comparison allows small local differences
 * and compensates for aliasing.
 *
 * The algorithm first performs light blurring on both images and then
 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
 * defined by adjecent pixels. This compensates for both 1-pixel deviations
 * in geometry and aliasing in texture data.
 *
 * Error metric is computed based on the differences. On valid images the
 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
 * 0.05.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note				Currently supports only UNORM_INT8 formats
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Error metric threshold (good values are 0.02-0.05)
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool fuzzyCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, float threshold, CompareLogMode logMode)
{
	return fuzzyCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold, logMode);
}

static deInt64 computeSquaredDiffSum (const ConstPixelBufferAccess& ref, const ConstPixelBufferAccess& cmp, const PixelBufferAccess& diffMask, int diffFactor)
{
	TCU_CHECK_INTERNAL(ref.getFormat().type == TextureFormat::UNORM_INT8 && cmp.getFormat().type == TextureFormat::UNORM_INT8);
	DE_ASSERT(ref.getWidth() == cmp.getWidth() && ref.getWidth() == diffMask.getWidth());
	DE_ASSERT(ref.getHeight() == cmp.getHeight() && ref.getHeight() == diffMask.getHeight());

	deInt64 diffSum = 0;

	for (int y = 0; y < cmp.getHeight(); y++)
	{
		for (int x = 0; x < cmp.getWidth(); x++)
		{
			IVec4	a		= ref.getPixelInt(x, y);
			IVec4	b		= cmp.getPixelInt(x, y);
			IVec4	diff	= abs(a - b);
			int		sum		= diff.x() + diff.y() + diff.z() + diff.w();
			int		sqSum	= diff.x()*diff.x() + diff.y()*diff.y() + diff.z()*diff.z() + diff.w()*diff.w();

			diffMask.setPixel(tcu::RGBA(deClamp32(sum*diffFactor, 0, 255), deClamp32(255-sum*diffFactor, 0, 255), 0, 255).toVec(), x, y);

			diffSum += (deInt64)sqSum;
		}
	}

	return diffSum;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel difference accuracy metric
 *
 * Computes accuracy metric using per-pixel differences between reference
 * and result images.
 *
 * \note					Supports only integer- and fixed-point formats
 * \param log				Test log for results
 * \param imageSetName		Name for image set when logging results
 * \param imageSetDesc		Description for image set
 * \param reference			Reference image
 * \param result			Result image
 * \param bestScoreDiff		Scaling factor
 * \param worstScoreDiff	Scaling factor
 * \param logMode			Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
int measurePixelDiffAccuracy (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
{
	TextureLevel	diffMask		(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
	int				diffFactor		= 8;
	deInt64			squaredSum		= computeSquaredDiffSum(reference, result, diffMask.getAccess(), diffFactor);
	float			sum				= deFloatSqrt((float)squaredSum);
	int				score			= deClamp32(deFloorFloatToInt32(100.0f - (de::max(sum-(float)bestScoreDiff, 0.0f) / (float)(worstScoreDiff-bestScoreDiff))*100.0f), 0, 100);
	const int		failThreshold	= 10;
	Vec4			pixelBias		(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4			pixelScale		(1.0f, 1.0f, 1.0f, 1.0f);

	if (logMode == COMPARE_LOG_EVERYTHING || score <= failThreshold)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computeScaleAndBias(reference, result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",			result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",		reference,	pixelScale, pixelBias)
			<< TestLog::Image("DiffMask",	"Difference",		diffMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",			result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	if (logMode != COMPARE_LOG_ON_ERROR || score <= failThreshold)
		log << TestLog::Integer("DiffSum", "Squared difference sum", "", QP_KEY_TAG_NONE, squaredSum)
			<< TestLog::Integer("Score", "Score", "", QP_KEY_TAG_QUALITY, score);

	return score;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel difference accuracy metric
 *
 * Computes accuracy metric using per-pixel differences between reference
 * and result images.
 *
 * \note					Supports only integer- and fixed-point formats
 * \param log				Test log for results
 * \param imageSetName		Name for image set when logging results
 * \param imageSetDesc		Description for image set
 * \param reference			Reference image
 * \param result			Result image
 * \param bestScoreDiff		Scaling factor
 * \param worstScoreDiff	Scaling factor
 * \param logMode			Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
int measurePixelDiffAccuracy (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
{
	return measurePixelDiffAccuracy(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), bestScoreDiff, worstScoreDiff, logMode);
}

/*--------------------------------------------------------------------*//*!
 * Returns the index of float in a float space without denormals
 * so that:
 * 1) f(0.0) = 0
 * 2) f(-0.0) = 0
 * 3) f(b) = f(a) + 1  <==>  b = nextAfter(a)
 *
 * See computeFloatFlushRelaxedULPDiff for details
 *//*--------------------------------------------------------------------*/
static deInt32 getPositionOfIEEEFloatWithoutDenormals (float x)
{
	DE_ASSERT(!deIsNaN(x)); // not sane

	if (x == 0.0f)
		return 0;
	else if (x < 0.0f)
		return -getPositionOfIEEEFloatWithoutDenormals(-x);
	else
	{
		DE_ASSERT(x > 0.0f);

		const tcu::Float32 f(x);

		if (f.isDenorm())
		{
			// Denorms are flushed to zero
			return 0;
		}
		else
		{
			// sign is 0, and it's a normal number. Natural position is its bit
			// pattern but since we've collapsed the denorms, we must remove
			// the gap here too to keep the float enumeration continuous.
			//
			// Denormals occupy one exponent pattern. Removing one from
			// exponent should to the trick.
			return (deInt32)(f.bits() - (1u << 23u));
		}
	}
}

static deUint32 computeFloatFlushRelaxedULPDiff (float a, float b)
{
	if (deIsNaN(a) && deIsNaN(b))
		return 0;
	else if (deIsNaN(a) || deIsNaN(b))
	{
		return 0xFFFFFFFFu;
	}
	else
	{
		// Using the "definition 5" in Muller, Jean-Michel. "On the definition of ulp (x)" (2005)
		// assuming a floating point space is IEEE single precision floating point space without
		// denormals (and signed zeros).
		const deInt32 aIndex = getPositionOfIEEEFloatWithoutDenormals(a);
		const deInt32 bIndex = getPositionOfIEEEFloatWithoutDenormals(b);
		return (deUint32)de::abs(aIndex - bIndex);
	}
}

static tcu::UVec4 computeFlushRelaxedULPDiff (const tcu::Vec4& a, const tcu::Vec4& b)
{
	return tcu::UVec4(computeFloatFlushRelaxedULPDiff(a.x(), b.x()),
					  computeFloatFlushRelaxedULPDiff(a.y(), b.y()),
					  computeFloatFlushRelaxedULPDiff(a.z(), b.z()),
					  computeFloatFlushRelaxedULPDiff(a.w(), b.w()));
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison uses ULP (units in last place) metric for computing the
 * difference between floating-point values and thus this function can
 * be used only for comparing floating-point texture data. In ULP calculation
 * the denormal numbers are allowed to be flushed to zero.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatUlpThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode)
{
	int					width				= reference.getWidth();
	int					height				= reference.getHeight();
	int					depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	UVec4				maxDiff				(0, 0, 0, 0);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	TCU_CHECK(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				const Vec4	refPix	= reference.getPixel(x, y, z);
				const Vec4	cmpPix	= result.getPixel(x, y, z);
				const UVec4	diff	= computeFlushRelaxedULPDiff(refPix, cmpPix);
				const bool	isOk	= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for floating-point and fixed-point formats.
 * Difference is computed in floating-point space.
 *
 * On failure an error image is generated that shows where the failing
 * pixels are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const Vec4& threshold, CompareLogMode logMode)
{
	int					width				= reference.getWidth();
	int					height				= reference.getHeight();
	int					depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	Vec4				maxDiff				(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				Vec4	refPix		= reference.getPixel(x, y, z);
				Vec4	cmpPix		= result.getPixel(x, y, z);

				Vec4	diff		= abs(refPix - cmpPix);
				bool	isOk		= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * color. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for floating-point and fixed-point formats.
 * Difference is computed in floating-point space.
 *
 * On failure an error image is generated that shows where the failing
 * pixels are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference color
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Vec4& reference, const ConstPixelBufferAccess& result, const Vec4& threshold, CompareLogMode logMode)
{
	const int			width				= result.getWidth();
	const int			height				= result.getHeight();
	const int			depth				= result.getDepth();

	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	Vec4				maxDiff				(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				const Vec4	cmpPix		= result.getPixel(x, y, z);
				const Vec4	diff		= abs(reference - cmpPix);
				const bool	isOk		= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(result, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result image is normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << ", reference = " << reference << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode)
{
	int					width				= reference.getWidth();
	int					height				= reference.getHeight();
	int					depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	UVec4				maxDiff				(0, 0, 0, 0);
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

	for (int z = 0; z < depth; z++)
	{
		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				IVec4	refPix		= reference.getPixelInt(x, y, z);
				IVec4	cmpPix		= result.getPixelInt(x, y, z);

				UVec4	diff		= abs(refPix - cmpPix).cast<deUint32>();
				bool	isOk		= boolAll(lessThanEqual(diff, threshold));

				maxDiff = max(maxDiff, diff);

				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
			}
		}
	}

	bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based deviation-ignoring comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if there is no pixel matching the given threshold
 * value in the search volume.
 *
 * If the search volume contains out-of-bounds pixels, comparison can be set
 * to either ignore these pixels in search or to accept any pixel that has
 * out-of-bounds pixels in its search volume.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log							Test log for results
 * \param imageSetName					Name for image set when logging results
 * \param imageSetDesc					Description for image set
 * \param reference						Reference image
 * \param result						Result image
 * \param threshold						Maximum allowed difference
 * \param maxPositionDeviation			Maximum allowed distance in the search
 *										volume.
 * \param acceptOutOfBoundsAsAnyValue	Accept any pixel in the boundary region
 * \param logMode						Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdPositionDeviationCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, CompareLogMode logMode)
{
	const int			width				= reference.getWidth();
	const int			height				= reference.getHeight();
	const int			depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	const int			numFailingPixels	= findNumPositionDeviationFailingPixels(errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
	const bool			compareOk			= numFailingPixels == 0;
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log	<< TestLog::Message
				<< "Image comparison failed:\n"
				<< "\tallowed position deviation = " << maxPositionDeviation << "\n"
				<< "\tcolor threshold = " << threshold
				<< TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based deviation-ignoring comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Pixel fails the test if there is no pixel matching the given
 * threshold value in the search volume. Comparison fails if the number of
 * failing pixels exceeds the given limit.
 *
 * If the search volume contains out-of-bounds pixels, comparison can be set
 * to either ignore these pixels in search or to accept any pixel that has
 * out-of-bounds pixels in its search volume.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log							Test log for results
 * \param imageSetName					Name for image set when logging results
 * \param imageSetDesc					Description for image set
 * \param reference						Reference image
 * \param result						Result image
 * \param threshold						Maximum allowed difference
 * \param maxPositionDeviation			Maximum allowed distance in the search
 *										volume.
 * \param acceptOutOfBoundsAsAnyValue	Accept any pixel in the boundary region
 * \param maxAllowedFailingPixels		Maximum number of failing pixels
 * \param logMode						Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdPositionDeviationErrorThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, int maxAllowedFailingPixels, CompareLogMode logMode)
{
	const int			width				= reference.getWidth();
	const int			height				= reference.getHeight();
	const int			depth				= reference.getDepth();
	TextureLevel		errorMaskStorage	(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
	PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
	const int			numFailingPixels	= findNumPositionDeviationFailingPixels(errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
	const bool			compareOk			= numFailingPixels <= maxAllowedFailingPixels;
	Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);

	if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		// All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
		if (tcu::getTextureChannelClass(reference.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
			tcu::getTextureChannelClass(result.getFormat().type)	!= tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
		{
			computeScaleAndBias(reference, result, pixelScale, pixelBias);
			log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
		}

		if (!compareOk)
			log	<< TestLog::Message
				<< "Image comparison failed:\n"
				<< "\tallowed position deviation = " << maxPositionDeviation << "\n"
				<< "\tcolor threshold = " << threshold
				<< TestLog::EndMessage;
		log << TestLog::Message << "Number of failing pixels = " << numFailingPixels << ", max allowed = " << maxAllowedFailingPixels << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum allowed difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool pixelThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, const RGBA& threshold, CompareLogMode logMode)
{
	return intThresholdCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold.toIVec().cast<deUint32>(), logMode);
}

/*--------------------------------------------------------------------*//*!
 * \brief Bilinear image comparison
 *
 * \todo [pyry] Describe
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note				Currently supports only RGBA, UNORM_INT8 formats
 * \param log			Test log for results
 * \param imageSetName	Name for image set when logging results
 * \param imageSetDesc	Description for image set
 * \param reference		Reference image
 * \param result		Result image
 * \param threshold		Maximum local difference
 * \param logMode		Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool bilinearCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const RGBA threshold, CompareLogMode logMode)
{
	TextureLevel		errorMask		(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
	bool				isOk			= bilinearCompare(reference, result, errorMask, threshold);
	Vec4				pixelBias		(0.0f, 0.0f, 0.0f, 0.0f);
	Vec4				pixelScale		(1.0f, 1.0f, 1.0f, 1.0f);

	if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computeScaleAndBias(reference, result, pixelScale, pixelBias);

		if (!isOk)
			log << TestLog::Message << "Image comparison failed, threshold = " << threshold << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result,		pixelScale, pixelBias)
			<< TestLog::Image("Reference",	"Reference",	reference,	pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask",	"Error mask",	errorMask)
			<< TestLog::EndImageSet;
	}
	else if (logMode == COMPARE_LOG_RESULT)
	{
		if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
			computePixelScaleBias(result, pixelScale, pixelBias);

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result, pixelScale, pixelBias)
			<< TestLog::EndImageSet;
	}

	return isOk;
}

} // tcu
