--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imageeditorengine/JpegRotator/src/JpegRotatorImpl.cpp Fri Jan 29 13:53:17 2010 +0200
@@ -0,0 +1,463 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "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:
+* Ixonos Plc
+*
+* Description:
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <eikenv.h>
+#include <bautils.h>
+#include <imageconversion.h>
+
+#include "JpegRotatorImpl.h"
+#include "JpegRotator.h"
+#include "CJpRotate.h"
+
+// debug log
+#include "imageeditordebugutils.h"
+
+// for timing log. It is separate, because other logging
+// would affect performance
+#include <flogger.h>
+
+// CONSTANTS
+const TInt KDefaultSaveBuffer = 1048576; // 16384
+
+//=============================================================================
+CJpegRotatorImpl * CJpegRotatorImpl::NewL (RFs& aFsSession)
+{
+ CJpegRotatorImpl * self = new (ELeave) CJpegRotatorImpl (aFsSession);
+ CleanupStack::PushL (self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+}
+
+//=============================================================================
+CJpegRotatorImpl::~CJpegRotatorImpl ()
+{
+
+ if (iRotator)
+ {
+ delete iRotator;
+ }
+
+ if (iCallBack)
+ {
+ iCallBack->Cancel();
+ delete iCallBack;
+ }
+
+}
+
+//=============================================================================
+void CJpegRotatorImpl::Cleanup ()
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::Cleanup");
+
+ iSourceFileName = KNullDesC();
+ iTargetFileName = KNullDesC();
+ iRotationMode = CJpegRotator::ERotModeCounterClockwise;
+ iCallerStatus = NULL;
+ iSourceImageSize.SetSize(0,0);
+ iHandleExifData = ETrue;
+ iCancelled = EFalse;
+
+#if defined (LOG_TIMING)
+ iLosslessMode = EFalse;
+#endif
+}
+
+//=============================================================================
+void CJpegRotatorImpl::Cancel ()
+{
+ if (iRotator)
+ {
+ iRotator->Cancel();
+ }
+
+ iCancelled = ETrue;
+}
+
+//=============================================================================
+void CJpegRotatorImpl::PrepareRotateFileL (
+ const TDesC& aSourceFileName,
+ const TDesC& aTargetFileName,
+ CJpegRotator::TRotationMode aRotationMode,
+ TBool aHandleExifData)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::PrepareRotateFileL");
+
+#if defined (LOG_TIMING)
+ iStartTime.UniversalTime();
+#endif
+
+ // Reset old values
+ Cleanup();
+
+ // Check that the source file exists
+ if ( !BaflUtils::FileExists (iFsSession, aSourceFileName) )
+ {
+ User::Leave (KErrNotFound);
+ }
+ // Check that the target file does not exist
+ if ( BaflUtils::FileExists (iFsSession, aTargetFileName) )
+ {
+ User::Leave (KErrAlreadyExists);
+ }
+ // Check that the target path exists
+ TParsePtrC parse (aTargetFileName);
+ if ( !BaflUtils::FolderExists (iFsSession, parse.DriveAndPath()) )
+ {
+ User::Leave (KErrPathNotFound);
+ }
+
+ // Check & store the rotate parameter
+ if ( CJpegRotator::ERotModeCounterClockwise == aRotationMode )
+ {
+ iRotationMode = CJpegRotator::ERotModeCounterClockwise;
+ }
+ else if ( CJpegRotator::ERotModeClockwise == aRotationMode )
+ {
+ iRotationMode = CJpegRotator::ERotModeClockwise;
+ }
+ else if ( CJpegRotator::ERotMode180 == aRotationMode )
+ {
+ iRotationMode = CJpegRotator::ERotMode180;
+ }
+ else
+ {
+ User::Leave (KErrArgument);
+ }
+
+
+ // Store the source file name and set target name
+ iSourceFileName = aSourceFileName;
+ iTargetFileName = aTargetFileName;
+ iHandleExifData = aHandleExifData;
+
+ // Store the JPEG quality factor etc.
+ GetSourceImagePropertiesL ( iSourceFileName );
+}
+
+//=============================================================================
+void CJpegRotatorImpl::StartAsyncRotate (TRequestStatus& aStatus, TBool aForceLossyMode)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::StartAsyncRotate");
+
+ // Use lossless rotate if possible
+ if( !aForceLossyMode && IsLosslessRotatePossible() )
+ {
+ StartAsyncLosslessRotate (aStatus);
+ }
+
+ else
+ {
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+
+ iCb = TCallBack(CJpegRotatorImpl::AsyncLosslessRotate, this);
+
+ iCallBack = new CAsyncCallBack (iCb, CActive::EPriorityStandard);
+
+ if (iCallBack)
+ {
+ iCallBack->CallBack();
+ }
+ else
+ {
+ FinishAsyncRotate (KErrNoMemory);
+ }
+
+ }
+
+}
+
+//=============================================================================
+void CJpegRotatorImpl::StartAsyncLosslessRotate (TRequestStatus& aStatus)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::StartAsyncLosslessRotate");
+
+ aStatus = KRequestPending;
+ iCallerStatus = &aStatus;
+
+ iCb = TCallBack(CJpegRotatorImpl::AsyncLosslessRotate, this);
+ // Create the callback utility used with the asynchronous version of rotate
+ iCallBack = new CAsyncCallBack (iCb, CActive::EPriorityStandard);
+
+ if (iCallBack)
+ {
+ iCallBack->CallBack();
+ }
+ else
+ {
+ FinishAsyncRotate (KErrNoMemory);
+ }
+
+}
+
+//=============================================================================
+TInt CJpegRotatorImpl::AsyncRotate (TAny* /*aThis*/)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::AsyncRotate");
+ /*
+ // In the asynchronous version, trap the rest of the functions
+ // to make sure that the caller's TRequestStatus is always
+ // completed, also in case of failures.
+ CJpegRotatorImpl* impl = static_cast<CJpegRotatorImpl*>(aThis);
+
+ // Rotate-in-one-go, lossy mode
+ TRAPD (err, impl->DoRotateL());
+ if (err == KErrNone)
+ {
+ TRAP (err, impl->SaveImageL())
+ }
+ impl->FinishAsyncRotate (err);
+*/
+ return KErrNotSupported;
+}
+
+//=============================================================================
+TInt CJpegRotatorImpl::AsyncLosslessRotate (TAny* aThis)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::AsyncLosslessRotate");
+
+ // In the asynchronous version, trap the rest of the functions
+ // to make sure that the caller's TRequestStatus is always
+ // completed, also in case of failures.
+ CJpegRotatorImpl* impl = static_cast<CJpegRotatorImpl*>(aThis);
+
+ // Rotate-in-one-go
+ TRAPD (err, impl->DoLosslessRotateL());
+
+ impl->FinishAsyncRotate (err);
+
+ return KErrNone;
+}
+
+//=============================================================================
+void CJpegRotatorImpl::FinishAsyncRotate (TInt aError)
+{
+ LOGFMT( KJpegRotatorLogFile, "CJpegRotatorImpl::FinishAsyncRotate (error: %d)", aError);
+
+ if( !iCancelled )
+ {
+ User::RequestComplete (iCallerStatus, aError);
+ }
+ else
+ {
+ Cleanup();
+ }
+
+ PostRotate();
+}
+
+//=============================================================================
+void CJpegRotatorImpl::DoRotateL ()
+{
+ User::Leave(KErrNotSupported);
+}
+
+//=============================================================================
+void CJpegRotatorImpl::DoLosslessRotateL ()
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::DoLosslessRotateL");
+
+ iLosslessMode = ETrue;
+
+#if defined (LOG_TIMING)
+ iSavingStartTime.UniversalTime();
+#endif
+
+ // Load JPEG file to source file buffer
+
+ RFile srcfile;
+ CleanupClosePushL (srcfile);
+ User::LeaveIfError ( srcfile.Open (iFsSession, iSourceFileName, EFileRead) );
+
+ TInt sourcebufsize;
+ User::LeaveIfError ( srcfile.Size(sourcebufsize) );
+ TInt targetbufsize = (TInt)(1.2 * sourcebufsize);
+
+ TInt saveBufferSize = KDefaultSaveBuffer;
+ if (targetbufsize < saveBufferSize)
+ {
+ saveBufferSize = targetbufsize;
+ }
+
+ CleanupStack::PopAndDestroy();
+
+ RFile trgfile;
+ User::LeaveIfError ( trgfile.Replace (iFsSession, iTargetFileName, EFileRead) );
+ CleanupClosePushL (trgfile);
+
+ CJpRotate* rotator = CJpRotate::NewLC(iFsSession, &trgfile, saveBufferSize);
+
+ rotator->SetCallBack( this );
+
+ switch ( iRotationMode )
+ {
+ case CJpegRotator::ERotModeCounterClockwise:
+ {
+ rotator->RotateL( iSourceFileName, true, false, false );
+ break;
+ }
+ case CJpegRotator::ERotMode180:
+ {
+ rotator->RotateL( iSourceFileName, false, true, true );
+ break;
+ }
+ case CJpegRotator::ERotModeClockwise:
+ default:
+ {
+ rotator->RotateL( iSourceFileName, true, true, true );
+ break;
+ }
+
+ }
+
+ CleanupStack::PopAndDestroy(2);
+
+ LOG( KJpegRotatorLogFile, "\t...DoLosslessRotateL: Done.");
+
+}
+
+//=============================================================================
+void CJpegRotatorImpl::JpRotateStatus( TInt /*aCount*/, TInt /*aTotal*/ )
+{
+// LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::JpRotateStatus" );
+// LOGFMT( KJpegRotatorLogFile, " count: %d", aCount );
+// LOGFMT( KJpegRotatorLogFile, " total: %d", aTotal );
+}
+
+
+//=============================================================================
+CJpegRotatorImpl::CJpegRotatorImpl (RFs& aFsSession) :
+iFsSession (aFsSession),
+iRotator (NULL),
+iHandleExifData (ETrue)
+{
+}
+
+//=============================================================================
+void CJpegRotatorImpl::ConstructL ()
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::ConstructL");
+
+
+}
+
+//=============================================================================
+void CJpegRotatorImpl::GetSourceImagePropertiesL ( const TDesC& /*aFileName*/ )
+{
+ /*
+ // Create a new image decoder
+ CImageDecoder * decoder = CImageDecoder::FileNewL (iFsSession, aFileName);
+ CleanupStack::PushL( decoder );
+
+ // Get reference to frame image data
+ const CFrameImageData & imageData = decoder->FrameData();
+
+ // Get JPEG quality factor
+ iOriginalJpegQualityFactor = KDefaultSavedJpegQuality;
+ if ( imageData.ImageDataCount() > 0 )
+ {
+ iOriginalJpegQualityFactor = ((const TJpegImageData*)imageData.GetImageData(0))->iQualityFactor;
+ }
+
+ // Image resolution
+ const TFrameInfo& frameInfo = decoder->FrameInfo();
+ iSourceImageSize = frameInfo.iOverallSizeInPixels;
+
+ CleanupStack::PopAndDestroy( decoder );
+ */
+}
+
+//=============================================================================
+void CJpegRotatorImpl::SetJpegCommentL (const TDesC8& /*aComment*/)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::SetJpegCommentL");
+
+}
+
+//=============================================================================
+void CJpegRotatorImpl::SetExifData (TUint8* /*aExifData*/, TUint /*aDataSize*/)
+{
+ LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::SetExifData");
+
+}
+
+//=============================================================================
+void CJpegRotatorImpl::PostRotate ()
+{
+#if defined (LOG_TIMING)
+/*
+ iFinishTime.UniversalTime();
+
+ TInt64 prepareTime = iSavingStartTime.Int64() - iStartTime.Int64();
+ TInt64 savingTime = iFinishTime.Int64() - iSavingStartTime.Int64();
+ TInt64 totalTime = iFinishTime.Int64() - iStartTime.Int64();
+
+ TBuf<128> text1;
+ if (iLosslessMode)
+ {
+ text1 = _L("Rotating from %S to %S. Lossless rotate was used.");
+ }
+ else
+ {
+ text1 = _L("Rotating from %S to %S. Lossy rotate was used.");
+ }
+
+ RFileLogger::WriteFormat(
+ KImageEditorLogDir,
+ KJpegRotatorTimingLogFile,
+ EFileLoggingModeAppend,
+ text1, &iSourceFileName, &iTargetFileName
+ );
+
+ RFileLogger::WriteFormat(
+ KImageEditorLogDir,
+ KJpegRotatorTimingLogFile,
+ EFileLoggingModeAppend,
+ _L("\tTime taken (microseconds): %d"),
+ totalTime );
+
+ RFileLogger::WriteFormat(
+ KImageEditorLogDir,
+ KJpegRotatorTimingLogFile,
+ EFileLoggingModeAppend,
+ _L( "\tprepare phase: %d"),
+ prepareTime );
+
+ RFileLogger::WriteFormat(
+ KImageEditorLogDir,
+ KJpegRotatorTimingLogFile,
+ EFileLoggingModeAppend,
+ _L( "\tsave phase: %d"),
+ savingTime );
+*/
+#endif
+}
+
+//=============================================================================
+TBool CJpegRotatorImpl::IsLosslessRotatePossible() const
+{
+ return ETrue;
+}
+
+
+// End of File