camera_metadata.c revision f5fb8a5516876c5a48cc44b4f1c99504e0b9f245
1d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala/*
2d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * Copyright (C) 2012 The Android Open Source Project
3d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
4d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
5d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * you may not use this file except in compliance with the License.
6d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * You may obtain a copy of the License at
7d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
8d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
9d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
10d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
11d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
12d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * See the License for the specific language governing permissions and
14d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * limitations under the License.
15d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala */
16623ff65afea34612498dcf33887ffaf8b194c281Eino-Ville Talvala#define _GNU_SOURCE // for fdprintf
17d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include <system/camera_metadata.h>
18d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include <cutils/log.h>
1994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#include <stdio.h>
2094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#include <stdlib.h>
2194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#include <errno.h>
2294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
2394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define OK         0
2494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define ERROR      1
2594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define NOT_FOUND -ENOENT
26d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala/**
27d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * A single metadata entry, storing an array of values of a given type. If the
28d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * array is no larger than 4 bytes in size, it is stored in the data.value[]
29d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * array; otherwise, it can found in the parent's data array at index
30d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * data.offset.
31d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala */
32f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalatypedef struct camera_metadata_buffer_entry {
33d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag;
34d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t   count;
35d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    union {
36d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t  offset;
37d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t value[4];
38d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } data;
39d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t  type;
40d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t  reserved[3];
41f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala} __attribute__((packed)) camera_metadata_buffer_entry_t;
42d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
43d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala/**
44d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * A packet of metadata. This is a list of entries, each of which may point to
45d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * its values stored at an offset in data.
46d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
47d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * It is assumed by the utility functions that the memory layout of the packet
48d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * is as follows:
49d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
50f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
51f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | camera_metadata_t                             |
52f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |                                               |
53f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
54f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | reserved for future expansion                 |
55f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
56f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | camera_metadata_buffer_entry_t #0             |
57f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
58f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | ....                                          |
59f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
60f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | camera_metadata_buffer_entry_t #entry_count-1 |
61f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
62f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | free space for                                |
63f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | (entry_capacity-entry_count) entries          |
64f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
65f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | start of camera_metadata.data                 |
66f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |                                               |
67f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
68f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | free space for                                |
69f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   | (data_capacity-data_count) bytes              |
70f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala *   |-----------------------------------------------|
71d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
72d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * With the total length of the whole packet being camera_metadata.size bytes.
73d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala *
74d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * In short, the entries and data are contiguous in memory after the metadata
75d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala * header.
76d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala */
77d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalastruct camera_metadata {
78d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t                   size;
7994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    uint32_t                 version;
8094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    uint32_t                 flags;
81d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t                   entry_count;
82d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t                   entry_capacity;
83f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entries;
84d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t                   data_count;
85d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t                   data_capacity;
86d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t                 *data;
87d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t                  reserved[0];
88d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala};
89d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
9094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Versioning information */
9194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define CURRENT_METADATA_VERSION 1
9294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
9394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Flag definitions */
9494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define FLAG_SORTED 0x00000001
9594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
9694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Tag information */
9794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
98d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalatypedef struct tag_info {
99d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    const char *tag_name;
100d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t     tag_type;
101d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} tag_info_t;
102d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
103d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include "camera_metadata_tag_info.c"
104d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
105d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t camera_metadata_type_size[NUM_TYPES] = {
106d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_BYTE]     = sizeof(uint8_t),
107d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT32]    = sizeof(int32_t),
108d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_FLOAT]    = sizeof(float),
109d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT64]    = sizeof(int64_t),
110d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_DOUBLE]   = sizeof(double),
111d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
112d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala};
113d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
114d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalachar *camera_metadata_type_names[NUM_TYPES] = {
115d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_BYTE]     = "byte",
116d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT32]    = "int32",
117d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_FLOAT]    = "float",
118d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT64]    = "int64",
119f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    [TYPE_DOUBLE]   = "double",
120d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_RATIONAL] = "rational"
121d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala};
122d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
123d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
124d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                            size_t data_capacity) {
125d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
126d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                                          data_capacity);
127d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    void *buffer = malloc(memory_needed);
128d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return place_camera_metadata(buffer, memory_needed,
129d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                 entry_capacity,
130d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                 data_capacity);
131d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
132d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
133d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *place_camera_metadata(void *dst,
134d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t dst_size,
135d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t entry_capacity,
136d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t data_capacity) {
137d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return NULL;
138d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (entry_capacity == 0) return NULL;
139d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
140d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
141d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                                          data_capacity);
142d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (memory_needed > dst_size) return NULL;
143d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
144d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    camera_metadata_t *metadata = (camera_metadata_t*)dst;
14594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->version = CURRENT_METADATA_VERSION;
14694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->flags = 0;
147d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_count = 0;
148d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_capacity = entry_capacity;
149f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    metadata->entries = (camera_metadata_buffer_entry_t*)(metadata + 1);
150d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_count = 0;
151d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_capacity = data_capacity;
152d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->size = memory_needed;
153d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata->data_capacity != 0) {
154d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        metadata->data =
155d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                (uint8_t*)(metadata->entries + metadata->entry_capacity);
156d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
157d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        metadata->data = NULL;
158d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
159d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
160d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata;
161d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
162d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalavoid free_camera_metadata(camera_metadata_t *metadata) {
163d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    free(metadata);
164d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
165d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
166d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_size(size_t entry_count,
167d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                      size_t data_count) {
168d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = sizeof(camera_metadata_t);
169f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
170d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memory_needed += sizeof(uint8_t[data_count]);
171d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return memory_needed;
172d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
173d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
174d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_size(const camera_metadata_t *metadata) {
175d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) return ERROR;
176d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
177d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->size;
178d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
179d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
180d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
181d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) return ERROR;
182d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
183d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    ptrdiff_t reserved_size = metadata->size -
184d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_size(metadata->entry_capacity,
185d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                           metadata->data_capacity);
186d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
187d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return calculate_camera_metadata_size(metadata->entry_count,
188d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                          metadata->data_count) + reserved_size;
189d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
190d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
191d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
192d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->entry_count;
193d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
194d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
195d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
196d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->entry_capacity;
197d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
198d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
199d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
200d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->data_count;
201d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
202d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
203d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
204d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->data_capacity;
205d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
206d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
207d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
208d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const camera_metadata_t *src) {
209d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = get_camera_metadata_compact_size(src);
210d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
211d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return NULL;
212d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst_size < memory_needed) return NULL;
213d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
214d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    // If copying a newer version of the structure, there may be additional
215d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    // header fields we don't know about but need to copy
216d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    ptrdiff_t reserved_size = src->size -
217d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_size(src->entry_capacity,
218d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                           src->data_capacity);
219d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
220d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    camera_metadata_t *metadata = (camera_metadata_t*)dst;
22194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->version = CURRENT_METADATA_VERSION;
22294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->flags = src->flags;
223d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_count = src->entry_count;
224d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_capacity = src->entry_count;
225f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    metadata->entries = (camera_metadata_buffer_entry_t*)
226d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             ((uint8_t *)(metadata + 1) + reserved_size);
227d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_count = src->data_count;
228d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_capacity = src->data_count;
229d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data = (uint8_t *)(metadata->entries + metadata->entry_capacity);
230d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->size = memory_needed;
231d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
232d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (reserved_size > 0) {
233d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(metadata->reserved, src->reserved, reserved_size);
234d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
235d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(metadata->entries, src->entries,
236f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
237d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(metadata->data, src->data,
238d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            sizeof(uint8_t[metadata->data_count]));
239d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
240d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata;
241d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
242d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
243d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint append_camera_metadata(camera_metadata_t *dst,
244d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const camera_metadata_t *src) {
245d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL || src == NULL ) return ERROR;
246d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
247d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
248d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
249d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
250d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(dst->entries + dst->entry_count, src->entries,
251f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
252d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(dst->data + dst->data_count, src->data,
253d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            sizeof(uint8_t[src->data_count]));
254d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->data_count != 0) {
255d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        unsigned int i;
256d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (i = dst->entry_count;
257d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             i < dst->entry_count + src->entry_count;
258d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             i++) {
259f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *entry = dst->entries + i;
260d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) {
261d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                entry->data.offset += dst->data_count;
262d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
263d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
264d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
265f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst->entry_count == 0) {
266f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Appending onto empty buffer, keep sorted state
267f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->flags |= src->flags & FLAG_SORTED;
268f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (src->entry_count != 0) {
269f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Both src, dst are nonempty, cannot assume sort remains
270f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->flags &= ~FLAG_SORTED;
271f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
272f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Src is empty, keep dst sorted state
273f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
274d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count += src->entry_count;
275d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->data_count += src->data_count;
276d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
277d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
278d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
279d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
280d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_entry_data_size(uint8_t type,
281d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
282d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type >= NUM_TYPES) return 0;
283d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes = data_count *
284d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            camera_metadata_type_size[type];
285d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return data_bytes <= 4 ? 0 : data_bytes;
286d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
287d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
28894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int add_camera_metadata_entry_raw(camera_metadata_t *dst,
289d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
290d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t  type,
291d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
292d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
293d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
294d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return ERROR;
295d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_count == dst->entry_capacity) return ERROR;
296d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data == NULL) return ERROR;
297d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
298d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes =
299d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_entry_data_size(type, data_count);
300d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
301f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count;
302d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->tag = tag;
303d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->type = type;
304d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->count = data_count;
305d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
306d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data_bytes == 0) {
307d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(entry->data.value, data,
308d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                data_count * camera_metadata_type_size[type] );
309d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
310d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        entry->data.offset = dst->data_count;
311d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
312d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        dst->data_count += data_bytes;
313d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
314d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count++;
31594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags &= ~FLAG_SORTED;
316d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
317d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
318d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
319d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint add_camera_metadata_entry(camera_metadata_t *dst,
320d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
321d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
322d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
323d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
324d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int type = get_camera_metadata_tag_type(tag);
325d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type == -1) {
32694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
327d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return ERROR;
328d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
329d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
330d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return add_camera_metadata_entry_raw(dst,
331d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag,
332d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type,
333d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data,
334d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_count);
335d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
336d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
33794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int compare_entry_tags(const void *p1, const void *p2) {
338f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
339f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
34094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return  tag1 < tag2 ? -1 :
34194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag1 == tag2 ? 0 :
34294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            1;
34394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
34494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
34594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint sort_camera_metadata(camera_metadata_t *dst) {
34694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst == NULL) return ERROR;
34794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst->flags & FLAG_SORTED) return OK;
34894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
34994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    qsort(dst->entries, dst->entry_count,
350f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t),
35194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            compare_entry_tags);
35294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags |= FLAG_SORTED;
35394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
35494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
35594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
35694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
357d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_entry(camera_metadata_t *src,
358f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
359f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
360f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (src == NULL || entry == NULL) return ERROR;
361d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (index >= src->entry_count) return ERROR;
362d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
363f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *buffer_entry = src->entries + index;
364d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
365f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->index = index;
366f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->tag = buffer_entry->tag;
367f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->type = buffer_entry->type;
368f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = buffer_entry->count;
369f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (buffer_entry->count *
370f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_type_size[buffer_entry->type] > 4) {
371f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = src->data + buffer_entry->data.offset;
372f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
373f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = buffer_entry->data.value;
37494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
37594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
37694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
37794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
37894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint find_camera_metadata_entry(camera_metadata_t *src,
37994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        uint32_t tag,
380f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
38194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src == NULL) return ERROR;
38294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
383f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t index;
38494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src->flags & FLAG_SORTED) {
38594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Sorted entries, do a binary search
386f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *search_entry = NULL;
387f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t key;
38894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        key.tag = tag;
389f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        search_entry = bsearch(&key,
39094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entries,
39194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entry_count,
392f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                sizeof(camera_metadata_buffer_entry_t),
39394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                compare_entry_tags);
394f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (search_entry == NULL) return NOT_FOUND;
395f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        index = search_entry - src->entries;
396d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
39794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Not sorted, linear search
398f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (index = 0; index < src->entry_count; index++) {
399f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (src->entries[index].tag == tag) {
40094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                break;
40194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            }
40294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
403f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (index == src->entry_count) return NOT_FOUND;
40494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
405f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
406f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return get_camera_metadata_entry(src, index,
407f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry);
408f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
409f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
410f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint delete_camera_metadata_entry(camera_metadata_t *dst,
411f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index) {
412f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
413f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
414f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
415f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
416f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
417f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->count);
418f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
419f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes > 0) {
420f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Shift data buffer to overwrite deleted data
421f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *start = dst->data + entry->data.offset;
422f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *end = start + data_bytes;
423f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t length = dst->data_count - entry->data.offset - data_bytes;
424f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memmove(start, end, length);
425f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
426f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Update all entry indices to account for shift
427f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *e = dst->entries;
428f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t i;
429f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (i = 0; i < dst->entry_count; i++) {
430f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (calculate_camera_metadata_entry_data_size(
431f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->type, e->count) > 0 &&
432f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset > entry->data.offset) {
433f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                e->data.offset -= data_bytes;
434f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
435f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            ++e;
43694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
437f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->data_count -= data_bytes;
438d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
439f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    // Shift entry array
440f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memmove(entry, entry + 1,
441f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t) *
442f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            (dst->entry_count - index - 1) );
443f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    dst->entry_count -= 1;
444f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
445f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return OK;
446f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
447f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
448f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint update_camera_metadata_entry(camera_metadata_t *dst,
449f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
450f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        const void *data,
451f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t data_count,
452f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *updated_entry) {
453f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
454f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
455f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
456f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
457f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
458f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes =
459f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
460f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    data_count);
461f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t entry_bytes =
462f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
463f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    entry->count);
464f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes != entry_bytes) {
465f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // May need to shift/add to data array
466f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
467f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // No room
468f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            return ERROR;
469f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
470f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (entry_bytes != 0) {
471f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Remove old data
472f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *start = dst->data + entry->data.offset;
473f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *end = start + entry_bytes;
474f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t length = dst->data_count - entry->data.offset - entry_bytes;
475f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memmove(start, end, length);
476f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count -= entry_bytes;
477f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
478f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Update all entry indices to account for shift
479f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *e = dst->entries;
480f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t i;
481f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            for (i = 0; i < dst->entry_count; i++) {
482f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                if (calculate_camera_metadata_entry_data_size(
483f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->type, e->count) > 0 &&
484f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->data.offset > entry->data.offset) {
485f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset -= entry_bytes;
486f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                }
487f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                ++e;
488f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
489f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
490f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
491f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (data_bytes != 0) {
492f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Append new data
493f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->data.offset = dst->data_count;
494f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
495f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memcpy(dst->data + entry->data.offset, data, data_bytes);
496f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count += data_bytes;
497f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
498f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (data_bytes != 0) {
499f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // data size unchanged, reuse same data location
500f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
501f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
502f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
503f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes == 0) {
504f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Data fits into entry
505f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(entry->data.value, data,
506f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                data_count * camera_metadata_type_size[entry->type]);
507f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
508f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
509f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = data_count;
510f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
511f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (updated_entry != NULL) {
512f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        get_camera_metadata_entry(dst,
513f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                index,
514f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                updated_entry);
515f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
516f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
517d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
518d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
519d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
520d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalastatic const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
521d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
522d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_section_name(uint32_t tag) {
523d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
524d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
52594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_section_name(
52694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
52794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
528d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
529d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT) {
530d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return NULL;
531d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
532d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return camera_metadata_section_names[tag_section];
533d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
534d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
535d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_tag_name(uint32_t tag) {
536d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
537d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
53894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_tag_name(
53994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
54094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
541d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
542d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT ||
543d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag >= camera_metadata_section_bounds[tag_section][1] ) {
544d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return NULL;
545d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
546d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
547d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_name;
548d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
549d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
550d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_tag_type(uint32_t tag) {
551d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
552d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
55394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_tag_type(
55494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
55594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
556d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
557d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT ||
558d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag >= camera_metadata_section_bounds[tag_section][1] ) {
559d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return -1;
560d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
561d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
562d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_type;
563d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
564d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
565d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
566d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    vendor_tag_ops = query_ops;
567d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
568d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
569d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
57094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr, int type, int count);
571d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
57294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalavoid dump_camera_metadata(const camera_metadata_t *metadata,
57394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int fd,
57494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int verbosity) {
575d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) {
57694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Metadata is null.", __FUNCTION__);
577d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return;
578d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
579d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    unsigned int i;
58094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd,
58194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            "Dumping camera metadata array. %d entries, "
58294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            "%d bytes of extra data.\n",
583d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            metadata->entry_count, metadata->data_count);
58494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd, "  (%d entries and %d bytes data reserved)\n",
585d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            metadata->entry_capacity, metadata->data_capacity);
58694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd, "  Version: %d, Flags: %08x\n",
58794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            metadata->version, metadata->flags);
588d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (i=0; i < metadata->entry_count; i++) {
589f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *entry = metadata->entries + i;
590d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
591d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *tag_name, *tag_section;
592d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_section = get_camera_metadata_section_name(entry->tag);
593d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_section == NULL) {
594d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_section = "unknownSection";
595d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
596d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_name = get_camera_metadata_tag_name(entry->tag);
597d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_name == NULL) {
598d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_name = "unknownTag";
599d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
600d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *type_name;
601d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) {
602d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = "unknown";
603d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
604d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = camera_metadata_type_names[entry->type];
605d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
60694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, "Tag: %s.%s (%05x): %s[%d]\n",
607d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_section,
608d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_name,
609d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->tag,
610d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             type_name,
611d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->count);
612d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
613d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 1) continue;
614d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
615d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) continue;
616d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
617d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t type_size = camera_metadata_type_size[entry->type];
618d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t *data_ptr;
619d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if ( type_size * entry->count > 4 ) {
620d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if (entry->data.offset >= metadata->data_count) {
62194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                ALOGE("%s: Malformed entry data offset: %d (max %d)",
62294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        __FUNCTION__,
62394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        entry->data.offset,
62494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        metadata->data_count);
625d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                continue;
626d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
627d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = metadata->data + entry->data.offset;
628d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
629d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = entry->data.value;
630d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
631d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        int count = entry->count;
632d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 2 && count > 16) count = 16;
633d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
63494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        print_data(fd, data_ptr, entry->type, count);
635d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
636d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
637d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
63894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr, int type, int count) {
639d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    static int values_per_line[NUM_TYPES] = {
640d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_BYTE]     = 16,
641d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT32]    = 4,
642d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_FLOAT]    = 8,
643d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT64]    = 2,
644d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_DOUBLE]   = 4,
645d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_RATIONAL] = 2,
646d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    };
647d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t type_size = camera_metadata_type_size[type];
648d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
649d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int lines = count / values_per_line[type];
650d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (count % values_per_line[type] != 0) lines++;
651d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
652d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int index = 0;
653d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int j, k;
654d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (j = 0; j < lines; j++) {
65594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, " [");
656d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (k = 0;
657d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k < values_per_line[type] && count > 0;
658d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k++, count--, index += type_size) {
659d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
660d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            switch (type) {
661d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_BYTE:
66294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%hhu ",
663d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(data_ptr + index));
664d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
665d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT32:
66694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%d ",
667d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int32_t*)(data_ptr + index));
668d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
669d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_FLOAT:
67094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
671d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
672d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
673d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT64:
67494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%lld ",
675d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int64_t*)(data_ptr + index));
676d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
677d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_DOUBLE:
67894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
679d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
680d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
681d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_RATIONAL: {
682d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t numerator = *(int32_t*)(data_ptr + index);
683d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t denominator = *(int32_t*)(data_ptr + index + 4);
68494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "(%d / %d) ",
685d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            numerator, denominator);
686d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
687d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                }
688d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                default:
68994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "??? ");
690d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
691d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
69294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, "]\n");
693d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
694d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
695