blob: 1287d2bccbc140a78c9e3ead4359e09c3e76c749 [file] [log] [blame]
/*
* Copyright 2021 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef CAMERA_INCLUDE_CROS_CAMERA_CAMERA_METADATA_UTILS_H_
#define CAMERA_INCLUDE_CROS_CAMERA_CAMERA_METADATA_UTILS_H_
#include <base/containers/span.h>
#include <base/numerics/safe_conversions.h>
#include <base/optional.h>
#include <system/camera_metadata.h>
// Utility template functions for accessing and modifying the contents of a
// camera_metadata_t object.
namespace cros {
struct Rational : public camera_metadata_rational_t {
// Members inherited from camera_metadata_rational_t:
//
// int32_t numerator;
// int32_t denominator;
float AsFloat() { return base::checked_cast<float>(numerator) / denominator; }
double AsDouble() {
return base::checked_cast<double>(numerator) / denominator;
}
};
// Gets the address of a single data element for |tag| in |metadata|. Returns
// base::nullopt if |metadata| does not store any data for |tag|.
template <typename T>
base::Optional<T*> GetMetadata(camera_metadata_t* metadata, uint32_t tag) {
camera_metadata_entry_t entry;
int ret = find_camera_metadata_entry(metadata, tag, &entry);
if (ret != 0 || entry.count == 0) {
return base::nullopt;
}
CHECK_EQ(camera_metadata_type_size[entry.type], sizeof(T));
return reinterpret_cast<T*>(entry.data.u8);
}
// Gets a read-write view of the data array of |tag| in |metadata|. Returns an
// empty base::span<T> if |metadata| does not have a data array for |tag|.
template <typename T>
base::span<T> GetMetadataAsSpan(camera_metadata_t* metadata, uint32_t tag) {
camera_metadata_entry_t entry;
int ret = find_camera_metadata_entry(metadata, tag, &entry);
if (ret != 0 || entry.count == 0) {
return base::span<T>();
}
CHECK_EQ(camera_metadata_type_size[entry.type], sizeof(T));
return {reinterpret_cast<T*>(entry.data.u8), entry.count};
}
// Gets the value of |tag| data in |metadata|. Returns base::nullopt if
// |metadata| does not store any data for |tag|.
template <typename T>
base::Optional<T> GetRoMetadata(const camera_metadata_t* metadata,
uint32_t tag) {
camera_metadata_ro_entry_t ro_entry;
int ret = find_camera_metadata_ro_entry(metadata, tag, &ro_entry);
if (ret != 0 || ro_entry.count == 0) {
return base::nullopt;
}
CHECK_EQ(camera_metadata_type_size[ro_entry.type], sizeof(T));
return *(reinterpret_cast<const T*>(ro_entry.data.u8));
}
// Gets a read-only view of the data array of |tag| in |metadata|. Returns an
// empty base::span<const T> if |metadata| does not have a data array for |tag|.
template <typename T>
base::span<const T> GetRoMetadataAsSpan(const camera_metadata_t* metadata,
uint32_t tag) {
camera_metadata_ro_entry_t ro_entry;
int ret = find_camera_metadata_ro_entry(metadata, tag, &ro_entry);
if (ret != 0 || ro_entry.count == 0) {
return base::span<const T>();
}
CHECK_EQ(camera_metadata_type_size[ro_entry.type], sizeof(T));
return {reinterpret_cast<const T*>(ro_entry.data.u8), ro_entry.count};
}
} // namespace cros
#endif // CAMERA_INCLUDE_CROS_CAMERA_CAMERA_METADATA_UTILS_H_