diff -r 000000000000 -r 5752a19fdefe imaging/imagingplugins/codecs/JPEGCodec/rgbbufferptr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imaging/imagingplugins/codecs/JPEGCodec/rgbbufferptr.cpp Wed Aug 25 12:29:52 2010 +0300 @@ -0,0 +1,184 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include "JpegConsts.h" + +#include "rgbbufferptr.h" + + +/*static*/ +CRgbBufferPtr* CRgbBufferPtr::NewL(CFbsBitmap& aBitmap, const TSize& aMCUSizeinPixels) + { + CRgbBufferPtr* self = new (ELeave) CRgbBufferPtr(aBitmap, aMCUSizeinPixels); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CRgbBufferPtr::CRgbBufferPtr(CFbsBitmap& aBitmap, const TSize& aMCUSizeinPixels): + iBitmapSize( aBitmap.SizeInPixels() ), + iMCUSizeinPixels( aMCUSizeinPixels ), + iBufferPos(-1,-1), + iBitmap( &aBitmap ) + { + } + +void CRgbBufferPtr::ConstructL() + { + if ((iBitmapSize.iWidth <= 0) || (iBitmapSize.iHeight <= 0)) + { + User::Leave(KErrArgument); + } + + iBitmapData = iBitmap->DataAddress(); + iBitmapScanlineLength = iBitmap->ScanLineLength(iBitmapSize.iWidth, iBitmap->DisplayMode()); + + if (iBitmap->DisplayMode() == EColor16M) + { + iBufferSizeInPixels.SetSize( iMCUSizeinPixels.iWidth, iMCUSizeinPixels.iHeight); + iBitmapDirectAccess = ETrue; + } + else + { + // we reduce number of bitmap round-robins using horizontally-widened buffer ONLY! + TInt width = Max(iMCUSizeinPixels.iWidth, Min(iMCUSizeinPixels.iWidth<<2, iBitmapSize.iWidth)); + if (width == iBitmapSize.iWidth ) + { + TInt oddPixels = width % iMCUSizeinPixels.iWidth; + if (oddPixels) + { + width += iMCUSizeinPixels.iWidth - oddPixels; + } + } + iBufferSizeInPixels.SetSize( width, iMCUSizeinPixels.iHeight); + iBitmapDirectAccess = EFalse; + } + + iOriginalRgbBuffer = reinterpret_cast(User::AllocL(Coord2Size(iBufferSizeInPixels.iWidth, iBufferSizeInPixels.iHeight) + sizeof(TUint32))); + iRgbBuffer = Align4(iOriginalRgbBuffer); + + iBufferScanlineLength = iBufferSizeInPixels.iWidth * KRgbBufferPixelSize; + } + +CRgbBufferPtr::~CRgbBufferPtr() + { + User::Free( iOriginalRgbBuffer); + iOriginalRgbBuffer = NULL; + iRgbBuffer = NULL; + } + + +CRgbBufferPtr::TConstRgbBufferPtr CRgbBufferPtr::LockBuffer(const TPoint& aTopLeft) + { + ASSERT( aTopLeft.iX < iBitmapSize.iWidth ); + ASSERT( aTopLeft.iY < iBitmapSize.iHeight ); + + //const TBool KDirectAccess = ( iBitmap->DisplayMode() == EColor16M ); + const TBool KInplaceAccess= iBitmapDirectAccess; + + if ( !KInplaceAccess && + aTopLeft.iY >= iBufferPos.iY && aTopLeft.iY + iMCUSizeinPixels.iHeight <= iBufferPos.iY + iBufferSizeInPixels.iHeight && + aTopLeft.iX >= iBufferPos.iX && aTopLeft.iX + iMCUSizeinPixels.iWidth <= iBufferPos.iX + iBufferSizeInPixels.iWidth + ) + { + iLockedPtr = ShiftPtr(iRgbBuffer, aTopLeft.iX - iBufferPos.iX); + return iLockedPtr; + } + + iLockedPtr = reinterpret_cast(iBitmapData) + iBitmapScanlineLength * aTopLeft.iY + KRgbBufferPixelSize * aTopLeft.iX; + + if (aTopLeft.iX + iMCUSizeinPixels.iWidth <= iBitmapSize.iWidth && + aTopLeft.iY + iMCUSizeinPixels.iHeight <= iBitmapSize.iHeight && + KInplaceAccess) + { + //ASSERT( iBitmapScanlineLength % KRgbBufferPixelSize == 0 ); + iNextLineOffset = iBitmapScanlineLength; + iBufferPos.iX = -1; + } + else + { + const TInt KLineLen = KRgbBufferPixelSize * Min(iBufferSizeInPixels.iWidth, iBitmapSize.iWidth - aTopLeft.iX); + const TInt KNumLines = Min(iBufferSizeInPixels.iHeight, iBitmapSize.iHeight - aTopLeft.iY); + + const TInt KBufferLineLen = iBufferScanlineLength; + + TRgbBufferPtr pixelBufferPtr = iRgbBuffer; + if (KInplaceAccess) + { + for (TInt y = KNumLines; y--; ) + { + Mem::Copy(pixelBufferPtr, iLockedPtr, KLineLen); + iLockedPtr += iBitmapScanlineLength; + + // now fill out hor trail using grey + const TInt green = pixelBufferPtr[ KLineLen - KRgbBufferPixelSize + 1 ]; // green of the last pixel + for (TInt f = KLineLen; f < KBufferLineLen; ++f) + { + pixelBufferPtr[ f ] = green; + } + pixelBufferPtr = ShiftPtr(pixelBufferPtr, iBufferSizeInPixels.iWidth ); + } + } + else + { + for (TInt y = aTopLeft.iY; y < aTopLeft.iY + KNumLines; y++ ) + { + TPtr8 pixelDes(reinterpret_cast(pixelBufferPtr), KLineLen, KLineLen ); + // GetScanLine() is extremely slow, so if support for bitmap modes other than EColor16M is require + // it shouldn't be used + iBitmap->GetScanLine(pixelDes, TPoint(aTopLeft.iX, y), iBufferSizeInPixels.iWidth, EColor16M); + + // now fill out hor trail using grey + const TInt green = pixelBufferPtr[ KLineLen - KRgbBufferPixelSize + 1 ]; // green of the last pixel + for (TInt f = KLineLen; f < KBufferLineLen; ++f) + { + pixelBufferPtr[ f ] = green; + } + pixelBufferPtr = ShiftPtr(pixelBufferPtr, iBufferSizeInPixels.iWidth ); + } + } + // fill out vertical trail + if ( KNumLines < iMCUSizeinPixels.iHeight ) + { + TUint32* fillBufferPtr = reinterpret_cast( pixelBufferPtr ); + // we're filling the whole buffer with mid-gray, so to reduce + // color entropy of padded block + pixelBufferPtr = ShiftPtr(pixelBufferPtr, -iBufferSizeInPixels.iWidth ); // go to the previous line + // make a grey using green component + TUint32 fillValue = (pixelBufferPtr[1] | pixelBufferPtr[1]<<8); + fillValue |= fillValue << 16; + TInt i = Coord2Size( iBufferSizeInPixels.iWidth, iBufferSizeInPixels.iHeight - KNumLines) >> 3; // /8 + do + { + *fillBufferPtr++ = fillValue; + *fillBufferPtr++ = fillValue; + } while (--i); + } + iLockedPtr = iRgbBuffer; + iNextLineOffset = iBufferScanlineLength; + iBufferPos = aTopLeft; + } + + return iLockedPtr; + } + +void CRgbBufferPtr::UnlockBuffer() + { + ASSERT( iLockedPtr != NULL ); + iLockedPtr = NULL; + } +