os/graphics/graphicstest/graphicstestharness/src/graphicsimagecomparison.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
/**
sl@0
    17
 @file
sl@0
    18
 @test
sl@0
    19
*/
sl@0
    20
sl@0
    21
#include "graphicsimagecomparison.h"
sl@0
    22
sl@0
    23
/**
sl@0
    24
Compares the contents of a rectangular region of one bitmap with a similarly sized
sl@0
    25
rectangular region of another bitmap.
sl@0
    26
sl@0
    27
@param aCompareSize, a const reference to a TSize object denoting the size of the
sl@0
    28
rectangular region for comparison.Negative and zero dimensions of this argument can
sl@0
    29
be passed in without returning a KErrArgument error.
sl@0
    30
@param aBitmap1Point, a const reference to a TPoint object denoting the top left
sl@0
    31
point of the rectangle in aBitmap1 used for comparison..
sl@0
    32
@param aBitmap2Point, a const reference to a TPoint object denoting the top left
sl@0
    33
point of the rectangle in aBitmap2 used for comparison.
sl@0
    34
@param aBitmap1, a const reference to the first CFbsBitmap for use in comparison.
sl@0
    35
@param aBitmap2, a const reference to the second CFbsBitmap for use in comparison.
sl@0
    36
@param aComparisonMask, a bit mask to be applied to the bitmap pixel data before
sl@0
    37
performing the comparison, in the form 0xAARRGGBB. Defaults to 0xFFFFFFFF 
sl@0
    38
@pre The rectanglular comparison region must reside wholly inside both of the bitmaps
sl@0
    39
@return KErrNone if the pixels contained in the bitmap rectangles are an exact match
sl@0
    40
or, otherwise, the count of the first unmatched pixel. Pixels are compared from TRUE
sl@0
    41
top-left to bottom-right in the horizontal direction (TRUE to cope with negative
sl@0
    42
dimensions of the aCompareSize object) An area of zero size will return KErrNone so
sl@0
    43
long as the pre-conditions are satisfied.
sl@0
    44
KErrArgument if the pre-conditions are not met.
sl@0
    45
*/
sl@0
    46
EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
sl@0
    47
                                                        const TPoint& aBitmap1Point,
sl@0
    48
                                                        const TPoint& aBitmap2Point,
sl@0
    49
                                                        const CFbsBitmap& aBitmap1,
sl@0
    50
                                                        const CFbsBitmap& aBitmap2,
sl@0
    51
                                                        const TUint32 aComparisonMask)
sl@0
    52
	{
sl@0
    53
	TInt err = CheckArguments(aCompareSize,
sl@0
    54
                              aBitmap1Point,
sl@0
    55
                              aBitmap2Point,
sl@0
    56
                              aBitmap1,
sl@0
    57
                              aBitmap2);
sl@0
    58
sl@0
    59
	if(err == KErrNone)
sl@0
    60
		{
sl@0
    61
		//Take local copies as cannot modify static arguments
sl@0
    62
		TSize localSize(aCompareSize);
sl@0
    63
		TPoint localPoint1(aBitmap1Point);
sl@0
    64
		TPoint localPoint2(aBitmap2Point);
sl@0
    65
sl@0
    66
		//Cope with negative aCompareSize dimensions
sl@0
    67
		if(aCompareSize.iWidth < 0)
sl@0
    68
			{
sl@0
    69
			localSize.iWidth = -localSize.iWidth;
sl@0
    70
			localPoint1.iX = localPoint1.iX - localSize.iWidth;
sl@0
    71
			localPoint2.iX = localPoint2.iX - localSize.iWidth;
sl@0
    72
			}
sl@0
    73
sl@0
    74
		if(aCompareSize.iHeight < 0)
sl@0
    75
			{
sl@0
    76
			localSize.iHeight = -localSize.iHeight;
sl@0
    77
			localPoint1.iY = localPoint1.iY - localSize.iHeight;
sl@0
    78
			localPoint2.iY = localPoint2.iY - localSize.iHeight;
sl@0
    79
			}
sl@0
    80
sl@0
    81
        // Set up buffers for obtaining scanlines
sl@0
    82
        TInt scanLineLength1 = aBitmap1.ScanLineLength(localSize.iWidth, ERgb);
sl@0
    83
		TUint8* buffer1 = new TUint8[scanLineLength1];
sl@0
    84
		if(!buffer1)
sl@0
    85
		    {
sl@0
    86
		    return KErrNoMemory;
sl@0
    87
		    }
sl@0
    88
        TPtr8 scanLine1(buffer1, scanLineLength1, scanLineLength1);
sl@0
    89
		TInt scanLineLength2 = aBitmap2.ScanLineLength(localSize.iWidth, ERgb);
sl@0
    90
        TUint8* buffer2 = new TUint8[scanLineLength2];
sl@0
    91
        if(!buffer2)
sl@0
    92
            {
sl@0
    93
            delete[] buffer1;
sl@0
    94
            return KErrNoMemory;
sl@0
    95
            }
sl@0
    96
        TPtr8 scanLine2(buffer2, scanLineLength2, scanLineLength2);
sl@0
    97
sl@0
    98
        //Perform scanline to scanline comparison without comparison mask
sl@0
    99
	    for(TInt y=0; y<localSize.iHeight; y++)
sl@0
   100
            {
sl@0
   101
            aBitmap1.GetScanLine(scanLine1, localPoint1+TPoint(0,y), localSize.iWidth, ERgb);
sl@0
   102
            aBitmap2.GetScanLine(scanLine2, localPoint2+TPoint(0,y), localSize.iWidth, ERgb);
sl@0
   103
            
sl@0
   104
            if(aComparisonMask!=0xFFFFFFFF || scanLine1.Compare(scanLine2)!=0)
sl@0
   105
                {
sl@0
   106
                //Comparison mask has been set, or scanlines are not equal
sl@0
   107
                //so perform pixel by pixel comparison using mask
sl@0
   108
                TRgb pixel1, pixel2;
sl@0
   109
                for(TInt x=0; x<localSize.iWidth; x++)
sl@0
   110
                    {
sl@0
   111
                    pixel1 = *(((TRgb*)buffer1) + x);
sl@0
   112
                    pixel2 = *(((TRgb*)buffer2) + x);
sl@0
   113
sl@0
   114
                    if( (pixel1.Internal()& aComparisonMask) != (pixel2.Internal()& aComparisonMask))
sl@0
   115
                        {
sl@0
   116
                        RDebug::Print(_L("x = %d y = %d  pixel1= %x pixel2 = %x"), x, y, pixel1.Internal(), pixel2.Internal());
sl@0
   117
                        delete[] buffer2;
sl@0
   118
                        delete[] buffer1;
sl@0
   119
                        return (y*localSize.iWidth + x) + 1;
sl@0
   120
                        }
sl@0
   121
                    }
sl@0
   122
                }
sl@0
   123
           }
sl@0
   124
	    delete[] buffer2;
sl@0
   125
	    delete[] buffer1;
sl@0
   126
        }
sl@0
   127
    return err;
sl@0
   128
	}
sl@0
   129
sl@0
   130
/**
sl@0
   131
Compares the contents of a rectangular region of a bitmap with a reference colour.
sl@0
   132
sl@0
   133
@param aCompareSize, a const reference to a TSize object denoting the size of the
sl@0
   134
rectangular region for comparison.Negative and zero dimensions of this argument can
sl@0
   135
be passed in without returning a KErrArgument error.
sl@0
   136
@param aBitmapPoint, a const reference to a TPoint object denoting the top left
sl@0
   137
point of the rectangle in aBitmap1 used for comparison..
sl@0
   138
@param aBitmap, a const reference to the CFbsBitmap for use in comparison.
sl@0
   139
@param aColor, the colour to test for
sl@0
   140
@param aComparisonMask, a bit mask to be applied to both the bitmap pixel data and the
sl@0
   141
colour data before performing the comparison, in the form 0xAARRGGBB. Defaults to 0xFFFFFFFF 
sl@0
   142
@pre The rectanglular comparison region must reside wholly inside the bitmap
sl@0
   143
@return KErrNone if the pixels contained in the bitmap rectangles are an exact match
sl@0
   144
to the reference colour or, otherwise, the count of the first unmatched pixel. Pixels
sl@0
   145
are compared from TRUE top-left to bottom-right in the horizontal direction (TRUE to
sl@0
   146
cope with negative dimensions of the aCompareSize object) An area of zero size will
sl@0
   147
return KErrNone so long as the pre-conditions are satisfied.
sl@0
   148
KErrArgument if the pre-conditions are not met.
sl@0
   149
*/
sl@0
   150
EXPORT_C TInt CTGraphicsImageComparison::CompareBitmaps(const TSize& aCompareSize,
sl@0
   151
                                                        const TPoint& aBitmapPoint,
sl@0
   152
                                                        const CFbsBitmap& aBitmap,
sl@0
   153
                                                        const TRgb& aColor,
sl@0
   154
                                                        const TUint32 aComparisonMask)
sl@0
   155
	{
sl@0
   156
	TInt err = CheckArgumentBitmap(aCompareSize,
sl@0
   157
                                   aBitmapPoint,
sl@0
   158
                                   aBitmap);
sl@0
   159
sl@0
   160
	if(err == KErrNone)
sl@0
   161
		{
sl@0
   162
		//Take local copies as cannot modify static arguments
sl@0
   163
		TSize localSize(aCompareSize);
sl@0
   164
		TPoint localPoint(aBitmapPoint);
sl@0
   165
sl@0
   166
		//Cope with negative aCompareSize dimensions
sl@0
   167
		if(aCompareSize.iWidth < 0)
sl@0
   168
			{
sl@0
   169
			localSize.iWidth = -localSize.iWidth;
sl@0
   170
			localPoint.iX = localPoint.iX - localSize.iWidth;
sl@0
   171
			}
sl@0
   172
sl@0
   173
		if(aCompareSize.iHeight < 0)
sl@0
   174
			{
sl@0
   175
			localSize.iHeight = -localSize.iHeight;
sl@0
   176
			localPoint.iY = localPoint.iY - localSize.iHeight;
sl@0
   177
			}
sl@0
   178
sl@0
   179
        // Set up buffers for obtaining scanlines
sl@0
   180
        TInt scanLineLength = aBitmap.ScanLineLength(localSize.iWidth, ERgb);
sl@0
   181
        TUint8* buffer = new TUint8[scanLineLength];
sl@0
   182
        if(!buffer)
sl@0
   183
            {
sl@0
   184
            return KErrNoMemory;
sl@0
   185
            }
sl@0
   186
        TPtr8 scanLine(buffer, scanLineLength, scanLineLength);
sl@0
   187
sl@0
   188
        //Perform the pixel by pixel comparison
sl@0
   189
        TRgb pixel;
sl@0
   190
		for(TInt y=0; y<localSize.iHeight; y++)
sl@0
   191
	 		{
sl@0
   192
            aBitmap.GetScanLine(scanLine, localPoint+TPoint(0,y), localSize.iWidth, ERgb);
sl@0
   193
	 		for(TInt x=0; x<localSize.iWidth; x++)
sl@0
   194
				{
sl@0
   195
                pixel = *(((TRgb*)buffer) + x);
sl@0
   196
sl@0
   197
                if( (pixel.Internal()& aComparisonMask) != (aColor.Internal()& aComparisonMask))
sl@0
   198
					{
sl@0
   199
					RDebug::Print(_L("x = %d y = %d  pixel= %x reference colour = %x"), x, y, pixel.Internal(), aColor.Internal());
sl@0
   200
                    delete[] buffer;
sl@0
   201
					return (y*localSize.iWidth + x) + 1;
sl@0
   202
					}
sl@0
   203
				}
sl@0
   204
	 		}
sl@0
   205
	    delete[] buffer;
sl@0
   206
		}
sl@0
   207
    return err;
sl@0
   208
	}
sl@0
   209
sl@0
   210
TInt CTGraphicsImageComparison::CheckArguments(const TSize& aCompareSize,
sl@0
   211
                                               const TPoint& aBitmap1Point,
sl@0
   212
                                               const TPoint& aBitmap2Point,
sl@0
   213
                                               const CFbsBitmap& aBitmap1,
sl@0
   214
                                               const CFbsBitmap& aBitmap2)
sl@0
   215
	{
sl@0
   216
	//Test that the arguments are valid for both bitmaps
sl@0
   217
	TInt err = CheckArgumentBitmap(aCompareSize, aBitmap1Point, aBitmap1);
sl@0
   218
sl@0
   219
	if(err == KErrNone)
sl@0
   220
		{
sl@0
   221
		err = CheckArgumentBitmap(aCompareSize, aBitmap2Point, aBitmap2);
sl@0
   222
		}
sl@0
   223
sl@0
   224
	return err;
sl@0
   225
	}
sl@0
   226
sl@0
   227
TInt CTGraphicsImageComparison::CheckArgumentBitmap(const TSize& aSize,
sl@0
   228
                                                    const TPoint& aPoint,
sl@0
   229
                                                    const CFbsBitmap& aBitmap)
sl@0
   230
	{
sl@0
   231
	//Top left-hand corner of the comparison rectangle is outside of the bitmap
sl@0
   232
	if( (aPoint.iX < 0) || (aPoint.iY < 0) )
sl@0
   233
		{
sl@0
   234
		return KErrArgument;
sl@0
   235
		}
sl@0
   236
sl@0
   237
	if(aSize.iWidth >= 0)
sl@0
   238
		{
sl@0
   239
		//Comparison rectangle is outside of the bitmap (rhs)
sl@0
   240
		if(aPoint.iX + aSize.iWidth > aBitmap.SizeInPixels().iWidth)
sl@0
   241
			{
sl@0
   242
			return KErrArgument;
sl@0
   243
			}
sl@0
   244
		}
sl@0
   245
	else
sl@0
   246
		{
sl@0
   247
		//Comparison rectangle is outside of the bitmap (lhs)
sl@0
   248
		if(aPoint.iX + aSize.iWidth < 0)
sl@0
   249
			{
sl@0
   250
			return KErrArgument;
sl@0
   251
			}
sl@0
   252
		}
sl@0
   253
sl@0
   254
	if(aSize.iHeight >= 0)
sl@0
   255
		{
sl@0
   256
		//Comparison rectangle is outside of the bitmap (bottom)
sl@0
   257
		if(aPoint.iY + aSize.iHeight > aBitmap.SizeInPixels().iHeight)
sl@0
   258
			{
sl@0
   259
			return KErrArgument;
sl@0
   260
			}
sl@0
   261
		}
sl@0
   262
	else
sl@0
   263
		{
sl@0
   264
		//Comparison rectangle is outside of the bitmap (top)
sl@0
   265
		if(aPoint.iY + aSize.iHeight < 0)
sl@0
   266
			{
sl@0
   267
			return KErrArgument;
sl@0
   268
			}
sl@0
   269
		}
sl@0
   270
sl@0
   271
	return KErrNone;
sl@0
   272
	}