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