ui/commandhandlers/commoncommandhandlers/src/glxcommandhandlerrotate.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:14:51 +0300
branchRCL_3
changeset 59 8e5f6eea9c9f
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 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: 
*
*/

#include <mpxcollectionpath.h>
#include <mglxmedialist.h>
#include <glxcommandfactory.h>
#include <glxcommandhandlerrotate.h>
#include <ExifRead.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "glxcommandhandlerrotateTraces.h"
#endif


GlxCommandHandlerRotate::GlxCommandHandlerRotate()
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_GLXCOMMANDHANDLERROTATE_ENTRY );
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_GLXCOMMANDHANDLERROTATE_EXIT );
    }

GlxCommandHandlerRotate::~GlxCommandHandlerRotate()
    {
    OstTraceFunctionEntry0( DUP1_GLXCOMMANDHANDLERROTATE_GLXCOMMANDHANDLERROTATE_ENTRY );
    OstTraceFunctionExit0( DUP1_GLXCOMMANDHANDLERROTATE_GLXCOMMANDHANDLERROTATE_EXIT );
    }

CMPXCommand* GlxCommandHandlerRotate::CreateCommandL(TInt aCommandId,
        MGlxMediaList& /*aMediaList*/, TBool& aConsume) const
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_CREATECOMMANDL_ENTRY );
    Q_UNUSED(aCommandId);
    Q_UNUSED(aConsume);
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_CREATECOMMANDL_EXIT );
    return NULL;
    }

void GlxCommandHandlerRotate::DoExecuteCommandL(TInt aCommandId,
        MGlxMediaList& aMediaList, TBool& aConsume)
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_DOEXECUTECOMMANDL_ENTRY );
    Q_UNUSED(aCommandId);
    Q_UNUSED(aConsume);
    const TGlxMedia& item = aMediaList.Item(aMediaList.FocusIndex());
    TFileName uri;
    uri.Copy(item.Uri());
    TRAPD(err,RotateImageL(uri));
    if (err != KErrNone)
        {
        OstTrace0( TRACE_NORMAL, GLXCOMMANDHANDLERROTATE_DOEXECUTECOMMANDL, "GlxCommandHandlerRotate::DoExecuteCommandL Exif Update failed" );
        }
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_DOEXECUTECOMMANDL_EXIT );
    }

void GlxCommandHandlerRotate::RotateImageL(TFileName aFileToBeRotated)
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_ROTATEIMAGEL_ENTRY );
    //Start an IFS session
    //File system 
    User::LeaveIfError(iFs.Connect());
    //first initialize the Exif Writer which is responsible for reading and writing the Exif Data
    //Will leave here itself in cases where the Exif data is absent
    InitializeExifWriterL(aFileToBeRotated);
    //read the Orientation tag stored in  the Exif Data
    TUint16 initialOrientation = ReadImageOrientationL();
    //as the image is rotated to 90 degrees clockwise calculate the new orientation by adding that angle
    TUint16 finalOrientation = CalculateFinalOrientationL(initialOrientation);
    // Set the Final Orientation on the file
    SetImageOrientationL(finalOrientation);
    // Clear the sessions acquired
    DestroyExifWriter();
    //close the File Session
    iFs.Close();
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_ROTATEIMAGEL_EXIT );
    }

void GlxCommandHandlerRotate::InitializeExifWriterL(
        TFileName aFileToBeRotated)
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_INITIALIZEEXIFWRITERL_ENTRY );
    User::LeaveIfError(iFileHandle.Open(iFs, aFileToBeRotated, EFileWrite));
    TInt filesize;
    User::LeaveIfError(iFileHandle.Size(filesize));
    iExifData = HBufC8::NewL(filesize);
    TPtr8 ptr(iExifData->Des());
    User::LeaveIfError(iFileHandle.Read(ptr));
    iExifWriter = CExifModify::NewL(*iExifData, CExifModify::EModify,
            CExifModify::ENoJpegParsing);
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_INITIALIZEEXIFWRITERL_EXIT );
    }

TUint16 GlxCommandHandlerRotate::ReadImageOrientationL()
{
	OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_READIMAGEORIENTATIONL_ENTRY );
	TUint16 initialOrientation;
	const CExifRead* exifReader = iExifWriter->Reader(); //not owned
    User::LeaveIfError(exifReader->GetOrientation(initialOrientation));
	OstTrace1( TRACE_NORMAL, GLXCOMMANDHANDLERROTATE_READIMAGEORIENTATIONL, "GlxCommandHandlerRotate::ReadImageOrientationL;initial orientation=%d", initialOrientation );
	OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_READIMAGEORIENTATIONL_EXIT );
	return (initialOrientation);
}

TUint16 GlxCommandHandlerRotate::CalculateFinalOrientationL(
        TUint16 aInitialOrientation)
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_CALCULATEFINALORIENTATIONL_ENTRY );
    /*
     * possible orientation state with angles for rotation
     * Possible Angles 0 - 90 - 180 - 270
     * Possible states 1 - 8 - 3 - 6 without a Flip
     * Possible states 2 - 7 - 4 - 5 when Flip is on
     */
    TUint16 finalOrientation = aInitialOrientation;
    if (aInitialOrientation > 8)
        {
        //invalid orientation passed Leave
        User::Leave(KErrCorrupt);
        }
    TInt rotOffset = 1;
    TInt isOrientationOdd = aInitialOrientation % 2;
    TInt initStateIndex = 0;
    TInt finalStateIndex = 0;
    //Setting the orientation states for the initial unflipped orientation combinations
    TInt orientationStateArray[] =
        {
        1, 8, 3, 6
        };
    //Seting the index for current orientation
    if (aInitialOrientation < 3)
        {
        initStateIndex = 0;
        }
    else if (aInitialOrientation >= 3 && aInitialOrientation < 5)
        {
        initStateIndex = 2;
        }
    else if (aInitialOrientation >= 5 && aInitialOrientation < 7)
        {
        initStateIndex = 3;
        }
    else if (aInitialOrientation >= 7 && aInitialOrientation <= 8)
        {
        initStateIndex = 1;
        }
    //Calculating the final orientation using the cyclic orientationStateArray. 
    //folding final index so that it behaves like a cyclic machine 
    finalStateIndex = (initStateIndex + rotOffset) % 4;
    finalOrientation = orientationStateArray[finalStateIndex];
    //Checking if a Flip was present 
    if (aInitialOrientation > 4 && isOrientationOdd)
        {
        finalOrientation -= 1;
        }
    if (aInitialOrientation < 5 && !isOrientationOdd)
        {
        finalOrientation += 1;
        }
    OstTrace1( TRACE_NORMAL, GLXCOMMANDHANDLERROTATE_CALCULATEFINALORIENTATIONL, "GlxCommandHandlerRotate::CalculateFinalOrientationL;finalOrientation=%d", finalOrientation );
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_CALCULATEFINALORIENTATIONL_EXIT );
    return finalOrientation;
    }

void GlxCommandHandlerRotate::SetImageOrientationL(TUint16 aFinalOrientation)
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_SETIMAGEORIENTATIONL_ENTRY );
    iExifWriter->SetOrientationL(aFinalOrientation);
    HBufC8* modifiedexifData = NULL;
    modifiedexifData = iExifWriter->WriteDataL(iExifData->Des());
    User::LeaveIfError(iFileHandle.Write(0, modifiedexifData->Des()));
    delete modifiedexifData;
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_SETIMAGEORIENTATIONL_EXIT );
    }

void GlxCommandHandlerRotate::DestroyExifWriter()
    {
    OstTraceFunctionEntry0( GLXCOMMANDHANDLERROTATE_DESTROYEXIFWRITER_ENTRY );
    iFileHandle.Close();
    if (iExifData != NULL)
        {
        delete iExifData;
        iExifData = NULL;
        }
    if (iExifWriter != NULL)
        {
        delete iExifWriter;
        iExifWriter = NULL;
        }
    OstTraceFunctionExit0( GLXCOMMANDHANDLERROTATE_DESTROYEXIFWRITER_EXIT );
    }