imageeditorengine/JpegRotator/src/JpegRotatorImpl.cpp
changeset 1 edfc90759b9f
equal deleted inserted replaced
0:57d4cdd99204 1:edfc90759b9f
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    <eikenv.h>
       
    23 #include    <bautils.h>
       
    24 #include    <imageconversion.h>
       
    25 
       
    26 #include    "JpegRotatorImpl.h"
       
    27 #include    "JpegRotator.h"
       
    28 #include    "CJpRotate.h"
       
    29 
       
    30 //  debug log
       
    31 #include "imageeditordebugutils.h"
       
    32 
       
    33 // for timing log. It is separate, because other logging
       
    34 // would affect performance
       
    35 #include    <flogger.h>
       
    36 
       
    37 // CONSTANTS
       
    38 const TInt KDefaultSaveBuffer = 1048576;  // 16384
       
    39 
       
    40 //=============================================================================
       
    41 CJpegRotatorImpl * CJpegRotatorImpl::NewL (RFs& aFsSession)
       
    42 {
       
    43 	CJpegRotatorImpl * self = new (ELeave) CJpegRotatorImpl (aFsSession);
       
    44 	CleanupStack::PushL (self);
       
    45 	self->ConstructL();
       
    46 	CleanupStack::Pop(); // self
       
    47 	return self;
       
    48 }
       
    49 
       
    50 //=============================================================================
       
    51 CJpegRotatorImpl::~CJpegRotatorImpl ()
       
    52 {
       
    53 
       
    54     if (iRotator)
       
    55     {
       
    56         delete iRotator;
       
    57     }
       
    58 
       
    59     if (iCallBack)
       
    60     {
       
    61         iCallBack->Cancel();
       
    62         delete iCallBack;
       
    63     }
       
    64     
       
    65 }
       
    66 
       
    67 //=============================================================================
       
    68 void CJpegRotatorImpl::Cleanup ()
       
    69 {
       
    70     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::Cleanup");
       
    71 
       
    72     iSourceFileName = KNullDesC();
       
    73     iTargetFileName = KNullDesC();
       
    74     iRotationMode = CJpegRotator::ERotModeCounterClockwise;
       
    75     iCallerStatus = NULL;
       
    76     iSourceImageSize.SetSize(0,0);
       
    77     iHandleExifData = ETrue;
       
    78     iCancelled = EFalse;
       
    79 
       
    80 #if defined (LOG_TIMING)
       
    81     iLosslessMode = EFalse;
       
    82 #endif
       
    83 }
       
    84 
       
    85 //=============================================================================
       
    86 void CJpegRotatorImpl::Cancel ()
       
    87 {
       
    88     if (iRotator)
       
    89     {
       
    90         iRotator->Cancel();    
       
    91     }
       
    92     
       
    93 	iCancelled = ETrue;
       
    94 }
       
    95 
       
    96 //=============================================================================
       
    97 void CJpegRotatorImpl::PrepareRotateFileL (
       
    98     const TDesC& aSourceFileName,
       
    99     const TDesC& aTargetFileName,
       
   100     CJpegRotator::TRotationMode aRotationMode,
       
   101     TBool aHandleExifData)
       
   102 {
       
   103     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::PrepareRotateFileL");
       
   104 
       
   105 #if defined (LOG_TIMING)
       
   106     iStartTime.UniversalTime();
       
   107 #endif
       
   108 
       
   109     // Reset old values
       
   110     Cleanup();
       
   111 
       
   112     // Check that the source file exists
       
   113     if ( !BaflUtils::FileExists (iFsSession, aSourceFileName) )
       
   114     {
       
   115         User::Leave (KErrNotFound);
       
   116     }
       
   117     // Check that the target file does not exist
       
   118     if ( BaflUtils::FileExists (iFsSession, aTargetFileName) )
       
   119     {
       
   120         User::Leave (KErrAlreadyExists);
       
   121     }
       
   122     // Check that the target path exists
       
   123     TParsePtrC parse (aTargetFileName);
       
   124     if ( !BaflUtils::FolderExists (iFsSession, parse.DriveAndPath()) )
       
   125     {
       
   126         User::Leave (KErrPathNotFound);
       
   127     }
       
   128 
       
   129     // Check & store the rotate parameter
       
   130     if ( CJpegRotator::ERotModeCounterClockwise == aRotationMode )
       
   131     {
       
   132         iRotationMode = CJpegRotator::ERotModeCounterClockwise;
       
   133     }
       
   134     else if ( CJpegRotator::ERotModeClockwise == aRotationMode )
       
   135     {
       
   136         iRotationMode = CJpegRotator::ERotModeClockwise;
       
   137     }
       
   138     else if ( CJpegRotator::ERotMode180 == aRotationMode )
       
   139     {
       
   140         iRotationMode = CJpegRotator::ERotMode180;
       
   141     }
       
   142     else
       
   143     {
       
   144         User::Leave (KErrArgument);
       
   145     }
       
   146 
       
   147 
       
   148     // Store the source file name and set target name
       
   149     iSourceFileName = aSourceFileName;
       
   150     iTargetFileName = aTargetFileName;
       
   151     iHandleExifData = aHandleExifData;
       
   152 
       
   153     // Store the JPEG quality factor etc.
       
   154     GetSourceImagePropertiesL ( iSourceFileName );
       
   155 }
       
   156 
       
   157 //=============================================================================
       
   158 void CJpegRotatorImpl::StartAsyncRotate (TRequestStatus& aStatus, TBool aForceLossyMode)
       
   159 {
       
   160     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::StartAsyncRotate");
       
   161 
       
   162     // Use lossless rotate if possible
       
   163     if( !aForceLossyMode && IsLosslessRotatePossible() )
       
   164     {
       
   165         StartAsyncLosslessRotate (aStatus);
       
   166     }
       
   167 
       
   168     else 
       
   169     {
       
   170         aStatus = KRequestPending;
       
   171         iCallerStatus = &aStatus;
       
   172 
       
   173         iCb = TCallBack(CJpegRotatorImpl::AsyncLosslessRotate, this);
       
   174           
       
   175         iCallBack = new CAsyncCallBack (iCb, CActive::EPriorityStandard);
       
   176                 
       
   177         if (iCallBack)
       
   178         {
       
   179         	iCallBack->CallBack();        	
       
   180         }
       
   181         else
       
   182         {
       
   183         	FinishAsyncRotate (KErrNoMemory); 
       
   184         }
       
   185 
       
   186     }
       
   187     
       
   188 }
       
   189 
       
   190 //=============================================================================
       
   191 void CJpegRotatorImpl::StartAsyncLosslessRotate (TRequestStatus& aStatus)
       
   192 {
       
   193     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::StartAsyncLosslessRotate");
       
   194 
       
   195     aStatus = KRequestPending;
       
   196     iCallerStatus = &aStatus;
       
   197     
       
   198     iCb = TCallBack(CJpegRotatorImpl::AsyncLosslessRotate, this);
       
   199     // Create the callback utility used with the asynchronous version of rotate
       
   200 	iCallBack = new CAsyncCallBack (iCb, CActive::EPriorityStandard);
       
   201 	
       
   202     if (iCallBack)
       
   203     {
       
   204     	iCallBack->CallBack();        	
       
   205     }
       
   206     else
       
   207     {
       
   208     	FinishAsyncRotate (KErrNoMemory); 
       
   209     }
       
   210 
       
   211 }
       
   212 
       
   213 //=============================================================================
       
   214 TInt CJpegRotatorImpl::AsyncRotate (TAny* /*aThis*/)
       
   215 {
       
   216     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::AsyncRotate");
       
   217  /*
       
   218     // In the asynchronous version, trap the rest of the functions 
       
   219     // to make sure that the caller's TRequestStatus is always 
       
   220     // completed, also in case of failures.
       
   221     CJpegRotatorImpl* impl = static_cast<CJpegRotatorImpl*>(aThis);
       
   222 
       
   223     // Rotate-in-one-go, lossy mode
       
   224     TRAPD (err, impl->DoRotateL());
       
   225     if (err == KErrNone)
       
   226     {
       
   227         TRAP (err, impl->SaveImageL())
       
   228     }
       
   229     impl->FinishAsyncRotate (err);
       
   230 */
       
   231     return KErrNotSupported;
       
   232 }
       
   233 
       
   234 //=============================================================================
       
   235 TInt CJpegRotatorImpl::AsyncLosslessRotate (TAny* aThis)
       
   236 {
       
   237     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::AsyncLosslessRotate");
       
   238 
       
   239     // In the asynchronous version, trap the rest of the functions 
       
   240     // to make sure that the caller's TRequestStatus is always 
       
   241     // completed, also in case of failures.
       
   242     CJpegRotatorImpl* impl = static_cast<CJpegRotatorImpl*>(aThis);
       
   243 
       
   244     // Rotate-in-one-go
       
   245     TRAPD (err, impl->DoLosslessRotateL());
       
   246 
       
   247     impl->FinishAsyncRotate (err);    
       
   248 
       
   249     return KErrNone;
       
   250 }
       
   251 
       
   252 //=============================================================================
       
   253 void CJpegRotatorImpl::FinishAsyncRotate (TInt aError)
       
   254 {
       
   255     LOGFMT( KJpegRotatorLogFile, "CJpegRotatorImpl::FinishAsyncRotate (error: %d)", aError);
       
   256 
       
   257 	if( !iCancelled )
       
   258 	{
       
   259 		User::RequestComplete (iCallerStatus, aError);
       
   260 	}
       
   261 	else
       
   262 	{
       
   263 		Cleanup();
       
   264 	}
       
   265 
       
   266     PostRotate();
       
   267 }
       
   268 
       
   269 //=============================================================================
       
   270 void CJpegRotatorImpl::DoRotateL ()
       
   271 {
       
   272     User::Leave(KErrNotSupported);
       
   273 }
       
   274 
       
   275 //=============================================================================
       
   276 void CJpegRotatorImpl::DoLosslessRotateL ()
       
   277 {
       
   278     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::DoLosslessRotateL");
       
   279 
       
   280     iLosslessMode = ETrue;
       
   281 
       
   282 #if defined (LOG_TIMING)
       
   283     iSavingStartTime.UniversalTime();
       
   284 #endif
       
   285 
       
   286 	//	Load JPEG file to source file buffer
       
   287 
       
   288 	RFile srcfile;
       
   289 	CleanupClosePushL (srcfile);
       
   290 	User::LeaveIfError ( srcfile.Open (iFsSession, iSourceFileName, EFileRead) );
       
   291 
       
   292 	TInt sourcebufsize;
       
   293 	User::LeaveIfError ( srcfile.Size(sourcebufsize) );
       
   294 	TInt targetbufsize = (TInt)(1.2 * sourcebufsize);
       
   295 
       
   296     TInt saveBufferSize = KDefaultSaveBuffer;
       
   297     if (targetbufsize < saveBufferSize)
       
   298     {
       
   299         saveBufferSize = targetbufsize;
       
   300     }
       
   301     
       
   302     CleanupStack::PopAndDestroy();
       
   303 
       
   304 	RFile trgfile;
       
   305 	User::LeaveIfError ( trgfile.Replace (iFsSession, iTargetFileName, EFileRead) );
       
   306     CleanupClosePushL (trgfile);
       
   307   	
       
   308     CJpRotate* rotator = CJpRotate::NewLC(iFsSession, &trgfile, saveBufferSize);
       
   309 
       
   310 	rotator->SetCallBack( this );
       
   311 
       
   312     switch ( iRotationMode )
       
   313     {
       
   314         case CJpegRotator::ERotModeCounterClockwise:
       
   315         {
       
   316             rotator->RotateL( iSourceFileName, true, false, false );
       
   317             break;
       
   318         }
       
   319         case CJpegRotator::ERotMode180:
       
   320         {
       
   321             rotator->RotateL( iSourceFileName, false, true, true );
       
   322             break;
       
   323         }
       
   324         case CJpegRotator::ERotModeClockwise:
       
   325         default:
       
   326         {
       
   327             rotator->RotateL( iSourceFileName, true, true, true );
       
   328             break;
       
   329         }
       
   330        
       
   331     }
       
   332 
       
   333     CleanupStack::PopAndDestroy(2);
       
   334 
       
   335     LOG( KJpegRotatorLogFile, "\t...DoLosslessRotateL: Done.");
       
   336 
       
   337 }
       
   338 
       
   339 //=============================================================================
       
   340 void CJpegRotatorImpl::JpRotateStatus( TInt /*aCount*/, TInt /*aTotal*/ )
       
   341 {
       
   342 //    LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::JpRotateStatus" );
       
   343 //    LOGFMT( KJpegRotatorLogFile, "   count: %d", aCount );
       
   344 //    LOGFMT( KJpegRotatorLogFile, "   total: %d", aTotal );   
       
   345 }
       
   346 
       
   347 
       
   348 //=============================================================================
       
   349 CJpegRotatorImpl::CJpegRotatorImpl (RFs& aFsSession) : 
       
   350 iFsSession (aFsSession),
       
   351 iRotator (NULL), 
       
   352 iHandleExifData (ETrue)
       
   353 {
       
   354 }
       
   355 
       
   356 //=============================================================================
       
   357 void CJpegRotatorImpl::ConstructL ()
       
   358 {
       
   359     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::ConstructL");
       
   360 
       
   361 
       
   362 }
       
   363 
       
   364 //=============================================================================
       
   365 void CJpegRotatorImpl::GetSourceImagePropertiesL ( const TDesC& /*aFileName*/ )
       
   366 {
       
   367     /*
       
   368     //	Create a new image decoder
       
   369     CImageDecoder * decoder = CImageDecoder::FileNewL (iFsSession, aFileName);
       
   370     CleanupStack::PushL( decoder );
       
   371 
       
   372     //  Get reference to frame image data
       
   373     const CFrameImageData & imageData = decoder->FrameData();
       
   374 
       
   375     //  Get JPEG quality factor
       
   376     iOriginalJpegQualityFactor = KDefaultSavedJpegQuality;
       
   377     if ( imageData.ImageDataCount() > 0 )
       
   378     {
       
   379         iOriginalJpegQualityFactor = ((const TJpegImageData*)imageData.GetImageData(0))->iQualityFactor;
       
   380     }
       
   381 
       
   382     //  Image resolution
       
   383     const TFrameInfo& frameInfo = decoder->FrameInfo();
       
   384     iSourceImageSize = frameInfo.iOverallSizeInPixels;
       
   385 
       
   386     CleanupStack::PopAndDestroy( decoder );
       
   387     */
       
   388 }
       
   389 
       
   390 //=============================================================================
       
   391 void CJpegRotatorImpl::SetJpegCommentL (const TDesC8& /*aComment*/)
       
   392 {
       
   393     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::SetJpegCommentL");
       
   394 
       
   395 }
       
   396 
       
   397 //=============================================================================
       
   398 void CJpegRotatorImpl::SetExifData (TUint8* /*aExifData*/, TUint /*aDataSize*/)
       
   399 {
       
   400     LOG( KJpegRotatorLogFile, "CJpegRotatorImpl::SetExifData");
       
   401 
       
   402 }
       
   403 
       
   404 //=============================================================================
       
   405 void CJpegRotatorImpl::PostRotate ()
       
   406 {
       
   407 #if defined (LOG_TIMING)
       
   408 /*
       
   409     iFinishTime.UniversalTime();
       
   410 
       
   411     TInt64 prepareTime = iSavingStartTime.Int64() - iStartTime.Int64();
       
   412     TInt64 savingTime = iFinishTime.Int64() - iSavingStartTime.Int64();
       
   413     TInt64 totalTime = iFinishTime.Int64() - iStartTime.Int64();
       
   414 
       
   415     TBuf<128> text1;
       
   416     if (iLosslessMode)
       
   417     {
       
   418         text1 = _L("Rotating from %S to %S. Lossless rotate was used.");
       
   419     }
       
   420     else
       
   421     {
       
   422         text1 = _L("Rotating from %S to %S. Lossy rotate was used.");
       
   423     }
       
   424 
       
   425 	RFileLogger::WriteFormat( 
       
   426         KImageEditorLogDir,
       
   427         KJpegRotatorTimingLogFile,
       
   428         EFileLoggingModeAppend,
       
   429         text1, &iSourceFileName, &iTargetFileName 
       
   430         );
       
   431 
       
   432     RFileLogger::WriteFormat( 
       
   433         KImageEditorLogDir,
       
   434         KJpegRotatorTimingLogFile,
       
   435         EFileLoggingModeAppend,
       
   436         _L("\tTime taken (microseconds): %d"),
       
   437         totalTime );
       
   438 
       
   439 	RFileLogger::WriteFormat( 
       
   440         KImageEditorLogDir,
       
   441         KJpegRotatorTimingLogFile,
       
   442         EFileLoggingModeAppend,
       
   443         _L( "\tprepare phase: %d"),
       
   444         prepareTime );
       
   445 
       
   446 	RFileLogger::WriteFormat( 
       
   447         KImageEditorLogDir,
       
   448         KJpegRotatorTimingLogFile,
       
   449         EFileLoggingModeAppend,
       
   450         _L( "\tsave phase: %d"),
       
   451         savingTime );
       
   452 */
       
   453 #endif
       
   454 }
       
   455 
       
   456 //=============================================================================
       
   457 TBool CJpegRotatorImpl::IsLosslessRotatePossible() const
       
   458 {
       
   459     return ETrue;
       
   460 }
       
   461 
       
   462 
       
   463 // End of File