imaging/imaginginttest/Codecs/PPM2/PPM2Codec.cpp
changeset 0 5752a19fdefe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imaging/imaginginttest/Codecs/PPM2/PPM2Codec.cpp	Wed Aug 25 12:29:52 2010 +0300
@@ -0,0 +1,281 @@
+// Copyright (c) 1999-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 <fbs.h>
+#include "PPM2Codec.h"
+#include "PPM2Panic.h"
+
+
+// CPpmReadCodec
+
+CPpmReadCodec* CPpmReadCodec::NewL(CPpmDecoder& aDecoder)
+	{
+	CPpmReadCodec* result = new (ELeave) CPpmReadCodec(aDecoder);
+	CleanupStack::PushL(result);
+	result->ConstructL();
+	CleanupStack::Pop(result);
+	return result;
+	}
+
+CPpmReadCodec::CPpmReadCodec(CPpmDecoder& aDecoder):
+	iDecoder(&aDecoder)
+	{}
+
+CPpmReadCodec::~CPpmReadCodec()
+	{
+	}
+
+void CPpmReadCodec::ProcessFrameL()
+	{
+	if (iDecoder->Compressed())
+		{
+		DoProcessCompressedL();
+		}		
+	else
+		{
+		DoProcessUncompressedL();	
+		}		
+	}
+
+TFrameState CPpmReadCodec::ProcessFrameL(TBufPtr8& /*aSrc*/)
+	{
+	__ASSERT_ALWAYS(EFalse, Panic(EIllegalCall));
+	return EFrameIncomplete;
+	}
+
+void CPpmReadCodec::Complete()
+	{
+	ImageProcessor()->FlushPixels(); 
+	}
+
+void CPpmReadCodec::DoProcessUncompressedL()
+	{
+	CImageProcessor*const imageProc = ImageProcessor();
+#if defined(__CONTINUE_CONVERT)
+	iDecoder->ResetPosition(iMarkedPosition);
+	for (; iPixelsProcessed<iPixelsExpected; iPixelsProcessed++)
+#else 
+	iDecoder->ResetPosition(0);
+	for (TInt pixelsProcessed=0; pixelsProcessed<iPixelsExpected; pixelsProcessed++)
+#endif // defined(__CONTINUE_CONVERT)
+		{
+		if (ShouldAbort())
+			{
+			break;
+			}
+			
+		iDecoder->SkipCommentAndWhiteSpaceL();
+		TUint rVal = iDecoder->ReadIntL();
+		iDecoder->SkipCommentAndWhiteSpaceL();
+		TUint gVal = iDecoder->ReadIntL();
+		iDecoder->SkipCommentAndWhiteSpaceL();
+		TUint bVal = iDecoder->ReadIntL();
+
+		TInt dataShift = iDecoder->DataShift();
+		TRgb rgb (rVal<<dataShift, gVal<<dataShift, bVal<<dataShift);
+
+		imageProc->SetPixel(rgb);
+
+#if defined(__CONTINUE_CONVERT)
+		iMarkedPosition = iDecoder->Position(); 
+#endif // defined(__CONTINUE_CONVERT)
+		}
+	}
+
+void CPpmReadCodec::DoProcessCompressedL()
+	{
+	CImageProcessor*const imageProc = ImageProcessor();
+#if defined(__CONTINUE_CONVERT)
+	iDecoder->ResetPosition(iMarkedPosition);
+	for (; iPixelsProcessed<iPixelsExpected; iPixelsProcessed++)
+#else 
+	iDecoder->ResetPosition(0);
+	for (TInt pixelsProcessed=0; pixelsProcessed<iPixelsExpected; pixelsProcessed++)
+#endif // defined(__CONTINUE_CONVERT)
+		{
+		if (ShouldAbort())
+			{
+			break;
+			}
+			
+		TUint rVal = iDecoder->GetByteL();
+		TUint gVal = iDecoder->GetByteL();
+		TUint bVal = iDecoder->GetByteL();
+
+		TInt dataShift = iDecoder->DataShift();
+		TRgb rgb (rVal<<dataShift, gVal<<dataShift, bVal<<dataShift);
+
+		imageProc->SetPixel(rgb);
+
+#if defined(__CONTINUE_CONVERT)
+		iMarkedPosition = iDecoder->Position(); // remember where we get to
+#endif // defined(__CONTINUE_CONVERT)
+		}
+	}
+
+void CPpmReadCodec::InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameImageData*/, TBool aDisableErrorDiffusion, CFbsBitmap& aFrame, CFbsBitmap* /*aDestinationMask*/)
+	{
+	TSize& originalSize = aFrameInfo.iOverallSizeInPixels;
+	CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL(aFrame,originalSize,aFrameInfo.iFrameDisplayMode, aDisableErrorDiffusion);
+	SetImageProcessor(imageProc);
+
+#if defined(__CONTINUE_CONVERT)
+	ResetFrameL(aFrameInfo, aFrame);
+#endif // defined(__CONTINUE_CONVERT)
+
+	ClearBitmapL(aFrame, KRgbWhite);
+		// do something sensible for partial streamed decodes
+
+	iPixelsExpected = originalSize.iWidth * originalSize.iHeight;
+#if defined(__CONTINUE_CONVERT)
+	iMarkedPosition = 0; 
+	iPixelsProcessed = 0;
+#endif // defined(__CONTINUE_CONVERT)
+	}
+
+void CPpmReadCodec::InitFrameHeader(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameData*/)
+	{
+	ASSERT(aFrameInfo.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised);
+	iFrameInfo = &aFrameInfo;
+	aFrameInfo.SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrameHeader);
+	}
+
+TFrameState CPpmReadCodec::ProcessFrameHeaderL(TBufPtr8&/* aData*/)
+	{
+	ASSERT(iFrameInfo);
+	iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete);
+	return EFrameComplete;
+	}
+
+void CPpmReadCodec::ResetFrameL(TFrameInfo& aFrameInfo, CFbsBitmap& aFrame)
+	{
+	Pos().SetXY(0,0);
+
+	TSize& originalSize = aFrameInfo.iOverallSizeInPixels;
+	CImageProcessor*const imageProc = ImageProcessor();
+	ASSERT(imageProc);
+	imageProc->PrepareL(aFrame,originalSize);
+	}
+
+// CPpm2WriteCodec
+
+const TInt KMaxColourValue=255;
+
+CPpm2WriteCodec::CPpm2WriteCodec(CPpmEncoder* aEncoder):
+	iEncoder(aEncoder)
+	{}
+
+CPpm2WriteCodec::~CPpm2WriteCodec()
+	{}
+
+void CPpm2WriteCodec::ConstructL()
+	{
+	CImageWriteCodec::ConstructL();
+	}
+
+CPpm2WriteCodec* CPpm2WriteCodec::NewL(CPpmEncoder* aEncoder)
+	{
+	CPpm2WriteCodec* result = new (ELeave) CPpm2WriteCodec(aEncoder);
+	CleanupStack::PushL(result);
+	result->ConstructL();
+	CleanupStack::Pop(result);
+	return result;
+	}
+
+void CPpm2WriteCodec::InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource)
+	{
+	SetSource(&aSource);
+	TUint8* destStartPtr = const_cast<TUint8*>(aDst.Ptr());
+	TUint8* destPtr = destStartPtr;
+#if defined(_DEBUG)
+	TUint8* destPtrLimit = destPtr + aDst.MaxLength();
+#endif // defined(_DEBUG)
+
+	TSize size = aSource.SizeInPixels();
+	iSourceRect = TRect(size);
+	iPos.SetXY(0,0);
+	iPos.iY = iSourceRect.iBr.iY - 1;
+
+	TBuf8<256> header; // set up header in buffer
+	header.Zero();
+
+	// now the standard header lines
+	_LIT8(KMagicHeader, "P6\n");
+	header.AppendFormat(KMagicHeader); // ppm magic for compressed
+	_LIT8(KSizeHeader, "%d %d\n");
+	header.AppendFormat(KSizeHeader, size.iWidth, size.iHeight);
+	_LIT8(KMaxValueHeader, "%d\n");
+	header.AppendFormat(KMaxValueHeader, KMaxColourValue);
+
+	TInt headerSize = header.Length();
+	aDst.Copy(header);
+	destPtr+=headerSize;
+
+	ASSERT(destPtr < destPtrLimit); // should always be true
+	}
+
+TFrameState CPpm2WriteCodec::ProcessFrameL(TBufPtr8& /*aDst*/)
+	{
+	ASSERT(EFalse); // won't be called in this version
+	return EFrameIncomplete;
+	}
+
+void CPpm2WriteCodec::DoProcessL(const CFbsBitmap& aSource)
+	{
+	TSize size = aSource.SizeInPixels();
+	TInt numLines = size.iHeight;
+
+	TInt scanLength = aSource.ScanLineLength(size.iWidth, EColor16M);
+	// create buffer of the appropriate length
+	TUint8* scanBuffer = STATIC_CAST(TUint8*, User::AllocLC(scanLength));
+
+	for (TInt line=0; line<numLines; line++)
+		{
+		if (ShouldAbort())
+			{
+			User::Leave(KErrCancel);
+			}
+			
+		TPtr8 scanLine (scanBuffer, 0, scanLength);
+
+		TPoint pos (0, line);
+		aSource.GetScanLine(scanLine, pos, scanLength, EColor16M);
+		// this comes out in order BGR, so switch
+		SwitchRGB(scanLine);
+
+		AppendDataL(scanLine);
+		}
+
+	CleanupStack::PopAndDestroy(); // scanBuffer
+	}
+
+// Assume original has pixels with BGR in order - switch to RGB
+void CPpm2WriteCodec::SwitchRGB(TDes8 &aBuf)
+	{
+	TUint8* buf = const_cast<TUint8*>(aBuf.Ptr());
+	TUint8* bufMax = buf + aBuf.Length();
+
+	while (buf<bufMax)
+		{
+		TUint8 b = buf[0];
+		TUint8 g = buf[1];
+		TUint8 r = buf[2];
+		buf[0] = r;
+		buf[1] = g;
+		buf[2] = b;
+
+		buf += 3; 
+		}
+	}