diff -r e1e28b0273b0 -r 93fff7023be8 IEBgps/src/IETNGenerator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IEBgps/src/IETNGenerator.cpp Fri Oct 15 10:18:29 2010 +0900 @@ -0,0 +1,709 @@ +/* +* Copyright (c) 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: Juha Kauppinen, Mika Hokkanen +* +* Description: Photo Browser +* +*/ + +#include //CImageDecoder +#include //CFbsBitmap +#include +//#include + +#include "IETNGenerator.h" +#include "IEBgpServerSession.h" +#include +#include "ImagicConsts.h" +#include "ieengineutils.h" + +_LIT8(KMimeJpeg, "image/jpeg"); +_LIT8(KMimePng, "image/png"); + +#define DO_NOT_USE_SCALING + + + +CIETNGeneratorAO* CIETNGeneratorAO::NewL(RFs& aFileServer, MIEThumbNailObserver &aObserver) +{ + CIETNGeneratorAO* self = new (ELeave) CIETNGeneratorAO(aFileServer, aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +CIETNGeneratorAO::~CIETNGeneratorAO() +{ + DP0_IMAGIC((_L("CIETNGeneratorAO::~CIETNGeneratorAO ++"))); + if(IsActive()) + Cancel(); + + CancelOutStaningRequests(); + DeleteObjects(); + + DP0_IMAGIC((_L("CIETNGeneratorAO::~CIETNGeneratorAO --"))); +} + +//EPriorityIdle, EPriorityLow, EPriorityStandard, EPriorityUserInput, EPriorityHigh +CIETNGeneratorAO::CIETNGeneratorAO(RFs& aFileServer, MIEThumbNailObserver &aObserver) +: iFileServer(aFileServer), + iThumbnailObserver(aObserver), + CActive(EPriorityStandard) +{ + +} + +void CIETNGeneratorAO::ConstructL() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::ConstructL ++"))); + + CActiveScheduler::Add(this); + iError = KErrNone; + decoderUid = CIEEngineUtils::GetImageDecoderUid(); + //i512x512TnBitmap = new (ELeave) CFbsBitmap(); + + DP0_IMAGIC((_L("CIETNGeneratorAO::ConstructL --"))); + } + +void CIETNGeneratorAO::RunL() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::RunL ++"))); + iError = iStatus.Int(); + +#ifdef _IMAGIC_DEBUG + TInt mem = 0; + TInt ret = HAL::Get(HALData::EMemoryRAMFree, mem); + DP1_IMAGIC(_L("CIETNGeneratorAO::RunL - mem: %d"),mem); +#endif + + if(iError != KErrNone) + { + DeleteObjects(); + + iConvertStatus = ENone; + + // inform to higher layer... and delete thumbnails we tried to create + DP1_IMAGIC(_L("CIETNGeneratorAO::RunL - Something wrong %d"), iError); + iThumbnailObserver.ThumbNailGenerationCompleted(iError); + } + + switch (iConvertStatus) + { + case EDecoding: + { + DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EDecoding"))); + TRAPD(err, DecodeL()); // TODO handle errors + if (err != KErrNone) + { + DP1_IMAGIC((_L("CIETNGeneratorAO::RunL - EDecoding error: %d")), err); + iThumbnailObserver.ThumbNailGenerationCompleted(err); //ASSERT(0); + iConvertStatus = ENone; + } + else + { +#ifdef DO_NOT_USE_SCALING + iConvertStatus = EEncoding; +#else + iConvertStatus = EScaling; +#endif + SetActive(); + } + } + break; + + case EScaling: + { + DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EScaling"))); + TRAPD(err, ScaleL()); + if (err != KErrNone) + { + DP1_IMAGIC((_L("CIETNGeneratorAO::RunL - EScaling error: %d")), err); + iThumbnailObserver.ThumbNailGenerationCompleted(err); //ASSERT(0); + iConvertStatus = ENone; + } + else + { + iConvertStatus = EEncoding; + SetActive(); + } + } + break; + + case EEncoding: + { + DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EEncoding"))); + TRAPD(err, EncodeL()); // TODO handle errors + if (err != KErrNone) + { + DP1_IMAGIC((_L("CIETNGeneratorAO::RunL - EEncoding error: %d")), err); + iThumbnailObserver.ThumbNailGenerationCompleted(err); //ASSERT(0); + iConvertStatus = ENone; + } + else + { + iConvertStatus = EReady; + +#ifdef USE_BITMAPS_TNS + if(!IsJPEG(iThumbnailSize)) + { + //When saving TN as bitmap we need to complete request immeadtely + //because bitmap saving is handled by CFbsBitmap class instead of image encoder + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + else + { + SetActive(); + } +#else + SetActive(); +#endif + } + } + break; + + case EReady: + { + DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EReady"))); + + // use same image for generating smaller thumbnails + if (IsLargeThumbnail(iThumbnailSize)) + { + /*DP0_IMAGIC((_L("CIETNGeneratorAO::RunL - EScaling"))); + TRAPD(err, ScaleL()); + if (err != KErrNone) + ASSERT(0);// TODO handle errors + iConvertStatus = EEncoding; + SetActive();*/ + } + + if( iImageEncoder ) + { + delete iImageEncoder; + iImageEncoder = NULL; + } + + if( iBitmap ) + { + iBitmap->Reset(); + delete iBitmap; + iBitmap = NULL; + } + +#ifdef DECODE_FROM_BUFFER + if(iSourceData) + { + delete iSourceData; + iSourceData = NULL; + } +#endif + + iConvertStatus = ENone; + +#ifndef USE_BITMAPS_TNS + WriteExifData(iThumbnailFileName, iResolutionSize); +#else + if(IsJPEG(iThumbnailSize)) + { + TRAPD(err, WriteExifDataL(iThumbnailFileName, iThumbnailSize)); + } +#endif + + iFileServer.SetModified(iThumbnailFileName, iSourceTime); + iThumbnailObserver.ThumbNailGenerationCompleted(KErrNone); + } + break; + } + + DP0_IMAGIC(_L("CIETNGeneratorAO::RunL --")); + } + +TBool CIETNGeneratorAO::IsJPEG(const TSize& aResolution) const + { +#ifdef USE_64X64_BITMAP_TN + return (aResolution.iWidth >= 512 || aResolution.iHeight >= 512); +#else + return (aResolution.iWidth >= 128 || aResolution.iHeight >= 128); +#endif + } + +TBool CIETNGeneratorAO::IsLargeThumbnail(const TSize& aResolution) const + { + return (aResolution.iHeight >= 512); + } + +void CIETNGeneratorAO::ScaleL() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::Scale++"))); + + if ( iImageDecoder ) + { + delete iImageDecoder; + iImageDecoder = NULL; + } + + if (iBitmapScaler ) + { + delete iImageDecoder; + iImageDecoder = NULL; + } + + iBitmapScaler = CBitmapScaler::NewL(); + iBitmapScaler->UseLowMemoryAlgorithm(ETrue); + + TSize tgtBitmapize; + + // If we want to create high resolution thumbnail, we use 512x512 resolution + // for low resolution TN we use size set in iResolutionSize + if(IsLargeThumbnail(iThumbnailSize)) + { + tgtBitmapize.iWidth = 512; + tgtBitmapize.iHeight = 512; + + if(iSourceSize.iWidth > iSourceSize.iHeight) + { + // If we have wide panorama, use higher resolution to width + if((iSourceSize.iWidth / iSourceSize.iHeight) > 1.6) + tgtBitmapize.iWidth = 1024; + } + else + { + // If we have wide panorama, use higher resolution to height + if((iSourceSize.iHeight / iSourceSize.iWidth) > 1.6) + tgtBitmapize.iHeight = 1024; + } + } + else + { + tgtBitmapize = iThumbnailSize; + } + + // Use max quality + iBitmapScaler->SetQualityAlgorithm(CBitmapScaler::EMaximumQuality); + //iBitmapScaler->SetQualityAlgorithm(CBitmapScaler::EMediumQuality); + //iBitmapScaler->SetQualityAlgorithm(CBitmapScaler::EMinimumQuality); + + DP2_IMAGIC(_L("CIETNGeneratorAO::Scale to %dx%d"), tgtBitmapize.iWidth, tgtBitmapize.iHeight); + + iBitmapScaler->Scale(&iStatus, *iBitmap, tgtBitmapize, EFalse); + + DP0_IMAGIC((_L("CIETNGeneratorAO::Scale--"))); + } + +void CIETNGeneratorAO::EncodeL() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::Encode++"))); + + if (iImageDecoder ) + { + delete iImageDecoder; + iImageDecoder = NULL; + } + if( iBitmapScaler ) + { + delete iBitmapScaler; + iBitmapScaler = NULL; + } + if( iImageEncoder ) + { + delete iImageEncoder; + iImageEncoder = NULL; + } + + TParse parser; + parser.Set(iThumbnailFileName, NULL, NULL ); + TFileName tnPath = parser.DriveAndPath(); + CIEEngineUtils::CreateTNFolder(iFileServer, tnPath); + +#ifdef USE_BITMAPS_TNS + // Save Bitmap thumbnails if resolution is 128x128 or smaller + if(!IsJPEG(iThumbnailSize)) + { + iBitmap->Save(iThumbnailFileName); + } + else //if bigger than then save jpg thumbnails +#endif + { +#if 0 + //If we had 512x512 resolution bitmap we make copy of it + if(iBitmap->SizeInPixels().iWidth == 512 && iBitmap->SizeInPixels().iHeight == 512) + { + i512x512TnBitmap->Reset(); + TInt error = i512x512TnBitmap->Create(iBitmap->SizeInPixels(), EColor16M); + + TUint8* dstData = (TUint8 *)i512x512TnBitmap->DataAddress(); + TUint8* srcData = (TUint8 *)iBitmap->DataAddress(); + TInt dataSize = iBitmap->SizeInPixels().iWidth * iBitmap->SizeInPixels().iHeight; + dataSize*=3; + + //Copy bitmap + for(TInt i=0; iConvert(&iStatus, *iBitmap, iFrameImageData); + } + + TEntry entry; + User::LeaveIfError(iFileServer.Entry(iThumbnailFileName, entry)); + // Remember the modified time of the source file + iSourceTime = entry.iModified; + + DP0_IMAGIC((_L("CIETNGeneratorAO::Encode--"))); + } + +void CIETNGeneratorAO::DecodeL() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::Decode++"))); + + if(iImageDecoder) + { + delete iImageDecoder; + iImageDecoder = NULL; + } + + DP1_IMAGIC((_L("CIETNGeneratorAO::Decode - Creating decoder... with filename: %S")),&iSourceFileName); +#ifdef USE_EXT_JPEG_DEC + iImageDecoder = CExtJpegDecoder::FileNewL(iFileServer, iSourceFileName); +#else + +#ifdef DECODE_FROM_BUFFER + if(iSourceData) { + delete iSourceData; + iSourceData = NULL; + } + + RFile jpgFile; + TInt fileSize; + + User::LeaveIfError(jpgFile.Open(iFileServer, iSourceFileName, EFileRead)); + jpgFile.Size(fileSize); + iSourceData = HBufC8::NewL(fileSize); + + TPtr8 buffer = iSourceData->Des(); + + jpgFile.Read(buffer, fileSize); + + jpgFile.Close(); + + iImageDecoder = CImageDecoder::DataNewL( + iFileServer, + *iSourceData, + CImageDecoder::EOptionNone, + KNullUid, + KNullUid, + decoderUid); + + +#else + iImageDecoder = CImageDecoder::FileNewL( + iFileServer, + iSourceFileName, + CImageDecoder::EOptionNone, + KNullUid, + KNullUid, + decoderUid); +#endif + +#endif + + + iMimeString = KMimeJpeg; +#ifdef DECODE_FROM_BUFFER + CImageDecoder::GetMimeTypeDataL( *iSourceData, iMimeString ); +#else + CImageDecoder::GetMimeTypeFileL( iFileServer, iSourceFileName, iMimeString ); +#endif + + iSourceSize = iImageDecoder->FrameInfo().iOverallSizeInPixels; + + DP2_IMAGIC((_L("CIETNGeneratorAO::Decode - image %dx%d")), iSourceSize.iWidth, iSourceSize.iHeight ); + + iBitmap = new (ELeave) CFbsBitmap(); + + TargetDecodingSize(iThumbnailSize, iSourceSize); + +#ifdef DO_NOT_USE_SCALING + if(IsLargeThumbnail(iThumbnailSize)) + { + iSourceSize.iHeight=512; + iSourceSize.iWidth=512; + } +#endif + + TInt error = iBitmap->Create(iSourceSize, EColor16M); + + iImageDecoder->Convert(&iStatus, *iBitmap, 0); + + DP0_IMAGIC((_L("CIETNGeneratorAO::Decode - convert bitmap... OK"))); + DP0_IMAGIC((_L("CIETNGeneratorAO::Decode--"))); + } + +void CIETNGeneratorAO::TargetDecodingSize(const TSize aTgtSize, TSize& aSrcSize) + { + DP0_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize++")); + + DP2_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize - Tgt %dx%d"),aTgtSize.iHeight, aTgtSize.iWidth); + DP2_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize - Src %dx%d"),aSrcSize.iHeight, aSrcSize.iWidth); + + // up to 32 times downscale in scaler + for (TInt i = 0;i < 5;i++) + { + if (aSrcSize.iWidth < aTgtSize.iWidth * 2 || + aSrcSize.iHeight < aTgtSize.iHeight * 2) + { + break; + } + + aSrcSize.iWidth >>= 1; + aSrcSize.iHeight >>= 1; + } + + // Check that we do not create odd resolution size thumbnail + if(aSrcSize.iHeight & 1) + aSrcSize.iHeight++; + if(aSrcSize.iWidth & 1) + aSrcSize.iWidth++; + + DP2_IMAGIC(_L("CIETNGeneratorAO::TargetDecodingSize - New Src %dx%d"), aSrcSize.iHeight, aSrcSize.iWidth); + DP0_IMAGIC((_L("CIETNGeneratorAO::TargetDecodingSize--"))); + } + +void CIETNGeneratorAO::WriteExifDataL(const TDes &aFilename, TSize aSize) + { + DP0_IMAGIC(_L("CIETNGeneratorAO::WriteExifData++")); + + // 1. Read JPEG image from the file to a buffer... + RFile file; + User::LeaveIfError( file.Open( iFileServer, aFilename, EFileWrite ) ); + CleanupClosePushL( file ); + TInt size = 0; + file.Size(size); + HBufC8* jpegImage = HBufC8::NewL( size ); + CleanupStack::PushL( jpegImage ); + TPtr8 bufferDes( jpegImage->Des() ); + User::LeaveIfError( file.Read( bufferDes ) ); + CleanupStack::Pop( jpegImage ); + CleanupStack::PopAndDestroy(); + CleanupStack::PushL( jpegImage ); + + file.Close(); + + // 2. Instantiate Exif modifier in ECreate mode... + CExifModify* modify = CExifModify::NewL( jpegImage->Des(), CExifModify::ECreate ); + CleanupStack::PushL( modify ); + + // 3. Insert (Set) at least the mandatory Exif data... + modify->SetXResolutionL( aSize.iWidth, 1 ); + modify->SetYResolutionL( aSize.iHeight, 1 ); + modify->SetResolutionUnitL( 2 ); + modify->SetYCbCrPositioningL( 1 ); + modify->SetComponentsConfigurationL( 1, 2, 3, 0 ); + modify->SetColorSpaceL( 1 ); + modify->SetPixelXDimensionL( aSize.iWidth ); + modify->SetPixelYDimensionL( aSize.iHeight ); + + // 4. Get the new Exif image... + // If zero length descriptor is given instead of jpeg->Des(), then only the + // Exif meta data is returned. + HBufC8* newExif = modify->WriteDataL( jpegImage->Des() ); + TPtr8 tmp = newExif->Des(); + + User::LeaveIfError( file.Replace( iFileServer, aFilename, EFileWrite ) ); + //Write Exif and jpeg image back to jpeg file + User::LeaveIfError(file.Write(*newExif)); + + /* Process the new Exif data */ + delete newExif; + newExif = NULL; + + // 5. Delete the modifier instance... + CleanupStack::PopAndDestroy( modify ); + CleanupStack::PopAndDestroy( jpegImage ); + + file.Close(); + + DP0_IMAGIC(_L("CIETNGeneratorAO::WriteExifData--")); + } + + +//Set JPEG image quality for encoding +void CIETNGeneratorAO::SetJpegImageDataL() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::SetJpegImageDataL++"))); + + TJpegImageData* jpegImageData; + jpegImageData = new (ELeave) TJpegImageData; + jpegImageData->iSampleScheme = TJpegImageData::EColor420; + jpegImageData->iQualityFactor = 80; + + if (iFrameImageData) + { + delete iFrameImageData; + iFrameImageData = NULL; + } + + iFrameImageData = CFrameImageData::NewL(); + + //Ownership of jpegImageData lies with CFrameImageData + User::LeaveIfError(iFrameImageData->AppendImageData(jpegImageData)); + + DP0_IMAGIC((_L("CIETNGeneratorAO::SetJpegImageDataL--"))); + } + +void CIETNGeneratorAO::DoCancel() + { + } + +TInt CIETNGeneratorAO::RunError(TInt /*aError*/) + { + return KErrNone; + } + +/* Set Image arrary received from Client.*/ +void CIETNGeneratorAO::SetImageArray(RArray aImageArray) + { + DP0_IMAGIC((_L("CIETNGeneratorAO::SetImageArray ++"))); + + iImageArray = aImageArray; + + DP0_IMAGIC((_L("CIETNGeneratorAO::SetImageArray --"))); + } + +void CIETNGeneratorAO::CreateThumbnailL( + const TDes& aSourceFile, + const TDes& aThumbnailFile, + const TSize &aSize) + { + DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL ++"))); + + iSourceFileName.Copy(aSourceFile); + iThumbnailFileName.Copy(aThumbnailFile); + iThumbnailSize = aSize; + + iConvertStatus = EDecoding; + if(!IsActive()) + { + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + + DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL --"))); + } + + +void CIETNGeneratorAO::CreateThumbnailL( + const TDes& aSourceFile, + const TDes& aThumbnailFile, + const TSize &aSize, + CFbsBitmap* /*a512x512TnBitmap*/) + { + DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL ++"))); + + iSourceFileName.Copy(aSourceFile); + iThumbnailFileName.Copy(aThumbnailFile); + iThumbnailSize = aSize; + + iConvertStatus = EDecoding; + if(!IsActive()) + { + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + + DP0_IMAGIC((_L("CIETNGeneratorAO::CreateThumbnailL --"))); + } + +void CIETNGeneratorAO::CancelOutStaningRequests() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::CancelOutStaningRequests ++"))); + + if(iError != KErrNone) + { + if(BaflUtils::FileExists(iFileServer, iThumbnailFileName)) + { + TInt err = BaflUtils::DeleteFile(iFileServer, iThumbnailFileName); + DP2_IMAGIC(_L("CIETNGeneratorAO::CancelOutStaningRequests - DeleteCorruptedThumbNailFile - file found: %S, err:%d"), &iThumbnailFileName, err); + } + } + + DeleteObjects(); + + DP0_IMAGIC((_L("CIETNGeneratorAO::CancelOutStaningRequests --"))); + } + +void CIETNGeneratorAO::DeleteObjects() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::DeleteObjects ++"))); + + if(iImageDecoder) + { + delete iImageDecoder; + iImageDecoder = NULL; + } + + if( iBitmapScaler ) + { + delete iBitmapScaler; + iBitmapScaler = NULL; + } + + if( iBitmap ) + { + delete iBitmap; + iBitmap = NULL; + } + + if( iImageEncoder ) + { + delete iImageEncoder; + iImageEncoder = NULL; + } + + if (iFrameImageData) + { + delete iFrameImageData; + iFrameImageData = NULL; + } + +#ifdef DECODE_FROM_BUFFER + if(iSourceData) + { + delete iSourceData; + iSourceData = NULL; + } +#endif + //delete i512x512TnBitmap; + + DP0_IMAGIC((_L("CIETNGeneratorAO::DeleteObjects --"))); + } + +void CIETNGeneratorAO::CancelRequestsAndDeleteObjects() + { + DP0_IMAGIC((_L("CIETNGeneratorAO::CancelRequestsAndDeleteObjects ++"))); + + CancelOutStaningRequests(); + DeleteObjects(); + + DP0_IMAGIC((_L("CIETNGeneratorAO::CancelRequestsAndDeleteObjects --"))); + }