cexifsymbian.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "cexifsymbian.h"
  2. #include <f32file.h>
  3. #include <e32debug.h>
  4. #include <exifread.h>
  5. #include <exifmodify.h>
  6. #include <exifutility.h>
  7. #include <exiftag.h>
  8. CExifSymbian::CExifSymbian(ExifHandler& aPublicAPI):
  9. CActive(EPriorityStandard),
  10. iPublicAPI(aPublicAPI),
  11. iState(ENothing)
  12. {
  13. CActiveScheduler::Add(this);
  14. }
  15. CExifSymbian* CExifSymbian::NewL(ExifHandler& aPublicAPI)
  16. {
  17. CExifSymbian* self = new (ELeave) CExifSymbian(aPublicAPI);
  18. CleanupStack::PushL(self);
  19. self->ConstructL();
  20. CleanupStack::Pop(self);
  21. return self;
  22. }
  23. CExifSymbian::~CExifSymbian()
  24. {
  25. Cancel();
  26. }
  27. void CExifSymbian::LoadGPSPosition(const TDesC& aFilename)
  28. {
  29. iFilename = aFilename;
  30. Cancel();
  31. iState = ELoadGPSPosition;
  32. iStatus = KRequestPending;
  33. SetActive();
  34. TRequestStatus* status = &iStatus;
  35. User::RequestComplete(status, KErrNone);
  36. }
  37. void CExifSymbian::ConstructL()
  38. {
  39. }
  40. void CExifSymbian::DoCancel()
  41. {
  42. TRequestStatus* status = &iStatus;
  43. User::RequestComplete(status, KErrCancel);
  44. }
  45. void CExifSymbian::RunL()
  46. {
  47. switch(iState){
  48. case ELoadGPSPosition:{
  49. RFile file;
  50. RFs fs;
  51. TInt error = 0;
  52. TReal64 m_longitude = 0;
  53. TReal64 m_latitude = 0;
  54. TInt tags;
  55. TUint16* ptr = NULL;
  56. TBool longitude = ETrue;
  57. TBool west=ETrue;
  58. TBool north = ETrue;
  59. User::LeaveIfError(fs.Connect());
  60. User::LeaveIfError( file.Open( fs, iFilename, EFileRead ) );
  61. CleanupClosePushL( file );
  62. TInt size = 0;
  63. file.Size(size);
  64. // Don’t read more than 64k
  65. if ( size > 65536 )
  66. size = 65536;
  67. HBufC8* exif = HBufC8::NewL( size );
  68. CleanupStack::PushL( exif );
  69. TPtr8 bufferDes( exif->Des() );
  70. User::LeaveIfError( file.Read( bufferDes, size ) );
  71. CleanupStack::Pop( exif );
  72. CleanupStack::PopAndDestroy();
  73. CleanupStack::PushL( exif );
  74. CExifRead* read = CExifRead::NewL( exif->Des(),CExifRead::ENoTagChecking | CExifRead::ENoJpeg );
  75. CleanupStack::PushL( read );
  76. if(read->IfdExists(EIfdGps)){
  77. TRAP(error, ptr = read->GetTagIdsL(EIfdGps,tags));
  78. if(error==KErrNone && ptr!=NULL){
  79. for(TInt i=1;i<5;i++){
  80. const CExifTag* tag = read->GetTagL(EIfdGps,ptr[i]);
  81. if(tag){
  82. switch(tag->TagInfo().iDataType)
  83. {
  84. case CExifTag::ETagAscii:
  85. {
  86. TBuf8<20> tmp;
  87. tmp.CopyLC(tag->Data());
  88. if(tmp.Find(_L8("n"))!=KErrNotFound || tmp.Find(_L8("s"))!=KErrNotFound ){
  89. longitude = EFalse;
  90. if(tmp.Find(_L8("n"))!=KErrNotFound)
  91. north = ETrue;
  92. else if(tmp.Find(_L8("s")))
  93. north = EFalse;
  94. }else{
  95. longitude = ETrue;
  96. if(tmp.Find(_L8("w"))!=KErrNotFound)
  97. west = ETrue;
  98. else if(tmp.Find(_L8("e")))
  99. west = EFalse;
  100. }
  101. }break;
  102. case CExifTag::ETagRational:
  103. {
  104. TReal64 num = 0;
  105. TInt tmpData;
  106. TReal64 numerator = 0;
  107. TReal64 denominator = 0;
  108. const TUint8* rationalData = tag->Data().Ptr();
  109. for(TUint c=0;c<tag->TagInfo().iDataCount;c++){
  110. numerator = 0;
  111. denominator = 0;
  112. Mem::Copy(&tmpData, rationalData + ((c * 2) * sizeof(tmpData)), sizeof(tmpData));
  113. numerator = tmpData;
  114. tmpData = 0;
  115. Mem::Copy(&tmpData, rationalData + (((c * 2) + 1) * sizeof(tmpData)), sizeof(tmpData));
  116. denominator = tmpData;
  117. switch(c){
  118. case 0:{
  119. num = (numerator/denominator);
  120. if(longitude)
  121. m_longitude = m_longitude + num;
  122. else
  123. m_latitude = m_latitude + num;
  124. }break;
  125. case 1:{
  126. num = (numerator/ denominator)/60;
  127. if(longitude)
  128. m_longitude = m_longitude + num;
  129. else
  130. m_latitude = m_latitude + num;
  131. }break;
  132. case 2:{
  133. num = (numerator/ denominator)/3600;
  134. if(longitude)
  135. m_longitude = m_longitude + num;
  136. else
  137. m_latitude = m_latitude + num;
  138. }break;
  139. default:break;
  140. }
  141. }
  142. }break;
  143. case CExifTag::ETagByte:
  144. case CExifTag::ETagShort:
  145. case CExifTag::ETagLong:
  146. case CExifTag::ETagSlong:
  147. case CExifTag::ETagSrational:
  148. case CExifTag::ETagUndefined:
  149. default:
  150. break;
  151. }
  152. }
  153. }
  154. delete ptr;
  155. }
  156. }
  157. CleanupStack::PopAndDestroy( read );
  158. CleanupStack::PopAndDestroy( exif );
  159. iState = ENothing;
  160. if(west)
  161. m_longitude = m_longitude*-1;
  162. if(!north)
  163. m_latitude = m_latitude*-1;
  164. QT_TRYCATCH_LEAVING(emit iPublicAPI.gpsPosition(error,m_longitude,m_latitude);)
  165. }break;
  166. default:break;
  167. }
  168. }