Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      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 #include <inttypes.h>
     18 #include <system/camera_metadata.h>
     19 #include <camera_metadata_hidden.h>
     20 
     21 #define LOG_TAG "camera_metadata"
     22 #include <cutils/log.h>
     23 #include <assert.h>
     24 #include <stdio.h>
     25 #include <stdlib.h>
     26 #include <errno.h>
     27 
     28 #define OK              0
     29 #define ERROR           1
     30 #define NOT_FOUND       -ENOENT
     31 #define SN_EVENT_LOG_ID 0x534e4554
     32 
     33 #define ALIGN_TO(val, alignment) \
     34     (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
     35 
     36 /**
     37  * A single metadata entry, storing an array of values of a given type. If the
     38  * array is no larger than 4 bytes in size, it is stored in the data.value[]
     39  * array; otherwise, it can found in the parent's data array at index
     40  * data.offset.
     41  */
     42 #define ENTRY_ALIGNMENT ((size_t) 4)
     43 typedef struct camera_metadata_buffer_entry {
     44     uint32_t tag;
     45     uint32_t count;
     46     union {
     47         uint32_t offset;
     48         uint8_t  value[4];
     49     } data;
     50     uint8_t  type;
     51     uint8_t  reserved[3];
     52 } camera_metadata_buffer_entry_t;
     53 
     54 typedef uint32_t metadata_uptrdiff_t;
     55 typedef uint32_t metadata_size_t;
     56 
     57 /**
     58  * A packet of metadata. This is a list of entries, each of which may point to
     59  * its values stored at an offset in data.
     60  *
     61  * It is assumed by the utility functions that the memory layout of the packet
     62  * is as follows:
     63  *
     64  *   |-----------------------------------------------|
     65  *   | camera_metadata_t                             |
     66  *   |                                               |
     67  *   |-----------------------------------------------|
     68  *   | reserved for future expansion                 |
     69  *   |-----------------------------------------------|
     70  *   | camera_metadata_buffer_entry_t #0             |
     71  *   |-----------------------------------------------|
     72  *   | ....                                          |
     73  *   |-----------------------------------------------|
     74  *   | camera_metadata_buffer_entry_t #entry_count-1 |
     75  *   |-----------------------------------------------|
     76  *   | free space for                                |
     77  *   | (entry_capacity-entry_count) entries          |
     78  *   |-----------------------------------------------|
     79  *   | start of camera_metadata.data                 |
     80  *   |                                               |
     81  *   |-----------------------------------------------|
     82  *   | free space for                                |
     83  *   | (data_capacity-data_count) bytes              |
     84  *   |-----------------------------------------------|
     85  *
     86  * With the total length of the whole packet being camera_metadata.size bytes.
     87  *
     88  * In short, the entries and data are contiguous in memory after the metadata
     89  * header.
     90  */
     91 #define METADATA_ALIGNMENT ((size_t) 4)
     92 struct camera_metadata {
     93     metadata_size_t          size;
     94     uint32_t                 version;
     95     uint32_t                 flags;
     96     metadata_size_t          entry_count;
     97     metadata_size_t          entry_capacity;
     98     metadata_uptrdiff_t      entries_start; // Offset from camera_metadata
     99     metadata_size_t          data_count;
    100     metadata_size_t          data_capacity;
    101     metadata_uptrdiff_t      data_start; // Offset from camera_metadata
    102     uint8_t                  reserved[];
    103 };
    104 
    105 /**
    106  * A datum of metadata. This corresponds to camera_metadata_entry_t::data
    107  * with the difference that each element is not a pointer. We need to have a
    108  * non-pointer type description in order to figure out the largest alignment
    109  * requirement for data (DATA_ALIGNMENT).
    110  */
    111 #define DATA_ALIGNMENT ((size_t) 8)
    112 typedef union camera_metadata_data {
    113     uint8_t u8;
    114     int32_t i32;
    115     float   f;
    116     int64_t i64;
    117     double  d;
    118     camera_metadata_rational_t r;
    119 } camera_metadata_data_t;
    120 
    121 /**
    122  * The preferred alignment of a packet of camera metadata. In general,
    123  * this is the lowest common multiple of the constituents of a metadata
    124  * package, i.e, of DATA_ALIGNMENT and ENTRY_ALIGNMENT.
    125  */
    126 #define MAX_ALIGNMENT(A, B) (((A) > (B)) ? (A) : (B))
    127 #define METADATA_PACKET_ALIGNMENT \
    128     MAX_ALIGNMENT(MAX_ALIGNMENT(DATA_ALIGNMENT, METADATA_ALIGNMENT), ENTRY_ALIGNMENT);
    129 
    130 /** Versioning information */
    131 #define CURRENT_METADATA_VERSION 1
    132 
    133 /** Flag definitions */
    134 #define FLAG_SORTED 0x00000001
    135 
    136 /** Tag information */
    137 
    138 typedef struct tag_info {
    139     const char *tag_name;
    140     uint8_t     tag_type;
    141 } tag_info_t;
    142 
    143 #include "camera_metadata_tag_info.c"
    144 
    145 const size_t camera_metadata_type_size[NUM_TYPES] = {
    146     [TYPE_BYTE]     = sizeof(uint8_t),
    147     [TYPE_INT32]    = sizeof(int32_t),
    148     [TYPE_FLOAT]    = sizeof(float),
    149     [TYPE_INT64]    = sizeof(int64_t),
    150     [TYPE_DOUBLE]   = sizeof(double),
    151     [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
    152 };
    153 
    154 const char *camera_metadata_type_names[NUM_TYPES] = {
    155     [TYPE_BYTE]     = "byte",
    156     [TYPE_INT32]    = "int32",
    157     [TYPE_FLOAT]    = "float",
    158     [TYPE_INT64]    = "int64",
    159     [TYPE_DOUBLE]   = "double",
    160     [TYPE_RATIONAL] = "rational"
    161 };
    162 
    163 static camera_metadata_buffer_entry_t *get_entries(
    164         const camera_metadata_t *metadata) {
    165     return (camera_metadata_buffer_entry_t*)
    166             ((uint8_t*)metadata + metadata->entries_start);
    167 }
    168 
    169 static uint8_t *get_data(const camera_metadata_t *metadata) {
    170     return (uint8_t*)metadata + metadata->data_start;
    171 }
    172 
    173 size_t get_camera_metadata_alignment() {
    174     return METADATA_PACKET_ALIGNMENT;
    175 }
    176 
    177 camera_metadata_t *allocate_copy_camera_metadata_checked(
    178         const camera_metadata_t *src,
    179         size_t src_size) {
    180 
    181     if (src == NULL) {
    182         return NULL;
    183     }
    184 
    185     void *buffer = malloc(src_size);
    186     memcpy(buffer, src, src_size);
    187 
    188     camera_metadata_t *metadata = (camera_metadata_t*) buffer;
    189     if (validate_camera_metadata_structure(metadata, &src_size) != OK) {
    190         free(buffer);
    191         return NULL;
    192     }
    193 
    194     return metadata;
    195 }
    196 
    197 camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
    198                                             size_t data_capacity) {
    199 
    200     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
    201                                                           data_capacity);
    202     void *buffer = malloc(memory_needed);
    203     return place_camera_metadata(buffer, memory_needed,
    204                                  entry_capacity,
    205                                  data_capacity);
    206 }
    207 
    208 camera_metadata_t *place_camera_metadata(void *dst,
    209                                          size_t dst_size,
    210                                          size_t entry_capacity,
    211                                          size_t data_capacity) {
    212     if (dst == NULL) return NULL;
    213 
    214     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
    215                                                           data_capacity);
    216     if (memory_needed > dst_size) return NULL;
    217 
    218     camera_metadata_t *metadata = (camera_metadata_t*)dst;
    219     metadata->version = CURRENT_METADATA_VERSION;
    220     metadata->flags = 0;
    221     metadata->entry_count = 0;
    222     metadata->entry_capacity = entry_capacity;
    223     metadata->entries_start =
    224             ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT);
    225     metadata->data_count = 0;
    226     metadata->data_capacity = data_capacity;
    227     metadata->size = memory_needed;
    228     size_t data_unaligned = (uint8_t*)(get_entries(metadata) +
    229             metadata->entry_capacity) - (uint8_t*)metadata;
    230     metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT);
    231 
    232     assert(validate_camera_metadata_structure(metadata, NULL) == OK);
    233     return metadata;
    234 }
    235 void free_camera_metadata(camera_metadata_t *metadata) {
    236     free(metadata);
    237 }
    238 
    239 size_t calculate_camera_metadata_size(size_t entry_count,
    240                                       size_t data_count) {
    241     size_t memory_needed = sizeof(camera_metadata_t);
    242     // Start entry list at aligned boundary
    243     memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT);
    244     memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
    245     // Start buffer list at aligned boundary
    246     memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT);
    247     memory_needed += sizeof(uint8_t[data_count]);
    248     return memory_needed;
    249 }
    250 
    251 size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
    252     if (metadata == NULL) return ERROR;
    253 
    254     return metadata->size;
    255 }
    256 
    257 size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
    258     if (metadata == NULL) return ERROR;
    259 
    260     return calculate_camera_metadata_size(metadata->entry_count,
    261                                           metadata->data_count);
    262 }
    263 
    264 size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
    265     return metadata->entry_count;
    266 }
    267 
    268 size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
    269     return metadata->entry_capacity;
    270 }
    271 
    272 size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
    273     return metadata->data_count;
    274 }
    275 
    276 size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
    277     return metadata->data_capacity;
    278 }
    279 
    280 camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
    281         const camera_metadata_t *src) {
    282     size_t memory_needed = get_camera_metadata_compact_size(src);
    283 
    284     if (dst == NULL) return NULL;
    285     if (dst_size < memory_needed) return NULL;
    286 
    287     camera_metadata_t *metadata =
    288         place_camera_metadata(dst, dst_size, src->entry_count, src->data_count);
    289 
    290     metadata->flags = src->flags;
    291     metadata->entry_count = src->entry_count;
    292     metadata->data_count = src->data_count;
    293 
    294     memcpy(get_entries(metadata), get_entries(src),
    295             sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
    296     memcpy(get_data(metadata), get_data(src),
    297             sizeof(uint8_t[metadata->data_count]));
    298 
    299     assert(validate_camera_metadata_structure(metadata, NULL) == OK);
    300     return metadata;
    301 }
    302 
    303 // This method should be used when the camera metadata cannot be trusted. For example, when it's
    304 // read from Parcel.
    305 static int validate_and_calculate_camera_metadata_entry_data_size(size_t *data_size, uint8_t type,
    306         size_t data_count) {
    307     if (type >= NUM_TYPES) return ERROR;
    308 
    309     // Check for overflow
    310     if (data_count != 0 &&
    311             camera_metadata_type_size[type] > (SIZE_MAX - DATA_ALIGNMENT + 1) / data_count) {
    312         android_errorWriteLog(SN_EVENT_LOG_ID, "30741779");
    313         return ERROR;
    314     }
    315 
    316     size_t data_bytes = data_count * camera_metadata_type_size[type];
    317 
    318     if (data_size) {
    319         *data_size = data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
    320     }
    321 
    322     return OK;
    323 }
    324 
    325 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
    326         size_t data_count) {
    327     if (type >= NUM_TYPES) return 0;
    328 
    329     size_t data_bytes = data_count *
    330             camera_metadata_type_size[type];
    331 
    332     return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
    333 }
    334 
    335 int validate_camera_metadata_structure(const camera_metadata_t *metadata,
    336                                        const size_t *expected_size) {
    337 
    338     if (metadata == NULL) {
    339         ALOGE("%s: metadata is null!", __FUNCTION__);
    340         return ERROR;
    341     }
    342 
    343     // Check that the metadata pointer is well-aligned first.
    344     {
    345         static const struct {
    346             const char *name;
    347             size_t alignment;
    348         } alignments[] = {
    349             {
    350                 .name = "camera_metadata",
    351                 .alignment = METADATA_ALIGNMENT
    352             },
    353             {
    354                 .name = "camera_metadata_buffer_entry",
    355                 .alignment = ENTRY_ALIGNMENT
    356             },
    357             {
    358                 .name = "camera_metadata_data",
    359                 .alignment = DATA_ALIGNMENT
    360             },
    361         };
    362 
    363         for (size_t i = 0; i < sizeof(alignments)/sizeof(alignments[0]); ++i) {
    364             uintptr_t aligned_ptr = ALIGN_TO(metadata, alignments[i].alignment);
    365 
    366             if ((uintptr_t)metadata != aligned_ptr) {
    367                 ALOGE("%s: Metadata pointer is not aligned (actual %p, "
    368                       "expected %p) to type %s",
    369                       __FUNCTION__, metadata,
    370                       (void*)aligned_ptr, alignments[i].name);
    371                 return ERROR;
    372             }
    373         }
    374     }
    375 
    376     /**
    377      * Check that the metadata contents are correct
    378      */
    379 
    380     if (expected_size != NULL && metadata->size > *expected_size) {
    381         ALOGE("%s: Metadata size (%" PRIu32 ") should be <= expected size (%zu)",
    382               __FUNCTION__, metadata->size, *expected_size);
    383         return ERROR;
    384     }
    385 
    386     if (metadata->entry_count > metadata->entry_capacity) {
    387         ALOGE("%s: Entry count (%" PRIu32 ") should be <= entry capacity "
    388               "(%" PRIu32 ")",
    389               __FUNCTION__, metadata->entry_count, metadata->entry_capacity);
    390         return ERROR;
    391     }
    392 
    393     if (metadata->data_count > metadata->data_capacity) {
    394         ALOGE("%s: Data count (%" PRIu32 ") should be <= data capacity "
    395               "(%" PRIu32 ")",
    396               __FUNCTION__, metadata->data_count, metadata->data_capacity);
    397         android_errorWriteLog(SN_EVENT_LOG_ID, "30591838");
    398         return ERROR;
    399     }
    400 
    401     const metadata_uptrdiff_t entries_end =
    402         metadata->entries_start + metadata->entry_capacity;
    403     if (entries_end < metadata->entries_start || // overflow check
    404         entries_end > metadata->data_start) {
    405 
    406         ALOGE("%s: Entry start + capacity (%" PRIu32 ") should be <= data start "
    407               "(%" PRIu32 ")",
    408                __FUNCTION__,
    409               (metadata->entries_start + metadata->entry_capacity),
    410               metadata->data_start);
    411         return ERROR;
    412     }
    413 
    414     const metadata_uptrdiff_t data_end =
    415         metadata->data_start + metadata->data_capacity;
    416     if (data_end < metadata->data_start || // overflow check
    417         data_end > metadata->size) {
    418 
    419         ALOGE("%s: Data start + capacity (%" PRIu32 ") should be <= total size "
    420               "(%" PRIu32 ")",
    421                __FUNCTION__,
    422               (metadata->data_start + metadata->data_capacity),
    423               metadata->size);
    424         return ERROR;
    425     }
    426 
    427     // Validate each entry
    428     const metadata_size_t entry_count = metadata->entry_count;
    429     camera_metadata_buffer_entry_t *entries = get_entries(metadata);
    430 
    431     for (size_t i = 0; i < entry_count; ++i) {
    432 
    433         if ((uintptr_t)&entries[i] != ALIGN_TO(&entries[i], ENTRY_ALIGNMENT)) {
    434             ALOGE("%s: Entry index %zu had bad alignment (address %p),"
    435                   " expected alignment %zu",
    436                   __FUNCTION__, i, &entries[i], ENTRY_ALIGNMENT);
    437             return ERROR;
    438         }
    439 
    440         camera_metadata_buffer_entry_t entry = entries[i];
    441 
    442         if (entry.type >= NUM_TYPES) {
    443             ALOGE("%s: Entry index %zu had a bad type %d",
    444                   __FUNCTION__, i, entry.type);
    445             return ERROR;
    446         }
    447 
    448         // TODO: fix vendor_tag_ops across processes so we don't need to special
    449         //       case vendor-specific tags
    450         uint32_t tag_section = entry.tag >> 16;
    451         int tag_type = get_camera_metadata_tag_type(entry.tag);
    452         if (tag_type != (int)entry.type && tag_section < VENDOR_SECTION) {
    453             ALOGE("%s: Entry index %zu had tag type %d, but the type was %d",
    454                   __FUNCTION__, i, tag_type, entry.type);
    455             return ERROR;
    456         }
    457 
    458         size_t data_size;
    459         if (validate_and_calculate_camera_metadata_entry_data_size(&data_size, entry.type,
    460                 entry.count) != OK) {
    461             ALOGE("%s: Entry data size is invalid. type: %u count: %u", __FUNCTION__, entry.type,
    462                     entry.count);
    463             return ERROR;
    464         }
    465 
    466         if (data_size != 0) {
    467             camera_metadata_data_t *data =
    468                     (camera_metadata_data_t*) (get_data(metadata) +
    469                                                entry.data.offset);
    470 
    471             if ((uintptr_t)data != ALIGN_TO(data, DATA_ALIGNMENT)) {
    472                 ALOGE("%s: Entry index %zu had bad data alignment (address %p),"
    473                       " expected align %zu, (tag name %s, data size %zu)",
    474                       __FUNCTION__, i, data, DATA_ALIGNMENT,
    475                       get_camera_metadata_tag_name(entry.tag) ?: "unknown",
    476                       data_size);
    477                 return ERROR;
    478             }
    479 
    480             size_t data_entry_end = entry.data.offset + data_size;
    481             if (data_entry_end < entry.data.offset || // overflow check
    482                 data_entry_end > metadata->data_capacity) {
    483 
    484                 ALOGE("%s: Entry index %zu data ends (%zu) beyond the capacity "
    485                       "%" PRIu32, __FUNCTION__, i, data_entry_end,
    486                       metadata->data_capacity);
    487                 return ERROR;
    488             }
    489 
    490         } else if (entry.count == 0) {
    491             if (entry.data.offset != 0) {
    492                 ALOGE("%s: Entry index %zu had 0 items, but offset was non-0 "
    493                      "(%" PRIu32 "), tag name: %s", __FUNCTION__, i, entry.data.offset,
    494                         get_camera_metadata_tag_name(entry.tag) ?: "unknown");
    495                 return ERROR;
    496             }
    497         } // else data stored inline, so we look at value which can be anything.
    498     }
    499 
    500     return OK;
    501 }
    502 
    503 int append_camera_metadata(camera_metadata_t *dst,
    504         const camera_metadata_t *src) {
    505     if (dst == NULL || src == NULL ) return ERROR;
    506 
    507     // Check for overflow
    508     if (src->entry_count + dst->entry_count < src->entry_count) return ERROR;
    509     if (src->data_count + dst->data_count < src->data_count) return ERROR;
    510     // Check for space
    511     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
    512     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
    513 
    514     memcpy(get_entries(dst) + dst->entry_count, get_entries(src),
    515             sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
    516     memcpy(get_data(dst) + dst->data_count, get_data(src),
    517             sizeof(uint8_t[src->data_count]));
    518     if (dst->data_count != 0) {
    519         camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
    520         for (size_t i = 0; i < src->entry_count; i++, entry++) {
    521             if ( calculate_camera_metadata_entry_data_size(entry->type,
    522                             entry->count) > 0 ) {
    523                 entry->data.offset += dst->data_count;
    524             }
    525         }
    526     }
    527     if (dst->entry_count == 0) {
    528         // Appending onto empty buffer, keep sorted state
    529         dst->flags |= src->flags & FLAG_SORTED;
    530     } else if (src->entry_count != 0) {
    531         // Both src, dst are nonempty, cannot assume sort remains
    532         dst->flags &= ~FLAG_SORTED;
    533     } else {
    534         // Src is empty, keep dst sorted state
    535     }
    536     dst->entry_count += src->entry_count;
    537     dst->data_count += src->data_count;
    538 
    539     assert(validate_camera_metadata_structure(dst, NULL) == OK);
    540     return OK;
    541 }
    542 
    543 camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
    544     int res;
    545     if (src == NULL) return NULL;
    546     camera_metadata_t *clone = allocate_camera_metadata(
    547         get_camera_metadata_entry_count(src),
    548         get_camera_metadata_data_count(src));
    549     if (clone != NULL) {
    550         res = append_camera_metadata(clone, src);
    551         if (res != OK) {
    552             free_camera_metadata(clone);
    553             clone = NULL;
    554         }
    555     }
    556     assert(validate_camera_metadata_structure(clone, NULL) == OK);
    557     return clone;
    558 }
    559 
    560 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
    561         uint32_t tag,
    562         uint8_t  type,
    563         const void *data,
    564         size_t data_count) {
    565 
    566     if (dst == NULL) return ERROR;
    567     if (dst->entry_count == dst->entry_capacity) return ERROR;
    568     if (data_count && data == NULL) return ERROR;
    569 
    570     size_t data_bytes =
    571             calculate_camera_metadata_entry_data_size(type, data_count);
    572     if (data_bytes + dst->data_count > dst->data_capacity) return ERROR;
    573 
    574     size_t data_payload_bytes =
    575             data_count * camera_metadata_type_size[type];
    576     camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
    577     memset(entry, 0, sizeof(camera_metadata_buffer_entry_t));
    578     entry->tag = tag;
    579     entry->type = type;
    580     entry->count = data_count;
    581 
    582     if (data_bytes == 0) {
    583         memcpy(entry->data.value, data,
    584                 data_payload_bytes);
    585     } else {
    586         entry->data.offset = dst->data_count;
    587         memcpy(get_data(dst) + entry->data.offset, data,
    588                 data_payload_bytes);
    589         dst->data_count += data_bytes;
    590     }
    591     dst->entry_count++;
    592     dst->flags &= ~FLAG_SORTED;
    593     assert(validate_camera_metadata_structure(dst, NULL) == OK);
    594     return OK;
    595 }
    596 
    597 int add_camera_metadata_entry(camera_metadata_t *dst,
    598         uint32_t tag,
    599         const void *data,
    600         size_t data_count) {
    601 
    602     int type = get_camera_metadata_tag_type(tag);
    603     if (type == -1) {
    604         ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
    605         return ERROR;
    606     }
    607 
    608     return add_camera_metadata_entry_raw(dst,
    609             tag,
    610             type,
    611             data,
    612             data_count);
    613 }
    614 
    615 static int compare_entry_tags(const void *p1, const void *p2) {
    616     uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
    617     uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
    618     return  tag1 < tag2 ? -1 :
    619             tag1 == tag2 ? 0 :
    620             1;
    621 }
    622 
    623 int sort_camera_metadata(camera_metadata_t *dst) {
    624     if (dst == NULL) return ERROR;
    625     if (dst->flags & FLAG_SORTED) return OK;
    626 
    627     qsort(get_entries(dst), dst->entry_count,
    628             sizeof(camera_metadata_buffer_entry_t),
    629             compare_entry_tags);
    630     dst->flags |= FLAG_SORTED;
    631 
    632     assert(validate_camera_metadata_structure(dst, NULL) == OK);
    633     return OK;
    634 }
    635 
    636 int get_camera_metadata_entry(camera_metadata_t *src,
    637         size_t index,
    638         camera_metadata_entry_t *entry) {
    639     if (src == NULL || entry == NULL) return ERROR;
    640     if (index >= src->entry_count) return ERROR;
    641 
    642     camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index;
    643 
    644     entry->index = index;
    645     entry->tag = buffer_entry->tag;
    646     entry->type = buffer_entry->type;
    647     entry->count = buffer_entry->count;
    648     if (buffer_entry->count *
    649             camera_metadata_type_size[buffer_entry->type] > 4) {
    650         entry->data.u8 = get_data(src) + buffer_entry->data.offset;
    651     } else {
    652         entry->data.u8 = buffer_entry->data.value;
    653     }
    654     return OK;
    655 }
    656 
    657 int get_camera_metadata_ro_entry(const camera_metadata_t *src,
    658         size_t index,
    659         camera_metadata_ro_entry_t *entry) {
    660     return get_camera_metadata_entry((camera_metadata_t*)src, index,
    661             (camera_metadata_entry_t*)entry);
    662 }
    663 
    664 int find_camera_metadata_entry(camera_metadata_t *src,
    665         uint32_t tag,
    666         camera_metadata_entry_t *entry) {
    667     if (src == NULL) return ERROR;
    668 
    669     uint32_t index;
    670     if (src->flags & FLAG_SORTED) {
    671         // Sorted entries, do a binary search
    672         camera_metadata_buffer_entry_t *search_entry = NULL;
    673         camera_metadata_buffer_entry_t key;
    674         key.tag = tag;
    675         search_entry = bsearch(&key,
    676                 get_entries(src),
    677                 src->entry_count,
    678                 sizeof(camera_metadata_buffer_entry_t),
    679                 compare_entry_tags);
    680         if (search_entry == NULL) return NOT_FOUND;
    681         index = search_entry - get_entries(src);
    682     } else {
    683         // Not sorted, linear search
    684         camera_metadata_buffer_entry_t *search_entry = get_entries(src);
    685         for (index = 0; index < src->entry_count; index++, search_entry++) {
    686             if (search_entry->tag == tag) {
    687                 break;
    688             }
    689         }
    690         if (index == src->entry_count) return NOT_FOUND;
    691     }
    692 
    693     return get_camera_metadata_entry(src, index,
    694             entry);
    695 }
    696 
    697 int find_camera_metadata_ro_entry(const camera_metadata_t *src,
    698         uint32_t tag,
    699         camera_metadata_ro_entry_t *entry) {
    700     return find_camera_metadata_entry((camera_metadata_t*)src, tag,
    701             (camera_metadata_entry_t*)entry);
    702 }
    703 
    704 
    705 int delete_camera_metadata_entry(camera_metadata_t *dst,
    706         size_t index) {
    707     if (dst == NULL) return ERROR;
    708     if (index >= dst->entry_count) return ERROR;
    709 
    710     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
    711     size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
    712             entry->count);
    713 
    714     if (data_bytes > 0) {
    715         // Shift data buffer to overwrite deleted data
    716         uint8_t *start = get_data(dst) + entry->data.offset;
    717         uint8_t *end = start + data_bytes;
    718         size_t length = dst->data_count - entry->data.offset - data_bytes;
    719         memmove(start, end, length);
    720 
    721         // Update all entry indices to account for shift
    722         camera_metadata_buffer_entry_t *e = get_entries(dst);
    723         size_t i;
    724         for (i = 0; i < dst->entry_count; i++) {
    725             if (calculate_camera_metadata_entry_data_size(
    726                     e->type, e->count) > 0 &&
    727                     e->data.offset > entry->data.offset) {
    728                 e->data.offset -= data_bytes;
    729             }
    730             ++e;
    731         }
    732         dst->data_count -= data_bytes;
    733     }
    734     // Shift entry array
    735     memmove(entry, entry + 1,
    736             sizeof(camera_metadata_buffer_entry_t) *
    737             (dst->entry_count - index - 1) );
    738     dst->entry_count -= 1;
    739 
    740     assert(validate_camera_metadata_structure(dst, NULL) == OK);
    741     return OK;
    742 }
    743 
    744 int update_camera_metadata_entry(camera_metadata_t *dst,
    745         size_t index,
    746         const void *data,
    747         size_t data_count,
    748         camera_metadata_entry_t *updated_entry) {
    749     if (dst == NULL) return ERROR;
    750     if (index >= dst->entry_count) return ERROR;
    751 
    752     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
    753 
    754     size_t data_bytes =
    755             calculate_camera_metadata_entry_data_size(entry->type,
    756                     data_count);
    757     size_t data_payload_bytes =
    758             data_count * camera_metadata_type_size[entry->type];
    759 
    760     size_t entry_bytes =
    761             calculate_camera_metadata_entry_data_size(entry->type,
    762                     entry->count);
    763     if (data_bytes != entry_bytes) {
    764         // May need to shift/add to data array
    765         if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
    766             // No room
    767             return ERROR;
    768         }
    769         if (entry_bytes != 0) {
    770             // Remove old data
    771             uint8_t *start = get_data(dst) + entry->data.offset;
    772             uint8_t *end = start + entry_bytes;
    773             size_t length = dst->data_count - entry->data.offset - entry_bytes;
    774             memmove(start, end, length);
    775             dst->data_count -= entry_bytes;
    776 
    777             // Update all entry indices to account for shift
    778             camera_metadata_buffer_entry_t *e = get_entries(dst);
    779             size_t i;
    780             for (i = 0; i < dst->entry_count; i++) {
    781                 if (calculate_camera_metadata_entry_data_size(
    782                         e->type, e->count) > 0 &&
    783                         e->data.offset > entry->data.offset) {
    784                     e->data.offset -= entry_bytes;
    785                 }
    786                 ++e;
    787             }
    788         }
    789 
    790         if (data_bytes != 0) {
    791             // Append new data
    792             entry->data.offset = dst->data_count;
    793 
    794             memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
    795             dst->data_count += data_bytes;
    796         }
    797     } else if (data_bytes != 0) {
    798         // data size unchanged, reuse same data location
    799         memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
    800     }
    801 
    802     if (data_bytes == 0) {
    803         // Data fits into entry
    804         memcpy(entry->data.value, data,
    805                 data_payload_bytes);
    806     }
    807 
    808     entry->count = data_count;
    809 
    810     if (updated_entry != NULL) {
    811         get_camera_metadata_entry(dst,
    812                 index,
    813                 updated_entry);
    814     }
    815 
    816     assert(validate_camera_metadata_structure(dst, NULL) == OK);
    817     return OK;
    818 }
    819 
    820 static const vendor_tag_ops_t *vendor_tag_ops = NULL;
    821 
    822 const char *get_camera_metadata_section_name(uint32_t tag) {
    823     uint32_t tag_section = tag >> 16;
    824     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    825         return vendor_tag_ops->get_section_name(
    826             vendor_tag_ops,
    827             tag);
    828     }
    829     if (tag_section >= ANDROID_SECTION_COUNT) {
    830         return NULL;
    831     }
    832     return camera_metadata_section_names[tag_section];
    833 }
    834 
    835 const char *get_camera_metadata_tag_name(uint32_t tag) {
    836     uint32_t tag_section = tag >> 16;
    837     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    838         return vendor_tag_ops->get_tag_name(
    839             vendor_tag_ops,
    840             tag);
    841     }
    842     if (tag_section >= ANDROID_SECTION_COUNT ||
    843         tag >= camera_metadata_section_bounds[tag_section][1] ) {
    844         return NULL;
    845     }
    846     uint32_t tag_index = tag & 0xFFFF;
    847     return tag_info[tag_section][tag_index].tag_name;
    848 }
    849 
    850 int get_camera_metadata_tag_type(uint32_t tag) {
    851     uint32_t tag_section = tag >> 16;
    852     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    853         return vendor_tag_ops->get_tag_type(
    854             vendor_tag_ops,
    855             tag);
    856     }
    857     if (tag_section >= ANDROID_SECTION_COUNT ||
    858             tag >= camera_metadata_section_bounds[tag_section][1] ) {
    859         return -1;
    860     }
    861     uint32_t tag_index = tag & 0xFFFF;
    862     return tag_info[tag_section][tag_index].tag_type;
    863 }
    864 
    865 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t* ops) {
    866     // **DEPRECATED**
    867     (void) ops;
    868     ALOGE("%s: This function has been deprecated", __FUNCTION__);
    869     return ERROR;
    870 }
    871 
    872 // Declared in system/media/private/camera/include/camera_metadata_hidden.h
    873 int set_camera_metadata_vendor_ops(const vendor_tag_ops_t* ops) {
    874     vendor_tag_ops = ops;
    875     return OK;
    876 }
    877 
    878 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type,
    879         int count,
    880         int indentation);
    881 
    882 void dump_camera_metadata(const camera_metadata_t *metadata,
    883         int fd,
    884         int verbosity) {
    885     dump_indented_camera_metadata(metadata, fd, verbosity, 0);
    886 }
    887 
    888 void dump_indented_camera_metadata(const camera_metadata_t *metadata,
    889         int fd,
    890         int verbosity,
    891         int indentation) {
    892     if (metadata == NULL) {
    893         dprintf(fd, "%*sDumping camera metadata array: Not allocated\n",
    894                 indentation, "");
    895         return;
    896     }
    897     unsigned int i;
    898     dprintf(fd,
    899             "%*sDumping camera metadata array: %" PRIu32 " / %" PRIu32 " entries, "
    900             "%" PRIu32 " / %" PRIu32 " bytes of extra data.\n", indentation, "",
    901             metadata->entry_count, metadata->entry_capacity,
    902             metadata->data_count, metadata->data_capacity);
    903     dprintf(fd, "%*sVersion: %d, Flags: %08x\n",
    904             indentation + 2, "",
    905             metadata->version, metadata->flags);
    906     camera_metadata_buffer_entry_t *entry = get_entries(metadata);
    907     for (i=0; i < metadata->entry_count; i++, entry++) {
    908 
    909         const char *tag_name, *tag_section;
    910         tag_section = get_camera_metadata_section_name(entry->tag);
    911         if (tag_section == NULL) {
    912             tag_section = "unknownSection";
    913         }
    914         tag_name = get_camera_metadata_tag_name(entry->tag);
    915         if (tag_name == NULL) {
    916             tag_name = "unknownTag";
    917         }
    918         const char *type_name;
    919         if (entry->type >= NUM_TYPES) {
    920             type_name = "unknown";
    921         } else {
    922             type_name = camera_metadata_type_names[entry->type];
    923         }
    924         dprintf(fd, "%*s%s.%s (%05x): %s[%" PRIu32 "]\n",
    925              indentation + 2, "",
    926              tag_section,
    927              tag_name,
    928              entry->tag,
    929              type_name,
    930              entry->count);
    931 
    932         if (verbosity < 1) continue;
    933 
    934         if (entry->type >= NUM_TYPES) continue;
    935 
    936         size_t type_size = camera_metadata_type_size[entry->type];
    937         uint8_t *data_ptr;
    938         if ( type_size * entry->count > 4 ) {
    939             if (entry->data.offset >= metadata->data_count) {
    940                 ALOGE("%s: Malformed entry data offset: %" PRIu32 " (max %" PRIu32 ")",
    941                         __FUNCTION__,
    942                         entry->data.offset,
    943                         metadata->data_count);
    944                 continue;
    945             }
    946             data_ptr = get_data(metadata) + entry->data.offset;
    947         } else {
    948             data_ptr = entry->data.value;
    949         }
    950         int count = entry->count;
    951         if (verbosity < 2 && count > 16) count = 16;
    952 
    953         print_data(fd, data_ptr, entry->tag, entry->type, count, indentation);
    954     }
    955 }
    956 
    957 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag,
    958         int type, int count, int indentation) {
    959     static int values_per_line[NUM_TYPES] = {
    960         [TYPE_BYTE]     = 16,
    961         [TYPE_INT32]    = 4,
    962         [TYPE_FLOAT]    = 8,
    963         [TYPE_INT64]    = 2,
    964         [TYPE_DOUBLE]   = 4,
    965         [TYPE_RATIONAL] = 2,
    966     };
    967     size_t type_size = camera_metadata_type_size[type];
    968     char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];
    969     uint32_t value;
    970 
    971     int lines = count / values_per_line[type];
    972     if (count % values_per_line[type] != 0) lines++;
    973 
    974     int index = 0;
    975     int j, k;
    976     for (j = 0; j < lines; j++) {
    977         dprintf(fd, "%*s[", indentation + 4, "");
    978         for (k = 0;
    979              k < values_per_line[type] && count > 0;
    980              k++, count--, index += type_size) {
    981 
    982             switch (type) {
    983                 case TYPE_BYTE:
    984                     value = *(data_ptr + index);
    985                     if (camera_metadata_enum_snprint(tag,
    986                                                      value,
    987                                                      value_string_tmp,
    988                                                      sizeof(value_string_tmp))
    989                         == OK) {
    990                         dprintf(fd, "%s ", value_string_tmp);
    991                     } else {
    992                         dprintf(fd, "%hhu ",
    993                                 *(data_ptr + index));
    994                     }
    995                     break;
    996                 case TYPE_INT32:
    997                     value =
    998                             *(int32_t*)(data_ptr + index);
    999                     if (camera_metadata_enum_snprint(tag,
   1000                                                      value,
   1001                                                      value_string_tmp,
   1002                                                      sizeof(value_string_tmp))
   1003                         == OK) {
   1004                         dprintf(fd, "%s ", value_string_tmp);
   1005                     } else {
   1006                         dprintf(fd, "%" PRId32 " ",
   1007                                 *(int32_t*)(data_ptr + index));
   1008                     }
   1009                     break;
   1010                 case TYPE_FLOAT:
   1011                     dprintf(fd, "%0.8f ",
   1012                             *(float*)(data_ptr + index));
   1013                     break;
   1014                 case TYPE_INT64:
   1015                     dprintf(fd, "%" PRId64 " ",
   1016                             *(int64_t*)(data_ptr + index));
   1017                     break;
   1018                 case TYPE_DOUBLE:
   1019                     dprintf(fd, "%0.8f ",
   1020                             *(double*)(data_ptr + index));
   1021                     break;
   1022                 case TYPE_RATIONAL: {
   1023                     int32_t numerator = *(int32_t*)(data_ptr + index);
   1024                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
   1025                     dprintf(fd, "(%d / %d) ",
   1026                             numerator, denominator);
   1027                     break;
   1028                 }
   1029                 default:
   1030                     dprintf(fd, "??? ");
   1031             }
   1032         }
   1033         dprintf(fd, "]\n");
   1034     }
   1035 }
   1036