ui/commandhandlers/commoncommandhandlers/src/glxcommandhandlerrotate.cpp
changeset 23 74c9f037fd5d
child 24 99ad1390cd33
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/commandhandlers/commoncommandhandlers/src/glxcommandhandlerrotate.cpp	Fri Mar 19 09:28:59 2010 +0200
@@ -0,0 +1,173 @@
+/*
+* 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;
+        } 
+}