camerauis/cameraapp/generic/src/cameracontroller/camimagedecoder.cpp
changeset 19 d9aefe59d544
parent 3 8b2d6d0384b0
child 21 fa6d9f75d6a6
child 28 3075d9b614e6
equal deleted inserted replaced
3:8b2d6d0384b0 19:d9aefe59d544
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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 *
       
    14 * Description:  Implementation of Camera image decoder
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include <imageconversion.h>
       
    22 #include <ExifRead.h>
       
    23 #include <ecam.h> // MCameraBuffer
       
    24 
       
    25 #include <eikenv.h>
       
    26 
       
    27 #include "camlogging.h"
       
    28 #include "camfilesaveutility.h"
       
    29 #include "cambuffershare.h"
       
    30 
       
    31 #include "camimagedecoder.h"
       
    32 
       
    33 // ===========================================================================
       
    34 // Local constants
       
    35 
       
    36 namespace NCamCameraController
       
    37   {
       
    38   // Decoding flags
       
    39   static const TUint32 KConversionOptions = 
       
    40     ( CImageDecoder::EOptionNone
       
    41     | CImageDecoder::EOptionAlwaysThread
       
    42     | CImageDecoder::EPreferFastDecode
       
    43     );
       
    44   
       
    45   // EXIF reader flags
       
    46   //   Only need the thumbnail, so no need to parse the
       
    47   //   main (jpeg) image.
       
    48   static const TUint KExifReaderFlags = CExifRead::ENoJpeg;
       
    49   
       
    50   // Other constants
       
    51   static const TInt KMaxRetries = 10;
       
    52   static const TInt KPriority = CActive::EPriorityHigh;
       
    53   }
       
    54 
       
    55 using namespace NCamCameraController;
       
    56 
       
    57 // ===========================================================================
       
    58 // public constructor and destructor
       
    59 
       
    60 CCamImageDecoder* 
       
    61 CCamImageDecoder::NewL( MCamImageDecoderObserver& aObserver )
       
    62   {
       
    63   CCamImageDecoder* self = 
       
    64       new (ELeave) CCamImageDecoder( aObserver );
       
    65 
       
    66   CleanupStack::PushL( self );
       
    67   self->ConstructL();
       
    68   CleanupStack::Pop( self );
       
    69 
       
    70   return self;  
       
    71   }
       
    72 
       
    73 
       
    74 CCamImageDecoder::~CCamImageDecoder()
       
    75   {
       
    76   PRINT( _L("Camera => ~CCamImageDecoder") );
       
    77   Cancel();
       
    78 
       
    79   delete iDecoder;
       
    80 
       
    81   SetImageData( NULL );
       
    82  if(iDecodedBitmap)
       
    83   	{
       
    84   	delete iDecodedBitmap;
       
    85   	iDecodedBitmap = NULL;
       
    86   	}
       
    87   iFs.Close();
       
    88   PRINT( _L("Camera <= ~CCamImageDecoder") );
       
    89   }
       
    90 
       
    91 // ===========================================================================
       
    92 // public methods
       
    93 void
       
    94 CCamImageDecoder::StartConversionL( CCamBufferShare* aBuffer )
       
    95   {
       
    96   PRINT( _L("Camera => CCamImageDecoder::StartConversionL") );
       
    97 
       
    98   // Data for CImageDecoder must be available throughout the conversion.
       
    99   // Need to stop any outstanding operation before deleting the descriptor.
       
   100   Cancel();
       
   101 
       
   102   PRINT( _L("Camera <> CCamImageDecoder: Copying image data..") );
       
   103   
       
   104   SetImageData( aBuffer );
       
   105 
       
   106   // GetImageDataL leaves if no data available.
       
   107   TDesC8* imageData = GetImageDataL();
       
   108 
       
   109   PRINT( _L("Camera <> CCamImageDecoder: Creating decoder..") );
       
   110 
       
   111   delete iDecoder;
       
   112   iDecoder = NULL;
       
   113   iDecoder = CImageDecoder::DataNewL( iFs, *imageData, (CImageDecoder::TOptions)KConversionOptions );
       
   114 
       
   115   if( iDecoder->FrameCount() > 0 )
       
   116     {
       
   117     const TFrameInfo& info( iDecoder->FrameInfo() );
       
   118     
       
   119 #ifdef _DEBUG   
       
   120     TSize size = info.iOverallSizeInPixels;
       
   121     PRINT2( _L("Camera <> CCamImageDecoder: Bmp size(%d,%d)"), size.iWidth, size.iHeight );
       
   122     PRINT1( _L("Camera <> CCamImageDecoder: Bmp dispmode(%d)"), info.iFrameDisplayMode );
       
   123 #endif
       
   124 
       
   125     PRINT( _L("Camera <> CCamImageDecoder: Create bitmap for snapshot..") );
       
   126     if( !iDecodedBitmap ) iDecodedBitmap = new (ELeave) CFbsBitmap;
       
   127     else                  iDecodedBitmap->Reset();
       
   128     
       
   129     TInt createError = iDecodedBitmap->Create( info.iOverallSizeInPixels, 
       
   130                                                info.iFrameDisplayMode );
       
   131     if( KErrNone != createError )
       
   132       {
       
   133       delete iDecodedBitmap;
       
   134       iDecodedBitmap = NULL;
       
   135       User::Leave( createError );
       
   136       }
       
   137 
       
   138     PRINT( _L("Camera <> CCamImageDecoder: start conversion..") );
       
   139     iRetryCounter = 0;
       
   140     iDecoder->Convert( &iStatus, *iDecodedBitmap, 0 );
       
   141     SetActive();
       
   142     }
       
   143   else
       
   144     {
       
   145     PRINT( _L("Camera <> CCamImageDecoder: No frame provided, leave..") );
       
   146     User::Leave( KErrNotFound );    
       
   147     }
       
   148 
       
   149   PRINT( _L("Camera <= CCamImageDecoder::StartConversionL") );
       
   150   }
       
   151 
       
   152 
       
   153 // ---------------------------------------------------------------------------
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 TDesC8*
       
   157 CCamImageDecoder::GetImageDataL()
       
   158   {
       
   159   PRINT( _L("Camera => CCamImageDecoder::GetImageDataL") );
       
   160   
       
   161   if( !iSharedImageData ||
       
   162       !iSharedImageData->SharedBuffer() )
       
   163     {
       
   164     User::Leave( KErrNotFound );
       
   165     }
       
   166 
       
   167   TDesC8* data = iSharedImageData->SharedBuffer()->DataL( 0 );
       
   168 
       
   169   if( !data )
       
   170     User::Leave( KErrNotFound );
       
   171 
       
   172   delete iThumbnailData;
       
   173   iThumbnailData = ReadExifThumbNail( *data ); // Returns NULL on errors
       
   174 
       
   175 #ifdef CAMERAAPP_CREATE_TESTIMAGE
       
   176   TRAPD( saveStatus1, SaveImageDataToFileL( *data, _L("testimagefull.jpg") ) );
       
   177   PRINT1( _L("Camera <> CCamImageDecoder: Save full image to file status:%d"), saveStatus1 );
       
   178   if( iThumbnailData )
       
   179     {
       
   180     TRAPD( saveStatus2, SaveImageDataToFileL( *iThumbnailData, _L("testimagethumb.jpg") ) );
       
   181     PRINT1( _L("Camera <> CCamImageDecoder: Save thumbnail to file status:%d"), saveStatus2 );
       
   182     }
       
   183 #endif
       
   184 
       
   185 
       
   186   if( iThumbnailData )
       
   187     {
       
   188     data = iThumbnailData;
       
   189     }  
       
   190 
       
   191   PRINT1( _L("Camera <= CCamImageDecoder::GetImageDataL, data size:%d"), data->Size() );
       
   192   return data;
       
   193   }
       
   194 
       
   195 // ---------------------------------------------------------------------------
       
   196 // ---------------------------------------------------------------------------
       
   197 //
       
   198 HBufC8*
       
   199 CCamImageDecoder::ReadExifThumbNail( const TDesC8& aExifData )
       
   200   {
       
   201   PRINT( _L("Camera => CCamImageDecoder::ReadExifThumbNailL") );
       
   202   HBufC8* thumb = NULL;
       
   203   TRAP_IGNORE( 
       
   204     {
       
   205     CExifRead* reader = CExifRead::NewL( aExifData, KExifReaderFlags );
       
   206     CleanupStack::PushL( reader );
       
   207     thumb = reader->GetThumbnailL();
       
   208     CleanupStack::PopAndDestroy( reader );
       
   209     });
       
   210 
       
   211   PRINT( _L("Camera <= CCamImageDecoder::ReadExifThumbNailL") );
       
   212   return thumb;
       
   213   }
       
   214 
       
   215 // ===========================================================================
       
   216 // from CActive
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // virtual 
       
   220 // ---------------------------------------------------------------------------
       
   221 //
       
   222 void 
       
   223 CCamImageDecoder::DoCancel()
       
   224   {
       
   225   PRINT( _L("Camera => CCamImageDecoder::DoCancel") );
       
   226 
       
   227   if( iDecoder )
       
   228     {
       
   229     iDecoder->Cancel();
       
   230     delete iDecoder;
       
   231     iDecoder = NULL;    
       
   232     }
       
   233 
       
   234   SetImageData( NULL );
       
   235 
       
   236   PRINT( _L("Camera <= CCamImageDecoder::DoCancel") );
       
   237   }
       
   238 
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // virtual 
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 void 
       
   245 CCamImageDecoder::RunL()
       
   246   {
       
   247   PRINT1( _L("Camera => CCamImageDecoder::RunL, iStatus:%d"), iStatus.Int() );
       
   248 
       
   249   switch( iStatus.Int() )
       
   250     {
       
   251     case KErrNone :
       
   252       {
       
   253       // CImageDecoder has finished using the data,
       
   254       // so we are able to free it.
       
   255       SetImageData( NULL );
       
   256       iObserver.ImageDecoded( iStatus.Int(), iDecodedBitmap );
       
   257       break;
       
   258       }
       
   259     case KErrUnderflow :
       
   260       {
       
   261       // Decoder did not have enough data to convert.
       
   262       // CImageDecoder documentation recommends calling
       
   263       // repeatedly ContinueConvert.
       
   264       if( iRetryCounter++ < KMaxRetries )
       
   265         {
       
   266         iStatus = KErrNone;
       
   267         iDecoder->ContinueConvert( &iStatus );
       
   268         SetActive();
       
   269         }
       
   270       else
       
   271         {
       
   272         // Handled in RunError
       
   273         User::Leave( KErrUnderflow );
       
   274         }
       
   275       break;
       
   276       }
       
   277     case KErrCancel :
       
   278     default :
       
   279       {
       
   280       User::Leave( iStatus.Int() );
       
   281       break;
       
   282       }
       
   283     }
       
   284 
       
   285   PRINT( _L("Camera <= CCamImageDecoder::RunL") );
       
   286   }
       
   287 
       
   288 
       
   289 // ---------------------------------------------------------------------------
       
   290 // virtual 
       
   291 // ---------------------------------------------------------------------------
       
   292 //
       
   293 TInt 
       
   294 CCamImageDecoder::RunError( TInt aError )
       
   295   {
       
   296   PRINT1( _L("Camera => CCamImageDecoder::RunError(%d)"), aError );
       
   297 
       
   298   SetImageData( NULL );
       
   299   // Leave has occurred in RunL.
       
   300   // Notify observer with error.
       
   301   iObserver.ImageDecoded( aError, NULL );
       
   302 
       
   303   PRINT( _L("Camera <= CCamImageDecoder::RunError") );
       
   304   return KErrNone;
       
   305   }
       
   306 
       
   307 
       
   308 // ===========================================================================
       
   309 void
       
   310 CCamImageDecoder::SetImageData( CCamBufferShare* aBuffer )
       
   311   {
       
   312   if( iSharedImageData )
       
   313     {
       
   314     iSharedImageData->Release();
       
   315     iSharedImageData = NULL;
       
   316     }
       
   317 
       
   318   iSharedImageData = aBuffer;
       
   319 
       
   320   if( iSharedImageData )
       
   321     iSharedImageData->Reserve();
       
   322   }
       
   323 
       
   324 // ===========================================================================
       
   325 // private constructors
       
   326 
       
   327 
       
   328 void
       
   329 CCamImageDecoder::ConstructL()
       
   330   {
       
   331   User::LeaveIfError( iFs.Connect() );
       
   332 
       
   333   CActiveScheduler::Add( this );
       
   334   }
       
   335 
       
   336 
       
   337 
       
   338 CCamImageDecoder::CCamImageDecoder( MCamImageDecoderObserver& aObserver )
       
   339   : CActive( KPriority  ),
       
   340     iObserver( aObserver )
       
   341   {
       
   342   }
       
   343 
       
   344 // end of file