examples/ForumNokia/ImageConverter/src/Imageconverterengine.cpp

00001 /*
00002  * Copyright � 2008 Nokia Corporation.
00003  */
00004 
00005 #include "ImageConverterEngine.h"
00006 
00007 #include <fbs.h>
00008 #include <ImageConversion.h>
00009 #include <BitmapTransforms.h>
00010 
00011 #include <eikdef.h>
00012 #include <eikenv.h>
00013 
00014 const TInt KMaxInfoMsgLength = 50;
00015 const TInt KFixImageHeight = 70;
00016 const TInt KFixImageWidth = 10;
00017 
00018 CImageConverterEngine* CImageConverterEngine::NewL( 
00019     MConverterController* aController )
00020     {
00021     CImageConverterEngine* self = 
00022         new(ELeave) CImageConverterEngine( aController );
00023     CleanupStack::PushL( self );
00024     
00025     self->ConstructL();
00026 
00027     CleanupStack::Pop(self);
00028     return self; 
00029     }
00030 
00031 CImageConverterEngine::CImageConverterEngine( 
00032     MConverterController* aController ) : 
00033     CActive( EPriorityStandard ), iController( aController )
00034     {
00035     }
00036 
00037 void CImageConverterEngine::ConstructL()
00038     {
00039     User::LeaveIfError( iFs.Connect() );
00040     iRotator = CBitmapRotator::NewL();
00041     iScaler = CBitmapScaler::NewL();
00042     //iGlobalNote = CAknGlobalNote::NewL();
00043     iState = EIdle;
00044     CActiveScheduler::Add( this );
00045     }
00046 
00047 CImageConverterEngine::~CImageConverterEngine()
00048     {
00049     Cancel();
00050     delete iImageEncoder; 
00051     delete iImageDecoder; // CImageDecoder must be deleted before the 
00052     iFs.Close();          //   related RFs is closed, 
00053     delete iBitmap;       //   otherwise a related thread might panic   
00054     delete iRotator;
00055     delete iScaler;
00056     //delete iGlobalNote;
00057     }
00058 
00059 void CImageConverterEngine::StartToDecodeL( TFileName& aFileName )
00060     {
00061     if (IsActive())
00062         {
00063         return;
00064         }
00065 
00066     delete iImageDecoder; iImageDecoder = NULL;
00067     delete iBitmap; iBitmap = NULL;
00068 
00069     iFilename.Copy(aFileName);
00070     
00071     // create the decoder
00072     iImageDecoder = CImageDecoder::FileNewL( iFs, aFileName );
00073     
00074     // create the destination bitmap
00075     iBitmap = new (ELeave) CFbsBitmap();
00076     iBitmap->Create( iImageDecoder->FrameInfo().iOverallSizeInPixels,
00077                      iImageDecoder->FrameInfo().iFrameDisplayMode ); 
00078 
00079     // start conversion to bitmap
00080     iState = EDecoding;
00081     iImageDecoder->Convert( &iStatus, *iBitmap );
00082     SetActive();
00083     }
00084 
00085 void CImageConverterEngine::StartToEncodeL( 
00086     TFileName& aFileName, TUid aImageType, TUid aImageSubType )
00087     {
00088     if (!iBitmap)
00089         {
00090         return;
00091         }
00092     
00093     if (iImageEncoder)
00094         {
00095         delete iImageEncoder; 
00096         iImageEncoder = NULL;
00097         }
00098 
00099     // create the encoder
00100     iImageEncoder = CImageEncoder::FileNewL( iFs, aFileName, 
00101         CImageEncoder::EOptionNone, aImageType, aImageSubType );
00102 
00103     iState = EEncoding;
00104     iImageEncoder->Convert( &iStatus, *iBitmap );
00105     SetActive();
00106     
00107     ShowProgress();
00108     }
00109 
00110 void CImageConverterEngine::DoCancel()
00111     {
00112     CancelProgress();
00113     
00114     if( iState == EDecoding )
00115         {
00116         iImageDecoder->Cancel();
00117         }
00118     else if( iState == EEncoding )
00119         {
00120         iImageEncoder->Cancel();
00121         }
00122     else if( iState == ERotating )
00123         {
00124         iRotator->Cancel();
00125         }
00126     else if( iState == EScaling )
00127         {
00128         iScaler->Cancel();
00129         }
00130     else
00131         {
00132         // State is EIdle, do nothing
00133         }
00134     }
00135     
00136 
00137 void CImageConverterEngine::RunL()
00138     {
00139     CancelProgress();
00140 
00141     switch( iState ) 
00142         {
00143         case EDecoding:
00144             {
00145             iScaleDownCounter = 0;
00146             if( iStatus == KErrNone ) 
00147                 {
00148                 if (FitToScreen())
00149                     {
00150                     iState = EIdle;
00151                     _LIT(KImageReady, "Image ready");
00152                     iController->NotifyCompletion( KErrNone, KImageReady );
00153                     }
00154                 else
00155                     {
00156                     _LIT(KImageReady, "Image not ready");
00157                     iController->NotifyCompletion( KErrNotReady, KImageReady );
00158                     DoFitToScreen();
00159                     }
00160                 break;
00161                 }
00162             else if( iStatus == KErrUnderflow ) 
00163                 {
00164                 ShowProgress();
00165                 iImageDecoder->ContinueConvert( &iStatus );
00166                 SetActive();
00167                 break;
00168                 }
00169             else if ( iStatus == KErrCorrupt )
00170                 {
00171                 iState = EIdle;
00172                 _LIT(KImageCorrupt, "Image file corrupted");
00173                 iController->NotifyCompletion( KErrCorrupt, KImageCorrupt );
00174                 break;
00175                 }
00176             else
00177                 {
00178                 // Unknown error
00179                 iState = EIdle;
00180                 _LIT( KErrorMsg, "Error while opening image:%d" );
00181                 TBuf<KMaxInfoMsgLength> buf;
00182                 buf.Format( KErrorMsg, iStatus.Int() );
00183                 iController->NotifyCompletion( iStatus.Int(), KErrorMsg );
00184                 break;
00185                 }
00186             }
00187         case EEncoding:
00188             {
00189             _LIT(KImageSaved, "Image saved");
00190             iState = EIdle;
00191             iController->NotifyCompletion( iStatus.Int(), KImageSaved);
00192             break;
00193             }
00194         case EScaling:
00195             {
00196             iState = EIdle;
00197             iController->NotifyCompletion( iStatus.Int(), KNullDesC );
00198             break;
00199             }
00200         default:
00201         case ERotating:
00202             {
00203             iState = EIdle;
00204             iController->NotifyCompletion( iStatus.Int(), KNullDesC );
00205             break;
00206             }
00207         }   
00208     }
00209 
00210 TInt CImageConverterEngine::RunError(TInt /*aError*/)   
00211     {
00212     CancelProgress();
00213     // Our RunL does not contain any method calls that would leave, so this method
00214     // should never be called.
00215     return KErrNone;
00216     }
00217 
00218 void CImageConverterEngine::GetEncoderImageTypesL( 
00219     RImageTypeDescriptionArray& aImageTypeArray )
00220     {
00221     CImageEncoder::GetImageTypesL( aImageTypeArray );
00222     }
00223 
00224 CFrameInfoStrings* CImageConverterEngine::GetImageInfoL()
00225     {
00226     // notice that the information is returned from the original image
00227     //  hence the scaling of the bitmap does not affect the info until
00228     //  the bitmap is encoded back to image file and opened again
00229     if( iImageDecoder )
00230         {
00231         return( iImageDecoder->FrameInfoStringsL() );
00232         }
00233     else
00234         {
00235         return NULL ;
00236         }
00237     }
00238 
00239 void CImageConverterEngine::Rotate( TDirection aDirection )
00240     {
00241     if (iState != EIdle || !iBitmap)
00242         {
00243         // Do nothing, if we are in the middle of processing a previous command
00244         return;
00245         }
00246         
00247     if( aDirection == EClockwise90 ) 
00248         {
00249         iRotator->Rotate( &iStatus, *iBitmap, 
00250             CBitmapRotator::ERotation90DegreesClockwise );  
00251         }
00252     else 
00253         { 
00254         // 270 clockwise == 90 anticlockwise
00255         iRotator->Rotate( &iStatus, *iBitmap, 
00256             CBitmapRotator::ERotation270DegreesClockwise ); 
00257         }
00258 
00259     iState = ERotating;
00260     SetActive();
00261     
00262     ShowProgress();
00263     }
00264 
00265 TBool CImageConverterEngine::FitToScreen()
00266     {
00267     TBool ret = ETrue;
00268     TPixelsTwipsAndRotation sizeAndRotation;
00269     CEikonEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation(sizeAndRotation);
00270     if (iBitmap->SizeInPixels().iHeight > sizeAndRotation.iPixelSize.iHeight-KFixImageHeight || 
00271         iBitmap->SizeInPixels().iWidth > sizeAndRotation.iPixelSize.iWidth-KFixImageWidth)
00272         {
00273         ret = EFalse;
00274         }
00275     return ret;
00276     }
00277 
00278 void CImageConverterEngine::DoFitToScreen()
00279     {
00280     TPixelsTwipsAndRotation sizeAndRotation;
00281     CEikonEnv::Static()->ScreenDevice()->GetDefaultScreenSizeAndRotation(sizeAndRotation);
00282 
00283     TInt newWidth = (sizeAndRotation.iPixelSize.iWidth-KFixImageWidth);
00284     TInt newHeight = (sizeAndRotation.iPixelSize.iHeight-KFixImageHeight);
00285         
00286     // the maintain aspect ratio is by default set to true
00287     iScaler->Scale( &iStatus, *iBitmap, TSize(newWidth,newHeight) );
00288 
00289     iState = EScaling;
00290     SetActive();
00291     }
00292 
00293 TBool CImageConverterEngine::CanDownScaleMore()
00294     {
00295     if (iScaleDownCounter > 2)
00296         {
00297         return EFalse;
00298         }
00299     else
00300         {
00301         return ETrue;
00302         }
00303     }
00304 
00305 TInt CImageConverterEngine::Scale( TInt aPercent )
00306     {
00307     if (iState != EIdle || !iBitmap)
00308         {
00309         // Do nothing, if we are in the middle of processing a previous command         
00310         return KErrNotReady;
00311         }
00312 
00313     // Scaling down
00314     if (aPercent > 100)
00315         {
00316         if (!CanDownScaleMore())
00317             {
00318             return KErrCancel;
00319             }
00320         iScaleDownCounter++;
00321 
00322         TReal32 multiplier; 
00323     
00324         multiplier = aPercent/(TReal32)100.0;
00325     
00326         TInt newWidth = (TInt)(iBitmap->SizeInPixels().iWidth * multiplier);
00327         TInt newHeight = (TInt)(iBitmap->SizeInPixels().iHeight * multiplier);
00328             
00329         // the maintain aspect ratio is by default set to true
00330         iScaler->Scale( &iStatus, *iBitmap, TSize(newWidth,newHeight) );
00331 
00332         iState = EScaling;
00333         SetActive();
00334         ShowProgress();
00335         }
00336     // Scaling up gives original picture
00337     else
00338         {
00339         TRAPD(err,
00340                 StartToDecodeL(iFilename));
00341         if (err)
00342             {
00343             return err;
00344             }
00345         }
00346 
00347     return KErrNone;
00348     }
00349     
00350 CFbsBitmap* CImageConverterEngine::GetBitmap()
00351     {
00352     if (iState != EIdle)
00353         return NULL;
00354     else
00355         return iBitmap;
00356     }
00357 
00358 void CImageConverterEngine::ShowProgress()
00359     {
00360     //TRAPD(err,
00361     //    iNoteId = iGlobalNote->ShowNoteL(EAknGlobalWaitNote,_L("Working..."));
00362     //    );
00363     }
00364 
00365 void CImageConverterEngine::CancelProgress()
00366     {
00367     //TRAPD(err,
00368     //    iGlobalNote->CancelNoteL(iNoteId);
00369     //    );
00370     }
00371 
00372 
00373 

Generated by  doxygen 1.6.2