// -----------------------------------------------------------------------------
// CMaskedBitmap::CopyBitmapData
// -----------------------------------------------------------------------------
TInt BitmapUtil::CopyBitmapData( const CFbsBitmap& aSource, CFbsBitmap& aDestination,
                                   const TSize& aSize, const TDisplayMode& aDisplayMode )
    {
    HBufC8* scanLine = HBufC8::New( aSource.ScanLineLength( aSize.iWidth, aDisplayMode ) );
    if( scanLine )
        {
        TPtr8 scanPtr( scanLine->Des() );
        TPoint pp;
        for( pp.iY = 0; pp.iY < aSize.iHeight; ++pp.iY )
            {
            aSource.GetScanLine( scanPtr, pp, aSize.iWidth, aDisplayMode );
            aDestination.SetScanLine( scanPtr, pp.iY );
            }

        delete scanLine;
        return KErrNone;
        }
    return KErrNoMemory; // scanLine alloc failed
    }
/*
-----------------------------------------------------------------------------

  ProcessL

  Process image referenced by aImage (modify aImage).
  May leave with KErrNoMemory if no memory available

  Return Values:  none

-----------------------------------------------------------------------------
*/
void CDCDithering::ProcessL(CFbsBitmap& aImage)
{
    TUint	r, g, b;	// Color components
    TUint8*	dataPtr;	// Pointer to data

    //Dithering variables, init to 0
    TInt	count=0;
    TInt16	dither=0;

    //EColor16M image is needed
    if (aImage.DisplayMode() != EColor16M || aImage.DisplayMode() != EColor16M)
        return;

    // Line Buffer and pointer to the data
    TUint imageWidth = aImage.SizeInPixels().iWidth;
    TUint scanLineLengthInBytes = aImage.ScanLineLength(imageWidth, aImage.DisplayMode());

    //Allocate buffer for scanline
    iScanLineBuffer = HBufC8::NewMaxL(scanLineLengthInBytes);
    //Pointer to scanline
    TPtr8 linePtr = iScanLineBuffer->Des();

    //Step through image lines
    for (TInt lineNo=0; lineNo<aImage.SizeInPixels().iHeight; ++lineNo)
    {
        //Get line
        aImage.GetScanLine(linePtr, TPoint(0, lineNo), imageWidth, aImage.DisplayMode());
        //CHECK! CONST_CAST not used in every algorithm which way is better?
        dataPtr = CONST_CAST(TUint8*, linePtr.Ptr());

        //Step through image pixels
        for (TUint x=0; x < imageWidth; ++x)
        {
            // Get original values
            b = *dataPtr++;
            g = *dataPtr++;
            r = *dataPtr++;

            //Compute DCDithering factor from base count
            switch (count&1)
            {
            case 0:
                dither = (TInt16)(dither*0x7ffd);
                break;
            case 1:
                dither = (TInt16)(dither+0x7f21);
                break;
            }

            //Add DCDithering factor, adjust gain according to quantization factors.
            r = Limit255((TInt)r + (dither>>13));
            g = Limit255((TInt)g - (dither>>14));
            b = Limit255((TInt)b + (dither>>13));

            //Move to the previous pixel
            dataPtr -= 3;

            /* Set the result */
            *dataPtr++ = (TUint8)b;
            *dataPtr++ = (TUint8)g;
            *dataPtr++ = (TUint8)r;

            //Increase bae count
            count++;
        }

        //Set scan line
        aImage.SetScanLine(linePtr, lineNo);
    }

    //Free allocated memory
    delete(iScanLineBuffer);
    iScanLineBuffer = 0;
}