camera_metadata.c revision 1d27e5b8a575620bb64406289c7c229662de92ca
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
106fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvalaconst size_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
115fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvalaconst char *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
283fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvalacamera_metadata_t *clone_camera_metadata(camera_metadata_t *src) {
284fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    int res;
285fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    camera_metadata_t *clone = allocate_camera_metadata(
286fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        get_camera_metadata_entry_count(src),
287fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        get_camera_metadata_data_count(src));
288fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    if (clone != NULL) {
289fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        res = append_camera_metadata(clone, src);
290fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        if (res != OK) {
291fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala            free_camera_metadata(clone);
292fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala            clone = NULL;
293fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        }
294fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    }
295fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    return clone;
296fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala}
297fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala
298d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_entry_data_size(uint8_t type,
299d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
300d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type >= NUM_TYPES) return 0;
301d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes = data_count *
302d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            camera_metadata_type_size[type];
303d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return data_bytes <= 4 ? 0 : data_bytes;
304d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
305d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
30694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int add_camera_metadata_entry_raw(camera_metadata_t *dst,
307d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
308d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t  type,
309d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
310d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
311d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
312d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return ERROR;
313d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_count == dst->entry_capacity) return ERROR;
314d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data == NULL) return ERROR;
315d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
316d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes =
317d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_entry_data_size(type, data_count);
318d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
319f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count;
320d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->tag = tag;
321d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->type = type;
322d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->count = data_count;
323d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
324d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data_bytes == 0) {
325d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(entry->data.value, data,
326d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                data_count * camera_metadata_type_size[type] );
327d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
328d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        entry->data.offset = dst->data_count;
329d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
330d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        dst->data_count += data_bytes;
331d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
332d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count++;
33394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags &= ~FLAG_SORTED;
334d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
335d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
336d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
337d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint add_camera_metadata_entry(camera_metadata_t *dst,
338d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
339d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
340d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
341d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
342d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int type = get_camera_metadata_tag_type(tag);
343d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type == -1) {
34494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
345d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return ERROR;
346d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
347d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
348d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return add_camera_metadata_entry_raw(dst,
349d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag,
350d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type,
351d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data,
352d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_count);
353d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
354d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
35594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int compare_entry_tags(const void *p1, const void *p2) {
356f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
357f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
35894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return  tag1 < tag2 ? -1 :
35994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag1 == tag2 ? 0 :
36094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            1;
36194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
36294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
36394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint sort_camera_metadata(camera_metadata_t *dst) {
36494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst == NULL) return ERROR;
36594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst->flags & FLAG_SORTED) return OK;
36694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
36794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    qsort(dst->entries, dst->entry_count,
368f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t),
36994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            compare_entry_tags);
37094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags |= FLAG_SORTED;
37194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
37294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
37394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
37494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
375d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_entry(camera_metadata_t *src,
376f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
377f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
378f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (src == NULL || entry == NULL) return ERROR;
379d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (index >= src->entry_count) return ERROR;
380d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
381f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *buffer_entry = src->entries + index;
382d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
383f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->index = index;
384f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->tag = buffer_entry->tag;
385f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->type = buffer_entry->type;
386f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = buffer_entry->count;
387f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (buffer_entry->count *
388f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_type_size[buffer_entry->type] > 4) {
389f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = src->data + buffer_entry->data.offset;
390f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
391f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = buffer_entry->data.value;
39294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
39394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
39494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
39594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
39694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint find_camera_metadata_entry(camera_metadata_t *src,
39794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        uint32_t tag,
398f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
39994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src == NULL) return ERROR;
40094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
401f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t index;
40294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src->flags & FLAG_SORTED) {
40394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Sorted entries, do a binary search
404f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *search_entry = NULL;
405f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t key;
40694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        key.tag = tag;
407f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        search_entry = bsearch(&key,
40894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entries,
40994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entry_count,
410f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                sizeof(camera_metadata_buffer_entry_t),
41194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                compare_entry_tags);
412f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (search_entry == NULL) return NOT_FOUND;
413f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        index = search_entry - src->entries;
414d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
41594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Not sorted, linear search
416f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (index = 0; index < src->entry_count; index++) {
417f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (src->entries[index].tag == tag) {
41894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                break;
41994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            }
42094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
421f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (index == src->entry_count) return NOT_FOUND;
42294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
423f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
424f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return get_camera_metadata_entry(src, index,
425f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry);
426f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
427f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
428f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint delete_camera_metadata_entry(camera_metadata_t *dst,
429f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index) {
430f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
431f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
432f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
433f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
434f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
435f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->count);
436f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
437f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes > 0) {
438f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Shift data buffer to overwrite deleted data
439f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *start = dst->data + entry->data.offset;
440f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *end = start + data_bytes;
441f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t length = dst->data_count - entry->data.offset - data_bytes;
442f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memmove(start, end, length);
443f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
444f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Update all entry indices to account for shift
445f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *e = dst->entries;
446f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t i;
447f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (i = 0; i < dst->entry_count; i++) {
448f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (calculate_camera_metadata_entry_data_size(
449f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->type, e->count) > 0 &&
450f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset > entry->data.offset) {
451f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                e->data.offset -= data_bytes;
452f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
453f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            ++e;
45494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
455f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->data_count -= data_bytes;
456d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
457f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    // Shift entry array
458f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memmove(entry, entry + 1,
459f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t) *
460f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            (dst->entry_count - index - 1) );
461f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    dst->entry_count -= 1;
462f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
463f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return OK;
464f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
465f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
466f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint update_camera_metadata_entry(camera_metadata_t *dst,
467f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
468f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        const void *data,
469f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t data_count,
470f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *updated_entry) {
471f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
472f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
473f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
474f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
475f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
476f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes =
477f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
478f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    data_count);
479f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t entry_bytes =
480f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
481f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    entry->count);
482f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes != entry_bytes) {
483f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // May need to shift/add to data array
484f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
485f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // No room
486f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            return ERROR;
487f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
488f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (entry_bytes != 0) {
489f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Remove old data
490f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *start = dst->data + entry->data.offset;
491f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *end = start + entry_bytes;
492f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t length = dst->data_count - entry->data.offset - entry_bytes;
493f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memmove(start, end, length);
494f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count -= entry_bytes;
495f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
496f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Update all entry indices to account for shift
497f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *e = dst->entries;
498f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t i;
499f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            for (i = 0; i < dst->entry_count; i++) {
500f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                if (calculate_camera_metadata_entry_data_size(
501f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->type, e->count) > 0 &&
502f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->data.offset > entry->data.offset) {
503f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset -= entry_bytes;
504f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                }
505f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                ++e;
506f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
507f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
508f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
509f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (data_bytes != 0) {
510f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Append new data
511f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->data.offset = dst->data_count;
512f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
513f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memcpy(dst->data + entry->data.offset, data, data_bytes);
514f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count += data_bytes;
515f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
516f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (data_bytes != 0) {
517f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // data size unchanged, reuse same data location
518f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
519f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
520f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
521f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes == 0) {
522f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Data fits into entry
523f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(entry->data.value, data,
524f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                data_count * camera_metadata_type_size[entry->type]);
525f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
526f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
527f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = data_count;
528f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
529f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (updated_entry != NULL) {
530f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        get_camera_metadata_entry(dst,
531f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                index,
532f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                updated_entry);
533f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
534f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
535d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
536d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
537d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
53898d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvalaint set_camera_metadata_user_pointer(camera_metadata_t *dst, void* user) {
53998d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    if (dst == NULL) return ERROR;
54098d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    dst->user = user;
54198d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    return OK;
54298d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala}
54398d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala
54498d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvalaint get_camera_metadata_user_pointer(camera_metadata_t *dst, void** user) {
54598d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    if (dst == NULL) return ERROR;
54698d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    *user = dst->user;
54798d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    return OK;
54898d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala}
54998d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala
550d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalastatic const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
551d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
552d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_section_name(uint32_t tag) {
553d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
554d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
55594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_section_name(
55694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
55794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
558d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
559d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT) {
560d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return NULL;
561d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
562d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return camera_metadata_section_names[tag_section];
563d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
564d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
565d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_tag_name(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_name(
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 NULL;
575d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
576d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
577d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_name;
578d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
579d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
580d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_tag_type(uint32_t tag) {
581d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
582d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
58394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_tag_type(
58494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
58594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
586d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
587d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT ||
588d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag >= camera_metadata_section_bounds[tag_section][1] ) {
589d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return -1;
590d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
591d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
592d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_type;
593d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
594d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
595d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
596d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    vendor_tag_ops = query_ops;
597d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
598d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
599d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
6001d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr, int type, int count,
6011d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int indentation);
602d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
60394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalavoid dump_camera_metadata(const camera_metadata_t *metadata,
60494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int fd,
60594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int verbosity) {
6061d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala    dump_indented_camera_metadata(metadata, fd, verbosity, 0);
6071d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala}
6081d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala
6091d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalavoid dump_indented_camera_metadata(const camera_metadata_t *metadata,
6101d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int fd,
6111d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int verbosity,
6121d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int indentation) {
613d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) {
61494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Metadata is null.", __FUNCTION__);
615d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return;
616d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
617d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    unsigned int i;
61894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd,
6191d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            "%*sDumping camera metadata array. %d / %d entries, "
6201d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            "%d / %d bytes of extra data.\n", indentation, "",
6211d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            metadata->entry_count, metadata->entry_capacity,
6221d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            metadata->data_count, metadata->data_capacity);
6231d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala    fdprintf(fd, "%*sVersion: %d, Flags: %08x\n",
6241d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            indentation + 2, "",
62594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            metadata->version, metadata->flags);
626d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (i=0; i < metadata->entry_count; i++) {
627f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *entry = metadata->entries + i;
628d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
629d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *tag_name, *tag_section;
630d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_section = get_camera_metadata_section_name(entry->tag);
631d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_section == NULL) {
632d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_section = "unknownSection";
633d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
634d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_name = get_camera_metadata_tag_name(entry->tag);
635d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_name == NULL) {
636d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_name = "unknownTag";
637d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
638d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *type_name;
639d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) {
640d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = "unknown";
641d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
642d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = camera_metadata_type_names[entry->type];
643d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
6441d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        fdprintf(fd, "%*s%s.%s (%05x): %s[%d]\n",
6451d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala             indentation + 2, "",
646d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_section,
647d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_name,
648d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->tag,
649d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             type_name,
650d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->count);
651d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
652d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 1) continue;
653d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
654d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) continue;
655d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
656d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t type_size = camera_metadata_type_size[entry->type];
657d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t *data_ptr;
658d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if ( type_size * entry->count > 4 ) {
659d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if (entry->data.offset >= metadata->data_count) {
66094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                ALOGE("%s: Malformed entry data offset: %d (max %d)",
66194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        __FUNCTION__,
66294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        entry->data.offset,
66394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        metadata->data_count);
664d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                continue;
665d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
666d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = metadata->data + entry->data.offset;
667d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
668d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = entry->data.value;
669d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
670d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        int count = entry->count;
671d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 2 && count > 16) count = 16;
672d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
6731d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        print_data(fd, data_ptr, entry->type, count, indentation);
674d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
675d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
676d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
6771d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr,
6781d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int type, int count, int indentation) {
679d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    static int values_per_line[NUM_TYPES] = {
680d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_BYTE]     = 16,
681d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT32]    = 4,
682d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_FLOAT]    = 8,
683d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT64]    = 2,
684d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_DOUBLE]   = 4,
685d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_RATIONAL] = 2,
686d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    };
687d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t type_size = camera_metadata_type_size[type];
688d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
689d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int lines = count / values_per_line[type];
690d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (count % values_per_line[type] != 0) lines++;
691d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
692d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int index = 0;
693d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int j, k;
694d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (j = 0; j < lines; j++) {
6951d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        fdprintf(fd, "%*s[", indentation + 4, "");
696d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (k = 0;
697d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k < values_per_line[type] && count > 0;
698d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k++, count--, index += type_size) {
699d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
700d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            switch (type) {
701d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_BYTE:
70294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%hhu ",
703d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(data_ptr + index));
704d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
705d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT32:
70694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%d ",
707d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int32_t*)(data_ptr + index));
708d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
709d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_FLOAT:
71094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
711d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
712d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
713d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT64:
71494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%lld ",
715d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int64_t*)(data_ptr + index));
716d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
717d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_DOUBLE:
71894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
719d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
720d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
721d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_RATIONAL: {
722d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t numerator = *(int32_t*)(data_ptr + index);
723d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t denominator = *(int32_t*)(data_ptr + index + 4);
72494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "(%d / %d) ",
725d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            numerator, denominator);
726d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
727d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                }
728d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                default:
72994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "??? ");
730d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
731d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
73294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, "]\n");
733d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
734d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
735