photosgallery/collectionframework/thumbnailcreator/src/glxtnloadthumbnailtask.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:45:44 +0200
changeset 0 4e91876724a2
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2008-2009 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:    Base class for tasks which load thumbnails
*
*/




#include "glxtnloadthumbnailtask.h"

#include <glxassert.h>
#include <glxtracer.h>
#include <glxlog.h>
#include <glxthumbnail.h>
#include <imageconversion.h>
#include <s32mem.h>

#include "glxtnfileinfo.h"
#include "glxtnfileutility.h"
#include "glxtnimagedecoderfactory.h"
#include "glxtnthumbnailrequest.h"
#include "mglxtnstorage.h"



// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CGlxtnLoadThumbnailTask::CGlxtnLoadThumbnailTask( const TGlxtnTaskId& aId,
                                    const TGlxThumbnailRequest& aRequestInfo,
                                    CGlxtnFileUtility& aFileUtility,
                                    MGlxtnThumbnailCreatorClient& aClient) :
    CGlxtnClientTask( aId, aRequestInfo.iId, aClient ),
    iFileUtility( aFileUtility ), iRequestedSize( aRequestInfo.iSizeClass ),
    iDrmAllowed( aRequestInfo.iDrmAllowed )
    {
    TRACER("CGlxtnLoadThumbnailTask::CGlxtnLoadThumbnailTask()");
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CGlxtnLoadThumbnailTask::~CGlxtnLoadThumbnailTask() 
    {
    TRACER("CGlxtnLoadThumbnailTask::~CGlxtnLoadThumbnailTask()");
    delete iDecoder;
    delete iThumbnail;
    delete iThumbData;
    delete iInfo;
    }

// -----------------------------------------------------------------------------
// ConstructL
// -----------------------------------------------------------------------------
//
void CGlxtnLoadThumbnailTask::ConstructL( TInt aBitmapHandle )
    {
    TRACER("void CGlxtnLoadThumbnailTask::ConstructL()");
    // Duplicate the client's bitmap
    iThumbnail = new (ELeave) CFbsBitmap();
    User::LeaveIfError( iThumbnail->Duplicate( aBitmapHandle ) );
    }

// ---------------------------------------------------------------------------
// DoCancel
// ---------------------------------------------------------------------------
//
void CGlxtnLoadThumbnailTask::DoCancel()
    {
    TRACER("void CGlxtnLoadThumbnailTask::DoCancel()");
    if ( iDecoder )
        {
        iDecoder->Cancel();
        }

    Storage()->StorageCancel();
    }

// ---------------------------------------------------------------------------
// LoadThumbnailL
// ---------------------------------------------------------------------------
//
TBool CGlxtnLoadThumbnailTask::LoadThumbnailL( TRequestStatus& aStatus )
    {
    TRACER("TBool CGlxtnLoadThumbnailTask::LoadThumbnailL()");
    GLX_ASSERT_DEBUG( iInfo, Panic( EGlxPanicNullPointer ), "No file info" );

    if ( Storage() && iFileUtility.IsPersistentSize( iRequestedSize ) )
        {
        Storage()->LoadThumbnailDataL( iThumbData, iFormat, ItemId(),
                                    *iInfo, iRequestedSize, &aStatus );
        iState = EStateLoading;

        return ETrue;
        }

    return EFalse;
    }

// ---------------------------------------------------------------------------
// HandleLoadedThumbnailL
// ---------------------------------------------------------------------------
//
TBool CGlxtnLoadThumbnailTask::HandleLoadedThumbnailL(TRequestStatus& aStatus)
    {
    TRACER("CGlxtnLoadThumbnailTask::HandleLoadedThumbnailL()");
	TBool active = EFalse;

    User::LeaveIfNull( iThumbData );

    switch ( iFormat )
        {
        case EGlxIDF_Bitmap:
            {
            CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
            CleanupStack::PushL( bitmap );

            RDesReadStream stream( *iThumbData );
            CleanupClosePushL( stream );
            stream >> *bitmap;
            CleanupStack::PopAndDestroy( &stream );

            User::LeaveIfError( iThumbnail->Resize( bitmap->SizeInPixels() ) );

            CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( iThumbnail );
            CleanupStack::PushL( device );
            CFbsBitGc* context = NULL;
            User::LeaveIfError( device->CreateContext( context ) );
            CleanupStack::PushL( context );

            context->BitBlt( TPoint(), bitmap );

            CleanupStack::PopAndDestroy( context ); 
            CleanupStack::PopAndDestroy( device );

            CleanupStack::PopAndDestroy( bitmap );
            }
            break;

    	case EGlxIDF_JPEG:
            iDecoder = GlxtnImageDecoderFactory::NewL(
                                    iFileUtility.FsSession(), *iThumbData );
            DecodeThumbnailL( aStatus, EFalse );
            active = ETrue;
            break;

        default:
            User::Leave( KErrNotSupported );
            break;
        }

    return active;
    }

// ---------------------------------------------------------------------------
// DecodeThumbnailL
// ---------------------------------------------------------------------------
//
void CGlxtnLoadThumbnailTask::DecodeThumbnailL( TRequestStatus& aStatus,
                                                TBool /*aScaleBitmap*/ )
    {
    TRACER("CGlxtnLoadThumbnailTask::DecodeThumbnailL()");
    GLX_ASSERT_DEBUG( iDecoder, Panic( EGlxPanicNullPointer ), "No decoder" );

    // Resize empty bitmap to required size
    TSize thumbSize( iDecoder->FrameInfo().iOverallSizeInPixels );
    GLX_DEBUG3("CGlxtnLoadThumbnailTask::DecodeThumbnailL() thumbSize w(%d) h(%d)", 
            thumbSize.iWidth, thumbSize.iHeight);
   
    // Always adjust the target bitmap size 
	// as Exif thumbnail could be bigger in size
    TSize targetSize = iRequestedSize;
    if( (thumbSize.iWidth <= targetSize.iWidth ) && 
	    (thumbSize.iHeight <= targetSize.iHeight ) )
         {
         targetSize.iWidth  = thumbSize.iWidth;
         targetSize.iHeight = thumbSize.iHeight;
         }
    else if ( targetSize.iHeight * thumbSize.iWidth
             < targetSize.iWidth * thumbSize.iHeight )
         {
         // Source has taller aspect than target so reduce target width
         targetSize.iWidth =  ( ( targetSize.iHeight * thumbSize.iWidth )
                                 / (  thumbSize.iHeight ) );
         }
    else
         {
         // Source has wider aspect than target so reduce target height
         targetSize.iHeight = (targetSize.iWidth * thumbSize.iHeight)
                                 / thumbSize.iWidth;
         }
    GLX_DEBUG3("CGlxtnLoadThumbnailTask::DecodeThumbnailL() targetSize w(%d) h(%d)", 
            targetSize.iWidth, targetSize.iHeight);
     
    User::LeaveIfError( iThumbnail->Resize(targetSize) );

    iDecoder->Convert( &aStatus, *iThumbnail );
    iState = EStateDecodingThumbnail;
    }