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