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 #include <cutils/log.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <errno.h>
     22 
     23 #define OK         0
     24 #define ERROR      1
     25 #define NOT_FOUND -ENOENT
     26 /**
     27  * A single metadata entry, storing an array of values of a given type. If the
     28  * array is no larger than 4 bytes in size, it is stored in the data.value[]
     29  * array; otherwise, it can found in the parent's data array at index
     30  * data.offset.
     31  */
     32 typedef struct camera_metadata_buffer_entry {
     33     uint32_t tag;
     34     size_t   count;
     35     union {
     36         size_t  offset;
     37         uint8_t value[4];
     38     } data;
     39     uint8_t  type;
     40     uint8_t  reserved[3];
     41 } __attribute__((packed)) camera_metadata_buffer_entry_t;
     42 
     43 /**
     44  * A packet of metadata. This is a list of entries, each of which may point to
     45  * its values stored at an offset in data.
     46  *
     47  * It is assumed by the utility functions that the memory layout of the packet
     48  * is as follows:
     49  *
     50  *   |-----------------------------------------------|
     51  *   | camera_metadata_t                             |
     52  *   |                                               |
     53  *   |-----------------------------------------------|
     54  *   | reserved for future expansion                 |
     55  *   |-----------------------------------------------|
     56  *   | camera_metadata_buffer_entry_t #0             |
     57  *   |-----------------------------------------------|
     58  *   | ....                                          |
     59  *   |-----------------------------------------------|
     60  *   | camera_metadata_buffer_entry_t #entry_count-1 |
     61  *   |-----------------------------------------------|
     62  *   | free space for                                |
     63  *   | (entry_capacity-entry_count) entries          |
     64  *   |-----------------------------------------------|
     65  *   | start of camera_metadata.data                 |
     66  *   |                                               |
     67  *   |-----------------------------------------------|
     68  *   | free space for                                |
     69  *   | (data_capacity-data_count) bytes              |
     70  *   |-----------------------------------------------|
     71  *
     72  * With the total length of the whole packet being camera_metadata.size bytes.
     73  *
     74  * In short, the entries and data are contiguous in memory after the metadata
     75  * header.
     76  */
     77 struct camera_metadata {
     78     size_t                   size;
     79     uint32_t                 version;
     80     uint32_t                 flags;
     81     size_t                   entry_count;
     82     size_t                   entry_capacity;
     83     camera_metadata_buffer_entry_t *entries;
     84     size_t                   data_count;
     85     size_t                   data_capacity;
     86     uint8_t                 *data;
     87     void                    *user; // User set pointer, not copied with buffer
     88     uint8_t                  reserved[0];
     89 };
     90 
     91 /** Versioning information */
     92 #define CURRENT_METADATA_VERSION 1
     93 
     94 /** Flag definitions */
     95 #define FLAG_SORTED 0x00000001
     96 
     97 /** Tag information */
     98 
     99 typedef struct tag_info {
    100     const char *tag_name;
    101     uint8_t     tag_type;
    102 } tag_info_t;
    103 
    104 #include "camera_metadata_tag_info.c"
    105 
    106 const size_t camera_metadata_type_size[NUM_TYPES] = {
    107     [TYPE_BYTE]     = sizeof(uint8_t),
    108     [TYPE_INT32]    = sizeof(int32_t),
    109     [TYPE_FLOAT]    = sizeof(float),
    110     [TYPE_INT64]    = sizeof(int64_t),
    111     [TYPE_DOUBLE]   = sizeof(double),
    112     [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
    113 };
    114 
    115 const char *camera_metadata_type_names[NUM_TYPES] = {
    116     [TYPE_BYTE]     = "byte",
    117     [TYPE_INT32]    = "int32",
    118     [TYPE_FLOAT]    = "float",
    119     [TYPE_INT64]    = "int64",
    120     [TYPE_DOUBLE]   = "double",
    121     [TYPE_RATIONAL] = "rational"
    122 };
    123 
    124 camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
    125                                             size_t data_capacity) {
    126     if (entry_capacity == 0) return NULL;
    127 
    128     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
    129                                                           data_capacity);
    130     void *buffer = malloc(memory_needed);
    131     return place_camera_metadata(buffer, memory_needed,
    132                                  entry_capacity,
    133                                  data_capacity);
    134 }
    135 
    136 camera_metadata_t *place_camera_metadata(void *dst,
    137                                          size_t dst_size,
    138                                          size_t entry_capacity,
    139                                          size_t data_capacity) {
    140     if (dst == NULL) return NULL;
    141     if (entry_capacity == 0) return NULL;
    142 
    143     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
    144                                                           data_capacity);
    145     if (memory_needed > dst_size) return NULL;
    146 
    147     camera_metadata_t *metadata = (camera_metadata_t*)dst;
    148     metadata->version = CURRENT_METADATA_VERSION;
    149     metadata->flags = 0;
    150     metadata->entry_count = 0;
    151     metadata->entry_capacity = entry_capacity;
    152     metadata->entries = (camera_metadata_buffer_entry_t*)(metadata + 1);
    153     metadata->data_count = 0;
    154     metadata->data_capacity = data_capacity;
    155     metadata->size = memory_needed;
    156     if (metadata->data_capacity != 0) {
    157         metadata->data =
    158                 (uint8_t*)(metadata->entries + metadata->entry_capacity);
    159     } else {
    160         metadata->data = NULL;
    161     }
    162     metadata->user = NULL;
    163 
    164     return metadata;
    165 }
    166 void free_camera_metadata(camera_metadata_t *metadata) {
    167     free(metadata);
    168 }
    169 
    170 size_t calculate_camera_metadata_size(size_t entry_count,
    171                                       size_t data_count) {
    172     size_t memory_needed = sizeof(camera_metadata_t);
    173     memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
    174     memory_needed += sizeof(uint8_t[data_count]);
    175     return memory_needed;
    176 }
    177 
    178 size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
    179     if (metadata == NULL) return ERROR;
    180 
    181     return metadata->size;
    182 }
    183 
    184 size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
    185     if (metadata == NULL) return ERROR;
    186 
    187     ptrdiff_t reserved_size = metadata->size -
    188             calculate_camera_metadata_size(metadata->entry_capacity,
    189                                            metadata->data_capacity);
    190 
    191     return calculate_camera_metadata_size(metadata->entry_count,
    192                                           metadata->data_count) + reserved_size;
    193 }
    194 
    195 size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
    196     return metadata->entry_count;
    197 }
    198 
    199 size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
    200     return metadata->entry_capacity;
    201 }
    202 
    203 size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
    204     return metadata->data_count;
    205 }
    206 
    207 size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
    208     return metadata->data_capacity;
    209 }
    210 
    211 camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
    212         const camera_metadata_t *src) {
    213     size_t memory_needed = get_camera_metadata_compact_size(src);
    214 
    215     if (dst == NULL) return NULL;
    216     if (dst_size < memory_needed) return NULL;
    217 
    218     // If copying a newer version of the structure, there may be additional
    219     // header fields we don't know about but need to copy
    220     ptrdiff_t reserved_size = src->size -
    221             calculate_camera_metadata_size(src->entry_capacity,
    222                                            src->data_capacity);
    223 
    224     camera_metadata_t *metadata = (camera_metadata_t*)dst;
    225     metadata->version = CURRENT_METADATA_VERSION;
    226     metadata->flags = src->flags;
    227     metadata->entry_count = src->entry_count;
    228     metadata->entry_capacity = src->entry_count;
    229     metadata->entries = (camera_metadata_buffer_entry_t*)
    230              ((uint8_t *)(metadata + 1) + reserved_size);
    231     metadata->data_count = src->data_count;
    232     metadata->data_capacity = src->data_count;
    233     metadata->data = (uint8_t *)(metadata->entries + metadata->entry_capacity);
    234     metadata->size = memory_needed;
    235 
    236     if (reserved_size > 0) {
    237         memcpy(metadata->reserved, src->reserved, reserved_size);
    238     }
    239     memcpy(metadata->entries, src->entries,
    240             sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
    241     memcpy(metadata->data, src->data,
    242             sizeof(uint8_t[metadata->data_count]));
    243     metadata->user = NULL;
    244 
    245     return metadata;
    246 }
    247 
    248 int append_camera_metadata(camera_metadata_t *dst,
    249         const camera_metadata_t *src) {
    250     if (dst == NULL || src == NULL ) return ERROR;
    251 
    252     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
    253     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
    254 
    255     memcpy(dst->entries + dst->entry_count, src->entries,
    256             sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
    257     memcpy(dst->data + dst->data_count, src->data,
    258             sizeof(uint8_t[src->data_count]));
    259     if (dst->data_count != 0) {
    260         unsigned int i;
    261         for (i = dst->entry_count;
    262              i < dst->entry_count + src->entry_count;
    263              i++) {
    264             camera_metadata_buffer_entry_t *entry = dst->entries + i;
    265             if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) {
    266                 entry->data.offset += dst->data_count;
    267             }
    268         }
    269     }
    270     if (dst->entry_count == 0) {
    271         // Appending onto empty buffer, keep sorted state
    272         dst->flags |= src->flags & FLAG_SORTED;
    273     } else if (src->entry_count != 0) {
    274         // Both src, dst are nonempty, cannot assume sort remains
    275         dst->flags &= ~FLAG_SORTED;
    276     } else {
    277         // Src is empty, keep dst sorted state
    278     }
    279     dst->entry_count += src->entry_count;
    280     dst->data_count += src->data_count;
    281 
    282     return OK;
    283 }
    284 
    285 camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
    286     int res;
    287     if (src == NULL) return NULL;
    288     camera_metadata_t *clone = allocate_camera_metadata(
    289         get_camera_metadata_entry_count(src),
    290         get_camera_metadata_data_count(src));
    291     if (clone != NULL) {
    292         res = append_camera_metadata(clone, src);
    293         if (res != OK) {
    294             free_camera_metadata(clone);
    295             clone = NULL;
    296         }
    297     }
    298     return clone;
    299 }
    300 
    301 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
    302         size_t data_count) {
    303     if (type >= NUM_TYPES) return 0;
    304     size_t data_bytes = data_count *
    305             camera_metadata_type_size[type];
    306     return data_bytes <= 4 ? 0 : data_bytes;
    307 }
    308 
    309 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
    310         uint32_t tag,
    311         uint8_t  type,
    312         const void *data,
    313         size_t data_count) {
    314 
    315     if (dst == NULL) return ERROR;
    316     if (dst->entry_count == dst->entry_capacity) return ERROR;
    317     if (data == NULL) return ERROR;
    318 
    319     size_t data_bytes =
    320             calculate_camera_metadata_entry_data_size(type, data_count);
    321 
    322     camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count;
    323     entry->tag = tag;
    324     entry->type = type;
    325     entry->count = data_count;
    326 
    327     if (data_bytes == 0) {
    328         memcpy(entry->data.value, data,
    329                 data_count * camera_metadata_type_size[type] );
    330     } else {
    331         entry->data.offset = dst->data_count;
    332         memcpy(dst->data + entry->data.offset, data, data_bytes);
    333         dst->data_count += data_bytes;
    334     }
    335     dst->entry_count++;
    336     dst->flags &= ~FLAG_SORTED;
    337     return OK;
    338 }
    339 
    340 int add_camera_metadata_entry(camera_metadata_t *dst,
    341         uint32_t tag,
    342         const void *data,
    343         size_t data_count) {
    344 
    345     int type = get_camera_metadata_tag_type(tag);
    346     if (type == -1) {
    347         ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
    348         return ERROR;
    349     }
    350 
    351     return add_camera_metadata_entry_raw(dst,
    352             tag,
    353             type,
    354             data,
    355             data_count);
    356 }
    357 
    358 static int compare_entry_tags(const void *p1, const void *p2) {
    359     uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
    360     uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
    361     return  tag1 < tag2 ? -1 :
    362             tag1 == tag2 ? 0 :
    363             1;
    364 }
    365 
    366 int sort_camera_metadata(camera_metadata_t *dst) {
    367     if (dst == NULL) return ERROR;
    368     if (dst->flags & FLAG_SORTED) return OK;
    369 
    370     qsort(dst->entries, dst->entry_count,
    371             sizeof(camera_metadata_buffer_entry_t),
    372             compare_entry_tags);
    373     dst->flags |= FLAG_SORTED;
    374 
    375     return OK;
    376 }
    377 
    378 int get_camera_metadata_entry(camera_metadata_t *src,
    379         size_t index,
    380         camera_metadata_entry_t *entry) {
    381     if (src == NULL || entry == NULL) return ERROR;
    382     if (index >= src->entry_count) return ERROR;
    383 
    384     camera_metadata_buffer_entry_t *buffer_entry = src->entries + index;
    385 
    386     entry->index = index;
    387     entry->tag = buffer_entry->tag;
    388     entry->type = buffer_entry->type;
    389     entry->count = buffer_entry->count;
    390     if (buffer_entry->count *
    391             camera_metadata_type_size[buffer_entry->type] > 4) {
    392         entry->data.u8 = src->data + buffer_entry->data.offset;
    393     } else {
    394         entry->data.u8 = buffer_entry->data.value;
    395     }
    396     return OK;
    397 }
    398 
    399 int find_camera_metadata_entry(camera_metadata_t *src,
    400         uint32_t tag,
    401         camera_metadata_entry_t *entry) {
    402     if (src == NULL) return ERROR;
    403 
    404     uint32_t index;
    405     if (src->flags & FLAG_SORTED) {
    406         // Sorted entries, do a binary search
    407         camera_metadata_buffer_entry_t *search_entry = NULL;
    408         camera_metadata_buffer_entry_t key;
    409         key.tag = tag;
    410         search_entry = bsearch(&key,
    411                 src->entries,
    412                 src->entry_count,
    413                 sizeof(camera_metadata_buffer_entry_t),
    414                 compare_entry_tags);
    415         if (search_entry == NULL) return NOT_FOUND;
    416         index = search_entry - src->entries;
    417     } else {
    418         // Not sorted, linear search
    419         for (index = 0; index < src->entry_count; index++) {
    420             if (src->entries[index].tag == tag) {
    421                 break;
    422             }
    423         }
    424         if (index == src->entry_count) return NOT_FOUND;
    425     }
    426 
    427     return get_camera_metadata_entry(src, index,
    428             entry);
    429 }
    430 
    431 int find_camera_metadata_ro_entry(const camera_metadata_t *src,
    432         uint32_t tag,
    433         camera_metadata_ro_entry_t *entry) {
    434     return find_camera_metadata_entry((camera_metadata_t*)src, tag,
    435             (camera_metadata_entry_t*)entry);
    436 }
    437 
    438 
    439 int delete_camera_metadata_entry(camera_metadata_t *dst,
    440         size_t index) {
    441     if (dst == NULL) return ERROR;
    442     if (index >= dst->entry_count) return ERROR;
    443 
    444     camera_metadata_buffer_entry_t *entry = dst->entries + index;
    445     size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
    446             entry->count);
    447 
    448     if (data_bytes > 0) {
    449         // Shift data buffer to overwrite deleted data
    450         uint8_t *start = dst->data + entry->data.offset;
    451         uint8_t *end = start + data_bytes;
    452         size_t length = dst->data_count - entry->data.offset - data_bytes;
    453         memmove(start, end, length);
    454 
    455         // Update all entry indices to account for shift
    456         camera_metadata_buffer_entry_t *e = dst->entries;
    457         size_t i;
    458         for (i = 0; i < dst->entry_count; i++) {
    459             if (calculate_camera_metadata_entry_data_size(
    460                     e->type, e->count) > 0 &&
    461                     e->data.offset > entry->data.offset) {
    462                 e->data.offset -= data_bytes;
    463             }
    464             ++e;
    465         }
    466         dst->data_count -= data_bytes;
    467     }
    468     // Shift entry array
    469     memmove(entry, entry + 1,
    470             sizeof(camera_metadata_buffer_entry_t) *
    471             (dst->entry_count - index - 1) );
    472     dst->entry_count -= 1;
    473 
    474     return OK;
    475 }
    476 
    477 int update_camera_metadata_entry(camera_metadata_t *dst,
    478         size_t index,
    479         const void *data,
    480         size_t data_count,
    481         camera_metadata_entry_t *updated_entry) {
    482     if (dst == NULL) return ERROR;
    483     if (index >= dst->entry_count) return ERROR;
    484 
    485     camera_metadata_buffer_entry_t *entry = dst->entries + index;
    486 
    487     size_t data_bytes =
    488             calculate_camera_metadata_entry_data_size(entry->type,
    489                     data_count);
    490     size_t entry_bytes =
    491             calculate_camera_metadata_entry_data_size(entry->type,
    492                     entry->count);
    493     if (data_bytes != entry_bytes) {
    494         // May need to shift/add to data array
    495         if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
    496             // No room
    497             return ERROR;
    498         }
    499         if (entry_bytes != 0) {
    500             // Remove old data
    501             uint8_t *start = dst->data + entry->data.offset;
    502             uint8_t *end = start + entry_bytes;
    503             size_t length = dst->data_count - entry->data.offset - entry_bytes;
    504             memmove(start, end, length);
    505             dst->data_count -= entry_bytes;
    506 
    507             // Update all entry indices to account for shift
    508             camera_metadata_buffer_entry_t *e = dst->entries;
    509             size_t i;
    510             for (i = 0; i < dst->entry_count; i++) {
    511                 if (calculate_camera_metadata_entry_data_size(
    512                         e->type, e->count) > 0 &&
    513                         e->data.offset > entry->data.offset) {
    514                     e->data.offset -= entry_bytes;
    515                 }
    516                 ++e;
    517             }
    518         }
    519 
    520         if (data_bytes != 0) {
    521             // Append new data
    522             entry->data.offset = dst->data_count;
    523 
    524             memcpy(dst->data + entry->data.offset, data, data_bytes);
    525             dst->data_count += data_bytes;
    526         }
    527     } else if (data_bytes != 0) {
    528         // data size unchanged, reuse same data location
    529         memcpy(dst->data + entry->data.offset, data, data_bytes);
    530     }
    531 
    532     if (data_bytes == 0) {
    533         // Data fits into entry
    534         memcpy(entry->data.value, data,
    535                 data_count * camera_metadata_type_size[entry->type]);
    536     }
    537 
    538     entry->count = data_count;
    539 
    540     if (updated_entry != NULL) {
    541         get_camera_metadata_entry(dst,
    542                 index,
    543                 updated_entry);
    544     }
    545 
    546     return OK;
    547 }
    548 
    549 int set_camera_metadata_user_pointer(camera_metadata_t *dst, void* user) {
    550     if (dst == NULL) return ERROR;
    551     dst->user = user;
    552     return OK;
    553 }
    554 
    555 int get_camera_metadata_user_pointer(camera_metadata_t *dst, void** user) {
    556     if (dst == NULL) return ERROR;
    557     *user = dst->user;
    558     return OK;
    559 }
    560 
    561 static const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
    562 
    563 const char *get_camera_metadata_section_name(uint32_t tag) {
    564     uint32_t tag_section = tag >> 16;
    565     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    566         return vendor_tag_ops->get_camera_vendor_section_name(
    567             vendor_tag_ops,
    568             tag);
    569     }
    570     if (tag_section >= ANDROID_SECTION_COUNT) {
    571         return NULL;
    572     }
    573     return camera_metadata_section_names[tag_section];
    574 }
    575 
    576 const char *get_camera_metadata_tag_name(uint32_t tag) {
    577     uint32_t tag_section = tag >> 16;
    578     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    579         return vendor_tag_ops->get_camera_vendor_tag_name(
    580             vendor_tag_ops,
    581             tag);
    582     }
    583     if (tag_section >= ANDROID_SECTION_COUNT ||
    584         tag >= camera_metadata_section_bounds[tag_section][1] ) {
    585         return NULL;
    586     }
    587     uint32_t tag_index = tag & 0xFFFF;
    588     return tag_info[tag_section][tag_index].tag_name;
    589 }
    590 
    591 int get_camera_metadata_tag_type(uint32_t tag) {
    592     uint32_t tag_section = tag >> 16;
    593     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
    594         return vendor_tag_ops->get_camera_vendor_tag_type(
    595             vendor_tag_ops,
    596             tag);
    597     }
    598     if (tag_section >= ANDROID_SECTION_COUNT ||
    599             tag >= camera_metadata_section_bounds[tag_section][1] ) {
    600         return -1;
    601     }
    602     uint32_t tag_index = tag & 0xFFFF;
    603     return tag_info[tag_section][tag_index].tag_type;
    604 }
    605 
    606 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
    607     vendor_tag_ops = query_ops;
    608     return OK;
    609 }
    610 
    611 static void print_data(int fd, const uint8_t *data_ptr, int type, int count,
    612         int indentation);
    613 
    614 void dump_camera_metadata(const camera_metadata_t *metadata,
    615         int fd,
    616         int verbosity) {
    617     dump_indented_camera_metadata(metadata, fd, verbosity, 0);
    618 }
    619 
    620 void dump_indented_camera_metadata(const camera_metadata_t *metadata,
    621         int fd,
    622         int verbosity,
    623         int indentation) {
    624     if (metadata == NULL) {
    625         fdprintf(fd, "%*sDumping camera metadata array: Not allocated\n",
    626                 indentation, "");
    627         return;
    628     }
    629     unsigned int i;
    630     fdprintf(fd,
    631             "%*sDumping camera metadata array: %d / %d entries, "
    632             "%d / %d bytes of extra data.\n", indentation, "",
    633             metadata->entry_count, metadata->entry_capacity,
    634             metadata->data_count, metadata->data_capacity);
    635     fdprintf(fd, "%*sVersion: %d, Flags: %08x\n",
    636             indentation + 2, "",
    637             metadata->version, metadata->flags);
    638     for (i=0; i < metadata->entry_count; i++) {
    639         camera_metadata_buffer_entry_t *entry = metadata->entries + i;
    640 
    641         const char *tag_name, *tag_section;
    642         tag_section = get_camera_metadata_section_name(entry->tag);
    643         if (tag_section == NULL) {
    644             tag_section = "unknownSection";
    645         }
    646         tag_name = get_camera_metadata_tag_name(entry->tag);
    647         if (tag_name == NULL) {
    648             tag_name = "unknownTag";
    649         }
    650         const char *type_name;
    651         if (entry->type >= NUM_TYPES) {
    652             type_name = "unknown";
    653         } else {
    654             type_name = camera_metadata_type_names[entry->type];
    655         }
    656         fdprintf(fd, "%*s%s.%s (%05x): %s[%d]\n",
    657              indentation + 2, "",
    658              tag_section,
    659              tag_name,
    660              entry->tag,
    661              type_name,
    662              entry->count);
    663 
    664         if (verbosity < 1) continue;
    665 
    666         if (entry->type >= NUM_TYPES) continue;
    667 
    668         size_t type_size = camera_metadata_type_size[entry->type];
    669         uint8_t *data_ptr;
    670         if ( type_size * entry->count > 4 ) {
    671             if (entry->data.offset >= metadata->data_count) {
    672                 ALOGE("%s: Malformed entry data offset: %d (max %d)",
    673                         __FUNCTION__,
    674                         entry->data.offset,
    675                         metadata->data_count);
    676                 continue;
    677             }
    678             data_ptr = metadata->data + entry->data.offset;
    679         } else {
    680             data_ptr = entry->data.value;
    681         }
    682         int count = entry->count;
    683         if (verbosity < 2 && count > 16) count = 16;
    684 
    685         print_data(fd, data_ptr, entry->type, count, indentation);
    686     }
    687 }
    688 
    689 static void print_data(int fd, const uint8_t *data_ptr,
    690         int type, int count, int indentation) {
    691     static int values_per_line[NUM_TYPES] = {
    692         [TYPE_BYTE]     = 16,
    693         [TYPE_INT32]    = 4,
    694         [TYPE_FLOAT]    = 8,
    695         [TYPE_INT64]    = 2,
    696         [TYPE_DOUBLE]   = 4,
    697         [TYPE_RATIONAL] = 2,
    698     };
    699     size_t type_size = camera_metadata_type_size[type];
    700 
    701     int lines = count / values_per_line[type];
    702     if (count % values_per_line[type] != 0) lines++;
    703 
    704     int index = 0;
    705     int j, k;
    706     for (j = 0; j < lines; j++) {
    707         fdprintf(fd, "%*s[", indentation + 4, "");
    708         for (k = 0;
    709              k < values_per_line[type] && count > 0;
    710              k++, count--, index += type_size) {
    711 
    712             switch (type) {
    713                 case TYPE_BYTE:
    714                     fdprintf(fd, "%hhu ",
    715                             *(data_ptr + index));
    716                     break;
    717                 case TYPE_INT32:
    718                     fdprintf(fd, "%d ",
    719                             *(int32_t*)(data_ptr + index));
    720                     break;
    721                 case TYPE_FLOAT:
    722                     fdprintf(fd, "%0.2f ",
    723                             *(float*)(data_ptr + index));
    724                     break;
    725                 case TYPE_INT64:
    726                     fdprintf(fd, "%lld ",
    727                             *(int64_t*)(data_ptr + index));
    728                     break;
    729                 case TYPE_DOUBLE:
    730                     fdprintf(fd, "%0.2f ",
    731                             *(float*)(data_ptr + index));
    732                     break;
    733                 case TYPE_RATIONAL: {
    734                     int32_t numerator = *(int32_t*)(data_ptr + index);
    735                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
    736                     fdprintf(fd, "(%d / %d) ",
    737                             numerator, denominator);
    738                     break;
    739                 }
    740                 default:
    741                     fdprintf(fd, "??? ");
    742             }
    743         }
    744         fdprintf(fd, "]\n");
    745     }
    746 }
    747