Home | History | Annotate | Download | only in OMXCameraAdapter
      1 /*
      2  * Copyright (C) Texas Instruments - http://www.ti.com/
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18 * @file OMXExif.cpp
     19 *
     20 * This file contains functionality for handling EXIF insertion.
     21 *
     22 */
     23 
     24 #undef LOG_TAG
     25 
     26 #define LOG_TAG "CameraHAL"
     27 
     28 #include "CameraHal.h"
     29 #include "OMXCameraAdapter.h"
     30 #include <math.h>
     31 
     32 namespace android {
     33 
     34 status_t OMXCameraAdapter::setParametersEXIF(const CameraParameters &params,
     35                                              BaseCameraAdapter::AdapterState state)
     36 {
     37     status_t ret = NO_ERROR;
     38     const char *valstr = NULL;
     39     double gpsPos;
     40 
     41     LOG_FUNCTION_NAME;
     42 
     43     if( ( valstr = params.get(CameraParameters::KEY_GPS_LATITUDE) ) != NULL )
     44         {
     45         gpsPos = strtod(valstr, NULL);
     46 
     47         if ( convertGPSCoord(gpsPos,
     48                              mEXIFData.mGPSData.mLatDeg,
     49                              mEXIFData.mGPSData.mLatMin,
     50                              mEXIFData.mGPSData.mLatSec,
     51                              mEXIFData.mGPSData.mLatSecDiv ) == NO_ERROR )
     52             {
     53 
     54             if ( 0 < gpsPos )
     55                 {
     56                 strncpy(mEXIFData.mGPSData.mLatRef, GPS_NORTH_REF, GPS_REF_SIZE);
     57                 }
     58             else
     59                 {
     60                 strncpy(mEXIFData.mGPSData.mLatRef, GPS_SOUTH_REF, GPS_REF_SIZE);
     61                 }
     62 
     63             mEXIFData.mGPSData.mLatValid = true;
     64             }
     65         else
     66             {
     67             mEXIFData.mGPSData.mLatValid = false;
     68             }
     69         }
     70     else
     71         {
     72         mEXIFData.mGPSData.mLatValid = false;
     73         }
     74 
     75     if( ( valstr = params.get(CameraParameters::KEY_GPS_LONGITUDE) ) != NULL )
     76         {
     77         gpsPos = strtod(valstr, NULL);
     78 
     79         if ( convertGPSCoord(gpsPos,
     80                              mEXIFData.mGPSData.mLongDeg,
     81                              mEXIFData.mGPSData.mLongMin,
     82                              mEXIFData.mGPSData.mLongSec,
     83                              mEXIFData.mGPSData.mLongSecDiv) == NO_ERROR )
     84             {
     85 
     86             if ( 0 < gpsPos )
     87                 {
     88                 strncpy(mEXIFData.mGPSData.mLongRef, GPS_EAST_REF, GPS_REF_SIZE);
     89                 }
     90             else
     91                 {
     92                 strncpy(mEXIFData.mGPSData.mLongRef, GPS_WEST_REF, GPS_REF_SIZE);
     93                 }
     94 
     95             mEXIFData.mGPSData.mLongValid= true;
     96             }
     97         else
     98             {
     99             mEXIFData.mGPSData.mLongValid = false;
    100             }
    101         }
    102     else
    103         {
    104         mEXIFData.mGPSData.mLongValid = false;
    105         }
    106 
    107     if( ( valstr = params.get(CameraParameters::KEY_GPS_ALTITUDE) ) != NULL )
    108         {
    109         gpsPos = strtod(valstr, NULL);
    110         mEXIFData.mGPSData.mAltitude = floor(fabs(gpsPos));
    111         if (gpsPos < 0) {
    112             mEXIFData.mGPSData.mAltitudeRef = 1;
    113         } else {
    114             mEXIFData.mGPSData.mAltitudeRef = 0;
    115         }
    116         mEXIFData.mGPSData.mAltitudeValid = true;
    117         }
    118     else
    119         {
    120         mEXIFData.mGPSData.mAltitudeValid= false;
    121         }
    122 
    123     if( (valstr = params.get(CameraParameters::KEY_GPS_TIMESTAMP)) != NULL )
    124         {
    125         long gpsTimestamp = strtol(valstr, NULL, 10);
    126         struct tm *timeinfo = gmtime( ( time_t * ) & (gpsTimestamp) );
    127         if ( NULL != timeinfo )
    128             {
    129             mEXIFData.mGPSData.mTimeStampHour = timeinfo->tm_hour;
    130             mEXIFData.mGPSData.mTimeStampMin = timeinfo->tm_min;
    131             mEXIFData.mGPSData.mTimeStampSec = timeinfo->tm_sec;
    132             mEXIFData.mGPSData.mTimeStampValid = true;
    133             }
    134         else
    135             {
    136             mEXIFData.mGPSData.mTimeStampValid = false;
    137             }
    138         }
    139     else
    140         {
    141         mEXIFData.mGPSData.mTimeStampValid = false;
    142         }
    143 
    144     if( ( valstr = params.get(CameraParameters::KEY_GPS_TIMESTAMP) ) != NULL )
    145         {
    146         long gpsDatestamp = strtol(valstr, NULL, 10);
    147         struct tm *timeinfo = gmtime( ( time_t * ) & (gpsDatestamp) );
    148         if ( NULL != timeinfo )
    149             {
    150             strftime(mEXIFData.mGPSData.mDatestamp, GPS_DATESTAMP_SIZE, "%Y:%m:%d", timeinfo);
    151             mEXIFData.mGPSData.mDatestampValid = true;
    152             }
    153         else
    154             {
    155             mEXIFData.mGPSData.mDatestampValid = false;
    156             }
    157         }
    158     else
    159         {
    160         mEXIFData.mGPSData.mDatestampValid = false;
    161         }
    162 
    163     if( ( valstr = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD) ) != NULL )
    164         {
    165         strncpy(mEXIFData.mGPSData.mProcMethod, valstr, GPS_PROCESSING_SIZE-1);
    166         mEXIFData.mGPSData.mProcMethodValid = true;
    167         }
    168     else
    169         {
    170         mEXIFData.mGPSData.mProcMethodValid = false;
    171         }
    172 
    173     if( ( valstr = params.get(TICameraParameters::KEY_GPS_MAPDATUM) ) != NULL )
    174         {
    175         strncpy(mEXIFData.mGPSData.mMapDatum, valstr, GPS_MAPDATUM_SIZE-1);
    176         mEXIFData.mGPSData.mMapDatumValid = true;
    177         }
    178     else
    179         {
    180         mEXIFData.mGPSData.mMapDatumValid = false;
    181         }
    182 
    183     if( ( valstr = params.get(TICameraParameters::KEY_GPS_VERSION) ) != NULL )
    184         {
    185         strncpy(mEXIFData.mGPSData.mVersionId, valstr, GPS_VERSION_SIZE-1);
    186         mEXIFData.mGPSData.mVersionIdValid = true;
    187         }
    188     else
    189         {
    190         mEXIFData.mGPSData.mVersionIdValid = false;
    191         }
    192 
    193     if( ( valstr = params.get(TICameraParameters::KEY_EXIF_MODEL ) ) != NULL )
    194         {
    195         CAMHAL_LOGVB("EXIF Model: %s", valstr);
    196         mEXIFData.mModelValid= true;
    197         }
    198     else
    199         {
    200         mEXIFData.mModelValid= false;
    201         }
    202 
    203     if( ( valstr = params.get(TICameraParameters::KEY_EXIF_MAKE ) ) != NULL )
    204         {
    205         CAMHAL_LOGVB("EXIF Make: %s", valstr);
    206         mEXIFData.mMakeValid = true;
    207         }
    208     else
    209         {
    210         mEXIFData.mMakeValid= false;
    211         }
    212 
    213     LOG_FUNCTION_NAME_EXIT;
    214 
    215     return ret;
    216 }
    217 
    218 status_t OMXCameraAdapter::setupEXIF()
    219 {
    220     status_t ret = NO_ERROR;
    221     OMX_ERRORTYPE eError = OMX_ErrorNone;
    222     OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer;
    223     OMX_TI_CONFIG_EXIF_TAGS *exifTags;
    224     unsigned char *sharedPtr = NULL;
    225     struct timeval sTv;
    226     struct tm *pTime;
    227     OMXCameraPortParameters * capData = NULL;
    228     MemoryManager memMgr;
    229     OMX_U8** memmgr_buf_array = NULL;
    230     int buf_size = 0;
    231 
    232     LOG_FUNCTION_NAME;
    233 
    234     sharedBuffer.pSharedBuff = NULL;
    235     capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    236 
    237     if ( OMX_StateInvalid == mComponentState )
    238         {
    239         CAMHAL_LOGEA("OMX component is in invalid state");
    240         ret = -EINVAL;
    241         }
    242 
    243     if ( NO_ERROR == ret )
    244         {
    245         OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER);
    246         sharedBuffer.nPortIndex = mCameraAdapterParameters.mImagePortIndex;
    247 
    248         //We allocate the shared buffer dynamically based on the
    249         //requirements of the EXIF tags. The additional buffers will
    250         //get stored after the EXIF configuration structure and the pointers
    251         //will contain offsets within the shared buffer itself.
    252         buf_size = sizeof(OMX_TI_CONFIG_EXIF_TAGS) +
    253                           ( EXIF_MODEL_SIZE ) +
    254                           ( EXIF_MAKE_SIZE ) +
    255                           ( EXIF_DATE_TIME_SIZE ) +
    256                           ( GPS_MAPDATUM_SIZE ) +
    257                           ( GPS_PROCESSING_SIZE );
    258         buf_size = ((buf_size+4095)/4096)*4096;
    259         sharedBuffer.nSharedBuffSize = buf_size;
    260 
    261         memmgr_buf_array = (OMX_U8 **)memMgr.allocateBuffer(0, 0, NULL, buf_size, 1);
    262         sharedBuffer.pSharedBuff =  ( OMX_U8 * ) memmgr_buf_array[0];
    263 
    264         if ( NULL == sharedBuffer.pSharedBuff )
    265             {
    266             CAMHAL_LOGEA("No resources to allocate OMX shared buffer");
    267             ret = -1;
    268             }
    269 
    270         //Extra data begins right after the EXIF configuration structure.
    271         sharedPtr = sharedBuffer.pSharedBuff + sizeof(OMX_TI_CONFIG_EXIF_TAGS);
    272         }
    273 
    274     if ( NO_ERROR == ret )
    275         {
    276         exifTags = ( OMX_TI_CONFIG_EXIF_TAGS * ) sharedBuffer.pSharedBuff;
    277         OMX_INIT_STRUCT_PTR (exifTags, OMX_TI_CONFIG_EXIF_TAGS);
    278         exifTags->nPortIndex = mCameraAdapterParameters.mImagePortIndex;
    279 
    280         eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp,
    281                                ( OMX_INDEXTYPE ) OMX_TI_IndexConfigExifTags,
    282                                &sharedBuffer );
    283         if ( OMX_ErrorNone != eError )
    284             {
    285             CAMHAL_LOGEB("Error while retrieving EXIF configuration structure 0x%x", eError);
    286             ret = -1;
    287             }
    288         }
    289 
    290     if ( NO_ERROR == ret )
    291         {
    292         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusModel ) &&
    293               ( mEXIFData.mModelValid ) )
    294             {
    295             strncpy(( char * ) sharedPtr,
    296                     ( char * ) mParams.get(TICameraParameters::KEY_EXIF_MODEL ),
    297                     EXIF_MODEL_SIZE - 1);
    298 
    299             exifTags->pModelBuff = ( OMX_S8 * ) ( sharedPtr - sharedBuffer.pSharedBuff );
    300             exifTags->ulModelBuffSizeBytes = strlen((char*)sharedPtr) + 1;
    301             sharedPtr += EXIF_MODEL_SIZE;
    302             exifTags->eStatusModel = OMX_TI_TagUpdated;
    303             }
    304 
    305          if ( ( OMX_TI_TagReadWrite == exifTags->eStatusMake) &&
    306                ( mEXIFData.mMakeValid ) )
    307              {
    308              strncpy( ( char * ) sharedPtr,
    309                           ( char * ) mParams.get(TICameraParameters::KEY_EXIF_MAKE ),
    310                           EXIF_MAKE_SIZE - 1);
    311 
    312              exifTags->pMakeBuff = ( OMX_S8 * ) ( sharedPtr - sharedBuffer.pSharedBuff );
    313              exifTags->ulMakeBuffSizeBytes = strlen((char*)sharedPtr) + 1;
    314              sharedPtr += EXIF_MAKE_SIZE;
    315              exifTags->eStatusMake = OMX_TI_TagUpdated;
    316              }
    317 
    318         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusFocalLength ))
    319         {
    320             unsigned int numerator = 0, denominator = 0;
    321             ExifElementsTable::stringToRational(mParams.get(CameraParameters::KEY_FOCAL_LENGTH),
    322                                                 &numerator, &denominator);
    323             if (numerator || denominator) {
    324                 exifTags->ulFocalLength[0] = (OMX_U32) numerator;
    325                 exifTags->ulFocalLength[1] = (OMX_U32) denominator;
    326                 CAMHAL_LOGVB("exifTags->ulFocalLength = [%u] [%u]",
    327                              (unsigned int)(exifTags->ulFocalLength[0]),
    328                              (unsigned int)(exifTags->ulFocalLength[1]));
    329                 exifTags->eStatusFocalLength = OMX_TI_TagUpdated;
    330             }
    331         }
    332 
    333          if ( OMX_TI_TagReadWrite == exifTags->eStatusDateTime )
    334              {
    335              int status = gettimeofday (&sTv, NULL);
    336              pTime = localtime (&sTv.tv_sec);
    337              if ( ( 0 == status ) && ( NULL != pTime ) )
    338                 {
    339                 snprintf(( char * ) sharedPtr, EXIF_DATE_TIME_SIZE,
    340                          "%04d:%02d:%02d %02d:%02d:%02d",
    341                          pTime->tm_year + 1900,
    342                          pTime->tm_mon + 1,
    343                          pTime->tm_mday,
    344                          pTime->tm_hour,
    345                          pTime->tm_min,
    346                          pTime->tm_sec );
    347                 }
    348 
    349              exifTags->pDateTimeBuff = ( OMX_S8 * ) ( sharedPtr - sharedBuffer.pSharedBuff );
    350              sharedPtr += EXIF_DATE_TIME_SIZE;
    351              exifTags->ulDateTimeBuffSizeBytes = EXIF_DATE_TIME_SIZE;
    352              exifTags->eStatusDateTime = OMX_TI_TagUpdated;
    353              }
    354 
    355          if ( OMX_TI_TagReadWrite == exifTags->eStatusImageWidth )
    356              {
    357              exifTags->ulImageWidth = capData->mWidth;
    358              exifTags->eStatusImageWidth = OMX_TI_TagUpdated;
    359              }
    360 
    361          if ( OMX_TI_TagReadWrite == exifTags->eStatusImageHeight )
    362              {
    363              exifTags->ulImageHeight = capData->mHeight;
    364              exifTags->eStatusImageHeight = OMX_TI_TagUpdated;
    365              }
    366 
    367          if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsLatitude ) &&
    368               ( mEXIFData.mGPSData.mLatValid ) )
    369             {
    370             exifTags->ulGpsLatitude[0] = abs(mEXIFData.mGPSData.mLatDeg);
    371             exifTags->ulGpsLatitude[2] = abs(mEXIFData.mGPSData.mLatMin);
    372             exifTags->ulGpsLatitude[4] = abs(mEXIFData.mGPSData.mLatSec);
    373             exifTags->ulGpsLatitude[1] = 1;
    374             exifTags->ulGpsLatitude[3] = 1;
    375             exifTags->ulGpsLatitude[5] = abs(mEXIFData.mGPSData.mLatSecDiv);
    376             exifTags->eStatusGpsLatitude = OMX_TI_TagUpdated;
    377             }
    378 
    379         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpslatitudeRef ) &&
    380              ( mEXIFData.mGPSData.mLatValid ) )
    381             {
    382             exifTags->cGpslatitudeRef[0] = ( OMX_S8 ) mEXIFData.mGPSData.mLatRef[0];
    383             exifTags->cGpslatitudeRef[1] = '\0';
    384             exifTags->eStatusGpslatitudeRef = OMX_TI_TagUpdated;
    385             }
    386 
    387          if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsLongitude ) &&
    388               ( mEXIFData.mGPSData.mLongValid ) )
    389             {
    390             exifTags->ulGpsLongitude[0] = abs(mEXIFData.mGPSData.mLongDeg);
    391             exifTags->ulGpsLongitude[2] = abs(mEXIFData.mGPSData.mLongMin);
    392             exifTags->ulGpsLongitude[4] = abs(mEXIFData.mGPSData.mLongSec);
    393             exifTags->ulGpsLongitude[1] = 1;
    394             exifTags->ulGpsLongitude[3] = 1;
    395             exifTags->ulGpsLongitude[5] = abs(mEXIFData.mGPSData.mLongSecDiv);
    396             exifTags->eStatusGpsLongitude = OMX_TI_TagUpdated;
    397             }
    398 
    399         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsLongitudeRef ) &&
    400              ( mEXIFData.mGPSData.mLongValid ) )
    401             {
    402             exifTags->cGpsLongitudeRef[0] = ( OMX_S8 ) mEXIFData.mGPSData.mLongRef[0];
    403             exifTags->cGpsLongitudeRef[1] = '\0';
    404             exifTags->eStatusGpsLongitudeRef = OMX_TI_TagUpdated;
    405             }
    406 
    407         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsAltitude ) &&
    408              ( mEXIFData.mGPSData.mAltitudeValid) )
    409             {
    410             exifTags->ulGpsAltitude[0] = ( OMX_U32 ) mEXIFData.mGPSData.mAltitude;
    411             exifTags->ulGpsAltitude[1] = 1;
    412             exifTags->eStatusGpsAltitude = OMX_TI_TagUpdated;
    413             }
    414 
    415         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsAltitudeRef ) &&
    416              ( mEXIFData.mGPSData.mAltitudeValid) )
    417             {
    418             exifTags->ucGpsAltitudeRef = (OMX_U8) mEXIFData.mGPSData.mAltitudeRef;
    419             exifTags->eStatusGpsAltitudeRef = OMX_TI_TagUpdated;
    420             }
    421 
    422         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsMapDatum ) &&
    423              ( mEXIFData.mGPSData.mMapDatumValid ) )
    424             {
    425             memcpy(sharedPtr, mEXIFData.mGPSData.mMapDatum, GPS_MAPDATUM_SIZE);
    426 
    427             exifTags->pGpsMapDatumBuff = ( OMX_S8 * ) ( sharedPtr - sharedBuffer.pSharedBuff );
    428             exifTags->ulGpsMapDatumBuffSizeBytes = GPS_MAPDATUM_SIZE;
    429             exifTags->eStatusGpsMapDatum = OMX_TI_TagUpdated;
    430             sharedPtr += GPS_MAPDATUM_SIZE;
    431             }
    432 
    433         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsProcessingMethod ) &&
    434              ( mEXIFData.mGPSData.mProcMethodValid ) )
    435             {
    436             exifTags->pGpsProcessingMethodBuff = ( OMX_S8 * ) ( sharedPtr - sharedBuffer.pSharedBuff );
    437             memcpy(sharedPtr, ExifAsciiPrefix, sizeof(ExifAsciiPrefix));
    438             sharedPtr += sizeof(ExifAsciiPrefix);
    439 
    440             memcpy(sharedPtr,
    441                    mEXIFData.mGPSData.mProcMethod,
    442                    ( GPS_PROCESSING_SIZE - sizeof(ExifAsciiPrefix) ) );
    443             exifTags->ulGpsProcessingMethodBuffSizeBytes = GPS_PROCESSING_SIZE;
    444             exifTags->eStatusGpsProcessingMethod = OMX_TI_TagUpdated;
    445             sharedPtr += GPS_PROCESSING_SIZE;
    446             }
    447 
    448         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsVersionId ) &&
    449              ( mEXIFData.mGPSData.mVersionIdValid ) )
    450             {
    451             exifTags->ucGpsVersionId[0] = ( OMX_U8 ) mEXIFData.mGPSData.mVersionId[0];
    452             exifTags->ucGpsVersionId[1] =  ( OMX_U8 ) mEXIFData.mGPSData.mVersionId[1];
    453             exifTags->ucGpsVersionId[2] = ( OMX_U8 ) mEXIFData.mGPSData.mVersionId[2];
    454             exifTags->ucGpsVersionId[3] = ( OMX_U8 ) mEXIFData.mGPSData.mVersionId[3];
    455             exifTags->eStatusGpsVersionId = OMX_TI_TagUpdated;
    456             }
    457 
    458         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsTimeStamp ) &&
    459              ( mEXIFData.mGPSData.mTimeStampValid ) )
    460             {
    461             exifTags->ulGpsTimeStamp[0] = mEXIFData.mGPSData.mTimeStampHour;
    462             exifTags->ulGpsTimeStamp[2] = mEXIFData.mGPSData.mTimeStampMin;
    463             exifTags->ulGpsTimeStamp[4] = mEXIFData.mGPSData.mTimeStampSec;
    464             exifTags->ulGpsTimeStamp[1] = 1;
    465             exifTags->ulGpsTimeStamp[3] = 1;
    466             exifTags->ulGpsTimeStamp[5] = 1;
    467             exifTags->eStatusGpsTimeStamp = OMX_TI_TagUpdated;
    468             }
    469 
    470         if ( ( OMX_TI_TagReadWrite == exifTags->eStatusGpsDateStamp ) &&
    471              ( mEXIFData.mGPSData.mDatestampValid ) )
    472             {
    473             strncpy( ( char * ) exifTags->cGpsDateStamp,
    474                          ( char * ) mEXIFData.mGPSData.mDatestamp,
    475                          GPS_DATESTAMP_SIZE );
    476             exifTags->eStatusGpsDateStamp = OMX_TI_TagUpdated;
    477             }
    478 
    479         eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
    480                                ( OMX_INDEXTYPE ) OMX_TI_IndexConfigExifTags,
    481                                &sharedBuffer );
    482 
    483         if ( OMX_ErrorNone != eError )
    484             {
    485             CAMHAL_LOGEB("Error while setting EXIF configuration 0x%x", eError);
    486             ret = -1;
    487             }
    488         }
    489 
    490     if ( NULL != memmgr_buf_array )
    491         {
    492         memMgr.freeBuffer(memmgr_buf_array);
    493         }
    494 
    495     LOG_FUNCTION_NAME_EXIT;
    496 
    497     return ret;
    498 }
    499 
    500 status_t OMXCameraAdapter::setupEXIF_libjpeg(ExifElementsTable* exifTable)
    501 {
    502     status_t ret = NO_ERROR;
    503     OMX_ERRORTYPE eError = OMX_ErrorNone;
    504     struct timeval sTv;
    505     struct tm *pTime;
    506     OMXCameraPortParameters * capData = NULL;
    507 
    508     LOG_FUNCTION_NAME;
    509 
    510     capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
    511 
    512     if ((NO_ERROR == ret) && (mEXIFData.mModelValid)) {
    513         ret = exifTable->insertElement(TAG_MODEL, mParams.get(TICameraParameters::KEY_EXIF_MODEL));
    514     }
    515 
    516      if ((NO_ERROR == ret) && (mEXIFData.mMakeValid)) {
    517         ret = exifTable->insertElement(TAG_MAKE, mParams.get(TICameraParameters::KEY_EXIF_MAKE));
    518      }
    519 
    520     if ((NO_ERROR == ret)) {
    521         unsigned int numerator = 0, denominator = 0;
    522         ExifElementsTable::stringToRational(mParams.get(CameraParameters::KEY_FOCAL_LENGTH),
    523                                             &numerator, &denominator);
    524         if (numerator || denominator) {
    525             char temp_value[256]; // arbitrarily long string
    526             snprintf(temp_value,
    527                  sizeof(temp_value)/sizeof(char),
    528                  "%u/%u", numerator, denominator);
    529             ret = exifTable->insertElement(TAG_FOCALLENGTH, temp_value);
    530 
    531         }
    532     }
    533 
    534     if ((NO_ERROR == ret)) {
    535         int status = gettimeofday (&sTv, NULL);
    536         pTime = localtime (&sTv.tv_sec);
    537         char temp_value[EXIF_DATE_TIME_SIZE + 1];
    538         if ((0 == status) && (NULL != pTime)) {
    539             snprintf(temp_value, EXIF_DATE_TIME_SIZE,
    540                      "%04d:%02d:%02d %02d:%02d:%02d",
    541                      pTime->tm_year + 1900,
    542                      pTime->tm_mon + 1,
    543                      pTime->tm_mday,
    544                      pTime->tm_hour,
    545                      pTime->tm_min,
    546                      pTime->tm_sec );
    547 
    548             ret = exifTable->insertElement(TAG_DATETIME, temp_value);
    549         }
    550      }
    551 
    552     if ((NO_ERROR == ret)) {
    553         char temp_value[5];
    554         snprintf(temp_value, sizeof(temp_value)/sizeof(char), "%lu", capData->mWidth);
    555         ret = exifTable->insertElement(TAG_IMAGE_WIDTH, temp_value);
    556      }
    557 
    558     if ((NO_ERROR == ret)) {
    559         char temp_value[5];
    560         snprintf(temp_value, sizeof(temp_value)/sizeof(char), "%lu", capData->mHeight);
    561         ret = exifTable->insertElement(TAG_IMAGE_LENGTH, temp_value);
    562      }
    563 
    564     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mLatValid)) {
    565         char temp_value[256]; // arbitrarily long string
    566         snprintf(temp_value,
    567                  sizeof(temp_value)/sizeof(char) - 1,
    568                  "%d/%d,%d/%d,%d/%d",
    569                  abs(mEXIFData.mGPSData.mLatDeg), 1,
    570                  abs(mEXIFData.mGPSData.mLatMin), 1,
    571                  abs(mEXIFData.mGPSData.mLatSec), abs(mEXIFData.mGPSData.mLatSecDiv));
    572         ret = exifTable->insertElement(TAG_GPS_LAT, temp_value);
    573     }
    574 
    575     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mLatValid)) {
    576         ret = exifTable->insertElement(TAG_GPS_LAT_REF, mEXIFData.mGPSData.mLatRef);
    577     }
    578 
    579     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mLongValid)) {
    580         char temp_value[256]; // arbitrarily long string
    581         snprintf(temp_value,
    582                  sizeof(temp_value)/sizeof(char) - 1,
    583                  "%d/%d,%d/%d,%d/%d",
    584                  abs(mEXIFData.mGPSData.mLongDeg), 1,
    585                  abs(mEXIFData.mGPSData.mLongMin), 1,
    586                  abs(mEXIFData.mGPSData.mLongSec), abs(mEXIFData.mGPSData.mLongSecDiv));
    587         ret = exifTable->insertElement(TAG_GPS_LONG, temp_value);
    588     }
    589 
    590     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mLongValid)) {
    591         ret = exifTable->insertElement(TAG_GPS_LONG_REF, mEXIFData.mGPSData.mLongRef);
    592     }
    593 
    594     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mAltitudeValid)) {
    595         char temp_value[256]; // arbitrarily long string
    596         snprintf(temp_value,
    597                  sizeof(temp_value)/sizeof(char) - 1,
    598                  "%d/%d",
    599                  abs( mEXIFData.mGPSData.mAltitude), 1);
    600         ret = exifTable->insertElement(TAG_GPS_ALT, temp_value);
    601     }
    602 
    603     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mAltitudeValid)) {
    604         char temp_value[5];
    605         snprintf(temp_value,
    606                  sizeof(temp_value)/sizeof(char) - 1,
    607                  "%d", mEXIFData.mGPSData.mAltitudeRef);
    608         ret = exifTable->insertElement(TAG_GPS_ALT_REF, temp_value);
    609     }
    610 
    611     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mMapDatumValid)) {
    612         ret = exifTable->insertElement(TAG_GPS_MAP_DATUM, mEXIFData.mGPSData.mMapDatum);
    613     }
    614 
    615     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mProcMethodValid)) {
    616         char temp_value[GPS_PROCESSING_SIZE];
    617 
    618         memcpy(temp_value, ExifAsciiPrefix, sizeof(ExifAsciiPrefix));
    619         memcpy(temp_value + sizeof(ExifAsciiPrefix),
    620                mParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD),
    621                (GPS_PROCESSING_SIZE - sizeof(ExifAsciiPrefix)));
    622         ret = exifTable->insertElement(TAG_GPS_PROCESSING_METHOD, temp_value);
    623     }
    624 
    625     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mVersionIdValid)) {
    626         char temp_value[256]; // arbitrarily long string
    627         snprintf(temp_value,
    628                  sizeof(temp_value)/sizeof(char) - 1,
    629                  "%d,%d,%d,%d",
    630                  mEXIFData.mGPSData.mVersionId[0],
    631                  mEXIFData.mGPSData.mVersionId[1],
    632                  mEXIFData.mGPSData.mVersionId[2],
    633                  mEXIFData.mGPSData.mVersionId[3]);
    634         ret = exifTable->insertElement(TAG_GPS_VERSION_ID, temp_value);
    635     }
    636 
    637     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mTimeStampValid)) {
    638         char temp_value[256]; // arbitrarily long string
    639         snprintf(temp_value,
    640                  sizeof(temp_value)/sizeof(char) - 1,
    641                  "%d/%d,%d/%d,%d/%d",
    642                  mEXIFData.mGPSData.mTimeStampHour, 1,
    643                  mEXIFData.mGPSData.mTimeStampMin, 1,
    644                  mEXIFData.mGPSData.mTimeStampSec, 1);
    645         ret = exifTable->insertElement(TAG_GPS_TIMESTAMP, temp_value);
    646     }
    647 
    648     if ((NO_ERROR == ret) && (mEXIFData.mGPSData.mDatestampValid) ) {
    649         ret = exifTable->insertElement(TAG_GPS_DATESTAMP, mEXIFData.mGPSData.mDatestamp);
    650     }
    651 
    652     if ((NO_ERROR == ret) && mParams.get(CameraParameters::KEY_ROTATION) ) {
    653         const char* exif_orient =
    654            ExifElementsTable::degreesToExifOrientation(mParams.get(CameraParameters::KEY_ROTATION));
    655 
    656         if (exif_orient) {
    657            ret = exifTable->insertElement(TAG_ORIENTATION, exif_orient);
    658         }
    659     }
    660 
    661     LOG_FUNCTION_NAME_EXIT;
    662 
    663     return ret;
    664 }
    665 
    666 status_t OMXCameraAdapter::convertGPSCoord(double coord,
    667                                            int &deg,
    668                                            int &min,
    669                                            int &sec,
    670                                            int &secDivisor)
    671 {
    672     double tmp;
    673 
    674     LOG_FUNCTION_NAME;
    675 
    676     if ( coord == 0 ) {
    677 
    678         LOGE("Invalid GPS coordinate");
    679 
    680         return -EINVAL;
    681     }
    682 
    683     deg = (int) floor(fabs(coord));
    684     tmp = ( fabs(coord) - floor(fabs(coord)) ) * GPS_MIN_DIV;
    685     min = (int) floor(tmp);
    686     tmp = ( tmp - floor(tmp) ) * ( GPS_SEC_DIV * GPS_SEC_ACCURACY );
    687     sec = (int) floor(tmp);
    688     secDivisor = GPS_SEC_ACCURACY;
    689 
    690     if( sec >= ( GPS_SEC_DIV * GPS_SEC_ACCURACY ) ) {
    691         sec = 0;
    692         min += 1;
    693     }
    694 
    695     if( min >= 60 ) {
    696         min = 0;
    697         deg += 1;
    698     }
    699 
    700     LOG_FUNCTION_NAME_EXIT;
    701 
    702     return NO_ERROR;
    703 }
    704 
    705 };
    706