ui/commandhandlers/commoncommandhandlers/src/glxcommandhandlerrotate.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Mar 2010 09:28:59 +0200
changeset 23 74c9f037fd5d
child 24 99ad1390cd33
permissions -rw-r--r--
Revision: 201007 Kit: 201011

/*
* 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 <QDebug>
#include <ExifRead.h>

GlxCommandHandlerRotate::GlxCommandHandlerRotate()
{
    qDebug("GlxCommandHandlerRotate::GlxCommandHandlerRotate() ");
}

GlxCommandHandlerRotate::~GlxCommandHandlerRotate()
{
    qDebug("GlxCommandHandlerRotate::~GlxCommandHandlerRotate() ");
}

CMPXCommand* GlxCommandHandlerRotate::CreateCommandL(TInt aCommandId, MGlxMediaList& aMediaList, TBool& aConsume) const 
{
	Q_UNUSED(aCommandId);
	Q_UNUSED(aConsume);
    qDebug("GlxCommandHandlerRotate::CreateCommandL");
    return NULL;
}

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

	}
}
void GlxCommandHandlerRotate::RotateImageL(TFileName aFileToBeRotated)
{
	//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();
}

void GlxCommandHandlerRotate::InitializeExifWriterL(TFileName aFileToBeRotated)
{
	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);
}

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

TUint16 GlxCommandHandlerRotate::CalculateFinalOrientationL(TUint16 aInitialOrientation)
{
	/*
     * 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;
        }
	qDebug("GlxCommandHandlerRotate::CalculateFinalOrientationL final orientation = %d", finalOrientation);
    return finalOrientation;
}

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

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