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