/*-------------------------------------------------------------------------
 * 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 tcu::IVec4	okColor				(0, 255, 0, 255);
	const tcu::IVec4	errorColor			(255, 0, 0, 255);
	const int			width				= reference.getWidth();
	const int			height				= reference.getHeight();
	const int			depth				= reference.getDepth();
	int					numFailingPixels	= 0;

	// Accept pixels "sampling" over the image bounds pixels since "taps" could be anything
	const int			beginX				= (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.x()) : (0);
	const int			beginY				= (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.y()) : (0);
	const int			beginZ				= (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.z()) : (0);
	const int			endX				= (acceptOutOfBoundsAsAnyValue) ? (width  - maxPositionDeviation.x()) : (width);
	const int			endY				= (acceptOutOfBoundsAsAnyValue) ? (height - maxPositionDeviation.y()) : (height);
	const int			endZ				= (acceptOutOfBoundsAsAnyValue) ? (depth  - maxPositionDeviation.z()) : (depth);

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

	tcu::clear(errorMask, okColor);

	for (int z = beginZ; z < endZ; z++)
	{
		for (int y = beginY; y < endY; y++)
		{
			for (int x = beginX; x < endX; 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)
						continue;
				}

				// Find matching pixels for both result and reference pixel

				{
					bool pixelFoundForReference = 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;
					}

					if (!pixelFoundForReference)
					{
						errorMask.setPixel(errorColor, x, y, z);
						++numFailingPixels;
						continue;
					}
				}
				{
					bool pixelFoundForResult = false;

					// 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 (!pixelFoundForResult)
					{
						errorMask.setPixel(errorColor, x, y, z);
						++numFailingPixels;
						continue;
					}
				}
			}
		}
	}

	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. Add one since the removed range
			// contained one representable value, 0.
			return (deInt32)(f.bits() - (1u << 23u) + 1u);
		}
	}
}

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
