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