imagehandlingutilities/thumbnailmanager/plugins/image/src/thumbnailimagedecoderv2.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Feb 2010 23:07:36 +0200
branchRCL_3
changeset 5 82749d516180
parent 0 2014ca87e772
child 7 2eb74cf6572e
permissions -rw-r--r--
Revision: 201003 Kit: 201007

/*
* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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:
*
* Description:  Image thumbnail decoder
 *
*/


//INCLUDE FILES
#include <e32base.h>
#include <imageconversion.h>
#include <exifread.h>

#include <iclextjpegapi.h>
#include "thumbnailimagedecoderv2.h"
#include "thumbnaillog.h"
#include "thumbnailpanic.h"
#include "thumbnailmanagerconstants.h"

// ============================ MEMBER FUNCTIONS ===============================
//------------------------------------------------------------------------
// CThumbnailImageDecoder::CThumbnailImageDecoder()
// C++ default constructor can NOT contain any code, that might leave.
// ---------------------------------------------------------------------------
//
CThumbnailImageDecoderv2::CThumbnailImageDecoderv2( RFs& aFs): CActive(
    EPriorityStandard ), iFs( aFs )
    {
    CActiveScheduler::Add( this );
    }


// ---------------------------------------------------------------------------
// CThumbnailImageDecoder::~CThumbnailImageDecoder()
// Destructor.
// ---------------------------------------------------------------------------
//
CThumbnailImageDecoderv2::~CThumbnailImageDecoderv2()
    {
    Release();
    }


// -----------------------------------------------------------------------------
// CThumbnailImageDecoder::CreateL()
// Creates thumbnail of image
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::CreateL(TDesC8& aBuffer, MThumbnailProviderObserver& aObserver)
    {
    TN_DEBUG1( "CThumbnailImageDecoderv2::CreateL() start" );

    iBuffer = &aBuffer;
    iObserver = &aObserver;

    CreateDecoderL();
    
    TN_DEBUG1( "CThumbnailImageDecoderv2::CreateL() end" );
    }

// -----------------------------------------------------------------------------
// CThumbnailImageDecoder::DecodeL()
// Decode the thumbnail image
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::DecodeL( )
    {
    TN_DEBUG1( "CThumbnailImageDecoderv2::DecodeL() start" );
    
    // Create the bitmap
    if ( !iBitmap )
        {
        iBitmap = new( ELeave )CFbsBitmap();
        }
    
	//set displaymode from global constants
    User::LeaveIfError( iBitmap->Create( iDecoder->FrameInfo().iOverallSizeInPixels, iDecoder->FrameInfo().iFrameDisplayMode) );

    iDecoder->Convert( &iStatus, * iBitmap );
    while ( iStatus == KErrUnderflow )
        {
        iDecoder->ContinueConvert( &iStatus );
        }
    SetActive();  
    
    TN_DEBUG1( "CThumbnailImageDecoderv2::DecodeL() end" );
    }


// -----------------------------------------------------------------------------
// CThumbnailImageDecoder::Release()
// Releases resources
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::Release()
    {
    Cancel();
    delete iDecoder;
    iDecoder = NULL;
    }


// -----------------------------------------------------------------------------
// CThumbnailImageDecoder::DoCancel()
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::DoCancel()
    {
    if ( iDecoder )
        {
        iDecoder->Cancel();
        delete iDecoder;
        iDecoder = NULL;
        }
    }


// -----------------------------------------------------------------------------
// CThumbnailImageDecoder::RunL()
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::RunL()
    {
    // This call takes ownership of iBitmap
    // EXIF always false
    // Rotated always false
    iObserver->ThumbnailProviderReady( iStatus.Int(), iBitmap, iOriginalSize, EFalse, EFalse);

    iBitmap = NULL; // owned by server now
    iBuffer = NULL;
    Release();
    }


// -----------------------------------------------------------------------------
// CThumbnailImageDecoder::CreateDecoderL
// Creates image decoder
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::CreateDecoderL()
    {
    TN_DEBUG1( "CThumbnailImageDecoderv2::CreateDecoderL() start" );
    
    delete iDecoder;
    iDecoder = NULL;
    
    CImageDecoder::TOptions options = ( CImageDecoder::TOptions )( 
            CImageDecoder::EOptionNoDither | CImageDecoder::EPreferFastDecode | CImageDecoder::EOptionAlwaysThread );

    TRAPD( decErr, iDecoder = CExtJpegDecoder::DataNewL( 
            CExtJpegDecoder::EHwImplementation, iFs, *iBuffer, options ));
                    
    if ( decErr != KErrNone )
        {
        TN_DEBUG2( "CThumbnailImageDecoderv2::CreateDecoderL() - HW CExtJpegDecoder failed = %d", decErr );
        TRAP( decErr, iDecoder = CExtJpegDecoder::DataNewL(
                CExtJpegDecoder::ESwImplementation, iFs, *iBuffer, options ));
        
        if ( decErr != KErrNone )
            {
            TN_DEBUG2( "CThumbnailImageDecoderv2::CreateDecoderL() - SW CExtJpegDecoder failed %d", decErr);
            LeaveIfCorruptL( decErr );
            
            TRAP( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, KJpegMime(), options ) );
            
            if ( decErr != KErrNone )
                {                  
                TN_DEBUG2( "CThumbnailImageDecoderv2::CreateDecoderL() - CImageDecoder failed %d", decErr);
                LeaveIfCorruptL( decErr );
            
                // don't force any mime type
                TRAPD( decErr, iDecoder = CImageDecoder::DataNewL( iFs, *iBuffer, options ) );
                if ( decErr != KErrNone )
                    {                    
                    TN_DEBUG2( "CThumbnailImageDecoderv2::CImageDecoder() - CImageDecoder no mime error %d", decErr  );
                    User::Leave( decErr );
                    }
                }
            
            TN_DEBUG1( "CThumbnailImageDecoderv2::CreateDecoderL() - CImageDecoder created" );
            }
        else
            {
            TN_DEBUG1( "CThumbnailImageDecoderv2:CreateDecoderL() - SW CExtJpegDecoder created" );
            }               
        }
    else
        {
        TN_DEBUG1( "CThumbnailImageDecoderv2::CreateDecoderL() - HW CExtJpegDecoder created" );
        }
     
    TN_DEBUG1( "CThumbnailImageDecoderv2::CreateDecoderL() end" );
    }

// -----------------------------------------------------------------------------
// CThumbnailImageDecoderv2::LeaveIfCorruptL()
// Leave if image is corrupted
// -----------------------------------------------------------------------------
//
void CThumbnailImageDecoderv2::LeaveIfCorruptL(const TInt aError )
    {
    //no sense to try other codecs if image is corrupted
    if( aError == KErrCorrupt || aError == KErrUnderflow)
        {
        User::Leave( aError );
        }
    }

//End of file