imagehandlingutilities/thumbnailmanager/plugins/image/src/thumbnailimagedecoder.cpp
changeset 54 48dd0f169f0d
parent 42 2e2a89493e2b
equal deleted inserted replaced
42:2e2a89493e2b 54:48dd0f169f0d
     1 /*
       
     2 * Copyright (c) 2006-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:  Image thumbnail decoder
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //INCLUDE FILES
       
    21 #include <e32base.h>
       
    22 #include <imageconversion.h>
       
    23 #include <ExifRead.h>
       
    24 #include <e32math.h>
       
    25 
       
    26 #include <IclExtJpegApi.h>
       
    27 #include "thumbnailimagedecoder.h"
       
    28 #include "thumbnaillog.h"
       
    29 #include "thumbnailpanic.h"
       
    30 #include "OstTraceDefinitions.h"
       
    31 #ifdef OST_TRACE_COMPILER_IN_USE
       
    32 #include "thumbnailimagedecoderTraces.h"
       
    33 #endif
       
    34 
       
    35 
       
    36 const TUid KImageTypeSVGUid = 
       
    37     {
       
    38     0x102073E7
       
    39 };
       
    40 
       
    41 // CImageDecoder supports up to 1/8 size reduction if EFullyScaleable is
       
    42 // not set.
       
    43 const TInt KMaximumReductionFactor = 8;
       
    44 
       
    45 // Matchers for recognizing JPEG files
       
    46 _LIT( KJpegMime, "image/jpeg" );
       
    47 
       
    48 // Matcher for recognizing SVG files
       
    49 _LIT( KSvgMime, "image/svg+xml" );
       
    50 
       
    51 
       
    52 
       
    53 // ============================ MEMBER FUNCTIONS ===============================
       
    54 
       
    55 // ---------------------------------------------------------------------------
       
    56 // CThumbnailImageDecoder::CThumbnailImageDecoder()
       
    57 // C++ default constructor can NOT contain any code, that might leave.
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 CThumbnailImageDecoder::CThumbnailImageDecoder( RFs& aFs ): 
       
    61     CActive(EPriorityStandard ), iBitmap( NULL ), iJpegReadBuffer( NULL ),  
       
    62     iExifThumbImage( NULL ), iFs( aFs ), iBuffer( NULL )
       
    63     {
       
    64     CActiveScheduler::Add( this );
       
    65     }
       
    66 
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // CThumbnailImageDecoder::~CThumbnailImageDecoder()
       
    70 // Destructor.
       
    71 // ---------------------------------------------------------------------------
       
    72 //
       
    73 CThumbnailImageDecoder::~CThumbnailImageDecoder()
       
    74     {
       
    75     Release();
       
    76     }
       
    77 
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // CThumbnailImageDecoder::CreateL()
       
    81 // Creates thumbnail of image
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 void CThumbnailImageDecoder::CreateL( RFile64& aFile, MThumbnailProviderObserver&
       
    85     aObserver, const CThumbnailManager::TThumbnailQualityPreference aQualityPreference, const
       
    86     TDataType& aMimeType, const TSize& aSize)
       
    87     {
       
    88     TN_DEBUG1( "CThumbnailImageDecoder::CreateL() start" );
       
    89     OstTrace0( TRACE_NORMAL, CTHUMBNAILIMAGEDECODER_CREATEL, "CThumbnailImageDecoder::CreateL - start" );
       
    90 
       
    91     iBuffer = NULL;
       
    92     iSize = aSize;
       
    93     iMimeType = aMimeType;
       
    94     iObserver = &aObserver;
       
    95     iFile = aFile;
       
    96 
       
    97     CreateDecoderL( aQualityPreference );
       
    98 
       
    99     const TFrameInfo info( iDecoder->FrameInfo());
       
   100     if (( info.iOverallSizeInPixels.iWidth < 1 ) || (
       
   101         info.iOverallSizeInPixels.iHeight < 1 ))
       
   102         {
       
   103         User::Leave( KErrCorrupt );
       
   104         }
       
   105     iFrameInfoFlags = info.iFlags;
       
   106     iOriginalSize = info.iOverallSizeInPixels;
       
   107     
       
   108     TN_DEBUG1( "CThumbnailImageDecoder::CreateL() end" );
       
   109     OstTrace0( TRACE_NORMAL, DUP1_CTHUMBNAILIMAGEDECODER_CREATEL, "CThumbnailImageDecoder::CreateL - end" );
       
   110     }
       
   111 
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CThumbnailImageDecoder::CreateL()
       
   115 // Creates thumbnail of image
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 void CThumbnailImageDecoder::CreateL( const TDesC8* aBuffer, MThumbnailProviderObserver&
       
   119     aObserver, const CThumbnailManager::TThumbnailQualityPreference aQualityPreference, const
       
   120     TDataType& aMimeType, const TSize& aSize)
       
   121     {
       
   122     TN_DEBUG1( "CThumbnailImageDecoder::CreateL() start" );
       
   123     OstTrace0( TRACE_NORMAL, DUP2_CTHUMBNAILIMAGEDECODER_CREATEL, "CThumbnailImageDecoder::CreateL - start" );
       
   124 
       
   125     iSize = aSize;
       
   126     iMimeType = aMimeType;
       
   127     iObserver = &aObserver;
       
   128     iBuffer = aBuffer;
       
   129     
       
   130     CreateDecoderL( aQualityPreference );
       
   131 
       
   132     const TFrameInfo info( iDecoder->FrameInfo());
       
   133     if (( info.iOverallSizeInPixels.iWidth < 1 ) || (
       
   134         info.iOverallSizeInPixels.iHeight < 1 ))
       
   135         {
       
   136         User::Leave( KErrCorrupt );
       
   137         }
       
   138     iFrameInfoFlags = info.iFlags;
       
   139     iOriginalSize = info.iOverallSizeInPixels;
       
   140     
       
   141     TN_DEBUG1( "CThumbnailImageDecoder::CreateL() end" );
       
   142     OstTrace0( TRACE_NORMAL, DUP3_CTHUMBNAILIMAGEDECODER_CREATEL, "CThumbnailImageDecoder::CreateL - end" );
       
   143     }
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CThumbnailImageDecoder::DecodeL()
       
   147 // Decode the thumbnail image
       
   148 // -----------------------------------------------------------------------------
       
   149 //
       
   150 void CThumbnailImageDecoder::DecodeL( const TDisplayMode aDisplayMode, const CThumbnailManager::TThumbnailFlags aFlags)
       
   151     {
       
   152     TN_DEBUG1( "CThumbnailImageDecoder::DecodeL() start" );
       
   153     OstTrace0( TRACE_NORMAL, CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL - start" );
       
   154     
       
   155     // Create the bitmap
       
   156     if ( !iBitmap )
       
   157         {
       
   158         iBitmap = new( ELeave )CFbsBitmap();
       
   159         }
       
   160     
       
   161     TN_DEBUG3( "CThumbnailImageDecoder::DecodeL() %d x %d", iSize.iWidth, iSize.iHeight );
       
   162     OstTraceExt2( TRACE_NORMAL, DUP1_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL;iSize.iWidth=%d;iSize.iHeight=%d", iSize.iWidth, iSize.iHeight );
       
   163     if( iOriginalSize.iWidth < iOriginalSize.iHeight )
       
   164         {
       
   165         TInt height = iSize.iHeight;
       
   166         iSize.iHeight = iSize.iWidth;
       
   167         iSize.iWidth = height;
       
   168         iPortrait = ETrue;
       
   169         TN_DEBUG3( "CThumbnailImageDecoder::DecodeL() %d x %d", iSize.iWidth, iSize.iHeight );
       
   170         OstTraceExt2( TRACE_NORMAL, DUP2_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL;iSize.iWidth=%d;iSize.iHeight=%d", iSize.iWidth, iSize.iHeight );
       
   171         }
       
   172     else
       
   173         {
       
   174         iPortrait = EFalse;
       
   175         }
       
   176     
       
   177     TN_DEBUG3( "CThumbnailImageDecoder::DecodeL() iOriginalSize = %d x %d", iOriginalSize.iWidth, iOriginalSize.iHeight );
       
   178     OstTraceExt2( TRACE_NORMAL, DUP3_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL;iOriginalSize.iWidth=%d;iOriginalSize.iHeight=%d", iOriginalSize.iWidth, iOriginalSize.iHeight );
       
   179 
       
   180     //Size in both x and y dimension must be non-zero, positive value
       
   181     TSize loadSize( iOriginalSize) ;
       
   182     
       
   183     if(iOriginalSize.iHeight < iSize.iHeight || iOriginalSize.iWidth < iSize.iWidth )
       
   184         {
       
   185         loadSize = iOriginalSize;
       
   186         TN_DEBUG1( "CThumbnailImageDecoder::DecodeL() LoadSize is OriginalSize" );
       
   187         OstTrace0( TRACE_NORMAL, DUP4_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL - LoadSize is OriginalSize" );
       
   188         }
       
   189     else if((iFrameInfoFlags& TFrameInfo::EFullyScaleable || IsSvg()) && aFlags == !CThumbnailManager::ECropToAspectRatio)
       
   190         {
       
   191         loadSize = iSize;
       
   192         TN_DEBUG1( "CThumbnailImageDecoder::DecodeL() EFullyScaleable start" );
       
   193         OstTrace0( TRACE_NORMAL, DUP5_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL - EFullyScaleable start" );
       
   194         const TReal32 srcAspect = static_cast < TReal32 > (
       
   195               iOriginalSize.iWidth ) / iOriginalSize.iHeight;
       
   196 
       
   197           // set loadsize to maximum size within target size 
       
   198           if ( (loadSize.iHeight * srcAspect) <= loadSize.iWidth )
       
   199               {
       
   200               TReal trg = 0;
       
   201               TReal src( loadSize.iHeight * srcAspect );
       
   202               Math::Round( trg, src, 0 );
       
   203               loadSize.SetSize( trg, loadSize.iHeight );
       
   204               }
       
   205           else
       
   206               {
       
   207               TReal trg;
       
   208               TReal src( loadSize.iWidth / srcAspect );
       
   209               Math::Round( trg, src, 0 );
       
   210               loadSize.SetSize( loadSize.iWidth, trg );
       
   211               }
       
   212         
       
   213         TN_DEBUG3( "CThumbnailImageDecoder::DecodeL() EFullyScaleable loadSize = %d x %d", loadSize.iWidth, loadSize.iHeight );
       
   214         OstTraceExt2( TRACE_NORMAL, DUP6_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL - EFullyScaleable;loadSize.iWidth=%d;loadSize.iHeight=%d", loadSize.iWidth, loadSize.iHeight );
       
   215         }
       
   216     else 
       
   217         {
       
   218         
       
   219         // Size reduction factor. 1/1, 1/2, 1/4, and 1/8 are possible values for all
       
   220         // plug-ins. SVG graphics can be rendered at any size.
       
   221         TInt reductionFactor = 1;
       
   222         while ( reductionFactor < KMaximumReductionFactor && ( iSize.iWidth <
       
   223             loadSize.iWidth / 2 ) && ( iSize.iHeight < loadSize.iHeight / 2 ))
       
   224             {
       
   225             // magic: use loadSize that is half of previous size
       
   226             loadSize.iWidth /= 2;
       
   227             loadSize.iHeight /= 2;
       
   228             reductionFactor *= 2;
       
   229             }
       
   230         // If original size is not an exact multiple of reduction factor,
       
   231         // we need to round loadSize up
       
   232         if ( reductionFactor && iOriginalSize.iWidth % reductionFactor )
       
   233             {
       
   234             loadSize.iWidth++;
       
   235             }
       
   236         if ( reductionFactor && iOriginalSize.iHeight % reductionFactor )
       
   237             {
       
   238             loadSize.iHeight++;
       
   239             }
       
   240         TN_DEBUG4( 
       
   241             "CThumbnailImageDecoder::DecodeL() - loadSize = (%d,%d) reduction = 1/%d ", loadSize.iWidth, loadSize.iHeight, reductionFactor );
       
   242         OstTraceExt3( TRACE_NORMAL, DUP7_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL;loadSize.iWidth=%d;loadSize.iHeight=%d;reductionFactor=%d", loadSize.iWidth, loadSize.iHeight, reductionFactor );
       
   243         }
       
   244 
       
   245     TInt err = iBitmap->Create( loadSize, aDisplayMode );
       
   246     if (err != KErrNone)
       
   247         {
       
   248         delete iBitmap;
       
   249         iBitmap = NULL;
       
   250         User::Leave(err);
       
   251         }
       
   252 
       
   253     iDecoder->Convert( &iStatus, * iBitmap );
       
   254     
       
   255     SetActive();
       
   256     
       
   257     TN_DEBUG1( "CThumbnailImageDecoder::DecodeL() end" );
       
   258     OstTrace0( TRACE_NORMAL, DUP8_CTHUMBNAILIMAGEDECODER_DECODEL, "CThumbnailImageDecoder::DecodeL - end" );
       
   259     }
       
   260 
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 // CThumbnailImageDecoder::Release()
       
   264 // Releases resources
       
   265 // -----------------------------------------------------------------------------
       
   266 //
       
   267 void CThumbnailImageDecoder::Release()
       
   268     {
       
   269     Cancel();
       
   270    
       
   271     delete iDecoder;
       
   272     iDecoder = NULL;
       
   273     
       
   274     delete iBitmap;
       
   275     iBitmap = NULL;
       
   276     delete iJpegReadBuffer;
       
   277     iJpegReadBuffer = NULL;
       
   278     delete iExifThumbImage;
       
   279     iExifThumbImage = NULL;
       
   280     
       
   281     iBuffer = NULL; // we don't own the buffer
       
   282     }
       
   283 
       
   284 
       
   285 // -----------------------------------------------------------------------------
       
   286 // CThumbnailImageDecoder::DoCancel()
       
   287 // -----------------------------------------------------------------------------
       
   288 //
       
   289 void CThumbnailImageDecoder::DoCancel()
       
   290     {
       
   291     if ( iDecoder )
       
   292         {
       
   293         iDecoder->Cancel();
       
   294         delete iDecoder;
       
   295         iDecoder = NULL;
       
   296         }
       
   297     
       
   298     delete iBitmap;
       
   299     iBitmap = NULL;
       
   300     delete iJpegReadBuffer;
       
   301     iJpegReadBuffer = NULL;
       
   302     delete iExifThumbImage;
       
   303     iExifThumbImage = NULL;
       
   304     
       
   305     iBuffer = NULL; // we don't own the buffer
       
   306     }
       
   307 
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 // CThumbnailImageDecoder::RunL()
       
   311 // -----------------------------------------------------------------------------
       
   312 //
       
   313 void CThumbnailImageDecoder::RunL()
       
   314     {
       
   315     // This call takes ownership of iBitmap
       
   316     iObserver->ThumbnailProviderReady( iStatus.Int(), iBitmap, iOriginalSize, iEXIF, iPortrait );
       
   317 
       
   318     iBitmap = NULL; // owned by server now
       
   319     iBuffer = NULL; // we don't own the buffer
       
   320     
       
   321     Release();
       
   322     }
       
   323 
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // CThumbnailImageDecoder::IsJpeg()
       
   327 // -----------------------------------------------------------------------------
       
   328 //
       
   329 TBool CThumbnailImageDecoder::IsJpeg()
       
   330     {
       
   331     __ASSERT_DEBUG(( iMimeType.Des() != KNullDesC ), ThumbnailPanic(
       
   332         EThumbnailEmptyDescriptor ));
       
   333 
       
   334     if ( KJpegMime() == iMimeType.Des())
       
   335         {
       
   336         return ETrue;
       
   337         }
       
   338     return EFalse;
       
   339     }
       
   340 
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CThumbnailImageDecoder::IsSvg()
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 TBool CThumbnailImageDecoder::IsSvg()
       
   347     {
       
   348     __ASSERT_DEBUG(( iMimeType.Des() != KNullDesC ), ThumbnailPanic(
       
   349         EThumbnailEmptyDescriptor ));
       
   350 
       
   351     if ( KSvgMime() == iMimeType.Des())
       
   352         {
       
   353         return ETrue;
       
   354         }
       
   355     return EFalse;
       
   356     }
       
   357 
       
   358 
       
   359 // -----------------------------------------------------------------------------
       
   360 // CThumbnailImageDecoder::CreateDecoderL
       
   361 // Creates image decoder
       
   362 // -----------------------------------------------------------------------------
       
   363 //
       
   364 void CThumbnailImageDecoder::CreateDecoderL( CThumbnailManager::TThumbnailQualityPreference
       
   365     aFlags )
       
   366     {
       
   367     TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() start" );
       
   368     OstTrace0( TRACE_NORMAL, CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - start" );
       
   369     
       
   370     TBool thumbFound( EFalse );
       
   371     
       
   372     // If the image is in jpeg format, try to get thumbnail from EXIF data (if EOptimizeForQuality not set)
       
   373     if ( IsJpeg() && !( aFlags == CThumbnailManager::EOptimizeForQuality ))
       
   374         {
       
   375         TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() create exif decoder" );
       
   376         OstTrace0( TRACE_NORMAL, DUP1_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - create exif decoder" );
       
   377         TRAPD( err, CreateExifDecoderL( aFlags ));
       
   378         thumbFound = ( err == KErrNone );
       
   379         iEXIF = ETrue;
       
   380         }
       
   381 
       
   382     if ( !thumbFound )
       
   383         {
       
   384         iEXIF = EFalse;
       
   385         TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() create normal decoder" );
       
   386         OstTrace0( TRACE_NORMAL, DUP2_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - create normal decoder" );
       
   387         
       
   388         delete iDecoder;
       
   389         iDecoder = NULL;
       
   390         
       
   391         TFileName fullName;
       
   392         if ( !iBuffer )
       
   393             {
       
   394             iFile.FullName( fullName );
       
   395             }
       
   396         
       
   397         CImageDecoder::TOptions options;
       
   398         if ( aFlags == CThumbnailManager::EOptimizeForQuality )
       
   399             {
       
   400             options = ( CImageDecoder::TOptions )( CImageDecoder
       
   401                 ::EOptionNoDither );
       
   402             }
       
   403         else
       
   404             {
       
   405             options  = ( CImageDecoder::TOptions )( CImageDecoder
       
   406                 ::EOptionNoDither | CImageDecoder::EPreferFastDecode );
       
   407             }
       
   408 
       
   409         if ( IsSvg())
       
   410             {
       
   411             if ( !iBuffer )
       
   412                 {
       
   413                 iDecoder = CImageDecoder::FileNewL( iFile, ContentAccess::EPeek, 
       
   414                         options, KImageTypeSVGUid, KNullUid, KNullUid );
       
   415                 
       
   416                 TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder created" );
       
   417                 OstTrace0( TRACE_NORMAL, DUP3_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder created" );
       
   418                 }
       
   419             else
       
   420                 {
       
   421                 TRAPD( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, options, KImageTypeSVGUid ) );
       
   422                 
       
   423                 if ( decErr != KErrNone )
       
   424                     {
       
   425                     TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - error 1" );
       
   426                     OstTrace0( TRACE_NORMAL, DUP4_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - error 1" );
       
   427                     
       
   428                     User::Leave( decErr );
       
   429                     }
       
   430                 
       
   431                 TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder created" );
       
   432                 OstTrace0( TRACE_NORMAL, DUP5_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder created" );
       
   433                 }
       
   434             }
       
   435         else if ( !IsJpeg())
       
   436             {
       
   437             if ( !iBuffer )
       
   438                 {
       
   439                 iDecoder = CImageDecoder::FileNewL( iFile, ContentAccess::EPeek, options );
       
   440                 
       
   441                 TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder created" );
       
   442                 OstTrace0( TRACE_NORMAL, DUP6_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder created" );
       
   443                 }
       
   444             else
       
   445                 {
       
   446                 TRAPD( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, iMimeType.Des8(), options) );
       
   447                 
       
   448                 if ( decErr != KErrNone )
       
   449                     {                        
       
   450                     TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder error %d", decErr );
       
   451                     OstTrace1( TRACE_NORMAL, DUP7_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder error;decErr=%d", decErr );
       
   452                     LeaveIfCorruptL(decErr);
       
   453                     
       
   454                     // don't force any mime type
       
   455                     TRAPD( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, options ) );
       
   456                     
       
   457                     if ( decErr != KErrNone )
       
   458                         {                        
       
   459                         TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder no mime error %d", decErr );
       
   460                         OstTrace1( TRACE_NORMAL, DUP8_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder no mime error;decErr=%d", decErr );
       
   461                         
       
   462                         User::Leave( decErr );
       
   463                         }
       
   464                     }
       
   465                 
       
   466                 TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder created" );
       
   467                 OstTrace0( TRACE_NORMAL, DUP9_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder created" );
       
   468                 }
       
   469             }
       
   470         else
       
   471             {
       
   472             if ( !iBuffer )
       
   473                 {
       
   474                 TRAPD( decErr, iDecoder = CExtJpegDecoder::FileNewL(
       
   475                         CExtJpegDecoder::EHwImplementation, iFs, fullName, options) );
       
   476                 
       
   477                 if ( decErr != KErrNone )
       
   478                     {
       
   479                     TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - HW CExtJpegDecoder failed %d", decErr);
       
   480                     OstTrace1( TRACE_NORMAL, DUP10_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL;decErr=%d - HW CExtJpegDecoder failed ", decErr );
       
   481                     LeaveIfCorruptL(decErr);
       
   482                     
       
   483                     TRAP( decErr, iDecoder = CExtJpegDecoder::FileNewL(
       
   484                             CExtJpegDecoder::ESwImplementation, iFs, fullName, options) );
       
   485                     
       
   486                     if ( decErr != KErrNone )
       
   487                         {
       
   488                         TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - SW CExtJpegDecoder failed %d", decErr);
       
   489                         OstTrace1( TRACE_NORMAL, DUP11_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - SW CExtJpegDecoder failed;decErr=%d", decErr );
       
   490                         LeaveIfCorruptL(decErr);
       
   491                         
       
   492                         TRAP( decErr, iDecoder = CImageDecoder::FileNewL( iFile, ContentAccess::EPeek, options ));
       
   493                         
       
   494                         if( decErr != KErrNone)
       
   495                             {
       
   496                             TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder failed %d", decErr);
       
   497                             OstTrace1( TRACE_NORMAL, DUP12_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder failed ;decErr=%d", decErr );
       
   498                             User::Leave( decErr );
       
   499                             }
       
   500                         
       
   501                         TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder created" );
       
   502                         OstTrace0( TRACE_NORMAL, DUP13_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder created" );
       
   503                         }
       
   504                     else
       
   505                         {
       
   506                         TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - SW CExtJpegDecoder created" );
       
   507                         OstTrace0( TRACE_NORMAL, DUP14_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - SW CExtJpegDecoder created" );
       
   508                         }
       
   509                     }
       
   510                 else 
       
   511                     {
       
   512                     TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - HW CExtJpegDecoder created" );
       
   513                     OstTrace0( TRACE_NORMAL, DUP15_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL" );
       
   514                     }
       
   515                 }
       
   516             else
       
   517                 {
       
   518                 TRAPD( decErr, iDecoder = CExtJpegDecoder::DataNewL(
       
   519                         CExtJpegDecoder::EHwImplementation, iFs, *iBuffer, options ));
       
   520                 
       
   521                 if ( decErr != KErrNone )
       
   522                     {
       
   523                     TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - HW CExtJpegDecoder failed %d", decErr);
       
   524                     OstTrace1( TRACE_NORMAL, DUP16_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - HW CExtJpegDecoder failed;decErr=%d", decErr );
       
   525                     LeaveIfCorruptL(decErr);
       
   526                     
       
   527                     TRAP( decErr, iDecoder = CExtJpegDecoder::DataNewL(
       
   528                             CExtJpegDecoder::ESwImplementation, iFs, *iBuffer, options ));
       
   529                     
       
   530                     if ( decErr != KErrNone )
       
   531                         {                       
       
   532                         TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - SW CExtJpegDecoder failed %d", decErr);
       
   533                         OstTrace1( TRACE_NORMAL, DUP17_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - SW CExtJpegDecoder failed;decErr=%d", decErr );
       
   534                         LeaveIfCorruptL(decErr);
       
   535                         TRAPD( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, iMimeType.Des8(), options) );
       
   536                         
       
   537                         if ( decErr != KErrNone )
       
   538                             {                        
       
   539                             TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder failed %d", decErr);
       
   540                             OstTrace1( TRACE_NORMAL, DUP18_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder failed;decErr=%d", decErr );
       
   541                             LeaveIfCorruptL(decErr);
       
   542                             // don't force any mime type
       
   543                             TRAPD( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, options ) );
       
   544 
       
   545                             if ( decErr != KErrNone )
       
   546                                 {                                
       
   547                                 TN_DEBUG2( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder no mime failed %d", decErr);
       
   548                                 OstTrace1( TRACE_NORMAL, DUP19_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder no mime failed;decErr=%d", decErr );
       
   549                                 User::Leave( decErr );
       
   550                                 }
       
   551                             }
       
   552                         
       
   553                         TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - CImageDecoder created" );
       
   554                         OstTrace0( TRACE_NORMAL, DUP20_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - CImageDecoder created" );
       
   555                         }
       
   556                     else
       
   557                         {
       
   558                         TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - SW CExtJpegDecoder created" );
       
   559                         OstTrace0( TRACE_NORMAL, DUP21_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - SW CExtJpegDecoder created" );
       
   560                         }               
       
   561                     }
       
   562                 else
       
   563                     {
       
   564                     TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() - HW CExtJpegDecoder created" );
       
   565                     OstTrace0( TRACE_NORMAL, DUP22_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - HW CExtJpegDecoder created" );
       
   566                     }               
       
   567                 }
       
   568             }
       
   569         }
       
   570     
       
   571     TN_DEBUG1( "CThumbnailImageDecoder::CreateDecoderL() end" );
       
   572     OstTrace0( TRACE_NORMAL, DUP23_CTHUMBNAILIMAGEDECODER_CREATEDECODERL, "CThumbnailImageDecoder::CreateDecoderL - end" );
       
   573     }
       
   574 
       
   575 
       
   576 // -----------------------------------------------------------------------------
       
   577 // CThumbnailImageDecoder::CreateExifDecoderL()
       
   578 // -----------------------------------------------------------------------------
       
   579 //
       
   580 void CThumbnailImageDecoder::CreateExifDecoderL( CThumbnailManager
       
   581     ::TThumbnailQualityPreference aFlags )
       
   582     {
       
   583     TN_DEBUG1( "CThumbnailImageDecoder::CreateExifDecoderL() start" );
       
   584     OstTrace0( TRACE_NORMAL, CTHUMBNAILIMAGEDECODER_CREATEEXIFDECODERL, "CThumbnailImageDecoder::CreateExifDecoderL - start" );
       
   585     
       
   586     // If the image is in jpeg format, try to get thumbnail from EXIF data.
       
   587     CExifRead* reader = NULL;
       
   588     
       
   589     if ( !iBuffer )
       
   590         {    
       
   591         TInt64 size( 0 );
       
   592         User::LeaveIfError( iFile.Size( size ));
       
   593     
       
   594         TInt readSize = Min( size, KJpegLoadBufferSize );
       
   595     
       
   596         delete iJpegReadBuffer;
       
   597         iJpegReadBuffer = NULL;
       
   598         iJpegReadBuffer = HBufC8::NewL( readSize );
       
   599         TPtr8 localBuffer = iJpegReadBuffer->Des();
       
   600     
       
   601         User::LeaveIfError( iFile.Read( localBuffer, readSize ));
       
   602         reader = CExifRead::NewL( localBuffer, CExifRead::ENoJpeg );
       
   603         }
       
   604     else
       
   605         {
       
   606         reader = CExifRead::NewL( *iBuffer, CExifRead::ENoJpeg );
       
   607         }
       
   608     
       
   609     CleanupStack::PushL( reader );
       
   610 
       
   611     iExifThumbImage = reader->GetThumbnailL();
       
   612     CleanupStack::PopAndDestroy( reader );
       
   613 
       
   614     User::LeaveIfNull( iExifThumbImage );
       
   615 
       
   616     delete iDecoder;
       
   617     iDecoder = NULL;
       
   618 
       
   619     CImageDecoder::TOptions options;
       
   620     if ( aFlags == CThumbnailManager::EOptimizeForQuality )
       
   621         {
       
   622         options = ( CImageDecoder::TOptions )( CImageDecoder::EOptionNoDither );
       
   623         }
       
   624     else
       
   625         {
       
   626         options = ( CImageDecoder::TOptions )( CImageDecoder::EOptionNoDither |
       
   627             CImageDecoder::EPreferFastDecode  );
       
   628         }
       
   629 
       
   630     TRAPD( err, iDecoder = CExtJpegDecoder::DataNewL( iFs, * iExifThumbImage, options ));
       
   631 
       
   632     if ( err == KErrNotFound || err == KErrNotSupported )
       
   633         {
       
   634         delete iDecoder;
       
   635         iDecoder = NULL;
       
   636 
       
   637         iDecoder = CImageDecoder::DataNewL( iFs, * iExifThumbImage, options );
       
   638         }
       
   639     else
       
   640         {
       
   641         TN_DEBUG2( "CThumbnailImageDecoder::CreateExifDecoderL() - CExtJpegDecoder err == %d", err );
       
   642         User::LeaveIfError( err );
       
   643         }
       
   644 
       
   645     TN_DEBUG1( "CThumbnailImageDecoder::CreateExifDecoderL() end" );
       
   646     OstTrace0( TRACE_NORMAL, DUP1_CTHUMBNAILIMAGEDECODER_CREATEEXIFDECODERL, "CThumbnailImageDecoder::CreateExifDecoderL - end" );
       
   647     }
       
   648 
       
   649 
       
   650 // -----------------------------------------------------------------------------
       
   651 // CThumbnailImageDecoder::CreateExifDecoderL()
       
   652 // Returns size of original image
       
   653 // -----------------------------------------------------------------------------
       
   654 //
       
   655 const TSize& CThumbnailImageDecoder::OriginalSize()const
       
   656     {
       
   657     return iOriginalSize;
       
   658     }
       
   659 
       
   660 // -----------------------------------------------------------------------------
       
   661 // CThumbnailImageDecoder::LeaveIfCorruptL()
       
   662 // Leave is image is corrupted
       
   663 // -----------------------------------------------------------------------------
       
   664 //
       
   665 void CThumbnailImageDecoder::LeaveIfCorruptL(const TInt aError )
       
   666     {
       
   667     //no sense to try other codecs if image is corrupted
       
   668     if( aError == KErrCorrupt || aError == KErrUnderflow)
       
   669         {
       
   670         User::Leave( aError );
       
   671         }
       
   672     }
       
   673 
       
   674 //End of file