From patchwork Fri Jul 14 14:15:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 18828 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 54AAEC32AB for ; Fri, 14 Jul 2023 14:16:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D2346628D7; Fri, 14 Jul 2023 16:16:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1689344174; bh=21h9/sAEYM75LWopORzoBDULCTVzIfbDSYtOMTm5ysY=; 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=Ssn7BKAqUYW8aA5CXiQ2tWmcnpbVSybhGMDahJRVlG66C99zxjM9W1Ht8SRAyObVN yYOzJ9L7fPwtM+NWnTch5cVcFVIDgmhppWFJiSLMfSb7d39N/Q+PuKi+8lVIH5r4iH 2/2DdsOjFGA+xkg6Gw5+nrc/N1qpkJr4+zCCDiLkhgBtlnwgHlf1hgiSGrlDetRAFy KInAwzF65ABeIEFTzl5EWiiyOnuBpEkC6myh4BXwCkHzdRXhczqOWgv+ZtfBA0yCub IPlNY1CfoKpqw2rHz8tU6WBQKfuxbqn4pLpsjiFbX8qpEZclUrmAcuV/OUexDlzaqt GJIz1cuRcZb0Q== 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 8A951628CB for ; Fri, 14 Jul 2023 16:16:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="fpAwlQBc"; dkim-atps=neutral Received: from uno.localdomain (mob-5-90-9-92.net.vodafone.it [5.90.9.92]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3EECD7F3; Fri, 14 Jul 2023 16:15:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1689344121; bh=21h9/sAEYM75LWopORzoBDULCTVzIfbDSYtOMTm5ysY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fpAwlQBcf6CxBBbnxLDtn9NuwyWo11K5vudSW1mGQ4RrK/Ml6bj6t1AWIVYD0iM53 nXExyZM9pgcq4llhuf+aPv4140klM00D6uRpUB2lxOkwGgRROtDHusQiBgqEE/gfzY HwiLoFF9miZQXuRjVwj2cIEssp2xPVCyDlnkCPlE= To: libcamera-devel@lists.libcamera.org Date: Fri, 14 Jul 2023 16:15:46 +0200 Message-Id: <20230714141549.11085-7-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230714141549.11085-1-jacopo.mondi@ideasonboard.com> References: <20230714141549.11085-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/9] libcamera: transform: Add operations with 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" Add two operations that allows to combine Transform with Orientation. - Transform operator/(Orientation1, Orientation2) allows to easily get back the Transform that needs to be applied to Orientation2 to get Orientation1 - Orientation operator*(Orientation1, Transform) allows to apply a Transform to an Orientation and obtain back the combination of the two The two operations allow application that are willing to use Transform to operate with the Orientation part of CameraConfiguration. Signed-off-by: Jacopo Mondi --- include/libcamera/transform.h | 5 ++ src/libcamera/transform.cpp | 98 +++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/include/libcamera/transform.h b/include/libcamera/transform.h index 573adf18715d..a7470c70a755 100644 --- a/include/libcamera/transform.h +++ b/include/libcamera/transform.h @@ -74,6 +74,11 @@ Transform transformFromRotation(int angle, bool *success = nullptr); Transform transformFromOrientation(const CameraConfiguration::Orientation &orientation); CameraConfiguration::Orientation transformToOrientation(const Transform &transform); +Transform operator/(CameraConfiguration::Orientation o1, + CameraConfiguration::Orientation o2); +CameraConfiguration::Orientation operator*(CameraConfiguration::Orientation o1, + Transform t); + const char *transformToString(Transform t); } /* namespace libcamera */ diff --git a/src/libcamera/transform.cpp b/src/libcamera/transform.cpp index 03d2b52e7f38..61dbb1ff1dd5 100644 --- a/src/libcamera/transform.cpp +++ b/src/libcamera/transform.cpp @@ -357,6 +357,104 @@ CameraConfiguration::Orientation transformToOrientation(const Transform &transfo return CameraConfiguration::rotate0; } +/** + * \brief Return the Transform that applied to \a o2 gives \a o1 + * \param o1 The Orientation to obtain + * \param o2 The base Orientation + * + * This operation can be used to easily compute the Transform to apply to a + * base orientation \a o2 to get the desired orientation \a o1. + * + * The CameraSensor class uses this function to compute what Transform to apply + * to a camera with mounting rotation \a o2 (the base) to obtain the user + * requested orientation \a o1. + * + * \return A Transform that applied to \a o2 gives \a o1 + */ +Transform operator/(CameraConfiguration::Orientation o1, + CameraConfiguration::Orientation o2) +{ + Transform t1 = transformFromOrientation(o1); + Transform t2 = transformFromOrientation(o2); + + /* Return immediately if the two are identical. */ + if (t1 == t2) + return Transform::Identity; + + /* If t1 is identity we need to apply -t2 to get it. */ + if (t1 == Transform::Identity) + return -t2; + + /* If t2 is identity, to get t1 we still need to do... t1. */ + if (t2 == Transform::Identity) + return t1; + + Transform combined = t1 ^ t2; + Transform result = combined; + + /* + * If the base orientation is transposed we need to invert the flips on + * the combined result. + * + * Using Rot90 as an example: + * + * Rot180 / Rot90 = Rot90 + * = (H|V) ^ (T|V) = (T|H) + * = invert_flips(T|H) = (T|V) = Rot90 + * + * Rot0 / Rot90 = Rot270 + * = () ^ (T|V) = (T|V) + * = invert_flips(T|V) = (T|H) = Rot270 + * + * Rot270 / Rot90 = Rot180 + * = (T|H) ^ (T|V) = (H|V) + * = invert_flips(H|V) = (V|H) = Rot180 + * + * Rot180Transpose / Rot90 = V + * = (T|H|V) ^ (T|V) = (H) + * = invert_flips(H) = (V) + * + * Rot270 / Transpose = V + * = (T|H) ^ T = H + * = invert_flips(H) = (V) + */ + if (!!(t2 & Transform::Transpose)) { + result = combined & Transform::Transpose; + if (!!(combined & Transform::HFlip)) + result |= Transform::VFlip; + if (!!(combined & Transform::VFlip)) + result |= Transform::HFlip; + } + + return result; +} + +/** + * \brief Apply the Transform \a t on the base orientation \a o + * \param o The base orientation + * \param t The transform to apply on \a o + * \return The Orientation resulting from applying \a t on \a o + */ +CameraConfiguration::Orientation operator*(CameraConfiguration::Orientation o, + Transform t) +{ + /* Apply an Indentity always gives us back the other operand. */ + if (t == Transform::Identity) + return o; + + /* + * As operator*(Transform t2, Transform t1) composes two Tranform + * by applying t1 first then t2 according to the canonical function + * composition notion, we here first apply a Transform corresponding to + * the base orientation and the apply \a t to it. + */ + Transform t1 = transformFromOrientation(o); + if (t1 == Transform::Identity) + return transformToOrientation(t); + + return transformToOrientation(t * t1); +} + /** * \brief Return a character string describing the transform * \param[in] t The transform to be described.