mmplugins/imagingplugins/codecs/TIFFCodec/TIFFConvert.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFConvert.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,271 @@
+// 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 <barsc.h>
+#include <barsread.h>
+#include <bautils.h>
+#include <imageconversion.h>
+#include "ImageClientMain.h"
+#include "ImageUtils.h"
+#include <101F45C0_extra.rsg>
+#include "icl/ICL_UIDS.hrh"
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <icl/icl_uids_const.hrh>
+#include <icl/icl_uids_def.hrh>
+#include <icl/imagecodecdef.h>
+#endif
+#include "TIFFCodec.h"
+
+_LIT(KTIFFPanicCategory, "TIFFConvertPlugin");
+
+// Global panic function
+GLDEF_C void Panic(TIclPanic aError)
+	{
+	User::Panic(KTIFFPanicCategory, aError);
+	}
+
+// TTiffValueReader.
+TUint32 TTiffValueReader::ReadUint32(const TUint8* aPtr) const
+	{
+	TUint value;
+	if (iEndianness == ETiffLittleEndian)
+		{
+		value  = aPtr[0];
+		value |= aPtr[1] << 8;
+		value |= aPtr[2] << 16;
+		value |= aPtr[3] << 24;
+		}
+	else
+		{
+		value  = aPtr[0] << 24;
+		value |= aPtr[1] << 16;
+		value |= aPtr[2] << 8;
+		value |= aPtr[3];
+		}
+	return TUint32(value);
+	}
+
+TUint16 TTiffValueReader::ReadUint16(const TUint8* aPtr) const
+	{
+	TUint value;
+	if (iEndianness == ETiffLittleEndian)
+		{
+		value  = aPtr[0];
+		value |= aPtr[1] << 8;
+		}
+	else
+		{
+		value  = aPtr[0] << 8;
+		value |= aPtr[1];
+		}
+	return TUint16(value);
+	}
+
+
+// Tiff decoder.
+CTiffDecoder* CTiffDecoder::NewL()
+	{
+	return new(ELeave) CTiffDecoder(ETiffUnknownSubType);
+	}
+
+CTiffDecoder* CTiffDecoder::NewLittleEndianL()
+	{
+	return new(ELeave) CTiffDecoder(ETiffLittleEndianSubType);
+	}
+
+CTiffDecoder* CTiffDecoder::NewBigEndianL()
+	{
+	return new(ELeave) CTiffDecoder(ETiffBigEndianSubType);
+	}
+
+CTiffDecoder::CTiffDecoder(TTiffSubType aTiffSubType)
+	{
+	iTiffSubType = aTiffSubType;
+	}
+
+CTiffDecoder::~CTiffDecoder()
+	{
+	Cleanup();
+	}
+
+void CTiffDecoder::Cleanup()
+	{
+	// Delete any objects we should get rid of
+
+	// Base class included
+	CImageDecoderPlugin::Cleanup();
+	}
+
+void CTiffDecoder::ImageType(TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType) const
+	{
+	__ASSERT_ALWAYS((aFrameNumber >= 0) && (aFrameNumber < NumberOfFrames()), Panic(EFrameNumberOutOfRange));
+	aImageType = KImageTypeTIFFUid;
+	if (iTiffSubType == ETiffLittleEndianSubType)
+		aImageSubType = KImageTypeTIFFSubTypeLittleEndianUid;
+	else
+		aImageSubType = KImageTypeTIFFSubTypeBigEndianUid;
+	}
+
+// Scan header.
+void CTiffDecoder::ScanDataL()
+	{
+	ReadFormatL();
+
+	ASSERT(ImageReadCodec() == NULL);
+
+	CTiffReadCodec* imageReadCodec;
+
+	imageReadCodec = CTiffReadCodec::NewL(iFormatInfo, *this);
+	
+	SetImageReadCodec(imageReadCodec);
+	
+	ReadFrameHeadersL();
+	}
+
+#define KTiffHeaderLittleEndianDefine		{ 0x49, 0x49, 0x2A, 0x00 }
+#define KTiffHeaderBigEndianDefine			{ 0x4D, 0x4D, 0x00, 0x2A }
+LOCAL_D const TUint8 TiffLittleEndianSignature[KTiffSignatureLength] = KTiffHeaderLittleEndianDefine;
+LOCAL_D const TUint8 TiffBigEndianSignature[KTiffSignatureLength] = KTiffHeaderBigEndianDefine;
+void CTiffDecoder::ReadFormatL()
+	{
+	TPtrC8 bufferDes;
+
+	ReadDataL(0, bufferDes, KTiffHeaderSize);
+
+	// Validate the header.
+	if (bufferDes.Length() < KTiffHeaderSize)
+		User::Leave(KErrUnderflow);
+
+	iFormatInfo.iSignature = PtrReadUtil::ReadUint32(CONST_CAST(TUint8*, bufferDes.Ptr()));
+
+	switch (iTiffSubType)
+		{
+	case ETiffUnknownSubType:
+		if (iFormatInfo.iSignature == *REINTERPRET_CAST(const TUint32*,TiffLittleEndianSignature))
+			iFormatInfo.iEndianness = ETiffLittleEndian;
+		else if (iFormatInfo.iSignature == *REINTERPRET_CAST(const TUint32*,TiffBigEndianSignature))
+			iFormatInfo.iEndianness = ETiffBigEndian;
+		else
+			User::Leave(KErrCorrupt);
+		break;
+
+	case ETiffLittleEndianSubType:
+		if (iFormatInfo.iSignature != *REINTERPRET_CAST(const TUint32*,TiffLittleEndianSignature))
+			User::Leave(KErrCorrupt);
+
+		iFormatInfo.iEndianness = ETiffLittleEndian;
+		break;
+
+	case ETiffBigEndianSubType:
+		if (iFormatInfo.iSignature != *REINTERPRET_CAST(const TUint32*,TiffBigEndianSignature))
+			User::Leave(KErrCorrupt);
+
+		iFormatInfo.iEndianness = ETiffBigEndian;
+		break;
+		}
+
+	TTiffValueReader valueReader = TTiffValueReader(iFormatInfo.iEndianness);
+
+	const TUint8* ifdPtr = &bufferDes[KTiffSignatureLength];
+	iFormatInfo.iFirstIfd = valueReader.ReadUint32(ifdPtr);
+	
+	//Ifd (offset in file) should always be pointing to bytes after header.
+	if (iFormatInfo.iFirstIfd < KTiffSignatureLength)   
+		{
+		User::Leave(KErrCorrupt);
+		}
+	
+	SetStartPosition(iFormatInfo.iFirstIfd);
+
+	// Set max data length, since header does not contain this information.
+	SetDataLength(KMaxTInt);
+	}
+
+CFrameInfoStrings* CTiffDecoder::FrameInfoStringsL(RFs& aFs, TInt aFrameNumber)
+	{
+
+	const TUid KTiffCodecDllUid = {KTIFFCodecDllUidValue};
+
+	RResourceFile resourceFile;
+	OpenExtraResourceFileLC(aFs,KTiffCodecDllUid,resourceFile);
+
+	HBufC8* resourceInfo = resourceFile.AllocReadLC(THEDECODERINFO);
+	TResourceReader resourceReader;
+	resourceReader.SetBuffer(resourceInfo);
+
+	TBuf<KCodecResourceStringMax> info;
+	TBuf<KCodecResourceStringMax> templte;
+
+	const TFrameInfo& frameInfo = FrameInfo(aFrameNumber);
+	const CFrameImageData& frameData = FrameData(aFrameNumber);
+	const TTiffImageData* tiffImageData = STATIC_CAST(const TTiffImageData*, frameData.GetFrameData(0));
+
+	CFrameInfoStrings* frameInfoStrings = CFrameInfoStrings::NewLC();
+
+	info = resourceReader.ReadTPtrC();
+	frameInfoStrings->SetDecoderL(info);
+
+	CDesCArrayFlat* resourceArray = resourceReader.ReadDesCArrayL();
+	CleanupStack::PushL(resourceArray);
+	TUint formatIndex;
+	switch (tiffImageData->iCompression)
+		{
+		case TTiffIfdEntry::EGroup3FaxCompression:
+			if (tiffImageData->iT4Options & TTiffIfdEntry::ET4TwoDimentionalCoding)
+				formatIndex = EFormatGroup3Fax2D;
+			else
+				formatIndex = EFormatGroup3Fax1D;
+			break;
+
+		case TTiffIfdEntry::EGroup4FaxCompression:
+			formatIndex = EFormatGroup4Fax;
+			break;
+
+		default:
+			formatIndex = EFormatUnknown;
+			break;
+		}
+	info = (*resourceArray)[formatIndex];
+	CleanupStack::PopAndDestroy(resourceArray);
+	frameInfoStrings->SetFormatL(info);
+
+	TInt width = frameInfo.iOverallSizeInPixels.iWidth;
+	TInt height = frameInfo.iOverallSizeInPixels.iHeight;
+	TInt depth = frameInfo.iBitsPerPixel;
+
+	templte = resourceReader.ReadTPtrC();
+	info.Format(templte, width, height);
+	frameInfoStrings->SetDimensionsL(info);
+
+	resourceArray = resourceReader.ReadDesCArrayL();
+	CleanupStack::PushL(resourceArray);
+	formatIndex = (frameInfo.iFlags & TFrameInfo::EColor) ? 1 : 0;
+	templte = (*resourceArray)[formatIndex];
+	CleanupStack::PopAndDestroy(resourceArray);
+	info.Format(templte, depth);
+	frameInfoStrings->SetDepthL(info);
+
+	// leave details blank
+
+	CleanupStack::Pop(frameInfoStrings); 
+	CleanupStack::PopAndDestroy(2); // resourceInfo + resourceFile
+	return frameInfoStrings;
+	}
+
+TInt CTiffDecoder::CurrentFilePosition()
+	{
+	return StartPosition() + Position();
+	}
+