mmplugins/imagingplugins/imagedisplay/plugins/mng/MngRenderer.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/imagedisplay/plugins/mng/MngRenderer.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,507 @@
+// Copyright (c) 2004-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:
+//
+
+/** 	@file
+	@internalTechnology */
+#include <fbs.h>
+#include "MngPanic.h"
+
+#include "MngRenderer.h"
+
+/** 
+ the color will be used as a "default" to clear background if an image doesn't
+ have one defined and there is no alpha channel
+*/
+const TUint KDefaultColor=0; 
+
+/*static*/
+CMngRenderer* CMngRenderer::NewL(const TSize& aSize, TBool aAlphaNeeded, TDisplayMode aDestDisplayMode, TDisplayMode aMaskDisplayMode)
+	{
+	CMngRenderer* self=new (ELeave) CMngRenderer(aSize, aAlphaNeeded, aDestDisplayMode, aMaskDisplayMode);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CMngRenderer::CMngRenderer(const TSize& aSize, TBool aAlphaNeeded, TDisplayMode aDestDisplayMode, TDisplayMode aMaskDisplayMode)
+ : iAlphaNeeded(aAlphaNeeded),
+   iRenderSize(aSize),
+   iDestDisplayMode(aDestDisplayMode),
+   iMaskDisplayMode(aMaskDisplayMode)
+	{
+	}
+
+void CMngRenderer::ConstructL()
+	{
+	TInt pixelSize;
+	CRgbPixelConsumer::SetPixelFunc setPixelFunction;
+	if(iDestDisplayMode == EColor16MA || iDestDisplayMode == EColor16MU)
+		{
+		pixelSize = KRgbaPixelSize;
+		setPixelFunction = &CRgbPixelConsumer::SetRGBAPixel;
+		}
+	else
+		{
+		pixelSize = KRgbPixelSize;
+		setPixelFunction = &CRgbPixelConsumer::SetRGBPixel;
+		}
+		
+	iRgbConsumer = new (ELeave) CRgbPixelConsumer(pixelSize);
+	iRgbConsumer->InitL(iRenderSize);
+			
+	if (iAlphaNeeded) // as required by source image
+		{
+		iAlphaConsumer= new (ELeave) CAlphaPixelConsumer();
+		iAlphaConsumer->InitL(iRenderSize);
+		
+		if (iDestDisplayMode == EColor16MA && iMaskDisplayMode != EGray256)  // No mask
+			{
+			// In this case, there is a single 16MA destination, so we need to put the
+			// alpha data into the alpha channel, rather than 0xFF.
+			iRgbConsumer->SetAlphaEnabledBitmap(ETrue);
+			}
+		}
+	iRgbConsumer->SetAlphaConsumer(iAlphaConsumer);
+		
+	iRgbProcessor=CRgbProcessor::NewL(this);
+	iRgbProcessor->SetPixelConsumer(iRgbConsumer);
+	iRgbProcessor->SetPixelFunction(setPixelFunction);
+	
+	CAlphaProcessor* Alpha= NULL;
+	if (iAlphaNeeded)
+		{
+		Alpha = CAlphaProcessor::NewL();
+		iAlphaProcessor = Alpha;
+		Alpha->SetPixelConsumer(iAlphaConsumer);
+		}
+	}
+
+CMngRenderer::~CMngRenderer()
+	{
+	delete iRgbProcessor;
+	delete iAlphaProcessor;
+
+	if (NULL != iRgbFilter)
+		{
+		iRgbFilter->Release();
+		iRgbFilter = NULL;
+		}
+	delete iRgbConsumer;
+	delete iAlphaConsumer;
+	}
+
+void CMngRenderer::Reset()
+	{
+	SetOutputEnabled(ETrue);
+	iBgColourSet	= EFalse;
+	iBgColourIsMandatory = EFalse;
+	iBgColour		= KDefaultColor;
+	const TPoint KZero(0,0);
+	iViewPortOrigin = KZero;
+	iClippingRect	= TRect(KZero, iRenderSize.AsPoint());
+	iImageClipRect	= iClippingRect;
+	iBgClipRect		= iClippingRect;
+
+	// Subframes with No Loops
+	// updated rect as empty 
+   	UpdateRectEmpty();
+	//
+
+	iRgbConsumer->SetClippingRect(iClippingRect);
+	iRgbConsumer->SetOrigin(KZero);
+
+	ImageProcessor().SetPos(KZero);
+	ImageProcessor().SetYPosIncrement(1);
+
+	if (iAlphaConsumer)
+		{
+		iAlphaConsumer->SetClippingRect(iClippingRect);
+		iAlphaConsumer->SetOrigin(KZero);
+		}
+	}
+
+/*
+Clears the current layer clipping rect
+*/
+void CMngRenderer::ClearOutputRect()
+	{
+   	UpdateRect(iBgClipRect);
+
+	if (iBgColourSet && iBgColourIsMandatory)
+		{
+		iRgbConsumer->Clear( iBgColour, iBgClipRect );
+		if (iAlphaConsumer)
+			{
+			iAlphaConsumer->Clear(KOpaqueAlpha, iBgClipRect);
+			}
+		}
+	else
+		{
+		if (iAlphaConsumer)
+			{
+			iAlphaConsumer->Clear(KTransparentAlpha, iBgClipRect);
+			if (iDestDisplayMode == EColor16MA && iMaskDisplayMode != EGray256)
+				{
+				iRgbConsumer->ClearAlpha(KTransparentAlpha, iBgClipRect);
+				}
+			}
+		else
+			{
+			// no alpha, so clear by available color
+			iRgbConsumer->Clear(iBgColour, iBgClipRect );
+			}
+		}
+	}
+
+void CMngRenderer::OnNewImageL()
+	{
+	if (iAlphaConsumer)
+		{
+		iAlphaConsumer->SetEnabled(EFalse);
+		}
+	}
+
+void CMngRenderer::SetBackground(const TRgb aBgColour, TBool aColourIsMandatory)
+	{
+	iBgColour			= aBgColour.Internal();
+	iBgColourIsMandatory= aColourIsMandatory;
+	iBgColourSet= ETrue;
+	}
+
+void CMngRenderer::SetImageOrigin(const TPoint& aOrigin)
+	{
+	iViewPortOrigin = aOrigin;
+	iRgbConsumer->SetOrigin(aOrigin);
+	if (iAlphaConsumer)
+		{
+		iAlphaConsumer->SetOrigin(aOrigin);	
+		}
+	}
+
+void CMngRenderer::SetImageClipRect(const TRect& aClippingRect)
+	{
+	iImageClipRect	= aClippingRect;
+	iClippingRect	= aClippingRect;
+	iClippingRect.Intersection(iBgClipRect);
+
+	iRgbConsumer->SetClippingRect(iClippingRect);
+	if (iAlphaConsumer)
+		{
+		iAlphaConsumer->SetClippingRect(iClippingRect);	
+		}
+	}
+
+void CMngRenderer::SetBgClipRect(const TRect& aClippingRect)
+	{
+	iBgClipRect		= aClippingRect;
+	iBgClipRect.Intersection(TRect(TPoint(0,0), iRenderSize.AsPoint()));
+	iClippingRect	= iBgClipRect;
+	iClippingRect.Intersection(iImageClipRect);
+
+	iRgbConsumer->SetClippingRect(iClippingRect);
+	if (iAlphaConsumer)
+		{
+		iAlphaConsumer->SetClippingRect(iClippingRect);	
+		}
+	}
+
+void CMngRenderer::SetRgbFilter(MPixelFilter* aPixelFilter)
+	{
+	if (NULL != iRgbFilter)
+		{
+		iRgbFilter->Release();
+		}
+	if (NULL != aPixelFilter)
+		{
+		aPixelFilter->AddRef();
+		}
+	iRgbFilter = aPixelFilter;
+	iRgbProcessor->SetPixelFilter(aPixelFilter);
+	}
+
+//Subframes with No Loops
+void CMngRenderer::UpdateRect(const TRect& aRect) 
+	{
+	/** Top Left Minima */
+	if(iUpdateRect.iTl.iX > aRect.iTl.iX )	
+		{
+		iUpdateRect.iTl.iX = aRect.iTl.iX;
+		}
+		
+	if(iUpdateRect.iTl.iY > aRect.iTl.iY)
+		{
+		iUpdateRect.iTl.iY = aRect.iTl.iY;
+		}
+		
+	/** Bottom Right Maxima */
+	if(iUpdateRect.iBr.iX < aRect.iBr.iX )	
+		{
+		iUpdateRect.iBr.iX = aRect.iBr.iX;
+		}
+		
+	if(iUpdateRect.iBr.iY < aRect.iBr.iY)
+		{
+		iUpdateRect.iBr.iY = aRect.iBr.iY;
+		}
+	}
+	
+void CMngRenderer::UpdateRectEmpty()
+	{
+	const TPoint KZero(0,0);
+	iUpdateRect.iBr = KZero;
+    iUpdateRect.iTl = iRenderSize.AsPoint();
+	}
+//
+
+//  from the CImageProcessor //
+
+TBool CPixelProcessor::SetPixelBlock(TRgb* /*aColorBuffer*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CPixelProcessor::SetPixels(TRgb* /*aColorBuffer*/,TInt /*aBufferLength*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CPixelProcessor::SetMonoPixel(TInt /*aGray256*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CPixelProcessor::SetMonoPixelRun(TInt /*aGray256*/,TInt /*aCount*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CPixelProcessor::SetMonoPixels(TUint32* /*aGray256Buffer*/,TInt /*aBufferLength*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CPixelProcessor::SetMonoPixelBlock(TUint32* /*aGray256Buffer*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CPixelProcessor::SetPos(const TPoint& aPosition)
+	{
+	iPixelPosition = aPosition;
+	return ETrue;
+	}
+
+TBool CPixelProcessor::FlushPixels()
+	{
+	if (NULL != iPixelFilter)
+		{
+		iPixelFilter->Commit();
+		}
+	return ETrue;
+	}
+
+void CPixelProcessor::PrepareL(CFbsBitmap& /*aBitmap*/,const TRect& aImageRect)
+	{
+	iCurrentImgSize = aImageRect.Size();
+	iPixelsToSkip	= iPixelPadding;
+	iYInc			= 1;
+	iPixelPosition.SetXY(0,0);
+	if (NULL != iPixelConsumer)
+		{
+		iPixelConsumer->Prepare();	
+		}
+	if (NULL != iPixelFilter)
+		{
+		iPixelFilter->PrepareL(iCurrentImgSize, static_cast<CRgbPixelConsumer*>(iPixelConsumer) ); 
+		}
+	}
+
+void CPixelProcessor::PrepareL(CFbsBitmap& /*aBitmap*/,const TRect& /*aImageRect*/,const TSize& /*aRgbBlockSize*/)
+	{
+	ASSERT(EFalse);
+	}
+
+void CPixelProcessor::SetYPosIncrement(TInt aYInc)
+	{
+	iYInc = aYInc;
+	}
+
+void CPixelProcessor::SetLineRepeat(TInt /*aLineRepeat*/)
+	{
+	// we don't use progressive decoding
+	}
+
+void CPixelProcessor::SetPixelPadding(TInt aNumberOfPixels)
+	{
+	iPixelPadding = aNumberOfPixels; 
+	}
+
+/*static*/
+CRgbProcessor* CRgbProcessor::NewL(CMngRenderer* aMngRenderer) 
+	{
+	return new (ELeave) CRgbProcessor(aMngRenderer); 
+	}
+	
+CRgbProcessor::CRgbProcessor(CMngRenderer* aMngRenderer):iMngRenderer(aMngRenderer)	
+	{
+	}
+
+
+TBool CRgbProcessor::SetPixels(TRgb* aColorBuffer,TInt aBufferLength)
+	{
+	ASSERT(aBufferLength>0);
+	if (aBufferLength > iPixelsToSkip)
+		{	
+		aBufferLength -= iPixelsToSkip;
+		iPixelsToSkip = 0;
+		if (iPixelFilter==NULL)
+			{		
+			do 
+				{
+				SetPixelImpl(*aColorBuffer++);
+				} while (--aBufferLength > 0);
+			}
+		else
+			{
+			do
+				{
+				SetPixelImplWithPf(*aColorBuffer++);
+				} while (--aBufferLength > 0);
+			}
+		}
+	else
+		{
+		iPixelsToSkip -= aBufferLength;
+		}		
+	return ETrue;
+	}
+
+TBool CRgbProcessor::SetPixelRun(TRgb aColor,TInt aCount)
+	{
+	if (aCount > iPixelsToSkip)
+		{
+		aCount -= iPixelsToSkip;
+		iPixelsToSkip = 0;
+		if (iPixelFilter==NULL)
+			{
+			do
+				{
+				SetPixelImpl(aColor);
+				} while (--aCount);
+			}
+		else
+			{
+			do
+				{
+				SetPixelImplWithPf(aColor);
+				} while (--aCount);
+			}
+		}
+	else
+		{
+		iPixelsToSkip -= aCount;
+		}
+	return ETrue;
+	}
+
+//Subframes with No Loops
+//added here
+void CRgbProcessor::PrepareL(CFbsBitmap& aBitmap,const TRect& aImageRect)  
+	{
+	//updation with this new image. new image rect is defined by OriginSet(iViewPortOrigin) and OriginSet+Bottom right calc from aImageRect size
+	TSize imageSize(aImageRect.Width(), aImageRect.Height());
+	TRect imageRect(iMngRenderer->ViewPortOrigin(),imageSize);
+	imageRect.Intersection(iMngRenderer->ClippingRect()); //Bug fix
+	iMngRenderer->UpdateRect(imageRect);  
+
+	CPixelProcessor::PrepareL(aBitmap, aImageRect);
+	}
+//
+
+TBool CRgbProcessor::SetPixel(TRgb aColor)
+	{
+	if (iPixelsToSkip)
+		{
+		--iPixelsToSkip;
+		return ETrue;
+		}
+	return iPixelFilter==NULL? SetPixelImpl(aColor) : SetPixelImplWithPf(aColor);
+	}
+		
+inline 
+TBool CRgbProcessor::SetPixelImplWithPf(TRgb aColor)
+	{
+	iPixelFilter->SetPixel(iPixelPosition, aColor.Internal());
+
+	if (++iPixelPosition.iX == iCurrentImgSize.iWidth)
+		{
+		iPixelPosition.iX	= 0;
+		iPixelPosition.iY  += iYInc;
+		iPixelsToSkip		= iPixelPadding;
+		}	
+	return ETrue;
+	}
+	
+inline 
+TBool CRgbProcessor::SetPixelImpl(TRgb aColor)
+	{
+	iPixelConsumer->SetPos(iPixelPosition);
+	CALL_SETPIXEL_FUNCTION(*Consumer(), iSetPixelFunction)(TRgbaColour(aColor.Internal()));
+
+	if (++iPixelPosition.iX == iCurrentImgSize.iWidth)
+		{
+		iPixelPosition.iX	= 0;
+		iPixelPosition.iY  += iYInc;
+		iPixelsToSkip		= iPixelPadding;
+		}
+
+	return ETrue;
+	}
+	
+
+/*static*/
+CAlphaProcessor* CAlphaProcessor::NewL()
+	{
+	return new (ELeave) CAlphaProcessor();
+	}
+
+void CAlphaProcessor::PrepareL(CFbsBitmap& aBitmap, const TRect& aImageRect)
+	{
+	CPixelProcessor::PrepareL(aBitmap, aImageRect);
+	if (Consumer())
+		{
+		Consumer()->SetEnabled(ETrue);	
+		}
+	}
+
+TBool CAlphaProcessor::SetPixelRun(TRgb /*aColor*/,TInt /*aCount*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+
+TBool CAlphaProcessor::SetPixel(TRgb /*aColor*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}
+