@@ -19,6 +19,7 @@
#include <libcamera/base/signal.h>
#include <libcamera/controls.h>
+#include <libcamera/orientation.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
#include <libcamera/transform.h>
@@ -67,6 +68,7 @@ public:
std::size_t size() const;
Transform transform;
+ Orientation orientation;
protected:
CameraConfiguration();
@@ -12,6 +12,7 @@ libcamera_public_headers = files([
'framebuffer_allocator.h',
'geometry.h',
'logging.h',
+ 'orientation.h',
'pixel_format.h',
'request.h',
'stream.h',
new file mode 100644
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2023, Ideas On Board Oy
+ *
+ * orientation.h - Image orientation
+ */
+
+#pragma once
+
+#include <iostream>
+
+namespace libcamera {
+
+enum class Orientation {
+ /* EXIF tag 274 starts from '1' */
+ rotate0 = 1,
+ rotate0Flip,
+ rotate180,
+ rotate180Flip,
+ rotate90Flip,
+ rotate270,
+ rotate270Flip,
+ rotate90,
+};
+
+std::ostream &operator<<(std::ostream &out, const Orientation &orientation);
+
+} /* namespace libcamera */
@@ -160,7 +160,8 @@ LOG_DECLARE_CATEGORY(Camera)
* \brief Create an empty camera configuration
*/
CameraConfiguration::CameraConfiguration()
- : transform(Transform::Identity), config_({})
+ : transform(Transform::Identity), orientation(Orientation::rotate0),
+ config_({})
{
}
@@ -404,6 +405,21 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
* may adjust this field at its discretion if the selection is not supported.
*/
+/**
+ * \var CameraConfiguration::orientation
+ * \brief The desired orientation of the images produced by the camera
+ *
+ * The orientation field is a user-specified 2D plane transformation that
+ * specifies how the application wants the camera images to be rotated in
+ * the memory buffers.
+ *
+ * If the application requested orientation cannot be obtained the validate()
+ * function will Adjust this field to the actual orientation of the images
+ * as produced by the camera pipeline.
+ *
+ * By default the orientation field is set to Orientation::rotate0.
+ */
+
/**
* \var CameraConfiguration::config_
* \brief The vector of stream configurations
@@ -34,6 +34,7 @@ libcamera_sources = files([
'mapped_framebuffer.cpp',
'media_device.cpp',
'media_object.cpp',
+ 'orientation.cpp',
'pipeline_handler.cpp',
'pixel_format.cpp',
'process.cpp',
new file mode 100644
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2023, Ideas On Board Oy
+ *
+ * orientation.cpp - Image orientation
+ */
+
+#include <libcamera/orientation.h>
+
+#include <array>
+#include <string>
+
+/**
+ * \file libcamera/orientation.h
+ * \brief Image orientation definition
+ */
+
+namespace libcamera {
+
+/**
+ * \enum Orientation
+ * \brief The image orientation in a memory buffer
+ *
+ * The Orientation enumeration describes the orientation of the images
+ * produced by the camera pipeline as they get received by the application
+ * inside memory buffers.
+ *
+ * All the possible 2D plane transformations of an image are expressed as the
+ * combination of two basic operations:
+ *
+ * 'a': rotate the image 90 degrees clockwise
+ * 'b': flip the image horizontally (mirroring)
+ *
+ * plus an identity operator 'e'.
+ *
+ * The composition of operations 'a' and 'b' according to the canonical function
+ * composition notion 'b * a' (where 'a' is applied first, then 'b' is applied
+ * next) gives origin to a symmetric group of order 8, or dihedral group.
+ *
+ * See https://en.wikipedia.org/wiki/Dihedral_group#/media/File:Dih4_cycle_graph.svg
+ * as an example of the 2D plane transformation and how they originate from
+ * the composition of the 'a' and 'b' operations.
+ *
+ * The image orientation expressed using the Orientation enumeration can be
+ * then inferred by applying a multiple of a 90 degrees rotation from the origin
+ * and then applying any horizontal mirroring to a base image assume to be
+ * naturally oriented (no rotation and no mirroring applied).
+ *
+ * The enumeration numerical values follow the ones defined by the EXIF
+ * Specification version 2.32, Tag 274 "Orientation", while the names of the
+ * enumerated values report the rotation and mirroring operations performed.
+ *
+ * In example Orientation::rotate90Flip describes the image transformation
+ * obtained by rotating 90 degrees clockwise first and then applying an
+ * horizontal mirroring.
+ */
+
+/**
+ * \brief Prints human-friendly names for Orientation items
+ * \param[in] out The output stream
+ * \param[in] orientation The Orientation item
+ * \return The output stream \a out
+ */
+std::ostream &operator<<(std::ostream &out, const Orientation &orientation)
+{
+ constexpr std::array<const char *, 9> orientationNames = {
+ "", /* Orientation starts counting from 1. */
+ "rotate0", "rotate0Flip",
+ "rotate180", "rotate180Flip",
+ "rotate90Flip", "rotate270",
+ "rotate270Flip", "rotate90",
+ };
+
+ out << orientationNames[static_cast<unsigned int>(orientation)];
+ return out;
+}
+
+} /* namespace libcamera */