From patchwork Mon Jul 24 07:10:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18864 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 31BE9BDC71 for ; Mon, 24 Jul 2023 07:11:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7E2DA628CC; Mon, 24 Jul 2023 09:11:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1690182683; bh=yzZAi3e2eilrv1EvD0hf800qyt3WTFM+D5evp0TGr3o=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=j4yaHqc377DBLBYtE8/jN6E8rEQ/V1OtpRdbGPP1fVpcPdSkf01fphU62hz/MFvDl 7cosJ1UjhbBT4RM071u3lk63j1zsvC9JRLXUu3sbEWYhXlhMt3oKbxw7HVRMDsvklQ QMip7rigd+ybSLVyWDvOHfUbFQ8nRcTwlgibqG1TpJh9NyhxDN9MLlAonOlGXNG72R nhslnpLFwZoWIVDnMturDKn3S2WTZdS6ite9BETwJoyi3X4YRd5wU8MeEJzDEK4Yys lqFbSjalu486uxrc8LUOnUsRxdgjssEG2cVGhDVoWWcVVk7cczBIZSpPuAGpwJLnDG QDOgD7G4OmRXw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CC00F61E25 for ; Mon, 24 Jul 2023 09:11:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="J1V6JJdt"; dkim-atps=neutral Received: from uno.localdomain (mob-5-91-20-233.net.vodafone.it [5.91.20.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1B2CF2C6; Mon, 24 Jul 2023 09:10:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1690182623; bh=yzZAi3e2eilrv1EvD0hf800qyt3WTFM+D5evp0TGr3o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J1V6JJdtwJVEPXH6i+kvl4wvzN7WWZO2gc+GoOv6G3+6Al3344FtkJhFCO2aAR6yK uVcJucI7Kq5e5IqIf3SvamBOwte0Yh8nj6+RtqHy1eY4DzNkunHpF8aYld+VMLSkvu 3DjOuqq2t1c8froMi1gQsjhbBBT/CuRr3xJY90qg= To: libcamera-devel@lists.libcamera.org Date: Mon, 24 Jul 2023 09:10:53 +0200 Message-Id: <20230724071101.5256-3-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230724071101.5256-1-jacopo.mondi@ideasonboard.com> References: <20230724071101.5256-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 02/10] libcamera: camera: Introduce Orientation X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Introduce the Orientation enumeration which describes the possible 2D transformations that can be applied to an image using two basic plane transformations. Add to the CameraConfiguration class a new member 'orientation' which is used to specify the image orientation in the memory buffers delivered to applications. The enumeration values follow the ones defined by the EXIF specification at revision 2.32, Tag 274 'orientation'. The newly introduced field is meant to replace CameraConfiguration::transform which is not removed yet not to break compilation. Signed-off-by: Jacopo Mondi Reviewed-by: David Plowman --- include/libcamera/camera.h | 2 + include/libcamera/meson.build | 1 + include/libcamera/orientation.h | 28 ++++++++++++ src/libcamera/camera.cpp | 18 +++++++- src/libcamera/meson.build | 1 + src/libcamera/orientation.cpp | 78 +++++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 include/libcamera/orientation.h create mode 100644 src/libcamera/orientation.cpp diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 004bc89455f5..6e9342773962 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -67,6 +68,7 @@ public: std::size_t size() const; Transform transform; + Orientation orientation; protected: CameraConfiguration(); diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index 408b7acf152c..a24c50d66a82 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -12,6 +12,7 @@ libcamera_public_headers = files([ 'framebuffer_allocator.h', 'geometry.h', 'logging.h', + 'orientation.h', 'pixel_format.h', 'request.h', 'stream.h', diff --git a/include/libcamera/orientation.h b/include/libcamera/orientation.h new file mode 100644 index 000000000000..63ac4aba07ce --- /dev/null +++ b/include/libcamera/orientation.h @@ -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 + +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 */ diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 0eecee766f00..d4ad4a553752 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -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 diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index b24f82965764..d0e26f6b4141 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -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', diff --git a/src/libcamera/orientation.cpp b/src/libcamera/orientation.cpp new file mode 100644 index 000000000000..f2ee14dd4182 --- /dev/null +++ b/src/libcamera/orientation.cpp @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Ideas On Board Oy + * + * orientation.cpp - Image orientation + */ + +#include + +#include +#include + +/** + * \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 orientationNames = { + "", /* Orientation starts counting from 1. */ + "rotate0", "rotate0Flip", + "rotate180", "rotate180Flip", + "rotate90Flip", "rotate270", + "rotate270Flip", "rotate90", + }; + + out << orientationNames[static_cast(orientation)]; + return out; +} + +} /* namespace libcamera */