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), tag name: %s", __FUNCTION__, i, entry.data.offset,
    435                         get_camera_metadata_tag_name(entry.tag) ?: "unknown");
    436                 return ERROR;
    437             }
    438         } // else data stored inline, so we look at value which can be anything.
    439     }
    440 
    441     return OK;
    442 }
    443 
    444 int append_camera_metadata(camera_metadata_t *dst,
    445         const camera_metadata_t *src) {
    446     if (dst == NULL || src == NULL ) return ERROR;
    447 
    448     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
    449     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
    450 
    451     memcpy(get_entries(dst) + dst->entry_count, get_entries(src),
    452             sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
    453     memcpy(get_data(dst) + dst->data_count, get_data(src),
    454             sizeof(uint8_t[src->data_count]));
    455     if (dst->data_count != 0) {
    456         camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
    457         for (size_t i = 0; i < src->entry_count; i++, entry++) {
    458             if ( calculate_camera_metadata_entry_data_size(entry->type,
    459                             entry->count) > 0 ) {
    460                 entry->data.offset += dst->data_count;
    461             }
    462         }
    463     }
    464     if (dst->entry_count == 0) {
    465         // Appending onto empty buffer, keep sorted state
    466         dst->flags |= src->flags & FLAG_SORTED;
    467     } else if (src->entry_count != 0) {
    468         // Both src, dst are nonempty, cannot assume sort remains
    469         dst->flags &= ~FLAG_SORTED;
    470     } else {
    471         // Src is empty, keep dst sorted state
    472     }
    473     dst->entry_count += src->entry_count;
    474     dst->data_count += src->data_count;
    475 
    476     return OK;
    477 }
    478 
    479 camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
    480     int res;
    481     if (src == NULL) return NULL;
    482     camera_metadata_t *clone = allocate_camera_metadata(
    483         get_camera_metadata_entry_count(src),
    484         get_camera_metadata_data_count(src));
    485     if (clone != NULL) {
    486         res = append_camera_metadata(clone, src);
    487         if (res != OK) {
    488             free_camera_metadata(clone);
    489             clone = NULL;
    490         }
    491     }
    492     return clone;
    493 }
    494 
    495 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
    496         size_t data_count) {
    497     if (type >= NUM_TYPES) return 0;
    498     size_t data_bytes = data_count *
    499             camera_metadata_type_size[type];
    500     return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
    501 }
    502 
    503 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
    504         uint32_t tag,
    505         uint8_t  type,
    506         const void *data,
    507         size_t data_count) {
    508 
    509     if (dst == NULL) return ERROR;
    510     if (dst->entry_count == dst->entry_capacity) return ERROR;
    511     if (data == NULL) return ERROR;
    512 
    513     size_t data_bytes =
    514             calculate_camera_metadata_entry_data_size(type, data_count);
    515     if (data_bytes + dst->data_count > dst->data_capacity) return ERROR;
    516 
    517     size_t data_payload_bytes =
    518             data_count * camera_metadata_type_size[type];
    519     camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
    520     memset(entry, 0, sizeof(camera_metadata_buffer_entry_t));
    521     entry->tag = tag;
    522     entry->type = type;
    523     entry->count = data_count;
    524 
    525     if (data_bytes == 0) {
    526         memcpy(entry->data.value, data,
    527                 data_payload_bytes);
    528     } else {
    529         entry->data.offset = dst->data_count;
    530         memcpy(get_data(dst) + entry->data.offset, data,
    531                 data_payload_bytes);
    532         dst->data_count += data_bytes;
    533     }
    534     dst->entry_count++;
    535     dst->flags &= ~FLAG_SORTED;
    536     return OK;
    537 }
    538 
    539 int add_camera_metadata_entry(camera_metadata_t *dst,
    540         uint32_t tag,
    541         const void *data,
    542         size_t data_count) {
    543 
    544     int type = get_camera_metadata_tag_type(tag);
    545     if (type == -1) {
    546         ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
    547         return ERROR;
    548     }
    549 
    550     return add_camera_metadata_entry_raw(dst,
    551             tag,
    552             type,
    553             data,
    554             data_count);
    555 }
    556 
    557 static int compare_entry_tags(const void *p1, const void *p2) {
    558     uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
    559     uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
    560     return  tag1 < tag2 ? -1 :
    561             tag1 == tag2 ? 0 :
    562             1;
    563 }
    564 
    565 int sort_camera_metadata(camera_metadata_t *dst) {
    566     if (dst == NULL) return ERROR;
    567     if (dst->flags & FLAG_SORTED) return OK;
    568 
    569     qsort(get_entries(dst), dst->entry_count,
    570             sizeof(camera_metadata_buffer_entry_t),
    571             compare_entry_tags);
    572     dst->flags |= FLAG_SORTED;
    573 
    574     return OK;
    575 }
    576 
    577 int get_camera_metadata_entry(camera_metadata_t *src,
    578         size_t index,
    579         camera_metadata_entry_t *entry) {
    580     if (src == NULL || entry == NULL) return ERROR;
    581     if (index >= src->entry_count) return ERROR;
    582 
    583     camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index;
    584 
    585     entry->index = index;
    586     entry->tag = buffer_entry->tag;
    587     entry->type = buffer_entry->type;
    588     entry->count = buffer_entry->count;
    589     if (buffer_entry->count *
    590             camera_metadata_type_size[buffer_entry->type] > 4) {
    591         entry->data.u8 = get_data(src) + buffer_entry->data.offset;
    592     } else {
    593         entry->data.u8 = buffer_entry->data.value;
    594     }
    595     return OK;
    596 }
    597 
    598 int find_camera_metadata_entry(camera_metadata_t *src,
    599         uint32_t tag,
    600         camera_metadata_entry_t *entry) {
    601     if (src == NULL) return ERROR;
    602 
    603     uint32_t index;
    604     if (src->flags & FLAG_SORTED) {
    605         // Sorted entries, do a binary search
    606         camera_metadata_buffer_entry_t *search_entry = NULL;
    607         camera_metadata_buffer_entry_t key;
    608         key.tag = tag;
    609         search_entry = bsearch(&key,
    610                 get_entries(src),
    611                 src->entry_count,
    612                 sizeof(camera_metadata_buffer_entry_t),
    613                 compare_entry_tags);
    614         if (search_entry == NULL) return NOT_FOUND;
    615         index = search_entry - get_entries(src);
    616     } else {
    617         // Not sorted, linear search
    618         camera_metadata_buffer_entry_t *search_entry = get_entries(src);
    619         for (index = 0; index < src->entry_count; index++, search_entry++) {
    620             if (search_entry->tag == tag) {
    621                 break;
    622             }
    623         }
    624         if (index == src->entry_count) return NOT_FOUND;
    625     }
    626 
    627     return get_camera_metadata_entry(src, index,
    628             entry);
    629 }
    630 
    631 int find_camera_metadata_ro_entry(const camera_metadata_t *src,
    632         uint32_t tag,
    633         camera_metadata_ro_entry_t *entry) {
    634     return find_camera_metadata_entry((camera_metadata_t*)src, tag,
    635             (camera_metadata_entry_t*)entry);
    636 }
    637 
    638 
    639 int delete_camera_metadata_entry(camera_metadata_t *dst,
    640         size_t index) {
    641     if (dst == NULL) return ERROR;
    642     if (index >= dst->entry_count) return ERROR;
    643 
    644     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
    645     size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
    646             entry->count);
    647 
    648     if (data_bytes > 0) {
    649         // Shift data buffer to overwrite deleted data
    650         uint8_t *start = get_data(dst) + entry->data.offset;
    651         uint8_t *end = start + data_bytes;
    652         size_t length = dst->data_count - entry->data.offset - data_bytes;
    653         memmove(start, end, length);
    654 
    655         // Update all entry indices to account for shift
    656         camera_metadata_buffer_entry_t *e = get_entries(dst);
    657         size_t i;
    658         for (i = 0; i < dst->entry_count; i++) {
    659             if (calculate_camera_metadata_entry_data_size(
    660                     e->type, e->count) > 0 &&
    661                     e->data.offset > entry->data.offset) {
    662                 e->data.offset -= data_bytes;
    663             }
    664             ++e;
    665         }
    666         dst->data_count -= data_bytes;
    667     }
    668     // Shift entry array
    669     memmove(entry, entry + 1,
    670             sizeof(camera_metadata_buffer_entry_t) *
    671             (dst->entry_count - index - 1) );
    672     dst->entry_count -= 1;
    673 
    674     return OK;
    675 }
    676 
    677 int update_camera_metadata_entry(camera_metadata_t *dst,
    678         size_t index,
    679         const void *data,
    680         size_t data_count,
    681         camera_metadata_entry_t *updated_entry) {
    682     if (dst == NULL) return ERROR;
    683     if (index >= dst->entry_count) return ERROR;
    684 
    685     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
    686 
    687     size_t data_bytes =
    688             calculate_camera_metadata_entry_data_size(entry->type,
    689                     data_count);
    690     size_t data_payload_bytes =
    691             data_count * camera_metadata_type_size[entry->type];
    692 
    693     size_t entry_bytes =
    694             calculate_camera_metadata_entry_data_size(entry->type,
    695                     entry->count);
    696     if (data_bytes != entry_bytes) {
    697         // May need to shift/add to data array
    698         if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
    699             // No room
    700             return ERROR;
    701         }
    702         if (entry_bytes != 0) {
    703             // Remove old data
    704             uint8_t *start = get_data(dst) + entry->data.offset;
    705             uint8_t *end = start + entry_bytes;
    706             size_t length = dst->data_count - entry->data.offset - entry_bytes;
    707             memmove(start, end, length);
    708             dst->data_count -= entry_bytes;
    709 
    710             // Update all entry indices to account for shift
    711             camera_metadata_buffer_entry_t *e = get_entries(dst);
    712             size_t i;
    713             for (i = 0; i < dst->entry_count; i++) {
    714                 if (calculate_camera_metadata_entry_data_size(
    715                         e->type, e->count) > 0 &&
    716                         e->data.offset > entry->data.offset) {
    717                     e->data.offset -= entry_bytes;
    718                 }
    719                 ++e;
    720             }
    721         }
    722 
    723         if (data_bytes != 0) {
    724             // Append new data
    725             entry->data.offset = dst->data_count;
    726 
    727             memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
    728             dst->data_count += data_bytes;
    729         }
    730     } else if (data_bytes != 0) {
    731         // data size unchanged, reuse same data location
    732         memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
    733     }
    734 
    735     if (data_bytes == 0) {
    736         // Data fits into entry
    737         memcpy(entry->data.value, data,
    738                 data_payload_bytes);
    739     }
    740 
    741     entry->count = data_count;
    742 
    743     if (updated_entry != NULL) {
    744         get_camera_metadata_entry(dst,
    745                 index,
    746                 updated_entry);
    747     }
    748 
    749     return OK;
    750 }
    751 
    752 int set_camera_metadata_user_pointer(camera_metadata_t *dst, void* user) {
    753     if (dst == NULL) return ERROR;
    754     dst->user = user;
    755     return OK;
    756 }
    757 
    758 int get_camera_metadata_user_pointer(camera_metadata_t *dst, void** user) {
    759     if (dst == NULL) return ERROR;
    760     *user = dst->user;
    761     return OK;
    762 }
    763 
    764 static const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
    765 
    766 const char *get_camera_metadata_section_name(uint32_t tag) {
    767     uint32_t tag_section = tag >> 16;
    768     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    769         return vendor_tag_ops->get_camera_vendor_section_name(
    770             vendor_tag_ops,
    771             tag);
    772     }
    773     if (tag_section >= ANDROID_SECTION_COUNT) {
    774         return NULL;
    775     }
    776     return camera_metadata_section_names[tag_section];
    777 }
    778 
    779 const char *get_camera_metadata_tag_name(uint32_t tag) {
    780     uint32_t tag_section = tag >> 16;
    781     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    782         return vendor_tag_ops->get_camera_vendor_tag_name(
    783             vendor_tag_ops,
    784             tag);
    785     }
    786     if (tag_section >= ANDROID_SECTION_COUNT ||
    787         tag >= camera_metadata_section_bounds[tag_section][1] ) {
    788         return NULL;
    789     }
    790     uint32_t tag_index = tag & 0xFFFF;
    791     return tag_info[tag_section][tag_index].tag_name;
    792 }
    793 
    794 int get_camera_metadata_tag_type(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_camera_vendor_tag_type(
    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 -1;
    804     }
    805     uint32_t tag_index = tag & 0xFFFF;
    806     return tag_info[tag_section][tag_index].tag_type;
    807 }
    808 
    809 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
    810     vendor_tag_ops = query_ops;
    811     return OK;
    812 }
    813 
    814 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type,
    815         int count,
    816         int indentation);
    817 
    818 void dump_camera_metadata(const camera_metadata_t *metadata,
    819         int fd,
    820         int verbosity) {
    821     dump_indented_camera_metadata(metadata, fd, verbosity, 0);
    822 }
    823 
    824 void dump_indented_camera_metadata(const camera_metadata_t *metadata,
    825         int fd,
    826         int verbosity,
    827         int indentation) {
    828     if (metadata == NULL) {
    829         fdprintf(fd, "%*sDumping camera metadata array: Not allocated\n",
    830                 indentation, "");
    831         return;
    832     }
    833     unsigned int i;
    834     fdprintf(fd,
    835             "%*sDumping camera metadata array: %d / %d entries, "
    836             "%d / %d bytes of extra data.\n", indentation, "",
    837             metadata->entry_count, metadata->entry_capacity,
    838             metadata->data_count, metadata->data_capacity);
    839     fdprintf(fd, "%*sVersion: %d, Flags: %08x\n",
    840             indentation + 2, "",
    841             metadata->version, metadata->flags);
    842     camera_metadata_buffer_entry_t *entry = get_entries(metadata);
    843     for (i=0; i < metadata->entry_count; i++, entry++) {
    844 
    845         const char *tag_name, *tag_section;
    846         tag_section = get_camera_metadata_section_name(entry->tag);
    847         if (tag_section == NULL) {
    848             tag_section = "unknownSection";
    849         }
    850         tag_name = get_camera_metadata_tag_name(entry->tag);
    851         if (tag_name == NULL) {
    852             tag_name = "unknownTag";
    853         }
    854         const char *type_name;
    855         if (entry->type >= NUM_TYPES) {
    856             type_name = "unknown";
    857         } else {
    858             type_name = camera_metadata_type_names[entry->type];
    859         }
    860         fdprintf(fd, "%*s%s.%s (%05x): %s[%d]\n",
    861              indentation + 2, "",
    862              tag_section,
    863              tag_name,
    864              entry->tag,
    865              type_name,
    866              entry->count);
    867 
    868         if (verbosity < 1) continue;
    869 
    870         if (entry->type >= NUM_TYPES) continue;
    871 
    872         size_t type_size = camera_metadata_type_size[entry->type];
    873         uint8_t *data_ptr;
    874         if ( type_size * entry->count > 4 ) {
    875             if (entry->data.offset >= metadata->data_count) {
    876                 ALOGE("%s: Malformed entry data offset: %d (max %d)",
    877                         __FUNCTION__,
    878                         entry->data.offset,
    879                         metadata->data_count);
    880                 continue;
    881             }
    882             data_ptr = get_data(metadata) + entry->data.offset;
    883         } else {
    884             data_ptr = entry->data.value;
    885         }
    886         int count = entry->count;
    887         if (verbosity < 2 && count > 16) count = 16;
    888 
    889         print_data(fd, data_ptr, entry->tag, entry->type, count, indentation);
    890     }
    891 }
    892 
    893 static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag,
    894         int type, int count, int indentation) {
    895     static int values_per_line[NUM_TYPES] = {
    896         [TYPE_BYTE]     = 16,
    897         [TYPE_INT32]    = 4,
    898         [TYPE_FLOAT]    = 8,
    899         [TYPE_INT64]    = 2,
    900         [TYPE_DOUBLE]   = 4,
    901         [TYPE_RATIONAL] = 2,
    902     };
    903     size_t type_size = camera_metadata_type_size[type];
    904     char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE];
    905     uint32_t value;
    906 
    907     int lines = count / values_per_line[type];
    908     if (count % values_per_line[type] != 0) lines++;
    909 
    910     int index = 0;
    911     int j, k;
    912     for (j = 0; j < lines; j++) {
    913         fdprintf(fd, "%*s[", indentation + 4, "");
    914         for (k = 0;
    915              k < values_per_line[type] && count > 0;
    916              k++, count--, index += type_size) {
    917 
    918             switch (type) {
    919                 case TYPE_BYTE:
    920                     value = *(data_ptr + index);
    921                     if (camera_metadata_enum_snprint(tag,
    922                                                      value,
    923                                                      value_string_tmp,
    924                                                      sizeof(value_string_tmp))
    925                         == OK) {
    926                         fdprintf(fd, "%s ", value_string_tmp);
    927                     } else {
    928                         fdprintf(fd, "%hhu ",
    929                                 *(data_ptr + index));
    930                     }
    931                     break;
    932                 case TYPE_INT32:
    933                     value =
    934                             *(int32_t*)(data_ptr + index);
    935                     if (camera_metadata_enum_snprint(tag,
    936                                                      value,
    937                                                      value_string_tmp,
    938                                                      sizeof(value_string_tmp))
    939                         == OK) {
    940                         fdprintf(fd, "%s ", value_string_tmp);
    941                     } else {
    942                         fdprintf(fd, "%d ",
    943                                 *(int32_t*)(data_ptr + index));
    944                     }
    945                     break;
    946                 case TYPE_FLOAT:
    947                     fdprintf(fd, "%0.2f ",
    948                             *(float*)(data_ptr + index));
    949                     break;
    950                 case TYPE_INT64:
    951                     fdprintf(fd, "%lld ",
    952                             *(int64_t*)(data_ptr + index));
    953                     break;
    954                 case TYPE_DOUBLE:
    955                     fdprintf(fd, "%0.2f ",
    956                             *(double*)(data_ptr + index));
    957                     break;
    958                 case TYPE_RATIONAL: {
    959                     int32_t numerator = *(int32_t*)(data_ptr + index);
    960                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
    961                     fdprintf(fd, "(%d / %d) ",
    962                             numerator, denominator);
    963                     break;
    964                 }
    965                 default:
    966                     fdprintf(fd, "??? ");
    967             }
    968         }
    969         fdprintf(fd, "]\n");
    970     }
    971 }
    972