diff options
author | ghepeu <ghepeu@gmail.com> | 2013-05-05 02:30:20 +0200 |
---|---|---|
committer | ghepeu <ghepeu@gmail.com> | 2013-05-05 14:49:05 +0200 |
commit | bcbeb5ebefcbe020751f793af075b3ab2596c899 (patch) | |
tree | a5647945735be0203fc37ec5258479bb5e89f4a2 /camera | |
parent | 8f1e7b0333d4f7ec1fa946c02b7d07a2a5ac3104 (diff) | |
download | device_samsung_galaxys2-common-bcbeb5ebefcbe020751f793af075b3ab2596c899.zip device_samsung_galaxys2-common-bcbeb5ebefcbe020751f793af075b3ab2596c899.tar.gz device_samsung_galaxys2-common-bcbeb5ebefcbe020751f793af075b3ab2596c899.tar.bz2 |
galaxys2-common: fix EXIF data generated by the camera
* ensure that all IFDs are 12 bytes long; previously when the data field contained less than 4 bytes of data the IFDs were truncated too soon
* change all data types and number of components according to the EXIF standard
* get the actual status of the flash from the camera; previosly the camera flash settings (which are not valid EXIF values) were copied in
* fix calculations of GPS coordinates
With these changes the EXIF generated by the camera are valid and readable. There are still issues with some tags but most data is correct now.
Thanks to dafnis, who identified the problematic fields, and tryptophane, who helped testing.
Patch Set 2: fix whitespaces.
Change-Id: I513ea89f69ff26646e6a4a439b1cd5b835cba8d6
Diffstat (limited to 'camera')
-rw-r--r-- | camera/exynos_exif.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/camera/exynos_exif.c b/camera/exynos_exif.c index 0f6c4f1..bb97a17 100644 --- a/camera/exynos_exif.c +++ b/camera/exynos_exif.c @@ -133,8 +133,8 @@ int exynos_exif_attributes_create_gps(struct exynos_camera *exynos_camera, return 0; } - gps_latitude = (long) (gps_latitude_float * 10000) / 1; - gps_longitude = (long) (gps_longitude_float * 10000) / 1; + gps_latitude = (long) (gps_latitude_float * 10000000) / 1; + gps_longitude = (long) (gps_longitude_float * 10000000) / 1; gps_altitude = (long) (gps_altitude_float * 100) / 1; gps_timestamp = (long) gps_timestamp_int; @@ -159,26 +159,26 @@ int exynos_exif_attributes_create_gps(struct exynos_camera *exynos_camera, exif_attributes->gps_altitude_ref = 1; - gps_latitude_abs = fabs(gps_latitude / 10000.0); - gps_longitude_abs = fabs(gps_longitude / 10000.0); - gps_altitude_abs = fabs(gps_altitude / 100.0); + gps_latitude_abs = fabs(gps_latitude); + gps_longitude_abs = fabs(gps_longitude); + gps_altitude_abs = fabs(gps_altitude); exif_attributes->gps_latitude[0].num = (uint32_t) gps_latitude_abs; - exif_attributes->gps_latitude[0].den = 1; + exif_attributes->gps_latitude[0].den = 10000000; exif_attributes->gps_latitude[1].num = 0; exif_attributes->gps_latitude[1].den = 1; exif_attributes->gps_latitude[2].num = 0; exif_attributes->gps_latitude[2].den = 1; exif_attributes->gps_longitude[0].num = (uint32_t) gps_longitude_abs; - exif_attributes->gps_longitude[0].den = 1; + exif_attributes->gps_longitude[0].den = 10000000; exif_attributes->gps_longitude[1].num = 0; exif_attributes->gps_longitude[1].den = 1; exif_attributes->gps_longitude[2].num = 0; exif_attributes->gps_longitude[2].den = 1; exif_attributes->gps_altitude.num = (uint32_t) gps_altitude_abs; - exif_attributes->gps_altitude.den = 1; + exif_attributes->gps_altitude.den = 100; gmtime_r(&gps_timestamp, &time_info); @@ -207,6 +207,7 @@ int exynos_exif_attributes_create_params(struct exynos_camera *exynos_camera, int exposure_time; int iso_speed; int exposure; + int flash_results; int rc; @@ -274,6 +275,13 @@ int exynos_exif_attributes_create_params(struct exynos_camera *exynos_camera, exif_attributes->iso_speed_rating = iso_speed; + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_FLASH, + &flash_results); + if (rc < 0) + ALOGE("%s: g ctrl failed!", __func__); + + exif_attributes->flash = flash_results; + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_BV, (int *) &bv); if (rc < 0) { @@ -330,11 +338,6 @@ bv_ioctl: break; } - if (exynos_camera->flash_mode == FLASH_MODE_BASE) - exif_attributes->flash = EXIF_DEF_FLASH; - else - exif_attributes->flash = exynos_camera->flash_mode; - if (exynos_camera->whitebalance == WHITE_BALANCE_AUTO || exynos_camera->whitebalance == WHITE_BALANCE_BASE) exif_attributes->white_balance = EXIF_WB_AUTO; @@ -394,7 +397,7 @@ int exynos_exif_write_data(void *exif_data, unsigned short tag, *offset += count * length; } else { memcpy(pointer, data, count * length); - pointer += count * length; + pointer += 4; } size = (int) pointer - (int) exif_data; @@ -412,7 +415,7 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, unsigned char exif_marker[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; unsigned char tiff_marker[] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 }; - unsigned char user_comment_code[] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 }; + unsigned char user_comment_code[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; unsigned char exif_ascii_prefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; camera_memory_t *exif_data_memory; @@ -553,7 +556,7 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_VERSION, - EXIF_TYPE_UNDEFINED, 1, NULL, NULL, &exif_attributes->exif_version, sizeof(exif_attributes->exif_version)); + EXIF_TYPE_UNDEFINED, 4, NULL, NULL, &exif_attributes->exif_version, sizeof(char)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_ORG, @@ -617,15 +620,15 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_MODE, - EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->exposure_mode, sizeof(exif_attributes->exposure_mode)); + EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->exposure_mode, sizeof(exif_attributes->exposure_mode)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_WHITE_BALANCE, - EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->white_balance, sizeof(exif_attributes->white_balance)); + EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->white_balance, sizeof(exif_attributes->white_balance)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_SCENCE_CAPTURE_TYPE, - EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->scene_capture_type, sizeof(exif_attributes->scene_capture_type)); + EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->scene_capture_type, sizeof(exif_attributes->scene_capture_type)); pointer += count; value = 0; @@ -651,11 +654,11 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, offset += NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_VERSION_ID, - EXIF_TYPE_LONG, 4, NULL, NULL, &exif_attributes->gps_version_id, 1); + EXIF_TYPE_BYTE, 4, NULL, NULL, &exif_attributes->gps_version_id, sizeof(char)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE_REF, - EXIF_TYPE_ASCII, 2, NULL, NULL, &exif_attributes->gps_latitude_ref, 1); + EXIF_TYPE_ASCII, 2, NULL, NULL, &exif_attributes->gps_latitude_ref, sizeof(char)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE, @@ -663,14 +666,15 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE_REF, - EXIF_TYPE_ASCII, 2, NULL, NULL, &exif_attributes->gps_longitude_ref, 1); + EXIF_TYPE_ASCII, 2, NULL, NULL, &exif_attributes->gps_longitude_ref, sizeof(char)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &exif_attributes->gps_longitude, sizeof(exif_attributes->gps_longitude[0])); + pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE_REF, - EXIF_TYPE_BYTE, 1, NULL, NULL, &exif_attributes->gps_altitude_ref, 1); + EXIF_TYPE_BYTE, 1, NULL, NULL, &exif_attributes->gps_altitude_ref, sizeof(char)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE, @@ -690,7 +694,7 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, memcpy((void *) ((int) data + (int) sizeof(exif_ascii_prefix)), exif_attributes->gps_processing_method, value); count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_PROCESSING_METHOD, - EXIF_TYPE_UNDEFINED, value + sizeof(exif_ascii_prefix), &offset, exif_ifd_start, data, 1); + EXIF_TYPE_UNDEFINED, value + sizeof(exif_ascii_prefix), &offset, exif_ifd_start, data, sizeof(char)); pointer += count; free(data); @@ -729,7 +733,7 @@ int exynos_exif_create(struct exynos_camera *exynos_camera, pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_COMPRESSION_SCHEME, - EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->compression_scheme, sizeof(exif_attributes->compression_scheme)); + EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->compression_scheme, sizeof(exif_attributes->compression_scheme)); pointer += count; count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION, |