OSDN Git Service

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