os/graphics/graphicstest/graphicstestharness/src/graphicsimagecomparison.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @test
    19 */
    20 
    21 #include "graphicsimagecomparison.h"
    22 
    23 /**
    24 Compares the contents of a rectangular region of one bitmap with a similarly sized
    25 rectangular region of another bitmap.
    26 
    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.
    45 */
    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)
    52 	{
    53 	TInt err = CheckArguments(aCompareSize,
    54                               aBitmap1Point,
    55                               aBitmap2Point,
    56                               aBitmap1,
    57                               aBitmap2);
    58 
    59 	if(err == KErrNone)
    60 		{
    61 		//Take local copies as cannot modify static arguments
    62 		TSize localSize(aCompareSize);
    63 		TPoint localPoint1(aBitmap1Point);
    64 		TPoint localPoint2(aBitmap2Point);
    65 
    66 		//Cope with negative aCompareSize dimensions
    67 		if(aCompareSize.iWidth < 0)
    68 			{
    69 			localSize.iWidth = -localSize.iWidth;
    70 			localPoint1.iX = localPoint1.iX - localSize.iWidth;
    71 			localPoint2.iX = localPoint2.iX - localSize.iWidth;
    72 			}
    73 
    74 		if(aCompareSize.iHeight < 0)
    75 			{
    76 			localSize.iHeight = -localSize.iHeight;
    77 			localPoint1.iY = localPoint1.iY - localSize.iHeight;
    78 			localPoint2.iY = localPoint2.iY - localSize.iHeight;
    79 			}
    80 
    81         // Set up buffers for obtaining scanlines
    82         TInt scanLineLength1 = aBitmap1.ScanLineLength(localSize.iWidth, ERgb);
    83 		TUint8* buffer1 = new TUint8[scanLineLength1];
    84 		if(!buffer1)
    85 		    {
    86 		    return KErrNoMemory;
    87 		    }
    88         TPtr8 scanLine1(buffer1, scanLineLength1, scanLineLength1);
    89 		TInt scanLineLength2 = aBitmap2.ScanLineLength(localSize.iWidth, ERgb);
    90         TUint8* buffer2 = new TUint8[scanLineLength2];
    91         if(!buffer2)
    92             {
    93             delete[] buffer1;
    94             return KErrNoMemory;
    95             }
    96         TPtr8 scanLine2(buffer2, scanLineLength2, scanLineLength2);
    97 
    98         //Perform scanline to scanline comparison without comparison mask
    99 	    for(TInt y=0; y<localSize.iHeight; y++)
   100             {
   101             aBitmap1.GetScanLine(scanLine1, localPoint1+TPoint(0,y), localSize.iWidth, ERgb);
   102             aBitmap2.GetScanLine(scanLine2, localPoint2+TPoint(0,y), localSize.iWidth, ERgb);
   103             
   104             if(aComparisonMask!=0xFFFFFFFF || scanLine1.Compare(scanLine2)!=0)
   105                 {
   106                 //Comparison mask has been set, or scanlines are not equal
   107                 //so perform pixel by pixel comparison using mask
   108                 TRgb pixel1, pixel2;
   109                 for(TInt x=0; x<localSize.iWidth; x++)
   110                     {
   111                     pixel1 = *(((TRgb*)buffer1) + x);
   112                     pixel2 = *(((TRgb*)buffer2) + x);
   113 
   114                     if( (pixel1.Internal()& aComparisonMask) != (pixel2.Internal()& aComparisonMask))
   115                         {
   116                         RDebug::Print(_L("x = %d y = %d  pixel1= %x pixel2 = %x"), x, y, pixel1.Internal(), pixel2.Internal());
   117                         delete[] buffer2;
   118                         delete[] buffer1;
   119                         return (y*localSize.iWidth + x) + 1;
   120                         }
   121                     }
   122                 }
   123            }
   124 	    delete[] buffer2;
   125 	    delete[] buffer1;
   126         }
   127     return err;
   128 	}
   129 
   130 /**
   131 Compares the contents of a rectangular region of a bitmap with a reference colour.
   132 
   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.
   149 */
   150 EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
   151                                                         const TPoint& aBitmapPoint,
   152                                                         const CFbsBitmap& aBitmap,
   153                                                         const TRgb& aColor,
   154                                                         const TUint32 aComparisonMask)
   155 	{
   156 	TInt err = CheckArgumentBitmap(aCompareSize,
   157                                    aBitmapPoint,
   158                                    aBitmap);
   159 
   160 	if(err == KErrNone)
   161 		{
   162 		//Take local copies as cannot modify static arguments
   163 		TSize localSize(aCompareSize);
   164 		TPoint localPoint(aBitmapPoint);
   165 
   166 		//Cope with negative aCompareSize dimensions
   167 		if(aCompareSize.iWidth < 0)
   168 			{
   169 			localSize.iWidth = -localSize.iWidth;
   170 			localPoint.iX = localPoint.iX - localSize.iWidth;
   171 			}
   172 
   173 		if(aCompareSize.iHeight < 0)
   174 			{
   175 			localSize.iHeight = -localSize.iHeight;
   176 			localPoint.iY = localPoint.iY - localSize.iHeight;
   177 			}
   178 
   179         // Set up buffers for obtaining scanlines
   180         TInt scanLineLength = aBitmap.ScanLineLength(localSize.iWidth, ERgb);
   181         TUint8* buffer = new TUint8[scanLineLength];
   182         if(!buffer)
   183             {
   184             return KErrNoMemory;
   185             }
   186         TPtr8 scanLine(buffer, scanLineLength, scanLineLength);
   187 
   188         //Perform the pixel by pixel comparison
   189         TRgb pixel;
   190 		for(TInt y=0; y<localSize.iHeight; y++)
   191 	 		{
   192             aBitmap.GetScanLine(scanLine, localPoint+TPoint(0,y), localSize.iWidth, ERgb);
   193 	 		for(TInt x=0; x<localSize.iWidth; x++)
   194 				{
   195                 pixel = *(((TRgb*)buffer) + x);
   196 
   197                 if( (pixel.Internal()& aComparisonMask) != (aColor.Internal()& aComparisonMask))
   198 					{
   199 					RDebug::Print(_L("x = %d y = %d  pixel= %x reference colour = %x"), x, y, pixel.Internal(), aColor.Internal());
   200                     delete[] buffer;
   201 					return (y*localSize.iWidth + x) + 1;
   202 					}
   203 				}
   204 	 		}
   205 	    delete[] buffer;
   206 		}
   207     return err;
   208 	}
   209 
   210 TInt CTGraphicsImageComparison::CheckArguments(const TSize& aCompareSize,
   211                                                const TPoint& aBitmap1Point,
   212                                                const TPoint& aBitmap2Point,
   213                                                const CFbsBitmap& aBitmap1,
   214                                                const CFbsBitmap& aBitmap2)
   215 	{
   216 	//Test that the arguments are valid for both bitmaps
   217 	TInt err = CheckArgumentBitmap(aCompareSize, aBitmap1Point, aBitmap1);
   218 
   219 	if(err == KErrNone)
   220 		{
   221 		err = CheckArgumentBitmap(aCompareSize, aBitmap2Point, aBitmap2);
   222 		}
   223 
   224 	return err;
   225 	}
   226 
   227 TInt CTGraphicsImageComparison::CheckArgumentBitmap(const TSize& aSize,
   228                                                     const TPoint& aPoint,
   229                                                     const CFbsBitmap& aBitmap)
   230 	{
   231 	//Top left-hand corner of the comparison rectangle is outside of the bitmap
   232 	if( (aPoint.iX < 0) || (aPoint.iY < 0) )
   233 		{
   234 		return KErrArgument;
   235 		}
   236 
   237 	if(aSize.iWidth >= 0)
   238 		{
   239 		//Comparison rectangle is outside of the bitmap (rhs)
   240 		if(aPoint.iX + aSize.iWidth > aBitmap.SizeInPixels().iWidth)
   241 			{
   242 			return KErrArgument;
   243 			}
   244 		}
   245 	else
   246 		{
   247 		//Comparison rectangle is outside of the bitmap (lhs)
   248 		if(aPoint.iX + aSize.iWidth < 0)
   249 			{
   250 			return KErrArgument;
   251 			}
   252 		}
   253 
   254 	if(aSize.iHeight >= 0)
   255 		{
   256 		//Comparison rectangle is outside of the bitmap (bottom)
   257 		if(aPoint.iY + aSize.iHeight > aBitmap.SizeInPixels().iHeight)
   258 			{
   259 			return KErrArgument;
   260 			}
   261 		}
   262 	else
   263 		{
   264 		//Comparison rectangle is outside of the bitmap (top)
   265 		if(aPoint.iY + aSize.iHeight < 0)
   266 			{
   267 			return KErrArgument;
   268 			}
   269 		}
   270 
   271 	return KErrNone;
   272 	}