diff -r 420f6808bf21 -r f9e827349359 photosgallery/viewframework/texturemanager/src/glxbitmapdecoderwrapper.cpp --- a/photosgallery/viewframework/texturemanager/src/glxbitmapdecoderwrapper.cpp Wed Jun 09 09:41:51 2010 +0300 +++ b/photosgallery/viewframework/texturemanager/src/glxbitmapdecoderwrapper.cpp Mon Jun 21 15:40:32 2010 +0300 @@ -29,27 +29,31 @@ #include #include #include +#include +#include + namespace -{ -const TInt KGlxDecodingThreshold = 3000000; -const TInt KGlxDecodingThresholdDimension = 2000; - + { + const TInt KGlxDecodingThreshold = 3000000; + const TInt KGlxDecodingThresholdDimension = 2000; -// Photos low_ram_threshold [8.637 MB] as in oomconfig.xml -const TInt KGlxCriticalRAMForPhotos = 9056550; -const TInt KGlxDecodeBitmapFactor = 3; -// All EXIF data is within the first KGlxMaxExifSize bytes of the file -const TInt KGlxMaxExifSize = 0x10000; -} + // Photos low_ram_threshold [8.637 MB] as in oomconfig.xml + const TInt KGlxCriticalRAMForPhotos = 9056550; + const TInt KGlxDecodeBitmapFactor = 3; + + _LIT(KMimeJpeg,"image/jpeg"); + _LIT(KMimeJpg,"image/jpg"); + } // --------------------------------------------------------------------------- // Two-phased constructor. // --------------------------------------------------------------------------- // -CGlxBitmapDecoderWrapper* CGlxBitmapDecoderWrapper::NewL(MGlxBitmapDecoderObserver* aObserver) +CGlxBitmapDecoderWrapper* CGlxBitmapDecoderWrapper::NewL( + MGlxBitmapDecoderObserver* aObserver) { - TRACER("CGlxBitmapDecoderWrapper:: NewL "); - CGlxBitmapDecoderWrapper* self = new(ELeave)CGlxBitmapDecoderWrapper(); + TRACER("CGlxBitmapDecoderWrapper::NewL()"); + CGlxBitmapDecoderWrapper* self = new (ELeave) CGlxBitmapDecoderWrapper(); CleanupStack::PushL(self); self->ConstructL(aObserver); CleanupStack::Pop(self); @@ -60,20 +64,19 @@ // Constructor // --------------------------------------------------------------------------- // -CGlxBitmapDecoderWrapper::CGlxBitmapDecoderWrapper() - :CActive( EPriorityLow ) - { - TRACER("CGlxBitmapDecoderWrapper:: NewL "); - } +CGlxBitmapDecoderWrapper::CGlxBitmapDecoderWrapper() : + CActive(EPriorityLow) + { + TRACER("CGlxBitmapDecoderWrapper::CGlxBitmapDecoderWrapper()"); + } // --------------------------------------------------------------------------- // Destructor // --------------------------------------------------------------------------- // - CGlxBitmapDecoderWrapper::~CGlxBitmapDecoderWrapper() { - TRACER("CGlxBitmapDecoderWrapper:: ~CGlxBitmapDecoderWrapper "); + TRACER("CGlxBitmapDecoderWrapper::~CGlxBitmapDecoderWrapper()"); iFs.Close(); Cancel(); if (iImageDecoder) @@ -81,6 +84,11 @@ delete iImageDecoder; iImageDecoder = NULL; } + if (iImagePath) + { + delete iImagePath; + iImagePath = NULL; + } } // --------------------------------------------------------------------------- @@ -97,16 +105,17 @@ // --------------------------------------------------------------------------- // DoDecodeImageL // --------------------------------------------------------------------------- +void CGlxBitmapDecoderWrapper::DoDecodeImageL(const TDesC& aSourceFileName, + TInt aIndex) + { + TRACER("CGlxBitmapDecoderWrapper::DoDecodeImageL()"); + GLX_LOG_URI("CGlxBitmapDecoderWrapper::DoDecodeImageL(%S)", + &aSourceFileName); -void CGlxBitmapDecoderWrapper::DoDecodeImageL(const TDesC & aSourceFileName,TInt aIndex) - { - TRACER("CGlxBitmapDecoderWrapper:: DoDecodeImageL "); iThumbnailIndex = aIndex; - //Variable used to get the decoder type used - TBool isExtDecoderUsed = ETrue; - + #ifdef _DEBUG - iDecodeProcessstartTime.HomeTime(); + iStartTime.HomeTime(); #endif if (iImageDecoder) @@ -114,61 +123,40 @@ delete iImageDecoder; iImageDecoder = NULL; } - - CImageDecoder::TOptions options = (CImageDecoder::TOptions) - ( CImageDecoder::EOptionNoDither | CImageDecoder::EOptionAlwaysThread ); + + CImageDecoder::TOptions options = + (CImageDecoder::TOptions) (CImageDecoder::EOptionNoDither + | CImageDecoder::EOptionAlwaysThread); // Use extended JPEG decoder + GLX_DEBUG1("DoDecodeImageL:: EHwImplementation" ); TRAPD( err, iImageDecoder = CExtJpegDecoder::FileNewL( - CExtJpegDecoder::EHwImplementation, iFs, aSourceFileName, options ) ); - if ( KErrNone != err ) + CExtJpegDecoder::EHwImplementation, iFs, + aSourceFileName, options ) ); + GLX_DEBUG2("DoDecodeImageL:: EHwImplementation (%d)", err); + if (KErrNone != err) { - GLX_LOG_INFO( "DoDecodeImageL:: ESwImplementation" ); TRAP(err,iImageDecoder = CExtJpegDecoder::FileNewL( - CExtJpegDecoder::ESwImplementation, iFs, aSourceFileName, options ) ); - if ( KErrNone != err ) + CExtJpegDecoder::ESwImplementation, iFs, + aSourceFileName, options ) ); + GLX_DEBUG2("DoDecodeImageL:: ESwImplementation (%d)", err); + if (KErrNone != err) { - GLX_LOG_INFO( "DoDecodeImageL:: CImageDecoder" ); + GLX_DEBUG1("DoDecodeImageL::CImageDecoder"); // Not a JPEG - use standard decoder - iImageDecoder = CImageDecoder::FileNewL( iFs, aSourceFileName, options ); - isExtDecoderUsed = EFalse; + iImageDecoder = CImageDecoder::FileNewL(iFs, aSourceFileName, + options); } } #ifdef _DEBUG - iStopTime.HomeTime(); - GLX_DEBUG1("=== DECODER CREATION ==="); - GLX_DEBUG2("Decoder Creation took <%d> us", - (TInt)iStopTime.MicroSecondsFrom(iDecodeProcessstartTime).Int64()); + iStopTime.HomeTime(); + GLX_DEBUG2("*** Decoder Creation took <%d> us ***", + (TInt)iStopTime.MicroSecondsFrom(iStartTime).Int64()); #endif - + TSize imageSize = iImageDecoder->FrameInfo().iOverallSizeInPixels; - if(isExtDecoderUsed) - { - TUint16 orientation=0; - //Read the orientation from the Exif header of the image if present - TRAPD(error, orientation=GetOrientationL(aSourceFileName)); - if(KErrNone == error ) - { - //Get the rotation angle and the flip status from orientation - TInt rotAngle = 0; - TBool flipStatus = EFalse; - GetRotationParameters(orientation, rotAngle, flipStatus); - //Set the parameters to the decoder - CExtJpegDecoder* extDecoder = (CExtJpegDecoder*)iImageDecoder; - extDecoder->SetRotationL(rotAngle); - if(flipStatus) - { - extDecoder->SetMirroringL(); - } - //Switch Image Height and width in case orientation > 4 as that - //corresponds to angles 180 and 270 degrees - if (orientation > 4) - { - imageSize.SetSize(imageSize.iHeight,imageSize.iWidth); - } - } - - } + GLX_DEBUG3("GlxDecoderWrapper::DecodeImageL() - OverallSize: w=%d, h=%d", + imageSize.iWidth, imageSize.iHeight); iOriginalSize.iWidth = imageSize.iWidth; iOriginalSize.iHeight = imageSize.iHeight; @@ -177,140 +165,161 @@ delete iBitmap; iBitmap = NULL; } + + if (iImagePath) + { + delete iImagePath; + iImagePath = NULL; + } + iImagePath = aSourceFileName.Alloc(); + DecodeImageL(); } + // --------------------------------------------------------------------------- // DecodeImageL // --------------------------------------------------------------------------- // void CGlxBitmapDecoderWrapper::DecodeImageL() { - TRACER("CGlxBitmapDecoderWrapper:: DecodeImageL "); + TRACER("CGlxBitmapDecoderWrapper::DecodeImageL()"); TReal32 mFactor = 1; - TReal32 mFactor1 = 1; + TReal mFactor1 = 1; TReal32 mFactor2 = 1; //Set Size according to level and state TReal32 width = iOriginalSize.iWidth; TReal32 height = iOriginalSize.iHeight; - GLX_LOG_INFO1("DecodeImageL:width=%f", width); - GLX_LOG_INFO1("DecodeImageL:height=%f",height); - - if ( KGlxDecodingThreshold < (width * height)) + + if (KGlxDecodingThreshold < (width * height)) { - mFactor1 = TReal32(KGlxDecodingThreshold) / (width*height); - GLX_LOG_INFO1("mFactor1 =%f",mFactor1); + TReal tempFactor = TReal32(KGlxDecodingThreshold) + / (width * height); + User::LeaveIfError(Math::Sqrt(mFactor1, tempFactor)); + GLX_DEBUG2("DecodeImageL() - mFactor1 = %f", mFactor1); } - - if ( KGlxDecodingThresholdDimension < width || KGlxDecodingThresholdDimension < height) + + if (KGlxDecodingThresholdDimension < width + || KGlxDecodingThresholdDimension < height) { - mFactor2 = TReal32(KGlxDecodingThresholdDimension) / Max(width, height); - GLX_LOG_INFO1("mFactor2 =%f",mFactor2); + mFactor2 = TReal32(KGlxDecodingThresholdDimension) / Max(width, + height); + GLX_DEBUG2("DecodeImageL() - mFactor2 = %f", mFactor2); } - mFactor = Min(mFactor1 , mFactor2); - GLX_LOG_INFO1("Final mFactor =%f",mFactor); + mFactor = Min(TReal32(mFactor1), mFactor2); + GLX_DEBUG2("DecodeImageL() - Final mFactor = %f", mFactor); // create the destination bitmap - if(!iBitmap) + if (!iBitmap) { TInt freeMemory = 0; - HAL::Get( HALData::EMemoryRAMFree, freeMemory ); - width*=mFactor; - height*=mFactor; - TInt minmemorytodecode = KGlxDecodeBitmapFactor*width*height; - GLX_LOG_INFO2("DecodeImageL: after factoring width=%f, height=%f", width, height); - GLX_LOG_INFO2("DecodeImageL:minmemorytodecode=%d, freememory=%d", + HAL::Get(HALData::EMemoryRAMFree, freeMemory); + width *= mFactor; + height *= mFactor; + TInt minmemorytodecode = KGlxDecodeBitmapFactor * width * height; + GLX_DEBUG3("DecodeImageL: minmemorytodecode=%d, freememory=%d", minmemorytodecode, freeMemory); - if(minmemorytodecode < (freeMemory - KGlxCriticalRAMForPhotos)) + + iTargetBitmapSize.iWidth = width; + iTargetBitmapSize.iHeight = height; + GLX_DEBUG3("DecodeImageL: iTargetBitmapSize w=%d, h=%d", + iTargetBitmapSize.iWidth, iTargetBitmapSize.iHeight); + __ASSERT_DEBUG(width > 0 && height > 0, Panic(EGlxPanicIllegalArgument)); + + if (minmemorytodecode < (freeMemory - KGlxCriticalRAMForPhotos)) { - GLX_LOG_INFO("DecodeImageL:RAM available decoding image"); - + GLX_DEBUG1("DecodeImageL:RAM available decoding image"); iBitmap = new (ELeave) CFbsBitmap(); - iBitmap->Create( TSize(width,height),iImageDecoder->FrameInfo().iFrameDisplayMode ); + iBitmap->Create(ReCalculateSizeL(), + iImageDecoder->FrameInfo().iFrameDisplayMode); #ifdef _DEBUG iStartTime.HomeTime(); // Get home time #endif - iImageDecoder->Convert( &iStatus, *iBitmap ); + iImageDecoder->Convert(&iStatus, *iBitmap); } else { //case when sufficient memory is not available //request OOM FW to release the required memory - GLX_LOG_INFO("DecodeImageL:insufficient RAM - request OOM"); + GLX_DEBUG1("DecodeImageL:insufficient RAM - request OOM"); TInt err = OOMRequestFreeMemoryL(minmemorytodecode); - if(err == KErrNoMemory) + if (err == KErrNoMemory) { //if OOM fails, release Photos Cache - GLX_LOG_INFO("DecodeImageL:insufficient RAM - OOM failed - request Cache"); + GLX_DEBUG1("DecodeImageL:insufficient RAM - OOM failed" + " - request Cache"); MGlxCache* cacheManager = MGlxCache::InstanceL(); - cacheManager->ReleaseRAML(ETrue); + cacheManager->ReleaseRAML(ETrue); cacheManager->Close(); //Try and release memory again err = OOMRequestFreeMemoryL(minmemorytodecode); } - if(err != KErrNoMemory) + if (err != KErrNoMemory) { - GLX_LOG_INFO("DecodeImageL:Sufficient RAM available"); + GLX_DEBUG1("DecodeImageL:Sufficient RAM available"); iBitmap = new (ELeave) CFbsBitmap(); - iBitmap->Create( TSize(width,height),iImageDecoder->FrameInfo().iFrameDisplayMode ); + iBitmap->Create(ReCalculateSizeL(), + iImageDecoder->FrameInfo().iFrameDisplayMode); #ifdef _DEBUG - iStartTime.HomeTime(); // Get home time + iStartTime.HomeTime(); // Get home time #endif - iImageDecoder->Convert( &iStatus, *iBitmap ); + iImageDecoder->Convert(&iStatus, *iBitmap); } else { - GLX_LOG_INFO("NOT ENOUGH MEMORY - Using the Fullscreen Thumbnail For Zoom"); + GLX_DEBUG1("NOT ENOUGH MEMORY - " + "Using the Fullscreen Thumbnail For Zoom"); //release the file held by decoder immediately. iImageDecoder->Cancel(); delete iImageDecoder; iImageDecoder = NULL; //Inform the client that there is no decode happened and there we take care //of showing the fullscreen thumbnail. - iObserver->HandleBitmapDecodedL(iThumbnailIndex,NULL); - return; + iObserver->HandleBitmapDecodedL(iThumbnailIndex, NULL); + return; } } SetActive(); } } + // --------------------------------------------------------------------------- // RunL // --------------------------------------------------------------------------- // void CGlxBitmapDecoderWrapper::RunL() { - TRACER("CGlxBitmapDecoderWrapper:: RunL "); + TRACER("CGlxBitmapDecoderWrapper::RunL()"); if( iStatus == KErrNone ) { iObserver->HandleBitmapDecodedL(iThumbnailIndex,iBitmap); iBitmap = NULL; //release the file held by decoder immediately. - GLX_LOG_INFO( " CGlxBitmapDecoderWrapper::RunL:Decoding Finished" ); + GLX_DEBUG1("CGlxBitmapDecoderWrapper::RunL:Decoding Finished"); iImageDecoder->Cancel(); delete iImageDecoder; iImageDecoder = NULL; #ifdef _DEBUG iStopTime.HomeTime(); - GLX_DEBUG1("=== IMAGE DECODE ==="); - GLX_DEBUG2("=>Image Decode Took took <%d> us", + GLX_DEBUG2("*** Image Decode took <%d> us ***", (TInt)iStopTime.MicroSecondsFrom(iStartTime).Int64()); #endif } } + // --------------------------------------------------------------------------- // DoCancel // --------------------------------------------------------------------------- // void CGlxBitmapDecoderWrapper::DoCancel() { - TRACER("CGlxBitmapDecoderWrapper:: DoCancel "); + TRACER("CGlxBitmapDecoderWrapper::DoCancel "); if(iImageDecoder) { - GLX_LOG_INFO( " CGlxBitmapDecoderWrapper::DoCancel:Deleting" ); + GLX_DEBUG1("CGlxBitmapDecoderWrapper::DoCancel iImageDecoder delete"); iImageDecoder->Cancel(); delete iImageDecoder; iImageDecoder = NULL; @@ -323,106 +332,84 @@ } // --------------------------------------------------------------------------- -// GetOrientationL -// --------------------------------------------------------------------------- -// -TUint16 CGlxBitmapDecoderWrapper::GetOrientationL(const TDesC& aFileName) - { - TRACER("CGlxBitmapDecoderWrapper:: GetOrientationL "); - //Get Exif Metadata and the orientation tag from the file first - RFile file; - CleanupClosePushL(file); - User::LeaveIfError(file.Open(iFs, - aFileName, EFileRead)); - TInt size; - User::LeaveIfError(file.Size(size)); - if ( KGlxMaxExifSize < size ) - { - size = KGlxMaxExifSize; - } - TUint16 orientation = 9; - HBufC8* exifData = HBufC8::NewLC(size); - TPtr8 ptr(exifData->Des()); - User::LeaveIfError(file.Read(ptr)); - CExifRead* exifReader = NULL; - TRAPD(exifErr,exifReader = CExifRead::NewL(*exifData, CExifRead::ENoJpeg)); - if(exifErr == KErrNone) - { - CleanupStack::PushL(exifReader); - - TInt readErr = exifReader->GetOrientation(orientation); - if(readErr != KErrNone) - { - orientation = 9; - } - CleanupStack::PopAndDestroy(exifReader); - } - CleanupStack::PopAndDestroy(exifData); - //Close and pop file Session - CleanupStack::PopAndDestroy(&file); - return orientation; - - } -// --------------------------------------------------------------------------- -// DoCancel -// --------------------------------------------------------------------------- -// -void CGlxBitmapDecoderWrapper::GetRotationParameters(TUint16 aOrientation, TInt& aRotAngle, TBool& aFlipStatus) - { - TRACER("CGlxBitmapDecoderWrapper:: DoCancel "); - //Get the orientation and set rotation on the decoder - //as well as update the original size - aRotAngle = 0; - aFlipStatus = EFalse; - TInt isOrientationOdd = aOrientation%2; - if(aOrientation>8) - { - return; - } - if(aOrientation >= 3 && aOrientation < 5) - { - aRotAngle = 180; - } - else if(aOrientation >= 5 && aOrientation < 7) - { - aRotAngle = 90; - - } - else if(aOrientation >= 7 && aOrientation <= 8) - { - aRotAngle = 270; - } - if(aOrientation>4 ) - { - if(isOrientationOdd ) - { - aFlipStatus = ETrue; - } - } - - } - -// --------------------------------------------------------------------------- // OOMRequestFreeMemoryL // --------------------------------------------------------------------------- // -TInt CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL( TInt aBytesRequested) +TInt CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL(TInt aBytesRequested) { TRACER("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL"); - GLX_LOG_INFO1("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL() aBytesRequested=%d", - aBytesRequested); + GLX_LOG_INFO1("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL() " + "aBytesRequested=%d", aBytesRequested); ROomMonitorSession oomMonitor; - User::LeaveIfError( oomMonitor.Connect() ); + User::LeaveIfError(oomMonitor.Connect()); // No leaving code after this point, so no need to use cleanup stack // for oomMonitor - TInt errorCode = oomMonitor.RequestFreeMemory( aBytesRequested ); - GLX_LOG_INFO1("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL(1) errorCode=%d",errorCode); - if ( errorCode != KErrNone ) + TInt errorCode = oomMonitor.RequestFreeMemory(aBytesRequested); + GLX_LOG_INFO1("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL(1) " + "errorCode=%d",errorCode); + if (errorCode != KErrNone) { // try one more time - errorCode = oomMonitor.RequestFreeMemory( aBytesRequested ); - GLX_LOG_INFO1("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL(2) errorCode=%d",errorCode); + errorCode = oomMonitor.RequestFreeMemory(aBytesRequested); + GLX_LOG_INFO1("CGlxBitmapDecoderWrapper::OOMRequestFreeMemoryL(2) " + "errorCode=%d",errorCode); } oomMonitor.Close(); return errorCode; } + +// ----------------------------------------------------------------------------- +// DoesMimeTypeNeedsRecalculateL() +// ----------------------------------------------------------------------------- +// +TBool CGlxBitmapDecoderWrapper::DoesMimeTypeNeedsRecalculateL() + { + TRACER("CGlxBitmapDecoderWrapper::DoesMimeTypeNeedsRecalculateL"); + RApaLsSession session; + TDataType mimeType; + TUid uid; + + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + User::LeaveIfError(session.AppForDocument(iImagePath->Des(), uid, + mimeType)); + CleanupStack::PopAndDestroy(&session); + + if (mimeType.Des().Compare(KMimeJpeg) == 0 || mimeType.Des().Compare( + KMimeJpg) == 0) + { + GLX_LOG_INFO("CGlxBitmapDecoderWrapper::DoesMimeTypeNeedsRecalculateL - jpeg"); + return EFalse; + } + else + { + GLX_LOG_INFO("CGlxHdmiSurfaceUpdater::DoesMimeTypeNeedsRecalculateL - non jpeg"); + return ETrue; + } + } + +// ----------------------------------------------------------------------------- +// ReCalculateSize +// ----------------------------------------------------------------------------- +TSize CGlxBitmapDecoderWrapper::ReCalculateSizeL() + { + TRACER("CGlxBitmapDecoderWrapper::ReCalculateSizeL()"); + if (DoesMimeTypeNeedsRecalculateL()) + { + TSize fullFrameSize = iImageDecoder->FrameInfo().iOverallSizeInPixels; + // calculate the reduction factor on what size we need + TInt reductionFactor = iImageDecoder->ReductionFactor(fullFrameSize, + iTargetBitmapSize); + // get the reduced size onto destination size + TSize destSize; + User::LeaveIfError(iImageDecoder->ReducedSize(fullFrameSize, + reductionFactor, destSize)); + GLX_LOG_INFO2("CGlxBitmapDecoderWrapper::ReCalculateSizeL() " + "destSize=%d, %d",destSize.iWidth,destSize.iHeight); + return destSize; + } + else + { + return iTargetBitmapSize; + } + }