camappengine/StillConverter/Src/CaeStillEncoder.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) 2002 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 Encoder for Camera Application Engine
*
*/



// INCLUDE FILES
#include <eikenv.h>

#include "CaeStillConverter.h"
#include "CaeStillEncoder.h"
#include "CaeStillCommon.h"

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


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


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


// ---------------------------------------------------------
// CCaeStillEncoder::~CCaeStillEncoder
// Destructor.
// ---------------------------------------------------------
//
EXPORT_C CCaeStillEncoder::~CCaeStillEncoder()
    {
    Cancel();
    Cleanup();
    
    // For RTRT code coverage analysis.
    // #pragma attol insert _ATCPQ_DUMP(0);
    }


// ---------------------------------------------------------
// CCaeStillEncoder::SetObserver
// Sets Still encoder observer.
// ---------------------------------------------------------
//
EXPORT_C void CCaeStillEncoder::SetObserver( 
    MCaeStillEncoderObserver* aObserver )
    {
    iObserver = aObserver;
    }


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

// ---------------------------------------------------------
// CCaeStillEncoder::SetCompressionQuality
// Sets compression quality.
// ---------------------------------------------------------
//
EXPORT_C void CCaeStillEncoder::SetCompressionQuality( 
    TInt aQuality )
    {
    iJpegQuality = Min( KJpegQualityMax, Max( KJpegQualityMin, aQuality ) );
    }


// ---------------------------------------------------------
// CCaeStillEncoder::CompressionQuality
// Gets compression quality.
// ---------------------------------------------------------
//
EXPORT_C TInt CCaeStillEncoder::CompressionQuality() const
    {
    return iJpegQuality;
    }


// ---------------------------------------------------------
// CCaeStillEncoder::ConvertCFbsBitmapToHBufC8L
// Creates CImageItem object, places it in the internal 
// queue and starts bitmap to memory image conversion.
// ---------------------------------------------------------
//
EXPORT_C void CCaeStillEncoder::ConvertCFbsBitmapToHBufC8L( 
    CFbsBitmap* aBitmap,  
    TTargetFormat aTargetFormat )
    {
    LOGTEXT( _L( "Cae: CCaeStillEncoder::ConvertCFbsBitmapToHBufC8L() entering" ) );

    CleanupStack::PushL( aBitmap );

    // Create image item and set up image data.

    CImageItem* imageItem = new( ELeave ) CImageItem;

    imageItem->iBitmap = aBitmap;

    CleanupStack::Pop( aBitmap );
    CleanupStack::PushL( imageItem );

    switch ( aTargetFormat )
        {
        case ETargetFormatJPEG:
        default:
            {
            imageItem->iImageTypeUid = KImageTypeJPGUid;

            imageItem->iFrameImageData = CFrameImageData::NewL(); 
            // ( do not push member variable to cleanup stack )

            TJpegImageData* imagedata = new( ELeave ) TJpegImageData;
            CleanupStack::PushL( imagedata );

            imagedata->iSampleScheme = KCaeJpegColorSampling;
            imagedata->iQualityFactor = iJpegQuality;

            User::LeaveIfError ( imageItem->iFrameImageData->AppendImageData( imagedata ) );

            CleanupStack::Pop( imagedata );
            break;
            }
        }

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

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

    CleanupStack::Pop( imageItem );

    // Start image conversion if not busy.
    if ( !IsBusy() )
        {
        TRAPD( error, ConvertL() );
        if ( error != KErrNone )
            {
            ConversionComplete( error );
            }
        }

    LOGTEXT( _L( "Cae: CCaeStillEncoder::ConvertCFbsBitmapToHBufC8L() returning" ) );
    }


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

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


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


// ---------------------------------------------------------
// CCaeStillEncoder::ConstructL
// Symbian 2nd phase constructor that can leave.
// ---------------------------------------------------------
//
void CCaeStillEncoder::ConstructL()
    {
    CCaeStillConverter::ConstructL();
    }


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


// ---------------------------------------------------------
// CCaeStillEncoder::ConvertL
// Converts bitmap to memory JPEG image.
// Allocates Image Conversion Library (ICL) encoder and 
// starts conversion.
// ---------------------------------------------------------
//
void CCaeStillEncoder::ConvertL()
    {
    LOGTEXT( _L( "Cae: CCaeStillEncoder::ConvertL() entering" ) );

    // Do not delete the encoded image here, just set to NULL.
    iEncodedImage = NULL;

    // Allocate new ICL encoder.
    delete iEncoder;
    iEncoder = NULL;
    
    // Use the default codec or the specific codec
    iEncoder = CImageEncoder::DataNewL( iEncodedImage, 
    	CImageEncoder::EOptionNone, (*iImageQueue)[0]->iImageTypeUid, 
    	KNullUid, iImageCodecUid ); 

    LOGTEXT3( _L( "Cae: CCaeStillEncoder::ConvertL(). Requested encoder: %x, Found encoder: %x" ), iImageCodecUid.iUid, iEncoder->ImplementationUid().iUid );
    
    #ifdef CAE_TEST_VERSION
    // For simulating errors when compiled as special "test version".
    CaeStillConvertErrorL();
    #endif    

    iState = EConvert;
    iStatus = KRequestPending;
    iEncoder->Convert( &iStatus, 
                       *(*iImageQueue)[0]->iBitmap, 
                       (*iImageQueue)[0]->iFrameImageData );
    SetActive();

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


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

    if ( iEncoder )
        {
        iEncoder->Cancel();
        delete iEncoder;
        iEncoder = NULL;
        }

    // To be outputted via call-back.
    CFbsBitmap* bitmap = NULL;
    
    if ( iImageQueue->Count() > 0 )
        {
        bitmap = (*iImageQueue)[0]->iBitmap;

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

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

    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 bitmap 
    // and iEncodedImage.
    iObserver->McaeseoHBufC8ImageReady( bitmap, iEncodedImage, aError, KZeroImageSize );
    iEncodedImage = NULL; // Ownership has been given away

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


//  End of File