os/graphics/graphicstest/graphicstestharness/src/graphicsimagecomparison.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicstest/graphicstestharness/src/graphicsimagecomparison.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,272 @@
     1.4 +// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +/**
    1.20 + @file
    1.21 + @test
    1.22 +*/
    1.23 +
    1.24 +#include "graphicsimagecomparison.h"
    1.25 +
    1.26 +/**
    1.27 +Compares the contents of a rectangular region of one bitmap with a similarly sized
    1.28 +rectangular region of another bitmap.
    1.29 +
    1.30 +@param aCompareSize, a const reference to a TSize object denoting the size of the
    1.31 +rectangular region for comparison.Negative and zero dimensions of this argument can
    1.32 +be passed in without returning a KErrArgument error.
    1.33 +@param aBitmap1Point, a const reference to a TPoint object denoting the top left
    1.34 +point of the rectangle in aBitmap1 used for comparison..
    1.35 +@param aBitmap2Point, a const reference to a TPoint object denoting the top left
    1.36 +point of the rectangle in aBitmap2 used for comparison.
    1.37 +@param aBitmap1, a const reference to the first CFbsBitmap for use in comparison.
    1.38 +@param aBitmap2, a const reference to the second CFbsBitmap for use in comparison.
    1.39 +@param aComparisonMask, a bit mask to be applied to the bitmap pixel data before
    1.40 +performing the comparison, in the form 0xAARRGGBB. Defaults to 0xFFFFFFFF 
    1.41 +@pre The rectanglular comparison region must reside wholly inside both of the bitmaps
    1.42 +@return KErrNone if the pixels contained in the bitmap rectangles are an exact match
    1.43 +or, otherwise, the count of the first unmatched pixel. Pixels are compared from TRUE
    1.44 +top-left to bottom-right in the horizontal direction (TRUE to cope with negative
    1.45 +dimensions of the aCompareSize object) An area of zero size will return KErrNone so
    1.46 +long as the pre-conditions are satisfied.
    1.47 +KErrArgument if the pre-conditions are not met.
    1.48 +*/
    1.49 +EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
    1.50 +                                                        const TPoint& aBitmap1Point,
    1.51 +                                                        const TPoint& aBitmap2Point,
    1.52 +                                                        const CFbsBitmap& aBitmap1,
    1.53 +                                                        const CFbsBitmap& aBitmap2,
    1.54 +                                                        const TUint32 aComparisonMask)
    1.55 +	{
    1.56 +	TInt err = CheckArguments(aCompareSize,
    1.57 +                              aBitmap1Point,
    1.58 +                              aBitmap2Point,
    1.59 +                              aBitmap1,
    1.60 +                              aBitmap2);
    1.61 +
    1.62 +	if(err == KErrNone)
    1.63 +		{
    1.64 +		//Take local copies as cannot modify static arguments
    1.65 +		TSize localSize(aCompareSize);
    1.66 +		TPoint localPoint1(aBitmap1Point);
    1.67 +		TPoint localPoint2(aBitmap2Point);
    1.68 +
    1.69 +		//Cope with negative aCompareSize dimensions
    1.70 +		if(aCompareSize.iWidth < 0)
    1.71 +			{
    1.72 +			localSize.iWidth = -localSize.iWidth;
    1.73 +			localPoint1.iX = localPoint1.iX - localSize.iWidth;
    1.74 +			localPoint2.iX = localPoint2.iX - localSize.iWidth;
    1.75 +			}
    1.76 +
    1.77 +		if(aCompareSize.iHeight < 0)
    1.78 +			{
    1.79 +			localSize.iHeight = -localSize.iHeight;
    1.80 +			localPoint1.iY = localPoint1.iY - localSize.iHeight;
    1.81 +			localPoint2.iY = localPoint2.iY - localSize.iHeight;
    1.82 +			}
    1.83 +
    1.84 +        // Set up buffers for obtaining scanlines
    1.85 +        TInt scanLineLength1 = aBitmap1.ScanLineLength(localSize.iWidth, ERgb);
    1.86 +		TUint8* buffer1 = new TUint8[scanLineLength1];
    1.87 +		if(!buffer1)
    1.88 +		    {
    1.89 +		    return KErrNoMemory;
    1.90 +		    }
    1.91 +        TPtr8 scanLine1(buffer1, scanLineLength1, scanLineLength1);
    1.92 +		TInt scanLineLength2 = aBitmap2.ScanLineLength(localSize.iWidth, ERgb);
    1.93 +        TUint8* buffer2 = new TUint8[scanLineLength2];
    1.94 +        if(!buffer2)
    1.95 +            {
    1.96 +            delete[] buffer1;
    1.97 +            return KErrNoMemory;
    1.98 +            }
    1.99 +        TPtr8 scanLine2(buffer2, scanLineLength2, scanLineLength2);
   1.100 +
   1.101 +        //Perform scanline to scanline comparison without comparison mask
   1.102 +	    for(TInt y=0; y<localSize.iHeight; y++)
   1.103 +            {
   1.104 +            aBitmap1.GetScanLine(scanLine1, localPoint1+TPoint(0,y), localSize.iWidth, ERgb);
   1.105 +            aBitmap2.GetScanLine(scanLine2, localPoint2+TPoint(0,y), localSize.iWidth, ERgb);
   1.106 +            
   1.107 +            if(aComparisonMask!=0xFFFFFFFF || scanLine1.Compare(scanLine2)!=0)
   1.108 +                {
   1.109 +                //Comparison mask has been set, or scanlines are not equal
   1.110 +                //so perform pixel by pixel comparison using mask
   1.111 +                TRgb pixel1, pixel2;
   1.112 +                for(TInt x=0; x<localSize.iWidth; x++)
   1.113 +                    {
   1.114 +                    pixel1 = *(((TRgb*)buffer1) + x);
   1.115 +                    pixel2 = *(((TRgb*)buffer2) + x);
   1.116 +
   1.117 +                    if( (pixel1.Internal()& aComparisonMask) != (pixel2.Internal()& aComparisonMask))
   1.118 +                        {
   1.119 +                        RDebug::Print(_L("x = %d y = %d  pixel1= %x pixel2 = %x"), x, y, pixel1.Internal(), pixel2.Internal());
   1.120 +                        delete[] buffer2;
   1.121 +                        delete[] buffer1;
   1.122 +                        return (y*localSize.iWidth + x) + 1;
   1.123 +                        }
   1.124 +                    }
   1.125 +                }
   1.126 +           }
   1.127 +	    delete[] buffer2;
   1.128 +	    delete[] buffer1;
   1.129 +        }
   1.130 +    return err;
   1.131 +	}
   1.132 +
   1.133 +/**
   1.134 +Compares the contents of a rectangular region of a bitmap with a reference colour.
   1.135 +
   1.136 +@param aCompareSize, a const reference to a TSize object denoting the size of the
   1.137 +rectangular region for comparison.Negative and zero dimensions of this argument can
   1.138 +be passed in without returning a KErrArgument error.
   1.139 +@param aBitmapPoint, a const reference to a TPoint object denoting the top left
   1.140 +point of the rectangle in aBitmap1 used for comparison..
   1.141 +@param aBitmap, a const reference to the CFbsBitmap for use in comparison.
   1.142 +@param aColor, the colour to test for
   1.143 +@param aComparisonMask, a bit mask to be applied to both the bitmap pixel data and the
   1.144 +colour data before performing the comparison, in the form 0xAARRGGBB. Defaults to 0xFFFFFFFF 
   1.145 +@pre The rectanglular comparison region must reside wholly inside the bitmap
   1.146 +@return KErrNone if the pixels contained in the bitmap rectangles are an exact match
   1.147 +to the reference colour or, otherwise, the count of the first unmatched pixel. Pixels
   1.148 +are compared from TRUE top-left to bottom-right in the horizontal direction (TRUE to
   1.149 +cope with negative dimensions of the aCompareSize object) An area of zero size will
   1.150 +return KErrNone so long as the pre-conditions are satisfied.
   1.151 +KErrArgument if the pre-conditions are not met.
   1.152 +*/
   1.153 +EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
   1.154 +                                                        const TPoint& aBitmapPoint,
   1.155 +                                                        const CFbsBitmap& aBitmap,
   1.156 +                                                        const TRgb& aColor,
   1.157 +                                                        const TUint32 aComparisonMask)
   1.158 +	{
   1.159 +	TInt err = CheckArgumentBitmap(aCompareSize,
   1.160 +                                   aBitmapPoint,
   1.161 +                                   aBitmap);
   1.162 +
   1.163 +	if(err == KErrNone)
   1.164 +		{
   1.165 +		//Take local copies as cannot modify static arguments
   1.166 +		TSize localSize(aCompareSize);
   1.167 +		TPoint localPoint(aBitmapPoint);
   1.168 +
   1.169 +		//Cope with negative aCompareSize dimensions
   1.170 +		if(aCompareSize.iWidth < 0)
   1.171 +			{
   1.172 +			localSize.iWidth = -localSize.iWidth;
   1.173 +			localPoint.iX = localPoint.iX - localSize.iWidth;
   1.174 +			}
   1.175 +
   1.176 +		if(aCompareSize.iHeight < 0)
   1.177 +			{
   1.178 +			localSize.iHeight = -localSize.iHeight;
   1.179 +			localPoint.iY = localPoint.iY - localSize.iHeight;
   1.180 +			}
   1.181 +
   1.182 +        // Set up buffers for obtaining scanlines
   1.183 +        TInt scanLineLength = aBitmap.ScanLineLength(localSize.iWidth, ERgb);
   1.184 +        TUint8* buffer = new TUint8[scanLineLength];
   1.185 +        if(!buffer)
   1.186 +            {
   1.187 +            return KErrNoMemory;
   1.188 +            }
   1.189 +        TPtr8 scanLine(buffer, scanLineLength, scanLineLength);
   1.190 +
   1.191 +        //Perform the pixel by pixel comparison
   1.192 +        TRgb pixel;
   1.193 +		for(TInt y=0; y<localSize.iHeight; y++)
   1.194 +	 		{
   1.195 +            aBitmap.GetScanLine(scanLine, localPoint+TPoint(0,y), localSize.iWidth, ERgb);
   1.196 +	 		for(TInt x=0; x<localSize.iWidth; x++)
   1.197 +				{
   1.198 +                pixel = *(((TRgb*)buffer) + x);
   1.199 +
   1.200 +                if( (pixel.Internal()& aComparisonMask) != (aColor.Internal()& aComparisonMask))
   1.201 +					{
   1.202 +					RDebug::Print(_L("x = %d y = %d  pixel= %x reference colour = %x"), x, y, pixel.Internal(), aColor.Internal());
   1.203 +                    delete[] buffer;
   1.204 +					return (y*localSize.iWidth + x) + 1;
   1.205 +					}
   1.206 +				}
   1.207 +	 		}
   1.208 +	    delete[] buffer;
   1.209 +		}
   1.210 +    return err;
   1.211 +	}
   1.212 +
   1.213 +TInt CTGraphicsImageComparison::CheckArguments(const TSize& aCompareSize,
   1.214 +                                               const TPoint& aBitmap1Point,
   1.215 +                                               const TPoint& aBitmap2Point,
   1.216 +                                               const CFbsBitmap& aBitmap1,
   1.217 +                                               const CFbsBitmap& aBitmap2)
   1.218 +	{
   1.219 +	//Test that the arguments are valid for both bitmaps
   1.220 +	TInt err = CheckArgumentBitmap(aCompareSize, aBitmap1Point, aBitmap1);
   1.221 +
   1.222 +	if(err == KErrNone)
   1.223 +		{
   1.224 +		err = CheckArgumentBitmap(aCompareSize, aBitmap2Point, aBitmap2);
   1.225 +		}
   1.226 +
   1.227 +	return err;
   1.228 +	}
   1.229 +
   1.230 +TInt CTGraphicsImageComparison::CheckArgumentBitmap(const TSize& aSize,
   1.231 +                                                    const TPoint& aPoint,
   1.232 +                                                    const CFbsBitmap& aBitmap)
   1.233 +	{
   1.234 +	//Top left-hand corner of the comparison rectangle is outside of the bitmap
   1.235 +	if( (aPoint.iX < 0) || (aPoint.iY < 0) )
   1.236 +		{
   1.237 +		return KErrArgument;
   1.238 +		}
   1.239 +
   1.240 +	if(aSize.iWidth >= 0)
   1.241 +		{
   1.242 +		//Comparison rectangle is outside of the bitmap (rhs)
   1.243 +		if(aPoint.iX + aSize.iWidth > aBitmap.SizeInPixels().iWidth)
   1.244 +			{
   1.245 +			return KErrArgument;
   1.246 +			}
   1.247 +		}
   1.248 +	else
   1.249 +		{
   1.250 +		//Comparison rectangle is outside of the bitmap (lhs)
   1.251 +		if(aPoint.iX + aSize.iWidth < 0)
   1.252 +			{
   1.253 +			return KErrArgument;
   1.254 +			}
   1.255 +		}
   1.256 +
   1.257 +	if(aSize.iHeight >= 0)
   1.258 +		{
   1.259 +		//Comparison rectangle is outside of the bitmap (bottom)
   1.260 +		if(aPoint.iY + aSize.iHeight > aBitmap.SizeInPixels().iHeight)
   1.261 +			{
   1.262 +			return KErrArgument;
   1.263 +			}
   1.264 +		}
   1.265 +	else
   1.266 +		{
   1.267 +		//Comparison rectangle is outside of the bitmap (top)
   1.268 +		if(aPoint.iY + aSize.iHeight < 0)
   1.269 +			{
   1.270 +			return KErrArgument;
   1.271 +			}
   1.272 +		}
   1.273 +
   1.274 +	return KErrNone;
   1.275 +	}