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