diff options
-rw-r--r-- | camera/src/Android.mk | 1 | ||||
-rw-r--r-- | camera/src/camera_metadata.c | 156 | ||||
-rw-r--r-- | camera/tests/camera_metadata_tests.cpp | 214 |
3 files changed, 308 insertions, 63 deletions
diff --git a/camera/src/Android.mk b/camera/src/Android.mk index 19a6f5b9..d3366182 100644 --- a/camera/src/Android.mk +++ b/camera/src/Android.mk @@ -17,6 +17,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS += \ -Wall \ -fvisibility=hidden \ + -std=c99 include $(BUILD_SHARED_LIBRARY) diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c index 0b6597df..e5c2f251 100644 --- a/camera/src/camera_metadata.c +++ b/camera/src/camera_metadata.c @@ -23,6 +23,19 @@ #define OK 0 #define ERROR 1 #define NOT_FOUND -ENOENT + +#define _Alignas(T) \ + ({struct _AlignasStruct { char c; T field; }; \ + offsetof(struct _AlignasStruct, field); }) + +// Align entry buffers as the compiler would +#define ENTRY_ALIGNMENT _Alignas(camera_metadata_buffer_entry_t) +// Align data buffer to largest supported data type +#define DATA_ALIGNMENT _Alignas(camera_metadata_data_t) + +#define ALIGN_TO(val, alignment) \ + (((uint32_t)(val) + ((alignment) - 1)) & ~((alignment) - 1)) + /** * A single metadata entry, storing an array of values of a given type. If the * array is no larger than 4 bytes in size, it is stored in the data.value[] @@ -38,7 +51,7 @@ typedef struct camera_metadata_buffer_entry { } data; uint8_t type; uint8_t reserved[3]; -} __attribute__((packed)) camera_metadata_buffer_entry_t; +} camera_metadata_buffer_entry_t; /** * A packet of metadata. This is a list of entries, each of which may point to @@ -80,14 +93,29 @@ struct camera_metadata { uint32_t flags; size_t entry_count; size_t entry_capacity; - camera_metadata_buffer_entry_t *entries; + ptrdiff_t entries_start; // Offset from camera_metadata size_t data_count; size_t data_capacity; - uint8_t *data; + ptrdiff_t data_start; // Offset from camera_metadata void *user; // User set pointer, not copied with buffer uint8_t reserved[0]; }; +/** + * A datum of metadata. This corresponds to camera_metadata_entry_t::data + * with the difference that each element is not a pointer. We need to have a + * non-pointer type description in order to figure out the largest alignment + * requirement for data (DATA_ALIGNMENT). + */ +typedef union camera_metadata_data { + uint8_t u8; + int32_t i32; + float f; + int64_t i64; + double d; + camera_metadata_rational_t r; +} camera_metadata_data_t; + /** Versioning information */ #define CURRENT_METADATA_VERSION 1 @@ -121,6 +149,16 @@ const char *camera_metadata_type_names[NUM_TYPES] = { [TYPE_RATIONAL] = "rational" }; +static camera_metadata_buffer_entry_t *get_entries( + const camera_metadata_t *metadata) { + return (camera_metadata_buffer_entry_t*) + ((uint8_t*)metadata + metadata->entries_start); +} + +static uint8_t *get_data(const camera_metadata_t *metadata) { + return (uint8_t*)metadata + metadata->data_start; +} + camera_metadata_t *allocate_camera_metadata(size_t entry_capacity, size_t data_capacity) { if (entry_capacity == 0) return NULL; @@ -149,15 +187,17 @@ camera_metadata_t *place_camera_metadata(void *dst, metadata->flags = 0; metadata->entry_count = 0; metadata->entry_capacity = entry_capacity; - metadata->entries = (camera_metadata_buffer_entry_t*)(metadata + 1); + metadata->entries_start = + ALIGN_TO(sizeof(camera_metadata_t), ENTRY_ALIGNMENT); metadata->data_count = 0; metadata->data_capacity = data_capacity; metadata->size = memory_needed; if (metadata->data_capacity != 0) { - metadata->data = - (uint8_t*)(metadata->entries + metadata->entry_capacity); + size_t data_unaligned = (uint8_t*)(get_entries(metadata) + + metadata->entry_capacity) - (uint8_t*)metadata; + metadata->data_start = ALIGN_TO(data_unaligned, DATA_ALIGNMENT); } else { - metadata->data = NULL; + metadata->data_start = 0; } metadata->user = NULL; @@ -170,7 +210,11 @@ void free_camera_metadata(camera_metadata_t *metadata) { size_t calculate_camera_metadata_size(size_t entry_count, size_t data_count) { size_t memory_needed = sizeof(camera_metadata_t); + // Start entry list at aligned boundary + memory_needed = ALIGN_TO(memory_needed, ENTRY_ALIGNMENT); memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]); + // Start buffer list at aligned boundary + memory_needed = ALIGN_TO(memory_needed, DATA_ALIGNMENT); memory_needed += sizeof(uint8_t[data_count]); return memory_needed; } @@ -184,12 +228,8 @@ size_t get_camera_metadata_size(const camera_metadata_t *metadata) { size_t get_camera_metadata_compact_size(const camera_metadata_t *metadata) { if (metadata == NULL) return ERROR; - ptrdiff_t reserved_size = metadata->size - - calculate_camera_metadata_size(metadata->entry_capacity, - metadata->data_capacity); - return calculate_camera_metadata_size(metadata->entry_count, - metadata->data_count) + reserved_size; + metadata->data_count); } size_t get_camera_metadata_entry_count(const camera_metadata_t *metadata) { @@ -215,30 +255,16 @@ camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size, if (dst == NULL) return NULL; if (dst_size < memory_needed) return NULL; - // If copying a newer version of the structure, there may be additional - // header fields we don't know about but need to copy - ptrdiff_t reserved_size = src->size - - calculate_camera_metadata_size(src->entry_capacity, - src->data_capacity); + camera_metadata_t *metadata = + place_camera_metadata(dst, dst_size, src->entry_count, src->data_count); - camera_metadata_t *metadata = (camera_metadata_t*)dst; - metadata->version = CURRENT_METADATA_VERSION; metadata->flags = src->flags; metadata->entry_count = src->entry_count; - metadata->entry_capacity = src->entry_count; - metadata->entries = (camera_metadata_buffer_entry_t*) - ((uint8_t *)(metadata + 1) + reserved_size); metadata->data_count = src->data_count; - metadata->data_capacity = src->data_count; - metadata->data = (uint8_t *)(metadata->entries + metadata->entry_capacity); - metadata->size = memory_needed; - if (reserved_size > 0) { - memcpy(metadata->reserved, src->reserved, reserved_size); - } - memcpy(metadata->entries, src->entries, + memcpy(get_entries(metadata), get_entries(src), sizeof(camera_metadata_buffer_entry_t[metadata->entry_count])); - memcpy(metadata->data, src->data, + memcpy(get_data(metadata), get_data(src), sizeof(uint8_t[metadata->data_count])); metadata->user = NULL; @@ -252,17 +278,15 @@ int append_camera_metadata(camera_metadata_t *dst, if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR; if (dst->data_capacity < src->data_count + dst->data_count) return ERROR; - memcpy(dst->entries + dst->entry_count, src->entries, + memcpy(get_entries(dst) + dst->entry_count, get_entries(src), sizeof(camera_metadata_buffer_entry_t[src->entry_count])); - memcpy(dst->data + dst->data_count, src->data, + memcpy(get_data(dst) + dst->data_count, get_data(src), sizeof(uint8_t[src->data_count])); if (dst->data_count != 0) { - unsigned int i; - for (i = dst->entry_count; - i < dst->entry_count + src->entry_count; - i++) { - camera_metadata_buffer_entry_t *entry = dst->entries + i; - if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) { + camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count; + for (size_t i = 0; i < src->entry_count; i++, entry++) { + if ( calculate_camera_metadata_entry_data_size(entry->type, + entry->count) > 0 ) { entry->data.offset += dst->data_count; } } @@ -303,7 +327,7 @@ size_t calculate_camera_metadata_entry_data_size(uint8_t type, if (type >= NUM_TYPES) return 0; size_t data_bytes = data_count * camera_metadata_type_size[type]; - return data_bytes <= 4 ? 0 : data_bytes; + return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); } static int add_camera_metadata_entry_raw(camera_metadata_t *dst, @@ -318,18 +342,22 @@ static int add_camera_metadata_entry_raw(camera_metadata_t *dst, size_t data_bytes = calculate_camera_metadata_entry_data_size(type, data_count); + if (data_bytes + dst->data_count > dst->data_capacity) return ERROR; - camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count; + size_t data_payload_bytes = + data_count * camera_metadata_type_size[type]; + camera_metadata_buffer_entry_t *entry = get_entries(dst) + dst->entry_count; entry->tag = tag; entry->type = type; entry->count = data_count; if (data_bytes == 0) { memcpy(entry->data.value, data, - data_count * camera_metadata_type_size[type] ); + data_payload_bytes); } else { entry->data.offset = dst->data_count; - memcpy(dst->data + entry->data.offset, data, data_bytes); + memcpy(get_data(dst) + entry->data.offset, data, + data_payload_bytes); dst->data_count += data_bytes; } dst->entry_count++; @@ -367,7 +395,7 @@ int sort_camera_metadata(camera_metadata_t *dst) { if (dst == NULL) return ERROR; if (dst->flags & FLAG_SORTED) return OK; - qsort(dst->entries, dst->entry_count, + qsort(get_entries(dst), dst->entry_count, sizeof(camera_metadata_buffer_entry_t), compare_entry_tags); dst->flags |= FLAG_SORTED; @@ -381,7 +409,7 @@ int get_camera_metadata_entry(camera_metadata_t *src, if (src == NULL || entry == NULL) return ERROR; if (index >= src->entry_count) return ERROR; - camera_metadata_buffer_entry_t *buffer_entry = src->entries + index; + camera_metadata_buffer_entry_t *buffer_entry = get_entries(src) + index; entry->index = index; entry->tag = buffer_entry->tag; @@ -389,7 +417,7 @@ int get_camera_metadata_entry(camera_metadata_t *src, entry->count = buffer_entry->count; if (buffer_entry->count * camera_metadata_type_size[buffer_entry->type] > 4) { - entry->data.u8 = src->data + buffer_entry->data.offset; + entry->data.u8 = get_data(src) + buffer_entry->data.offset; } else { entry->data.u8 = buffer_entry->data.value; } @@ -408,16 +436,17 @@ int find_camera_metadata_entry(camera_metadata_t *src, camera_metadata_buffer_entry_t key; key.tag = tag; search_entry = bsearch(&key, - src->entries, + get_entries(src), src->entry_count, sizeof(camera_metadata_buffer_entry_t), compare_entry_tags); if (search_entry == NULL) return NOT_FOUND; - index = search_entry - src->entries; + index = search_entry - get_entries(src); } else { // Not sorted, linear search - for (index = 0; index < src->entry_count; index++) { - if (src->entries[index].tag == tag) { + camera_metadata_buffer_entry_t *search_entry = get_entries(src); + for (index = 0; index < src->entry_count; index++, search_entry++) { + if (search_entry->tag == tag) { break; } } @@ -441,19 +470,19 @@ int delete_camera_metadata_entry(camera_metadata_t *dst, if (dst == NULL) return ERROR; if (index >= dst->entry_count) return ERROR; - camera_metadata_buffer_entry_t *entry = dst->entries + index; + camera_metadata_buffer_entry_t *entry = get_entries(dst) + index; size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type, entry->count); if (data_bytes > 0) { // Shift data buffer to overwrite deleted data - uint8_t *start = dst->data + entry->data.offset; + uint8_t *start = get_data(dst) + entry->data.offset; uint8_t *end = start + data_bytes; size_t length = dst->data_count - entry->data.offset - data_bytes; memmove(start, end, length); // Update all entry indices to account for shift - camera_metadata_buffer_entry_t *e = dst->entries; + camera_metadata_buffer_entry_t *e = get_entries(dst); size_t i; for (i = 0; i < dst->entry_count; i++) { if (calculate_camera_metadata_entry_data_size( @@ -482,11 +511,14 @@ int update_camera_metadata_entry(camera_metadata_t *dst, if (dst == NULL) return ERROR; if (index >= dst->entry_count) return ERROR; - camera_metadata_buffer_entry_t *entry = dst->entries + index; + camera_metadata_buffer_entry_t *entry = get_entries(dst) + index; size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type, data_count); + size_t data_payload_bytes = + data_count * camera_metadata_type_size[entry->type]; + size_t entry_bytes = calculate_camera_metadata_entry_data_size(entry->type, entry->count); @@ -498,14 +530,14 @@ int update_camera_metadata_entry(camera_metadata_t *dst, } if (entry_bytes != 0) { // Remove old data - uint8_t *start = dst->data + entry->data.offset; + uint8_t *start = get_data(dst) + entry->data.offset; uint8_t *end = start + entry_bytes; size_t length = dst->data_count - entry->data.offset - entry_bytes; memmove(start, end, length); dst->data_count -= entry_bytes; // Update all entry indices to account for shift - camera_metadata_buffer_entry_t *e = dst->entries; + camera_metadata_buffer_entry_t *e = get_entries(dst); size_t i; for (i = 0; i < dst->entry_count; i++) { if (calculate_camera_metadata_entry_data_size( @@ -521,18 +553,18 @@ int update_camera_metadata_entry(camera_metadata_t *dst, // Append new data entry->data.offset = dst->data_count; - memcpy(dst->data + entry->data.offset, data, data_bytes); + memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes); dst->data_count += data_bytes; } } else if (data_bytes != 0) { // data size unchanged, reuse same data location - memcpy(dst->data + entry->data.offset, data, data_bytes); + memcpy(get_data(dst) + entry->data.offset, data, data_payload_bytes); } if (data_bytes == 0) { // Data fits into entry memcpy(entry->data.value, data, - data_count * camera_metadata_type_size[entry->type]); + data_payload_bytes); } entry->count = data_count; @@ -635,8 +667,8 @@ void dump_indented_camera_metadata(const camera_metadata_t *metadata, fdprintf(fd, "%*sVersion: %d, Flags: %08x\n", indentation + 2, "", metadata->version, metadata->flags); - for (i=0; i < metadata->entry_count; i++) { - camera_metadata_buffer_entry_t *entry = metadata->entries + i; + camera_metadata_buffer_entry_t *entry = get_entries(metadata); + for (i=0; i < metadata->entry_count; i++, entry++) { const char *tag_name, *tag_section; tag_section = get_camera_metadata_section_name(entry->tag); @@ -675,7 +707,7 @@ void dump_indented_camera_metadata(const camera_metadata_t *metadata, metadata->data_count); continue; } - data_ptr = metadata->data + entry->data.offset; + data_ptr = get_data(metadata) + entry->data.offset; } else { data_ptr = entry->data.value; } @@ -728,7 +760,7 @@ static void print_data(int fd, const uint8_t *data_ptr, break; case TYPE_DOUBLE: fdprintf(fd, "%0.2f ", - *(float*)(data_ptr + index)); + *(double*)(data_ptr + index)); break; case TYPE_RATIONAL: { int32_t numerator = *(int32_t*)(data_ptr + index); diff --git a/camera/tests/camera_metadata_tests.cpp b/camera/tests/camera_metadata_tests.cpp index 06c59f43..47faf426 100644 --- a/camera/tests/camera_metadata_tests.cpp +++ b/camera/tests/camera_metadata_tests.cpp @@ -32,6 +32,11 @@ #define ERROR 1 #define NOT_FOUND (-ENOENT) +#define _Alignas(T) \ + ({struct _AlignasStruct { char c; T field; }; \ + offsetof(struct _AlignasStruct, field); }) + + TEST(camera_metadata, allocate_normal) { camera_metadata_t *m = NULL; const size_t entry_capacity = 5; @@ -302,7 +307,7 @@ void add_test_metadata(camera_metadata_t *m, int entry_count) { } EXPECT_EQ(data_used, get_camera_metadata_data_count(m)); EXPECT_EQ(entries_used, get_camera_metadata_entry_count(m)); - EXPECT_GT(get_camera_metadata_data_capacity(m), + EXPECT_GE(get_camera_metadata_data_capacity(m), get_camera_metadata_data_count(m)); } @@ -354,6 +359,26 @@ TEST(camera_metadata, add_get_toomany) { free_camera_metadata(m); } +TEST(camera_metadata, add_too_much_data) { + camera_metadata_t *m = NULL; + const size_t entry_capacity = 5; + int result; + size_t data_used = entry_capacity * calculate_camera_metadata_entry_data_size( + get_camera_metadata_tag_type(ANDROID_SENSOR_EXPOSURE_TIME), 1); + m = allocate_camera_metadata(entry_capacity + 1, data_used); + + + add_test_metadata(m, entry_capacity); + + int64_t exposure_time = 12345; + result = add_camera_metadata_entry(m, + ANDROID_SENSOR_EXPOSURE_TIME, + &exposure_time, 1); + EXPECT_EQ(ERROR, result); + + free_camera_metadata(m); +} + TEST(camera_metadata, copy_metadata) { camera_metadata_t *m = NULL; const size_t entry_capacity = 50; @@ -1596,3 +1621,190 @@ TEST(camera_metadata, user_pointer) { free(buf); free_camera_metadata(m); } + +TEST(camera_metadata, memcpy) { + camera_metadata_t *m = NULL; + const size_t entry_capacity = 50; + const size_t data_capacity = 450; + + int result; + + m = allocate_camera_metadata(entry_capacity, data_capacity); + + add_test_metadata(m, 5); + + uint8_t *dst = new uint8_t[get_camera_metadata_size(m)]; + + memcpy(dst, m, get_camera_metadata_size(m)); + + camera_metadata_t *m2 = reinterpret_cast<camera_metadata_t*>(dst); + + ASSERT_EQ(get_camera_metadata_size(m), + get_camera_metadata_size(m2)); + EXPECT_EQ(get_camera_metadata_compact_size(m), + get_camera_metadata_compact_size(m2)); + ASSERT_EQ(get_camera_metadata_entry_count(m), + get_camera_metadata_entry_count(m2)); + EXPECT_EQ(get_camera_metadata_entry_capacity(m), + get_camera_metadata_entry_capacity(m2)); + EXPECT_EQ(get_camera_metadata_data_count(m), + get_camera_metadata_data_count(m2)); + EXPECT_EQ(get_camera_metadata_data_capacity(m), + get_camera_metadata_data_capacity(m2)); + + camera_metadata_entry_t e1, e2; + for (size_t i = 0; i < get_camera_metadata_entry_count(m); i++) { + result = get_camera_metadata_entry(m, i, &e1); + ASSERT_EQ(OK, result); + result = get_camera_metadata_entry(m2, i, &e2); + ASSERT_EQ(OK, result); + + EXPECT_EQ(e1.index, e2.index); + EXPECT_EQ(e1.tag, e2.tag); + ASSERT_EQ(e1.type, e2.type); + ASSERT_EQ(e1.count, e2.count); + + ASSERT_TRUE(!memcmp(e1.data.u8, e2.data.u8, + camera_metadata_type_size[e1.type] * e1.count)); + } + + // Make sure updating one metadata buffer doesn't change the other + + int64_t double_exposure_time[] = { 100, 200 }; + + result = update_camera_metadata_entry(m, 0, + double_exposure_time, + sizeof(double_exposure_time)/sizeof(int64_t), NULL); + EXPECT_EQ(OK, result); + + result = get_camera_metadata_entry(m, 0, &e1); + ASSERT_EQ(OK, result); + result = get_camera_metadata_entry(m2, 0, &e2); + ASSERT_EQ(OK, result); + + EXPECT_EQ(e1.index, e2.index); + EXPECT_EQ(e1.tag, e2.tag); + ASSERT_EQ(e1.type, e2.type); + ASSERT_EQ((size_t)2, e1.count); + ASSERT_EQ((size_t)1, e2.count); + EXPECT_EQ(100, e1.data.i64[0]); + EXPECT_EQ(200, e1.data.i64[1]); + EXPECT_EQ(100, e2.data.i64[0]); + + // And in the reverse direction as well + + double_exposure_time[0] = 300; + result = update_camera_metadata_entry(m2, 0, + double_exposure_time, + sizeof(double_exposure_time)/sizeof(int64_t), NULL); + EXPECT_EQ(OK, result); + + result = get_camera_metadata_entry(m, 0, &e1); + ASSERT_EQ(OK, result); + result = get_camera_metadata_entry(m2, 0, &e2); + ASSERT_EQ(OK, result); + + EXPECT_EQ(e1.index, e2.index); + EXPECT_EQ(e1.tag, e2.tag); + ASSERT_EQ(e1.type, e2.type); + ASSERT_EQ((size_t)2, e1.count); + ASSERT_EQ((size_t)2, e2.count); + EXPECT_EQ(100, e1.data.i64[0]); + EXPECT_EQ(200, e1.data.i64[1]); + EXPECT_EQ(300, e2.data.i64[0]); + EXPECT_EQ(200, e2.data.i64[1]); + + delete dst; + free_camera_metadata(m); +} + +TEST(camera_metadata, data_alignment) { + // Verify that when we store the data, the data aligned as we expect + camera_metadata_t *m = NULL; + const size_t entry_capacity = 50; + const size_t data_capacity = 450; + char dummy_data[data_capacity] = {0,}; + + int m_types[] = { + TYPE_BYTE, + TYPE_INT32, + TYPE_FLOAT, + TYPE_INT64, + TYPE_DOUBLE, + TYPE_RATIONAL + }; + const size_t (&m_type_sizes)[NUM_TYPES] = camera_metadata_type_size; + size_t m_type_align[] = { + _Alignas(uint8_t), // BYTE + _Alignas(int32_t), // INT32 + _Alignas(float), // FLOAT + _Alignas(int64_t), // INT64 + _Alignas(double), // DOUBLE + _Alignas(camera_metadata_rational_t), // RATIONAL + }; + /* arbitrary tags. the important thing is that their type + corresponds to m_type_sizes[i] + */ + int m_type_tags[] = { + ANDROID_REQUEST_TYPE, + ANDROID_REQUEST_ID, + ANDROID_LENS_FOCUS_DISTANCE, + ANDROID_SENSOR_EXPOSURE_TIME, + ANDROID_JPEG_GPS_COORDINATES, + ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP + }; + + /* + if the asserts fail, its because we added more types. + this means the test should be updated to include more types. + */ + ASSERT_EQ((size_t)NUM_TYPES, sizeof(m_types)/sizeof(m_types[0])); + ASSERT_EQ((size_t)NUM_TYPES, sizeof(m_type_align)/sizeof(m_type_align[0])); + ASSERT_EQ((size_t)NUM_TYPES, sizeof(m_type_tags)/sizeof(m_type_tags[0])); + + for (int m_type = 0; m_type < (int)NUM_TYPES; ++m_type) { + + ASSERT_EQ(m_types[m_type], + get_camera_metadata_tag_type(m_type_tags[m_type])); + + // misalignment possibilities are [0,type_size) for any type pointer + for (size_t i = 0; i < m_type_sizes[m_type]; ++i) { + + /* data_count = 1, we may store data in the index. + data_count = 10, we will store data separately + */ + for (int data_count = 1; data_count <= 10; data_count += 9) { + + m = allocate_camera_metadata(entry_capacity, data_capacity); + + // add dummy data to test various different padding requirements + ASSERT_EQ(OK, + add_camera_metadata_entry(m, + m_type_tags[TYPE_BYTE], + &dummy_data[0], + data_count + i)); + // insert the type we care to test + ASSERT_EQ(OK, + add_camera_metadata_entry(m, m_type_tags[m_type], + &dummy_data[0], data_count)); + + // now check the alignment for our desired type. it should be ok + camera_metadata_ro_entry_t entry = camera_metadata_ro_entry_t(); + ASSERT_EQ(OK, + find_camera_metadata_ro_entry(m, m_type_tags[m_type], + &entry)); + + void* data_ptr = (void*)entry.data.u8; + void* aligned_ptr = (void*)((uintptr_t)data_ptr & ~(m_type_align[m_type] - 1)); + EXPECT_EQ(aligned_ptr, data_ptr) << + "Wrong alignment for type " << + camera_metadata_type_names[m_type] << + " with " << (data_count + i) << " dummy bytes and " << + " data_count " << data_count << + " expected alignment was: " << m_type_align[m_type]; + + free_camera_metadata(m); + } + } + } +} |