diff options
author | Tyler Luu <tluu@ti.com> | 2011-09-07 22:19:09 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-09-12 16:15:48 -0700 |
commit | 36e9bdd56757ff8048e08f6e52f234480c44f122 (patch) | |
tree | 5eccf8d64f6fd808fc2d1a6ed8f590cdc49607ef /camera/Encoder_libjpeg.cpp | |
parent | 6b5eaf29c3d17a24731bf9271bd0d199d433813e (diff) | |
download | hardware_ti_omap4xxx-36e9bdd56757ff8048e08f6e52f234480c44f122.zip hardware_ti_omap4xxx-36e9bdd56757ff8048e08f6e52f234480c44f122.tar.gz hardware_ti_omap4xxx-36e9bdd56757ff8048e08f6e52f234480c44f122.tar.bz2 |
CameraHal: Add Exif support to video snapshot
Use jhead library to insert Exif to jpeg stream
returned from libjpeg.
Change-Id: Ia6398180b7ef3c1b3ddcb35e489527289565fef5
Signed-off-by: Tyler Luu <tluu@ti.com>
Diffstat (limited to 'camera/Encoder_libjpeg.cpp')
-rw-r--r-- | camera/Encoder_libjpeg.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/camera/Encoder_libjpeg.cpp b/camera/Encoder_libjpeg.cpp index dfdd934..99650cc 100644 --- a/camera/Encoder_libjpeg.cpp +++ b/camera/Encoder_libjpeg.cpp @@ -41,8 +41,21 @@ extern "C" { #include "jerror.h" } +#define ARRAY_SIZE(array) (sizeof((array)) / sizeof((array)[0])) + namespace android { +struct string_pair { + const char* string1; + const char* string2; +}; +static string_pair degress_to_exif_lut [] = { + // degrees, exif_orientation + {"0", "1"}, + {"90", "6"}, + {"180", "3"}, + {"270", "8"}, +}; struct libjpeg_destination_mgr : jpeg_destination_mgr { libjpeg_destination_mgr(uint8_t* input, int size); @@ -101,6 +114,86 @@ static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { } } +/* public static functions */ +const char* ExifElementsTable::degreesToExifOrientation(const char* degrees) { + for (int i = 0; i < ARRAY_SIZE(degress_to_exif_lut); i++) { + if (!strcmp(degrees, degress_to_exif_lut[i].string1)) { + return degress_to_exif_lut[i].string2; + } + } + return NULL; +} + +void ExifElementsTable::insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size) { + ReadMode_t read_mode = (ReadMode_t)(READ_METADATA | READ_IMAGE); + + ResetJpgfile(); + if (ReadJpegSectionsFromBuffer(jpeg, jpeg_size, read_mode)) { + jpeg_opened = true; + create_EXIF(table, exif_tag_count, gps_tag_count); + } +} + +void ExifElementsTable::saveJpeg(unsigned char* jpeg, size_t jpeg_size) { + if (jpeg_opened) { + WriteJpegToBuffer(jpeg, jpeg_size); + DiscardData(); + jpeg_opened = false; + } +} + +/* public functions */ +ExifElementsTable::~ExifElementsTable() { + int num_elements = gps_tag_count + exif_tag_count; + + for (int i = 0; i < num_elements; i++) { + if (table[i].Value) { + free(table[i].Value); + } + } + + if (jpeg_opened) { + DiscardData(); + } +} + +status_t ExifElementsTable::insertElement(const char* tag, const char* value) { + int value_length = 0; + status_t ret = NO_ERROR; + + if (!value || !tag) { + return -EINVAL; + } + + if (position >= MAX_EXIF_TAGS_SUPPORTED) { + CAMHAL_LOGEA("Max number of EXIF elements already inserted"); + return NO_MEMORY; + } + + value_length = strlen(value); + + if (IsGpsTag(tag)) { + table[position].GpsTag = TRUE; + table[position].Tag = GpsTagNameToValue(tag); + gps_tag_count++; + } else { + table[position].GpsTag = FALSE; + table[position].Tag = TagNameToValue(tag); + exif_tag_count++; + } + + table[position].DataLength = 0; + table[position].Value = (char*) malloc(sizeof(char) * (value_length + 1)); + + if (table[position].Value) { + strncpy(table[position].Value, value, value_length); + table[position].DataLength = value_length + 1; + } + + position++; + return ret; +} + /* private member functions */ size_t Encoder_libjpeg::encode() { jpeg_compress_struct cinfo; |