camera_metadata.c revision 98d02fd0be8cd09479262959a542dd2620bf6074
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;
8798d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    void                    *user; // User set pointer, not copied with buffer
88d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t                  reserved[0];
89d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala};
90d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
9194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Versioning information */
9294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define CURRENT_METADATA_VERSION 1
9394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
9494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Flag definitions */
9594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala#define FLAG_SORTED 0x00000001
9694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
9794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala/** Tag information */
9894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
99d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalatypedef struct tag_info {
100d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    const char *tag_name;
101d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint8_t     tag_type;
102d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala} tag_info_t;
103d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
104d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala#include "camera_metadata_tag_info.c"
105d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
106d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t camera_metadata_type_size[NUM_TYPES] = {
107d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_BYTE]     = sizeof(uint8_t),
108d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT32]    = sizeof(int32_t),
109d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_FLOAT]    = sizeof(float),
110d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT64]    = sizeof(int64_t),
111d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_DOUBLE]   = sizeof(double),
112d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
113d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala};
114d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
115d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalachar *camera_metadata_type_names[NUM_TYPES] = {
116d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_BYTE]     = "byte",
117d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT32]    = "int32",
118d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_FLOAT]    = "float",
119d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_INT64]    = "int64",
120f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    [TYPE_DOUBLE]   = "double",
121d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    [TYPE_RATIONAL] = "rational"
122d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala};
123d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
124d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
125d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                            size_t data_capacity) {
126d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
127d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                                          data_capacity);
128d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    void *buffer = malloc(memory_needed);
129d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return place_camera_metadata(buffer, memory_needed,
130d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                 entry_capacity,
131d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                 data_capacity);
132d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
133d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
134d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *place_camera_metadata(void *dst,
135d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t dst_size,
136d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t entry_capacity,
137d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t data_capacity) {
138d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return NULL;
139d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (entry_capacity == 0) return NULL;
140d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
141d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
142d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                                          data_capacity);
143d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (memory_needed > dst_size) return NULL;
144d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
145d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    camera_metadata_t *metadata = (camera_metadata_t*)dst;
14694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->version = CURRENT_METADATA_VERSION;
14794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->flags = 0;
148d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_count = 0;
149d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_capacity = entry_capacity;
150f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    metadata->entries = (camera_metadata_buffer_entry_t*)(metadata + 1);
151d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_count = 0;
152d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_capacity = data_capacity;
153d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->size = memory_needed;
154d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata->data_capacity != 0) {
155d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        metadata->data =
156d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                (uint8_t*)(metadata->entries + metadata->entry_capacity);
157d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
158d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        metadata->data = NULL;
159d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
16098d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    metadata->user = NULL;
161d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
162d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata;
163d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
164d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalavoid free_camera_metadata(camera_metadata_t *metadata) {
165d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    free(metadata);
166d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
167d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
168d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_size(size_t entry_count,
169d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                      size_t data_count) {
170d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = sizeof(camera_metadata_t);
171f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
172d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memory_needed += sizeof(uint8_t[data_count]);
173d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return memory_needed;
174d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
175d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
176d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_size(const camera_metadata_t *metadata) {
177d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) return ERROR;
178d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
179d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->size;
180d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
181d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
182d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
183d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) return ERROR;
184d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
185d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    ptrdiff_t reserved_size = metadata->size -
186d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_size(metadata->entry_capacity,
187d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                           metadata->data_capacity);
188d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
189d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return calculate_camera_metadata_size(metadata->entry_count,
190d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                          metadata->data_count) + reserved_size;
191d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
192d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
193d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
194d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->entry_count;
195d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
196d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
197d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
198d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->entry_capacity;
199d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
200d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
201d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
202d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->data_count;
203d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
204d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
205d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
206d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->data_capacity;
207d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
208d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
209d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
210d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const camera_metadata_t *src) {
211d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = get_camera_metadata_compact_size(src);
212d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
213d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return NULL;
214d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst_size < memory_needed) return NULL;
215d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
216d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    // If copying a newer version of the structure, there may be additional
217d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    // header fields we don't know about but need to copy
218d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    ptrdiff_t reserved_size = src->size -
219d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_size(src->entry_capacity,
220d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                           src->data_capacity);
221d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
222d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    camera_metadata_t *metadata = (camera_metadata_t*)dst;
22394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->version = CURRENT_METADATA_VERSION;
22494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->flags = src->flags;
225d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_count = src->entry_count;
226d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_capacity = src->entry_count;
227f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    metadata->entries = (camera_metadata_buffer_entry_t*)
228d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             ((uint8_t *)(metadata + 1) + reserved_size);
229d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_count = src->data_count;
230d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_capacity = src->data_count;
231d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data = (uint8_t *)(metadata->entries + metadata->entry_capacity);
232d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->size = memory_needed;
233d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
234d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (reserved_size > 0) {
235d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(metadata->reserved, src->reserved, reserved_size);
236d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
237d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(metadata->entries, src->entries,
238f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
239d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(metadata->data, src->data,
240d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            sizeof(uint8_t[metadata->data_count]));
24198d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    metadata->user = NULL;
242d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
243d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata;
244d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
245d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
246d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint append_camera_metadata(camera_metadata_t *dst,
247d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const camera_metadata_t *src) {
248d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL || src == NULL ) return ERROR;
249d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
250d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
251d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
252d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
253d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(dst->entries + dst->entry_count, src->entries,
254f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
255d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(dst->data + dst->data_count, src->data,
256d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            sizeof(uint8_t[src->data_count]));
257d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->data_count != 0) {
258d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        unsigned int i;
259d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (i = dst->entry_count;
260d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             i < dst->entry_count + src->entry_count;
261d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             i++) {
262f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *entry = dst->entries + i;
263d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) {
264d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                entry->data.offset += dst->data_count;
265d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
266d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
267d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
268f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst->entry_count == 0) {
269f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Appending onto empty buffer, keep sorted state
270f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->flags |= src->flags & FLAG_SORTED;
271f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (src->entry_count != 0) {
272f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Both src, dst are nonempty, cannot assume sort remains
273f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->flags &= ~FLAG_SORTED;
274f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
275f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Src is empty, keep dst sorted state
276f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
277d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count += src->entry_count;
278d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->data_count += src->data_count;
279d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
280d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
281d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
282d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
283d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_entry_data_size(uint8_t type,
284d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
285d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type >= NUM_TYPES) return 0;
286d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes = data_count *
287d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            camera_metadata_type_size[type];
288d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return data_bytes <= 4 ? 0 : data_bytes;
289d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
290d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
29194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int add_camera_metadata_entry_raw(camera_metadata_t *dst,
292d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
293d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t  type,
294d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
295d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
296d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
297d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return ERROR;
298d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_count == dst->entry_capacity) return ERROR;
299d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data == NULL) return ERROR;
300d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
301d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes =
302d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_entry_data_size(type, data_count);
303d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
304f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count;
305d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->tag = tag;
306d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->type = type;
307d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->count = data_count;
308d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
309d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data_bytes == 0) {
310d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(entry->data.value, data,
311d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                data_count * camera_metadata_type_size[type] );
312d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
313d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        entry->data.offset = dst->data_count;
314d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
315d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        dst->data_count += data_bytes;
316d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
317d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count++;
31894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags &= ~FLAG_SORTED;
319d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
320d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
321d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
322d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint add_camera_metadata_entry(camera_metadata_t *dst,
323d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
324d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
325d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
326d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
327d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int type = get_camera_metadata_tag_type(tag);
328d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type == -1) {
32994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
330d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return ERROR;
331d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
332d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
333d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return add_camera_metadata_entry_raw(dst,
334d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag,
335d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type,
336d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data,
337d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_count);
338d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
339d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
34094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int compare_entry_tags(const void *p1, const void *p2) {
341f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
342f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
34394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return  tag1 < tag2 ? -1 :
34494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag1 == tag2 ? 0 :
34594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            1;
34694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
34794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
34894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint sort_camera_metadata(camera_metadata_t *dst) {
34994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst == NULL) return ERROR;
35094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst->flags & FLAG_SORTED) return OK;
35194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
35294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    qsort(dst->entries, dst->entry_count,
353f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t),
35494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            compare_entry_tags);
35594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags |= FLAG_SORTED;
35694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
35794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
35894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
35994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
360d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_entry(camera_metadata_t *src,
361f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
362f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
363f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (src == NULL || entry == NULL) return ERROR;
364d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (index >= src->entry_count) return ERROR;
365d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
366f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *buffer_entry = src->entries + index;
367d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
368f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->index = index;
369f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->tag = buffer_entry->tag;
370f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->type = buffer_entry->type;
371f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = buffer_entry->count;
372f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (buffer_entry->count *
373f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_type_size[buffer_entry->type] > 4) {
374f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = src->data + buffer_entry->data.offset;
375f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
376f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = buffer_entry->data.value;
37794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
37894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
37994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
38094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
38194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint find_camera_metadata_entry(camera_metadata_t *src,
38294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        uint32_t tag,
383f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
38494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src == NULL) return ERROR;
38594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
386f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t index;
38794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src->flags & FLAG_SORTED) {
38894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Sorted entries, do a binary search
389f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *search_entry = NULL;
390f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t key;
39194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        key.tag = tag;
392f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        search_entry = bsearch(&key,
39394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entries,
39494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entry_count,
395f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                sizeof(camera_metadata_buffer_entry_t),
39694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                compare_entry_tags);
397f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (search_entry == NULL) return NOT_FOUND;
398f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        index = search_entry - src->entries;
399d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
40094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Not sorted, linear search
401f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (index = 0; index < src->entry_count; index++) {
402f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (src->entries[index].tag == tag) {
40394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                break;
40494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            }
40594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
406f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (index == src->entry_count) return NOT_FOUND;
40794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
408f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
409f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return get_camera_metadata_entry(src, index,
410f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry);
411f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
412f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
413f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint delete_camera_metadata_entry(camera_metadata_t *dst,
414f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index) {
415f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
416f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
417f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
418f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
419f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
420f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->count);
421f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
422f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes > 0) {
423f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Shift data buffer to overwrite deleted data
424f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *start = dst->data + entry->data.offset;
425f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *end = start + data_bytes;
426f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t length = dst->data_count - entry->data.offset - data_bytes;
427f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memmove(start, end, length);
428f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
429f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Update all entry indices to account for shift
430f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *e = dst->entries;
431f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t i;
432f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (i = 0; i < dst->entry_count; i++) {
433f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (calculate_camera_metadata_entry_data_size(
434f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->type, e->count) > 0 &&
435f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset > entry->data.offset) {
436f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                e->data.offset -= data_bytes;
437f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
438f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            ++e;
43994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
440f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->data_count -= data_bytes;
441d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
442f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    // Shift entry array
443f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memmove(entry, entry + 1,
444f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t) *
445f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            (dst->entry_count - index - 1) );
446f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    dst->entry_count -= 1;
447f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
448f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return OK;
449f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
450f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
451f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint update_camera_metadata_entry(camera_metadata_t *dst,
452f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
453f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        const void *data,
454f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t data_count,
455f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *updated_entry) {
456f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
457f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
458f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
459f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
460f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
461f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes =
462f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
463f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    data_count);
464f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t entry_bytes =
465f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
466f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    entry->count);
467f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes != entry_bytes) {
468f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // May need to shift/add to data array
469f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
470f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // No room
471f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            return ERROR;
472f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
473f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (entry_bytes != 0) {
474f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Remove old data
475f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *start = dst->data + entry->data.offset;
476f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *end = start + entry_bytes;
477f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t length = dst->data_count - entry->data.offset - entry_bytes;
478f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memmove(start, end, length);
479f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count -= entry_bytes;
480f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
481f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Update all entry indices to account for shift
482f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *e = dst->entries;
483f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t i;
484f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            for (i = 0; i < dst->entry_count; i++) {
485f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                if (calculate_camera_metadata_entry_data_size(
486f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->type, e->count) > 0 &&
487f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->data.offset > entry->data.offset) {
488f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset -= entry_bytes;
489f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                }
490f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                ++e;
491f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
492f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
493f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
494f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (data_bytes != 0) {
495f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Append new data
496f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->data.offset = dst->data_count;
497f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
498f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memcpy(dst->data + entry->data.offset, data, data_bytes);
499f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count += data_bytes;
500f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
501f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (data_bytes != 0) {
502f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // data size unchanged, reuse same data location
503f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
504f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
505f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
506f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes == 0) {
507f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Data fits into entry
508f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(entry->data.value, data,
509f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                data_count * camera_metadata_type_size[entry->type]);
510f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
511f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
512f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = data_count;
513f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
514f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (updated_entry != NULL) {
515f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        get_camera_metadata_entry(dst,
516f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                index,
517f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                updated_entry);
518f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
519f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
520d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
521d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
522d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
52398d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvalaint set_camera_metadata_user_pointer(camera_metadata_t *dst, void* user) {
52498d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    if (dst == NULL) return ERROR;
52598d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    dst->user = user;
52698d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    return OK;
52798d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala}
52898d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala
52998d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvalaint get_camera_metadata_user_pointer(camera_metadata_t *dst, void** user) {
53098d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    if (dst == NULL) return ERROR;
53198d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    *user = dst->user;
53298d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    return OK;
53398d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala}
53498d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala
535d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalastatic const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
536d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
537d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_section_name(uint32_t tag) {
538d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
539d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
54094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_section_name(
54194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
54294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
543d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
544d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT) {
545d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return NULL;
546d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
547d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return camera_metadata_section_names[tag_section];
548d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
549d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
550d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_tag_name(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_name(
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 NULL;
560d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
561d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
562d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_name;
563d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
564d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
565d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_tag_type(uint32_t tag) {
566d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
567d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
56894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_tag_type(
56994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
57094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
571d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
572d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT ||
573d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag >= camera_metadata_section_bounds[tag_section][1] ) {
574d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return -1;
575d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
576d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
577d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_type;
578d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
579d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
580d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
581d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    vendor_tag_ops = query_ops;
582d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
583d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
584d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
58594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr, int type, int count);
586d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
58794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalavoid dump_camera_metadata(const camera_metadata_t *metadata,
58894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int fd,
58994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int verbosity) {
590d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) {
59194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Metadata is null.", __FUNCTION__);
592d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return;
593d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
594d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    unsigned int i;
59594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd,
59694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            "Dumping camera metadata array. %d entries, "
59794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            "%d bytes of extra data.\n",
598d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            metadata->entry_count, metadata->data_count);
59994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd, "  (%d entries and %d bytes data reserved)\n",
600d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            metadata->entry_capacity, metadata->data_capacity);
60194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd, "  Version: %d, Flags: %08x\n",
60294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            metadata->version, metadata->flags);
603d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (i=0; i < metadata->entry_count; i++) {
604f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *entry = metadata->entries + i;
605d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
606d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *tag_name, *tag_section;
607d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_section = get_camera_metadata_section_name(entry->tag);
608d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_section == NULL) {
609d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_section = "unknownSection";
610d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
611d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_name = get_camera_metadata_tag_name(entry->tag);
612d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_name == NULL) {
613d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_name = "unknownTag";
614d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
615d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *type_name;
616d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) {
617d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = "unknown";
618d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
619d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = camera_metadata_type_names[entry->type];
620d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
62194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, "Tag: %s.%s (%05x): %s[%d]\n",
622d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_section,
623d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_name,
624d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->tag,
625d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             type_name,
626d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->count);
627d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
628d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 1) continue;
629d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
630d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) continue;
631d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
632d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t type_size = camera_metadata_type_size[entry->type];
633d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t *data_ptr;
634d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if ( type_size * entry->count > 4 ) {
635d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if (entry->data.offset >= metadata->data_count) {
63694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                ALOGE("%s: Malformed entry data offset: %d (max %d)",
63794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        __FUNCTION__,
63894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        entry->data.offset,
63994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        metadata->data_count);
640d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                continue;
641d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
642d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = metadata->data + entry->data.offset;
643d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
644d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = entry->data.value;
645d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
646d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        int count = entry->count;
647d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 2 && count > 16) count = 16;
648d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
64994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        print_data(fd, data_ptr, entry->type, count);
650d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
651d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
652d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
65394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr, int type, int count) {
654d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    static int values_per_line[NUM_TYPES] = {
655d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_BYTE]     = 16,
656d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT32]    = 4,
657d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_FLOAT]    = 8,
658d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT64]    = 2,
659d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_DOUBLE]   = 4,
660d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_RATIONAL] = 2,
661d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    };
662d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t type_size = camera_metadata_type_size[type];
663d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
664d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int lines = count / values_per_line[type];
665d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (count % values_per_line[type] != 0) lines++;
666d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
667d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int index = 0;
668d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int j, k;
669d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (j = 0; j < lines; j++) {
67094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, " [");
671d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (k = 0;
672d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k < values_per_line[type] && count > 0;
673d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k++, count--, index += type_size) {
674d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
675d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            switch (type) {
676d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_BYTE:
67794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%hhu ",
678d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(data_ptr + index));
679d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
680d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT32:
68194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%d ",
682d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int32_t*)(data_ptr + index));
683d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
684d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_FLOAT:
68594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
686d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
687d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
688d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT64:
68994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%lld ",
690d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int64_t*)(data_ptr + index));
691d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
692d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_DOUBLE:
69394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
694d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
695d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
696d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_RATIONAL: {
697d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t numerator = *(int32_t*)(data_ptr + index);
698d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t denominator = *(int32_t*)(data_ptr + index + 4);
69994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "(%d / %d) ",
700d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            numerator, denominator);
701d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
702d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                }
703d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                default:
70494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "??? ");
705d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
706d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
70794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, "]\n");
708d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
709d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
710