camappengine/StillConverter/Src/CaeStillDecoder.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:51:24 +0200
changeset 0 9b3e960ffc8a
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2003 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:  Still Image Decoder for Camera Application Engine
*
*/



// INCLUDE FILES
#include <eikenv.h>

#include "CaeStillConverter.h"
#include "CaeStillDecoder.h"
#include "CaeStillCommon.h"

#ifdef CAE_TEST_VERSION
#include "CaeStillConverterTestErrors.h"
#endif


// ================= MEMBER FUNCTIONS =======================


// ---------------------------------------------------------
// CCaeStillDecoder::NewL
// Two-phased constructor.
// ---------------------------------------------------------
//
EXPORT_C CCaeStillDecoder* CCaeStillDecoder::NewL()
    {
    CCaeStillDecoder* self = new( ELeave ) CCaeStillDecoder;
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------
// CCaeStillDecoder::~CCaeStillDecoder
// Destructor.
// ---------------------------------------------------------
//
EXPORT_C CCaeStillDecoder::~CCaeStillDecoder()
    {
    delete iDecoder;
    delete iDecodedImage;
    iFs.Close(); 

    // For RTRT code coverage analysis.
    // #pragma attol insert _ATCPQ_DUMP(0);
    }


// ---------------------------------------------------------
// CCaeStillDecoder::SetObserver
// Sets Still Decoder observer.
// ---------------------------------------------------------
//
EXPORT_C void CCaeStillDecoder::SetObserver( 
    MCaeStillDecoderObserver* aObserver )
    {
    iObserver = aObserver;
    }


// -----------------------------------------------------------------------------
// CCaeStillDecoder::SetImageCodecL
// Sets the specific image codec implementation to be used in decoding.
// -----------------------------------------------------------------------------
//
void CCaeStillDecoder::SetImageCodecL( 
	TUid aCodecUid )
    {
    iImageCodecUid = aCodecUid;
    }

        
// ---------------------------------------------------------
// CCaeStillDecoder::ConvertHBufC8ToCFbsBitmapL
// Creates CImageItem object, places it in the internal 
// queue and starts memory image to bitmap conversion.
// ---------------------------------------------------------
//
EXPORT_C void CCaeStillDecoder::ConvertHBufC8ToCFbsBitmapL( 
    HBufC8* aImageBuffer,
    TDisplayMode aTargetBitmapMode,
    const TSize& aTargetBitmapSize,
    const TSize& aFullyScaledTargetBitmapSize )
    {
    LOGTEXT( _L( "Cae: CCaeStillDecoder::ConvertHBufC8ToCFbsBitmapL() entering" ) );

    CleanupStack::PushL( aImageBuffer );

    // Create image item and set up image data.

    CImageItem* imageItem = new( ELeave ) CImageItem;
    imageItem->iBitmapDisplayMode = aTargetBitmapMode;
    imageItem->iImageBuffer = aImageBuffer;
    imageItem->iBitmapSize = aTargetBitmapSize;
    imageItem->iFullyScaledBitmapSize = aFullyScaledTargetBitmapSize;
    CleanupStack::Pop( aImageBuffer );
    CleanupStack::PushL( imageItem ); 

    #ifdef CAE_TEST_VERSION
    // For simulating errors when compiled as special "test version".
    CaeConvertHBufC8ToCFbsBitmapErrorL();
    #endif    

    // Add image to the queue.
    User::LeaveIfError ( iImageQueue->Append( imageItem ) );

    CleanupStack::Pop( imageItem );

    // Start image conversion if not busy. Busy means that e.g. conversion is currently running. 
    if ( !IsBusy() )
        {
        TRAPD( error, ConvertL() );
        if ( error != KErrNone )
            {
            ConversionComplete( error );
            }
        }

    LOGTEXT( _L( "Cae: CCaeStillDecoder::ConvertHBufC8ToCFbsBitmapL() returning" ) );
    }


// ---------------------------------------------------------
// CCaeStillDecoder::Cleanup
// Destroy all allocations.
// ---------------------------------------------------------
//
EXPORT_C void CCaeStillDecoder::Cleanup()
    {
    if ( iDecoder )
        {
        iDecoder->Cancel();
        delete iDecoder;
        iDecoder = NULL;
        }

    if ( iState != EIdle )
        {
        delete iDecodedImage;
        iDecodedImage = NULL;
        }
    
    if ( iImageQueue )
        {
        iImageQueue->ResetAndDestroy();
        }
    }


// ---------------------------------------------------------
// CCaeStillDecoder::CCaeStillDecoder
// Default constructor. 
// This can NOT leave.
// ---------------------------------------------------------
//
CCaeStillDecoder::CCaeStillDecoder()
    {
    CActiveScheduler::Add( this );
    }


// ---------------------------------------------------------
// CCaeStillDecoder::ConstructL
// Symbian 2nd phase constructor that can leave.
// ---------------------------------------------------------
//
void CCaeStillDecoder::ConstructL()
    {
    CCaeStillConverter::ConstructL();
    User::LeaveIfError( iFs.Connect() );
    }


// ---------------------------------------------------------
// CCaeStillDecoder::DoCancel
// From CActive, implements cancellation of an outstanding request.
// ---------------------------------------------------------
//
void CCaeStillDecoder::DoCancel()
    {
    Cleanup();
    iState = EIdle;
    }


// ---------------------------------------------------------
// CCaeStillDecoder::ConvertL
// Converts bitmap to memory JPEG image.
// ---------------------------------------------------------
//
void CCaeStillDecoder::ConvertL()
    {
    LOGTEXT( _L( "Cae: CCaeStillDecoder::ConvertL() entering" ) );

    iState = EConvert;
    
    // Use the default codec or the specific codec
    iDecoder = CImageDecoder::DataNewL( iFs, *(*iImageQueue)[0]->iImageBuffer, 
    	CImageDecoder::EOptionNone, KNullUid, KNullUid, iImageCodecUid );
    
    iDecodedImage = NULL;
    iDecodedImage = new( ELeave ) CFbsBitmap;

    // Set target bitmap size
    TSize targetBitmapSize = (*iImageQueue)[0]->iBitmapSize;

    const TFrameInfo& frameInfo = iDecoder->FrameInfo( 0 );
    TUid impUid = iDecoder->ImplementationUid();
    LOGTEXT3( _L( "Cae: CCaeStillDecoder::ConvertL() Requested decoder: %x, Found decoder: %x" ), iImageCodecUid.iUid, impUid.iUid );
    LOGTEXT2( _L( "Cae: CCaeStillDecoder::ConvertL() Free scaling support: %d" ), frameInfo.iFlags & TFrameInfo::EFullyScaleable );

    //
    // Use free scaling always with special decoder or with any decoder that supports it
    //
    if ( (( impUid == KUidSpecialFreeScalingDecoder ) || ( frameInfo.iFlags & TFrameInfo::EFullyScaleable ))  
         && ( (*iImageQueue)[0]->iFullyScaledBitmapSize != TSize( 0, 0 ) ) )
        {
        LOGTEXT( _L( "Cae: CCaeStillDecoder::ConvertL(). Use free scaling in decoding" ) );
        targetBitmapSize = (*iImageQueue)[0]->iFullyScaledBitmapSize;
        }

    User::LeaveIfError( iDecodedImage->Create(
        targetBitmapSize, 
        (*iImageQueue)[0]->iBitmapDisplayMode ) );

    #ifdef CAE_TEST_VERSION
    // For simulating errors when compiled as special "test version".
    CaeStillConvertErrorL();
    #endif    

    iState = EConvert;
    iStatus = KRequestPending;
    iDecoder->Convert( &iStatus, *iDecodedImage );
    SetActive();

    LOGTEXT( _L( "Cae: CCaeStillDecoder::ConvertL() returning" ) );
    }


// ---------------------------------------------------------
// CCaeStillDecoder::ConversionComplete
// Perfoms necessary cleanup and delivers result to the client.
// ---------------------------------------------------------
//
void CCaeStillDecoder::ConversionComplete( 
    TInt aError )
    {
    LOGTEXT( _L( "Cae: CCaeStillDecoder::ConversionComplete() entering" ) );
    #ifdef _DEBUG
    if ( aError ) 
        {
        LOGTEXT( _L( "Cae: CCaeStillDecoder::ConversionComplete(): error detected" ) );
        }
    #endif

    // Delete the decoder object and image queue item
    if ( iDecoder )
        {
        iDecoder->Cancel();
        delete iDecoder;
        iDecoder = NULL;
        }

    // To be outputted via call-back.
    HBufC8* imageBuffer = NULL;

    if ( iImageQueue->Count() > 0 )
        {
        imageBuffer = (*iImageQueue)[0]->iImageBuffer;

        (*iImageQueue)[0]->iImageBuffer = NULL; // Prevent deletion of source image.
        delete ( *iImageQueue )[0];

        // Remove item pointer from the queue and compress the queue.
        iImageQueue->Remove( 0 ); // Remove item pointer from the queue and compress the queue.
        }

    iState = EIdle;

    const TInt KZeroImageSize = 0; // Image size argument currently not in use.

    // Call back the client to deliver the result image. Gives away the ownership of the imageBuffer
    // and iDecodedImage.
    iObserver->McaesdoCFbsBitmapImageReady( imageBuffer, iDecodedImage, aError, KZeroImageSize );
    iDecodedImage = NULL; // Ownership has been given away

    LOGTEXT( _L( "Cae: CCaeStillDecoder::ConversionComplete() returning" ) );
    }


//  End of File