imagingandcamerafws/imaginginttest/Codecs/PPM2/PPM2Convert.cpp
branchRCL_3
changeset 50 948c7f65f6d4
parent 0 40261b775718
equal deleted inserted replaced
49:735348f59235 50:948c7f65f6d4
       
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <barsc.h>
       
    17 #include <barsread.h>
       
    18 #include <bautils.h>
       
    19 #include <imageconversion.h>
       
    20 #include <101F45F2_extra.rsg>
       
    21 #include "PPM2Codec.h"
       
    22 #include "PPM2Panic.h"
       
    23 #include "PPMDecs.h"
       
    24 #include "PPM2Uids.hrh"
       
    25 // #include "PPMData.h" TODO do we need this
       
    26 
       
    27 _LIT(KPPM2PanicCategory, "PPM2ConvertPlugin");
       
    28 
       
    29 
       
    30 // Global panic function
       
    31 GLDEF_C void Panic(TInt aError)
       
    32 	{
       
    33 	User::Panic(KPPM2PanicCategory, aError);
       
    34 	}
       
    35 
       
    36 
       
    37 // decoder.
       
    38 CPpmDecoder* CPpmDecoder::NewL()
       
    39 	{
       
    40 	return new (ELeave) CPpmDecoder;
       
    41 	}
       
    42 
       
    43 CPpmDecoder::CPpmDecoder()
       
    44 	{}
       
    45 
       
    46 CPpmDecoder::~CPpmDecoder()
       
    47 	{
       
    48 	Cleanup();
       
    49 	}
       
    50 
       
    51 void CPpmDecoder::ImageType(TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType) const
       
    52 	{
       
    53 	__ASSERT_ALWAYS(aFrameNumber == 0, Panic(EFrameNumberOutOfRange));
       
    54 	aImageType = KImageTypePpmUid;
       
    55 	aImageSubType = KNullUid;
       
    56 	}
       
    57 
       
    58 // Scan header.
       
    59 // Validate that format is correct.
       
    60 // Create codec.
       
    61 // Fill in image info. (All frames)
       
    62 void CPpmDecoder::ScanDataL()
       
    63 	{
       
    64 	ReadFormatL();
       
    65 	
       
    66 	ASSERT(ImageReadCodec() == NULL);
       
    67 	CImageReadCodec* imageReadCodec = CPpmReadCodec::NewL(*this); 
       
    68 	SetImageReadCodec(imageReadCodec);
       
    69 
       
    70 	ReadFrameHeadersL();
       
    71 	}
       
    72 
       
    73 const TInt KPpmFileHeaderSize = 512; // use a high figure to get around possible comments - assumes high enough
       
    74 
       
    75 void CPpmDecoder::ReadFormatL()
       
    76 	{
       
    77 	TPtrC8 bufferDes;
       
    78 	ReadDataL(0, bufferDes, KPpmFileHeaderSize); // does setup too, but we don't use the buffer
       
    79 
       
    80 	SetStartPosition(0);
       
    81 	ResetPosition(0);
       
    82 	InternalizeHeaderL();
       
    83 	}
       
    84 
       
    85 void CPpmDecoder::InternalizeHeaderL()
       
    86 	{
       
    87 	// first check we have either P3 or P6 at top of file
       
    88 	TChar char1 = GetByteL();
       
    89 	if (char1!='P')
       
    90 		{
       
    91 		User::Leave(KErrNotSupported);
       
    92 		}		
       
    93 	TChar char2 = GetByteL();
       
    94 	if (char2=='3')
       
    95 		{
       
    96 		SetCompressed(EFalse);
       
    97 		}		
       
    98 	else if (char2=='6')
       
    99 		{
       
   100 		SetCompressed(ETrue);
       
   101 		}		
       
   102 	else
       
   103 		{
       
   104 		User::Leave(KErrNotSupported);
       
   105 		}		
       
   106 
       
   107 	SkipCommentAndWhiteSpaceL();
       
   108 
       
   109 	TInt width = ReadIntL();
       
   110 
       
   111 	SkipCommentAndWhiteSpaceL();
       
   112 
       
   113 	TInt height = ReadIntL();
       
   114 
       
   115 	SkipCommentAndWhiteSpaceL();
       
   116 
       
   117 	TInt maxValue = ReadIntL();
       
   118 	if (maxValue>255)
       
   119 		{
       
   120 		User::Leave(KErrNotSupported);
       
   121 		}		
       
   122 
       
   123 	TInt bitsPerPixel, power;
       
   124 	for (bitsPerPixel=1, power=2; maxValue>power-1; power<<=1, bitsPerPixel+=1)
       
   125 		/*loop*/;
       
   126 
       
   127 	if (Compressed()) 
       
   128 		{
       
   129 		IncByte(); // skip over just the end of line
       
   130 		}		
       
   131 
       
   132 	// we are now pointing at the data
       
   133 
       
   134 	SetStartPosition(Position());
       
   135 	SetDataLength(KMaxTInt); // we don't know image size, so set big
       
   136 
       
   137 	TSize size = TSize(width, height);
       
   138 	iMaxValue = maxValue;
       
   139 
       
   140 	TFrameInfo imageInfo = ImageInfo();
       
   141 	imageInfo.iFrameCoordsInPixels.SetRect(TPoint(0, 0), size);
       
   142 	imageInfo.iOverallSizeInPixels = size;
       
   143 	imageInfo.iFrameSizeInTwips = TSize(0, 0);
       
   144 	imageInfo.iBitsPerPixel = bitsPerPixel;
       
   145 	imageInfo.iDelay = 0;
       
   146 	imageInfo.iFlags = TFrameInfo::EColor|TFrameInfo::ECanDither;
       
   147 	TDisplayMode mode;
       
   148 	if (bitsPerPixel<=4) // we always have rgb values
       
   149 		{
       
   150 		mode=EColor4K;
       
   151 		}		
       
   152 	else
       
   153 		{
       
   154 		mode=EColor16M;
       
   155 		}		
       
   156 	imageInfo.iFrameDisplayMode = mode;
       
   157 	SetImageInfo(imageInfo);
       
   158 
       
   159 	iDataShift = 8 - bitsPerPixel; // correct everything to 0..255
       
   160 	ASSERT(iDataShift>=0);
       
   161 	}
       
   162 
       
   163 CFrameInfoStrings* CPpmDecoder::FrameInfoStringsL(RFs& aFs, TInt aFrameNumber)
       
   164 	{
       
   165 	if (aFrameNumber!=0)
       
   166 		{
       
   167 		User::Leave(KErrArgument);
       
   168 		}		
       
   169 
       
   170 	const TUid ppmCodecDllUid = {KPpm2DecoderDllUidValue};
       
   171 
       
   172 	RResourceFile resourceFile;
       
   173 	OpenExtraResourceFileLC(aFs,ppmCodecDllUid,resourceFile);
       
   174 
       
   175 	HBufC8* resourceInfo = resourceFile.AllocReadLC(THEDECODERINFO);
       
   176 	TResourceReader resourceReader;
       
   177 	resourceReader.SetBuffer(resourceInfo);
       
   178 
       
   179 	TBuf<128> info;
       
   180 	TBuf<128> templte;
       
   181 
       
   182 	CFrameInfoStrings* frameInfoStrings = CFrameInfoStrings::NewLC();
       
   183 
       
   184 	info = resourceReader.ReadTPtrC();
       
   185 	frameInfoStrings->SetDecoderL(info);
       
   186 
       
   187 	info = resourceReader.ReadTPtrC();
       
   188 	frameInfoStrings->SetFormatL(info);
       
   189 
       
   190 	templte = resourceReader.ReadTPtrC();
       
   191 	const TFrameInfo& frameInfo = FrameInfo(aFrameNumber);
       
   192 	const TSize& size = frameInfo.iOverallSizeInPixels;
       
   193 	info.Format(templte, size.iWidth, size.iHeight);
       
   194 	frameInfoStrings->SetDimensionsL(info);
       
   195 
       
   196 	templte = resourceReader.ReadTPtrC();
       
   197 	info.Format(templte, iMaxValue);
       
   198 	frameInfoStrings->SetDepthL(info);
       
   199 
       
   200 	CDesCArrayFlat* resourceArray = resourceReader.ReadDesCArrayL();
       
   201 	CleanupStack::PushL(resourceArray);
       
   202 	TUint formatIndex = Compressed() ? 1 : 0;
       
   203 	info = (*resourceArray)[formatIndex];
       
   204 	CleanupStack::PopAndDestroy(resourceArray);
       
   205 	frameInfoStrings->SetDetailsL(info);
       
   206 	
       
   207 	CleanupStack::Pop(frameInfoStrings); 
       
   208 	CleanupStack::PopAndDestroy(2); // resourceInfo + resourceFile
       
   209 	return frameInfoStrings;
       
   210 	}
       
   211 
       
   212 //
       
   213 
       
   214 void CPpmDecoder::DoConvert()
       
   215 	{
       
   216 	CPpmReadCodec* codec = STATIC_CAST(CPpmReadCodec*, ImageReadCodec());
       
   217 	ASSERT(ValidDestination());
       
   218 	TInt error=KErrNone;
       
   219 #if !defined(__CONTINUE_CONVERT)
       
   220 	TRAP(error, codec->ResetFrameL(*iFrameInfo[iCurrentFrame], Destination()));
       
   221 #endif // !defined(__CONTINUE_CONVERT)
       
   222 	if (error==KErrNone)
       
   223 		{
       
   224 		TRAP(error, codec->ProcessFrameL());
       
   225 		}
       
   226 				
       
   227 	ImageReadCodec()->Complete();
       
   228 	RequestComplete(error);
       
   229 	}
       
   230 
       
   231 //
       
   232 
       
   233 TUint CPpmDecoder::GetByteL()
       
   234 	{
       
   235 	TUint result = PeekByteL();
       
   236 	IncByte();
       
   237 	return result;
       
   238 	}
       
   239 
       
   240 void CPpmDecoder::IncByte()
       
   241 	{
       
   242 	TInt position = Position();
       
   243 	SetPosition(position + 1);
       
   244 	}
       
   245 
       
   246 TUint CPpmDecoder::PeekByteL()
       
   247 	{
       
   248 	TInt offset = Position() - iBase + StartPosition();
       
   249 
       
   250 	if (!BytesValid() || !(offset>=0 && offset<SourceLength()))
       
   251 		{
       
   252 		TInt base = StartPosition() + Position();
       
   253 		TRAPD(error, ReadDataL(base, iSourceBuffer, FrameBlockSize(0)));
       
   254 		if (error!=KErrNone)
       
   255 			{
       
   256 			if (error == KErrEof) // should probably not occur, but just in case TODO
       
   257 				{
       
   258 				error = KErrUnderflow;
       
   259 				}
       
   260 				
       
   261 			User::Leave(error);
       
   262 			}
       
   263 		if (iSourceBuffer == KNullDesC8) // no more data
       
   264 			{
       
   265 			User::Leave(KErrUnderflow);
       
   266 			}
       
   267 			
       
   268 		iBase = base;
       
   269 		offset = 0; // really iStartPosition + iPosition - iBase
       
   270 		SetBytesValid(ETrue);
       
   271 		ASSERT(offset>=0 && offset<SourceLength());
       
   272 		}
       
   273  	return iSourceBuffer[offset];
       
   274 	}
       
   275 
       
   276 void CPpmDecoder::ResetPosition(TInt aPosition)
       
   277 	{
       
   278 	SetPosition(aPosition);
       
   279 	SetBytesValid(EFalse);
       
   280 	}
       
   281 
       
   282 TInt CPpmDecoder::ReadIntL()
       
   283 	{
       
   284 	TInt result = 0;
       
   285 	for(;;)
       
   286 		{
       
   287 		TChar ch(PeekByteL());
       
   288 		if (!ch.IsDigit())
       
   289 			{
       
   290 			break;
       
   291 			}			
       
   292 		IncByte();
       
   293 		TInt val = TInt(ch) - TInt('0');
       
   294 		result = result*10 + val;
       
   295 		}
       
   296 	return result;
       
   297 	}
       
   298 
       
   299 void CPpmDecoder::SkipCommentAndWhiteSpaceL()
       
   300 	{
       
   301 	for (;;)
       
   302 		{
       
   303 		TChar peek = PeekByteL();
       
   304 		if (peek.IsSpace())
       
   305 			{
       
   306 			do 
       
   307 				{
       
   308 				IncByte();
       
   309 				peek = PeekByteL();
       
   310 				}
       
   311 			while(peek.IsSpace());
       
   312 			}
       
   313 		else if (peek=='#') // comment - skip to end of line
       
   314 			{
       
   315 			do 
       
   316 				{
       
   317 				peek = GetByteL();
       
   318 				}
       
   319 			while(peek!='\n');
       
   320 			}
       
   321 		else
       
   322 			break;
       
   323 		}
       
   324 	}
       
   325 
       
   326 // PNG encoder
       
   327 CPpmEncoder* CPpmEncoder::NewL()
       
   328 	{
       
   329 	return new (ELeave) CPpmEncoder;
       
   330 	}
       
   331 
       
   332 CPpmEncoder::CPpmEncoder()
       
   333 	{
       
   334 	}
       
   335 
       
   336 CPpmEncoder::~CPpmEncoder()
       
   337 	{
       
   338 	CImageEncoderPlugin::Cleanup();
       
   339 	}
       
   340 
       
   341 void CPpmEncoder::PrepareEncoderL(const CFrameImageData* /*aFrameImageData*/)
       
   342 	{
       
   343 	CPpm2WriteCodec* codec = CPpm2WriteCodec::NewL(this);
       
   344 	SetImageWriteCodec(codec);		// takes ownership of imageReadCodec
       
   345 	}
       
   346 
       
   347 void CPpmEncoder::UpdateHeaderL()
       
   348 	{
       
   349 	}
       
   350 
       
   351 void CPpmEncoder::DoConvert()
       
   352 	{
       
   353 	TRAPD(error, DoConvertL()); // encapsulate call to reduce number of traps
       
   354 	RequestComplete(error);
       
   355 	}
       
   356 
       
   357 void CPpmEncoder::DoConvertL()
       
   358 	{
       
   359 	static_cast<CPpm2WriteCodec*>(ImageWriteCodec())->DoProcessL(Source());
       
   360 
       
   361 	FinishConvertL();
       
   362 	}
       
   363 
       
   364 void CPpmEncoder::AppendDataL(const TDesC8& aData)
       
   365 	{
       
   366 	TInt& position = Position();
       
   367 	WriteDataL(position, aData);
       
   368 	position += aData.Length();
       
   369 	}
       
   370 
       
   371 #ifndef EKA2
       
   372 
       
   373 // DLL entry point
       
   374 GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
       
   375 	{
       
   376 	return KErrNone;
       
   377 	}
       
   378 
       
   379 #endif // EKA2