• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setParametersEXIF(const CameraParameters & params,BaseCameraAdapter::AdapterState state)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 
setupEXIF()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 = gmtime (&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 
setupEXIF_libjpeg(ExifElementsTable * exifTable)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 = gmtime (&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 
convertGPSCoord(double coord,int & deg,int & min,int & sec,int & secDivisor)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