IEBgps/src/IEFaceBrowser.cpp
changeset 3 93fff7023be8
equal deleted inserted replaced
2:e1e28b0273b0 3:93fff7023be8
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors: Juha Kauppinen, Mika Hokkanen
       
    13 * 
       
    14 * Description: Photo Browser
       
    15 *
       
    16 */
       
    17 
       
    18 // Include files
       
    19 #include <e32debug.h>
       
    20 #include <e32math.h>
       
    21 #include <exifmodify.h>
       
    22 #include <BAUTILS.H>
       
    23 #include "IEFaceBrowser.h"
       
    24 #include "IEBgpsInfo.h"
       
    25 #include "IEImageData.h"
       
    26 #include "ImagicConsts.h"
       
    27 #include "debug.h"
       
    28 #include <hal.h>
       
    29 
       
    30 // ================= MEMBER FUNCTIONS ================================ //
       
    31 CFaceBrowser* CFaceBrowser::NewLC(
       
    32         RFs& aFileServer, 
       
    33         MIEFaceBrowserObserver& aFaceBrowserObserver)
       
    34     {
       
    35     DP0_IMAGIC(_L("CFaceBrowser::NewLC ++"));
       
    36     
       
    37     CFaceBrowser* self = new (ELeave) CFaceBrowser(aFileServer, aFaceBrowserObserver);
       
    38     CleanupStack::PushL(self);
       
    39     self->ConstructL();
       
    40     CleanupStack::Pop();
       
    41     
       
    42     DP0_IMAGIC(_L("CFaceBrowser::NewLC --"));
       
    43     
       
    44     return self;
       
    45     }
       
    46 
       
    47 CFaceBrowser::CFaceBrowser(
       
    48         RFs& aFileServer, 
       
    49         MIEFaceBrowserObserver& aFaceBrowserObserver) :
       
    50         iUtils(iFileServer),
       
    51         iFileServer(aFileServer), 
       
    52         iFaceBrowserObserver(aFaceBrowserObserver), 
       
    53         CActive(EPriorityIdle)
       
    54     {
       
    55     
       
    56     }
       
    57 
       
    58 CFaceBrowser::~CFaceBrowser()
       
    59     {
       
    60     DP0_IMAGIC(_L("CFaceBrowser::~CFaceBrowser ++"));
       
    61     
       
    62     if(iImageDecoder)
       
    63         {
       
    64         iImageDecoder->CancelDecoding();
       
    65         
       
    66         delete iImageDecoder;
       
    67         iImageDecoder = NULL;
       
    68         }
       
    69     
       
    70     if(iImageEncoder)
       
    71         {
       
    72         iImageEncoder->CancelEncoding();
       
    73         
       
    74         delete iImageEncoder;
       
    75         iImageEncoder = NULL;
       
    76         }
       
    77     
       
    78     if(iSymbianImageDecoder)
       
    79     {
       
    80         delete iSymbianImageDecoder;
       
    81         iSymbianImageDecoder = NULL;   
       
    82     }
       
    83     
       
    84     if(IsActive())
       
    85         Cancel();
       
    86     
       
    87 #ifdef IDL_BGPS
       
    88     if(iIDLImageProcessor)
       
    89         {
       
    90         delete iIDLImageProcessor;
       
    91         iIDLImageProcessor = NULL;
       
    92         }
       
    93 #endif
       
    94     
       
    95     if(iInputBuffer)
       
    96         {
       
    97         delete iInputBuffer;
       
    98         iInputBuffer = NULL;
       
    99         }
       
   100     
       
   101     if(iOutputBuffer)
       
   102         {
       
   103         delete iOutputBuffer;
       
   104         iOutputBuffer = NULL;
       
   105         }
       
   106     
       
   107     if(iFaceYuvDataArray.Count() > 0)
       
   108         {
       
   109         TCroppedFaces croppedFace;
       
   110         HBufC8* buffer = NULL;
       
   111         TInt count = iFaceYuvDataArray.Count();
       
   112         for(TInt i=0; i<count; i++)
       
   113             {
       
   114             croppedFace = iFaceYuvDataArray[0];
       
   115             buffer = croppedFace.iYuvdata;
       
   116             
       
   117             iFaceYuvDataArray.Remove(0);
       
   118             
       
   119             delete buffer;
       
   120             buffer = NULL;
       
   121             }
       
   122         }
       
   123     
       
   124     iFaceYuvDataArray.Close();
       
   125     
       
   126     if(iImageDataArray.Count() > 0)
       
   127         {
       
   128         TInt count = iImageDataArray.Count();
       
   129         for(TInt i=0; i<count; i++)
       
   130             iImageDataArray.Remove(0);
       
   131         }
       
   132 
       
   133     iImageDataArray.Close();
       
   134     
       
   135     iFaceCoordinates.Close();
       
   136     if (iTempFaceCoordinates)
       
   137         iTempFaceCoordinates->Close();
       
   138    
       
   139     DP0_IMAGIC(_L("CFaceBrowser::~CFaceBrowser --"));    
       
   140     }
       
   141 
       
   142 void CFaceBrowser::ConstructL()
       
   143     {
       
   144     TInt error = KErrNone;
       
   145     
       
   146     DP0_IMAGIC(_L("CFaceBrowser::ConstructL ++"));
       
   147     
       
   148     CActiveScheduler::Add(this);
       
   149     
       
   150     iImageDecoder = CIEImageDecoder::NewL(iFileServer, *this);
       
   151     
       
   152     iImageEncoder = CIEImageEncoder::NewL(iFileServer, *this);
       
   153     
       
   154 #ifdef IDLBGPS
       
   155     iIDLImageProcessor = CIDLImageProcessing::NewL(*this);
       
   156 #endif
       
   157     
       
   158     iBrowsingState = EStateIdle;
       
   159     
       
   160     iNumberOfImages = 0;
       
   161     iNumberOfImagesBrowsed = 0;
       
   162     iNumberOfFacesCropped = 0;    
       
   163     iNumberOfFaces = 0;
       
   164     iTotalNumberOfFaces = 0;
       
   165       
       
   166     //RDebug::Print(_L("IDL_Engine_Create error = %d"), error);
       
   167     
       
   168     if(error != KErrNone)
       
   169         User::Leave(error);
       
   170     
       
   171     DP0_IMAGIC(_L("CFaceBrowser::ConstructL --"));    
       
   172     }
       
   173 
       
   174 void CFaceBrowser::RunL()
       
   175     {
       
   176     DP0_IMAGIC(_L("CFaceBrowser::RunL ++"));
       
   177     
       
   178     TInt error = KErrNone;
       
   179     
       
   180     switch(iBrowsingState)
       
   181         {
       
   182         case ECreatingBitmap:
       
   183             {
       
   184             DP0_IMAGIC(_L("CFaceBrowser::RunL() - ECreatingBitmap"));
       
   185             TInt error = iStatus.Int();
       
   186             if(iSymbianImageDecoder)
       
   187                 {
       
   188                 delete iSymbianImageDecoder;
       
   189                 iSymbianImageDecoder = NULL;   
       
   190                 }
       
   191 #ifdef IDL_BGPS
       
   192             ContinueFBAfterImageConversionL();
       
   193 #else
       
   194             //ExecuteFaceDetectionL();
       
   195 #endif
       
   196             }
       
   197             break;
       
   198         
       
   199         case EFaceBrowsingRunning:
       
   200             {
       
   201             DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingRunning"));
       
   202             
       
   203             TRAP(error, BrowseFacesL(iImageDataArray[iNumberOfImagesBrowsed]));
       
   204             
       
   205             if(error != KErrNone)
       
   206                 {
       
   207                 Cleanup();
       
   208                 iFaceBrowserObserver.FaceBrowsingError(error);
       
   209                 }                
       
   210             }
       
   211             break;
       
   212         
       
   213         case ESingleFaceBrowsingRunning:
       
   214             {
       
   215             DP0_IMAGIC(_L("CFaceBrowser::RunL() - ESingleFaceBrowsingRunning"));
       
   216             
       
   217             //TRAP(error, BrowseFacesL(iImageDataArray[iSingleFaceBrowsingIndex]));
       
   218             TRAP(error, BrowseFacesL(iCurrentImageData));
       
   219             
       
   220             if(error != KErrNone)
       
   221                 {
       
   222                 Cleanup();
       
   223                 iFaceBrowserObserver.FaceBrowsingError(error);
       
   224                 }                
       
   225             }
       
   226             break;
       
   227 
       
   228         case EFaceBrowsingPaused:
       
   229             {
       
   230             DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingPaused"));
       
   231             }
       
   232             break;
       
   233             
       
   234         case EFaceBrowsingStopped:
       
   235             {
       
   236             DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingStopped"));
       
   237             
       
   238             Cleanup();
       
   239             }
       
   240             break;
       
   241             
       
   242         case EFaceBrowsingCompleted:
       
   243             {
       
   244             DP0_IMAGIC(_L("CFaceBrowser::RunL() - EFaceBrowsingCompleted"));
       
   245             
       
   246             Cleanup();
       
   247             iFaceBrowserObserver.FaceBrowsingComplete();
       
   248             }
       
   249             break;
       
   250             
       
   251         case ESingleFaceBrowsingComplete:
       
   252             {
       
   253             DP0_IMAGIC(_L("CFaceBrowser::RunL() - ESingleFaceBrowsingComplete"));
       
   254             
       
   255             Cleanup2();
       
   256             iFaceBrowserObserver.FaceSingleFaceBrowsingComplete();
       
   257             }
       
   258             break;
       
   259                                
       
   260         default:
       
   261             break;
       
   262         }
       
   263     
       
   264     DP0_IMAGIC(_L("CFaceBrowser::RunL --"));    
       
   265     }
       
   266 
       
   267 
       
   268 void CFaceBrowser::CheckCroppedFaceFileNames()
       
   269     {
       
   270     DP0_IMAGIC(_L("CFaceBrowser::CheckCroppedFaceFileNames"));
       
   271     
       
   272     TInt count = iFaceYuvDataArray.Count();
       
   273     //Check that file was really cropped
       
   274     for(TInt i=0; i<count; i++)
       
   275         {
       
   276         if(BaflUtils::FileExists(iFileServer, iFaceYuvDataArray[i].iFileName))
       
   277             {
       
   278             //do nothing
       
   279             }
       
   280         else
       
   281             {
       
   282             iFaceYuvDataArray.Remove(i);
       
   283             }
       
   284         //CImageData* data = new CImageData;
       
   285         //data->iMGFilename = iFaceYuvDataArray[i].iFileName;
       
   286         //iImageDataArray.Append(data);
       
   287         }
       
   288     }
       
   289             
       
   290 
       
   291 void CFaceBrowser::DoCancel()
       
   292     {
       
   293     DP0_IMAGIC(_L("CFaceBrowser::DoCancel ++"));
       
   294     
       
   295     iImageDecoder->CancelDecoding();
       
   296     iImageEncoder->CancelEncoding();
       
   297     
       
   298     DP0_IMAGIC(_L("CFaceBrowser::DoCancel --"));
       
   299     }
       
   300 
       
   301 TInt CFaceBrowser::RunError(TInt aError)
       
   302     {
       
   303     DP1_IMAGIC(_L("CFaceBrowser::RunError - Error: %d"), aError);
       
   304     return aError;
       
   305     }
       
   306 
       
   307 void CFaceBrowser::BitmapReady(TInt /*aError*/)
       
   308     {
       
   309     
       
   310     }
       
   311 
       
   312 // =============================== PUBLIC FUNCTIONS ============================== //
       
   313 
       
   314 void CFaceBrowser::StartFaceBrowsing(RArray<CImageData*> aImageDataArray)
       
   315     {
       
   316     DP0_IMAGIC(_L("CFaceBrowser::StartFaceBrowsing ++"));
       
   317     
       
   318     if(iBrowsingState != EStateIdle)
       
   319         iFaceBrowserObserver.FaceBrowsingError(KErrInUse); // Better error code ?
       
   320     
       
   321     if(aImageDataArray.Count() == 0)
       
   322         {
       
   323         DP0_IMAGIC(_L("ImageDataArray is empty!!!!"));
       
   324         iFaceBrowserObserver.FaceBrowsingError(KErrArgument);
       
   325         }
       
   326     else
       
   327         {
       
   328         iBrowsingState = EFaceBrowsingRunning;
       
   329         //Take local copy of imagedata array
       
   330         for(TInt i=0; i<aImageDataArray.Count(); i++)
       
   331             {
       
   332             if(!aImageDataArray[i]->iGridData.iCorrupted)
       
   333                 iImageDataArray.Append(aImageDataArray[i]);
       
   334             }
       
   335         
       
   336         iNumberOfImages = iImageDataArray.Count();
       
   337         
       
   338         DP1_IMAGIC(_L("Number of images: %d"), iNumberOfImages);        
       
   339         ContinueLoop();        
       
   340         }
       
   341     
       
   342     DP0_IMAGIC(_L("CFaceBrowser::StartFaceBrowsing --"));    
       
   343     }
       
   344 
       
   345 //void CFaceBrowser::StartSingleFaceDetection(TInt aIndex, RArray<TRect>* aImageCoordArray)
       
   346 //void CFaceBrowser::StartSingleFaceDetection(TInt aIndex, RArray<TRect>* aImageCoordArray, RArray<CImageData*> aImageDataArray)
       
   347 void CFaceBrowser::StartSingleFaceBrowsing(TInt aIndex, RArray<TRect>* aImageCoordArray, CImageData* aImageData)
       
   348     {
       
   349     DP0_IMAGIC(_L("CFaceBrowser::StartSingleFaceBrowsing ++"));
       
   350     
       
   351     iCurrentImageData = aImageData;
       
   352     iSingleFaceBrowsingIndex = aIndex;
       
   353     iTempFaceCoordinates = aImageCoordArray;
       
   354     
       
   355     if(iBrowsingState != EStateIdle)
       
   356         iFaceBrowserObserver.FaceBrowsingError(KErrInUse); // Better error code ?
       
   357     
       
   358     iBrowsingState = ESingleFaceBrowsingRunning;
       
   359     
       
   360     /*//Take local copy of imagedata array
       
   361     for(TInt i=0; i<aImageDataArray.Count(); i++)//TODO, copy only one array element, not all in alrray
       
   362         {
       
   363         if(!aImageDataArray[i]->iGridData.iCorrupted)
       
   364             iImageDataArray.Append(aImageDataArray[i]);
       
   365         }
       
   366     */
       
   367     iNumberOfImages = iImageDataArray.Count();
       
   368   
       
   369     DP0_IMAGIC(_L("CFaceBrowser::StartSingleFaceBrowsing --"));
       
   370     ContinueLoop();        
       
   371     }
       
   372 
       
   373 void CFaceBrowser::CancelFaceBrowsing()
       
   374     {
       
   375     DP0_IMAGIC(_L("CFaceBrowser::CancelFaceBrowsing ++"));
       
   376     
       
   377     Cleanup2();
       
   378     
       
   379     if(IsActive())
       
   380         Cancel();
       
   381     
       
   382     //Cleanup();//TODO, check if this is needed
       
   383     
       
   384     DP0_IMAGIC(_L("CFaceBrowser::CancelFaceBrowsing ++"));
       
   385     }
       
   386 
       
   387 TInt CFaceBrowser::FindFaces(const TFileName a512x512TNFileName, RArray<TRect>& aCordArray)
       
   388     {
       
   389     DP1_IMAGIC(_L("CFaceBrowser::FindFaces, a512x512TNFileName = %S ++"), &a512x512TNFileName);
       
   390     
       
   391     TInt error = KErrNone;
       
   392     
       
   393     TRAP(error, iUtils.ReadFaceCoordinatesL(a512x512TNFileName, aCordArray));
       
   394     if(error != KErrNone) return error;
       
   395     
       
   396     DP0_IMAGIC(_L("CFaceBrowser::FindFaces --"));
       
   397     
       
   398     return error;    
       
   399     }
       
   400 
       
   401 TInt CFaceBrowser::GetNumberOfFaces(const TFileName /*aFile*/)
       
   402     {
       
   403     return 0;
       
   404     }
       
   405 
       
   406 //void CIEEngineImp::RemoveExifFaceCoordsL(const TDes& aFilename, TPoint aTlCoord, TPoint aBrCoord, TInt aFaceNumber)
       
   407 
       
   408 
       
   409 TInt CFaceBrowser::RemoveFaceCoordinate(const TFileName a512x512TNFileName, RArray<TRect>& aCordArray)
       
   410     {
       
   411     DP0_IMAGIC(_L("CFaceBrowser::RemoveFaceCoordinate++"));
       
   412     
       
   413      //Read first current make note
       
   414      TInt makerNoteSize;
       
   415      HBufC8* makerNote = ReadExifMakerNoteL(a512x512TNFileName, makerNoteSize);
       
   416      
       
   417      //Read first current maker note to new array from given file
       
   418      //RArray<TRect> newCordArray;
       
   419      //ReadFaceCoordinatesL(a512x512TNFileName, newCordArray);
       
   420      
       
   421      //Allocate buffer for coords to be removed
       
   422      HBufC8* heapComment = HBufC8::NewL(100);
       
   423      TPtr8 ptrCoords = heapComment->Des();
       
   424      //Copy coords to be removed to descriptor
       
   425      for(TInt i=0; i < aCordArray.Count(); i++)
       
   426          {
       
   427          ptrCoords.AppendNum(aCordArray[i].iTl.iX);
       
   428          ptrCoords.Append(' ');
       
   429          ptrCoords.AppendNum(aCordArray[i].iTl.iY);
       
   430          ptrCoords.Append(' ');
       
   431          ptrCoords.AppendNum(aCordArray[i].iBr.iX );
       
   432          ptrCoords.Append(' ');
       
   433          ptrCoords.AppendNum(aCordArray[i].iBr.iY);
       
   434          ptrCoords.Trim();
       
   435          }
       
   436      
       
   437      //Find coordinates from maker note
       
   438      TPtr8 tmpPtr = makerNote->Des();
       
   439      TInt res = tmpPtr.Find(ptrCoords);
       
   440      
       
   441      if(res == KErrNotFound)
       
   442          return res;
       
   443          
       
   444      //Remove coordinates from maker note
       
   445      TInt l = ptrCoords.Length();
       
   446      tmpPtr.Delete(res, ptrCoords.Length()+1);
       
   447      
       
   448      //Find number of faces from maker note and update it
       
   449      _LIT8(KNumberOfFace, "#");
       
   450      res = tmpPtr.Find(KNumberOfFace);
       
   451      
       
   452      TLex8 lex(makerNote->Ptr());
       
   453      lex.SkipAndMark(res+1);
       
   454      TInt faceCount = 0;
       
   455      lex.Val(faceCount);
       
   456      
       
   457      //Check lenght of number of faces string
       
   458      TInt length = 0;
       
   459      //TInt aFaceNumber = 1;
       
   460      if(faceCount < 10)
       
   461          length = 1;
       
   462      else
       
   463          length = 2;
       
   464           
       
   465      HBufC8* numberOfFaces = HBufC8::NewL(length);
       
   466      TPtr8 FaceNroPtr = numberOfFaces->Des();
       
   467      FaceNroPtr.AppendNum(faceCount-1);
       
   468               
       
   469      tmpPtr.Replace(res+1, length, FaceNroPtr);
       
   470      //TPtr8 numberOfFaces;
       
   471      
       
   472      delete numberOfFaces;
       
   473      //numberOfFaces.Copy();
       
   474      
       
   475      
       
   476      // 1. Read JPEG image from the file to a buffer...
       
   477      RFile file;
       
   478      User::LeaveIfError( file.Open( iFileServer, a512x512TNFileName, EFileWrite ) );
       
   479      CleanupClosePushL( file );
       
   480      TInt size = 0;
       
   481      file.Size(size);
       
   482      HBufC8* jpegImage = HBufC8::NewL( size );
       
   483      CleanupStack::PushL( jpegImage );
       
   484      TPtr8 bufferDes( jpegImage->Des() );
       
   485      User::LeaveIfError( file.Read( bufferDes ) );
       
   486      CleanupStack::Pop( jpegImage );
       
   487      CleanupStack::PopAndDestroy();
       
   488      CleanupStack::PushL( jpegImage );
       
   489      
       
   490      file.Close();
       
   491      
       
   492      // 2. Instantiate Exif modifier in ECreate mode...
       
   493      CExifModify* modify = CExifModify::NewL( jpegImage->Des(), CExifModify::EModify );
       
   494      CleanupStack::PushL( modify );
       
   495      
       
   496      //3. Insert (Set) at least the mandatory Exif data.
       
   497      //TInt descSize = 300;
       
   498      //HBufC8* heapComment = HBufC8::NewL(descSize);
       
   499      TPtr8 ptr = makerNote->Des();
       
   500      
       
   501      modify->SetMakerNoteL(ptr);
       
   502      //modify->SetMakerNoteL(makerNote->Des());
       
   503      
       
   504      
       
   505      // 4. Get the new Exif image...
       
   506      // If zero length descriptor is given instead of jpeg->Des(), then only the
       
   507      // Exif meta data is returned.
       
   508      //HBufC8* newExif = modify->WriteDataL( jpegImage->Des() );
       
   509      HBufC8* newExif;
       
   510      TRAPD(err, newExif = modify->WriteDataL( jpegImage->Des() ));
       
   511      
       
   512      if(err != KErrNone)
       
   513          {
       
   514          TInt i=0;
       
   515          }
       
   516      
       
   517      //TPtr8 tmp = newExif->Des();
       
   518      
       
   519      User::LeaveIfError( file.Replace( iFileServer, a512x512TNFileName, EFileWrite ) );
       
   520      //Write Exif and jpeg image back to jpeg file
       
   521      User::LeaveIfError(file.Write(*newExif));
       
   522      
       
   523      // Process the new Exif data
       
   524      delete newExif;
       
   525      newExif = NULL;
       
   526      
       
   527      // 5. Delete the modifier instance...
       
   528      CleanupStack::PopAndDestroy( modify );
       
   529      CleanupStack::PopAndDestroy( jpegImage );
       
   530      
       
   531      file.Close();
       
   532     
       
   533     DP0_IMAGIC(_L("CFaceBrowser::RemoveFaceCoordinate--"));
       
   534     return KErrNone;
       
   535     }
       
   536 
       
   537 
       
   538 //Writes face coordinates to Exif data if faces was found
       
   539 TInt CFaceBrowser::AddFaceCoordinate(const TFileName aFilename, RArray<TRect>& aCordArray)
       
   540     {
       
   541     DP0_IMAGIC(_L("CFaceBrowser::AddFaceCoordinate++"));
       
   542     //Read first current maker note to new array from given file
       
   543     RArray<TRect> newCordArray;
       
   544     iUtils.ReadFaceCoordinatesL(aFilename, newCordArray);
       
   545      
       
   546     //Append existing coords to new coords array
       
   547     for(TInt i=0; i<newCordArray.Count(); i++)
       
   548         {
       
   549         aCordArray.Append(newCordArray[i]);
       
   550         }
       
   551               
       
   552      //Write all coords to file exif data manufactorer note
       
   553     iUtils.WriteFaceCoordinatesL(aFilename, aCordArray);
       
   554      
       
   555     newCordArray.Close();
       
   556     
       
   557     DP0_IMAGIC(_L("CFaceBrowser::AddFaceCoordinate--"));
       
   558 
       
   559     return KErrNone;
       
   560     }
       
   561 
       
   562 
       
   563 HBufC8* CFaceBrowser::ReadExifMakerNoteL(const TDes &aFileName, TInt& aSize)
       
   564     {
       
   565     DP0_IMAGIC(_L("CFaceBrowser::ReadExifMakerNoteL++"));
       
   566     HBufC8* makerNote;
       
   567     
       
   568     // 1. Read Exif image from the file to a buffer...
       
   569     RFile file;
       
   570     User::LeaveIfError( file.Open( iFileServer, aFileName , EFileRead ) );
       
   571     CleanupClosePushL( file );
       
   572     TInt size = 65536;
       
   573         
       
   574     HBufC8* exif = HBufC8::NewL( size );
       
   575     CleanupStack::PushL( exif );
       
   576     TPtr8 bufferDes( exif->Des() ); 
       
   577     TInt err1 = file.Read( bufferDes );
       
   578     TInt length = bufferDes.Length();
       
   579     
       
   580     if(length <= 0 )
       
   581         {
       
   582         CleanupStack::Pop( exif );
       
   583         CleanupStack::PopAndDestroy();
       
   584         //return NULL;
       
   585         }
       
   586     else
       
   587         {
       
   588         CleanupStack::Pop( exif );
       
   589         CleanupStack::PopAndDestroy();
       
   590         CleanupStack::PushL( exif );
       
   591         
       
   592         // 2. Instantiate Exif reader...
       
   593         CExifRead* ExifRead;
       
   594         TInt err = 0;
       
   595         TRAP(err, ExifRead = CExifRead::NewL( exif->Des(),CExifRead::ENoJpeg ));//CExifRead::ENoTagChecking | CExifRead::ENoJpeg
       
   596         
       
   597         //HBufC8* comment = NULL;
       
   598         if(err != KErrNone)
       
   599             {
       
   600             }
       
   601         else
       
   602             {
       
   603             CleanupStack::PushL( ExifRead );
       
   604         
       
   605             // 3. Get required data from the Exif image...
       
   606             TUint32  xRes;
       
   607             TUint32  yRes;
       
   608             ExifRead->GetPixelXDimension(xRes);
       
   609             ExifRead->GetPixelYDimension(yRes);  
       
   610                     
       
   611             makerNote = ExifRead->GetMakerNoteL(); 
       
   612             
       
   613             // Delete the reader instance...
       
   614             CleanupStack::PopAndDestroy( ExifRead );
       
   615             }
       
   616        
       
   617         file.Close();
       
   618         CleanupStack::PopAndDestroy( exif );
       
   619         //DP0_IMAGIC(_L("CIEEngineImp::ReadExifData--"));
       
   620         
       
   621         if(makerNote == NULL)
       
   622             {
       
   623             User::Leave(KErrNotFound);
       
   624             }
       
   625         else
       
   626             {
       
   627             aSize = makerNote->Length();
       
   628             //return (TUint8*)makerNote->Des().Ptr();
       
   629             return makerNote;
       
   630             }
       
   631         //return comment->Des()->Ptr();
       
   632         
       
   633         }
       
   634     DP0_IMAGIC(_L("CFaceBrowser::ReadExifMakerNoteL--"));
       
   635     
       
   636     return NULL;
       
   637     }
       
   638 
       
   639     
       
   640 // ================================ FACE BROWSING RELATED FUNCTIONS =============================== //
       
   641 
       
   642 //This is called from RunL when face browsing is started
       
   643 void CFaceBrowser::BrowseFacesL(CImageData* aImageData)
       
   644     {
       
   645     DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL++"));
       
   646     
       
   647     if(iBrowsingState != EFaceBrowsingRunning && iBrowsingState != ESingleFaceBrowsingRunning)
       
   648         User::Leave(KErrNotSupported);
       
   649     
       
   650     TBool coordnatesExists = EFalse;
       
   651     iCurrentImageData = aImageData;
       
   652     
       
   653     TFileName filename;
       
   654     iCurrentImageData->GetFileName(filename, ESize512x512);
       
   655     DP1_IMAGIC(_L("CFaceBrowser::BrowseFacesL 512x512TNFile = %S ++"), &filename);
       
   656     
       
   657     // 512x512 TN are supposed to be created in TN generation phase and should be present
       
   658     if(!iCurrentImageData->IsImageReady(ESize512x512))
       
   659         {
       
   660         Cleanup();
       
   661         User::Leave(KErrNotFound);
       
   662         }        
       
   663     else
       
   664         {
       
   665         iCurrentImageData->GetFileName(iCurrent512x512TNFileName, ESize512x512); //target file to write face coords
       
   666         }
       
   667     
       
   668     //If coordinates exist we do not process image anymore
       
   669     TRAPD(error, iUtils.ReadFaceCoordinatesL(iCurrent512x512TNFileName, iFaceCoordinates));
       
   670     if (error == KErrNone)
       
   671         {
       
   672         if(iBrowsingState == ESingleFaceBrowsingRunning)
       
   673             {
       
   674             if(iBrowsingState == ESingleFaceBrowsingRunning)
       
   675                  for(TInt i = 0; i<iFaceCoordinates.Count(); i++)
       
   676                     iTempFaceCoordinates->Append(iFaceCoordinates[i]);
       
   677             
       
   678             iBrowsingState = ESingleFaceBrowsingComplete;
       
   679             }
       
   680         else
       
   681             {
       
   682             //Increment to the next image index
       
   683             iNumberOfImagesBrowsed++;
       
   684             //Check if we are at the end of image array
       
   685             if(iNumberOfImagesBrowsed == iNumberOfImages)
       
   686                 {
       
   687                 iBrowsingState = EFaceBrowsingCompleted;
       
   688                 }
       
   689             }
       
   690         
       
   691         //and continue to next image
       
   692         ContinueLoop();
       
   693         }
       
   694     //Here we have image which has to be processed for face detection
       
   695     else
       
   696         {
       
   697         iPrevBrowsingState = iBrowsingState;
       
   698         iBrowsingState = ECreatingBitmap;
       
   699         
       
   700         TSize size;
       
   701         if(aImageData->GetAspectRatio() > 1)
       
   702             {
       
   703             size.iWidth=320;
       
   704             size.iHeight=320/aImageData->GetAspectRatio();
       
   705             }
       
   706         else
       
   707             {
       
   708             size.iWidth=320*aImageData->GetAspectRatio();
       
   709             size.iHeight=320;
       
   710             }
       
   711         
       
   712         if(size.iWidth%2 != 0)
       
   713             size.iWidth++;
       
   714         if(size.iHeight%2 != 0)
       
   715             size.iHeight++;
       
   716         
       
   717         iBitmap = new (ELeave) CFbsBitmap();
       
   718         iBitmap->Create(size, EColor16M);
       
   719         
       
   720         iSymbianImageDecoder = CImageDecoder::FileNewL(iFileServer, iCurrent512x512TNFileName, CImageDecoder::EPreferFastDecode);
       
   721         iSymbianImageDecoder->Convert(&iStatus, *iBitmap, 0);
       
   722         
       
   723         if(!IsActive())
       
   724             SetActive();
       
   725         
       
   726         }
       
   727     
       
   728     DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL --"));
       
   729     }
       
   730 
       
   731 #ifdef IDLBGPS
       
   732 void CFaceBrowser::ContinueFBAfterImageConversionL()
       
   733     {
       
   734     DP0_IMAGIC(_L("CFaceBrowser::ContinueFBAfterImageConversionL ++"));
       
   735     
       
   736     iBrowsingState = iPrevBrowsingState;
       
   737     
       
   738     TSize size = iBitmap->SizeInPixels();
       
   739     
       
   740     //Init IDL
       
   741     TInt value = 0;
       
   742     InitializeL(EIDLFeatureFaceDetection, size, size, &value, ETrue);
       
   743     
       
   744     // Code for the previous face detection which needed YUV input
       
   745     //TUint8* yuvArray;
       
   746     //TInt yuvDataSize = size.iHeight * size.iWidth * 3 / 2;
       
   747     //yuvArray = new TUint8 [yuvDataSize];
       
   748     //
       
   749     //ConvertRgb2Yuv(iBitmap, yuvArray, 3/*aBytesPerPixel*/, size);
       
   750     // 
       
   751     //iInputBuffer->Des().Copy(yuvArray, yuvDataSize);
       
   752     
       
   753     TInt bitmapSize = size.iHeight * size.iWidth * 3;
       
   754     
       
   755     // This is in the BGR order
       
   756     iInputBuffer->Des().Copy((TUint8 *)iBitmap->DataAddress(), bitmapSize);
       
   757     //delete yuvArray;
       
   758 #if 0
       
   759     //just for testing --->
       
   760     _LIT(KTestPath, "C:\\Images\\RGB2YUV.YUV");
       
   761     TFileName temp;
       
   762     temp.Copy(KTestPath);
       
   763     
       
   764     RFile file;
       
   765     User::LeaveIfError(file.Replace(iFileServer, temp, EFileWrite));
       
   766     TInt dataSize = iInputBuffer->Size();
       
   767     file.Write(iInputBuffer->Des());
       
   768     //file.Write(yuvArray);
       
   769     file.Flush();
       
   770     file.Close();    
       
   771     //TODO, just for testing <---
       
   772 #endif
       
   773 
       
   774 #if 0
       
   775     //just for testing ---> 
       
   776     _LIT(KTestPath, "C:\\Images\\RawRGB.rgb");
       
   777     TFileName temp;
       
   778     temp.Copy(KTestPath);
       
   779         
       
   780     RFile file;
       
   781     User::LeaveIfError(file.Replace(iFileServer, temp, EFileWrite));
       
   782     TInt dataSize = iInputBuffer->Size();
       
   783     file.Write(iInputBuffer->Des());
       
   784     file.Flush();
       
   785     file.Close();    
       
   786     //just for testing <---
       
   787 #endif
       
   788 
       
   789         
       
   790     TInt error = KErrNone;
       
   791     TRAP(error, BrowseFacesL(iCurrent512x512TNFileName, iFaceCoordinates));
       
   792     
       
   793     if(error != KErrNone)
       
   794         {
       
   795         Cleanup();
       
   796         iFaceBrowserObserver.FaceBrowsingError(error);
       
   797         }
       
   798     
       
   799 #if 0
       
   800     //only for debug
       
   801     _LIT(KTestPath, "C:\\Images\\RGB2YUV.MBM");
       
   802     TFileName temp;
       
   803     temp.Copy(KTestPath);
       
   804     iBitmap->Save(temp);
       
   805 #endif
       
   806     
       
   807     iBitmap->Reset();
       
   808     delete iBitmap;
       
   809     
       
   810     if(iBrowsingState == ESingleFaceBrowsingRunning)
       
   811         iBrowsingState = ESingleFaceDetectionComplete;
       
   812     
       
   813     ContinueLoop();
       
   814     
       
   815     DP0_IMAGIC(_L("CFaceBrowser::ContinueFBAfterImageConversionL --"));
       
   816     }
       
   817 #endif
       
   818 
       
   819 //http://wiki.forum.nokia.com/index.php/TSS001195_-_RGB_to_YUV_conversion
       
   820 void CFaceBrowser::ConvertRgb2Yuv(CFbsBitmap* aSourceBitmap, TUint8* aYuv, TInt aBytesPerPixel, const TSize aSize)
       
   821     {
       
   822     DP0_IMAGIC(_L("CFaceBrowser::ConvertRgb2Yuv++"));
       
   823     
       
   824     // Definitions that help access each colour component in source bitmap
       
   825     #define   sR ((TInt32)(s[2]))
       
   826     #define   sG ((TInt32)(s[1]))
       
   827     #define   sB ((TInt32)(s[0]))
       
   828      
       
   829     const TInt KImageNumPixels = aSize.iHeight*aSize.iWidth;
       
   830      
       
   831     // Lock source bitmap (CFbsBitmap)
       
   832     aSourceBitmap->LockHeap(EFalse);
       
   833     TUint8* s = (TUint8*)aSourceBitmap->DataAddress();
       
   834         
       
   835     TInt i = 0;
       
   836     TInt ui = KImageNumPixels;
       
   837     TInt vi = KImageNumPixels + KImageNumPixels/4;
       
   838        
       
   839     //iYuv is an array of TUint8 values, length (KImageNumPixels*3/2)
       
   840          
       
   841     for(TInt j=0; j < aSize.iHeight; j++)
       
   842         {
       
   843         for(TInt k=0; k < aSize.iWidth; k++)
       
   844             {
       
   845             // Y value is generated for each pixel
       
   846             aYuv[i] = (TUint8)( (  66*sR + 129*sG +  25*sB + 128) >> 8 ) + 16;
       
   847               
       
   848             // U, V values are generated for every other pixel on every other scanline 
       
   849             if(0 == j%2 && 0 == k%2)
       
   850                 {
       
   851                 aYuv[ui++] = (TUint8)( (-38*sR - 74*sG + 112*sB + 128) >> 8 ) + 128;
       
   852                 aYuv[vi++] = (TUint8)( (112*sR - 94*sG - 18*sB + 128) >> 8 ) + 128;
       
   853                 }
       
   854             i++; 
       
   855             s+=aBytesPerPixel; // Number of bytes representing one pixel in source
       
   856                                // bitmap e.g. if bitmap display mode == EColor16M 
       
   857                                // (24bits/pixel), then iBytesPerPixel == 3
       
   858             }
       
   859         }
       
   860        
       
   861     aSourceBitmap->UnlockHeap(EFalse);
       
   862     // iYuv now contains the source frame converted to YUV420p format
       
   863     
       
   864     DP0_IMAGIC(_L("CFaceBrowser::ConvertRgb2Yuv--"));
       
   865     }
       
   866 
       
   867 #ifdef IDLBGPS
       
   868 //This is called after YUV data has been completed
       
   869 void CFaceBrowser::BrowseFacesL(const TFileName a512x512TNFileName, RArray<TRect>& aFaceCoordinates)
       
   870     {
       
   871     DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL ++"));
       
   872     
       
   873        
       
   874     TPtr8 inBuffer = iInputBuffer->Des();
       
   875     TPtr8 outBuffer = iOutputBuffer->Des();
       
   876     
       
   877     iIDLImageProcessor->SetInOutDataL(inBuffer, outBuffer);
       
   878     iIDLImageProcessor->ProcessImageL();
       
   879     
       
   880     TInt count = aFaceCoordinates.Count();
       
   881     for(TInt i=0; i<count; i++)
       
   882         aFaceCoordinates.Remove(0);
       
   883     
       
   884     GetFaceCoordinates(iNumberOfFaces, aFaceCoordinates);
       
   885     
       
   886     //Add number of faces to image data
       
   887     iCurrentImageData->SetNumberOfFaces(iNumberOfFaces);
       
   888     
       
   889     if(iBrowsingState == ESingleFaceBrowsingRunning)
       
   890          for(TInt i = 0; i<aFaceCoordinates.Count(); i++)
       
   891             iTempFaceCoordinates->Append(aFaceCoordinates[i]);
       
   892  
       
   893     iUtils.WriteFaceCoordinatesL(a512x512TNFileName, aFaceCoordinates);
       
   894     
       
   895     if(iBrowsingState == EFaceBrowsingRunning)
       
   896         {
       
   897         if(iBrowsingState == EFaceBrowsingRunning)
       
   898             iNumberOfImagesBrowsed++;
       
   899         
       
   900         if(iNumberOfImagesBrowsed == iNumberOfImages)
       
   901             iBrowsingState = EFaceBrowsingCompleted;
       
   902         }
       
   903     else if(iBrowsingState == ESingleFaceBrowsingRunning)
       
   904         {
       
   905         iBrowsingState = ESingleFaceDetectionComplete;
       
   906         }
       
   907     
       
   908         
       
   909     DP0_IMAGIC(_L("CFaceBrowser::BrowseFacesL --"));
       
   910     }
       
   911 
       
   912 void CFaceBrowser::GetFaceCoordinates(TInt& aNumberOfFaces, RArray<TRect>& aCordArray)
       
   913     {
       
   914     DP0_IMAGIC(_L("CFaceBrowser::GetFaceCoordinates ++"));
       
   915     
       
   916     iIDLImageProcessor->GetFacesDetected(aNumberOfFaces);
       
   917     
       
   918     if(aNumberOfFaces <= 0)
       
   919         DP0_IMAGIC(_L("No faces found!!!"));
       
   920     else
       
   921         {
       
   922         DP1_IMAGIC(_L("Number of faces found: %d"), aNumberOfFaces);
       
   923         
       
   924         // Clean up the coordinate array
       
   925         if(aCordArray.Count() > 0)
       
   926             {
       
   927             TInt count = aCordArray.Count();
       
   928             for(TInt i=0; i<count; i++)
       
   929                 aCordArray.Remove(0);
       
   930             }
       
   931         
       
   932         iIDLImageProcessor->GetFaceCoordinates(aCordArray);
       
   933         aCordArray.SortSigned();
       
   934         }
       
   935     
       
   936     DP0_IMAGIC(_L("CFaceBrowser::GetFaceCoordinates --"));
       
   937     }
       
   938 #endif
       
   939 
       
   940 // =============================== FACE CROPPING RELATED FUNCTIONS ============================ //
       
   941 
       
   942 void CFaceBrowser::CropFacesL(CImageData* aImageData)
       
   943     {
       
   944     DP0_IMAGIC(_L("CFaceBrowser::CropFacesL ++"));
       
   945     
       
   946     TInt error = KErrNone;
       
   947     iCurrentImageData = aImageData;
       
   948     iNumberOfFacesCropped = 0;
       
   949     
       
   950     TFileName imageFileName;
       
   951     aImageData->GetFileName(imageFileName, EFullSize);
       
   952     error = MakeFacesDir(imageFileName);
       
   953     
       
   954     if(error != KErrNone && error != KErrAlreadyExists)
       
   955         User::Leave(error);
       
   956     
       
   957     // 512x512 and 320x320 TN are supposed to be created in TN generation phase and should be present
       
   958     if(!iCurrentImageData->IsImageReady(ESize512x512) || !iCurrentImageData->IsImageReady(EFullSize))
       
   959         {
       
   960         Cleanup();
       
   961         User::Leave(KErrNotFound);
       
   962         }        
       
   963     else
       
   964         {
       
   965         iCurrentImageData->GetFileName(iCurrent512x512TNFileName, ESize512x512);
       
   966         iCurrentImageData->GetFileName(iCurrentImageFileName, EFullSize);
       
   967         }
       
   968     
       
   969     // We assume that all the images were searched for faces before face cropping started
       
   970     // Hence not checking if face coordinates exists or n ot
       
   971     iUtils.ReadFaceCoordinatesL(iCurrent512x512TNFileName, iFaceCoordinates);
       
   972     
       
   973     if(iFaceCoordinates.Count() == 0)
       
   974         {
       
   975         iNumberOfImagesBrowsed++;
       
   976         
       
   977         if(iNumberOfImagesBrowsed == iNumberOfImages)
       
   978             iBrowsingState = EFaceCroppingCompleted;
       
   979                 
       
   980         ContinueLoop();
       
   981         }
       
   982     else
       
   983         {
       
   984         iTotalNumberOfFaces +=  iFaceCoordinates.Count();
       
   985         DP1_IMAGIC(_L("iTotalNumberOfFaces = %d"), iTotalNumberOfFaces);
       
   986         
       
   987         iImageDecoder->GetImageSizeL(iCurrentImageFileName, iSize);
       
   988         
       
   989         if(!CheckOddSize(iSize))
       
   990             {
       
   991             TInt size = iSize.iWidth * iSize.iHeight * 3 / 2;
       
   992                     
       
   993             PrepareInOutBuffersL(ETrue, size, EFalse, 0);
       
   994             
       
   995             iImageDecoder->ConvertJpeg2YuvL(iCurrentImageFileName, *iInputBuffer);
       
   996             }
       
   997         else
       
   998             {
       
   999             iNumberOfImagesBrowsed++;
       
  1000             
       
  1001             if(iNumberOfImagesBrowsed == iNumberOfImages)
       
  1002                 iBrowsingState = EFaceCroppingCompleted;
       
  1003                             
       
  1004             ContinueLoop();
       
  1005             }        
       
  1006         }
       
  1007     
       
  1008     DP0_IMAGIC(_L("CFaceBrowser::CropFacesL --"));
       
  1009     }
       
  1010 
       
  1011 
       
  1012 void CFaceBrowser::CropFacesL(const TFileName /*aImageFileName*/, RArray<TRect>& aFaceCoordinates)
       
  1013     {
       
  1014     DP1_IMAGIC(_L("CFaceBrowser::CropFacesL++, number of faces: %d"), aFaceCoordinates.Count());
       
  1015 
       
  1016 #ifdef IDLBGPS_CROP
       
  1017 
       
  1018     TRect rect(0, 0, 0, 0);
       
  1019     TParse parser;
       
  1020     parser.Set(aImageFileName, NULL, NULL);
       
  1021         
       
  1022     iNumberOfImagesBrowsed++;
       
  1023     
       
  1024     // Clean the face data array
       
  1025     if(iFaceYuvDataArray.Count() > 0)
       
  1026         {
       
  1027         TCroppedFaces temp;
       
  1028         HBufC8* buffer = NULL;
       
  1029         TInt count  = iFaceYuvDataArray.Count();
       
  1030         
       
  1031         for(TInt i=0; i<count; i++)
       
  1032             {
       
  1033             temp = iFaceYuvDataArray[0];
       
  1034             
       
  1035             iFaceYuvDataArray.Remove(0);
       
  1036             
       
  1037             buffer = temp.iYuvdata;
       
  1038             
       
  1039             delete buffer;
       
  1040             buffer = NULL;
       
  1041             }
       
  1042         }
       
  1043     
       
  1044     for(TInt faceIndex=0; faceIndex<aFaceCoordinates.Count(); faceIndex++)
       
  1045         {
       
  1046         TSize tnSize;
       
  1047         TFileName thumbnailFileName;
       
  1048         
       
  1049         iCurrentImageData->GetFileName(thumbnailFileName, ESize32x32);
       
  1050         iImageDecoder->GetImageSizeL(thumbnailFileName, tnSize);
       
  1051         
       
  1052         rect = GetFaceRect(iSize, tnSize, aFaceCoordinates[faceIndex]);
       
  1053         
       
  1054         InitializeL(EIDLFeatureCrop, iSize, rect.Size(), &rect, EFalse);
       
  1055         
       
  1056         TPtr8 inBuffer = iInputBuffer->Des();
       
  1057         TPtr8 outBuffer = iOutputBuffer->Des();
       
  1058         
       
  1059         iIDLImageProcessor->SetInOutDataL(inBuffer, outBuffer);
       
  1060         iIDLImageProcessor->ProcessImageL();
       
  1061         
       
  1062         DP1_IMAGIC(_L("Face cropped: %d"), faceIndex);
       
  1063         
       
  1064         TCroppedFaces croppedFace;
       
  1065         croppedFace.iYuvdata = HBufC8::NewL(iOutputBuffer->Size());
       
  1066         croppedFace.iYuvdata->Des().Copy(iOutputBuffer->Des());
       
  1067         
       
  1068         croppedFace.iFileName.Append(parser.DriveAndPath());
       
  1069         croppedFace.iFileName.Append(KFaces);
       
  1070         croppedFace.iFileName.Append(parser.Name());
       
  1071         croppedFace.iFileName.Append(KUnderScr);
       
  1072         croppedFace.iFileName.AppendNum(faceIndex);
       
  1073         croppedFace.iFileName.Append(parser.Ext());
       
  1074         
       
  1075         croppedFace.iCroppedSize = rect.Size();        
       
  1076         
       
  1077         iFaceYuvDataArray.Append(croppedFace);
       
  1078         iCroppedFilenames->Append(croppedFace.iFileName);
       
  1079         }
       
  1080 #endif
       
  1081     
       
  1082     iBrowsingState = EEncodingFaces;
       
  1083     
       
  1084     DP0_IMAGIC(_L("CFaceBrowser::CropFacesL --"));
       
  1085     }
       
  1086 
       
  1087 TRect CFaceBrowser::GetFaceRect(const TSize aOrgImageSize, const TSize aRelImageSize, const TRect aFaceRect)
       
  1088     {
       
  1089     DP0_IMAGIC(_L("CFaceBrowser::GetFaceRect ++"));
       
  1090 
       
  1091     TRect faceRect(0, 0, 0, 0);
       
  1092     
       
  1093     faceRect.iTl = aFaceRect.iTl;
       
  1094     faceRect.iBr = aFaceRect.iBr;
       
  1095     
       
  1096     TReal width = 0;
       
  1097     TReal height = 0;
       
  1098     TReal aspectRatioX = 0;
       
  1099     TReal aspectRatioY = 0;
       
  1100     
       
  1101     //Converting the face rect to original image size
       
  1102     aspectRatioX = (TReal)aOrgImageSize.iWidth / (TReal)aRelImageSize.iWidth;
       
  1103     aspectRatioY = (TReal)aOrgImageSize.iHeight / (TReal)aRelImageSize.iHeight;
       
  1104     
       
  1105     //Make cropped rect bigger
       
  1106     //faceRect.Grow(faceRect.Width()/4, (faceRect.Height()/2));
       
  1107     faceRect.Grow(faceRect.Width()/2.5, (faceRect.Height()/1.5));
       
  1108     //And move ract bit higher
       
  1109     //faceRect.Move(0, -(faceRect.Height()/6));
       
  1110     faceRect.Move(0, -(faceRect.Height()/8));
       
  1111     
       
  1112     if(aspectRatioX != 1.0 || aspectRatioY != 1.0)
       
  1113         {
       
  1114         //Scale cropping rect size to original  
       
  1115         faceRect.iTl.iX *= aspectRatioX;
       
  1116         faceRect.iTl.iY *= aspectRatioY;
       
  1117         faceRect.iBr.iX *= aspectRatioX;
       
  1118         faceRect.iBr.iY *= aspectRatioY;
       
  1119         
       
  1120         // Check for extreme values and negative values
       
  1121         // Any invalid values will be made max valid values
       
  1122         if(faceRect.iTl.iX < 0) faceRect.iTl.iX = 0;
       
  1123         if(faceRect.iTl.iY < 0) faceRect.iTl.iY = 0;
       
  1124         if(faceRect.iTl.iX >= aOrgImageSize.iWidth) faceRect.iBr.iX = aOrgImageSize.iWidth-1;
       
  1125         if(faceRect.iTl.iY >= aOrgImageSize.iHeight) faceRect.iBr.iY = aOrgImageSize.iHeight-1;
       
  1126         if(faceRect.iBr.iX > aOrgImageSize.iWidth) faceRect.iBr.iX = aOrgImageSize.iWidth;
       
  1127         if(faceRect.iBr.iY > aOrgImageSize.iHeight) faceRect.iBr.iY = aOrgImageSize.iHeight;
       
  1128         
       
  1129         }    
       
  1130     
       
  1131     // Make sure that the width and height are divisible by 2, else encoder/decoder will give -10 error
       
  1132     TReal remainder = 0;
       
  1133     
       
  1134     Math::Mod(remainder, faceRect.Size().iWidth, 2);
       
  1135     
       
  1136     if(remainder != 0)
       
  1137         faceRect.iBr.iX--;
       
  1138     
       
  1139     Math::Mod(remainder, faceRect.Size().iHeight, 2);
       
  1140     
       
  1141     if(remainder != 0)
       
  1142         faceRect.iBr.iY--;
       
  1143 
       
  1144     DP4_IMAGIC(_L("CFaceBrowser::GetFaceRect faceRect(%d, %d, %d, %d)--"), faceRect.iTl.iX, faceRect.iTl.iY, faceRect.iBr.iX, faceRect.iBr.iY);
       
  1145     
       
  1146     return faceRect;
       
  1147     }
       
  1148 
       
  1149 TInt CFaceBrowser::MakeFacesDir(const TFileName aImageName)
       
  1150     {
       
  1151     DP0_IMAGIC(_L("CFaceBrowser::MakeFacesDir ++"));
       
  1152     
       
  1153     TInt error = KErrNone;
       
  1154     
       
  1155     TParse parser;
       
  1156     parser.Set(aImageName, NULL, NULL);
       
  1157     
       
  1158     TFileName faceDir = parser.DriveAndPath();
       
  1159     faceDir.Append(KFaces);
       
  1160     
       
  1161     if(BaflUtils::PathExists(iFileServer, faceDir))
       
  1162         error = KErrAlreadyExists;
       
  1163     else
       
  1164         {
       
  1165         error = iFileServer.MkDir(faceDir);
       
  1166         
       
  1167         if(error == KErrNone)
       
  1168             error = iFileServer.SetAtt(faceDir, KEntryAttNormal, KEntryAttNormal);
       
  1169         }
       
  1170     
       
  1171     DP0_IMAGIC(_L("CFaceBrowser::MakeFacesDir --"));
       
  1172     
       
  1173     return error;
       
  1174     }
       
  1175 
       
  1176 void CFaceBrowser::EncodeFaceL(const TCroppedFaces aCroppedFace)
       
  1177     {
       
  1178     DP0_IMAGIC(_L("CFaceBrowser::EncodeFaceL ++"));
       
  1179     
       
  1180     HBufC8* buffer = aCroppedFace.iYuvdata;
       
  1181    
       
  1182     TFileName fileName = aCroppedFace.iFileName;
       
  1183     TSize size = aCroppedFace.iCroppedSize;
       
  1184     
       
  1185     DP1_IMAGIC(_L("Encoding Image: %S"), &fileName);
       
  1186     DP2_IMAGIC(_L("Size: %dx%d"), size.iWidth, size.iHeight);
       
  1187     
       
  1188     iImageEncoder->ConvertYuv2JpegL(fileName, *buffer, size);
       
  1189     
       
  1190     DP0_IMAGIC(_L("CFaceBrowser::EncodeFaceL --"));
       
  1191     }
       
  1192 
       
  1193 // =============================== COMMON FUNCTIONS ============================================== //
       
  1194 
       
  1195 #ifdef IDLBGPS
       
  1196 void CFaceBrowser::InitializeL(const TIDLFeatures aIDLFeature, const TSize aInSize, const TSize aOutSize, TAny* aValue, TBool aInBufferCreate)
       
  1197     {
       
  1198     DP4_IMAGIC(_L("CFaceBrowser::InitializeL, aInsize = %dx%d, aOutSize = %dx%d ++"), aInSize.iWidth, aInSize.iHeight, aOutSize.iWidth, aOutSize.iHeight);
       
  1199     
       
  1200 //    TInt value = 0;
       
  1201     TInt outputBufferSize = 0;
       
  1202     //TInt inputBufferSize = (aInSize.iWidth * aInSize.iHeight * 3 / 2);
       
  1203     TInt inputBufferSize = aInSize.iWidth * aInSize.iHeight * 3;
       
  1204     
       
  1205     iIDLImageProcessor->SetFeatureL(aIDLFeature, aValue);
       
  1206     //iIDLImageProcessor->InitializeFeatureL(aInSize, 
       
  1207     //                                        aOutSize, 
       
  1208     //                                        EIDLFormatYUV420, 
       
  1209     //                                        EIDLFormatYUV420);
       
  1210     iIDLImageProcessor->InitializeFeatureL(aInSize, 
       
  1211                                                 aOutSize, 
       
  1212                                                 EIDLFormatRGB, 
       
  1213                                                 EIDLFormatRGB);
       
  1214     
       
  1215     iIDLImageProcessor->AllocateBuffersL(outputBufferSize);
       
  1216     
       
  1217     PrepareInOutBuffersL(aInBufferCreate, inputBufferSize, ETrue, outputBufferSize);
       
  1218     
       
  1219     DP0_IMAGIC(_L("CFaceBrowser::InitializeL --"));
       
  1220     }
       
  1221 #endif
       
  1222 
       
  1223 void CFaceBrowser::PrepareInOutBuffersL(TBool aInBufferCreate, const TInt aInBufSize, TBool aOutBufferCreate, const TInt aOutBufSize)
       
  1224     {
       
  1225     DP0_IMAGIC(_L("CFaceBrowser::PrepareInOutBuffersL ++"));
       
  1226     
       
  1227     if(aInBufferCreate)
       
  1228         {
       
  1229         if(aInBufSize <= 0)
       
  1230             User::Leave(KErrArgument);
       
  1231         
       
  1232         if(iInputBuffer)
       
  1233             {
       
  1234             delete iInputBuffer;
       
  1235             iInputBuffer = NULL;
       
  1236             }
       
  1237         
       
  1238         iInputBuffer = HBufC8::NewL(aInBufSize);
       
  1239         }
       
  1240     
       
  1241     if(aOutBufferCreate)
       
  1242         {
       
  1243         if(aOutBufSize <= 0)
       
  1244             User::Leave(KErrArgument);
       
  1245         
       
  1246         if(iOutputBuffer)
       
  1247             {
       
  1248             delete iOutputBuffer;
       
  1249             iOutputBuffer = NULL;
       
  1250             }
       
  1251         
       
  1252         iOutputBuffer = HBufC8::NewL(aOutBufSize);
       
  1253         }
       
  1254     
       
  1255     DP0_IMAGIC(_L("CFaceBrowser::PrepareInOutBuffersL --"));
       
  1256     }
       
  1257 
       
  1258 TBool CFaceBrowser::CheckOddSize(const TSize aSize)
       
  1259     {
       
  1260     DP0_IMAGIC(_L("CFaceBrowser::CheckOddSize ++"));
       
  1261     
       
  1262     TReal remainder = 0;
       
  1263     
       
  1264     Math::Mod(remainder, aSize.iWidth, 2);
       
  1265     
       
  1266     if(remainder != 0) return ETrue;
       
  1267     
       
  1268     Math::Mod(remainder, aSize.iHeight, 2);
       
  1269     
       
  1270     if(remainder != 0) return ETrue;
       
  1271     
       
  1272     DP0_IMAGIC(_L("CFaceBrowser::CheckOddSize --"));
       
  1273     
       
  1274     return EFalse;
       
  1275     }
       
  1276 
       
  1277 #if 0
       
  1278 TFileName CFaceBrowser::MakeTNFileName(const TFileName aImageFileName, TBool a512TNFile, TBool /*a320TNFileName*/)
       
  1279     {
       
  1280     DP1_IMAGIC(_L("CFaceBrowser::Make512x512TNFileName, aImageFileName = %S ++"), &aImageFileName);
       
  1281     
       
  1282     TParse fileNameParser;
       
  1283     fileNameParser.Set(aImageFileName, NULL, NULL);
       
  1284     
       
  1285     TFileName tnFileName;
       
  1286     
       
  1287     tnFileName = fileNameParser.DriveAndPath();
       
  1288     
       
  1289     if(a512TNFile /*&& !a320TNFileName*/)
       
  1290         {
       
  1291         tnFileName.Append(K512x512TNFilePath);
       
  1292         tnFileName.Append(fileNameParser.Name());
       
  1293         tnFileName.Append(KTNExt);
       
  1294         }
       
  1295 /*    if(!a512TNFile && a320TNFileName)
       
  1296         {
       
  1297         tnFileName.Append(K320TNFilePath);
       
  1298         tnFileName.Append(fileNameParser.Name());
       
  1299         tnFileName.Append(K320TNFileExt);
       
  1300         }*/
       
  1301     
       
  1302     DP1_IMAGIC(_L("CFaceBrowser::Make512x512TNFileName fileName512x512TN = %S --"), &tnFileName);
       
  1303     
       
  1304     return tnFileName;
       
  1305     }
       
  1306 #endif    
       
  1307 
       
  1308 void CFaceBrowser::Cleanup()
       
  1309     {
       
  1310     DP0_IMAGIC(_L("CFaceBrowser::Cleanup ++"));
       
  1311     
       
  1312     if(iImageDecoder)
       
  1313             iImageDecoder->CancelDecoding();
       
  1314             
       
  1315     if(iImageEncoder)
       
  1316         iImageEncoder->CancelEncoding();
       
  1317         
       
  1318     if(iFaceCoordinates.Count() > 0)
       
  1319         {
       
  1320         TInt count = iFaceCoordinates.Count();
       
  1321         for(TInt i=0; i<count; i++)
       
  1322             iFaceCoordinates.Remove(0);
       
  1323         }
       
  1324     
       
  1325     if(iFaceYuvDataArray.Count() > 0)
       
  1326         {
       
  1327         TCroppedFaces croppedFaces;
       
  1328         HBufC8* buffer = NULL;
       
  1329         TInt count = iFaceYuvDataArray.Count();
       
  1330         
       
  1331         for(TInt i=0; i<count; i++)
       
  1332             {
       
  1333             croppedFaces = iFaceYuvDataArray[0];
       
  1334             iFaceYuvDataArray.Remove(0);
       
  1335             
       
  1336             buffer = croppedFaces.iYuvdata;
       
  1337             
       
  1338             delete buffer;
       
  1339             buffer = NULL;
       
  1340             }
       
  1341         }
       
  1342 /*    
       
  1343     if(iImageDataArray.Count() > 0)
       
  1344         {
       
  1345         TInt count = iImageDataArray.Count();
       
  1346         for(TInt i=0; i<count; i++)
       
  1347             iImageDataArray.Remove(0);
       
  1348         }
       
  1349  */   
       
  1350     iNumberOfFaces = 0;
       
  1351     iNumberOfImages = 0;
       
  1352     iNumberOfImagesBrowsed = 0;
       
  1353     iNumberOfFacesCropped = 0;
       
  1354     
       
  1355     iCurrentImageData = NULL;
       
  1356     
       
  1357     iCurrentImageFileName = KEmptyString;
       
  1358     iCurrent512x512TNFileName = KEmptyString;
       
  1359     //iCurrent320x320TNFileName = KEmptyString;
       
  1360     
       
  1361     iBrowsingState = EStateIdle;
       
  1362     
       
  1363     DP0_IMAGIC(_L("CFaceBrowser::Cleanup --"));
       
  1364     }
       
  1365 
       
  1366 void CFaceBrowser::Cleanup2()
       
  1367     {
       
  1368     DP0_IMAGIC(_L("CFaceBrowser::Cleanup2 ++"));
       
  1369     
       
  1370     if(iImageDecoder)
       
  1371         iImageDecoder->CancelDecoding();
       
  1372         
       
  1373     if(iImageEncoder)
       
  1374         iImageEncoder->CancelEncoding();
       
  1375     
       
  1376     if(iFaceYuvDataArray.Count() > 0)
       
  1377         {
       
  1378         TCroppedFaces croppedFaces;
       
  1379         HBufC8* buffer = NULL;
       
  1380         TInt count = iFaceYuvDataArray.Count();
       
  1381         
       
  1382         for(TInt i=0; i<count; i++)
       
  1383             {
       
  1384             croppedFaces = iFaceYuvDataArray[0];
       
  1385             iFaceYuvDataArray.Remove(0);
       
  1386             
       
  1387             buffer = croppedFaces.iYuvdata;
       
  1388             
       
  1389             delete buffer;
       
  1390             buffer = NULL;
       
  1391             }
       
  1392         }
       
  1393 
       
  1394     iBrowsingState = EStateIdle;
       
  1395     
       
  1396     DP0_IMAGIC(_L("CFaceBrowser::Cleanup2 --"));
       
  1397     }
       
  1398 
       
  1399 void CFaceBrowser::ContinueLoop()
       
  1400     {
       
  1401     DP0_IMAGIC(_L("CFaceBrowser::ContinueLoop++"));
       
  1402     
       
  1403     if(!IsActive())
       
  1404         {
       
  1405         SetActive();
       
  1406         TRequestStatus* status = &iStatus;
       
  1407         User::RequestComplete(status, KErrNone);            
       
  1408         }
       
  1409     
       
  1410     DP0_IMAGIC(_L("CFaceBrowser::ContinueLoop--"));
       
  1411     }
       
  1412 
       
  1413 void CFaceBrowser::WriteFaceCoordToExif(TInt numOfFaces, RArray<TRect> faceCoordinates) {
       
  1414     //Add number of faces to image data
       
  1415     iCurrentImageData->SetNumberOfFaces(numOfFaces);
       
  1416     
       
  1417     if(iBrowsingState == ESingleFaceBrowsingRunning)
       
  1418          for(TInt i = 0; i<iFaceCoordinates.Count(); i++)
       
  1419             iTempFaceCoordinates->Append(iFaceCoordinates[i]);
       
  1420  
       
  1421     iUtils.WriteFaceCoordinatesL(iCurrent512x512TNFileName, faceCoordinates);
       
  1422 }
       
  1423 
       
  1424 // EOF