diff -r 735348f59235 -r 948c7f65f6d4 mmplugins/imagingplugins/codecs/TIFFCodec/TIFFConvert.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmplugins/imagingplugins/codecs/TIFFCodec/TIFFConvert.cpp Wed Sep 01 12:38:50 2010 +0100 @@ -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 +#include +#include +#include +#include "ImageClientMain.h" +#include "ImageUtils.h" +#include <101F45C0_extra.rsg> +#include "icl/ICL_UIDS.hrh" +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#include +#include +#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 info; + TBuf 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(); + } +