OSDN Git Service

Camera: Actually make camera_metadata memcopyable
[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 #define _GNU_SOURCE // for fdprintf
17 #include <system/camera_metadata.h>
18 #include <cutils/log.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <errno.h>
22
23 #define OK         0
24 #define ERROR      1
25 #define NOT_FOUND -ENOENT
26
27 #define _Alignas(T) \
28     ({struct _AlignasStruct { char c; T field; };       \
29         offsetof(struct _AlignasStruct, field); })
30
31 // Align entry buffers as the compiler would
32 #define ENTRY_ALIGNMENT _Alignas(camera_metadata_buffer_entry_t)
33 // Align data buffer to largest supported data type
34 #define DATA_ALIGNMENT _Alignas(camera_metadata_rational_t)
35
36 #define ALIGN_TO(val, alignment) \
37     (((uint32_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
38
39 /**
40  * A single metadata entry, storing an array of values of a given type. If the
41  * array is no larger than 4 bytes in size, it is stored in the data.value[]
42  * array; otherwise, it can found in the parent's data array at index
43  * data.offset.
44  */
45 typedef struct camera_metadata_buffer_entry {
46     uint32_t tag;
47     size_t   count;
48     union {
49         size_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 /**
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 struct camera_metadata {
91     size_t                   size;
92     uint32_t                 version;
93     uint32_t                 flags;
94     size_t                   entry_count;
95     size_t                   entry_capacity;
96     ptrdiff_t                entries_start; // Offset from camera_metadata
97     size_t                   data_count;
98     size_t                   data_capacity;
99     ptrdiff_t                data_start; // Offset from camera_metadata
100     void                    *user; // User set pointer, not copied with buffer
101     uint8_t                  reserved[0];
102 };
103
104 /** Versioning information */
105 #define CURRENT_METADATA_VERSION 1
106
107 /** Flag definitions */
108 #define FLAG_SORTED 0x00000001
109
110 /** Tag information */
111
112 typedef struct tag_info {
113     const char *tag_name;
114     uint8_t     tag_type;
115 } tag_info_t;
116
117 #include "camera_metadata_tag_info.c"
118
119 const size_t camera_metadata_type_size[NUM_TYPES] = {
120     [TYPE_BYTE]     = sizeof(uint8_t),
121     [TYPE_INT32]    = sizeof(int32_t),
122     [TYPE_FLOAT]    = sizeof(float),
123     [TYPE_INT64]    = sizeof(int64_t),
124     [TYPE_DOUBLE]   = sizeof(double),
125     [TYPE_RATIONAL] = sizeof(camera_metadata_rational_t)
126 };
127
128 const char *camera_metadata_type_names[NUM_TYPES] = {
129     [TYPE_BYTE]     = "byte",
130     [TYPE_INT32]    = "int32",
131     [TYPE_FLOAT]    = "float",
132     [TYPE_INT64]    = "int64",
133     [TYPE_DOUBLE]   = "double",
134     [TYPE_RATIONAL] = "rational"
135 };
136
137 static camera_metadata_buffer_entry_t *get_entries(
138         const camera_metadata_t *metadata) {
139     return (camera_metadata_buffer_entry_t*)
140             ((uint8_t*)metadata + metadata->entries_start);
141 }
142
143 static uint8_t *get_data(const camera_metadata_t *metadata) {
144     return (uint8_t*)metadata + metadata->data_start;
145 }
146
147 camera_metadata_t *allocate_camera_metadata(size_t entry_capacity,
148                                             size_t data_capacity) {
149     if (entry_capacity == 0) return NULL;
150
151     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
152                                                           data_capacity);
153     void *buffer = malloc(memory_needed);
154     return place_camera_metadata(buffer, memory_needed,
155                                  entry_capacity,
156                                  data_capacity);
157 }
158
159 camera_metadata_t *place_camera_metadata(void *dst,
160                                          size_t dst_size,
161                                          size_t entry_capacity,
162                                          size_t data_capacity) {
163     if (dst == NULL) return NULL;
164     if (entry_capacity == 0) return NULL;
165
166     size_t memory_needed = calculate_camera_metadata_size(entry_capacity,
167                                                           data_capacity);
168     if (memory_needed > dst_size) return NULL;
169
170     camera_metadata_t *metadata = (camera_metadata_t*)dst;
171     metadata->version = CURRENT_METADATA_VERSION;
172     metadata->flags = 0;
173     metadata->entry_count = 0;
174     metadata->entry_capacity = entry_capacity;
175     metadata->entries_start =
176             ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT);
177     metadata->data_count = 0;
178     metadata->data_capacity = data_capacity;
179     metadata->size = memory_needed;
180     if (metadata->data_capacity != 0) {
181         size_t data_unaligned = (uint8_t*)(get_entries(metadata) +
182                 metadata->entry_capacity) - (uint8_t*)metadata;
183         metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT);
184     } else {
185         metadata->data_start = 0;
186     }
187     metadata->user = NULL;
188
189     return metadata;
190 }
191 void free_camera_metadata(camera_metadata_t *metadata) {
192     free(metadata);
193 }
194
195 size_t calculate_camera_metadata_size(size_t entry_count,
196                                       size_t data_count) {
197     size_t memory_needed = sizeof(camera_metadata_t);
198     // Start entry list at aligned boundary
199     memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT);
200     memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
201     // Start buffer list at aligned boundary
202     memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT);
203     memory_needed += sizeof(uint8_t[data_count]);
204     return memory_needed;
205 }
206
207 size_t get_camera_metadata_size(const camera_metadata_t *metadata) {
208     if (metadata == NULL) return ERROR;
209
210     return metadata->size;
211 }
212
213 size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) {
214     if (metadata == NULL) return ERROR;
215
216     return calculate_camera_metadata_size(metadata->entry_count,
217                                           metadata->data_count);
218 }
219
220 size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) {
221     return metadata->entry_count;
222 }
223
224 size_t get_camera_metadata_entry_capacity(const camera_metadata_t *metadata) {
225     return metadata->entry_capacity;
226 }
227
228 size_t get_camera_metadata_data_count(const camera_metadata_t *metadata) {
229     return metadata->data_count;
230 }
231
232 size_t get_camera_metadata_data_capacity(const camera_metadata_t *metadata) {
233     return metadata->data_capacity;
234 }
235
236 camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
237         const camera_metadata_t *src) {
238     size_t memory_needed = get_camera_metadata_compact_size(src);
239
240     if (dst == NULL) return NULL;
241     if (dst_size < memory_needed) return NULL;
242
243     camera_metadata_t *metadata =
244         place_camera_metadata(dst, dst_size, src->entry_count, src->data_count);
245
246     metadata->flags = src->flags;
247     metadata->entry_count = src->entry_count;
248     metadata->data_count = src->data_count;
249
250     memcpy(get_entries(metadata), get_entries(src),
251             sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
252     memcpy(get_data(metadata), get_data(src),
253             sizeof(uint8_t[metadata->data_count]));
254     metadata->user = NULL;
255
256     return metadata;
257 }
258
259 int append_camera_metadata(camera_metadata_t *dst,
260         const camera_metadata_t *src) {
261     if (dst == NULL || src == NULL ) return ERROR;
262
263     if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR;
264     if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
265
266     memcpy(get_entries(dst) + dst->entry_count, get_entries(src),
267             sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
268     memcpy(get_data(dst) + dst->data_count, get_data(src),
269             sizeof(uint8_t[src->data_count]));
270     if (dst->data_count != 0) {
271         camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
272         for (size_t i = 0; i < src->entry_count; i++, entry++) {
273             if ( calculate_camera_metadata_entry_data_size(entry->type,
274                             entry->count) > 0 ) {
275                 entry->data.offset += dst->data_count;
276             }
277         }
278     }
279     if (dst->entry_count == 0) {
280         // Appending onto empty buffer, keep sorted state
281         dst->flags |= src->flags & FLAG_SORTED;
282     } else if (src->entry_count != 0) {
283         // Both src, dst are nonempty, cannot assume sort remains
284         dst->flags &= ~FLAG_SORTED;
285     } else {
286         // Src is empty, keep dst sorted state
287     }
288     dst->entry_count += src->entry_count;
289     dst->data_count += src->data_count;
290
291     return OK;
292 }
293
294 camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
295     int res;
296     if (src == NULL) return NULL;
297     camera_metadata_t *clone = allocate_camera_metadata(
298         get_camera_metadata_entry_count(src),
299         get_camera_metadata_data_count(src));
300     if (clone != NULL) {
301         res = append_camera_metadata(clone, src);
302         if (res != OK) {
303             free_camera_metadata(clone);
304             clone = NULL;
305         }
306     }
307     return clone;
308 }
309
310 size_t calculate_camera_metadata_entry_data_size(uint8_t type,
311         size_t data_count) {
312     if (type >= NUM_TYPES) return 0;
313     size_t data_bytes = data_count *
314             camera_metadata_type_size[type];
315     return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT);
316 }
317
318 static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
319         uint32_t tag,
320         uint8_t  type,
321         const void *data,
322         size_t data_count) {
323
324     if (dst == NULL) return ERROR;
325     if (dst->entry_count == dst->entry_capacity) return ERROR;
326     if (data == NULL) return ERROR;
327
328     size_t data_bytes =
329             calculate_camera_metadata_entry_data_size(type, data_count);
330     if (data_bytes + dst->data_count > dst->data_capacity) return ERROR;
331
332     size_t data_payload_bytes =
333             data_count * camera_metadata_type_size[type];
334     camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count;
335     entry->tag = tag;
336     entry->type = type;
337     entry->count = data_count;
338
339     if (data_bytes == 0) {
340         memcpy(entry->data.value, data,
341                 data_payload_bytes);
342     } else {
343         entry->data.offset = dst->data_count;
344         memcpy(get_data(dst) + entry->data.offset, data,
345                 data_payload_bytes);
346         dst->data_count += data_bytes;
347     }
348     dst->entry_count++;
349     dst->flags &= ~FLAG_SORTED;
350     return OK;
351 }
352
353 int add_camera_metadata_entry(camera_metadata_t *dst,
354         uint32_t tag,
355         const void *data,
356         size_t data_count) {
357
358     int type = get_camera_metadata_tag_type(tag);
359     if (type == -1) {
360         ALOGE("%s: Unknown tag %04x.", __FUNCTION__, tag);
361         return ERROR;
362     }
363
364     return add_camera_metadata_entry_raw(dst,
365             tag,
366             type,
367             data,
368             data_count);
369 }
370
371 static int compare_entry_tags(const void *p1, const void *p2) {
372     uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
373     uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
374     return  tag1 < tag2 ? -1 :
375             tag1 == tag2 ? 0 :
376             1;
377 }
378
379 int sort_camera_metadata(camera_metadata_t *dst) {
380     if (dst == NULL) return ERROR;
381     if (dst->flags & FLAG_SORTED) return OK;
382
383     qsort(get_entries(dst), dst->entry_count,
384             sizeof(camera_metadata_buffer_entry_t),
385             compare_entry_tags);
386     dst->flags |= FLAG_SORTED;
387
388     return OK;
389 }
390
391 int get_camera_metadata_entry(camera_metadata_t *src,
392         size_t index,
393         camera_metadata_entry_t *entry) {
394     if (src == NULL || entry == NULL) return ERROR;
395     if (index >= src->entry_count) return ERROR;
396
397     camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index;
398
399     entry->index = index;
400     entry->tag = buffer_entry->tag;
401     entry->type = buffer_entry->type;
402     entry->count = buffer_entry->count;
403     if (buffer_entry->count *
404             camera_metadata_type_size[buffer_entry->type] > 4) {
405         entry->data.u8 = get_data(src) + buffer_entry->data.offset;
406     } else {
407         entry->data.u8 = buffer_entry->data.value;
408     }
409     return OK;
410 }
411
412 int find_camera_metadata_entry(camera_metadata_t *src,
413         uint32_t tag,
414         camera_metadata_entry_t *entry) {
415     if (src == NULL) return ERROR;
416
417     uint32_t index;
418     if (src->flags & FLAG_SORTED) {
419         // Sorted entries, do a binary search
420         camera_metadata_buffer_entry_t *search_entry = NULL;
421         camera_metadata_buffer_entry_t key;
422         key.tag = tag;
423         search_entry = bsearch(&key,
424                 get_entries(src),
425                 src->entry_count,
426                 sizeof(camera_metadata_buffer_entry_t),
427                 compare_entry_tags);
428         if (search_entry == NULL) return NOT_FOUND;
429         index = search_entry - get_entries(src);
430     } else {
431         // Not sorted, linear search
432         camera_metadata_buffer_entry_t *search_entry = get_entries(src);
433         for (index = 0; index < src->entry_count; index++, search_entry++) {
434             if (search_entry->tag == tag) {
435                 break;
436             }
437         }
438         if (index == src->entry_count) return NOT_FOUND;
439     }
440
441     return get_camera_metadata_entry(src, index,
442             entry);
443 }
444
445 int find_camera_metadata_ro_entry(const camera_metadata_t *src,
446         uint32_t tag,
447         camera_metadata_ro_entry_t *entry) {
448     return find_camera_metadata_entry((camera_metadata_t*)src, tag,
449             (camera_metadata_entry_t*)entry);
450 }
451
452
453 int delete_camera_metadata_entry(camera_metadata_t *dst,
454         size_t index) {
455     if (dst == NULL) return ERROR;
456     if (index >= dst->entry_count) return ERROR;
457
458     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
459     size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
460             entry->count);
461
462     if (data_bytes > 0) {
463         // Shift data buffer to overwrite deleted data
464         uint8_t *start = get_data(dst) + entry->data.offset;
465         uint8_t *end = start + data_bytes;
466         size_t length = dst->data_count - entry->data.offset - data_bytes;
467         memmove(start, end, length);
468
469         // Update all entry indices to account for shift
470         camera_metadata_buffer_entry_t *e = get_entries(dst);
471         size_t i;
472         for (i = 0; i < dst->entry_count; i++) {
473             if (calculate_camera_metadata_entry_data_size(
474                     e->type, e->count) > 0 &&
475                     e->data.offset > entry->data.offset) {
476                 e->data.offset -= data_bytes;
477             }
478             ++e;
479         }
480         dst->data_count -= data_bytes;
481     }
482     // Shift entry array
483     memmove(entry, entry + 1,
484             sizeof(camera_metadata_buffer_entry_t) *
485             (dst->entry_count - index - 1) );
486     dst->entry_count -= 1;
487
488     return OK;
489 }
490
491 int update_camera_metadata_entry(camera_metadata_t *dst,
492         size_t index,
493         const void *data,
494         size_t data_count,
495         camera_metadata_entry_t *updated_entry) {
496     if (dst == NULL) return ERROR;
497     if (index >= dst->entry_count) return ERROR;
498
499     camera_metadata_buffer_entry_t *entry = get_entries(dst) + index;
500
501     size_t data_bytes =
502             calculate_camera_metadata_entry_data_size(entry->type,
503                     data_count);
504     size_t data_payload_bytes =
505             data_count * camera_metadata_type_size[entry->type];
506
507     size_t entry_bytes =
508             calculate_camera_metadata_entry_data_size(entry->type,
509                     entry->count);
510     if (data_bytes != entry_bytes) {
511         // May need to shift/add to data array
512         if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
513             // No room
514             return ERROR;
515         }
516         if (entry_bytes != 0) {
517             // Remove old data
518             uint8_t *start = get_data(dst) + entry->data.offset;
519             uint8_t *end = start + entry_bytes;
520             size_t length = dst->data_count - entry->data.offset - entry_bytes;
521             memmove(start, end, length);
522             dst->data_count -= entry_bytes;
523
524             // Update all entry indices to account for shift
525             camera_metadata_buffer_entry_t *e = get_entries(dst);
526             size_t i;
527             for (i = 0; i < dst->entry_count; i++) {
528                 if (calculate_camera_metadata_entry_data_size(
529                         e->type, e->count) > 0 &&
530                         e->data.offset > entry->data.offset) {
531                     e->data.offset -= entry_bytes;
532                 }
533                 ++e;
534             }
535         }
536
537         if (data_bytes != 0) {
538             // Append new data
539             entry->data.offset = dst->data_count;
540
541             memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
542             dst->data_count += data_bytes;
543         }
544     } else if (data_bytes != 0) {
545         // data size unchanged, reuse same data location
546         memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes);
547     }
548
549     if (data_bytes == 0) {
550         // Data fits into entry
551         memcpy(entry->data.value, data,
552                 data_payload_bytes);
553     }
554
555     entry->count = data_count;
556
557     if (updated_entry != NULL) {
558         get_camera_metadata_entry(dst,
559                 index,
560                 updated_entry);
561     }
562
563     return OK;
564 }
565
566 int set_camera_metadata_user_pointer(camera_metadata_t *dst, void* user) {
567     if (dst == NULL) return ERROR;
568     dst->user = user;
569     return OK;
570 }
571
572 int get_camera_metadata_user_pointer(camera_metadata_t *dst, void** user) {
573     if (dst == NULL) return ERROR;
574     *user = dst->user;
575     return OK;
576 }
577
578 static const vendor_tag_query_ops_t *vendor_tag_ops = NULL;
579
580 const char *get_camera_metadata_section_name(uint32_t tag) {
581     uint32_t tag_section = tag >> 16;
582     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
583         return vendor_tag_ops->get_camera_vendor_section_name(
584             vendor_tag_ops,
585             tag);
586     }
587     if (tag_section >= ANDROID_SECTION_COUNT) {
588         return NULL;
589     }
590     return camera_metadata_section_names[tag_section];
591 }
592
593 const char *get_camera_metadata_tag_name(uint32_t tag) {
594     uint32_t tag_section = tag >> 16;
595     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
596         return vendor_tag_ops->get_camera_vendor_tag_name(
597             vendor_tag_ops,
598             tag);
599     }
600     if (tag_section >= ANDROID_SECTION_COUNT ||
601         tag >= camera_metadata_section_bounds[tag_section][1] ) {
602         return NULL;
603     }
604     uint32_t tag_index = tag & 0xFFFF;
605     return tag_info[tag_section][tag_index].tag_name;
606 }
607
608 int get_camera_metadata_tag_type(uint32_t tag) {
609     uint32_t tag_section = tag >> 16;
610     if (tag_section >= VENDOR_SECTION && vendor_tag_ops != NULL) {
611         return vendor_tag_ops->get_camera_vendor_tag_type(
612             vendor_tag_ops,
613             tag);
614     }
615     if (tag_section >= ANDROID_SECTION_COUNT ||
616             tag >= camera_metadata_section_bounds[tag_section][1] ) {
617         return -1;
618     }
619     uint32_t tag_index = tag & 0xFFFF;
620     return tag_info[tag_section][tag_index].tag_type;
621 }
622
623 int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t *query_ops) {
624     vendor_tag_ops = query_ops;
625     return OK;
626 }
627
628 static void print_data(int fd, const uint8_t *data_ptr, int type, int count,
629         int indentation);
630
631 void dump_camera_metadata(const camera_metadata_t *metadata,
632         int fd,
633         int verbosity) {
634     dump_indented_camera_metadata(metadata, fd, verbosity, 0);
635 }
636
637 void dump_indented_camera_metadata(const camera_metadata_t *metadata,
638         int fd,
639         int verbosity,
640         int indentation) {
641     if (metadata == NULL) {
642         fdprintf(fd, "%*sDumping camera metadata array: Not allocated\n",
643                 indentation, "");
644         return;
645     }
646     unsigned int i;
647     fdprintf(fd,
648             "%*sDumping camera metadata array: %d / %d entries, "
649             "%d / %d bytes of extra data.\n", indentation, "",
650             metadata->entry_count, metadata->entry_capacity,
651             metadata->data_count, metadata->data_capacity);
652     fdprintf(fd, "%*sVersion: %d, Flags: %08x\n",
653             indentation + 2, "",
654             metadata->version, metadata->flags);
655     camera_metadata_buffer_entry_t *entry = get_entries(metadata);
656     for (i=0; i < metadata->entry_count; i++, entry++) {
657
658         const char *tag_name, *tag_section;
659         tag_section = get_camera_metadata_section_name(entry->tag);
660         if (tag_section == NULL) {
661             tag_section = "unknownSection";
662         }
663         tag_name = get_camera_metadata_tag_name(entry->tag);
664         if (tag_name == NULL) {
665             tag_name = "unknownTag";
666         }
667         const char *type_name;
668         if (entry->type >= NUM_TYPES) {
669             type_name = "unknown";
670         } else {
671             type_name = camera_metadata_type_names[entry->type];
672         }
673         fdprintf(fd, "%*s%s.%s (%05x): %s[%d]\n",
674              indentation + 2, "",
675              tag_section,
676              tag_name,
677              entry->tag,
678              type_name,
679              entry->count);
680
681         if (verbosity < 1) continue;
682
683         if (entry->type >= NUM_TYPES) continue;
684
685         size_t type_size = camera_metadata_type_size[entry->type];
686         uint8_t *data_ptr;
687         if ( type_size * entry->count > 4 ) {
688             if (entry->data.offset >= metadata->data_count) {
689                 ALOGE("%s: Malformed entry data offset: %d (max %d)",
690                         __FUNCTION__,
691                         entry->data.offset,
692                         metadata->data_count);
693                 continue;
694             }
695             data_ptr = get_data(metadata) + entry->data.offset;
696         } else {
697             data_ptr = entry->data.value;
698         }
699         int count = entry->count;
700         if (verbosity < 2 && count > 16) count = 16;
701
702         print_data(fd, data_ptr, entry->type, count, indentation);
703     }
704 }
705
706 static void print_data(int fd, const uint8_t *data_ptr,
707         int type, int count, int indentation) {
708     static int values_per_line[NUM_TYPES] = {
709         [TYPE_BYTE]     = 16,
710         [TYPE_INT32]    = 4,
711         [TYPE_FLOAT]    = 8,
712         [TYPE_INT64]    = 2,
713         [TYPE_DOUBLE]   = 4,
714         [TYPE_RATIONAL] = 2,
715     };
716     size_t type_size = camera_metadata_type_size[type];
717
718     int lines = count / values_per_line[type];
719     if (count % values_per_line[type] != 0) lines++;
720
721     int index = 0;
722     int j, k;
723     for (j = 0; j < lines; j++) {
724         fdprintf(fd, "%*s[", indentation + 4, "");
725         for (k = 0;
726              k < values_per_line[type] && count > 0;
727              k++, count--, index += type_size) {
728
729             switch (type) {
730                 case TYPE_BYTE:
731                     fdprintf(fd, "%hhu ",
732                             *(data_ptr + index));
733                     break;
734                 case TYPE_INT32:
735                     fdprintf(fd, "%d ",
736                             *(int32_t*)(data_ptr + index));
737                     break;
738                 case TYPE_FLOAT:
739                     fdprintf(fd, "%0.2f ",
740                             *(float*)(data_ptr + index));
741                     break;
742                 case TYPE_INT64:
743                     fdprintf(fd, "%lld ",
744                             *(int64_t*)(data_ptr + index));
745                     break;
746                 case TYPE_DOUBLE:
747                     fdprintf(fd, "%0.2f ",
748                             *(double*)(data_ptr + index));
749                     break;
750                 case TYPE_RATIONAL: {
751                     int32_t numerator = *(int32_t*)(data_ptr + index);
752                     int32_t denominator = *(int32_t*)(data_ptr + index + 4);
753                     fdprintf(fd, "(%d / %d) ",
754                             numerator, denominator);
755                     break;
756                 }
757                 default:
758                     fdprintf(fd, "??? ");
759             }
760         }
761         fdprintf(fd, "]\n");
762     }
763 }