1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include <pthread.h>
31 #include "mm_jpeg_dbg.h"
32 #include "mm_jpeg.h"
33 #include <errno.h>
34 #include <math.h>
35
36
37 #define LOWER(a) ((a) & 0xFFFF)
38 #define UPPER(a) (((a)>>16) & 0xFFFF)
39 #define CHANGE_ENDIAN_16(a) ((0x00FF & ((a)>>8)) | (0xFF00 & ((a)<<8)))
40 #define ROUND(a)((a >= 0) ? (long)(a + 0.5) : (long)(a - 0.5))
41
42
43 /** addExifEntry:
44 *
45 * Arguments:
46 * @exif_info : Exif info struct
47 * @p_session: job session
48 * @tagid : exif tag ID
49 * @type : data type
50 * @count : number of data in uint of its type
51 * @data : input data ptr
52 *
53 * Retrun : int32_t type of status
54 * 0 -- success
55 * none-zero failure code
56 *
57 * Description:
58 * Function to add an entry to exif data
59 *
60 **/
addExifEntry(QOMX_EXIF_INFO * p_exif_info,exif_tag_id_t tagid,exif_tag_type_t type,uint32_t count,void * data)61 int32_t addExifEntry(QOMX_EXIF_INFO *p_exif_info, exif_tag_id_t tagid,
62 exif_tag_type_t type, uint32_t count, void *data)
63 {
64 int32_t rc = 0;
65 int32_t numOfEntries = p_exif_info->numOfEntries;
66 QEXIF_INFO_DATA *p_info_data = p_exif_info->exif_data;
67 if(numOfEntries >= MAX_EXIF_TABLE_ENTRIES) {
68 ALOGE("%s: Number of entries exceeded limit", __func__);
69 return -1;
70 }
71
72 p_info_data[numOfEntries].tag_id = tagid;
73 p_info_data[numOfEntries].tag_entry.type = type;
74 p_info_data[numOfEntries].tag_entry.count = count;
75 p_info_data[numOfEntries].tag_entry.copy = 1;
76 switch (type) {
77 case EXIF_BYTE: {
78 if (count > 1) {
79 uint8_t *values = (uint8_t *)malloc(count);
80 if (values == NULL) {
81 ALOGE("%s: No memory for byte array", __func__);
82 rc = -1;
83 } else {
84 memcpy(values, data, count);
85 p_info_data[numOfEntries].tag_entry.data._bytes = values;
86 }
87 } else {
88 p_info_data[numOfEntries].tag_entry.data._byte = *(uint8_t *)data;
89 }
90 }
91 break;
92 case EXIF_ASCII: {
93 char *str = NULL;
94 str = (char *)malloc(count + 1);
95 if (str == NULL) {
96 ALOGE("%s: No memory for ascii string", __func__);
97 rc = -1;
98 } else {
99 memset(str, 0, count + 1);
100 memcpy(str, data, count);
101 p_info_data[numOfEntries].tag_entry.data._ascii = str;
102 }
103 }
104 break;
105 case EXIF_SHORT: {
106 if (count > 1) {
107 uint16_t *values = (uint16_t *)malloc(count * sizeof(uint16_t));
108 if (values == NULL) {
109 ALOGE("%s: No memory for short array", __func__);
110 rc = -1;
111 } else {
112 memcpy(values, data, count * sizeof(uint16_t));
113 p_info_data[numOfEntries].tag_entry.data._shorts = values;
114 }
115 } else {
116 p_info_data[numOfEntries].tag_entry.data._short = *(uint16_t *)data;
117 }
118 }
119 break;
120 case EXIF_LONG: {
121 if (count > 1) {
122 uint32_t *values = (uint32_t *)malloc(count * sizeof(uint32_t));
123 if (values == NULL) {
124 ALOGE("%s: No memory for long array", __func__);
125 rc = -1;
126 } else {
127 memcpy(values, data, count * sizeof(uint32_t));
128 p_info_data[numOfEntries].tag_entry.data._longs = values;
129 }
130 } else {
131 p_info_data[numOfEntries].tag_entry.data._long = *(uint32_t *)data;
132 }
133 }
134 break;
135 case EXIF_RATIONAL: {
136 if (count > 1) {
137 rat_t *values = (rat_t *)malloc(count * sizeof(rat_t));
138 if (values == NULL) {
139 ALOGE("%s: No memory for rational array", __func__);
140 rc = -1;
141 } else {
142 memcpy(values, data, count * sizeof(rat_t));
143 p_info_data[numOfEntries].tag_entry.data._rats = values;
144 }
145 } else {
146 p_info_data[numOfEntries].tag_entry.data._rat = *(rat_t *)data;
147 }
148 }
149 break;
150 case EXIF_UNDEFINED: {
151 uint8_t *values = (uint8_t *)malloc(count);
152 if (values == NULL) {
153 ALOGE("%s: No memory for undefined array", __func__);
154 rc = -1;
155 } else {
156 memcpy(values, data, count);
157 p_info_data[numOfEntries].tag_entry.data._undefined = values;
158 }
159 }
160 break;
161 case EXIF_SLONG: {
162 if (count > 1) {
163 int32_t *values = (int32_t *)malloc(count * sizeof(int32_t));
164 if (values == NULL) {
165 ALOGE("%s: No memory for signed long array", __func__);
166 rc = -1;
167 } else {
168 memcpy(values, data, count * sizeof(int32_t));
169 p_info_data[numOfEntries].tag_entry.data._slongs = values;
170 }
171 } else {
172 p_info_data[numOfEntries].tag_entry.data._slong = *(int32_t *)data;
173 }
174 }
175 break;
176 case EXIF_SRATIONAL: {
177 if (count > 1) {
178 srat_t *values = (srat_t *)malloc(count * sizeof(srat_t));
179 if (values == NULL) {
180 ALOGE("%s: No memory for signed rational array", __func__);
181 rc = -1;
182 } else {
183 memcpy(values, data, count * sizeof(srat_t));
184 p_info_data[numOfEntries].tag_entry.data._srats = values;
185 }
186 } else {
187 p_info_data[numOfEntries].tag_entry.data._srat = *(srat_t *)data;
188 }
189 }
190 break;
191 }
192
193 // Increase number of entries
194 p_exif_info->numOfEntries++;
195 return rc;
196 }
197
198 /** releaseExifEntry
199 *
200 * Arguments:
201 * @p_exif_data : Exif info struct
202 *
203 * Retrun : int32_t type of status
204 * 0 -- success
205 * none-zero failure code
206 *
207 * Description:
208 * Function to release an entry from exif data
209 *
210 **/
releaseExifEntry(QEXIF_INFO_DATA * p_exif_data)211 int32_t releaseExifEntry(QEXIF_INFO_DATA *p_exif_data)
212 {
213 switch (p_exif_data->tag_entry.type) {
214 case EXIF_BYTE: {
215 if (p_exif_data->tag_entry.count > 1 &&
216 p_exif_data->tag_entry.data._bytes != NULL) {
217 free(p_exif_data->tag_entry.data._bytes);
218 p_exif_data->tag_entry.data._bytes = NULL;
219 }
220 }
221 break;
222 case EXIF_ASCII: {
223 if (p_exif_data->tag_entry.data._ascii != NULL) {
224 free(p_exif_data->tag_entry.data._ascii);
225 p_exif_data->tag_entry.data._ascii = NULL;
226 }
227 }
228 break;
229 case EXIF_SHORT: {
230 if (p_exif_data->tag_entry.count > 1 &&
231 p_exif_data->tag_entry.data._shorts != NULL) {
232 free(p_exif_data->tag_entry.data._shorts);
233 p_exif_data->tag_entry.data._shorts = NULL;
234 }
235 }
236 break;
237 case EXIF_LONG: {
238 if (p_exif_data->tag_entry.count > 1 &&
239 p_exif_data->tag_entry.data._longs != NULL) {
240 free(p_exif_data->tag_entry.data._longs);
241 p_exif_data->tag_entry.data._longs = NULL;
242 }
243 }
244 break;
245 case EXIF_RATIONAL: {
246 if (p_exif_data->tag_entry.count > 1 &&
247 p_exif_data->tag_entry.data._rats != NULL) {
248 free(p_exif_data->tag_entry.data._rats);
249 p_exif_data->tag_entry.data._rats = NULL;
250 }
251 }
252 break;
253 case EXIF_UNDEFINED: {
254 if (p_exif_data->tag_entry.data._undefined != NULL) {
255 free(p_exif_data->tag_entry.data._undefined);
256 p_exif_data->tag_entry.data._undefined = NULL;
257 }
258 }
259 break;
260 case EXIF_SLONG: {
261 if (p_exif_data->tag_entry.count > 1 &&
262 p_exif_data->tag_entry.data._slongs != NULL) {
263 free(p_exif_data->tag_entry.data._slongs);
264 p_exif_data->tag_entry.data._slongs = NULL;
265 }
266 }
267 break;
268 case EXIF_SRATIONAL: {
269 if (p_exif_data->tag_entry.count > 1 &&
270 p_exif_data->tag_entry.data._srats != NULL) {
271 free(p_exif_data->tag_entry.data._srats);
272 p_exif_data->tag_entry.data._srats = NULL;
273 }
274 }
275 break;
276 } /*end of switch*/
277
278 return 0;
279 }
280
281 /** process_sensor_data:
282 *
283 * Arguments:
284 * @p_sensor_params : ptr to sensor data
285 *
286 * Return : int32_t type of status
287 * NO_ERROR -- success
288 * none-zero failure code
289 *
290 * Description:
291 * process sensor data
292 *
293 * Notes: this needs to be filled for the metadata
294 **/
process_sensor_data(cam_sensor_params_t * p_sensor_params,QOMX_EXIF_INFO * exif_info)295 int process_sensor_data(cam_sensor_params_t *p_sensor_params,
296 QOMX_EXIF_INFO *exif_info)
297 {
298 int rc = 0;
299 rat_t val_rat;
300 double av;
301
302 if (NULL == p_sensor_params) {
303 ALOGE("%s %d: Sensor params are null", __func__, __LINE__);
304 return 0;
305 }
306
307 CDBG_HIGH("%s:%d] From metadata aperture = %f ", __func__, __LINE__,
308 p_sensor_params->aperture_value );
309
310 if (p_sensor_params->aperture_value >= 1.0) {
311 val_rat.num = (uint32_t)(p_sensor_params->aperture_value * 100);
312 val_rat.denom = 100;
313 rc = addExifEntry(exif_info, EXIFTAGID_APERTURE, EXIF_RATIONAL, 1, &val_rat);
314 if (rc) {
315 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
316 }
317
318 val_rat.num = (uint32_t)(p_sensor_params->aperture_value * 100);
319 val_rat.denom = 100;
320 rc = addExifEntry(exif_info, EXIFTAGID_F_NUMBER, EXIF_RATIONAL, 1, &val_rat);
321 if (rc) {
322 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
323 }
324 }
325
326 /*Flash*/
327 short val_short;
328 if (p_sensor_params->flash_state == CAM_FLASH_STATE_FIRED) {
329 val_short = 1;
330 } else {
331 val_short = 0;
332 }
333 CDBG_HIGH("%s: Flash value %d flash mode %d flash state %d", __func__, val_short,
334 p_sensor_params->flash_mode, p_sensor_params->flash_state);
335 rc = addExifEntry(exif_info, EXIFTAGID_FLASH, EXIF_SHORT, 1, &val_short);
336 if (rc) {
337 ALOGE("%s %d]: Error adding flash exif entry", __func__, __LINE__);
338 }
339 /* Sensing Method */
340 val_short = p_sensor_params->sensing_method;
341 rc = addExifEntry(exif_info, EXIFTAGID_SENSING_METHOD, EXIF_SHORT,
342 sizeof(val_short)/2, &val_short);
343 if (rc) {
344 ALOGE("%s:%d]: Error adding flash Exif Entry", __func__, __LINE__);
345 }
346
347 /*Focal Length in 35 MM Film */
348 val_short = (short) p_sensor_params->focal_length*p_sensor_params->crop_factor;
349 rc = addExifEntry(exif_info, EXIFTAGID_FOCAL_LENGTH_35MM, EXIF_SHORT, 1, &val_short);
350 if (rc) {
351 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
352 }
353
354 return rc;
355 }
356
357
358 /** process_3a_data:
359 *
360 * Arguments:
361 * @p_3a_params : ptr to 3a data
362 *
363 * Return : int32_t type of status
364 * NO_ERROR -- success
365 * none-zero failure code
366 *
367 * Description:
368 * process 3a data
369 *
370 * Notes: this needs to be filled for the metadata
371 **/
process_3a_data(cam_3a_params_t * p_3a_params,QOMX_EXIF_INFO * exif_info)372 int process_3a_data(cam_3a_params_t *p_3a_params, QOMX_EXIF_INFO *exif_info)
373 {
374 int rc = 0;
375 srat_t val_srat;
376 rat_t val_rat;
377 double shutter_speed_value;
378
379 if (NULL == p_3a_params) {
380 ALOGE("%s %d: 3A params are null", __func__, __LINE__);
381 return 0;
382 }
383
384 CDBG_HIGH("%s:%d] exp_time %f, iso_value %d, wb_mode %d", __func__, __LINE__,
385 p_3a_params->exp_time, p_3a_params->iso_value, p_3a_params->wb_mode);
386
387 /*Exposure time*/
388 if (p_3a_params->exp_time == 0) {
389 val_rat.num = 0;
390 val_rat.denom = 0;
391 } else {
392 val_rat.num = 1;
393 val_rat.denom = ROUND(1.0/p_3a_params->exp_time);
394 }
395 CDBG_HIGH("%s: numer %d denom %d %d", __func__, val_rat.num, val_rat.denom, sizeof(val_rat)/(8));
396
397 rc = addExifEntry(exif_info, EXIFTAGID_EXPOSURE_TIME, EXIF_RATIONAL,
398 (sizeof(val_rat)/(8)), &val_rat);
399 if (rc) {
400 ALOGE("%s:%d]: Error adding Exif Entry Exposure time",
401 __func__, __LINE__);
402 }
403
404 /* Shutter Speed*/
405 if (p_3a_params->exp_time > 0) {
406 shutter_speed_value = log10(1/p_3a_params->exp_time)/log10(2);
407 val_srat.num = shutter_speed_value * 1000;
408 val_srat.denom = 1000;
409 } else {
410 val_srat.num = 0;
411 val_srat.denom = 0;
412 }
413 rc = addExifEntry(exif_info, EXIFTAGID_SHUTTER_SPEED, EXIF_SRATIONAL,
414 (sizeof(val_srat)/(8)), &val_srat);
415 if (rc) {
416 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
417 }
418
419 /*ISO*/
420 short val_short;
421 val_short = p_3a_params->iso_value;
422 rc = addExifEntry(exif_info, EXIFTAGID_ISO_SPEED_RATING, EXIF_SHORT,
423 sizeof(val_short)/2, &val_short);
424 if (rc) {
425 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
426 }
427
428 /*WB mode*/
429 if (p_3a_params->wb_mode == CAM_WB_MODE_AUTO)
430 val_short = 0;
431 else
432 val_short = 1;
433 rc = addExifEntry(exif_info, EXIFTAGID_WHITE_BALANCE, EXIF_SHORT,
434 sizeof(val_short)/2, &val_short);
435 if (rc) {
436 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
437 }
438
439 /* Metering Mode */
440 val_short = (unsigned short) p_3a_params->metering_mode;
441 rc = addExifEntry(exif_info,EXIFTAGID_METERING_MODE, EXIF_SHORT,
442 sizeof(val_short)/2, &val_short);
443 if (rc) {
444 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
445 }
446
447 /*Exposure Program*/
448 val_short = (unsigned short) p_3a_params->exposure_program;
449 rc = addExifEntry(exif_info,EXIFTAGID_EXPOSURE_PROGRAM, EXIF_SHORT,
450 sizeof(val_short)/2, &val_short);
451 if (rc) {
452 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
453 }
454
455 /*Exposure Mode */
456 val_short = (unsigned short) p_3a_params->exposure_mode;
457 rc = addExifEntry(exif_info,EXIFTAGID_EXPOSURE_MODE, EXIF_SHORT,
458 sizeof(val_short)/2, &val_short);
459 if (rc) {
460 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
461 }
462
463 /*Scenetype*/
464 uint8_t val_undef;
465 val_undef = (uint8_t) p_3a_params->scenetype;
466 rc = addExifEntry(exif_info,EXIFTAGID_SCENE_TYPE, EXIF_UNDEFINED,
467 sizeof(val_undef), &val_undef);
468 if (rc) {
469 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
470 }
471
472 /* Brightness Value*/
473 val_srat.num = p_3a_params->brightness*100;
474 val_srat.denom = 100;
475 rc = addExifEntry(exif_info,EXIFTAGID_BRIGHTNESS, EXIF_SRATIONAL,
476 (sizeof(val_srat)/(8)), &val_srat);
477 if (rc) {
478 ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__);
479 }
480
481 return rc;
482 }
483
484 /** process_meta_data
485 *
486 * Arguments:
487 * @p_meta : ptr to metadata
488 * @exif_info: Exif info struct
489 * @mm_jpeg_exif_params: exif params
490 *
491 * Return : int32_t type of status
492 * NO_ERROR -- success
493 * none-zero failure code
494 *
495 * Description:
496 * Extract exif data from the metadata
497 **/
process_meta_data(metadata_buffer_t * p_meta,QOMX_EXIF_INFO * exif_info,mm_jpeg_exif_params_t * p_cam_exif_params,cam_hal_version_t hal_version)498 int process_meta_data(metadata_buffer_t *p_meta, QOMX_EXIF_INFO *exif_info,
499 mm_jpeg_exif_params_t *p_cam_exif_params, cam_hal_version_t hal_version)
500 {
501 int rc = 0;
502 cam_sensor_params_t p_sensor_params;
503 cam_3a_params_t p_3a_params;
504 cam_auto_scene_t *scene_cap_type;
505
506 if (!p_meta) {
507 ALOGE("%s %d:Meta data is NULL", __func__, __LINE__);
508 return 0;
509 }
510
511 memset(&p_3a_params, 0, sizeof(cam_3a_params_t));
512 memset(&p_sensor_params, 0, sizeof(cam_sensor_params_t));
513
514 if (hal_version == CAM_HAL_V1) {
515 if (p_cam_exif_params) {
516 p_sensor_params = p_cam_exif_params->sensor_params;
517 p_3a_params = p_cam_exif_params->cam_3a_params;
518 } else {
519 p_sensor_params.focal_length = 0;
520 p_sensor_params.f_number = 0;
521 p_sensor_params.sensing_method = 1;
522 p_sensor_params.crop_factor = 0;
523 p_3a_params.exp_time = 0.0;
524 p_3a_params.iso_value = 0;
525 p_3a_params.metering_mode = 0;
526 p_3a_params.exposure_program = 0;
527 p_3a_params.exposure_mode = 255;
528 p_3a_params.scenetype = 1;
529 p_3a_params.brightness = 0.0;
530 }
531
532 } else {
533 /* Process 3a data */
534 int32_t *iso =
535 (int32_t *)POINTER_OF_META(CAM_INTF_META_SENSOR_SENSITIVITY, p_meta);
536 if (NULL != iso) {
537 p_3a_params.iso_value= *iso;
538 } else {
539 ALOGE("%s: Cannot extract Iso value", __func__);
540 }
541
542 int64_t *sensor_exposure_time =
543 (int64_t *)POINTER_OF_META(CAM_INTF_META_SENSOR_EXPOSURE_TIME, p_meta);
544 if (NULL != sensor_exposure_time) {
545 p_3a_params.exp_time = (double)(*sensor_exposure_time / 1000000000.0);
546 } else {
547 ALOGE("%s: Cannot extract Exp time value", __func__);
548 }
549
550 cam_wb_mode_type *wb_mode =
551 (cam_wb_mode_type *)POINTER_OF_META(CAM_INTF_PARM_WHITE_BALANCE, p_meta);
552 if (NULL != wb_mode) {
553 p_3a_params.wb_mode = *wb_mode;
554 } else {
555 ALOGE("%s: Cannot extract white balance mode", __func__);
556 }
557
558 /* Process sensor data */
559 float *aperture = (float *)POINTER_OF_META(CAM_INTF_META_LENS_APERTURE, p_meta);
560 if (NULL != aperture) {
561 p_sensor_params.aperture_value = *aperture;
562 } else {
563 ALOGE("%s: Cannot extract Aperture value", __func__);
564 }
565
566 uint8_t *flash_mode = (uint8_t *) POINTER_OF_META(CAM_INTF_META_FLASH_MODE, p_meta);
567 if (NULL != flash_mode) {
568 p_sensor_params.flash_mode = *flash_mode;
569 } else {
570 ALOGE("%s: Cannot extract flash mode value", __func__);
571 }
572
573 uint8_t *flash_state =
574 (uint8_t *) POINTER_OF_META(CAM_INTF_META_FLASH_STATE, p_meta);
575 if (NULL != flash_state) {
576 p_sensor_params.flash_state = *flash_state;
577 } else {
578 ALOGE("%s: Cannot extract flash state value", __func__);
579 }
580 }
581 rc = process_3a_data(&p_3a_params, exif_info);
582 if (rc) {
583 ALOGE("%s %d: Failed to add 3a exif params", __func__, __LINE__);
584 }
585
586 rc = process_sensor_data(&p_sensor_params, exif_info);
587 if (rc) {
588 ALOGE("%s %d: Failed to extract sensor params", __func__, __LINE__);
589 }
590 short val_short;
591 scene_cap_type =
592 (cam_auto_scene_t *)POINTER_OF_META(CAM_INTF_META_ASD_SCENE_CAPTURE_TYPE, p_meta);
593 if(scene_cap_type != NULL)
594 val_short = (short) *scene_cap_type;
595 else val_short = 0;
596 rc = addExifEntry(exif_info, EXIFTAGID_SCENE_CAPTURE_TYPE, EXIF_SHORT,
597 sizeof(val_short)/2, &val_short);
598 if (rc) {
599 ALOGE("%s:%d]: Error adding ASD Exif Entry", __func__, __LINE__);
600 }
601
602 /* set orientation to ORIENTATION_UNDEFINED */
603 int16_t orientation = 0;
604 rc = addExifEntry(exif_info, EXIFTAGID_ORIENTATION,
605 EXIF_SHORT,
606 1,
607 (void *)&orientation);
608 if (rc) {
609 ALOGE("%s:%d]: Error adding Exif Entry Orientation",
610 __func__, __LINE__);
611 }
612
613 return rc;
614 }
615