First public contribution.
1 // Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include "graphicsimagecomparison.h"
24 Compares the contents of a rectangular region of one bitmap with a similarly sized
25 rectangular region of another bitmap.
27 @param aCompareSize, a const reference to a TSize object denoting the size of the
28 rectangular region for comparison.Negative and zero dimensions of this argument can
29 be passed in without returning a KErrArgument error.
30 @param aBitmap1Point, a const reference to a TPoint object denoting the top left
31 point of the rectangle in aBitmap1 used for comparison..
32 @param aBitmap2Point, a const reference to a TPoint object denoting the top left
33 point of the rectangle in aBitmap2 used for comparison.
34 @param aBitmap1, a const reference to the first CFbsBitmap for use in comparison.
35 @param aBitmap2, a const reference to the second CFbsBitmap for use in comparison.
36 @param aComparisonMask, a bit mask to be applied to the bitmap pixel data before
37 performing the comparison, in the form 0xAARRGGBB. Defaults to 0xFFFFFFFF
38 @pre The rectanglular comparison region must reside wholly inside both of the bitmaps
39 @return KErrNone if the pixels contained in the bitmap rectangles are an exact match
40 or, otherwise, the count of the first unmatched pixel. Pixels are compared from TRUE
41 top-left to bottom-right in the horizontal direction (TRUE to cope with negative
42 dimensions of the aCompareSize object) An area of zero size will return KErrNone so
43 long as the pre-conditions are satisfied.
44 KErrArgument if the pre-conditions are not met.
46 EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
47 const TPoint& aBitmap1Point,
48 const TPoint& aBitmap2Point,
49 const CFbsBitmap& aBitmap1,
50 const CFbsBitmap& aBitmap2,
51 const TUint32 aComparisonMask)
53 TInt err = CheckArguments(aCompareSize,
61 //Take local copies as cannot modify static arguments
62 TSize localSize(aCompareSize);
63 TPoint localPoint1(aBitmap1Point);
64 TPoint localPoint2(aBitmap2Point);
66 //Cope with negative aCompareSize dimensions
67 if(aCompareSize.iWidth < 0)
69 localSize.iWidth = -localSize.iWidth;
70 localPoint1.iX = localPoint1.iX - localSize.iWidth;
71 localPoint2.iX = localPoint2.iX - localSize.iWidth;
74 if(aCompareSize.iHeight < 0)
76 localSize.iHeight = -localSize.iHeight;
77 localPoint1.iY = localPoint1.iY - localSize.iHeight;
78 localPoint2.iY = localPoint2.iY - localSize.iHeight;
81 // Set up buffers for obtaining scanlines
82 TInt scanLineLength1 = aBitmap1.ScanLineLength(localSize.iWidth, ERgb);
83 TUint8* buffer1 = new TUint8[scanLineLength1];
88 TPtr8 scanLine1(buffer1, scanLineLength1, scanLineLength1);
89 TInt scanLineLength2 = aBitmap2.ScanLineLength(localSize.iWidth, ERgb);
90 TUint8* buffer2 = new TUint8[scanLineLength2];
96 TPtr8 scanLine2(buffer2, scanLineLength2, scanLineLength2);
98 //Perform scanline to scanline comparison without comparison mask
99 for(TInt y=0; y<localSize.iHeight; y++)
101 aBitmap1.GetScanLine(scanLine1, localPoint1+TPoint(0,y), localSize.iWidth, ERgb);
102 aBitmap2.GetScanLine(scanLine2, localPoint2+TPoint(0,y), localSize.iWidth, ERgb);
104 if(aComparisonMask!=0xFFFFFFFF || scanLine1.Compare(scanLine2)!=0)
106 //Comparison mask has been set, or scanlines are not equal
107 //so perform pixel by pixel comparison using mask
109 for(TInt x=0; x<localSize.iWidth; x++)
111 pixel1 = *(((TRgb*)buffer1) + x);
112 pixel2 = *(((TRgb*)buffer2) + x);
114 if( (pixel1.Internal()& aComparisonMask) != (pixel2.Internal()& aComparisonMask))
116 RDebug::Print(_L("x = %d y = %d pixel1= %x pixel2 = %x"), x, y, pixel1.Internal(), pixel2.Internal());
119 return (y*localSize.iWidth + x) + 1;
131 Compares the contents of a rectangular region of a bitmap with a reference colour.
133 @param aCompareSize, a const reference to a TSize object denoting the size of the
134 rectangular region for comparison.Negative and zero dimensions of this argument can
135 be passed in without returning a KErrArgument error.
136 @param aBitmapPoint, a const reference to a TPoint object denoting the top left
137 point of the rectangle in aBitmap1 used for comparison..
138 @param aBitmap, a const reference to the CFbsBitmap for use in comparison.
139 @param aColor, the colour to test for
140 @param aComparisonMask, a bit mask to be applied to both the bitmap pixel data and the
141 colour data before performing the comparison, in the form 0xAARRGGBB. Defaults to 0xFFFFFFFF
142 @pre The rectanglular comparison region must reside wholly inside the bitmap
143 @return KErrNone if the pixels contained in the bitmap rectangles are an exact match
144 to the reference colour or, otherwise, the count of the first unmatched pixel. Pixels
145 are compared from TRUE top-left to bottom-right in the horizontal direction (TRUE to
146 cope with negative dimensions of the aCompareSize object) An area of zero size will
147 return KErrNone so long as the pre-conditions are satisfied.
148 KErrArgument if the pre-conditions are not met.
150 EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
151 const TPoint& aBitmapPoint,
152 const CFbsBitmap& aBitmap,
154 const TUint32 aComparisonMask)
156 TInt err = CheckArgumentBitmap(aCompareSize,
162 //Take local copies as cannot modify static arguments
163 TSize localSize(aCompareSize);
164 TPoint localPoint(aBitmapPoint);
166 //Cope with negative aCompareSize dimensions
167 if(aCompareSize.iWidth < 0)
169 localSize.iWidth = -localSize.iWidth;
170 localPoint.iX = localPoint.iX - localSize.iWidth;
173 if(aCompareSize.iHeight < 0)
175 localSize.iHeight = -localSize.iHeight;
176 localPoint.iY = localPoint.iY - localSize.iHeight;
179 // Set up buffers for obtaining scanlines
180 TInt scanLineLength = aBitmap.ScanLineLength(localSize.iWidth, ERgb);
181 TUint8* buffer = new TUint8[scanLineLength];
186 TPtr8 scanLine(buffer, scanLineLength, scanLineLength);
188 //Perform the pixel by pixel comparison
190 for(TInt y=0; y<localSize.iHeight; y++)
192 aBitmap.GetScanLine(scanLine, localPoint+TPoint(0,y), localSize.iWidth, ERgb);
193 for(TInt x=0; x<localSize.iWidth; x++)
195 pixel = *(((TRgb*)buffer) + x);
197 if( (pixel.Internal()& aComparisonMask) != (aColor.Internal()& aComparisonMask))
199 RDebug::Print(_L("x = %d y = %d pixel= %x reference colour = %x"), x, y, pixel.Internal(), aColor.Internal());
201 return (y*localSize.iWidth + x) + 1;
210 TInt CTGraphicsImageComparison::CheckArguments(const TSize& aCompareSize,
211 const TPoint& aBitmap1Point,
212 const TPoint& aBitmap2Point,
213 const CFbsBitmap& aBitmap1,
214 const CFbsBitmap& aBitmap2)
216 //Test that the arguments are valid for both bitmaps
217 TInt err = CheckArgumentBitmap(aCompareSize, aBitmap1Point, aBitmap1);
221 err = CheckArgumentBitmap(aCompareSize, aBitmap2Point, aBitmap2);
227 TInt CTGraphicsImageComparison::CheckArgumentBitmap(const TSize& aSize,
228 const TPoint& aPoint,
229 const CFbsBitmap& aBitmap)
231 //Top left-hand corner of the comparison rectangle is outside of the bitmap
232 if( (aPoint.iX < 0) || (aPoint.iY < 0) )
237 if(aSize.iWidth >= 0)
239 //Comparison rectangle is outside of the bitmap (rhs)
240 if(aPoint.iX + aSize.iWidth > aBitmap.SizeInPixels().iWidth)
247 //Comparison rectangle is outside of the bitmap (lhs)
248 if(aPoint.iX + aSize.iWidth < 0)
254 if(aSize.iHeight >= 0)
256 //Comparison rectangle is outside of the bitmap (bottom)
257 if(aPoint.iY + aSize.iHeight > aBitmap.SizeInPixels().iHeight)
264 //Comparison rectangle is outside of the bitmap (top)
265 if(aPoint.iY + aSize.iHeight < 0)