camera_metadata.c revision 2f4aca6526bbbaa9069f2683cdc60c0453a22055
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) {
1262f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala    if (entry_capacity == 0) return NULL;
1272f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala
128d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
129d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                                          data_capacity);
130d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    void *buffer = malloc(memory_needed);
131d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return place_camera_metadata(buffer, memory_needed,
132d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                 entry_capacity,
133d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                 data_capacity);
134d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
135d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
136d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t *place_camera_metadata(void *dst,
137d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t dst_size,
138d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t entry_capacity,
139d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                         size_t data_capacity) {
140d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return NULL;
141d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (entry_capacity == 0) return NULL;
142d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
143d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
144d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                                          data_capacity);
145d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (memory_needed > dst_size) return NULL;
146d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
147d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    camera_metadata_t *metadata = (camera_metadata_t*)dst;
14894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->version = CURRENT_METADATA_VERSION;
14994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->flags = 0;
150d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_count = 0;
151d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_capacity = entry_capacity;
152f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    metadata->entries = (camera_metadata_buffer_entry_t*)(metadata + 1);
153d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_count = 0;
154d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_capacity = data_capacity;
155d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->size = memory_needed;
156d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata->data_capacity != 0) {
157d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        metadata->data =
158d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                (uint8_t*)(metadata->entries + metadata->entry_capacity);
159d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
160d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        metadata->data = NULL;
161d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
16298d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    metadata->user = NULL;
163d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
164d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata;
165d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
166d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalavoid free_camera_metadata(camera_metadata_t *metadata) {
167d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    free(metadata);
168d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
169d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
170d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_size(size_t entry_count,
171d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                      size_t data_count) {
172d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = sizeof(camera_metadata_t);
173f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
174d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memory_needed += sizeof(uint8_t[data_count]);
175d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return memory_needed;
176d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
177d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
178d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_size(const camera_metadata_t *metadata) {
179d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) return ERROR;
180d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
181d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->size;
182d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
183d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
184d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
185d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) return ERROR;
186d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
187d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    ptrdiff_t reserved_size = metadata->size -
188d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_size(metadata->entry_capacity,
189d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                           metadata->data_capacity);
190d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
191d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return calculate_camera_metadata_size(metadata->entry_count,
192d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                          metadata->data_count) + reserved_size;
193d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
194d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
195d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
196d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->entry_count;
197d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
198d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
199d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
200d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->entry_capacity;
201d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
202d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
203d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
204d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->data_count;
205d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
206d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
207d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
208d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata->data_capacity;
209d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
210d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
211d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalacamera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
212d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const camera_metadata_t *src) {
213d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t memory_needed = get_camera_metadata_compact_size(src);
214d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
215d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return NULL;
216d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst_size < memory_needed) return NULL;
217d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
218d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    // If copying a newer version of the structure, there may be additional
219d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    // header fields we don't know about but need to copy
220d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    ptrdiff_t reserved_size = src->size -
221d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_size(src->entry_capacity,
222d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                                           src->data_capacity);
223d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
224d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    camera_metadata_t *metadata = (camera_metadata_t*)dst;
22594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->version = CURRENT_METADATA_VERSION;
22694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    metadata->flags = src->flags;
227d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_count = src->entry_count;
228d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->entry_capacity = src->entry_count;
229f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    metadata->entries = (camera_metadata_buffer_entry_t*)
230d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             ((uint8_t *)(metadata + 1) + reserved_size);
231d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_count = src->data_count;
232d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data_capacity = src->data_count;
233d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->data = (uint8_t *)(metadata->entries + metadata->entry_capacity);
234d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    metadata->size = memory_needed;
235d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
236d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (reserved_size > 0) {
237d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(metadata->reserved, src->reserved, reserved_size);
238d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
239d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(metadata->entries, src->entries,
240f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
241d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(metadata->data, src->data,
242d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            sizeof(uint8_t[metadata->data_count]));
24398d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    metadata->user = NULL;
244d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
245d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return metadata;
246d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
247d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
248d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint append_camera_metadata(camera_metadata_t *dst,
249d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const camera_metadata_t *src) {
250d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL || src == NULL ) return ERROR;
251d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
252d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
253d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
254d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
255d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(dst->entries + dst->entry_count, src->entries,
256f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
257d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    memcpy(dst->data + dst->data_count, src->data,
258d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            sizeof(uint8_t[src->data_count]));
259d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->data_count != 0) {
260d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        unsigned int i;
261d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (i = dst->entry_count;
262d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             i < dst->entry_count + src->entry_count;
263d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             i++) {
264f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *entry = dst->entries + i;
265d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) {
266d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                entry->data.offset += dst->data_count;
267d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
268d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
269d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
270f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst->entry_count == 0) {
271f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Appending onto empty buffer, keep sorted state
272f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->flags |= src->flags & FLAG_SORTED;
273f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (src->entry_count != 0) {
274f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Both src, dst are nonempty, cannot assume sort remains
275f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->flags &= ~FLAG_SORTED;
276f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
277f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Src is empty, keep dst sorted state
278f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
279d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count += src->entry_count;
280d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->data_count += src->data_count;
281d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
282d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
283d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
284d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
2852f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvalacamera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
286fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    int res;
2872f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala    if (src == NULL) return NULL;
288fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    camera_metadata_t *clone = allocate_camera_metadata(
289fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        get_camera_metadata_entry_count(src),
290fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        get_camera_metadata_data_count(src));
291fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    if (clone != NULL) {
292fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        res = append_camera_metadata(clone, src);
293fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        if (res != OK) {
294fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala            free_camera_metadata(clone);
295fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala            clone = NULL;
296fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala        }
297fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    }
298fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala    return clone;
299fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala}
300fd2588282491637c61ba828eeb69c9486d8aaeabEino-Ville Talvala
301d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalasize_t calculate_camera_metadata_entry_data_size(uint8_t type,
302d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
303d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type >= NUM_TYPES) return 0;
304d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes = data_count *
305d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            camera_metadata_type_size[type];
306d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return data_bytes <= 4 ? 0 : data_bytes;
307d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
308d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
30994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int add_camera_metadata_entry_raw(camera_metadata_t *dst,
310d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
311d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t  type,
312d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
313d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
314d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
315d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst == NULL) return ERROR;
316d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (dst->entry_count == dst->entry_capacity) return ERROR;
317d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data == NULL) return ERROR;
318d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
319d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t data_bytes =
320d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            calculate_camera_metadata_entry_data_size(type, data_count);
321d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
322f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count;
323d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->tag = tag;
324d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->type = type;
325d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    entry->count = data_count;
326d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
327d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (data_bytes == 0) {
328d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(entry->data.value, data,
329d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                data_count * camera_metadata_type_size[type] );
330d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
331d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        entry->data.offset = dst->data_count;
332d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
333d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        dst->data_count += data_bytes;
334d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
335d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    dst->entry_count++;
33694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags &= ~FLAG_SORTED;
337d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
338d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
339d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
340d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint add_camera_metadata_entry(camera_metadata_t *dst,
341d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint32_t tag,
342d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const void *data,
343d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t data_count) {
344d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
345d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int type = get_camera_metadata_tag_type(tag);
346d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (type == -1) {
34794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
348d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return ERROR;
349d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
350d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
351d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return add_camera_metadata_entry_raw(dst,
352d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag,
353d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type,
354d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data,
355d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_count);
356d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
357d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
35894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalastatic int compare_entry_tags(const void *p1, const void *p2) {
359f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
360f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
36194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return  tag1 < tag2 ? -1 :
36294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag1 == tag2 ? 0 :
36394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            1;
36494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
36594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
36694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint sort_camera_metadata(camera_metadata_t *dst) {
36794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst == NULL) return ERROR;
36894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (dst->flags & FLAG_SORTED) return OK;
36994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
37094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    qsort(dst->entries, dst->entry_count,
371f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t),
37294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            compare_entry_tags);
37394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    dst->flags |= FLAG_SORTED;
37494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
37594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
37694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
37794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
378d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_entry(camera_metadata_t *src,
379f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
380f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
381f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (src == NULL || entry == NULL) return ERROR;
382d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (index >= src->entry_count) return ERROR;
383d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
384f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *buffer_entry = src->entries + index;
385d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
386f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->index = index;
387f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->tag = buffer_entry->tag;
388f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->type = buffer_entry->type;
389f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = buffer_entry->count;
390f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (buffer_entry->count *
391f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_type_size[buffer_entry->type] > 4) {
392f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = src->data + buffer_entry->data.offset;
393f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else {
394f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        entry->data.u8 = buffer_entry->data.value;
39594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
39694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    return OK;
39794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala}
39894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
39994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalaint find_camera_metadata_entry(camera_metadata_t *src,
40094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        uint32_t tag,
401f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *entry) {
40294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src == NULL) return ERROR;
40394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala
404f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    uint32_t index;
40594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    if (src->flags & FLAG_SORTED) {
40694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Sorted entries, do a binary search
407f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *search_entry = NULL;
408f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t key;
40994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        key.tag = tag;
410f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        search_entry = bsearch(&key,
41194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entries,
41294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                src->entry_count,
413f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                sizeof(camera_metadata_buffer_entry_t),
41494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                compare_entry_tags);
415f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (search_entry == NULL) return NOT_FOUND;
416f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        index = search_entry - src->entries;
417d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    } else {
41894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        // Not sorted, linear search
419f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (index = 0; index < src->entry_count; index++) {
420f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (src->entries[index].tag == tag) {
42194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                break;
42294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            }
42394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
424f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (index == src->entry_count) return NOT_FOUND;
42594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    }
426f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
427f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return get_camera_metadata_entry(src, index,
428f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry);
429f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
430f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
4312f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvalaint find_camera_metadata_ro_entry(const camera_metadata_t *src,
4322f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala        uint32_t tag,
4332f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala        camera_metadata_ro_entry_t *entry) {
4342f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala    return find_camera_metadata_entry((camera_metadata_t*)src, tag,
4352f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala            (camera_metadata_entry_t*)entry);
4362f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala}
4372f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala
4382f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala
439f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint delete_camera_metadata_entry(camera_metadata_t *dst,
440f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index) {
441f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
442f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
443f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
444f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
445f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
446f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->count);
447f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
448f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes > 0) {
449f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Shift data buffer to overwrite deleted data
450f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *start = dst->data + entry->data.offset;
451f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        uint8_t *end = start + data_bytes;
452f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t length = dst->data_count - entry->data.offset - data_bytes;
453f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memmove(start, end, length);
454f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
455f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Update all entry indices to account for shift
456f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *e = dst->entries;
457f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t i;
458f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        for (i = 0; i < dst->entry_count; i++) {
459f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            if (calculate_camera_metadata_entry_data_size(
460f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->type, e->count) > 0 &&
461f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset > entry->data.offset) {
462f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                e->data.offset -= data_bytes;
463f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
464f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            ++e;
46594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        }
466f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        dst->data_count -= data_bytes;
467d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
468f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    // Shift entry array
469f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    memmove(entry, entry + 1,
470f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            sizeof(camera_metadata_buffer_entry_t) *
471f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            (dst->entry_count - index - 1) );
472f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    dst->entry_count -= 1;
473f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
474f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    return OK;
475f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala}
476f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
477f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvalaint update_camera_metadata_entry(camera_metadata_t *dst,
478f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t index,
479f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        const void *data,
480f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        size_t data_count,
481f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_entry_t *updated_entry) {
482f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (dst == NULL) return ERROR;
483f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (index >= dst->entry_count) return ERROR;
484f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
485f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    camera_metadata_buffer_entry_t *entry = dst->entries + index;
486f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
487f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t data_bytes =
488f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
489f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    data_count);
490f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    size_t entry_bytes =
491f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            calculate_camera_metadata_entry_data_size(entry->type,
492f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    entry->count);
493f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes != entry_bytes) {
494f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // May need to shift/add to data array
495f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
496f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // No room
497f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            return ERROR;
498f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
499f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (entry_bytes != 0) {
500f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Remove old data
501f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *start = dst->data + entry->data.offset;
502f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            uint8_t *end = start + entry_bytes;
503f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t length = dst->data_count - entry->data.offset - entry_bytes;
504f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memmove(start, end, length);
505f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count -= entry_bytes;
506f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
507f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Update all entry indices to account for shift
508f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            camera_metadata_buffer_entry_t *e = dst->entries;
509f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            size_t i;
510f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            for (i = 0; i < dst->entry_count; i++) {
511f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                if (calculate_camera_metadata_entry_data_size(
512f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->type, e->count) > 0 &&
513f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                        e->data.offset > entry->data.offset) {
514f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                    e->data.offset -= entry_bytes;
515f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                }
516f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                ++e;
517f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            }
518f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
519f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
520f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        if (data_bytes != 0) {
521f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            // Append new data
522f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            entry->data.offset = dst->data_count;
523f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
524f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            memcpy(dst->data + entry->data.offset, data, data_bytes);
525f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala            dst->data_count += data_bytes;
526f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        }
527f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    } else if (data_bytes != 0) {
528f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // data size unchanged, reuse same data location
529f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(dst->data + entry->data.offset, data, data_bytes);
530f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
531f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
532f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (data_bytes == 0) {
533f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        // Data fits into entry
534f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        memcpy(entry->data.value, data,
535f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                data_count * camera_metadata_type_size[entry->type]);
536f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
537f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
538f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    entry->count = data_count;
539f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
540f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    if (updated_entry != NULL) {
541f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        get_camera_metadata_entry(dst,
542f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                index,
543f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala                updated_entry);
544f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala    }
545f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala
546d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
547d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
548d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
54998d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvalaint set_camera_metadata_user_pointer(camera_metadata_t *dst, void* user) {
55098d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    if (dst == NULL) return ERROR;
55198d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    dst->user = user;
55298d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    return OK;
55398d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala}
55498d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala
55598d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvalaint get_camera_metadata_user_pointer(camera_metadata_t *dst, void** user) {
55698d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    if (dst == NULL) return ERROR;
55798d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    *user = dst->user;
55898d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala    return OK;
55998d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala}
56098d02fd0be8cd09479262959a542dd2620bf6074Eino-Ville Talvala
561d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalastatic const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
562d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
563d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_section_name(uint32_t tag) {
564d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
565d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
56694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_section_name(
56794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
56894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
569d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
570d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT) {
571d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return NULL;
572d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
573d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return camera_metadata_section_names[tag_section];
574d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
575d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
576d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaconst char *get_camera_metadata_tag_name(uint32_t tag) {
577d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
578d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
57994c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_tag_name(
58094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
58194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
582d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
583d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT ||
584d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag >= camera_metadata_section_bounds[tag_section][1] ) {
585d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return NULL;
586d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
587d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
588d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_name;
589d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
590d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
591d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint get_camera_metadata_tag_type(uint32_t tag) {
592d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_section = tag >> 16;
593d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
59494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        return vendor_tag_ops->get_camera_vendor_tag_type(
59594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            vendor_tag_ops,
59694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            tag);
597d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
598d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (tag_section >= ANDROID_SECTION_COUNT ||
599d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag >= camera_metadata_section_bounds[tag_section][1] ) {
600d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return -1;
601d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
602d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    uint32_t tag_index = tag & 0xFFFF;
603d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return tag_info[tag_section][tag_index].tag_type;
604d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
605d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
606d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvalaint set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
607d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    vendor_tag_ops = query_ops;
608d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    return OK;
609d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
610d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
6111d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr, int type, int count,
6121d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int indentation);
613d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
61494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvalavoid dump_camera_metadata(const camera_metadata_t *metadata,
61594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int fd,
61694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        int verbosity) {
6171d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala    dump_indented_camera_metadata(metadata, fd, verbosity, 0);
6181d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala}
6191d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala
6201d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalavoid dump_indented_camera_metadata(const camera_metadata_t *metadata,
6211d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int fd,
6221d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int verbosity,
6231d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int indentation) {
624d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (metadata == NULL) {
6252f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala        fdprintf(fd, "%*sDumping camera metadata array: Not allocated",
6262f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala                indentation, "");
627d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        return;
628d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
629d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    unsigned int i;
63094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala    fdprintf(fd,
6312f4aca6526bbbaa9069f2683cdc60c0453a22055Eino-Ville Talvala            "%*sDumping camera metadata array: %d / %d entries, "
6321d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            "%d / %d bytes of extra data.\n", indentation, "",
6331d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            metadata->entry_count, metadata->entry_capacity,
6341d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            metadata->data_count, metadata->data_capacity);
6351d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala    fdprintf(fd, "%*sVersion: %d, Flags: %08x\n",
6361d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala            indentation + 2, "",
63794c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala            metadata->version, metadata->flags);
638d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (i=0; i < metadata->entry_count; i++) {
639f5fb8a5516876c5a48cc44b4f1c99504e0b9f245Eino-Ville Talvala        camera_metadata_buffer_entry_t *entry = metadata->entries + i;
640d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
641d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *tag_name, *tag_section;
642d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_section = get_camera_metadata_section_name(entry->tag);
643d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_section == NULL) {
644d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_section = "unknownSection";
645d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
646d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        tag_name = get_camera_metadata_tag_name(entry->tag);
647d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (tag_name == NULL) {
648d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            tag_name = "unknownTag";
649d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
650d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        const char *type_name;
651d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) {
652d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = "unknown";
653d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
654d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            type_name = camera_metadata_type_names[entry->type];
655d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
6561d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        fdprintf(fd, "%*s%s.%s (%05x): %s[%d]\n",
6571d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala             indentation + 2, "",
658d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_section,
659d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             tag_name,
660d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->tag,
661d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             type_name,
662d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             entry->count);
663d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
664d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 1) continue;
665d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
666d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (entry->type >= NUM_TYPES) continue;
667d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
668d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        size_t type_size = camera_metadata_type_size[entry->type];
669d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        uint8_t *data_ptr;
670d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if ( type_size * entry->count > 4 ) {
671d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            if (entry->data.offset >= metadata->data_count) {
67294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                ALOGE("%s: Malformed entry data offset: %d (max %d)",
67394c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        __FUNCTION__,
67494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        entry->data.offset,
67594c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                        metadata->data_count);
676d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                continue;
677d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
678d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = metadata->data + entry->data.offset;
679d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        } else {
680d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            data_ptr = entry->data.value;
681d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
682d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        int count = entry->count;
683d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        if (verbosity < 2 && count > 16) count = 16;
684d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
6851d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        print_data(fd, data_ptr, entry->type, count, indentation);
686d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
687d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
688d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
6891d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvalastatic void print_data(int fd, const uint8_t *data_ptr,
6901d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        int type, int count, int indentation) {
691d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    static int values_per_line[NUM_TYPES] = {
692d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_BYTE]     = 16,
693d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT32]    = 4,
694d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_FLOAT]    = 8,
695d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_INT64]    = 2,
696d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_DOUBLE]   = 4,
697d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        [TYPE_RATIONAL] = 2,
698d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    };
699d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    size_t type_size = camera_metadata_type_size[type];
700d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
701d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int lines = count / values_per_line[type];
702d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    if (count % values_per_line[type] != 0) lines++;
703d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
704d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int index = 0;
705d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    int j, k;
706d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    for (j = 0; j < lines; j++) {
7071d27e5b8a575620bb64406289c7c229662de92caEino-Ville Talvala        fdprintf(fd, "%*s[", indentation + 4, "");
708d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        for (k = 0;
709d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k < values_per_line[type] && count > 0;
710d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala             k++, count--, index += type_size) {
711d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala
712d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            switch (type) {
713d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_BYTE:
71494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%hhu ",
715d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(data_ptr + index));
716d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
717d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT32:
71894c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%d ",
719d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int32_t*)(data_ptr + index));
720d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
721d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_FLOAT:
72294c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
723d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
724d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
725d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_INT64:
72694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%lld ",
727d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(int64_t*)(data_ptr + index));
728d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
729d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_DOUBLE:
73094c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "%0.2f ",
731d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            *(float*)(data_ptr + index));
732d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
733d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                case TYPE_RATIONAL: {
734d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t numerator = *(int32_t*)(data_ptr + index);
735d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    int32_t denominator = *(int32_t*)(data_ptr + index + 4);
73694c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "(%d / %d) ",
737d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                            numerator, denominator);
738d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                    break;
739d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                }
740d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala                default:
74194c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala                    fdprintf(fd, "??? ");
742d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala            }
743d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala        }
74494c1901a96c268f55012809f8261f2ec89c16deaEino-Ville Talvala        fdprintf(fd, "]\n");
745d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala    }
746d8afb4d1a4245b2a9d722cbb358a4d6febed89cfEino-Ville Talvala}
747