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 + }