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 ¶ms,
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 °,
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