From bcbeb5ebefcbe020751f793af075b3ab2596c899 Mon Sep 17 00:00:00 2001 From: ghepeu Date: Sun, 5 May 2013 02:30:20 +0200 Subject: [PATCH] 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 --- camera/exynos_exif.c | 54 ++++++++++++++++++++++++-------------------- 1 file 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,